• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "core/components_ng/pattern/menu/preview/menu_preview_layout_algorithm.h"
17 
18 #include "core/components_ng/pattern/menu/menu_pattern.h"
19 #include "core/components_ng/pattern/menu/preview/menu_preview_pattern.h"
20 
21 namespace OHOS::Ace::NG {
Measure(LayoutWrapper * layoutWrapper)22 void MenuPreviewLayoutAlgorithm::Measure(LayoutWrapper* layoutWrapper)
23 {
24     UpdateLayoutConstraintForPreview(layoutWrapper);
25     auto layoutConstraint = layoutWrapper->GetLayoutProperty()->CreateChildConstraint();
26     for (const auto& child : layoutWrapper->GetAllChildrenWithBuild()) {
27         child->Measure(layoutConstraint);
28     }
29 
30     LinearLayoutAlgorithm::Measure(layoutWrapper);
31 }
32 
Layout(LayoutWrapper * layoutWrapper)33 void MenuPreviewLayoutAlgorithm::Layout(LayoutWrapper* layoutWrapper)
34 {
35     auto preview = layoutWrapper->GetHostNode();
36     CHECK_NULL_VOID(preview);
37     auto previewPattern = preview->GetPattern<MenuPreviewPattern>();
38     CHECK_NULL_VOID(previewPattern);
39     auto menuWrapper = previewPattern->GetMenuWrapper();
40     CHECK_NULL_VOID(menuWrapper);
41     auto menuWrapperPattern = menuWrapper->GetPattern<MenuWrapperPattern>();
42     CHECK_NULL_VOID(menuWrapperPattern);
43     auto menuNode = menuWrapperPattern->GetMenu();
44     CHECK_NULL_VOID(menuNode);
45     auto menuLayoutAlgorithmWrapper = menuNode->GetLayoutAlgorithm();
46     CHECK_NULL_VOID(menuLayoutAlgorithmWrapper);
47     auto menuLayoutAlgorithm = DynamicCast<MenuLayoutAlgorithm>(menuLayoutAlgorithmWrapper->GetLayoutAlgorithm());
48     CHECK_NULL_VOID(menuLayoutAlgorithm);
49     auto menuPattern = menuNode->GetPattern<MenuPattern>();
50     CHECK_NULL_VOID(menuPattern);
51     if (!menuPattern->HasLaid()) {
52         menuLayoutAlgorithm->Measure(AceType::RawPtr(menuNode));
53         menuLayoutAlgorithm->Layout(AceType::RawPtr(menuNode));
54         // This is a workaround, because sometimes the dirty will not be marked to the top menu node,
55         // the image size of the hoverScale may change. After the change, the image needs to call layout to send
56         // the measured paint to the rosen paint.
57         LayoutHoverScaleImage(menuWrapperPattern);
58     }
59     menuPattern->SetHasLaid(false);
60     for (const auto& child : layoutWrapper->GetAllChildrenWithBuild()) {
61         child->Layout();
62     }
63     LinearLayoutAlgorithm::Layout(layoutWrapper);
64 }
65 
LayoutHoverScaleImage(const RefPtr<MenuWrapperPattern> & wrapperPattern)66 void MenuPreviewLayoutAlgorithm::LayoutHoverScaleImage(const RefPtr<MenuWrapperPattern>& wrapperPattern)
67 {
68     CHECK_NULL_VOID(wrapperPattern);
69     if (!wrapperPattern->GetIsShowHoverImage()) {
70         return;
71     }
72     auto hoverScaleImage = wrapperPattern->GetHoverImagePreview();
73     CHECK_NULL_VOID(hoverScaleImage);
74     hoverScaleImage->Layout();
75 }
76 
UpdateLayoutConstraintForPreview(LayoutWrapper * layoutWrapper)77 void MenuPreviewLayoutAlgorithm::UpdateLayoutConstraintForPreview(LayoutWrapper* layoutWrapper)
78 {
79     auto preview = layoutWrapper->GetHostNode();
80     CHECK_NULL_VOID(preview);
81     auto previewPattern = preview->GetPattern<MenuPreviewPattern>();
82     CHECK_NULL_VOID(previewPattern);
83     auto menuWrapper = previewPattern->GetMenuWrapper();
84     CHECK_NULL_VOID(menuWrapper);
85     auto menuWrapperPattern = menuWrapper->GetPattern<MenuWrapperPattern>();
86     CHECK_NULL_VOID(menuWrapperPattern);
87     auto menuParam = menuWrapperPattern->GetMenuParam();
88     CHECK_NULL_VOID(menuParam.isPreviewContainScale);
89     auto menuNode = menuWrapperPattern->GetMenu();
90     CHECK_NULL_VOID(menuNode);
91     auto menuPattern = menuNode->GetPattern<MenuPattern>();
92     CHECK_NULL_VOID(menuPattern);
93     auto menuWindowRect = menuPattern->GetMenuWindowRect();
94     auto maxWidth = menuWindowRect.Width();
95     auto maxHeight = menuWindowRect.Height();
96     auto targetSize = menuPattern->GetTargetSize();
97     auto isOversize = GreatNotEqual(targetSize.Width(), maxWidth) || GreatNotEqual(targetSize.Height(), maxHeight);
98     if (isOversize) {
99         auto widthDelta = targetSize.Width() - maxWidth;
100         auto heightDelta = targetSize.Height() - maxHeight;
101         if (GreatOrEqual(widthDelta, heightDelta)) {
102             maxHeight = targetSize.Height() * (maxWidth / targetSize.Width());
103         } else {
104             maxWidth = targetSize.Width() * (maxHeight / targetSize.Height());
105         }
106         auto layoutConstraint = layoutWrapper->GetLayoutProperty()->CreateChildConstraint();
107         layoutConstraint.maxSize.SetWidth(maxWidth);
108         layoutConstraint.maxSize.SetHeight(maxHeight);
109         layoutConstraint.selfIdealSize.SetWidth(maxWidth);
110         layoutConstraint.selfIdealSize.SetHeight(maxHeight);
111         layoutWrapper->GetLayoutProperty()->UpdateLayoutConstraint(layoutConstraint);
112     }
113 }
114 } // namespace OHOS::Ace::NG
115