• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-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/tabs/tab_content_model_ng.h"
17 #include <optional>
18 
19 #include "base/memory/ace_type.h"
20 #include "base/memory/referenced.h"
21 #include "base/utils/utils.h"
22 #include "core/components/tab_bar/tab_theme.h"
23 #include "core/components_ng/base/frame_node.h"
24 #include "core/components_ng/base/view_stack_processor.h"
25 #include "core/components_ng/pattern/image/image_layout_property.h"
26 #include "core/components_ng/pattern/image/image_pattern.h"
27 #include "core/components_ng/pattern/linear_layout/linear_layout_pattern.h"
28 #include "core/components_ng/pattern/swiper/swiper_pattern.h"
29 #include "core/components_ng/pattern/tabs/tab_bar_item_pattern.h"
30 #include "core/components_ng/pattern/tabs/tab_bar_pattern.h"
31 #include "core/components_ng/pattern/tabs/tab_content_event_hub.h"
32 #include "core/components_ng/pattern/tabs/tab_content_node.h"
33 #include "core/components_ng/pattern/tabs/tab_content_pattern.h"
34 #include "core/components_ng/pattern/tabs/tabs_node.h"
35 #include "core/components_ng/pattern/text/text_pattern.h"
36 #include "core/components_ng/pattern/symbol/constants.h"
37 #include "core/components_ng/pattern/symbol/symbol_effect_options.h"
38 #include "core/components_v2/inspector/inspector_constants.h"
39 
40 namespace OHOS::Ace::NG {
41 namespace {
42 constexpr uint16_t PIXEL_ROUND = static_cast<uint16_t>(PixelRoundPolicy::FORCE_FLOOR_START) |
43                                 static_cast<uint16_t>(PixelRoundPolicy::FORCE_FLOOR_TOP) |
44                                 static_cast<uint16_t>(PixelRoundPolicy::FORCE_CEIL_END) |
45                                 static_cast<uint16_t>(PixelRoundPolicy::FORCE_CEIL_BOTTOM);
46 constexpr uint32_t DEFAULT_RENDERING_STRATEGY = 2;
47 const auto MASK_COUNT = 2;
48 }
49 
Create(std::function<void ()> && deepRenderFunc)50 void TabContentModelNG::Create(std::function<void()>&& deepRenderFunc)
51 {
52     auto* stack = ViewStackProcessor::GetInstance();
53     auto nodeId = stack->ClaimNodeId();
54     auto deepRender = [nodeId, deepRenderFunc = std::move(deepRenderFunc)]() -> RefPtr<UINode> {
55         CHECK_NULL_RETURN(deepRenderFunc, nullptr);
56         ScopedViewStackProcessor scopedViewStackProcessor;
57         deepRenderFunc();
58         auto deepChild = ViewStackProcessor::GetInstance()->Finish();
59         auto parent = FrameNode::GetFrameNode(V2::TAB_CONTENT_ITEM_ETS_TAG, nodeId);
60         if (deepChild && parent) {
61             deepChild->MountToParent(parent);
62         }
63         return deepChild;
64     };
65     ACE_LAYOUT_SCOPED_TRACE("Create[%s][self:%d]", V2::TAB_CONTENT_ITEM_ETS_TAG, nodeId);
66     auto frameNode = TabContentNode::GetOrCreateTabContentNode(V2::TAB_CONTENT_ITEM_ETS_TAG, nodeId,
67         [shallowBuilder = AceType::MakeRefPtr<ShallowBuilder>(std::move(deepRender))]() {
68             return AceType::MakeRefPtr<TabContentPattern>(shallowBuilder);
69         });
70     stack->Push(frameNode);
71     auto pipelineContext = PipelineContext::GetCurrentContext();
72     CHECK_NULL_VOID(pipelineContext);
73     auto tabTheme = pipelineContext->GetTheme<TabTheme>();
74     CHECK_NULL_VOID(tabTheme);
75     SetTabBar(tabTheme->GetDefaultTabBarName(), "", std::nullopt, nullptr, true); // Set default tab bar.
76     ACE_UPDATE_LAYOUT_PROPERTY(TabContentLayoutProperty, Text, tabTheme->GetDefaultTabBarName());
77 }
78 
Create()79 void TabContentModelNG::Create()
80 {
81     auto* stack = ViewStackProcessor::GetInstance();
82     int32_t nodeId = stack->ClaimNodeId();
83     ACE_LAYOUT_SCOPED_TRACE("Create[%s][self:%d]", V2::TAB_CONTENT_ITEM_ETS_TAG, nodeId);
84     auto frameNode = TabContentNode::GetOrCreateTabContentNode(
85         V2::TAB_CONTENT_ITEM_ETS_TAG, nodeId, []() { return AceType::MakeRefPtr<TabContentPattern>(nullptr); });
86     stack->Push(frameNode);
87     auto pipelineContext = PipelineContext::GetCurrentContext();
88     CHECK_NULL_VOID(pipelineContext);
89     auto tabTheme = pipelineContext->GetTheme<TabTheme>();
90     CHECK_NULL_VOID(tabTheme);
91     SetTabBar(tabTheme->GetDefaultTabBarName(), "", std::nullopt, nullptr, true); // Set default tab bar.
92     ACE_UPDATE_LAYOUT_PROPERTY(TabContentLayoutProperty, Text, tabTheme->GetDefaultTabBarName());
93 }
94 
CreateFrameNode(int32_t nodeId)95 RefPtr<FrameNode> TabContentModelNG::CreateFrameNode(int32_t nodeId)
96 {
97     auto frameNode = TabContentNode::GetOrCreateTabContentNode(
98         V2::TAB_CONTENT_ITEM_ETS_TAG, nodeId, []() { return AceType::MakeRefPtr<TabContentPattern>(nullptr); });
99     auto pipelineContext = PipelineContext::GetCurrentContextSafely();
100     CHECK_NULL_RETURN(pipelineContext, nullptr);
101     auto tabTheme = pipelineContext->GetTheme<TabTheme>();
102     CHECK_NULL_RETURN(tabTheme, nullptr);
103     auto layout = frameNode->GetLayoutProperty<TabContentLayoutProperty>();
104     CHECK_NULL_RETURN(layout, nullptr);
105     auto text = tabTheme->GetDefaultTabBarName();
106     layout->UpdateText(text);
107     layout->UpdateIcon("");
108     auto pattern = frameNode->GetPattern<TabContentPattern>();
109     CHECK_NULL_RETURN(pattern, nullptr);
110     pattern->SetTabBar(text, "", std::nullopt, nullptr);
111     return frameNode;
112 }
113 
Pop()114 void TabContentModelNG::Pop()
115 {
116     auto tabContent = AceType::Claim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
117     AddTabBarItem(tabContent, DEFAULT_NODE_SLOT, true);
118     NG::ViewStackProcessor::GetInstance()->PopContainer();
119 }
120 
FindTabsNode(const RefPtr<UINode> & tabContent)121 RefPtr<TabsNode> TabContentModelNG::FindTabsNode(const RefPtr<UINode>& tabContent)
122 {
123     CHECK_NULL_RETURN(tabContent, nullptr);
124     RefPtr<UINode> parent = tabContent->GetParent();
125 
126     while (parent) {
127         if (AceType::InstanceOf<TabsNode>(parent)) {
128             return AceType::DynamicCast<TabsNode>(parent);
129         }
130         parent = parent->GetParent();
131     }
132     return nullptr;
133 }
134 
AddTabBarItem(const RefPtr<UINode> & tabContent,int32_t position,bool update)135 void TabContentModelNG::AddTabBarItem(const RefPtr<UINode>& tabContent, int32_t position, bool update)
136 {
137     CHECK_NULL_VOID(tabContent);
138     auto tabContentId = tabContent->GetId();
139 
140     auto tabContentNode = AceType::DynamicCast<TabContentNode>(tabContent);
141     CHECK_NULL_VOID(tabContentNode);
142 
143     if (update && !tabContentNode->HasTabBarItemId()) {
144         return;
145     }
146 
147     auto tabsNode = FindTabsNode(tabContent);
148     CHECK_NULL_VOID(tabsNode);
149     auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
150     CHECK_NULL_VOID(tabBarNode);
151     auto tabBarRenderContext = tabBarNode->GetRenderContext();
152     CHECK_NULL_VOID(tabBarRenderContext);
153     auto tabContentPattern = tabContentNode->GetPattern<TabContentPattern>();
154     CHECK_NULL_VOID(tabContentPattern);
155     const auto& tabBarParam = tabContentPattern->GetTabBarParam();
156 
157     // Create column node to contain image and text or builder.
158     auto columnNode = FrameNode::GetOrCreateFrameNode(V2::COLUMN_ETS_TAG, tabContentNode->GetTabBarItemId(),
159         []() { return AceType::MakeRefPtr<TabBarItemPattern>(); });
160     auto pipelineContext = tabsNode->GetContext();
161     CHECK_NULL_VOID(pipelineContext);
162     auto tabTheme = pipelineContext->GetTheme<TabTheme>();
163     CHECK_NULL_VOID(tabTheme);
164     auto linearLayoutProperty = columnNode->GetLayoutProperty<LinearLayoutProperty>();
165     CHECK_NULL_VOID(linearLayoutProperty);
166     linearLayoutProperty->UpdateMainAxisAlign(FlexAlign::CENTER);
167     linearLayoutProperty->UpdateCrossAxisAlign(FlexAlign::CENTER);
168     linearLayoutProperty->UpdateSpace(tabTheme->GetBottomTabBarSpace());
169     linearLayoutProperty->UpdatePixelRound(PIXEL_ROUND);
170     auto columnRenderContext = columnNode->GetRenderContext();
171     CHECK_NULL_VOID(columnRenderContext);
172     columnRenderContext->UpdateClipEdge(tabBarRenderContext->GetClipEdgeValue(true));
173     auto tabBarPattern = tabBarNode->GetPattern<TabBarPattern>();
174     CHECK_NULL_VOID(tabBarPattern);
175     tabBarPattern->SetTabBarStyle(tabBarParam.GetTabBarStyle());
176     tabBarPattern->AddTabBarItemClickEvent(columnNode);
177     tabBarPattern->AddTabBarItemCallBack(columnNode);
178     auto selectedMode = tabContentPattern->GetSelectedMode();
179     auto indicatorStyle = tabContentPattern->GetIndicatorStyle();
180     auto boardStyle = tabContentPattern->GetBoardStyle();
181     auto bottomTabBarStyle = tabContentPattern->GetBottomTabBarStyle();
182     auto padding = tabContentPattern->GetPadding();
183     auto tabLayoutProperty = AceType::DynamicCast<TabsLayoutProperty>(tabsNode->GetLayoutProperty());
184     CHECK_NULL_VOID(tabLayoutProperty);
185     auto tabBarLayoutProperty = AceType::DynamicCast<TabBarLayoutProperty>(tabBarNode->GetLayoutProperty());
186     CHECK_NULL_VOID(tabBarLayoutProperty);
187     auto tabsDirection = tabLayoutProperty->GetNonAutoLayoutDirection();
188     auto tabBarDirection = tabBarLayoutProperty->GetLayoutDirection();
189     auto isRTL = tabBarDirection == TextDirection::RTL ||
190              (tabBarDirection == TextDirection::AUTO && tabsDirection == TextDirection::RTL);
191     if (isRTL && tabContentPattern->GetUseLocalizedPadding()) {
192         PaddingProperty paddingRtl;
193         paddingRtl.left = padding.right;
194         paddingRtl.right = padding.left;
195         paddingRtl.top = padding.top;
196         paddingRtl.bottom = padding.bottom;
197         padding = paddingRtl;
198     }
199 
200     if (tabBarParam.GetTabBarStyle() == TabBarStyle::BOTTOMTABBATSTYLE) {
201         if (bottomTabBarStyle.layoutMode == LayoutMode::HORIZONTAL) {
202             linearLayoutProperty->UpdateFlexDirection(FlexDirection::ROW);
203             linearLayoutProperty->UpdateSpace(tabTheme->GetHorizontalBottomTabBarSpace());
204             linearLayoutProperty->UpdateCrossAxisAlign(bottomTabBarStyle.verticalAlign);
205             linearLayoutProperty->SetIsVertical(false);
206         } else {
207             linearLayoutProperty->UpdateFlexDirection(FlexDirection::COLUMN);
208             linearLayoutProperty->UpdateSpace(tabTheme->GetBottomTabBarSpace());
209             linearLayoutProperty->UpdateMainAxisAlign(bottomTabBarStyle.verticalAlign);
210             linearLayoutProperty->SetIsVertical(true);
211         }
212     }
213 
214     auto swiperNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabs());
215     CHECK_NULL_VOID(swiperNode);
216     auto myIndex = swiperNode->GetChildFlatIndex(tabContentId).second;
217 
218     tabBarPattern->SetTabBarStyle(tabBarParam.GetTabBarStyle(), myIndex);
219     tabBarPattern->SetBottomTabBarStyle(bottomTabBarStyle, myIndex);
220     auto labelStyle = tabContentPattern->GetLabelStyle();
221     tabBarPattern->SetLabelStyle(columnNode->GetId(), labelStyle);
222     auto iconStyle = tabContentPattern->GetIconStyle();
223     tabBarPattern->SetIconStyle(iconStyle, myIndex);
224     auto symbol = tabContentPattern->GetSymbol();
225     tabBarPattern->SetSymbol(symbol, myIndex);
226     auto tabBarStyle = tabContentPattern->GetTabBarStyle();
227     if (tabBarStyle == TabBarStyle::SUBTABBATSTYLE) {
228         auto renderContext = columnNode->GetRenderContext();
229         CHECK_NULL_VOID(renderContext);
230         BorderRadiusProperty borderRadiusProperty;
231         borderRadiusProperty.SetRadius(boardStyle.borderRadius);
232         renderContext->UpdateBorderRadius(borderRadiusProperty);
233     }
234     if (tabBarStyle != TabBarStyle::SUBTABBATSTYLE) {
235         indicatorStyle.marginTop = 0.0_vp;
236     }
237     tabBarPattern->SetSelectedMode(selectedMode, myIndex);
238     tabBarPattern->SetIndicatorStyle(indicatorStyle, myIndex);
239 
240     // Create tab bar with builder.
241     if (tabBarParam.HasBuilder()) {
242         ScopedViewStackProcessor builderViewStackProcessor;
243         tabBarParam.ExecuteBuilder();
244         auto builderNode = ViewStackProcessor::GetInstance()->Finish();
245         if (static_cast<int32_t>(columnNode->GetChildren().size()) != 0) {
246             columnNode->Clean();
247         }
248         if (builderNode) {
249             builderNode->MountToParent(columnNode);
250         }
251         auto oldColumnNode = tabsNode->GetBuilderByContentId(tabContentId, columnNode);
252         if (!oldColumnNode) {
253             auto index = std::clamp(myIndex, 0, static_cast<int32_t>(tabBarNode->GetChildren().size()) - MASK_COUNT);
254             columnNode->MountToParent(tabBarNode, index);
255         } else if (oldColumnNode != columnNode) {
256             tabBarNode->ReplaceChild(oldColumnNode, columnNode);
257         }
258         columnNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD);
259         tabBarPattern->AddTabBarItemType(columnNode->GetId(), TabBarParamType::CUSTOM_BUILDER);
260         tabBarPattern->SetIsExecuteBuilder(true);
261         tabBarNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_PARENT);
262         return;
263     }
264 
265     // Create text node and image node.
266     RefPtr<FrameNode> textNode;
267     RefPtr<FrameNode> iconNode;
268     auto layoutProperty = columnNode->GetLayoutProperty();
269     CHECK_NULL_VOID(layoutProperty);
270     if (tabBarStyle == TabBarStyle::SUBTABBATSTYLE || tabBarStyle == TabBarStyle::BOTTOMTABBATSTYLE) {
271         layoutProperty->UpdatePadding(padding);
272         auto accessibilityProperty = columnNode->GetAccessibilityProperty<AccessibilityProperty>();
273         accessibilityProperty->SetAccessibilityGroup(true);
274         auto id = tabContentPattern->GetId();
275         columnNode->UpdateInspectorId(id);
276     } else {
277         auto tabBarItemPadding = tabTheme->GetSubTabItemPadding();
278         layoutProperty->UpdatePadding({ CalcLength(tabBarItemPadding), CalcLength(tabBarItemPadding),
279             CalcLength(tabBarItemPadding), CalcLength(tabBarItemPadding) });
280     }
281 
282     bool isFrameNode = tabBarStyle == TabBarStyle::SUBTABBATSTYLE && tabContentPattern->HasSubTabBarStyleNode();
283     if (isFrameNode) {
284         tabBarPattern->AddTabBarItemType(columnNode->GetId(), TabBarParamType::COMPONENT_CONTENT);
285     } else {
286         tabBarPattern->AddTabBarItemType(columnNode->GetId(), TabBarParamType::NORMAL);
287     }
288     if (static_cast<int32_t>(columnNode->GetChildren().size()) == 0) {
289         if (tabBarParam.GetSymbol().has_value()) {
290             iconNode = FrameNode::GetOrCreateFrameNode(V2::SYMBOL_ETS_TAG,
291                 ElementRegister::GetInstance()->MakeUniqueId(), []() { return AceType::MakeRefPtr<TextPattern>(); });
292         } else {
293             iconNode = FrameNode::GetOrCreateFrameNode(V2::IMAGE_ETS_TAG,
294                 ElementRegister::GetInstance()->MakeUniqueId(), []() { return AceType::MakeRefPtr<ImagePattern>(); });
295         }
296         if (isFrameNode) {
297             textNode = tabContentPattern->FireCustomStyleNode();
298         } else {
299             textNode = FrameNode::GetOrCreateFrameNode(V2::TEXT_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
300                 []() { return AceType::MakeRefPtr<TextPattern>(); });
301         }
302         CHECK_NULL_VOID(textNode);
303         CHECK_NULL_VOID(iconNode);
304         auto index = std::clamp(position, 0, static_cast<int32_t>(tabBarNode->GetChildren().size()) - MASK_COUNT);
305         columnNode->MountToParent(tabBarNode, index);
306         iconNode->MountToParent(columnNode);
307         textNode->MountToParent(columnNode);
308     } else {
309         if (isFrameNode) {
310             auto builderNode = tabContentPattern->FireCustomStyleNode();
311             columnNode->ReplaceChild(AceType::DynamicCast<FrameNode>(columnNode->GetChildren().back()), builderNode);
312         }
313         auto oldIcon = AceType::DynamicCast<FrameNode>(columnNode->GetChildren().front());
314         CHECK_NULL_VOID(oldIcon);
315         if (tabBarParam.GetSymbol().has_value() && oldIcon->GetTag() != V2::SYMBOL_ETS_TAG) {
316             auto icon = FrameNode::GetOrCreateFrameNode(V2::SYMBOL_ETS_TAG,
317                 ElementRegister::GetInstance()->MakeUniqueId(), []() { return AceType::MakeRefPtr<TextPattern>(); });
318             columnNode->ReplaceChild(oldIcon, icon);
319         } else if (!tabBarParam.GetIcon().empty() && oldIcon->GetTag() != V2::IMAGE_ETS_TAG) {
320             auto icon = FrameNode::GetOrCreateFrameNode(V2::IMAGE_ETS_TAG,
321                 ElementRegister::GetInstance()->MakeUniqueId(), []() { return AceType::MakeRefPtr<ImagePattern>(); });
322             columnNode->ReplaceChild(oldIcon, icon);
323         }
324         iconNode = AceType::DynamicCast<FrameNode>(columnNode->GetChildren().front());
325         textNode = AceType::DynamicCast<FrameNode>(columnNode->GetChildren().back());
326     }
327     CHECK_NULL_VOID(textNode);
328     CHECK_NULL_VOID(iconNode);
329 
330     auto swiperPattern = swiperNode->GetPattern<SwiperPattern>();
331     CHECK_NULL_VOID(swiperPattern);
332     auto swiperLayoutProperty = swiperNode->GetLayoutProperty<SwiperLayoutProperty>();
333     CHECK_NULL_VOID(swiperLayoutProperty);
334     int32_t indicator = 0;
335     if (tabLayoutProperty->GetIndexSetByUser().has_value()) {
336         indicator = tabLayoutProperty->GetIndexSetByUser().value();
337     } else if (swiperLayoutProperty->GetIndex().has_value()) {
338         indicator = swiperLayoutProperty->GetIndex().value();
339     }
340     int32_t totalCount = swiperPattern->TotalCount();
341     if (indicator > totalCount - 1 || indicator < 0) {
342         indicator = 0;
343     }
344     tabBarPattern->UpdateSubTabBoard(indicator);
345     // Update property of text.
346     auto textLayoutProperty = textNode->GetLayoutProperty<TextLayoutProperty>();
347     CHECK_NULL_VOID(textLayoutProperty);
348     auto axis = tabBarLayoutProperty->GetAxis().value_or(Axis::HORIZONTAL);
349     if ((!swiperPattern->IsUseCustomAnimation() || !swiperPattern->GetCustomAnimationToIndex().has_value()) &&
350         !isFrameNode) {
351         if (myIndex == indicator) {
352             if (labelStyle.selectedColor.has_value()) {
353                 textLayoutProperty->UpdateTextColor(labelStyle.selectedColor.value());
354             } else {
355                 selectedMode == SelectedMode::BOARD && axis == Axis::HORIZONTAL ?
356                     textLayoutProperty->UpdateTextColor(tabTheme->GetSubTabBoardTextOnColor()) :
357                     textLayoutProperty->UpdateTextColor(tabTheme->GetSubTabTextOnColor());
358             }
359         } else {
360             if (labelStyle.unselectedColor.has_value()) {
361                 textLayoutProperty->UpdateTextColor(labelStyle.unselectedColor.value());
362             } else {
363                 textLayoutProperty->UpdateTextColor(tabTheme->GetSubTabTextOffColor());
364             }
365         }
366     }
367 
368     auto textRenderContext = textNode->GetRenderContext();
369     CHECK_NULL_VOID(textRenderContext);
370     textRenderContext->UpdateClipEdge(true);
371     if (!isFrameNode) {
372         textLayoutProperty->UpdateContent(tabBarParam.GetText());
373         textLayoutProperty->UpdateFontSize(tabTheme->GetSubTabTextDefaultFontSize());
374         textLayoutProperty->UpdateTextAlign(TextAlign::CENTER);
375         textLayoutProperty->UpdateMaxLines(1);
376         textLayoutProperty->UpdateTextOverflow(TextOverflow::ELLIPSIS);
377     }
378     if (tabBarStyle == TabBarStyle::BOTTOMTABBATSTYLE) {
379         textLayoutProperty->UpdateFlexShrink(1.0f);
380     }
381 
382     if (!tabBarParam.GetIcon().empty() || tabBarStyle == TabBarStyle::BOTTOMTABBATSTYLE) {
383         textLayoutProperty->UpdateFontSize(tabTheme->GetBottomTabTextSize());
384     }
385     if (tabBarStyle == TabBarStyle::BOTTOMTABBATSTYLE) {
386         textLayoutProperty->UpdateFontWeight(FontWeight::MEDIUM);
387     } else if (tabBarStyle == TabBarStyle::SUBTABBATSTYLE && !isFrameNode) {
388         textLayoutProperty->UpdateFontWeight(myIndex == indicator ? FontWeight::MEDIUM : FontWeight::NORMAL);
389     }
390     if (tabBarStyle == TabBarStyle::BOTTOMTABBATSTYLE && bottomTabBarStyle.layoutMode == LayoutMode::HORIZONTAL) {
391         textLayoutProperty->UpdateTextAlign(TextAlign::LEFT);
392         if (!labelStyle.fontSize.has_value() &&
393             Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
394             textLayoutProperty->UpdateFontSize(tabTheme->GetBottomTabHorizontalTextSize());
395         }
396     }
397     if (!isFrameNode) {
398         UpdateLabelStyle(labelStyle, textLayoutProperty);
399     }
400 
401     // Update property of image/symbol.
402     if (tabBarParam.GetSymbol().has_value()) {
403         auto symbolProperty = iconNode->GetLayoutProperty<TextLayoutProperty>();
404         CHECK_NULL_VOID(symbolProperty);
405         UpdateDefaultSymbol(tabTheme, symbolProperty);
406         auto modifierOnApply = tabBarParam.GetSymbol().value().onApply;
407         if (myIndex == indicator) {
408             tabBarPattern->SetImageColorOnIndex(indicator);
409             symbolProperty->UpdateSymbolColorList({tabTheme->GetBottomTabSymbolOn()});
410             if (modifierOnApply != nullptr) {
411                 modifierOnApply(AccessibilityManager::WeakClaim(AccessibilityManager::RawPtr(iconNode)), "normal");
412                 UpdateDefaultSymbol(tabTheme, symbolProperty);
413                 symbolProperty->UpdateSymbolColorList({tabTheme->GetBottomTabSymbolOn()});
414             }
415             if (modifierOnApply != nullptr && tabBarParam.GetSymbol().value().selectedFlag) {
416                 modifierOnApply(AccessibilityManager::WeakClaim(AccessibilityManager::RawPtr(iconNode)),
417                     "selected");
418                 UpdateSymbolEffect(symbolProperty, false);
419             }
420         } else {
421             symbolProperty->UpdateSymbolColorList({tabTheme->GetBottomTabSymbolOff()});
422             if (modifierOnApply != nullptr) {
423                 modifierOnApply(AccessibilityManager::WeakClaim(AccessibilityManager::RawPtr(iconNode)), "normal");
424                 UpdateSymbolEffect(symbolProperty, false);
425             }
426         }
427     } else {
428         auto imageProperty = iconNode->GetLayoutProperty<ImageLayoutProperty>();
429         CHECK_NULL_VOID(imageProperty);
430         if (!tabBarParam.GetIcon().empty() || tabBarStyle == TabBarStyle::BOTTOMTABBATSTYLE) {
431             imageProperty->UpdateUserDefinedIdealSize(CalcSize(
432                 NG::CalcLength(tabTheme->GetBottomTabImageSize()), NG::CalcLength(tabTheme->GetBottomTabImageSize())));
433         } else {
434             imageProperty->UpdateUserDefinedIdealSize(CalcSize());
435         }
436         ImageSourceInfo imageSourceInfo(tabBarParam.GetIcon());
437         auto imagePaintProperty = iconNode->GetPaintProperty<ImageRenderProperty>();
438         CHECK_NULL_VOID(imagePaintProperty);
439         if (imageSourceInfo.IsSvg() && myIndex == indicator) {
440             tabBarPattern->SetImageColorOnIndex(indicator);
441             if (iconStyle.selectedColor.has_value()) {
442                 imagePaintProperty->UpdateSvgFillColor(iconStyle.selectedColor.value());
443             } else {
444                 imagePaintProperty->UpdateSvgFillColor(tabTheme->GetBottomTabIconOn());
445             }
446         }
447         if (imageSourceInfo.IsSvg() && myIndex != indicator) {
448             if (iconStyle.unselectedColor.has_value()) {
449                 imagePaintProperty->UpdateSvgFillColor(iconStyle.unselectedColor.value());
450             } else {
451                 imagePaintProperty->UpdateSvgFillColor(tabTheme->GetBottomTabIconOff());
452             }
453         }
454         imageProperty->UpdateImageSourceInfo(imageSourceInfo);
455     }
456     columnNode->MarkModifyDone();
457     textNode->MarkModifyDone();
458     textNode->MarkDirtyNode();
459     iconNode->MarkModifyDone();
460     tabBarNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_PARENT);
461 }
462 
RemoveTabBarItem(const RefPtr<TabContentNode> & tabContentNode)463 void TabContentModelNG::RemoveTabBarItem(const RefPtr<TabContentNode>& tabContentNode)
464 {
465     CHECK_NULL_VOID(tabContentNode);
466     if (!tabContentNode->HasTabBarItemId()) {
467         return;
468     }
469 
470     auto tabBarItemId = tabContentNode->GetTabBarItemId();
471     auto tabBarItemNode = ElementRegister::GetInstance()->GetUINodeById(tabBarItemId);
472     CHECK_NULL_VOID(tabBarItemNode);
473     auto tabBarNode = tabBarItemNode->GetParent();
474     CHECK_NULL_VOID(tabBarNode);
475     auto tabBarFrameNode = AceType::DynamicCast<FrameNode>(tabBarNode);
476     CHECK_NULL_VOID(tabBarFrameNode);
477     auto tabBarPattern = tabBarFrameNode->GetPattern<TabBarPattern>();
478     CHECK_NULL_VOID(tabBarPattern);
479     tabBarPattern->RemoveTabBarItemInfo(tabBarItemId);
480     tabBarNode->RemoveChild(tabBarItemNode);
481     tabContentNode->ResetTabBarItemId();
482 
483     auto tabsNode = FindTabsNode(tabContentNode);
484     CHECK_NULL_VOID(tabsNode);
485     tabsNode->RemoveBuilderByContentId(tabContentNode->GetId());
486     tabBarFrameNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_PARENT);
487 }
488 
SetTabBar(const std::optional<std::string> & text,const std::optional<std::string> & icon,const std::optional<TabBarSymbol> & tabBarSymbol,TabBarBuilderFunc && builder,bool)489 void TabContentModelNG::SetTabBar(const std::optional<std::string>& text, const std::optional<std::string>& icon,
490     const std::optional<TabBarSymbol>& tabBarSymbol, TabBarBuilderFunc&& builder, bool /*useContentOnly*/)
491 {
492     ACE_UPDATE_LAYOUT_PROPERTY(TabContentLayoutProperty, Icon, icon.value_or(""));
493     ACE_UPDATE_LAYOUT_PROPERTY(TabContentLayoutProperty, Text, text.value_or(""));
494     auto frameNodePattern = ViewStackProcessor::GetInstance()->GetMainFrameNodePattern<TabContentPattern>();
495     CHECK_NULL_VOID(frameNodePattern);
496     frameNodePattern->SetTabBar(text.value_or(""), icon.value_or(""), tabBarSymbol, std::move(builder));
497 }
498 
SetTabBarStyle(TabBarStyle tabBarStyle)499 void TabContentModelNG::SetTabBarStyle(TabBarStyle tabBarStyle)
500 {
501     auto frameNodePattern = ViewStackProcessor::GetInstance()->GetMainFrameNodePattern<TabContentPattern>();
502     CHECK_NULL_VOID(frameNodePattern);
503     frameNodePattern->SetTabBarStyle(tabBarStyle);
504 }
505 
SetIndicator(const IndicatorStyle & indicator)506 void TabContentModelNG::SetIndicator(const IndicatorStyle& indicator)
507 {
508     auto frameNodePattern = ViewStackProcessor::GetInstance()->GetMainFrameNodePattern<TabContentPattern>();
509     CHECK_NULL_VOID(frameNodePattern);
510     frameNodePattern->SetIndicatorStyle(indicator);
511 }
512 
SetCustomTabBar(FrameNode * node,FrameNode * tabBar)513 void TabContentModelNG::SetCustomTabBar(FrameNode* node, FrameNode* tabBar)
514 {
515     CHECK_NULL_VOID(node);
516     CHECK_NULL_VOID(tabBar);
517     auto frameNodePattern = node->GetPattern<TabContentPattern>();
518     CHECK_NULL_VOID(frameNodePattern);
519     frameNodePattern->SetTabBarStyle(TabBarStyle::NOSTYLE);
520     frameNodePattern->SetCustomTabBar(tabBar);
521 }
522 
SetBoard(const BoardStyle & board)523 void TabContentModelNG::SetBoard(const BoardStyle& board)
524 {
525     auto frameNodePattern = ViewStackProcessor::GetInstance()->GetMainFrameNodePattern<TabContentPattern>();
526     CHECK_NULL_VOID(frameNodePattern);
527     frameNodePattern->SetBoardStyle(board);
528 }
529 
SetSelectedMode(SelectedMode selectedMode)530 void TabContentModelNG::SetSelectedMode(SelectedMode selectedMode)
531 {
532     auto frameNodePattern = ViewStackProcessor::GetInstance()->GetMainFrameNodePattern<TabContentPattern>();
533     CHECK_NULL_VOID(frameNodePattern);
534     frameNodePattern->SetSelectedMode(selectedMode);
535 }
536 
SetLabelStyle(const LabelStyle & labelStyle)537 void TabContentModelNG::SetLabelStyle(const LabelStyle& labelStyle)
538 {
539     auto frameNodePattern = ViewStackProcessor::GetInstance()->GetMainFrameNodePattern<TabContentPattern>();
540     CHECK_NULL_VOID(frameNodePattern);
541     frameNodePattern->SetLabelStyle(labelStyle);
542 }
543 
SetIconStyle(const IconStyle & iconStyle)544 void TabContentModelNG::SetIconStyle(const IconStyle& iconStyle)
545 {
546     auto frameNodePattern = ViewStackProcessor::GetInstance()->GetMainFrameNodePattern<TabContentPattern>();
547     CHECK_NULL_VOID(frameNodePattern);
548     frameNodePattern->SetIconStyle(iconStyle);
549 }
550 
SetPadding(const PaddingProperty & padding)551 void TabContentModelNG::SetPadding(const PaddingProperty& padding)
552 {
553     auto frameNodePattern = ViewStackProcessor::GetInstance()->GetMainFrameNodePattern<TabContentPattern>();
554     CHECK_NULL_VOID(frameNodePattern);
555     frameNodePattern->SetPadding(padding);
556 }
557 
SetUseLocalizedPadding(bool useLocalizedPadding)558 void TabContentModelNG::SetUseLocalizedPadding(bool useLocalizedPadding)
559 {
560     auto frameNodePattern = ViewStackProcessor::GetInstance()->GetMainFrameNodePattern<TabContentPattern>();
561     CHECK_NULL_VOID(frameNodePattern);
562     frameNodePattern->SetUseLocalizedPadding(useLocalizedPadding);
563 }
564 
SetLayoutMode(LayoutMode layoutMode)565 void TabContentModelNG::SetLayoutMode(LayoutMode layoutMode)
566 {
567     auto frameNodePattern = ViewStackProcessor::GetInstance()->GetMainFrameNodePattern<TabContentPattern>();
568     CHECK_NULL_VOID(frameNodePattern);
569     frameNodePattern->SetLayoutMode(layoutMode);
570 }
571 
SetVerticalAlign(FlexAlign verticalAlign)572 void TabContentModelNG::SetVerticalAlign(FlexAlign verticalAlign)
573 {
574     auto frameNodePattern = ViewStackProcessor::GetInstance()->GetMainFrameNodePattern<TabContentPattern>();
575     CHECK_NULL_VOID(frameNodePattern);
576     frameNodePattern->SetVerticalAlign(verticalAlign);
577 }
578 
SetSymmetricExtensible(bool isExtensible)579 void TabContentModelNG::SetSymmetricExtensible(bool isExtensible)
580 {
581     auto frameNodePattern = ViewStackProcessor::GetInstance()->GetMainFrameNodePattern<TabContentPattern>();
582     CHECK_NULL_VOID(frameNodePattern);
583     frameNodePattern->SetSymmetricExtensible(isExtensible);
584 }
585 
SetId(const std::string & id)586 void TabContentModelNG::SetId(const std::string& id)
587 {
588     auto frameNodePattern = ViewStackProcessor::GetInstance()->GetMainFrameNodePattern<TabContentPattern>();
589     CHECK_NULL_VOID(frameNodePattern);
590     frameNodePattern->SetId(id);
591 }
592 
UpdateLabelStyle(const LabelStyle & labelStyle,RefPtr<TextLayoutProperty> textLayoutProperty)593 void TabContentModelNG::UpdateLabelStyle(const LabelStyle& labelStyle, RefPtr<TextLayoutProperty> textLayoutProperty)
594 {
595     CHECK_NULL_VOID(textLayoutProperty);
596 
597     if (labelStyle.fontSize.has_value()) {
598         textLayoutProperty->UpdateFontSize(labelStyle.fontSize.value());
599     }
600     if (labelStyle.fontWeight.has_value()) {
601         textLayoutProperty->UpdateFontWeight(labelStyle.fontWeight.value());
602     }
603     if (labelStyle.fontStyle.has_value()) {
604         textLayoutProperty->UpdateItalicFontStyle(labelStyle.fontStyle.value());
605     }
606     if (labelStyle.fontFamily.has_value()) {
607         textLayoutProperty->UpdateFontFamily(labelStyle.fontFamily.value());
608     }
609     if (labelStyle.textOverflow.has_value()) {
610         textLayoutProperty->UpdateTextOverflow(labelStyle.textOverflow.value());
611     }
612     if (labelStyle.maxLines.has_value()) {
613         textLayoutProperty->UpdateMaxLines(labelStyle.maxLines.value());
614     }
615     if (labelStyle.minFontSize.has_value()) {
616         textLayoutProperty->UpdateAdaptMinFontSize(labelStyle.minFontSize.value());
617     }
618     if (labelStyle.maxFontSize.has_value()) {
619         textLayoutProperty->UpdateAdaptMaxFontSize(labelStyle.maxFontSize.value());
620     }
621     if (labelStyle.heightAdaptivePolicy.has_value()) {
622         textLayoutProperty->UpdateHeightAdaptivePolicy(labelStyle.heightAdaptivePolicy.value());
623     }
624 }
625 
UpdateDefaultSymbol(RefPtr<TabTheme> & tabTheme,RefPtr<TextLayoutProperty> symbolProperty)626 void TabContentModelNG::UpdateDefaultSymbol(RefPtr<TabTheme>& tabTheme, RefPtr<TextLayoutProperty> symbolProperty)
627 {
628     symbolProperty->UpdateFontSize(tabTheme->GetBottomTabImageSize());
629     symbolProperty->UpdateSymbolRenderingStrategy(DEFAULT_RENDERING_STRATEGY);
630     UpdateSymbolEffect(symbolProperty, false);
631 }
UpdateSymbolEffect(RefPtr<TextLayoutProperty> symbolProperty,bool isActive)632 void TabContentModelNG::UpdateSymbolEffect(RefPtr<TextLayoutProperty> symbolProperty, bool isActive)
633 {
634     auto symbolEffectOptions = SymbolEffectOptions(SymbolEffectType::BOUNCE);
635     symbolEffectOptions.SetIsTxtActive(isActive);
636     symbolEffectOptions.SetIsTxtActiveSource(0);
637     symbolProperty->UpdateSymbolEffectOptions(symbolEffectOptions);
638 }
639 
SetOnWillShow(std::function<void ()> && onWillShow)640 void TabContentModelNG::SetOnWillShow(std::function<void()>&& onWillShow)
641 {
642     auto tabContentNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
643     CHECK_NULL_VOID(tabContentNode);
644     auto tabContentEventHub = tabContentNode->GetEventHub<TabContentEventHub>();
645     CHECK_NULL_VOID(tabContentEventHub);
646     tabContentEventHub->SetOnWillShow(onWillShow);
647 }
648 
SetOnWillHide(std::function<void ()> && onWillHide)649 void TabContentModelNG::SetOnWillHide(std::function<void()>&& onWillHide)
650 {
651     auto tabContentNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
652     CHECK_NULL_VOID(tabContentNode);
653     auto tabContentEventHub = tabContentNode->GetEventHub<TabContentEventHub>();
654     CHECK_NULL_VOID(tabContentEventHub);
655     tabContentEventHub->SetOnWillHide(onWillHide);
656 }
657 
SetCustomStyleNode(const RefPtr<FrameNode> & customStyleNode)658 void TabContentModelNG::SetCustomStyleNode(const RefPtr<FrameNode>& customStyleNode)
659 {
660     auto pattern = ViewStackProcessor::GetInstance()->GetMainFrameNodePattern<TabContentPattern>();
661     CHECK_NULL_VOID(pattern);
662     pattern->SetCustomStyleNode(customStyleNode);
663 }
664 
SetTabBarBuilder(FrameNode * node,TabBarBuilderFunc && builder)665 void TabContentModelNG::SetTabBarBuilder(FrameNode* node, TabBarBuilderFunc&& builder)
666 {
667     CHECK_NULL_VOID(node);
668     auto frameNodePattern = node->GetPattern<TabContentPattern>();
669     CHECK_NULL_VOID(frameNodePattern);
670     frameNodePattern->SetTabBar("", "", std::nullopt, std::move(builder));
671 }
672 
SetTabBarLabel(FrameNode * node,const std::string & label)673 void TabContentModelNG::SetTabBarLabel(FrameNode* node, const std::string& label)
674 {
675     CHECK_NULL_VOID(node);
676     auto frameNodePattern = node->GetPattern<TabContentPattern>();
677     CHECK_NULL_VOID(frameNodePattern);
678     frameNodePattern->SetTabBar(label, "", std::nullopt, nullptr);
679 }
680 } // namespace OHOS::Ace::NG
681