• 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/overlay/sheet_presentation_layout_algorithm.h"
17 #include "ui/base/referenced.h"
18 #include "core/components_ng/pattern/overlay/sheet_presentation_pattern.h"
19 #include "core/components_ng/pattern/overlay/sheet_view.h"
20 #include "core/components_ng/pattern/overlay/sheet_wrapper_pattern.h"
21 
22 namespace OHOS::Ace::NG {
23 namespace {
24 constexpr int32_t DOUBLE_SIZE = 2;
25 } // namespace
26 
InitParameter(LayoutWrapper * layoutWrapper)27 void SheetPresentationLayoutAlgorithm::InitParameter(LayoutWrapper* layoutWrapper)
28 {
29     CHECK_NULL_VOID(layoutWrapper);
30     auto host = layoutWrapper->GetHostNode();
31     CHECK_NULL_VOID(host);
32     auto sheetPattern = host->GetPattern<SheetPresentationPattern>();
33     CHECK_NULL_VOID(sheetPattern);
34     auto pipeline = host->GetContext();
35     CHECK_NULL_VOID(pipeline);
36     auto sheetTheme = pipeline->GetTheme<SheetTheme>();
37     CHECK_NULL_VOID(sheetTheme);
38 
39     // if 2in1, enableHoverMode is true by default.
40     DeviceType deviceType = SystemProperties::GetDeviceType();
41     auto enableHoverMode = sheetStyle_.enableHoverMode.value_or((deviceType == DeviceType::TWO_IN_ONE) ? true : false);
42     hoverModeArea_ = sheetStyle_.hoverModeArea.value_or(
43         (deviceType == DeviceType::TWO_IN_ONE) ? HoverModeAreaType::TOP_SCREEN : HoverModeAreaType::BOTTOM_SCREEN);
44     auto safeAreaManager = pipeline->GetSafeAreaManager();
45     auto keyboardInsert = safeAreaManager->GetKeyboardInset();
46     isKeyBoardShow_ = keyboardInsert.IsValid();
47     isHoverMode_ = enableHoverMode ? pipeline->IsHalfFoldHoverStatus() : false;
48     if (deviceType == DeviceType::TWO_IN_ONE) {
49         // if 2in1 WaterfallWindowMode, enableHoverMode is true by default.
50         isWaterfallWindowMode_ = sheetPattern->IsWaterfallWindowMode();
51         isHoverMode_ = enableHoverMode ? isWaterfallWindowMode_ : false;
52     }
53 }
54 
CalculateSheetHeightInOtherScenes(LayoutWrapper * layoutWrapper,const float heightBefore) const55 float SheetPresentationLayoutAlgorithm::CalculateSheetHeightInOtherScenes(
56     LayoutWrapper* layoutWrapper, const float heightBefore) const
57 {
58     auto height = heightBefore;
59     CHECK_NULL_RETURN(layoutWrapper, height);
60     auto host = layoutWrapper->GetHostNode();
61     CHECK_NULL_RETURN(host, height);
62     auto sheetPattern = host->GetPattern<SheetPresentationPattern>();
63     CHECK_NULL_RETURN(sheetPattern, height);
64     auto foldCreaseRect = sheetPattern->GetFoldScreenRect(); // relative window
65     if (sheetType_ != SheetType::SHEET_CENTER || !isHoverMode_) {
66         return height;
67     }
68     float maxUpSheetHeight = foldCreaseRect.Top() - SHEET_HOVERMODE_UP_HEIGHT.ConvertToPx();
69     float maxDownSheetHeight = sheetMaxHeight_ - SHEET_HOVERMODE_DOWN_HEIGHT.ConvertToPx() - foldCreaseRect.Bottom();
70     NG::RectF floatButtons;
71     if (isWaterfallWindowMode_) {
72         auto sheetWrapper = host->GetParent();
73         CHECK_NULL_RETURN(sheetWrapper, height);
74         auto sheetWrapperNode = AceType::DynamicCast<FrameNode>(sheetWrapper);
75         CHECK_NULL_RETURN(sheetWrapperNode, height);
76         maxUpSheetHeight = foldCreaseRect.Top() - sheetWrapperNode->GetPositionToScreen().GetY() -
77                            DOUBLE_SIZE * (SHEET_BLANK_MINI_HEIGHT.ConvertToPx());
78         if (sheetPattern->GetWindowButtonRectForAllAPI(floatButtons)) {
79             maxUpSheetHeight =
80                 foldCreaseRect.Top() - DOUBLE_SIZE * (floatButtons.Height() + SHEET_BLANK_MINI_HEIGHT.ConvertToPx());
81         }
82     }
83     TAG_LOGD(AceLogTag::ACE_SHEET, "maxUpSheetHeight: %{public}f, maxDownSheetHeight: %{public}f.", maxUpSheetHeight,
84         maxDownSheetHeight);
85     return std::min(height,
86         (hoverModeArea_ == HoverModeAreaType::TOP_SCREEN || isKeyBoardShow_) ? maxUpSheetHeight : maxDownSheetHeight);
87 }
88 
CalculateSheetOffsetInOtherScenes(LayoutWrapper * layoutWrapper)89 void SheetPresentationLayoutAlgorithm::CalculateSheetOffsetInOtherScenes(LayoutWrapper* layoutWrapper)
90 {
91     CHECK_NULL_VOID(layoutWrapper);
92     auto host = layoutWrapper->GetHostNode();
93     CHECK_NULL_VOID(host);
94     auto sheetPattern = host->GetPattern<SheetPresentationPattern>();
95     CHECK_NULL_VOID(sheetPattern);
96     auto geometryNode = layoutWrapper->GetGeometryNode();
97     CHECK_NULL_VOID(geometryNode);
98     auto foldCreaseRect = sheetPattern->GetFoldScreenRect(); // relative window
99     auto frameSizeHeight = geometryNode->GetFrameSize().Height();
100     if (sheetType_ != SheetType::SHEET_CENTER || !isHoverMode_) {
101         return;
102     }
103     float upScreenHeight = foldCreaseRect.Top() - SHEET_HOVERMODE_UP_HEIGHT.ConvertToPx();
104     float downScreenHeight = sheetMaxHeight_ - SHEET_HOVERMODE_DOWN_HEIGHT.ConvertToPx() - foldCreaseRect.Bottom();
105     float topStartOffsetY = SHEET_HOVERMODE_UP_HEIGHT.ConvertToPx();
106     NG::RectF floatButtons;
107     if (isWaterfallWindowMode_) {
108         auto sheetWrapper = host->GetParent();
109         CHECK_NULL_VOID(sheetWrapper);
110         auto sheetWrapperNode = AceType::DynamicCast<FrameNode>(sheetWrapper);
111         CHECK_NULL_VOID(sheetWrapperNode);
112         upScreenHeight = foldCreaseRect.Top() - sheetWrapperNode->GetPositionToScreen().GetY();
113         topStartOffsetY = 0.0f;
114         if (sheetPattern->GetWindowButtonRectForAllAPI(floatButtons)) {
115             upScreenHeight =
116                 foldCreaseRect.Top() - DOUBLE_SIZE * (floatButtons.Height() + SHEET_BLANK_MINI_HEIGHT.ConvertToPx());
117             topStartOffsetY = floatButtons.Height() + SHEET_BLANK_MINI_HEIGHT.ConvertToPx();
118         }
119     }
120     if (hoverModeArea_ == HoverModeAreaType::TOP_SCREEN || isKeyBoardShow_) {
121         sheetOffsetY_ = topStartOffsetY + (upScreenHeight - frameSizeHeight) / DOUBLE_SIZE;
122     } else {
123         sheetOffsetY_ = foldCreaseRect.Bottom() + (downScreenHeight - frameSizeHeight) / DOUBLE_SIZE;
124     }
125 }
126 
ComputeWidthAndHeight(LayoutWrapper * layoutWrapper)127 void SheetPresentationLayoutAlgorithm::ComputeWidthAndHeight(LayoutWrapper* layoutWrapper)
128 {
129     auto host = layoutWrapper->GetHostNode();
130     CHECK_NULL_VOID(host);
131     auto sheetWrapper = AceType::DynamicCast<FrameNode>(host->GetParent());
132     CHECK_NULL_VOID(sheetWrapper);
133     auto sheetWrapperPattern = sheetWrapper->GetPattern<SheetWrapperPattern>();
134     CHECK_NULL_VOID(sheetWrapperPattern);
135     auto layoutProperty = AceType::DynamicCast<SheetPresentationProperty>(layoutWrapper->GetLayoutProperty());
136     CHECK_NULL_VOID(layoutProperty);
137     auto parentConstraint = layoutWrapper->GetGeometryNode()->GetParentLayoutConstraint();
138     LayoutConstraintF layoutConstraint = parentConstraint.value();
139     layoutProperty->UpdateLayoutConstraint(layoutConstraint);
140     auto maxSize = layoutConstraint.maxSize;
141     sheetMaxHeight_ = maxSize.Height();
142     sheetMaxWidth_ = maxSize.Width();
143     auto showInSubWindow = sheetStyle_.showInSubWindow.value_or(false);
144     auto parentHeightConstraint = sheetMaxHeight_;
145     auto parentWidthConstraint = sheetMaxWidth_;
146     if (showInSubWindow && !sheetWrapperPattern->ShowInUEC()) {
147         auto host = layoutWrapper->GetHostNode();
148         CHECK_NULL_VOID(host);
149         auto sheetWrapper = AceType::DynamicCast<FrameNode>(host->GetParent());
150         CHECK_NULL_VOID(sheetWrapper);
151         auto sheetWrapperPattern = sheetWrapper->GetPattern<SheetWrapperPattern>();
152         CHECK_NULL_VOID(sheetWrapperPattern);
153         auto mainWindowRect = sheetWrapperPattern->GetMainWindowRect();
154         parentHeightConstraint = mainWindowRect.Height();
155         parentWidthConstraint = mainWindowRect.Width();
156     }
157     sheetWidth_ = GetWidthByScreenSizeType(parentWidthConstraint, layoutWrapper);
158     sheetHeight_ = GetHeightByScreenSizeType(parentHeightConstraint, parentWidthConstraint, layoutWrapper);
159 }
160 
MeasureDragBar(LayoutWrapper * layoutWrapper,LayoutConstraintF constraint)161 void SheetPresentationLayoutAlgorithm::MeasureDragBar(LayoutWrapper* layoutWrapper, LayoutConstraintF constraint)
162 {
163     auto host = layoutWrapper->GetHostNode();
164     CHECK_NULL_VOID(host);
165     auto sheetPattern = host->GetPattern<SheetPresentationPattern>();
166     CHECK_NULL_VOID(sheetPattern);
167     auto dragBarNode = sheetPattern->GetDragBarNode();
168     CHECK_NULL_VOID(dragBarNode);
169     dragBarNode->Measure(constraint);
170 }
171 
MeasureOperation(LayoutWrapper * layoutWrapper,LayoutConstraintF constraint)172 void SheetPresentationLayoutAlgorithm::MeasureOperation(LayoutWrapper* layoutWrapper, LayoutConstraintF constraint)
173 {
174     auto host = layoutWrapper->GetHostNode();
175     CHECK_NULL_VOID(host);
176     auto sheetPattern = host->GetPattern<SheetPresentationPattern>();
177     CHECK_NULL_VOID(sheetPattern);
178     auto operationNode = sheetPattern->GetTitleBuilderNode();
179     CHECK_NULL_VOID(operationNode);
180     operationNode->Measure(constraint);
181 }
182 
MeasureCloseIcon(LayoutWrapper * layoutWrapper,LayoutConstraintF constraint)183 void SheetPresentationLayoutAlgorithm::MeasureCloseIcon(LayoutWrapper* layoutWrapper, LayoutConstraintF constraint)
184 {
185     auto host = layoutWrapper->GetHostNode();
186     CHECK_NULL_VOID(host);
187     auto sheetPattern = host->GetPattern<SheetPresentationPattern>();
188     CHECK_NULL_VOID(sheetPattern);
189     auto sheetCloseIcon = sheetPattern->GetSheetCloseIcon();
190     CHECK_NULL_VOID(sheetCloseIcon);
191     sheetCloseIcon->Measure(constraint);
192 }
193 
Measure(LayoutWrapper * layoutWrapper)194 void SheetPresentationLayoutAlgorithm::Measure(LayoutWrapper* layoutWrapper)
195 {
196     CHECK_NULL_VOID(layoutWrapper);
197     auto layoutProperty = AceType::DynamicCast<SheetPresentationProperty>(layoutWrapper->GetLayoutProperty());
198     CHECK_NULL_VOID(layoutProperty);
199     sheetStyle_ = layoutProperty->GetSheetStyleValue(SheetStyle());
200     auto layoutConstraint = layoutProperty->GetLayoutConstraint();
201     if (!layoutConstraint) {
202         TAG_LOGE(AceLogTag::ACE_SHEET, "fail to measure sheet due to layoutConstraint is nullptr");
203         return;
204     }
205     InitParameter(layoutWrapper);
206     if (layoutWrapper->GetGeometryNode() && layoutWrapper->GetGeometryNode()->GetParentLayoutConstraint()) {
207         ComputeWidthAndHeight(layoutWrapper);
208         AddArrowHeightToSheetSize();
209         SizeF idealSize(sheetWidth_, sheetHeight_);
210         layoutWrapper->GetGeometryNode()->SetFrameSize(idealSize);
211         layoutWrapper->GetGeometryNode()->SetContentSize(idealSize);
212         auto childConstraint = CreateSheetChildConstraint(layoutProperty, layoutWrapper);
213         layoutConstraint->percentReference = SizeF(sheetWidth_, sheetHeight_);
214         MeasureDragBar(layoutWrapper, childConstraint);
215         MeasureOperation(layoutWrapper, childConstraint);
216         MeasureCloseIcon(layoutWrapper, childConstraint);
217         auto host = layoutWrapper->GetHostNode();
218         CHECK_NULL_VOID(host);
219         auto sheetPattern = host->GetPattern<SheetPresentationPattern>();
220         CHECK_NULL_VOID(sheetPattern);
221         auto scrollNode = sheetPattern->GetSheetScrollNode();
222         CHECK_NULL_VOID(scrollNode);
223         childConstraint.selfIdealSize.SetWidth(childConstraint.maxSize.Width());
224         scrollNode->Measure(childConstraint);
225         if ((sheetType_ == SheetType::SHEET_CENTER || sheetType_ == SheetType::SHEET_POPUP ||
226             (sheetType_ == SheetType::SHEET_BOTTOM_OFFSET))
227             && (sheetStyle_.sheetHeight.sheetMode.value_or(SheetMode::LARGE) == SheetMode::AUTO)) {
228             auto secondChild = AceType::DynamicCast<LayoutWrapper>(scrollNode);
229             CHECK_NULL_VOID(secondChild);
230             auto&& scrollChild = secondChild->GetAllChildrenWithBuild();
231             auto builder = scrollChild.front();
232             CHECK_NULL_VOID(builder);
233             auto builderGeometryNode = builder->GetGeometryNode();
234             CHECK_NULL_VOID(builderGeometryNode);
235             sheetHeight_ = sheetPattern->GetTitleBuilderHeight() + builderGeometryNode->GetFrameSize().Height();
236             float sheetMaxHeight = sheetMaxHeight_;
237             if (SheetInSplitWindow()) {
238                 auto pipelineContext = PipelineContext::GetCurrentContext();
239                 auto windowGlobalRect = pipelineContext->GetDisplayWindowRectInfo();
240                 sheetMaxHeight = windowGlobalRect.Height() - SHEET_SPLIT_STATUS_BAR.ConvertToPx()-
241                     SHEET_SPLIT_AI_BAR.ConvertToPx();
242             }
243             auto pipeline = host->GetContext();
244             CHECK_NULL_VOID(pipeline);
245             auto sheetTheme = pipeline->GetTheme<SheetTheme>();
246             CHECK_NULL_VOID(sheetTheme);
247             auto bigWindowMinHeight = sheetTheme->GetBigWindowMinHeight();
248             auto maxHeight = std::min(sheetMaxHeight, sheetMaxWidth_) * POPUP_LARGE_SIZE;
249             maxHeight = SheetInSplitWindow()
250                 ? maxHeight : std::max(maxHeight, static_cast<float>(bigWindowMinHeight.ConvertToPx()));
251             if (LessNotEqual(sheetHeight_, 0.0f)) {
252                 sheetHeight_ = SHEET_BIG_WINDOW_HEIGHT.ConvertToPx();
253             } else if (LessOrEqual(sheetHeight_, bigWindowMinHeight.ConvertToPx()) && !SheetInSplitWindow()) {
254                 sheetHeight_ = bigWindowMinHeight.ConvertToPx();
255             } else if (GreatOrEqual(sheetHeight_, maxHeight)) {
256                 sheetHeight_ = maxHeight;
257             }
258             SizeF idealSize(sheetWidth_, sheetHeight_);
259             layoutWrapper->GetGeometryNode()->SetFrameSize(idealSize);
260             childConstraint = CreateSheetChildConstraint(layoutProperty, layoutWrapper);
261             secondChild->Measure(childConstraint);
262         }
263     }
264 }
265 
ComputeCenterStyleOffset(LayoutWrapper * layoutWrapper)266 void SheetPresentationLayoutAlgorithm::ComputeCenterStyleOffset(LayoutWrapper* layoutWrapper)
267 {
268     auto showInSubWindow = sheetStyle_.showInSubWindow.value_or(false);
269     if (!showInSubWindow) {
270         sheetOffsetX_ = (sheetMaxWidth_ - sheetWidth_) / DOUBLE_SIZE;
271         return;
272     }
273     auto host = layoutWrapper->GetHostNode();
274     CHECK_NULL_VOID(host);
275     auto sheetWrapper = AceType::DynamicCast<FrameNode>(host->GetParent());
276     CHECK_NULL_VOID(sheetWrapper);
277     auto sheetWrapperPattern = sheetWrapper->GetPattern<SheetWrapperPattern>();
278     CHECK_NULL_VOID(sheetWrapperPattern);
279     auto geometryNode = host->GetGeometryNode();
280     CHECK_NULL_VOID(geometryNode);
281     auto sheetFrameSize = geometryNode->GetFrameSize();
282 
283     if (sheetWrapperPattern->ShowInUEC()) {
284         ComputeCenterOffsetForUECSubwindow(layoutWrapper);
285     } else {
286         ComputeCenterOffsetForNotUECSubwindow(layoutWrapper);
287     }
288 
289     std::vector<Rect> rects;
290     auto rect = Rect(sheetOffsetX_, sheetOffsetY_,
291         sheetFrameSize.Width(), sheetFrameSize.Height());
292     rects.emplace_back(rect);
293     SubwindowManager::GetInstance()->SetHotAreas(rects, SubwindowType::TYPE_SHEET,
294         host->GetId(), sheetWrapperPattern->GetSubWindowId());
295 }
296 
ComputeCenterOffsetForUECSubwindow(LayoutWrapper * layoutWrapper)297 void SheetPresentationLayoutAlgorithm::ComputeCenterOffsetForUECSubwindow(
298     LayoutWrapper* layoutWrapper)
299 {
300     CHECK_NULL_VOID(layoutWrapper);
301     auto host = layoutWrapper->GetHostNode();
302     CHECK_NULL_VOID(host);
303     sheetOffsetX_ = (sheetMaxWidth_ - sheetWidth_) / DOUBLE_SIZE;
304     sheetOffsetY_ = (sheetMaxHeight_ - sheetHeight_) / DOUBLE_SIZE;
305 }
306 
ComputeCenterOffsetForNotUECSubwindow(LayoutWrapper * layoutWrapper)307 void SheetPresentationLayoutAlgorithm::ComputeCenterOffsetForNotUECSubwindow(LayoutWrapper* layoutWrapper)
308 {
309     CHECK_NULL_VOID(layoutWrapper);
310     auto host = layoutWrapper->GetHostNode();
311     CHECK_NULL_VOID(host);
312     auto sheetWrapper = AceType::DynamicCast<FrameNode>(host->GetParent());
313     CHECK_NULL_VOID(sheetWrapper);
314     auto sheetWrapperPattern = sheetWrapper->GetPattern<SheetWrapperPattern>();
315     CHECK_NULL_VOID(sheetWrapperPattern);
316     auto mainWindowRect = sheetWrapperPattern->GetMainWindowRect();
317     auto geometryNode = host->GetGeometryNode();
318     CHECK_NULL_VOID(geometryNode);
319     auto sheetFrameSize = geometryNode->GetFrameSize();
320     auto hostWindowId = SubwindowManager::GetInstance()->GetParentContainerId(sheetWrapperPattern->GetSubWindowId());
321     ContainerScope scope(hostWindowId);
322     auto container = AceEngine::Get().GetContainer(hostWindowId);
323     CHECK_NULL_VOID(container);
324     auto mainWindowContext = AceType::DynamicCast<NG::PipelineContext>(container->GetPipelineContext());
325 
326     auto subContainer = AceEngine::Get().GetContainer(sheetWrapperPattern->GetSubWindowId());
327     CHECK_NULL_VOID(subContainer);
328     auto subWindowContext = AceType::DynamicCast<NG::PipelineContext>(subContainer->GetPipelineContext());
329     CHECK_NULL_VOID(subWindowContext);
330     auto subwindowRootRect = subWindowContext->GetRootRect();
331     sheetOffsetY_ = (subwindowRootRect.Height() - sheetFrameSize.Height()) / DOUBLE_SIZE;
332     sheetOffsetX_ = (subwindowRootRect.Width()  - sheetFrameSize.Width()) / DOUBLE_SIZE;
333 
334     OffsetF windowAnchoroffset;
335     auto sheetTheme = mainWindowContext->GetTheme<SheetTheme>();
336     CHECK_NULL_VOID(sheetTheme);
337     auto bigWindowMinHeight = sheetTheme->GetBigWindowMinHeight();
338     RectF containerModal;
339     RectF buttonsRect;
340     // By default, subWindow and mainWindow are aligned based on center anchor.
341     // When mainwindow is reduced to a certain extent, centerSheet will stick to the title bar of the mainWindow layout.
342     // At this time, the anchor point of subWindow and mainWindow need to be moved down at a distance.
343     // The distance is equal to a half of the reduced height.
344     if (mainWindowContext && mainWindowContext->GetContainerModalButtonsRect(containerModal, buttonsRect)) {
345         auto maxMainWindowHeight = bigWindowMinHeight.ConvertToPx() +
346             DOUBLE_SIZE * (buttonsRect.Height() + SHEET_BLANK_MINI_HEIGHT.ConvertToPx());
347         windowAnchoroffset.SetY(mainWindowRect.Height() > maxMainWindowHeight ? 0.0f :
348             (maxMainWindowHeight - mainWindowRect.Height()) / DOUBLE_SIZE);
349     }
350     SubwindowManager::GetInstance()->SetWindowAnchorInfo(
351         windowAnchoroffset, SubwindowType::TYPE_SHEET, host->GetId(), sheetWrapperPattern->GetSubWindowId());
352 }
353 
ComputePopupStyleOffset(LayoutWrapper * layoutWrapper)354 void SheetPresentationLayoutAlgorithm::ComputePopupStyleOffset(LayoutWrapper* layoutWrapper)
355 {
356     sheetOffsetX_ = sheetPopupInfo_.sheetOffsetX;
357     sheetOffsetY_ = sheetPopupInfo_.sheetOffsetY;
358     auto showInSubWindow = sheetStyle_.showInSubWindow.value_or(false);
359     if (showInSubWindow) {
360         auto host = layoutWrapper->GetHostNode();
361         CHECK_NULL_VOID(host);
362         auto sheetWrapper = AceType::DynamicCast<FrameNode>(host->GetParent());
363         CHECK_NULL_VOID(sheetWrapper);
364         auto sheetWrapperPattern = sheetWrapper->GetPattern<SheetWrapperPattern>();
365         CHECK_NULL_VOID(sheetWrapperPattern);
366         MinusSubwindowDistance(sheetWrapper);
367         std::vector<Rect> rects;
368         auto rect = Rect(sheetOffsetX_, sheetOffsetY_,
369             host->GetGeometryNode()->GetFrameSize().Width(), host->GetGeometryNode()->GetFrameSize().Height());
370         rects.emplace_back(rect);
371         auto subWindowMgr = SubwindowManager::GetInstance();
372         subWindowMgr->SetHotAreas(rects, SubwindowType::TYPE_SHEET, host->GetId(),
373             sheetWrapperPattern->GetSubWindowId());
374     }
375 }
376 
MinusSubwindowDistance(const RefPtr<FrameNode> & sheetWrapper)377 void SheetPresentationLayoutAlgorithm::MinusSubwindowDistance(const RefPtr<FrameNode>& sheetWrapper)
378 {
379     // when subwindow is not full screen for split or small floating window
380     CHECK_NULL_VOID(sheetWrapper);
381     auto sheetWrapperPattern = sheetWrapper->GetPattern<SheetWrapperPattern>();
382     CHECK_NULL_VOID(sheetWrapperPattern);
383     auto subContainer = AceEngine::Get().GetContainer(sheetWrapperPattern->GetSubWindowId());
384     CHECK_NULL_VOID(subContainer);
385     auto subWindowContext = AceType::DynamicCast<NG::PipelineContext>(subContainer->GetPipelineContext());
386     CHECK_NULL_VOID(subWindowContext);
387     auto subWindowGlobalRect = subWindowContext->GetDisplayWindowRectInfo();
388     sheetOffsetX_ -= subWindowGlobalRect.Left();
389     sheetOffsetY_ -= subWindowGlobalRect.Top();
390 }
391 
LayoutTitleBuilder(const NG::OffsetF & translate,LayoutWrapper * layoutWrapper)392 void SheetPresentationLayoutAlgorithm::LayoutTitleBuilder(const NG::OffsetF& translate, LayoutWrapper* layoutWrapper)
393 {
394     auto host = layoutWrapper->GetHostNode();
395     CHECK_NULL_VOID(host);
396     auto sheetPattern = host->GetPattern<SheetPresentationPattern>();
397     CHECK_NULL_VOID(sheetPattern);
398     auto titleBuilderNode = sheetPattern->GetTitleBuilderNode();
399     CHECK_NULL_VOID(titleBuilderNode);
400     auto index = host->GetChildIndexById(titleBuilderNode->GetId());
401     auto titleBuilderWrapper = layoutWrapper->GetOrCreateChildByIndex(index);
402     CHECK_NULL_VOID(titleBuilderWrapper);
403     auto geometryNode = titleBuilderWrapper->GetGeometryNode();
404     CHECK_NULL_VOID(geometryNode);
405     auto offset = translate;
406     auto dragBarNode = sheetPattern->GetDragBarNode();
407     CHECK_NULL_VOID(dragBarNode);
408     if (!sheetStyle_.enableFloatingDragBar.value_or(false) || !sheetPattern->IsSheetBottomStyle()) {
409         auto dragBar = dragBarNode->GetGeometryNode();
410         CHECK_NULL_VOID(dragBar);
411         offset += OffsetF(0, dragBar->GetFrameSize().Height());
412     }
413     geometryNode->SetMarginFrameOffset(offset);
414     titleBuilderWrapper->Layout();
415 }
416 
LayoutCloseIcon(const NG::OffsetF & translate,LayoutWrapper * layoutWrapper)417 void SheetPresentationLayoutAlgorithm::LayoutCloseIcon(const NG::OffsetF& translate,
418     LayoutWrapper* layoutWrapper)
419 {
420     auto host = layoutWrapper->GetHostNode();
421     CHECK_NULL_VOID(host);
422     auto sheetPattern = host->GetPattern<SheetPresentationPattern>();
423     CHECK_NULL_VOID(sheetPattern);
424     auto sheetCloseNode = sheetPattern->GetSheetCloseIcon();
425     CHECK_NULL_VOID(sheetCloseNode);
426     auto index = host->GetChildIndexById(sheetCloseNode->GetId());
427     auto closeIconWrapper = layoutWrapper->GetOrCreateChildByIndex(index);
428     CHECK_NULL_VOID(closeIconWrapper);
429     auto geometryNode = closeIconWrapper->GetGeometryNode();
430     CHECK_NULL_VOID(geometryNode);
431 
432     auto pipeline = host->GetContext();
433     CHECK_NULL_VOID(pipeline);
434     auto sheetTheme = pipeline->GetTheme<SheetTheme>();
435     CHECK_NULL_VOID(sheetTheme);
436     auto sheetGeometryNode = layoutWrapper->GetGeometryNode();
437     CHECK_NULL_VOID(sheetGeometryNode);
438     auto closeIconX = sheetGeometryNode->GetFrameSize().Width() -
439                       static_cast<float>(sheetTheme->GetCloseIconButtonWidth().ConvertToPx()) -
440                       static_cast<float>(sheetTheme->GetTitleTextMargin().ConvertToPx());
441     if (AceApplicationInfo::GetInstance().IsRightToLeft() &&
442         AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
443         closeIconX = static_cast<float>(sheetTheme->GetTitleTextMargin().ConvertToPx());
444     }
445     auto closeIconY = static_cast<float>(sheetTheme->GetTitleTextMargin().ConvertToPx());
446     OffsetF positionOffset;
447     positionOffset.SetX(closeIconX + translate.GetX());
448     positionOffset.SetY(closeIconY + translate.GetY());
449     geometryNode->SetMarginFrameOffset(positionOffset);
450     closeIconWrapper->Layout();
451 }
452 
LayoutScrollNode(const NG::OffsetF & translate,LayoutWrapper * layoutWrapper)453 void SheetPresentationLayoutAlgorithm::LayoutScrollNode(const NG::OffsetF& translate, LayoutWrapper* layoutWrapper)
454 {
455     auto host = layoutWrapper->GetHostNode();
456     CHECK_NULL_VOID(host);
457     auto sheetPattern = host->GetPattern<SheetPresentationPattern>();
458     CHECK_NULL_VOID(sheetPattern);
459     auto scrollNode = sheetPattern->GetSheetScrollNode();
460     CHECK_NULL_VOID(scrollNode);
461     auto index = host->GetChildIndexById(scrollNode->GetId());
462     auto scrollWrapper = layoutWrapper->GetOrCreateChildByIndex(index);
463     CHECK_NULL_VOID(scrollWrapper);
464 
465     auto offset = translate;
466     auto titleBuilder = sheetPattern->GetTitleBuilderNode();
467     auto dragBarNode = sheetPattern->GetDragBarNode();
468     if (titleBuilder) {
469         auto titleBuilderNode = titleBuilder->GetGeometryNode();
470         CHECK_NULL_VOID(titleBuilderNode);
471         float titleHeight =
472             Positive(titleBuilderNode->GetFrameSize().Height()) ? titleBuilderNode->GetFrameSize().Height() : 0.0f;
473         auto dragBar = dragBarNode->GetGeometryNode();
474         CHECK_NULL_VOID(dragBar);
475         if (!sheetStyle_.enableFloatingDragBar.value_or(false) || !sheetPattern->IsSheetBottomStyle()) {
476             offset += OffsetF(0, titleHeight + dragBar->GetFrameSize().Height());
477         } else {
478             offset += OffsetF(0, titleHeight);
479         }
480     }
481     auto geometryNode = scrollWrapper->GetGeometryNode();
482     geometryNode->SetMarginFrameOffset(offset);
483     scrollWrapper->Layout();
484 }
485 
LayoutDragBar(const NG::OffsetF & translate,LayoutWrapper * layoutWrapper)486 void SheetPresentationLayoutAlgorithm::LayoutDragBar(const NG::OffsetF& translate, LayoutWrapper* layoutWrapper)
487 {
488     auto host = layoutWrapper->GetHostNode();
489     CHECK_NULL_VOID(host);
490     auto sheetPattern = host->GetPattern<SheetPresentationPattern>();
491     CHECK_NULL_VOID(sheetPattern);
492     auto dragBarNode = sheetPattern->GetDragBarNode();
493     CHECK_NULL_VOID(dragBarNode);
494     auto index = host->GetChildIndexById(dragBarNode->GetId());
495     auto dragBarWrapper = layoutWrapper->GetOrCreateChildByIndex(index);
496     CHECK_NULL_VOID(dragBarWrapper);
497     auto geometryNode = dragBarWrapper->GetGeometryNode();
498     CHECK_NULL_VOID(geometryNode);
499     auto pipeline = host->GetContext();
500     CHECK_NULL_VOID(pipeline);
501     auto sheetTheme = pipeline->GetTheme<SheetTheme>();
502     CHECK_NULL_VOID(sheetTheme);
503     auto sheetGeometryNode = layoutWrapper->GetGeometryNode();
504     CHECK_NULL_VOID(sheetGeometryNode);
505     auto dragBarX = (sheetGeometryNode->GetFrameSize().Width() - geometryNode->GetFrameSize().Width()) / 2;
506     OffsetF positionOffset;
507     positionOffset.SetX(dragBarX + translate.GetX());
508     CHECK_NULL_VOID(geometryNode);
509     geometryNode->SetMarginFrameOffset(positionOffset);
510     dragBarWrapper->Layout();
511 }
512 
Layout(LayoutWrapper * layoutWrapper)513 void SheetPresentationLayoutAlgorithm::Layout(LayoutWrapper* layoutWrapper)
514 {
515     CHECK_NULL_VOID(layoutWrapper);
516     sheetOffsetX_ = (sheetMaxWidth_ - sheetWidth_) / DOUBLE_SIZE;
517     if (sheetType_ == SheetType::SHEET_BOTTOMLANDSPACE) {
518         sheetOffsetX_ = (sheetMaxWidth_ - sheetWidth_) / DOUBLE_SIZE;
519     } else if (sheetType_ == SheetType::SHEET_CENTER) {
520         ComputeCenterStyleOffset(layoutWrapper);
521     } else if (sheetType_ == SheetType::SHEET_POPUP) {
522         ComputePopupStyleOffset(layoutWrapper);
523     } else if (sheetType_ == SheetType::SHEET_BOTTOM_OFFSET) {
524         sheetOffsetY_ = (sheetMaxHeight_ - sheetHeight_ + sheetStyle_.bottomOffset->GetY());
525         sheetOffsetX_ = sheetOffsetX_ + sheetStyle_.bottomOffset->GetX();
526     }
527     CalculateSheetOffsetInOtherScenes(layoutWrapper);
528     TAG_LOGD(AceLogTag::ACE_SHEET, "Sheet layout info, sheetOffsetX_ is: %{public}f, sheetOffsetY_ is: %{public}f",
529         sheetOffsetX_, sheetOffsetY_);
530     OffsetF positionOffset;
531     positionOffset.SetX(sheetOffsetX_);
532     positionOffset.SetY(0.0f);
533     auto geometryNode = layoutWrapper->GetGeometryNode();
534     CHECK_NULL_VOID(geometryNode);
535     // This step is only to determine the position of x, because y is to be done by the bit movement effect
536     geometryNode->SetMarginFrameOffset(positionOffset);
537     OffsetF translate(0.0f, 0.0f);
538     if (sheetType_ == SheetType::SHEET_POPUP) {
539         UpdateTranslateOffsetWithPlacement(translate, layoutWrapper);
540     }
541     LayoutCloseIcon(translate, layoutWrapper);
542     LayoutDragBar(translate, layoutWrapper);
543     LayoutTitleBuilder(translate, layoutWrapper);
544     LayoutScrollNode(translate, layoutWrapper);
545 }
546 
UpdateTranslateOffsetWithPlacement(OffsetF & translate,LayoutWrapper * layoutWrapper)547 void SheetPresentationLayoutAlgorithm::UpdateTranslateOffsetWithPlacement(OffsetF& translate,
548     LayoutWrapper* layoutWrapper)
549 {
550     auto host = layoutWrapper->GetHostNode();
551     CHECK_NULL_VOID(host);
552     if (host->LessThanAPITargetVersion(PlatformVersion::VERSION_EIGHTEEN)) {
553         translate += OffsetF(0, SHEET_ARROW_HEIGHT.ConvertToPx());
554         return;
555     }
556     if ((sheetPopupInfo_.placementRechecked && sheetPopupInfo_.placementOnTarget) ||
557         !sheetPopupInfo_.showArrow) {
558         return;
559     }
560     // child content should not show in arrow, so that child layout need translate to avoid sheet arrow.
561     switch (sheetPopupInfo_.finalPlacement) {
562         case Placement::BOTTOM_LEFT:
563             [[fallthrough]];
564         case Placement::BOTTOM_RIGHT:
565             [[fallthrough]];
566         case Placement::BOTTOM: {
567             translate += OffsetF(0.f, SHEET_ARROW_HEIGHT.ConvertToPx());
568             break;
569         }
570         case Placement::RIGHT_TOP:
571             [[fallthrough]];
572         case Placement::RIGHT_BOTTOM:
573             [[fallthrough]];
574         case Placement::RIGHT: {
575             translate += OffsetF(SHEET_ARROW_HEIGHT.ConvertToPx(), 0.f);
576             break;
577         }
578         default:
579             break;
580     }
581 }
582 
GetHeightByScreenSizeType(const float parentConstraintHeight,const float parentConstraintWidth,LayoutWrapper * layoutWrapper) const583 float SheetPresentationLayoutAlgorithm::GetHeightByScreenSizeType(const float parentConstraintHeight,
584     const float parentConstraintWidth, LayoutWrapper* layoutWrapper) const
585 {
586     float height = parentConstraintHeight;
587     switch (sheetType_) {
588         case SheetType::SHEET_BOTTOM:
589         case SheetType::SHEET_BOTTOM_FREE_WINDOW:
590         case SheetType::SHEET_BOTTOMLANDSPACE:
591             height = parentConstraintHeight;
592             break;
593         case SheetType::SHEET_BOTTOM_OFFSET:
594         case SheetType::SHEET_CENTER:
595             height = GetHeightBySheetStyle(parentConstraintHeight, parentConstraintWidth, layoutWrapper);
596             break;
597         case SheetType::SHEET_POPUP:
598             height = GetHeightBySheetStyle(parentConstraintHeight, parentConstraintWidth, layoutWrapper) +
599                 SHEET_ARROW_HEIGHT.ConvertToPx();
600             // The sheet height can only be confirmed after the placement is confirmed.
601             if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_EIGHTEEN)) {
602                 height -= SHEET_ARROW_HEIGHT.ConvertToPx();
603             }
604             break;
605         default:
606             break;
607     }
608     height = CalculateSheetHeightInOtherScenes(layoutWrapper, height);
609     return height;
610 }
611 
GetWidthByScreenSizeType(const float parentConstraintWidth,LayoutWrapper * layoutWrapper) const612 float SheetPresentationLayoutAlgorithm::GetWidthByScreenSizeType(const float parentConstraintWidth,
613     LayoutWrapper* layoutWrapper) const
614 {
615     float sheetWidth = parentConstraintWidth;
616     auto host = layoutWrapper->GetHostNode();
617     CHECK_NULL_RETURN(host, sheetWidth);
618     auto sheetPattern = host->GetPattern<SheetPresentationPattern>();
619     CHECK_NULL_RETURN(sheetPattern, sheetWidth);
620     switch (sheetType_) {
621         case SheetType::SHEET_BOTTOM:
622             if (sheetPattern->IsPhoneInLandScape()) {
623                 sheetWidth = std::min(static_cast<float>(SHEET_LANDSCAPE_WIDTH.ConvertToPx()), parentConstraintWidth);
624                 break;
625             }
626             [[fallthrough]];
627         case SheetType::SHEET_BOTTOM_FREE_WINDOW:
628             sheetWidth = parentConstraintWidth;
629             break;
630         case SheetType::SHEET_BOTTOMLANDSPACE:
631             [[fallthrough]];
632         case SheetType::SHEET_CENTER:
633             sheetWidth = GetCenterDefaultWidth(host);
634             break;
635         case SheetType::SHEET_POPUP:
636             sheetWidth = SHEET_POPUP_WIDTH.ConvertToPx();
637             break;
638         default:
639             break;
640     }
641 
642     if (!sheetStyle_.width.has_value()) {
643         return sheetWidth;
644     }
645     auto width = 0.0f;
646     if (sheetStyle_.width->Unit() == DimensionUnit::PERCENT) {
647         width = sheetStyle_.width->ConvertToPxWithSize(parentConstraintWidth);
648     } else {
649         width = sheetStyle_.width->ConvertToPx();
650     }
651     if (LessNotEqual(width, 0.0f) || width > parentConstraintWidth) {
652         width = sheetWidth;
653     }
654     return width;
655 }
656 
GetCenterDefaultWidth(const RefPtr<FrameNode> & host) const657 float SheetPresentationLayoutAlgorithm::GetCenterDefaultWidth(const RefPtr<FrameNode>& host) const
658 {
659     auto sheetWidth = SHEET_LANDSCAPE_WIDTH.ConvertToPx();
660     CHECK_NULL_RETURN(host, sheetWidth);
661     auto pipeline = host->GetContext();
662     CHECK_NULL_RETURN(pipeline, sheetWidth);
663     auto sheetTheme = pipeline->GetTheme<SheetTheme>();
664     CHECK_NULL_RETURN(sheetTheme, sheetWidth);
665     sheetWidth = sheetTheme->GetCenterDefaultWidth().ConvertToPx();
666     return sheetWidth;
667 }
668 
ComputeMaxHeight(const float parentConstraintHeight,const float parentConstraintWidth,LayoutWrapper * layoutWrapper) const669 float SheetPresentationLayoutAlgorithm::ComputeMaxHeight(const float parentConstraintHeight,
670     const float parentConstraintWidth, LayoutWrapper* layoutWrapper) const
671 {
672     float sheetMaxHeight = parentConstraintHeight;
673     if (SheetInSplitWindow()) {
674         sheetMaxHeight = parentConstraintHeight - SHEET_SPLIT_STATUS_BAR.ConvertToPx() -
675             SHEET_SPLIT_AI_BAR.ConvertToPx();
676     }
677     NG::RectF floatButtons;
678     auto host = layoutWrapper->GetHostNode();
679     CHECK_NULL_RETURN(host, 0.0f);
680     auto sheetPattern = host->GetPattern<SheetPresentationPattern>();
681     CHECK_NULL_RETURN(sheetPattern, 0.0f);
682     auto maxHeight = (std::min(sheetMaxHeight, parentConstraintWidth)) * POPUP_LARGE_SIZE;
683     if (sheetPattern->GetWindowButtonRect(floatButtons)) {
684         maxHeight = sheetMaxHeight - DOUBLE_SIZE *
685             (floatButtons.Height() + SHEET_BLANK_MINI_HEIGHT.ConvertToPx());
686     } else if (sheetStyle_.showInSubWindow.value_or(false)) {
687         auto sheetWrapper = AceType::DynamicCast<FrameNode>(host->GetParent());
688         CHECK_NULL_RETURN(sheetWrapper, 0.0f);
689         auto sheetWrapperPattern = sheetWrapper->GetPattern<SheetWrapperPattern>();
690         CHECK_NULL_RETURN(sheetWrapperPattern, 0.0f);
691         RectF containerModal;
692         RectF buttonsRect;
693         auto subwindowId = sheetWrapperPattern->GetSubWindowId();
694         auto currentId = SubwindowManager::GetInstance()->GetParentContainerId(subwindowId);
695         ContainerScope scope(currentId);
696         auto mainWindowContext = PipelineContext::GetContextByContainerId(currentId);
697         if (mainWindowContext && mainWindowContext->GetContainerModalButtonsRect(containerModal, buttonsRect)) {
698             maxHeight = (std::min(parentConstraintHeight - buttonsRect.Height(),
699                 parentConstraintWidth)) * POPUP_LARGE_SIZE;
700         }
701     }
702     return maxHeight;
703 }
704 
GetHeightBySheetStyle(const float parentConstraintHeight,const float parentConstraintWidth,LayoutWrapper * layoutWrapper) const705 float SheetPresentationLayoutAlgorithm::GetHeightBySheetStyle(const float parentConstraintHeight,
706     const float parentConstraintWidth, LayoutWrapper* layoutWrapper) const
707 {
708     float height = 0.0f;
709     bool isMediumOrLargeMode = false;
710     if (sheetStyle_.sheetHeight.sheetMode == SheetMode::MEDIUM ||
711         sheetStyle_.sheetHeight.sheetMode == SheetMode::LARGE) {
712         isMediumOrLargeMode =  true;
713     }
714     if (sheetStyle_.sheetHeight.height.has_value() || isMediumOrLargeMode) {
715         auto maxHeight = ComputeMaxHeight(parentConstraintHeight, parentConstraintWidth, layoutWrapper);
716         if (sheetStyle_.sheetHeight.height->Unit() == DimensionUnit::PERCENT) {
717             height = sheetStyle_.sheetHeight.height->ConvertToPxWithSize(maxHeight);
718         } else if (isMediumOrLargeMode) {
719             height = SHEET_BIG_WINDOW_HEIGHT.ConvertToPx();
720         } else {
721             height = sheetStyle_.sheetHeight.height->ConvertToPx();
722         }
723         auto host = layoutWrapper->GetHostNode();
724         CHECK_NULL_RETURN(host, height);
725         auto pipeline = host->GetContext();
726         CHECK_NULL_RETURN(pipeline, height);
727         auto sheetTheme = pipeline->GetTheme<SheetTheme>();
728         CHECK_NULL_RETURN(sheetTheme, height);
729         auto bigWindowMinHeight = sheetTheme->GetBigWindowMinHeight();
730         maxHeight = SheetInSplitWindow()
731             ? maxHeight : std::max(maxHeight, static_cast<float>(bigWindowMinHeight.ConvertToPx()));
732         // The minimum value of maxHeight is 320
733         if (LessNotEqual(height, 0.0f)) {
734             height = SHEET_BIG_WINDOW_HEIGHT.ConvertToPx();
735         } else if (LessOrEqual(height, bigWindowMinHeight.ConvertToPx()) && !SheetInSplitWindow()) {
736             height = bigWindowMinHeight.ConvertToPx();
737         } else if (GreatOrEqual(height, maxHeight)) {
738             height = maxHeight;
739         }
740     } else {
741         height = SHEET_BIG_WINDOW_HEIGHT.ConvertToPx();
742     }
743     return height;
744 }
745 
CreateSheetChildConstraint(RefPtr<SheetPresentationProperty> layoutprop,LayoutWrapper * layoutWrapper)746 LayoutConstraintF SheetPresentationLayoutAlgorithm::CreateSheetChildConstraint(
747     RefPtr<SheetPresentationProperty> layoutprop, LayoutWrapper* layoutWrapper)
748 {
749     auto childConstraint = layoutprop->CreateChildConstraint();
750     auto host = layoutWrapper->GetHostNode();
751     CHECK_NULL_RETURN(host, childConstraint);
752     auto pipeline = host->GetContext();
753     CHECK_NULL_RETURN(pipeline, childConstraint);
754     auto sheetTheme = pipeline->GetTheme<SheetTheme>();
755     CHECK_NULL_RETURN(sheetTheme, childConstraint);
756 
757     childConstraint.maxSize.SetWidth(sheetWidth_);
758     auto maxHeight = sheetHeight_;
759     if ((sheetStyle_.isTitleBuilder.has_value()) &&
760         ((sheetType_ == SheetType::SHEET_CENTER) || (sheetType_ == SheetType::SHEET_POPUP))) {
761         auto sheetPattern = host->GetPattern<SheetPresentationPattern>();
762         CHECK_NULL_RETURN(sheetPattern, childConstraint);
763         maxHeight -= sheetPattern->GetTitleBuilderHeight();
764     }
765     auto maxWidth = sheetWidth_;
766     if (sheetType_ == SheetType::SHEET_POPUP) {
767         UpdateMaxSizeWithPlacement(maxWidth, maxHeight, layoutWrapper);
768     }
769     if (sheetPopupInfo_.finalPlacement != Placement::NONE) {
770         childConstraint.maxSize.SetWidth(maxWidth);
771     }
772     childConstraint.maxSize.SetHeight(maxHeight);
773     childConstraint.parentIdealSize = OptionalSizeF(sheetWidth_, sheetHeight_);
774     childConstraint.percentReference = SizeF(sheetWidth_, sheetHeight_);
775     return childConstraint;
776 }
777 
UpdateMaxSizeWithPlacement(float & maxWidth,float & maxHeight,LayoutWrapper * layoutWrapper)778 void SheetPresentationLayoutAlgorithm::UpdateMaxSizeWithPlacement(float& maxWidth, float& maxHeight,
779     LayoutWrapper* layoutWrapper)
780 {
781     auto host = layoutWrapper->GetHostNode();
782     CHECK_NULL_VOID(host);
783     if (host->LessThanAPITargetVersion(PlatformVersion::VERSION_EIGHTEEN)) {
784         maxHeight -= SHEET_ARROW_HEIGHT.ConvertToPx();
785         return;
786     }
787 
788     if ((sheetPopupInfo_.placementRechecked && sheetPopupInfo_.placementOnTarget) ||
789         !sheetPopupInfo_.showArrow) {
790         return;
791     }
792 
793     switch (sheetPopupInfo_.finalPlacement) {
794         case Placement::BOTTOM_LEFT:
795             [[fallthrough]];
796         case Placement::BOTTOM_RIGHT:
797             [[fallthrough]];
798         case Placement::BOTTOM:
799             [[fallthrough]];
800         case Placement::TOP_LEFT:
801             [[fallthrough]];
802         case Placement::TOP_RIGHT:
803             [[fallthrough]];
804         case Placement::TOP: {
805             maxHeight -= SHEET_ARROW_HEIGHT.ConvertToPx();
806             break;
807         }
808         case Placement::RIGHT_TOP:
809             [[fallthrough]];
810         case Placement::RIGHT_BOTTOM:
811             [[fallthrough]];
812         case Placement::RIGHT:
813             [[fallthrough]];
814         case Placement::LEFT_TOP:
815             [[fallthrough]];
816         case Placement::LEFT_BOTTOM:
817             [[fallthrough]];
818         case Placement::LEFT: {
819             maxWidth -= SHEET_ARROW_HEIGHT.ConvertToPx();
820             break;
821         }
822         default:
823             break;
824     }
825 }
826 
SheetInSplitWindow() const827 bool SheetPresentationLayoutAlgorithm::SheetInSplitWindow() const
828 {
829     //whether window in up and down split mode
830     auto pipelineContext = PipelineContext::GetCurrentContext();
831     CHECK_NULL_RETURN(pipelineContext, false);
832     auto windowManager = pipelineContext->GetWindowManager();
833     CHECK_NULL_RETURN(windowManager, false);
834     auto windowGlobalRect = pipelineContext->GetDisplayWindowRectInfo();
835     int32_t deviceHeight = SystemProperties::GetDeviceHeight();
836     if (sheetType_ == SheetType::SHEET_CENTER && windowManager && windowGlobalRect.Height() < deviceHeight &&
837         (windowManager->GetWindowMode() == WindowMode::WINDOW_MODE_SPLIT_PRIMARY ||
838         windowManager->GetWindowMode() == WindowMode::WINDOW_MODE_SPLIT_SECONDARY)) {
839         return true;
840     }
841     return false;
842 }
843 
UpdatePopupInfoAndRemeasure(LayoutWrapper * layoutWrapper,const SheetPopupInfo & sheetPopupInfo,const float & sheetWidth,const float & sheetHeight)844 void SheetPresentationLayoutAlgorithm::UpdatePopupInfoAndRemeasure(LayoutWrapper* layoutWrapper,
845     const SheetPopupInfo& sheetPopupInfo, const float& sheetWidth, const float& sheetHeight)
846 {
847     if (sheetType_ != SheetType::SHEET_POPUP) {
848         return;
849     }
850     sheetPopupInfo_ = sheetPopupInfo;
851     sheetOffsetX_ = sheetPopupInfo.sheetOffsetX;
852     sheetOffsetY_ = sheetPopupInfo.sheetOffsetY;
853     auto host = layoutWrapper->GetHostNode();
854     CHECK_NULL_VOID(host);
855     if (host->LessThanAPITargetVersion(PlatformVersion::VERSION_EIGHTEEN)) {
856         return;
857     }
858     sheetWidth_ = sheetWidth;
859     sheetHeight_ = sheetHeight;
860     auto sheetPageWrapper = layoutWrapper->GetChildByIndex(0);
861     CHECK_NULL_VOID(sheetPageWrapper);
862     RemeasureForPopup(sheetPageWrapper);
863 }
864 
AddArrowHeightToSheetSize()865 void SheetPresentationLayoutAlgorithm::AddArrowHeightToSheetSize()
866 {
867     if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_EIGHTEEN) ||
868         sheetType_ != SheetType::SHEET_POPUP) {
869         return;
870     }
871 
872     if ((sheetPopupInfo_.placementRechecked && sheetPopupInfo_.placementOnTarget) ||
873         !sheetPopupInfo_.showArrow) {
874         return;
875     }
876 
877     switch (sheetPopupInfo_.finalPlacement) {
878         case Placement::BOTTOM_LEFT:
879             [[fallthrough]];
880         case Placement::BOTTOM_RIGHT:
881             [[fallthrough]];
882         case Placement::BOTTOM:
883             [[fallthrough]];
884         case Placement::TOP_LEFT:
885             [[fallthrough]];
886         case Placement::TOP_RIGHT:
887             [[fallthrough]];
888         case Placement::TOP: {
889             sheetHeight_ += SHEET_ARROW_HEIGHT.ConvertToPx();
890             break;
891         }
892         case Placement::RIGHT_TOP:
893             [[fallthrough]];
894         case Placement::RIGHT_BOTTOM:
895             [[fallthrough]];
896         case Placement::RIGHT:
897             [[fallthrough]];
898         case Placement::LEFT_TOP:
899             [[fallthrough]];
900         case Placement::LEFT_BOTTOM:
901             [[fallthrough]];
902         case Placement::LEFT: {
903             sheetWidth_ += SHEET_ARROW_HEIGHT.ConvertToPx();
904             break;
905         }
906         default:
907             break;
908     }
909 }
910 
RemeasureForPopup(const RefPtr<LayoutWrapper> & layoutWrapper)911 void SheetPresentationLayoutAlgorithm::RemeasureForPopup(const RefPtr<LayoutWrapper>& layoutWrapper)
912 {
913     CHECK_NULL_VOID(layoutWrapper);
914     if (layoutWrapper->GetGeometryNode() && layoutWrapper->GetGeometryNode()->GetParentLayoutConstraint()) {
915         auto parentConstraint = layoutWrapper->GetGeometryNode()->GetParentLayoutConstraint();
916         if (!parentConstraint.has_value()) {
917             return;
918         }
919         auto layoutConstraint = parentConstraint.value();
920         auto layoutProperty = AceType::DynamicCast<SheetPresentationProperty>(layoutWrapper->GetLayoutProperty());
921         CHECK_NULL_VOID(layoutProperty);
922         layoutProperty->UpdateLayoutConstraint(layoutConstraint);
923         AddArrowHeightToSheetSize();
924         TAG_LOGI(AceLogTag::ACE_SHEET, "remeasure size:(%{public}f, %{public}f)", sheetWidth_, sheetHeight_);
925         SizeF idealSize(sheetWidth_, sheetHeight_);
926         layoutWrapper->GetGeometryNode()->SetFrameSize(idealSize);
927         layoutWrapper->GetGeometryNode()->SetContentSize(idealSize);
928         auto childConstraint = CreateSheetChildConstraint(layoutProperty, Referenced::RawPtr(layoutWrapper));
929         layoutConstraint.percentReference = SizeF(sheetWidth_, sheetHeight_);
930         for (auto&& child : layoutWrapper->GetAllChildrenWithBuild()) {
931             child->Measure(childConstraint);
932         }
933         auto host = layoutWrapper->GetHostNode();
934         CHECK_NULL_VOID(host);
935         auto sheetPattern = host->GetPattern<SheetPresentationPattern>();
936         CHECK_NULL_VOID(sheetPattern);
937         auto scrollNode = sheetPattern->GetSheetScrollNode();
938         CHECK_NULL_VOID(scrollNode);
939         childConstraint.selfIdealSize.SetWidth(childConstraint.maxSize.Width());
940         scrollNode->Measure(childConstraint);
941     }
942 }
943 } // namespace OHOS::Ace::NG