1 /*
2 * Copyright (c) 2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "core/components_ng/pattern/container_modal/container_modal_toolbar.h"
16
17 #include "ui/base/ace_type.h"
18 #include "ui/base/referenced.h"
19 #include "ui/base/utils/utils.h"
20
21 #include "core/components/container_modal/container_modal_constants.h"
22 #include "core/components_ng/base/frame_node.h"
23 #include "core/components_ng/base/ui_node.h"
24 #include "core/components_ng/layout/layout_wrapper.h"
25 #include "core/components_ng/layout/layout_wrapper_node.h"
26 #include "core/components_ng/manager/toolbar/toolbar_manager.h"
27 #include "core/components_ng/pattern/container_modal/container_modal_pattern.h"
28 #include "core/components_ng/pattern/flex/flex_layout_styles.h"
29 #include "core/components_ng/pattern/linear_layout/linear_layout_pattern.h"
30 #include "core/components_ng/pattern/navigation/nav_bar_node.h"
31 #include "core/components_ng/pattern/navigation/nav_bar_pattern.h"
32 #include "core/components_ng/pattern/navigation/navigation_pattern.h"
33 #include "core/components_ng/pattern/navigation/navigation_title_util.h"
34 #include "core/components_ng/pattern/navrouter/navdestination_layout_algorithm.h"
35 #include "core/components_ng/pattern/navrouter/navdestination_layout_property.h"
36 #include "core/components_ng/pattern/navrouter/navdestination_pattern.h"
37 #include "core/components_ng/pattern/side_bar/side_bar_container_layout_algorithm.h"
38 #include "core/components_ng/pattern/side_bar/side_bar_container_pattern.h"
39 #include "core/components_ng/pattern/stack/stack_layout_property.h"
40 #include "core/components_ng/pattern/toolbaritem/toolbaritem_pattern.h"
41
42 namespace OHOS::Ace::NG {
43
44 namespace {
45 constexpr float TITLE_ITEM_HEIGT_S = 56.0; // 56vp height of title
46 constexpr float TITLE_ITEM_HEIGT_M = 64.0; // 64vp height of title
47 constexpr float TITLE_ITEM_HEIGT_L = 72.0; // 72vp height of title
48 constexpr float ROW_MARGIN = 4.0;
49 constexpr float ROW_TOTAL_MARGIN = 8.0;
50 constexpr uint32_t TITLE_MGR_CALLBACK_ID = 0;
51 constexpr uint32_t FLOATING_TITLE_MGR_CALLBACK_ID = 1;
52 } // namespace
53
InitToolBarManager()54 void ContainerModalToolBar::InitToolBarManager()
55 {
56 if (!toolbarManager_) {
57 auto toolbar = pattern_.Upgrade();
58 CHECK_NULL_VOID(toolbar);
59 auto pipeline = toolbar->GetContext();
60 CHECK_NULL_VOID(pipeline);
61 toolbarManager_ = pipeline->GetToolbarManager();
62 }
63 }
64
SetOnChangeCallback()65 void ContainerModalToolBar::SetOnChangeCallback()
66 {
67 CHECK_NULL_VOID(toolbarManager_);
68 if (!hasSetOnchangeCallback_) {
69 std::function<void()> func = [weak = WeakClaim(this)]() {
70 auto pattern = weak.Upgrade();
71 CHECK_NULL_VOID(pattern);
72 pattern->OnToolBarLayoutChange();
73 };
74 toolbarManager_->SetToolBarChangeCallback(std::move(func));
75 hasSetOnchangeCallback_ = true;
76 }
77 if (!isFloating_ && !hasSetUpdateSideTitleBgColor_) {
78 std::function<void(const Color&, const Color&, const BlurStyle&)> func =
79 [wk = WeakClaim(this)](
80 const Color& sideBarColor, const Color& sideBarContainerColor, const BlurStyle& sideBarBlurStyle) {
81 auto pattern = wk.Upgrade();
82 CHECK_NULL_VOID(pattern);
83 pattern->UpdateSideTitleBgColor(sideBarColor, sideBarContainerColor, sideBarBlurStyle);
84 };
85 toolbarManager_->SetSideBarColorChangeCallback(std::move(func));
86 hasSetUpdateSideTitleBgColor_ = true;
87 }
88 if (!hasSetNavigationModeChangeCallback_) {
89 std::function<void()> navigationModefunc = [weak = WeakClaim(this), toolbarMgr = toolbarManager_]() {
90 CHECK_NULL_VOID(toolbarMgr);
91 auto pattern = weak.Upgrade();
92 CHECK_NULL_VOID(pattern);
93 NavigationMode navigationMode = toolbarMgr->GetNavigationMode();
94 if (navigationMode != NavigationMode::SPLIT) {
95 pattern->RemoveAllToolbarItem();
96 }
97 };
98 toolbarManager_->SetNavigationModeChangeCallback(std::move(navigationModefunc));
99 hasSetNavigationModeChangeCallback_ = true;
100 }
101 }
102
SetToolbarBuilder(const RefPtr<FrameNode> & parent,std::function<RefPtr<UINode> ()> & builder)103 void ContainerModalToolBar::SetToolbarBuilder(const RefPtr<FrameNode>& parent, std::function<RefPtr<UINode>()>& builder)
104 {
105 CHECK_NULL_VOID(parent);
106 RemoveToolbarItem(parent);
107 UpdateTitleLayout();
108 CHECK_NULL_VOID(builder);
109 auto nodes = builder();
110 CHECK_NULL_VOID(nodes);
111 auto it = itemsWillOnTree_.find(parent);
112 if (it != itemsWillOnTree_.end()) {
113 it->second.clear();
114 }
115 auto children = nodes->GetChildren();
116 for (auto& item : children) {
117 itemsWillOnTree_[parent].push_back(item);
118 }
119 auto callback = [weak = WeakClaim(this), frame = WeakClaim(RawPtr(parent))]() {
120 auto toolbar = weak.Upgrade();
121 CHECK_NULL_VOID(toolbar);
122 auto frameNode = frame.Upgrade();
123 CHECK_NULL_VOID(frameNode);
124 toolbar->RemoveToolbarItem(frameNode);
125 toolbar->UpdateTitleLayout();
126 };
127 parent->SetRemoveToolbarItemCallback(
128 isFloating_ ? FLOATING_TITLE_MGR_CALLBACK_ID : TITLE_MGR_CALLBACK_ID, std::move(callback));
129 InitToolBarManager();
130 SetOnChangeCallback();
131 auto pattern = pattern_.Upgrade();
132 CHECK_NULL_VOID(pattern);
133 auto pipeline = pattern->GetContext();
134 CHECK_NULL_VOID(pipeline);
135 pipeline->AddAfterRenderTask([weak = WeakClaim(this)]() {
136 auto toolbar = weak.Upgrade();
137 CHECK_NULL_VOID(toolbar);
138 if (toolbar->GetNavOrSideBarNodes()) {
139 if (!(toolbar->HasNavOrSideBarNodes())) {
140 toolbar->SetHasNavOrSideBarNodes(true);
141 toolbar->ToInitNavOrSideBarNode();
142 }
143 } else {
144 return;
145 }
146 toolbar->ParsePlacementType();
147 });
148 }
149
ParsePlacementType()150 void ContainerModalToolBar::ParsePlacementType()
151 {
152 if (!GetNavOrSideBarNodes() || !HasNavOrSideBarNodes()) {
153 return;
154 }
155
156 bool hasItem = false;
157 for (auto it = itemsWillOnTree_.begin(); it != itemsWillOnTree_.end();) {
158 auto parent = it->first;
159 auto& list = it->second;
160 if (HandleToolbarItemList(parent, list)) {
161 it = itemsWillOnTree_.erase(it);
162 hasItem = true;
163 } else {
164 it++;
165 }
166 }
167 if (hasItem) {
168 AddToolbarItemToContainer();
169 OnToolBarLayoutChange();
170 }
171 }
172
GetItemTypeFromTag(const std::string & tag,uint32_t placement)173 ItemPlacementType ContainerModalToolBar::GetItemTypeFromTag(const std::string& tag, uint32_t placement)
174 {
175 if (tag == V2::SIDE_BAR_ETS_TAG) {
176 return placement ? ItemPlacementType::SIDE_BAR_END : ItemPlacementType::SIDE_BAR_START;
177 }
178 if (tag == V2::NAVBAR_ETS_TAG) {
179 return placement ? ItemPlacementType::NAV_BAR_END : ItemPlacementType::NAV_BAR_START;
180 }
181 if (tag == V2::NAVDESTINATION_VIEW_ETS_TAG) {
182 return placement ? ItemPlacementType::NAVDEST_END : ItemPlacementType::NAVDEST_START;
183 }
184 return ItemPlacementType::NONE;
185 }
186
HandleToolbarItemList(const RefPtr<FrameNode> & parentNode,std::list<RefPtr<UINode>> & list)187 bool ContainerModalToolBar::HandleToolbarItemList(const RefPtr<FrameNode>& parentNode, std::list<RefPtr<UINode>>& list)
188 {
189 CHECK_NULL_RETURN(parentNode, true);
190 std::string tag = GetTagFromNode(parentNode);
191 if (tag == "") {
192 return false;
193 }
194 for (auto& item : list) {
195 auto frameNode = AceType::DynamicCast<FrameNode>(item);
196 itemsOnTree_[parentNode].push_back(item);
197 auto pattern = frameNode->GetPattern<ToolBarItemPattern>();
198 int32_t placement = 0;
199 if (pattern) {
200 placement = pattern->GetPlacement();
201 auto id = GetItemTypeFromTag(tag, placement);
202 itemWillAdd_[id].emplace_back(frameNode);
203 }
204 }
205 return true;
206 }
207
UpdateTitleAfterRemove()208 void ContainerModalToolBar::UpdateTitleAfterRemove()
209 {
210 if (navbarRow_) {
211 navbarRow_->MarkDirtyNode(
212 PROPERTY_UPDATE_LAYOUT | PROPERTY_UPDATE_RENDER | PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD);
213 if (leftNavRow_) {
214 leftNavRow_->MarkDirtyNode(
215 PROPERTY_UPDATE_LAYOUT | PROPERTY_UPDATE_RENDER | PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD);
216 }
217 if (rightNavRow_) {
218 rightNavRow_->MarkDirtyNode(
219 PROPERTY_UPDATE_LAYOUT | PROPERTY_UPDATE_RENDER | PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD);
220 }
221 }
222 if (navDestbarRow_) {
223 navDestbarRow_->MarkDirtyNode(
224 PROPERTY_UPDATE_LAYOUT | PROPERTY_UPDATE_RENDER | PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD);
225 if (leftNavDestRow_) {
226 leftNavDestRow_->MarkDirtyNode(
227 PROPERTY_UPDATE_LAYOUT | PROPERTY_UPDATE_RENDER | PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD);
228 }
229 if (rightNavDestRow_) {
230 rightNavDestRow_->MarkDirtyNode(
231 PROPERTY_UPDATE_LAYOUT | PROPERTY_UPDATE_RENDER | PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD);
232 }
233 }
234 }
235
RemoveAllToolbarItem()236 void ContainerModalToolBar::RemoveAllToolbarItem()
237 {
238 for (auto& [_, list] : itemsOnTree_) {
239 for (auto& item : list) {
240 auto parent = item->GetParent();
241 if (parent) {
242 parent->RemoveChild(item);
243 parent->MarkNeedSyncRenderTree();
244 parent->RebuildRenderContextTree();
245 }
246 }
247 }
248 itemsOnTree_.clear();
249 UpdateTitleLayout();
250 }
251
RemoveToolbarItem(const RefPtr<FrameNode> & frameNode)252 void ContainerModalToolBar::RemoveToolbarItem(const RefPtr<FrameNode>& frameNode)
253 {
254 CHECK_NULL_VOID(frameNode);
255 auto& list = itemsOnTree_[frameNode];
256 for (auto& item : list) {
257 auto parent = item->GetParent();
258 if (parent) {
259 parent->RemoveChild(item);
260 parent->MarkNeedSyncRenderTree();
261 parent->RebuildRenderContextTree();
262 }
263 }
264 list.clear();
265 itemsOnTree_.erase(frameNode);
266 }
267
UpdateTitleLayout()268 void ContainerModalToolBar::UpdateTitleLayout()
269 {
270 auto pattern = pattern_.Upgrade();
271 CHECK_NULL_VOID(pattern);
272 UpdateTitleAfterRemove();
273 toolbarItemMaxHeight_ = 0.0f;
274 for (auto it = itemsOnTree_.begin(); it != itemsOnTree_.end(); it++) {
275 auto& list = it->second;
276 for (auto iit = list.begin(); iit != list.end(); iit++) {
277 auto toolbarNode = AceType::DynamicCast<FrameNode>(*iit);
278 CHECK_NULL_VOID(toolbarNode);
279 LayoutConstraintF Constraint;
280 toolbarNode->Measure(Constraint);
281 auto toolbarItemHeight = Dimension(toolbarNode->GetGeometryNode()->GetFrameSize().Height()).ConvertToVp();
282 if (GreatNotEqual(toolbarItemHeight, toolbarItemMaxHeight_)) {
283 toolbarItemMaxHeight_ = toolbarItemHeight;
284 }
285 }
286 }
287 if (!isTitleShow_ || customTitleShow_) {
288 RemoveToolbarRowContainers();
289 OnToolBarLayoutChange();
290 AdjustContainerModalTitleHeight();
291 }
292 }
293
AddToolbarItemToContainer()294 void ContainerModalToolBar::AddToolbarItemToContainer()
295 {
296 for (auto it = itemWillAdd_.begin(); it != itemWillAdd_.end(); it++) {
297 auto placementType = it->first;
298 if (placementType == ItemPlacementType::NONE) {
299 continue;
300 }
301 auto& list = it->second;
302 for (auto iit = list.begin(); iit != list.end();) {
303 if (AddToolbarItemToRow(placementType, *iit)) {
304 iit = list.erase(iit);
305 } else {
306 iit++;
307 }
308 }
309 }
310 }
311
AddToolbarItemToRow(ItemPlacementType placeMent,const RefPtr<FrameNode> & frameNode)312 bool ContainerModalToolBar::AddToolbarItemToRow(ItemPlacementType placeMent, const RefPtr<FrameNode>& frameNode)
313 {
314 if ((!toolbarManager_->HasNavBar() &&
315 (placeMent == ItemPlacementType::NAV_BAR_END || placeMent == ItemPlacementType::NAV_BAR_START)) ||
316 (!toolbarManager_->HasNavDest() &&
317 (placeMent == ItemPlacementType::NAVDEST_START || placeMent == ItemPlacementType::NAVDEST_END))) {
318 return false;
319 }
320
321 CHECK_NULL_RETURN(frameNode, false);
322 LayoutConstraintF Constraint;
323 frameNode->Measure(Constraint);
324 auto toolbarItemHeight = Dimension(frameNode->GetGeometryNode()->GetFrameSize().Height()).ConvertToVp();
325 if (GreatNotEqual(toolbarItemHeight, toolbarItemMaxHeight_)) {
326 toolbarItemMaxHeight_ = toolbarItemHeight;
327 }
328
329 return AddToolbarItemToSpecificRow(placeMent, frameNode);
330 }
331
AddToolbarItemToSpecificRow(ItemPlacementType placeMent,const RefPtr<FrameNode> & frameNode)332 bool ContainerModalToolBar::AddToolbarItemToSpecificRow(ItemPlacementType placeMent, const RefPtr<FrameNode>& frameNode)
333 {
334 bool ref = false;
335 switch (placeMent) {
336 case ItemPlacementType::NAV_BAR_START:
337 ref = AddToolbarItemToNavBarStart(frameNode);
338 break;
339 case ItemPlacementType::NAV_BAR_END:
340 ref = AddToolbarItemToNavBarEnd(frameNode);
341 break;
342 case ItemPlacementType::NAVDEST_START:
343 ref = AddToolbarItemToNavDestStart(frameNode);
344 break;
345 case ItemPlacementType::NAVDEST_END:
346 ref = AddToolbarItemToNavDestEnd(frameNode);
347 break;
348 default:
349 TAG_LOGE(AceLogTag::ACE_SUB_WINDOW, "Unknown placement");
350 return false;
351 }
352 auto containermodal = pattern_.Upgrade();
353 CHECK_NULL_RETURN(containermodal, ref);
354 containermodal->SetIsHaveToolBar(true);
355 if (!isTitleShow_ || customTitleShow_) {
356 auto pipeline = containermodal->GetContext();
357 CHECK_NULL_RETURN(pipeline, true);
358 auto overlayTask = [weak = WeakClaim(this)]() {
359 auto pattern = weak.Upgrade();
360 CHECK_NULL_VOID(pattern);
361 pattern->AdjustContainerModalTitleHeight();
362 };
363 pipeline->AddAfterRenderTask(overlayTask);
364 }
365 return ref;
366 }
367
AddToolbarItemToNavBarStart(const RefPtr<FrameNode> & frameNode)368 bool ContainerModalToolBar::AddToolbarItemToNavBarStart(const RefPtr<FrameNode>& frameNode)
369 {
370 if (!navbarRow_) {
371 AddNavBarRow();
372 }
373 if (navbarRow_) {
374 if (!leftNavRow_) {
375 AddLeftNavRow();
376 }
377 leftNavRow_->AddChild(frameNode);
378 leftNavRow_->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_PARENT);
379 return true;
380 }
381 return false;
382 }
383
AddToolbarItemToNavBarEnd(const RefPtr<FrameNode> & frameNode)384 bool ContainerModalToolBar::AddToolbarItemToNavBarEnd(const RefPtr<FrameNode>& frameNode)
385 {
386 if (!navbarRow_) {
387 AddNavBarRow();
388 }
389
390 if (navbarRow_) {
391 if (!rightNavRow_) {
392 AddLeftNavRow();
393 AddRightNavRow();
394 }
395 rightNavRow_->AddChild(frameNode);
396 rightNavRow_->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_PARENT);
397 return true;
398 }
399 return false;
400 }
401
AddToolbarItemToNavDestStart(const RefPtr<FrameNode> & frameNode)402 bool ContainerModalToolBar::AddToolbarItemToNavDestStart(const RefPtr<FrameNode>& frameNode)
403 {
404 if (!navDestbarRow_) {
405 AddNavDestBarRow();
406 }
407
408 if (navDestbarRow_) {
409 if (!leftNavDestRow_) {
410 AddLeftNavDestRow();
411 }
412 leftNavDestRow_->AddChild(frameNode);
413 leftNavDestRow_->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_PARENT);
414 return true;
415 }
416 return false;
417 }
418
AddToolbarItemToNavDestEnd(const RefPtr<FrameNode> & frameNode)419 bool ContainerModalToolBar::AddToolbarItemToNavDestEnd(const RefPtr<FrameNode>& frameNode)
420 {
421 if (!navDestbarRow_) {
422 AddNavDestBarRow();
423 }
424
425 if (navDestbarRow_) {
426 if (!rightNavDestRow_) {
427 AddLeftNavDestRow();
428 AddRightNavDestRow();
429 }
430 rightNavDestRow_->AddChild(frameNode);
431 rightNavDestRow_->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_PARENT);
432 return true;
433 }
434 return false;
435 }
436
AddNavBarRow()437 void ContainerModalToolBar::AddNavBarRow()
438 {
439 CHECK_NULL_VOID(title_);
440 auto navBarInfo = toolbarManager_->GetNavBarInfo();
441 if (navBarInfo.isShow) {
442 if (!navbarRow_) {
443 navbarRow_ = FrameNode::CreateFrameNode(V2::ROW_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
444 MakeRefPtr<LinearLayoutPattern>(false));
445 navbarRow_->UpdateInspectorId("NavBar");
446 auto layout = navbarRow_->GetLayoutProperty<LinearLayoutProperty>();
447 CHECK_NULL_VOID(layout);
448 layout->UpdateMainAxisAlign(FlexAlign::SPACE_BETWEEN);
449 layout->UpdateCrossAxisAlign(FlexAlign::CENTER);
450 auto renderContext = navbarRow_->GetRenderContext();
451 CHECK_NULL_VOID(renderContext);
452 renderContext->SetClipToFrame(true);
453 title_->AddChild(navbarRow_, 1);
454 navbarRow_->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_PARENT);
455 }
456 }
457 title_->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD);
458 }
459
AddLeftNavRow()460 void ContainerModalToolBar::AddLeftNavRow()
461 {
462 if (navbarRow_) {
463 if (!leftNavRow_) {
464 leftNavRow_ = FrameNode::CreateFrameNode(V2::ROW_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
465 MakeRefPtr<LinearLayoutPattern>(false));
466 leftNavRow_->UpdateInspectorId("LeftNavRow");
467 auto layout = leftNavRow_->GetLayoutProperty<LinearLayoutProperty>();
468 CHECK_NULL_VOID(layout);
469 MarginProperty margin;
470 margin.SetEdges(CalcLength(Dimension(ROW_MARGIN, DimensionUnit::VP)));
471 layout->UpdateMargin(margin);
472 navbarRow_->AddChild(leftNavRow_, 0);
473 leftNavRow_->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_PARENT);
474 }
475 navbarRow_->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_PARENT);
476 title_->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_PARENT);
477 }
478 AdjustNavbarRowWidth();
479 }
480
AddRightNavRow()481 void ContainerModalToolBar::AddRightNavRow()
482 {
483 if (navbarRow_) {
484 if (!rightNavRow_) {
485 rightNavRow_ = FrameNode::CreateFrameNode(V2::ROW_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
486 MakeRefPtr<LinearLayoutPattern>(false));
487 rightNavRow_->UpdateInspectorId("RightNavRow");
488 navbarRow_->AddChild(rightNavRow_);
489 auto layout = rightNavRow_->GetLayoutProperty<LinearLayoutProperty>();
490 CHECK_NULL_VOID(layout);
491 MarginProperty margin;
492 margin.SetEdges(CalcLength(Dimension(ROW_MARGIN, DimensionUnit::VP)));
493 layout->UpdateMargin(margin);
494 layout->UpdateMainAxisAlign(FlexAlign::FLEX_END);
495 rightNavRow_->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_PARENT);
496 }
497 navbarRow_->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_PARENT);
498 title_->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_PARENT);
499 }
500 AdjustNavbarRowWidth();
501 }
502
AddNavDestBarRow()503 void ContainerModalToolBar::AddNavDestBarRow()
504 {
505 auto navDestInfo = toolbarManager_->GetNavDestInfo();
506 if (navDestInfo.isShow) {
507 if (!navDestbarRow_) {
508 navDestbarRow_ = FrameNode::CreateFrameNode(V2::ROW_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
509 MakeRefPtr<LinearLayoutPattern>(false));
510 navDestbarRow_->UpdateInspectorId("NavDestBar");
511 auto layout = navDestbarRow_->GetLayoutProperty<LinearLayoutProperty>();
512 CHECK_NULL_VOID(layout);
513 layout->UpdateMainAxisAlign(FlexAlign::SPACE_BETWEEN);
514 layout->UpdateCrossAxisAlign(FlexAlign::CENTER);
515 auto renderContext = navDestbarRow_->GetRenderContext();
516 CHECK_NULL_VOID(renderContext);
517 renderContext->SetClipToFrame(true);
518 title_->AddChild(navDestbarRow_);
519 navDestbarRow_->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_PARENT);
520 }
521 }
522 title_->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD);
523 }
524
AddLeftNavDestRow()525 void ContainerModalToolBar::AddLeftNavDestRow()
526 {
527 if (navDestbarRow_) {
528 if (!leftNavDestRow_) {
529 leftNavDestRow_ = FrameNode::CreateFrameNode(V2::ROW_ETS_TAG,
530 ElementRegister::GetInstance()->MakeUniqueId(), MakeRefPtr<LinearLayoutPattern>(false));
531 leftNavDestRow_->UpdateInspectorId("LeftNavDest");
532 auto layout = leftNavDestRow_->GetLayoutProperty<LinearLayoutProperty>();
533 CHECK_NULL_VOID(layout);
534 MarginProperty margin;
535 margin.SetEdges(CalcLength(Dimension(ROW_MARGIN, DimensionUnit::VP)));
536 layout->UpdateMargin(margin);
537 navDestbarRow_->AddChild(leftNavDestRow_, 0);
538 leftNavDestRow_->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_PARENT);
539 }
540 navDestbarRow_->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_PARENT);
541 title_->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_PARENT);
542 }
543 AdjustNavDestRowWidth();
544 }
545
AddRightNavDestRow()546 void ContainerModalToolBar::AddRightNavDestRow()
547 {
548 if (navDestbarRow_) {
549 if (!rightNavDestRow_) {
550 rightNavDestRow_ = FrameNode::CreateFrameNode(V2::ROW_ETS_TAG,
551 ElementRegister::GetInstance()->MakeUniqueId(), MakeRefPtr<LinearLayoutPattern>(false));
552 rightNavDestRow_->UpdateInspectorId("RightNavDest");
553 navDestbarRow_->AddChild(rightNavDestRow_);
554 auto layout = rightNavDestRow_->GetLayoutProperty<LinearLayoutProperty>();
555 CHECK_NULL_VOID(layout);
556 MarginProperty margin;
557 margin.SetEdges(CalcLength(Dimension(ROW_MARGIN, DimensionUnit::VP)));
558 layout->UpdateMargin(margin);
559 layout->UpdateMainAxisAlign(FlexAlign::FLEX_END);
560 rightNavDestRow_->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_PARENT);
561 }
562 navDestbarRow_->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_PARENT);
563 title_->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_PARENT);
564 }
565 AdjustNavDestRowWidth();
566 }
567
RemoveToolbarRowContainers()568 void ContainerModalToolBar::RemoveToolbarRowContainers()
569 {
570 auto RemoveIfEmpty = [this](RefPtr<FrameNode>& container, const RefPtr<FrameNode>& parent) {
571 if (container && container->GetChildren().empty()) {
572 if (parent) {
573 parent->RemoveChild(container);
574 parent->MarkDirtyNode(
575 PROPERTY_UPDATE_LAYOUT | PROPERTY_UPDATE_RENDER | PROPERTY_UPDATE_MEASURE_SELF_AND_PARENT);
576 }
577 container = nullptr;
578 }
579 };
580 RemoveIfEmpty(rightNavRow_, navbarRow_);
581 RemoveIfEmpty(rightNavDestRow_, navDestbarRow_);
582 if (!rightNavRow_ && navbarRow_) {
583 RemoveIfEmpty(leftNavRow_, navbarRow_);
584 }
585 if (!rightNavDestRow_ && navDestbarRow_) {
586 RemoveIfEmpty(leftNavDestRow_, navDestbarRow_);
587 }
588 RemoveIfEmpty(navbarRow_, title_);
589 RemoveIfEmpty(navDestbarRow_, title_);
590 if (title_) {
591 title_->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD);
592 }
593 if (!navbarRow_ && !navDestbarRow_) {
594 auto containermodal = pattern_.Upgrade();
595 CHECK_NULL_VOID(containermodal);
596 containermodal->SetIsHaveToolBar(false);
597 }
598 }
599
OnToolBarLayoutChange()600 void ContainerModalToolBar::OnToolBarLayoutChange()
601 {
602 if (!toolbarManager_ || !HasNavOrSideBarNodes()) {
603 return;
604 }
605
606 auto pattern = pattern_.Upgrade();
607 CHECK_NULL_VOID(pattern);
608 auto pipeline = pattern->GetContext();
609 CHECK_NULL_VOID(pipeline);
610 pipeline->AddAfterRenderTask([weak = WeakClaim(this), toolbarMgr = toolbarManager_]() {
611 auto toolbar = weak.Upgrade();
612 CHECK_NULL_VOID(toolbar);
613 toolbar->AdjustTitleNodeWidth();
614 CHECK_NULL_VOID(toolbarMgr);
615 if (toolbarMgr->GetNavBarInfo().isShow) {
616 toolbar->AdjustNavbarRowWidth();
617 }
618 if (toolbarMgr->GetNavDestInfo().isShow) {
619 toolbar->AdjustNavDestRowWidth();
620 }
621 });
622 }
623
AdjustTitleNodeWidth()624 void ContainerModalToolBar::AdjustTitleNodeWidth()
625 {
626 auto sideBarInfo = toolbarManager_->GetSideBarInfo();
627 float titleNodeWidth = sideBarInfo.isShow ? sideBarInfo.width : 0;
628
629 auto titleNode = AceType::DynamicCast<FrameNode>(title_->GetChildren().front());
630 CHECK_NULL_VOID(titleNode);
631 auto titleNodeProperty = titleNode->GetLayoutProperty<LayoutProperty>();
632 CHECK_NULL_VOID(titleNodeProperty);
633 titleNodeProperty->UpdateMeasureType(MeasureType::MATCH_PARENT);
634
635 if (itemsOnTree_.empty()) {
636 titleNodeProperty->UpdateUserDefinedIdealSize(
637 CalcSize(CalcLength(1.0, DimensionUnit::PERCENT), CalcLength(1.0, DimensionUnit::PERCENT)));
638 titleNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_PARENT);
639 return;
640 }
641
642 auto renderContext = titleNode->GetRenderContext();
643 CHECK_NULL_VOID(renderContext);
644 renderContext->SetClipToFrame(true);
645 titleNodeProperty->UpdateUserDefinedIdealSize(
646 CalcSize(CalcLength(titleNodeWidth), CalcLength(1.0, DimensionUnit::PERCENT)));
647 titleNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_PARENT);
648 }
649
AdjustNavbarRowWidth()650 void ContainerModalToolBar::AdjustNavbarRowWidth()
651 {
652 auto pattern = pattern_.Upgrade();
653 CHECK_NULL_VOID(pattern);
654
655 auto sideBarInfo = toolbarManager_->GetSideBarInfo();
656 auto sideBarDividerInfo = toolbarManager_->GetSideBarDividerInfo();
657 auto navbarInfo = toolbarManager_->GetNavBarInfo();
658 auto navbarDividerInfo = toolbarManager_->GetNavBarDividerInfo();
659 auto navDestInfo = toolbarManager_->GetNavDestInfo();
660 auto controlButtonsWidth = pattern->GetControlButtonRowWidth();
661 float navbarRowWidth = 0.0f;
662
663 if (navbarInfo.isShow && navbarRow_) {
664 auto navbarRowProperty = navbarRow_->GetLayoutProperty<LinearLayoutProperty>();
665 CHECK_NULL_VOID(navbarRowProperty);
666 if (navDestInfo.isShow && LessOrEqual(navDestInfo.width, controlButtonsWidth.GetDimension().ConvertToPx())) {
667 navbarRowWidth = navDestInfo.width + navbarInfo.width - controlButtonsWidth.GetDimension().ConvertToPx();
668 } else {
669 navbarRowWidth = navbarInfo.width;
670 }
671 navbarRowProperty->UpdateUserDefinedIdealSize(CalcSize(CalcLength(navbarRowWidth), std::nullopt));
672 auto isRtl = AceApplicationInfo::GetInstance().IsRightToLeft();
673 MarginProperty navbarRowMargin;
674 if (isRtl) {
675 if (navDestInfo.isShow &&
676 LessOrEqual(navDestInfo.width, controlButtonsWidth.GetDimension().ConvertToPx())) {
677 navbarRowMargin.left = CalcLength(controlButtonsWidth.GetDimension().ConvertToPx());
678 navbarRowMargin.right = sideBarInfo.isShow ? CalcLength(sideBarDividerInfo.width) : CalcLength(0);
679 } else {
680 navbarRowMargin.left = CalcLength(navbarDividerInfo.width);
681 navbarRowMargin.right = sideBarInfo.isShow ? CalcLength(sideBarDividerInfo.width) : CalcLength(0);
682 }
683 } else {
684 if (navDestInfo.isShow &&
685 LessOrEqual(navDestInfo.width, controlButtonsWidth.GetDimension().ConvertToPx())) {
686 navbarRowMargin.left = sideBarInfo.isShow ? CalcLength(sideBarDividerInfo.width) : CalcLength(0);
687 navbarRowMargin.right = CalcLength(controlButtonsWidth.GetDimension().ConvertToPx());
688 } else {
689 navbarRowMargin.left = sideBarInfo.isShow ? CalcLength(sideBarDividerInfo.width) : CalcLength(0);
690 navbarRowMargin.right = CalcLength(navbarDividerInfo.width);
691 }
692 }
693 navbarRowProperty->UpdateMargin(navbarRowMargin);
694 navbarRow_->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD);
695 navbarRowProperty->UpdateVisibility(
696 NearEqual(navbarInfo.width, 0.0f) ? VisibleType::INVISIBLE : VisibleType::VISIBLE);
697 }
698 }
699
AdjustNavDestRowWidth()700 void ContainerModalToolBar::AdjustNavDestRowWidth()
701 {
702 auto pattern = pattern_.Upgrade();
703 CHECK_NULL_VOID(pattern);
704
705 CHECK_NULL_VOID(toolbarManager_);
706 auto sideBarInfo = toolbarManager_->GetSideBarInfo();
707 auto sideBarDividerInfo = toolbarManager_->GetSideBarDividerInfo();
708 auto navbarInfo = toolbarManager_->GetNavBarInfo();
709 auto navbarDividerInfo = toolbarManager_->GetNavBarDividerInfo();
710 auto navDestInfo = toolbarManager_->GetNavDestInfo();
711 auto controlButtonsWidth = pattern->GetControlButtonRowWidth();
712
713 if (navDestInfo.isShow && navDestbarRow_) {
714 float navDestbarRowAvailableWidth = navDestInfo.width - controlButtonsWidth.GetDimension().ConvertToPx();
715 auto navDestbarRowProperty = navDestbarRow_->GetLayoutProperty<LinearLayoutProperty>();
716 CHECK_NULL_VOID(navDestbarRowProperty);
717 navDestbarRowProperty->UpdateUserDefinedIdealSize(
718 CalcSize(CalcLength(navDestbarRowAvailableWidth), std::nullopt));
719 float navDestbarRowLeftMargin = 0.0f;
720 if (navbarRow_) {
721 navDestbarRowLeftMargin = navbarDividerInfo.width;
722 } else if (!sideBarInfo.isShow && !navbarInfo.isShow) {
723 navDestbarRowLeftMargin = 0.0f;
724 } else if (!sideBarInfo.isShow) {
725 navDestbarRowLeftMargin = navbarInfo.width + navbarDividerInfo.width;
726 } else if (!navbarInfo.isShow) {
727 navDestbarRowLeftMargin = sideBarDividerInfo.width;
728 } else {
729 navDestbarRowLeftMargin = sideBarDividerInfo.width + navbarInfo.width + navbarDividerInfo.width;
730 }
731 auto isRtl = AceApplicationInfo::GetInstance().IsRightToLeft();
732 MarginProperty navDestbarRowMargin;
733 if (isRtl) {
734 navDestbarRowMargin.left = CalcLength(controlButtonsWidth.GetDimension().ConvertToPx());
735 navDestbarRowMargin.right = CalcLength(navDestbarRowLeftMargin);
736 } else {
737 navDestbarRowMargin.left = CalcLength(navDestbarRowLeftMargin);
738 navDestbarRowMargin.right = CalcLength(controlButtonsWidth.GetDimension().ConvertToPx());
739 }
740 navDestbarRowProperty->UpdateMargin(navDestbarRowMargin);
741 navDestbarRow_->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD);
742 navDestbarRowProperty->UpdateVisibility(
743 NearEqual(navDestInfo.width, 0.0f) ? VisibleType::INVISIBLE : VisibleType::VISIBLE);
744 }
745 }
746
UpdateToolbarShow(bool isTitleShow,bool customTitleSettedShow)747 void ContainerModalToolBar::UpdateToolbarShow(bool isTitleShow, bool customTitleSettedShow)
748 {
749 auto pattern = pattern_.Upgrade();
750 CHECK_NULL_VOID(pattern);
751 isTitleShow_ = isTitleShow;
752 customTitleShow_ = customTitleSettedShow;
753
754 if (!isTitleShow || customTitleSettedShow) {
755 UpdateTitleLayout();
756 } else if (!customTitleSettedShow) {
757 pattern->SetControlButtonsRowHeight(CONTAINER_TITLE_HEIGHT);
758 }
759 }
760
AdjustContainerModalTitleHeight()761 void ContainerModalToolBar::AdjustContainerModalTitleHeight()
762 {
763 auto pattern = pattern_.Upgrade();
764 CHECK_NULL_VOID(pattern);
765
766 if (itemsOnTree_.empty()) {
767 pattern->titleHeight_ = CONTAINER_TITLE_HEIGHT;
768 pattern->SetContainerModalTitleHeight(CONTAINER_TITLE_HEIGHT.ConvertToPx());
769 ResetExpandStackNode();
770 return;
771 }
772
773 auto rowHeight = toolbarItemMaxHeight_ + ROW_TOTAL_MARGIN;
774 if (NearEqual(toolbarItemMaxHeight_, 0.0f)) {
775 pattern->titleHeight_ = CONTAINER_TITLE_HEIGHT;
776 } else if (LessOrEqual(rowHeight, TITLE_ITEM_HEIGT_S)) {
777 pattern->titleHeight_ = Dimension(TITLE_ITEM_HEIGT_S, DimensionUnit::VP);
778 } else if (GreatNotEqual(rowHeight, TITLE_ITEM_HEIGT_S) && LessOrEqual(rowHeight, TITLE_ITEM_HEIGT_M)) {
779 pattern->titleHeight_ = Dimension(TITLE_ITEM_HEIGT_M, DimensionUnit::VP);
780 } else if (GreatNotEqual(rowHeight, TITLE_ITEM_HEIGT_M)) {
781 pattern->titleHeight_ = Dimension(TITLE_ITEM_HEIGT_L, DimensionUnit::VP);
782 }
783 pattern->SetContainerModalTitleHeight(pattern->titleHeight_.ConvertToPx());
784 UpdateTargetNodesBarMargin();
785 }
786
GetTagFromNode(RefPtr<UINode> node)787 std::string ContainerModalToolBar::GetTagFromNode(RefPtr<UINode> node)
788 {
789 std::string tag = "";
790 CHECK_NULL_RETURN(node, tag);
791 auto navigationNode = navigationNode_.Upgrade();
792 while (node && node->GetTag() != V2::ROOT_ETS_TAG) {
793 if (node->GetTag() == V2::NAVBAR_ETS_TAG && navigationNode && navigationNode == node->GetParent()) {
794 tag = node->GetTag();
795 break;
796 }
797 if (node->GetTag() == V2::NAVDESTINATION_VIEW_ETS_TAG) {
798 if (node == navDestNode_) {
799 tag = node->GetTag();
800 break;
801 }
802 auto navDestContentNode = node->GetParent();
803 if (navDestContentNode && navigationNode && navigationNode == navDestContentNode->GetParent()) {
804 tag = node->GetTag();
805 break;
806 }
807 }
808 node = node->GetParent();
809 }
810 return tag;
811 }
812
813 /**
814 * @brief This method traverses the node hierarchy to identify and set specific target nodes
815 * (SideBar, Navigation, and Navigation Destination nodes) based on their tags and geometry.
816 *
817 * @return Returns true if any of the target nodes (SideBar, Navigation, or Navigation Destination)
818 * are found and set; otherwise, returns false.
819 *
820 * @details The method performs the following steps:
821 * - Retrieves the root content node and its geometry content.
822 * - Initializes a queue for breadth-first traversal of the node hierarchy.
823 * - Iterates through the child nodes to find nodes with specific tags:
824 * - SIDE_BAR_ETS_TAG: Identifies the SideBar node if its width matches the root content width.
825 * - NAVBAR_ETS_TAG: If the SideBar node has not be finded, identifies the Navigation node if its width matches
826 * the root content width, else identifies the Navigation node direct
827 * - NAVDESTINATION_VIEW_ETS_TAG: Identifies the Navigation Destination node.
828 * - Stops traversal once all required nodes are found or the hierarchy is fully traversed.
829 *
830 * @note The method uses a queue to perform breadth-first traversal and ensures that
831 * the search stops as soon as the required nodes are identified.
832 */
GetNavOrSideBarNodes()833 bool ContainerModalToolBar::GetNavOrSideBarNodes()
834 {
835 auto pattern = pattern_.Upgrade();
836 CHECK_NULL_RETURN(pattern, false);
837 auto contentNode = pattern->GetContentNode();
838 CHECK_NULL_RETURN(contentNode, false);
839 auto stage = contentNode->GetFirstChild();
840 CHECK_NULL_RETURN(stage, false);
841 auto page = stage->GetFirstChild();
842 CHECK_NULL_RETURN(page, false);
843 auto custom = page->GetFirstChild();
844 CHECK_NULL_RETURN(custom, false);
845 auto customNode = AceType::DynamicCast<FrameNode>(custom);
846 CHECK_NULL_RETURN(customNode, false);
847 auto customGeometryNode = customNode->GetGeometryNode();
848 CHECK_NULL_RETURN(customGeometryNode, false);
849 auto pageWidth = customGeometryNode->GetFrameSize().Width();
850 return GetNavOrSideBarNodesParseChildren(page, pageWidth);
851 }
852
GetNavOrSideBarNodesParseChildren(const RefPtr<UINode> & page,float pageWidth)853 bool ContainerModalToolBar::GetNavOrSideBarNodesParseChildren(const RefPtr<UINode>& page, float pageWidth)
854 {
855 std::queue<RefPtr<UINode>> queue {};
856 bool isSideBarFound = false;
857 bool isNavigationFound = false;
858 bool isNavDestFound = false;
859 queue.emplace(page);
860 RefPtr<UINode> parentNode;
861 float sideBarHeight = 0.0f;
862 while (!queue.empty()) {
863 parentNode = queue.front();
864 queue.pop();
865 auto children = parentNode->GetChildren();
866 if (children.empty()) {
867 continue;
868 }
869 for (auto child : children) {
870 queue.emplace(child);
871 auto childFrameNode = AceType::DynamicCast<FrameNode>(child);
872 CHECK_NULL_CONTINUE(childFrameNode)
873 if (IsTragetSideBarNodeParse(childFrameNode, pageWidth, sideBarHeight, isSideBarFound)) {
874 std::queue<RefPtr<UINode>>().swap(queue);
875 queue.emplace(child);
876 isSideBarFound = true;
877 break;
878 } else if (IsTragetNavigationNodeParse(
879 childFrameNode, pageWidth, sideBarHeight, isNavigationFound, isSideBarFound)) {
880 std::queue<RefPtr<UINode>>().swap(queue);
881 queue.emplace(child);
882 isSideBarFound = true;
883 isNavigationFound = true;
884 break;
885 } else if ((isNavigationFound && isSideBarFound) || (isNavigationFound &&
886 childFrameNode->GetTag() == V2::NAVDESTINATION_VIEW_ETS_TAG)) {
887 isSideBarFound = true;
888 isNavigationFound = true;
889 isNavDestFound = true;
890 navDestNode_ = childFrameNode;
891 }
892 if ((isNavigationFound && isSideBarFound) || (isNavigationFound && isNavDestFound)) {
893 break;
894 }
895 }
896 if ((isNavigationFound && isSideBarFound) || (isNavigationFound && isNavDestFound)) {
897 break;
898 }
899 }
900 if ((isNavigationFound && isSideBarFound) || (isNavigationFound && isNavDestFound)) {
901 return true;
902 }
903 return false;
904 }
905
IsTragetSideBarNodeParse(const RefPtr<FrameNode> & childFrameNode,float pageWidth,float & sideBarHeight,bool isSideBarFound)906 bool ContainerModalToolBar::IsTragetSideBarNodeParse(
907 const RefPtr<FrameNode>& childFrameNode, float pageWidth, float& sideBarHeight, bool isSideBarFound)
908 {
909 CHECK_NULL_RETURN(childFrameNode, false);
910 if (!isSideBarFound && childFrameNode->GetTag() == V2::SIDE_BAR_ETS_TAG) {
911 auto geometryNode = childFrameNode->GetGeometryNode();
912 CHECK_NULL_RETURN(geometryNode, false);
913 auto childWidth = geometryNode->GetFrameSize().Width();
914 if (NearEqual(pageWidth, childWidth)) {
915 sideBarHeight = geometryNode->GetFrameSize().Height();
916 sideBarNode_ = childFrameNode;
917 return true;
918 }
919 }
920 return false;
921 }
922
IsTragetNavigationNodeParse(const RefPtr<FrameNode> & childFrameNode,float pageWidth,float sideBarHeight,bool isNavigationFound,bool isSideBarFound)923 bool ContainerModalToolBar::IsTragetNavigationNodeParse(const RefPtr<FrameNode>& childFrameNode, float pageWidth,
924 float sideBarHeight, bool isNavigationFound, bool isSideBarFound)
925 {
926 CHECK_NULL_RETURN(childFrameNode, false);
927 CHECK_NULL_RETURN(toolbarManager_, false);
928
929 if (!isNavigationFound && childFrameNode->GetTag() == V2::NAVIGATION_VIEW_ETS_TAG) {
930 auto navigationPattern = childFrameNode->GetPattern<NavigationPattern>();
931 CHECK_NULL_RETURN(navigationPattern, false);
932 NavigationMode navigationMode = navigationPattern->GetNavigationMode();
933 if (!isSideBarFound) {
934 auto geometryNode = childFrameNode->GetGeometryNode();
935 CHECK_NULL_RETURN(geometryNode, false);
936 auto childWidth = geometryNode->GetFrameSize().Width();
937 if (NearEqual(pageWidth, childWidth) && navigationMode == NavigationMode::SPLIT) {
938 navigationNode_ = childFrameNode;
939 return true;
940 }
941 } else {
942 auto geometryNode = childFrameNode->GetGeometryNode();
943 CHECK_NULL_RETURN(geometryNode, false);
944 auto childHeight = geometryNode->GetFrameSize().Height();
945 if ((NearEqual(sideBarHeight, childHeight) || NearEqual(sideBarHeight, 0.0f)) &&
946 navigationMode == NavigationMode::SPLIT) {
947 navigationNode_ = childFrameNode;
948 return true;
949 }
950 }
951 }
952 return false;
953 }
954
ToInitNavOrSideBarNode()955 void ContainerModalToolBar::ToInitNavOrSideBarNode()
956 {
957 auto sideBarNode = sideBarNode_.Upgrade();
958 if (sideBarNode) {
959 auto sideBarPattern = AceType::DynamicCast<NG::SideBarContainerPattern>(sideBarNode->GetPattern());
960 if (sideBarPattern) {
961 sideBarPattern->InitToolBarManager();
962 sideBarNode->MarkModifyDone();
963 }
964 }
965 auto navigationNode = navigationNode_.Upgrade();
966 if (navigationNode) {
967 auto navigationPattern = AceType::DynamicCast<NG::NavigationPattern>(navigationNode->GetPattern());
968 if (navigationPattern) {
969 navigationPattern->InitToolBarManager();
970 navigationNode->MarkModifyDone();
971 }
972 }
973 CHECK_NULL_VOID(toolbarManager_);
974 std::function<void()> getTypeOfItem = [weak = WeakClaim(this)]() {
975 auto pattern = weak.Upgrade();
976 CHECK_NULL_VOID(pattern);
977 pattern->ParsePlacementType();
978 };
979 toolbarManager_->SetModifyDoneCallback(std::move(getTypeOfItem));
980 }
981
UpdateSideTitleBgColor(const Color & sideBarColor,const Color & sideBarContainerColor,const BlurStyle & blurStyle)982 void ContainerModalToolBar::UpdateSideTitleBgColor(
983 const Color& sideBarColor, const Color& sideBarContainerColor, const BlurStyle& blurStyle)
984 {
985 CHECK_NULL_VOID(title_);
986 auto titleNode = AceType::DynamicCast<FrameNode>(title_->GetChildren().front());
987 CHECK_NULL_VOID(titleNode);
988 auto ctx = titleNode->GetRenderContext();
989 CHECK_NULL_VOID(ctx);
990 Color color = sideBarContainerColor.BlendColorWithAlpha(sideBarColor);
991 ctx->UpdateBackgroundColor(color);
992 BlurStyleOption option;
993 option.blurStyle = blurStyle;
994 ctx->UpdateBackBlurStyle(option);
995 }
996
SetCustomTitleRowBlurStyle(BlurStyle & blurStyle)997 void ContainerModalToolBar::SetCustomTitleRowBlurStyle(BlurStyle& blurStyle)
998 {
999 auto pattern = pattern_.Upgrade();
1000 CHECK_NULL_VOID(pattern);
1001 auto customTitleRow = pattern->GetCustomTitleRow();
1002 CHECK_NULL_VOID(customTitleRow);
1003 auto renderContext = customTitleRow->GetRenderContext();
1004 CHECK_NULL_VOID(renderContext);
1005 BlurStyleOption styleOption;
1006 styleOption.blurStyle = blurStyle;
1007 renderContext->UpdateBackBlurStyle(styleOption);
1008 }
UpdateSidebarMargin()1009 void ContainerModalToolBar::UpdateSidebarMargin()
1010 {
1011 CHECK_NULL_VOID(toolbarManager_);
1012 if (toolbarManager_->GetIsMoveUp()) {
1013 auto sideBarContainerModelNode = toolbarManager_->GetSideBarContainerModel().Upgrade();
1014 CHECK_NULL_VOID(sideBarContainerModelNode);
1015 sideBarContainerModelNode->MarkDirtyNode(
1016 PROPERTY_UPDATE_LAYOUT | PROPERTY_UPDATE_RENDER | PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD);
1017 sideBarContainerModelNode->MarkModifyDone();
1018 isUpdateTargetNode_ = true;
1019 }
1020 }
1021
UpdateNavbarTitlebarMargin()1022 void ContainerModalToolBar::UpdateNavbarTitlebarMargin()
1023 {
1024 CHECK_NULL_VOID(toolbarManager_);
1025 if (toolbarManager_->GetIsMoveUp()) {
1026 auto navBarNode = toolbarManager_->GetNavBar().Upgrade();
1027 CHECK_NULL_VOID(navBarNode);
1028 auto navigation = navBarNode->GetParent();
1029 CHECK_NULL_VOID(navigation);
1030 auto navigationFrameNode = AceType::DynamicCast<FrameNode>(navigation);
1031 CHECK_NULL_VOID(navigationFrameNode);
1032 navigationFrameNode->MarkDirtyNode(
1033 PROPERTY_UPDATE_LAYOUT | PROPERTY_UPDATE_RENDER | PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD);
1034 navigationFrameNode->MarkModifyDone();
1035 isUpdateTargetNode_ = true;
1036 }
1037 }
1038
UpdateNavDestinationTitlebarMargin()1039 void ContainerModalToolBar::UpdateNavDestinationTitlebarMargin()
1040 {
1041 CHECK_NULL_VOID(toolbarManager_);
1042 if (toolbarManager_->GetIsMoveUp()) {
1043 auto navigationContentNode = toolbarManager_->GetNavDest().Upgrade();
1044 CHECK_NULL_VOID(navigationContentNode);
1045 auto navigationFrameNode = AceType::DynamicCast<FrameNode>(navigationContentNode->GetParent());
1046 CHECK_NULL_VOID(navigationFrameNode);
1047 auto navigationPattern = navigationFrameNode->GetPattern<NG::NavigationPattern>();
1048 CHECK_NULL_VOID(navigationPattern);
1049 auto navigationStack = navigationPattern->GetNavigationStack();
1050 CHECK_NULL_VOID(navigationStack);
1051 auto topNavDestinationNode = navigationStack->GetTopNavPath();
1052 if (!topNavDestinationNode.has_value()) {
1053 return;
1054 }
1055 auto navDestinationNode = AceType::DynamicCast<NG::NavDestinationGroupNode>(
1056 NG::NavigationGroupNode::GetNavDestinationNode(topNavDestinationNode->second));
1057 CHECK_NULL_VOID(navDestinationNode);
1058 navDestinationNode->MarkDirtyNode(
1059 PROPERTY_UPDATE_LAYOUT | PROPERTY_UPDATE_RENDER | PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD);
1060 navDestinationNode->MarkModifyDone();
1061 isUpdateTargetNode_ = true;
1062 }
1063 }
1064
UpdateTargetNodesBarMargin(bool reset)1065 void ContainerModalToolBar::UpdateTargetNodesBarMargin(bool reset)
1066 {
1067 if (!toolbarManager_ || isFloating_) {
1068 return;
1069 }
1070 auto pattern = pattern_.Upgrade();
1071 CHECK_NULL_VOID(pattern);
1072 if (reset) {
1073 if (!isUpdateTargetNode_) {
1074 return;
1075 }
1076 toolbarManager_->SetTitleHeight(Dimension(0.0f));
1077 } else {
1078 if (!isUpdateTargetNode_ && pattern->GetIsHaveToolBar() && pattern->IsExpandStackNode()) {
1079 ExpandStackNodeLayout();
1080 BlurStyle blurStyle = BlurStyle::THIN;
1081 SetCustomTitleRowBlurStyle(blurStyle);
1082 toolbarManager_->SetIsMoveUp(true);
1083 }
1084 toolbarManager_->SetTitleHeight(pattern->titleHeight_);
1085 }
1086
1087 UpdateNavDestinationTitlebarMargin();
1088 UpdateNavbarTitlebarMargin();
1089 UpdateSidebarMargin();
1090 }
1091
ExpandStackNodeLayout(bool reset)1092 void ContainerModalToolBar::ExpandStackNodeLayout(bool reset)
1093 {
1094 CHECK_NULL_VOID(title_);
1095 auto pattern = pattern_.Upgrade();
1096 CHECK_NULL_VOID(pattern);
1097 auto stackNode = pattern->GetStackNode();
1098 CHECK_NULL_VOID(stackNode);
1099 auto renderContext = stackNode->GetRenderContext();
1100 CHECK_NULL_VOID(renderContext);
1101 auto stackLayoutProperty = stackNode->GetLayoutProperty<StackLayoutProperty>();
1102 CHECK_NULL_VOID(stackLayoutProperty);
1103 if (reset) {
1104 auto titleRenderContext = title_->GetRenderContext();
1105 CHECK_NULL_VOID(titleRenderContext);
1106 titleRenderContext->ResetBackBlurStyle();
1107 renderContext->ResetPosition();
1108 renderContext->ResetZIndex();
1109 auto titleNode = AceType::DynamicCast<FrameNode>(title_->GetChildren().front());
1110 CHECK_NULL_VOID(titleNode);
1111 auto titleNodeCtx = titleNode->GetRenderContext();
1112 CHECK_NULL_VOID(titleNodeCtx);
1113 titleNodeCtx->ResetBackBlurStyle();
1114 titleNodeCtx->UpdateBackgroundColor(Color::TRANSPARENT);
1115 } else {
1116 renderContext->UpdatePosition(OffsetT(Dimension(0.0f), Dimension(0.0f)));
1117 renderContext->UpdateZIndex(-1);
1118 }
1119 auto columnNode = pattern->GetColumnNode();
1120 CHECK_NULL_VOID(columnNode);
1121 columnNode->MarkDirtyNode(PROPERTY_UPDATE_LAYOUT | PROPERTY_UPDATE_RENDER | PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD);
1122 columnNode->MarkModifyDone();
1123 }
1124
ResetExpandStackNode()1125 void ContainerModalToolBar::ResetExpandStackNode()
1126 {
1127 if (!isUpdateTargetNode_ || isFloating_ || !toolbarManager_) {
1128 return;
1129 }
1130 UpdateTargetNodesBarMargin(true);
1131 isUpdateTargetNode_ = false;
1132 toolbarManager_->SetIsMoveUp(false);
1133 ExpandStackNodeLayout(true);
1134 }
1135 } // namespace OHOS::Ace::NG