• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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_view.h"
17 
18 #include <cstdint>
19 #include <iterator>
20 
21 #include "base/memory/ace_type.h"
22 #include "base/memory/referenced.h"
23 #include "base/utils/utils.h"
24 #include "core/components_ng/base/frame_node.h"
25 #include "core/components_ng/base/view_stack_processor.h"
26 #include "core/components_ng/pattern/button/button_layout_property.h"
27 #include "core/components_ng/pattern/button/button_pattern.h"
28 #include "core/components_ng/pattern/custom/custom_node.h"
29 #include "core/components_ng/pattern/divider/divider_layout_property.h"
30 #include "core/components_ng/pattern/divider/divider_pattern.h"
31 #include "core/components_ng/pattern/divider/divider_render_property.h"
32 #include "core/components_ng/pattern/image/image_layout_property.h"
33 #include "core/components_ng/pattern/image/image_pattern.h"
34 #include "core/components_ng/pattern/linear_layout/linear_layout_pattern.h"
35 #include "core/components_ng/pattern/menu/menu_view.h"
36 #include "core/components_ng/pattern/navigation/bar_item_event_hub.h"
37 #include "core/components_ng/pattern/navigation/bar_item_node.h"
38 #include "core/components_ng/pattern/navigation/bar_item_pattern.h"
39 #include "core/components_ng/pattern/navigation/nav_bar_layout_property.h"
40 #include "core/components_ng/pattern/navigation/nav_bar_node.h"
41 #include "core/components_ng/pattern/navigation/nav_bar_pattern.h"
42 #include "core/components_ng/pattern/navigation/navigation_declaration.h"
43 #include "core/components_ng/pattern/navigation/navigation_group_node.h"
44 #include "core/components_ng/pattern/navigation/navigation_layout_property.h"
45 #include "core/components_ng/pattern/navigation/navigation_pattern.h"
46 #include "core/components_ng/pattern/navigation/title_bar_node.h"
47 #include "core/components_ng/pattern/navigation/title_bar_pattern.h"
48 #include "core/components_ng/pattern/navigator/navigator_event_hub.h"
49 #include "core/components_ng/pattern/navigator/navigator_pattern.h"
50 #include "core/components_ng/pattern/navrouter/navdestination_group_node.h"
51 #include "core/components_ng/pattern/navrouter/navdestination_layout_property.h"
52 #include "core/components_ng/pattern/navrouter/navrouter_group_node.h"
53 #include "core/components_ng/pattern/option/option_view.h"
54 #include "core/components_ng/pattern/select/select_view.h"
55 #include "core/components_ng/pattern/text/text_layout_property.h"
56 #include "core/components_ng/pattern/text/text_pattern.h"
57 #include "core/components_v2/inspector/inspector_constants.h"
58 #include "core/pipeline/base/element_register.h"
59 #include "core/pipeline_ng/ui_task_scheduler.h"
60 
61 namespace OHOS::Ace::NG {
62 namespace {
63 
CreateBarItemTextNode(const std::string & text)64 RefPtr<FrameNode> CreateBarItemTextNode(const std::string& text)
65 {
66     int32_t nodeId = ElementRegister::GetInstance()->MakeUniqueId();
67     auto textNode = FrameNode::CreateFrameNode(V2::TEXT_ETS_TAG, nodeId, AceType::MakeRefPtr<TextPattern>());
68     auto textLayoutProperty = textNode->GetLayoutProperty<TextLayoutProperty>();
69     CHECK_NULL_RETURN(textLayoutProperty, nullptr);
70     textLayoutProperty->UpdateContent(text);
71     textLayoutProperty->UpdateFontSize(TEXT_FONT_SIZE);
72     textLayoutProperty->UpdateTextColor(TEXT_COLOR);
73     textLayoutProperty->UpdateTextAlign(TextAlign::CENTER);
74     return textNode;
75 }
76 
CreateBarItemIconNode(const std::string & src)77 RefPtr<FrameNode> CreateBarItemIconNode(const std::string& src)
78 {
79     int32_t nodeId = ElementRegister::GetInstance()->MakeUniqueId();
80     ImageSourceInfo info(src);
81     auto iconNode = FrameNode::CreateFrameNode(V2::IMAGE_ETS_TAG, nodeId, AceType::MakeRefPtr<ImagePattern>());
82     auto imageLayoutProperty = iconNode->GetLayoutProperty<ImageLayoutProperty>();
83     CHECK_NULL_RETURN(imageLayoutProperty, nullptr);
84     auto theme = NavigationGetTheme();
85     CHECK_NULL_RETURN(theme, nullptr);
86 
87     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
88     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
89     CHECK_NULL_RETURN(navigationGroupNode, nullptr);
90     auto hub = navigationGroupNode->GetEventHub<EventHub>();
91     CHECK_NULL_RETURN(hub, nullptr);
92     if (!hub->IsEnabled()) {
93         info.SetFillColor(theme->GetMenuIconColor().BlendOpacity(theme->GetAlphaDisabled()));
94     } else {
95         info.SetFillColor(theme->GetMenuIconColor());
96     }
97     imageLayoutProperty->UpdateImageSourceInfo(info);
98     auto iconSize = theme->GetMenuIconSize();
99     imageLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(CalcLength(iconSize), CalcLength(iconSize)));
100     iconNode->MarkModifyDone();
101     return iconNode;
102 }
103 
UpdateBarItemNodeWithItem(const RefPtr<BarItemNode> & barItemNode,const BarItem & barItem)104 void UpdateBarItemNodeWithItem(const RefPtr<BarItemNode>& barItemNode, const BarItem& barItem)
105 {
106     if (barItem.text.has_value() && !barItem.text.value().empty()) {
107         auto textNode = CreateBarItemTextNode(barItem.text.value());
108         barItemNode->SetTextNode(textNode);
109         barItemNode->AddChild(textNode);
110     }
111     if (barItem.icon.has_value() && !barItem.icon.value().empty()) {
112         auto iconNode = CreateBarItemIconNode(barItem.icon.value());
113         barItemNode->SetIconNode(iconNode);
114         barItemNode->AddChild(iconNode);
115     }
116     if (barItem.action) {
117         auto eventHub = barItemNode->GetEventHub<BarItemEventHub>();
118         CHECK_NULL_VOID(eventHub);
119         eventHub->SetItemAction(barItem.action);
120     }
121     auto barItemPattern = barItemNode->GetPattern<BarItemPattern>();
122     barItemNode->MarkModifyDone();
123 }
124 
BuildMoreIemNode(const RefPtr<BarItemNode> & barItemNode)125 void BuildMoreIemNode(const RefPtr<BarItemNode>& barItemNode)
126 {
127     int32_t imageNodeId = ElementRegister::GetInstance()->MakeUniqueId();
128     auto imageNode = FrameNode::CreateFrameNode(V2::IMAGE_ETS_TAG, imageNodeId, AceType::MakeRefPtr<ImagePattern>());
129     auto imageLayoutProperty = imageNode->GetLayoutProperty<ImageLayoutProperty>();
130     CHECK_NULL_VOID(imageLayoutProperty);
131     auto theme = NavigationGetTheme();
132     CHECK_NULL_VOID(theme);
133 
134     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
135     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
136     CHECK_NULL_VOID(navigationGroupNode);
137     auto hub = navigationGroupNode->GetEventHub<EventHub>();
138     CHECK_NULL_VOID(hub);
139     auto info = ImageSourceInfo("");
140     info.SetResourceId(theme->GetMoreResourceId());
141     if (!hub->IsEnabled()) {
142         info.SetFillColor(theme->GetMenuIconColor().BlendOpacity(theme->GetAlphaDisabled()));
143     } else {
144         info.SetFillColor(theme->GetMenuIconColor());
145     }
146     imageLayoutProperty->UpdateImageSourceInfo(info);
147 
148     auto iconSize = theme->GetMenuIconSize();
149     imageLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(CalcLength(iconSize), CalcLength(iconSize)));
150     imageNode->MarkModifyDone();
151 
152     barItemNode->SetIconNode(imageNode);
153     barItemNode->AddChild(imageNode);
154     barItemNode->MarkModifyDone();
155 }
156 
BuildMoreItemNodeAction(const RefPtr<BarItemNode> & barItemNode,const RefPtr<FrameNode> & barMenuNode)157 void BuildMoreItemNodeAction(const RefPtr<BarItemNode>& barItemNode, const RefPtr<FrameNode>& barMenuNode)
158 {
159     auto eventHub = barItemNode->GetEventHub<BarItemEventHub>();
160     CHECK_NULL_VOID(eventHub);
161 
162     auto context = PipelineContext::GetCurrentContext();
163     auto clickCallback = [weakContext = AceType::WeakClaim(AceType::RawPtr(context)), id = barItemNode->GetId(),
164                              weakMenu = AceType::WeakClaim(AceType::RawPtr(barMenuNode)),
165                              weakBarItemNode = AceType::WeakClaim(AceType::RawPtr(barItemNode))]() {
166         auto context = weakContext.Upgrade();
167         CHECK_NULL_VOID(context);
168 
169         auto overlayManager = context->GetOverlayManager();
170         CHECK_NULL_VOID(overlayManager);
171 
172         auto menu = weakMenu.Upgrade();
173         CHECK_NULL_VOID(menu);
174 
175         auto barItemNode = weakBarItemNode.Upgrade();
176         CHECK_NULL_VOID(barItemNode);
177 
178         auto imageNode = barItemNode->GetChildAtIndex(0);
179         CHECK_NULL_VOID(imageNode);
180 
181         auto imageFrameNode = AceType::DynamicCast<FrameNode>(imageNode);
182         CHECK_NULL_VOID(imageFrameNode);
183         auto imgOffset = imageFrameNode->GetOffsetRelativeToWindow();
184         auto imageSize = imageFrameNode->GetGeometryNode()->GetFrameSize();
185 
186         imgOffset.SetX(imgOffset.GetX() + imageSize.Width());
187         imgOffset.SetY(imgOffset.GetY() + imageSize.Height() + static_cast<float>(MENU_AND_BUTTON_SPACE.ConvertToPx()));
188         overlayManager->ShowMenu(id, imgOffset, menu);
189     };
190     eventHub->SetItemAction(clickCallback);
191 }
192 
UpdateOldBarItems(const RefPtr<UINode> & oldBarContainer,const std::vector<BarItem> & newBarItems)193 void UpdateOldBarItems(const RefPtr<UINode>& oldBarContainer, const std::vector<BarItem>& newBarItems)
194 {
195     auto oldBarItems = oldBarContainer->GetChildren();
196     auto prevChildrenSize = static_cast<int32_t>(oldBarItems.size());
197     auto newChildrenSize = static_cast<int32_t>(newBarItems.size());
198     auto oldIter = oldBarItems.begin();
199     auto newIter = newBarItems.begin();
200     // if old container has m items and incoming array has n items
201     // we update first min(m, n) items in the old container
202     for (int32_t i = 0; i < std::min(prevChildrenSize, newChildrenSize); i++) {
203         do {
204             auto oldBarItem = AceType::DynamicCast<BarItemNode>(*oldIter);
205             BarItem newBarItem = *newIter;
206             if (!oldBarItem) {
207                 break;
208             }
209             // TODO: fix error for update condition when add or delete child, and update old bar item will not work
210             if (newBarItem.text.has_value()) {
211                 oldBarItem->UpdateText(newBarItem.text.value());
212                 if (oldBarItem->GetTextNode()) {
213                     auto textNode = AceType::DynamicCast<FrameNode>(oldBarItem->GetTextNode());
214                     CHECK_NULL_VOID(textNode);
215                     auto textLayoutProperty = textNode->GetLayoutProperty<TextLayoutProperty>();
216                     CHECK_NULL_VOID(textLayoutProperty);
217                     textLayoutProperty->UpdateContent(newBarItem.text.value());
218                     textNode->MarkModifyDone();
219                 } else {
220                     auto textNode = CreateBarItemTextNode(newBarItem.text.value());
221                     oldBarItem->SetTextNode(textNode);
222                     oldBarItem->AddChild(textNode);
223                     oldBarItem->MarkModifyDone();
224                 }
225             } else {
226                 oldBarItem->ResetText();
227                 if (oldBarItem->GetTextNode()) {
228                     auto textNode = AceType::DynamicCast<FrameNode>(oldBarItem->GetTextNode());
229                     CHECK_NULL_VOID(textNode);
230                     oldBarItem->RemoveChild(textNode);
231                 }
232             }
233             if (newBarItem.icon.has_value()) {
234                 oldBarItem->UpdateIconSrc(newBarItem.icon.value());
235                 if (oldBarItem->GetIconNode()) {
236                     auto iconNode = AceType::DynamicCast<FrameNode>(oldBarItem->GetIconNode());
237                     CHECK_NULL_VOID(iconNode);
238                     auto imageLayoutProperty = iconNode->GetLayoutProperty<ImageLayoutProperty>();
239                     CHECK_NULL_VOID(imageLayoutProperty);
240                     imageLayoutProperty->UpdateImageSourceInfo(ImageSourceInfo(newBarItem.icon.value()));
241                     iconNode->MarkModifyDone();
242                 } else {
243                     auto iconNode = CreateBarItemIconNode(newBarItem.icon.value());
244                     oldBarItem->SetIconNode(iconNode);
245                     oldBarItem->AddChild(iconNode);
246                     oldBarItem->MarkModifyDone();
247                 }
248             } else {
249                 oldBarItem->ResetIconSrc();
250                 if (oldBarItem->GetIconNode()) {
251                     auto iconNode = AceType::DynamicCast<FrameNode>(oldBarItem->GetIconNode());
252                     CHECK_NULL_VOID(iconNode);
253                     oldBarItem->RemoveChild(iconNode);
254                 }
255             }
256         } while (false);
257         oldIter++;
258         newIter++;
259     }
260     // if m > n, we remove (m - n) children from the back of old container
261     if (prevChildrenSize > newChildrenSize) {
262         for (int32_t i = 0; i < prevChildrenSize - newChildrenSize; i++) {
263             oldBarContainer->RemoveChild(oldBarItems.back());
264             oldBarItems.pop_back();
265         }
266     } else if (prevChildrenSize < newChildrenSize) {
267         // if m < n, we add (n - m) children created by info in new item list
268         for (int32_t i = 0; i < newChildrenSize - prevChildrenSize; i++) {
269             auto nodeId = ElementRegister::GetInstance()->MakeUniqueId();
270             auto barItemNode = AceType::MakeRefPtr<BarItemNode>(V2::BAR_ITEM_ETS_TAG, nodeId);
271             barItemNode->InitializePatternAndContext();
272             UpdateBarItemNodeWithItem(barItemNode, *newIter);
273             oldBarContainer->AddChild(barItemNode);
274             newIter++;
275         }
276     }
277     auto container = AceType::DynamicCast<TitleBarNode>(oldBarContainer);
278     CHECK_NULL_VOID(container);
279     container->MarkModifyDone();
280 }
281 } // namespace
282 
Create()283 void NavigationView::Create()
284 {
285     auto* stack = ViewStackProcessor::GetInstance();
286     // navigation node
287     int32_t nodeId = stack->ClaimNodeId();
288     auto navigationGroupNode = NavigationGroupNode::GetOrCreateGroupNode(
289         V2::NAVIGATION_VIEW_ETS_TAG, nodeId, []() { return AceType::MakeRefPtr<NavigationPattern>(); });
290 
291     // navBar node
292     if (!navigationGroupNode->GetNavBarNode()) {
293         int32_t navBarNodeId = ElementRegister::GetInstance()->MakeUniqueId();
294         auto navBarNode = NavBarNode::GetOrCreateNavBarNode(
295             V2::NAVBAR_ETS_TAG, navBarNodeId, []() { return AceType::MakeRefPtr<NavBarPattern>(); });
296         navigationGroupNode->AddChild(navBarNode);
297         navigationGroupNode->SetNavBarNode(navBarNode);
298 
299         // titleBar node
300         if (!navBarNode->GetTitleBarNode()) {
301             int32_t titleBarNodeId = ElementRegister::GetInstance()->MakeUniqueId();
302             auto titleBarNode = TitleBarNode::GetOrCreateTitleBarNode(
303                 V2::TITLE_BAR_ETS_TAG, titleBarNodeId, []() { return AceType::MakeRefPtr<TitleBarPattern>(); });
304             navBarNode->AddChild(titleBarNode);
305             navBarNode->SetTitleBarNode(titleBarNode);
306         }
307 
308         // navBar content node
309         if (!navBarNode->GetNavBarContentNode()) {
310             int32_t navBarContentNodeId = ElementRegister::GetInstance()->MakeUniqueId();
311             auto navBarContentNode = FrameNode::GetOrCreateFrameNode(V2::NAVBAR_CONTENT_ETS_TAG, navBarContentNodeId,
312                 []() { return AceType::MakeRefPtr<LinearLayoutPattern>(true); });
313             navBarNode->AddChild(navBarContentNode);
314             navBarNode->SetNavBarContentNode(navBarContentNode);
315         }
316 
317         // toolBar node
318         if (!navBarNode->GetToolBarNode()) {
319             int32_t toolBarNodeId = ElementRegister::GetInstance()->MakeUniqueId();
320             auto toolBarNode = FrameNode::GetOrCreateFrameNode(
321                 V2::TOOL_BAR_ETS_TAG, toolBarNodeId, []() { return AceType::MakeRefPtr<LinearLayoutPattern>(false); });
322             navBarNode->AddChild(toolBarNode);
323             navBarNode->SetToolBarNode(toolBarNode);
324             navBarNode->SetPreToolBarNode(toolBarNode);
325             navBarNode->UpdatePrevToolBarIsCustom(false);
326         }
327         auto navBarLayoutProperty = navBarNode->GetLayoutProperty<NavBarLayoutProperty>();
328         CHECK_NULL_VOID(navBarLayoutProperty);
329         navBarLayoutProperty->UpdateTitleMode(NavigationTitleMode::FREE);
330     }
331 
332     // content node
333     if (!navigationGroupNode->GetContentNode()) {
334         int32_t contentNodeId = ElementRegister::GetInstance()->MakeUniqueId();
335         auto contentNode = FrameNode::GetOrCreateFrameNode(V2::NAVIGATION_CONTENT_ETS_TAG, contentNodeId,
336             []() { return AceType::MakeRefPtr<LinearLayoutPattern>(true); });
337         navigationGroupNode->AddChild(contentNode);
338         navigationGroupNode->SetContentNode(contentNode);
339 
340         auto context = contentNode->GetRenderContext();
341         CHECK_NULL_VOID(context);
342         context->UpdateBackgroundColor(CONTENT_COLOR);
343     }
344 
345     // divider node
346     if (!navigationGroupNode->GetDividerNode()) {
347         int32_t dividerNodeId = ElementRegister::GetInstance()->MakeUniqueId();
348         auto dividerNode = FrameNode::GetOrCreateFrameNode(
349             V2::DIVIDER_ETS_TAG, dividerNodeId, []() { return AceType::MakeRefPtr<DividerPattern>(); });
350         navigationGroupNode->AddChild(dividerNode);
351         navigationGroupNode->SetDividerNode(dividerNode);
352 
353         auto dividerLayoutProperty = dividerNode->GetLayoutProperty<DividerLayoutProperty>();
354         CHECK_NULL_VOID(dividerLayoutProperty);
355         dividerLayoutProperty->UpdateStrokeWidth(DIVIDER_WIDTH);
356         dividerLayoutProperty->UpdateVertical(true);
357         auto dividerRenderProperty = dividerNode->GetPaintProperty<DividerRenderProperty>();
358         CHECK_NULL_VOID(dividerRenderProperty);
359         dividerRenderProperty->UpdateDividerColor(DIVIDER_COLOR);
360     }
361 
362     stack->Push(navigationGroupNode);
363     auto navigationLayoutProperty = navigationGroupNode->GetLayoutProperty<NavigationLayoutProperty>();
364     navigationLayoutProperty->UpdateNavigationMode(NavigationMode::AUTO);
365     navigationLayoutProperty->UpdateNavBarWidth(DEFAULT_NAV_BAR_WIDTH);
366 }
367 
SetTitle(const std::string & title,bool hasSubTitle)368 void NavigationView::SetTitle(const std::string& title, bool hasSubTitle)
369 {
370     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
371     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
372     CHECK_NULL_VOID(navigationGroupNode);
373     auto navBarNode = AceType::DynamicCast<NavBarNode>(navigationGroupNode->GetNavBarNode());
374     CHECK_NULL_VOID(navBarNode);
375     do {
376         if (!navBarNode->GetTitle()) {
377             navBarNode->UpdateTitleNodeOperation(ChildNodeOperation::ADD);
378             break;
379         }
380         // if previous title is not a frame node, we remove it and create a new node
381         auto titleNode = AceType::DynamicCast<FrameNode>(navBarNode->GetTitle());
382         if (!titleNode) {
383             navBarNode->UpdateTitleNodeOperation(ChildNodeOperation::REPLACE);
384             break;
385         }
386         auto titleProperty = titleNode->GetLayoutProperty<TextLayoutProperty>();
387         // if no subtitle, title's maxLine = 1. if has subtitle, title's maxLine = 2.
388         if (!hasSubTitle && navBarNode->GetSubtitle()) {
389             navBarNode->SetSubtitle(nullptr);
390             titleProperty->UpdateMaxLines(1);
391         } else {
392             titleProperty->UpdateMaxLines(2);
393         }
394         // previous title is not a text node and might be custom, we remove it and create a new node
395         if (!titleProperty) {
396             navBarNode->UpdateTitleNodeOperation(ChildNodeOperation::REPLACE);
397             break;
398         }
399         // text content is the same, do nothing
400         if (titleProperty->GetContentValue() == title) {
401             navBarNode->UpdateTitleNodeOperation(ChildNodeOperation::NONE);
402             return;
403         }
404         // update title content only without changing node
405         titleProperty->UpdateContent(title);
406         navBarNode->UpdateTitleNodeOperation(ChildNodeOperation::NONE);
407         navBarNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
408         return;
409     } while (false);
410     int32_t titleNodeId = ElementRegister::GetInstance()->MakeUniqueId();
411     auto titleNode = FrameNode::CreateFrameNode(V2::TEXT_ETS_TAG, titleNodeId, AceType::MakeRefPtr<TextPattern>());
412     auto textLayoutProperty = titleNode->GetLayoutProperty<TextLayoutProperty>();
413     CHECK_NULL_VOID(textLayoutProperty);
414     textLayoutProperty->UpdateContent(title);
415 
416     auto theme = NavigationGetTheme();
417     CHECK_NULL_VOID(theme);
418     auto navBarLayoutProperty = navBarNode->GetLayoutProperty<NavBarLayoutProperty>();
419     CHECK_NULL_VOID(navBarLayoutProperty);
420     if (navBarLayoutProperty->GetTitleModeValue(NavigationTitleMode::FREE) == NavigationTitleMode::MINI) {
421         textLayoutProperty->UpdateFontSize(theme->GetTitleFontSize());
422     } else {
423         textLayoutProperty->UpdateFontSize(theme->GetTitleFontSizeBig());
424     }
425     textLayoutProperty->UpdateTextColor(theme->GetTitleColor());
426     textLayoutProperty->UpdateFontWeight(FontWeight::MEDIUM);
427     if (!hasSubTitle) {
428         textLayoutProperty->UpdateMaxLines(1);
429     } else {
430         textLayoutProperty->UpdateMaxLines(2);
431     }
432     textLayoutProperty->UpdateTextOverflow(TextOverflow::ELLIPSIS);
433     navBarNode->SetTitle(titleNode);
434     navBarNode->UpdatePrevTitleIsCustom(false);
435 }
436 
SetCustomTitle(const RefPtr<UINode> & customTitle)437 void NavigationView::SetCustomTitle(const RefPtr<UINode>& customTitle)
438 {
439     CHECK_NULL_VOID(customTitle);
440     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
441     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
442     CHECK_NULL_VOID(navigationGroupNode);
443     auto navBarNode = AceType::DynamicCast<NavBarNode>(navigationGroupNode->GetNavBarNode());
444     CHECK_NULL_VOID(navBarNode);
445     if (navBarNode->GetTitle()) {
446         if (customTitle->GetId() == navBarNode->GetTitle()->GetId()) {
447             navBarNode->UpdateTitleNodeOperation(ChildNodeOperation::NONE);
448         } else {
449             navBarNode->SetTitle(customTitle);
450             navBarNode->UpdateTitleNodeOperation(ChildNodeOperation::REPLACE);
451             navBarNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
452         }
453         return;
454     }
455     navBarNode->SetTitle(customTitle);
456     navBarNode->UpdateTitleNodeOperation(ChildNodeOperation::ADD);
457     navBarNode->UpdatePrevTitleIsCustom(true);
458 }
459 
SetSubtitle(const std::string & subtitle)460 void NavigationView::SetSubtitle(const std::string& subtitle)
461 {
462     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
463     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
464     CHECK_NULL_VOID(navigationGroupNode);
465     auto navBarNode = AceType::DynamicCast<NavBarNode>(navigationGroupNode->GetNavBarNode());
466     CHECK_NULL_VOID(navBarNode);
467     do {
468         if (!navBarNode->GetSubtitle()) {
469             navBarNode->UpdateSubtitleNodeOperation(ChildNodeOperation::ADD);
470             break;
471         }
472         auto subtitleNode = AceType::DynamicCast<FrameNode>(navBarNode->GetSubtitle());
473         if (!subtitleNode) {
474             navBarNode->UpdateSubtitleNodeOperation(ChildNodeOperation::REPLACE);
475             break;
476         }
477         auto subtitleProperty = subtitleNode->GetLayoutProperty<TextLayoutProperty>();
478         if (!subtitleProperty) {
479             navBarNode->UpdateSubtitleNodeOperation(ChildNodeOperation::REPLACE);
480             break;
481         }
482         if (subtitleProperty->GetContentValue() == subtitle) {
483             navBarNode->UpdateSubtitleNodeOperation(ChildNodeOperation::NONE);
484             return;
485         }
486         subtitleProperty->UpdateContent(subtitle);
487         navBarNode->UpdateSubtitleNodeOperation(ChildNodeOperation::NONE);
488         navBarNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
489         return;
490     } while (false);
491     int32_t subtitleNodeId = ElementRegister::GetInstance()->MakeUniqueId();
492     auto subtitleNode =
493         FrameNode::CreateFrameNode(V2::TEXT_ETS_TAG, subtitleNodeId, AceType::MakeRefPtr<TextPattern>());
494     auto textLayoutProperty = subtitleNode->GetLayoutProperty<TextLayoutProperty>();
495     CHECK_NULL_VOID(textLayoutProperty);
496     textLayoutProperty->UpdateContent(subtitle);
497     textLayoutProperty->UpdateFontSize(SUBTITLE_FONT_SIZE);
498     textLayoutProperty->UpdateTextColor(SUBTITLE_COLOR);
499     textLayoutProperty->UpdateFontWeight(FontWeight::REGULAR); // ohos_id_text_font_family_regular
500     textLayoutProperty->UpdateMaxLines(1);
501     textLayoutProperty->UpdateTextOverflow(TextOverflow::ELLIPSIS);
502     navBarNode->SetSubtitle(subtitleNode);
503 }
504 
SetMenuItems(std::vector<BarItem> && menuItems)505 void NavigationView::SetMenuItems(std::vector<BarItem>&& menuItems)
506 {
507     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
508     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
509     CHECK_NULL_VOID(navigationGroupNode);
510     auto navBarNode = AceType::DynamicCast<NavBarNode>(navigationGroupNode->GetNavBarNode());
511     CHECK_NULL_VOID(navBarNode);
512     // if previous menu is custom, just remove it and create new menu, otherwise update old menu
513     if (navBarNode->GetPrevMenuIsCustom().value_or(false)) {
514         navBarNode->UpdateMenuNodeOperation(ChildNodeOperation::REPLACE);
515     } else {
516         if (navBarNode->GetMenu()) {
517             navBarNode->UpdateMenuNodeOperation(ChildNodeOperation::REPLACE);
518         } else {
519             navBarNode->UpdateMenuNodeOperation(ChildNodeOperation::ADD);
520         }
521     }
522     int32_t menuNodeId = ElementRegister::GetInstance()->MakeUniqueId();
523     auto menuNode = FrameNode::GetOrCreateFrameNode(
524         V2::NAVIGATION_MENU_ETS_TAG, menuNodeId, []() { return AceType::MakeRefPtr<LinearLayoutPattern>(false); });
525     auto rowProperty = menuNode->GetLayoutProperty<LinearLayoutProperty>();
526     CHECK_NULL_VOID(rowProperty);
527     rowProperty->UpdateMainAxisAlign(FlexAlign::SPACE_BETWEEN);
528 
529     auto theme = NavigationGetTheme();
530     auto mostMenuItemCount = theme->GetMostMenuItemCountInBar();
531     bool needMoreButton = menuItems.size() > mostMenuItemCount ? true : false;
532     int32_t count = 0;
533     std::vector<OptionParam> params;
534     for (const auto& menuItem : menuItems) {
535         ++count;
536         if (needMoreButton && (count > mostMenuItemCount - 1)) {
537             params.push_back(std::make_pair(menuItem.text.value(), menuItem.action));
538         } else {
539             auto menuItemNode = FrameNode::CreateFrameNode(V2::MENU_ITEM_ETS_TAG,
540                 ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<ButtonPattern>());
541             CHECK_NULL_VOID(menuItemNode);
542             auto menuItemLayoutProperty = menuItemNode->GetLayoutProperty<ButtonLayoutProperty>();
543             CHECK_NULL_VOID(menuItemLayoutProperty);
544             menuItemLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(CalcLength(BACK_BUTTON_SIZE.ConvertToPx()),
545                 CalcLength(BACK_BUTTON_SIZE.ConvertToPx())));
546             menuItemLayoutProperty->UpdateType(ButtonType::NORMAL);
547             menuItemLayoutProperty->UpdateBorderRadius(BUTTON_RADIUS);
548             auto renderContext = menuItemNode->GetRenderContext();
549             CHECK_NULL_VOID(renderContext);
550             renderContext->UpdateBackgroundColor(Color::TRANSPARENT);
551 
552             auto eventHub = menuItemNode->GetOrCreateInputEventHub();
553             CHECK_NULL_VOID(eventHub);
554             eventHub->SetHoverEffect(HoverEffectType::BOARD);
555 
556             PaddingProperty padding;
557             padding.left = CalcLength(BUTTON_PADDING.ConvertToPx());
558             padding.right = CalcLength(BUTTON_PADDING.ConvertToPx());
559             padding.top = CalcLength(BUTTON_PADDING.ConvertToPx());
560             padding.bottom = CalcLength(BUTTON_PADDING.ConvertToPx());
561             menuItemLayoutProperty->UpdatePadding(padding);
562 
563             int32_t barItemNodeId = ElementRegister::GetInstance()->MakeUniqueId();
564             auto barItemNode = AceType::MakeRefPtr<BarItemNode>(V2::BAR_ITEM_ETS_TAG, barItemNodeId);
565             barItemNode->InitializePatternAndContext();
566             UpdateBarItemNodeWithItem(barItemNode, menuItem);
567             auto barItemLayoutProperty = barItemNode->GetLayoutProperty();
568             CHECK_NULL_VOID(barItemLayoutProperty);
569             barItemLayoutProperty->UpdateMeasureType(MeasureType::MATCH_PARENT);
570 
571             barItemNode->MountToParent(menuItemNode);
572             barItemNode->MarkModifyDone();
573             menuItemNode->MarkModifyDone();
574             menuNode->AddChild(menuItemNode);
575         }
576     }
577 
578     // build more button
579     if (needMoreButton) {
580         int32_t barItemNodeId = ElementRegister::GetInstance()->MakeUniqueId();
581         auto barItemNode = AceType::MakeRefPtr<BarItemNode>(V2::BAR_ITEM_ETS_TAG, barItemNodeId);
582         barItemNode->InitializePatternAndContext();
583         auto barItemLayoutProperty = barItemNode->GetLayoutProperty();
584         CHECK_NULL_VOID(barItemLayoutProperty);
585         barItemLayoutProperty->UpdateMeasureType(MeasureType::MATCH_PARENT);
586 
587         BuildMoreIemNode(barItemNode);
588 
589         auto barMenuNode = MenuView::Create(std::move(params), barItemNodeId, MenuType::NAVIGATION_MENU);
590         BuildMoreItemNodeAction(barItemNode, barMenuNode);
591         auto menuItemNode = FrameNode::CreateFrameNode(V2::MENU_ITEM_ETS_TAG,
592             ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<ButtonPattern>());
593         CHECK_NULL_VOID(menuItemNode);
594         auto menuItemLayoutProperty = menuItemNode->GetLayoutProperty<ButtonLayoutProperty>();
595         CHECK_NULL_VOID(menuItemLayoutProperty);
596         menuItemLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(CalcLength(BACK_BUTTON_SIZE.ConvertToPx()),
597             CalcLength(BACK_BUTTON_SIZE.ConvertToPx())));
598         menuItemLayoutProperty->UpdateType(ButtonType::NORMAL);
599         menuItemLayoutProperty->UpdateBorderRadius(BUTTON_RADIUS);
600         auto renderContext = menuItemNode->GetRenderContext();
601         CHECK_NULL_VOID(renderContext);
602         renderContext->UpdateBackgroundColor(Color::TRANSPARENT);
603 
604         auto eventHub = menuItemNode->GetOrCreateInputEventHub();
605         CHECK_NULL_VOID(eventHub);
606         eventHub->SetHoverEffect(HoverEffectType::BOARD);
607 
608         PaddingProperty padding;
609         padding.left = CalcLength(BUTTON_PADDING.ConvertToPx());
610         padding.right = CalcLength(BUTTON_PADDING.ConvertToPx());
611         padding.top = CalcLength(BUTTON_PADDING.ConvertToPx());
612         padding.bottom = CalcLength(BUTTON_PADDING.ConvertToPx());
613         menuItemLayoutProperty->UpdatePadding(padding);
614 
615         barItemNode->MountToParent(menuItemNode);
616         barItemNode->MarkModifyDone();
617         menuItemNode->MarkModifyDone();
618         menuNode->AddChild(menuItemNode);
619         navBarNode->SetMenuNode(barMenuNode);
620     }
621 
622     navBarNode->SetMenu(menuNode);
623     navBarNode->UpdatePrevMenuIsCustom(false);
624 }
625 
SetCustomMenu(const RefPtr<UINode> & customMenu)626 void NavigationView::SetCustomMenu(const RefPtr<UINode>& customMenu)
627 {
628     CHECK_NULL_VOID(customMenu);
629     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
630     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
631     CHECK_NULL_VOID(navigationGroupNode);
632     auto navBarNode = AceType::DynamicCast<NavBarNode>(navigationGroupNode->GetNavBarNode());
633     CHECK_NULL_VOID(navBarNode);
634     // if previous menu exists, remove it if their ids are not the same
635     // if previous node is not custom, their ids must not be the same
636     if (navBarNode->GetMenu()) {
637         if (customMenu->GetId() == navBarNode->GetMenu()->GetId()) {
638             navBarNode->UpdateMenuNodeOperation(ChildNodeOperation::NONE);
639             return;
640         }
641         navBarNode->SetMenu(customMenu);
642         navBarNode->UpdatePrevMenuIsCustom(true);
643         navBarNode->UpdateMenuNodeOperation(ChildNodeOperation::REPLACE);
644         return;
645     }
646     navBarNode->SetMenu(customMenu);
647     navBarNode->UpdatePrevMenuIsCustom(true);
648     navBarNode->UpdateMenuNodeOperation(ChildNodeOperation::ADD);
649 }
650 
SetTitleMode(NavigationTitleMode mode)651 void NavigationView::SetTitleMode(NavigationTitleMode mode)
652 {
653     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
654     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
655     CHECK_NULL_VOID(navigationGroupNode);
656     auto navBarNode = AceType::DynamicCast<NavBarNode>(navigationGroupNode->GetNavBarNode());
657     CHECK_NULL_VOID(navBarNode);
658     auto navBarLayoutProperty = navBarNode->GetLayoutProperty<NavBarLayoutProperty>();
659     CHECK_NULL_VOID(navBarLayoutProperty);
660     bool needAddBackButton = false;
661     bool needRemoveBackButton = false;
662 
663     do {
664         // add back button if current mode is mini and one of the following condition:
665         // first create or not first create but previous mode is not mini
666         if (navBarLayoutProperty->GetTitleModeValue(NavigationTitleMode::FREE) != NavigationTitleMode::MINI &&
667             mode == NavigationTitleMode::MINI) {
668             needAddBackButton = true;
669             break;
670         }
671         // remove back button if current mode is not mini and previous mode is mini
672         if (navBarLayoutProperty->GetTitleModeValue(NavigationTitleMode::FREE) == NavigationTitleMode::MINI &&
673             mode != NavigationTitleMode::MINI) {
674             needRemoveBackButton = true;
675             break;
676         }
677     } while (false);
678     navBarLayoutProperty->UpdateTitleMode(static_cast<NG::NavigationTitleMode>(mode));
679     if (needAddBackButton) {
680         // put component inside navigator pattern to trigger back navigation
681         auto navigator = FrameNode::CreateFrameNode(V2::NAVIGATOR_ETS_TAG,
682             ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<NavigatorPattern>());
683         auto hub = navigator->GetEventHub<NavigatorEventHub>();
684         CHECK_NULL_VOID(hub);
685         hub->SetType(NavigatorType::BACK);
686         navigator->MarkModifyDone();
687 
688         auto backButtonNode = FrameNode::CreateFrameNode(V2::BACK_BUTTON_ETS_TAG,
689             ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<ButtonPattern>());
690         CHECK_NULL_VOID(backButtonNode);
691         auto backButtonLayoutProperty = backButtonNode->GetLayoutProperty<ButtonLayoutProperty>();
692         CHECK_NULL_VOID(backButtonLayoutProperty);
693         backButtonLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(CalcLength(BACK_BUTTON_SIZE.ConvertToPx()),
694             CalcLength(BACK_BUTTON_SIZE.ConvertToPx())));
695         backButtonLayoutProperty->UpdateType(ButtonType::NORMAL);
696         backButtonLayoutProperty->UpdateBorderRadius(BUTTON_RADIUS);
697         backButtonLayoutProperty->UpdateMeasureType(MeasureType::MATCH_PARENT);
698         auto renderContext = backButtonNode->GetRenderContext();
699         CHECK_NULL_VOID(renderContext);
700         renderContext->UpdateBackgroundColor(Color::TRANSPARENT);
701 
702         auto eventHub = backButtonNode->GetOrCreateInputEventHub();
703         CHECK_NULL_VOID(eventHub);
704         eventHub->SetHoverEffect(HoverEffectType::BOARD);
705 
706         PaddingProperty padding;
707         padding.left = CalcLength(BUTTON_PADDING.ConvertToPx());
708         padding.right = CalcLength(BUTTON_PADDING.ConvertToPx());
709         padding.top = CalcLength(BUTTON_PADDING.ConvertToPx());
710         padding.bottom = CalcLength(BUTTON_PADDING.ConvertToPx());
711         backButtonLayoutProperty->UpdatePadding(padding);
712 
713         auto backButtonImageNode = FrameNode::CreateFrameNode(V2::BACK_BUTTON_IMAGE_ETS_TAG,
714             ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<ImagePattern>());
715         CHECK_NULL_VOID(backButtonImageNode);
716         auto theme = NavigationGetTheme();
717         CHECK_NULL_VOID(theme);
718         ImageSourceInfo imageSourceInfo;
719         imageSourceInfo.SetResourceId(theme->GetBackResourceId());
720         auto backButtonImageLayoutProperty = backButtonImageNode->GetLayoutProperty<ImageLayoutProperty>();
721         CHECK_NULL_VOID(backButtonImageLayoutProperty);
722         auto navigationEventHub = navigationGroupNode->GetEventHub<EventHub>();
723         CHECK_NULL_VOID(navigationEventHub);
724         if (!navigationEventHub->IsEnabled()) {
725             imageSourceInfo.SetFillColor(theme->GetBackButtonIconColor().BlendOpacity(theme->GetAlphaDisabled()));
726         } else {
727             imageSourceInfo.SetFillColor(theme->GetBackButtonIconColor());
728         }
729         backButtonImageLayoutProperty->UpdateImageSourceInfo(imageSourceInfo);
730         backButtonImageLayoutProperty->UpdateMeasureType(MeasureType::MATCH_PARENT);
731 
732         backButtonImageNode->MountToParent(backButtonNode);
733         backButtonImageNode->MarkModifyDone();
734         backButtonNode->MountToParent(navigator);
735         backButtonNode->MarkModifyDone();
736 
737         navBarNode->SetBackButton(navigator);
738         navBarNode->UpdateBackButtonNodeOperation(ChildNodeOperation::ADD);
739         return;
740     }
741     if (needRemoveBackButton) {
742         navBarNode->UpdateBackButtonNodeOperation(ChildNodeOperation::REMOVE);
743     }
744 }
745 
SetNavBarWidth(const Dimension & value)746 void NavigationView::SetNavBarWidth(const Dimension& value)
747 {
748     ACE_UPDATE_LAYOUT_PROPERTY(NavigationLayoutProperty, NavBarWidth, value);
749 }
750 
SetNavigationMode(NavigationMode mode)751 void NavigationView::SetNavigationMode(NavigationMode mode)
752 {
753     ACE_UPDATE_LAYOUT_PROPERTY(NavigationLayoutProperty, NavigationMode, mode);
754 }
755 
SetUsrNavigationMode(NavigationMode mode)756 void NavigationView::SetUsrNavigationMode(NavigationMode mode)
757 {
758     ACE_UPDATE_LAYOUT_PROPERTY(NavigationLayoutProperty, UsrNavigationMode, mode);
759 }
760 
SetNavBarPosition(NG::NavBarPosition mode)761 void NavigationView::SetNavBarPosition(NG::NavBarPosition mode)
762 {
763     ACE_UPDATE_LAYOUT_PROPERTY(NavigationLayoutProperty, NavBarPosition, static_cast<NG::NavBarPosition>(mode));
764 }
765 
SetHideNavBar(bool hideNavBar)766 void NavigationView::SetHideNavBar(bool hideNavBar)
767 {
768     ACE_UPDATE_LAYOUT_PROPERTY(NavigationLayoutProperty, HideNavBar, hideNavBar);
769 }
770 
SetTitleHeight(const Dimension & height)771 void NavigationView::SetTitleHeight(const Dimension& height)
772 {
773     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
774     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
775     CHECK_NULL_VOID(navigationGroupNode);
776     auto navBarNode = AceType::DynamicCast<NavBarNode>(navigationGroupNode->GetNavBarNode());
777     CHECK_NULL_VOID(navBarNode);
778     auto titleBarNode = AceType::DynamicCast<TitleBarNode>(navBarNode->GetTitleBarNode());
779     CHECK_NULL_VOID(titleBarNode);
780     auto titleBarLayoutProperty = titleBarNode->GetLayoutProperty<TitleBarLayoutProperty>();
781     CHECK_NULL_VOID(titleBarLayoutProperty);
782     titleBarLayoutProperty->UpdateTitleHeight(height);
783 }
784 
SetHideTitleBar(bool hideTitleBar)785 void NavigationView::SetHideTitleBar(bool hideTitleBar)
786 {
787     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
788     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
789     CHECK_NULL_VOID(navigationGroupNode);
790     auto navBarNode = AceType::DynamicCast<NavBarNode>(navigationGroupNode->GetNavBarNode());
791     CHECK_NULL_VOID(navBarNode);
792     auto navBarLayoutProperty = navBarNode->GetLayoutProperty<NavBarLayoutProperty>();
793     CHECK_NULL_VOID(navBarLayoutProperty);
794     navBarLayoutProperty->UpdateHideTitleBar(hideTitleBar);
795 }
796 
SetHideBackButton(bool hideBackButton)797 void NavigationView::SetHideBackButton(bool hideBackButton)
798 {
799     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
800     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
801     CHECK_NULL_VOID(navigationGroupNode);
802     auto navBarNode = AceType::DynamicCast<NavBarNode>(navigationGroupNode->GetNavBarNode());
803     CHECK_NULL_VOID(navBarNode);
804     auto navBarLayoutProperty = navBarNode->GetLayoutProperty<NavBarLayoutProperty>();
805     CHECK_NULL_VOID(navBarLayoutProperty);
806     navBarLayoutProperty->UpdateHideBackButton(hideBackButton);
807 }
808 
SetHideToolBar(bool hideToolBar)809 void NavigationView::SetHideToolBar(bool hideToolBar)
810 {
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 navBarLayoutProperty = navBarNode->GetLayoutProperty<NavBarLayoutProperty>();
817     CHECK_NULL_VOID(navBarLayoutProperty);
818     navBarLayoutProperty->UpdateHideToolBar(hideToolBar);
819 }
820 
SetToolBarItems(std::vector<BarItem> && toolBarItems)821 void NavigationView::SetToolBarItems(std::vector<BarItem>&& toolBarItems)
822 {
823     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
824     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
825     CHECK_NULL_VOID(navigationGroupNode);
826     auto navBarNode = AceType::DynamicCast<NavBarNode>(navigationGroupNode->GetNavBarNode());
827     CHECK_NULL_VOID(navBarNode);
828     if (navBarNode->GetPrevToolBarIsCustom().value_or(false)) {
829         navBarNode->UpdateToolBarNodeOperation(ChildNodeOperation::REPLACE);
830     } else {
831         if (navBarNode->GetPreToolBarNode() &&
832             static_cast<int32_t>(navBarNode->GetPreToolBarNode()->GetChildren().size()) != 0) {
833             UpdateOldBarItems(navBarNode->GetPreToolBarNode(), toolBarItems);
834             navBarNode->SetToolBarNode(navBarNode->GetPreToolBarNode());
835             navBarNode->UpdateToolBarNodeOperation(ChildNodeOperation::NONE);
836             return;
837         }
838         navBarNode->UpdateToolBarNodeOperation(ChildNodeOperation::REPLACE);
839     }
840     auto toolBarNode = AceType::DynamicCast<FrameNode>(navBarNode->GetPreToolBarNode());
841     CHECK_NULL_VOID(toolBarNode);
842     auto rowProperty = toolBarNode->GetLayoutProperty<LinearLayoutProperty>();
843     CHECK_NULL_VOID(rowProperty);
844     rowProperty->UpdateMainAxisAlign(FlexAlign::SPACE_EVENLY);
845     for (const auto& toolBarItem : toolBarItems) {
846         int32_t barItemNodeId = ElementRegister::GetInstance()->MakeUniqueId();
847         auto barItemNode = AceType::MakeRefPtr<BarItemNode>(V2::BAR_ITEM_ETS_TAG, barItemNodeId);
848         barItemNode->InitializePatternAndContext();
849         UpdateBarItemNodeWithItem(barItemNode, toolBarItem);
850         toolBarNode->AddChild(barItemNode);
851     }
852     navBarNode->SetToolBarNode(toolBarNode);
853     navBarNode->SetPreToolBarNode(toolBarNode);
854     navBarNode->UpdatePrevToolBarIsCustom(false);
855 }
856 
SetCustomToolBar(const RefPtr<UINode> & customToolBar)857 void NavigationView::SetCustomToolBar(const RefPtr<UINode>& customToolBar)
858 {
859     CHECK_NULL_VOID(customToolBar);
860     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
861     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
862     CHECK_NULL_VOID(navigationGroupNode);
863     auto navBarNode = AceType::DynamicCast<NavBarNode>(navigationGroupNode->GetNavBarNode());
864     CHECK_NULL_VOID(navBarNode);
865     if (navBarNode->GetPrevToolBarIsCustom().value_or(false)) {
866         if (customToolBar->GetId() == navBarNode->GetToolBarNode()->GetId()) {
867             navBarNode->UpdateToolBarNodeOperation(ChildNodeOperation::NONE);
868             navBarNode->UpdatePrevToolBarIsCustom(true);
869             return;
870         }
871     }
872     navBarNode->UpdateToolBarNodeOperation(ChildNodeOperation::REPLACE);
873     auto toolBarNode = navBarNode->GetToolBarNode();
874     CHECK_NULL_VOID(toolBarNode);
875     toolBarNode->Clean();
876     customToolBar->MountToParent(toolBarNode);
877     navBarNode->UpdatePrevToolBarIsCustom(true);
878 }
879 
SetOnTitleModeChange(std::function<void (NavigationTitleMode)> && onTitleModeChange)880 void NavigationView::SetOnTitleModeChange(std::function<void(NavigationTitleMode)>&& onTitleModeChange)
881 {
882     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
883     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
884     CHECK_NULL_VOID(navigationGroupNode);
885     auto eventHub = navigationGroupNode->GetEventHub<NavigationEventHub>();
886     CHECK_NULL_VOID(eventHub);
887     eventHub->SetOnTitleModeChange(std::move(onTitleModeChange));
888 }
889 
SetOnNavBarStateChange(std::function<void (bool)> && onNavBarStateChange)890 void NavigationView::SetOnNavBarStateChange(std::function<void(bool)>&& onNavBarStateChange)
891 {
892     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
893     auto navigationEventHub = AceType::DynamicCast<NavigationEventHub>(frameNode->GetEventHub<EventHub>());
894     CHECK_NULL_VOID(navigationEventHub);
895     navigationEventHub->SetOnNavBarStateChange(std::move(onNavBarStateChange));
896 }
897 
SetBackButtonIcon(const std::string & src,bool noPixMap,RefPtr<PixelMap> & pixMap)898 void NavigationView::SetBackButtonIcon(const std::string& src, bool noPixMap, RefPtr<PixelMap>& pixMap)
899 {
900     ImageSourceInfo imageSourceInfo(src);
901     ACE_UPDATE_LAYOUT_PROPERTY(NavigationLayoutProperty, NoPixMap, noPixMap);
902     ACE_UPDATE_LAYOUT_PROPERTY(NavigationLayoutProperty, ImageSource, imageSourceInfo);
903     ACE_UPDATE_LAYOUT_PROPERTY(NavigationLayoutProperty, PixelMap, pixMap);
904     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
905     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
906     CHECK_NULL_VOID(navigationGroupNode);
907     auto navBarNode = AceType::DynamicCast<NavBarNode>(navigationGroupNode->GetNavBarNode());
908     CHECK_NULL_VOID(navBarNode);
909     auto navBarContentNode = navBarNode->GetNavBarContentNode();
910     CHECK_NULL_VOID(navBarContentNode);
911     if (navBarContentNode->GetChildren().empty()) {
912         return;
913     }
914     for (const auto& navBarContentChild : navBarContentNode->GetChildren()) {
915         auto navBarContentChildFrameNode = AceType::DynamicCast<FrameNode>(navBarContentChild);
916         CHECK_NULL_VOID(navBarContentChildFrameNode);
917         if (navBarContentChildFrameNode->GetTag() != V2::NAVROUTER_VIEW_ETS_TAG) {
918             return;
919         }
920         auto navRouterNode = AceType::DynamicCast<NavRouterGroupNode>(navBarContentChildFrameNode);
921         CHECK_NULL_VOID(navRouterNode);
922         auto navDestinationNode = AceType::DynamicCast<NavDestinationGroupNode>(navRouterNode->GetNavDestinationNode());
923         CHECK_NULL_VOID(navDestinationNode);
924         auto navDestinationLayoutProperty = navDestinationNode->GetLayoutProperty<NavDestinationLayoutProperty>();
925         navDestinationLayoutProperty->UpdateImageSource(imageSourceInfo);
926         navDestinationLayoutProperty->UpdateNoPixMap(noPixMap);
927         navDestinationLayoutProperty->UpdatePixelMap(pixMap);
928         navDestinationNode->MarkModifyDone();
929     }
930 }
931 
932 } // namespace OHOS::Ace::NG
933