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