1 /*
2 * Copyright (c) 2022-2024 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/overlay_manager.h"
17
18 #include <cstdint>
19 #include <string>
20 #include <utility>
21 #include <vector>
22 #if defined(OHOS_STANDARD_SYSTEM) and !defined(ACE_UNITTEST)
23 #include "want.h"
24 #endif
25
26 #include "base/error/error_code.h"
27 #include "base/geometry/ng/offset_t.h"
28 #include "base/geometry/ng/size_t.h"
29 #include "base/log/dump_log.h"
30 #include "base/log/log.h"
31 #include "base/memory/ace_type.h"
32 #include "base/memory/referenced.h"
33 #include "base/subwindow/subwindow_manager.h"
34 #include "base/utils/measure_util.h"
35 #include "base/utils/system_properties.h"
36 #include "base/utils/utils.h"
37 #include "base/window/foldable_window.h"
38 #include "core/animation/animation_pub.h"
39 #include "core/animation/spring_curve.h"
40 #include "core/common/ace_application_info.h"
41 #include "core/common/ace_engine.h"
42 #include "core/common/container.h"
43 #include "core/common/ime/input_method_manager.h"
44 #include "core/common/interaction/interaction_interface.h"
45 #include "core/common/modal_ui_extension.h"
46 #include "core/common/recorder/event_recorder.h"
47 #include "core/components/common/properties/color.h"
48 #include "core/components/select/select_theme.h"
49 #include "core/components/text_overlay/text_overlay_theme.h"
50 #include "core/components/toast/toast_theme.h"
51 #include "core/components_ng/animation/geometry_transition.h"
52 #include "core/components_ng/base/frame_node.h"
53 #include "core/components_ng/base/ui_node.h"
54 #include "core/components_ng/base/view_abstract.h"
55 #include "core/components_ng/base/view_stack_processor.h"
56 #include "core/components_ng/event/focus_hub.h"
57 #include "core/components_ng/manager/focus/focus_view.h"
58 #include "core/components_ng/pattern/bubble/bubble_event_hub.h"
59 #include "core/components_ng/pattern/bubble/bubble_pattern.h"
60 #include "core/components_ng/pattern/calendar_picker/calendar_dialog_view.h"
61 #include "core/components_ng/pattern/dialog/dialog_pattern.h"
62 #include "core/components_ng/pattern/dialog/dialog_view.h"
63 #include "core/components_ng/pattern/menu/menu_item/menu_item_model_ng.h"
64 #include "core/components_ng/pattern/menu/menu_item/menu_item_pattern.h"
65 #include "core/components_ng/pattern/menu/menu_item_group/menu_item_group_view.h"
66 #include "core/components_ng/pattern/menu/menu_layout_property.h"
67 #include "core/components_ng/pattern/menu/menu_pattern.h"
68 #include "core/components_ng/pattern/menu/menu_theme.h"
69 #include "core/components_ng/pattern/menu/menu_view.h"
70 #include "core/components_ng/pattern/menu/preview/menu_preview_pattern.h"
71 #include "core/components_ng/pattern/menu/wrapper/menu_wrapper_pattern.h"
72 #include "core/components_ng/pattern/navigation/navigation_group_node.h"
73 #include "core/components_ng/pattern/navigation/navigation_pattern.h"
74 #include "core/components_ng/pattern/overlay/keyboard_base_pattern.h"
75 #include "core/components_ng/pattern/overlay/keyboard_view.h"
76 #include "core/components_ng/pattern/overlay/modal_presentation_pattern.h"
77 #include "core/components_ng/pattern/overlay/overlay_container_pattern.h"
78 #include "core/components_ng/pattern/overlay/popup_base_pattern.h"
79 #include "core/components_ng/pattern/overlay/sheet_drag_bar_pattern.h"
80 #include "core/components_ng/pattern/overlay/sheet_presentation_pattern.h"
81 #include "core/components_ng/pattern/overlay/sheet_presentation_property.h"
82 #include "core/components_ng/pattern/overlay/sheet_style.h"
83 #include "core/components_ng/pattern/overlay/sheet_view.h"
84 #include "core/components_ng/pattern/overlay/sheet_wrapper_pattern.h"
85 #include "core/components_ng/pattern/picker/datepicker_dialog_view.h"
86 #include "core/components_ng/pattern/stage/stage_pattern.h"
87 #include "core/components_ng/pattern/text_field/text_field_manager.h"
88 #include "core/components_ng/pattern/text_picker/textpicker_dialog_view.h"
89 #include "core/components_ng/pattern/time_picker/timepicker_dialog_view.h"
90 #include "core/components_ng/pattern/toast/toast_pattern.h"
91 #include "core/components_ng/pattern/ui_extension/ui_extension_model.h"
92 #include "core/components_ng/pattern/video/video_full_screen_pattern.h"
93 #include "core/components_ng/property/measure_property.h"
94 #include "core/components_ng/property/property.h"
95 #include "core/components_v2/inspector/inspector_constants.h"
96 #include "core/pipeline/pipeline_base.h"
97 #include "core/pipeline/pipeline_context.h"
98 #ifdef WEB_SUPPORTED
99 #if !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM)
100 #include "core/components_ng/pattern/web/web_pattern.h"
101 #else
102 #include "core/components_ng/pattern/web/cross_platform/web_pattern.h"
103 #endif
104 #endif
105
106 namespace OHOS::Ace::NG {
107 namespace {
108 // should be moved to theme.
109 constexpr int32_t TOAST_ANIMATION_DURATION = 100;
110 constexpr int32_t MENU_ANIMATION_DURATION = 150;
111 constexpr float TOAST_ANIMATION_POSITION = 15.0f;
112
113 constexpr float PIXELMAP_DRAG_SCALE = 1.0f;
114 constexpr float NUM_FLOAT_2 = 2.0f;
115 constexpr int32_t PIXELMAP_ANIMATION_DURATION = 250;
116 constexpr float PIXELMAP_ANIMATION_DEFAULT_LIMIT_SCALE = 0.5f;
117
118 constexpr int32_t FULL_MODAL_ALPHA_ANIMATION_DURATION = 200;
119
120 constexpr int32_t SHEET_HALF_SIZE = 2;
121 // dialog animation params
122 const RefPtr<Curve> SHOW_SCALE_ANIMATION_CURVE = AceType::MakeRefPtr<CubicCurve>(0.38f, 1.33f, 0.6f, 1.0f);
123
124 constexpr int32_t ROOT_MIN_NODE = 1;
125 constexpr int32_t ATOMIC_SERVICE_MIN_SIZE = 2;
126
127 // OVERLAY_EXISTS: overlay was removed
128 // OVERLAY_REMOVE:: overlay exists
129 // OVERLAY_NOTHING:nothing
130 constexpr int32_t OVERLAY_EXISTS = 0;
131 constexpr int32_t OVERLAY_REMOVE = 1;
132 constexpr int32_t OVERLAY_NOTHING = 2;
133
134 // custom keyboard animation params
135 const RefPtr<Curve> SHOW_CUSTOM_KEYBOARD_ANIMATION_CURVE =
136 AceType::MakeRefPtr<InterpolatingSpring>(0.0f, 1.0f, 342.0f, 37.0f);
137 const RefPtr<Curve> HIDE_CUSTOM_KEYBOARD_ANIMATION_CURVE =
138 AceType::MakeRefPtr<InterpolatingSpring>(4.0f, 1.0f, 342.0f, 37.0f);
139
140 const RefPtr<InterpolatingSpring> MENU_ANIMATION_CURVE =
141 AceType::MakeRefPtr<InterpolatingSpring>(0.0f, 1.0f, 528.0f, 35.0f);
142
143 const RefPtr<Curve> CUSTOM_PREVIEW_ANIMATION_CURVE =
144 AceType::MakeRefPtr<InterpolatingSpring>(0.0f, 1.0f, 280.0f, 30.0f);
145 const std::string HOVER_IMAGE_CLIP_DISAPPEAR_PROPERTY_NAME = "hoverImageClipDisAppear";
146 constexpr double MENU_ORIGINAL_SCALE = 0.6f;
147 constexpr int32_t DUMP_LOG_DEPTH_1 = 1;
148 constexpr int32_t DUMP_LOG_DEPTH_2 = 2;
149
150 constexpr int32_t EVENT_COLUMN_SLOT = -2;
151
152 const float MINIMUM_AMPLITUDE_RATION = 0.08f;
153
154 // UIExtensionComponent Transform param key
155 #if defined(OHOS_STANDARD_SYSTEM) and !defined(ACE_UNITTEST)
156 constexpr char WANT_PARAM_UIEXTNODE_ANGLE_KEY[] = "modalUIExtNodeAngle";
157 constexpr char WANT_PARAM_UIEXTNODE_WIDTH_KEY[] = "modalUIExtNodeWidth";
158 constexpr char WANT_PARAM_UIEXTNODE_HEIGHT_KEY[] = "modalUIExtNodeHeight";
159 #endif
160 constexpr int32_t UIEXTNODE_ANGLE_90 = 90;
161 constexpr int32_t UIEXTNODE_ANGLE_180 = 180;
162 constexpr int32_t UIEXTNODE_ANGLE_270 = 270;
163
164 constexpr double DISTANCE_THRESHOLD = 20.0;
165
GetLastPage()166 RefPtr<FrameNode> GetLastPage()
167 {
168 auto pipelineContext = PipelineContext::GetCurrentContext();
169 CHECK_NULL_RETURN(pipelineContext, nullptr);
170 auto stageManager = pipelineContext->GetStageManager();
171 CHECK_NULL_RETURN(stageManager, nullptr);
172 auto pageNode = stageManager->GetLastPage();
173 return pageNode;
174 }
175
ShowPreviewBgDisappearAnimationProc(const RefPtr<RenderContext> & previewRenderContext,const RefPtr<MenuTheme> & menuTheme,bool isShowHoverImage)176 void ShowPreviewBgDisappearAnimationProc(const RefPtr<RenderContext>& previewRenderContext,
177 const RefPtr<MenuTheme>& menuTheme, bool isShowHoverImage)
178 {
179 auto shadow = previewRenderContext->GetBackShadow();
180 if (!shadow.has_value()) {
181 shadow = Shadow::CreateShadow(ShadowStyle::None);
182 }
183 previewRenderContext->UpdateBackShadow(shadow.value());
184 auto disappearDuration = menuTheme->GetDisappearDuration();
185 AnimationOption previewOption;
186 if (isShowHoverImage) {
187 previewOption.SetCurve(CUSTOM_PREVIEW_ANIMATION_CURVE);
188 } else {
189 previewOption.SetCurve(Curves::SHARP);
190 previewOption.SetDuration(disappearDuration);
191 }
192 AnimationUtils::Animate(previewOption, [previewRenderContext, shadow]() mutable {
193 CHECK_NULL_VOID(previewRenderContext);
194 auto color = shadow->GetColor();
195 auto newColor = Color::FromARGB(1, color.GetRed(), color.GetGreen(), color.GetBlue());
196 shadow->SetColor(newColor);
197 previewRenderContext->UpdateBackShadow(shadow.value());
198 BorderRadiusProperty borderRadius;
199 borderRadius.SetRadius(0.0_vp);
200 previewRenderContext->UpdateBorderRadius(borderRadius);
201 });
202 }
203
UpdateHoverImagePreviewOpacityAnimation(const RefPtr<MenuTheme> & menuTheme,const RefPtr<MenuPattern> & menuPattern,RefPtr<FrameNode> & previewChild)204 void UpdateHoverImagePreviewOpacityAnimation(const RefPtr<MenuTheme>& menuTheme,
205 const RefPtr<MenuPattern>& menuPattern, RefPtr<FrameNode>& previewChild)
206 {
207 CHECK_NULL_VOID(menuPattern);
208 CHECK_NULL_VOID(menuPattern->GetIsShowHoverImage());
209
210 CHECK_NULL_VOID(previewChild);
211 auto previewRenderContext = previewChild->GetRenderContext();
212 CHECK_NULL_VOID(previewRenderContext);
213
214 bool isCustomPreview = previewChild->GetTag() == V2::MENU_PREVIEW_ETS_TAG;
215 // only update custom preview opacity
216 CHECK_NULL_VOID(isCustomPreview);
217
218 AnimationOption option;
219 option.SetDuration(menuTheme->GetHoverImagePreviewDisAppearDuration());
220 option.SetCurve(Curves::FRICTION);
221 AnimationUtils::Animate(
222 option, [previewRenderContext]() {
223 CHECK_NULL_VOID(previewRenderContext);
224 previewRenderContext->UpdateOpacity(0.0);
225 });
226 }
227
ShowPreviewDisappearAnimationProc(const RefPtr<MenuWrapperPattern> & menuWrapperPattern,RefPtr<FrameNode> & previewChild)228 void ShowPreviewDisappearAnimationProc(const RefPtr<MenuWrapperPattern>& menuWrapperPattern,
229 RefPtr<FrameNode>& previewChild)
230 {
231 CHECK_NULL_VOID(menuWrapperPattern);
232 CHECK_NULL_VOID(previewChild);
233 auto previewRenderContext = previewChild->GetRenderContext();
234 CHECK_NULL_VOID(previewRenderContext);
235 if (menuWrapperPattern->HasPreviewTransitionEffect()) {
236 auto layoutProperty = previewChild->GetLayoutProperty();
237 CHECK_NULL_VOID(layoutProperty);
238 layoutProperty->UpdateVisibility(VisibleType::INVISIBLE, true);
239 return;
240 }
241
242 auto menuChild = menuWrapperPattern->GetMenu();
243 CHECK_NULL_VOID(menuChild);
244 auto menuPattern = menuChild->GetPattern<MenuPattern>();
245 CHECK_NULL_VOID(menuPattern);
246 auto previewPosition = menuPattern->GetPreviewOriginOffset();
247
248 auto pipelineContext = menuChild->GetContext();
249 CHECK_NULL_VOID(pipelineContext);
250 auto menuTheme = pipelineContext->GetTheme<MenuTheme>();
251 CHECK_NULL_VOID(menuTheme);
252 UpdateHoverImagePreviewOpacityAnimation(menuTheme, menuPattern, previewChild);
253
254 auto springMotionResponse = menuTheme->GetPreviewDisappearSpringMotionResponse();
255 auto springMotionDampingFraction = menuTheme->GetPreviewDisappearSpringMotionDampingFraction();
256 AnimationOption scaleOption;
257 auto motion = AceType::MakeRefPtr<ResponsiveSpringMotion>(springMotionResponse, springMotionDampingFraction);
258 scaleOption.SetCurve(motion);
259 float previewScale = 1.0f;
260 if (menuPattern->GetPreviewMode() == MenuPreviewMode::IMAGE) {
261 auto previewGeometryNode = previewChild->GetGeometryNode();
262 CHECK_NULL_VOID(previewGeometryNode);
263 auto preivewSize = previewGeometryNode->GetFrameSize();
264 if (!NearEqual(menuPattern->GetTargetSize().Width(), preivewSize.Width())) {
265 previewScale = menuPattern->GetTargetSize().Width() / preivewSize.Width();
266 }
267 }
268 ShowPreviewBgDisappearAnimationProc(previewRenderContext, menuTheme, menuWrapperPattern->GetIsShowHoverImage());
269
270 CHECK_NULL_VOID(!menuPattern->GetIsShowHoverImage());
271 AnimationUtils::Animate(scaleOption,
272 [previewRenderContext, previewPosition, previewScale]() {
273 CHECK_NULL_VOID(previewRenderContext);
274 previewRenderContext->UpdatePosition(
275 OffsetT<Dimension>(Dimension(previewPosition.GetX()), Dimension(previewPosition.GetY())));
276 previewRenderContext->UpdateTransformScale(VectorF(previewScale, previewScale));
277 });
278 }
279
UpdatePreviewVisibleAreaByFrameWhenDisappear(const RefPtr<RenderContext> & clipContext,const RefPtr<MenuPreviewPattern> & previewPattern,float value,float radius,float distVal)280 void UpdatePreviewVisibleAreaByFrameWhenDisappear(const RefPtr<RenderContext>& clipContext,
281 const RefPtr<MenuPreviewPattern>& previewPattern, float value, float radius, float distVal)
282 {
283 CHECK_NULL_VOID(previewPattern);
284 CHECK_NULL_VOID(!NearZero(distVal));
285 auto rate = (value - previewPattern->GetClipEndValue()) / distVal;
286
287 auto clipStartWidth = previewPattern->GetStackAfterScaleActualWidth();
288 auto clipStartHeight = previewPattern->GetStackAfterScaleActualHeight();
289 auto clipEndWidth = previewPattern->GetHoverImageAfterScaleWidth();
290 auto clipEndHeight = previewPattern->GetHoverImageAfterScaleHeight();
291
292 auto curentClipAreaWidth = rate * (clipEndWidth - clipStartWidth) + clipStartWidth;
293 auto curentClipAreaHeight = rate * (clipEndHeight - clipStartHeight) + clipStartHeight;
294
295 auto clipOffset = previewPattern->GetHoverImageAfterScaleOffset();
296 RoundRect roundRectInstance;
297 roundRectInstance.SetRect(RectF(OffsetF(rate * clipOffset.GetX(), rate * clipOffset.GetY()),
298 SizeF(curentClipAreaWidth, curentClipAreaHeight)));
299 roundRectInstance.SetCornerRadius((1 - rate) * radius);
300 CHECK_NULL_VOID(clipContext);
301 clipContext->ClipWithRoundRect(roundRectInstance);
302 }
303
UpdatePreivewVisibleAreaWhenDisappear(const RefPtr<FrameNode> & hoverImageStackNode,const RefPtr<FrameNode> & previewNode)304 void UpdatePreivewVisibleAreaWhenDisappear(const RefPtr<FrameNode>& hoverImageStackNode,
305 const RefPtr<FrameNode>& previewNode)
306 {
307 CHECK_NULL_VOID(hoverImageStackNode && previewNode);
308 auto previewPattern = previewNode->GetPattern<MenuPreviewPattern>();
309 CHECK_NULL_VOID(previewPattern);
310
311 // reverse
312 auto clipStartValue = previewPattern->GetClipEndValue();
313 auto clipEndValue = previewPattern->GetClipStartValue();
314 clipEndValue += NearEqual(clipStartValue, clipEndValue) ? 1.0f : 0;
315 auto dist = clipEndValue - clipStartValue;
316
317 auto pipelineContext = previewNode->GetContext();
318 CHECK_NULL_VOID(pipelineContext);
319 auto menuTheme = pipelineContext->GetTheme<MenuTheme>();
320 CHECK_NULL_VOID(menuTheme);
321 hoverImageStackNode->CreateAnimatablePropertyFloat(HOVER_IMAGE_CLIP_DISAPPEAR_PROPERTY_NAME, 0,
322 [weak = AceType::WeakClaim(AceType::RawPtr(hoverImageStackNode)),
323 previewWeak = AceType::WeakClaim(AceType::RawPtr(previewNode)),
324 radius = menuTheme->GetPreviewBorderRadius().ConvertToPx(), distVal = dist](float value) {
325 auto clipNode = weak.Upgrade();
326 CHECK_NULL_VOID(clipNode);
327 auto clipContext = clipNode->GetRenderContext();
328 CHECK_NULL_VOID(clipContext);
329
330 auto preview = previewWeak.Upgrade();
331 CHECK_NULL_VOID(preview);
332 auto previewPattern = preview->GetPattern<MenuPreviewPattern>();
333 CHECK_NULL_VOID(previewPattern);
334 UpdatePreviewVisibleAreaByFrameWhenDisappear(clipContext, previewPattern, value, radius, distVal);
335 });
336 AnimationOption option;
337 option.SetCurve(CUSTOM_PREVIEW_ANIMATION_CURVE);
338 hoverImageStackNode->UpdateAnimatablePropertyFloat(HOVER_IMAGE_CLIP_DISAPPEAR_PROPERTY_NAME, clipStartValue);
339 auto clipAnimation_ = AnimationUtils::StartAnimation(option, [hoverImageStackNode, clipEndValue]() {
340 CHECK_NULL_VOID(hoverImageStackNode);
341 hoverImageStackNode->UpdateAnimatablePropertyFloat(HOVER_IMAGE_CLIP_DISAPPEAR_PROPERTY_NAME, clipEndValue);
342 });
343 }
344
UpdateHoverImageDisappearScaleAndPosition(const RefPtr<MenuWrapperPattern> & menuWrapperPattern,const RefPtr<MenuPreviewPattern> & previewPattern)345 void UpdateHoverImageDisappearScaleAndPosition(const RefPtr<MenuWrapperPattern>& menuWrapperPattern,
346 const RefPtr<MenuPreviewPattern>& previewPattern)
347 {
348 CHECK_NULL_VOID(menuWrapperPattern);
349 CHECK_NULL_VOID(menuWrapperPattern->GetIsShowHoverImage());
350
351 CHECK_NULL_VOID(previewPattern);
352 // reverse scale
353 auto scaleTo = previewPattern->GetHoverImageScaleFrom();
354 auto pipelineContext = PipelineContext::GetCurrentContext();
355 CHECK_NULL_VOID(pipelineContext);
356 auto menuTheme = pipelineContext->GetTheme<MenuTheme>();
357 CHECK_NULL_VOID(menuTheme);
358 auto scaleAfter = LessNotEqual(scaleTo, 0.0) ? menuTheme->GetPreviewBeforeAnimationScale() : scaleTo;
359
360 auto stackNode = menuWrapperPattern->GetHoverImageStackNode();
361 CHECK_NULL_VOID(stackNode);
362 auto stackContext = stackNode->GetRenderContext();
363 CHECK_NULL_VOID(stackContext);
364
365 auto flexNode = menuWrapperPattern->GetHoverImageFlexNode();
366 CHECK_NULL_VOID(flexNode);
367 auto flexContext = flexNode->GetRenderContext();
368 CHECK_NULL_VOID(flexContext);
369
370 auto menuChild = menuWrapperPattern->GetMenu();
371 CHECK_NULL_VOID(menuChild);
372 auto menuPattern = menuChild->GetPattern<MenuPattern>();
373 CHECK_NULL_VOID(menuPattern);
374 auto previewPosition = menuPattern->GetPreviewOriginOffset();
375
376 menuWrapperPattern->StopHoverImageToPreviewAnimation();
377 AnimationOption option = AnimationOption();
378 option.SetCurve(CUSTOM_PREVIEW_ANIMATION_CURVE);
379 AnimationUtils::Animate(
380 option, [stackContext, scaleAfter, flexContext, previewPosition]() {
381 CHECK_NULL_VOID(stackContext);
382 stackContext->UpdateTransformScale(VectorF(scaleAfter, scaleAfter));
383
384 CHECK_NULL_VOID(flexContext);
385 flexContext->UpdatePosition(
386 OffsetT<Dimension>(Dimension(previewPosition.GetX()), Dimension(previewPosition.GetY())));
387 });
388
389 ShowPreviewBgDisappearAnimationProc(stackContext, menuTheme, menuWrapperPattern->GetHoverImageStackNode());
390 }
391
ShowPreviewDisappearAnimation(const RefPtr<MenuWrapperPattern> & menuWrapperPattern)392 void ShowPreviewDisappearAnimation(const RefPtr<MenuWrapperPattern>& menuWrapperPattern)
393 {
394 CHECK_NULL_VOID(menuWrapperPattern);
395 auto previewChild = menuWrapperPattern->GetPreview();
396 CHECK_NULL_VOID(previewChild);
397 ShowPreviewDisappearAnimationProc(menuWrapperPattern, previewChild);
398
399 CHECK_NULL_VOID(menuWrapperPattern->GetIsShowHoverImage());
400 auto hoverImagePreview = menuWrapperPattern->GetHoverImagePreview();
401 CHECK_NULL_VOID(hoverImagePreview);
402 ShowPreviewDisappearAnimationProc(menuWrapperPattern, hoverImagePreview);
403
404 auto previewPattern = previewChild->GetPattern<MenuPreviewPattern>();
405 CHECK_NULL_VOID(previewPattern);
406 if (previewPattern->IsHoverImageAnimationPlaying()) {
407 menuWrapperPattern->SetIsStopHoverImageAnimation(true);
408 previewPattern->SetIsHoverImageAnimationPlaying(false);
409 } else {
410 UpdatePreivewVisibleAreaWhenDisappear(menuWrapperPattern->GetHoverImageStackNode(), previewChild);
411 }
412 UpdateHoverImageDisappearScaleAndPosition(menuWrapperPattern, previewPattern);
413 }
414
UpdateContextMenuDisappearPositionAnimation(const RefPtr<FrameNode> & menu,const NG::OffsetF & offset,float menuScale)415 void UpdateContextMenuDisappearPositionAnimation(const RefPtr<FrameNode>& menu, const NG::OffsetF& offset,
416 float menuScale)
417 {
418 CHECK_NULL_VOID(menu);
419 auto menuWrapperPattern = menu->GetPattern<MenuWrapperPattern>();
420 CHECK_NULL_VOID(menuWrapperPattern);
421 auto menuChild = menuWrapperPattern->GetMenu();
422 CHECK_NULL_VOID(menuChild);
423 auto menuRenderContext = menuChild->GetRenderContext();
424 CHECK_NULL_VOID(menuRenderContext);
425 auto menuPattern = menuChild->GetPattern<MenuPattern>();
426 CHECK_NULL_VOID(menuPattern);
427 auto menuPosition = menuChild->GetGeometryNode()->GetFrameOffset();
428 menuPosition += offset;
429 menuChild->GetGeometryNode()->SetFrameOffset(menuPosition);
430 menuPattern->SetEndOffset(menuPosition);
431
432 auto pipelineContext = PipelineContext::GetCurrentContext();
433 CHECK_NULL_VOID(pipelineContext);
434 auto menuTheme = pipelineContext->GetTheme<MenuTheme>();
435 CHECK_NULL_VOID(menuTheme);
436
437 auto scaleAfter = LessNotEqual(menuScale, 0.0) ? 1.0f : menuScale;
438 auto springMotionResponse = menuTheme->GetPreviewDisappearSpringMotionResponse();
439 auto springMotionDampingFraction = menuTheme->GetPreviewDisappearSpringMotionDampingFraction();
440 AnimationOption positionOption;
441 auto motion = AceType::MakeRefPtr<ResponsiveSpringMotion>(springMotionResponse, springMotionDampingFraction);
442 positionOption.SetCurve(motion);
443 AnimationUtils::Animate(positionOption, [menuRenderContext, menuPosition, scaleAfter]() {
444 CHECK_NULL_VOID(menuRenderContext);
445 menuRenderContext->UpdatePosition(
446 OffsetT<Dimension>(Dimension(menuPosition.GetX()), Dimension(menuPosition.GetY())));
447 // menuScale default value is 1.0f, only update menu scale with not the default value
448 if (scaleAfter != 1.0f) {
449 menuRenderContext->UpdateTransformScale(VectorF(scaleAfter, scaleAfter));
450 }
451 });
452 }
453
ContextMenuSwitchDragPreviewScaleAnimationProc(const RefPtr<RenderContext> & dragPreviewContext,const RefPtr<RenderContext> & previewRenderContext,const RefPtr<FrameNode> & previewChild,const NG::OffsetF & offset,int32_t duration)454 void ContextMenuSwitchDragPreviewScaleAnimationProc(const RefPtr<RenderContext>& dragPreviewContext,
455 const RefPtr<RenderContext>& previewRenderContext, const RefPtr<FrameNode>& previewChild,
456 const NG::OffsetF& offset, int32_t duration)
457 {
458 CHECK_NULL_VOID(previewChild);
459 auto previewPattern = previewChild->GetPattern<MenuPreviewPattern>();
460 CHECK_NULL_VOID(previewPattern);
461 CHECK_NULL_VOID(previewPattern->GetIsShowHoverImage());
462
463 CHECK_NULL_VOID(dragPreviewContext);
464 auto width = dragPreviewContext->GetPaintRectWithTransform().Width();
465 auto height = dragPreviewContext->GetPaintRectWithTransform().Height();
466
467 CHECK_NULL_VOID(previewRenderContext);
468 auto previewWidth = previewPattern->GetCustomPreviewWidth();
469 auto previewHeight = previewPattern->GetCustomPreviewHeight();
470
471 // reverse scale
472 float scaleTo = 1.0f;
473 if (previewWidth - width < previewHeight - height) {
474 CHECK_EQUAL_VOID(previewWidth, 0);
475 scaleTo = width / previewWidth;
476 } else {
477 CHECK_EQUAL_VOID(previewHeight, 0);
478 scaleTo = height / previewHeight;
479 }
480 auto scaleAfter = LessNotEqual(scaleTo, 0.0) ? 1.0f : scaleTo;
481 AnimationOption option = AnimationOption();
482 option.SetDuration(duration);
483 option.SetCurve(Curves::FRICTION);
484 AnimationUtils::Animate(
485 option,
486 [previewRenderContext, dragPreviewContext, scaleAfter, offset]() {
487 CHECK_NULL_VOID(previewRenderContext);
488 previewRenderContext->UpdateTransformScale(VectorF(scaleAfter, scaleAfter));
489 previewRenderContext->UpdateTransformTranslate({ offset.GetX(), offset.GetY(), 0.0f });
490
491 CHECK_NULL_VOID(dragPreviewContext);
492 dragPreviewContext->UpdateTransformTranslate({ offset.GetX(), offset.GetY(), 0.0f });
493 });
494 }
495
UpdateContextMenuSwitchDragPreviewBefore(const RefPtr<FrameNode> & menu)496 void UpdateContextMenuSwitchDragPreviewBefore(const RefPtr<FrameNode>& menu)
497 {
498 CHECK_NULL_VOID(menu);
499 auto menuWrapperPattern = menu->GetPattern<MenuWrapperPattern>();
500 CHECK_NULL_VOID(menuWrapperPattern && menuWrapperPattern->GetIsShowHoverImage());
501 auto previewChild = menuWrapperPattern->GetPreview();
502 CHECK_NULL_VOID(previewChild);
503 auto previewPattern = previewChild->GetPattern<MenuPreviewPattern>();
504 CHECK_NULL_VOID(previewPattern);
505
506 if (previewPattern->IsHoverImageScalePlaying()) {
507 auto previewRenderContext = previewChild->GetRenderContext();
508 CHECK_NULL_VOID(previewRenderContext);
509 previewRenderContext->UpdateOpacity(0.0);
510 }
511 }
512
ContextMenuSwitchDragPreviewAnimationProc(const RefPtr<FrameNode> & menu,const RefPtr<NG::FrameNode> & dragPreviewNode,const NG::OffsetF & offset)513 void ContextMenuSwitchDragPreviewAnimationProc(const RefPtr<FrameNode>& menu,
514 const RefPtr<NG::FrameNode>& dragPreviewNode, const NG::OffsetF& offset)
515 {
516 CHECK_NULL_VOID(dragPreviewNode && menu);
517 auto menuWrapperPattern = menu->GetPattern<MenuWrapperPattern>();
518 CHECK_NULL_VOID(menuWrapperPattern && menuWrapperPattern->GetIsShowHoverImage());
519
520 auto pipelineContext = PipelineContext::GetCurrentContext();
521 CHECK_NULL_VOID(pipelineContext);
522 auto menuTheme = pipelineContext->GetTheme<MenuTheme>();
523 CHECK_NULL_VOID(menuTheme);
524 // consistent with the menu disappear duration
525 auto duration = menuTheme->GetDisappearDuration();
526
527 auto previewChild = menuWrapperPattern->GetPreview();
528 CHECK_NULL_VOID(previewChild);
529 auto previewRenderContext = previewChild->GetRenderContext();
530 CHECK_NULL_VOID(previewRenderContext);
531 auto dragPreviewContext = dragPreviewNode->GetRenderContext();
532 CHECK_NULL_VOID(dragPreviewContext);
533
534 // update custom preview scale and position
535 ContextMenuSwitchDragPreviewScaleAnimationProc(dragPreviewContext, previewRenderContext, previewChild, offset,
536 duration);
537
538 // custom preview and drag preview update Opacity
539 CHECK_NULL_VOID(!menuWrapperPattern->GetIsShowHoverImagePreviewStartDrag());
540 menuWrapperPattern->SetIsShowHoverImagePreviewStartDrag(true);
541 auto imageNode = menuWrapperPattern->GetHoverImagePreview();
542 CHECK_NULL_VOID(imageNode);
543 auto imageContext = imageNode->GetRenderContext();
544 CHECK_NULL_VOID(imageContext);
545 imageContext->UpdateOpacity(0.0);
546
547 previewRenderContext->UpdateOpacity(1.0);
548 dragPreviewContext->UpdateOpacity(0.0);
549 AnimationOption option;
550 option.SetDuration(duration);
551 option.SetCurve(Curves::FRICTION);
552 option.SetOnFinishEvent(
553 [id = Container::CurrentId(), menuWrapperPattern] {
554 ContainerScope scope(id);
555 menuWrapperPattern->SetIsShowHoverImagePreviewStartDrag(false);
556 });
557 AnimationUtils::Animate(
558 option, [previewRenderContext, dragPreviewContext]() mutable {
559 CHECK_NULL_VOID(previewRenderContext);
560 previewRenderContext->UpdateOpacity(0.0);
561
562 BorderRadiusProperty borderRadius;
563 borderRadius.SetRadius(0.0_vp);
564 previewRenderContext->UpdateBorderRadius(borderRadius);
565
566 CHECK_NULL_VOID(dragPreviewContext);
567 dragPreviewContext->UpdateOpacity(1.0);
568 },
569 option.GetOnFinishEvent());
570 }
571
ShowContextMenuDisappearAnimation(AnimationOption & option,const RefPtr<MenuWrapperPattern> & menuWrapperPattern,bool startDrag=false)572 void ShowContextMenuDisappearAnimation(
573 AnimationOption& option, const RefPtr<MenuWrapperPattern>& menuWrapperPattern, bool startDrag = false)
574 {
575 CHECK_NULL_VOID(menuWrapperPattern);
576 auto menuChild = menuWrapperPattern->GetMenu();
577 CHECK_NULL_VOID(menuChild);
578 auto menuRenderContext = menuChild->GetRenderContext();
579 CHECK_NULL_VOID(menuRenderContext);
580 auto menuPattern = menuChild->GetPattern<MenuPattern>();
581 CHECK_NULL_VOID(menuPattern);
582 auto menuPosition = menuPattern->GetEndOffset();
583 menuWrapperPattern->ClearAllSubMenu();
584
585 auto pipelineContext = PipelineContext::GetCurrentContext();
586 CHECK_NULL_VOID(pipelineContext);
587 auto menuTheme = pipelineContext->GetTheme<MenuTheme>();
588 CHECK_NULL_VOID(menuTheme);
589 if (startDrag) {
590 menuRenderContext->UpdateTransformScale(
591 VectorF(menuTheme->GetMenuDragAnimationScale(), menuTheme->GetMenuDragAnimationScale()));
592 }
593 auto springMotionResponse = menuTheme->GetPreviewDisappearSpringMotionResponse();
594 auto springMotionDampingFraction = menuTheme->GetPreviewDisappearSpringMotionDampingFraction();
595 AnimationOption positionOption;
596 auto motion = AceType::MakeRefPtr<ResponsiveSpringMotion>(springMotionResponse, springMotionDampingFraction);
597 positionOption.SetCurve(motion);
598 AnimationUtils::Animate(positionOption, [menuRenderContext, menuPosition]() {
599 CHECK_NULL_VOID(menuRenderContext);
600 menuRenderContext->UpdatePosition(
601 OffsetT<Dimension>(Dimension(menuPosition.GetX()), Dimension(menuPosition.GetY())));
602 });
603
604 auto disappearDuration = menuTheme->GetDisappearDuration();
605 auto menuAnimationScale = menuTheme->GetMenuAnimationScale();
606 AnimationOption scaleOption;
607 scaleOption.SetCurve(Curves::FAST_OUT_LINEAR_IN);
608 scaleOption.SetDuration(disappearDuration);
609 AnimationUtils::Animate(scaleOption, [menuRenderContext, menuAnimationScale]() {
610 CHECK_NULL_VOID(menuRenderContext);
611 menuRenderContext->UpdateTransformScale({ menuAnimationScale, menuAnimationScale });
612 });
613
614 option.SetDuration(disappearDuration);
615 option.SetCurve(Curves::FRICTION);
616 AnimationUtils::Animate(
617 option,
618 [menuRenderContext]() {
619 CHECK_NULL_VOID(menuRenderContext);
620 menuRenderContext->UpdateOpacity(0.0);
621 },
622 option.GetOnFinishEvent());
623 }
624
FireMenuDisappear(AnimationOption & option,const RefPtr<MenuWrapperPattern> & menuWrapperPattern)625 void FireMenuDisappear(AnimationOption& option, const RefPtr<MenuWrapperPattern>& menuWrapperPattern)
626 {
627 CHECK_NULL_VOID(menuWrapperPattern);
628 auto menuNode = menuWrapperPattern->GetMenu();
629 CHECK_NULL_VOID(menuNode);
630 auto menuRenderContext = menuNode->GetRenderContext();
631 CHECK_NULL_VOID(menuRenderContext);
632 MENU_ANIMATION_CURVE->UpdateMinimumAmplitudeRatio(MINIMUM_AMPLITUDE_RATION);
633 option.SetCurve(MENU_ANIMATION_CURVE);
634 AnimationUtils::Animate(option, [menuRenderContext]() {
635 if (menuRenderContext) {
636 menuRenderContext->UpdateTransformScale(VectorF(MENU_ORIGINAL_SCALE, MENU_ORIGINAL_SCALE));
637 menuRenderContext->UpdateOpacity(0.0f);
638 }
639 }, option.GetOnFinishEvent());
640 }
641
SendPopupAccessibilityPageOpen(const RefPtr<FrameNode> & popupNode)642 void SendPopupAccessibilityPageOpen(const RefPtr<FrameNode>& popupNode)
643 {
644 CHECK_NULL_VOID(popupNode);
645 auto accessibilityProperty = popupNode->GetAccessibilityProperty<BubbleAccessibilityProperty>();
646 CHECK_NULL_VOID(accessibilityProperty);
647 accessibilityProperty->SetShowedState(1);
648 popupNode->OnAccessibilityEvent(
649 AccessibilityEventType::PAGE_OPEN, WindowsContentChangeTypes::CONTENT_CHANGE_TYPE_SUBTREE);
650 }
651 } // namespace
652
~OverlayManager()653 OverlayManager::~OverlayManager()
654 {
655 TAG_LOGI(AceLogTag::ACE_OVERLAY, "OverlayManager destroyed");
656 popupMap_.clear();
657 }
658
UpdateContextMenuDisappearPosition(const NG::OffsetF & offset,float menuScale,bool isRedragStart,int32_t menuWrapperId)659 void OverlayManager::UpdateContextMenuDisappearPosition(
660 const NG::OffsetF& offset, float menuScale, bool isRedragStart, int32_t menuWrapperId)
661 {
662 auto pipelineContext = PipelineContext::GetCurrentContext();
663 CHECK_NULL_VOID(pipelineContext);
664 auto overlayManager = pipelineContext->GetOverlayManager();
665 CHECK_NULL_VOID(overlayManager);
666 if (isRedragStart) {
667 overlayManager->ResetContextMenuRestartDragVector();
668 }
669
670 if (menuMap_.empty()) {
671 return;
672 }
673
674 RefPtr<FrameNode> menuWrapper = nullptr;
675 for (auto [targetId, node] : menuMap_) {
676 if (node && node->GetId() == menuWrapperId) {
677 menuWrapper = node;
678 }
679 }
680
681 CHECK_NULL_VOID(menuWrapper && menuWrapper->GetTag() == V2::MENU_WRAPPER_ETS_TAG);
682 overlayManager->UpdateDragMoveVector(offset);
683
684 if (overlayManager->IsOriginDragMoveVector() || !overlayManager->IsUpdateDragMoveVector()) {
685 return;
686 }
687
688 UpdateContextMenuDisappearPositionAnimation(menuWrapper, overlayManager->GetUpdateDragMoveVector(), menuScale);
689 }
690
CalculateMenuPosition(const RefPtr<FrameNode> & menuWrapperNode,const OffsetF & offset)691 OffsetF OverlayManager::CalculateMenuPosition(const RefPtr<FrameNode>& menuWrapperNode, const OffsetF& offset)
692 {
693 CHECK_NULL_RETURN(menuWrapperNode, OffsetF(0.0f, 0.0f));
694 if (IsContextMenuDragHideFinished()) {
695 return OffsetF(0.0f, 0.0f);
696 }
697 UpdateDragMoveVector(offset);
698 if (IsOriginDragMoveVector() || !IsUpdateDragMoveVector()) {
699 return OffsetF(0.0f, 0.0f);
700 }
701
702 auto menuWrapperPattern = menuWrapperNode->GetPattern<MenuWrapperPattern>();
703 CHECK_NULL_RETURN(menuWrapperPattern, OffsetF(0.0f, 0.0f));
704 auto menuNode = menuWrapperPattern->GetMenu();
705 CHECK_NULL_RETURN(menuNode, OffsetF(0.0f, 0.0f));
706 auto menuOffset = GetUpdateDragMoveVector();
707 auto menuPattern = menuNode->GetPattern<MenuPattern>();
708 CHECK_NULL_RETURN(menuPattern, OffsetF(0.0f, 0.0f));
709 auto menuGeometryNode = menuNode->GetGeometryNode();
710 CHECK_NULL_RETURN(menuGeometryNode, OffsetF(0.0f, 0.0f));
711 auto menuPosition = menuGeometryNode->GetFrameOffset();
712 menuPosition += menuOffset;
713 menuGeometryNode->SetFrameOffset(menuPosition);
714 menuPattern->SetEndOffset(menuPosition);
715 return menuPosition;
716 }
717
GetMenuPreviewCenter(NG::OffsetF & offset)718 bool OverlayManager::GetMenuPreviewCenter(NG::OffsetF& offset)
719 {
720 auto rootNode = rootNodeWeak_.Upgrade();
721 CHECK_NULL_RETURN(rootNode, false);
722 for (const auto& child : rootNode->GetChildren()) {
723 auto node = DynamicCast<FrameNode>(child);
724 if (node && node->GetTag() == V2::MENU_WRAPPER_ETS_TAG) {
725 auto menuWarpperPattern = node->GetPattern<MenuWrapperPattern>();
726 CHECK_NULL_RETURN(menuWarpperPattern, false);
727 auto previewChild = menuWarpperPattern->GetPreview();
728 CHECK_NULL_RETURN(previewChild, false);
729 auto geometryNode = previewChild->GetGeometryNode();
730 if (geometryNode && geometryNode->GetFrameRect().IsEmpty()) {
731 return false;
732 }
733 auto previewOffset = previewChild->GetPaintRectCenter();
734 offset.SetX(previewOffset.GetX());
735 offset.SetY(previewOffset.GetY());
736 return true;
737 }
738 }
739 return false;
740 }
741
ContextMenuSwitchDragPreviewAnimation(const RefPtr<NG::FrameNode> & dragPreviewNode,const NG::OffsetF & offset)742 void OverlayManager::ContextMenuSwitchDragPreviewAnimation(const RefPtr<NG::FrameNode>& dragPreviewNode,
743 const NG::OffsetF& offset)
744 {
745 CHECK_NULL_VOID(dragPreviewNode);
746 if (menuMap_.empty()) {
747 return;
748 }
749 auto rootNode = rootNodeWeak_.Upgrade();
750 for (const auto& child : rootNode->GetChildren()) {
751 auto node = DynamicCast<FrameNode>(child);
752 if (node && node->GetTag() == V2::MENU_WRAPPER_ETS_TAG) {
753 UpdateContextMenuSwitchDragPreviewBefore(node);
754 ContextMenuSwitchDragPreviewAnimationProc(node, dragPreviewNode, offset);
755 }
756 }
757 }
758
PostDialogFinishEvent(const WeakPtr<FrameNode> & nodeWk)759 void OverlayManager::PostDialogFinishEvent(const WeakPtr<FrameNode>& nodeWk)
760 {
761 TAG_LOGI(AceLogTag::ACE_DIALOG, "post dialog finish event enter");
762 auto context = PipelineContext::GetCurrentContext();
763 CHECK_NULL_VOID(context);
764 auto taskExecutor = context->GetTaskExecutor();
765 CHECK_NULL_VOID(taskExecutor);
766 // animation finish event should be posted to UI thread.
767 taskExecutor->PostTask(
768 [weak = WeakClaim(this), nodeWk, id = Container::CurrentId()]() {
769 ContainerScope scope(id);
770 auto overlayManager = weak.Upgrade();
771 auto node = nodeWk.Upgrade();
772 CHECK_NULL_VOID(overlayManager && node);
773 SafeAreaExpandOpts opts = { .type = SAFE_AREA_TYPE_NONE };
774 node->GetLayoutProperty()->UpdateSafeAreaExpandOpts(opts);
775 overlayManager->OnDialogCloseEvent(node);
776 },
777 TaskExecutor::TaskType::UI, "ArkUIOverlayDialogCloseEvent");
778 }
779
FireAutoSave(const RefPtr<FrameNode> & ContainerNode)780 void OverlayManager::FireAutoSave(const RefPtr<FrameNode>& ContainerNode)
781 {
782 TAG_LOGD(AceLogTag::ACE_OVERLAY, "fire auto save enter");
783 CHECK_NULL_VOID(ContainerNode);
784 if (!ContainerNode->NeedRequestAutoSave()) {
785 return;
786 }
787 auto container = Container::Current();
788 auto currentId = Container::CurrentId();
789 CHECK_NULL_VOID(container);
790
791 const auto& nodeTag = ContainerNode->GetTag();
792 if (nodeTag == V2::SHEET_PAGE_TAG) {
793 // BindSheet does not use subwindowManage. If use subwindow for display, autosave is started in the main window.
794 auto layoutProperty = ContainerNode->GetLayoutProperty<SheetPresentationProperty>();
795 CHECK_NULL_VOID(layoutProperty);
796 auto currentStyle = layoutProperty->GetSheetStyleValue();
797 if (currentStyle.instanceId.has_value()) {
798 auto pattern = ContainerNode->GetPattern<SheetPresentationPattern>();
799 CHECK_NULL_VOID(pattern);
800 auto targetNode = FrameNode::GetFrameNode(pattern->GetTargetTag(), pattern->GetTargetId());
801 CHECK_NULL_VOID(targetNode);
802 currentId = targetNode->GetInstanceId();
803 }
804 } else if (container->IsSubContainer()) {
805 currentId = SubwindowManager::GetInstance()->GetParentContainerId(Container::CurrentId());
806 }
807 container->RequestAutoSave(ContainerNode, nullptr, nullptr, true, currentId);
808 }
809
OnDialogCloseEvent(const RefPtr<FrameNode> & node)810 void OverlayManager::OnDialogCloseEvent(const RefPtr<FrameNode>& node)
811 {
812 CHECK_NULL_VOID(node);
813 TAG_LOGI(AceLogTag::ACE_DIALOG, "on dialog/%{public}d close event enter", node->GetId());
814
815 BlurOverlayNode(node);
816 FireAutoSave(node);
817
818 auto dialogPattern = node->GetPattern<DialogPattern>();
819 CHECK_NULL_VOID(dialogPattern);
820 auto option = dialogPattern->GetCloseAnimation().value_or(AnimationOption());
821 auto onFinish = option.GetOnFinishEvent();
822
823 auto dialogLayoutProp = dialogPattern->GetLayoutProperty<DialogLayoutProperty>();
824 bool isShowInSubWindow = false;
825 if (dialogLayoutProp) {
826 isShowInSubWindow = dialogLayoutProp->GetShowInSubWindowValue(false);
827 }
828 if (onFinish != nullptr) {
829 onFinish();
830 }
831
832 auto container = Container::Current();
833 auto currentId = Container::CurrentId();
834 CHECK_NULL_VOID(container);
835 if (isShowInSubWindow && !container->IsSubContainer()) {
836 currentId = SubwindowManager::GetInstance()->GetSubContainerId(currentId);
837 }
838
839 ContainerScope scope(currentId);
840 auto root = node->GetParent();
841 CHECK_NULL_VOID(root);
842 node->OnAccessibilityEvent(
843 AccessibilityEventType::CHANGE, WindowsContentChangeTypes::CONTENT_CHANGE_TYPE_SUBTREE);
844 DeleteDialogHotAreas(node);
845 TAG_LOGD(AceLogTag::ACE_OVERLAY, "remove DialogNode/%{public}d from RootNode/%{public}d",
846 node->GetId(), root->GetId());
847 root->RemoveChild(node, node->GetIsUseTransitionAnimator());
848 root->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
849
850 if (container->IsDialogContainer() || isShowInSubWindow) {
851 SubwindowManager::GetInstance()->HideSubWindowNG();
852 }
853 }
854
OpenDialogAnimation(const RefPtr<FrameNode> & node)855 void OverlayManager::OpenDialogAnimation(const RefPtr<FrameNode>& node)
856 {
857 TAG_LOGD(AceLogTag::ACE_OVERLAY, "open dialog animation");
858 CHECK_NULL_VOID(node);
859 auto pipeline = PipelineContext::GetCurrentContext();
860 CHECK_NULL_VOID(pipeline);
861 auto theme = pipeline->GetTheme<DialogTheme>();
862 CHECK_NULL_VOID(theme);
863 auto root = rootNodeWeak_.Upgrade();
864 auto dialogPattern = node->GetPattern<DialogPattern>();
865 dialogPattern->CallDialogWillAppearCallback();
866 auto container = Container::Current();
867 if (container && container->IsScenceBoardWindow()) {
868 root = dialogPattern->GetDialogProperties().windowScene.Upgrade();
869 }
870 CHECK_NULL_VOID(root);
871 MountToParentWithService(root, node);
872 root->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
873 BlurLowerNode(node);
874
875 AnimationOption option;
876 // default opacity animation params
877 option.SetCurve(Curves::SHARP);
878 option.SetDuration(theme->GetOpacityAnimationDurIn());
879 option.SetFillMode(FillMode::FORWARDS);
880 option = dialogPattern->GetOpenAnimation().value_or(option);
881 option.SetIteration(1);
882 option.SetAnimationDirection(AnimationDirection::NORMAL);
883 auto onFinish = option.GetOnFinishEvent();
884 option.SetOnFinishEvent(
885 [weak = WeakClaim(this), nodeWK = WeakPtr<FrameNode>(node), onFinish] {
886 if (onFinish) {
887 onFinish();
888 }
889 auto overlayManager = weak.Upgrade();
890 auto node = nodeWK.Upgrade();
891 CHECK_NULL_VOID(overlayManager && node);
892 overlayManager->FocusOverlayNode(node);
893 auto dialogPattern = node->GetPattern<DialogPattern>();
894 dialogPattern->CallDialogDidAppearCallback();
895 });
896 auto ctx = node->GetRenderContext();
897 option.SetFinishCallbackType(dialogPattern->GetOpenAnimation().has_value()
898 ? dialogPattern->GetOpenAnimation().value().GetFinishCallbackType()
899 : FinishCallbackType::REMOVED);
900 CHECK_NULL_VOID(ctx);
901 ctx->OpacityAnimation(option, theme->GetOpacityStart(), theme->GetOpacityEnd());
902 // scale animation on dialog content
903 auto contentNode = DynamicCast<FrameNode>(node->GetFirstChild());
904 CHECK_NULL_VOID(contentNode);
905 ctx = contentNode->GetRenderContext();
906 CHECK_NULL_VOID(ctx);
907 option.SetOnFinishEvent(nullptr);
908 option.SetCurve(SHOW_SCALE_ANIMATION_CURVE);
909 option.SetDuration(dialogPattern->GetOpenAnimation().has_value()
910 ? dialogPattern->GetOpenAnimation().value().GetDuration()
911 : theme->GetAnimationDurationIn());
912 ctx->ScaleAnimation(option, theme->GetScaleStart(), theme->GetScaleEnd());
913 node->OnAccessibilityEvent(
914 AccessibilityEventType::CHANGE, WindowsContentChangeTypes::CONTENT_CHANGE_TYPE_SUBTREE);
915 }
916
CloseDialogAnimation(const RefPtr<FrameNode> & node)917 void OverlayManager::CloseDialogAnimation(const RefPtr<FrameNode>& node)
918 {
919 TAG_LOGD(AceLogTag::ACE_OVERLAY, "close dialog animation");
920 CHECK_NULL_VOID(node);
921 auto pipeline = PipelineContext::GetCurrentContext();
922 CHECK_NULL_VOID(pipeline);
923 auto theme = pipeline->GetTheme<DialogTheme>();
924 CHECK_NULL_VOID(theme);
925 SafeAreaExpandOpts opts = { .type = SAFE_AREA_TYPE_KEYBOARD };
926 node->GetLayoutProperty()->UpdateSafeAreaExpandOpts(opts);
927
928 // default opacity animation params
929 AnimationOption option;
930 option.SetFillMode(FillMode::FORWARDS);
931 option.SetCurve(Curves::SHARP);
932 option.SetDuration(theme->GetAnimationDurationOut());
933 // get customized animation params
934 auto dialogPattern = node->GetPattern<DialogPattern>();
935 dialogPattern->CallDialogWillDisappearCallback();
936 option = dialogPattern->GetCloseAnimation().value_or(option);
937 option.SetIteration(1);
938 option.SetAnimationDirection(AnimationDirection::NORMAL);
939 option.SetOnFinishEvent(
940 [weak = WeakClaim(this), nodeWk = WeakPtr<FrameNode>(node), dialogPattern, id = Container::CurrentId()] {
941 ContainerScope scope(id);
942 auto overlayManager = weak.Upgrade();
943 CHECK_NULL_VOID(overlayManager);
944 overlayManager->PostDialogFinishEvent(nodeWk);
945 dialogPattern->CallDialogDidDisappearCallback();
946 });
947 auto ctx = node->GetRenderContext();
948 if (!ctx) {
949 TAG_LOGW(AceLogTag::ACE_OVERLAY, "not find render context when closing dialog");
950 return;
951 }
952 option.SetFinishCallbackType(dialogPattern->GetOpenAnimation().has_value()
953 ? dialogPattern->GetOpenAnimation().value().GetFinishCallbackType()
954 : FinishCallbackType::REMOVED);
955 ctx->OpacityAnimation(option, theme->GetOpacityEnd(), theme->GetOpacityStart());
956
957 // scale animation
958 auto contentNode = DynamicCast<FrameNode>(node->GetFirstChild());
959 CHECK_NULL_VOID(contentNode);
960 ctx = contentNode->GetRenderContext();
961 CHECK_NULL_VOID(ctx);
962 option.SetOnFinishEvent(nullptr);
963 option.SetCurve(Curves::FRICTION);
964 ctx->ScaleAnimation(option, theme->GetScaleEnd(), theme->GetScaleStart());
965 // start animation immediately
966 pipeline->RequestFrame();
967 }
968
SetDialogTransitionEffect(const RefPtr<FrameNode> & node)969 void OverlayManager::SetDialogTransitionEffect(const RefPtr<FrameNode>& node)
970 {
971 TAG_LOGD(AceLogTag::ACE_OVERLAY, "set dialog transition");
972 CHECK_NULL_VOID(node);
973 auto root = rootNodeWeak_.Upgrade();
974 auto dialogPattern = node->GetPattern<DialogPattern>();
975 dialogPattern->CallDialogWillAppearCallback();
976
977 auto layoutProperty = node->GetLayoutProperty();
978 layoutProperty->UpdateVisibility(VisibleType::VISIBLE, true);
979
980 auto ctx = node->GetRenderContext();
981 CHECK_NULL_VOID(ctx);
982 ctx->SetTransitionInCallback(
983 [weak = WeakClaim(this), nodeWK = WeakPtr<FrameNode>(node)] {
984 auto overlayManager = weak.Upgrade();
985 auto node = nodeWK.Upgrade();
986 CHECK_NULL_VOID(overlayManager && node);
987 overlayManager->FocusOverlayNode(node);
988 auto dialogPattern = node->GetPattern<DialogPattern>();
989 dialogPattern->CallDialogDidAppearCallback();
990 }
991 );
992
993 auto container = Container::Current();
994 if (container && container->IsScenceBoardWindow()) {
995 root = dialogPattern->GetDialogProperties().windowScene.Upgrade();
996 }
997
998 CHECK_NULL_VOID(root);
999 MountToParentWithService(root, node);
1000 root->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
1001 BlurLowerNode(node);
1002 node->OnAccessibilityEvent(
1003 AccessibilityEventType::CHANGE, WindowsContentChangeTypes::CONTENT_CHANGE_TYPE_SUBTREE);
1004 }
1005
CloseDialogMatchTransition(const RefPtr<FrameNode> & node)1006 void OverlayManager::CloseDialogMatchTransition(const RefPtr<FrameNode>& node)
1007 {
1008 TAG_LOGD(AceLogTag::ACE_OVERLAY, "close dialog match transition");
1009 CHECK_NULL_VOID(node);
1010 SafeAreaExpandOpts opts = { .type = SAFE_AREA_TYPE_KEYBOARD };
1011 node->GetLayoutProperty()->UpdateSafeAreaExpandOpts(opts);
1012 auto dialogPattern = node->GetPattern<DialogPattern>();
1013 dialogPattern->CallDialogWillDisappearCallback();
1014
1015 auto ctx = node->GetRenderContext();
1016 if (!ctx) {
1017 TAG_LOGW(AceLogTag::ACE_OVERLAY, "not find render context when closing dialog");
1018 return;
1019 }
1020 auto layoutProperty = node->GetLayoutProperty();
1021 layoutProperty->UpdateVisibility(VisibleType::INVISIBLE, true);
1022 if (ctx->HasDisappearTransition()) {
1023 ctx->SetTransitionOutCallback(
1024 [weak = WeakClaim(this), nodeWk = WeakPtr<FrameNode>(node), id = Container::CurrentId()] {
1025 ContainerScope scope(id);
1026 auto overlayManager = weak.Upgrade();
1027 CHECK_NULL_VOID(overlayManager);
1028 overlayManager->PostDialogFinishEvent(nodeWk);
1029 auto node = nodeWk.Upgrade();
1030 CHECK_NULL_VOID(node);
1031 auto dialogPattern = node->GetPattern<DialogPattern>();
1032 dialogPattern->CallDialogDidDisappearCallback();
1033 });
1034 } else {
1035 auto id = Container::CurrentId();
1036 ContainerScope scope(id);
1037 auto overlayManager = WeakClaim(this).Upgrade();
1038 CHECK_NULL_VOID(overlayManager);
1039 auto nodeWk = WeakPtr<FrameNode>(node);
1040 overlayManager->PostDialogFinishEvent(nodeWk);
1041 dialogPattern->CallDialogDidDisappearCallback();
1042 }
1043 }
1044
SetContainerButtonEnable(bool isEnabled)1045 void OverlayManager::SetContainerButtonEnable(bool isEnabled)
1046 {
1047 auto pipeline = PipelineContext::GetCurrentContext();
1048 CHECK_NULL_VOID(pipeline);
1049 pipeline->SetCloseButtonStatus(isEnabled);
1050 }
1051
UpdateMenuVisibility(const RefPtr<FrameNode> & menu)1052 void OverlayManager::UpdateMenuVisibility(const RefPtr<FrameNode>& menu)
1053 {
1054 auto layoutProperty = menu->GetLayoutProperty();
1055 CHECK_NULL_VOID(layoutProperty);
1056 layoutProperty->UpdateVisibility(VisibleType::VISIBLE, true);
1057 }
1058
OnShowMenuAnimationFinished(const WeakPtr<FrameNode> menuWK,const WeakPtr<OverlayManager> weak,int32_t instanceId)1059 void OverlayManager::OnShowMenuAnimationFinished(const WeakPtr<FrameNode> menuWK, const WeakPtr<OverlayManager> weak,
1060 int32_t instanceId)
1061 {
1062 auto menu = menuWK.Upgrade();
1063 auto overlayManager = weak.Upgrade();
1064 CHECK_NULL_VOID(menu && overlayManager);
1065 ContainerScope scope(instanceId);
1066 auto menuNode = AceType::DynamicCast<FrameNode>(menu->GetChildAtIndex(0));
1067 CHECK_NULL_VOID(menuNode);
1068 auto menuLayoutProp = menuNode->GetLayoutProperty<MenuLayoutProperty>();
1069 CHECK_NULL_VOID(menuLayoutProp);
1070 if (!menuLayoutProp->GetIsRectInTargetValue(false)) {
1071 overlayManager->FocusOverlayNode(menu);
1072 }
1073 auto menuWrapperPattern = menu->GetPattern<MenuWrapperPattern>();
1074 menuWrapperPattern->CallMenuAppearCallback();
1075 menuWrapperPattern->SetMenuStatus(MenuStatus::SHOW);
1076 }
1077
ShowMenuAnimation(const RefPtr<FrameNode> & menu)1078 void OverlayManager::ShowMenuAnimation(const RefPtr<FrameNode>& menu)
1079 {
1080 BlurLowerNode(menu);
1081 auto wrapperPattern = menu->GetPattern<MenuWrapperPattern>();
1082 CHECK_NULL_VOID(wrapperPattern);
1083 wrapperPattern->CallMenuAboutToAppearCallback();
1084 wrapperPattern->SetMenuStatus(MenuStatus::ON_SHOW_ANIMATION);
1085 SetIsMenuShow(true);
1086 if (wrapperPattern->HasTransitionEffect()) {
1087 UpdateMenuVisibility(menu);
1088 auto renderContext = menu->GetRenderContext();
1089 CHECK_NULL_VOID(renderContext);
1090 renderContext->SetTransitionInCallback(
1091 [weak = WeakClaim(this), menuWK = WeakClaim(RawPtr(menu)), id = Container::CurrentId()] {
1092 auto overlayManager = weak.Upgrade();
1093 CHECK_NULL_VOID(overlayManager);
1094 overlayManager->OnShowMenuAnimationFinished(menuWK, weak, id);
1095 overlayManager->SendToAccessibility(menuWK, true);
1096 });
1097 return;
1098 }
1099 AnimationOption option;
1100 option.SetCurve(Curves::FAST_OUT_SLOW_IN);
1101 option.SetDuration(MENU_ANIMATION_DURATION);
1102 option.SetFillMode(FillMode::FORWARDS);
1103 option.SetOnFinishEvent(
1104 [weak = WeakClaim(this), menuWK = WeakClaim(RawPtr(menu)), id = Container::CurrentId()] {
1105 auto overlayManager = weak.Upgrade();
1106 CHECK_NULL_VOID(overlayManager);
1107 overlayManager->OnShowMenuAnimationFinished(menuWK, weak, id);
1108 overlayManager->SendToAccessibility(menuWK, true);
1109 });
1110 if (wrapperPattern->GetPreviewMode() == MenuPreviewMode::CUSTOM) {
1111 auto pipelineContext = PipelineContext::GetCurrentContext();
1112 CHECK_NULL_VOID(pipelineContext);
1113 auto menuTheme = pipelineContext->GetTheme<NG::MenuTheme>();
1114 CHECK_NULL_VOID(menuTheme);
1115 option.SetDuration(menuTheme->GetContextMenuAppearDuration());
1116 auto previewChild = wrapperPattern->GetPreview();
1117 if (previewChild) {
1118 auto previewPattern = AceType::DynamicCast<MenuPreviewPattern>(previewChild->GetPattern());
1119 if (previewPattern) {
1120 previewPattern->SetFirstShow();
1121 }
1122 }
1123 }
1124 wrapperPattern->SetAniamtinOption(option);
1125 SetPatternFirstShow(menu);
1126 }
1127
SendToAccessibility(const WeakPtr<FrameNode> node,bool isShow)1128 void OverlayManager::SendToAccessibility(const WeakPtr<FrameNode> node, bool isShow)
1129 {
1130 auto menuWrapper = node.Upgrade();
1131 CHECK_NULL_VOID(menuWrapper);
1132 auto wrapperPattern = menuWrapper->GetPattern<MenuWrapperPattern>();
1133 CHECK_NULL_VOID(wrapperPattern);
1134 auto menu = wrapperPattern->GetMenu();
1135 CHECK_NULL_VOID(menu);
1136 auto accessibilityProperty = menu->GetAccessibilityProperty<MenuAccessibilityProperty>();
1137 CHECK_NULL_VOID(accessibilityProperty);
1138 accessibilityProperty->SetAccessibilityIsShow(isShow);
1139 if (isShow) {
1140 menu->OnAccessibilityEvent(AccessibilityEventType::PAGE_OPEN,
1141 WindowsContentChangeTypes::CONTENT_CHANGE_TYPE_SUBTREE);
1142 TAG_LOGI(AceLogTag::ACE_OVERLAY, "Send event to %{public}d",
1143 static_cast<int32_t>(AccessibilityEventType::PAGE_OPEN));
1144 } else {
1145 menu->OnAccessibilityEvent(AccessibilityEventType::PAGE_CLOSE,
1146 WindowsContentChangeTypes::CONTENT_CHANGE_TYPE_SUBTREE);
1147 TAG_LOGI(AceLogTag::ACE_OVERLAY, "Send event to %{public}d",
1148 static_cast<int32_t>(AccessibilityEventType::PAGE_CLOSE));
1149 }
1150 }
1151
SetPatternFirstShow(const RefPtr<FrameNode> & menu)1152 void OverlayManager::SetPatternFirstShow(const RefPtr<FrameNode>& menu)
1153 {
1154 auto wrapperPattern = menu->GetPattern<MenuWrapperPattern>();
1155 CHECK_NULL_VOID(wrapperPattern);
1156 wrapperPattern->SetFirstShow();
1157 auto menuChild = wrapperPattern->GetMenu();
1158 CHECK_NULL_VOID(menuChild);
1159 auto menuPattern = AceType::DynamicCast<MenuPattern>(menuChild->GetPattern());
1160 CHECK_NULL_VOID(menuPattern);
1161 menuPattern->SetFirstShow();
1162 menuPattern->SetMenuShow();
1163 }
1164
OnPopMenuAnimationFinished(const WeakPtr<FrameNode> menuWK,const WeakPtr<UINode> rootWeak,const WeakPtr<OverlayManager> weak,int32_t instanceId)1165 void OverlayManager::OnPopMenuAnimationFinished(const WeakPtr<FrameNode> menuWK, const WeakPtr<UINode> rootWeak,
1166 const WeakPtr<OverlayManager> weak, int32_t instanceId)
1167 {
1168 TAG_LOGI(AceLogTag::ACE_OVERLAY, "close menu animation finished");
1169 auto menu = menuWK.Upgrade();
1170 CHECK_NULL_VOID(menu);
1171 auto menuNode = AceType::DynamicCast<FrameNode>(menu->GetChildAtIndex(0));
1172 CHECK_NULL_VOID(menuNode);
1173 auto eventHub = menuNode->GetEventHub<EventHub>();
1174 CHECK_NULL_VOID(eventHub);
1175 eventHub->SetEnabledInternal(true);
1176 auto menuPattern = menuNode->GetPattern<MenuPattern>();
1177 CHECK_NULL_VOID(menuPattern);
1178 auto root = rootWeak.Upgrade();
1179 auto overlayManager = weak.Upgrade();
1180 CHECK_NULL_VOID(overlayManager);
1181
1182 overlayManager->SetContextMenuDragHideFinished(true);
1183 DragEventActuator::ExecutePreDragAction(PreDragStatus::PREVIEW_LANDING_FINISHED);
1184 auto menuWrapperPattern = menu->GetPattern<MenuWrapperPattern>();
1185 menuWrapperPattern->CallMenuDisappearCallback();
1186 menuWrapperPattern->SetMenuStatus(MenuStatus::HIDE);
1187 auto mainPipeline = PipelineContext::GetMainPipelineContext();
1188 if (mainPipeline && menuWrapperPattern->GetMenuDisappearCallback()) {
1189 ContainerScope scope(mainPipeline->GetInstanceId());
1190 mainPipeline->FlushPipelineImmediately();
1191 }
1192 // clear contextMenu then return
1193 auto pipeline = PipelineBase::GetCurrentContext();
1194 CHECK_NULL_VOID(pipeline);
1195 auto theme = pipeline->GetTheme<SelectTheme>();
1196 CHECK_NULL_VOID(theme);
1197 auto expandDisplay = theme->GetExpandDisplay();
1198 auto menuLayoutProp = menuPattern->GetLayoutProperty<MenuLayoutProperty>();
1199 CHECK_NULL_VOID(menuLayoutProp);
1200 bool isShowInSubWindow = menuLayoutProp->GetShowInSubWindowValue(true);
1201 auto targetId = menuWrapperPattern->GetTargetId();
1202 overlayManager->EraseMenuInfo(targetId);
1203 if (((menuWrapperPattern && menuWrapperPattern->IsContextMenu()) || (isShowInSubWindow && expandDisplay)) &&
1204 (menuPattern->GetTargetTag() != V2::SELECT_ETS_TAG)) {
1205 SubwindowManager::GetInstance()->ClearMenuNG(instanceId, menuWrapperPattern->GetTargetId());
1206 overlayManager->ResetContextMenuDragHideFinished();
1207 overlayManager->SetIsMenuShow(false);
1208 return;
1209 }
1210 overlayManager->RemoveMenuNotInSubWindow(menuWK, rootWeak, weak);
1211 overlayManager->SetIsMenuShow(false);
1212 }
1213
PopMenuAnimation(const RefPtr<FrameNode> & menu,bool showPreviewAnimation,bool startDrag)1214 void OverlayManager::PopMenuAnimation(const RefPtr<FrameNode>& menu, bool showPreviewAnimation, bool startDrag)
1215 {
1216 TAG_LOGI(AceLogTag::ACE_OVERLAY, "pop menu animation enter");
1217 CHECK_NULL_VOID(menu);
1218 auto wrapperPattern = menu->GetPattern<MenuWrapperPattern>();
1219 CHECK_NULL_VOID(wrapperPattern);
1220
1221 if (wrapperPattern->IsHide()) {
1222 return;
1223 }
1224
1225 ResetLowerNodeFocusable(menu);
1226 ResetContextMenuDragHideFinished();
1227 RemoveMenuBadgeNode(menu);
1228
1229 auto menuNode = AceType::DynamicCast<FrameNode>(menu->GetChildAtIndex(0));
1230 CHECK_NULL_VOID(menuNode);
1231 auto eventHub = menuNode->GetEventHub<EventHub>();
1232 CHECK_NULL_VOID(eventHub);
1233 eventHub->SetEnabledInternal(false);
1234
1235 wrapperPattern->CallMenuAboutToDisappearCallback();
1236 wrapperPattern->SetMenuStatus(MenuStatus::ON_HIDE_ANIMATION);
1237 if (wrapperPattern->HasTransitionEffect() || wrapperPattern->HasFoldModeChangedTransition()) {
1238 if (wrapperPattern->GetPreviewMode() != MenuPreviewMode::NONE) {
1239 ShowPreviewDisappearAnimation(wrapperPattern);
1240 }
1241 auto layoutProperty = menu->GetLayoutProperty();
1242 CHECK_NULL_VOID(layoutProperty);
1243 layoutProperty->UpdateVisibility(VisibleType::INVISIBLE, true);
1244 auto renderContext = menu->GetRenderContext();
1245 CHECK_NULL_VOID(renderContext);
1246 if (wrapperPattern->HasFoldModeChangedTransition()) {
1247 TAG_LOGI(AceLogTag::ACE_OVERLAY, "Close menu when foldMode is changed, disappear transiton is %{public}d",
1248 renderContext->HasDisappearTransition());
1249 }
1250
1251 if (renderContext->HasDisappearTransition()) {
1252 renderContext->SetTransitionOutCallback(
1253 [rootWeak = rootNodeWeak_, menuWK = WeakClaim(RawPtr(menu)), id = Container::CurrentId(),
1254 weak = WeakClaim(this)] {
1255 ContainerScope scope(id);
1256 auto overlayManager = weak.Upgrade();
1257 CHECK_NULL_VOID(overlayManager);
1258 overlayManager->SendToAccessibility(menuWK, false);
1259 overlayManager->OnPopMenuAnimationFinished(menuWK, rootWeak, weak, id);
1260 });
1261 } else {
1262 auto context = PipelineContext::GetCurrentContext();
1263 CHECK_NULL_VOID(context);
1264 auto taskExecutor = context->GetTaskExecutor();
1265 CHECK_NULL_VOID(taskExecutor);
1266 taskExecutor->PostTask(
1267 [rootWeak = rootNodeWeak_, menuWK = WeakClaim(RawPtr(menu)), id = Container::CurrentId(),
1268 weak = WeakClaim(this)] {
1269 ContainerScope scope(id);
1270 auto overlayManager = weak.Upgrade();
1271 CHECK_NULL_VOID(overlayManager);
1272 overlayManager->SendToAccessibility(menuWK, false);
1273 overlayManager->OnPopMenuAnimationFinished(menuWK, rootWeak, weak, id);
1274 },
1275 TaskExecutor::TaskType::UI, "ArkUIOverlayPopMenuAnimation");
1276 }
1277 return;
1278 }
1279
1280 AnimationOption option;
1281 option.SetCurve(Curves::FAST_OUT_SLOW_IN);
1282 option.SetDuration(MENU_ANIMATION_DURATION);
1283 option.SetFillMode(FillMode::FORWARDS);
1284 if (!startDrag) {
1285 DragEventActuator::ExecutePreDragAction(PreDragStatus::PREVIEW_LANDING_STARTED);
1286 }
1287 option.SetOnFinishEvent([rootWeak = rootNodeWeak_, menuWK = WeakClaim(RawPtr(menu)), id = Container::CurrentId(),
1288 weak = WeakClaim(this)] {
1289 ContainerScope scope(id);
1290 auto overlayManager = weak.Upgrade();
1291 CHECK_NULL_VOID(overlayManager);
1292 overlayManager->SendToAccessibility(menuWK, false);
1293 overlayManager->OnPopMenuAnimationFinished(menuWK, rootWeak, weak, id);
1294 });
1295 ShowMenuClearAnimation(menu, option, showPreviewAnimation, startDrag);
1296 }
1297
ClearMenuAnimation(const RefPtr<FrameNode> & menu,bool showPreviewAnimation,bool startDrag)1298 void OverlayManager::ClearMenuAnimation(const RefPtr<FrameNode>& menu, bool showPreviewAnimation, bool startDrag)
1299 {
1300 TAG_LOGD(AceLogTag::ACE_OVERLAY, "clear menu animation enter");
1301 ResetLowerNodeFocusable(menu);
1302 RemoveMenuBadgeNode(menu);
1303 AnimationOption option;
1304 option.SetCurve(Curves::FAST_OUT_SLOW_IN);
1305 option.SetDuration(MENU_ANIMATION_DURATION);
1306 option.SetFillMode(FillMode::FORWARDS);
1307 option.SetOnFinishEvent([rootWeak = rootNodeWeak_, menuWK = WeakClaim(RawPtr(menu)), id = Container::CurrentId(),
1308 weak = WeakClaim(this)] {
1309 auto menu = menuWK.Upgrade();
1310 auto root = rootWeak.Upgrade();
1311 auto overlayManager = weak.Upgrade();
1312 CHECK_NULL_VOID(menu && overlayManager);
1313 ContainerScope scope(id);
1314 auto container = Container::Current();
1315 if (container && container->IsScenceBoardWindow()) {
1316 root = overlayManager->FindWindowScene(menu);
1317 }
1318 CHECK_NULL_VOID(root);
1319 auto menuWrapperPattern = menu->GetPattern<MenuWrapperPattern>();
1320 // clear contextMenu then return
1321 if ((menuWrapperPattern && menuWrapperPattern->IsContextMenu())) {
1322 return;
1323 }
1324 overlayManager->BlurOverlayNode(menu);
1325 root->RemoveChild(menu);
1326 root->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
1327 });
1328 ShowMenuClearAnimation(menu, option, showPreviewAnimation, startDrag);
1329 }
1330
ShowMenuClearAnimation(const RefPtr<FrameNode> & menuWrapper,AnimationOption & option,bool showPreviewAnimation,bool startDrag)1331 void OverlayManager::ShowMenuClearAnimation(const RefPtr<FrameNode>& menuWrapper, AnimationOption& option,
1332 bool showPreviewAnimation, bool startDrag)
1333 {
1334 TAG_LOGI(AceLogTag::ACE_OVERLAY, "show menuWrapper clear animation enter");
1335 auto context = menuWrapper->GetRenderContext();
1336 CHECK_NULL_VOID(context);
1337 auto pipeline = PipelineBase::GetCurrentContext();
1338 CHECK_NULL_VOID(pipeline);
1339 auto menuWrapperPattern = menuWrapper->GetPattern<MenuWrapperPattern>();
1340 CHECK_NULL_VOID(menuWrapperPattern);
1341 auto menuAnimationOffset = menuWrapperPattern->GetAnimationOffset();
1342 auto outterMenu = menuWrapperPattern->GetMenu();
1343 CHECK_NULL_VOID(outterMenu);
1344 auto outterMenuPattern = outterMenu->GetPattern<MenuPattern>();
1345 CHECK_NULL_VOID(outterMenuPattern);
1346 bool isShow = outterMenuPattern->GetDisappearAnimation();
1347 bool isPreviewModeNone = menuWrapperPattern->GetPreviewMode() == MenuPreviewMode::NONE;
1348 if (!isPreviewModeNone
1349 || (isPreviewModeNone && IsContextMenuBindedOnOrigNode() && !showPreviewAnimation && startDrag)) {
1350 if (!showPreviewAnimation) {
1351 CleanPreviewInSubWindow();
1352 } else {
1353 ShowPreviewDisappearAnimation(menuWrapperPattern);
1354 }
1355 ShowContextMenuDisappearAnimation(option, menuWrapperPattern, startDrag);
1356 } else if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE) && isShow) {
1357 FireMenuDisappear(option, menuWrapperPattern);
1358 } else {
1359 AnimationUtils::Animate(
1360 option,
1361 [context, menuAnimationOffset]() {
1362 context->UpdateOpacity(0.0);
1363 context->UpdateOffset(menuAnimationOffset);
1364 },
1365 option.GetOnFinishEvent());
1366 #if defined(ANDROID_PLATFORM) || defined(IOS_PLATFORM)
1367 auto* transactionProxy = Rosen::RSTransactionProxy::GetInstance();
1368 if (transactionProxy != nullptr) {
1369 transactionProxy->FlushImplicitTransaction();
1370 }
1371 #endif
1372 }
1373 // start animation immediately
1374 pipeline->RequestFrame();
1375 }
1376
1377 // check if there is a bound menu on the current floating node on the main window
IsContextMenuBindedOnOrigNode()1378 bool OverlayManager::IsContextMenuBindedOnOrigNode()
1379 {
1380 auto mainPipeline = PipelineContext::GetMainPipelineContext();
1381 CHECK_NULL_RETURN(mainPipeline, false);
1382 auto dragDropManager = mainPipeline->GetDragDropManager();
1383 CHECK_NULL_RETURN(dragDropManager, false);
1384 auto draggingNode = dragDropManager->GetPrepareDragFrameNode().Upgrade();
1385 CHECK_NULL_RETURN(draggingNode, false);
1386 auto eventHub = draggingNode->GetEventHub<EventHub>();
1387 CHECK_NULL_RETURN(eventHub, false);
1388 auto frameNode = eventHub->GetFrameNode();
1389 CHECK_NULL_RETURN(frameNode, false);
1390 auto focusHub = frameNode->GetFocusHub();
1391 CHECK_NULL_RETURN(focusHub, false);
1392 return focusHub->FindContextMenuOnKeyEvent(OnKeyEventType::CONTEXT_MENU);
1393 }
1394
ShowToast(const NG::ToastInfo & toastInfo)1395 void OverlayManager::ShowToast(const NG::ToastInfo& toastInfo)
1396 {
1397 TAG_LOGD(AceLogTag::ACE_OVERLAY, "show toast enter");
1398 auto context = PipelineContext::GetCurrentContext();
1399 CHECK_NULL_VOID(context);
1400 auto rootNode = context->GetRootElement();
1401 CHECK_NULL_VOID(rootNode);
1402
1403 // only one toast
1404 for (auto [id, toastNodeWeak] : toastMap_) {
1405 rootNode->RemoveChild(toastNodeWeak.Upgrade());
1406 }
1407 toastMap_.clear();
1408 auto toastNode = ToastView::CreateToastNode(toastInfo);
1409 CHECK_NULL_VOID(toastNode);
1410 auto toastId = toastNode->GetId();
1411 // mount to parent
1412 TAG_LOGD(AceLogTag::ACE_OVERLAY, "toast mount to root");
1413 toastNode->MountToParent(rootNode);
1414 rootNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
1415 toastMap_[toastId] = toastNode;
1416 OpenToastAnimation(toastNode, toastInfo.duration);
1417 if (toastInfo.showMode == NG::ToastShowMode::DEFAULT) {
1418 TAG_LOGD(AceLogTag::ACE_OVERLAY, "show toast DEFAULT");
1419 } else if (toastInfo.showMode == NG::ToastShowMode::TOP_MOST) {
1420 TAG_LOGD(AceLogTag::ACE_OVERLAY, "show toast TOP_MOST");
1421 } else if (toastInfo.showMode == NG::ToastShowMode::SYSTEM_TOP_MOST) {
1422 TAG_LOGD(AceLogTag::ACE_OVERLAY, "show toast SYSTEM_TOP_MOST");
1423 }
1424 }
1425
OpenToastAnimation(const RefPtr<FrameNode> & toastNode,int32_t duration)1426 void OverlayManager::OpenToastAnimation(const RefPtr<FrameNode>& toastNode, int32_t duration)
1427 {
1428 TAG_LOGD(AceLogTag::ACE_OVERLAY, "open toast animation enter");
1429 auto toastId = toastNode->GetId();
1430 AnimationOption option;
1431 auto curve = AceType::MakeRefPtr<CubicCurve>(0.2f, 0.0f, 0.1f, 1.0f);
1432 option.SetCurve(curve);
1433 option.SetDuration(TOAST_ANIMATION_DURATION);
1434 option.SetFillMode(FillMode::FORWARDS);
1435 duration = std::max(duration, AceApplicationInfo::GetInstance().GetBarrierfreeDuration());
1436 continuousTask_.Reset([weak = WeakClaim(this), toastId, duration, id = Container::CurrentId()]() {
1437 auto overlayManager = weak.Upgrade();
1438 CHECK_NULL_VOID(overlayManager);
1439 ContainerScope scope(id);
1440 overlayManager->PopToast(toastId);
1441 });
1442 option.SetOnFinishEvent([continuousTask = continuousTask_, duration, id = Container::CurrentId()] {
1443 ContainerScope scope(id);
1444 auto context = PipelineContext::GetCurrentContext();
1445 CHECK_NULL_VOID(context);
1446 auto taskExecutor = context->GetTaskExecutor();
1447 CHECK_NULL_VOID(taskExecutor);
1448 taskExecutor->PostDelayedTask(
1449 continuousTask, TaskExecutor::TaskType::UI, duration, "ArkUIOverlayContinuousPopToast");
1450 });
1451 auto ctx = toastNode->GetRenderContext();
1452 CHECK_NULL_VOID(ctx);
1453 ctx->UpdateOpacity(0.0);
1454 ctx->OnTransformTranslateUpdate({ 0.0f, TOAST_ANIMATION_POSITION, 0.0f });
1455 AnimationUtils::Animate(
1456 option,
1457 [ctx]() {
1458 if (ctx) {
1459 ctx->UpdateOpacity(1.0);
1460 ctx->OnTransformTranslateUpdate({ 0.0f, 0.0f, 0.0f });
1461 }
1462 },
1463 option.GetOnFinishEvent());
1464 auto toastProperty = toastNode->GetLayoutProperty<ToastLayoutProperty>();
1465 CHECK_NULL_VOID(toastProperty);
1466 toastProperty->SetSelectStatus(ToastLayoutProperty::SelectStatus::ON);
1467 toastNode->OnAccessibilityEvent(
1468 AccessibilityEventType::PAGE_OPEN, WindowsContentChangeTypes::CONTENT_CHANGE_TYPE_SUBTREE);
1469 }
1470
PopToast(int32_t toastId)1471 void OverlayManager::PopToast(int32_t toastId)
1472 {
1473 TAG_LOGD(AceLogTag::ACE_OVERLAY, "pop toast enter");
1474 AnimationOption option;
1475 auto curve = AceType::MakeRefPtr<CubicCurve>(0.2f, 0.0f, 0.1f, 1.0f);
1476 option.SetCurve(curve);
1477 option.SetDuration(TOAST_ANIMATION_DURATION);
1478 option.SetFillMode(FillMode::FORWARDS);
1479 // OnFinishEvent should be executed in UI thread.
1480 option.SetOnFinishEvent([weak = WeakClaim(this), toastId] {
1481 TAG_LOGD(AceLogTag::ACE_OVERLAY, "start toast exit finish event");
1482 auto overlayManager = weak.Upgrade();
1483 CHECK_NULL_VOID(overlayManager);
1484 auto toastIter = overlayManager->toastMap_.find(toastId);
1485 if (toastIter == overlayManager->toastMap_.end()) {
1486 return;
1487 }
1488 auto toastUnderPop = toastIter->second.Upgrade();
1489 CHECK_NULL_VOID(toastUnderPop);
1490 auto context = PipelineContext::GetCurrentContext();
1491 CHECK_NULL_VOID(context);
1492 auto rootNode = context->GetRootElement();
1493 CHECK_NULL_VOID(rootNode);
1494 TAG_LOGI(AceLogTag::ACE_OVERLAY, "toast remove from root");
1495 rootNode->RemoveChild(toastUnderPop);
1496 overlayManager->toastMap_.erase(toastId);
1497 rootNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
1498
1499 auto container = Container::Current();
1500 CHECK_NULL_VOID(container);
1501 if (container->IsDialogContainer() || (container->IsSubContainer() && rootNode->GetChildren().empty())) {
1502 auto pattern = toastUnderPop->GetPattern<ToastPattern>();
1503 CHECK_NULL_VOID(pattern);
1504 auto toastInfo = pattern->GetToastInfo();
1505 // hide window when toast show in subwindow.
1506 if (toastInfo.showMode == NG::ToastShowMode::SYSTEM_TOP_MOST) {
1507 SubwindowManager::GetInstance()->HideSystemTopMostWindow();
1508 } else {
1509 SubwindowManager::GetInstance()->HideToastSubWindowNG();
1510 }
1511 }
1512 });
1513 auto toastIter = toastMap_.find(toastId);
1514 if (toastIter == toastMap_.end()) {
1515 return;
1516 }
1517 auto toastUnderPop = toastIter->second.Upgrade();
1518 CHECK_NULL_VOID(toastUnderPop);
1519 auto ctx = toastUnderPop->GetRenderContext();
1520 CHECK_NULL_VOID(ctx);
1521 ctx->UpdateOpacity(1.0);
1522 ctx->OnTransformTranslateUpdate({ 0.0f, 0.0f, 0.0f });
1523 AnimationUtils::Animate(
1524 option,
1525 [ctx]() {
1526 if (ctx) {
1527 ctx->UpdateOpacity(0.0);
1528 ctx->OnTransformTranslateUpdate({ 0.0f, TOAST_ANIMATION_POSITION, 0.0f });
1529 }
1530 },
1531 option.GetOnFinishEvent());
1532 #if defined(ANDROID_PLATFORM) || defined(IOS_PLATFORM)
1533 auto* transactionProxy = Rosen::RSTransactionProxy::GetInstance();
1534 if (transactionProxy != nullptr) {
1535 transactionProxy->FlushImplicitTransaction();
1536 }
1537 #endif
1538 // start animation immediately
1539 auto pipeline = PipelineContext::GetCurrentContext();
1540 CHECK_NULL_VOID(pipeline);
1541 pipeline->RequestFrame();
1542 auto toastProperty = toastUnderPop->GetLayoutProperty<ToastLayoutProperty>();
1543 CHECK_NULL_VOID(toastProperty);
1544 toastProperty->SetSelectStatus(ToastLayoutProperty::SelectStatus::OFF);
1545 toastUnderPop->OnAccessibilityEvent(
1546 AccessibilityEventType::PAGE_CLOSE, WindowsContentChangeTypes::CONTENT_CHANGE_TYPE_SUBTREE);
1547 }
1548
ClearToastInSubwindow()1549 void OverlayManager::ClearToastInSubwindow()
1550 {
1551 TAG_LOGD(AceLogTag::ACE_OVERLAY, "clear toast in subwindow enter");
1552 SubwindowManager::GetInstance()->ClearToastInSubwindow();
1553 }
1554
ClearToast()1555 void OverlayManager::ClearToast()
1556 {
1557 TAG_LOGD(AceLogTag::ACE_OVERLAY, "clear toast enter");
1558 auto context = PipelineContext::GetCurrentContext();
1559 CHECK_NULL_VOID(context);
1560 auto rootNode = context->GetRootElement();
1561 CHECK_NULL_VOID(rootNode);
1562 for (auto [id, toastNodeWeak] : toastMap_) {
1563 PopToast(id);
1564 }
1565 }
1566
ShowPopupAnimation(const RefPtr<FrameNode> & popupNode)1567 void OverlayManager::ShowPopupAnimation(const RefPtr<FrameNode>& popupNode)
1568 {
1569 auto popupPattern = popupNode->GetPattern<BubblePattern>();
1570 CHECK_NULL_VOID(popupPattern);
1571 popupPattern->ResetFocusState();
1572 BlurLowerNode(popupNode);
1573 auto onFinish = [popupNodeWk = WeakPtr<FrameNode>(popupNode), weak = WeakClaim(this)]() {
1574 auto overlayManager = weak.Upgrade();
1575 auto popupNode = popupNodeWk.Upgrade();
1576 CHECK_NULL_VOID(overlayManager && popupNode);
1577 overlayManager->FocusOverlayNode(popupNode);
1578 };
1579 if (popupPattern->GetHasTransition()) {
1580 popupPattern->StartEnteringTransitionEffects(popupNode, onFinish);
1581 } else {
1582 popupPattern->StartEnteringAnimation(onFinish);
1583 }
1584 }
1585
ShowPopupAnimationNG(const RefPtr<FrameNode> & popupNode)1586 void OverlayManager::ShowPopupAnimationNG(const RefPtr<FrameNode>& popupNode)
1587 {
1588 auto popupPattern = popupNode->GetPattern<BubblePattern>();
1589 CHECK_NULL_VOID(popupPattern);
1590 if (popupPattern->GetHasTransition()) {
1591 popupPattern->StartEnteringTransitionEffects(popupNode, nullptr);
1592 } else {
1593 popupPattern->StartEnteringAnimation(nullptr);
1594 }
1595 }
1596
HidePopupAnimation(const RefPtr<FrameNode> & popupNode,const std::function<void ()> & finish)1597 void OverlayManager::HidePopupAnimation(const RefPtr<FrameNode>& popupNode, const std::function<void()>& finish)
1598 {
1599 auto rootNode = rootNodeWeak_.Upgrade();
1600 auto popupPattern = popupNode->GetPattern<BubblePattern>();
1601 if (popupPattern->GetHasTransition()) {
1602 if (!popupNode->GetRenderContext()->HasDisappearTransition()) {
1603 popupPattern->SetTransitionStatus(TransitionStatus::INVISIABLE);
1604 popupNode->GetEventHub<BubbleEventHub>()->FireChangeEvent(false);
1605 RemoveChildWithService(rootNode, popupNode);
1606 rootNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
1607 auto layoutProp = popupNode->GetLayoutProperty<BubbleLayoutProperty>();
1608 CHECK_NULL_VOID(layoutProp);
1609 auto isShowInSubWindow = layoutProp->GetShowInSubWindow().value_or(false);
1610 if (isShowInSubWindow) {
1611 auto subwindowMgr = SubwindowManager::GetInstance();
1612 subwindowMgr->DeleteHotAreas(Container::CurrentId(), popupNode->GetId());
1613 }
1614 } else {
1615 popupPattern->StartExitingTransitionEffects(popupNode, finish);
1616 }
1617 } else {
1618 popupPattern->StartExitingAnimation(finish);
1619 }
1620 }
1621
ShowPopup(int32_t targetId,const PopupInfo & popupInfo,const std::function<void (int32_t)> && onWillDismiss,bool interactiveDismiss)1622 void OverlayManager::ShowPopup(int32_t targetId, const PopupInfo& popupInfo,
1623 const std::function<void(int32_t)>&& onWillDismiss, bool interactiveDismiss)
1624 {
1625 if (!UpdatePopupMap(targetId, popupInfo)) {
1626 TAG_LOGE(AceLogTag::ACE_OVERLAY, "failed to update popup map, tag:%{public}s",
1627 popupInfo.target.Upgrade()->GetTag().c_str());
1628 return;
1629 }
1630 auto rootNode = rootNodeWeak_.Upgrade();
1631 CHECK_NULL_VOID(rootNode);
1632 auto frameNode = AceType::DynamicCast<FrameNode>(rootNode);
1633 if (frameNode && !frameNode->IsLayoutComplete()) {
1634 auto context = PipelineContext::GetCurrentContext();
1635 CHECK_NULL_VOID(context);
1636 auto taskExecutor = context->GetTaskExecutor();
1637 CHECK_NULL_VOID(taskExecutor);
1638 taskExecutor->PostTask(
1639 [targetId, popupInfo, weak = WeakClaim(this), callback = std::move(onWillDismiss), interactiveDismiss]() {
1640 auto overlayManager = weak.Upgrade();
1641 CHECK_NULL_VOID(overlayManager);
1642 overlayManager->MountPopup(targetId, popupInfo, std::move(callback), interactiveDismiss);
1643 },
1644 TaskExecutor::TaskType::UI, "ArkUIOverlayShowPopup");
1645 } else {
1646 MountPopup(targetId, popupInfo, std::move(onWillDismiss), interactiveDismiss);
1647 }
1648 }
1649
UpdatePopupMap(int32_t targetId,const PopupInfo & popupInfo)1650 bool OverlayManager::UpdatePopupMap(int32_t targetId, const PopupInfo& popupInfo)
1651 {
1652 popupMap_[targetId] = popupInfo;
1653 if (!popupInfo.markNeedUpdate) {
1654 TAG_LOGW(AceLogTag::ACE_OVERLAY, "mark need update failed");
1655 return false;
1656 }
1657 popupMap_[targetId].markNeedUpdate = false;
1658 return true;
1659 }
1660
MountPopup(int32_t targetId,const PopupInfo & popupInfo,const std::function<void (int32_t)> && onWillDismiss,bool interactiveDismiss)1661 void OverlayManager::MountPopup(int32_t targetId, const PopupInfo& popupInfo,
1662 const std::function<void(int32_t)>&& onWillDismiss, bool interactiveDismiss)
1663 {
1664 // TargetNode may be destroyed when MontPopup is thrown thread.
1665 auto targetNode = popupInfo.target.Upgrade();
1666 CHECK_NULL_VOID(targetNode);
1667 auto popupNode = popupInfo.popupNode;
1668 CHECK_NULL_VOID(popupNode);
1669 auto layoutProp = popupNode->GetLayoutProperty<BubbleLayoutProperty>();
1670 CHECK_NULL_VOID(layoutProp);
1671 auto isShowInSubWindow = layoutProp->GetShowInSubWindow().value_or(false);
1672 auto paintProperty = popupNode->GetPaintProperty<BubbleRenderProperty>();
1673 CHECK_NULL_VOID(paintProperty);
1674 auto isTypeWithOption = paintProperty->GetPrimaryButtonShow().value_or(false);
1675 auto isUseCustom = paintProperty->GetUseCustom().value_or(false);
1676
1677 auto rootNode = rootNodeWeak_.Upgrade();
1678 auto container = Container::Current();
1679 if (container && container->IsScenceBoardWindow()) {
1680 rootNode = FindWindowScene(popupInfo.target.Upgrade());
1681 }
1682 CHECK_NULL_VOID(rootNode);
1683 CHECK_NULL_VOID(popupInfo.markNeedUpdate);
1684 CHECK_NULL_VOID(popupInfo.popupNode);
1685
1686 const auto& rootChildren = rootNode->GetChildren();
1687 auto iter = std::find(rootChildren.rbegin(), rootChildren.rend(), popupNode);
1688 if (iter == rootChildren.rend()) {
1689 MountToParentWithService(rootNode, popupNode);
1690 }
1691
1692 // attach popupNode before entering animation
1693 popupNode->GetEventHub<BubbleEventHub>()->FireChangeEvent(true);
1694 rootNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
1695 popupMap_[targetId].isCurrentOnShow = true;
1696
1697 auto popupPattern = popupNode->GetPattern<BubblePattern>();
1698 CHECK_NULL_VOID(popupPattern);
1699 popupPattern->AddPipelineCallBack();
1700 popupPattern->SetInteractiveDismiss(interactiveDismiss);
1701 popupPattern->UpdateOnWillDismiss(move(onWillDismiss));
1702 if ((isTypeWithOption && !isShowInSubWindow) ||
1703 (!Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN) && isUseCustom && popupInfo.focusable)) {
1704 ShowPopupAnimation(popupNode);
1705 } else {
1706 ShowPopupAnimationNG(popupNode);
1707 }
1708 SetPopupHotAreas(popupNode);
1709 SendPopupAccessibilityPageOpen(popupNode);
1710 }
1711
SetPopupHotAreas(RefPtr<FrameNode> popupNode)1712 void OverlayManager::SetPopupHotAreas(RefPtr<FrameNode> popupNode)
1713 {
1714 CHECK_NULL_VOID(popupNode);
1715 auto popupId = popupNode->GetId();
1716 auto popupPattern = popupNode->GetPattern<BubblePattern>();
1717 CHECK_NULL_VOID(popupPattern);
1718 auto layoutProp = popupNode->GetLayoutProperty<BubbleLayoutProperty>();
1719 CHECK_NULL_VOID(layoutProp);
1720 auto isBlock = layoutProp->GetBlockEventValue(true);
1721 auto isShowInSubWindow = layoutProp->GetShowInSubWindow().value_or(false);
1722 if (isShowInSubWindow && popupPattern->IsOnShow()) {
1723 std::vector<Rect> rects;
1724 if (!isBlock) {
1725 auto rect = Rect(popupPattern->GetChildOffset().GetX(), popupPattern->GetChildOffset().GetY(),
1726 popupPattern->GetChildSize().Width(), popupPattern->GetChildSize().Height());
1727 rects.emplace_back(rect);
1728 } else {
1729 auto parentWindowRect = popupPattern->GetHostWindowRect();
1730 auto rect = Rect(popupPattern->GetChildOffset().GetX(), popupPattern->GetChildOffset().GetY(),
1731 popupPattern->GetChildSize().Width(), popupPattern->GetChildSize().Height());
1732 rects.emplace_back(parentWindowRect);
1733 rects.emplace_back(rect);
1734 }
1735 auto subWindowMgr = SubwindowManager::GetInstance();
1736 subWindowMgr->SetHotAreas(rects, popupId, popupPattern->GetContainerId());
1737 }
1738 }
1739
HidePopup(int32_t targetId,const PopupInfo & popupInfo)1740 void OverlayManager::HidePopup(int32_t targetId, const PopupInfo& popupInfo)
1741 {
1742 TAG_LOGD(AceLogTag::ACE_OVERLAY, "hide popup enter");
1743 popupMap_[targetId] = popupInfo;
1744 if (!popupInfo.markNeedUpdate) {
1745 TAG_LOGW(AceLogTag::ACE_OVERLAY, "mark need update failed");
1746 return;
1747 }
1748 popupMap_[targetId].markNeedUpdate = false;
1749 auto focusable = popupInfo.focusable;
1750 auto popupNode = popupInfo.popupNode;
1751 CHECK_NULL_VOID(popupNode);
1752 auto layoutProp = popupNode->GetLayoutProperty<BubbleLayoutProperty>();
1753 CHECK_NULL_VOID(layoutProp);
1754 auto isShowInSubWindow = layoutProp->GetShowInSubWindow().value_or(false);
1755 auto paintProperty = popupNode->GetPaintProperty<BubbleRenderProperty>();
1756 CHECK_NULL_VOID(paintProperty);
1757 auto isTypeWithOption = paintProperty->GetPrimaryButtonShow().value_or(false);
1758 auto isUseCustom = paintProperty->GetUseCustom().value_or(false);
1759
1760 auto rootNode = rootNodeWeak_.Upgrade();
1761 auto container = Container::Current();
1762 if (container && container->IsScenceBoardWindow()) {
1763 rootNode = FindWindowScene(popupInfo.target.Upgrade());
1764 }
1765 CHECK_NULL_VOID(rootNode);
1766
1767 auto pipeline = rootNode->GetContextRefPtr();
1768 CHECK_NULL_VOID(pipeline);
1769 const auto& rootChildren = rootNode->GetChildren();
1770 auto iter = std::find(rootChildren.rbegin(), rootChildren.rend(), popupNode);
1771 // There is no overlay under the root node or it is not in atomicservice
1772 if (iter == rootChildren.rend() && !pipeline->GetInstallationFree()) {
1773 return;
1774 }
1775
1776 auto popupPattern = popupNode->GetPattern<BubblePattern>();
1777 CHECK_NULL_VOID(popupPattern);
1778 if (popupPattern->GetTransitionStatus() == TransitionStatus::EXITING) {
1779 return;
1780 }
1781 popupPattern->SetTransitionStatus(TransitionStatus::EXITING);
1782 if ((isTypeWithOption && !isShowInSubWindow) ||
1783 (!Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN) && isUseCustom && focusable)) {
1784 ResetLowerNodeFocusable(popupNode);
1785 }
1786 CheckReturnFocus(popupNode);
1787 auto accessibilityProperty = popupNode->GetAccessibilityProperty<BubbleAccessibilityProperty>();
1788 CHECK_NULL_VOID(accessibilityProperty);
1789 accessibilityProperty->SetShowedState(0);
1790 popupNode->OnAccessibilityEvent(
1791 AccessibilityEventType::PAGE_CLOSE, WindowsContentChangeTypes::CONTENT_CHANGE_TYPE_SUBTREE);
1792 // detach popupNode after exiting animation
1793 popupMap_[targetId].isCurrentOnShow = false;
1794 auto onFinish = [isShowInSubWindow, isTypeWithOption, isUseCustom, focusable,
1795 targetId, popupNodeWk = WeakPtr<FrameNode>(popupNode),
1796 rootNodeWk = WeakPtr<UINode>(rootNode), weak = WeakClaim(this)]() {
1797 auto rootNode = rootNodeWk.Upgrade();
1798 auto popupNode = popupNodeWk.Upgrade();
1799 auto overlayManager = weak.Upgrade();
1800 CHECK_NULL_VOID(rootNode && popupNode && overlayManager);
1801 if (overlayManager->popupMap_[targetId].isCurrentOnShow) {
1802 return;
1803 }
1804 auto popupPattern = popupNode->GetPattern<BubblePattern>();
1805 CHECK_NULL_VOID(popupPattern);
1806 popupPattern->SetTransitionStatus(TransitionStatus::INVISIABLE);
1807 popupNode->GetEventHub<BubbleEventHub>()->FireChangeEvent(false);
1808 popupNode->GetRenderContext()->UpdateChainedTransition(nullptr);
1809 overlayManager->RemoveChildWithService(rootNode, popupNode);
1810 rootNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
1811 overlayManager->ErasePopupInfo(targetId);
1812 if ((isTypeWithOption && !isShowInSubWindow) ||
1813 (!Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN) && isUseCustom && focusable)) {
1814 overlayManager->BlurOverlayNode(popupNode);
1815 }
1816 if (isShowInSubWindow) {
1817 auto subwindow = SubwindowManager::GetInstance();
1818 subwindow->DeleteHotAreas(Container::CurrentId(), popupNode->GetId());
1819 subwindow->HideSubWindowNG();
1820 }
1821 };
1822 HidePopupAnimation(popupNode, onFinish);
1823 RemoveEventColumn();
1824 RemovePixelMapAnimation(false, 0, 0);
1825 RemoveGatherNodeWithAnimation();
1826 RemoveFilter();
1827 }
1828
HidePopupWithoutAnimation(int32_t targetId,const PopupInfo & popupInfo)1829 RefPtr<FrameNode> OverlayManager::HidePopupWithoutAnimation(int32_t targetId, const PopupInfo& popupInfo)
1830 {
1831 TAG_LOGD(AceLogTag::ACE_OVERLAY, "hide popup without animation enter");
1832 popupMap_[targetId] = popupInfo;
1833 CHECK_NULL_RETURN(popupInfo.markNeedUpdate, nullptr);
1834 if (!popupInfo.markNeedUpdate) {
1835 TAG_LOGW(AceLogTag::ACE_OVERLAY, "mark need update failed");
1836 return nullptr;
1837 }
1838 CHECK_NULL_RETURN(popupInfo.popupNode, nullptr);
1839 auto bubbleRenderProp = popupInfo.popupNode->GetPaintProperty<BubbleRenderProperty>();
1840 CHECK_NULL_RETURN(bubbleRenderProp, nullptr);
1841 auto autoCancel = bubbleRenderProp->GetAutoCancel().value_or(true);
1842 if (!autoCancel) {
1843 return nullptr;
1844 }
1845 popupInfo.popupNode->GetEventHub<BubbleEventHub>()->FireChangeEvent(false);
1846 CHECK_NULL_RETURN(popupInfo.isCurrentOnShow, nullptr);
1847 popupMap_[targetId].isCurrentOnShow = false;
1848 auto pattern = popupInfo.popupNode->GetPattern<BubblePattern>();
1849 CHECK_NULL_RETURN(pattern, nullptr);
1850 pattern->SetTransitionStatus(TransitionStatus::INVISIABLE);
1851 auto rootNode = rootNodeWeak_.Upgrade();
1852 CHECK_NULL_RETURN(rootNode, nullptr);
1853 auto rootChildren = rootNode->GetChildren();
1854 auto iter = std::find(rootChildren.begin(), rootChildren.end(), popupInfo.popupNode);
1855 if (iter != rootChildren.end()) {
1856 return popupMap_[targetId].popupNode;
1857 }
1858 return nullptr;
1859 }
1860
ShowIndexerPopup(int32_t targetId,RefPtr<FrameNode> & customNode)1861 void OverlayManager::ShowIndexerPopup(int32_t targetId, RefPtr<FrameNode>& customNode)
1862 {
1863 TAG_LOGD(AceLogTag::ACE_OVERLAY, "show indexer popup enter");
1864 CHECK_NULL_VOID(customNode);
1865 auto rootNode = rootNodeWeak_.Upgrade();
1866 CHECK_NULL_VOID(rootNode);
1867 if (!customPopupMap_[targetId] || customPopupMap_[targetId] != customNode) {
1868 customPopupMap_[targetId] = customNode;
1869 customNode->MountToParent(rootNode);
1870 customNode->MarkModifyDone();
1871 rootNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
1872 }
1873 }
1874
RemoveIndexerPopupById(int32_t targetId)1875 void OverlayManager::RemoveIndexerPopupById(int32_t targetId)
1876 {
1877 TAG_LOGD(AceLogTag::ACE_OVERLAY, "remove indexer popup by id enter");
1878 if (customPopupMap_.empty()) {
1879 return;
1880 }
1881 auto rootNode = rootNodeWeak_.Upgrade();
1882 CHECK_NULL_VOID(rootNode);
1883 auto iter = customPopupMap_.find(targetId);
1884 if (iter != customPopupMap_.end()) {
1885 RemoveChildWithService(rootNode, iter->second);
1886 customPopupMap_.erase(iter);
1887 rootNode->MarkDirtyNode(PROPERTY_UPDATE_BY_CHILD_REQUEST);
1888 }
1889 }
1890
RemoveIndexerPopup()1891 void OverlayManager::RemoveIndexerPopup()
1892 {
1893 TAG_LOGD(AceLogTag::ACE_OVERLAY, "remove indexer popup enter");
1894 if (customPopupMap_.empty()) {
1895 return;
1896 }
1897 auto rootNode = rootNodeWeak_.Upgrade();
1898 CHECK_NULL_VOID(rootNode);
1899 for (const auto& popup : customPopupMap_) {
1900 auto popupNode = popup.second;
1901 RemoveChildWithService(rootNode, popupNode);
1902 }
1903 customPopupMap_.clear();
1904 rootNode->MarkDirtyNode(PROPERTY_UPDATE_BY_CHILD_REQUEST);
1905 }
1906
HideCustomPopups()1907 void OverlayManager::HideCustomPopups()
1908 {
1909 TAG_LOGD(AceLogTag::ACE_OVERLAY, "hide custom popup enter");
1910 if (popupMap_.empty()) {
1911 return;
1912 }
1913 for (const auto& popup : popupMap_) {
1914 auto popupInfo = popup.second;
1915 if (popupInfo.isCurrentOnShow && popupInfo.target.Upgrade()) {
1916 auto targetNodeId = popupInfo.target.Upgrade()->GetId();
1917 auto popupNode = popupInfo.popupNode;
1918 CHECK_NULL_VOID(popupNode);
1919 auto layoutProp = popupNode->GetLayoutProperty<BubbleLayoutProperty>();
1920 CHECK_NULL_VOID(layoutProp);
1921 auto paintProperty = popupNode->GetPaintProperty<BubbleRenderProperty>();
1922 CHECK_NULL_VOID(paintProperty);
1923 auto isTypeWithOption = paintProperty->GetPrimaryButtonShow().value_or(false);
1924 popupNode->GetEventHub<BubbleEventHub>()->FireChangeEvent(false);
1925 // if use popup with option, skip
1926 if (isTypeWithOption) {
1927 continue;
1928 }
1929 popupInfo.markNeedUpdate = true;
1930 auto showInSubWindow = layoutProp->GetShowInSubWindow().value_or(false);
1931 if (showInSubWindow) {
1932 SubwindowManager::GetInstance()->HidePopupNG(targetNodeId);
1933 } else {
1934 HidePopup(targetNodeId, popupInfo);
1935 }
1936 }
1937 }
1938 }
1939
HideAllPopups()1940 void OverlayManager::HideAllPopups()
1941 {
1942 TAG_LOGD(AceLogTag::ACE_OVERLAY, "hide all popup enter");
1943 if (popupMap_.empty()) {
1944 return;
1945 }
1946 auto tempPopupMap = popupMap_;
1947 for (const auto& popup : tempPopupMap) {
1948 auto popupInfo = popup.second;
1949 if (popupInfo.isCurrentOnShow && popupInfo.target.Upgrade()) {
1950 auto targetNodeId = popupInfo.target.Upgrade()->GetId();
1951 auto popupNode = popupInfo.popupNode;
1952 CHECK_NULL_VOID(popupNode);
1953 auto layoutProp = popupNode->GetLayoutProperty<BubbleLayoutProperty>();
1954 CHECK_NULL_VOID(layoutProp);
1955 popupInfo.markNeedUpdate = true;
1956 auto showInSubWindow = layoutProp->GetShowInSubWindow().value_or(false);
1957 if (showInSubWindow) {
1958 SubwindowManager::GetInstance()->HidePopupNG(targetNodeId);
1959 } else {
1960 HidePopup(targetNodeId, popupInfo);
1961 }
1962 }
1963 }
1964 }
1965
ErasePopup(int32_t targetId)1966 void OverlayManager::ErasePopup(int32_t targetId)
1967 {
1968 TAG_LOGD(AceLogTag::ACE_OVERLAY, "erase popup enter");
1969 auto it = popupMap_.find(targetId);
1970 if (it != popupMap_.end()) {
1971 auto rootNode = rootNodeWeak_.Upgrade();
1972 CHECK_NULL_VOID(rootNode);
1973 auto popupNode = it->second.popupNode;
1974 CHECK_NULL_VOID(popupNode);
1975 auto layoutProp = popupNode->GetLayoutProperty<BubbleLayoutProperty>();
1976 CHECK_NULL_VOID(layoutProp);
1977 auto isShowInSubWindow = layoutProp->GetShowInSubWindow().value_or(false);
1978 auto accessibilityProperty = popupNode->GetAccessibilityProperty<BubbleAccessibilityProperty>();
1979 CHECK_NULL_VOID(accessibilityProperty);
1980 accessibilityProperty->SetShowedState(0);
1981 popupNode->OnAccessibilityEvent(
1982 AccessibilityEventType::PAGE_CLOSE, WindowsContentChangeTypes::CONTENT_CHANGE_TYPE_SUBTREE);
1983 if (isShowInSubWindow) {
1984 auto subwindowMgr = SubwindowManager::GetInstance();
1985 subwindowMgr->DeleteHotAreas(Container::CurrentId(), popupNode->GetId());
1986 }
1987 RemoveChildWithService(rootNode, popupNode);
1988 rootNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
1989 popupMap_.erase(targetId);
1990 }
1991 }
1992
DismissPopup()1993 void OverlayManager::DismissPopup()
1994 {
1995 auto iter = popupMap_.find(dismissPopupId_);
1996 if (iter == popupMap_.end()) {
1997 return;
1998 }
1999 auto popupInfo = iter->second;
2000 popupInfo.markNeedUpdate = true;
2001 HidePopup(dismissPopupId_, popupInfo);
2002 }
2003
ShowMenuHelper(RefPtr<FrameNode> & menu,int32_t targetId,const NG::OffsetF & offset)2004 bool OverlayManager::ShowMenuHelper(RefPtr<FrameNode>& menu, int32_t targetId, const NG::OffsetF& offset)
2005 {
2006 TAG_LOGI(AceLogTag::ACE_OVERLAY, "show menu helper enter");
2007 if (!menu) {
2008 // get existing menuNode
2009 auto it = menuMap_.find(targetId);
2010 if (it != menuMap_.end()) {
2011 menu = it->second;
2012 }
2013 } else {
2014 // creating new menu
2015 menuMap_[targetId] = menu;
2016 }
2017 CHECK_NULL_RETURN(menu, false);
2018
2019 RefPtr<FrameNode> menuFrameNode = menu;
2020 if (menu->GetTag() != V2::MENU_ETS_TAG) {
2021 auto menuChild = menu->GetChildAtIndex(0);
2022 CHECK_NULL_RETURN(menuChild, false);
2023 menuFrameNode = DynamicCast<FrameNode>(menuChild);
2024 }
2025
2026 auto props = menuFrameNode->GetLayoutProperty<MenuLayoutProperty>();
2027 CHECK_NULL_RETURN(props, false);
2028 props->UpdateMenuOffset(offset);
2029 menuFrameNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD);
2030 return true;
2031 }
2032
ShowMenu(int32_t targetId,const NG::OffsetF & offset,RefPtr<FrameNode> menu)2033 void OverlayManager::ShowMenu(int32_t targetId, const NG::OffsetF& offset, RefPtr<FrameNode> menu)
2034 {
2035 TAG_LOGI(AceLogTag::ACE_OVERLAY, "show menu enter");
2036 if (!ShowMenuHelper(menu, targetId, offset)) {
2037 TAG_LOGW(AceLogTag::ACE_OVERLAY, "show menu helper failed");
2038 return;
2039 }
2040 auto rootNode = rootNodeWeak_.Upgrade();
2041 auto container = Container::Current();
2042 if (container && container->IsScenceBoardWindow()) {
2043 auto wrapperPattern = AceType::DynamicCast<MenuWrapperPattern>(menu->GetPattern());
2044 CHECK_NULL_VOID(wrapperPattern);
2045 auto menuChild = wrapperPattern->GetMenu();
2046 CHECK_NULL_VOID(menuChild);
2047 auto menuPattern = AceType::DynamicCast<MenuPattern>(menuChild->GetPattern());
2048 CHECK_NULL_VOID(menuPattern);
2049 rootNode = FindWindowScene(FrameNode::GetFrameNode(menuPattern->GetTargetTag(), menuPattern->GetTargetId()));
2050 }
2051 CHECK_NULL_VOID(rootNode);
2052 auto rootChildren = rootNode->GetChildren();
2053 auto iter = std::find(rootChildren.begin(), rootChildren.end(), menu);
2054 // menuNode already showing
2055 if (iter == rootChildren.end()) {
2056 MountToParentWithService(rootNode, menu);
2057 rootNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
2058 menu->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
2059 ShowMenuAnimation(menu);
2060 menu->MarkModifyDone();
2061 }
2062 }
2063
2064 // subwindow only contains one menu instance.
ShowMenuInSubWindow(int32_t targetId,const NG::OffsetF & offset,RefPtr<FrameNode> menu)2065 void OverlayManager::ShowMenuInSubWindow(int32_t targetId, const NG::OffsetF& offset, RefPtr<FrameNode> menu)
2066 {
2067 TAG_LOGI(AceLogTag::ACE_OVERLAY, "show menu insubwindow enter");
2068 auto menuOffset = offset;
2069 auto currentSubwindow = SubwindowManager::GetInstance()->GetCurrentWindow();
2070 if (currentSubwindow) {
2071 auto subwindowRect = currentSubwindow->GetRect();
2072 menuOffset -= subwindowRect.GetOffset();
2073 }
2074 if (!ShowMenuHelper(menu, targetId, menuOffset)) {
2075 TAG_LOGW(AceLogTag::ACE_OVERLAY, "show menu helper failed");
2076 return;
2077 }
2078 auto rootNode = rootNodeWeak_.Upgrade();
2079 CHECK_NULL_VOID(rootNode);
2080
2081 std::vector<int32_t> idsNeedClean;
2082 for (auto child: rootNode->GetChildren()) {
2083 idsNeedClean.push_back(child->GetId());
2084 }
2085 auto pipeline = rootNode->GetContext();
2086 CHECK_NULL_VOID(pipeline);
2087 pipeline->AddAfterLayoutTask([idsNeedClean, containerId = Container::CurrentId()] {
2088 auto subwindowMgr = SubwindowManager::GetInstance();
2089 for (auto child : idsNeedClean) {
2090 subwindowMgr->DeleteHotAreas(containerId, child);
2091 }
2092 });
2093 rootNode->Clean();
2094
2095 auto menuWrapperPattern = menu->GetPattern<MenuWrapperPattern>();
2096 CHECK_NULL_VOID(menuWrapperPattern);
2097 if (menuWrapperPattern->IsContextMenu() && menuWrapperPattern->GetPreviewMode() != MenuPreviewMode::NONE) {
2098 auto filterNode = menuWrapperPattern->GetFilterColumnNode();
2099 if (filterNode) {
2100 SetHasFilter(true);
2101 SetFilterColumnNode(filterNode);
2102 filterNode->MountToParent(rootNode);
2103 ShowFilterAnimation(filterNode);
2104 filterNode->MarkModifyDone();
2105 }
2106 }
2107 menu->MountToParent(rootNode);
2108 ShowMenuAnimation(menu);
2109 menu->MarkModifyDone();
2110 rootNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
2111 pipeline->FlushUITasks();
2112
2113 // set subwindow container id in menu.
2114 auto menuPattern = menu->GetPattern<PopupBasePattern>();
2115 CHECK_NULL_VOID(menuPattern);
2116 menuPattern->SetContainerId(Container::CurrentId());
2117 }
2118
HideMenuInSubWindow(const RefPtr<FrameNode> & menu,int32_t targetId)2119 void OverlayManager::HideMenuInSubWindow(const RefPtr<FrameNode>& menu, int32_t targetId)
2120 {
2121 TAG_LOGI(AceLogTag::ACE_OVERLAY, "hide menu insubwindow enter");
2122 CHECK_NULL_VOID(menu);
2123 if (menu->GetTag() == V2::MENU_WRAPPER_ETS_TAG) {
2124 auto wrapperPattern = menu->GetPattern<MenuWrapperPattern>();
2125 CHECK_NULL_VOID(wrapperPattern);
2126 wrapperPattern->UpdateMenuAnimation(menu);
2127 }
2128 PopMenuAnimation(menu);
2129 }
2130
HideMenuInSubWindow(bool showPreviewAnimation,bool startDrag)2131 void OverlayManager::HideMenuInSubWindow(bool showPreviewAnimation, bool startDrag)
2132 {
2133 TAG_LOGI(AceLogTag::ACE_OVERLAY, "hide menu insubwindow enter");
2134 if (menuMap_.empty()) {
2135 return;
2136 }
2137 auto rootNode = rootNodeWeak_.Upgrade();
2138 for (const auto& child : rootNode->GetChildren()) {
2139 auto node = DynamicCast<FrameNode>(child);
2140 if (node->GetTag() == V2::MENU_WRAPPER_ETS_TAG) {
2141 PopMenuAnimation(node, showPreviewAnimation, startDrag);
2142 }
2143 }
2144 }
2145
GetMenuNode(int32_t targetId)2146 RefPtr<FrameNode> OverlayManager::GetMenuNode(int32_t targetId)
2147 {
2148 auto it = menuMap_.find(targetId);
2149 if (it != menuMap_.end()) {
2150 return it->second;
2151 }
2152 return nullptr;
2153 }
2154
HideMenu(const RefPtr<FrameNode> & menu,int32_t targetId,bool isMenuOnTouch)2155 void OverlayManager::HideMenu(const RefPtr<FrameNode>& menu, int32_t targetId, bool isMenuOnTouch)
2156 {
2157 TAG_LOGI(AceLogTag::ACE_OVERLAY, "hide menu enter");
2158 PopMenuAnimation(menu);
2159 RemoveEventColumn();
2160 if (isMenuOnTouch) {
2161 RemovePixelMap();
2162 RemoveGatherNode();
2163 } else {
2164 RemovePixelMapAnimation(false, 0, 0);
2165 RemoveGatherNodeWithAnimation();
2166 }
2167 RemoveFilterAnimation();
2168 }
2169
HideAllMenus()2170 void OverlayManager::HideAllMenus()
2171 {
2172 TAG_LOGD(AceLogTag::ACE_OVERLAY, "hide all menus enter");
2173 auto container = Container::Current();
2174 if (container && container->IsScenceBoardWindow()) {
2175 for (const auto& windowScene : windowSceneSet_) {
2176 if (!windowScene.Upgrade()) {
2177 continue;
2178 }
2179 for (const auto& child : windowScene.Upgrade()->GetChildren()) {
2180 auto node = DynamicCast<FrameNode>(child);
2181 if (node && node->GetTag() == V2::MENU_WRAPPER_ETS_TAG) {
2182 PopMenuAnimation(node);
2183 }
2184 }
2185 }
2186 return;
2187 }
2188
2189 auto rootNode = rootNodeWeak_.Upgrade();
2190 CHECK_NULL_VOID(rootNode);
2191 for (const auto& child : rootNode->GetChildren()) {
2192 auto node = DynamicCast<FrameNode>(child);
2193 if (node && node->GetTag() == V2::MENU_WRAPPER_ETS_TAG) {
2194 auto wrapperPattern = node->GetPattern<MenuWrapperPattern>();
2195 CHECK_NULL_VOID(wrapperPattern);
2196 wrapperPattern->UpdateMenuAnimation(node);
2197 PopMenuAnimation(node);
2198 }
2199 }
2200 }
2201
DeleteMenu(int32_t targetId)2202 void OverlayManager::DeleteMenu(int32_t targetId)
2203 {
2204 TAG_LOGI(AceLogTag::ACE_OVERLAY, "delete menu enter");
2205 auto it = menuMap_.find(targetId);
2206 if (it == menuMap_.end()) {
2207 return;
2208 }
2209 auto node = AceType::DynamicCast<FrameNode>(it->second);
2210 if (node->GetParent()) {
2211 auto id = Container::CurrentId();
2212 SubwindowManager::GetInstance()->ClearMenu();
2213 SubwindowManager::GetInstance()->ClearMenuNG(id, targetId);
2214
2215 if (node->GetParent()) {
2216 RemoveEventColumn();
2217 RemoveMenuNotInSubWindow(WeakClaim(RawPtr(node)), rootNodeWeak_, WeakClaim(this));
2218 }
2219 }
2220 EraseMenuInfo(targetId);
2221 }
2222
CleanMenuInSubWindowWithAnimation()2223 void OverlayManager::CleanMenuInSubWindowWithAnimation()
2224 {
2225 TAG_LOGD(AceLogTag::ACE_OVERLAY, "clean menu insubwindow with animation enter");
2226 auto rootNode = rootNodeWeak_.Upgrade();
2227 CHECK_NULL_VOID(rootNode);
2228 RefPtr<FrameNode> menu;
2229 for (const auto& child : rootNode->GetChildren()) {
2230 auto node = DynamicCast<FrameNode>(child);
2231 if (node && node->GetTag() == V2::MENU_WRAPPER_ETS_TAG) {
2232 menu = node;
2233 break;
2234 }
2235 }
2236 CHECK_NULL_VOID(menu);
2237 PopMenuAnimation(menu);
2238 }
2239
CleanHoverImagePreviewInSubWindow(const RefPtr<FrameNode> & flexNode)2240 void OverlayManager::CleanHoverImagePreviewInSubWindow(const RefPtr<FrameNode>& flexNode)
2241 {
2242 CHECK_NULL_VOID(flexNode && flexNode->GetTag() == V2::FLEX_ETS_TAG);
2243 for (const auto& child : flexNode->GetChildren()) {
2244 auto node = DynamicCast<FrameNode>(child);
2245 CHECK_NULL_VOID(node && node->GetTag() == V2::STACK_ETS_TAG);
2246
2247 auto previewNode = node->GetLastChild();
2248 if (previewNode && previewNode->GetTag() == V2::MENU_PREVIEW_ETS_TAG) {
2249 node->RemoveChild(previewNode);
2250 }
2251
2252 auto imageNode = node->GetFirstChild();
2253 if (imageNode && imageNode->GetTag() == V2::IMAGE_ETS_TAG) {
2254 node->RemoveChild(imageNode);
2255 }
2256
2257 flexNode->RemoveChild(node);
2258 flexNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
2259 break;
2260 }
2261 }
2262
CleanPreviewInSubWindow()2263 void OverlayManager::CleanPreviewInSubWindow()
2264 {
2265 auto rootNode = rootNodeWeak_.Upgrade();
2266 CHECK_NULL_VOID(rootNode);
2267 for (const auto& child : rootNode->GetChildren()) {
2268 auto node = DynamicCast<FrameNode>(child);
2269 if (node && node->GetTag() == V2::MENU_WRAPPER_ETS_TAG) {
2270 for (auto& childNode : node->GetChildren()) {
2271 auto frameNode = DynamicCast<FrameNode>(childNode);
2272 if (frameNode && (frameNode->GetTag() == V2::FLEX_ETS_TAG ||
2273 frameNode->GetTag() == V2::MENU_PREVIEW_ETS_TAG || frameNode->GetTag() == V2::IMAGE_ETS_TAG)) {
2274 CleanHoverImagePreviewInSubWindow(frameNode);
2275 auto imagelayoutProperty = frameNode->GetLayoutProperty();
2276 if (imagelayoutProperty) {
2277 imagelayoutProperty->UpdateVisibility(VisibleType::GONE);
2278 } else {
2279 TAG_LOGW(AceLogTag::ACE_OVERLAY, "Preview image failed to set invisible.");
2280 }
2281 break;
2282 }
2283 }
2284 break;
2285 }
2286 }
2287 }
2288
CleanMenuInSubWindow(int32_t targetId)2289 void OverlayManager::CleanMenuInSubWindow(int32_t targetId)
2290 {
2291 TAG_LOGI(AceLogTag::ACE_OVERLAY, "clean menu insubwindow enter");
2292 auto rootNode = rootNodeWeak_.Upgrade();
2293 CHECK_NULL_VOID(rootNode);
2294
2295 for (const auto& child : rootNode->GetChildren()) {
2296 auto node = DynamicCast<FrameNode>(child);
2297 if (node && node->GetTag() != V2::MENU_WRAPPER_ETS_TAG) {
2298 continue;
2299 }
2300
2301 auto menuWrapperPattern = node->GetPattern<MenuWrapperPattern>();
2302 CHECK_NULL_VOID(menuWrapperPattern);
2303 if (menuWrapperPattern->GetTargetId() != targetId) {
2304 continue;
2305 }
2306
2307 for (auto& childNode : node->GetChildren()) {
2308 auto frameNode = DynamicCast<FrameNode>(childNode);
2309 if (frameNode && (frameNode->GetTag() == V2::FLEX_ETS_TAG ||
2310 frameNode->GetTag() == V2::MENU_PREVIEW_ETS_TAG || frameNode->GetTag() == V2::IMAGE_ETS_TAG)) {
2311 CleanHoverImagePreviewInSubWindow(frameNode);
2312 node->RemoveChild(frameNode);
2313 break;
2314 }
2315 }
2316 rootNode->RemoveChild(node);
2317 rootNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
2318 auto subwindowMgr = SubwindowManager::GetInstance();
2319 subwindowMgr->DeleteHotAreas(Container::CurrentId(), node->GetId());
2320 menuWrapperPattern->SetMenuStatus(MenuStatus::HIDE);
2321 break;
2322 }
2323 }
2324
CleanPopupInSubWindow()2325 void OverlayManager::CleanPopupInSubWindow()
2326 {
2327 TAG_LOGD(AceLogTag::ACE_OVERLAY, "clean popup insubwindow enter");
2328 auto rootNode = rootNodeWeak_.Upgrade();
2329 CHECK_NULL_VOID(rootNode);
2330 std::vector<RefPtr<FrameNode>> removeNodes;
2331 for (const auto& child : rootNode->GetChildren()) {
2332 if (!child || child->GetTag() != V2::POPUP_ETS_TAG) {
2333 continue;
2334 }
2335 auto id = child->GetId();
2336 for (const auto& popup : popupMap_) {
2337 auto popupInfo = popup.second;
2338 auto target = popup.first;
2339 if (id != popupInfo.popupId) {
2340 continue;
2341 }
2342 popupInfo.markNeedUpdate = true;
2343 auto removeNode = HidePopupWithoutAnimation(target, popupInfo);
2344 if (removeNode) {
2345 removeNodes.emplace_back(removeNode);
2346 auto subwindowMgr = SubwindowManager::GetInstance();
2347 subwindowMgr->DeleteHotAreas(Container::CurrentId(), removeNode->GetId());
2348 ErasePopupInfo(target);
2349 }
2350 break;
2351 }
2352 }
2353 for (const auto& removeNode : removeNodes) {
2354 rootNode->RemoveChild(removeNode);
2355 }
2356 rootNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
2357 }
2358
BeforeShowDialog(const RefPtr<FrameNode> & node)2359 void OverlayManager::BeforeShowDialog(const RefPtr<FrameNode>& node)
2360 {
2361 TAG_LOGD(AceLogTag::ACE_OVERLAY, "before show dialog");
2362 CHECK_NULL_VOID(node);
2363 if (dialogMap_.find(node->GetId()) != dialogMap_.end()) {
2364 return;
2365 }
2366 dialogMap_[node->GetId()] = node;
2367 }
2368
SetDialogMask(const DialogProperties & dialogProps)2369 RefPtr<FrameNode> OverlayManager::SetDialogMask(const DialogProperties& dialogProps)
2370 {
2371 DialogProperties Maskarg;
2372 Maskarg.isMask = true;
2373 Maskarg.autoCancel = dialogProps.autoCancel;
2374 Maskarg.onWillDismiss = dialogProps.onWillDismiss;
2375 Maskarg.maskColor = dialogProps.maskColor;
2376 return ShowDialog(Maskarg, nullptr, false);
2377 }
2378
ShowDialog(const DialogProperties & dialogProps,std::function<void ()> && buildFunc,bool isRightToLeft)2379 RefPtr<FrameNode> OverlayManager::ShowDialog(
2380 const DialogProperties& dialogProps, std::function<void()>&& buildFunc, bool isRightToLeft)
2381 {
2382 TAG_LOGD(AceLogTag::ACE_OVERLAY, "show dialog enter");
2383 RefPtr<UINode> customNode;
2384 // create custom builder content
2385 if (buildFunc) {
2386 NG::ScopedViewStackProcessor builderViewStackProcessor;
2387 buildFunc();
2388 customNode = NG::ViewStackProcessor::GetInstance()->Finish();
2389 CHECK_NULL_RETURN(customNode, nullptr);
2390 }
2391
2392 auto dialog = DialogView::CreateDialogNode(dialogProps, customNode);
2393 CHECK_NULL_RETURN(dialog, nullptr);
2394 BeforeShowDialog(dialog);
2395 if (dialogProps.transitionEffect != nullptr) {
2396 SetDialogTransitionEffect(dialog);
2397 } else {
2398 OpenDialogAnimation(dialog);
2399 }
2400 dialogCount_++;
2401 // set close button disable
2402 SetContainerButtonEnable(false);
2403 if (Recorder::EventRecorder::Get().IsComponentRecordEnable()) {
2404 Recorder::EventParamsBuilder builder;
2405 builder
2406 .SetType("Dialog")
2407 .SetEventType(Recorder::EventType::DIALOG_SHOW)
2408 .SetExtra(Recorder::KEY_TITLE, dialogProps.title)
2409 .SetExtra(Recorder::KEY_SUB_TITLE, dialogProps.subtitle);
2410 Recorder::EventRecorder::Get().OnEvent(std::move(builder));
2411 }
2412 return dialog;
2413 }
2414
ShowDialogWithNode(const DialogProperties & dialogProps,const RefPtr<UINode> & customNode,bool isRightToLeft)2415 RefPtr<FrameNode> OverlayManager::ShowDialogWithNode(
2416 const DialogProperties& dialogProps, const RefPtr<UINode>& customNode, bool isRightToLeft)
2417 {
2418 TAG_LOGD(AceLogTag::ACE_OVERLAY, "show dialog enter");
2419 CHECK_NULL_RETURN(customNode, nullptr);
2420 auto dialog = DialogView::CreateDialogNode(dialogProps, customNode);
2421 CHECK_NULL_RETURN(dialog, nullptr);
2422 BeforeShowDialog(dialog);
2423 if (dialogProps.transitionEffect != nullptr) {
2424 SetDialogTransitionEffect(dialog);
2425 } else {
2426 OpenDialogAnimation(dialog);
2427 }
2428 dialogCount_++;
2429 // set close button disable
2430 SetContainerButtonEnable(false);
2431 if (Recorder::EventRecorder::Get().IsComponentRecordEnable()) {
2432 Recorder::EventParamsBuilder builder;
2433 builder
2434 .SetType("Dialog")
2435 .SetEventType(Recorder::EventType::DIALOG_SHOW)
2436 .SetExtra(Recorder::KEY_TITLE, dialogProps.title)
2437 .SetExtra(Recorder::KEY_SUB_TITLE, dialogProps.subtitle);
2438 Recorder::EventRecorder::Get().OnEvent(std::move(builder));
2439 }
2440 return dialog;
2441 }
2442
GetDialogNodeWithExistContent(const RefPtr<UINode> & node)2443 RefPtr<FrameNode> OverlayManager::GetDialogNodeWithExistContent(const RefPtr<UINode>& node)
2444 {
2445 auto iter = dialogMap_.begin();
2446 while (iter != dialogMap_.end()) {
2447 auto dialogNode = (*iter).second;
2448 CHECK_NULL_RETURN(dialogNode, nullptr);
2449 auto dialogPattern = dialogNode->GetPattern<DialogPattern>();
2450 CHECK_NULL_RETURN(dialogPattern, nullptr);
2451 if (dialogPattern->GetCustomNode() == node) {
2452 return dialogNode;
2453 }
2454 iter++;
2455 }
2456 return nullptr;
2457 }
2458
RegisterDialogLifeCycleCallback(const RefPtr<FrameNode> & dialog,const DialogProperties & dialogProps)2459 void OverlayManager::RegisterDialogLifeCycleCallback(
2460 const RefPtr<FrameNode>& dialog, const DialogProperties& dialogProps)
2461 {
2462 auto dialogPattern = dialog->GetPattern<DialogPattern>();
2463 CHECK_NULL_VOID(dialogPattern);
2464 auto onDidAppearEvent = dialogProps.onDidAppear;
2465 dialogPattern->RegisterDialogDidAppearCallback(std::move(onDidAppearEvent));
2466 auto onDidDisappearEvent = dialogProps.onDidDisappear;
2467 dialogPattern->RegisterDialogDidDisappearCallback(std::move(onDidDisappearEvent));
2468 auto onWillAppearEvent = dialogProps.onWillAppear;
2469 dialogPattern->RegisterDialogWillAppearCallback(std::move(onWillAppearEvent));
2470 auto onWillDisappearEvent = dialogProps.onWillDisappear;
2471 dialogPattern->RegisterDialogWillDisappearCallback(std::move(onWillDisappearEvent));
2472 }
2473
CustomDialogRecordEvent(const DialogProperties & dialogProps)2474 void OverlayManager::CustomDialogRecordEvent(const DialogProperties& dialogProps)
2475 {
2476 if (Recorder::EventRecorder::Get().IsComponentRecordEnable()) {
2477 Recorder::EventParamsBuilder builder;
2478 builder
2479 .SetType("Dialog")
2480 .SetEventType(Recorder::EventType::DIALOG_SHOW)
2481 .SetExtra(Recorder::KEY_TITLE, dialogProps.title)
2482 .SetExtra(Recorder::KEY_SUB_TITLE, dialogProps.subtitle);
2483 Recorder::EventRecorder::Get().OnEvent(std::move(builder));
2484 }
2485 }
2486
RebuildCustomBuilder(RefPtr<UINode> & contentNode)2487 RefPtr<UINode> OverlayManager::RebuildCustomBuilder(RefPtr<UINode>& contentNode)
2488 {
2489 auto currentId = Container::CurrentId();
2490 if (!(currentId >= MIN_SUBCONTAINER_ID && currentId < MIN_PLUGIN_SUBCONTAINER_ID)) {
2491 return contentNode;
2492 }
2493
2494 RefPtr<UINode> customNode;
2495 auto lazyBuilderFunc = contentNode->GetBuilderFunc();
2496 if (lazyBuilderFunc) {
2497 NG::ScopedViewStackProcessor builderViewStackProcessor;
2498 lazyBuilderFunc();
2499 customNode = NG::ViewStackProcessor::GetInstance()->Finish();
2500 } else {
2501 customNode = contentNode;
2502 }
2503
2504 auto updateNodeFunc = contentNode->GetUpdateNodeFunc();
2505 if (updateNodeFunc) {
2506 updateNodeFunc(currentId, customNode);
2507 }
2508 auto updateNodeConfig = contentNode->GetUpdateNodeConfig();
2509 if (updateNodeConfig) {
2510 customNode->SetUpdateNodeConfig(std::move(updateNodeConfig));
2511 }
2512 return customNode;
2513 }
2514
ReloadBuilderNodeConfig()2515 void OverlayManager::ReloadBuilderNodeConfig()
2516 {
2517 if (dialogMap_.empty()) {
2518 return;
2519 }
2520 auto iter = dialogMap_.begin();
2521 while (iter != dialogMap_.end()) {
2522 auto dialogNode = (*iter).second;
2523 if (dialogNode) {
2524 auto dialogPattern = dialogNode->GetPattern<DialogPattern>();
2525 CHECK_NULL_VOID(dialogPattern);
2526 auto customNode = dialogPattern->GetCustomNode();
2527 if (customNode && customNode->GetUpdateNodeConfig()) {
2528 customNode->GetUpdateNodeConfig()();
2529 }
2530 }
2531 iter++;
2532 }
2533 }
2534
OpenCustomDialog(const DialogProperties & dialogProps,std::function<void (int32_t)> && callback)2535 void OverlayManager::OpenCustomDialog(const DialogProperties& dialogProps, std::function<void(int32_t)> &&callback)
2536 {
2537 RefPtr<UINode> customNode;
2538 bool showComponentContent = false;
2539 if (!callback) {
2540 TAG_LOGE(AceLogTag::ACE_DIALOG, "Parameters of OpenCustomDialog are incomplete because of no callback.");
2541 return;
2542 }
2543 if (dialogProps.customBuilder) {
2544 TAG_LOGD(AceLogTag::ACE_DIALOG, "open custom dialog with custom builder.");
2545 NG::ScopedViewStackProcessor builderViewStackProcessor(Container::CurrentId());
2546 dialogProps.customBuilder();
2547 customNode = NG::ViewStackProcessor::GetInstance()->Finish();
2548 if (!customNode) {
2549 TAG_LOGE(AceLogTag::ACE_DIALOG, "Fail to build custom node.");
2550 callback(-1);
2551 return;
2552 }
2553 } else {
2554 auto contentNode = dialogProps.contentNode.Upgrade();
2555 if (!contentNode) {
2556 TAG_LOGE(AceLogTag::ACE_DIALOG, "Content of custom dialog is null");
2557 callback(ERROR_CODE_DIALOG_CONTENT_ERROR);
2558 return;
2559 }
2560 if (GetDialogNodeWithExistContent(contentNode)) {
2561 TAG_LOGW(AceLogTag::ACE_DIALOG, "Content of custom dialog already existed.");
2562 callback(ERROR_CODE_DIALOG_CONTENT_ALREADY_EXIST);
2563 return;
2564 }
2565 TAG_LOGD(AceLogTag::ACE_DIALOG, "OpenCustomDialog ComponentContent id: %{public}d", contentNode->GetId());
2566 customNode = RebuildCustomBuilder(contentNode);
2567 showComponentContent = true;
2568 }
2569 auto dialog = DialogView::CreateDialogNode(dialogProps, customNode);
2570 if (!dialog) {
2571 TAG_LOGE(AceLogTag::ACE_DIALOG, "Fail to create dialog node.");
2572 callback(showComponentContent ? ERROR_CODE_DIALOG_CONTENT_ERROR : -1);
2573 return;
2574 }
2575 RegisterDialogLifeCycleCallback(dialog, dialogProps);
2576 BeforeShowDialog(dialog);
2577
2578 callback(showComponentContent ? ERROR_CODE_NO_ERROR : dialog->GetId());
2579
2580 if (dialogProps.transitionEffect != nullptr) {
2581 SetDialogTransitionEffect(dialog);
2582 } else {
2583 OpenDialogAnimation(dialog);
2584 }
2585
2586 dialogCount_++;
2587 CustomDialogRecordEvent(dialogProps);
2588 return;
2589 }
2590
CloseCustomDialog(const int32_t dialogId)2591 void OverlayManager::CloseCustomDialog(const int32_t dialogId)
2592 {
2593 auto iter = dialogMap_.end();
2594 if (dialogId == -1) {
2595 int32_t tmpNodeId = -1;
2596 RefPtr<FrameNode> tmpNode;
2597 iter = dialogMap_.begin();
2598 while (iter != dialogMap_.end()) {
2599 auto dialogNode = (*iter).second;
2600 if (dialogNode && dialogNode->GetId() > tmpNodeId) {
2601 tmpNodeId = dialogNode->GetId();
2602 tmpNode = dialogNode;
2603 }
2604 iter++;
2605 }
2606 if (tmpNode) {
2607 DeleteDialogHotAreas(tmpNode);
2608 CloseDialogInner(tmpNode);
2609 } else {
2610 TAG_LOGE(AceLogTag::ACE_DIALOG, "not find dialog when no dialog id");
2611 }
2612 } else {
2613 iter = dialogMap_.find(dialogId);
2614 if (iter == dialogMap_.end()) {
2615 TAG_LOGE(AceLogTag::ACE_DIALOG, "not find dialog by id %{public}d", dialogId);
2616 return;
2617 }
2618 RefPtr<FrameNode> tmpDialog = (*iter).second;
2619 DeleteDialogHotAreas(tmpDialog);
2620 CloseDialogInner(tmpDialog);
2621 }
2622 return;
2623 }
2624
CloseCustomDialog(const WeakPtr<NG::UINode> & node,std::function<void (int32_t)> && callback)2625 void OverlayManager::CloseCustomDialog(const WeakPtr<NG::UINode>& node, std::function<void(int32_t)> &&callback)
2626 {
2627 if (!callback) {
2628 TAG_LOGE(AceLogTag::ACE_DIALOG, "Parameters of CloseCustomDialog are incomplete because of no callback.");
2629 return;
2630 }
2631 auto contentNode = node.Upgrade();
2632 if (!contentNode) {
2633 TAG_LOGE(AceLogTag::ACE_DIALOG, "Content of custom dialog is null");
2634 callback(ERROR_CODE_DIALOG_CONTENT_ERROR);
2635 return;
2636 }
2637 TAG_LOGD(AceLogTag::ACE_DIALOG, "CloseCustomDialog ComponentContent id: %{public}d", contentNode->GetId());
2638 auto dialogNode = GetDialogNodeWithExistContent(contentNode);
2639 if (!dialogNode) {
2640 dialogNode = SubwindowManager::GetInstance()->GetSubwindowDialogNodeWithExistContent(contentNode);
2641 }
2642 if (dialogNode) {
2643 DeleteDialogHotAreas(dialogNode);
2644 CloseDialogInner(dialogNode);
2645 callback(ERROR_CODE_NO_ERROR);
2646 return;
2647 }
2648 TAG_LOGE(AceLogTag::ACE_DIALOG, "UpdateCustomDialog failed because cannot find dialog.");
2649 callback(ERROR_CODE_DIALOG_CONTENT_NOT_FOUND);
2650 }
2651
UpdateCustomDialog(const WeakPtr<NG::UINode> & node,const DialogProperties & dialogProps,std::function<void (int32_t)> && callback)2652 void OverlayManager::UpdateCustomDialog(
2653 const WeakPtr<NG::UINode>& node, const DialogProperties& dialogProps, std::function<void(int32_t)> &&callback)
2654 {
2655 if (!callback) {
2656 TAG_LOGE(AceLogTag::ACE_DIALOG, "Parameters of UpdateCustomDialog are incomplete because of no callback.");
2657 return;
2658 }
2659 auto contentNode = node.Upgrade();
2660 if (!contentNode) {
2661 TAG_LOGE(AceLogTag::ACE_DIALOG, "Content of custom dialog is null");
2662 callback(ERROR_CODE_DIALOG_CONTENT_ERROR);
2663 return;
2664 }
2665 TAG_LOGD(AceLogTag::ACE_DIALOG, "UpdateCustomDialog ComponentContent id: %{public}d", contentNode->GetId());
2666 auto dialogNode = GetDialogNodeWithExistContent(contentNode);
2667 if (!dialogNode) {
2668 dialogNode = SubwindowManager::GetInstance()->GetSubwindowDialogNodeWithExistContent(contentNode);
2669 }
2670 if (dialogNode) {
2671 auto dialogLayoutProp = AceType::DynamicCast<DialogLayoutProperty>(dialogNode->GetLayoutProperty());
2672 CHECK_NULL_VOID(dialogLayoutProp);
2673 dialogLayoutProp->UpdateDialogAlignment(dialogProps.alignment);
2674 dialogLayoutProp->UpdateDialogOffset(dialogProps.offset);
2675 dialogLayoutProp->UpdateAutoCancel(dialogProps.autoCancel);
2676 auto dialogContext = dialogNode->GetRenderContext();
2677 CHECK_NULL_VOID(dialogContext);
2678 auto pipelineContext = dialogNode->GetContext();
2679 CHECK_NULL_VOID(pipelineContext);
2680 auto dialogTheme = pipelineContext->GetTheme<DialogTheme>();
2681 CHECK_NULL_VOID(dialogTheme);
2682 dialogContext->UpdateBackgroundColor(dialogProps.maskColor.value_or(dialogTheme->GetMaskColorEnd()));
2683 dialogNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
2684
2685 callback(ERROR_CODE_NO_ERROR);
2686 return;
2687 }
2688 TAG_LOGE(AceLogTag::ACE_DIALOG, "CloseCustomDialog failed because cannot find dialog.");
2689 callback(ERROR_CODE_DIALOG_CONTENT_NOT_FOUND);
2690 }
2691
ShowCustomDialog(const RefPtr<FrameNode> & customNode)2692 void OverlayManager::ShowCustomDialog(const RefPtr<FrameNode>& customNode)
2693 {
2694 TAG_LOGD(AceLogTag::ACE_OVERLAY, "show custom dialog enter");
2695 BeforeShowDialog(customNode);
2696 OpenDialogAnimation(customNode);
2697 }
2698
RegisterDialogCallback(const RefPtr<FrameNode> & node,std::map<std::string,NG::DialogCancelEvent> dialogLifeCycleEvent)2699 void RegisterDialogCallback(
2700 const RefPtr<FrameNode>& node, std::map<std::string, NG::DialogCancelEvent> dialogLifeCycleEvent)
2701 {
2702 CHECK_NULL_VOID(node);
2703 auto pipeline = PipelineContext::GetCurrentContext();
2704 CHECK_NULL_VOID(pipeline);
2705 auto theme = pipeline->GetTheme<DialogTheme>();
2706 CHECK_NULL_VOID(theme);
2707 auto dialogPattern = node->GetPattern<DialogPattern>();
2708 if (!dialogLifeCycleEvent.empty()) {
2709 auto didAppearEvent = dialogLifeCycleEvent["didAppearId"];
2710 auto didDisappearEvent = dialogLifeCycleEvent["didDisappearId"];
2711 auto willAppearEvent = dialogLifeCycleEvent["willAppearId"];
2712 auto willDisappearEvent = dialogLifeCycleEvent["willDisappearId"];
2713 dialogPattern->RegisterDialogDidAppearCallback(std::move(didAppearEvent));
2714 dialogPattern->RegisterDialogDidDisappearCallback(std::move(didDisappearEvent));
2715 dialogPattern->RegisterDialogWillAppearCallback(std::move(willAppearEvent));
2716 dialogPattern->RegisterDialogWillDisappearCallback(std::move(willDisappearEvent));
2717 }
2718 }
2719
ShowDateDialog(const DialogProperties & dialogProps,const DatePickerSettingData & settingData,std::map<std::string,NG::DialogEvent> dialogEvent,std::map<std::string,NG::DialogGestureEvent> dialogCancelEvent,std::map<std::string,NG::DialogCancelEvent> dialogLifeCycleEvent,const std::vector<ButtonInfo> & buttonInfos)2720 void OverlayManager::ShowDateDialog(const DialogProperties& dialogProps, const DatePickerSettingData& settingData,
2721 std::map<std::string, NG::DialogEvent> dialogEvent, std::map<std::string, NG::DialogGestureEvent> dialogCancelEvent,
2722 std::map<std::string, NG::DialogCancelEvent> dialogLifeCycleEvent, const std::vector<ButtonInfo>& buttonInfos)
2723 {
2724 TAG_LOGD(AceLogTag::ACE_OVERLAY, "show date dialog enter");
2725 auto dialogNode = DatePickerDialogView::Show(
2726 dialogProps, std::move(settingData), buttonInfos, std::move(dialogEvent), std::move(dialogCancelEvent));
2727 RegisterDialogCallback(dialogNode, std::move(dialogLifeCycleEvent));
2728 BeforeShowDialog(dialogNode);
2729 OpenDialogAnimation(dialogNode);
2730 }
2731
ShowTimeDialog(const DialogProperties & dialogProps,const TimePickerSettingData & settingData,std::map<std::string,PickerTime> timePickerProperty,std::map<std::string,NG::DialogEvent> dialogEvent,std::map<std::string,NG::DialogGestureEvent> dialogCancelEvent,std::map<std::string,NG::DialogCancelEvent> dialogLifeCycleEvent,const std::vector<ButtonInfo> & buttonInfos)2732 void OverlayManager::ShowTimeDialog(const DialogProperties& dialogProps, const TimePickerSettingData& settingData,
2733 std::map<std::string, PickerTime> timePickerProperty, std::map<std::string, NG::DialogEvent> dialogEvent,
2734 std::map<std::string, NG::DialogGestureEvent> dialogCancelEvent,
2735 std::map<std::string, NG::DialogCancelEvent> dialogLifeCycleEvent, const std::vector<ButtonInfo>& buttonInfos)
2736 {
2737 TAG_LOGD(AceLogTag::ACE_OVERLAY, "show time dialog enter");
2738 auto dialogNode = TimePickerDialogView::Show(dialogProps, settingData, buttonInfos, std::move(timePickerProperty),
2739 std::move(dialogEvent), std::move(dialogCancelEvent));
2740 RegisterDialogCallback(dialogNode, std::move(dialogLifeCycleEvent));
2741 BeforeShowDialog(dialogNode);
2742 OpenDialogAnimation(dialogNode);
2743 }
2744
ShowTextDialog(const DialogProperties & dialogProps,const TextPickerSettingData & settingData,std::map<std::string,NG::DialogTextEvent> dialogEvent,std::map<std::string,NG::DialogGestureEvent> dialogCancelEvent,std::map<std::string,NG::DialogCancelEvent> dialogLifeCycleEvent,const std::vector<ButtonInfo> & buttonInfos)2745 void OverlayManager::ShowTextDialog(const DialogProperties& dialogProps, const TextPickerSettingData& settingData,
2746 std::map<std::string, NG::DialogTextEvent> dialogEvent,
2747 std::map<std::string, NG::DialogGestureEvent> dialogCancelEvent,
2748 std::map<std::string, NG::DialogCancelEvent> dialogLifeCycleEvent, const std::vector<ButtonInfo>& buttonInfos)
2749 {
2750 TAG_LOGD(AceLogTag::ACE_OVERLAY, "show text dialog enter");
2751 auto dialogNode = TextPickerDialogView::Show(
2752 dialogProps, settingData, buttonInfos, std::move(dialogEvent), std::move(dialogCancelEvent));
2753 RegisterDialogCallback(dialogNode, std::move(dialogLifeCycleEvent));
2754 BeforeShowDialog(dialogNode);
2755 OpenDialogAnimation(dialogNode);
2756 if (Recorder::EventRecorder::Get().IsComponentRecordEnable()) {
2757 Recorder::EventParamsBuilder builder;
2758 builder.SetType("TextPickerDialog").SetEventType(Recorder::EventType::DIALOG_SHOW);
2759 Recorder::EventRecorder::Get().OnEvent(std::move(builder));
2760 }
2761 }
2762
ShowCalendarDialog(const DialogProperties & dialogProps,const CalendarSettingData & settingData,std::map<std::string,NG::DialogEvent> dialogEvent,std::map<std::string,NG::DialogGestureEvent> dialogCancelEvent,std::map<std::string,NG::DialogCancelEvent> dialogLifeCycleEvent,const std::vector<ButtonInfo> & buttonInfos)2763 void OverlayManager::ShowCalendarDialog(const DialogProperties& dialogProps, const CalendarSettingData& settingData,
2764 std::map<std::string, NG::DialogEvent> dialogEvent, std::map<std::string, NG::DialogGestureEvent> dialogCancelEvent,
2765 std::map<std::string, NG::DialogCancelEvent> dialogLifeCycleEvent, const std::vector<ButtonInfo>& buttonInfos)
2766 {
2767 TAG_LOGD(AceLogTag::ACE_OVERLAY, "show calendar dialog enter");
2768 auto dialogNode = CalendarDialogView::Show(dialogProps, settingData,
2769 buttonInfos, std::move(dialogEvent), std::move(dialogCancelEvent));
2770 RegisterDialogCallback(dialogNode, std::move(dialogLifeCycleEvent));
2771 BeforeShowDialog(dialogNode);
2772 OpenDialogAnimation(dialogNode);
2773 }
2774
PopModalDialog(int32_t maskId)2775 void OverlayManager::PopModalDialog(int32_t maskId)
2776 {
2777 TAG_LOGD(AceLogTag::ACE_OVERLAY, "pop modal dialog enter");
2778 int32_t dialogId = -1;
2779 for (auto it = maskNodeIdMap_.begin(); it != maskNodeIdMap_.end(); it++) {
2780 if (maskId == it->second) {
2781 dialogId = it->first;
2782 break;
2783 }
2784 }
2785 auto subWindow = SubwindowManager::GetInstance()->GetSubwindow(subWindowId_);
2786 CHECK_NULL_VOID(subWindow);
2787 auto subOverlayManager = subWindow->GetOverlayManager();
2788 CHECK_NULL_VOID(subOverlayManager);
2789 std::map<int32_t, RefPtr<FrameNode>> DialogMap(
2790 subOverlayManager->GetDialogMap().begin(), subOverlayManager->GetDialogMap().end());
2791 for (auto it = DialogMap.begin(); it != DialogMap.end(); it++) {
2792 auto dialogProp = DynamicCast<DialogLayoutProperty>(it->second->GetLayoutProperty());
2793 if (dialogId == it->first) {
2794 auto hub = it->second->GetEventHub<DialogEventHub>();
2795 if (hub) {
2796 hub->FireCancelEvent();
2797 }
2798 subOverlayManager->CloseDialog(it->second);
2799 }
2800 }
2801 }
2802
RemoveDialogFromMap(const RefPtr<FrameNode> & node)2803 void OverlayManager::RemoveDialogFromMap(const RefPtr<FrameNode>& node)
2804 {
2805 TAG_LOGD(AceLogTag::ACE_OVERLAY, "remove dialog from map enter");
2806 CHECK_NULL_VOID(node);
2807 if (dialogMap_.find(node->GetId()) == dialogMap_.end()) {
2808 return;
2809 }
2810 dialogMap_.erase(node->GetId());
2811 }
2812
RemoveMaskFromMap(const RefPtr<FrameNode> & dialogNode)2813 void OverlayManager::RemoveMaskFromMap(const RefPtr<FrameNode>& dialogNode)
2814 {
2815 TAG_LOGD(AceLogTag::ACE_OVERLAY, "remove mask from map enter");
2816 CHECK_NULL_VOID(dialogNode);
2817 if (maskNodeIdMap_.find(dialogNode->GetId()) == maskNodeIdMap_.end()) {
2818 return;
2819 }
2820 maskNodeIdMap_.erase(dialogNode->GetId());
2821 }
2822
DialogInMapHoldingFocus()2823 bool OverlayManager::DialogInMapHoldingFocus()
2824 {
2825 TAG_LOGD(AceLogTag::ACE_OVERLAY, "dialog in map holding focus enter");
2826 if (dialogMap_.empty()) {
2827 return false;
2828 }
2829 auto iter = dialogMap_.begin();
2830 while (iter != dialogMap_.end()) {
2831 auto dialogNode = (*iter).second;
2832 if (dialogNode && dialogNode->GetFocusHub() && dialogNode->GetFocusHub()->IsCurrentFocus()) {
2833 return true;
2834 }
2835 iter++;
2836 }
2837 return false;
2838 }
2839
HasModalPage()2840 bool OverlayManager::HasModalPage()
2841 {
2842 if (modalList_.empty()) {
2843 return false;
2844 }
2845 for (auto modal : modalList_) {
2846 if (modal.Upgrade() && modal.Upgrade()->GetTag() == V2::MODAL_PAGE_TAG) {
2847 return true;
2848 }
2849 }
2850 return false;
2851 }
2852
GetDialog(int32_t dialogId)2853 RefPtr<FrameNode> OverlayManager::GetDialog(int32_t dialogId)
2854 {
2855 TAG_LOGD(AceLogTag::ACE_OVERLAY, "get dialog enter");
2856 for (auto it = dialogMap_.begin(); it != dialogMap_.end(); it++) {
2857 if (dialogId == it->second->GetId()) {
2858 return it->second;
2859 }
2860 }
2861 return nullptr;
2862 }
2863
CloseDialog(const RefPtr<FrameNode> & dialogNode)2864 void OverlayManager::CloseDialog(const RefPtr<FrameNode>& dialogNode)
2865 {
2866 TAG_LOGD(AceLogTag::ACE_OVERLAY, "close dialog enter");
2867 DeleteDialogHotAreas(dialogNode);
2868 auto dialogLayoutProp = AceType::DynamicCast<DialogLayoutProperty>(dialogNode->GetLayoutProperty());
2869 CHECK_NULL_VOID(dialogLayoutProp);
2870 if (dialogLayoutProp && dialogLayoutProp->GetShowInSubWindowValue(false) &&
2871 dialogLayoutProp->GetIsModal().value_or(true)) {
2872 RefPtr<OverlayManager> parentOverlayManager = nullptr;
2873 #if defined(ANDROID_PLATFORM) || defined(IOS_PLATFORM)
2874 auto container = Container::Current();
2875 auto currentId = Container::CurrentId();
2876 CHECK_NULL_VOID(container);
2877 if (container->IsSubContainer()) {
2878 currentId = SubwindowManager::GetInstance()->GetParentContainerId(Container::CurrentId());
2879 container = AceEngine::Get().GetContainer(currentId);
2880 CHECK_NULL_VOID(container);
2881 }
2882 ContainerScope scope(currentId);
2883 auto pipelineContext = container->GetPipelineContext();
2884 CHECK_NULL_VOID(pipelineContext);
2885 auto context = AceType::DynamicCast<NG::PipelineContext>(pipelineContext);
2886 CHECK_NULL_VOID(context);
2887 parentOverlayManager = context->GetOverlayManager();
2888 #else
2889 auto parentPipelineContext = PipelineContext::GetMainPipelineContext();
2890 CHECK_NULL_VOID(parentPipelineContext);
2891 parentOverlayManager = parentPipelineContext->GetOverlayManager();
2892 #endif
2893 CHECK_NULL_VOID(parentOverlayManager);
2894 RefPtr<FrameNode> maskNode =
2895 parentOverlayManager->GetDialog(parentOverlayManager->GetMaskNodeIdWithDialogId(dialogNode->GetId()));
2896 if (maskNode) {
2897 parentOverlayManager->CloseDialog(maskNode);
2898 } else {
2899 TAG_LOGD(AceLogTag::ACE_OVERLAY, "no maskNode in currentDialog/%{public}d", dialogNode->GetId());
2900 }
2901 }
2902 CloseDialogInner(dialogNode);
2903 }
2904
DeleteDialogHotAreas(const RefPtr<FrameNode> & dialogNode)2905 void OverlayManager::DeleteDialogHotAreas(const RefPtr<FrameNode>& dialogNode)
2906 {
2907 auto dialogLayoutProp = AceType::DynamicCast<DialogLayoutProperty>(dialogNode->GetLayoutProperty());
2908 CHECK_NULL_VOID(dialogLayoutProp);
2909 if (dialogLayoutProp->GetShowInSubWindowValue(false)) {
2910 SubwindowManager::GetInstance()->DeleteHotAreas(
2911 SubwindowManager::GetInstance()->GetDialogSubWindowId(), dialogNode->GetId());
2912 SubwindowManager::GetInstance()->HideDialogSubWindow(
2913 SubwindowManager::GetInstance()->GetDialogSubWindowId());
2914 }
2915 }
2916
CloseDialogInner(const RefPtr<FrameNode> & dialogNode)2917 void OverlayManager::CloseDialogInner(const RefPtr<FrameNode>& dialogNode)
2918 {
2919 RemoveDialogFromMap(dialogNode);
2920 if (dialogNode->IsRemoving()) {
2921 // already in close animation
2922 TAG_LOGW(AceLogTag::ACE_DIALOG, "dialogNode/%{public}d is removing", dialogNode->GetId());
2923 return;
2924 }
2925 dialogNode->MarkRemoving();
2926
2927 auto container = Container::Current();
2928 auto currentId = Container::CurrentId();
2929 CHECK_NULL_VOID(container);
2930 if (container->IsSubContainer()) {
2931 currentId = SubwindowManager::GetInstance()->GetParentContainerId(Container::CurrentId());
2932 container = AceEngine::Get().GetContainer(currentId);
2933 CHECK_NULL_VOID(container);
2934 }
2935 ContainerScope scope(currentId);
2936 auto pipelineContext = container->GetPipelineContext();
2937 CHECK_NULL_VOID(pipelineContext);
2938 auto context = AceType::DynamicCast<NG::PipelineContext>(pipelineContext);
2939 CHECK_NULL_VOID(context);
2940 auto overlayManager = context->GetOverlayManager();
2941 CHECK_NULL_VOID(overlayManager);
2942 overlayManager->ResetLowerNodeFocusable(dialogNode);
2943 auto dialogPattern = dialogNode->GetPattern<DialogPattern>();
2944 CHECK_NULL_VOID(dialogPattern);
2945 auto transitionEffect = dialogPattern->GetDialogProperties().transitionEffect;
2946 if (transitionEffect != nullptr) {
2947 CloseDialogMatchTransition(dialogNode);
2948 } else {
2949 CloseDialogAnimation(dialogNode);
2950 }
2951 dialogCount_--;
2952 overlayManager->RemoveMaskFromMap(dialogNode);
2953 // set close button enable
2954 if (dialogCount_ == 0) {
2955 SetContainerButtonEnable(true);
2956 }
2957 CallOnHideDialogCallback();
2958 }
2959
RemoveDialog(const RefPtr<FrameNode> & overlay,bool isBackPressed,bool isPageRouter)2960 bool OverlayManager::RemoveDialog(const RefPtr<FrameNode>& overlay, bool isBackPressed, bool isPageRouter)
2961 {
2962 TAG_LOGD(AceLogTag::ACE_OVERLAY, "remove dialog enter");
2963 if (overlay->IsRemoving()) {
2964 return false;
2965 }
2966 if (FireBackPressEvent()) {
2967 return true;
2968 }
2969 auto hub = overlay->GetEventHub<DialogEventHub>();
2970 if (!isPageRouter && hub) {
2971 hub->FireCancelEvent();
2972 }
2973 CloseDialog(overlay);
2974 if (isBackPressed) {
2975 SetBackPressEvent(nullptr);
2976 }
2977 return true;
2978 }
2979
PopupInteractiveDismiss(const RefPtr<FrameNode> & overlay)2980 bool OverlayManager::PopupInteractiveDismiss(const RefPtr<FrameNode>& overlay)
2981 {
2982 auto bubblePattern = overlay->GetPattern<BubblePattern>();
2983 CHECK_NULL_RETURN(bubblePattern, false);
2984 return !bubblePattern->GetInteractiveDismiss();
2985 }
2986
PopupCallBackOnWillDismiss(const RefPtr<FrameNode> & overlay)2987 bool OverlayManager::PopupCallBackOnWillDismiss(const RefPtr<FrameNode>& overlay)
2988 {
2989 auto bubblePattern = overlay->GetPattern<BubblePattern>();
2990 CHECK_NULL_RETURN(bubblePattern, false);
2991 if (bubblePattern->HasOnWillDismiss()) {
2992 int32_t dismissPopupId = GetPopupIdByNode(overlay);
2993 SetDismissPopupId(dismissPopupId);
2994 bubblePattern->CallOnWillDismiss(static_cast<int32_t>(DismissReason::BACK_PRESSED));
2995 return true;
2996 }
2997 return false;
2998 }
2999
RemoveBubble(const RefPtr<FrameNode> & overlay)3000 bool OverlayManager::RemoveBubble(const RefPtr<FrameNode>& overlay)
3001 {
3002 TAG_LOGD(AceLogTag::ACE_OVERLAY, "remove bubble enter");
3003 if (PopupInteractiveDismiss(overlay)) {
3004 return true;
3005 }
3006 if (PopupCallBackOnWillDismiss(overlay)) {
3007 return true;
3008 }
3009 for (const auto& popup : popupMap_) {
3010 auto targetId = popup.first;
3011 auto popupInfo = popup.second;
3012 if (overlay == popupInfo.popupNode) {
3013 popupInfo.markNeedUpdate = true;
3014 HidePopup(targetId, popupInfo);
3015 return true;
3016 }
3017 }
3018 return false;
3019 }
3020
RemoveMenu(const RefPtr<FrameNode> & overlay)3021 bool OverlayManager::RemoveMenu(const RefPtr<FrameNode>& overlay)
3022 {
3023 TAG_LOGI(AceLogTag::ACE_OVERLAY, "remove menu enter");
3024 auto menuWrapperPattern = overlay->GetPattern<MenuWrapperPattern>();
3025 CHECK_NULL_RETURN(menuWrapperPattern, false);
3026 menuWrapperPattern->UpdateMenuAnimation(overlay);
3027 menuWrapperPattern->HideMenu();
3028 return true;
3029 }
3030
RemoveDragPreview(const RefPtr<FrameNode> & overlay)3031 bool OverlayManager::RemoveDragPreview(const RefPtr<FrameNode>& overlay)
3032 {
3033 TAG_LOGI(AceLogTag::ACE_OVERLAY, "remove dragPreview enter");
3034 auto columnNode = pixmapColumnNodeWeak_.Upgrade();
3035 if (columnNode != overlay) {
3036 return false;
3037 }
3038 RemoveEventColumn();
3039 RemovePixelMap();
3040 RemoveGatherNode();
3041 return true;
3042 }
3043
GetPopupIdByNode(const RefPtr<FrameNode> & overlay)3044 int32_t OverlayManager::GetPopupIdByNode(const RefPtr<FrameNode>& overlay)
3045 {
3046 TAG_LOGD(AceLogTag::ACE_OVERLAY, "GetPopupIdByNode IN");
3047 int32_t targetId = -1;
3048 for (const auto& popup : popupMap_) {
3049 targetId = popup.first;
3050 auto popupInfo = popup.second;
3051 if (overlay == popupInfo.popupNode) {
3052 return targetId;
3053 }
3054 }
3055 return targetId;
3056 }
3057
RemoveOverlayCommon(const RefPtr<NG::UINode> & rootNode,RefPtr<NG::FrameNode> & overlay,RefPtr<Pattern> & pattern,bool isBackPressed,bool isPageRouter)3058 int32_t OverlayManager::RemoveOverlayCommon(const RefPtr<NG::UINode>& rootNode, RefPtr<NG::FrameNode>& overlay,
3059 RefPtr<Pattern>& pattern, bool isBackPressed, bool isPageRouter)
3060 {
3061 const size_t size = rootNode->GetChildren().size();
3062 if (size == 0) {
3063 return OVERLAY_EXISTS;
3064 }
3065 auto currentIndex = size - 1;
3066 while (InstanceOf<ToastPattern>(pattern)) {
3067 // still have nodes on root expect stage and toast node.
3068 if (currentIndex > 0) {
3069 currentIndex = currentIndex - 1;
3070 overlay = DynamicCast<FrameNode>(rootNode->GetChildAtIndex(currentIndex));
3071 CHECK_NULL_RETURN(overlay, OVERLAY_EXISTS);
3072 pattern = overlay->GetPattern();
3073 } else {
3074 return OVERLAY_EXISTS;
3075 }
3076 }
3077 CHECK_EQUAL_RETURN(overlay->GetTag(), V2::STAGE_ETS_TAG, OVERLAY_EXISTS);
3078 CHECK_EQUAL_RETURN(overlay->GetTag(), V2::OVERLAY_ETS_TAG, OVERLAY_EXISTS);
3079 CHECK_EQUAL_RETURN(overlay->GetTag(), V2::ATOMIC_SERVICE_ETS_TAG, OVERLAY_EXISTS);
3080 // close dialog with animation
3081 if (InstanceOf<DialogPattern>(pattern)) {
3082 if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE) && isPageRouter) {
3083 return OVERLAY_EXISTS;
3084 }
3085 auto dialogPattern = DynamicCast<DialogPattern>(pattern);
3086 CHECK_NULL_RETURN(dialogPattern, OVERLAY_EXISTS);
3087 if (dialogPattern->CallDismissInNDK(static_cast<int32_t>(DialogDismissReason::DIALOG_PRESS_BACK))) {
3088 return OVERLAY_REMOVE;
3089 } else if (dialogPattern->ShouldDismiss()) {
3090 SetDismissDialogId(overlay->GetId());
3091 dialogPattern->CallOnWillDismiss(static_cast<int32_t>(DialogDismissReason::DIALOG_PRESS_BACK));
3092 TAG_LOGI(AceLogTag::ACE_OVERLAY, "Dialog Should Dismiss");
3093 return OVERLAY_REMOVE;
3094 }
3095 return RemoveDialog(overlay, isBackPressed, isPageRouter) ? OVERLAY_REMOVE : OVERLAY_EXISTS;
3096 }
3097 if (InstanceOf<BubblePattern>(pattern)) {
3098 return RemoveBubble(overlay) ? OVERLAY_REMOVE : OVERLAY_EXISTS;
3099 }
3100 if (InstanceOf<MenuWrapperPattern>(pattern)) {
3101 RemoveDragPreview(overlay);
3102 return RemoveMenu(overlay) ? OVERLAY_REMOVE : OVERLAY_EXISTS;
3103 }
3104 if (InstanceOf<LinearLayoutPattern>(pattern)) {
3105 return RemoveDragPreview(overlay) ? OVERLAY_REMOVE : OVERLAY_NOTHING;
3106 }
3107 return OVERLAY_NOTHING;
3108 }
3109
RemoveOverlay(bool isBackPressed,bool isPageRouter)3110 bool OverlayManager::RemoveOverlay(bool isBackPressed, bool isPageRouter)
3111 {
3112 auto rootNode = rootNodeWeak_.Upgrade();
3113 CHECK_NULL_RETURN(rootNode, true);
3114 RemoveIndexerPopup();
3115 SetDragNodeNeedClean();
3116 auto pipeline = rootNode->GetContextRefPtr();
3117 CHECK_NULL_RETURN(pipeline, false);
3118 // There is overlay under the root node or it is in atomicservice
3119 if (rootNode->GetChildren().size() > ROOT_MIN_NODE || pipeline->GetInstallationFree()) {
3120 // stage node is at index 0, remove overlay at last
3121 auto overlay = GetOverlayFrameNode();
3122 CHECK_NULL_RETURN(overlay, false);
3123 auto pattern = overlay->GetPattern();
3124 auto ret = RemoveOverlayCommon(rootNode, overlay, pattern, isBackPressed, isPageRouter);
3125 if (ret == OVERLAY_REMOVE) {
3126 return true;
3127 } else if (ret == OVERLAY_EXISTS) {
3128 return false;
3129 }
3130 ret = ExceptComponent(rootNode, overlay, isBackPressed, isPageRouter);
3131 if (ret == OVERLAY_REMOVE) {
3132 return true;
3133 } else if (ret == OVERLAY_EXISTS) {
3134 return false;
3135 }
3136 // remove navDestination in navigation first
3137 do {
3138 CHECK_NULL_BREAK(rootNode->GetTag() != V2::NAVDESTINATION_VIEW_ETS_TAG);
3139 bool isEntry = false;
3140 auto navigationGroupNode =
3141 AceType::DynamicCast<NavigationGroupNode>(pipeline->FindNavigationNodeToHandleBack(overlay, isEntry));
3142 CHECK_NULL_BREAK(navigationGroupNode);
3143 return true;
3144 } while (0);
3145 if (!modalStack_.empty()) {
3146 TAG_LOGI(AceLogTag::ACE_SHEET, "Modal consumed backpressed event");
3147 if (isPageRouter) {
3148 return RemoveAllModalInOverlay();
3149 } else {
3150 return RemoveModalInOverlay();
3151 }
3152 }
3153 if (!InstanceOf<KeyboardPattern>(pattern)) {
3154 if (overlay->GetTag() != V2::SHEET_WRAPPER_TAG) {
3155 rootNode->RemoveChild(overlay);
3156 }
3157 rootNode->MarkDirtyNode(PROPERTY_UPDATE_BY_CHILD_REQUEST);
3158 return true;
3159 }
3160 }
3161 return false;
3162 }
3163
GetOverlayFrameNode()3164 RefPtr<FrameNode> OverlayManager::GetOverlayFrameNode()
3165 {
3166 auto rootNode = rootNodeWeak_.Upgrade();
3167 CHECK_NULL_RETURN(rootNode, nullptr);
3168 auto pipeline = rootNode->GetContextRefPtr();
3169 CHECK_NULL_RETURN(pipeline, nullptr);
3170 auto overlay = DynamicCast<FrameNode>(rootNode->GetLastChild());
3171 // There is no overlay under the root node or it is not in atomicservice
3172 if (!pipeline->GetInstallationFree() || rootNode->GetChildren().size() > ROOT_MIN_NODE) {
3173 return overlay;
3174 }
3175 for (auto child : rootNode->GetChildren()) {
3176 if (child->GetTag() == V2::ATOMIC_SERVICE_ETS_TAG) {
3177 auto atomicNode = child;
3178 CHECK_NULL_RETURN(atomicNode, nullptr);
3179 if (atomicNode->GetChildren().size() <= ATOMIC_SERVICE_MIN_SIZE) {
3180 return nullptr;
3181 }
3182 overlay = DynamicCast<FrameNode>(
3183 atomicNode->GetChildAtIndex(atomicNode->GetChildren().size() - ATOMIC_SERVICE_MIN_SIZE));
3184 break;
3185 }
3186 }
3187 return overlay;
3188 }
3189
ExceptComponent(const RefPtr<NG::UINode> & rootNode,RefPtr<NG::FrameNode> & overlay,bool isBackPressed,bool isPageRouter)3190 int32_t OverlayManager::ExceptComponent(const RefPtr<NG::UINode>& rootNode, RefPtr<NG::FrameNode>& overlay,
3191 bool isBackPressed, bool isPageRouter)
3192 {
3193 auto pattern = overlay->GetPattern();
3194 if (InstanceOf<VideoFullScreenPattern>(pattern)) {
3195 auto videoPattern = DynamicCast<VideoFullScreenPattern>(pattern);
3196 CHECK_NULL_RETURN(videoPattern, OVERLAY_EXISTS);
3197 return videoPattern->ExitFullScreen() ? OVERLAY_REMOVE : OVERLAY_EXISTS;
3198 }
3199 // OVERLAY_REMOVE if popup was removed, OVERLAY_NOTHING if not handle it
3200 if (overlay->GetTag() == V2::SHEET_WRAPPER_TAG) {
3201 return WebBackward(overlay);
3202 }
3203 return OVERLAY_NOTHING;
3204 }
3205
WebBackward(RefPtr<NG::FrameNode> & overlay)3206 int32_t OverlayManager::WebBackward(RefPtr<NG::FrameNode>& overlay)
3207 {
3208 #ifdef WEB_SUPPORTED
3209 RefPtr<NG::FrameNode> webNode;
3210 FindWebNode(overlay, webNode);
3211 if (webNode && InstanceOf<WebPattern>(webNode->GetPattern())) {
3212 auto webPattern = DynamicCast<WebPattern>(webNode->GetPattern());
3213 CHECK_NULL_RETURN(webPattern, OVERLAY_EXISTS);
3214 if (webPattern->Backward()) {
3215 return OVERLAY_REMOVE;
3216 }
3217 }
3218 #endif
3219 return OVERLAY_NOTHING;
3220 }
3221
FindWebNode(const RefPtr<NG::UINode> & node,RefPtr<NG::FrameNode> & webNode)3222 void OverlayManager::FindWebNode(const RefPtr<NG::UINode>& node, RefPtr<NG::FrameNode>& webNode)
3223 {
3224 CHECK_NULL_VOID(node);
3225
3226 if (webNode) {
3227 return;
3228 }
3229
3230 auto frameNode = AceType::DynamicCast<NG::FrameNode>(node);
3231 if (frameNode && !frameNode->IsInternal() && frameNode->GetTag() == V2::WEB_ETS_TAG) {
3232 webNode = frameNode;
3233 return;
3234 }
3235
3236 if (!node->GetChildren().empty()) {
3237 for (const auto& child : node->GetChildren()) {
3238 FindWebNode(child, webNode);
3239 }
3240 }
3241 }
3242
RemoveModalInOverlay()3243 bool OverlayManager::RemoveModalInOverlay()
3244 {
3245 auto topModalNode = modalStack_.top().Upgrade();
3246 CHECK_NULL_RETURN(topModalNode, false);
3247 auto rootNode = FindWindowScene(topModalNode);
3248 CHECK_NULL_RETURN(rootNode, true);
3249 auto overlay = DynamicCast<FrameNode>(rootNode->GetLastChild());
3250 if (overlay && overlay->GetTag() == V2::SHEET_WRAPPER_TAG && overlay->GetFirstChild() != topModalNode) {
3251 TAG_LOGD(AceLogTag::ACE_SHEET, "Refuse to back because sheet is in animation");
3252 return true;
3253 }
3254 if (topModalNode->GetTag() == V2::SHEET_PAGE_TAG) {
3255 auto sheetPattern = topModalNode->GetPattern<SheetPresentationPattern>();
3256 CHECK_NULL_RETURN(sheetPattern, false);
3257 sheetPattern->SheetInteractiveDismiss(BindSheetDismissReason::BACK_PRESSED);
3258 return true;
3259 } else if (topModalNode->GetTag() == V2::MODAL_PAGE_TAG) {
3260 auto modalPattern = topModalNode->GetPattern<ModalPresentationPattern>();
3261 CHECK_NULL_RETURN(modalPattern, false);
3262 if (modalPattern->HasOnWillDismiss()) {
3263 modalPattern->ModalInteractiveDismiss();
3264 return true;
3265 }
3266 }
3267 ModalPageLostFocus(topModalNode);
3268 auto pattern = topModalNode->GetPattern<PopupBasePattern>();
3269 if (isProhibitBack_ && pattern->GetTargetId() < 0) {
3270 return true;
3271 }
3272 auto builder = AceType::DynamicCast<FrameNode>(topModalNode->GetFirstChild());
3273 CHECK_NULL_RETURN(builder, false);
3274 if (!ModalExitProcess(topModalNode)) {
3275 return false;
3276 }
3277 PopTopModalNode();
3278 auto sheetPattern = topModalNode->GetPattern<SheetPresentationPattern>();
3279 if (topModalNode->GetTag() == V2::SHEET_PAGE_TAG && sheetPattern) {
3280 sheetMap_.erase(sheetPattern->GetSheetKey());
3281 }
3282 if (topModalNode->GetTag() == V2::MODAL_PAGE_TAG) {
3283 auto modalPattern = AceType::DynamicCast<ModalPresentationPattern>(pattern);
3284 CHECK_NULL_RETURN(modalPattern, false);
3285 auto modalTransition = modalPattern->GetType();
3286 if (modalTransition == ModalTransition::NONE || builder->GetRenderContext()->HasDisappearTransition()) {
3287 // Fire shown event of navdestination under the disappeared modal
3288 FireNavigationStateChange(true);
3289 }
3290 }
3291 FireModalPageHide();
3292 SaveLastModalNode();
3293 return true;
3294 }
3295
RemoveAllModalInOverlay(bool isRouterTransition)3296 bool OverlayManager::RemoveAllModalInOverlay(bool isRouterTransition)
3297 {
3298 if (modalStack_.empty()) {
3299 return true;
3300 }
3301
3302 auto topModalNode = modalStack_.top().Upgrade();
3303 bool isModalUiextensionNode = IsModalUiextensionNode(topModalNode);
3304 if (!isRouterTransition) {
3305 bool isProhibitedRemoveByNavigation = IsProhibitedRemoveByNavigation(topModalNode);
3306 TAG_LOGI(AceLogTag::ACE_OVERLAY,
3307 "isNavigation: isModalUiextensionNode: %{public}d, isProhibitedRemoveByNavigation: %{public}d",
3308 isModalUiextensionNode, isProhibitedRemoveByNavigation);
3309 if (isModalUiextensionNode && !isProhibitedRemoveByNavigation) {
3310 return RemoveAllModalInOverlayByStack();
3311 }
3312 return true;
3313 }
3314
3315 bool isProhibitedRemoveByRouter = IsProhibitedRemoveByRouter(topModalNode);
3316 TAG_LOGI(AceLogTag::ACE_OVERLAY,
3317 "isRouter: isModalUiextensionNode: %{public}d, isProhibitedRemoveByRouter: %{public}d,",
3318 isModalUiextensionNode, isProhibitedRemoveByRouter);
3319 if (isModalUiextensionNode && isProhibitedRemoveByRouter) {
3320 return RemoveAllModalInOverlayByList();
3321 }
3322
3323 return RemoveAllModalInOverlayByStack();
3324 }
3325
RemoveAllModalInOverlayByStack()3326 bool OverlayManager::RemoveAllModalInOverlayByStack()
3327 {
3328 while (!modalStack_.empty()) {
3329 auto topModalNode = modalStack_.top().Upgrade();
3330 if (!topModalNode) {
3331 modalStack_.pop();
3332 continue;
3333 }
3334 auto rootNode = FindWindowScene(topModalNode);
3335 CHECK_NULL_RETURN(rootNode, true);
3336 auto builder = AceType::DynamicCast<FrameNode>(topModalNode->GetFirstChild());
3337 CHECK_NULL_RETURN(builder, false);
3338 ModalPageLostFocus(topModalNode);
3339 if (!ModalExitProcess(topModalNode)) {
3340 continue;
3341 }
3342 if (!modalStack_.empty()) {
3343 modalStack_.pop();
3344 }
3345 if (!modalList_.empty()) {
3346 modalList_.pop_back();
3347 }
3348
3349 if (topModalNode->GetTag() == V2::MODAL_PAGE_TAG) {
3350 auto modalPattern = topModalNode->GetPattern<ModalPresentationPattern>();
3351 CHECK_NULL_RETURN(modalPattern, false);
3352 auto modalTransition = modalPattern->GetType();
3353 if (modalTransition == ModalTransition::NONE || builder->GetRenderContext()->HasDisappearTransition()) {
3354 // Fire shown event of navdestination under the disappeared modal
3355 FireNavigationStateChange(true);
3356 }
3357 }
3358 auto sheetPattern = topModalNode->GetPattern<SheetPresentationPattern>();
3359 if (topModalNode->GetTag() == V2::SHEET_PAGE_TAG && sheetPattern) {
3360 sheetMap_.erase(sheetPattern->GetSheetKey());
3361 }
3362 FireModalPageHide();
3363 SaveLastModalNode();
3364 }
3365 return true;
3366 }
3367
RemoveAllModalInOverlayByList()3368 bool OverlayManager::RemoveAllModalInOverlayByList()
3369 {
3370 TAG_LOGI(AceLogTag::ACE_OVERLAY,
3371 "RemoveAllModalInOverlayByList modalStack size: %{public}zu, "
3372 "modalList size: %{public}zu", modalStack_.size(), modalList_.size());
3373 if (modalStack_.size() != modalList_.size()) {
3374 TAG_LOGI(AceLogTag::ACE_OVERLAY,
3375 "Not RemoveAllModalInOverlayByList due to modalStack not same with modalList.");
3376 return true;
3377 }
3378
3379 bool ret = OnRemoveAllModalInOverlayByList();
3380 // To keep the modalStack consistent with the modalList
3381 AfterRemoveAllModalInOverlayByList();
3382 return ret;
3383 }
3384
OnRemoveAllModalInOverlayByList()3385 bool OverlayManager::OnRemoveAllModalInOverlayByList()
3386 {
3387 auto modalIter = modalList_.begin();
3388 while (modalIter != modalList_.end()) {
3389 auto topModalNode = (*modalIter).Upgrade();
3390 if (!topModalNode) {
3391 modalIter = modalList_.erase(modalIter);
3392 continue;
3393 }
3394 if (IsModalUiextensionNode(topModalNode)) {
3395 break;
3396 }
3397 auto rootNode = FindWindowScene(topModalNode);
3398 CHECK_NULL_RETURN(rootNode, true);
3399 auto builder = AceType::DynamicCast<FrameNode>(topModalNode->GetFirstChild());
3400 CHECK_NULL_RETURN(builder, false);
3401 ModalPageLostFocus(topModalNode);
3402 if (!ModalExitProcess(topModalNode)) {
3403 modalIter = modalList_.erase(modalIter);
3404 continue;
3405 }
3406 if (topModalNode->GetTag() == V2::MODAL_PAGE_TAG) {
3407 auto modalPattern = topModalNode->GetPattern<ModalPresentationPattern>();
3408 CHECK_NULL_RETURN(modalPattern, false);
3409 auto modalTransition = modalPattern->GetType();
3410 if (modalTransition == ModalTransition::NONE || builder->GetRenderContext()->HasDisappearTransition()) {
3411 // Fire shown event of navdestination under the disappeared modal
3412 FireNavigationStateChange(true);
3413 }
3414 }
3415 auto sheetPattern = topModalNode->GetPattern<SheetPresentationPattern>();
3416 if (topModalNode->GetTag() == V2::SHEET_PAGE_TAG && sheetPattern) {
3417 sheetMap_.erase(sheetPattern->GetSheetKey());
3418 }
3419 modalIter = modalList_.erase(modalIter);
3420 }
3421 return true;
3422 }
3423
AfterRemoveAllModalInOverlayByList()3424 void OverlayManager::AfterRemoveAllModalInOverlayByList()
3425 {
3426 TAG_LOGI(AceLogTag::ACE_OVERLAY,
3427 "AfterRemoveAllModalInOverlayByList modalList size: %{public}zu", modalList_.size());
3428 std::stack<WeakPtr<FrameNode>> modalStack;
3429 modalStack_.swap(modalStack);
3430 for (auto modal = modalList_.begin(); modal != modalList_.end(); ++modal) {
3431 modalStack_.push(*modal);
3432 }
3433 }
3434
IsModalUiextensionNode(const RefPtr<FrameNode> & topModalNode)3435 bool OverlayManager::IsModalUiextensionNode(const RefPtr<FrameNode>& topModalNode)
3436 {
3437 if (topModalNode == nullptr) {
3438 TAG_LOGI(AceLogTag::ACE_OVERLAY, "topModalNode is null,");
3439 return false;
3440 }
3441
3442 if (topModalNode->GetTag() != V2::MODAL_PAGE_TAG) {
3443 TAG_LOGI(AceLogTag::ACE_OVERLAY, "topModalNode is not modalPage");
3444 return false;
3445 }
3446
3447 auto modalPattern = topModalNode->GetPattern<ModalPresentationPattern>();
3448 CHECK_NULL_RETURN(modalPattern, false);
3449 return modalPattern->IsUIExtension();
3450 }
3451
IsProhibitedRemoveByRouter(const RefPtr<FrameNode> & topModalNode)3452 bool OverlayManager::IsProhibitedRemoveByRouter(const RefPtr<FrameNode>& topModalNode)
3453 {
3454 if (topModalNode == nullptr) {
3455 TAG_LOGI(AceLogTag::ACE_OVERLAY, "topModalNode is null,");
3456 return false;
3457 }
3458
3459 if (topModalNode->GetTag() != V2::MODAL_PAGE_TAG) {
3460 TAG_LOGI(AceLogTag::ACE_OVERLAY, "topModalNode is not modalPage");
3461 return false;
3462 }
3463
3464 auto modalPattern = topModalNode->GetPattern<ModalPresentationPattern>();
3465 CHECK_NULL_RETURN(modalPattern, false);
3466 return modalPattern->IsProhibitedRemoveByRouter();
3467 }
3468
IsProhibitedRemoveByNavigation(const RefPtr<FrameNode> & topModalNode)3469 bool OverlayManager::IsProhibitedRemoveByNavigation(const RefPtr<FrameNode>& topModalNode)
3470 {
3471 if (topModalNode == nullptr) {
3472 TAG_LOGI(AceLogTag::ACE_OVERLAY, "topModalNode is null,");
3473 return true;
3474 }
3475
3476 if (topModalNode->GetTag() != V2::MODAL_PAGE_TAG) {
3477 TAG_LOGI(AceLogTag::ACE_OVERLAY, "topModalNode is not modalPage");
3478 return true;
3479 }
3480
3481 auto modalPattern = topModalNode->GetPattern<ModalPresentationPattern>();
3482 CHECK_NULL_RETURN(modalPattern, true);
3483 return modalPattern->IsProhibitedRemoveByNavigation();
3484 }
3485
ModalExitProcess(const RefPtr<FrameNode> & topModalNode)3486 bool OverlayManager::ModalExitProcess(const RefPtr<FrameNode>& topModalNode)
3487 {
3488 auto rootNode = FindWindowScene(topModalNode);
3489 CHECK_NULL_RETURN(rootNode, true);
3490 if (topModalNode->GetTag() == V2::MODAL_PAGE_TAG) {
3491 return ModalPageExitProcess(topModalNode);
3492 }
3493 if (topModalNode->GetTag() == V2::SHEET_PAGE_TAG) {
3494 return SheetPageExitProcess(topModalNode);
3495 }
3496 return true;
3497 }
3498
PlayTransitionEffectOut(const RefPtr<FrameNode> & topModalNode)3499 void OverlayManager::PlayTransitionEffectOut(const RefPtr<FrameNode>& topModalNode)
3500 {
3501 const auto& layoutProperty = topModalNode->GetLayoutProperty();
3502 layoutProperty->UpdateVisibility(VisibleType::INVISIBLE, true);
3503
3504 const auto& renderContext = topModalNode->GetRenderContext();
3505 if (!renderContext->HasDisappearTransition()) {
3506 const auto& topModalPattern = topModalNode->GetPattern<ModalPresentationPattern>();
3507 if (!topModalPattern->IsExecuteOnDisappear()) {
3508 topModalPattern->OnDisappear();
3509 // Fire hidden event of navdestination on the disappeared modal
3510 FireNavigationStateChange(false, topModalNode);
3511 }
3512 auto rootNode = FindWindowScene(topModalNode);
3513 FireAutoSave(topModalNode);
3514 RemoveChildWithService(rootNode, topModalNode);
3515 rootNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
3516 // Fire shown event of navdestination under the disappeared modal
3517 FireNavigationStateChange(true);
3518 } else {
3519 topModalNode->GetRenderContext()->SetTransitionOutCallback(
3520 [modalWK = WeakClaim(RawPtr(topModalNode)), overlayWeak = WeakClaim(this)] {
3521 auto modal = modalWK.Upgrade();
3522 auto overlayManager = overlayWeak.Upgrade();
3523 CHECK_NULL_VOID(modal && overlayManager);
3524 auto root = overlayManager->FindWindowScene(modal);
3525 CHECK_NULL_VOID(root);
3526 const auto& modalPattern = modal->GetPattern<ModalPresentationPattern>();
3527 if (!modalPattern->IsExecuteOnDisappear()) {
3528 modalPattern->OnDisappear();
3529 // Fire hidden event of navdestination on the disappeared modal
3530 overlayManager->FireNavigationStateChange(false, modal);
3531 }
3532 overlayManager->FireAutoSave(modal);
3533 overlayManager->RemoveChildWithService(root, modal);
3534 root->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
3535 // Fire shown event of navdestination under the disappeared modal
3536 overlayManager->FireNavigationStateChange(true);
3537 });
3538 }
3539 }
3540
ModalPageExitProcess(const RefPtr<FrameNode> & topModalNode)3541 bool OverlayManager::ModalPageExitProcess(const RefPtr<FrameNode>& topModalNode)
3542 {
3543 auto rootNode = FindWindowScene(topModalNode);
3544 CHECK_NULL_RETURN(rootNode, true);
3545 auto builder = AceType::DynamicCast<FrameNode>(topModalNode->GetFirstChild());
3546 CHECK_NULL_RETURN(builder, false);
3547 topModalNode->GetPattern<ModalPresentationPattern>()->OnWillDisappear();
3548 auto modalTransition = topModalNode->GetPattern<ModalPresentationPattern>()->GetType();
3549 if (builder->GetRenderContext()->HasDisappearTransition()) {
3550 if (!topModalNode->GetPattern<ModalPresentationPattern>()->IsExecuteOnDisappear()) {
3551 topModalNode->GetPattern<ModalPresentationPattern>()->OnDisappear();
3552 // Fire hidden event of navdestination on the disappeared modal
3553 FireNavigationStateChange(false, topModalNode);
3554 }
3555 topModalNode->Clean(false, true);
3556 topModalNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
3557 }
3558 topModalNode->OnAccessibilityEvent(
3559 AccessibilityEventType::PAGE_CLOSE, WindowsContentChangeTypes::CONTENT_CHANGE_TYPE_SUBTREE);
3560 if (topModalNode->GetPattern<ModalPresentationPattern>()->HasTransitionEffect()) {
3561 PlayTransitionEffectOut(topModalNode);
3562 } else if (modalTransition == ModalTransition::DEFAULT) {
3563 PlayDefaultModalTransition(topModalNode, false);
3564 } else if (modalTransition == ModalTransition::ALPHA) {
3565 PlayAlphaModalTransition(topModalNode, false);
3566 } else if (!builder->GetRenderContext()->HasDisappearTransition()) {
3567 topModalNode->GetPattern<ModalPresentationPattern>()->OnDisappear();
3568 // Fire hidden event of navdestination on the disappeared modal
3569 FireNavigationStateChange(false, topModalNode);
3570 FireAutoSave(topModalNode);
3571 RemoveChildWithService(rootNode, topModalNode);
3572 rootNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
3573 }
3574 topModalNode->GetPattern<ModalPresentationPattern>()->FireCallback("false");
3575 return true;
3576 }
3577
SheetPageExitProcess(const RefPtr<FrameNode> & topModalNode)3578 bool OverlayManager::SheetPageExitProcess(const RefPtr<FrameNode>& topModalNode)
3579 {
3580 auto builder = AceType::DynamicCast<FrameNode>(topModalNode->GetLastChild());
3581 CHECK_NULL_RETURN(builder, false);
3582 topModalNode->GetPattern<SheetPresentationPattern>()->OnWillDisappear();
3583 if (builder->GetRenderContext()->HasDisappearTransition()) {
3584 if (!topModalNode->GetPattern<SheetPresentationPattern>()->IsExecuteOnDisappear()) {
3585 topModalNode->GetPattern<SheetPresentationPattern>()->OnDisappear();
3586 }
3587 topModalNode->Clean(false, true);
3588 topModalNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
3589 }
3590 auto maskNode = GetSheetMask(topModalNode);
3591 if (maskNode) {
3592 PlaySheetMaskTransition(maskNode, false);
3593 }
3594 auto sheetType = topModalNode->GetPattern<SheetPresentationPattern>()->GetSheetType();
3595 if (sheetType == SheetType::SHEET_POPUP) {
3596 PlayBubbleStyleSheetTransition(topModalNode, false);
3597 } else {
3598 PlaySheetTransition(topModalNode, false);
3599 }
3600 topModalNode->GetPattern<SheetPresentationPattern>()->FireCallback("false");
3601 return true;
3602 }
3603
RemovePopupInSubwindow(const RefPtr<Pattern> & pattern,const RefPtr<FrameNode> & overlay,const RefPtr<UINode> & rootNode)3604 bool OverlayManager::RemovePopupInSubwindow(const RefPtr<Pattern>& pattern, const RefPtr<FrameNode>& overlay,
3605 const RefPtr<UINode>& rootNode)
3606 {
3607 if (PopupInteractiveDismiss(overlay)) {
3608 return true;
3609 }
3610 if (PopupCallBackOnWillDismiss(overlay)) {
3611 return true;
3612 }
3613 auto popupPattern = DynamicCast<BubblePattern>(pattern);
3614 overlay->GetEventHub<BubbleEventHub>()->FireChangeEvent(false);
3615 auto container = Container::Current();
3616 auto currentId = Container::CurrentId();
3617 CHECK_NULL_RETURN(container, false);
3618 if (container->IsSubContainer()) {
3619 currentId = SubwindowManager::GetInstance()->GetParentContainerId(Container::CurrentId());
3620 }
3621 ContainerScope scope(currentId);
3622 for (const auto& popup : popupMap_) {
3623 auto targetId = popup.first;
3624 auto popupInfo = popup.second;
3625 if (overlay == popupInfo.popupNode) {
3626 popupMap_.erase(targetId);
3627 rootNode->RemoveChild(overlay);
3628 rootNode->MarkDirtyNode(PROPERTY_UPDATE_BY_CHILD_REQUEST);
3629 auto subwindow = SubwindowManager::GetInstance()->GetSubwindow(currentId);
3630 CHECK_NULL_RETURN(subwindow, false);
3631 subwindow->DeleteHotAreas(overlay->GetId());
3632 if (rootNode->GetChildren().empty()) {
3633 subwindow->HideSubWindowNG();
3634 }
3635 return true;
3636 }
3637 }
3638 return false;
3639 }
3640
RemoveOverlayInSubwindow()3641 bool OverlayManager::RemoveOverlayInSubwindow()
3642 {
3643 auto rootNode = rootNodeWeak_.Upgrade();
3644 CHECK_NULL_RETURN(rootNode, false);
3645 if (rootNode->GetChildren().empty()) {
3646 return false;
3647 }
3648
3649 // remove the overlay node just mounted in subwindow
3650 auto overlay = DynamicCast<FrameNode>(rootNode->GetLastChild());
3651 CHECK_NULL_RETURN(overlay, false);
3652 auto pattern = overlay->GetPattern();
3653 auto ret = RemoveOverlayCommon(rootNode, overlay, pattern, false, false);
3654 if (ret == OVERLAY_EXISTS) {
3655 return false;
3656 } else if (ret == OVERLAY_REMOVE) {
3657 return true;
3658 }
3659 rootNode->RemoveChild(overlay);
3660 rootNode->MarkDirtyNode(PROPERTY_UPDATE_BY_CHILD_REQUEST);
3661 if (rootNode->GetChildren().empty()) {
3662 SubwindowManager::GetInstance()->HideSubWindowNG();
3663 }
3664 if (InstanceOf<KeyboardPattern>(pattern)) {
3665 FocusHub::LostFocusToViewRoot();
3666 }
3667 return true;
3668 }
3669
FocusOverlayNode(const RefPtr<FrameNode> & overlayNode,bool isInSubWindow)3670 void OverlayManager::FocusOverlayNode(const RefPtr<FrameNode>& overlayNode, bool isInSubWindow)
3671 {
3672 CHECK_NULL_VOID(overlayNode);
3673 auto overlayHub = overlayNode->GetFocusHub();
3674 CHECK_NULL_VOID(overlayHub);
3675 auto focusView = overlayHub->GetFirstChildFocusView();
3676 CHECK_NULL_VOID(focusView);
3677 focusView->FocusViewShow();
3678 }
3679
BlurOverlayNode(const RefPtr<FrameNode> & currentOverlay,bool isInSubWindow)3680 void OverlayManager::BlurOverlayNode(const RefPtr<FrameNode>& currentOverlay, bool isInSubWindow) {}
3681
BlurLowerNode(const RefPtr<FrameNode> & currentOverlay)3682 void OverlayManager::BlurLowerNode(const RefPtr<FrameNode>& currentOverlay) {}
3683
ResetLowerNodeFocusable(const RefPtr<FrameNode> & currentOverlay)3684 void OverlayManager::ResetLowerNodeFocusable(const RefPtr<FrameNode>& currentOverlay) {}
3685
SaveLastModalNode()3686 void OverlayManager::SaveLastModalNode()
3687 {
3688 auto pipeline = PipelineContext::GetCurrentContext();
3689 CHECK_NULL_VOID(pipeline);
3690 auto stageManager = pipeline->GetStageManager();
3691 CHECK_NULL_VOID(stageManager);
3692 auto pageNode = stageManager->GetLastPage();
3693 CHECK_NULL_VOID(pageNode);
3694 if (modalStack_.empty()) {
3695 lastModalNode_ = WeakClaim(RawPtr(pageNode));
3696 } else {
3697 auto topModalNode = modalStack_.top().Upgrade();
3698 modalStack_.pop();
3699 if (modalStack_.empty()) {
3700 lastModalNode_ = WeakClaim(RawPtr(pageNode));
3701 } else {
3702 lastModalNode_ = modalStack_.top();
3703 }
3704 modalStack_.push(topModalNode);
3705 }
3706 }
3707
FireNavigationStateChange(bool show,const RefPtr<UINode> & node)3708 void OverlayManager::FireNavigationStateChange(bool show, const RefPtr<UINode>& node)
3709 {
3710 if (!show && node) {
3711 // Only check node When it is appointed
3712 NavigationPattern::FireNavigationStateChange(node, show);
3713 return;
3714 }
3715
3716 // Fire show event with non-empty stack. Only Check top modal node.
3717 RefPtr<FrameNode> topModalNode;
3718 if (!modalStack_.empty()) {
3719 topModalNode = GetModalNodeInStack(modalStack_);
3720 }
3721 if (show && topModalNode) {
3722 // Modal always displays on top of stage. If it existed, only need to check the top of modal stack.
3723 NavigationPattern::FireNavigationStateChange(topModalNode, show);
3724 return;
3725 }
3726
3727 auto lastPage = GetLastPage();
3728 CHECK_NULL_VOID(lastPage);
3729 auto pagePattern = lastPage->GetPattern<PagePattern>();
3730 bool notTriggerNavigationStateChange = show && pagePattern && !pagePattern->IsOnShow();
3731 if (notTriggerNavigationStateChange) {
3732 // navdestination will not fire onShow When parent page is hide.
3733 return;
3734 }
3735 NavigationPattern::FireNavigationStateChange(lastPage, show);
3736 }
3737
GetModalNodeInStack(std::stack<WeakPtr<FrameNode>> & stack)3738 RefPtr<FrameNode> OverlayManager::GetModalNodeInStack(std::stack<WeakPtr<FrameNode>>& stack)
3739 {
3740 if (stack.empty()) {
3741 return nullptr;
3742 }
3743 auto topModalNode = stack.top().Upgrade();
3744 CHECK_NULL_RETURN(topModalNode, nullptr);
3745 if (topModalNode->GetTag() == V2::MODAL_PAGE_TAG) {
3746 return topModalNode;
3747 } else {
3748 stack.pop();
3749 auto modalNode = GetModalNodeInStack(stack);
3750 stack.push(topModalNode);
3751 return modalNode;
3752 }
3753 }
3754
PlayTransitionEffectIn(const RefPtr<FrameNode> & modalNode)3755 void OverlayManager::PlayTransitionEffectIn(const RefPtr<FrameNode>& modalNode)
3756 {
3757 const auto& layoutProperty = modalNode->GetLayoutProperty();
3758 layoutProperty->UpdateVisibility(VisibleType::VISIBLE, true);
3759
3760 modalNode->GetRenderContext()->SetTransitionInCallback([modalWK = WeakClaim(RawPtr(modalNode))] {
3761 auto modal = modalWK.Upgrade();
3762 CHECK_NULL_VOID(modal);
3763 modal->GetPattern<ModalPresentationPattern>()->OnAppear();
3764 });
3765
3766 // Fire hidden event of navdestination under the appeared modal
3767 FireNavigationStateChange(false);
3768 }
3769
BindContentCover(bool isShow,std::function<void (const std::string &)> && callback,std::function<RefPtr<UINode> ()> && buildNodeFunc,NG::ModalStyle & modalStyle,std::function<void ()> && onAppear,std::function<void ()> && onDisappear,std::function<void ()> && onWillAppear,std::function<void ()> && onWillDisappear,const NG::ContentCoverParam & contentCoverParam,const RefPtr<FrameNode> & targetNode,int32_t sessionId)3770 void OverlayManager::BindContentCover(bool isShow, std::function<void(const std::string&)>&& callback,
3771 std::function<RefPtr<UINode>()>&& buildNodeFunc, NG::ModalStyle& modalStyle, std::function<void()>&& onAppear,
3772 std::function<void()>&& onDisappear, std::function<void()>&& onWillAppear, std::function<void()>&& onWillDisappear,
3773 const NG::ContentCoverParam& contentCoverParam, const RefPtr<FrameNode>& targetNode, int32_t sessionId)
3774 {
3775 return OnBindContentCover(isShow, std::move(callback), std::move(buildNodeFunc), modalStyle,
3776 std::move(onAppear), std::move(onDisappear), std::move(onWillAppear), std::move(onWillDisappear),
3777 contentCoverParam, targetNode, sessionId);
3778 }
3779
OnBindContentCover(bool isShow,std::function<void (const std::string &)> && callback,std::function<RefPtr<UINode> ()> && buildNodeFunc,NG::ModalStyle & modalStyle,std::function<void ()> && onAppear,std::function<void ()> && onDisappear,std::function<void ()> && onWillAppear,std::function<void ()> && onWillDisappear,const NG::ContentCoverParam & contentCoverParam,const RefPtr<FrameNode> & targetNode,int32_t sessionId)3780 void OverlayManager::OnBindContentCover(bool isShow, std::function<void(const std::string&)>&& callback,
3781 std::function<RefPtr<UINode>()>&& buildNodeFunc, NG::ModalStyle& modalStyle, std::function<void()>&& onAppear,
3782 std::function<void()>&& onDisappear, std::function<void()>&& onWillAppear, std::function<void()>&& onWillDisappear,
3783 const NG::ContentCoverParam& contentCoverParam, const RefPtr<FrameNode>& targetNode, int32_t sessionId)
3784 {
3785 int32_t targetId = targetNode ? targetNode->GetId() : sessionId;
3786 auto rootNode = FindWindowScene(targetNode);
3787 CHECK_NULL_VOID(rootNode);
3788 if (isShow) {
3789 auto modalTransition = modalStyle.modalTransition;
3790 if (!modalTransition.has_value()) {
3791 modalTransition = ModalTransition::DEFAULT;
3792 }
3793 auto targetModalNode = GetModal(targetId);
3794 if (targetModalNode) {
3795 const auto& targetModalPattern = targetModalNode->GetPattern<ModalPresentationPattern>();
3796 CHECK_NULL_VOID(targetModalPattern);
3797 auto modalRenderContext = targetModalNode->GetRenderContext();
3798 CHECK_NULL_VOID(modalRenderContext);
3799 if (modalStyle.backgroundColor.has_value()) {
3800 modalRenderContext->UpdateBackgroundColor(modalStyle.backgroundColor.value());
3801 }
3802 targetModalPattern->UpdateOnDisappear(std::move(onDisappear));
3803 targetModalPattern->UpdateOnWillDisappear(std::move(onWillDisappear));
3804 targetModalPattern->UpdateOnAppear(std::move(onAppear));
3805 targetModalPattern->UpdateOnWillDismiss(std::move(contentCoverParam.onWillDismiss));
3806 targetModalPattern->SetType(modalTransition.value());
3807 targetModalPattern->SetHasTransitionEffect(contentCoverParam.transitionEffect != nullptr);
3808 modalRenderContext->UpdateChainedTransition(contentCoverParam.transitionEffect);
3809 return;
3810 }
3811 if (onWillAppear) {
3812 onWillAppear();
3813 }
3814 HandleModalShow(std::move(callback), std::move(buildNodeFunc), modalStyle, std::move(onAppear),
3815 std::move(onDisappear), std::move(onWillDisappear), rootNode, contentCoverParam, targetId, modalTransition);
3816 return;
3817 }
3818
3819 // isShow = false, Pop ModalPage
3820 if (!modalStack_.empty()) {
3821 HandleModalPop(std::move(onWillDisappear), rootNode, targetId);
3822 }
3823 }
3824
HandleModalShow(std::function<void (const std::string &)> && callback,std::function<RefPtr<UINode> ()> && buildNodeFunc,NG::ModalStyle & modalStyle,std::function<void ()> && onAppear,std::function<void ()> && onDisappear,std::function<void ()> && onWillDisappear,const RefPtr<UINode> rootNode,const NG::ContentCoverParam & contentCoverParam,int32_t targetId,std::optional<ModalTransition> modalTransition)3825 void OverlayManager::HandleModalShow(std::function<void(const std::string&)>&& callback,
3826 std::function<RefPtr<UINode>()>&& buildNodeFunc, NG::ModalStyle& modalStyle, std::function<void()>&& onAppear,
3827 std::function<void()>&& onDisappear, std::function<void()>&& onWillDisappear, const RefPtr<UINode> rootNode,
3828 const NG::ContentCoverParam& contentCoverParam, int32_t targetId, std::optional<ModalTransition> modalTransition)
3829 {
3830 // builder content
3831 auto builder = AceType::DynamicCast<FrameNode>(buildNodeFunc());
3832 CHECK_NULL_VOID(builder);
3833 builder->GetRenderContext()->SetIsModalRootNode(true);
3834
3835 // create modal page
3836 auto modalNode = FrameNode::CreateFrameNode(V2::MODAL_PAGE_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
3837 AceType::MakeRefPtr<ModalPresentationPattern>(
3838 targetId, static_cast<ModalTransition>(modalTransition.value()), std::move(callback)));
3839 if (modalStyle.backgroundColor.has_value()) {
3840 modalNode->GetRenderContext()->UpdateBackgroundColor(modalStyle.backgroundColor.value());
3841 }
3842 auto modalPagePattern = modalNode->GetPattern<ModalPresentationPattern>();
3843 CHECK_NULL_VOID(modalPagePattern);
3844 modalPagePattern->UpdateOnDisappear(std::move(onDisappear));
3845 modalPagePattern->UpdateOnWillDisappear(std::move(onWillDisappear));
3846 modalPagePattern->UpdateOnAppear(std::move(onAppear));
3847 modalPagePattern->UpdateOnWillDismiss(std::move(contentCoverParam.onWillDismiss));
3848 modalPagePattern->UpdateUIExtensionMode(modalStyle.isUIExtension);
3849 modalPagePattern->SetProhibitedRemoveByRouter(modalStyle.prohibitedRemoveByRouter);
3850 modalPagePattern->SetProhibitedRemoveByNavigation(modalStyle.prohibitedRemoveByNavigation);
3851 modalPagePattern->SetHasTransitionEffect(contentCoverParam.transitionEffect != nullptr);
3852 modalNode->GetRenderContext()->UpdateChainedTransition(contentCoverParam.transitionEffect);
3853 modalStack_.push(WeakClaim(RawPtr(modalNode)));
3854 modalList_.emplace_back(WeakClaim(RawPtr(modalNode)));
3855 SaveLastModalNode();
3856 if (targetId < 0) {
3857 // modaluiextention node mounting
3858 modalNode->MountToParent(rootNode, DEFAULT_NODE_SLOT, false, false, true);
3859 } else {
3860 MountToParentWithService(rootNode, modalNode);
3861 }
3862 modalNode->AddChild(builder);
3863 if (!isAllowedBeCovered_ && modalNode->GetParent()) {
3864 TAG_LOGI(AceLogTag::ACE_OVERLAY,
3865 "modalNode->GetParent() %{public}d mark IsProhibitedAddChildNode when sessionId %{public}d,"
3866 "prohibitedRemoveByRouter: %{public}d.",
3867 modalNode->GetParent()->GetId(), targetId, modalStyle.prohibitedRemoveByRouter);
3868 if (AddCurSessionId(targetId)) {
3869 modalNode->GetParent()->UpdateModalUiextensionCount(true);
3870 }
3871 }
3872
3873 FireModalPageShow();
3874 modalNode->GetParent()->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
3875 if (contentCoverParam.transitionEffect != nullptr) {
3876 PlayTransitionEffectIn(modalNode);
3877 return;
3878 }
3879 if (!AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE) ||
3880 modalTransition == ModalTransition::NONE) {
3881 modalPagePattern->OnAppear();
3882 // Fire hidden event of navdestination under the appeared modal
3883 FireNavigationStateChange(false);
3884 }
3885 modalNode->OnAccessibilityEvent(
3886 AccessibilityEventType::PAGE_OPEN, WindowsContentChangeTypes::CONTENT_CHANGE_TYPE_SUBTREE);
3887 if (modalTransition == ModalTransition::DEFAULT) {
3888 PlayDefaultModalTransition(modalNode, true);
3889 } else if (modalTransition == ModalTransition::ALPHA) {
3890 PlayAlphaModalTransition(modalNode, true);
3891 }
3892 }
3893
HandleModalPop(std::function<void ()> && onWillDisappear,const RefPtr<UINode> rootNode,int32_t targetId)3894 void OverlayManager::HandleModalPop(
3895 std::function<void()>&& onWillDisappear, const RefPtr<UINode> rootNode, int32_t targetId)
3896 {
3897 auto topModalNode = GetModal(targetId);
3898 CHECK_NULL_VOID(topModalNode);
3899 if (!CheckTopModalNode(topModalNode, targetId)) {
3900 return;
3901 }
3902 auto builder = AceType::DynamicCast<FrameNode>(topModalNode->GetFirstChild());
3903 CHECK_NULL_VOID(builder);
3904 if (builder->GetRenderContext()->HasDisappearTransition()) {
3905 if (!topModalNode->GetPattern<ModalPresentationPattern>()->IsExecuteOnDisappear()) {
3906 topModalNode->GetPattern<ModalPresentationPattern>()->OnDisappear();
3907 // Fire hidden event of navdestination on the disappeared modal
3908 FireNavigationStateChange(false, topModalNode);
3909 }
3910 topModalNode->Clean(false, true);
3911 topModalNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
3912 }
3913 auto modalPresentationPattern = topModalNode->GetPattern<ModalPresentationPattern>();
3914 CHECK_NULL_VOID(modalPresentationPattern);
3915 auto modalTransition = modalPresentationPattern->GetType();
3916 // lost focus
3917 ModalPageLostFocus(topModalNode);
3918 if (onWillDisappear) {
3919 onWillDisappear();
3920 }
3921 topModalNode->OnAccessibilityEvent(
3922 AccessibilityEventType::PAGE_CLOSE, WindowsContentChangeTypes::CONTENT_CHANGE_TYPE_SUBTREE);
3923 if (modalPresentationPattern->HasTransitionEffect()) {
3924 PlayTransitionEffectOut(topModalNode);
3925 } else if (modalTransition == ModalTransition::DEFAULT) {
3926 PlayDefaultModalTransition(topModalNode, false);
3927 } else if (modalTransition == ModalTransition::ALPHA) {
3928 PlayAlphaModalTransition(topModalNode, false);
3929 } else if (!builder->GetRenderContext()->HasDisappearTransition()) {
3930 if (!modalPresentationPattern->IsExecuteOnDisappear()) {
3931 modalPresentationPattern->OnDisappear();
3932 // Fire hidden event of navdestination on the disappeared modal
3933 FireNavigationStateChange(false, topModalNode);
3934 }
3935 FireAutoSave(topModalNode);
3936 RemoveChildWithService(rootNode, topModalNode);
3937 rootNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
3938 }
3939 RemoveModal(targetId);
3940 if (modalTransition == ModalTransition::NONE || builder->GetRenderContext()->HasDisappearTransition()) {
3941 // Fire shown event of navdestination under the disappeared modal
3942 FireNavigationStateChange(true);
3943 }
3944 FireModalPageHide();
3945 SaveLastModalNode();
3946 }
3947
FireModalPageShow()3948 void OverlayManager::FireModalPageShow()
3949 {
3950 auto topModalNode = modalList_.back().Upgrade();
3951 CHECK_NULL_VOID(topModalNode);
3952 auto topModalFocusView = topModalNode->GetPattern<FocusView>();
3953 CHECK_NULL_VOID(topModalFocusView);
3954 topModalFocusView->FocusViewShow();
3955 }
3956
ModalPageLostFocus(const RefPtr<FrameNode> & node)3957 void OverlayManager::ModalPageLostFocus(const RefPtr<FrameNode>& node)
3958 {
3959 InputMethodManager::GetInstance()->ProcessModalPageScene();
3960 }
3961
FireModalPageHide()3962 void OverlayManager::FireModalPageHide() {}
3963
PlayDefaultModalTransition(const RefPtr<FrameNode> & modalNode,bool isTransitionIn)3964 void OverlayManager::PlayDefaultModalTransition(const RefPtr<FrameNode>& modalNode, bool isTransitionIn)
3965 {
3966 // current modal animation
3967 AnimationOption option;
3968 const RefPtr<InterpolatingSpring> curve =
3969 AceType::MakeRefPtr<InterpolatingSpring>(0.0f, CURVE_MASS, CURVE_STIFFNESS, CURVE_DAMPING);
3970 option.SetCurve(curve);
3971 option.SetFillMode(FillMode::FORWARDS);
3972 auto context = modalNode->GetRenderContext();
3973 CHECK_NULL_VOID(context);
3974
3975 auto rootHeight = GetRootHeight();
3976 auto modalPositionY = modalNode->GetGeometryNode()->GetFrameRect().GetY();
3977 auto showHeight = rootHeight - modalPositionY;
3978
3979 if (isTransitionIn) {
3980 PlayDefaultModalIn(modalNode, context, option, showHeight);
3981 } else {
3982 PlayDefaultModalOut(modalNode, context, option, showHeight);
3983 }
3984 }
3985
PlayDefaultModalIn(const RefPtr<FrameNode> & modalNode,const RefPtr<RenderContext> & context,AnimationOption option,float showHeight)3986 void OverlayManager::PlayDefaultModalIn(
3987 const RefPtr<FrameNode>& modalNode, const RefPtr<RenderContext>& context, AnimationOption option, float showHeight)
3988 {
3989 context->OnTransformTranslateUpdate({ 0.0f, showHeight, 0.0f });
3990 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
3991 option.SetOnFinishEvent([modalWK = WeakClaim(RawPtr(modalNode)), overlayWeak = WeakClaim(this)] {
3992 auto modal = modalWK.Upgrade();
3993 auto overlayManager = overlayWeak.Upgrade();
3994 CHECK_NULL_VOID(modal && overlayManager);
3995 modal->GetPattern<ModalPresentationPattern>()->OnAppear();
3996 // Fire hidden event of navdestination on the disappeared modal
3997 overlayManager->FireNavigationStateChange(false);
3998 });
3999 }
4000 AnimationUtils::Animate(
4001 option,
4002 [context]() {
4003 if (context) {
4004 context->OnTransformTranslateUpdate({ 0.0f, 0.0f, 0.0f });
4005 }
4006 },
4007 option.GetOnFinishEvent());
4008 }
4009
PlayDefaultModalOut(const RefPtr<FrameNode> & modalNode,const RefPtr<RenderContext> & context,AnimationOption option,float showHeight)4010 void OverlayManager::PlayDefaultModalOut(
4011 const RefPtr<FrameNode>& modalNode, const RefPtr<RenderContext>& context, AnimationOption option, float showHeight)
4012 {
4013 auto lastModalNode = lastModalNode_.Upgrade();
4014 CHECK_NULL_VOID(lastModalNode);
4015 auto lastModalContext = lastModalNode->GetRenderContext();
4016 CHECK_NULL_VOID(lastModalContext);
4017 lastModalContext->UpdateOpacity(1.0);
4018 option.SetOnFinishEvent(
4019 [rootWeak = rootNodeWeak_, modalWK = WeakClaim(RawPtr(modalNode)), overlayWeak = WeakClaim(this)] {
4020 auto modal = modalWK.Upgrade();
4021 auto overlayManager = overlayWeak.Upgrade();
4022 CHECK_NULL_VOID(modal && overlayManager);
4023 auto root = overlayManager->FindWindowScene(modal);
4024 CHECK_NULL_VOID(root);
4025 if (!modal->GetPattern<ModalPresentationPattern>()->IsExecuteOnDisappear()) {
4026 modal->GetPattern<ModalPresentationPattern>()->OnDisappear();
4027 // Fire hidden event of navdestination on the disappeared modal
4028 overlayManager->FireNavigationStateChange(false, modal);
4029 }
4030 overlayManager->FireAutoSave(modal);
4031 overlayManager->RemoveChildWithService(root, modal);
4032 root->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
4033 // Fire shown event of navdestination under the disappeared modal
4034 overlayManager->FireNavigationStateChange(true);
4035 });
4036 context->OnTransformTranslateUpdate({ 0.0f, 0.0f, 0.0f });
4037 AnimationUtils::Animate(
4038 option,
4039 [context, showHeight]() {
4040 if (context) {
4041 context->OnTransformTranslateUpdate({ 0.0f, showHeight, 0.0f });
4042 }
4043 },
4044 option.GetOnFinishEvent());
4045 }
4046
PlayAlphaModalTransition(const RefPtr<FrameNode> & modalNode,bool isTransitionIn)4047 void OverlayManager::PlayAlphaModalTransition(const RefPtr<FrameNode>& modalNode, bool isTransitionIn)
4048 {
4049 AnimationOption option;
4050 option.SetCurve(Curves::FRICTION);
4051 option.SetDuration(FULL_MODAL_ALPHA_ANIMATION_DURATION);
4052 option.SetFillMode(FillMode::FORWARDS);
4053 auto lastModalNode = lastModalNode_.Upgrade();
4054 CHECK_NULL_VOID(lastModalNode);
4055 auto lastModalContext = lastModalNode->GetRenderContext();
4056 CHECK_NULL_VOID(lastModalContext);
4057 auto context = modalNode->GetRenderContext();
4058 CHECK_NULL_VOID(context);
4059 if (isTransitionIn) {
4060 // last page animation
4061 lastModalContext->OpacityAnimation(option, 1, 0);
4062 lastModalContext->UpdateOpacity(0);
4063 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
4064 option.SetOnFinishEvent([modalWK = WeakClaim(RawPtr(modalNode)), overlayWeak = WeakClaim(this)] {
4065 auto modal = modalWK.Upgrade();
4066 auto overlayManager = overlayWeak.Upgrade();
4067 CHECK_NULL_VOID(modal && overlayManager);
4068 modal->GetPattern<ModalPresentationPattern>()->OnAppear();
4069 // Fire hidden event of navdestination on the disappeared modal
4070 overlayManager->FireNavigationStateChange(false);
4071 });
4072 }
4073 // current modal page animation
4074 context->OpacityAnimation(option, 0, 1);
4075 } else {
4076 // last page animation
4077 lastModalContext->OpacityAnimation(option, 0, 1);
4078
4079 // current modal page animation
4080 option.SetOnFinishEvent(
4081 [rootWeak = rootNodeWeak_, modalWK = WeakClaim(RawPtr(modalNode)), overlayWeak = WeakClaim(this)] {
4082 auto modal = modalWK.Upgrade();
4083 auto overlayManager = overlayWeak.Upgrade();
4084 CHECK_NULL_VOID(modal && overlayManager);
4085 auto root = overlayManager->FindWindowScene(modal);
4086 CHECK_NULL_VOID(root);
4087 if (!modal->GetPattern<ModalPresentationPattern>()->IsExecuteOnDisappear()) {
4088 modal->GetPattern<ModalPresentationPattern>()->OnDisappear();
4089 // Fire hidden event of navdestination on the disappeared modal
4090 overlayManager->FireNavigationStateChange(false, modal);
4091 }
4092 overlayManager->FireAutoSave(modal);
4093 overlayManager->RemoveChildWithService(root, modal);
4094 root->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
4095 // Fire shown event of navdestination under the disappeared modal
4096 overlayManager->FireNavigationStateChange(true);
4097 });
4098 context->OpacityAnimation(option, 1, 0);
4099 }
4100 }
4101
BindSheet(bool isShow,std::function<void (const std::string &)> && callback,std::function<RefPtr<UINode> ()> && buildNodeFunc,std::function<RefPtr<UINode> ()> && buildtitleNodeFunc,NG::SheetStyle & sheetStyle,std::function<void ()> && onAppear,std::function<void ()> && onDisappear,std::function<void ()> && shouldDismiss,std::function<void (const int32_t)> && onWillDismiss,std::function<void ()> && onWillAppear,std::function<void ()> && onWillDisappear,std::function<void (const float)> && onHeightDidChange,std::function<void (const float)> && onDetentsDidChange,std::function<void (const float)> && onWidthDidChange,std::function<void (const float)> && onTypeDidChange,std::function<void ()> && sheetSpringBack,const RefPtr<FrameNode> & targetNode)4102 void OverlayManager::BindSheet(bool isShow, std::function<void(const std::string&)>&& callback,
4103 std::function<RefPtr<UINode>()>&& buildNodeFunc, std::function<RefPtr<UINode>()>&& buildtitleNodeFunc,
4104 NG::SheetStyle& sheetStyle, std::function<void()>&& onAppear, std::function<void()>&& onDisappear,
4105 std::function<void()>&& shouldDismiss, std::function<void(const int32_t)>&& onWillDismiss,
4106 std::function<void()>&& onWillAppear, std::function<void()>&& onWillDisappear,
4107 std::function<void(const float)>&& onHeightDidChange, std::function<void(const float)>&& onDetentsDidChange,
4108 std::function<void(const float)>&& onWidthDidChange, std::function<void(const float)>&& onTypeDidChange,
4109 std::function<void()>&& sheetSpringBack, const RefPtr<FrameNode>& targetNode)
4110 {
4111 auto instanceId = sheetStyle.instanceId.has_value() ? sheetStyle.instanceId.value() : Container::CurrentId();
4112 ContainerScope scope(instanceId);
4113 auto pipeline = PipelineContext::GetCurrentContext();
4114 CHECK_NULL_VOID(pipeline);
4115 auto bindSheetTask = [weak = AceType::WeakClaim(this), isShow, callback = std::move(callback),
4116 buildNodeFunc = std::move(buildNodeFunc),
4117 buildtitleNodeFunc = std::move(buildtitleNodeFunc), sheetStyle,
4118 onAppear = std::move(onAppear), onDisappear = std::move(onDisappear),
4119 shouldDismiss = std::move(shouldDismiss), onWillDismiss = std::move(onWillDismiss),
4120 onWillAppear = std::move(onWillAppear), onWillDisappear = std::move(onWillDisappear),
4121 onHeightDidChange = std::move(onHeightDidChange),
4122 onDetentsDidChange = std::move(onDetentsDidChange),
4123 onWidthDidChange = std::move(onWidthDidChange),
4124 onTypeDidChange = std::move(onTypeDidChange), sheetSpringBack = std::move(sheetSpringBack),
4125 targetNode, instanceId]() mutable {
4126 ContainerScope scope(instanceId);
4127 auto overlay = weak.Upgrade();
4128 CHECK_NULL_VOID(overlay);
4129 overlay->OnBindSheet(isShow, std::move(callback), std::move(buildNodeFunc), std::move(buildtitleNodeFunc),
4130 sheetStyle, std::move(onAppear), std::move(onDisappear), std::move(shouldDismiss), std::move(onWillDismiss),
4131 std::move(onWillAppear), std::move(onWillDisappear), std::move(onHeightDidChange),
4132 std::move(onDetentsDidChange), std::move(onWidthDidChange), std::move(onTypeDidChange),
4133 std::move(sheetSpringBack), targetNode);
4134 auto pipeline = PipelineContext::GetCurrentContext();
4135 CHECK_NULL_VOID(pipeline);
4136 pipeline->FlushUITasks();
4137 };
4138 pipeline->RequestFrame();
4139 pipeline->AddAnimationClosure(bindSheetTask);
4140 }
4141
UpdateSheetMaskBackgroundColor(const RefPtr<FrameNode> & maskNode,const RefPtr<RenderContext> & maskRenderContext,const SheetStyle & sheetStyle)4142 void OverlayManager::UpdateSheetMaskBackgroundColor(
4143 const RefPtr<FrameNode>& maskNode, const RefPtr<RenderContext>& maskRenderContext, const SheetStyle& sheetStyle)
4144 {
4145 if (sheetStyle.maskColor.has_value()) {
4146 maskRenderContext->UpdateBackgroundColor(sheetStyle.maskColor.value());
4147 } else {
4148 maskNode->GetEventHub<EventHub>()->GetOrCreateGestureEventHub()->SetHitTestMode(
4149 HitTestMode::HTMTRANSPARENT);
4150 maskRenderContext->UpdateBackgroundColor(Color::TRANSPARENT);
4151 }
4152 }
4153
InitSheetMask(const RefPtr<FrameNode> & maskNode,const RefPtr<FrameNode> & sheetNode,const SheetStyle & sheetStyle)4154 void OverlayManager::InitSheetMask(
4155 const RefPtr<FrameNode>& maskNode, const RefPtr<FrameNode>& sheetNode, const SheetStyle& sheetStyle)
4156 {
4157 auto maskRenderContext = maskNode->GetRenderContext();
4158 CHECK_NULL_VOID(maskRenderContext);
4159 auto pipeline = PipelineContext::GetCurrentContext();
4160 CHECK_NULL_VOID(pipeline);
4161 auto sheetTheme = pipeline->GetTheme<SheetTheme>();
4162 CHECK_NULL_VOID(sheetTheme);
4163 auto sheetLayoutProps = sheetNode->GetLayoutProperty<SheetPresentationProperty>();
4164 CHECK_NULL_VOID(sheetLayoutProps);
4165 maskNode->GetEventHub<EventHub>()->GetOrCreateGestureEventHub()->SetHitTestMode(HitTestMode::HTMDEFAULT);
4166 if (!AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
4167 UpdateSheetMaskBackgroundColor(maskNode, maskRenderContext, sheetStyle);
4168 } else {
4169 auto eventConfirmHub = maskNode->GetOrCreateGestureEventHub();
4170 CHECK_NULL_VOID(eventConfirmHub);
4171 auto sheetMaskClickEvent = AceType::MakeRefPtr<NG::ClickEvent>(
4172 [weak = AceType::WeakClaim(AceType::RawPtr(sheetNode))](const GestureEvent& /* info */) {
4173 auto sheet = weak.Upgrade();
4174 CHECK_NULL_VOID(sheet);
4175 auto sheetPattern = sheet->GetPattern<SheetPresentationPattern>();
4176 CHECK_NULL_VOID(sheetPattern);
4177 if (sheetPattern->IsDragging()) {
4178 return;
4179 }
4180 sheetPattern->SheetInteractiveDismiss(BindSheetDismissReason::TOUCH_OUTSIDE);
4181 });
4182 auto maskNodeId = maskNode->GetId();
4183 sheetMaskClickEventMap_.emplace(maskNodeId, sheetMaskClickEvent);
4184 eventConfirmHub->AddClickEvent(sheetMaskClickEvent, DISTANCE_THRESHOLD);
4185 if (!sheetStyle.interactive.has_value()) {
4186 if (sheetNode->GetPattern<SheetPresentationPattern>()->GetSheetType() == SheetType::SHEET_POPUP) {
4187 maskNode->GetEventHub<EventHub>()->GetOrCreateGestureEventHub()->SetHitTestMode(
4188 HitTestMode::HTMTRANSPARENT);
4189 eventConfirmHub->RemoveClickEvent(sheetMaskClickEvent);
4190 sheetMaskClickEventMap_.erase(maskNodeId);
4191 }
4192 } else if (sheetStyle.interactive == true) {
4193 maskNode->GetEventHub<EventHub>()->GetOrCreateGestureEventHub()->SetHitTestMode(
4194 HitTestMode::HTMTRANSPARENT);
4195 eventConfirmHub->RemoveClickEvent(sheetMaskClickEvent);
4196 sheetMaskClickEventMap_.erase(maskNodeId);
4197 }
4198 }
4199 }
4200
CleanInvalidModalNode(const WeakPtr<FrameNode> & invalidNode)4201 void OverlayManager::CleanInvalidModalNode(const WeakPtr<FrameNode>& invalidNode)
4202 {
4203 // When a modalNode.Upgrade() == nullptr, the modalNode is invalid
4204 modalList_.remove(invalidNode);
4205 std::vector<WeakPtr<FrameNode>> sheetVector;
4206 while (!modalStack_.empty()) {
4207 if (modalStack_.top() != invalidNode) {
4208 sheetVector.push_back(modalStack_.top());
4209 }
4210 modalStack_.pop();
4211 }
4212 for (auto iter = sheetVector.rbegin(); iter != sheetVector.rend(); ++iter) {
4213 modalStack_.push(*iter);
4214 }
4215 }
4216
CloseSheet(const SheetKey & sheetKey)4217 void OverlayManager::CloseSheet(const SheetKey& sheetKey)
4218 {
4219 if (modalStack_.empty()) {
4220 return;
4221 }
4222 auto iter = sheetMap_.find(sheetKey);
4223 if (sheetMap_.empty() || iter == sheetMap_.end()) {
4224 DeleteModal(sheetKey.targetId);
4225 return;
4226 }
4227 auto sheetNode = iter->second.Upgrade();
4228 if (sheetNode == nullptr) {
4229 TAG_LOGE(AceLogTag::ACE_SHEET, "The sheetNode is null, clean it.");
4230 CleanViewContextMap(Container::CurrentId(), sheetKey.contentId);
4231 CleanInvalidModalNode(iter->second);
4232 sheetMap_.erase(sheetKey);
4233 SaveLastModalNode();
4234 return;
4235 }
4236 auto sheetPattern = sheetNode->GetPattern<SheetPresentationPattern>();
4237 CHECK_NULL_VOID(sheetPattern);
4238 sheetPattern->SetShowState(false);
4239 auto buildContent = sheetPattern->GetFirstFrameNodeOfBuilder();
4240 CHECK_NULL_VOID(buildContent);
4241 auto buildRenderContext = buildContent->GetRenderContext();
4242 CHECK_NULL_VOID(buildRenderContext);
4243 sheetPattern->OnWillDisappear();
4244 if (buildRenderContext->HasDisappearTransition()) {
4245 if (!sheetPattern->IsExecuteOnDisappear()) {
4246 sheetPattern->OnDisappear();
4247 }
4248 sheetPattern->OnDisappear();
4249 sheetNode->Clean(false, true);
4250 sheetNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
4251 }
4252 ModalPageLostFocus(sheetNode);
4253 PlaySheetTransitionWhenClose(sheetNode);
4254 sheetPattern->SetDismissProcess(true);
4255 sheetMap_.erase(sheetKey);
4256 CleanViewContextMap(Container::CurrentId(), sheetKey.contentId);
4257 RemoveSheetNode(sheetNode);
4258 FireModalPageHide();
4259 SaveLastModalNode();
4260 }
4261
PlaySheetTransitionWhenClose(const RefPtr<FrameNode> & sheetNode)4262 void OverlayManager::PlaySheetTransitionWhenClose(const RefPtr<FrameNode>& sheetNode)
4263 {
4264 CHECK_NULL_VOID(sheetNode);
4265 auto maskNode = GetSheetMask(sheetNode);
4266 if (maskNode) {
4267 PlaySheetMaskTransition(maskNode, false);
4268 }
4269 auto sheetPattern = sheetNode->GetPattern<SheetPresentationPattern>();
4270 CHECK_NULL_VOID(sheetPattern);
4271 auto sheetType = sheetPattern->GetSheetType();
4272 if (sheetType == SheetType::SHEET_POPUP) {
4273 PlayBubbleStyleSheetTransition(sheetNode, false);
4274 } else {
4275 PlaySheetTransition(sheetNode, false);
4276 }
4277 }
4278
DismissSheet()4279 void OverlayManager::DismissSheet()
4280 {
4281 if (modalStack_.empty()) {
4282 return;
4283 }
4284 auto iter = sheetMap_.find(dismissTarget_.sheetKey);
4285 if (sheetMap_.empty() || iter == sheetMap_.end()) {
4286 DeleteModal(dismissTarget_.GetTargetId());
4287 return;
4288 }
4289 auto sheetNode = iter->second.Upgrade();
4290 CHECK_NULL_VOID(sheetNode);
4291 if (sheetNode->GetTag() == V2::SHEET_PAGE_TAG) {
4292 auto sheetPattern = sheetNode->GetPattern<SheetPresentationPattern>();
4293 CHECK_NULL_VOID(sheetPattern);
4294 sheetPattern->DismissSheet();
4295 }
4296 }
4297
DismissContentCover()4298 void OverlayManager::DismissContentCover()
4299 {
4300 if (modalStack_.empty()) {
4301 return;
4302 }
4303 const auto& modalNode = GetModal(dismissTarget_.GetTargetId());
4304 if (modalNode == nullptr) {
4305 DeleteModal(dismissTarget_.GetTargetId());
4306 return;
4307 }
4308 if (modalNode->GetTag() == V2::MODAL_PAGE_TAG) {
4309 ModalPageLostFocus(modalNode);
4310 auto builder = AceType::DynamicCast<FrameNode>(modalNode->GetFirstChild());
4311 if (!ModalPageExitProcess(modalNode)) {
4312 return;
4313 }
4314 RemoveModal(dismissTarget_.GetTargetId());
4315 auto modalPattern = modalNode->GetPattern<ModalPresentationPattern>();
4316 CHECK_NULL_VOID(modalPattern);
4317 auto modalTransition = modalPattern->GetType();
4318 if (modalTransition == ModalTransition::NONE || builder->GetRenderContext()->HasDisappearTransition()) {
4319 FireNavigationStateChange(true);
4320 }
4321 FireModalPageHide();
4322 SaveLastModalNode();
4323 }
4324 }
4325
SheetSpringBack()4326 void OverlayManager::SheetSpringBack()
4327 {
4328 auto sheetNode = sheetMap_[dismissTarget_.sheetKey].Upgrade();
4329 CHECK_NULL_VOID(sheetNode);
4330 if (sheetNode->GetTag() == V2::SHEET_PAGE_TAG) {
4331 auto sheetPattern = sheetNode->GetPattern<SheetPresentationPattern>();
4332 CHECK_NULL_VOID(sheetPattern);
4333 sheetPattern->SheetSpringBack();
4334 }
4335 }
4336
GetModal(int32_t targetId)4337 RefPtr<FrameNode> OverlayManager::GetModal(int32_t targetId)
4338 {
4339 for (auto modal = modalList_.begin(); modal != modalList_.end(); modal++) {
4340 auto modalNode = (*modal).Upgrade();
4341 if (!modalNode) {
4342 continue;
4343 }
4344 int32_t modalTargetId = -1;
4345 if (modalNode->GetTag() == V2::MODAL_PAGE_TAG) {
4346 modalTargetId = modalNode->GetPattern<ModalPresentationPattern>()->GetTargetId();
4347 } else {
4348 continue;
4349 }
4350 if (modalTargetId == targetId) {
4351 return modalNode;
4352 }
4353 }
4354 return nullptr;
4355 }
4356
RemoveModal(int32_t targetId)4357 void OverlayManager::RemoveModal(int32_t targetId)
4358 {
4359 bool isDelete = false;
4360 for (auto modal = modalList_.begin(); modal != modalList_.end(); modal++) {
4361 auto modalNode = (*modal).Upgrade();
4362 if (!modalNode) {
4363 continue;
4364 }
4365 int32_t modalTargetId = -1;
4366 if (modalNode->GetTag() == V2::MODAL_PAGE_TAG) {
4367 modalTargetId = modalNode->GetPattern<ModalPresentationPattern>()->GetTargetId();
4368 } else {
4369 continue;
4370 }
4371 if (modalTargetId == targetId) {
4372 isDelete = true;
4373 modalList_.erase(modal);
4374 break;
4375 }
4376 }
4377 if (isDelete) {
4378 while (!modalStack_.empty()) {
4379 modalStack_.pop();
4380 }
4381 for (auto modal = modalList_.begin(); modal != modalList_.end(); modal++) {
4382 modalStack_.push(*modal);
4383 }
4384 }
4385 }
4386
RemoveSheetNode(const RefPtr<FrameNode> & sheetNode)4387 void OverlayManager::RemoveSheetNode(const RefPtr<FrameNode>& sheetNode)
4388 {
4389 CHECK_NULL_VOID(sheetNode);
4390 if (!modalList_.empty()) {
4391 modalList_.remove(WeakClaim(RawPtr(sheetNode)));
4392 }
4393 std::vector<WeakPtr<FrameNode>> sheetVector;
4394 while (!modalStack_.empty()) {
4395 if (modalStack_.top() != WeakClaim(RawPtr(sheetNode))) {
4396 sheetVector.push_back(modalStack_.top());
4397 }
4398 modalStack_.pop();
4399 }
4400 for (auto iter = sheetVector.rbegin(); iter != sheetVector.rend(); ++iter) {
4401 modalStack_.push(*iter);
4402 }
4403 }
4404
PlaySheetTransition(RefPtr<FrameNode> sheetNode,bool isTransitionIn,bool isFirstTransition)4405 void OverlayManager::PlaySheetTransition(
4406 RefPtr<FrameNode> sheetNode, bool isTransitionIn, bool isFirstTransition)
4407 {
4408 CHECK_NULL_VOID(sheetNode);
4409 sheetNode->OnAccessibilityEvent(
4410 isTransitionIn ? AccessibilityEventType::PAGE_OPEN : AccessibilityEventType::PAGE_CLOSE,
4411 WindowsContentChangeTypes::CONTENT_CHANGE_TYPE_SUBTREE);
4412
4413 // current sheet animation
4414 AnimationOption option;
4415 const RefPtr<InterpolatingSpring> curve =
4416 AceType::MakeRefPtr<InterpolatingSpring>(0.0f, CURVE_MASS, CURVE_STIFFNESS, CURVE_DAMPING);
4417 option.SetCurve(curve);
4418 option.SetFillMode(FillMode::FORWARDS);
4419 auto context = sheetNode->GetRenderContext();
4420 CHECK_NULL_VOID(context);
4421 context->UpdateRenderGroup(true, false, true);
4422 TAG_LOGD(AceLogTag::ACE_SHEET, "UpdateRenderGroup start");
4423 auto sheetPattern = sheetNode->GetPattern<SheetPresentationPattern>();
4424 CHECK_NULL_VOID(sheetPattern);
4425 auto sheetMaxHeight = sheetPattern->GetPageHeightWithoutOffset();
4426 auto sheetParent = DynamicCast<FrameNode>(sheetNode->GetParent());
4427 CHECK_NULL_VOID(sheetParent);
4428 if (isTransitionIn) {
4429 sheetPattern->SetCurrentHeight(sheetHeight_);
4430 float offset = 0.0f;
4431 auto sheetType = sheetPattern->GetSheetType();
4432 if (sheetType == SheetType::SHEET_POPUP || sheetPattern->IsCurSheetNeedHalfFoldHover()) {
4433 offset = sheetPattern->GetSheetOffset();
4434 } else {
4435 offset = sheetMaxHeight - sheetHeight_;
4436 }
4437 if (isFirstTransition) {
4438 context->UpdateTransformTranslate({ 0.0f, sheetMaxHeight, 0.0f });
4439 if (NearZero(sheetHeight_)) {
4440 return;
4441 }
4442 }
4443 if (sheetPattern->IsFoldStatusChanged()) {
4444 option.SetDuration(0);
4445 option.SetCurve(Curves::LINEAR);
4446 }
4447 sheetPattern->FireOnTypeDidChange();
4448 sheetPattern->FireOnWidthDidChange(sheetNode);
4449 option.SetOnFinishEvent(
4450 [sheetWK = WeakClaim(RawPtr(sheetNode)), weak = AceType::WeakClaim(this), isFirst = isFirstTransition] {
4451 auto sheetNode = sheetWK.Upgrade();
4452 CHECK_NULL_VOID(sheetNode);
4453 auto context = sheetNode->GetRenderContext();
4454 CHECK_NULL_VOID(context);
4455 context->UpdateRenderGroup(false, false, true);
4456 TAG_LOGD(AceLogTag::ACE_SHEET, "UpdateRenderGroup finished");
4457 auto pattern = sheetNode->GetPattern<SheetPresentationPattern>();
4458 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE) &&
4459 isFirst) {
4460 pattern->OnAppear();
4461 }
4462 pattern->AvoidAiBar();
4463 auto overlay = weak.Upgrade();
4464 CHECK_NULL_VOID(overlay);
4465 pattern->FireOnDetentsDidChange(overlay->sheetHeight_);
4466 pattern->FireOnHeightDidChange(overlay->sheetHeight_);
4467 });
4468 ACE_SCOPED_TRACE("Sheet start admission");
4469 AnimationUtils::Animate(
4470 option,
4471 [context, offset]() {
4472 if (context) {
4473 context->UpdateTransformTranslate({ 0.0f, offset, 0.0f });
4474 }
4475 },
4476 option.GetOnFinishEvent());
4477 } else {
4478 option.SetOnFinishEvent(
4479 [rootWeak = rootNodeWeak_, sheetWK = WeakClaim(RawPtr(sheetNode)), weakOverlayManager = WeakClaim(this)] {
4480 auto sheet = sheetWK.Upgrade();
4481 auto overlayManager = weakOverlayManager.Upgrade();
4482 CHECK_NULL_VOID(sheet && overlayManager);
4483 if (!sheet->GetPattern<SheetPresentationPattern>()->IsExecuteOnDisappear()) {
4484 sheet->GetPattern<SheetPresentationPattern>()->OnDisappear();
4485 }
4486 auto root = overlayManager->FindWindowScene(sheet);
4487 CHECK_NULL_VOID(root);
4488 auto sheetParent = DynamicCast<FrameNode>(sheet->GetParent());
4489 CHECK_NULL_VOID(sheetParent);
4490 overlayManager->FireAutoSave(sheet);
4491 overlayManager->RemoveChildWithService(root, sheetParent);
4492 root->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
4493 });
4494 sheetParent->GetEventHub<EventHub>()->GetOrCreateGestureEventHub()->SetHitTestMode(HitTestMode::HTMTRANSPARENT);
4495 AnimationUtils::Animate(
4496 option,
4497 [context, sheetMaxHeight]() {
4498 if (context) {
4499 context->UpdateTransformTranslate({ 0.0f, sheetMaxHeight, 0.0f });
4500 }
4501 },
4502 option.GetOnFinishEvent());
4503 }
4504 }
4505
OnBindSheet(bool isShow,std::function<void (const std::string &)> && callback,std::function<RefPtr<UINode> ()> && buildNodeFunc,std::function<RefPtr<UINode> ()> && buildtitleNodeFunc,NG::SheetStyle & sheetStyle,std::function<void ()> && onAppear,std::function<void ()> && onDisappear,std::function<void ()> && shouldDismiss,std::function<void (const int32_t)> && onWillDismiss,std::function<void ()> && onWillAppear,std::function<void ()> && onWillDisappear,std::function<void (const float)> && onHeightDidChange,std::function<void (const float)> && onDetentsDidChange,std::function<void (const float)> && onWidthDidChange,std::function<void (const float)> && onTypeDidChange,std::function<void ()> && sheetSpringBack,const RefPtr<FrameNode> & targetNode)4506 void OverlayManager::OnBindSheet(bool isShow, std::function<void(const std::string&)>&& callback,
4507 std::function<RefPtr<UINode>()>&& buildNodeFunc, std::function<RefPtr<UINode>()>&& buildtitleNodeFunc,
4508 NG::SheetStyle& sheetStyle, std::function<void()>&& onAppear, std::function<void()>&& onDisappear,
4509 std::function<void()>&& shouldDismiss, std::function<void(const int32_t)>&& onWillDismiss,
4510 std::function<void()>&& onWillAppear, std::function<void()>&& onWillDisappear,
4511 std::function<void(const float)>&& onHeightDidChange, std::function<void(const float)>&& onDetentsDidChange,
4512 std::function<void(const float)>&& onWidthDidChange, std::function<void(const float)>&& onTypeDidChange,
4513 std::function<void()>&& sheetSpringBack, const RefPtr<FrameNode>& targetNode)
4514 {
4515 int32_t targetId = targetNode->GetId();
4516 if (!isShow) {
4517 CloseSheet(SheetKey(targetId));
4518 return;
4519 }
4520 SheetKey sheetKey(targetId);
4521 auto iter = sheetMap_.find(sheetKey);
4522 if (iter != sheetMap_.end()) {
4523 auto sheetNode = iter->second.Upgrade();
4524 CHECK_NULL_VOID(sheetNode);
4525 UpdateSheetPage(sheetNode, sheetStyle, targetId, false, false,
4526 std::move(onAppear), std::move(onDisappear), std::move(shouldDismiss), std::move(onWillDismiss),
4527 std::move(onWillDisappear), std::move(onHeightDidChange),
4528 std::move(onDetentsDidChange), std::move(onWidthDidChange),
4529 std::move(onTypeDidChange), std::move(sheetSpringBack));
4530 return;
4531 }
4532 // build content
4533 RefPtr<UINode> sheetContentNode = buildNodeFunc();
4534 CHECK_NULL_VOID(sheetContentNode);
4535 auto frameChildNode = sheetContentNode->GetFrameChildByIndex(0, true);
4536 if (!frameChildNode) {
4537 // The function should return if the frameNodeChild of the builder is empty,
4538 // otherwise an exception will occur when unmount an empty node.
4539 TAG_LOGE(AceLogTag::ACE_SHEET, "sheet buildNode is nullptr");
4540 return;
4541 }
4542 OnBindSheetInner(std::move(callback), sheetContentNode, std::move(buildtitleNodeFunc),
4543 sheetStyle, std::move(onAppear), std::move(onDisappear), std::move(shouldDismiss), std::move(onWillDismiss),
4544 std::move(onWillAppear), std::move(onWillDisappear), std::move(onHeightDidChange),
4545 std::move(onDetentsDidChange), std::move(onWidthDidChange),
4546 std::move(onTypeDidChange), std::move(sheetSpringBack), targetNode);
4547 }
4548
OpenBindSheetByUIContext(const RefPtr<FrameNode> & sheetContentNode,std::function<RefPtr<UINode> ()> && buildtitleNodeFunc,NG::SheetStyle & sheetStyle,std::function<void ()> && onAppear,std::function<void ()> && onDisappear,std::function<void ()> && shouldDismiss,std::function<void (const int32_t)> && onWillDismiss,std::function<void ()> && onWillAppear,std::function<void ()> && onWillDisappear,std::function<void (const float)> && onHeightDidChange,std::function<void (const float)> && onDetentsDidChange,std::function<void (const float)> && onWidthDidChange,std::function<void (const float)> && onTypeDidChange,std::function<void ()> && sheetSpringBack,std::function<void (const int32_t,const int32_t)> cleanViewContextMapCallback,const RefPtr<FrameNode> & targetNode)4549 void OverlayManager::OpenBindSheetByUIContext(
4550 const RefPtr<FrameNode>& sheetContentNode, std::function<RefPtr<UINode>()>&& buildtitleNodeFunc,
4551 NG::SheetStyle& sheetStyle, std::function<void()>&& onAppear, std::function<void()>&& onDisappear,
4552 std::function<void()>&& shouldDismiss, std::function<void(const int32_t)>&& onWillDismiss,
4553 std::function<void()>&& onWillAppear, std::function<void()>&& onWillDisappear,
4554 std::function<void(const float)>&& onHeightDidChange,
4555 std::function<void(const float)>&& onDetentsDidChange,
4556 std::function<void(const float)>&& onWidthDidChange,
4557 std::function<void(const float)>&& onTypeDidChange,
4558 std::function<void()>&& sheetSpringBack,
4559 std::function<void(const int32_t, const int32_t)> cleanViewContextMapCallback,
4560 const RefPtr<FrameNode>& targetNode)
4561 {
4562 if (cleanViewContextMapCallback_ == nullptr) {
4563 cleanViewContextMapCallback_ = cleanViewContextMapCallback;
4564 }
4565 auto instanceId = sheetStyle.instanceId.has_value() ? sheetStyle.instanceId.value() : Container::CurrentId();
4566 ContainerScope scope(instanceId);
4567 OnBindSheetInner(nullptr, sheetContentNode, std::move(buildtitleNodeFunc),
4568 sheetStyle, std::move(onAppear), std::move(onDisappear), std::move(shouldDismiss), std::move(onWillDismiss),
4569 std::move(onWillAppear), std::move(onWillDisappear), std::move(onHeightDidChange),
4570 std::move(onDetentsDidChange), std::move(onWidthDidChange),
4571 std::move(onTypeDidChange), std::move(sheetSpringBack), targetNode, true);
4572 }
4573
UpdateBindSheetByUIContext(const RefPtr<NG::FrameNode> & sheetContentNode,NG::SheetStyle & sheetStyle,int32_t targetId,bool isPartialUpdate)4574 void OverlayManager::UpdateBindSheetByUIContext(
4575 const RefPtr<NG::FrameNode>& sheetContentNode, NG::SheetStyle& sheetStyle, int32_t targetId, bool isPartialUpdate)
4576 {
4577 SheetKey sheetKey;
4578 if (!CreateSheetKey(sheetContentNode, targetId, sheetKey)) {
4579 TAG_LOGE(AceLogTag::ACE_SHEET, "CreateSheetKey failed");
4580 return;
4581 }
4582 targetId = sheetKey.targetId;
4583 auto iter = sheetMap_.find(sheetKey);
4584 if (iter != sheetMap_.end()) {
4585 auto sheetNode = iter->second.Upgrade();
4586 CHECK_NULL_VOID(sheetNode);
4587 UpdateSheetPage(sheetNode, sheetStyle, targetId, true, isPartialUpdate);
4588 }
4589 TAG_LOGE(AceLogTag::ACE_SHEET, "Can not find sheet.");
4590 return;
4591 }
4592
UpdateSheetRender(const RefPtr<FrameNode> & sheetPageNode,NG::SheetStyle & sheetStyle,bool isPartialUpdate)4593 void OverlayManager::UpdateSheetRender(
4594 const RefPtr<FrameNode>& sheetPageNode, NG::SheetStyle& sheetStyle, bool isPartialUpdate)
4595 {
4596 CHECK_NULL_VOID(sheetPageNode);
4597 auto sheetRenderContext = sheetPageNode->GetRenderContext();
4598 CHECK_NULL_VOID(sheetRenderContext);
4599 auto pipeline = sheetPageNode->GetContext();
4600 CHECK_NULL_VOID(pipeline);
4601 auto sheetTheme = pipeline->GetTheme<SheetTheme>();
4602 CHECK_NULL_VOID(sheetTheme);
4603 SetSheetBackgroundColor(sheetPageNode, sheetTheme, sheetStyle);
4604 if (sheetStyle.backgroundBlurStyle.has_value()) {
4605 SetSheetBackgroundBlurStyle(sheetPageNode, sheetStyle.backgroundBlurStyle.value());
4606 }
4607 auto sheetNodePattern = sheetPageNode->GetPattern<SheetPresentationPattern>();
4608 CHECK_NULL_VOID(sheetNodePattern);
4609 sheetNodePattern->SetSheetBorderWidth();
4610 if (sheetStyle.borderStyle.has_value()) {
4611 sheetRenderContext->UpdateBorderStyle(sheetStyle.borderStyle.value());
4612 }
4613 if (sheetStyle.borderColor.has_value()) {
4614 sheetRenderContext->UpdateBorderColor(sheetStyle.borderColor.value());
4615 }
4616 if (sheetStyle.shadow.has_value()) {
4617 sheetRenderContext->UpdateBackShadow(sheetStyle.shadow.value());
4618 } else if (!isPartialUpdate) {
4619 sheetRenderContext->UpdateBackShadow(ShadowConfig::NoneShadow);
4620 }
4621 sheetNodePattern->UpdateMaskBackgroundColor();
4622 }
UpdateSheetProperty(const RefPtr<FrameNode> & sheetNode,NG::SheetStyle & currentStyle,bool isPartialUpdate)4623 void OverlayManager::UpdateSheetProperty(const RefPtr<FrameNode>& sheetNode,
4624 NG::SheetStyle& currentStyle, bool isPartialUpdate)
4625 {
4626 auto pipeline = sheetNode->GetContext();
4627 CHECK_NULL_VOID(pipeline);
4628 UpdateSheetRender(sheetNode, currentStyle, isPartialUpdate);
4629 auto maskNode = GetSheetMask(sheetNode);
4630 if (maskNode) {
4631 UpdateSheetMask(maskNode, sheetNode, currentStyle, isPartialUpdate);
4632 }
4633 sheetNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
4634 pipeline->FlushUITasks();
4635 ComputeSheetOffset(currentStyle, sheetNode);
4636 }
4637
UpdateSheetPage(const RefPtr<FrameNode> & sheetNode,NG::SheetStyle & sheetStyle,int32_t targetId,bool isStartByUIContext,bool isPartialUpdate,std::function<void ()> && onAppear,std::function<void ()> && onDisappear,std::function<void ()> && shouldDismiss,std::function<void (const int32_t)> && onWillDismiss,std::function<void ()> && onWillDisappear,std::function<void (const float)> && onHeightDidChange,std::function<void (const float)> && onDetentsDidChange,std::function<void (const float)> && onWidthDidChange,std::function<void (const float)> && onTypeDidChange,std::function<void ()> && sheetSpringBack)4638 void OverlayManager::UpdateSheetPage(const RefPtr<FrameNode>& sheetNode, NG::SheetStyle& sheetStyle,
4639 int32_t targetId, bool isStartByUIContext, bool isPartialUpdate,
4640 std::function<void()>&& onAppear, std::function<void()>&& onDisappear,
4641 std::function<void()>&& shouldDismiss, std::function<void(const int32_t)>&& onWillDismiss,
4642 std::function<void()>&& onWillDisappear, std::function<void(const float)>&& onHeightDidChange,
4643 std::function<void(const float)>&& onDetentsDidChange,
4644 std::function<void(const float)>&& onWidthDidChange,
4645 std::function<void(const float)>&& onTypeDidChange,
4646 std::function<void()>&& sheetSpringBack)
4647 {
4648 if (sheetNode->GetTag() != V2::SHEET_PAGE_TAG ||
4649 sheetNode->GetPattern<SheetPresentationPattern>()->GetTargetId() != targetId) {
4650 return;
4651 }
4652 auto sheetNodePattern = sheetNode->GetPattern<SheetPresentationPattern>();
4653 CHECK_NULL_VOID(sheetNodePattern);
4654 auto customHeightOrDetentsChanged = sheetNodePattern->IsCustomHeightOrDetentsChanged(sheetStyle);
4655 if (isStartByUIContext) {
4656 auto currentStyle = UpdateSheetStyle(sheetNode, sheetStyle, isPartialUpdate);
4657 UpdateSheetProperty(sheetNode, currentStyle, isPartialUpdate);
4658 } else {
4659 sheetNodePattern->UpdateOnAppear(std::move(onAppear));
4660 sheetNodePattern->UpdateOnDisappear(std::move(onDisappear));
4661 sheetNodePattern->UpdateShouldDismiss(std::move(shouldDismiss));
4662 sheetNodePattern->UpdateOnWillDismiss(std::move(onWillDismiss));
4663 sheetNodePattern->UpdateOnWillDisappear(std::move(onWillDisappear));
4664 sheetNodePattern->UpdateOnHeightDidChange(std::move(onHeightDidChange));
4665 sheetNodePattern->UpdateOnDetentsDidChange(std::move(onDetentsDidChange));
4666 sheetNodePattern->UpdateOnWidthDidChange(std::move(onWidthDidChange));
4667 sheetNodePattern->UpdateOnTypeDidChange(std::move(onTypeDidChange));
4668 sheetNodePattern->UpdateSheetSpringBack(std::move(sheetSpringBack));
4669 auto layoutProperty = sheetNode->GetLayoutProperty<SheetPresentationProperty>();
4670 layoutProperty->UpdateSheetStyle(sheetStyle);
4671 UpdateSheetProperty(sheetNode, sheetStyle, isPartialUpdate);
4672 }
4673 sheetNode->MarkModifyDone();
4674 auto sheetType = sheetNodePattern->GetSheetType();
4675 if (sheetType != SheetType::SHEET_POPUP && !sheetNodePattern->GetDismissProcess() && customHeightOrDetentsChanged) {
4676 PlaySheetTransition(sheetNode, true, false);
4677 }
4678 }
4679
UpdateSheetStyle(const RefPtr<FrameNode> & sheetNode,const SheetStyle & sheetStyle,bool isPartialUpdate)4680 SheetStyle OverlayManager::UpdateSheetStyle(
4681 const RefPtr<FrameNode>& sheetNode, const SheetStyle& sheetStyle, bool isPartialUpdate)
4682 {
4683 auto layoutProperty = sheetNode->GetLayoutProperty<SheetPresentationProperty>();
4684 CHECK_NULL_RETURN(layoutProperty, sheetStyle);
4685 auto currentStyle = layoutProperty->GetSheetStyleValue();
4686 if (isPartialUpdate) {
4687 currentStyle.PartialUpdate(sheetStyle);
4688 } else {
4689 auto currentShowInPage = currentStyle.showInPage;
4690 auto currentInstanceId = currentStyle.instanceId;
4691 currentStyle = sheetStyle;
4692 currentStyle.showInPage = currentShowInPage;
4693 currentStyle.instanceId = currentInstanceId;
4694 }
4695 layoutProperty->UpdateSheetStyle(currentStyle);
4696 return currentStyle;
4697 }
4698
CloseBindSheetByUIContext(const RefPtr<NG::FrameNode> & sheetContentNode,int32_t targetId)4699 void OverlayManager::CloseBindSheetByUIContext(const RefPtr<NG::FrameNode>& sheetContentNode, int32_t targetId)
4700 {
4701 SheetKey sheetKey;
4702 if (!CreateSheetKey(sheetContentNode, targetId, sheetKey)) {
4703 TAG_LOGE(AceLogTag::ACE_SHEET, "CreateSheetKey failed");
4704 return;
4705 }
4706 CloseSheet(sheetKey);
4707 }
4708
OnBindSheetInner(std::function<void (const std::string &)> && callback,const RefPtr<UINode> & sheetContentNode,std::function<RefPtr<UINode> ()> && buildtitleNodeFunc,NG::SheetStyle & sheetStyle,std::function<void ()> && onAppear,std::function<void ()> && onDisappear,std::function<void ()> && shouldDismiss,std::function<void (const int32_t)> && onWillDismiss,std::function<void ()> && onWillAppear,std::function<void ()> && onWillDisappear,std::function<void (const float)> && onHeightDidChange,std::function<void (const float)> && onDetentsDidChange,std::function<void (const float)> && onWidthDidChange,std::function<void (const float)> && onTypeDidChange,std::function<void ()> && sheetSpringBack,const RefPtr<FrameNode> & targetNode,bool isStartByUIContext)4709 void OverlayManager::OnBindSheetInner(std::function<void(const std::string&)>&& callback,
4710 const RefPtr<UINode>& sheetContentNode, std::function<RefPtr<UINode>()>&& buildtitleNodeFunc,
4711 NG::SheetStyle& sheetStyle, std::function<void()>&& onAppear, std::function<void()>&& onDisappear,
4712 std::function<void()>&& shouldDismiss, std::function<void(const int32_t)>&& onWillDismiss,
4713 std::function<void()>&& onWillAppear, std::function<void()>&& onWillDisappear,
4714 std::function<void(const float)>&& onHeightDidChange, std::function<void(const float)>&& onDetentsDidChange,
4715 std::function<void(const float)>&& onWidthDidChange,
4716 std::function<void(const float)>&& onTypeDidChange,
4717 std::function<void()>&& sheetSpringBack, const RefPtr<FrameNode>& targetNode, bool isStartByUIContext)
4718 {
4719 CHECK_NULL_VOID(sheetContentNode);
4720 auto titleBuilder = AceType::DynamicCast<FrameNode>(buildtitleNodeFunc());
4721 if (titleBuilder) {
4722 titleBuilder->GetRenderContext()->SetIsModalRootNode(true);
4723 }
4724
4725 CHECK_NULL_VOID(targetNode);
4726 auto sheetNode = SheetView::CreateSheetPage(
4727 targetNode->GetId(), targetNode->GetTag(), sheetContentNode, titleBuilder, std::move(callback), sheetStyle);
4728 CHECK_NULL_VOID(sheetNode);
4729 SetSheetProperty(sheetNode, sheetStyle, std::move(onAppear), std::move(onDisappear),
4730 std::move(shouldDismiss), std::move(onWillDismiss),
4731 std::move(onWillAppear), std::move(onWillDisappear), std::move(onHeightDidChange),
4732 std::move(onDetentsDidChange), std::move(onWidthDidChange),
4733 std::move(onTypeDidChange), std::move(sheetSpringBack));
4734 SaveSheePageNode(sheetNode, sheetContentNode, targetNode, isStartByUIContext);
4735 auto maskNode = CreateSheetMask(sheetNode, targetNode, sheetStyle);
4736 CHECK_NULL_VOID(maskNode);
4737
4738 auto sheetNodePattern = sheetNode->GetPattern<SheetPresentationPattern>();
4739 CHECK_NULL_VOID(sheetNodePattern);
4740 if (onWillAppear) {
4741 TAG_LOGI(AceLogTag::ACE_SHEET, "bindSheet lifecycle change to onWillAppear state.");
4742 onWillAppear();
4743 }
4744 if (!AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
4745 sheetNodePattern->OnAppear();
4746 }
4747
4748 // start transition animation
4749 auto sheetType = sheetNodePattern->GetSheetType();
4750 if (sheetType == SheetType::SHEET_POPUP) {
4751 PlayBubbleStyleSheetTransition(sheetNode, true);
4752 } else {
4753 PlaySheetTransition(sheetNode, true);
4754 }
4755
4756 auto pageNode = AceType::DynamicCast<FrameNode>(maskNode->GetParent());
4757 CHECK_NULL_VOID(pageNode);
4758 //when sheet shows in page
4759 if (pageNode->GetTag() == V2::PAGE_ETS_TAG) {
4760 //set focus on sheet when page has more than one child
4761 auto focusView = pageNode->GetPattern<FocusView>();
4762 CHECK_NULL_VOID(focusView);
4763 auto focusHub = sheetNode->GetFocusHub();
4764 CHECK_NULL_VOID(focusHub);
4765 focusView->SetViewRootScope(focusHub);
4766 }
4767 }
4768
SetSheetProperty(const RefPtr<FrameNode> & sheetPageNode,NG::SheetStyle & sheetStyle,std::function<void ()> && onAppear,std::function<void ()> && onDisappear,std::function<void ()> && shouldDismiss,std::function<void (const int32_t)> && onWillDismiss,std::function<void ()> && onWillAppear,std::function<void ()> && onWillDisappear,std::function<void (const float)> && onHeightDidChange,std::function<void (const float)> && onDetentsDidChange,std::function<void (const float)> && onWidthDidChange,std::function<void (const float)> && onTypeDidChange,std::function<void ()> && sheetSpringBack)4769 void OverlayManager::SetSheetProperty(
4770 const RefPtr<FrameNode>& sheetPageNode,
4771 NG::SheetStyle& sheetStyle, std::function<void()>&& onAppear, std::function<void()>&& onDisappear,
4772 std::function<void()>&& shouldDismiss, std::function<void(const int32_t)>&& onWillDismiss,
4773 std::function<void()>&& onWillAppear, std::function<void()>&& onWillDisappear,
4774 std::function<void(const float)>&& onHeightDidChange, std::function<void(const float)>&& onDetentsDidChange,
4775 std::function<void(const float)>&& onWidthDidChange,
4776 std::function<void(const float)>&& onTypeDidChange,
4777 std::function<void()>&& sheetSpringBack)
4778 {
4779 UpdateSheetRender(sheetPageNode, sheetStyle, true);
4780 auto sheetNodePattern = sheetPageNode->GetPattern<SheetPresentationPattern>();
4781 CHECK_NULL_VOID(sheetNodePattern);
4782 sheetNodePattern->UpdateOnAppear(std::move(onAppear));
4783 sheetNodePattern->UpdateOnDisappear(std::move(onDisappear));
4784 sheetNodePattern->UpdateShouldDismiss(std::move(shouldDismiss));
4785 sheetNodePattern->UpdateOnWillDismiss(std::move(onWillDismiss));
4786 sheetNodePattern->UpdateOnWillDisappear(std::move(onWillDisappear));
4787 sheetNodePattern->UpdateOnHeightDidChange(std::move(onHeightDidChange));
4788 sheetNodePattern->UpdateOnDetentsDidChange(std::move(onDetentsDidChange));
4789 sheetNodePattern->UpdateOnWidthDidChange(std::move(onWidthDidChange));
4790 sheetNodePattern->UpdateOnTypeDidChange(std::move(onTypeDidChange));
4791 sheetNodePattern->UpdateSheetSpringBack(std::move(sheetSpringBack));
4792 }
4793
SaveSheePageNode(const RefPtr<FrameNode> & sheetPageNode,const RefPtr<UINode> & sheetContentNode,const RefPtr<FrameNode> & targetNode,bool isStartByUIContext)4794 void OverlayManager::SaveSheePageNode(
4795 const RefPtr<FrameNode>& sheetPageNode, const RefPtr<UINode>& sheetContentNode,
4796 const RefPtr<FrameNode>& targetNode, bool isStartByUIContext)
4797 {
4798 int32_t targetId = targetNode->GetId();
4799 auto root = AceType::DynamicCast<FrameNode>(rootNodeWeak_.Upgrade());
4800 CHECK_NULL_VOID(root);
4801 bool isValidTarget = CheckTargetIdIsValid(targetId);
4802 SheetKey sheetKey;
4803 if (isStartByUIContext) {
4804 sheetKey = SheetKey(isValidTarget, sheetContentNode->GetId(), targetId);
4805 } else {
4806 sheetKey = SheetKey(targetId);
4807 }
4808 auto sheetNodePattern = sheetPageNode->GetPattern<SheetPresentationPattern>();
4809 CHECK_NULL_VOID(sheetNodePattern);
4810 sheetNodePattern->SetSheetKey(sheetKey);
4811 sheetMap_.emplace(sheetKey, WeakClaim(RawPtr(sheetPageNode)));
4812 modalStack_.push(WeakClaim(RawPtr(sheetPageNode)));
4813 modalList_.emplace_back(WeakClaim(RawPtr(sheetPageNode)));
4814 SaveLastModalNode();
4815 sheetNodePattern->SetOverlay(AceType::WeakClaim(this));
4816 }
4817
CheckTargetIdIsValid(int32_t targetId)4818 bool OverlayManager::CheckTargetIdIsValid(int32_t targetId)
4819 {
4820 if (targetId < 0) {
4821 return false;
4822 }
4823 auto rootNode = rootNodeWeak_.Upgrade();
4824 CHECK_NULL_RETURN(rootNode, false);
4825 auto rootId = rootNode->GetId();
4826 return rootId != targetId;
4827 }
4828
CreateSheetMask(const RefPtr<FrameNode> & sheetPageNode,const RefPtr<FrameNode> & targetNode,NG::SheetStyle & sheetStyle)4829 RefPtr<FrameNode> OverlayManager::CreateSheetMask(const RefPtr<FrameNode>& sheetPageNode,
4830 const RefPtr<FrameNode>& targetNode, NG::SheetStyle& sheetStyle)
4831 {
4832 // create maskColor node(sheetWrapper)
4833 auto maskNode = FrameNode::CreateFrameNode(V2::SHEET_WRAPPER_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
4834 AceType::MakeRefPtr<SheetWrapperPattern>());
4835 CHECK_NULL_RETURN(maskNode, nullptr);
4836 auto maskLayoutProps = maskNode->GetLayoutProperty();
4837 CHECK_NULL_RETURN(maskLayoutProps, nullptr);
4838 maskLayoutProps->UpdateMeasureType(MeasureType::MATCH_PARENT);
4839 maskLayoutProps->UpdateAlignment(Alignment::TOP_LEFT);
4840 auto maskRenderContext = maskNode->GetRenderContext();
4841 CHECK_NULL_RETURN(maskRenderContext, nullptr);
4842 maskRenderContext->UpdateClipEdge(true);
4843 sheetPageNode->MountToParent(maskNode);
4844 InitSheetMask(maskNode, sheetPageNode, sheetStyle);
4845 auto rootNode = FindWindowScene(targetNode);
4846 CHECK_NULL_RETURN(rootNode, nullptr);
4847 MountToParentWithService(rootNode, maskNode);
4848 FireModalPageShow();
4849 rootNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
4850 auto pipeline = sheetPageNode->GetContext();
4851 CHECK_NULL_RETURN(pipeline, nullptr);
4852 pipeline->FlushUITasks();
4853 PlaySheetMaskTransition(maskNode, true);
4854 ComputeSheetOffset(sheetStyle, sheetPageNode);
4855 return maskNode;
4856 }
4857
CreateSheetKey(const RefPtr<NG::FrameNode> & sheetContentNode,int32_t targetId,SheetKey & sheetKey)4858 bool OverlayManager::CreateSheetKey(const RefPtr<NG::FrameNode>& sheetContentNode, int32_t targetId,
4859 SheetKey& sheetKey)
4860 {
4861 CHECK_NULL_RETURN(sheetContentNode, false);
4862 bool isTargetIdValid = CheckTargetIdIsValid(targetId);
4863 if (!isTargetIdValid) {
4864 auto rootNode = rootNodeWeak_.Upgrade();
4865 CHECK_NULL_RETURN(rootNode, false);
4866 targetId = rootNode->GetId();
4867 }
4868 sheetKey = SheetKey(isTargetIdValid, sheetContentNode->GetId(), targetId);
4869 return true;
4870 }
4871
UpdateSheetMask(const RefPtr<FrameNode> & maskNode,const RefPtr<FrameNode> & sheetNode,const SheetStyle & sheetStyle,bool isPartialUpdate)4872 void OverlayManager::UpdateSheetMask(const RefPtr<FrameNode>& maskNode,
4873 const RefPtr<FrameNode>& sheetNode, const SheetStyle& sheetStyle, bool isPartialUpdate)
4874 {
4875 auto maskRenderContext = maskNode->GetRenderContext();
4876 CHECK_NULL_VOID(maskRenderContext);
4877 auto pipeline = PipelineContext::GetCurrentContext();
4878 CHECK_NULL_VOID(pipeline);
4879 auto sheetTheme = pipeline->GetTheme<SheetTheme>();
4880 CHECK_NULL_VOID(sheetTheme);
4881 auto sheetLayoutProps = sheetNode->GetLayoutProperty<SheetPresentationProperty>();
4882 CHECK_NULL_VOID(sheetLayoutProps);
4883 maskNode->GetEventHub<EventHub>()->GetOrCreateGestureEventHub()->SetHitTestMode(HitTestMode::HTMDEFAULT);
4884
4885 if (!AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
4886 UpdateSheetMaskBackgroundColor(maskNode, maskRenderContext, sheetStyle);
4887 } else {
4888 if (sheetStyle.maskColor.has_value() || !isPartialUpdate) {
4889 maskRenderContext->UpdateBackgroundColor(sheetStyle.maskColor.value_or(sheetTheme->GetMaskColor()));
4890 }
4891 auto eventConfirmHub = maskNode->GetOrCreateGestureEventHub();
4892 CHECK_NULL_VOID(eventConfirmHub);
4893
4894 auto maskNodeId = maskNode->GetId();
4895 auto iter = sheetMaskClickEventMap_.find(maskNodeId);
4896 if (iter == sheetMaskClickEventMap_.end() &&
4897 sheetStyle.interactive.has_value() && !sheetStyle.interactive.value()) {
4898 auto sheetMaskClickEvent = AceType::MakeRefPtr<NG::ClickEvent>(
4899 [weak = AceType::WeakClaim(AceType::RawPtr(sheetNode))](const GestureEvent& /* info */) {
4900 auto sheet = weak.Upgrade();
4901 CHECK_NULL_VOID(sheet);
4902 auto sheetPattern = sheet->GetPattern<SheetPresentationPattern>();
4903 CHECK_NULL_VOID(sheetPattern);
4904 if (sheetPattern->IsDragging()) {
4905 return;
4906 }
4907 sheetPattern->SheetInteractiveDismiss(BindSheetDismissReason::TOUCH_OUTSIDE);
4908 });
4909 sheetMaskClickEventMap_.emplace(maskNodeId, sheetMaskClickEvent);
4910 eventConfirmHub->AddClickEvent(sheetMaskClickEvent, DISTANCE_THRESHOLD);
4911 return;
4912 }
4913
4914 if ((!sheetStyle.interactive.has_value() && !isPartialUpdate &&
4915 sheetNode->GetPattern<SheetPresentationPattern>()->GetSheetType() == SheetType::SHEET_POPUP) ||
4916 sheetStyle.interactive.value_or(false)) {
4917 maskNode->GetEventHub<EventHub>()->GetOrCreateGestureEventHub()->SetHitTestMode(
4918 HitTestMode::HTMTRANSPARENT);
4919 maskRenderContext->UpdateBackgroundColor(Color::TRANSPARENT);
4920 eventConfirmHub->RemoveClickEvent(iter->second);
4921 sheetMaskClickEventMap_.erase(maskNodeId);
4922 }
4923 }
4924 }
4925
PlayBubbleStyleSheetTransition(RefPtr<FrameNode> sheetNode,bool isTransitionIn)4926 void OverlayManager::PlayBubbleStyleSheetTransition(RefPtr<FrameNode> sheetNode, bool isTransitionIn)
4927 {
4928 auto sheetPattern = sheetNode->GetPattern<SheetPresentationPattern>();
4929 CHECK_NULL_VOID(sheetPattern);
4930 if (isTransitionIn) {
4931 sheetPattern->ResetToInvisible();
4932 sheetPattern->SetCurrentHeight(sheetHeight_);
4933 sheetPattern->StartOffsetEnteringAnimation();
4934 sheetPattern->FireOnHeightDidChange(sheetHeight_);
4935 sheetPattern->StartAlphaEnteringAnimation([sheetWK = WeakClaim(RawPtr(sheetNode))] {
4936 auto sheet = sheetWK.Upgrade();
4937 CHECK_NULL_VOID(sheet);
4938 auto sheetPattern = sheet->GetPattern<SheetPresentationPattern>();
4939 CHECK_NULL_VOID(sheetPattern);
4940 sheetPattern->ProcessColumnRect();
4941 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
4942 sheetPattern->OnAppear();
4943 }
4944 });
4945 } else {
4946 sheetPattern->StartOffsetExitingAnimation();
4947 sheetPattern->StartAlphaExitingAnimation(
4948 [rootWeak = rootNodeWeak_, sheetWK = WeakClaim(RawPtr(sheetNode)), id = Container::CurrentId(),
4949 weakOverlayManager = WeakClaim(this)] {
4950 ContainerScope scope(id);
4951 auto context = PipelineContext::GetCurrentContext();
4952 CHECK_NULL_VOID(context);
4953 auto taskExecutor = context->GetTaskExecutor();
4954 CHECK_NULL_VOID(taskExecutor);
4955 // animation finish event should be posted to UI thread.
4956 taskExecutor->PostTask(
4957 [rootWeak, sheetWK, id, weakOverlayManager]() {
4958 auto sheet = sheetWK.Upgrade();
4959 auto overlayManager = weakOverlayManager.Upgrade();
4960 CHECK_NULL_VOID(sheet && overlayManager);
4961
4962 ContainerScope scope(id);
4963 if (!sheet->GetPattern<SheetPresentationPattern>()->IsExecuteOnDisappear()) {
4964 sheet->GetPattern<SheetPresentationPattern>()->OnDisappear();
4965 }
4966 auto root = overlayManager->FindWindowScene(sheet);
4967 CHECK_NULL_VOID(root);
4968 auto sheetParent = DynamicCast<FrameNode>(sheet->GetParent());
4969 CHECK_NULL_VOID(sheetParent);
4970 overlayManager->FireAutoSave(sheet);
4971 overlayManager->RemoveChildWithService(root, sheetParent);
4972 root->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
4973 },
4974 TaskExecutor::TaskType::UI, "ArkUIOverlaySheetExitingAnimation");
4975 });
4976 }
4977 }
4978
PlaySheetMaskTransition(RefPtr<FrameNode> maskNode,bool isTransitionIn)4979 void OverlayManager::PlaySheetMaskTransition(RefPtr<FrameNode> maskNode, bool isTransitionIn)
4980 {
4981 AnimationOption option;
4982 const RefPtr<InterpolatingSpring> curve =
4983 AceType::MakeRefPtr<InterpolatingSpring>(0.0f, CURVE_MASS, CURVE_STIFFNESS, CURVE_DAMPING);
4984 option.SetCurve(curve);
4985 option.SetFillMode(FillMode::FORWARDS);
4986 auto context = maskNode->GetRenderContext();
4987 CHECK_NULL_VOID(context);
4988 auto sheetNode = AceType::DynamicCast<FrameNode>(maskNode->GetChildAtIndex(0));
4989 CHECK_NULL_VOID(sheetNode);
4990 auto sheetPattern = sheetNode->GetPattern<SheetPresentationPattern>();
4991 CHECK_NULL_VOID(sheetPattern);
4992 auto backgroundColor = sheetPattern->GetMaskBackgroundColor();
4993 if (isTransitionIn) {
4994 context->UpdateBackgroundColor(backgroundColor.ChangeOpacity(0.0f));
4995 AnimationUtils::Animate(
4996 option,
4997 [context, backgroundColor]() {
4998 CHECK_NULL_VOID(context);
4999 context->UpdateBackgroundColor(backgroundColor);
5000 });
5001 } else {
5002 auto iter = sheetMaskClickEventMap_.find(maskNode->GetId());
5003 if (iter != sheetMaskClickEventMap_.end()) {
5004 auto eventConfirmHub = maskNode->GetOrCreateGestureEventHub();
5005 CHECK_NULL_VOID(eventConfirmHub);
5006 eventConfirmHub->RemoveClickEvent(iter->second);
5007 }
5008 maskNode->GetEventHub<EventHub>()->GetOrCreateGestureEventHub()->SetHitTestMode(HitTestMode::HTMTRANSPARENT);
5009 context->UpdateBackgroundColor(backgroundColor);
5010 AnimationUtils::Animate(
5011 option,
5012 [context, backgroundColor]() {
5013 CHECK_NULL_VOID(context);
5014 context->UpdateBackgroundColor(backgroundColor.ChangeOpacity(0.0f));
5015 });
5016 }
5017 }
5018
SetSheetBackgroundColor(const RefPtr<FrameNode> & sheetNode,const RefPtr<SheetTheme> & sheetTheme,const NG::SheetStyle & sheetStyle,bool isPartialUpdate)5019 void OverlayManager::SetSheetBackgroundColor(const RefPtr<FrameNode>& sheetNode, const RefPtr<SheetTheme>& sheetTheme,
5020 const NG::SheetStyle& sheetStyle, bool isPartialUpdate)
5021 {
5022 if (!AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
5023 if (sheetStyle.backgroundColor.has_value()) {
5024 sheetNode->GetRenderContext()->UpdateBackgroundColor(sheetStyle.backgroundColor.value());
5025 }
5026 } else if (sheetStyle.backgroundColor.has_value() || !isPartialUpdate) {
5027 sheetNode->GetRenderContext()->UpdateBackgroundColor(sheetStyle.backgroundColor.value_or(
5028 sheetTheme->GetSheetBackgoundColor()));
5029 }
5030 }
5031
SetSheetBackgroundBlurStyle(const RefPtr<FrameNode> & sheetNode,const BlurStyleOption & bgBlurStyle)5032 void OverlayManager::SetSheetBackgroundBlurStyle(const RefPtr<FrameNode>& sheetNode, const BlurStyleOption& bgBlurStyle)
5033 {
5034 auto renderContext = sheetNode->GetRenderContext();
5035 CHECK_NULL_VOID(renderContext);
5036
5037 if (renderContext->GetBackgroundEffect().has_value()) {
5038 renderContext->UpdateBackgroundEffect(std::nullopt);
5039 }
5040 renderContext->UpdateBackBlurStyle(bgBlurStyle);
5041 if (renderContext->GetBackBlurRadius().has_value()) {
5042 renderContext->UpdateBackBlurRadius(Dimension());
5043 }
5044 }
5045
CheckTopModalNode(const RefPtr<FrameNode> & topModalNode,int32_t targetId)5046 bool OverlayManager::CheckTopModalNode(const RefPtr<FrameNode>& topModalNode, int32_t targetId)
5047 {
5048 if (topModalNode->GetTag() != V2::SHEET_PAGE_TAG && topModalNode->GetTag() != V2::MODAL_PAGE_TAG) {
5049 return false;
5050 }
5051 if (topModalNode->GetTag() == V2::SHEET_PAGE_TAG ||
5052 topModalNode->GetPattern<ModalPresentationPattern>()->GetTargetId() != targetId) {
5053 DeleteModal(targetId);
5054 return false;
5055 }
5056 return true;
5057 }
5058
ComputeSheetOffset(NG::SheetStyle & sheetStyle,RefPtr<FrameNode> sheetNode)5059 void OverlayManager::ComputeSheetOffset(NG::SheetStyle& sheetStyle, RefPtr<FrameNode> sheetNode)
5060 {
5061 auto sheetPattern = sheetNode->GetPattern<SheetPresentationPattern>();
5062 CHECK_NULL_VOID(sheetPattern);
5063 auto sheetMaxHeight = sheetPattern->GetPageHeightWithoutOffset();
5064 auto largeHeight = sheetMaxHeight - SHEET_BLANK_MINI_HEIGHT.ConvertToPx();
5065 auto geometryNode = sheetNode->GetGeometryNode();
5066 CHECK_NULL_VOID(geometryNode);
5067 auto sheetHeight = geometryNode->GetFrameSize().Height();
5068
5069 auto sheetType = sheetPattern->GetSheetType();
5070 switch (sheetType) {
5071 case SheetType::SHEET_BOTTOMLANDSPACE:
5072 if (!AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
5073 sheetHeight_ = largeHeight;
5074 break;
5075 }
5076 case SheetType::SHEET_BOTTOM:
5077 case SheetType::SHEET_BOTTOM_FREE_WINDOW:
5078 if (!sheetStyle.detents.empty()) {
5079 ComputeDetentsSheetOffset(sheetStyle, sheetNode);
5080 } else {
5081 ComputeSingleGearSheetOffset(sheetStyle, sheetNode);
5082 }
5083 break;
5084 case SheetType::SHEET_CENTER:
5085 sheetHeight_ = (sheetHeight + sheetMaxHeight) / SHEET_HALF_SIZE;
5086 break;
5087 case SheetType::SHEET_POPUP:
5088 sheetHeight_ = sheetMaxHeight;
5089 break;
5090 default:
5091 break;
5092 }
5093 }
5094
5095 // if device is phone, fold status, screen is in landscape mode, preferType is BOTTOM
CheckDeviceInLandscape(NG::SheetStyle & sheetStyle,RefPtr<FrameNode> sheetNode,float & sheetTopSafeArea)5096 void OverlayManager::CheckDeviceInLandscape(
5097 NG::SheetStyle& sheetStyle, RefPtr<FrameNode> sheetNode, float& sheetTopSafeArea)
5098 {
5099 auto sheetPattern = sheetNode->GetPattern<SheetPresentationPattern>();
5100 CHECK_NULL_VOID(sheetPattern);
5101 if (sheetStyle.sheetType.has_value() && sheetStyle.sheetType.value() == SheetType::SHEET_BOTTOM &&
5102 sheetPattern->IsPhoneInLandScape()) {
5103 sheetTopSafeArea = 0.0f;
5104 }
5105 }
5106
ComputeSingleGearSheetOffset(NG::SheetStyle & sheetStyle,RefPtr<FrameNode> sheetNode)5107 void OverlayManager::ComputeSingleGearSheetOffset(NG::SheetStyle& sheetStyle, RefPtr<FrameNode> sheetNode)
5108 {
5109 auto sheetPattern = sheetNode->GetPattern<SheetPresentationPattern>();
5110 CHECK_NULL_VOID(sheetPattern);
5111 auto sheetMaxHeight = sheetPattern->GetPageHeightWithoutOffset();
5112 auto sheetTopSafeArea = sheetPattern->GetSheetTopSafeArea();
5113
5114 CheckDeviceInLandscape(sheetStyle, sheetNode, sheetTopSafeArea);
5115 auto largeHeight = sheetMaxHeight - SHEET_BLANK_MINI_HEIGHT.ConvertToPx() - sheetTopSafeArea;
5116 if (sheetStyle.sheetMode.has_value()) {
5117 if (sheetStyle.sheetMode == SheetMode::MEDIUM) {
5118 sheetHeight_ = sheetMaxHeight * MEDIUM_SIZE;
5119 if (!Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
5120 sheetHeight_ = sheetMaxHeight * MEDIUM_SIZE_PRE;
5121 }
5122 } else if (sheetStyle.sheetMode == SheetMode::LARGE) {
5123 sheetHeight_ = largeHeight;
5124 } else if (sheetStyle.sheetMode == SheetMode::AUTO) {
5125 sheetHeight_ = sheetPattern->GetFitContentHeight();
5126 if (GreatNotEqual(sheetHeight_, largeHeight)) {
5127 sheetHeight_ = largeHeight;
5128 }
5129 }
5130 } else {
5131 float height = 0.0f;
5132 if (sheetStyle.height->Unit() == DimensionUnit::PERCENT) {
5133 height = sheetStyle.height->ConvertToPxWithSize(sheetMaxHeight - sheetTopSafeArea);
5134 } else {
5135 height = sheetStyle.height->ConvertToPx();
5136 }
5137 if (height > largeHeight) {
5138 sheetHeight_ = largeHeight;
5139 } else if (height < 0) {
5140 sheetHeight_ = largeHeight;
5141 } else {
5142 sheetHeight_ = height;
5143 }
5144 }
5145 }
5146
ComputeDetentsSheetOffset(NG::SheetStyle & sheetStyle,RefPtr<FrameNode> sheetNode)5147 void OverlayManager::ComputeDetentsSheetOffset(NG::SheetStyle& sheetStyle, RefPtr<FrameNode> sheetNode)
5148 {
5149 auto sheetPattern = sheetNode->GetPattern<SheetPresentationPattern>();
5150 CHECK_NULL_VOID(sheetPattern);
5151 auto sheetMaxHeight = sheetPattern->GetPageHeightWithoutOffset();
5152 auto sheetTopSafeArea = sheetPattern->GetSheetTopSafeArea();
5153 CheckDeviceInLandscape(sheetStyle, sheetNode, sheetTopSafeArea);
5154 auto largeHeight = sheetMaxHeight - SHEET_BLANK_MINI_HEIGHT.ConvertToPx() - sheetTopSafeArea;
5155 auto selection = sheetStyle.detents[sheetPattern->GetDetentsIndex()];
5156 if (selection.sheetMode.has_value()) {
5157 if (selection.sheetMode == SheetMode::MEDIUM) {
5158 sheetHeight_ = sheetMaxHeight * MEDIUM_SIZE;
5159 if (!Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
5160 sheetHeight_ = sheetMaxHeight * MEDIUM_SIZE_PRE;
5161 }
5162 } else if (selection.sheetMode == SheetMode::LARGE) {
5163 sheetHeight_ = largeHeight;
5164 } else if (selection.sheetMode == SheetMode::AUTO) {
5165 sheetHeight_ = sheetPattern->GetFitContentHeight();
5166 if (GreatNotEqual(sheetHeight_, largeHeight)) {
5167 sheetHeight_ = largeHeight;
5168 }
5169 }
5170 } else {
5171 float height = 0.0f;
5172 if (selection.height->Unit() == DimensionUnit::PERCENT) {
5173 height = selection.height->ConvertToPxWithSize(sheetMaxHeight - sheetTopSafeArea);
5174 } else {
5175 height = selection.height->ConvertToPx();
5176 }
5177 if (height > largeHeight) {
5178 sheetHeight_ = largeHeight;
5179 } else if (height < 0) {
5180 sheetHeight_ = largeHeight;
5181 } else {
5182 sheetHeight_ = height;
5183 }
5184 }
5185 }
5186
CleanSheet(const RefPtr<FrameNode> & sheetNode,const SheetKey & sheetKey)5187 void OverlayManager::CleanSheet(const RefPtr<FrameNode>& sheetNode, const SheetKey& sheetKey)
5188 {
5189 if (modalStack_.empty()) {
5190 return;
5191 }
5192 auto iter = sheetMap_.find(sheetKey);
5193 if (sheetMap_.empty() || iter == sheetMap_.end()) {
5194 DeleteModal(sheetKey.targetId, false);
5195 return;
5196 }
5197 auto mapSheetNode = iter->second.Upgrade();
5198 CHECK_NULL_VOID(mapSheetNode);
5199 if (mapSheetNode->GetTag() != V2::SHEET_PAGE_TAG) {
5200 return;
5201 }
5202 if (mapSheetNode->GetPattern<SheetPresentationPattern>()->GetTargetId() != sheetKey.targetId) {
5203 return;
5204 }
5205 ModalPageLostFocus(mapSheetNode);
5206 sheetMap_.erase(sheetKey);
5207 CleanViewContextMap(Container::CurrentId(), sheetKey.contentId);
5208 RemoveSheetNode(sheetNode);
5209 FireModalPageHide();
5210 SaveLastModalNode();
5211 }
5212
DestroySheet(const RefPtr<FrameNode> & sheetNode,const SheetKey & sheetKey)5213 void OverlayManager::DestroySheet(const RefPtr<FrameNode>& sheetNode, const SheetKey& sheetKey)
5214 {
5215 auto rootNode = FindWindowScene(sheetNode);
5216 CHECK_NULL_VOID(rootNode);
5217 auto root = DynamicCast<FrameNode>(rootNode);
5218 sheetNode->GetPattern<SheetPresentationPattern>()->OnDisappear();
5219 auto sheetParent = DynamicCast<FrameNode>(sheetNode->GetParent());
5220 CHECK_NULL_VOID(sheetParent);
5221 RemoveChildWithService(root, sheetParent);
5222 root->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
5223 }
5224
DeleteModal(int32_t targetId,bool needOnWillDisappear)5225 void OverlayManager::DeleteModal(int32_t targetId, bool needOnWillDisappear)
5226 {
5227 bool isDelete = false;
5228 bool isModal = true;
5229 for (auto modal = modalList_.begin(); modal != modalList_.end(); modal++) {
5230 auto modalNode = (*modal).Upgrade();
5231 if (!modalNode) {
5232 continue;
5233 }
5234 int32_t currentTargetId = -1;
5235 if (modalNode->GetTag() == V2::MODAL_PAGE_TAG) {
5236 isModal = true;
5237 currentTargetId = modalNode->GetPattern<ModalPresentationPattern>()->GetTargetId();
5238 } else if (modalNode->GetTag() == V2::SHEET_PAGE_TAG) {
5239 isModal = false;
5240 currentTargetId = modalNode->GetPattern<SheetPresentationPattern>()->GetTargetId();
5241 } else {
5242 return;
5243 }
5244 if (currentTargetId == targetId) {
5245 isDelete = true;
5246 modalList_.erase(modal);
5247 DeleteModalNode(targetId, modalNode, isModal, needOnWillDisappear);
5248 break;
5249 }
5250 }
5251 if (isDelete) {
5252 while (!modalStack_.empty()) {
5253 modalStack_.pop();
5254 }
5255 for (auto modal = modalList_.begin(); modal != modalList_.end(); modal++) {
5256 modalStack_.push(*modal);
5257 }
5258 SaveLastModalNode();
5259 }
5260 }
5261
DeleteModalNode(int32_t targetId,RefPtr<FrameNode> & modalNode,bool isModal,bool needOnWillDisappear)5262 void OverlayManager::DeleteModalNode(
5263 int32_t targetId, RefPtr<FrameNode>& modalNode, bool isModal, bool needOnWillDisappear)
5264 {
5265 auto rootNode = FindWindowScene(modalNode);
5266 CHECK_NULL_VOID(rootNode);
5267 if (isModal) {
5268 if (needOnWillDisappear) {
5269 modalNode->GetPattern<ModalPresentationPattern>()->OnWillDisappear();
5270 }
5271 modalNode->GetPattern<ModalPresentationPattern>()->OnDisappear();
5272 modalNode->GetPattern<ModalPresentationPattern>()->FireCallback("false");
5273 // Fire hidden event of navdestination on the disappeared modal
5274 FireNavigationStateChange(false, modalNode);
5275 RemoveChildWithService(rootNode, modalNode);
5276 } else {
5277 auto sheetPattern = modalNode->GetPattern<SheetPresentationPattern>();
5278 CHECK_NULL_VOID(sheetPattern);
5279 if (needOnWillDisappear) {
5280 sheetPattern->OnWillDisappear();
5281 }
5282 sheetPattern->OnDisappear();
5283 sheetPattern->FireCallback("false");
5284 sheetMap_.erase(sheetPattern->GetSheetKey());
5285 auto sheetParent = DynamicCast<FrameNode>(modalNode->GetParent());
5286 CHECK_NULL_VOID(sheetParent);
5287 RemoveChildWithService(rootNode, sheetParent);
5288 }
5289 rootNode->MarkDirtyNode(PROPERTY_UPDATE_BY_CHILD_REQUEST);
5290 }
5291
PopTopModalNode()5292 void OverlayManager::PopTopModalNode()
5293 {
5294 if (!modalStack_.empty()) {
5295 modalStack_.pop();
5296 }
5297 if (!modalList_.empty()) {
5298 modalList_.pop_back();
5299 }
5300 }
5301
GetSheetMask(const RefPtr<FrameNode> & sheetNode)5302 RefPtr<FrameNode> OverlayManager::GetSheetMask(const RefPtr<FrameNode>& sheetNode)
5303 {
5304 // get bindsheet masknode
5305 CHECK_NULL_RETURN(sheetNode, nullptr);
5306 auto sheetParent = sheetNode->GetParent();
5307 CHECK_NULL_RETURN(sheetParent, nullptr);
5308 return DynamicCast<FrameNode>(sheetParent);
5309 }
5310
SetCustomKeyboardOption(bool supportAvoidance)5311 void OverlayManager::SetCustomKeyboardOption(bool supportAvoidance)
5312 {
5313 auto pipeline = PipelineContext::GetMainPipelineContext();
5314 CHECK_NULL_VOID(pipeline);
5315 keyboardAvoidance_ = supportAvoidance;
5316 }
5317
PlayKeyboardTransition(const RefPtr<FrameNode> & customKeyboard,bool isTransitionIn)5318 void OverlayManager::PlayKeyboardTransition(const RefPtr<FrameNode>& customKeyboard, bool isTransitionIn)
5319 {
5320 CHECK_NULL_VOID(customKeyboard);
5321 AnimationOption option;
5322 if (isTransitionIn) {
5323 option.SetCurve(SHOW_CUSTOM_KEYBOARD_ANIMATION_CURVE);
5324 } else {
5325 option.SetCurve(HIDE_CUSTOM_KEYBOARD_ANIMATION_CURVE);
5326 }
5327 option.SetFillMode(FillMode::FORWARDS);
5328 auto context = customKeyboard->GetRenderContext();
5329 CHECK_NULL_VOID(context);
5330 auto keyboardOffsetInfo = CalcCustomKeyboardOffset(customKeyboard);
5331 if (isTransitionIn) {
5332 context->OnTransformTranslateUpdate({ 0.0f, keyboardOffsetInfo.inAniStartOffset, 0.0f });
5333 AnimationUtils::Animate(option, [context, finalOffset = keyboardOffsetInfo.finalOffset]() {
5334 if (context) {
5335 context->OnTransformTranslateUpdate({ 0.0f, finalOffset, 0.0f });
5336 }
5337 });
5338 } else {
5339 context->UpdateOpacity(1.0);
5340 option.SetOnFinishEvent([customKeyboard] {
5341 auto parent = customKeyboard->GetParent();
5342 CHECK_NULL_VOID(parent);
5343 parent->RemoveChild(customKeyboard);
5344 });
5345 AnimationUtils::Animate(
5346 option,
5347 [context, outAniEndOffset = keyboardOffsetInfo.outAniEndOffset]() {
5348 if (context) {
5349 context->OnTransformTranslateUpdate({ 0.0f, outAniEndOffset, 0.0f });
5350 }
5351 },
5352 option.GetOnFinishEvent());
5353 }
5354 }
5355
UpdateCustomKeyboardPosition()5356 void OverlayManager::UpdateCustomKeyboardPosition()
5357 {
5358 for (auto iter = customKeyboardMap_.begin(); iter != customKeyboardMap_.end(); iter++) {
5359 auto customKeyboardNode = iter->second;
5360 if (!customKeyboardNode) {
5361 continue;
5362 }
5363 auto parent = customKeyboardNode->GetParent();
5364 if (!parent) {
5365 continue;
5366 }
5367 auto renderContext = customKeyboardNode->GetRenderContext();
5368 CHECK_NULL_VOID(renderContext);
5369 auto keyboardOffsetInfo = CalcCustomKeyboardOffset(customKeyboardNode);
5370 renderContext->OnTransformTranslateUpdate({ 0.0f, keyboardOffsetInfo.finalOffset, 0.0f });
5371 }
5372 }
5373
CalcCustomKeyboardOffset(const RefPtr<FrameNode> & customKeyboard)5374 CustomKeyboardOffsetInfo OverlayManager::CalcCustomKeyboardOffset(const RefPtr<FrameNode>& customKeyboard)
5375 {
5376 CustomKeyboardOffsetInfo keyboardOffsetInfo;
5377 CHECK_NULL_RETURN(customKeyboard, keyboardOffsetInfo);
5378 auto pipeline = customKeyboard->GetContext();
5379 CHECK_NULL_RETURN(pipeline, keyboardOffsetInfo);
5380 auto pageNode = pipeline->GetStageManager()->GetLastPage();
5381 CHECK_NULL_RETURN(pageNode, keyboardOffsetInfo);
5382 auto pageHeight = pageNode->GetGeometryNode()->GetFrameSize().Height();
5383 auto keyboardHeight = customKeyboard->GetGeometryNode()->GetFrameSize().Height();
5384 auto rootNode = rootNodeWeak_.Upgrade();
5385 CHECK_NULL_RETURN(rootNode, keyboardOffsetInfo);
5386 auto finalOffset = 0.0f;
5387 if (rootNode->GetTag() == V2::STACK_ETS_TAG) {
5388 auto rootNd = AceType::DynamicCast<FrameNode>(rootNode);
5389 pageHeight = rootNd->GetGeometryNode()->GetFrameSize().Height();
5390 finalOffset = (pageHeight - keyboardHeight) - (pageHeight - keyboardHeight) / NUM_FLOAT_2;
5391 }
5392 keyboardOffsetInfo.finalOffset = finalOffset;
5393 keyboardOffsetInfo.inAniStartOffset = pageHeight;
5394 keyboardOffsetInfo.outAniEndOffset = finalOffset + keyboardHeight;
5395 return keyboardOffsetInfo;
5396 }
5397
BindKeyboard(const std::function<void ()> & keyboardBuilder,int32_t targetId)5398 void OverlayManager::BindKeyboard(const std::function<void()>& keyboardBuilder, int32_t targetId)
5399 {
5400 if (customKeyboardMap_.find(targetId) != customKeyboardMap_.end()) {
5401 return;
5402 }
5403 auto rootNode = rootNodeWeak_.Upgrade();
5404 CHECK_NULL_VOID(rootNode);
5405 auto customKeyboard = KeyboardView::CreateKeyboard(targetId, keyboardBuilder);
5406 if (!customKeyboard) {
5407 return;
5408 }
5409 ACE_LAYOUT_SCOPED_TRACE("BindKeyboard[targetId:%d]", targetId);
5410 customKeyboard->MountToParent(rootNode);
5411 rootNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
5412 customKeyboardMap_[targetId] = customKeyboard;
5413 auto pipeline = PipelineContext::GetCurrentContext();
5414 CHECK_NULL_VOID(pipeline);
5415 pipeline->AddAfterLayoutTask([weak = WeakClaim(this), customKeyboard] {
5416 auto overlayManager = weak.Upgrade();
5417 CHECK_NULL_VOID(overlayManager);
5418 overlayManager->PlayKeyboardTransition(customKeyboard, true);
5419 });
5420 }
5421
BindKeyboardWithNode(const RefPtr<UINode> & keyboard,int32_t targetId)5422 void OverlayManager::BindKeyboardWithNode(const RefPtr<UINode>& keyboard, int32_t targetId)
5423 {
5424 if (customKeyboardMap_.find(targetId) != customKeyboardMap_.end()) {
5425 return;
5426 }
5427 ACE_LAYOUT_SCOPED_TRACE("BindKeyboardWithNode[targetId:%d]", targetId);
5428 auto rootNode = rootNodeWeak_.Upgrade();
5429 CHECK_NULL_VOID(rootNode);
5430 auto customKeyboard = KeyboardView::CreateKeyboardWithNode(targetId, keyboard);
5431 if (!customKeyboard) {
5432 return;
5433 }
5434 customKeyboard->MountToParent(rootNode);
5435 rootNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
5436 customKeyboardMap_[targetId] = customKeyboard;
5437 PlayKeyboardTransition(customKeyboard, true);
5438 }
5439
CloseKeyboard(int32_t targetId)5440 void OverlayManager::CloseKeyboard(int32_t targetId)
5441 {
5442 auto it = customKeyboardMap_.find(targetId);
5443 if (it == customKeyboardMap_.end()) {
5444 return;
5445 }
5446 ACE_LAYOUT_SCOPED_TRACE("CloseKeyboard[targetId:%d]", targetId);
5447 auto customKeyboard = it->second;
5448 CHECK_NULL_VOID(customKeyboard);
5449 auto pipeline = customKeyboard->GetContext();
5450 CHECK_NULL_VOID(pipeline);
5451 auto pattern = customKeyboard->GetPattern<KeyboardPattern>();
5452 CHECK_NULL_VOID(pattern);
5453 customKeyboardMap_.erase(pattern->GetTargetId());
5454 PlayKeyboardTransition(customKeyboard, false);
5455 Rect keyboardRect = Rect(0.0f, 0.0f, 0.0f, 0.0f);
5456 pipeline->OnVirtualKeyboardAreaChange(keyboardRect);
5457 }
5458
AvoidCustomKeyboard(int32_t targetId,float safeHeight)5459 void OverlayManager::AvoidCustomKeyboard(int32_t targetId, float safeHeight)
5460 {
5461 auto it = customKeyboardMap_.find(targetId);
5462 if (it == customKeyboardMap_.end()) {
5463 return;
5464 }
5465 auto customKeyboard = it->second;
5466 CHECK_NULL_VOID(customKeyboard);
5467 auto pattern = customKeyboard->GetPattern<KeyboardPattern>();
5468 CHECK_NULL_VOID(pattern);
5469 pattern->SetKeyboardSafeHeight(safeHeight);
5470 pattern->SetKeyboardAreaChange(keyboardAvoidance_);
5471 pattern->SetKeyboardOption(keyboardAvoidance_);
5472 }
5473
5474 // This function will be used in SceneBoard Thread only.
5475 // if need to show the pop-up component,
5476 // it expects to receive the target component bound by the pop-up component to find the windowScene component.
5477 // if need to hide the pop-up component,
5478 // it expects to receive the the pop-up component to return the parent component.
5479 // And the parent component will be the windowScene component exactly.
FindWindowScene(RefPtr<FrameNode> targetNode)5480 RefPtr<UINode> OverlayManager::FindWindowScene(RefPtr<FrameNode> targetNode)
5481 {
5482 auto container = Container::Current();
5483 if (!container || !container->IsScenceBoardWindow() || isAttachToCustomNode_) {
5484 return rootNodeWeak_.Upgrade();
5485 }
5486 CHECK_NULL_RETURN(targetNode, nullptr);
5487 auto parent = targetNode->GetParent();
5488 while (parent && parent->GetTag() != V2::WINDOW_SCENE_ETS_TAG) {
5489 parent = parent->GetParent();
5490 }
5491 CHECK_NULL_RETURN(parent, nullptr);
5492 windowSceneSet_.insert(parent);
5493 return parent;
5494 }
5495
MountFilterToWindowScene(const RefPtr<FrameNode> & columnNode,const RefPtr<UINode> & windowScene)5496 void OverlayManager::MountFilterToWindowScene(const RefPtr<FrameNode>& columnNode, const RefPtr<UINode>& windowScene)
5497 {
5498 CHECK_NULL_VOID(windowScene);
5499 columnNode->MountToParent(windowScene);
5500 columnNode->OnMountToParentDone();
5501 windowScene->MarkDirtyNode(PROPERTY_UPDATE_BY_CHILD_REQUEST);
5502 filterColumnNodeWeak_ = columnNode;
5503 hasFilter_ = true;
5504 }
5505
5506 /**
5507 * Mount pixelMap to wndow scene for lifting or for drag moving.
5508 * When isDragPixelMap is true, the pixelMap is saved by dragPixmapColumnNodeWeak_ used for moving with drag finger or
5509 * mouse, etc.
5510 * When isDragPixelMap is false, the pixelMap is saved by pixmapColumnNodeWeak_ used for lifting.
5511 */
MountPixelMapToWindowScene(const RefPtr<FrameNode> & columnNode,const RefPtr<UINode> & windowScene,bool isDragPixelMap)5512 void OverlayManager::MountPixelMapToWindowScene(
5513 const RefPtr<FrameNode>& columnNode, const RefPtr<UINode>& windowScene, bool isDragPixelMap)
5514 {
5515 CHECK_NULL_VOID(windowScene);
5516 columnNode->MountToParent(windowScene);
5517 columnNode->OnMountToParentDone();
5518 windowScene->MarkDirtyNode(PROPERTY_UPDATE_BY_CHILD_REQUEST);
5519 if (isDragPixelMap) {
5520 dragPixmapColumnNodeWeak_ = columnNode;
5521 hasDragPixelMap_ = true;
5522 } else {
5523 pixmapColumnNodeWeak_ = columnNode;
5524 hasPixelMap_ = true;
5525 }
5526 }
5527
MountEventToWindowScene(const RefPtr<FrameNode> & columnNode,const RefPtr<UINode> & windowScene)5528 void OverlayManager::MountEventToWindowScene(const RefPtr<FrameNode>& columnNode, const RefPtr<UINode>& windowScene)
5529 {
5530 CHECK_NULL_VOID(windowScene);
5531 columnNode->MountToParent(windowScene);
5532 columnNode->OnMountToParentDone();
5533 eventColumnNodeWeak_ = columnNode;
5534 hasEvent_ = true;
5535 }
5536
5537 /**
5538 * Mount pixelMap to root node for lifting or for drag moving.
5539 * When isDragPixelMap is true, the pixelMap is saved by dragPixmapColumnNodeWeak_ used for moving with drag finger or
5540 * mouse, etc.
5541 * When isDragPixelMap is false, the pixelMap is saved by pixmapColumnNodeWeak_ used for lifting.
5542 */
MountPixelMapToRootNode(const RefPtr<FrameNode> & columnNode,bool isDragPixelMap)5543 void OverlayManager::MountPixelMapToRootNode(const RefPtr<FrameNode>& columnNode, bool isDragPixelMap)
5544 {
5545 auto rootNode = rootNodeWeak_.Upgrade();
5546 CHECK_NULL_VOID(rootNode);
5547 columnNode->MountToParent(rootNode);
5548 columnNode->OnMountToParentDone();
5549 rootNode->MarkDirtyNode(PROPERTY_UPDATE_BY_CHILD_REQUEST);
5550 if (isDragPixelMap) {
5551 dragPixmapColumnNodeWeak_ = columnNode;
5552 hasDragPixelMap_ = true;
5553 } else {
5554 pixmapColumnNodeWeak_ = columnNode;
5555 hasPixelMap_ = true;
5556 }
5557 }
5558
MountEventToRootNode(const RefPtr<FrameNode> & columnNode)5559 void OverlayManager::MountEventToRootNode(const RefPtr<FrameNode>& columnNode)
5560 {
5561 auto rootNode = rootNodeWeak_.Upgrade();
5562 CHECK_NULL_VOID(rootNode);
5563 columnNode->MountToParent(rootNode, EVENT_COLUMN_SLOT);
5564 columnNode->OnMountToParentDone();
5565 eventColumnNodeWeak_ = columnNode;
5566 hasEvent_ = true;
5567 }
5568
RemovePixelMap()5569 void OverlayManager::RemovePixelMap()
5570 {
5571 if (!hasPixelMap_) {
5572 return;
5573 }
5574 auto columnNode = pixmapColumnNodeWeak_.Upgrade();
5575 if (!columnNode) {
5576 hasPixelMap_ = false;
5577 isOnAnimation_ = false;
5578 return;
5579 }
5580 auto rootNode = columnNode->GetParent();
5581 CHECK_NULL_VOID(rootNode);
5582 rootNode->RemoveChild(columnNode);
5583 rootNode->RebuildRenderContextTree();
5584 rootNode->MarkDirtyNode(PROPERTY_UPDATE_BY_CHILD_REQUEST);
5585 hasPixelMap_ = false;
5586 isOnAnimation_ = false;
5587 }
5588
RemovePixelMapAnimation(bool startDrag,double x,double y,bool isSubwindowOverlay)5589 void OverlayManager::RemovePixelMapAnimation(bool startDrag, double x, double y, bool isSubwindowOverlay)
5590 {
5591 if (isOnAnimation_ || !hasPixelMap_) {
5592 return;
5593 }
5594 if (startDrag) {
5595 if (!isSubwindowOverlay) {
5596 RemovePixelMap();
5597 }
5598 return;
5599 }
5600 auto columnNode = pixmapColumnNodeWeak_.Upgrade();
5601 if (!columnNode) {
5602 RemoveEventColumn();
5603 hasPixelMap_ = false;
5604 return;
5605 }
5606 auto imageNode = AceType::DynamicCast<FrameNode>(columnNode->GetFirstChild());
5607 CHECK_NULL_VOID(imageNode);
5608 auto imageContext = imageNode->GetRenderContext();
5609 CHECK_NULL_VOID(imageContext);
5610 auto hub = columnNode->GetOrCreateGestureEventHub();
5611 CHECK_NULL_VOID(hub);
5612 auto frameNode = hub->GetFrameNode();
5613 CHECK_NULL_VOID(frameNode);
5614 RefPtr<PixelMap> pixelMap = hub->GetPixelMap();
5615 CHECK_NULL_VOID(pixelMap);
5616 float scale = PIXELMAP_DRAG_SCALE;
5617 UpdatePixelMapScale(scale);
5618 int32_t width = pixelMap->GetWidth();
5619 int32_t height = pixelMap->GetHeight();
5620
5621 auto shadow = imageContext->GetBackShadow();
5622 if (!shadow.has_value()) {
5623 shadow = Shadow::CreateShadow(ShadowStyle::None);
5624 }
5625 imageContext->UpdateBackShadow(shadow.value());
5626 AnimationOption option;
5627 option.SetCurve(Curves::SHARP);
5628 option.SetDuration(PIXELMAP_ANIMATION_DURATION);
5629 AnimationUtils::Animate(option, [imageContext, shadow]() mutable {
5630 if (imageContext) {
5631 auto color = shadow->GetColor();
5632 auto newColor = Color::FromARGB(1, color.GetRed(), color.GetGreen(), color.GetBlue());
5633 shadow->SetColor(newColor);
5634 imageContext->UpdateBackShadow(shadow.value());
5635 BorderRadiusProperty borderRadius;
5636 borderRadius.SetRadius(0.0_vp);
5637 imageContext->UpdateBorderRadius(borderRadius);
5638 }
5639 });
5640
5641 auto pipelineContext = PipelineContext::GetCurrentContext();
5642 CHECK_NULL_VOID(pipelineContext);
5643 auto menuTheme = pipelineContext->GetTheme<NG::MenuTheme>();
5644 CHECK_NULL_VOID(menuTheme);
5645 auto springMotionResponse = menuTheme->GetPreviewDisappearSpringMotionResponse();
5646 auto springMotionDampingFraction = menuTheme->GetPreviewDisappearSpringMotionDampingFraction();
5647
5648 AnimationOption scaleOption;
5649 auto motion = AceType::MakeRefPtr<ResponsiveSpringMotion>(springMotionResponse, springMotionDampingFraction);
5650 scaleOption.SetCurve(motion);
5651
5652 DragEventActuator::ExecutePreDragAction(PreDragStatus::PREVIEW_LANDING_STARTED);
5653 scaleOption.SetOnFinishEvent([weak = WeakClaim(this), isSubwindowOverlay] {
5654 auto pipeline = PipelineContext::GetCurrentContext();
5655 CHECK_NULL_VOID(pipeline);
5656 auto dragDropManager = pipeline->GetDragDropManager();
5657 CHECK_NULL_VOID(dragDropManager);
5658 DragEventActuator::ExecutePreDragAction(PreDragStatus::PREVIEW_LANDING_FINISHED);
5659 if (!dragDropManager->IsNeedDisplayInSubwindow() && !isSubwindowOverlay) {
5660 InteractionInterface::GetInstance()->SetDragWindowVisible(true);
5661 }
5662 auto overlayManager = weak.Upgrade();
5663 CHECK_NULL_VOID(overlayManager);
5664 if (overlayManager->hasEvent_) {
5665 overlayManager->RemoveEventColumn();
5666 }
5667 overlayManager->RemovePixelMap();
5668 });
5669
5670 auto coordinateX = imageNode->GetOffsetRelativeToWindow().GetX() - frameNode->GetOffsetRelativeToWindow().GetX();
5671 auto coordinateY = imageNode->GetOffsetRelativeToWindow().GetY() - frameNode->GetOffsetRelativeToWindow().GetY();
5672 AnimationUtils::Animate(
5673 scaleOption,
5674 [imageContext, startDrag, x, y, width, height, scale, coordinateX, coordinateY]() {
5675 if (startDrag) {
5676 imageContext->UpdatePosition(OffsetT<Dimension>(
5677 Dimension(x - (x - coordinateX) * scale +
5678 PIXELMAP_ANIMATION_DEFAULT_LIMIT_SCALE * width * (scale - PIXELMAP_DRAG_SCALE)),
5679 Dimension(y - (y - coordinateY) * scale +
5680 PIXELMAP_ANIMATION_DEFAULT_LIMIT_SCALE * height * (scale - PIXELMAP_DRAG_SCALE))));
5681 imageContext->UpdateTransformScale({ scale, scale });
5682 imageContext->OnModifyDone();
5683 } else {
5684 imageContext->UpdateTransformScale(VectorF(1.0f, 1.0f));
5685 }
5686 },
5687 scaleOption.GetOnFinishEvent());
5688 isOnAnimation_ = true;
5689 }
5690
RemoveDragPixelMap()5691 void OverlayManager::RemoveDragPixelMap()
5692 {
5693 TAG_LOGI(AceLogTag::ACE_DRAG, "remove drag pixelMap enter");
5694 if (!hasDragPixelMap_) {
5695 return;
5696 }
5697 auto columnNode = dragPixmapColumnNodeWeak_.Upgrade();
5698 if (!columnNode) {
5699 hasDragPixelMap_ = false;
5700 return;
5701 }
5702 auto rootNode = columnNode->GetParent();
5703 CHECK_NULL_VOID(rootNode);
5704 rootNode->RemoveChild(columnNode);
5705 rootNode->RebuildRenderContextTree();
5706 rootNode->MarkDirtyNode(PROPERTY_UPDATE_BY_CHILD_REQUEST);
5707 hasDragPixelMap_ = false;
5708 }
5709
UpdatePixelMapScale(float & scale)5710 void OverlayManager::UpdatePixelMapScale(float& scale)
5711 {
5712 auto columnNode = pixmapColumnNodeWeak_.Upgrade();
5713 CHECK_NULL_VOID(columnNode);
5714 auto hub = columnNode->GetOrCreateGestureEventHub();
5715 CHECK_NULL_VOID(hub);
5716 RefPtr<PixelMap> pixelMap = hub->GetPixelMap();
5717 CHECK_NULL_VOID(pixelMap);
5718 int32_t height = pixelMap->GetHeight();
5719 int32_t width = pixelMap->GetWidth();
5720 if (height == 0 || width == 0) {
5721 return;
5722 }
5723 int32_t deviceWidth = SystemProperties::GetDeviceWidth();
5724 int32_t deviceHeight = SystemProperties::GetDeviceHeight();
5725 int32_t maxDeviceLength = std::max(deviceHeight, deviceWidth);
5726 int32_t minDeviceLength = std::min(deviceHeight, deviceWidth);
5727 if (maxDeviceLength * PIXELMAP_DEFALUT_LIMIT_SCALE > minDeviceLength) {
5728 if (height > minDeviceLength * PIXELMAP_DEFALUT_LIMIT_SCALE) {
5729 scale = static_cast<float>(minDeviceLength * PIXELMAP_DEFALUT_LIMIT_SCALE) / height;
5730 }
5731 } else {
5732 if (hub->GetTextDraggable() && height > minDeviceLength / PIXELMAP_DRAG_WGR_SCALE &&
5733 width > minDeviceLength * PIXELMAP_DRAG_WGR_TEXT_SCALE / PIXELMAP_DRAG_WGR_SCALE) {
5734 scale = fmin(static_cast<float>(minDeviceLength / PIXELMAP_DRAG_WGR_SCALE) / height,
5735 static_cast<float>(minDeviceLength * PIXELMAP_DRAG_WGR_TEXT_SCALE / PIXELMAP_DRAG_WGR_SCALE) / width);
5736 } else if (height > minDeviceLength / PIXELMAP_DRAG_WGR_SCALE &&
5737 width > minDeviceLength / PIXELMAP_DRAG_WGR_SCALE) {
5738 scale = fmin(static_cast<float>(minDeviceLength / PIXELMAP_DRAG_WGR_SCALE) / height,
5739 static_cast<float>(minDeviceLength / PIXELMAP_DRAG_WGR_SCALE) / width);
5740 }
5741 }
5742 }
5743
RemoveFilterAnimation()5744 void OverlayManager::RemoveFilterAnimation()
5745 {
5746 if (!hasFilter_) {
5747 return;
5748 }
5749 auto filterNode = filterColumnNodeWeak_.Upgrade();
5750 CHECK_NULL_VOID(filterNode);
5751 auto filterContext = filterNode->GetRenderContext();
5752 CHECK_NULL_VOID(filterContext);
5753 auto pipelineContext = PipelineContext::GetCurrentContext();
5754 CHECK_NULL_VOID(pipelineContext);
5755 auto menuTheme = pipelineContext->GetTheme<NG::MenuTheme>();
5756 CHECK_NULL_VOID(menuTheme);
5757 AnimationOption option;
5758 option.SetOnFinishEvent([weak = WeakClaim(this)] {
5759 auto overlayManager = weak.Upgrade();
5760 CHECK_NULL_VOID(overlayManager);
5761 if (!overlayManager->hasFilterActived) {
5762 overlayManager->RemoveFilter();
5763 }
5764 });
5765 option.SetDuration(menuTheme->GetFilterAnimationDuration());
5766 option.SetCurve(Curves::SHARP);
5767 AnimationUtils::Animate(
5768 option,
5769 [filterContext]() {
5770 CHECK_NULL_VOID(filterContext);
5771 BlurStyleOption styleOption;
5772 styleOption.blurStyle = BlurStyle::NO_MATERIAL;
5773 filterContext->UpdateBackBlurStyle(styleOption);
5774 },
5775 option.GetOnFinishEvent());
5776 }
5777
RemoveFilter()5778 void OverlayManager::RemoveFilter()
5779 {
5780 if (!hasFilter_) {
5781 return;
5782 }
5783 auto columnNode = filterColumnNodeWeak_.Upgrade();
5784 if (columnNode) {
5785 auto rootNode = columnNode->GetParent();
5786 CHECK_NULL_VOID(rootNode);
5787 rootNode->RemoveChild(columnNode);
5788 rootNode->RebuildRenderContextTree();
5789 }
5790 hasFilter_ = false;
5791 }
5792
RemoveEventColumn()5793 void OverlayManager::RemoveEventColumn()
5794 {
5795 if (!hasEvent_) {
5796 TAG_LOGI(AceLogTag::ACE_DRAG, "remove eventColumn, hasEvent is false.");
5797 return;
5798 }
5799 auto columnNode = eventColumnNodeWeak_.Upgrade();
5800 if (!columnNode) {
5801 hasEvent_ = false;
5802 TAG_LOGI(AceLogTag::ACE_DRAG, "remove eventColumn, columnNode is null.");
5803 return;
5804 }
5805 auto rootNode = columnNode->GetParent();
5806 CHECK_NULL_VOID(rootNode);
5807 rootNode->RemoveChild(columnNode);
5808 hasEvent_ = false;
5809 TAG_LOGI(AceLogTag::ACE_DRAG, "remove eventColumn success.");
5810 }
5811
ResetRootNode(int32_t sessionId)5812 void OverlayManager::ResetRootNode(int32_t sessionId)
5813 {
5814 if (curSessionIds_.find(sessionId) == curSessionIds_.end()) {
5815 return;
5816 }
5817
5818 TAG_LOGI(AceLogTag::ACE_OVERLAY, "ResetRootNode %{public}d.", sessionId);
5819 curSessionIds_.erase(sessionId);
5820 auto rootNode = FindWindowScene(nullptr);
5821 CHECK_NULL_VOID(rootNode);
5822 rootNode->UpdateModalUiextensionCount(false);
5823 }
5824
SetIsAllowedBeCovered(bool isAllowedBeCovered)5825 void OverlayManager::SetIsAllowedBeCovered(bool isAllowedBeCovered)
5826 {
5827 isAllowedBeCovered_ = isAllowedBeCovered;
5828 }
5829
AddCurSessionId(int32_t sessionId)5830 bool OverlayManager::AddCurSessionId(int32_t sessionId)
5831 {
5832 if (curSessionIds_.find(sessionId) != curSessionIds_.end()) {
5833 return false;
5834 }
5835
5836 curSessionIds_.insert(sessionId);
5837 return true;
5838 }
5839
CreateModalUIExtension(const RefPtr<WantWrap> & wantWrap,const ModalUIExtensionCallbacks & callbacks,const ModalUIExtensionConfig & config)5840 int32_t OverlayManager::CreateModalUIExtension(const RefPtr<WantWrap>& wantWrap,
5841 const ModalUIExtensionCallbacks& callbacks, const ModalUIExtensionConfig& config)
5842 {
5843 auto& want = wantWrap->GetWant();
5844 return CreateModalUIExtension(want, callbacks, config);
5845 }
5846
HandleUIExtNodeSize(const AAFwk::Want & want,RefPtr<FrameNode> uiExtNode)5847 bool OverlayManager::HandleUIExtNodeSize(const AAFwk::Want& want, RefPtr<FrameNode> uiExtNode)
5848 {
5849 #if defined(OHOS_STANDARD_SYSTEM) and !defined(ACE_UNITTEST)
5850 auto uiExtNodeWidth = want.GetIntParam(WANT_PARAM_UIEXTNODE_WIDTH_KEY, 0);
5851 auto uiExtNodeHeight = want.GetIntParam(WANT_PARAM_UIEXTNODE_HEIGHT_KEY, 0);
5852 #else
5853 auto uiExtNodeWidth = 0;
5854 auto uiExtNodeHeight = 0;
5855 #endif
5856 auto layoutProperty = uiExtNode->GetLayoutProperty();
5857 CHECK_NULL_RETURN(layoutProperty, false);
5858 auto calcWidth =
5859 CalcLength((uiExtNodeWidth > 0) ? Dimension(uiExtNodeWidth) : Dimension(1.0, DimensionUnit::PERCENT));
5860 auto calcHeight =
5861 CalcLength((uiExtNodeHeight > 0) ? Dimension(uiExtNodeHeight) : Dimension(1.0, DimensionUnit::PERCENT));
5862 TAG_LOGD(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
5863 "UIExtensionNode Size[%{public}d, [%{public}d].", uiExtNodeWidth, uiExtNodeHeight);
5864 layoutProperty->UpdateUserDefinedIdealSize(CalcSize(calcWidth, calcHeight));
5865 return true;
5866 }
5867
HandleUIExtNodeAngle(int32_t uiExtNodeAngle,RefPtr<FrameNode> uiExtNode)5868 bool OverlayManager::HandleUIExtNodeAngle(int32_t uiExtNodeAngle, RefPtr<FrameNode> uiExtNode)
5869 {
5870 auto layoutProperty = uiExtNode->GetLayoutProperty();
5871 CHECK_NULL_RETURN(layoutProperty, false);
5872 const auto& renderContext = uiExtNode->GetRenderContext();
5873 CHECK_NULL_RETURN(renderContext, false);
5874 TAG_LOGD(AceLogTag::ACE_UIEXTENSIONCOMPONENT, "RootSize[%{public}f, %{public}f], Angle[%{public}d].",
5875 GetRootWidth(), GetRootHeight(), uiExtNodeAngle);
5876 switch (uiExtNodeAngle) {
5877 case UIEXTNODE_ANGLE_90: {
5878 layoutProperty->UpdateUserDefinedIdealSize(CalcSize(CalcLength(Dimension(GetRootHeight())),
5879 CalcLength(Dimension(GetRootWidth()))));
5880 TranslateOptions translate(GetRootWidth(), 0, 0);
5881 renderContext->UpdateTransformTranslate(translate);
5882 NG::Vector5F rotate(0.0f, 0.0f, 1.0f, 90.0f, 0.0f);
5883 DimensionOffset offset(Dimension(0), Dimension(0));
5884 renderContext->UpdateTransformRotate(rotate);
5885 renderContext->UpdateTransformCenter(offset);
5886 break;
5887 }
5888 case UIEXTNODE_ANGLE_180: {
5889 auto full = CalcLength(Dimension(1.0, DimensionUnit::PERCENT));
5890 layoutProperty->UpdateUserDefinedIdealSize(CalcSize(full, full));
5891 NG::Vector5F rotate(0.0f, 0.0f, 1.0f, 180.0f, 0.0f);
5892 DimensionOffset offset(0.5_pct, 0.5_pct);
5893 renderContext->UpdateTransformRotate(rotate);
5894 renderContext->UpdateTransformCenter(offset);
5895 break;
5896 }
5897 case UIEXTNODE_ANGLE_270: {
5898 layoutProperty->UpdateUserDefinedIdealSize(CalcSize(CalcLength(Dimension(GetRootHeight())),
5899 CalcLength(Dimension(GetRootWidth()))));
5900 TranslateOptions translate(0, GetRootHeight(), 0);
5901 renderContext->UpdateTransformTranslate(translate);
5902 NG::Vector5F rotate(0.0f, 0.0f, 1.0f, 270.0f, 0.0f);
5903 DimensionOffset offset(Dimension(0), Dimension(0));
5904 renderContext->UpdateTransformRotate(rotate);
5905 renderContext->UpdateTransformCenter(offset);
5906 break;
5907 }
5908 }
5909 return true;
5910 }
5911
HandleUIExtNodeTransform(const AAFwk::Want & want,RefPtr<FrameNode> uiExtNode)5912 bool OverlayManager::HandleUIExtNodeTransform(const AAFwk::Want& want, RefPtr<FrameNode> uiExtNode)
5913 {
5914 auto containerId = Container::CurrentId();
5915 auto foldWindow = FoldableWindow::CreateFoldableWindow(containerId);
5916 bool isFoldExpand = foldWindow && (foldWindow->IsFoldExpand());
5917 #if defined(OHOS_STANDARD_SYSTEM) and !defined(ACE_UNITTEST)
5918 auto uiExtNodeAngle = want.GetIntParam(WANT_PARAM_UIEXTNODE_ANGLE_KEY, 0);
5919 #else
5920 auto uiExtNodeAngle = 0;
5921 #endif
5922 if (!(isFoldExpand) && UIExtNodeAngleValid(uiExtNodeAngle)) {
5923 return HandleUIExtNodeAngle(uiExtNodeAngle, uiExtNode);
5924 } else if (!UIExtNodeAngleValid(uiExtNodeAngle)) {
5925 return HandleUIExtNodeSize(want, uiExtNode);
5926 }
5927 return true;
5928 }
5929
UIExtNodeAngleValid(int32_t uiExtNodeAngle)5930 bool OverlayManager::UIExtNodeAngleValid(int32_t uiExtNodeAngle)
5931 {
5932 return (uiExtNodeAngle == UIEXTNODE_ANGLE_90) ||
5933 (uiExtNodeAngle == UIEXTNODE_ANGLE_180) || (uiExtNodeAngle == UIEXTNODE_ANGLE_270);
5934 }
5935
CreateModalUIExtension(const AAFwk::Want & want,const ModalUIExtensionCallbacks & callbacks,const ModalUIExtensionConfig & config)5936 int32_t OverlayManager::CreateModalUIExtension(
5937 const AAFwk::Want& want, const ModalUIExtensionCallbacks& callbacks,
5938 const ModalUIExtensionConfig& config)
5939 {
5940 isProhibitBack_ = config.isProhibitBack;
5941 NG::InnerModalUIExtensionConfig innerModalUIExtensionConfig = { .isAsyncModalBinding = config.isAsyncModalBinding,
5942 .isDensityFollowHost = config.isDensityFollowHost };
5943 auto uiExtNode = ModalUIExtension::Create(want, callbacks, innerModalUIExtensionConfig);
5944 if (!HandleUIExtNodeTransform(want, uiExtNode)) {
5945 return 0;
5946 }
5947 auto buildNodeFunc = [uiExtNode]() -> RefPtr<UINode> {
5948 uiExtNode->MarkModifyDone();
5949 return uiExtNode;
5950 };
5951 auto sessionId = ModalUIExtension::GetSessionId(uiExtNode);
5952 if (!config.isAsyncModalBinding) {
5953 ModalStyle modalStyle = OverlayManager::SetUIExtensionModalStyleAndGet(config.prohibitedRemoveByRouter,
5954 config.prohibitedRemoveByNavigation);
5955 SetIsAllowedBeCovered(config.isAllowedBeCovered);
5956 // Convert the sessionId into a negative number to distinguish it from the targetId of other modal pages
5957 BindContentCover(true, nullptr, std::move(buildNodeFunc), modalStyle, nullptr, nullptr, nullptr, nullptr,
5958 ContentCoverParam(), nullptr, -(sessionId));
5959 SetIsAllowedBeCovered(true); // Reset isAllowedBeCovered
5960 } else {
5961 auto bindModalCallback = [weak = WeakClaim(this), buildNodeFunc, sessionId, id = Container::CurrentId(),
5962 isAllowedBeCovered = config.isAllowedBeCovered,
5963 prohibitedRemoveByRouter = config.prohibitedRemoveByRouter,
5964 prohibitedRemoveByNavigation = config.prohibitedRemoveByNavigation,
5965 doAfterAsyncModalBinding = std::move(config.doAfterAsyncModalBinding)]() {
5966 ContainerScope scope(id);
5967 auto overlayManager = weak.Upgrade();
5968 CHECK_NULL_VOID(overlayManager);
5969 overlayManager->SetIsAllowedBeCovered(isAllowedBeCovered);
5970 ModalStyle modalStyle = OverlayManager::SetUIExtensionModalStyleAndGet(prohibitedRemoveByRouter,
5971 prohibitedRemoveByNavigation);
5972 overlayManager->BindContentCover(true, nullptr, std::move(buildNodeFunc), modalStyle, nullptr, nullptr,
5973 nullptr, nullptr, ContentCoverParam(), nullptr, -(sessionId));
5974 overlayManager->SetIsAllowedBeCovered(true);
5975 if (doAfterAsyncModalBinding) {
5976 doAfterAsyncModalBinding();
5977 }
5978 };
5979 ModalUIExtension::SetBindModalCallback(uiExtNode, std::move(bindModalCallback));
5980 uiExtNodes_[sessionId] = WeakClaim(RawPtr(uiExtNode));
5981 }
5982 return sessionId;
5983 }
5984
SetUIExtensionModalStyleAndGet(bool prohibitedRemoveByRouter,bool prohibitedRemoveByNavigation)5985 ModalStyle OverlayManager::SetUIExtensionModalStyleAndGet(bool prohibitedRemoveByRouter,
5986 bool prohibitedRemoveByNavigation)
5987 {
5988 ModalStyle modalStyle;
5989 modalStyle.modalTransition = NG::ModalTransition::NONE;
5990 modalStyle.isUIExtension = true;
5991 modalStyle.prohibitedRemoveByRouter = prohibitedRemoveByRouter;
5992 modalStyle.prohibitedRemoveByNavigation = prohibitedRemoveByNavigation;
5993
5994 return modalStyle;
5995 }
5996
ClearUIExtensionNode()5997 void OverlayManager::ClearUIExtensionNode()
5998 {
5999 for (auto& item: uiExtNodes_) {
6000 auto uiExtNode = item.second.Upgrade();
6001 if (uiExtNode) {
6002 ModalUIExtension::SetBindModalCallback(uiExtNode, nullptr);
6003 }
6004 }
6005 uiExtNodes_.clear();
6006 }
6007
DeleteUIExtensionNode(int32_t sessionId)6008 void OverlayManager::DeleteUIExtensionNode(int32_t sessionId)
6009 {
6010 auto iter = uiExtNodes_.find(sessionId);
6011 if (iter != uiExtNodes_.end()) {
6012 auto uiExtNode = iter->second.Upgrade();
6013 if (uiExtNode) {
6014 ModalUIExtension::SetBindModalCallback(uiExtNode, nullptr);
6015 }
6016 uiExtNodes_.erase(sessionId);
6017 }
6018 }
6019
CloseModalUIExtension(int32_t sessionId)6020 void OverlayManager::CloseModalUIExtension(int32_t sessionId)
6021 {
6022 DeleteUIExtensionNode(sessionId);
6023 ModalStyle modalStyle;
6024 modalStyle.modalTransition = NG::ModalTransition::NONE;
6025 BindContentCover(false, nullptr, nullptr, modalStyle, nullptr, nullptr, nullptr, nullptr, ContentCoverParam(),
6026 nullptr, -(sessionId));
6027 ResetRootNode(-(sessionId));
6028 }
6029
UpdateModalUIExtensionConfig(int32_t sessionId,const ModalUIExtensionAllowedUpdateConfig & config)6030 void OverlayManager::UpdateModalUIExtensionConfig(
6031 int32_t sessionId, const ModalUIExtensionAllowedUpdateConfig& config)
6032 {
6033 auto targetModalNode = GetModal((-(sessionId)));
6034 if (!targetModalNode) {
6035 TAG_LOGE(AceLogTag::ACE_OVERLAY,
6036 "not has sessionId(%{public}d) when UpdateModalUIExtensionConfig", sessionId);
6037 return;
6038 }
6039
6040 const auto& targetModalPattern = targetModalNode->GetPattern<ModalPresentationPattern>();
6041 CHECK_NULL_VOID(targetModalPattern);
6042 targetModalPattern->SetProhibitedRemoveByNavigation(config.prohibitedRemoveByNavigation);
6043 targetModalPattern->SetProhibitedRemoveByRouter(config.prohibitedRemoveByRouter);
6044 TAG_LOGE(AceLogTag::ACE_OVERLAY,
6045 "UpdateModalUIExtensionConfig seccess with sessionId(%{public}d)", sessionId);
6046 }
6047
BuildAIEntityMenu(const std::vector<std::pair<std::string,std::function<void ()>>> & menuOptions)6048 RefPtr<FrameNode> OverlayManager::BuildAIEntityMenu(
6049 const std::vector<std::pair<std::string, std::function<void()>>>& menuOptions)
6050 {
6051 TAG_LOGI(AceLogTag::ACE_OVERLAY, "build AI entity menu enter");
6052 auto menuNode = FrameNode::CreateFrameNode(V2::MENU_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
6053 AceType::MakeRefPtr<InnerMenuPattern>(-1, V2::MENU_ETS_TAG, MenuType::MULTI_MENU));
6054 CHECK_NULL_RETURN(menuNode, nullptr);
6055 for (const auto& menuOption : menuOptions) {
6056 MenuItemGroupView::Create();
6057 auto menuItemGroupNode = DynamicCast<FrameNode>(ViewStackProcessor::GetInstance()->Finish());
6058 CHECK_NULL_RETURN(menuItemGroupNode, nullptr);
6059 MenuItemProperties menuItemProperties;
6060 menuItemProperties.content = menuOption.first;
6061 MenuItemModelNG menuItemModel;
6062 menuItemModel.Create(menuItemProperties);
6063 auto menuItemNode = DynamicCast<FrameNode>(ViewStackProcessor::GetInstance()->Finish());
6064 CHECK_NULL_RETURN(menuItemNode, nullptr);
6065 auto menuItemPattern = menuItemNode->GetPattern<MenuItemPattern>();
6066 CHECK_NULL_RETURN(menuItemPattern, nullptr);
6067 menuItemPattern->SetOnClickAIMenuItem(menuOption.second);
6068 menuItemNode->MountToParent(menuItemGroupNode);
6069 menuItemGroupNode->MountToParent(menuNode);
6070 }
6071 return menuNode;
6072 }
6073
CreateAIEntityMenu(const std::vector<std::pair<std::string,std::function<void ()>>> & menuOptions,const RefPtr<FrameNode> & targetNode)6074 RefPtr<FrameNode> OverlayManager::CreateAIEntityMenu(
6075 const std::vector<std::pair<std::string, std::function<void()>>>& menuOptions, const RefPtr<FrameNode>& targetNode)
6076 {
6077 TAG_LOGI(AceLogTag::ACE_OVERLAY, "create AI entity menu enter");
6078 CHECK_NULL_RETURN(targetNode, nullptr);
6079 auto pipeline = PipelineContext::GetCurrentContext();
6080 CHECK_NULL_RETURN(pipeline, nullptr);
6081 MenuParam menuParam;
6082 menuParam.type = MenuType::MENU;
6083 menuParam.placement = Placement::BOTTOM_LEFT;
6084 auto menuWrapperNode =
6085 MenuView::Create(BuildAIEntityMenu(menuOptions), targetNode->GetId(), targetNode->GetTag(), menuParam, true);
6086 return menuWrapperNode;
6087 }
6088
ShowAIEntityMenu(const std::vector<std::pair<std::string,std::function<void ()>>> & menuOptions,const RectF & aiRect,const RefPtr<FrameNode> & targetNode)6089 bool OverlayManager::ShowAIEntityMenu(const std::vector<std::pair<std::string, std::function<void()>>>& menuOptions,
6090 const RectF& aiRect, const RefPtr<FrameNode>& targetNode)
6091 {
6092 TAG_LOGI(AceLogTag::ACE_OVERLAY, "show AI entity menu enter");
6093 CHECK_NULL_RETURN(targetNode, false);
6094 auto menuWrapperNode = CreateAIEntityMenu(menuOptions, targetNode);
6095 CHECK_NULL_RETURN(menuWrapperNode, false);
6096 menuWrapperNode->GetOrCreateFocusHub()->SetFocusable(false);
6097 auto wrapperPattern = menuWrapperNode->GetPattern<MenuWrapperPattern>();
6098 CHECK_NULL_RETURN(wrapperPattern, false);
6099 auto pipeline = targetNode->GetContext();
6100 CHECK_NULL_RETURN(pipeline, false);
6101 auto safeAreaManager = pipeline->GetSafeAreaManager();
6102 CHECK_NULL_RETURN(safeAreaManager, false);
6103 auto targetId = targetNode->GetId();
6104 wrapperPattern->RegisterMenuAppearCallback([overlayWk = WeakClaim(this),
6105 safeAreaWK = WeakClaim(RawPtr(safeAreaManager)), targetId, containerId = Container::CurrentId()]() {
6106 ContainerScope scope(containerId);
6107 auto safeAreaManager = safeAreaWK.Upgrade();
6108 CHECK_NULL_VOID(safeAreaManager);
6109 safeAreaManager->AddKeyboardChangeCallbackConsideringUIExt(targetId, [overlayWk, targetId, containerId]() {
6110 ContainerScope scope(containerId);
6111 auto overlayManager = overlayWk.Upgrade();
6112 CHECK_NULL_VOID(overlayManager);
6113 overlayManager->CloseAIEntityMenu(targetId);
6114 });
6115 });
6116 wrapperPattern->RegisterMenuDisappearCallback(
6117 [safeAreaWK = WeakClaim(RawPtr(safeAreaManager)), targetId, containerId = Container::CurrentId()]() {
6118 ContainerScope scope(containerId);
6119 auto safeAreaManager = safeAreaWK.Upgrade();
6120 CHECK_NULL_VOID(safeAreaManager);
6121 safeAreaManager->RemoveKeyboardChangeCallbackConsideringUIExt(targetId);
6122 });
6123 auto menuNode = DynamicCast<FrameNode>(menuWrapperNode->GetFirstChild());
6124 CHECK_NULL_RETURN(menuNode, false);
6125 auto menuLayoutProperty = menuNode->GetLayoutProperty<MenuLayoutProperty>();
6126 CHECK_NULL_RETURN(menuLayoutProperty, false);
6127 menuLayoutProperty->UpdateIsRectInTarget(true);
6128 menuLayoutProperty->UpdateTargetSize(aiRect.GetSize());
6129
6130 auto theme = pipeline->GetTheme<SelectTheme>();
6131 CHECK_NULL_RETURN(theme, false);
6132 if (theme->GetExpandDisplay()) {
6133 MenuParam menuParam {};
6134 SubwindowManager::GetInstance()->ShowMenuNG(menuWrapperNode, menuParam, targetNode, aiRect.GetOffset());
6135 } else {
6136 ShowMenu(targetNode->GetId(), aiRect.GetOffset(), menuWrapperNode);
6137 }
6138 return true;
6139 }
6140
CloseAIEntityMenu(int32_t targetId)6141 void OverlayManager::CloseAIEntityMenu(int32_t targetId)
6142 {
6143 auto pipeline = PipelineContext::GetCurrentContextSafely();
6144 CHECK_NULL_VOID(pipeline);
6145 auto theme = pipeline->GetTheme<SelectTheme>();
6146 CHECK_NULL_VOID(theme);
6147 auto expandDisplay = theme->GetExpandDisplay();
6148 if (expandDisplay) {
6149 SubwindowManager::GetInstance()->ClearMenu();
6150 SubwindowManager::GetInstance()->ClearMenuNG(Container::CurrentId(), targetId);
6151 } else {
6152 auto menuNode = GetMenuNode(targetId);
6153 CHECK_NULL_VOID(menuNode);
6154 HideMenu(menuNode, targetId);
6155 }
6156 }
6157
CreateOverlayNode()6158 void OverlayManager::CreateOverlayNode()
6159 {
6160 TAG_LOGD(AceLogTag::ACE_OVERLAY, "create overlay node enter");
6161 if (overlayNode_) {
6162 return;
6163 }
6164 auto rootNode = rootNodeWeak_.Upgrade();
6165 CHECK_NULL_VOID(rootNode);
6166 auto pipelineContext = PipelineContext::GetCurrentContext();
6167 CHECK_NULL_VOID(pipelineContext);
6168 auto stageManager = pipelineContext->GetStageManager();
6169 CHECK_NULL_VOID(stageManager);
6170 auto stageNode = stageManager->GetStageNode();
6171 CHECK_NULL_VOID(stageNode);
6172 overlayNode_ = FrameNode::CreateFrameNode(V2::OVERLAY_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
6173 AceType::MakeRefPtr<OverlayContainerPattern>());
6174 CHECK_NULL_VOID(overlayNode_);
6175 overlayNode_->SetHitTestMode(HitTestMode::HTMTRANSPARENT_SELF);
6176 auto layoutProperty = overlayNode_->GetLayoutProperty();
6177 CHECK_NULL_VOID(layoutProperty);
6178 auto full = CalcLength(Dimension(1.0, DimensionUnit::PERCENT));
6179 layoutProperty->UpdateUserDefinedIdealSize(CalcSize(full, full));
6180 rootNode->AddChildAfter(overlayNode_, stageNode);
6181 }
6182
AddFrameNodeToOverlay(const RefPtr<NG::FrameNode> & node,std::optional<int32_t> index)6183 void OverlayManager::AddFrameNodeToOverlay(const RefPtr<NG::FrameNode>& node, std::optional<int32_t> index)
6184 {
6185 TAG_LOGD(AceLogTag::ACE_OVERLAY, "add FrameNode to the overlay node enter");
6186 CHECK_NULL_VOID(node);
6187 int32_t level = -1;
6188 if (index.has_value() && index.value() >= 0) {
6189 level = index.value();
6190 }
6191 CreateOverlayNode();
6192 CHECK_NULL_VOID(overlayNode_);
6193 if (frameNodeMapOnOverlay_.find(node->GetId()) != frameNodeMapOnOverlay_.end()) {
6194 overlayNode_->RemoveChild(node);
6195 frameNodeMapOnOverlay_.erase(node->GetId());
6196 }
6197 const auto& children = overlayNode_->GetChildren();
6198 if (level == -1) {
6199 overlayNode_->AddChild(node);
6200 } else if (children.empty() || frameNodeMapOnOverlay_[overlayNode_->GetFirstChild()->GetId()] == -1 ||
6201 level < frameNodeMapOnOverlay_[overlayNode_->GetFirstChild()->GetId()]) {
6202 overlayNode_->AddChild(node, 0);
6203 } else {
6204 for (auto it = children.rbegin(); it != children.rend(); ++it) {
6205 auto childLevel = frameNodeMapOnOverlay_[(*it)->GetId()];
6206 if (childLevel < 0) {
6207 continue;
6208 }
6209 if (childLevel <= level) {
6210 auto beforeNode = DynamicCast<FrameNode>(*it);
6211 CHECK_NULL_VOID(beforeNode);
6212 overlayNode_->AddChildAfter(node, beforeNode);
6213 break;
6214 }
6215 }
6216 }
6217 overlayNode_->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD);
6218 frameNodeMapOnOverlay_[node->GetId()] = level;
6219 auto focusHub = node->GetFocusHub();
6220 CHECK_NULL_VOID(focusHub);
6221 focusHub->RequestFocus();
6222 }
6223
RemoveFrameNodeOnOverlay(const RefPtr<NG::FrameNode> & node)6224 void OverlayManager::RemoveFrameNodeOnOverlay(const RefPtr<NG::FrameNode>& node)
6225 {
6226 TAG_LOGD(AceLogTag::ACE_OVERLAY, "delete the FrameNode on the overlay node enter");
6227 CHECK_NULL_VOID(node);
6228 if (frameNodeMapOnOverlay_.find(node->GetId()) == frameNodeMapOnOverlay_.end()) {
6229 TAG_LOGW(AceLogTag::ACE_OVERLAY, "the node does not exist in the overlay");
6230 return;
6231 }
6232 CHECK_NULL_VOID(overlayNode_);
6233 overlayNode_->RemoveChild(node);
6234 frameNodeMapOnOverlay_.erase(node->GetId());
6235 if (overlayNode_->GetChildren().empty()) {
6236 auto rootNode = rootNodeWeak_.Upgrade();
6237 CHECK_NULL_VOID(rootNode);
6238 rootNode->RemoveChild(overlayNode_);
6239 overlayNode_.Reset();
6240 frameNodeMapOnOverlay_.clear();
6241 rootNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD);
6242 return;
6243 }
6244 overlayNode_->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD);
6245 }
6246
ShowNodeOnOverlay(const RefPtr<NG::FrameNode> & node)6247 void OverlayManager::ShowNodeOnOverlay(const RefPtr<NG::FrameNode>& node)
6248 {
6249 TAG_LOGD(AceLogTag::ACE_OVERLAY, "show the FrameNode on the overlay node enter");
6250 CHECK_NULL_VOID(node);
6251 CHECK_NULL_VOID(overlayNode_);
6252 auto layoutProperty = node->GetLayoutProperty();
6253 CHECK_NULL_VOID(layoutProperty);
6254 if (layoutProperty->GetVisibility().has_value() && layoutProperty->GetVisibilityValue() == VisibleType::VISIBLE) {
6255 return;
6256 }
6257 layoutProperty->UpdateVisibility(VisibleType::VISIBLE);
6258 node->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD);
6259 auto focusHub = node->GetFocusHub();
6260 CHECK_NULL_VOID(focusHub);
6261 focusHub->RequestFocus();
6262 }
6263
HideNodeOnOverlay(const RefPtr<NG::FrameNode> & node)6264 void OverlayManager::HideNodeOnOverlay(const RefPtr<NG::FrameNode>& node)
6265 {
6266 TAG_LOGD(AceLogTag::ACE_OVERLAY, "hide the FrameNode on the overlay node enter");
6267 CHECK_NULL_VOID(node);
6268 CHECK_NULL_VOID(overlayNode_);
6269 auto layoutProperty = node->GetLayoutProperty();
6270 CHECK_NULL_VOID(layoutProperty);
6271 if (layoutProperty->GetVisibility().has_value() && layoutProperty->GetVisibilityValue() == VisibleType::GONE) {
6272 return;
6273 }
6274 layoutProperty->UpdateVisibility(VisibleType::GONE);
6275 node->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD);
6276 auto focusHub = node->GetFocusHub();
6277 CHECK_NULL_VOID(focusHub);
6278 focusHub->LostFocusToViewRoot();
6279 }
6280
ShowAllNodesOnOverlay()6281 void OverlayManager::ShowAllNodesOnOverlay()
6282 {
6283 TAG_LOGD(AceLogTag::ACE_OVERLAY, "show all FrameNodes on the overlay node enter");
6284 CHECK_NULL_VOID(overlayNode_);
6285 for (auto& child : overlayNode_->GetChildren()) {
6286 auto frameNode = DynamicCast<FrameNode>(child);
6287 CHECK_NULL_VOID(frameNode);
6288 auto layoutProperty = frameNode->GetLayoutProperty();
6289 CHECK_NULL_VOID(layoutProperty);
6290 layoutProperty->UpdateVisibility(VisibleType::VISIBLE);
6291 }
6292 overlayNode_->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD);
6293 auto focusView = overlayNode_->GetPattern<FocusView>();
6294 CHECK_NULL_VOID(focusView);
6295 focusView->FocusViewShow();
6296 }
6297
HideAllNodesOnOverlay()6298 void OverlayManager::HideAllNodesOnOverlay()
6299 {
6300 TAG_LOGD(AceLogTag::ACE_OVERLAY, "hide all FrameNodes on the overlay node enter");
6301 CHECK_NULL_VOID(overlayNode_);
6302 for (auto& child : overlayNode_->GetChildren()) {
6303 auto frameNode = DynamicCast<FrameNode>(child);
6304 CHECK_NULL_VOID(frameNode);
6305 auto layoutProperty = frameNode->GetLayoutProperty();
6306 CHECK_NULL_VOID(layoutProperty);
6307 layoutProperty->UpdateVisibility(VisibleType::GONE);
6308 }
6309 overlayNode_->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD);
6310 auto focusView = overlayNode_->GetPattern<FocusView>();
6311 CHECK_NULL_VOID(focusView);
6312 focusView->FocusViewClose();
6313 }
6314
MarkDirty(PropertyChangeFlag flag)6315 void OverlayManager::MarkDirty(PropertyChangeFlag flag)
6316 {
6317 auto root = rootNodeWeak_.Upgrade();
6318 CHECK_NULL_VOID(root);
6319 auto pipeline = PipelineContext::GetCurrentContext();
6320 CHECK_NULL_VOID(pipeline);
6321 auto markNode = root;
6322 if (pipeline->GetInstallationFree()) {
6323 markNode = root->GetFirstChild();
6324 TAG_LOGD(AceLogTag::ACE_OVERLAY, "atomicService node need marked");
6325 }
6326 for (auto&& child : markNode->GetChildren()) {
6327 // first child is Stage node in main window, subwindow not has Stage node.
6328 if (child != root->GetFirstChild() || pipeline->IsSubPipeline()) {
6329 child->MarkDirtyNode(flag);
6330 // sheetPage Node will MarkDirty when VirtualKeyboard Height Changes
6331 auto sheetParent = DynamicCast<FrameNode>(child);
6332 if (sheetParent && sheetParent->GetTag() == V2::SHEET_WRAPPER_TAG) {
6333 auto sheet = sheetParent->GetChildAtIndex(0);
6334 if (sheet) {
6335 sheet->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
6336 }
6337 }
6338 }
6339 }
6340 }
6341
MarkDirtyOverlay()6342 void OverlayManager::MarkDirtyOverlay()
6343 {
6344 auto root = rootNodeWeak_.Upgrade();
6345 CHECK_NULL_VOID(root);
6346 auto child = root->GetLastChild();
6347 CHECK_NULL_VOID(child);
6348 // sheetPage Node will MarkDirty when VirtualKeyboard Height Changes
6349 auto sheetParent = DynamicCast<FrameNode>(child);
6350 if (sheetParent && sheetParent->GetTag() == V2::SHEET_WRAPPER_TAG) {
6351 auto sheet = sheetParent->GetChildAtIndex(0);
6352 if (sheet) {
6353 sheet->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
6354 }
6355 }
6356 }
6357
CheckPageNeedAvoidKeyboard() const6358 bool OverlayManager::CheckPageNeedAvoidKeyboard() const
6359 {
6360 auto root = rootNodeWeak_.Upgrade();
6361 CHECK_NULL_RETURN(root, true);
6362 auto child = root->GetLastChild();
6363 CHECK_NULL_RETURN(child, true);
6364 // page will not avoid keyboard when lastChild is sheet
6365 if (child->GetTag() != V2::SHEET_WRAPPER_TAG) {
6366 return true;
6367 }
6368 auto frameNode = DynamicCast<FrameNode>(child);
6369 return !(frameNode && frameNode->GetFocusHub() && frameNode->GetFocusHub()->IsCurrentFocus());
6370 }
6371
GetRootWidth() const6372 float OverlayManager::GetRootWidth() const
6373 {
6374 auto rootNode = rootNodeWeak_.Upgrade();
6375 CHECK_NULL_RETURN(rootNode, 0.0);
6376 auto rootGeometryNode = AceType::DynamicCast<FrameNode>(rootNode)->GetGeometryNode();
6377 CHECK_NULL_RETURN(rootGeometryNode, 0.0);
6378 auto rootWidth = rootGeometryNode->GetFrameSize().Width();
6379 return rootWidth;
6380 }
6381
GetRootHeight() const6382 float OverlayManager::GetRootHeight() const
6383 {
6384 auto rootNode = rootNodeWeak_.Upgrade();
6385 CHECK_NULL_RETURN(rootNode, 0.0);
6386 auto rootGeometryNode = AceType::DynamicCast<FrameNode>(rootNode)->GetGeometryNode();
6387 CHECK_NULL_RETURN(rootGeometryNode, 0.0);
6388 auto rootHeight = rootGeometryNode->GetFrameSize().Height();
6389 return rootHeight;
6390 }
6391
CheckReturnFocus(RefPtr<FrameNode> node)6392 void OverlayManager::CheckReturnFocus(RefPtr<FrameNode> node) {}
6393
isMaskNode(int32_t maskId)6394 bool OverlayManager::isMaskNode(int32_t maskId)
6395 {
6396 for (const auto& [key, value] : maskNodeIdMap_) {
6397 if (value == maskId) {
6398 return true;
6399 }
6400 }
6401 return false;
6402 }
6403
GetMaskNodeIdWithDialogId(int32_t dialogId)6404 int32_t OverlayManager::GetMaskNodeIdWithDialogId(int32_t dialogId)
6405 {
6406 auto iter = maskNodeIdMap_.find(dialogId);
6407 return (iter == maskNodeIdMap_.end()) ? -1 : iter->second;
6408 }
6409
MountGatherNodeToRootNode(const RefPtr<FrameNode> & frameNode,const std::vector<GatherNodeChildInfo> & gatherNodeChildrenInfo)6410 void OverlayManager::MountGatherNodeToRootNode(const RefPtr<FrameNode>& frameNode,
6411 const std::vector<GatherNodeChildInfo>& gatherNodeChildrenInfo)
6412 {
6413 auto rootNode = rootNodeWeak_.Upgrade();
6414 CHECK_NULL_VOID(rootNode);
6415 frameNode->MountToParent(rootNode);
6416 frameNode->OnMountToParentDone();
6417 rootNode->MarkDirtyNode(PROPERTY_UPDATE_BY_CHILD_REQUEST);
6418 gatherNodeWeak_ = frameNode;
6419 hasGatherNode_ = true;
6420 gatherNodeChildrenInfo_ = gatherNodeChildrenInfo;
6421 }
6422
MountGatherNodeToWindowScene(const RefPtr<FrameNode> & frameNode,const std::vector<GatherNodeChildInfo> & gatherNodeChildrenInfo,const RefPtr<UINode> & windowScene)6423 void OverlayManager::MountGatherNodeToWindowScene(const RefPtr<FrameNode>& frameNode,
6424 const std::vector<GatherNodeChildInfo>& gatherNodeChildrenInfo,
6425 const RefPtr<UINode>& windowScene)
6426 {
6427 CHECK_NULL_VOID(windowScene);
6428 frameNode->MountToParent(windowScene);
6429 frameNode->OnMountToParentDone();
6430 windowScene->MarkDirtyNode(PROPERTY_UPDATE_BY_CHILD_REQUEST);
6431 gatherNodeWeak_ = frameNode;
6432 hasGatherNode_ = true;
6433 gatherNodeChildrenInfo_ = gatherNodeChildrenInfo;
6434 }
6435
RemoveGatherNode()6436 void OverlayManager::RemoveGatherNode()
6437 {
6438 CHECK_EQUAL_VOID(hasGatherNode_, false);
6439 auto frameNode = gatherNodeWeak_.Upgrade();
6440 CHECK_NULL_VOID(frameNode);
6441 TAG_LOGI(AceLogTag::ACE_DRAG, "Remove gather node");
6442 auto rootNode = frameNode->GetParent();
6443 CHECK_NULL_VOID(rootNode);
6444 rootNode->RemoveChild(frameNode);
6445 rootNode->MarkDirtyNode(PROPERTY_UPDATE_BY_CHILD_REQUEST);
6446 hasGatherNode_ = false;
6447 gatherNodeWeak_ = nullptr;
6448 gatherNodeChildrenInfo_.clear();
6449 }
6450
RemoveGatherNodeWithAnimation()6451 void OverlayManager::RemoveGatherNodeWithAnimation()
6452 {
6453 if (!hasGatherNode_) {
6454 return;
6455 }
6456 TAG_LOGI(AceLogTag::ACE_DRAG, "Remove gather node with animation");
6457 AnimationOption option;
6458 option.SetDuration(PIXELMAP_ANIMATION_DURATION);
6459 option.SetCurve(Curves::SHARP);
6460
6461 option.SetOnFinishEvent([weak = gatherNodeWeak_] {
6462 auto context = PipelineContext::GetCurrentContext();
6463 CHECK_NULL_VOID(context);
6464 auto taskExecutor = context->GetTaskExecutor();
6465 CHECK_NULL_VOID(taskExecutor);
6466 // animation finish event should be posted to UI thread.
6467 taskExecutor->PostTask(
6468 [weak, id = Container::CurrentId()]() {
6469 ContainerScope scope(id);
6470 auto frameNode = weak.Upgrade();
6471 CHECK_NULL_VOID(frameNode);
6472 auto rootNode = frameNode->GetParent();
6473 CHECK_NULL_VOID(rootNode);
6474 rootNode->RemoveChild(frameNode);
6475 rootNode->MarkDirtyNode(PROPERTY_UPDATE_BY_CHILD_REQUEST);
6476 },
6477 TaskExecutor::TaskType::UI, "ArkUIOverlayRemoveGatherNodeEvent");
6478 });
6479 gatherNodeWeak_ = nullptr;
6480 hasGatherNode_ = false;
6481 AnimationUtils::Animate(
6482 option,
6483 [gatherNodeChildrenInfo = gatherNodeChildrenInfo_]() {
6484 for (auto& child : gatherNodeChildrenInfo) {
6485 auto imageNode = child.imageNode.Upgrade();
6486 CHECK_NULL_VOID(imageNode);
6487 auto imageContext = imageNode->GetRenderContext();
6488 CHECK_NULL_VOID(imageContext);
6489 imageContext->UpdatePosition(OffsetT<Dimension>(Dimension(child.offset.GetX()),
6490 Dimension(child.offset.GetY())));
6491 imageContext->UpdateTransformScale({ 1.0f, 1.0f });
6492 Vector5F rotate = Vector5F(0.0f, 0.0f, 1.0f, 0.0f, 0.0f);
6493 imageContext->UpdateTransformRotate(rotate);
6494 imageContext->UpdateOpacity(1.0);
6495 BorderRadiusProperty borderRadius;
6496 borderRadius.SetRadius(0.0_vp);
6497 imageContext->UpdateBorderRadius(borderRadius);
6498 }
6499 },
6500 option.GetOnFinishEvent());
6501 }
6502
UpdateGatherNodeToTop()6503 void OverlayManager::UpdateGatherNodeToTop()
6504 {
6505 auto frameNode = gatherNodeWeak_.Upgrade();
6506 CHECK_NULL_VOID(frameNode);
6507 auto rootNode = frameNode->GetParent();
6508 CHECK_NULL_VOID(rootNode);
6509 rootNode->RemoveChild(frameNode);
6510 frameNode->MountToParent(rootNode);
6511 frameNode->OnMountToParentDone();
6512 rootNode->RebuildRenderContextTree();
6513 rootNode->MarkDirtyNode(PROPERTY_UPDATE_BY_CHILD_REQUEST);
6514 }
6515
GetPixelMapContentNode(bool isSubwindowOverlay) const6516 RefPtr<FrameNode> OverlayManager::GetPixelMapContentNode(bool isSubwindowOverlay) const
6517 {
6518 if (isSubwindowOverlay) {
6519 RefPtr<FrameNode> imageNode = GetPixelMapContentNodeForSubwindow();
6520 return imageNode;
6521 }
6522 auto column = pixmapColumnNodeWeak_.Upgrade();
6523 CHECK_NULL_RETURN(column, nullptr);
6524 auto imageNode = AceType::DynamicCast<FrameNode>(column->GetFirstChild());
6525 return imageNode;
6526 }
6527
GetPixelMapContentNodeForSubwindow() const6528 RefPtr<FrameNode> OverlayManager::GetPixelMapContentNodeForSubwindow() const
6529 {
6530 auto rootNode = rootNodeWeak_.Upgrade();
6531 CHECK_NULL_RETURN(rootNode, nullptr);
6532 for (const auto& child : rootNode->GetChildren()) {
6533 auto node = DynamicCast<FrameNode>(child);
6534 if (node && node->GetTag() != V2::MENU_WRAPPER_ETS_TAG) {
6535 continue;
6536 }
6537 for (auto& childNode : node->GetChildren()) {
6538 auto frameNode = DynamicCast<FrameNode>(childNode);
6539 if (frameNode &&
6540 (frameNode->GetTag() == V2::MENU_PREVIEW_ETS_TAG || frameNode->GetTag() == V2::IMAGE_ETS_TAG)) {
6541 return frameNode;
6542 }
6543 }
6544 }
6545 return nullptr;
6546 }
6547
UpdatePixelMapPosition(bool isSubwindowOverlay)6548 void OverlayManager::UpdatePixelMapPosition(bool isSubwindowOverlay)
6549 {
6550 if (!isSubwindowOverlay && !hasPixelMap_) {
6551 return;
6552 }
6553 if (IsOriginDragMoveVector() || !IsUpdateDragMoveVector()) {
6554 return;
6555 }
6556 auto moveVector = GetUpdateDragMoveVector();
6557 RefPtr<FrameNode> imageNode = GetPixelMapContentNode(isSubwindowOverlay);
6558 CHECK_NULL_VOID(imageNode);
6559 auto imageContext = imageNode->GetRenderContext();
6560 CHECK_NULL_VOID(imageContext);
6561 auto rect = imageNode->GetOffsetRelativeToWindow();
6562 imageContext->UpdatePosition(OffsetT<Dimension>(Dimension(moveVector.GetX() + rect.GetX()),
6563 Dimension(moveVector.GetY() + rect.GetY())));
6564 imageContext->OnModifyDone();
6565 }
6566
GetDragPixelMapContentNode() const6567 RefPtr<FrameNode> OverlayManager::GetDragPixelMapContentNode() const
6568 {
6569 auto column = dragPixmapColumnNodeWeak_.Upgrade();
6570 CHECK_NULL_RETURN(column, nullptr);
6571 auto imageNode = AceType::DynamicCast<FrameNode>(column->GetFirstChild());
6572 return imageNode;
6573 }
6574
GetPixelMapBadgeNode() const6575 RefPtr<FrameNode> OverlayManager::GetPixelMapBadgeNode() const
6576 {
6577 auto column = pixmapColumnNodeWeak_.Upgrade();
6578 CHECK_NULL_RETURN(column, nullptr);
6579 auto textNode = AceType::DynamicCast<FrameNode>(column->GetLastChild());
6580 CHECK_NULL_RETURN(textNode, nullptr);
6581 return textNode;
6582 }
6583
GetDragPixelMapBadgeNode() const6584 RefPtr<FrameNode> OverlayManager::GetDragPixelMapBadgeNode() const
6585 {
6586 auto column = dragPixmapColumnNodeWeak_.Upgrade();
6587 CHECK_NULL_RETURN(column, nullptr);
6588 auto textNode = AceType::DynamicCast<FrameNode>(column->GetLastChild());
6589 CHECK_NULL_RETURN(textNode, nullptr);
6590 return textNode;
6591 }
6592
RemoveMenuBadgeNode(const RefPtr<FrameNode> & menuWrapperNode)6593 void OverlayManager::RemoveMenuBadgeNode(const RefPtr<FrameNode>& menuWrapperNode)
6594 {
6595 CHECK_NULL_VOID(menuWrapperNode);
6596 auto pattern = menuWrapperNode->GetPattern<MenuWrapperPattern>();
6597 CHECK_NULL_VOID(pattern);
6598 auto badgeNode = pattern->GetBadgeNode();
6599 CHECK_NULL_VOID(badgeNode);
6600 menuWrapperNode->RemoveChild(badgeNode);
6601 menuWrapperNode->RebuildRenderContextTree();
6602 menuWrapperNode->MarkDirtyNode(PROPERTY_UPDATE_BY_CHILD_REQUEST);
6603 }
6604
RemovePreviewBadgeNode()6605 void OverlayManager::RemovePreviewBadgeNode()
6606 {
6607 auto columnNode = pixmapColumnNodeWeak_.Upgrade();
6608 CHECK_NULL_VOID(columnNode);
6609 auto textNode = AceType::DynamicCast<FrameNode>(columnNode->GetChildAtIndex(1));
6610 CHECK_NULL_VOID(textNode);
6611 columnNode->RemoveChild(textNode);
6612 columnNode->RebuildRenderContextTree();
6613 columnNode->MarkDirtyNode(PROPERTY_UPDATE_BY_CHILD_REQUEST);
6614 }
6615
GetRootNode() const6616 const WeakPtr<UINode>& OverlayManager::GetRootNode() const
6617 {
6618 return rootNodeWeak_;
6619 }
6620
GetGroupManager() const6621 const RefPtr<GroupManager>& OverlayManager::GetGroupManager() const
6622 {
6623 return groupManager_;
6624 }
6625
ShowFilterAnimation(const RefPtr<FrameNode> & columnNode)6626 void OverlayManager::ShowFilterAnimation(const RefPtr<FrameNode>& columnNode)
6627 {
6628 CHECK_NULL_VOID(columnNode);
6629
6630 auto filterRenderContext = columnNode->GetRenderContext();
6631 CHECK_NULL_VOID(filterRenderContext);
6632
6633 auto pipelineContext = PipelineContext::GetCurrentContext();
6634 CHECK_NULL_VOID(pipelineContext);
6635 auto menuTheme = pipelineContext->GetTheme<NG::MenuTheme>();
6636 CHECK_NULL_VOID(menuTheme);
6637
6638 auto maskColor = menuTheme->GetPreviewMenuMaskColor();
6639 BlurStyleOption styleOption;
6640 styleOption.blurStyle = BlurStyle::BACKGROUND_THIN;
6641 styleOption.colorMode = ThemeColorMode::SYSTEM;
6642
6643 AnimationOption option;
6644 option.SetDuration(menuTheme->GetFilterAnimationDuration());
6645 option.SetCurve(Curves::SHARP);
6646 option.SetOnFinishEvent([] {
6647 auto pipelineContext = PipelineContext::GetCurrentContext();
6648 auto manager = pipelineContext->GetOverlayManager();
6649 CHECK_NULL_VOID(manager);
6650 manager->SetFilterActive(false);
6651 });
6652 filterRenderContext->UpdateBackBlurRadius(Dimension(0.0f));
6653 AnimationUtils::Animate(
6654 option,
6655 [filterRenderContext, styleOption, maskColor, menuTheme]() {
6656 CHECK_NULL_VOID(filterRenderContext);
6657 if (menuTheme->GetHasBackBlur()) {
6658 filterRenderContext->UpdateBackBlurStyle(styleOption);
6659 } else {
6660 filterRenderContext->UpdateBackgroundColor(maskColor);
6661 }
6662 },
6663 option.GetOnFinishEvent());
6664 }
6665
RemoveMenuNotInSubWindow(const WeakPtr<FrameNode> & menuWK,const WeakPtr<UINode> & rootWeak,const WeakPtr<OverlayManager> & overlayWeak)6666 void OverlayManager::RemoveMenuNotInSubWindow(
6667 const WeakPtr<FrameNode>& menuWK, const WeakPtr<UINode>& rootWeak, const WeakPtr<OverlayManager>& overlayWeak)
6668 {
6669 auto menu = menuWK.Upgrade();
6670 CHECK_NULL_VOID(menu);
6671 auto rootNode = rootWeak.Upgrade();
6672 CHECK_NULL_VOID(rootNode);
6673 auto overlayManager = overlayWeak.Upgrade();
6674 CHECK_NULL_VOID(overlayManager);
6675
6676 auto container = Container::Current();
6677 if (container && container->IsScenceBoardWindow()) {
6678 rootNode = overlayManager->FindWindowScene(menu);
6679 }
6680 CHECK_NULL_VOID(rootNode);
6681 RemoveChildWithService(rootNode, menu);
6682 rootNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
6683 }
6684
DumpOverlayInfo() const6685 void OverlayManager::DumpOverlayInfo() const
6686 {
6687 auto container = Container::Current();
6688 if (container) {
6689 DumpLog::GetInstance().Print("Container: ");
6690 DumpLog::GetInstance().Print(DUMP_LOG_DEPTH_1, "ContainerId: " + std::to_string(container->GetInstanceId()));
6691 DumpLog::GetInstance().Print(
6692 DUMP_LOG_DEPTH_1, "IsSubContainer: " + std::string(container->IsSubContainer() ? "true" : "false"));
6693 }
6694
6695 DumpLog::GetInstance().Print("----------PopupMapInfo----------");
6696 DumpPopupMapInfo();
6697
6698 DumpLog::GetInstance().Print("----------MenuMapInfo----------");
6699 DumpMapInfo(menuMap_, "MenuMap");
6700
6701 DumpLog::GetInstance().Print("----------DialogMapInfo----------");
6702 DumpMapInfo(dialogMap_, "DialogMap", false);
6703
6704 DumpLog::GetInstance().Print("----------CustomPopupMapInfo----------");
6705 DumpMapInfo(customPopupMap_, "CustomPopupMap");
6706
6707 DumpLog::GetInstance().Print("----------CustomKeyboardMapInfo----------");
6708 DumpMapInfo(customKeyboardMap_, "CustomKeyboardMap");
6709
6710 DumpLog::GetInstance().Print("----------ToastMapInfo----------");
6711 DumpMapInfo(toastMap_, "ToastMap", false);
6712
6713 DumpLog::GetInstance().Print("----------SheetMapInfo----------");
6714 DumpSheetMapInfo(sheetMap_, "SheetMap");
6715
6716 DumpLog::GetInstance().Print("----------MaskNodeIdMapInfo----------");
6717 DumpMaskNodeIdMapInfo();
6718
6719 DumpLog::GetInstance().Print("----------ModalListInfo----------");
6720 DumpModalListInfo();
6721 }
6722
DumpPopupMapInfo() const6723 void OverlayManager::DumpPopupMapInfo() const
6724 {
6725 DumpLog::GetInstance().Print("PopupMap: ");
6726 DumpLog::GetInstance().Print(DUMP_LOG_DEPTH_1, "Size: " + std::to_string(popupMap_.size()));
6727 DumpLog::GetInstance().Print(DUMP_LOG_DEPTH_1, "Entries: [");
6728
6729 for (const auto& entry : popupMap_) {
6730 std::string entryLog = "";
6731 auto targetId = entry.first;
6732 auto targetNode = ElementRegister::GetInstance()->GetSpecificItemById<FrameNode>(targetId);
6733 auto popupInfo = entry.second;
6734 auto popupNode = popupInfo.popupNode;
6735 DumpEntry(targetNode, targetId, popupNode);
6736 }
6737
6738 DumpLog::GetInstance().Print(DUMP_LOG_DEPTH_1, "]");
6739 }
6740
DumpMapInfo(std::unordered_map<int32_t,RefPtr<FrameNode>> map,const std::string mapName,bool hasTarget) const6741 void OverlayManager::DumpMapInfo(
6742 std::unordered_map<int32_t, RefPtr<FrameNode>> map, const std::string mapName, bool hasTarget) const
6743 {
6744 DumpLog::GetInstance().Print(mapName + ": ");
6745 DumpLog::GetInstance().Print(DUMP_LOG_DEPTH_1, "Size: " + std::to_string(map.size()));
6746 DumpLog::GetInstance().Print(DUMP_LOG_DEPTH_1, "Entries: [");
6747
6748 for (const auto& entry : map) {
6749 auto targetId = entry.first;
6750 auto targetNode = ElementRegister::GetInstance()->GetSpecificItemById<FrameNode>(targetId);
6751 auto node = entry.second;
6752
6753 if (hasTarget) {
6754 DumpEntry(targetNode, targetId, node);
6755 } else {
6756 std::string entryLog = GetMapNodeLog(node, hasTarget);
6757 DumpLog::GetInstance().Print(DUMP_LOG_DEPTH_2, entryLog);
6758 }
6759 }
6760
6761 DumpLog::GetInstance().Print(DUMP_LOG_DEPTH_1, "]");
6762 }
6763
DumpMapInfo(std::unordered_map<int32_t,WeakPtr<FrameNode>> map,const std::string mapName,bool hasTarget) const6764 void OverlayManager::DumpMapInfo(
6765 std::unordered_map<int32_t, WeakPtr<FrameNode>> map, const std::string mapName, bool hasTarget) const
6766 {
6767 DumpLog::GetInstance().Print(mapName + ": ");
6768 DumpLog::GetInstance().Print(DUMP_LOG_DEPTH_1, "Size: " + std::to_string(map.size()));
6769 DumpLog::GetInstance().Print(DUMP_LOG_DEPTH_1, "Entries: [");
6770
6771 for (const auto& entry : map) {
6772 auto targetId = entry.first;
6773 auto targetNode = ElementRegister::GetInstance()->GetSpecificItemById<FrameNode>(targetId);
6774 auto node = entry.second.Upgrade();
6775 if (hasTarget) {
6776 DumpEntry(targetNode, targetId, node);
6777 } else {
6778 std::string entryLog = GetMapNodeLog(node, hasTarget);
6779 DumpLog::GetInstance().Print(DUMP_LOG_DEPTH_2, entryLog);
6780 }
6781 }
6782
6783 DumpLog::GetInstance().Print(DUMP_LOG_DEPTH_1, "]");
6784 }
6785
DumpSheetMapInfo(const std::unordered_map<SheetKey,WeakPtr<FrameNode>,SheetKeyHash> & map,const std::string mapName) const6786 void OverlayManager::DumpSheetMapInfo(
6787 const std::unordered_map<SheetKey, WeakPtr<FrameNode>, SheetKeyHash>& map,
6788 const std::string mapName) const
6789 {
6790 DumpLog::GetInstance().Print(mapName + ": ");
6791 DumpLog::GetInstance().Print(DUMP_LOG_DEPTH_1, "Size: " + std::to_string(map.size()));
6792 DumpLog::GetInstance().Print(DUMP_LOG_DEPTH_1, "Entries: [");
6793
6794 for (const auto& entry : map) {
6795 auto targetId = entry.first.targetId;
6796 auto targetNode = ElementRegister::GetInstance()->GetSpecificItemById<FrameNode>(targetId);
6797 auto node = entry.second.Upgrade();
6798 DumpEntry(targetNode, targetId, node);
6799 }
6800
6801 DumpLog::GetInstance().Print(DUMP_LOG_DEPTH_1, "]");
6802 }
6803
DumpMaskNodeIdMapInfo() const6804 void OverlayManager::DumpMaskNodeIdMapInfo() const
6805 {
6806 DumpLog::GetInstance().Print("MaskNodeIdMap: ");
6807 DumpLog::GetInstance().Print(DUMP_LOG_DEPTH_1, "Size: " + std::to_string(maskNodeIdMap_.size()));
6808 DumpLog::GetInstance().Print(DUMP_LOG_DEPTH_1, "Entries: [");
6809
6810 for (const auto& entry : maskNodeIdMap_) {
6811 auto targetId = entry.first;
6812 auto targetNode = ElementRegister::GetInstance()->GetSpecificItemById<FrameNode>(targetId);
6813 auto nodeId = entry.second;
6814 auto node = ElementRegister::GetInstance()->GetSpecificItemById<FrameNode>(nodeId);
6815 std::string entryLog = "DialogId: " + std::to_string(targetId);
6816 entryLog += ", DialogTag: " + (targetNode ? targetNode->GetTag() : "NULL");
6817 entryLog += ", NodeId: " + std::to_string(nodeId);
6818 entryLog += ", NodeTag: " + (node ? node->GetTag() : "NULL");
6819 DumpLog::GetInstance().Print(DUMP_LOG_DEPTH_2, entryLog);
6820 }
6821
6822 DumpLog::GetInstance().Print(DUMP_LOG_DEPTH_1, "]");
6823 }
6824
DumpModalListInfo() const6825 void OverlayManager::DumpModalListInfo() const
6826 {
6827 DumpLog::GetInstance().Print("ModalList: ");
6828 DumpLog::GetInstance().Print(DUMP_LOG_DEPTH_1, "Size: " + std::to_string(modalList_.size()));
6829 DumpLog::GetInstance().Print(DUMP_LOG_DEPTH_1, "Entries: [");
6830
6831 for (auto modal = modalList_.begin(); modal != modalList_.end(); ++modal) {
6832 std::string entryLog = "";
6833 auto modalNode = modal->Upgrade();
6834 entryLog += GetMapNodeLog(modalNode, false);
6835 DumpLog::GetInstance().Print(DUMP_LOG_DEPTH_2, entryLog);
6836 }
6837
6838 DumpLog::GetInstance().Print(DUMP_LOG_DEPTH_1, "]");
6839 }
6840
DumpEntry(const RefPtr<FrameNode> & targetNode,int32_t targetId,const RefPtr<FrameNode> & node) const6841 void OverlayManager::DumpEntry(
6842 const RefPtr<FrameNode>& targetNode, int32_t targetId, const RefPtr<FrameNode>& node) const
6843 {
6844 std::string entryLog = "TargetId: " + std::to_string(targetId);
6845 entryLog += ", TargetTag: " + (targetNode ? targetNode->GetTag() : "NULL");
6846 entryLog += GetMapNodeLog(node);
6847 DumpLog::GetInstance().Print(DUMP_LOG_DEPTH_2, entryLog);
6848 }
6849
GetMapNodeLog(const RefPtr<FrameNode> & node,bool hasTarget) const6850 std::string OverlayManager::GetMapNodeLog(const RefPtr<FrameNode>& node, bool hasTarget) const
6851 {
6852 CHECK_NULL_RETURN(node, "");
6853 std::string entryLog = (hasTarget ? ", " : "");
6854 entryLog += "NodeId: " + std::to_string(node->GetId()) + ", NodeTag: " + node->GetTag();
6855 return entryLog;
6856 }
6857
OnUIExtensionWindowSizeChange()6858 void OverlayManager::OnUIExtensionWindowSizeChange()
6859 {
6860 for (auto iter = dialogMap_.begin(); iter != dialogMap_.end(); iter++) {
6861 auto dialogNode = (*iter).second;
6862 CHECK_NULL_VOID(dialogNode);
6863 auto dialogPattern = dialogNode->GetPattern<DialogPattern>();
6864 CHECK_NULL_VOID(dialogPattern);
6865 dialogPattern->InitHostWindowRect();
6866 dialogNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
6867 }
6868 }
6869
MountToParentWithService(const RefPtr<UINode> & rootNode,const RefPtr<FrameNode> & node)6870 void OverlayManager::MountToParentWithService(const RefPtr<UINode>& rootNode, const RefPtr<FrameNode>& node)
6871 {
6872 CHECK_NULL_VOID(node);
6873 CHECK_NULL_VOID(rootNode);
6874 auto pipeline = rootNode->GetContextRefPtr();
6875 CHECK_NULL_VOID(pipeline);
6876 if (pipeline->GetInstallationFree()) {
6877 // it is in atomicservice
6878 SetNodeBeforeAppbar(rootNode, node);
6879 } else {
6880 node->MountToParent(rootNode);
6881 }
6882 }
6883
RemoveChildWithService(const RefPtr<UINode> & rootNode,const RefPtr<FrameNode> & node)6884 void OverlayManager::RemoveChildWithService(const RefPtr<UINode>& rootNode, const RefPtr<FrameNode>& node)
6885 {
6886 CHECK_NULL_VOID(rootNode);
6887 CHECK_NULL_VOID(node);
6888 auto parent = node->GetParent();
6889 CHECK_NULL_VOID(parent);
6890 parent->RemoveChild(node);
6891 }
6892
SetNodeBeforeAppbar(const RefPtr<NG::UINode> & rootNode,const RefPtr<FrameNode> & node)6893 void OverlayManager::SetNodeBeforeAppbar(const RefPtr<NG::UINode>& rootNode, const RefPtr<FrameNode>& node)
6894 {
6895 CHECK_NULL_VOID(rootNode);
6896 CHECK_NULL_VOID(node);
6897 for (auto child : rootNode->GetChildren()) {
6898 CHECK_NULL_VOID(child);
6899 if (child->GetTag() != V2::ATOMIC_SERVICE_ETS_TAG) {
6900 continue;
6901 }
6902 for (auto childNode : child->GetChildren()) {
6903 CHECK_NULL_VOID(childNode);
6904 if (childNode->GetTag() == V2::APP_BAR_ETS_TAG) {
6905 TAG_LOGD(AceLogTag::ACE_OVERLAY, "setNodeBeforeAppbar AddChildBefore");
6906 child->AddChildBefore(node, childNode);
6907 return;
6908 }
6909 }
6910 }
6911 }
6912
IsRootExpansive() const6913 bool OverlayManager::IsRootExpansive() const
6914 {
6915 auto rootNode = rootNodeWeak_.Upgrade();
6916 CHECK_NULL_RETURN(rootNode, false);
6917 auto pipelineContext = rootNode->GetContext();
6918 CHECK_NULL_RETURN(pipelineContext, false);
6919 auto manager = pipelineContext->GetSafeAreaManager();
6920 CHECK_NULL_RETURN(manager, false);
6921 if (manager->IsFullScreen()) {
6922 // if window is full screen, sheetPage should layout under 8vp + status bar height under parent
6923 return false;
6924 }
6925
6926 // if page parent is full screen, sheetPage should layout 8vp under parent
6927 auto layoutProp = DynamicCast<FrameNode>(rootNode)->GetLayoutProperty();
6928 CHECK_NULL_RETURN(layoutProp, false);
6929 const auto& opts = layoutProp->GetSafeAreaExpandOpts();
6930 return opts && opts->Expansive();
6931 }
6932
SetDragNodeNeedClean()6933 void OverlayManager::SetDragNodeNeedClean()
6934 {
6935 auto mainPipeline = PipelineContext::GetMainPipelineContext();
6936 CHECK_NULL_VOID(mainPipeline);
6937 auto dragDropManager = mainPipeline->GetDragDropManager();
6938 CHECK_NULL_VOID(dragDropManager);
6939 dragDropManager->SetIsDragNodeNeedClean(true);
6940 }
6941 } // namespace OHOS::Ace::NG
6942