• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "core/components_ng/pattern/navigation/navigation_model_ng.h"
17 
18 #include "base/geometry/dimension.h"
19 #include "base/i18n/localization.h"
20 #include "base/memory/ace_type.h"
21 #include "base/memory/referenced.h"
22 #include "base/utils/utils.h"
23 #include "core/components/common/properties/alignment.h"
24 #include "core/components/common/properties/color.h"
25 #include "core/components/common/properties/shadow.h"
26 #include "core/components/common/properties/shadow_config.h"
27 #include "core/components_ng/base/frame_node.h"
28 #include "core/components_ng/base/view_stack_processor.h"
29 #include "core/components_ng/pattern/button/button_layout_property.h"
30 #include "core/components_ng/pattern/button/button_pattern.h"
31 #include "core/components_ng/pattern/custom/custom_node.h"
32 #include "core/components_ng/pattern/divider/divider_layout_property.h"
33 #include "core/components_ng/pattern/divider/divider_pattern.h"
34 #include "core/components_ng/pattern/divider/divider_render_property.h"
35 #include "core/components_ng/pattern/image/image_layout_property.h"
36 #include "core/components_ng/pattern/image/image_pattern.h"
37 #include "core/components_ng/pattern/linear_layout/linear_layout_pattern.h"
38 #include "core/components_ng/pattern/menu/menu_view.h"
39 #include "core/components_ng/pattern/navigation/bar_item_event_hub.h"
40 #include "core/components_ng/pattern/navigation/bar_item_node.h"
41 #include "core/components_ng/pattern/navigation/bar_item_pattern.h"
42 #include "core/components_ng/pattern/navigation/nav_bar_layout_property.h"
43 #include "core/components_ng/pattern/navigation/nav_bar_pattern.h"
44 #include "core/components_ng/pattern/navigation/navigation_content_pattern.h"
45 #include "core/components_ng/pattern/navigation/navigation_declaration.h"
46 #include "core/components_ng/pattern/navigation/navigation_event_hub.h"
47 #include "core/components_ng/pattern/navigation/navigation_layout_property.h"
48 #include "core/components_ng/pattern/navigation/navigation_pattern.h"
49 #include "core/components_ng/pattern/navigation/title_bar_node.h"
50 #include "core/components_ng/pattern/navigation/title_bar_pattern.h"
51 #include "core/components_ng/pattern/navigation/tool_bar_node.h"
52 #include "core/components_ng/pattern/navigation/tool_bar_pattern.h"
53 #include "core/components_ng/pattern/navigator/navigator_event_hub.h"
54 #include "core/components_ng/pattern/navigator/navigator_pattern.h"
55 #include "core/components_ng/pattern/navrouter/navdestination_group_node.h"
56 #include "core/components_ng/pattern/navrouter/navdestination_layout_property.h"
57 #include "core/components_ng/pattern/navrouter/navrouter_group_node.h"
58 #include "core/components_ng/pattern/option/option_view.h"
59 #include "core/components_ng/pattern/select/select_model.h"
60 #include "core/components_ng/pattern/select/select_model_ng.h"
61 #include "core/components_ng/pattern/stack/stack_pattern.h"
62 #include "core/components_ng/pattern/text/text_layout_property.h"
63 #include "core/components_ng/pattern/text/text_pattern.h"
64 #include "core/components_v2/inspector/inspector_constants.h"
65 #include "core/pipeline/base/element_register.h"
66 #include "core/pipeline_ng/ui_task_scheduler.h"
67 #include "frameworks/bridge/common/utils/engine_helper.h"
68 
69 namespace OHOS::Ace::NG {
70 namespace {
CreateBarItemTextNode(const std::string & text)71 RefPtr<FrameNode> CreateBarItemTextNode(const std::string& text)
72 {
73     int32_t nodeId = ElementRegister::GetInstance()->MakeUniqueId();
74     auto textNode = FrameNode::CreateFrameNode(V2::TEXT_ETS_TAG, nodeId, AceType::MakeRefPtr<TextPattern>());
75     auto textLayoutProperty = textNode->GetLayoutProperty<TextLayoutProperty>();
76     CHECK_NULL_RETURN(textLayoutProperty, nullptr);
77     textLayoutProperty->UpdateContent(text);
78     textLayoutProperty->UpdateFontSize(TEXT_FONT_SIZE);
79     textLayoutProperty->UpdateTextColor(TEXT_COLOR);
80     textLayoutProperty->UpdateTextAlign(TextAlign::CENTER);
81     return textNode;
82 }
83 
CreateBarItemIconNode(const std::string & src)84 RefPtr<FrameNode> CreateBarItemIconNode(const std::string& src)
85 {
86     int32_t nodeId = ElementRegister::GetInstance()->MakeUniqueId();
87     ImageSourceInfo info(src);
88     auto iconNode = FrameNode::CreateFrameNode(V2::IMAGE_ETS_TAG, nodeId, AceType::MakeRefPtr<ImagePattern>());
89     auto imageLayoutProperty = iconNode->GetLayoutProperty<ImageLayoutProperty>();
90     CHECK_NULL_RETURN(imageLayoutProperty, nullptr);
91     auto theme = NavigationGetTheme();
92     CHECK_NULL_RETURN(theme, nullptr);
93 
94     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
95     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
96     CHECK_NULL_RETURN(navigationGroupNode, nullptr);
97     auto hub = navigationGroupNode->GetEventHub<EventHub>();
98     CHECK_NULL_RETURN(hub, nullptr);
99     if (!hub->IsEnabled()) {
100         info.SetFillColor(theme->GetMenuIconColor().BlendOpacity(theme->GetAlphaDisabled()));
101     } else {
102         info.SetFillColor(theme->GetMenuIconColor());
103     }
104     imageLayoutProperty->UpdateImageSourceInfo(info);
105 
106     auto iconSize = theme->GetMenuIconSize();
107     imageLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(CalcLength(iconSize), CalcLength(iconSize)));
108     iconNode->MarkModifyDone();
109     return iconNode;
110 }
111 
UpdateBarItemNodeWithItem(const RefPtr<BarItemNode> & barItemNode,const BarItem & barItem)112 void UpdateBarItemNodeWithItem(const RefPtr<BarItemNode>& barItemNode, const BarItem& barItem)
113 {
114     if (barItem.text.has_value() && !barItem.text.value().empty()) {
115         auto textNode = CreateBarItemTextNode(barItem.text.value());
116         barItemNode->SetTextNode(textNode);
117         barItemNode->AddChild(textNode);
118     }
119     if (barItem.icon.has_value() && !barItem.icon.value().empty()) {
120         auto iconNode = CreateBarItemIconNode(barItem.icon.value());
121         barItemNode->SetIconNode(iconNode);
122         barItemNode->AddChild(iconNode);
123     }
124     if (barItem.action) {
125         auto eventHub = barItemNode->GetEventHub<BarItemEventHub>();
126         CHECK_NULL_VOID(eventHub);
127         eventHub->SetItemAction(barItem.action);
128     }
129     auto barItemPattern = barItemNode->GetPattern<BarItemPattern>();
130     barItemNode->MarkModifyDone();
131 }
132 
UpdateOldBarItems(const RefPtr<UINode> & oldBarContainer,const std::vector<BarItem> & newBarItems)133 void UpdateOldBarItems(const RefPtr<UINode>& oldBarContainer, const std::vector<BarItem>& newBarItems)
134 {
135     auto oldBarItems = oldBarContainer->GetChildren();
136     auto prevChildrenSize = static_cast<int32_t>(oldBarItems.size());
137     auto newChildrenSize = static_cast<int32_t>(newBarItems.size());
138     auto oldIter = oldBarItems.begin();
139     auto newIter = newBarItems.begin();
140     // if old container has m items and incoming array has n items
141     // we update first min(m, n) items in the old container
142     for (int32_t i = 0; i < std::min(prevChildrenSize, newChildrenSize); i++) {
143         do {
144             auto oldBarItem = AceType::DynamicCast<BarItemNode>(*oldIter);
145             BarItem newBarItem = *newIter;
146             if (!oldBarItem) {
147                 break;
148             }
149             // TODO: fix error for update condition when add or delete child, and update old bar item will not work
150             if (newBarItem.text.has_value()) {
151                 oldBarItem->UpdateText(newBarItem.text.value());
152                 if (oldBarItem->GetTextNode()) {
153                     auto textNode = AceType::DynamicCast<FrameNode>(oldBarItem->GetTextNode());
154                     CHECK_NULL_VOID(textNode);
155                     auto textLayoutProperty = textNode->GetLayoutProperty<TextLayoutProperty>();
156                     CHECK_NULL_VOID(textLayoutProperty);
157                     textLayoutProperty->UpdateContent(newBarItem.text.value());
158                     textNode->MarkModifyDone();
159                 } else {
160                     auto textNode = CreateBarItemTextNode(newBarItem.text.value());
161                     oldBarItem->SetTextNode(textNode);
162                     oldBarItem->AddChild(textNode);
163                     oldBarItem->MarkModifyDone();
164                 }
165             } else {
166                 oldBarItem->ResetText();
167                 if (oldBarItem->GetTextNode()) {
168                     auto textNode = AceType::DynamicCast<FrameNode>(oldBarItem->GetTextNode());
169                     CHECK_NULL_VOID(textNode);
170                     oldBarItem->RemoveChild(textNode);
171                 }
172             }
173             if (newBarItem.icon.has_value()) {
174                 oldBarItem->UpdateIconSrc(newBarItem.icon.value());
175                 if (oldBarItem->GetIconNode()) {
176                     auto iconNode = AceType::DynamicCast<FrameNode>(oldBarItem->GetIconNode());
177                     CHECK_NULL_VOID(iconNode);
178                     auto imageLayoutProperty = iconNode->GetLayoutProperty<ImageLayoutProperty>();
179                     CHECK_NULL_VOID(imageLayoutProperty);
180                     imageLayoutProperty->UpdateImageSourceInfo(ImageSourceInfo(newBarItem.icon.value()));
181                     iconNode->MarkModifyDone();
182                 } else {
183                     auto iconNode = CreateBarItemIconNode(newBarItem.icon.value());
184                     oldBarItem->SetIconNode(iconNode);
185                     oldBarItem->AddChild(iconNode);
186                     oldBarItem->MarkModifyDone();
187                 }
188             } else {
189                 oldBarItem->ResetIconSrc();
190                 if (oldBarItem->GetIconNode()) {
191                     auto iconNode = AceType::DynamicCast<FrameNode>(oldBarItem->GetIconNode());
192                     CHECK_NULL_VOID(iconNode);
193                     oldBarItem->RemoveChild(iconNode);
194                 }
195             }
196         } while (false);
197         oldIter++;
198         newIter++;
199     }
200     // if m > n, we remove (m - n) children from the back of old container
201     if (prevChildrenSize > newChildrenSize) {
202         for (int32_t i = 0; i < prevChildrenSize - newChildrenSize; i++) {
203             oldBarContainer->RemoveChild(oldBarItems.back());
204             oldBarItems.pop_back();
205         }
206     } else if (prevChildrenSize < newChildrenSize) {
207         // if m < n, we add (n - m) children created by info in new item list
208         for (int32_t i = 0; i < newChildrenSize - prevChildrenSize; i++) {
209             auto nodeId = ElementRegister::GetInstance()->MakeUniqueId();
210             auto barItemNode = AceType::MakeRefPtr<BarItemNode>(V2::BAR_ITEM_ETS_TAG, nodeId);
211             barItemNode->InitializePatternAndContext();
212             UpdateBarItemNodeWithItem(barItemNode, *newIter);
213             oldBarContainer->AddChild(barItemNode);
214             newIter++;
215         }
216     }
217     auto container = AceType::DynamicCast<TitleBarNode>(oldBarContainer);
218     CHECK_NULL_VOID(container);
219     container->MarkModifyDone();
220 }
221 
CreateToolBarDividerNode(const RefPtr<NavBarNode> & navBarNode)222 void CreateToolBarDividerNode(const RefPtr<NavBarNode>& navBarNode)
223 {
224     int32_t dividerNodeId = ElementRegister::GetInstance()->MakeUniqueId();
225     auto dividerNode = FrameNode::GetOrCreateFrameNode(
226         V2::DIVIDER_ETS_TAG, dividerNodeId, []() { return AceType::MakeRefPtr<DividerPattern>(); });
227     navBarNode->AddChild(dividerNode);
228     auto dividerLayoutProperty = dividerNode->GetLayoutProperty<DividerLayoutProperty>();
229     CHECK_NULL_VOID(dividerLayoutProperty);
230     auto theme = NavigationGetTheme();
231     CHECK_NULL_VOID(theme);
232     dividerLayoutProperty->UpdateStrokeWidth(theme->GetToolBarDividerWidth());
233     dividerLayoutProperty->UpdateVertical(false);
234     auto dividerRenderProperty = dividerNode->GetPaintProperty<DividerRenderProperty>();
235     CHECK_NULL_VOID(dividerRenderProperty);
236     dividerRenderProperty->UpdateDividerColor(theme->GetToolBarDividerColor());
237     navBarNode->SetToolBarDividerNode(dividerNode);
238 }
239 
CreateToolbarItemsContainerNode(const RefPtr<FrameNode> & toolBarNode)240 RefPtr<FrameNode> CreateToolbarItemsContainerNode(const RefPtr<FrameNode>& toolBarNode)
241 {
242     int32_t containerNodeId = ElementRegister::GetInstance()->MakeUniqueId();
243     auto containerNode = FrameNode::GetOrCreateFrameNode(
244         V2::TOOL_BAR_ETS_TAG, containerNodeId, []() { return AceType::MakeRefPtr<LinearLayoutPattern>(false); });
245     CHECK_NULL_RETURN(containerNode, nullptr);
246     auto containerRowProperty = containerNode->GetLayoutProperty<LinearLayoutProperty>();
247     CHECK_NULL_RETURN(containerRowProperty, nullptr);
248     containerRowProperty->UpdateMainAxisAlign(FlexAlign::SPACE_EVENLY);
249     toolBarNode->AddChild(containerNode);
250     return containerNode;
251 }
252 
CreateToolbarItemTextNode(const std::string & text)253 RefPtr<FrameNode> CreateToolbarItemTextNode(const std::string& text)
254 {
255     int32_t nodeId = ElementRegister::GetInstance()->MakeUniqueId();
256     auto textNode = FrameNode::CreateFrameNode(V2::TEXT_ETS_TAG, nodeId, AceType::MakeRefPtr<TextPattern>());
257     auto textLayoutProperty = textNode->GetLayoutProperty<TextLayoutProperty>();
258     CHECK_NULL_RETURN(textLayoutProperty, nullptr);
259     auto theme = NavigationGetTheme();
260     CHECK_NULL_RETURN(theme, nullptr);
261     textLayoutProperty->UpdateContent(text);
262     textLayoutProperty->UpdateFontSize(theme->GetToolBarItemFontSize());
263     textLayoutProperty->UpdateTextColor(theme->GetToolBarItemFontColor());
264     textLayoutProperty->UpdateTextAlign(TextAlign::CENTER);
265     textLayoutProperty->UpdateFontWeight(FontWeight::MEDIUM);
266     textLayoutProperty->UpdateAdaptMinFontSize(theme->GetToolBarItemMinFontSize());
267     textLayoutProperty->UpdateAdaptMaxFontSize(theme->GetToolBarItemFontSize());
268     textLayoutProperty->UpdateMaxLines(theme->GetToolbarItemTextMaxLines());
269     textLayoutProperty->UpdateTextOverflow(TextOverflow::ELLIPSIS);
270     textLayoutProperty->UpdateHeightAdaptivePolicy(TextHeightAdaptivePolicy::MIN_FONT_SIZE_FIRST);
271 
272     textLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(CalcLength(1.0, DimensionUnit::PERCENT), std::nullopt));
273     return textNode;
274 }
275 
CreateToolbarItemIconNode(const std::string & src)276 RefPtr<FrameNode> CreateToolbarItemIconNode(const std::string& src)
277 {
278     int32_t nodeId = ElementRegister::GetInstance()->MakeUniqueId();
279     ImageSourceInfo info(src);
280     auto iconNode = FrameNode::CreateFrameNode(V2::IMAGE_ETS_TAG, nodeId, AceType::MakeRefPtr<ImagePattern>());
281     auto imageLayoutProperty = iconNode->GetLayoutProperty<ImageLayoutProperty>();
282     CHECK_NULL_RETURN(imageLayoutProperty, nullptr);
283     auto theme = NavigationGetTheme();
284     CHECK_NULL_RETURN(theme, nullptr);
285 
286     info.SetFillColor(theme->GetToolbarIconColor());
287     imageLayoutProperty->UpdateImageSourceInfo(info);
288 
289     auto iconSize = theme->GetToolbarIconSize();
290     imageLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(CalcLength(iconSize), CalcLength(iconSize)));
291 
292     iconNode->MarkModifyDone();
293     return iconNode;
294 }
295 
CheckNavigationGroupEnableStatus()296 bool CheckNavigationGroupEnableStatus()
297 {
298     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
299     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
300     CHECK_NULL_RETURN(navigationGroupNode, false);
301     auto eventHub = navigationGroupNode->GetEventHub<EventHub>();
302     CHECK_NULL_RETURN(eventHub, false);
303     return eventHub->IsEnabled();
304 }
305 
RegisterToolbarHotZoneEvent(const RefPtr<FrameNode> & buttonNode,const RefPtr<BarItemNode> & barItemNode)306 void RegisterToolbarHotZoneEvent(const RefPtr<FrameNode>& buttonNode, const RefPtr<BarItemNode>& barItemNode)
307 {
308     auto gestureEventHub = buttonNode->GetOrCreateGestureEventHub();
309     CHECK_NULL_VOID(gestureEventHub);
310     auto clickCallback = [weakNode = WeakPtr<BarItemNode>(barItemNode)](GestureEvent& info) {
311         if (info.GetSourceDevice() == SourceType::KEYBOARD) {
312             return;
313         }
314         auto barItemNode = weakNode.Upgrade();
315         auto eventHub = barItemNode->GetEventHub<BarItemEventHub>();
316         CHECK_NULL_VOID(eventHub);
317         auto pattern = barItemNode->GetPattern<BarItemPattern>();
318         CHECK_NULL_VOID(pattern);
319         eventHub->FireItemAction();
320         pattern->UpdateBarItemActiveStatusResource();
321     };
322     gestureEventHub->AddClickEvent(AceType::MakeRefPtr<ClickEvent>(clickCallback));
323 }
324 
UpdateToolbarItemNodeWithConfiguration(const RefPtr<BarItemNode> & barItemNode,const BarItem & barItem,const RefPtr<FrameNode> & buttonNode)325 void UpdateToolbarItemNodeWithConfiguration(
326     const RefPtr<BarItemNode>& barItemNode, const BarItem& barItem, const RefPtr<FrameNode>& buttonNode)
327 {
328     barItemNode->SetBarItemUsedInToolbarConfiguration(true);
329     if (barItem.text.has_value() && !barItem.text.value().empty()) {
330         auto textNode = CreateToolbarItemTextNode(barItem.text.value());
331         barItemNode->SetTextNode(textNode);
332         barItemNode->AddChild(textNode);
333     }
334     if (barItem.icon.has_value() && !barItem.icon.value().empty()) {
335         auto iconNode = CreateToolbarItemIconNode(barItem.icon.value());
336         barItemNode->SetIconNode(iconNode);
337         barItemNode->AddChild(iconNode);
338     }
339     if (barItem.action) {
340         auto eventHub = barItemNode->GetEventHub<BarItemEventHub>();
341         CHECK_NULL_VOID(eventHub);
342         eventHub->SetItemAction(barItem.action);
343         RegisterToolbarHotZoneEvent(buttonNode, barItemNode);
344     }
345 
346     auto theme = NavigationGetTheme();
347     CHECK_NULL_VOID(theme);
348     bool navigationEnableStatus = CheckNavigationGroupEnableStatus();
349     if (barItem.status == NG::NavToolbarItemStatus::DISABLED || !navigationEnableStatus) {
350         auto renderContext = barItemNode->GetRenderContext();
351         CHECK_NULL_VOID(renderContext);
352         renderContext->UpdateOpacity(theme->GetToolbarItemDisabledAlpha());
353 
354         auto itemEventHub = barItemNode->GetEventHub<BarItemEventHub>();
355         CHECK_NULL_VOID(itemEventHub);
356         itemEventHub->SetEnabled(false);
357 
358         auto buttonEventHub = buttonNode->GetEventHub<ButtonEventHub>();
359         CHECK_NULL_VOID(buttonEventHub);
360         buttonEventHub->SetEnabled(false);
361     }
362 
363     auto barItemPattern = barItemNode->GetPattern<BarItemPattern>();
364     if (barItem.status == NG::NavToolbarItemStatus::ACTIVE && barItem.activeIcon.has_value() &&
365         !barItem.activeIcon.value().empty() && barItem.icon.has_value() && !barItem.icon.value().empty()) {
366         ImageSourceInfo initialIconInfo(barItem.icon.value());
367         initialIconInfo.SetFillColor(theme->GetToolbarIconColor());
368         ImageSourceInfo activeIconInfo(barItem.activeIcon.value());
369         activeIconInfo.SetFillColor(theme->GetToolbarActiveIconColor());
370         barItemPattern->SetInitialIconImageSourceInfo(initialIconInfo);
371         barItemPattern->SetActiveIconImageSourceInfo(activeIconInfo);
372         barItemPattern->SetToolbarItemStatus(barItem.status);
373         barItemPattern->SetCurrentIconStatus(NG::ToolbarIconStatus::INITIAL);
374     }
375     barItemNode->MarkModifyDone();
376 }
377 
AddSafeIntervalBetweenToolbarItem(MarginProperty & margin,uint32_t count,size_t toolbarItemSize,bool needMoreButton)378 void AddSafeIntervalBetweenToolbarItem(
379     MarginProperty& margin, uint32_t count, size_t toolbarItemSize, bool needMoreButton)
380 {
381     auto theme = NavigationGetTheme();
382     CHECK_NULL_VOID(theme);
383     if (count == ONE_TOOLBAR_ITEM && toolbarItemSize != ONE_TOOLBAR_ITEM) {
384         margin.right = CalcLength(theme->GetToolbarItemMargin());
385     } else if (!needMoreButton && (count == toolbarItemSize) && (toolbarItemSize != ONE_TOOLBAR_ITEM)) {
386         margin.left = CalcLength(theme->GetToolbarItemMargin());
387     } else if (toolbarItemSize == ONE_TOOLBAR_ITEM) {
388         margin.left = CalcLength(theme->GetToolbarItemSpecialMargin());
389         margin.right = CalcLength(theme->GetToolbarItemSpecialMargin());
390     } else {
391         margin.left = CalcLength(theme->GetToolbarItemMargin());
392         margin.right = CalcLength(theme->GetToolbarItemMargin());
393     }
394 }
395 
CreateToolbarItemInContainer(const NG::BarItem & toolBarItem,size_t toolbarItemSize,uint32_t count,bool needMoreButton)396 RefPtr<FrameNode> CreateToolbarItemInContainer(
397     const NG::BarItem& toolBarItem, size_t toolbarItemSize, uint32_t count, bool needMoreButton)
398 {
399     auto theme = NavigationGetTheme();
400     CHECK_NULL_RETURN(theme, nullptr);
401     auto buttonPattern = AceType::MakeRefPtr<NG::ButtonPattern>();
402     CHECK_NULL_RETURN(buttonPattern, nullptr);
403     buttonPattern->setComponentButtonType(ComponentButtonType::NAVIGATION);
404     buttonPattern->SetFocusBorderColor(theme->GetToolBarItemFocusColor());
405     buttonPattern->SetFocusBorderWidth(theme->GetToolBarItemFocusBorderWidth());
406     auto toolBarItemNode = FrameNode::CreateFrameNode(
407         V2::MENU_ITEM_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), buttonPattern);
408     CHECK_NULL_RETURN(toolBarItemNode, nullptr);
409     auto toolBarItemLayoutProperty = toolBarItemNode->GetLayoutProperty<ButtonLayoutProperty>();
410     CHECK_NULL_RETURN(toolBarItemLayoutProperty, nullptr);
411     toolBarItemLayoutProperty->UpdateUserDefinedIdealSize(
412         CalcSize(std::nullopt, CalcLength(theme->GetToolbarItemHeigth())));
413     toolBarItemLayoutProperty->UpdateType(ButtonType::NORMAL);
414     toolBarItemLayoutProperty->UpdateBorderRadius(theme->GetToolBarItemBorderRadius());
415     auto renderContext = toolBarItemNode->GetRenderContext();
416     CHECK_NULL_RETURN(renderContext, nullptr);
417     renderContext->UpdateBackgroundColor(Color::TRANSPARENT);
418     MarginProperty margin;
419     AddSafeIntervalBetweenToolbarItem(margin, count, toolbarItemSize, needMoreButton);
420     toolBarItemLayoutProperty->UpdateMargin(margin);
421 
422     PaddingProperty padding;
423     padding.left = CalcLength(theme->GetToolbarItemLeftOrRightPadding());
424     padding.right = CalcLength(theme->GetToolbarItemLeftOrRightPadding());
425     padding.top = CalcLength(theme->GetToolbarItemTopPadding());
426     padding.bottom = CalcLength(theme->GetToolbarItemBottomPadding());
427     toolBarItemLayoutProperty->UpdatePadding(padding);
428 
429     int32_t barItemNodeId = ElementRegister::GetInstance()->MakeUniqueId();
430     auto barItemNode = AceType::MakeRefPtr<BarItemNode>(V2::BAR_ITEM_ETS_TAG, barItemNodeId);
431     barItemNode->InitializePatternAndContext();
432     UpdateToolbarItemNodeWithConfiguration(barItemNode, toolBarItem, toolBarItemNode);
433     auto barItemLayoutProperty = barItemNode->GetLayoutProperty();
434     CHECK_NULL_RETURN(barItemLayoutProperty, nullptr);
435     barItemLayoutProperty->UpdateMeasureType(MeasureType::MATCH_PARENT);
436 
437     barItemNode->MountToParent(toolBarItemNode);
438     toolBarItemNode->MarkModifyDone();
439 
440     return toolBarItemNode;
441 }
442 
BuildToolbarMoreItemNode(const RefPtr<BarItemNode> & barItemNode)443 void BuildToolbarMoreItemNode(const RefPtr<BarItemNode>& barItemNode)
444 {
445     int32_t imageNodeId = ElementRegister::GetInstance()->MakeUniqueId();
446     auto imageNode = FrameNode::CreateFrameNode(V2::IMAGE_ETS_TAG, imageNodeId, AceType::MakeRefPtr<ImagePattern>());
447     auto imageLayoutProperty = imageNode->GetLayoutProperty<ImageLayoutProperty>();
448     CHECK_NULL_VOID(imageLayoutProperty);
449     auto theme = NavigationGetTheme();
450     CHECK_NULL_VOID(theme);
451 
452     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
453     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
454     CHECK_NULL_VOID(navigationGroupNode);
455     auto hub = navigationGroupNode->GetEventHub<EventHub>();
456     CHECK_NULL_VOID(hub);
457     auto renderContext = barItemNode->GetRenderContext();
458     CHECK_NULL_VOID(renderContext);
459     auto info = ImageSourceInfo("");
460     info.SetResourceId(theme->GetMoreResourceId());
461     if (!hub->IsEnabled()) {
462         renderContext->UpdateOpacity(theme->GetToolbarItemDisabledAlpha());
463     } else {
464         info.SetFillColor(theme->GetToolbarIconColor());
465     }
466     imageLayoutProperty->UpdateImageSourceInfo(info);
467     auto iconSize = theme->GetToolbarIconSize();
468     imageLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(CalcLength(iconSize), CalcLength(iconSize)));
469     imageNode->MarkModifyDone();
470 
471     auto textNode = CreateToolbarItemTextNode(Localization::GetInstance()->GetEntryLetters("common.more"));
472     CHECK_NULL_VOID(textNode);
473     barItemNode->SetTextNode(textNode);
474     barItemNode->SetBarItemUsedInToolbarConfiguration(true);
475     barItemNode->AddChild(textNode);
476     barItemNode->SetIconNode(imageNode);
477     barItemNode->AddChild(imageNode);
478     barItemNode->MarkModifyDone();
479 }
480 
CreateToolbarMoreMenuNode(const RefPtr<BarItemNode> & barItemNode)481 RefPtr<FrameNode> CreateToolbarMoreMenuNode(const RefPtr<BarItemNode>& barItemNode)
482 {
483     auto theme = NavigationGetTheme();
484     CHECK_NULL_RETURN(theme, nullptr);
485     auto buttonPattern = AceType::MakeRefPtr<NG::ButtonPattern>();
486     CHECK_NULL_RETURN(buttonPattern, nullptr);
487     buttonPattern->setComponentButtonType(ComponentButtonType::NAVIGATION);
488     buttonPattern->SetFocusBorderColor(theme->GetToolBarItemFocusColor());
489     buttonPattern->SetFocusBorderWidth(theme->GetToolBarItemFocusBorderWidth());
490     auto toolBarItemNode = FrameNode::CreateFrameNode(
491         V2::MENU_ITEM_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), buttonPattern);
492     CHECK_NULL_RETURN(toolBarItemNode, nullptr);
493     auto menuItemLayoutProperty = toolBarItemNode->GetLayoutProperty<ButtonLayoutProperty>();
494     CHECK_NULL_RETURN(menuItemLayoutProperty, nullptr);
495     menuItemLayoutProperty->UpdateUserDefinedIdealSize(
496         CalcSize(std::nullopt, CalcLength(theme->GetToolbarItemHeigth())));
497     menuItemLayoutProperty->UpdateType(ButtonType::NORMAL);
498     menuItemLayoutProperty->UpdateBorderRadius(theme->GetToolBarItemBorderRadius());
499 
500     auto renderContext = toolBarItemNode->GetRenderContext();
501     CHECK_NULL_RETURN(renderContext, nullptr);
502     renderContext->UpdateBackgroundColor(Color::TRANSPARENT);
503 
504     MarginProperty menuButtonMargin;
505     menuButtonMargin.left = CalcLength(theme->GetToolbarItemMargin());
506     menuItemLayoutProperty->UpdateMargin(menuButtonMargin);
507 
508     PaddingProperty padding;
509     padding.left = CalcLength(theme->GetToolbarItemLeftOrRightPadding());
510     padding.right = CalcLength(theme->GetToolbarItemLeftOrRightPadding());
511     padding.top = CalcLength(theme->GetToolbarItemTopPadding());
512     padding.bottom = CalcLength(theme->GetToolbarItemBottomPadding());
513     menuItemLayoutProperty->UpdatePadding(padding);
514 
515     barItemNode->MountToParent(toolBarItemNode);
516     barItemNode->MarkModifyDone();
517     toolBarItemNode->MarkModifyDone();
518 
519     return toolBarItemNode;
520 }
521 
BuildToolbarMoreMenuNodeAction(const RefPtr<BarItemNode> & barItemNode,const RefPtr<FrameNode> & barMenuNode,const RefPtr<FrameNode> & buttonNode)522 void BuildToolbarMoreMenuNodeAction(
523     const RefPtr<BarItemNode>& barItemNode, const RefPtr<FrameNode>& barMenuNode, const RefPtr<FrameNode>& buttonNode)
524 {
525     auto eventHub = barItemNode->GetEventHub<BarItemEventHub>();
526     CHECK_NULL_VOID(eventHub);
527 
528     auto context = PipelineContext::GetCurrentContext();
529     auto clickCallback = [weakContext = WeakPtr<PipelineContext>(context), id = barItemNode->GetId(),
530                              weakMenu = WeakPtr<FrameNode>(barMenuNode),
531                              weakBarItemNode = WeakPtr<BarItemNode>(barItemNode)]() {
532         auto context = weakContext.Upgrade();
533         CHECK_NULL_VOID(context);
534 
535         auto overlayManager = context->GetOverlayManager();
536         CHECK_NULL_VOID(overlayManager);
537 
538         auto menu = weakMenu.Upgrade();
539         CHECK_NULL_VOID(menu);
540 
541         auto barItemNode = weakBarItemNode.Upgrade();
542         CHECK_NULL_VOID(barItemNode);
543 
544         auto imageNode = barItemNode->GetChildAtIndex(0);
545         CHECK_NULL_VOID(imageNode);
546 
547         auto imageFrameNode = AceType::DynamicCast<FrameNode>(imageNode);
548         CHECK_NULL_VOID(imageFrameNode);
549         auto imgOffset = imageFrameNode->GetOffsetRelativeToWindow();
550         auto imageSize = imageFrameNode->GetGeometryNode()->GetFrameSize();
551 
552         auto menuNode = AceType::DynamicCast<FrameNode>(menu->GetChildAtIndex(0));
553         CHECK_NULL_VOID(menuNode);
554         auto menuLayoutProperty = menuNode->GetLayoutProperty<MenuLayoutProperty>();
555         CHECK_NULL_VOID(menuLayoutProperty);
556         menuLayoutProperty->UpdateTargetSize(imageSize);
557         auto menuPattern = menuNode->GetPattern<MenuPattern>();
558         CHECK_NULL_VOID(menuPattern);
559         menuPattern->SetIsSelectMenu(true);
560 
561         imgOffset.SetX(imgOffset.GetX());
562         imgOffset.SetY(imgOffset.GetY() - imageSize.Height());
563         overlayManager->ShowMenu(id, imgOffset, menu);
564     };
565     eventHub->SetItemAction(clickCallback);
566     RegisterToolbarHotZoneEvent(buttonNode, barItemNode);
567 }
568 } // namespace
569 
Create()570 void NavigationModelNG::Create()
571 {
572     auto* stack = ViewStackProcessor::GetInstance();
573     // navigation node
574     int32_t nodeId = stack->ClaimNodeId();
575     ACE_LAYOUT_SCOPED_TRACE("Create[%s][self:%d]", V2::NAVIGATION_VIEW_ETS_TAG, nodeId);
576     auto navigationGroupNode = NavigationGroupNode::GetOrCreateGroupNode(
577         V2::NAVIGATION_VIEW_ETS_TAG, nodeId, []() { return AceType::MakeRefPtr<NavigationPattern>(); });
578     if (!CreateNavBarNodeIfNeeded(navigationGroupNode) ||  // navBar node
579         !CreateContentNodeIfNeeded(navigationGroupNode) || // content node
580         !CreateDividerNodeIfNeeded(navigationGroupNode)) { // divider node
581         return;
582     }
583 
584     stack->Push(navigationGroupNode);
585     auto navigationLayoutProperty = navigationGroupNode->GetLayoutProperty<NavigationLayoutProperty>();
586     if (!navigationLayoutProperty->HasNavigationMode()) {
587         navigationLayoutProperty->UpdateNavigationMode(NavigationMode::AUTO);
588     }
589     navigationLayoutProperty->UpdateNavBarWidth(DEFAULT_NAV_BAR_WIDTH);
590 }
591 
CreateNavBarNodeIfNeeded(const RefPtr<NavigationGroupNode> & navigationGroupNode)592 bool NavigationModelNG::CreateNavBarNodeIfNeeded(const RefPtr<NavigationGroupNode>& navigationGroupNode)
593 {
594     if (!navigationGroupNode->GetNavBarNode()) {
595         int32_t navBarNodeId = ElementRegister::GetInstance()->MakeUniqueId();
596         ACE_LAYOUT_SCOPED_TRACE("Create[%s][self:%d]", V2::NAVBAR_ETS_TAG, navBarNodeId);
597         auto navBarNode = NavBarNode::GetOrCreateNavBarNode(
598             V2::NAVBAR_ETS_TAG, navBarNodeId, []() { return AceType::MakeRefPtr<NavBarPattern>(); });
599         navBarNode->SetJSViewActive(true);
600         auto navBarRenderContext = navBarNode->GetRenderContext();
601         CHECK_NULL_RETURN(navBarRenderContext, false);
602         navBarRenderContext->UpdateClipEdge(true);
603         navigationGroupNode->AddChild(navBarNode);
604         navigationGroupNode->SetNavBarNode(navBarNode);
605 
606         if (!CreateNavBarNodeChildsIfNeeded(navBarNode)) {
607             return false;
608         }
609 
610         auto navBarLayoutProperty = navBarNode->GetLayoutProperty<NavBarLayoutProperty>();
611         CHECK_NULL_RETURN(navBarLayoutProperty, false);
612         navBarLayoutProperty->UpdateTitleMode(NavigationTitleMode::FREE);
613     }
614 
615     return true;
616 }
617 
CreateNavBarNodeChildsIfNeeded(const RefPtr<NavBarNode> & navBarNode)618 bool NavigationModelNG::CreateNavBarNodeChildsIfNeeded(const RefPtr<NavBarNode>& navBarNode)
619 {
620     // titleBar node
621     if (!navBarNode->GetTitleBarNode()) {
622         int32_t titleBarNodeId = ElementRegister::GetInstance()->MakeUniqueId();
623         ACE_LAYOUT_SCOPED_TRACE("Create[%s][self:%d]", V2::TITLE_BAR_ETS_TAG, titleBarNodeId);
624         auto titleBarNode = TitleBarNode::GetOrCreateTitleBarNode(
625             V2::TITLE_BAR_ETS_TAG, titleBarNodeId, []() { return AceType::MakeRefPtr<TitleBarPattern>(); });
626         navBarNode->AddChild(titleBarNode);
627         navBarNode->SetTitleBarNode(titleBarNode);
628     }
629 
630     // navBar content node
631     if (!navBarNode->GetNavBarContentNode()) {
632         int32_t navBarContentNodeId = ElementRegister::GetInstance()->MakeUniqueId();
633         ACE_LAYOUT_SCOPED_TRACE("Create[%s][self:%d]", V2::NAVBAR_CONTENT_ETS_TAG, navBarContentNodeId);
634         auto navBarContentNode = FrameNode::GetOrCreateFrameNode(V2::NAVBAR_CONTENT_ETS_TAG, navBarContentNodeId,
635             []() { return AceType::MakeRefPtr<LinearLayoutPattern>(true); });
636         auto navBarContentRenderContext = navBarContentNode->GetRenderContext();
637         CHECK_NULL_RETURN(navBarContentRenderContext, false);
638         navBarContentRenderContext->UpdateClipEdge(true);
639         navBarNode->AddChild(navBarContentNode);
640         navBarNode->SetNavBarContentNode(navBarContentNode);
641 
642         if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
643             SafeAreaExpandOpts opts = {.type = SAFE_AREA_TYPE_SYSTEM, .edges = SAFE_AREA_EDGE_ALL};
644             navBarContentNode->GetLayoutProperty()->UpdateSafeAreaExpandOpts(opts);
645         }
646     }
647 
648     // toolBar node
649     if (!navBarNode->GetToolBarNode()) {
650         int32_t toolBarNodeId = ElementRegister::GetInstance()->MakeUniqueId();
651         ACE_LAYOUT_SCOPED_TRACE("Create[%s][self:%d]", V2::TOOL_BAR_ETS_TAG, toolBarNodeId);
652         auto toolBarNode = NavToolbarNode::GetOrCreateToolbarNode(
653             V2::TOOL_BAR_ETS_TAG, toolBarNodeId, []() { return AceType::MakeRefPtr<NavToolbarPattern>(); });
654         toolBarNode->MarkModifyDone();
655         auto property = toolBarNode->GetLayoutProperty();
656         CHECK_NULL_RETURN(property, false);
657         property->UpdateVisibility(VisibleType::GONE);
658         navBarNode->AddChild(toolBarNode);
659         navBarNode->SetToolBarNode(toolBarNode);
660         navBarNode->SetPreToolBarNode(toolBarNode);
661         navBarNode->UpdatePrevToolBarIsCustom(false);
662     }
663 
664     return true;
665 }
666 
CreateContentNodeIfNeeded(const RefPtr<NavigationGroupNode> & navigationGroupNode)667 bool NavigationModelNG::CreateContentNodeIfNeeded(const RefPtr<NavigationGroupNode>& navigationGroupNode)
668 {
669     if (!navigationGroupNode->GetContentNode()) {
670         int32_t contentNodeId = ElementRegister::GetInstance()->MakeUniqueId();
671         ACE_LAYOUT_SCOPED_TRACE("Create[%s][self:%d]", V2::NAVIGATION_CONTENT_ETS_TAG, contentNodeId);
672         auto contentNode = FrameNode::GetOrCreateFrameNode(V2::NAVIGATION_CONTENT_ETS_TAG, contentNodeId,
673             []() { return AceType::MakeRefPtr<NavigationContentPattern>(); });
674         contentNode->GetLayoutProperty()->UpdateAlignment(Alignment::TOP_LEFT);
675         contentNode->GetEventHub<EventHub>()->GetOrCreateGestureEventHub()->SetHitTestMode(
676             HitTestMode::HTMTRANSPARENT_SELF);
677         navigationGroupNode->AddChild(contentNode);
678         navigationGroupNode->SetContentNode(contentNode);
679     }
680 
681     return true;
682 }
683 
CreateDividerNodeIfNeeded(const RefPtr<NavigationGroupNode> & navigationGroupNode)684 bool NavigationModelNG::CreateDividerNodeIfNeeded(const RefPtr<NavigationGroupNode>& navigationGroupNode)
685 {
686     if (!navigationGroupNode->GetDividerNode()) {
687         int32_t dividerNodeId = ElementRegister::GetInstance()->MakeUniqueId();
688         ACE_LAYOUT_SCOPED_TRACE("Create[%s][self:%d]", V2::DIVIDER_ETS_TAG, dividerNodeId);
689         auto dividerNode = FrameNode::GetOrCreateFrameNode(
690             V2::DIVIDER_ETS_TAG, dividerNodeId, []() { return AceType::MakeRefPtr<DividerPattern>(); });
691         navigationGroupNode->AddChild(dividerNode);
692         navigationGroupNode->SetDividerNode(dividerNode);
693 
694         if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
695             SafeAreaExpandOpts opts = {.type = SAFE_AREA_TYPE_SYSTEM, .edges = SAFE_AREA_EDGE_ALL};
696             dividerNode->GetLayoutProperty()->UpdateSafeAreaExpandOpts(opts);
697         }
698 
699         auto dividerLayoutProperty = dividerNode->GetLayoutProperty<DividerLayoutProperty>();
700         CHECK_NULL_RETURN(dividerLayoutProperty, false);
701         dividerLayoutProperty->UpdateStrokeWidth(DIVIDER_WIDTH);
702         dividerLayoutProperty->UpdateVertical(true);
703         auto theme = NavigationGetTheme();
704         CHECK_NULL_RETURN(theme, false);
705         auto dividerRenderProperty = dividerNode->GetPaintProperty<DividerRenderProperty>();
706         CHECK_NULL_RETURN(dividerRenderProperty, false);
707         dividerRenderProperty->UpdateDividerColor(Color::TRANSPARENT);
708         dividerNode->GetRenderContext()->UpdateBackgroundColor(theme->GetNavigationDividerColor());
709     }
710 
711     return true;
712 }
713 
ParseCommonTitle(bool hasSubTitle,bool hasMainTitle,const std::string & subtitle,const std::string & title,bool ignoreMainTitle)714 bool NavigationModelNG::ParseCommonTitle(
715     bool hasSubTitle, bool hasMainTitle, const std::string& subtitle, const std::string& title, bool ignoreMainTitle)
716 {
717     if (!hasSubTitle && !hasMainTitle) {
718         return false;
719     }
720     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
721     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
722     CHECK_NULL_RETURN(navigationGroupNode, false);
723     auto navBarNode = AceType::DynamicCast<NavBarNode>(navigationGroupNode->GetNavBarNode());
724     CHECK_NULL_RETURN(navBarNode, false);
725     auto titleBarNode = AceType::DynamicCast<TitleBarNode>(navBarNode->GetTitleBarNode());
726     CHECK_NULL_RETURN(titleBarNode, false);
727     if (navBarNode->GetPrevTitleIsCustomValue(false)) {
728         titleBarNode->RemoveChild(titleBarNode->GetTitle());
729         titleBarNode->SetTitle(nullptr);
730         auto titleBarLayoutProperty = titleBarNode->GetLayoutProperty<TitleBarLayoutProperty>();
731         CHECK_NULL_RETURN(titleBarLayoutProperty, false);
732         if (titleBarLayoutProperty->HasTitleHeight()) {
733             titleBarLayoutProperty->ResetTitleHeight();
734             navBarNode->GetLayoutProperty<NavBarLayoutProperty>()->ResetTitleMode();
735         }
736     }
737     navBarNode->UpdatePrevTitleIsCustom(false);
738 
739     // create or update main title
740     do {
741         if (ignoreMainTitle) {
742             break;
743         }
744         auto mainTitle = AceType::DynamicCast<FrameNode>(titleBarNode->GetTitle());
745         if (!hasMainTitle) {
746             // remove main title if any.
747             titleBarNode->RemoveChild(mainTitle);
748             titleBarNode->SetTitle(nullptr);
749             break;
750         }
751 
752         if (mainTitle) {
753             // update main title
754             auto textLayoutProperty = mainTitle->GetLayoutProperty<TextLayoutProperty>();
755             textLayoutProperty->UpdateMaxLines(hasSubTitle ? 1 : 2);
756             textLayoutProperty->UpdateContent(title);
757             break;
758         }
759         // create and init main title
760         mainTitle = FrameNode::CreateFrameNode(
761             V2::TEXT_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<TextPattern>());
762         auto textLayoutProperty = mainTitle->GetLayoutProperty<TextLayoutProperty>();
763         auto theme = NavigationGetTheme();
764         textLayoutProperty->UpdateMaxLines(hasSubTitle ? 1 : 2);
765         textLayoutProperty->UpdateContent(title);
766         textLayoutProperty->UpdateTextColor(theme->GetTitleColor());
767         textLayoutProperty->UpdateFontWeight(FontWeight::MEDIUM);
768         textLayoutProperty->UpdateTextOverflow(TextOverflow::ELLIPSIS);
769         titleBarNode->SetTitle(mainTitle);
770         titleBarNode->AddChild(mainTitle);
771     } while (false);
772 
773     // create or update subtitle
774     auto subTitle = AceType::DynamicCast<FrameNode>(titleBarNode->GetSubtitle());
775     if (!hasSubTitle) {
776         // remove subtitle if any.
777         titleBarNode->RemoveChild(subTitle);
778         titleBarNode->SetSubtitle(nullptr);
779         return true;
780     }
781     if (subTitle) {
782         // update subtitle
783         auto textLayoutProperty = subTitle->GetLayoutProperty<TextLayoutProperty>();
784         textLayoutProperty->UpdateContent(subtitle);
785         auto renderContext = subTitle->GetRenderContext();
786         renderContext->UpdateOpacity(1.0);
787     } else {
788         // create and init subtitle
789         subTitle = FrameNode::CreateFrameNode(
790             V2::TEXT_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<TextPattern>());
791         auto textLayoutProperty = subTitle->GetLayoutProperty<TextLayoutProperty>();
792         auto theme = NavigationGetTheme();
793         textLayoutProperty->UpdateContent(subtitle);
794         textLayoutProperty->UpdateFontSize(theme->GetSubTitleFontSize());
795         textLayoutProperty->UpdateTextColor(theme->GetSubTitleColor());
796         textLayoutProperty->UpdateFontWeight(FontWeight::REGULAR); // ohos_id_text_font_family_regular
797         textLayoutProperty->UpdateMaxLines(1);
798         textLayoutProperty->UpdateTextOverflow(TextOverflow::ELLIPSIS);
799         titleBarNode->SetSubtitle(subTitle);
800         titleBarNode->AddChild(subTitle);
801     }
802     return true;
803 }
804 
SetTitle(const std::string & title,bool hasSubTitle)805 void NavigationModelNG::SetTitle(const std::string& title, bool hasSubTitle) {}
806 
SetCustomTitle(const RefPtr<AceType> & customNode)807 void NavigationModelNG::SetCustomTitle(const RefPtr<AceType>& customNode)
808 {
809     auto customTitle = AceType::DynamicCast<NG::UINode>(customNode);
810     CHECK_NULL_VOID(customTitle);
811     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
812     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
813     CHECK_NULL_VOID(navigationGroupNode);
814     auto navBarNode = AceType::DynamicCast<NavBarNode>(navigationGroupNode->GetNavBarNode());
815     CHECK_NULL_VOID(navBarNode);
816     auto titleBarNode = AceType::DynamicCast<TitleBarNode>(navBarNode->GetTitleBarNode());
817     CHECK_NULL_VOID(titleBarNode);
818 
819     if (!navBarNode->GetPrevTitleIsCustomValue(false)) {
820         titleBarNode->RemoveChild(titleBarNode->GetTitle());
821         titleBarNode->RemoveChild(titleBarNode->GetSubtitle());
822         titleBarNode->SetTitle(nullptr);
823         titleBarNode->SetSubtitle(nullptr);
824     }
825     navBarNode->UpdatePrevTitleIsCustom(true);
826 
827     auto currentTitle = titleBarNode->GetTitle();
828     if (currentTitle && customTitle->GetId() == currentTitle->GetId()) {
829         // do nothing
830         return;
831     }
832     // update custom title
833     titleBarNode->RemoveChild(currentTitle);
834     titleBarNode->SetTitle(customTitle);
835     titleBarNode->AddChild(customTitle);
836 }
837 
SetTitleHeight(const Dimension & height,bool isValid)838 void NavigationModelNG::SetTitleHeight(const Dimension& height, bool isValid)
839 {
840     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
841     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
842     CHECK_NULL_VOID(navigationGroupNode);
843     auto navBarNode = AceType::DynamicCast<NavBarNode>(navigationGroupNode->GetNavBarNode());
844     CHECK_NULL_VOID(navBarNode);
845     auto titleBarNode = AceType::DynamicCast<TitleBarNode>(navBarNode->GetTitleBarNode());
846     CHECK_NULL_VOID(titleBarNode);
847     auto titleBarLayoutProperty = titleBarNode->GetLayoutProperty<TitleBarLayoutProperty>();
848     CHECK_NULL_VOID(titleBarLayoutProperty);
849     if (!isValid) {
850         titleBarLayoutProperty->ResetTitleHeight();
851         return;
852     }
853     titleBarLayoutProperty->UpdateTitleHeight(height);
854     SetHideBackButton(true);
855     auto navBarLayoutProperty = navBarNode->GetLayoutProperty<NavBarLayoutProperty>();
856     CHECK_NULL_VOID(navBarLayoutProperty);
857     navBarLayoutProperty->UpdateTitleMode(static_cast<NG::NavigationTitleMode>(NavigationTitleMode::MINI));
858 }
859 
SetTitleMode(NG::NavigationTitleMode mode)860 void NavigationModelNG::SetTitleMode(NG::NavigationTitleMode mode)
861 {
862     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
863     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
864     CHECK_NULL_VOID(navigationGroupNode);
865     auto navBarNode = AceType::DynamicCast<NavBarNode>(navigationGroupNode->GetNavBarNode());
866     CHECK_NULL_VOID(navBarNode);
867     auto navBarLayoutProperty = navBarNode->GetLayoutProperty<NavBarLayoutProperty>();
868     CHECK_NULL_VOID(navBarLayoutProperty);
869     auto titleBarNode = AceType::DynamicCast<TitleBarNode>(navBarNode->GetTitleBarNode());
870     CHECK_NULL_VOID(titleBarNode);
871     auto titleBarLayoutProperty = titleBarNode->GetLayoutProperty<TitleBarLayoutProperty>();
872     CHECK_NULL_VOID(titleBarLayoutProperty);
873     const auto& titleHeightProperty = titleBarLayoutProperty->GetTitleHeight();
874     if (titleHeightProperty.has_value()) {
875         mode = NavigationTitleMode::MINI;
876     }
877     navBarLayoutProperty->UpdateTitleMode(static_cast<NG::NavigationTitleMode>(mode));
878     auto backButtonNode = AceType::DynamicCast<FrameNode>(titleBarNode->GetBackButton());
879     if (mode != NavigationTitleMode::MINI) {
880         // remove back button if any.
881         titleBarNode->RemoveChild(backButtonNode);
882         titleBarNode->SetBackButton(nullptr);
883         return;
884     }
885 
886     if (backButtonNode != nullptr) {
887         return;
888     }
889     // create back button
890     backButtonNode = FrameNode::CreateFrameNode(
891         V2::BACK_BUTTON_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<ButtonPattern>());
892     auto gestureEventHub = backButtonNode->GetOrCreateGestureEventHub();
893     CHECK_NULL_VOID(gestureEventHub);
894     auto context = PipelineContext::GetCurrentContext();
895     auto clickCallback = [weakContext = WeakPtr<PipelineContext>(context)](GestureEvent& /* info */) {
896         auto context = weakContext.Upgrade();
897         CHECK_NULL_VOID(context);
898         bool result = context->OnBackPressed();
899         if (!result) {
900             auto delegate = EngineHelper::GetCurrentDelegate();
901             CHECK_NULL_VOID(delegate);
902             delegate->Back("");
903         }
904     };
905     gestureEventHub->AddClickEvent(AceType::MakeRefPtr<ClickEvent>(clickCallback));
906     auto buttonPattern = backButtonNode->GetPattern<ButtonPattern>();
907     CHECK_NULL_VOID(buttonPattern);
908     buttonPattern->SetSkipColorConfigurationUpdate();
909     auto backButtonLayoutProperty = backButtonNode->GetLayoutProperty<ButtonLayoutProperty>();
910     CHECK_NULL_VOID(backButtonLayoutProperty);
911     backButtonLayoutProperty->UpdateUserDefinedIdealSize(
912         CalcSize(CalcLength(BACK_BUTTON_SIZE), CalcLength(BACK_BUTTON_SIZE)));
913     backButtonLayoutProperty->UpdateType(ButtonType::NORMAL);
914     backButtonLayoutProperty->UpdateBorderRadius(BorderRadiusProperty(BUTTON_RADIUS_SIZE));
915     backButtonLayoutProperty->UpdateMeasureType(MeasureType::MATCH_PARENT);
916     auto renderContext = backButtonNode->GetRenderContext();
917     CHECK_NULL_VOID(renderContext);
918     renderContext->UpdateBackgroundColor(Color::TRANSPARENT);
919 
920     auto eventHub = backButtonNode->GetOrCreateInputEventHub();
921     CHECK_NULL_VOID(eventHub);
922 
923     PaddingProperty padding;
924     padding.left = CalcLength(BUTTON_PADDING);
925     padding.right = CalcLength(BUTTON_PADDING);
926     padding.top = CalcLength(BUTTON_PADDING);
927     padding.bottom = CalcLength(BUTTON_PADDING);
928     backButtonLayoutProperty->UpdatePadding(padding);
929 
930     auto backButtonImageNode = FrameNode::CreateFrameNode(V2::BACK_BUTTON_IMAGE_ETS_TAG,
931         ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<ImagePattern>());
932     CHECK_NULL_VOID(backButtonImageNode);
933     auto theme = NavigationGetTheme();
934     CHECK_NULL_VOID(theme);
935     ImageSourceInfo imageSourceInfo;
936     imageSourceInfo.SetResourceId(theme->GetBackResourceId());
937     auto backButtonImageLayoutProperty = backButtonImageNode->GetLayoutProperty<ImageLayoutProperty>();
938     CHECK_NULL_VOID(backButtonImageLayoutProperty);
939 
940     auto navigationEventHub = navigationGroupNode->GetEventHub<EventHub>();
941     CHECK_NULL_VOID(navigationEventHub);
942     if (!navigationEventHub->IsEnabled()) {
943         imageSourceInfo.SetFillColor(theme->GetBackButtonIconColor().BlendOpacity(theme->GetAlphaDisabled()));
944     } else {
945         imageSourceInfo.SetFillColor(theme->GetBackButtonIconColor());
946     }
947     backButtonImageLayoutProperty->UpdateImageSourceInfo(imageSourceInfo);
948     backButtonImageLayoutProperty->UpdateMeasureType(MeasureType::MATCH_PARENT);
949 
950     backButtonImageNode->MountToParent(backButtonNode);
951     backButtonImageNode->MarkModifyDone();
952     backButtonNode->MarkModifyDone();
953     titleBarNode->SetBackButton(backButtonNode);
954     titleBarNode->AddChild(backButtonNode, 0);
955 }
956 
SetSubtitle(const std::string & subtitle)957 void NavigationModelNG::SetSubtitle(const std::string& subtitle)
958 {
959     ParseCommonTitle(true, false, subtitle, "", true);
960 }
961 
SetHideTitleBar(bool hideTitleBar)962 void NavigationModelNG::SetHideTitleBar(bool hideTitleBar)
963 {
964     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
965     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
966     CHECK_NULL_VOID(navigationGroupNode);
967     auto navBarNode = AceType::DynamicCast<NavBarNode>(navigationGroupNode->GetNavBarNode());
968     CHECK_NULL_VOID(navBarNode);
969     auto navBarLayoutProperty = navBarNode->GetLayoutProperty<NavBarLayoutProperty>();
970     CHECK_NULL_VOID(navBarLayoutProperty);
971     navBarLayoutProperty->UpdateHideTitleBar(hideTitleBar);
972 }
973 
SetHideNavBar(bool hideNavBar)974 void NavigationModelNG::SetHideNavBar(bool hideNavBar)
975 {
976     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
977     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
978     CHECK_NULL_VOID(navigationGroupNode);
979     auto pattern = navigationGroupNode->GetPattern<NavigationPattern>();
980     CHECK_NULL_VOID(pattern);
981     auto navigationLayoutProperty = navigationGroupNode->GetLayoutProperty<NavigationLayoutProperty>();
982     CHECK_NULL_VOID(navigationLayoutProperty);
983 
984     auto lastHideNavBarValue = navigationLayoutProperty->GetHideNavBar();
985     if (lastHideNavBarValue.has_value()) {
986         pattern->SetNavBarVisibilityChange(hideNavBar != lastHideNavBarValue.value());
987     } else {
988         pattern->SetNavBarVisibilityChange(true);
989     }
990     auto navBarNode = AceType::DynamicCast<FrameNode>(navigationGroupNode->GetNavBarNode());
991     auto layoutProperty = navBarNode->GetLayoutProperty();
992     layoutProperty->UpdateVisibility(hideNavBar ? VisibleType::INVISIBLE : VisibleType::VISIBLE, true);
993     navBarNode->SetJSViewActive(!hideNavBar);
994     if (pattern->GetNavBarVisibilityChange()) {
995         navBarNode->MarkDirtyNode();
996     }
997     ACE_UPDATE_LAYOUT_PROPERTY(NavigationLayoutProperty, HideNavBar, hideNavBar);
998 }
999 
SetBackButtonIcon(const std::string & src,bool noPixMap,RefPtr<PixelMap> & pixMap,const std::string & bundleName,const std::string & moduleName)1000 void NavigationModelNG::SetBackButtonIcon(const std::string& src, bool noPixMap, RefPtr<PixelMap>& pixMap,
1001     const std::string& bundleName, const std::string& moduleName)
1002 {
1003     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
1004     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
1005     CHECK_NULL_VOID(navigationGroupNode);
1006 
1007     auto navBarNode = AceType::DynamicCast<NavBarNode>(navigationGroupNode->GetNavBarNode());
1008     CHECK_NULL_VOID(navBarNode);
1009     auto titleBarNode = AceType::DynamicCast<TitleBarNode>(navBarNode->GetTitleBarNode());
1010     CHECK_NULL_VOID(titleBarNode);
1011     auto titleBarLayoutProperty = titleBarNode->GetLayoutProperty<TitleBarLayoutProperty>();
1012     CHECK_NULL_VOID(titleBarLayoutProperty);
1013     ImageSourceInfo imageSourceInfo(src, bundleName, moduleName);
1014     ACE_UPDATE_LAYOUT_PROPERTY(NavigationLayoutProperty, NoPixMap, noPixMap);
1015     ACE_UPDATE_LAYOUT_PROPERTY(NavigationLayoutProperty, ImageSource, imageSourceInfo);
1016     ACE_UPDATE_LAYOUT_PROPERTY(NavigationLayoutProperty, PixelMap, pixMap);
1017     titleBarLayoutProperty->UpdateImageSource(imageSourceInfo);
1018     titleBarLayoutProperty->UpdateNoPixMap(noPixMap);
1019     titleBarLayoutProperty->UpdatePixelMap(pixMap);
1020     titleBarNode->MarkModifyDone();
1021 }
1022 
SetHideBackButton(bool hideBackButton)1023 void NavigationModelNG::SetHideBackButton(bool hideBackButton)
1024 {
1025     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
1026     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
1027     CHECK_NULL_VOID(navigationGroupNode);
1028     auto navBarNode = AceType::DynamicCast<NavBarNode>(navigationGroupNode->GetNavBarNode());
1029     CHECK_NULL_VOID(navBarNode);
1030     auto navBarLayoutProperty = navBarNode->GetLayoutProperty<NavBarLayoutProperty>();
1031     CHECK_NULL_VOID(navBarLayoutProperty);
1032     navBarLayoutProperty->UpdateHideBackButton(hideBackButton);
1033 }
1034 
SetHideToolBar(bool hideToolBar)1035 void NavigationModelNG::SetHideToolBar(bool hideToolBar)
1036 {
1037     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
1038     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
1039     CHECK_NULL_VOID(navigationGroupNode);
1040     auto navBarNode = AceType::DynamicCast<NavBarNode>(navigationGroupNode->GetNavBarNode());
1041     CHECK_NULL_VOID(navBarNode);
1042     auto navBarLayoutProperty = navBarNode->GetLayoutProperty<NavBarLayoutProperty>();
1043     CHECK_NULL_VOID(navBarLayoutProperty);
1044     navBarLayoutProperty->UpdateHideToolBar(hideToolBar);
1045 }
1046 
SetCustomToolBar(const RefPtr<AceType> & customNode)1047 void NavigationModelNG::SetCustomToolBar(const RefPtr<AceType>& customNode)
1048 {
1049     auto customToolBar = AceType::DynamicCast<NG::UINode>(customNode);
1050     CHECK_NULL_VOID(customToolBar);
1051     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
1052     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
1053     CHECK_NULL_VOID(navigationGroupNode);
1054     auto navBarNode = AceType::DynamicCast<NavBarNode>(navigationGroupNode->GetNavBarNode());
1055     CHECK_NULL_VOID(navBarNode);
1056     if (navBarNode->GetPrevToolBarIsCustom().value_or(false)) {
1057         if (customToolBar->GetId() == navBarNode->GetToolBarNode()->GetId()) {
1058             navBarNode->UpdateToolBarNodeOperation(ChildNodeOperation::NONE);
1059             navBarNode->UpdatePrevToolBarIsCustom(true);
1060             return;
1061         }
1062     }
1063     navBarNode->UpdateToolBarNodeOperation(ChildNodeOperation::REPLACE);
1064     auto toolBarNode = AceType::DynamicCast<NavToolbarNode>(navBarNode->GetToolBarNode());
1065     CHECK_NULL_VOID(toolBarNode);
1066     toolBarNode->Clean();
1067     customToolBar->MountToParent(toolBarNode);
1068     navBarNode->UpdatePrevToolBarIsCustom(true);
1069     toolBarNode->SetHasValidContent(true);
1070     auto property = toolBarNode->GetLayoutProperty();
1071     CHECK_NULL_VOID(property);
1072     property->UpdateVisibility(VisibleType::VISIBLE);
1073 }
1074 
NeedSetItems()1075 bool NavigationModelNG::NeedSetItems()
1076 {
1077     return true;
1078 }
1079 
SetToolBarItems(std::vector<NG::BarItem> && toolBarItems)1080 void NavigationModelNG::SetToolBarItems(std::vector<NG::BarItem>&& toolBarItems)
1081 {
1082     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
1083     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
1084     CHECK_NULL_VOID(navigationGroupNode);
1085     auto navBarNode = AceType::DynamicCast<NavBarNode>(navigationGroupNode->GetNavBarNode());
1086     CHECK_NULL_VOID(navBarNode);
1087     if (navBarNode->GetPrevToolBarIsCustom().value_or(false)) {
1088         navBarNode->UpdateToolBarNodeOperation(ChildNodeOperation::REPLACE);
1089     } else {
1090         if (navBarNode->GetPreToolBarNode() &&
1091             static_cast<int32_t>(navBarNode->GetPreToolBarNode()->GetChildren().size()) != 0) {
1092             UpdateOldBarItems(navBarNode->GetPreToolBarNode(), toolBarItems);
1093             navBarNode->SetToolBarNode(navBarNode->GetPreToolBarNode());
1094             navBarNode->UpdateToolBarNodeOperation(ChildNodeOperation::NONE);
1095             return;
1096         }
1097         navBarNode->UpdateToolBarNodeOperation(ChildNodeOperation::REPLACE);
1098     }
1099     auto toolBarNode = AceType::DynamicCast<NavToolbarNode>(navBarNode->GetPreToolBarNode());
1100     CHECK_NULL_VOID(toolBarNode);
1101     auto rowProperty = toolBarNode->GetLayoutProperty<LinearLayoutProperty>();
1102     CHECK_NULL_VOID(rowProperty);
1103     rowProperty->UpdateMainAxisAlign(FlexAlign::SPACE_EVENLY);
1104     for (const auto& toolBarItem : toolBarItems) {
1105         int32_t barItemNodeId = ElementRegister::GetInstance()->MakeUniqueId();
1106         auto barItemNode = AceType::MakeRefPtr<BarItemNode>(V2::BAR_ITEM_ETS_TAG, barItemNodeId);
1107         barItemNode->InitializePatternAndContext();
1108         UpdateBarItemNodeWithItem(barItemNode, toolBarItem);
1109         toolBarNode->AddChild(barItemNode);
1110     }
1111     bool hasValidContent = !toolBarNode->GetChildren().empty();
1112     toolBarNode->SetHasValidContent(hasValidContent);
1113     rowProperty->UpdateVisibility(hasValidContent ? VisibleType::VISIBLE : VisibleType::GONE);
1114     navBarNode->SetToolBarNode(toolBarNode);
1115     navBarNode->SetPreToolBarNode(toolBarNode);
1116     navBarNode->UpdatePrevToolBarIsCustom(false);
1117 }
1118 
SetToolbarConfiguration(std::vector<NG::BarItem> && toolBarItems)1119 void NavigationModelNG::SetToolbarConfiguration(std::vector<NG::BarItem>&& toolBarItems)
1120 {
1121     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
1122     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
1123     CHECK_NULL_VOID(navigationGroupNode);
1124     auto navBarNode = AceType::DynamicCast<NavBarNode>(navigationGroupNode->GetNavBarNode());
1125     CHECK_NULL_VOID(navBarNode);
1126     if (navBarNode->GetPrevToolBarIsCustom().value_or(false)) {
1127         navBarNode->UpdateToolBarNodeOperation(ChildNodeOperation::REPLACE);
1128     } else {
1129         auto toolbarNode = AceType::DynamicCast<NavToolbarNode>(navBarNode->GetPreToolBarNode());
1130         auto containerNode = toolbarNode->GetToolbarContainerNode();
1131         if (toolbarNode && containerNode) {
1132             navBarNode->UpdateToolBarNodeOperation(ChildNodeOperation::REPLACE);
1133             auto preToolbarNode = navBarNode->GetPreToolBarNode();
1134             preToolbarNode->RemoveChild(containerNode);
1135             navBarNode->RemoveChild(navBarNode->GetToolBarDividerNode());
1136         } else {
1137             navBarNode->UpdateToolBarNodeOperation(ChildNodeOperation::ADD);
1138         }
1139     }
1140     auto toolBarNode = AceType::DynamicCast<NavToolbarNode>(navBarNode->GetPreToolBarNode());
1141     CHECK_NULL_VOID(toolBarNode);
1142     toolBarNode->SetIsUseNewToolbar(true);
1143     auto rowProperty = toolBarNode->GetLayoutProperty<LinearLayoutProperty>();
1144     CHECK_NULL_VOID(rowProperty);
1145     rowProperty->UpdateMainAxisAlign(FlexAlign::CENTER);
1146 
1147     if (Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN) ||
1148         !SystemProperties::GetNavigationBlurEnabled()) {
1149         CreateToolBarDividerNode(navBarNode);
1150     }
1151 
1152     auto containerNode = CreateToolbarItemsContainerNode(toolBarNode);
1153     CHECK_NULL_VOID(containerNode);
1154     toolBarNode->SetToolbarContainerNode(containerNode);
1155     bool needMoreButton = toolBarItems.size() > MAXIMUM_TOOLBAR_ITEMS_IN_BAR ? true : false;
1156     uint32_t count = 0;
1157     std::vector<OptionParam> params;
1158     for (const auto& toolBarItem : toolBarItems) {
1159         ++count;
1160         if (needMoreButton && (count > MAXIMUM_TOOLBAR_ITEMS_IN_BAR - 1)) {
1161             params.push_back({ toolBarItem.text.value_or(""), toolBarItem.icon.value_or(""), toolBarItem.action });
1162         } else {
1163             auto toolBarItemNode =
1164                 CreateToolbarItemInContainer(toolBarItem, toolBarItems.size(), count, needMoreButton);
1165             CHECK_NULL_VOID(toolBarItemNode);
1166             containerNode->AddChild(toolBarItemNode);
1167         }
1168     }
1169 
1170     bool hasValidContent = !containerNode->GetChildren().empty();
1171     toolBarNode->SetHasValidContent(hasValidContent);
1172     rowProperty->UpdateVisibility(hasValidContent ? VisibleType::VISIBLE : VisibleType::GONE);
1173 
1174     if (needMoreButton) {
1175         int32_t barItemNodeId = ElementRegister::GetInstance()->MakeUniqueId();
1176         auto barItemNode = AceType::MakeRefPtr<BarItemNode>(V2::BAR_ITEM_ETS_TAG, barItemNodeId);
1177         barItemNode->InitializePatternAndContext();
1178         auto barItemLayoutProperty = barItemNode->GetLayoutProperty();
1179         CHECK_NULL_VOID(barItemLayoutProperty);
1180         barItemLayoutProperty->UpdateMeasureType(MeasureType::MATCH_PARENT);
1181         BuildToolbarMoreItemNode(barItemNode);
1182         MenuParam menuParam;
1183         menuParam.isShowInSubWindow = false;
1184         auto barMenuNode = MenuView::Create(
1185             std::move(params), barItemNodeId, V2::BAR_ITEM_ETS_TAG, MenuType::NAVIGATION_MENU, menuParam);
1186         auto toolBarItemNode = CreateToolbarMoreMenuNode(barItemNode);
1187         CHECK_NULL_VOID(toolBarItemNode);
1188         BuildToolbarMoreMenuNodeAction(barItemNode, barMenuNode, toolBarItemNode);
1189         containerNode->AddChild(toolBarItemNode);
1190         navBarNode->SetToolbarMenuNode(barMenuNode);
1191     }
1192     navBarNode->SetToolBarNode(toolBarNode);
1193     navBarNode->SetPreToolBarNode(toolBarNode);
1194     navBarNode->UpdatePrevToolBarIsCustom(false);
1195     navBarNode->SetNarBarUseToolbarConfiguration(true);
1196 
1197     auto navBarPattern = navBarNode->GetPattern<NavBarPattern>();
1198     CHECK_NULL_VOID(navBarPattern);
1199     navBarPattern->SetToolBarMenuItems(toolBarItems);
1200 }
1201 
SetMenuItems(std::vector<NG::BarItem> && menuItems)1202 void NavigationModelNG::SetMenuItems(std::vector<NG::BarItem>&& menuItems)
1203 {
1204     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
1205     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
1206     CHECK_NULL_VOID(navigationGroupNode);
1207     auto navBarNode = AceType::DynamicCast<NavBarNode>(navigationGroupNode->GetNavBarNode());
1208     CHECK_NULL_VOID(navBarNode);
1209     auto titleBarNode = AceType::DynamicCast<TitleBarNode>(navBarNode->GetTitleBarNode());
1210     CHECK_NULL_VOID(titleBarNode);
1211     // if previous menu is custom, just remove it and create new menu, otherwise update old menu
1212     if (navBarNode->GetPrevMenuIsCustom().value_or(false)) {
1213         navBarNode->UpdateMenuNodeOperation(ChildNodeOperation::REPLACE);
1214     } else {
1215         if (navBarNode->GetMenu()) {
1216             navBarNode->UpdateMenuNodeOperation(ChildNodeOperation::REPLACE);
1217         } else {
1218             navBarNode->UpdateMenuNodeOperation(ChildNodeOperation::ADD);
1219         }
1220     }
1221     auto navBarPattern = navBarNode->GetPattern<NavBarPattern>();
1222     CHECK_NULL_VOID(navBarPattern);
1223     navBarPattern->SetTitleBarMenuItems(menuItems);
1224     navBarPattern->SetMenuNodeId(ElementRegister::GetInstance()->MakeUniqueId());
1225     navBarPattern->SetLandscapeMenuNodeId(ElementRegister::GetInstance()->MakeUniqueId());
1226     navBarNode->UpdatePrevMenuIsCustom(false);
1227 }
1228 
SetCustomMenu(const RefPtr<AceType> & customNode)1229 void NavigationModelNG::SetCustomMenu(const RefPtr<AceType>& customNode)
1230 {
1231     auto customMenu = AceType::DynamicCast<NG::UINode>(customNode);
1232     CHECK_NULL_VOID(customMenu);
1233     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
1234     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
1235     CHECK_NULL_VOID(navigationGroupNode);
1236     auto navBarNode = AceType::DynamicCast<NavBarNode>(navigationGroupNode->GetNavBarNode());
1237     CHECK_NULL_VOID(navBarNode);
1238     auto titleBarNode = AceType::DynamicCast<TitleBarNode>(navBarNode->GetTitleBarNode());
1239     CHECK_NULL_VOID(titleBarNode);
1240     // if previous menu exists, remove it if their ids are not the same
1241     // if previous node is not custom, their ids must not be the same
1242     if (navBarNode->GetMenu()) {
1243         if (customMenu->GetId() == navBarNode->GetMenu()->GetId()) {
1244             navBarNode->UpdateMenuNodeOperation(ChildNodeOperation::NONE);
1245             return;
1246         }
1247         navBarNode->SetMenu(customMenu);
1248         navBarNode->UpdatePrevMenuIsCustom(true);
1249         navBarNode->UpdateMenuNodeOperation(ChildNodeOperation::REPLACE);
1250         return;
1251     }
1252     navBarNode->SetMenu(customMenu);
1253     navBarNode->UpdatePrevMenuIsCustom(true);
1254     navBarNode->UpdateMenuNodeOperation(ChildNodeOperation::ADD);
1255 }
1256 
SetOnTitleModeChange(std::function<void (NG::NavigationTitleMode)> && onTitleModeChange,std::function<void (const BaseEventInfo * baseInfo)> && eventInfo)1257 void NavigationModelNG::SetOnTitleModeChange(std::function<void(NG::NavigationTitleMode)>&& onTitleModeChange,
1258     std::function<void(const BaseEventInfo* baseInfo)>&& eventInfo)
1259 {
1260     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
1261     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
1262     CHECK_NULL_VOID(navigationGroupNode);
1263     auto eventHub = navigationGroupNode->GetEventHub<NavigationEventHub>();
1264     CHECK_NULL_VOID(eventHub);
1265     eventHub->SetOnTitleModeChange(std::move(eventInfo));
1266 }
1267 
SetUsrNavigationMode(NavigationMode mode)1268 void NavigationModelNG::SetUsrNavigationMode(NavigationMode mode)
1269 {
1270     ACE_UPDATE_LAYOUT_PROPERTY(NavigationLayoutProperty, UsrNavigationMode, mode);
1271 }
1272 
SetNavBarPosition(NG::NavBarPosition mode)1273 void NavigationModelNG::SetNavBarPosition(NG::NavBarPosition mode)
1274 {
1275     ACE_UPDATE_LAYOUT_PROPERTY(NavigationLayoutProperty, NavBarPosition, static_cast<NG::NavBarPosition>(mode));
1276 }
1277 
SetNavBarWidth(const Dimension & value)1278 void NavigationModelNG::SetNavBarWidth(const Dimension& value)
1279 {
1280     ACE_UPDATE_LAYOUT_PROPERTY(NavigationLayoutProperty, NavBarWidth, value);
1281     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
1282     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
1283     CHECK_NULL_VOID(navigationGroupNode);
1284     auto navigationPattern = navigationGroupNode->GetPattern<NavigationPattern>();
1285     CHECK_NULL_VOID(navigationPattern);
1286     navigationPattern->SetUserSetNavBarWidthFlag(true);
1287     if (navigationPattern->GetInitNavBarWidth() != value) {
1288         navigationPattern->SetInitNavBarWidth(value);
1289     }
1290 }
1291 
SetMinNavBarWidth(const Dimension & value)1292 void NavigationModelNG::SetMinNavBarWidth(const Dimension& value)
1293 {
1294     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
1295     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
1296     CHECK_NULL_VOID(navigationGroupNode);
1297     auto navigationPattern = navigationGroupNode->GetPattern<NavigationPattern>();
1298     CHECK_NULL_VOID(navigationPattern);
1299     navigationPattern->SetIfNeedInit(true);
1300     ACE_UPDATE_LAYOUT_PROPERTY(NavigationLayoutProperty, MinNavBarWidth, value);
1301 }
1302 
SetMaxNavBarWidth(const Dimension & value)1303 void NavigationModelNG::SetMaxNavBarWidth(const Dimension& value)
1304 {
1305     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
1306     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
1307     CHECK_NULL_VOID(navigationGroupNode);
1308     auto navigationPattern = navigationGroupNode->GetPattern<NavigationPattern>();
1309     CHECK_NULL_VOID(navigationPattern);
1310     navigationPattern->SetIfNeedInit(true);
1311     ACE_UPDATE_LAYOUT_PROPERTY(NavigationLayoutProperty, MaxNavBarWidth, value);
1312 }
1313 
SetMinContentWidth(const Dimension & value)1314 void NavigationModelNG::SetMinContentWidth(const Dimension& value)
1315 {
1316     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
1317     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
1318     CHECK_NULL_VOID(navigationGroupNode);
1319     auto navigationPattern = navigationGroupNode->GetPattern<NavigationPattern>();
1320     CHECK_NULL_VOID(navigationPattern);
1321     navigationPattern->SetIfNeedInit(true);
1322     ACE_UPDATE_LAYOUT_PROPERTY(NavigationLayoutProperty, MinContentWidth, value);
1323 }
1324 
SetOnNavBarStateChange(std::function<void (bool)> && onNavBarStateChange)1325 void NavigationModelNG::SetOnNavBarStateChange(std::function<void(bool)>&& onNavBarStateChange)
1326 {
1327     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
1328     auto navigationEventHub = AceType::DynamicCast<NavigationEventHub>(frameNode->GetEventHub<EventHub>());
1329     CHECK_NULL_VOID(navigationEventHub);
1330     navigationEventHub->SetOnNavBarStateChange(std::move(onNavBarStateChange));
1331 }
1332 
SetOnNavigationModeChange(std::function<void (NavigationMode)> && modeChange)1333 void NavigationModelNG::SetOnNavigationModeChange(std::function<void(NavigationMode)>&& modeChange)
1334 {
1335     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
1336     auto navigationEventHub = AceType::DynamicCast<NavigationEventHub>(frameNode->GetEventHub<EventHub>());
1337     CHECK_NULL_VOID(navigationEventHub);
1338     navigationEventHub->SetOnNavigationModeChange(std::move(modeChange));
1339 }
1340 
SetNavigationMode(NavigationMode mode)1341 void NavigationModelNG::SetNavigationMode(NavigationMode mode)
1342 {
1343     ACE_UPDATE_LAYOUT_PROPERTY(NavigationLayoutProperty, NavigationMode, mode);
1344 }
1345 
SetNavigationStack(const RefPtr<NG::NavigationStack> & navigationStack)1346 void NavigationModelNG::SetNavigationStack(const RefPtr<NG::NavigationStack>& navigationStack)
1347 {
1348     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
1349     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
1350     CHECK_NULL_VOID(navigationGroupNode);
1351     auto pattern = navigationGroupNode->GetPattern<NavigationPattern>();
1352     CHECK_NULL_VOID(pattern);
1353     const auto& stack = pattern->GetNavigationStack();
1354     if (stack) {
1355         stack->UpdateStackInfo(navigationStack);
1356     } else {
1357         pattern->SetNavigationStack(navigationStack);
1358     }
1359 }
1360 
SetNavigationStackWithCreatorAndUpdater(std::function<RefPtr<NG::NavigationStack> ()> creator,std::function<void (RefPtr<NG::NavigationStack>)> updater)1361 void NavigationModelNG::SetNavigationStackWithCreatorAndUpdater(
1362     std::function<RefPtr<NG::NavigationStack>()> creator, std::function<void(RefPtr<NG::NavigationStack>)> updater)
1363 {
1364     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
1365     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
1366     CHECK_NULL_VOID(navigationGroupNode);
1367     auto pattern = navigationGroupNode->GetPattern<NavigationPattern>();
1368     CHECK_NULL_VOID(pattern);
1369     RefPtr<NavigationStack> stack = pattern->GetNavigationStack();
1370     if (!stack) {
1371         stack = creator();
1372         pattern->SetNavigationStack(stack);
1373     }
1374     updater(stack);
1375 }
1376 
SetNavigationStack()1377 void NavigationModelNG::SetNavigationStack()
1378 {
1379     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
1380     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
1381     CHECK_NULL_VOID(navigationGroupNode);
1382     auto pattern = navigationGroupNode->GetPattern<NavigationPattern>();
1383     CHECK_NULL_VOID(pattern);
1384     auto navigationStack = pattern->GetNavigationStack();
1385     if (!navigationStack) {
1386         auto navigationStack = AceType::MakeRefPtr<NavigationStack>();
1387         pattern->SetNavigationStack(navigationStack);
1388     }
1389 }
1390 
SetNavigationStackProvided(bool provided)1391 void NavigationModelNG::SetNavigationStackProvided(bool provided)
1392 {
1393     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
1394     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
1395     CHECK_NULL_VOID(navigationGroupNode);
1396     auto pattern = navigationGroupNode->GetPattern<NavigationPattern>();
1397     CHECK_NULL_VOID(pattern);
1398     pattern->SetNavigationStackProvided(provided);
1399 }
1400 
SetNavDestination(std::function<void (std::string)> && builder)1401 void NavigationModelNG::SetNavDestination(std::function<void(std::string)>&& builder)
1402 {
1403     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
1404     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
1405     CHECK_NULL_VOID(navigationGroupNode);
1406     auto pattern = navigationGroupNode->GetPattern<NavigationPattern>();
1407     CHECK_NULL_VOID(pattern);
1408     pattern->SetNavDestination(std::move(builder));
1409 }
1410 
GetNavigationStack()1411 RefPtr<NG::NavigationStack> NavigationModelNG::GetNavigationStack()
1412 {
1413     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
1414     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
1415     CHECK_NULL_RETURN(navigationGroupNode, nullptr);
1416     auto pattern = navigationGroupNode->GetPattern<NavigationPattern>();
1417     CHECK_NULL_RETURN(pattern, nullptr);
1418     return pattern->GetNavigationStack();
1419 }
1420 
SetMenuCount(int32_t menuCount)1421 void NavigationModelNG::SetMenuCount(int32_t menuCount)
1422 {
1423     return;
1424 }
1425 
SetHideToolBar(FrameNode * frameNode,bool hideToolBar)1426 void NavigationModelNG::SetHideToolBar(FrameNode* frameNode, bool hideToolBar)
1427 {
1428     CHECK_NULL_VOID(frameNode);
1429     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
1430     CHECK_NULL_VOID(navigationGroupNode);
1431     auto navBarNode = AceType::DynamicCast<NavBarNode>(navigationGroupNode->GetNavBarNode());
1432     CHECK_NULL_VOID(navBarNode);
1433     auto navBarLayoutProperty = navBarNode->GetLayoutProperty<NavBarLayoutProperty>();
1434     CHECK_NULL_VOID(navBarLayoutProperty);
1435     navBarLayoutProperty->UpdateHideToolBar(hideToolBar);
1436 }
1437 
SetMinContentWidth(FrameNode * frameNode,const Dimension & value)1438 void NavigationModelNG::SetMinContentWidth(FrameNode* frameNode, const Dimension& value)
1439 {
1440     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
1441     CHECK_NULL_VOID(navigationGroupNode);
1442     auto navigationPattern = navigationGroupNode->GetPattern<NavigationPattern>();
1443     CHECK_NULL_VOID(navigationPattern);
1444     navigationPattern->SetIfNeedInit(true);
1445     ACE_UPDATE_NODE_LAYOUT_PROPERTY(NavigationLayoutProperty, MinContentWidth, value, frameNode);
1446 }
1447 
SetMinNavBarWidth(FrameNode * frameNode,const Dimension & value)1448 void NavigationModelNG::SetMinNavBarWidth(FrameNode* frameNode, const Dimension& value)
1449 {
1450     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
1451     CHECK_NULL_VOID(navigationGroupNode);
1452     auto navigationPattern = navigationGroupNode->GetPattern<NavigationPattern>();
1453     CHECK_NULL_VOID(navigationPattern);
1454     navigationPattern->SetIfNeedInit(true);
1455     ACE_UPDATE_NODE_LAYOUT_PROPERTY(NavigationLayoutProperty, MinNavBarWidth, value, frameNode);
1456 }
1457 
SetMaxNavBarWidth(FrameNode * frameNode,const Dimension & value)1458 void NavigationModelNG::SetMaxNavBarWidth(FrameNode* frameNode, const Dimension& value)
1459 {
1460     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
1461     CHECK_NULL_VOID(navigationGroupNode);
1462     auto navigationPattern = navigationGroupNode->GetPattern<NavigationPattern>();
1463     CHECK_NULL_VOID(navigationPattern);
1464     navigationPattern->SetIfNeedInit(true);
1465     ACE_UPDATE_NODE_LAYOUT_PROPERTY(NavigationLayoutProperty, MaxNavBarWidth, value, frameNode);
1466 }
1467 
SetNavBarWidth(FrameNode * frameNode,const Dimension & value)1468 void NavigationModelNG::SetNavBarWidth(FrameNode* frameNode, const Dimension& value)
1469 {
1470     CHECK_NULL_VOID(frameNode);
1471     ACE_UPDATE_NODE_LAYOUT_PROPERTY(NavigationLayoutProperty, NavBarWidth, value, frameNode);
1472     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
1473     CHECK_NULL_VOID(navigationGroupNode);
1474     auto navigationPattern = navigationGroupNode->GetPattern<NavigationPattern>();
1475     CHECK_NULL_VOID(navigationPattern);
1476     navigationPattern->SetUserSetNavBarWidthFlag(true);
1477 }
1478 
SetNavBarPosition(FrameNode * frameNode,NG::NavBarPosition mode)1479 void NavigationModelNG::SetNavBarPosition(FrameNode* frameNode, NG::NavBarPosition mode)
1480 {
1481     ACE_UPDATE_NODE_LAYOUT_PROPERTY(
1482         NavigationLayoutProperty, NavBarPosition, static_cast<NG::NavBarPosition>(mode), frameNode);
1483 }
1484 
SetUsrNavigationMode(FrameNode * frameNode,NavigationMode mode)1485 void NavigationModelNG::SetUsrNavigationMode(FrameNode* frameNode, NavigationMode mode)
1486 {
1487     ACE_UPDATE_NODE_LAYOUT_PROPERTY(NavigationLayoutProperty, UsrNavigationMode, mode, frameNode);
1488 }
1489 
SetBackButtonIcon(FrameNode * frameNode,const std::string & src,bool noPixMap,RefPtr<PixelMap> & pixMap)1490 void NavigationModelNG::SetBackButtonIcon(
1491     FrameNode* frameNode, const std::string& src, bool noPixMap, RefPtr<PixelMap>& pixMap)
1492 {
1493     CHECK_NULL_VOID(frameNode);
1494     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
1495     CHECK_NULL_VOID(navigationGroupNode);
1496 
1497     auto navBarNode = AceType::DynamicCast<NavBarNode>(navigationGroupNode->GetNavBarNode());
1498     CHECK_NULL_VOID(navBarNode);
1499     auto titleBarNode = AceType::DynamicCast<TitleBarNode>(navBarNode->GetTitleBarNode());
1500     CHECK_NULL_VOID(titleBarNode);
1501     auto titleBarLayoutProperty = titleBarNode->GetLayoutProperty<TitleBarLayoutProperty>();
1502     CHECK_NULL_VOID(titleBarLayoutProperty);
1503     ImageSourceInfo imageSourceInfo(src);
1504     ACE_UPDATE_NODE_LAYOUT_PROPERTY(NavigationLayoutProperty, NoPixMap, noPixMap, frameNode);
1505     ACE_UPDATE_NODE_LAYOUT_PROPERTY(NavigationLayoutProperty, ImageSource, imageSourceInfo, frameNode);
1506     ACE_UPDATE_NODE_LAYOUT_PROPERTY(NavigationLayoutProperty, PixelMap, pixMap, frameNode);
1507     titleBarLayoutProperty->UpdateImageSource(imageSourceInfo);
1508     titleBarLayoutProperty->UpdateNoPixMap(noPixMap);
1509     titleBarLayoutProperty->UpdatePixelMap(pixMap);
1510     titleBarNode->MarkModifyDone();
1511 }
1512 
SetHideNavBar(FrameNode * frameNode,bool hideNavBar)1513 void NavigationModelNG::SetHideNavBar(FrameNode* frameNode, bool hideNavBar)
1514 {
1515     CHECK_NULL_VOID(frameNode);
1516     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
1517     CHECK_NULL_VOID(navigationGroupNode);
1518     auto pattern = navigationGroupNode->GetPattern<NavigationPattern>();
1519     CHECK_NULL_VOID(pattern);
1520     auto navigationLayoutProperty = navigationGroupNode->GetLayoutProperty<NavigationLayoutProperty>();
1521     CHECK_NULL_VOID(navigationLayoutProperty);
1522 
1523     auto lastHideNavBarValue = navigationLayoutProperty->GetHideNavBar();
1524     if (lastHideNavBarValue.has_value()) {
1525         pattern->SetNavBarVisibilityChange(hideNavBar != lastHideNavBarValue.value());
1526     } else {
1527         pattern->SetNavBarVisibilityChange(true);
1528     }
1529 
1530     ACE_UPDATE_NODE_LAYOUT_PROPERTY(NavigationLayoutProperty, HideNavBar, hideNavBar, frameNode);
1531 }
1532 
SetHideTitleBar(FrameNode * frameNode,bool hideTitleBar)1533 void NavigationModelNG::SetHideTitleBar(FrameNode* frameNode, bool hideTitleBar)
1534 {
1535     CHECK_NULL_VOID(frameNode);
1536     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
1537     CHECK_NULL_VOID(navigationGroupNode);
1538     auto navBarNode = AceType::DynamicCast<NavBarNode>(navigationGroupNode->GetNavBarNode());
1539     CHECK_NULL_VOID(navBarNode);
1540     auto navBarLayoutProperty = navBarNode->GetLayoutProperty<NavBarLayoutProperty>();
1541     CHECK_NULL_VOID(navBarLayoutProperty);
1542     navBarLayoutProperty->UpdateHideTitleBar(hideTitleBar);
1543 }
1544 
SetSubtitle(FrameNode * frameNode,const std::string & subtitle)1545 void NavigationModelNG::SetSubtitle(FrameNode* frameNode, const std::string& subtitle)
1546 {
1547     CHECK_NULL_VOID(frameNode);
1548     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
1549     CHECK_NULL_VOID(navigationGroupNode);
1550     auto navBarNode = AceType::DynamicCast<NavBarNode>(navigationGroupNode->GetNavBarNode());
1551     CHECK_NULL_VOID(navBarNode);
1552     auto titleBarNode = AceType::DynamicCast<TitleBarNode>(navBarNode->GetTitleBarNode());
1553     CHECK_NULL_VOID(titleBarNode);
1554     if (navBarNode->GetPrevTitleIsCustomValue(false)) {
1555         titleBarNode->RemoveChild(titleBarNode->GetTitle());
1556         titleBarNode->SetTitle(nullptr);
1557         auto titleBarLayoutProperty = titleBarNode->GetLayoutProperty<TitleBarLayoutProperty>();
1558         CHECK_NULL_VOID(titleBarLayoutProperty);
1559         if (titleBarLayoutProperty->HasTitleHeight()) {
1560             titleBarLayoutProperty->ResetTitleHeight();
1561             navBarNode->GetLayoutProperty<NavBarLayoutProperty>()->ResetTitleMode();
1562         }
1563     }
1564     navBarNode->UpdatePrevTitleIsCustom(false);
1565     // create or update subtitle
1566     auto subTitle = AceType::DynamicCast<FrameNode>(titleBarNode->GetSubtitle());
1567     if (subTitle) {
1568         // update subtitle
1569         auto textLayoutProperty = subTitle->GetLayoutProperty<TextLayoutProperty>();
1570         textLayoutProperty->UpdateContent(subtitle);
1571         auto renderContext = subTitle->GetRenderContext();
1572         renderContext->UpdateOpacity(1.0);
1573     } else {
1574         // create and init subtitle
1575         subTitle = FrameNode::CreateFrameNode(
1576             V2::TEXT_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<TextPattern>());
1577         auto textLayoutProperty = subTitle->GetLayoutProperty<TextLayoutProperty>();
1578         auto theme = NavigationGetTheme();
1579         textLayoutProperty->UpdateContent(subtitle);
1580         textLayoutProperty->UpdateFontSize(theme->GetSubTitleFontSize());
1581         textLayoutProperty->UpdateTextColor(theme->GetSubTitleColor());
1582         textLayoutProperty->UpdateFontWeight(FontWeight::REGULAR); // ohos_id_text_font_family_regular
1583         textLayoutProperty->UpdateMaxLines(1);
1584         textLayoutProperty->UpdateTextOverflow(TextOverflow::ELLIPSIS);
1585         titleBarNode->SetSubtitle(subTitle);
1586         titleBarNode->AddChild(subTitle);
1587     }
1588 }
1589 
SetHideBackButton(FrameNode * frameNode,bool hideBackButton)1590 void NavigationModelNG::SetHideBackButton(FrameNode* frameNode, bool hideBackButton)
1591 {
1592     CHECK_NULL_VOID(frameNode);
1593     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
1594     CHECK_NULL_VOID(navigationGroupNode);
1595     auto navBarNode = AceType::DynamicCast<NavBarNode>(navigationGroupNode->GetNavBarNode());
1596     CHECK_NULL_VOID(navBarNode);
1597     auto navBarLayoutProperty = navBarNode->GetLayoutProperty<NavBarLayoutProperty>();
1598     CHECK_NULL_VOID(navBarLayoutProperty);
1599     navBarLayoutProperty->UpdateHideBackButton(hideBackButton);
1600 }
1601 
SetTitleMode(FrameNode * frameNode,NG::NavigationTitleMode mode)1602 void NavigationModelNG::SetTitleMode(FrameNode* frameNode, NG::NavigationTitleMode mode)
1603 {
1604     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
1605     CHECK_NULL_VOID(navigationGroupNode);
1606     auto navBarNode = AceType::DynamicCast<NavBarNode>(navigationGroupNode->GetNavBarNode());
1607     CHECK_NULL_VOID(navBarNode);
1608     auto navBarLayoutProperty = navBarNode->GetLayoutProperty<NavBarLayoutProperty>();
1609     CHECK_NULL_VOID(navBarLayoutProperty);
1610     auto titleBarNode = AceType::DynamicCast<TitleBarNode>(navBarNode->GetTitleBarNode());
1611     CHECK_NULL_VOID(titleBarNode);
1612     auto titleBarLayoutProperty = titleBarNode->GetLayoutProperty<TitleBarLayoutProperty>();
1613     CHECK_NULL_VOID(titleBarLayoutProperty);
1614     const auto& titleHeightProperty = titleBarLayoutProperty->GetTitleHeight();
1615     if (titleHeightProperty.has_value()) {
1616         mode = NavigationTitleMode::MINI;
1617     }
1618     navBarLayoutProperty->UpdateTitleMode(static_cast<NG::NavigationTitleMode>(mode));
1619     auto backButtonNode = AceType::DynamicCast<FrameNode>(titleBarNode->GetBackButton());
1620     if (mode != NavigationTitleMode::MINI) {
1621         // remove back button if any.
1622         titleBarNode->RemoveChild(backButtonNode);
1623         titleBarNode->SetBackButton(nullptr);
1624         return;
1625     }
1626 
1627     if (backButtonNode != nullptr) {
1628         return;
1629     }
1630     // create back button
1631     backButtonNode = FrameNode::CreateFrameNode(
1632         V2::BACK_BUTTON_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<ButtonPattern>());
1633     auto gestureEventHub = backButtonNode->GetOrCreateGestureEventHub();
1634     CHECK_NULL_VOID(gestureEventHub);
1635     auto context = PipelineContext::GetCurrentContext();
1636     auto clickCallback = [weakContext = WeakPtr<PipelineContext>(context)](GestureEvent& /* info */) {
1637         auto context = weakContext.Upgrade();
1638         CHECK_NULL_VOID(context);
1639         bool result = context->OnBackPressed();
1640         if (!result) {
1641             auto delegate = EngineHelper::GetCurrentDelegate();
1642             CHECK_NULL_VOID(delegate);
1643             delegate->Back("");
1644         }
1645     };
1646     gestureEventHub->AddClickEvent(AceType::MakeRefPtr<ClickEvent>(clickCallback));
1647     auto buttonPattern = backButtonNode->GetPattern<ButtonPattern>();
1648     CHECK_NULL_VOID(buttonPattern);
1649     buttonPattern->SetSkipColorConfigurationUpdate();
1650     auto backButtonLayoutProperty = backButtonNode->GetLayoutProperty<ButtonLayoutProperty>();
1651     CHECK_NULL_VOID(backButtonLayoutProperty);
1652     backButtonLayoutProperty->UpdateUserDefinedIdealSize(
1653         CalcSize(CalcLength(BACK_BUTTON_SIZE), CalcLength(BACK_BUTTON_SIZE)));
1654     backButtonLayoutProperty->UpdateType(ButtonType::NORMAL);
1655     backButtonLayoutProperty->UpdateBorderRadius(BorderRadiusProperty(BUTTON_RADIUS_SIZE));
1656     backButtonLayoutProperty->UpdateMeasureType(MeasureType::MATCH_PARENT);
1657     auto renderContext = backButtonNode->GetRenderContext();
1658     CHECK_NULL_VOID(renderContext);
1659     renderContext->UpdateBackgroundColor(Color::TRANSPARENT);
1660 
1661     auto eventHub = backButtonNode->GetOrCreateInputEventHub();
1662     CHECK_NULL_VOID(eventHub);
1663 
1664     PaddingProperty padding;
1665     padding.left = CalcLength(BUTTON_PADDING);
1666     padding.right = CalcLength(BUTTON_PADDING);
1667     padding.top = CalcLength(BUTTON_PADDING);
1668     padding.bottom = CalcLength(BUTTON_PADDING);
1669     backButtonLayoutProperty->UpdatePadding(padding);
1670 
1671     auto backButtonImageNode = FrameNode::CreateFrameNode(V2::BACK_BUTTON_IMAGE_ETS_TAG,
1672         ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<ImagePattern>());
1673     CHECK_NULL_VOID(backButtonImageNode);
1674     auto theme = NavigationGetTheme();
1675     CHECK_NULL_VOID(theme);
1676     ImageSourceInfo imageSourceInfo;
1677     imageSourceInfo.SetResourceId(theme->GetBackResourceId());
1678     auto backButtonImageLayoutProperty = backButtonImageNode->GetLayoutProperty<ImageLayoutProperty>();
1679     CHECK_NULL_VOID(backButtonImageLayoutProperty);
1680 
1681     auto navigationEventHub = navigationGroupNode->GetEventHub<EventHub>();
1682     CHECK_NULL_VOID(navigationEventHub);
1683     if (!navigationEventHub->IsEnabled()) {
1684         imageSourceInfo.SetFillColor(theme->GetBackButtonIconColor().BlendOpacity(theme->GetAlphaDisabled()));
1685     } else {
1686         imageSourceInfo.SetFillColor(theme->GetBackButtonIconColor());
1687     }
1688     backButtonImageLayoutProperty->UpdateImageSourceInfo(imageSourceInfo);
1689     backButtonImageLayoutProperty->UpdateMeasureType(MeasureType::MATCH_PARENT);
1690 
1691     backButtonImageNode->MountToParent(backButtonNode);
1692     backButtonImageNode->MarkModifyDone();
1693     backButtonNode->MarkModifyDone();
1694     titleBarNode->SetBackButton(backButtonNode);
1695     titleBarNode->AddChild(backButtonNode, 0);
1696 }
1697 
SetIsCustomAnimation(bool isCustom)1698 void NavigationModelNG::SetIsCustomAnimation(bool isCustom)
1699 {
1700     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
1701     CHECK_NULL_VOID(frameNode);
1702     auto pattern = frameNode->GetPattern<NavigationPattern>();
1703     CHECK_NULL_VOID(pattern);
1704     pattern->SetIsCustomAnimation(isCustom);
1705 }
1706 
SetCustomTransition(NavigationTransitionEvent && customTransition)1707 void NavigationModelNG::SetCustomTransition(NavigationTransitionEvent&& customTransition)
1708 {
1709     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
1710     CHECK_NULL_VOID(frameNode);
1711     auto pattern = frameNode->GetPattern<NavigationPattern>();
1712     CHECK_NULL_VOID(pattern);
1713     pattern->SetNavigationTransition(std::move(customTransition));
1714 }
1715 
SetTitlebarOptions(NavigationTitlebarOptions && opt)1716 void NavigationModelNG::SetTitlebarOptions(NavigationTitlebarOptions&& opt)
1717 {
1718     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
1719     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
1720     CHECK_NULL_VOID(navigationGroupNode);
1721     auto navBarNode = AceType::DynamicCast<NavBarNode>(navigationGroupNode->GetNavBarNode());
1722     CHECK_NULL_VOID(navBarNode);
1723     auto titleBarNode = AceType::DynamicCast<TitleBarNode>(navBarNode->GetTitleBarNode());
1724     CHECK_NULL_VOID(titleBarNode);
1725     auto titleBarPattern = titleBarNode->GetPattern<TitleBarPattern>();
1726     CHECK_NULL_VOID(titleBarPattern);
1727     titleBarPattern->SetTitlebarOptions(std::move(opt));
1728 }
1729 
SetToolbarOptions(NavigationToolbarOptions && opt)1730 void NavigationModelNG::SetToolbarOptions(NavigationToolbarOptions&& opt)
1731 {
1732     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
1733     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
1734     CHECK_NULL_VOID(navigationGroupNode);
1735     auto navBarNode = AceType::DynamicCast<NavBarNode>(navigationGroupNode->GetNavBarNode());
1736     CHECK_NULL_VOID(navBarNode);
1737     auto toolBarNode = AceType::DynamicCast<NavToolbarNode>(navBarNode->GetToolBarNode());
1738     CHECK_NULL_VOID(toolBarNode);
1739     auto toolBarPattern = toolBarNode->GetPattern<NavToolbarPattern>();
1740     CHECK_NULL_VOID(toolBarPattern);
1741     toolBarPattern->SetToolbarOptions(std::move(opt));
1742 }
1743 } // namespace OHOS::Ace::NG
1744