From 974ae3e3a42d591ddd0275699e1782643e70bb86 Mon Sep 17 00:00:00 2001 From: yangbiao199318 Date: Mon, 3 Mar 2025 23:06:18 +0800 Subject: [PATCH] [feate]Add toolBar Item to Title Signed-off-by: yangbiao199318 Change-Id: Id0d108546a1941843b1f988caecf60edc7e32aee Signed-off-by: yangbiao199318 --- .gitee/CODEOWNERS | 4 + .../bridge/declarative_frontend/BUILD.gn | 2 + .../engine/jsi/jsi_view_register.cpp | 10 + .../engine/jsi/jsi_view_register_impl.cpp | 2 + .../jsview/js_toolbaritem.cpp | 72 +++ .../jsview/js_toolbaritem.h | 31 + .../jsview/js_view_abstract.cpp | 25 + .../jsview/js_view_abstract.h | 1 + .../models/view_abstract_model_impl.cpp | 2 + .../jsview/models/view_abstract_model_impl.h | 1 + .../core/components/common/layout/constants.h | 5 + .../core/components_ng/base/frame_node.cpp | 3 + .../core/components_ng/base/frame_node.h | 6 + .../components_ng/base/view_abstract_model.h | 3 + .../base/view_abstract_model_ng.cpp | 24 + .../base/view_abstract_model_ng.h | 2 + .../core/components_ng/manager/BUILD.gn | 1 + .../manager/toolbar/toolbar_manager.cpp | 90 +++ .../manager/toolbar/toolbar_manager.h | 134 +++++ .../core/components_ng/pattern/BUILD.gn | 1 + .../container_modal_pattern.cpp | 533 ++++++++++++++++++ .../container_modal/container_modal_pattern.h | 59 +- .../container_modal/container_modal_view.cpp | 5 +- .../pattern/navigation/navigation_pattern.cpp | 54 +- .../pattern/navigation/navigation_pattern.h | 13 + .../side_bar/side_bar_container_pattern.cpp | 78 +++ .../side_bar/side_bar_container_pattern.h | 14 + .../pattern/toolbaritem/toolbaritem_model.h | 40 ++ .../toolbaritem/toolbaritem_model_ng.cpp | 52 ++ .../toolbaritem/toolbaritem_model_ng.h | 36 ++ .../pattern/toolbaritem/toolbaritem_pattern.h | 52 ++ .../inspector/inspector_constants.cpp | 6 + .../inspector/inspector_constants.h | 6 + .../core/pipeline_ng/pipeline_context.h | 7 + test/unittest/BUILD.gn | 1 + 35 files changed, 1366 insertions(+), 9 deletions(-) create mode 100644 frameworks/bridge/declarative_frontend/jsview/js_toolbaritem.cpp create mode 100644 frameworks/bridge/declarative_frontend/jsview/js_toolbaritem.h create mode 100644 frameworks/core/components_ng/manager/toolbar/toolbar_manager.cpp create mode 100644 frameworks/core/components_ng/manager/toolbar/toolbar_manager.h create mode 100644 frameworks/core/components_ng/pattern/toolbaritem/toolbaritem_model.h create mode 100644 frameworks/core/components_ng/pattern/toolbaritem/toolbaritem_model_ng.cpp create mode 100644 frameworks/core/components_ng/pattern/toolbaritem/toolbaritem_model_ng.h create mode 100644 frameworks/core/components_ng/pattern/toolbaritem/toolbaritem_pattern.h diff --git a/.gitee/CODEOWNERS b/.gitee/CODEOWNERS index 8a5b4494b0d..16db63c5412 100644 --- a/.gitee/CODEOWNERS +++ b/.gitee/CODEOWNERS @@ -1322,6 +1322,8 @@ frameworks/bridge/declarative_frontend/jsview/js_texttimer.cpp @arkui_image frameworks/bridge/declarative_frontend/jsview/js_texttimer.h @arkui_image frameworks/bridge/declarative_frontend/jsview/js_toggle.cpp @arkuipopupwindow frameworks/bridge/declarative_frontend/jsview/js_toggle.h @arkuipopupwindow +frameworks/bridge/declarative_frontend/jsview/js_toolbaritem.cpp @arkuievent +frameworks/bridge/declarative_frontend/jsview/js_toolbaritem.h @arkuievent frameworks/bridge/declarative_frontend/jsview/js_touch_handler.cpp @arkuievent frameworks/bridge/declarative_frontend/jsview/js_touch_handler.h @arkuievent frameworks/bridge/declarative_frontend/jsview/js_ui_extension.cpp @arkuiabilitygroup @@ -2374,6 +2376,7 @@ frameworks/core/components_ng/manager/safe_area/ @arkuilayout frameworks/core/components_ng/manager/select_content_overlay/ @huawei_g_five frameworks/core/components_ng/manager/select_overlay/ @huawei_g_five frameworks/core/components_ng/manager/shared_overlay/ @arkuiframework +frameworks/core/components_ng/manager/toolbar/ @arkuievent frameworks/core/components_ng/pattern/ability_component/ @arkuilayout frameworks/core/components_ng/pattern/action_sheet/ @arkuipopupwindow frameworks/core/components_ng/pattern/animator/ @arkui_superman @@ -2528,6 +2531,7 @@ frameworks/core/components_ng/pattern/texttimer/ @arkui_image frameworks/core/components_ng/pattern/time_picker/ @arkui_image frameworks/core/components_ng/pattern/toast/ @arkuipopupwindow frameworks/core/components_ng/pattern/toggle/ @arkuipopupwindow +frameworks/core/components_ng/pattern/toolbaritem/ @arkuievent frameworks/core/components_ng/pattern/ui_extension/ @arkuiabilitygroup frameworks/core/components_ng/pattern/video/ @arkuilayout frameworks/core/components_ng/pattern/view_context/ @arkuiframework diff --git a/frameworks/bridge/declarative_frontend/BUILD.gn b/frameworks/bridge/declarative_frontend/BUILD.gn index 4f6c8e36694..0aa92b23e0e 100644 --- a/frameworks/bridge/declarative_frontend/BUILD.gn +++ b/frameworks/bridge/declarative_frontend/BUILD.gn @@ -399,6 +399,7 @@ template("declarative_js_engine") { "jsview/js_textpicker.cpp", "jsview/js_texttimer.cpp", "jsview/js_toggle.cpp", + "jsview/js_toolbaritem.cpp", "jsview/js_touch_handler.cpp", "jsview/js_utils.cpp", "jsview/js_view.cpp", @@ -965,6 +966,7 @@ template("declarative_js_engine_ng") { "jsview/js_textpicker.cpp", "jsview/js_texttimer.cpp", "jsview/js_toggle.cpp", + "jsview/js_toolbaritem.cpp", "jsview/js_utils.cpp", "jsview/js_view.cpp", "jsview/js_view_abstract.cpp", diff --git a/frameworks/bridge/declarative_frontend/engine/jsi/jsi_view_register.cpp b/frameworks/bridge/declarative_frontend/engine/jsi/jsi_view_register.cpp index 67db7597d77..e6698df3589 100644 --- a/frameworks/bridge/declarative_frontend/engine/jsi/jsi_view_register.cpp +++ b/frameworks/bridge/declarative_frontend/engine/jsi/jsi_view_register.cpp @@ -1435,6 +1435,10 @@ void JsRegisterFormViews( buttonType.Constant("Arc", (int)ButtonType::ARC); buttonType.Constant("ROUNDED_RECTANGLE", (int)ButtonType::ROUNDED_RECTANGLE); + JSObjectTemplate toolbaritemPlacement; + toolbaritemPlacement.Constant("TOP_BAR_LEADING", (int)ToolBarItemPlacement::TOP_BAR_LEADING); + toolbaritemPlacement.Constant("TOP_BAR_TRAILING", (int)ToolBarItemPlacement::TOP_BAR_TRAILING); + JSObjectTemplate iconPosition; iconPosition.Constant("Start", 0); iconPosition.Constant("End", 1); @@ -1451,6 +1455,7 @@ void JsRegisterFormViews( globalObj->Set(vm, panda::StringRef::NewFromUtf8(vm, "Align"), *alignment); globalObj->Set(vm, panda::StringRef::NewFromUtf8(vm, "Overflow"), *overflow); globalObj->Set(vm, panda::StringRef::NewFromUtf8(vm, "ButtonType"), *buttonType); + globalObj->Set(vm, panda::StringRef::NewFromUtf8(vm, "ToolBarItemPlacement"), *toolbaritemPlacement); globalObj->Set(vm, panda::StringRef::NewFromUtf8(vm, "LoadingProgressStyle"), *loadingProgressStyle); globalObj->Set(vm, panda::StringRef::NewFromUtf8(vm, "ProgressStyle"), *progressStyle); globalObj->Set(vm, panda::StringRef::NewFromUtf8(vm, "ToggleType"), *toggleType); @@ -1649,6 +1654,10 @@ void JsRegisterViews(BindingTarget globalObj, void* nativeEngine) buttonType.Constant("Arc", (int)ButtonType::ARC); buttonType.Constant("ROUNDED_RECTANGLE", (int)ButtonType::ROUNDED_RECTANGLE); + JSObjectTemplate toolbaritemPlacement; + toolbaritemPlacement.Constant("TOP_BAR_LEADING", (int)ToolBarItemPlacement::TOP_BAR_LEADING); + toolbaritemPlacement.Constant("TOP_BAR_TRAILING", (int)ToolBarItemPlacement::TOP_BAR_TRAILING); + JSObjectTemplate iconPosition; iconPosition.Constant("Start", 0); iconPosition.Constant("End", 1); @@ -1670,6 +1679,7 @@ void JsRegisterViews(BindingTarget globalObj, void* nativeEngine) globalObj->Set(vm, panda::StringRef::NewFromUtf8(vm, "Align"), *alignment); globalObj->Set(vm, panda::StringRef::NewFromUtf8(vm, "Overflow"), *overflow); globalObj->Set(vm, panda::StringRef::NewFromUtf8(vm, "ButtonType"), *buttonType); + globalObj->Set(vm, panda::StringRef::NewFromUtf8(vm, "ToolBarItemPlacement"), *toolbaritemPlacement); globalObj->Set(vm, panda::StringRef::NewFromUtf8(vm, "LoadingProgressStyle"), *loadingProgressStyle); globalObj->Set(vm, panda::StringRef::NewFromUtf8(vm, "ProgressStyle"), *progressStyle); globalObj->Set(vm, panda::StringRef::NewFromUtf8(vm, "ToggleType"), *toggleType); diff --git a/frameworks/bridge/declarative_frontend/engine/jsi/jsi_view_register_impl.cpp b/frameworks/bridge/declarative_frontend/engine/jsi/jsi_view_register_impl.cpp index 8976ad748ee..e611b8d795f 100644 --- a/frameworks/bridge/declarative_frontend/engine/jsi/jsi_view_register_impl.cpp +++ b/frameworks/bridge/declarative_frontend/engine/jsi/jsi_view_register_impl.cpp @@ -154,6 +154,7 @@ #include "bridge/declarative_frontend/jsview/js_textpicker.h" #include "bridge/declarative_frontend/jsview/js_texttimer.h" #include "bridge/declarative_frontend/jsview/js_toggle.h" +#include "bridge/declarative_frontend/jsview/js_toolbaritem.h" #include "bridge/declarative_frontend/jsview/js_view_context.h" #include "bridge/declarative_frontend/jsview/js_view_stack_processor.h" #include "bridge/declarative_frontend/jsview/js_water_flow.h" @@ -598,6 +599,7 @@ static const std::unordered_map> { "StepperItem", JSStepperItem::JSBind }, #endif { "Toggle", JSToggle::JSBind }, + { "ToolBarItem", JSToolBarItem::JSBind }, { "Blank", JSBlank::JSBind }, { "Calendar", JSCalendar::JSBind }, #ifndef ARKUI_WEARABLE diff --git a/frameworks/bridge/declarative_frontend/jsview/js_toolbaritem.cpp b/frameworks/bridge/declarative_frontend/jsview/js_toolbaritem.cpp new file mode 100644 index 00000000000..2bb8d086085 --- /dev/null +++ b/frameworks/bridge/declarative_frontend/jsview/js_toolbaritem.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "frameworks/bridge/declarative_frontend/jsview/js_toolbaritem.h" + +#include "core/components_ng/pattern/toolbaritem/toolbaritem_model.h" +#include "core/components_ng/pattern/toolbaritem/toolbaritem_model_ng.h" + +namespace OHOS::Ace { + +std::unique_ptr ToolBarItemModel::instance_ = nullptr; +std::mutex ToolBarItemModel::mutex_; + +ToolBarItemModel* ToolBarItemModel::GetInstance() +{ + if (!instance_) { + std::lock_guard lock(mutex_); + if (!instance_) { +#ifdef NG_BUILD + instance_.reset(new NG::ToolBarItemModelNG()); +#else + if (Container::IsCurrentUseNewPipeline()) { + instance_.reset(new NG::ToolBarItemModelNG()); + } else { + instance_.reset(new NG::ToolBarItemModelNG()); + } + +#endif + } + } + return instance_.get(); +} + +} // namespace OHOS::Ace + +namespace OHOS::Ace::Framework { + +namespace {} // namespace + +void JSToolBarItem::Create(const JSCallbackInfo& info) +{ + JSRef toolbaritemObj = JSRef::Cast(info[0]); + int32_t value = static_cast(ToolBarItemPlacement::TOP_BAR_LEADING); + if (toolbaritemObj->GetProperty(JSToolBarItem::PLACEMENT)->IsNumber()) { + value = static_cast(toolbaritemObj->GetProperty(JSToolBarItem::PLACEMENT)->ToNumber()); + } + if ((ToolBarItemPlacement)value == ToolBarItemPlacement::TOP_BAR_LEADING || + (ToolBarItemPlacement)value == ToolBarItemPlacement::TOP_BAR_TRAILING) { + ToolBarItemModel::GetInstance()->Create(value); + } +} + +void JSToolBarItem::JSBind(BindingTarget globalObj) +{ + JSClass::Declare("ToolBarItem"); + JSClass::StaticMethod("create", &JSToolBarItem::Create); + JSClass::InheritAndBind(globalObj); +} + +} // namespace OHOS::Ace::Framework \ No newline at end of file diff --git a/frameworks/bridge/declarative_frontend/jsview/js_toolbaritem.h b/frameworks/bridge/declarative_frontend/jsview/js_toolbaritem.h new file mode 100644 index 00000000000..7c5368ed324 --- /dev/null +++ b/frameworks/bridge/declarative_frontend/jsview/js_toolbaritem.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FRAMEWORKS_BRIDGE_DECLARATIVE_FRONTEND_JS_VIEW_JS_TOOLBARITEM_H +#define FRAMEWORKS_BRIDGE_DECLARATIVE_FRONTEND_JS_VIEW_JS_TOOLBARITEM_H + +#include "frameworks/bridge/declarative_frontend/jsview/js_container_base.h" + +namespace OHOS::Ace::Framework { + +class JSToolBarItem : public JSContainerBase { +public: + static void JSBind(BindingTarget globalObj); + static void Create(const JSCallbackInfo& info); + static constexpr char PLACEMENT[] = "placement"; +}; + +} // namespace OHOS::Ace::Framework +#endif // FRAMEWORKS_BRIDGE_DECLARATIVE_FRONTEND_JS_VIEW_JS_TOOLBARITEM_H \ No newline at end of file diff --git a/frameworks/bridge/declarative_frontend/jsview/js_view_abstract.cpp b/frameworks/bridge/declarative_frontend/jsview/js_view_abstract.cpp index d2603ce7e4b..ef6402715b3 100644 --- a/frameworks/bridge/declarative_frontend/jsview/js_view_abstract.cpp +++ b/frameworks/bridge/declarative_frontend/jsview/js_view_abstract.cpp @@ -81,6 +81,8 @@ #include "core/components_ng/base/view_abstract_model_ng.h" #include "core/components_ng/base/view_stack_model.h" #include "core/components_ng/base/inspector.h" +#include "core/components_ng/pattern/toolbaritem/toolbaritem_model.h" +#include "core/components_ng/pattern/toolbaritem/toolbaritem_pattern.h" #include "core/event/key_event.h" namespace OHOS::Ace::NG { @@ -1607,6 +1609,28 @@ void JSViewAbstract::JsHeight(const JSCallbackInfo& info) JsHeight(info[0]); } +void JSViewAbstract::JsToolbar(const JSCallbackInfo& info) +{ + // Check the parameters + if (info.Length() <= 0 || !info[0]->IsObject()) { + return; + } + JSRef toolbarObj = JSRef::Cast(info[0]); + auto builder = toolbarObj->GetProperty("builder"); + if (!builder->IsFunction()) { + return; + }; + ToolBarItemModel::GetInstance()->SetIsFirstCreate(true); + auto builderFunc = AceType::MakeRefPtr(JSRef::Cast(builder)); + CHECK_NULL_VOID(builderFunc); + auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc)]() { + JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); + ACE_SCORING_EVENT("Toolbar"); + func->Execute(); + }; + ViewAbstractModel::GetInstance()->SetToolbarBuilder(std::move(buildFunc)); +} + bool JSViewAbstract::JsHeight(const JSRef& jsValue) { CalcDimension value; @@ -6894,6 +6918,7 @@ void JSViewAbstract::JSBind(BindingTarget globalObj) JSClass::StaticMethod("width", &JSViewAbstract::JsWidth); JSClass::StaticMethod("height", &JSViewAbstract::JsHeight); + JSClass::StaticMethod("toolbar", &JSViewAbstract::JsToolbar); JSClass::StaticMethod("responseRegion", &JSViewAbstract::JsResponseRegion); JSClass::StaticMethod("mouseResponseRegion", &JSViewAbstract::JsMouseResponseRegion); JSClass::StaticMethod("size", &JSViewAbstract::JsSize); diff --git a/frameworks/bridge/declarative_frontend/jsview/js_view_abstract.h b/frameworks/bridge/declarative_frontend/jsview/js_view_abstract.h index cf47596d664..f025d58dbd5 100755 --- a/frameworks/bridge/declarative_frontend/jsview/js_view_abstract.h +++ b/frameworks/bridge/declarative_frontend/jsview/js_view_abstract.h @@ -147,6 +147,7 @@ public: static RefPtr ParseJsTransitionEffect(const JSCallbackInfo& info); static void JsWidth(const JSCallbackInfo& info); static void JsHeight(const JSCallbackInfo& info); + static void JsToolbar(const JSCallbackInfo& info); static void JsBackgroundColor(const JSCallbackInfo& info); static void JsBackgroundImage(const JSCallbackInfo& info); static void JsBackgroundImageSize(const JSCallbackInfo& info); diff --git a/frameworks/bridge/declarative_frontend/jsview/models/view_abstract_model_impl.cpp b/frameworks/bridge/declarative_frontend/jsview/models/view_abstract_model_impl.cpp index cdcd10944d3..d72abcda298 100755 --- a/frameworks/bridge/declarative_frontend/jsview/models/view_abstract_model_impl.cpp +++ b/frameworks/bridge/declarative_frontend/jsview/models/view_abstract_model_impl.cpp @@ -215,6 +215,8 @@ void ViewAbstractModelImpl::SetHeight(const CalcDimension& height) } } +void ViewAbstractModelImpl::SetToolbarBuilder(std::function&& buildFunc) {} + void ViewAbstractModelImpl::SetMinWidth(const CalcDimension& minWidth) { auto box = ViewStackProcessor::GetInstance()->GetBoxComponent(); diff --git a/frameworks/bridge/declarative_frontend/jsview/models/view_abstract_model_impl.h b/frameworks/bridge/declarative_frontend/jsview/models/view_abstract_model_impl.h index 60565112c52..c1dd3c9970a 100755 --- a/frameworks/bridge/declarative_frontend/jsview/models/view_abstract_model_impl.h +++ b/frameworks/bridge/declarative_frontend/jsview/models/view_abstract_model_impl.h @@ -33,6 +33,7 @@ public: void SetWidth(const CalcDimension& width) override; void SetHeight(const CalcDimension& height) override; + void SetToolbarBuilder(std::function&& buildFunc) override; void ClearWidthOrHeight(bool isWidth) override {}; void SetMinWidth(const CalcDimension& minWidth) override; void SetMinHeight(const CalcDimension& minHeight) override; diff --git a/frameworks/core/components/common/layout/constants.h b/frameworks/core/components/common/layout/constants.h index c718446e1ef..f6636292f9a 100644 --- a/frameworks/core/components/common/layout/constants.h +++ b/frameworks/core/components/common/layout/constants.h @@ -44,6 +44,11 @@ enum class ButtonType { ROUNDED_RECTANGLE, }; +enum class ToolBarItemPlacement { + TOP_BAR_LEADING, + TOP_BAR_TRAILING +}; + enum class RectWidthStyle { TIGHT, MAX, diff --git a/frameworks/core/components_ng/base/frame_node.cpp b/frameworks/core/components_ng/base/frame_node.cpp index 9f7b81f51e5..10720a73531 100644 --- a/frameworks/core/components_ng/base/frame_node.cpp +++ b/frameworks/core/components_ng/base/frame_node.cpp @@ -1479,6 +1479,9 @@ void FrameNode::TryVisibleChangeOnDescendant(VisibleType preVisibility, VisibleT void FrameNode::OnDetachFromMainTree(bool recursive, PipelineContext* context) { + if (detachRelatedNodeCallback_) { + detachRelatedNodeCallback_(); + } auto focusHub = GetFocusHub(); if (focusHub) { auto focusView = focusHub->GetFirstChildFocusView(); diff --git a/frameworks/core/components_ng/base/frame_node.h b/frameworks/core/components_ng/base/frame_node.h index ca7ea9a161b..dfb80ca4a56 100644 --- a/frameworks/core/components_ng/base/frame_node.h +++ b/frameworks/core/components_ng/base/frame_node.h @@ -1342,6 +1342,10 @@ public: void AddVisibilityDumpInfo(const std::pair>& dumpInfo); std::string PrintVisibilityDumpInfo() const; + void SetDetachRelatedNodeCallback(std::function&& callback) + { + detachRelatedNodeCallback_ = std::move(callback); + } protected: void DumpInfo() override; @@ -1637,6 +1641,8 @@ private: RefPtr kitNode_; ACE_DISALLOW_COPY_AND_MOVE(FrameNode); + + std::function detachRelatedNodeCallback_; }; } // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/base/view_abstract_model.h b/frameworks/core/components_ng/base/view_abstract_model.h index 978b44b3afb..33a15ace59e 100755 --- a/frameworks/core/components_ng/base/view_abstract_model.h +++ b/frameworks/core/components_ng/base/view_abstract_model.h @@ -374,6 +374,9 @@ public: virtual void SetObscured(const std::vector& reasons) = 0; virtual void SetPrivacySensitive(bool flag) = 0; + // toolbar + virtual void SetToolbarBuilder(std::function&& buildFunc) = 0; + // background virtual void BindBackground(std::function&& buildFunc, const Alignment& align) = 0; diff --git a/frameworks/core/components_ng/base/view_abstract_model_ng.cpp b/frameworks/core/components_ng/base/view_abstract_model_ng.cpp index b538d40fbd3..47f887a0846 100644 --- a/frameworks/core/components_ng/base/view_abstract_model_ng.cpp +++ b/frameworks/core/components_ng/base/view_abstract_model_ng.cpp @@ -20,6 +20,7 @@ #include "core/components_ng/base/view_abstract.h" #include "core/components_ng/event/focus_hub.h" #include "core/components_ng/pattern/menu/menu_theme.h" +#include "core/components_ng/pattern/container_modal/container_modal_pattern.h" #include "core/components_ng/pattern/menu/wrapper/menu_wrapper_pattern.h" #include "core/components_ng/pattern/navrouter/navdestination_pattern.h" #include "core/components_ng/pattern/overlay/overlay_manager.h" @@ -518,6 +519,29 @@ void ViewAbstractModelNG::BindDragWithContextMenuParams(FrameNode* targetNode, c } } +void ViewAbstractModelNG::SetToolbarBuilder(std::function&& buildFunc) +{ + CHECK_NULL_VOID(buildFunc); + auto buildNodeFunc = [func = std::move(buildFunc)]() -> RefPtr { + NG::ScopedViewStackProcessor builderViewStackProcessor; + func(); + auto customNode = NG::ViewStackProcessor::GetInstance()->Finish(); + return customNode; + }; + auto pipelineContext = NG::PipelineContext::GetMainPipelineContext(); + CHECK_NULL_VOID(pipelineContext); + auto rootNode = pipelineContext->GetRootElement(); + CHECK_NULL_VOID(rootNode); + auto containerMode = AceType::DynamicCast(rootNode->GetChildren().front()); + CHECK_NULL_VOID(containerMode); + auto pattern = containerMode->GetPattern(); + CHECK_NULL_VOID(pattern); + auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode()); + auto parent = frameNode.Upgrade(); + CHECK_NULL_VOID(parent); + pattern->SetToolbarBuilder(parent, std::move(buildNodeFunc)); +} + void ViewAbstractModelNG::BindBackground(std::function&& buildFunc, const Alignment& align) { auto buildNodeFunc = [buildFunc = std::move(buildFunc)]() -> RefPtr { diff --git a/frameworks/core/components_ng/base/view_abstract_model_ng.h b/frameworks/core/components_ng/base/view_abstract_model_ng.h index 6b9d5e3ae0e..806b18f80f4 100755 --- a/frameworks/core/components_ng/base/view_abstract_model_ng.h +++ b/frameworks/core/components_ng/base/view_abstract_model_ng.h @@ -1330,6 +1330,8 @@ public: ViewAbstract::DismissPopup(); } + void SetToolbarBuilder(std::function&& buildFunc) override; + void BindBackground(std::function&& buildFunc, const Alignment& align) override; int32_t OpenMenu(NG::MenuParam& menuParam, const RefPtr& customNode, const int32_t& targetId) override diff --git a/frameworks/core/components_ng/manager/BUILD.gn b/frameworks/core/components_ng/manager/BUILD.gn index b11469783fa..b5623ef6391 100644 --- a/frameworks/core/components_ng/manager/BUILD.gn +++ b/frameworks/core/components_ng/manager/BUILD.gn @@ -51,5 +51,6 @@ build_component_ng("manager_ng") { "select_overlay/select_overlay_proxy.cpp", "shared_overlay/shared_overlay_manager.cpp", "shared_overlay/shared_transition_effect.cpp", + "toolbar/toolbar_manager.cpp", ] } diff --git a/frameworks/core/components_ng/manager/toolbar/toolbar_manager.cpp b/frameworks/core/components_ng/manager/toolbar/toolbar_manager.cpp new file mode 100644 index 00000000000..abf2b5d7f90 --- /dev/null +++ b/frameworks/core/components_ng/manager/toolbar/toolbar_manager.cpp @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "toolbar_manager.h" + +namespace OHOS::Ace::NG { +void ToolbarManager::SetSideBarInfo(const ToolbarInfo& info) +{ + sideBarInfo_ = info; + OnChange(); +} + +void ToolbarManager::SetSideBarDividerInfo(const ToolbarInfo& info) +{ + sideBarDividerInfo_ = info; + OnChange(); +} + +void ToolbarManager::SetNavBarInfo(const ToolbarInfo& info) +{ + navBarInfo_ = info; + OnChange(); +} + +void ToolbarManager::SetNavBarDividerInfo(const ToolbarInfo& info) +{ + navBarDividerInfo_ = info; + OnChange(); +} + +void ToolbarManager::SetNavDestInfo(const ToolbarInfo& info) +{ + navDestInfo_ = info; + OnChange(); +} + +void ToolbarManager::SetToolBarChangeCallback(const std::function&& callback) +{ + onChangeCallbackFunc_ = std::move(callback); +} + +void ToolbarManager::OnChange() +{ + if (onChangeCallbackFunc_) { + onChangeCallbackFunc_(); + } +} + +void ToolbarManager::SetModifyDoneCallback(const std::function&& callback) +{ + modifyDoneCallbackFunc_ = std::move(callback); +} + +void ToolbarManager::OnNavigationModifyDone() +{ + if (modifyDoneCallbackFunc_) { + modifyDoneCallbackFunc_(); + } +} + +void ToolbarManager::OnSideBarModifyDone() +{ + if (modifyDoneCallbackFunc_) { + modifyDoneCallbackFunc_(); + } +} + +void ToolbarManager::SetSideBarColorChangeCallback(const std::function&& callback) +{ + sideBarColorChangeCallbackFunc_ = std::move(callback); +} + +void ToolbarManager::OnChangeSideBarColor() +{ + if (sideBarColorChangeCallbackFunc_) { + sideBarColorChangeCallbackFunc_(); + } +} +} // namespace OHOS::Ace::NG \ No newline at end of file diff --git a/frameworks/core/components_ng/manager/toolbar/toolbar_manager.h b/frameworks/core/components_ng/manager/toolbar/toolbar_manager.h new file mode 100644 index 00000000000..f735cbc6e09 --- /dev/null +++ b/frameworks/core/components_ng/manager/toolbar/toolbar_manager.h @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_MANAGER_TOOLBAR_TOOLBAR_MANAGER_H +#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_MANAGER_TOOLBAR_TOOLBAR_MANAGER_H + +#include "base/memory/ace_type.h" +#include "core/components_ng/base/frame_node.h" + +namespace OHOS::Ace::NG { + +struct ToolbarInfo { + bool isShow; + float width; +}; + +class ToolbarManager : public virtual AceType { + DECLARE_ACE_TYPE(ToolbarManager, AceType); + +public: + ToolbarManager() = default; + ~ToolbarManager() override = default; + + void SetHasSideBar(bool hasSideBar) + { + hasSideBar_ = hasSideBar; + } + + bool HasSideBar() const + { + return hasSideBar_; + } + + void SetHasNavBar(bool hasNavBar) + { + hasNavBar_ = hasNavBar; + } + + bool HasNavBar() const + { + return hasNavBar_; + } + + void SetHasNavDest(bool hasNavDest) + { + hasNavDest_ = hasNavDest; + } + + bool HasNavDest() const + { + return hasNavDest_; + } + + ToolbarInfo GetSideBarInfo() const + { + return sideBarInfo_; + } + void SetSideBarInfo(const ToolbarInfo& info); + + ToolbarInfo GetSideBarDividerInfo() const + { + return sideBarDividerInfo_; + } + + void SetSideBarDividerInfo(const ToolbarInfo& info); + + ToolbarInfo GetNavBarInfo() const + { + return navBarInfo_; + } + + void SetNavBarInfo(const ToolbarInfo& info); + + ToolbarInfo GetNavBarDividerInfo() const + { + return navBarDividerInfo_; + } + + void SetNavBarDividerInfo(const ToolbarInfo& info); + + ToolbarInfo GetNavDestInfo() const + { + return navDestInfo_; + } + + void SetNavDestInfo(const ToolbarInfo& info); + + void SetSideBarColor(const Color& color) + { + sideBarColor_ = color; + OnChangeSideBarColor(); + } + + Color GetSideBarColor() const + { + return sideBarColor_; + } + + void SetSideBarColorChangeCallback(const std::function&& callback); + void OnChangeSideBarColor(); + void SetToolBarChangeCallback(const std::function&& callback); + void OnChange(); + void SetModifyDoneCallback(const std::function&& callback); + void OnNavigationModifyDone(); + void OnSideBarModifyDone(); + +private: + bool hasSideBar_ = false; + bool hasNavBar_ = false; + bool hasNavDest_ = false; + ToolbarInfo sideBarInfo_; + Color sideBarColor_; + ToolbarInfo sideBarDividerInfo_; + ToolbarInfo navBarInfo_; + ToolbarInfo navBarDividerInfo_; + ToolbarInfo navDestInfo_; + std::function sideBarColorChangeCallbackFunc_; + std::function onChangeCallbackFunc_; + std::function modifyDoneCallbackFunc_; +}; +} // namespace OHOS::Ace::NG +#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_MANAGER_TOOLBAR_TOOLBAR_MANAGER_H \ No newline at end of file diff --git a/frameworks/core/components_ng/pattern/BUILD.gn b/frameworks/core/components_ng/pattern/BUILD.gn index a91539f8d69..8e89ab431e4 100644 --- a/frameworks/core/components_ng/pattern/BUILD.gn +++ b/frameworks/core/components_ng/pattern/BUILD.gn @@ -560,6 +560,7 @@ build_component_ng("pattern_ng") { "toggle/switch_paint_property.cpp", "toggle/switch_pattern.cpp", "toggle/toggle_model_ng.cpp", + "toolbaritem/toolbaritem_model_ng.cpp", "video/video_accessibility_property.cpp", "video/video_full_screen_node.cpp", "video/video_full_screen_pattern.cpp", diff --git a/frameworks/core/components_ng/pattern/container_modal/container_modal_pattern.cpp b/frameworks/core/components_ng/pattern/container_modal/container_modal_pattern.cpp index 0271fb4cf0b..255375c5af8 100644 --- a/frameworks/core/components_ng/pattern/container_modal/container_modal_pattern.cpp +++ b/frameworks/core/components_ng/pattern/container_modal/container_modal_pattern.cpp @@ -16,11 +16,20 @@ #include "core/components_ng/pattern/container_modal/container_modal_pattern.h" #include "base/subwindow/subwindow_manager.h" +#include "core/components_ng/base/frame_node.h" +#include "core/components_ng/base/ui_node.h" +#include "core/components_ng/manager/toolbar/toolbar_manager.h" #include "core/components_ng/pattern/button/button_event_hub.h" #include "core/components_ng/pattern/button/button_layout_property.h" #include "core/components_ng/pattern/container_modal/container_modal_theme.h" +#include "core/components_ng/pattern/flex/flex_layout_styles.h" #include "core/components_ng/pattern/image/image_layout_property.h" #include "core/components_ng/pattern/linear_layout/linear_layout_property.h" +#include "core/components_ng/pattern/linear_layout/linear_layout_pattern.h" +#include "core/components_ng/pattern/toolbaritem/toolbaritem_pattern.h" +#include "ui/base/ace_type.h" +#include "ui/base/referenced.h" +#include "ui/base/utils/utils.h" namespace OHOS::Ace::NG { @@ -34,6 +43,9 @@ constexpr double MOUSE_MOVE_POPUP_DISTANCE = 5.0; // 5.0px constexpr double MOVE_POPUP_DISTANCE_X = 40.0; // 40.0px constexpr double MOVE_POPUP_DISTANCE_Y = 20.0; // 20.0px constexpr double TITLE_POPUP_DISTANCE = 37.0; // 37vp height of title +constexpr float TITLE_ITEM_HEIGT_S = 56.0; // 56vp height of title +constexpr float TITLE_ITEM_HEIGT_M = 64.0; // 64vp height of title +constexpr float TITLE_ITEM_HEIGT_L = 72.0; // 72vp height of title } // namespace void ContainerModalPattern::ShowTitle(bool isShow, bool hasDeco, bool needUpdate) @@ -1028,4 +1040,525 @@ void ContainerModalPattern::EnableContainerModalCustomGesture(RefPtrSetEnableContainerModalCustomGesture(enable); containerPattern->InitColumnTouchTestFunc(); } + +void ContainerModalPattern::InitToolBarManager() +{ + if (!toolbarManager_) { + auto pipeline = GetHost()->GetContext(); + CHECK_NULL_VOID(pipeline); + toolbarManager_ = pipeline->GetToolbarManager(); + + std::function func = [weak = WeakClaim(this)]() { + auto pattern = weak.Upgrade(); + CHECK_NULL_VOID(pattern); + pattern->OnToolBarLayoutChange(); + }; + toolbarManager_->SetToolBarChangeCallback(std::move(func)); + + std::function getTypeOfItem = [weak = WeakClaim(this)]() { + auto pattern = weak.Upgrade(); + pattern->PrasePlaceMentType(); + }; + toolbarManager_->SetModifyDoneCallback(std::move(getTypeOfItem)); + } +} + +void ContainerModalPattern::SetToolbarBuilder( + const RefPtr& parent, std::function()>&& builder) +{ + auto node = builder(); + CHECK_NULL_VOID(node); + auto it = itemsWillOnTree_.find(parent); + if (it != itemsWillOnTree_.end()) { + it->second.clear(); + } + it = itemsOnTree_.find(parent); + if (it != itemsOnTree_.end()) { + it->second.clear(); + } + auto children = node->GetChildren(); + + for (auto& item : children) { + itemsWillOnTree_[parent].push_back(item); + itemsOnTree_[parent].push_back(item); + } + auto callback = [weak = WeakClaim(this), frame = WeakClaim(RawPtr(parent))]() { + auto pattern = weak.Upgrade(); + CHECK_NULL_VOID(pattern); + auto frameNode = frame.Upgrade(); + CHECK_NULL_VOID(frameNode); + pattern->RemoveToolbarItem(frameNode); + }; + parent->SetDetachRelatedNodeCallback(std::move(callback)); + InitToolBarManager(); + + auto pipeline = GetContext(); + CHECK_NULL_VOID(pipeline); + pipeline->AddAfterRenderTask([weak = WeakClaim(this)]() { + auto pattern = weak.Upgrade(); + CHECK_NULL_VOID(pattern); + pattern->PrasePlaceMentType(); + }); +} + +void ContainerModalPattern::PrasePlaceMentType() +{ + bool hasItem = false; + for (auto it = itemsWillOnTree_.begin(); it != itemsWillOnTree_.end();) { + auto parent = it->first; + auto& list = it->second; + if (HandleToolbarItemList(parent, list)) { + it = itemsWillOnTree_.erase(it); + hasItem = true; + } else { + it++; + } + } + if (hasItem) { + AddToolbarItemToContainer(); + } +} + +ItemPlacementType ContainerModalPattern::GetItemTypeFromTag(const std::string& tag, uint32_t placement) +{ + if (tag == V2::SIDE_BAR_ETS_TAG) + return placement ? ItemPlacementType::SIDE_BAR_END : ItemPlacementType::SIDE_BAR_START; + if (tag == V2::NAVBAR_ETS_TAG) + return placement ? ItemPlacementType::NAV_BAR_END : ItemPlacementType::NAV_BAR_START; + if (tag == V2::NAVDESTINATION_VIEW_ETS_TAG) + return placement ? ItemPlacementType::NAVDEST_END : ItemPlacementType::NAVDEST_START; + return ItemPlacementType::NONE; +} + +bool ContainerModalPattern::HandleToolbarItemList(const RefPtr& parentNode, std::list>& list) +{ + CHECK_NULL_RETURN(parentNode, true); + + auto parent = AceType::DynamicCast(parentNode); + CHECK_NULL_RETURN(parent, true); + std::string tag = ""; + while (parent && parent->GetTag() != V2::ROOT_ETS_TAG) { + if (parent->GetTag() == V2::SIDE_BAR_ETS_TAG || parent->GetTag() == V2::NAVBAR_ETS_TAG || + parent->GetTag() == V2::NAVDESTINATION_VIEW_ETS_TAG) { + tag = parent->GetTag(); + break; + } + parent = parent->GetParent(); + } + if (tag == "") { + return false; + } + + for (auto& item : list) { + auto frameNode = AceType::DynamicCast(item); + + auto pattern = frameNode->GetPattern(); + int32_t placement = 0; + if (pattern) { + placement = pattern->GetPlacement(); + auto id = GetItemTypeFromTag(tag, placement); + itemWillAdd_[id].emplace_back(frameNode); + } + } + return true; +} + +void ContainerModalPattern::RemoveToolbarItem(const RefPtr& frameNode) +{ + auto& list = itemsOnTree_[frameNode]; + for (auto& item : list) { + auto parent = item->GetParent(); + if (parent) { + parent->RemoveChild(item); + parent->MarkNeedSyncRenderTree(); + parent->RebuildRenderContextTree(); + } + } + list.clear(); + itemsOnTree_.erase(frameNode); + if (navbarRow_) { + navbarRow_->MarkDirtyNode( + PROPERTY_UPDATE_LAYOUT | PROPERTY_UPDATE_RENDER | PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD); + if (leftNavRow_) { + leftNavRow_->MarkDirtyNode( + PROPERTY_UPDATE_LAYOUT | PROPERTY_UPDATE_RENDER | PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD); + } + if (rightNavRow_) { + rightNavRow_->MarkDirtyNode( + PROPERTY_UPDATE_LAYOUT | PROPERTY_UPDATE_RENDER | PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD); + } + } + if (navDestbarRow_) { + navDestbarRow_->MarkDirtyNode( + PROPERTY_UPDATE_LAYOUT | PROPERTY_UPDATE_RENDER | PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD); + if (leftNavDestRow_) { + leftNavDestRow_->MarkDirtyNode( + PROPERTY_UPDATE_LAYOUT | PROPERTY_UPDATE_RENDER | PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD); + } + if (rightNavDestRow_) { + rightNavDestRow_->MarkDirtyNode( + PROPERTY_UPDATE_LAYOUT | PROPERTY_UPDATE_RENDER | PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD); + } + } + toolbarItemMaxHeight_ = 0.0f; + for (auto it = itemsOnTree_.begin(); it != itemsOnTree_.end(); it++) { + auto& list = it->second; + for (auto iit = list.begin(); iit != list.end(); iit++) { + auto toolbarNode = AceType::DynamicCast(*iit); + LayoutConstraintF Constraint; + toolbarNode->Measure(Constraint); + auto toolbarItemHeight = Dimension(toolbarNode->GetGeometryNode()->GetFrameSize().Height()).ConvertToVp(); + if (toolbarItemHeight > toolbarItemMaxHeight_) { + toolbarItemMaxHeight_ = toolbarItemHeight; + } + } + } + OnToolBarLayoutChange(); + AdjustContainerModalTitleHeight(); +} + +void ContainerModalPattern::AddToolbarItemToContainer() +{ + for (auto it = itemWillAdd_.begin(); it != itemWillAdd_.end(); it++) { + auto placementType = it->first; + if (placementType == ItemPlacementType::NONE) { + continue; + } + auto& list = it->second; + for (auto iit = list.begin(); iit != list.end();) { + if (AddToolbarItemToRow(placementType, *iit)) { + iit = list.erase(iit); + } else { + iit++; + } + } + } +} + +bool ContainerModalPattern::AddToolbarItemToRow(ItemPlacementType placeMent, const RefPtr& frameNode) +{ + if ((!toolbarManager_->HasNavBar() && + (placeMent == ItemPlacementType::NAV_BAR_END || placeMent == ItemPlacementType::NAV_BAR_START)) || + (!toolbarManager_->HasNavDest() && + (placeMent == ItemPlacementType::NAVDEST_START || placeMent == ItemPlacementType::NAVDEST_END))) { + return false; + } + CHECK_NULL_RETURN(frameNode, false); + LayoutConstraintF Constraint; + frameNode->Measure(Constraint); + auto toolbarItemHeight = Dimension(frameNode->GetGeometryNode()->GetFrameSize().Height()).ConvertToVp(); + if (toolbarItemHeight > toolbarItemMaxHeight_) { + toolbarItemMaxHeight_ = toolbarItemHeight; + } + auto toolbarItemPattern = frameNode->GetPattern(); + CHECK_NULL_RETURN(toolbarItemPattern, false); + if (!navbarRow_ || !navDestbarRow_) { + AddToolbarRowContainers(); + } + return AddToolbarItemToSpecificRow(placeMent, frameNode); +} + +bool ContainerModalPattern::AddToolbarItemToSpecificRow(ItemPlacementType placeMent, const RefPtr& frameNode) +{ + bool ref = false; + switch (placeMent) { + case ItemPlacementType::NAV_BAR_START: + ref = AddToolbarItemToNavBarStart(frameNode); + break; + case ItemPlacementType::NAV_BAR_END: + ref = AddToolbarItemToNavBarEnd(frameNode); + break; + case ItemPlacementType::NAVDEST_START: + ref = AddToolbarItemToNavDestStart(frameNode); + break; + case ItemPlacementType::NAVDEST_END: + ref = AddToolbarItemToNavDestEnd(frameNode); + break; + default: + TAG_LOGE(AceLogTag::ACE_SUB_WINDOW, "Unknown placement"); + return false; + } + auto overlayTask = [weak = WeakClaim(this)]() { + auto pattern = weak.Upgrade(); + CHECK_NULL_VOID(pattern); + pattern->AdjustContainerModalTitleHeight(); + }; + auto pipeline = GetContext(); + CHECK_NULL_RETURN(pipeline, true); + pipeline->AddAfterRenderTask(overlayTask); + return ref; +} + +bool ContainerModalPattern::AddToolbarItemToNavBarStart(const RefPtr& frameNode) +{ + if (navbarRow_) { + if (!leftNavRow_) { + AddToolbarRowContainers(); + } + leftNavRow_->AddChild(frameNode); + leftNavRow_->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_PARENT); + return true; + } + return false; +} + +bool ContainerModalPattern::AddToolbarItemToNavBarEnd(const RefPtr& frameNode) +{ + if (navbarRow_) { + if (!rightNavRow_) { + AddToolbarRowContainers(); + } + rightNavRow_->AddChild(frameNode); + rightNavRow_->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_PARENT); + return true; + } + return false; +} + +bool ContainerModalPattern::AddToolbarItemToNavDestStart(const RefPtr& frameNode) +{ + if (navDestbarRow_) { + if (!leftNavDestRow_) { + AddToolbarRowContainers(); + } + leftNavDestRow_->AddChild(frameNode); + leftNavDestRow_->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_PARENT); + return true; + } + return false; +} + +bool ContainerModalPattern::AddToolbarItemToNavDestEnd(const RefPtr& frameNode) +{ + if (navDestbarRow_) { + if (!rightNavDestRow_) { + AddToolbarRowContainers(); + } + rightNavDestRow_->AddChild(frameNode); + rightNavDestRow_->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_PARENT); + return true; + } + return false; +} + +void ContainerModalPattern::AddToolbarRowContainers() +{ + auto pipelineContext = PipelineContext::GetCurrentContext(); + CHECK_NULL_VOID(pipelineContext); + + auto customTitleRow = GetCustomTitleRow(); + CHECK_NULL_VOID(customTitleRow); + + auto sideBarInfo = toolbarManager_->GetSideBarInfo(); + auto navBarInfo = toolbarManager_->GetNavBarInfo(); + auto navDestInfo = toolbarManager_->GetNavDestInfo(); + + AddSideBarDivider(customTitleRow, sideBarInfo); + AddNavBarRow(customTitleRow, navBarInfo, sideBarInfo); + AddNavDestBarRow(customTitleRow, navDestInfo); + + customTitleRow->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); +} + +void ContainerModalPattern::AddSideBarDivider(const RefPtr& customTitleRow, const ToolbarInfo& sideBarInfo) +{ + if (sideBarInfo.isShow && !sideBarDivider_) { + sideBarDivider_ = FrameNode::CreateFrameNode( + V2::ROW_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), MakeRefPtr(true)); + auto customTitleNode = GetCustomTitleNode(); + CHECK_NULL_VOID(customTitleNode); + customTitleRow->AddChildAfter(sideBarDivider_, customTitleNode->GetParent()); + sideBarDivider_->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_PARENT); + } +} + +void ContainerModalPattern::AddNavBarRow( + const RefPtr& customTitleRow, const ToolbarInfo& navBarInfo, const ToolbarInfo& sideBarInfo) +{ + if (navBarInfo.isShow) { + if (!navbarRow_) { + navbarRow_ = FrameNode::CreateFrameNode(V2::ROW_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), + MakeRefPtr(false)); + navbarRow_->UpdateInspectorId("NavBar"); + auto layout = navbarRow_->GetLayoutProperty(); + CHECK_NULL_VOID(layout); + layout->UpdateMainAxisAlign(FlexAlign::SPACE_BETWEEN); + navbarRow_->GetRenderContext()->SetClipToFrame(true); + if (sideBarInfo.isShow) { + customTitleRow->AddChildAfter(navbarRow_, sideBarDivider_); + } else { + auto customTitleNode = GetCustomTitleNode(); + CHECK_NULL_VOID(customTitleNode); + customTitleRow->AddChildAfter(navbarRow_, customTitleNode->GetParent()); + } + AddNavBarDivider(customTitleRow); + navbarRow_->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD); + } + if (navbarRow_) { + if (!leftNavRow_) { + leftNavRow_ = FrameNode::CreateFrameNode(V2::ROW_ETS_TAG, + ElementRegister::GetInstance()->MakeUniqueId(), MakeRefPtr(false)); + leftNavRow_->UpdateInspectorId("LeftNavRow"); + navbarRow_->AddChild(leftNavRow_); + leftNavRow_->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); + } + if (!rightNavRow_) { + rightNavRow_ = FrameNode::CreateFrameNode(V2::ROW_ETS_TAG, + ElementRegister::GetInstance()->MakeUniqueId(), MakeRefPtr(false)); + rightNavRow_->UpdateInspectorId("RightNavRow"); + navbarRow_->AddChild(rightNavRow_); + auto layout = rightNavRow_->GetLayoutProperty(); + CHECK_NULL_VOID(layout); + layout->UpdateMainAxisAlign(FlexAlign::FLEX_END); + rightNavRow_->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); + } + navbarRow_->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD); + } + AdjustNavbarRowWidth(); + } +} + +void ContainerModalPattern::AddNavBarDivider(const RefPtr& customTitleRow) +{ + if (!navBarDivider_) { + navBarDivider_ = FrameNode::CreateFrameNode( + V2::ROW_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), MakeRefPtr(false)); + navBarDivider_->UpdateInspectorId("NavBarDivider"); + customTitleRow->AddChildAfter(navBarDivider_, navbarRow_); + navBarDivider_->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_PARENT); + } +} + +void ContainerModalPattern::AddNavDestBarRow(const RefPtr& customTitleRow, const ToolbarInfo& navDestInfo) +{ + if (navDestInfo.isShow) { + if (!navDestbarRow_) { + navDestbarRow_ = FrameNode::CreateFrameNode(V2::ROW_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), + MakeRefPtr(false)); + navDestbarRow_->UpdateInspectorId("NavDestBar"); + auto layout = navDestbarRow_->GetLayoutProperty(); + CHECK_NULL_VOID(layout); + layout->UpdateMainAxisAlign(FlexAlign::SPACE_BETWEEN); + navDestbarRow_->GetRenderContext()->SetClipToFrame(true); + customTitleRow->AddChild(navDestbarRow_); + navDestbarRow_->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD); + } + + if (navDestbarRow_) { + if (!leftNavDestRow_) { + leftNavDestRow_ = FrameNode::CreateFrameNode(V2::ROW_ETS_TAG, + ElementRegister::GetInstance()->MakeUniqueId(), MakeRefPtr(false)); + leftNavDestRow_->UpdateInspectorId("LeftNavDest"); + navDestbarRow_->AddChild(leftNavDestRow_); + leftNavDestRow_->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); + } + if (!rightNavDestRow_) { + rightNavDestRow_ = FrameNode::CreateFrameNode(V2::ROW_ETS_TAG, + ElementRegister::GetInstance()->MakeUniqueId(), MakeRefPtr(false)); + rightNavDestRow_->UpdateInspectorId("RightNavDest"); + auto layout = rightNavDestRow_->GetLayoutProperty(); + CHECK_NULL_VOID(layout); + layout->UpdateMainAxisAlign(FlexAlign::FLEX_END); + navDestbarRow_->AddChild(rightNavDestRow_); + rightNavDestRow_->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); + } + navDestbarRow_->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); + AdjustNavDestRowWidth(); + } + } +} + +void ContainerModalPattern::OnToolBarLayoutChange() +{ + if (!toolbarManager_) { + return; + } + + if (toolbarManager_->GetNavBarInfo().isShow) { + AddToolbarItemToContainer(); + AdjustNavbarRowWidth(); + } + if (toolbarManager_->GetNavDestInfo().isShow) { + AddToolbarItemToContainer(); + AdjustNavDestRowWidth(); + } +} + +void ContainerModalPattern::AdjustNavbarRowWidth() +{ + auto sideBarInfo = toolbarManager_->GetSideBarInfo(); + auto sideBarDividerInfo = toolbarManager_->GetSideBarDividerInfo(); + auto navbarInfo = toolbarManager_->GetNavBarInfo(); + auto navbarDividerInfo = toolbarManager_->GetNavBarDividerInfo(); + + float titleNodeWidth = sideBarInfo.isShow ? sideBarInfo.width : 0; + auto customTitleNode = GetCustomTitleNode(); + CHECK_NULL_VOID(customTitleNode); + auto titleNode = AceType::DynamicCast(customTitleNode->GetParent()); + CHECK_NULL_VOID(titleNode); + + auto titleNodeProperty = titleNode->GetLayoutProperty(); + CHECK_NULL_VOID(titleNodeProperty); + + titleNodeProperty->UpdateMeasureType(MeasureType::MATCH_PARENT); + titleNode->GetRenderContext()->SetClipToFrame(true); + titleNodeProperty->UpdateUserDefinedIdealSize( + CalcSize(CalcLength(titleNodeWidth), CalcLength(1.0, DimensionUnit::PERCENT))); + titleNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD); + titleNode->MarkDirtyNode(PROPERTY_UPDATE_RENDER); + + float sideBarDividerWidth = sideBarInfo.isShow ? sideBarDividerInfo.width : 0; + if (sideBarDivider_) { + auto sideBarDividerProperty = sideBarDivider_->GetLayoutProperty(); + CHECK_NULL_VOID(sideBarDividerProperty); + sideBarDividerProperty->UpdateUserDefinedIdealSize( + CalcSize(CalcLength(sideBarDividerWidth), CalcLength(1.0, DimensionUnit::PERCENT))); + sideBarDivider_->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_PARENT); + } + if (navbarInfo.isShow && navbarRow_) { + auto navbarRowProperty = navbarRow_->GetLayoutProperty(); + CHECK_NULL_VOID(navbarRowProperty); + navbarRowProperty->UpdateUserDefinedIdealSize(CalcSize(CalcLength(navbarInfo.width), std::nullopt)); + navbarRow_->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD); + + auto navBarDividerProperty = navBarDivider_->GetLayoutProperty(); + CHECK_NULL_VOID(navBarDividerProperty); + navBarDividerProperty->UpdateUserDefinedIdealSize( + CalcSize(CalcLength(navbarDividerInfo.width), CalcLength(1.0, DimensionUnit::PERCENT))); + navBarDivider_->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_PARENT); + } +} + +void ContainerModalPattern::AdjustNavDestRowWidth() +{ + auto pipelineContext = PipelineContext::GetCurrentContext(); + CHECK_NULL_VOID(pipelineContext); + auto navDestInfo = toolbarManager_->GetNavDestInfo(); + auto controlButtonsWidth = GetControlButtonRowWidth(); + + if (navDestInfo.isShow && navDestbarRow_) { + float navDestbarRowAvailableWidth = navDestInfo.width - controlButtonsWidth.GetDimension().ConvertToPx(); + auto navDestbarRowProperty = navDestbarRow_->GetLayoutProperty(); + CHECK_NULL_VOID(navDestbarRowProperty); + navDestbarRowProperty->UpdateUserDefinedIdealSize( + CalcSize(CalcLength(navDestbarRowAvailableWidth), std::nullopt)); + navDestbarRow_->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD); + } +} + +void ContainerModalPattern::AdjustContainerModalTitleHeight() +{ + if (itemsOnTree_.empty()) { + SetContainerModalTitleHeight(CONTAINER_TITLE_HEIGHT.ConvertToPx()); + } + + if (toolbarItemMaxHeight_ <= TITLE_ITEM_HEIGT_S) { + titleHeight_ = Dimension(TITLE_ITEM_HEIGT_S, DimensionUnit::VP); + } else if (toolbarItemMaxHeight_ > TITLE_ITEM_HEIGT_S && toolbarItemMaxHeight_ <= TITLE_ITEM_HEIGT_M) { + titleHeight_ = Dimension(TITLE_ITEM_HEIGT_M, DimensionUnit::VP); + } else if (toolbarItemMaxHeight_ > TITLE_ITEM_HEIGT_M) { + titleHeight_ = Dimension(TITLE_ITEM_HEIGT_L, DimensionUnit::VP); + } + SetContainerModalTitleHeight(titleHeight_.ConvertToPx()); +} } // namespace OHOS::Ace::NG \ No newline at end of file diff --git a/frameworks/core/components_ng/pattern/container_modal/container_modal_pattern.h b/frameworks/core/components_ng/pattern/container_modal/container_modal_pattern.h index 49560a9f2d1..f41ecad6e1c 100644 --- a/frameworks/core/components_ng/pattern/container_modal/container_modal_pattern.h +++ b/frameworks/core/components_ng/pattern/container_modal/container_modal_pattern.h @@ -23,9 +23,20 @@ #include "core/components_ng/pattern/container_modal/container_modal_accessibility_property.h" #include "core/components_ng/pattern/custom/custom_title_node.h" #include "core/components_ng/pattern/pattern.h" +#include "core/components_ng/property/property.h" #include "core/pipeline_ng/pipeline_context.h" + namespace OHOS::Ace::NG { +enum class ItemPlacementType { + NONE = -1, + SIDE_BAR_START = 0, + SIDE_BAR_END, + NAV_BAR_START, + NAV_BAR_END, + NAVDEST_START, + NAVDEST_END, +}; class ACE_EXPORT ContainerModalPattern : public Pattern { DECLARE_ACE_TYPE(ContainerModalPattern, Pattern); @@ -123,7 +134,9 @@ public: { auto row = GetCustomTitleRow(); CHECK_NULL_RETURN(row, nullptr); - return AceType::DynamicCast(row->GetChildren().front()); + auto title= row->GetChildren().front(); + CHECK_NULL_RETURN(title, nullptr); + return AceType::DynamicCast(title->GetChildren().front()); } RefPtr GetStackNode() @@ -213,6 +226,33 @@ public: static void EnableContainerModalCustomGesture(RefPtr pipeline, bool enable); + void InitToolBarManager(); + void SetToolbarBuilder(const RefPtr& parent, std::function()>&& builder); + void PrasePlaceMentType(); + bool HandleToolbarItemList(const RefPtr& parentNode, std::list>& list); + ItemPlacementType GetItemTypeFromTag(const std::string& tag, uint32_t placement); + void RemoveToolbarItem(const RefPtr& frameNode); + + void AddToolbarItemToContainer(); + bool AddToolbarItemToRow(ItemPlacementType placeMent, const RefPtr& node); + bool AddToolbarItemToSpecificRow(ItemPlacementType placeMent, const RefPtr& frameNode); + bool AddToolbarItemToNavBarStart(const RefPtr& frameNode); + bool AddToolbarItemToNavBarEnd(const RefPtr& frameNode); + bool AddToolbarItemToNavDestStart(const RefPtr& frameNode); + bool AddToolbarItemToNavDestEnd(const RefPtr& frameNode); + + void AddToolbarRowContainers(); + void AddSideBarDivider(const RefPtr& customTitleRow, const ToolbarInfo& sideBarInfo); + void AddNavBarRow( + const RefPtr& customTitleRow, const ToolbarInfo& navBarInfo, const ToolbarInfo& sideBarInfo); + void AddNavBarDivider(const RefPtr& customTitleRow); + void AddNavDestBarRow(const RefPtr& customTitleRow, const ToolbarInfo& navDestInfo); + + void OnToolBarLayoutChange(); + void AdjustNavbarRowWidth(); + void AdjustNavDestRowWidth(); + void AdjustContainerModalTitleHeight(); + protected: virtual RefPtr GetTitleItemByIndex(const RefPtr& controlButtonsNode, int32_t originIndex) { @@ -252,6 +292,16 @@ protected: Color activeColor_; Color inactiveColor_; void InitTitleRowLayoutProperty(RefPtr titleRow, bool isFloating); + + RefPtr sideBarDivider_ = nullptr; + RefPtr navbarRow_ = nullptr; + RefPtr leftNavRow_ = nullptr; + RefPtr rightNavRow_ = nullptr; + RefPtr navBarDivider_ = nullptr; + RefPtr navDestbarRow_ = nullptr; + RefPtr leftNavDestRow_ = nullptr; + RefPtr rightNavDestRow_ = nullptr; + protected: void WindowFocus(bool isFocus); void SetTitleButtonHide( @@ -271,6 +321,7 @@ protected: float moveX_ = 0.0f; float moveY_ = 0.0f; + float toolbarItemMaxHeight_ = 0.0f; bool hasDeco_ = true; bool isFocus_ = false; bool hideSplitButton_ = false; @@ -279,6 +330,12 @@ protected: bool enableContainerModalCustomGesture_ = false; RRect windowPaintRect_; bool isCustomColor_; + + RefPtr toolbarManager_; + + std::map>> itemWillAdd_; + std::map, std::list>> itemsWillOnTree_; + std::map, std::list>> itemsOnTree_; }; } // namespace OHOS::Ace::NG #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_CONTAINER_MODAL_CONTAINER_MODAL_PATTERN_H diff --git a/frameworks/core/components_ng/pattern/container_modal/container_modal_view.cpp b/frameworks/core/components_ng/pattern/container_modal/container_modal_view.cpp index 4b31d456aa1..c8db4a9a2cf 100644 --- a/frameworks/core/components_ng/pattern/container_modal/container_modal_view.cpp +++ b/frameworks/core/components_ng/pattern/container_modal/container_modal_view.cpp @@ -116,7 +116,10 @@ RefPtr ContainerModalView::BuildTitleContainer(RefPtr& con } CHECK_NULL_RETURN(customTitleBarNode, nullptr); - containerTitleRow->AddChild(customTitleBarNode); + auto customTitleBarRow = FrameNode::CreateFrameNode( + V2::ROW_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), MakeRefPtr(false)); + customTitleBarRow->AddChild(customTitleBarNode); + containerTitleRow->AddChild(customTitleBarRow); return containerTitleRow; } diff --git a/frameworks/core/components_ng/pattern/navigation/navigation_pattern.cpp b/frameworks/core/components_ng/pattern/navigation/navigation_pattern.cpp index de83141d552..20af4643c0d 100644 --- a/frameworks/core/components_ng/pattern/navigation/navigation_pattern.cpp +++ b/frameworks/core/components_ng/pattern/navigation/navigation_pattern.cpp @@ -381,6 +381,8 @@ void NavigationPattern::OnModifyDone() RestoreJsStackIfNeeded(); UpdateToobarFocusColor(); UpdateDividerBackgroundColor(); + InitToolBarManager(); + toolbarManager_->OnNavigationModifyDone(); } void NavigationPattern::SetSystemBarStyle(const RefPtr& style) @@ -1745,6 +1747,9 @@ void NavigationPattern::FireNavBarWidthChangeEvent(const RefPtr& Dimension(realBavBarWidth / frameWidth, DimensionUnit::PERCENT) : Dimension(realNavBarWidthDimension.GetNativeValue(userSetDimensionUnit), userSetDimensionUnit); } + auto dividerWidth = static_cast(DIVIDER_WIDTH.ConvertToPx()); + UpdateNavBarToolBarManager(true, realBavBarWidth); + UpdateNavDestToolBarManager(frameWidth - realBavBarWidth - dividerWidth); auto eventHub = host->GetEventHub(); CHECK_NULL_VOID(eventHub); eventHub->FireNavBarWidthChangeEvent(usrSetUnitWidth); @@ -1869,11 +1874,9 @@ void NavigationPattern::HandleDragUpdate(float xOffset) CHECK_NULL_VOID(host); auto geometryNode = host->GetGeometryNode(); CHECK_NULL_VOID(geometryNode); - auto frameSize = geometryNode->GetFrameSize(); - auto frameWidth = frameSize.Width(); + auto frameWidth = geometryNode->GetFrameSize().Width(); auto constraint = navigationLayoutProperty->GetLayoutConstraint(); auto parentSize = CreateIdealSize(constraint.value(), Axis::HORIZONTAL, MeasureType::MATCH_PARENT); - float minNavBarWidthPx = minNavBarWidthValue_.ConvertToPxWithSize(parentSize.Width().value_or(0.0f)); float maxNavBarWidthPx = maxNavBarWidthValue_.ConvertToPxWithSize(parentSize.Width().value_or(0.0f)); float minContentWidthPx = minContentWidthValue_.ConvertToPxWithSize(parentSize.Width().value_or(0.0f)); @@ -1908,12 +1911,12 @@ void NavigationPattern::HandleDragUpdate(float xOffset) } else { realNavBarWidth_ = minNavBarWidthPx; } + UpdateDividerToolBarManager(realDividerWidth_); } - realNavBarWidth_ = std::min(realNavBarWidth_, frameWidth); - realNavBarWidth_ = std::min(realNavBarWidth_, maxNavBarWidthPx); - realNavBarWidth_ = std::max(realNavBarWidth_, minNavBarWidthPx); - // MEASURE + realNavBarWidth_ = std::max(std::min(std::min(realNavBarWidth_, frameWidth), maxNavBarWidthPx), minNavBarWidthPx); + UpdateNavDestToolBarManager(frameWidth - realNavBarWidth_ - realDividerWidth_); if (realNavBarWidth_ != currentNavBarWidth) { + UpdateNavBarToolBarManager(true, realNavBarWidth_); host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD); } } @@ -4224,4 +4227,41 @@ void NavigationPattern::ClearPageAndNavigationConfig() } SetPageViewportConfig(nullptr); } + +void NavigationPattern::UpdateNavBarToolBarManager(bool isShow, float width) +{ + InitToolBarManager(); + auto info = toolbarManager_->GetNavBarInfo(); + if (width == info.width && isShow == info.isShow) { + return; + } + info.isShow = isShow; + info.width = width; + toolbarManager_->SetHasNavBar(true); + toolbarManager_->SetNavBarInfo(info); +} + +void NavigationPattern::UpdateNavDestToolBarManager(float width) +{ + InitToolBarManager(); + auto info = toolbarManager_->GetNavDestInfo(); + if (width == info.width) { + return; + } + info.isShow = true; + info.width = width; + toolbarManager_->SetHasNavDest(true); + toolbarManager_->SetNavDestInfo(info); +} + +void NavigationPattern::UpdateDividerToolBarManager(float dividerWidth) +{ + InitToolBarManager(); + auto info = toolbarManager_->GetNavBarDividerInfo(); + if (dividerWidth == info.width) { + return; + } + info.width = dividerWidth; + toolbarManager_->SetNavBarDividerInfo(info); +} } // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/pattern/navigation/navigation_pattern.h b/frameworks/core/components_ng/pattern/navigation/navigation_pattern.h index 0ffb5434628..b164350a5dc 100644 --- a/frameworks/core/components_ng/pattern/navigation/navigation_pattern.h +++ b/frameworks/core/components_ng/pattern/navigation/navigation_pattern.h @@ -608,6 +608,18 @@ private: RefPtr FindNavDestinationNodeInPreList(const uint64_t navDestinationId) const; bool IsStandardPage(const RefPtr& uiNode) const; void UpdateDividerBackgroundColor(); + void UpdateNavBarToolBarManager(bool isShow, float width); + void UpdateDividerToolBarManager(float dividerWidth); + void UpdateNavDestToolBarManager(float width); + + void InitToolBarManager() + { + if (!toolbarManager_) { + auto pipeline = GetHost()->GetContext(); + CHECK_NULL_VOID(pipeline); + toolbarManager_ = pipeline->GetToolbarManager(); + } + } void GetVisibleNodes(bool isPre, std::vector>& visibleNodes); void UpdatePageViewportConfigIfNeeded(const RefPtr& preTopDestination, @@ -638,6 +650,7 @@ private: RefPtr hoverEvent_; RefPtr panEvent_; RefPtr dragBarPanEvent_; + RefPtr toolbarManager_; std::vector> proxyList_; RectF dragRect_; RectF dragBarRect_; diff --git a/frameworks/core/components_ng/pattern/side_bar/side_bar_container_pattern.cpp b/frameworks/core/components_ng/pattern/side_bar/side_bar_container_pattern.cpp index f69b87d1ff7..108dda3b962 100644 --- a/frameworks/core/components_ng/pattern/side_bar/side_bar_container_pattern.cpp +++ b/frameworks/core/components_ng/pattern/side_bar/side_bar_container_pattern.cpp @@ -16,6 +16,7 @@ #include "core/components_ng/pattern/side_bar/side_bar_container_pattern.h" #include +#include "base/log/ace_trace.h" #if defined(OHOS_STANDARD_SYSTEM) and !defined(ACE_UNITTEST) #include "accessibility_element_info.h" @@ -424,6 +425,8 @@ void SideBarContainerPattern::OnModifyDone() if (!hasInit_) { hasInit_ = true; } + InitToolBarManager(); + toolbarManager_->OnSideBarModifyDone(); } void SideBarContainerPattern::CreateAndMountNodes() @@ -452,6 +455,7 @@ void SideBarContainerPattern::CreateAndMountNodes() auto sideBarTheme = context->GetTheme(); CHECK_NULL_VOID(sideBarTheme); Color bgColor = sideBarTheme->GetSideBarBackgroundColor(); + UpdateSideBarColorToolBarManager(bgColor); renderContext->UpdateBackgroundColor(bgColor); } if (SystemProperties::GetSideBarContainerBlurEnable() && @@ -963,9 +967,45 @@ bool SideBarContainerPattern::OnDirtyLayoutWrapperSwap( auto layoutProperty = GetLayoutProperty(); CHECK_NULL_RETURN(layoutProperty, false); const auto& paddingProperty = layoutProperty->GetPaddingProperty(); + + UpdateSideBarStatus(); + UpdateSideBarDividerToolBarManager(realDividerWidth_); + return paddingProperty != nullptr; } +void SideBarContainerPattern::UpdateSideBarStatus() +{ + auto host = GetHost(); + auto geometryNode = host->GetGeometryNode(); + CHECK_NULL_VOID(geometryNode); + auto layoutProperty = GetLayoutProperty(); + CHECK_NULL_VOID(layoutProperty); + auto frameSize = geometryNode->GetFrameSize(); + bool showSideBar = true; + switch (sideBarStatus_) { + case SideBarStatus::SHOW: { + showSideBar = true; + break; + } + case SideBarStatus::HIDDEN: { + showSideBar = false; + break; + } + case SideBarStatus::CHANGING: { + if (inAnimation_) { + showSideBar = !showSideBar_; + } + break; + } + default: { + showSideBar = layoutProperty->GetShowSideBar().value_or(true); + break; + } + } + UpdateSideBarToolBarManager(showSideBar, realSideBarWidth_.ConvertToPxWithSize(frameSize.Width())); +} + void SideBarContainerPattern::AddDividerHotZoneRect(const RefPtr& layoutAlgorithm) { CHECK_NULL_VOID(layoutAlgorithm); @@ -1118,6 +1158,10 @@ void SideBarContainerPattern::FireSideBarWidthChangeEvent() Dimension usrSetUnitWidth = DimensionUnit::PERCENT == userSetDimensionUnit ? ConvertPxToPercent(realSideBarWidthPx) : Dimension(realSideBarWidth_.GetNativeValue(userSetDimensionUnit), userSetDimensionUnit); + auto geometryNode = host->GetGeometryNode(); + CHECK_NULL_VOID(geometryNode); + auto frameSize = geometryNode->GetFrameSize(); + UpdateSideBarToolBarManager(true, usrSetUnitWidth.ConvertToPxWithSize(frameSize.Width())); eventHub->FireSideBarWidthChangeEvent(usrSetUnitWidth); } @@ -1426,4 +1470,38 @@ bool SideBarContainerPattern::OnThemeScopeUpdate(int32_t themeScopeId) imgFrameNode->MarkDirtyNode(); return false; } + +void SideBarContainerPattern::UpdateSideBarToolBarManager(bool isShow, float width) +{ + InitToolBarManager(); + auto info = toolbarManager_->GetSideBarInfo(); + if (info.isShow == isShow && info.width == width) { + return; + } + info.isShow = isShow; + info.width = width; + toolbarManager_->SetHasSideBar(true); + toolbarManager_->SetSideBarInfo(info); +} + +void SideBarContainerPattern::UpdateSideBarColorToolBarManager(const Color& backgroudColor) +{ + InitToolBarManager(); + auto color = toolbarManager_->GetSideBarColor(); + if (color == backgroudColor) { + return; + } + toolbarManager_->SetSideBarColor(backgroudColor); +} + +void SideBarContainerPattern::UpdateSideBarDividerToolBarManager(float dividerWidth) +{ + InitToolBarManager(); + auto info = toolbarManager_->GetSideBarDividerInfo(); + if (info.width == dividerWidth) { + return; + } + info.width = dividerWidth; + toolbarManager_->SetSideBarDividerInfo(info); +} } // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/pattern/side_bar/side_bar_container_pattern.h b/frameworks/core/components_ng/pattern/side_bar/side_bar_container_pattern.h index abdcc3b23fb..af0ac36e3e1 100644 --- a/frameworks/core/components_ng/pattern/side_bar/side_bar_container_pattern.h +++ b/frameworks/core/components_ng/pattern/side_bar/side_bar_container_pattern.h @@ -208,6 +208,19 @@ private: void SetAccessibilityEvent(); void InitImageErrorCallback(const RefPtr& sideBarTheme, const RefPtr& imgNode); void SetMouseStyle(MouseFormat format); + void UpdateSideBarToolBarManager(bool isShowDivider, float width); + void UpdateSideBarColorToolBarManager(const Color& backgroudColor); + void UpdateSideBarDividerToolBarManager(float dividerWidth); + void UpdateSideBarStatus(); + + void InitToolBarManager() + { + if (!toolbarManager_) { + auto pipeline = GetHost()->GetContext(); + CHECK_NULL_VOID(pipeline); + toolbarManager_ = pipeline->GetToolbarManager(); + } + } RefPtr hoverEvent_; RefPtr dividerMouseEvent_; @@ -218,6 +231,7 @@ private: RefPtr> rightToLeftAnimation_; RefPtr> leftToRightAnimation_; RefPtr dragEvent_; + RefPtr toolbarManager_; float currentOffset_ = 0.0f; float realDividerWidth_ = 0.0f; diff --git a/frameworks/core/components_ng/pattern/toolbaritem/toolbaritem_model.h b/frameworks/core/components_ng/pattern/toolbaritem/toolbaritem_model.h new file mode 100644 index 00000000000..3cbda00db4e --- /dev/null +++ b/frameworks/core/components_ng/pattern/toolbaritem/toolbaritem_model.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_TOOLBARITEM_TOOLBARITEM_MODEL_H +#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_TOOLBARITEM_TOOLBARITEM_MODEL_H + +#include + +#include "base/utils/macros.h" + +namespace OHOS::Ace { + +class ACE_FORCE_EXPORT ToolBarItemModel { +public: + static ToolBarItemModel* GetInstance(); + virtual ~ToolBarItemModel() = default; + + virtual void Create(int32_t value); + virtual void SetIsFirstCreate(bool value); + +private: + static std::unique_ptr instance_; + static std::mutex mutex_; +}; + +} // namespace OHOS::Ace + +#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_TOOLBARITEM_TOOLBARITEM_MODEL_H \ No newline at end of file diff --git a/frameworks/core/components_ng/pattern/toolbaritem/toolbaritem_model_ng.cpp b/frameworks/core/components_ng/pattern/toolbaritem/toolbaritem_model_ng.cpp new file mode 100644 index 00000000000..9df77ad00b1 --- /dev/null +++ b/frameworks/core/components_ng/pattern/toolbaritem/toolbaritem_model_ng.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "core/components_ng/pattern/toolbaritem/toolbaritem_model_ng.h" + +#include "core/components_ng/base/frame_node.h" +#include "core/components_ng/base/view_stack_processor.h" +#include "core/components_ng/pattern/linear_layout/linear_layout_pattern.h" +#include "core/components_ng/pattern/toolbaritem/toolbaritem_pattern.h" + +namespace OHOS::Ace::NG { + +void ToolBarItemModelNG::Create(int32_t value) +{ + auto* stack = ViewStackProcessor::GetInstance(); + + if (isFirstCreate) { + auto nodeId = stack->ClaimNodeId(); + toolbarNode = FrameNode::GetOrCreateFrameNode( + V2::TOOLBAR_ETS_TAG, nodeId, []() { return AceType::MakeRefPtr(false); }); + stack->Push(toolbarNode); + isFirstCreate = false; + } + + auto toolbaritemNode = FrameNode::GetOrCreateFrameNode(V2::TOOLBARITEM_ETS_TAG, + ElementRegister::GetInstance()->MakeUniqueId(), []() { return AceType::MakeRefPtr(); }); + toolbarNode->AddChild(toolbaritemNode); + stack->Push(toolbaritemNode); + + auto pattern = toolbaritemNode->GetPattern(); + CHECK_NULL_VOID(pattern); + pattern->SetPlacement(value); +} + +void ToolBarItemModelNG::SetIsFirstCreate(bool value) +{ + isFirstCreate = value; +} + +} // namespace OHOS::Ace::NG \ No newline at end of file diff --git a/frameworks/core/components_ng/pattern/toolbaritem/toolbaritem_model_ng.h b/frameworks/core/components_ng/pattern/toolbaritem/toolbaritem_model_ng.h new file mode 100644 index 00000000000..6c8b0cb3a74 --- /dev/null +++ b/frameworks/core/components_ng/pattern/toolbaritem/toolbaritem_model_ng.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_TOOLBARITEM_TOOLBARITEM_MODEL_NG_H +#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_TOOLBARITEM_TOOLBARITEM_MODEL_NG_H + +#include "core/components_ng/base/frame_node.h" +#include "core/components_ng/pattern/toolbaritem/toolbaritem_model.h" + +namespace OHOS::Ace::NG { + +class ACE_EXPORT ToolBarItemModelNG : public ToolBarItemModel { +public: + void Create(int32_t value) override; + void SetIsFirstCreate(bool value) override; + +private: + bool isFirstCreate = true; + RefPtr toolbarNode; +}; + +} // namespace OHOS::Ace::NG + +#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_TOOLBARITEM_TOOLBARITEM_MODEL_NG_H \ No newline at end of file diff --git a/frameworks/core/components_ng/pattern/toolbaritem/toolbaritem_pattern.h b/frameworks/core/components_ng/pattern/toolbaritem/toolbaritem_pattern.h new file mode 100644 index 00000000000..0b846b7eba8 --- /dev/null +++ b/frameworks/core/components_ng/pattern/toolbaritem/toolbaritem_pattern.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_TOOLBARITEM_TOOLBARITEM_PATTERN_H +#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_TOOLBARITEM_TOOLBARITEM_PATTERN_H + +#include "core/components_ng/pattern/pattern.h" + +namespace OHOS::Ace::NG { + +class ACE_EXPORT ToolBarItemPattern : public Pattern { + DECLARE_ACE_TYPE(ToolBarItemPattern, Pattern); + +public: + ToolBarItemPattern() = default; + ~ToolBarItemPattern() override = default; + + bool IsAtomicNode() const override + { + return false; + } + + void SetPlacement(int32_t placement) + { + placement_ = placement; + } + + int32_t GetPlacement() const + { + return placement_; + } + +private: + int32_t placement_ = 0; + ACE_DISALLOW_COPY_AND_MOVE(ToolBarItemPattern); +}; + +} // namespace OHOS::Ace::NG + +#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_TOOLBARITEM_TOOLBARITEM_PATTERN_H \ No newline at end of file diff --git a/frameworks/core/components_v2/inspector/inspector_constants.cpp b/frameworks/core/components_v2/inspector/inspector_constants.cpp index cb38dba221a..f4f3900f2b2 100644 --- a/frameworks/core/components_v2/inspector/inspector_constants.cpp +++ b/frameworks/core/components_v2/inspector/inspector_constants.cpp @@ -404,6 +404,12 @@ const char STEPPER_ETS_TAG[] = "Stepper"; const char STEPPER_ITEM_COMPONENT_TAG[] = "StepperItemComponentV2"; const char STEPPER_ITEM_ETS_TAG[] = "StepperItem"; +// toolbar +const char TOOLBAR_ETS_TAG[] = "Tool_Bar"; + +// toolbaritem +const char TOOLBARITEM_ETS_TAG[] = "ToolBarItem"; + // scrollbar const char SCROLL_BAR_COMPONENT_TAG[] = "ScrollBarComponent"; const char SCROLL_BAR_ETS_TAG[] = "ScrollBar"; diff --git a/frameworks/core/components_v2/inspector/inspector_constants.h b/frameworks/core/components_v2/inspector/inspector_constants.h index 24ff4d203df..e7e5de4efe9 100644 --- a/frameworks/core/components_v2/inspector/inspector_constants.h +++ b/frameworks/core/components_v2/inspector/inspector_constants.h @@ -412,6 +412,12 @@ ACE_EXPORT extern const char STEPPER_ETS_TAG[]; ACE_EXPORT extern const char STEPPER_ITEM_COMPONENT_TAG[]; ACE_EXPORT extern const char STEPPER_ITEM_ETS_TAG[]; +// toolbar +ACE_EXPORT extern const char TOOLBAR_ETS_TAG[]; + +// toolbaritem +ACE_EXPORT extern const char TOOLBARITEM_ETS_TAG[]; + // scrollBar ACE_EXPORT extern const char SCROLL_BAR_COMPONENT_TAG[]; ACE_EXPORT extern const char SCROLL_BAR_ETS_TAG[]; diff --git a/frameworks/core/pipeline_ng/pipeline_context.h b/frameworks/core/pipeline_ng/pipeline_context.h index 86350e6509f..5f650835db3 100644 --- a/frameworks/core/pipeline_ng/pipeline_context.h +++ b/frameworks/core/pipeline_ng/pipeline_context.h @@ -50,6 +50,7 @@ #include "core/components_ng/manager/safe_area/safe_area_manager.h" #include "core/components_ng/manager/select_overlay/select_overlay_manager.h" #include "core/components_ng/manager/shared_overlay/shared_overlay_manager.h" +#include "core/components_ng/manager/toolbar/toolbar_manager.h" #include "core/components_ng/pattern/custom/custom_node.h" #ifdef WINDOW_SCENE_SUPPORTED #include "core/components_ng/pattern/ui_extension/ui_extension_manager.h" @@ -929,6 +930,11 @@ public: return privacySensitiveManager_; } + const RefPtr& GetToolbarManager() const + { + return toolbarManager_; + } + void ChangeSensitiveNodes(bool flag) override { privacySensitiveManager_->TriggerFrameNodesSensitive(flag); @@ -1377,6 +1383,7 @@ private: RefPtr safeAreaManager_ = MakeRefPtr(); RefPtr frameRateManager_ = MakeRefPtr(); RefPtr privacySensitiveManager_ = MakeRefPtr(); + RefPtr toolbarManager_ = MakeRefPtr(); Rect displayAvailableRect_; WeakPtr dirtyFocusNode_; WeakPtr dirtyFocusScope_; diff --git a/test/unittest/BUILD.gn b/test/unittest/BUILD.gn index d2b5196ac47..b749dfc915e 100644 --- a/test/unittest/BUILD.gn +++ b/test/unittest/BUILD.gn @@ -384,6 +384,7 @@ ohos_source_set("ace_components_manager") { "$ace_root/frameworks/core/components_ng/manager/select_overlay/select_overlay_proxy.cpp", "$ace_root/frameworks/core/components_ng/manager/shared_overlay/shared_overlay_manager.cpp", "$ace_root/frameworks/core/components_ng/manager/shared_overlay/shared_transition_effect.cpp", + "$ace_root/frameworks/core/components_ng/manager/toolbar/toolbar_manager.cpp", ] deps = [ "$ace_root/frameworks/core/components/theme:build_theme_code" ] configs = [ ":ace_unittest_config" ] -- Gitee