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