From 497e8728dd303f3254d38b6b60b9f5b70e3c099c Mon Sep 17 00:00:00 2001 From: huzhanjiang Date: Wed, 25 Jun 2025 21:32:55 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=90dialog=E3=80=91dialog=20=E9=81=BF?= =?UTF-8?q?=E8=AE=A9=E4=B8=89=E9=94=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: huzhanjiang Change-Id: I480062e13388c5a0908299f7aa6a9c213a53f4e9 --- .../dialog/dialog_layout_algorithm.cpp | 5 +- .../pattern/dialog/dialog_layout_algorithm.h | 1 + .../pattern/dialog/dialog_pattern.cpp | 48 +++++++++++++++++++ .../pattern/dialog/dialog_pattern.h | 14 +++++- .../pattern/dialog/dialog_pattern_test_ng.cpp | 33 +++++++++++++ 5 files changed, 98 insertions(+), 3 deletions(-) diff --git a/frameworks/core/components_ng/pattern/dialog/dialog_layout_algorithm.cpp b/frameworks/core/components_ng/pattern/dialog/dialog_layout_algorithm.cpp index 82a7a9bc2c3..177d661fad5 100644 --- a/frameworks/core/components_ng/pattern/dialog/dialog_layout_algorithm.cpp +++ b/frameworks/core/components_ng/pattern/dialog/dialog_layout_algorithm.cpp @@ -58,6 +58,9 @@ void DialogLayoutAlgorithm::Measure(LayoutWrapper* layoutWrapper) CHECK_NULL_VOID(dialogProp); auto dialogPattern = hostNode->GetPattern(); CHECK_NULL_VOID(dialogPattern); + NG::RectF floatButtons; + dialogPattern->GetWindowButtonRect(floatButtons); + floatButtonsHeight_ = floatButtons.Height(); auto parent = hostNode->GetParent(); expandDisplay_ = dialogTheme->GetExpandDisplay() || dialogPattern->IsShowInFreeMultiWindow(); keyboardAvoidMode_ = dialogPattern->GetDialogProperties().keyboardAvoidMode; @@ -696,7 +699,7 @@ void DialogLayoutAlgorithm::AvoidScreen( static_cast(availableRect.Bottom() - childSize.Height())); left = std::clamp(static_cast(left - wrapperOffset_.GetX()), 0.0f, static_cast(wrapperSize_.Width() - childSize.Width())); - top = std::clamp(static_cast(top - wrapperOffset_.GetY()), 0.0f, + top = std::clamp(static_cast(top - wrapperOffset_.GetY()), floatButtonsHeight_, static_cast(wrapperSize_.Height() - childSize.Height())); topLeftPoint.SetX(left); topLeftPoint.SetY(top); diff --git a/frameworks/core/components_ng/pattern/dialog/dialog_layout_algorithm.h b/frameworks/core/components_ng/pattern/dialog/dialog_layout_algorithm.h index 56af044025e..15f87268318 100644 --- a/frameworks/core/components_ng/pattern/dialog/dialog_layout_algorithm.h +++ b/frameworks/core/components_ng/pattern/dialog/dialog_layout_algorithm.h @@ -148,6 +148,7 @@ private: float embeddedDialogOffsetY_ = 0.0f; float stackRootDialogOffsetY_ = 0.0f; float safeAreaBottomLength_ = 0.0f; + float floatButtonsHeight_ = 0.0f; WeakPtr context_ = nullptr; diff --git a/frameworks/core/components_ng/pattern/dialog/dialog_pattern.cpp b/frameworks/core/components_ng/pattern/dialog/dialog_pattern.cpp index 132c807d201..92078263bd0 100644 --- a/frameworks/core/components_ng/pattern/dialog/dialog_pattern.cpp +++ b/frameworks/core/components_ng/pattern/dialog/dialog_pattern.cpp @@ -133,6 +133,7 @@ void DialogPattern::OnAttachToFrameNode() auto callbackId = pipelineContext->RegisterFoldDisplayModeChangedCallback(std::move(foldModeChangeCallback)); UpdateFoldDisplayModeChangedCallbackId(callbackId); RegisterHoverModeChangeCallback(); + RegisterAvoidInfoChangeListener(host); } void DialogPattern::RegisterHoverModeChangeCallback() @@ -173,6 +174,7 @@ void DialogPattern::OnDetachFromFrameNode(FrameNode* frameNode) if (HasHoverModeChangedCallbackId()) { pipeline->UnRegisterHalfFoldHoverChangedCallback(hoverModeChangedCallbackId_.value_or(-1)); } + UnRegisterAvoidInfoChangeListener(frameNode); } void DialogPattern::OnFontConfigurationUpdate() @@ -2717,6 +2719,52 @@ void DialogPattern::UpdateButtonBackgroundColor(const Color& color, int32_t butt } } +bool DialogPattern::GetWindowButtonRect(NG::RectF& floatButtons) +{ + auto host = GetHost(); + CHECK_NULL_RETURN(host, false); + auto pipelineContext = host->GetContext(); + CHECK_NULL_RETURN(pipelineContext, false); + auto avoidInfoMgr = pipelineContext->GetAvoidInfoManager(); + CHECK_NULL_RETURN(avoidInfoMgr, false); + NG::RectF floatContainerModal; + if (avoidInfoMgr->NeedAvoidContainerModal() && + avoidInfoMgr->GetContainerModalButtonsRect(floatContainerModal, floatButtons)) { + TAG_LOGD(AceLogTag::ACE_DIALOG, "When hidden, floatButtons rect is %{public}s", + floatButtons.ToString().c_str()); + return true; + }; + TAG_LOGD(AceLogTag::ACE_DIALOG, "Window title builder shown"); + return false; +} + +void DialogPattern::OnAvoidInfoChange(const ContainerModalAvoidInfo& info) +{ + auto host = GetHost(); + CHECK_NULL_VOID(host); + host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE); +} + +void DialogPattern::RegisterAvoidInfoChangeListener(const RefPtr& hostNode) +{ + CHECK_NULL_VOID(hostNode); + auto pipeline = hostNode->GetContext(); + CHECK_NULL_VOID(pipeline); + auto mgr = pipeline->GetAvoidInfoManager(); + CHECK_NULL_VOID(mgr); + mgr->AddAvoidInfoListener(WeakClaim(this)); +} + +void DialogPattern::UnRegisterAvoidInfoChangeListener(FrameNode* hostNode) +{ + CHECK_NULL_VOID(hostNode); + auto pipeline = hostNode->GetContext(); + CHECK_NULL_VOID(pipeline); + auto mgr = pipeline->GetAvoidInfoManager(); + CHECK_NULL_VOID(mgr); + mgr->RemoveAvoidInfoListener(WeakClaim(this)); +} + void DialogPattern::UpdateButtonText(const std::string text, int32_t buttonIndex) { int32_t btnIndex = 0; diff --git a/frameworks/core/components_ng/pattern/dialog/dialog_pattern.h b/frameworks/core/components_ng/pattern/dialog/dialog_pattern.h index b41a5365784..5c354b8e199 100644 --- a/frameworks/core/components_ng/pattern/dialog/dialog_pattern.h +++ b/frameworks/core/components_ng/pattern/dialog/dialog_pattern.h @@ -34,6 +34,7 @@ #include "core/components_ng/pattern/overlay/popup_base_pattern.h" #include "core/components_ng/pattern/dialog/alert_dialog_model.h" #include "core/components_ng/pattern/action_sheet/action_sheet_model.h" +#include "core/components_ng/manager/avoid_info/avoid_info_manager.h" namespace OHOS::Ace::NG { class InspectorFilter; @@ -50,8 +51,12 @@ enum class DialogDismissReason { DIALOG_TOUCH_OUTSIDE, DIALOG_CLOSE_BUTTON, }; -class DialogPattern : public PopupBasePattern, public FocusView, public AutoFillTriggerStateHolder { - DECLARE_ACE_TYPE(DialogPattern, PopupBasePattern, FocusView, AutoFillTriggerStateHolder); +class DialogPattern : public PopupBasePattern, + public FocusView, + public AutoFillTriggerStateHolder, + public IAvoidInfoListener { + DECLARE_ACE_TYPE(DialogPattern, PopupBasePattern, FocusView, + AutoFillTriggerStateHolder, IAvoidInfoListener); public: DialogPattern(const RefPtr& dialogTheme, const RefPtr& customNode) @@ -175,6 +180,8 @@ public: InitHostWindowRect(); } + bool GetWindowButtonRect(NG::RectF& floatButtons); + const DialogProperties& GetDialogProperties() const { return dialogProperties_; @@ -386,6 +393,9 @@ private: void InitFocusEvent(const RefPtr& focusHub); void HandleBlurEvent(); void HandleFocusEvent(); + void OnAvoidInfoChange(const ContainerModalAvoidInfo& info) override; + void RegisterAvoidInfoChangeListener(const RefPtr& hostNode); + void UnRegisterAvoidInfoChangeListener(FrameNode* hostNode); void PopDialog(int32_t buttonIdx); bool NeedUpdateHostWindowRect(); diff --git a/test/unittest/core/pattern/dialog/dialog_pattern_test_ng.cpp b/test/unittest/core/pattern/dialog/dialog_pattern_test_ng.cpp index aab4288f962..0a7dac26ef3 100644 --- a/test/unittest/core/pattern/dialog/dialog_pattern_test_ng.cpp +++ b/test/unittest/core/pattern/dialog/dialog_pattern_test_ng.cpp @@ -76,6 +76,7 @@ const NG::BorderWidthProperty BORDERWIDTH = { .leftDimen = Dimension(DIMENSIONVA const BorderColorProperty BORDERCOLOR = { .bottomColor = Color::WHITE }; const Color COLOR = Color::WHITE; const NG::BorderRadiusProperty BORDERRADIUS = BorderRadiusProperty(Dimension(DIMENSIONVALUE)); +const RectF CONTROL_RECT = RectF(0.0f, 0.0f, 100.0f, 100.0f); } // namespace class DialogPatternAdditionalTestNg : public testing::Test { @@ -1838,4 +1839,36 @@ HWTEST_F(DialogPatternAdditionalTestNg, DialogPatternTestRegisterButtonOnKeyEven auto focusHub = button->GetFocusHub(); ASSERT_NE(focusHub, nullptr); } + +/** + * @tc.name: GetWindowButtonRect + * @tc.desc: Test GetWindowButtonRect + * @tc.type: FUNC + */ +HWTEST_F(DialogPatternAdditionalTestNg, GetWindowButtonRect, TestSize.Level1) +{ + /** + * @tc.steps: step0. create dialog node. + * @tc.expected: the dialog node created successfully. + */ + auto dialogTheme = AceType::MakeRefPtr(); + ASSERT_NE(dialogTheme, nullptr); + RefPtr dialog = FrameNode::CreateFrameNode( + V2::ALERT_DIALOG_ETS_TAG, 1, AceType::MakeRefPtr(dialogTheme, nullptr)); + ASSERT_NE(dialog, nullptr); + auto pattern = dialog->GetPattern(); + ASSERT_NE(pattern, nullptr); + auto pipelineContext = dialog->GetContext(); + ASSERT_NE(pipelineContext, nullptr); + auto avoidInfoMgr = pipelineContext->GetAvoidInfoManager(); + ASSERT_NE(avoidInfoMgr, nullptr); + avoidInfoMgr->avoidInfo_.needAvoid = false; + avoidInfoMgr->avoidInfo_.controlBottonsRect = CONTROL_RECT; + RectF floatButtons; + pattern->GetWindowButtonRect(floatButtons); + EXPECT_EQ(floatButtons, RectF()); + avoidInfoMgr->avoidInfo_.needAvoid = true; + pattern->GetWindowButtonRect(floatButtons); + EXPECT_EQ(floatButtons, CONTROL_RECT); +} } // namespace OHOS::Ace::NG -- Gitee