diff --git a/frameworks/core/components_ng/pattern/app_bar/atomic_service_pattern.cpp b/frameworks/core/components_ng/pattern/app_bar/atomic_service_pattern.cpp index 9e73b2b5a4593b5bb6815ae28a552b68d4fefd83..e516b9a419771a0ffcda73175091db3a7f33e360 100644 --- a/frameworks/core/components_ng/pattern/app_bar/atomic_service_pattern.cpp +++ b/frameworks/core/components_ng/pattern/app_bar/atomic_service_pattern.cpp @@ -26,30 +26,25 @@ #include "core/pipeline_ng/pipeline_context.h" namespace OHOS::Ace::NG { +constexpr int32_t ATOMIC_SERVICE_MIN_SIZE = 2; +constexpr int32_t FIRST_OVERLAY_INDEX = 1; + void AtomicServicePattern::BeforeCreateLayoutWrapper() { auto pipeline = PipelineContext::GetCurrentContext(); CHECK_NULL_VOID(pipeline); - auto safeArea = pipeline->GetSafeArea(); auto host = GetHost(); CHECK_NULL_VOID(host); auto manager = pipeline->GetSafeAreaManager(); CHECK_NULL_VOID(manager); manager->SetIsAtomicService(true); manager->AddGeoRestoreNode(host); - PaddingProperty padding { - .left = CalcLength(safeArea.left_.Length()), - .right = CalcLength(safeArea.right_.Length()), - .top = CalcLength(safeArea.top_.Length()), - .bottom = CalcLength(safeArea.bottom_.Length()), - }; - host->GetLayoutProperty()->UpdatePadding(padding); - auto systemSafeArea = manager->GetSystemSafeArea(); auto theme = pipeline->GetTheme(); CHECK_NULL_VOID(theme); float topMargin = theme->GetMenuBarTopMargin().ConvertToPx(); - topMargin += (systemSafeArea.top_.Length() - safeArea.top_.Length()); + topMargin += systemSafeArea.top_.Length(); + UpdateOverlayLayout(); auto menuBarRow = GetMenuBarRow(); CHECK_NULL_VOID(menuBarRow); auto renderContext = menuBarRow->GetRenderContext(); @@ -61,11 +56,60 @@ void AtomicServicePattern::BeforeCreateLayoutWrapper() } else { UpdateMenuBarColor(theme, menuBar, SystemProperties::GetColorMode() != ColorMode::DARK); } + UpdateLayoutMargin(); +} +void AtomicServicePattern::UpdateLayoutMargin() +{ + auto pipeline = PipelineContext::GetCurrentContext(); + CHECK_NULL_VOID(pipeline); + auto safeArea = pipeline->GetSafeArea(); + auto atom = GetHost(); + CHECK_NULL_VOID(atom); + MarginProperty margin; + margin.left = CalcLength(safeArea.left_.Length()); + margin.right = CalcLength(safeArea.right_.Length()); + margin.top = CalcLength(safeArea.top_.Length()); + margin.bottom = CalcLength(safeArea.bottom_.Length()); + // update stage margin + auto stage = AceType::DynamicCast(atom->GetChildAtIndex(0)); + CHECK_NULL_VOID(stage); + auto layoutProperty = stage->GetLayoutProperty(); + CHECK_NULL_VOID(layoutProperty); + layoutProperty->UpdateMargin(margin); + stage->MarkModifyDone(); + stage->MarkDirtyNode(); + // update menuBarRow margin + MarginProperty appBarmargin; + appBarmargin.left = CalcLength(safeArea.left_.Length()); + appBarmargin.right = CalcLength(safeArea.right_.Length()); + auto menuBarRow = GetMenuBarRow(); + CHECK_NULL_VOID(menuBarRow); + auto property = menuBarRow->GetLayoutProperty(); + CHECK_NULL_VOID(property); + property->UpdateMargin(appBarmargin); menuBarRow->MarkModifyDone(); menuBarRow->MarkDirtyNode(); } +void AtomicServicePattern::UpdateOverlayLayout() +{ + auto atom = GetHost(); + CHECK_NULL_VOID(atom); + if (atom->GetChildren().size() <= ATOMIC_SERVICE_MIN_SIZE) { + return; + } + for (int index = FIRST_OVERLAY_INDEX; + index <= static_cast(atom->GetChildren().size()) - ATOMIC_SERVICE_MIN_SIZE; index++) { + auto overlay = AceType::DynamicCast(atom->GetChildAtIndex(index)); + CHECK_NULL_VOID(overlay); + auto overlayRender = overlay->GetRenderContext(); + overlayRender->UpdatePosition(OffsetT()); + overlay->MarkModifyDone(); + overlay->MarkDirtyNode(); + } +} + void AtomicServicePattern::OnAttachToFrameNode() { auto host = GetHost(); @@ -99,7 +143,7 @@ RefPtr AtomicServicePattern::GetMenuBarRow() { auto atom = GetHost(); CHECK_NULL_RETURN(atom, nullptr); - auto menuBarRow = AceType::DynamicCast(atom->GetChildAtIndex(1)); + auto menuBarRow = AceType::DynamicCast(atom->GetChildren().back()); return menuBarRow; } diff --git a/frameworks/core/components_ng/pattern/app_bar/atomic_service_pattern.h b/frameworks/core/components_ng/pattern/app_bar/atomic_service_pattern.h index 8495a125accd455fe27fa147ef5a085779d5b547..8ffaadf975a4c5972cc44328f54ce9a9bfb48167 100644 --- a/frameworks/core/components_ng/pattern/app_bar/atomic_service_pattern.h +++ b/frameworks/core/components_ng/pattern/app_bar/atomic_service_pattern.h @@ -56,6 +56,10 @@ public: void UpdateIconLayout(RefPtr& theme, RefPtr& icon, bool isLeft); std::optional settedColorMode = std::nullopt; + +private: + void UpdateLayoutMargin(); + void UpdateOverlayLayout(); }; } // namespace OHOS::Ace::NG #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_ATOMIC_SERVICE_PATTERN_H diff --git a/frameworks/core/components_ng/pattern/overlay/overlay_manager.cpp b/frameworks/core/components_ng/pattern/overlay/overlay_manager.cpp index d3612c07856b5a813951af08d9e1e61e93ce7de9..15dfc232c41b2cf25e88314cbbb92dd53637b4ba 100644 --- a/frameworks/core/components_ng/pattern/overlay/overlay_manager.cpp +++ b/frameworks/core/components_ng/pattern/overlay/overlay_manager.cpp @@ -111,6 +111,7 @@ const RefPtr SHOW_SCALE_ANIMATION_CURVE = AceType::MakeRefPtr constexpr int32_t ROOT_MIN_NODE = 1; constexpr int32_t TOAST_MIN_NODE = 2; +constexpr int32_t ATOMIC_SERVICE_MIN_SIZE = 2; // OVERLAY_EXISTS: overlay was removed // OVERLAY_REMOVE:: overlay exists @@ -596,7 +597,7 @@ void OverlayManager::OpenDialogAnimation(const RefPtr& node) root = dialogPattern->GetDialogProperties().windowScene.Upgrade(); } CHECK_NULL_VOID(root); - node->MountToParent(root); + MountToParentWithService(root, node); root->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); BlurLowerNode(node); @@ -720,7 +721,7 @@ void OverlayManager::SetDialogTransitionEffect(const RefPtr& node) } CHECK_NULL_VOID(root); - node->MountToParent(root); + MountToParentWithService(root, node); root->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); BlurLowerNode(node); node->OnAccessibilityEvent(AccessibilityEventType::CHANGE, WindowsContentChangeTypes::CONTENT_CHANGE_TYPE_SUBTREE); @@ -1248,7 +1249,7 @@ void OverlayManager::HidePopupAnimation(const RefPtr& popupNode, cons if (!popupNode->GetRenderContext()->HasDisappearTransition()) { popupPattern->SetTransitionStatus(TransitionStatus::INVISIABLE); popupNode->GetEventHub()->FireChangeEvent(false); - rootNode->RemoveChild(popupNode); + RemoveChildWithService(rootNode, popupNode); rootNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); auto layoutProp = popupNode->GetLayoutProperty(); CHECK_NULL_VOID(layoutProp); @@ -1332,7 +1333,7 @@ void OverlayManager::MountPopup(int32_t targetId, const PopupInfo& popupInfo, const auto& rootChildren = rootNode->GetChildren(); auto iter = std::find(rootChildren.rbegin(), rootChildren.rend(), popupNode); if (iter == rootChildren.rend()) { - popupNode->MountToParent(rootNode); + MountToParentWithService(rootNode, popupNode); } // attach popupNode before entering animation @@ -1408,9 +1409,12 @@ void OverlayManager::HidePopup(int32_t targetId, const PopupInfo& popupInfo) } CHECK_NULL_VOID(rootNode); + auto pipeline = rootNode->GetContextRefPtr(); + CHECK_NULL_VOID(pipeline); const auto& rootChildren = rootNode->GetChildren(); auto iter = std::find(rootChildren.rbegin(), rootChildren.rend(), popupNode); - if (iter == rootChildren.rend()) { + // There is no overlay under the root node or it is not in atomicservice + if (iter == rootChildren.rend() && !pipeline->GetInstallationFree()) { return; } @@ -1442,7 +1446,7 @@ void OverlayManager::HidePopup(int32_t targetId, const PopupInfo& popupInfo) popupPattern->SetTransitionStatus(TransitionStatus::INVISIABLE); popupNode->GetEventHub()->FireChangeEvent(false); popupNode->GetRenderContext()->UpdateChainedTransition(nullptr); - rootNode->RemoveChild(popupNode); + overlayManager->RemoveChildWithService(rootNode, popupNode); rootNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); overlayManager->ErasePopupInfo(targetId); if ((isTypeWithOption && !isShowInSubWindow) || @@ -1520,7 +1524,7 @@ void OverlayManager::RemoveIndexerPopupById(int32_t targetId) CHECK_NULL_VOID(rootNode); auto iter = customPopupMap_.find(targetId); if (iter != customPopupMap_.end()) { - rootNode->RemoveChild(iter->second); + RemoveChildWithService(rootNode, iter->second); customPopupMap_.erase(iter); rootNode->MarkDirtyNode(PROPERTY_UPDATE_BY_CHILD_REQUEST); } @@ -1536,7 +1540,7 @@ void OverlayManager::RemoveIndexerPopup() CHECK_NULL_VOID(rootNode); for (const auto& popup : customPopupMap_) { auto popupNode = popup.second; - rootNode->RemoveChild(popupNode); + RemoveChildWithService(rootNode, popupNode); } customPopupMap_.clear(); rootNode->MarkDirtyNode(PROPERTY_UPDATE_BY_CHILD_REQUEST); @@ -1616,7 +1620,7 @@ void OverlayManager::ErasePopup(int32_t targetId) auto subwindowMgr = SubwindowManager::GetInstance(); subwindowMgr->DeleteHotAreas(Container::CurrentId(), popupNode->GetId()); } - rootNode->RemoveChild(popupNode); + RemoveChildWithService(rootNode, popupNode); rootNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); popupMap_.erase(targetId); } @@ -2593,9 +2597,12 @@ bool OverlayManager::RemoveOverlay(bool isBackPressed, bool isPageRouter) auto rootNode = rootNodeWeak_.Upgrade(); CHECK_NULL_RETURN(rootNode, true); RemoveIndexerPopup(); - if (rootNode->GetChildren().size() > ROOT_MIN_NODE) { + auto pipeline = rootNode->GetContextRefPtr(); + CHECK_NULL_RETURN(pipeline, false); + // There is overlay under the root node or it is in atomicservice + if (rootNode->GetChildren().size() > ROOT_MIN_NODE || pipeline->GetInstallationFree()) { // stage node is at index 0, remove overlay at last - auto overlay = DynamicCast(rootNode->GetLastChild()); + auto overlay = GetOverlayFrameNode(); CHECK_NULL_RETURN(overlay, false); auto ret = ExceptComponent(rootNode, overlay, isBackPressed, isPageRouter); if (ret == OVERLAY_REMOVE) { @@ -2609,8 +2616,6 @@ bool OverlayManager::RemoveOverlay(bool isBackPressed, bool isPageRouter) // remove navDestination in navigation first do { CHECK_NULL_BREAK(rootNode->GetTag() != V2::NAVDESTINATION_VIEW_ETS_TAG); - auto pipeline = PipelineContext::GetCurrentContext(); - CHECK_NULL_BREAK(pipeline); auto navigationGroupNode = AceType::DynamicCast(pipeline->FindNavigationNodeToHandleBack(overlay)); CHECK_NULL_BREAK(navigationGroupNode); @@ -2635,6 +2640,32 @@ bool OverlayManager::RemoveOverlay(bool isBackPressed, bool isPageRouter) return false; } +RefPtr OverlayManager::GetOverlayFrameNode() +{ + auto rootNode = rootNodeWeak_.Upgrade(); + CHECK_NULL_RETURN(rootNode, nullptr); + auto pipeline = rootNode->GetContextRefPtr(); + CHECK_NULL_RETURN(pipeline, nullptr); + auto overlay = DynamicCast(rootNode->GetLastChild()); + // There is no overlay under the root node or it is not in atomicservice + if (!pipeline->GetInstallationFree() || rootNode->GetChildren().size() > ROOT_MIN_NODE) { + return overlay; + } + for (auto child : rootNode->GetChildren()) { + if (child->GetTag() == V2::ATOMIC_SERVICE_ETS_TAG) { + auto atomicNode = child; + CHECK_NULL_RETURN(atomicNode, nullptr); + if (atomicNode->GetChildren().size() <= ATOMIC_SERVICE_MIN_SIZE) { + return nullptr; + } + overlay = DynamicCast( + atomicNode->GetChildAtIndex(atomicNode->GetChildren().size() - ATOMIC_SERVICE_MIN_SIZE)); + break; + } + } + return overlay; +} + int32_t OverlayManager::ExceptComponent(const RefPtr& rootNode, RefPtr& overlay, bool isBackPressed, bool isPageRouter) { @@ -5674,4 +5705,54 @@ void OverlayManager::OnUIExtensionWindowSizeChange() dialogNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE); } } + +void OverlayManager::MountToParentWithService(const RefPtr& rootNode, const RefPtr& node) +{ + CHECK_NULL_VOID(node); + CHECK_NULL_VOID(rootNode); + auto pipeline = rootNode->GetContextRefPtr(); + CHECK_NULL_VOID(pipeline); + if (pipeline->GetInstallationFree()) { + // it is in atomicservice + SetNodeBeforeAppbar(rootNode, node); + } else { + node->MountToParent(rootNode); + } +} + +void OverlayManager::RemoveChildWithService(const RefPtr& rootNode, const RefPtr& node) +{ + CHECK_NULL_VOID(rootNode); + CHECK_NULL_VOID(node); + auto pipeline = rootNode->GetContextRefPtr(); + CHECK_NULL_VOID(pipeline); + if (pipeline->GetInstallationFree()) { + // it is in atomicservice + auto parent = node->GetParent(); + CHECK_NULL_VOID(parent); + parent->RemoveChild(node); + } else { + rootNode->RemoveChild(node); + } +} + +void OverlayManager::SetNodeBeforeAppbar(const RefPtr& rootNode, const RefPtr& node) +{ + CHECK_NULL_VOID(rootNode); + CHECK_NULL_VOID(node); + for (auto child : rootNode->GetChildren()) { + CHECK_NULL_VOID(child); + if (child->GetTag() != V2::ATOMIC_SERVICE_ETS_TAG) { + continue; + } + for (auto childNode : child->GetChildren()) { + CHECK_NULL_VOID(childNode); + if (childNode->GetTag() == V2::APP_BAR_ETS_TAG) { + TAG_LOGD(AceLogTag::ACE_OVERLAY, "setNodeBeforeAppbar AddChildBefore"); + child->AddChildBefore(node, childNode); + return; + } + } + } +} } // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/pattern/overlay/overlay_manager.h b/frameworks/core/components_ng/pattern/overlay/overlay_manager.h index d318f1a1ceb7d1672e0b0a4e1619c6dbcd975ece..43b6613d154d843003f1d158ff5aea0d1d680301 100644 --- a/frameworks/core/components_ng/pattern/overlay/overlay_manager.h +++ b/frameworks/core/components_ng/pattern/overlay/overlay_manager.h @@ -660,6 +660,10 @@ private: void DumpModalListInfo() const; void DumpEntry(const RefPtr& targetNode, int32_t targetId, const RefPtr& node) const; std::string GetMapNodeLog(const RefPtr& node, bool hasTarget = true) const; + void SetNodeBeforeAppbar(const RefPtr& rootNode, const RefPtr& node); + RefPtr GetOverlayFrameNode(); + void MountToParentWithService(const RefPtr& rootNode, const RefPtr& node); + void RemoveChildWithService(const RefPtr& rootNode, const RefPtr& node); RefPtr overlayNode_; // Key: frameNode Id, Value: index