• 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 #include <string>
19 
20 #include "base/memory/ace_type.h"
21 #include "base/memory/referenced.h"
22 #include "base/utils/utils.h"
23 #include "core/common/resource/resource_parse_utils.h"
24 #include "core/components/tab_bar/tab_theme.h"
25 #include "core/components_ng/base/frame_node.h"
26 #include "core/components_ng/base/view_stack_processor.h"
27 #include "core/components_ng/pattern/image/image_layout_property.h"
28 #include "core/components_ng/pattern/image/image_pattern.h"
29 #include "core/components_ng/pattern/linear_layout/linear_layout_pattern.h"
30 #include "core/components_ng/pattern/swiper/swiper_pattern.h"
31 #include "core/components_ng/pattern/tabs/tab_bar_item_pattern.h"
32 #include "core/components_ng/pattern/tabs/tab_bar_pattern.h"
33 #include "core/components_ng/pattern/tabs/tab_content_event_hub.h"
34 #include "core/components_ng/pattern/tabs/tab_content_node.h"
35 #include "core/components_ng/pattern/tabs/tab_content_pattern.h"
36 #include "core/components_ng/pattern/tabs/tabs_node.h"
37 #include "core/components_ng/pattern/text/text_pattern.h"
38 #include "core/components_ng/pattern/symbol/constants.h"
39 #include "core/components_ng/pattern/symbol/symbol_effect_options.h"
40 #include "core/components_v2/inspector/inspector_constants.h"
41 
42 namespace OHOS::Ace::NG {
43 namespace {
44 constexpr uint16_t PIXEL_ROUND = static_cast<uint16_t>(PixelRoundPolicy::NO_FORCE_ROUND_START) |
45                                 static_cast<uint16_t>(PixelRoundPolicy::NO_FORCE_ROUND_TOP) |
46                                 static_cast<uint16_t>(PixelRoundPolicy::NO_FORCE_ROUND_END) |
47                                 static_cast<uint16_t>(PixelRoundPolicy::NO_FORCE_ROUND_BOTTOM);
48 constexpr uint32_t DEFAULT_RENDERING_STRATEGY = 2;
49 const auto MASK_COUNT = 2;
50 const std::string KEY_PADDING = "tabContent.tabBarPadding";
51 const std::string KEY_PADDING_LEFT = "tabContent.tabBarPadding.left";
52 const std::string KEY_PADDING_RIGHT = "tabContent.tabBarPadding.right";
53 const std::string KEY_PADDING_TOP = "tabContent.tabBarPadding.top";
54 const std::string KEY_PADDING_BOTTOM = "tabContent.tabBarPadding.bottom";
55 }
56 
Create(std::function<void ()> && deepRenderFunc)57 void TabContentModelNG::Create(std::function<void()>&& deepRenderFunc)
58 {
59     auto* stack = ViewStackProcessor::GetInstance();
60     auto nodeId = stack->ClaimNodeId();
61     auto deepRender = [nodeId, deepRenderFunc = std::move(deepRenderFunc)]() -> RefPtr<UINode> {
62         CHECK_NULL_RETURN(deepRenderFunc, nullptr);
63         ScopedViewStackProcessor scopedViewStackProcessor;
64         deepRenderFunc();
65         auto deepChild = ViewStackProcessor::GetInstance()->Finish();
66         auto parent = FrameNode::GetFrameNode(V2::TAB_CONTENT_ITEM_ETS_TAG, nodeId);
67         if (deepChild && parent) {
68             deepChild->MountToParent(parent);
69         }
70         return deepChild;
71     };
72     ACE_LAYOUT_SCOPED_TRACE("Create[%s][self:%d]", V2::TAB_CONTENT_ITEM_ETS_TAG, nodeId);
73     auto frameNode = TabContentNode::GetOrCreateTabContentNode(V2::TAB_CONTENT_ITEM_ETS_TAG, nodeId,
74         [shallowBuilder = AceType::MakeRefPtr<ShallowBuilder>(std::move(deepRender))]() {
75             return AceType::MakeRefPtr<TabContentPattern>(shallowBuilder);
76         });
77     stack->Push(frameNode);
78     auto pipelineContext = frameNode->GetContext();
79     CHECK_NULL_VOID(pipelineContext);
80     auto tabTheme = pipelineContext->GetTheme<TabTheme>();
81     CHECK_NULL_VOID(tabTheme);
82     SetTabBar(tabTheme->GetDefaultTabBarName(), "", std::nullopt, nullptr, true); // Set default tab bar.
83     ACE_UPDATE_LAYOUT_PROPERTY(TabContentLayoutProperty, Text, tabTheme->GetDefaultTabBarName());
84     if (SystemProperties::ConfigChangePerform()) {
85         auto tabsLayoutProperty = frameNode->GetLayoutProperty<TabContentLayoutProperty>();
86         CHECK_NULL_VOID(tabsLayoutProperty);
87         tabsLayoutProperty->ResetIndicatorColorSetByUser();
88         tabsLayoutProperty->ResetLabelUnselectedColorSetByUser();
89         tabsLayoutProperty->ResetLabelSelectedColorSetByUser();
90         tabsLayoutProperty->ResetIconUnselectedColorSetByUser();
91         tabsLayoutProperty->ResetIconSelectedColorSetByUser();
92     }
93 }
94 
Create()95 void TabContentModelNG::Create()
96 {
97     auto* stack = ViewStackProcessor::GetInstance();
98     int32_t nodeId = stack->ClaimNodeId();
99     ACE_LAYOUT_SCOPED_TRACE("Create[%s][self:%d]", V2::TAB_CONTENT_ITEM_ETS_TAG, nodeId);
100     auto frameNode = TabContentNode::GetOrCreateTabContentNode(
101         V2::TAB_CONTENT_ITEM_ETS_TAG, nodeId, []() { return AceType::MakeRefPtr<TabContentPattern>(nullptr); });
102     stack->Push(frameNode);
103     auto pipelineContext = frameNode->GetContext();
104     CHECK_NULL_VOID(pipelineContext);
105     auto tabTheme = pipelineContext->GetTheme<TabTheme>();
106     CHECK_NULL_VOID(tabTheme);
107     SetTabBar(tabTheme->GetDefaultTabBarName(), "", std::nullopt, nullptr, true); // Set default tab bar.
108     ACE_UPDATE_LAYOUT_PROPERTY(TabContentLayoutProperty, Text, tabTheme->GetDefaultTabBarName());
109 }
110 
CreateFrameNode(int32_t nodeId)111 RefPtr<FrameNode> TabContentModelNG::CreateFrameNode(int32_t nodeId)
112 {
113     auto frameNode = TabContentNode::GetOrCreateTabContentNode(
114         V2::TAB_CONTENT_ITEM_ETS_TAG, nodeId, []() { return AceType::MakeRefPtr<TabContentPattern>(nullptr); });
115     auto pipelineContext = frameNode->GetContext();
116     CHECK_NULL_RETURN(pipelineContext, nullptr);
117     auto tabTheme = pipelineContext->GetTheme<TabTheme>();
118     CHECK_NULL_RETURN(tabTheme, nullptr);
119     auto layout = frameNode->GetLayoutProperty<TabContentLayoutProperty>();
120     CHECK_NULL_RETURN(layout, nullptr);
121     auto text = tabTheme->GetDefaultTabBarName();
122     layout->UpdateText(text);
123     layout->UpdateIcon("");
124     auto pattern = frameNode->GetPattern<TabContentPattern>();
125     CHECK_NULL_RETURN(pattern, nullptr);
126     pattern->SetTabBar(text, "", std::nullopt, nullptr);
127     pattern->SetTabBarWithContent(nullptr);
128     return frameNode;
129 }
130 
Pop()131 void TabContentModelNG::Pop()
132 {
133     auto tabContent = AceType::Claim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
134     AddTabBarItem(tabContent, DEFAULT_NODE_SLOT, true);
135     NG::ViewStackProcessor::GetInstance()->PopContainer();
136 }
137 
FindTabsNode(const RefPtr<UINode> & tabContent)138 RefPtr<TabsNode> TabContentModelNG::FindTabsNode(const RefPtr<UINode>& tabContent)
139 {
140     CHECK_NULL_RETURN(tabContent, nullptr);
141     RefPtr<UINode> parent = tabContent->GetParent();
142 
143     while (parent) {
144         if (AceType::InstanceOf<TabsNode>(parent)) {
145             return AceType::DynamicCast<TabsNode>(parent);
146         }
147         parent = parent->GetParent();
148     }
149     return nullptr;
150 }
151 
AddTabBarItem(const RefPtr<UINode> & tabContent,int32_t position,bool update)152 void TabContentModelNG::AddTabBarItem(const RefPtr<UINode>& tabContent, int32_t position, bool update)
153 {
154     CHECK_NULL_VOID(tabContent);
155     auto tabContentId = tabContent->GetId();
156 
157     auto tabContentNode = AceType::DynamicCast<TabContentNode>(tabContent);
158     CHECK_NULL_VOID(tabContentNode);
159 
160     if (update && !tabContentNode->HasTabBarItemId()) {
161         return;
162     }
163 
164     auto tabsNode = FindTabsNode(tabContent);
165     CHECK_NULL_VOID(tabsNode);
166     auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
167     CHECK_NULL_VOID(tabBarNode);
168     auto tabBarRenderContext = tabBarNode->GetRenderContext();
169     CHECK_NULL_VOID(tabBarRenderContext);
170     auto tabContentPattern = tabContentNode->GetPattern<TabContentPattern>();
171     CHECK_NULL_VOID(tabContentPattern);
172     const auto& tabBarParam = tabContentPattern->GetTabBarParam();
173 
174     // Create column node to contain image and text or builder.
175     auto columnNode = FrameNode::GetOrCreateFrameNode(V2::COLUMN_ETS_TAG, tabContentNode->GetTabBarItemId(),
176         []() { return AceType::MakeRefPtr<TabBarItemPattern>(); });
177     auto pipelineContext = tabsNode->GetContext();
178     CHECK_NULL_VOID(pipelineContext);
179     auto tabTheme = pipelineContext->GetTheme<TabTheme>();
180     CHECK_NULL_VOID(tabTheme);
181     auto linearLayoutProperty = columnNode->GetLayoutProperty<LinearLayoutProperty>();
182     CHECK_NULL_VOID(linearLayoutProperty);
183     linearLayoutProperty->UpdateMainAxisAlign(FlexAlign::CENTER);
184     linearLayoutProperty->UpdateCrossAxisAlign(FlexAlign::CENTER);
185     linearLayoutProperty->UpdateSpace(tabTheme->GetBottomTabBarSpace());
186     linearLayoutProperty->UpdatePixelRound(PIXEL_ROUND);
187     auto columnRenderContext = columnNode->GetRenderContext();
188     CHECK_NULL_VOID(columnRenderContext);
189     if (tabTheme->GetIsChangeFocusTextStyle()) {
190         columnRenderContext->UpdateClipEdge(false);
191     } else {
192         columnRenderContext->UpdateClipEdge(tabBarRenderContext->GetClipEdgeValue(true));
193     }
194     auto tabBarPattern = tabBarNode->GetPattern<TabBarPattern>();
195     CHECK_NULL_VOID(tabBarPattern);
196     tabBarPattern->SetTabBarStyle(tabBarParam.GetTabBarStyle());
197     tabBarPattern->AddTabBarItemClickAndTouchEvent(columnNode);
198     tabBarPattern->AddTabBarItemCallBack(columnNode);
199     auto selectedMode = tabContentPattern->GetSelectedMode();
200     auto indicatorStyle = tabContentPattern->GetIndicatorStyle();
201     auto boardStyle = tabContentPattern->GetBoardStyle();
202     auto bottomTabBarStyle = tabContentPattern->GetBottomTabBarStyle();
203     auto padding = tabContentPattern->GetPadding();
204     auto tabLayoutProperty = AceType::DynamicCast<TabsLayoutProperty>(tabsNode->GetLayoutProperty());
205     CHECK_NULL_VOID(tabLayoutProperty);
206     auto tabBarLayoutProperty = AceType::DynamicCast<TabBarLayoutProperty>(tabBarNode->GetLayoutProperty());
207     CHECK_NULL_VOID(tabBarLayoutProperty);
208     auto tabsDirection = tabLayoutProperty->GetNonAutoLayoutDirection();
209     auto tabBarDirection = tabBarLayoutProperty->GetLayoutDirection();
210     auto isRTL = tabBarDirection == TextDirection::RTL ||
211              (tabBarDirection == TextDirection::AUTO && tabsDirection == TextDirection::RTL);
212     if (isRTL && tabContentPattern->GetUseLocalizedPadding()) {
213         PaddingProperty paddingRtl;
214         paddingRtl.left = padding.right;
215         paddingRtl.right = padding.left;
216         paddingRtl.top = padding.top;
217         paddingRtl.bottom = padding.bottom;
218         padding = paddingRtl;
219     }
220 
221     if (tabBarParam.GetTabBarStyle() == TabBarStyle::BOTTOMTABBATSTYLE) {
222         if (bottomTabBarStyle.layoutMode == LayoutMode::HORIZONTAL) {
223             linearLayoutProperty->UpdateFlexDirection(FlexDirection::ROW);
224             linearLayoutProperty->UpdateSpace(tabTheme->GetHorizontalBottomTabBarSpace());
225             linearLayoutProperty->UpdateCrossAxisAlign(bottomTabBarStyle.verticalAlign);
226             linearLayoutProperty->SetIsVertical(false);
227         } else {
228             linearLayoutProperty->UpdateFlexDirection(FlexDirection::COLUMN);
229             linearLayoutProperty->UpdateSpace(tabTheme->GetBottomTabBarSpace());
230             linearLayoutProperty->UpdateMainAxisAlign(bottomTabBarStyle.verticalAlign);
231             linearLayoutProperty->SetIsVertical(true);
232         }
233     }
234 
235     auto swiperNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabs());
236     CHECK_NULL_VOID(swiperNode);
237     auto myIndex = swiperNode->GetChildFlatIndex(tabContentId).second;
238 
239     auto newTabBar = tabBarPattern->IsNewTabBar(columnNode->GetId());
240     tabBarPattern->SetTabBarStyle(tabBarParam.GetTabBarStyle(), myIndex, newTabBar);
241     tabBarPattern->AddTabBarItemId(columnNode->GetId(), myIndex, newTabBar);
242     tabBarPattern->SetBottomTabBarStyle(bottomTabBarStyle, myIndex, newTabBar);
243     auto labelStyle = tabContentPattern->GetLabelStyle();
244     tabBarPattern->SetLabelStyle(columnNode->GetId(), labelStyle);
245     auto iconStyle = tabContentPattern->GetIconStyle();
246     tabBarPattern->SetIconStyle(iconStyle, myIndex, newTabBar);
247     auto symbol = tabContentPattern->GetSymbol();
248     tabBarPattern->SetSymbol(symbol, myIndex, newTabBar);
249     auto tabBarStyle = tabContentPattern->GetTabBarStyle();
250     if (tabBarStyle == TabBarStyle::SUBTABBATSTYLE) {
251         auto renderContext = columnNode->GetRenderContext();
252         CHECK_NULL_VOID(renderContext);
253         BorderRadiusProperty borderRadiusProperty;
254         borderRadiusProperty.SetRadius(boardStyle.borderRadius);
255         renderContext->UpdateBorderRadius(borderRadiusProperty);
256     }
257     if (tabBarStyle != TabBarStyle::SUBTABBATSTYLE) {
258         indicatorStyle.marginTop = 0.0_vp;
259     }
260     tabBarPattern->SetSelectedMode(selectedMode, myIndex, newTabBar);
261     tabBarPattern->SetIndicatorStyle(indicatorStyle, myIndex, newTabBar);
262 
263     if (tabBarParam.GetTabBarStyle() == TabBarStyle::NOSTYLE && !tabBarParam.HasBuilder() &&
264         !tabBarParam.HasContent() && tabBarParam.GetIcon().empty() && tabBarParam.GetText().empty()) {
265         if (!columnNode->GetChildren().empty()) {
266             columnNode->Clean();
267         }
268     }
269 
270     auto columnFocusHub = columnNode->GetFocusHub();
271     if (columnFocusHub) {
272         columnFocusHub->SetFocusDependence(FocusDependence::SELF);
273     }
274 
275     // Create tab bar with content.
276     if (tabBarParam.HasContent()) {
277         ScopedViewStackProcessor builderViewStackProcessor;
278         auto builderNode = tabBarParam.GetContent().Upgrade();
279         CHECK_NULL_VOID(builderNode);
280         if (!columnNode->GetChildren().empty()) {
281             columnNode->Clean();
282         }
283         if (builderNode) {
284             builderNode->MountToParent(columnNode);
285         }
286         tabBarPattern->SetIsExecuteBuilder(false);
287         auto oldColumnNode = tabsNode->GetBuilderByContentId(tabContentId, columnNode);
288         if (oldColumnNode != columnNode) {
289             if (!oldColumnNode) {
290                 auto index =
291                     std::clamp(myIndex, 0, static_cast<int32_t>(tabBarNode->GetChildren().size()) - MASK_COUNT);
292                 columnNode->MountToParent(tabBarNode, index);
293             } else if (oldColumnNode != columnNode) {
294                 tabBarNode->ReplaceChild(oldColumnNode, columnNode);
295             }
296         }
297         auto tabBarItemPadding = Dimension(0);
298         auto layoutProperty = columnNode->GetLayoutProperty();
299         layoutProperty->UpdatePadding({ CalcLength(tabBarItemPadding), CalcLength(tabBarItemPadding),
300             CalcLength(tabBarItemPadding), CalcLength(tabBarItemPadding), {}, {} });
301         columnNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD);
302         tabBarPattern->AddTabBarItemType(columnNode->GetId(), TabBarParamType::COMPONENT_CONTENT);
303         tabBarNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_PARENT);
304         return;
305     }
306 
307     // Create tab bar with builder.
308     if (tabBarParam.HasBuilder()) {
309         ScopedViewStackProcessor builderViewStackProcessor;
310         tabBarParam.ExecuteBuilder();
311         auto builderNode = ViewStackProcessor::GetInstance()->Finish();
312         if (static_cast<int32_t>(columnNode->GetChildren().size()) != 0) {
313             columnNode->Clean();
314         }
315         if (builderNode) {
316             builderNode->MountToParent(columnNode);
317         }
318         auto oldColumnNode = tabsNode->GetBuilderByContentId(tabContentId, columnNode);
319         if (!oldColumnNode) {
320             auto index = std::clamp(myIndex, 0, static_cast<int32_t>(tabBarNode->GetChildren().size()) - MASK_COUNT);
321             columnNode->MountToParent(tabBarNode, index);
322         } else if (oldColumnNode != columnNode) {
323             tabBarNode->ReplaceChild(oldColumnNode, columnNode);
324         }
325         columnNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD);
326         tabBarPattern->AddTabBarItemType(columnNode->GetId(), TabBarParamType::CUSTOM_BUILDER);
327         tabBarPattern->SetIsExecuteBuilder(true);
328         tabBarNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_PARENT);
329         return;
330     }
331 
332     // Create text node and image node.
333     RefPtr<FrameNode> textNode;
334     RefPtr<FrameNode> iconNode;
335     auto layoutProperty = columnNode->GetLayoutProperty();
336     CHECK_NULL_VOID(layoutProperty);
337     if (tabBarStyle == TabBarStyle::SUBTABBATSTYLE || tabBarStyle == TabBarStyle::BOTTOMTABBATSTYLE) {
338         layoutProperty->UpdatePadding(padding);
339         auto accessibilityProperty = columnNode->GetAccessibilityProperty<AccessibilityProperty>();
340         accessibilityProperty->SetAccessibilityGroup(true);
341         auto id = tabContentPattern->GetId();
342         columnNode->UpdateInspectorId(id);
343     } else {
344         auto tabBarItemPadding = tabTheme->GetSubTabItemPadding();
345         auto subTabItemHorizontalPadding_ = tabTheme->GetSubTabItemHorizontalPadding();
346         layoutProperty->UpdatePadding({ CalcLength(subTabItemHorizontalPadding_),
347             CalcLength(subTabItemHorizontalPadding_), CalcLength(tabBarItemPadding),
348             CalcLength(tabBarItemPadding), {}, {} });
349     }
350 
351     bool isFrameNode = tabBarStyle == TabBarStyle::SUBTABBATSTYLE && tabContentPattern->HasSubTabBarStyleNode();
352     if (isFrameNode) {
353         tabBarPattern->AddTabBarItemType(columnNode->GetId(), TabBarParamType::SUB_COMPONENT_CONTENT);
354     } else {
355         tabBarPattern->AddTabBarItemType(columnNode->GetId(), TabBarParamType::NORMAL);
356     }
357     if (static_cast<int32_t>(columnNode->GetChildren().size()) == 0) {
358         if (tabBarParam.GetSymbol().has_value()) {
359             iconNode = FrameNode::GetOrCreateFrameNode(V2::SYMBOL_ETS_TAG,
360                 ElementRegister::GetInstance()->MakeUniqueId(), []() { return AceType::MakeRefPtr<TextPattern>(); });
361         } else {
362             iconNode = FrameNode::GetOrCreateFrameNode(V2::IMAGE_ETS_TAG,
363                 ElementRegister::GetInstance()->MakeUniqueId(), []() { return AceType::MakeRefPtr<ImagePattern>(); });
364         }
365         if (isFrameNode) {
366             textNode = tabContentPattern->FireCustomStyleNode();
367         } else {
368             textNode = FrameNode::GetOrCreateFrameNode(V2::TEXT_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
369                 []() { return AceType::MakeRefPtr<TextPattern>(); });
370         }
371         CHECK_NULL_VOID(textNode);
372         CHECK_NULL_VOID(iconNode);
373         auto index = std::clamp(position, 0, static_cast<int32_t>(tabBarNode->GetChildren().size()) - MASK_COUNT);
374         columnNode->MountToParent(tabBarNode, index);
375         iconNode->MountToParent(columnNode);
376         textNode->MountToParent(columnNode);
377     } else {
378         if (isFrameNode) {
379             auto builderNode = tabContentPattern->FireCustomStyleNode();
380             columnNode->ReplaceChild(AceType::DynamicCast<FrameNode>(columnNode->GetChildren().back()), builderNode);
381         }
382         auto oldIcon = AceType::DynamicCast<FrameNode>(columnNode->GetChildren().front());
383         CHECK_NULL_VOID(oldIcon);
384         if (tabBarParam.GetSymbol().has_value() && oldIcon->GetTag() != V2::SYMBOL_ETS_TAG) {
385             auto icon = FrameNode::GetOrCreateFrameNode(V2::SYMBOL_ETS_TAG,
386                 ElementRegister::GetInstance()->MakeUniqueId(), []() { return AceType::MakeRefPtr<TextPattern>(); });
387             columnNode->ReplaceChild(oldIcon, icon);
388         } else if (!tabBarParam.GetIcon().empty() && oldIcon->GetTag() != V2::IMAGE_ETS_TAG) {
389             auto icon = FrameNode::GetOrCreateFrameNode(V2::IMAGE_ETS_TAG,
390                 ElementRegister::GetInstance()->MakeUniqueId(), []() { return AceType::MakeRefPtr<ImagePattern>(); });
391             columnNode->ReplaceChild(oldIcon, icon);
392         }
393         iconNode = AceType::DynamicCast<FrameNode>(columnNode->GetChildren().front());
394         textNode = AceType::DynamicCast<FrameNode>(columnNode->GetChildren().back());
395     }
396     CHECK_NULL_VOID(textNode);
397     CHECK_NULL_VOID(iconNode);
398 
399     auto swiperPattern = swiperNode->GetPattern<SwiperPattern>();
400     CHECK_NULL_VOID(swiperPattern);
401     auto swiperLayoutProperty = swiperNode->GetLayoutProperty<SwiperLayoutProperty>();
402     CHECK_NULL_VOID(swiperLayoutProperty);
403     int32_t indicator = 0;
404     if (tabLayoutProperty->GetIndexSetByUser().has_value()) {
405         indicator = tabLayoutProperty->GetIndexSetByUser().value();
406     } else if (swiperLayoutProperty->GetIndex().has_value()) {
407         indicator = swiperLayoutProperty->GetIndex().value();
408     }
409     int32_t totalCount = swiperPattern->TotalCount();
410     if (indicator > totalCount - 1 || indicator < 0) {
411         indicator = 0;
412     }
413     tabBarPattern->UpdateSubTabBoard(indicator);
414     // Update property of text.
415     auto textLayoutProperty = textNode->GetLayoutProperty<TextLayoutProperty>();
416     CHECK_NULL_VOID(textLayoutProperty);
417     auto axis = tabBarLayoutProperty->GetAxis().value_or(Axis::HORIZONTAL);
418     if ((!swiperPattern->IsUseCustomAnimation() || !swiperPattern->GetCustomAnimationToIndex().has_value()) &&
419         !isFrameNode) {
420         if (myIndex == indicator) {
421             if (labelStyle.selectedColor.has_value()) {
422                 textLayoutProperty->UpdateTextColor(labelStyle.selectedColor.value());
423             } else {
424                 selectedMode == SelectedMode::BOARD && axis == Axis::HORIZONTAL ?
425                     textLayoutProperty->UpdateTextColor(tabTheme->GetSubTabBoardTextOnColor()) :
426                     textLayoutProperty->UpdateTextColor(tabTheme->GetSubTabTextOnColor());
427             }
428         } else {
429             if (labelStyle.unselectedColor.has_value()) {
430                 textLayoutProperty->UpdateTextColor(labelStyle.unselectedColor.value());
431             } else {
432                 textLayoutProperty->UpdateTextColor(tabTheme->GetSubTabTextOffColor());
433             }
434         }
435     }
436 
437     auto textRenderContext = textNode->GetRenderContext();
438     CHECK_NULL_VOID(textRenderContext);
439     textRenderContext->UpdateClipEdge(true);
440     if (!isFrameNode) {
441         textLayoutProperty->UpdateContent(tabBarParam.GetText());
442         textLayoutProperty->UpdateFontSize(tabTheme->GetSubTabTextDefaultFontSize());
443         textLayoutProperty->UpdateTextAlign(TextAlign::CENTER);
444         textLayoutProperty->UpdateMaxLines(1);
445         textLayoutProperty->UpdateTextOverflow(TextOverflow::ELLIPSIS);
446     }
447     if (tabBarStyle == TabBarStyle::BOTTOMTABBATSTYLE) {
448         textLayoutProperty->UpdateFlexShrink(1.0f);
449     }
450 
451     if (!tabBarParam.GetIcon().empty() || tabBarStyle == TabBarStyle::BOTTOMTABBATSTYLE) {
452         textLayoutProperty->UpdateFontSize(tabTheme->GetBottomTabTextSize());
453     }
454     if (tabBarStyle == TabBarStyle::BOTTOMTABBATSTYLE) {
455         textLayoutProperty->UpdateFontWeight(FontWeight::MEDIUM);
456     } else if (tabBarStyle == TabBarStyle::SUBTABBATSTYLE && !isFrameNode) {
457         textLayoutProperty->UpdateFontWeight(myIndex == indicator ? FontWeight::MEDIUM : FontWeight::NORMAL);
458     }
459     if (tabBarStyle == TabBarStyle::BOTTOMTABBATSTYLE && bottomTabBarStyle.layoutMode == LayoutMode::HORIZONTAL) {
460         textLayoutProperty->UpdateTextAlign(TextAlign::LEFT);
461         if (!labelStyle.fontSize.has_value() &&
462             Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
463             textLayoutProperty->UpdateFontSize(tabTheme->GetBottomTabHorizontalTextSize());
464         }
465     }
466     if (!isFrameNode) {
467         UpdateLabelStyle(labelStyle, textLayoutProperty);
468     }
469 
470     // Update property of image/symbol.
471     if (tabBarParam.GetSymbol().has_value()) {
472         auto symbolProperty = iconNode->GetLayoutProperty<TextLayoutProperty>();
473         CHECK_NULL_VOID(symbolProperty);
474         UpdateDefaultSymbol(tabTheme, symbolProperty);
475         auto modifierOnApply = tabBarParam.GetSymbol().value().onApply;
476         if (myIndex == indicator) {
477             tabBarPattern->SetImageColorOnIndex(indicator);
478             symbolProperty->UpdateSymbolColorList({tabTheme->GetBottomTabSymbolOn()});
479             if (modifierOnApply != nullptr) {
480                 modifierOnApply(AccessibilityManager::WeakClaim(AccessibilityManager::RawPtr(iconNode)), "normal");
481                 UpdateDefaultSymbol(tabTheme, symbolProperty);
482                 symbolProperty->UpdateSymbolColorList({tabTheme->GetBottomTabSymbolOn()});
483             }
484             if (modifierOnApply != nullptr && tabBarParam.GetSymbol().value().selectedFlag) {
485                 modifierOnApply(AccessibilityManager::WeakClaim(AccessibilityManager::RawPtr(iconNode)),
486                     "selected");
487                 UpdateSymbolEffect(symbolProperty, false);
488             }
489         } else {
490             symbolProperty->UpdateSymbolColorList({tabTheme->GetBottomTabSymbolOff()});
491             if (modifierOnApply != nullptr) {
492                 modifierOnApply(AccessibilityManager::WeakClaim(AccessibilityManager::RawPtr(iconNode)), "normal");
493                 UpdateSymbolEffect(symbolProperty, false);
494             }
495         }
496     } else {
497         auto imageProperty = iconNode->GetLayoutProperty<ImageLayoutProperty>();
498         CHECK_NULL_VOID(imageProperty);
499         if (!tabBarParam.GetIcon().empty() || tabBarStyle == TabBarStyle::BOTTOMTABBATSTYLE) {
500             imageProperty->UpdateUserDefinedIdealSize(CalcSize(
501                 NG::CalcLength(tabTheme->GetBottomTabImageSize()), NG::CalcLength(tabTheme->GetBottomTabImageSize())));
502         } else {
503             imageProperty->UpdateUserDefinedIdealSize(CalcSize());
504         }
505         ImageSourceInfo imageSourceInfo(tabBarParam.GetIcon());
506         auto imagePaintProperty = iconNode->GetPaintProperty<ImageRenderProperty>();
507         CHECK_NULL_VOID(imagePaintProperty);
508         if (imageSourceInfo.IsSvg() && myIndex == indicator) {
509             tabBarPattern->SetImageColorOnIndex(indicator);
510             if (iconStyle.selectedColor.has_value()) {
511                 imagePaintProperty->UpdateSvgFillColor(iconStyle.selectedColor.value());
512             } else {
513                 imagePaintProperty->UpdateSvgFillColor(tabTheme->GetBottomTabIconOn());
514             }
515         }
516         if (imageSourceInfo.IsSvg() && myIndex != indicator) {
517             if (iconStyle.unselectedColor.has_value()) {
518                 imagePaintProperty->UpdateSvgFillColor(iconStyle.unselectedColor.value());
519             } else {
520                 imagePaintProperty->UpdateSvgFillColor(tabTheme->GetBottomTabIconOff());
521             }
522         }
523         imageProperty->UpdateImageSourceInfo(imageSourceInfo);
524     }
525     columnNode->MarkModifyDone();
526     textNode->MarkModifyDone();
527     textNode->MarkDirtyNode();
528     iconNode->MarkModifyDone();
529     tabBarNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_PARENT);
530 }
531 
RemoveTabBarItem(const RefPtr<TabContentNode> & tabContentNode)532 void TabContentModelNG::RemoveTabBarItem(const RefPtr<TabContentNode>& tabContentNode)
533 {
534     CHECK_NULL_VOID(tabContentNode);
535     if (!tabContentNode->HasTabBarItemId()) {
536         return;
537     }
538 
539     auto tabBarItemId = tabContentNode->GetTabBarItemId();
540     auto tabBarItemNode = ElementRegister::GetInstance()->GetUINodeById(tabBarItemId);
541     CHECK_NULL_VOID(tabBarItemNode);
542     auto tabBarNode = tabBarItemNode->GetParent();
543     CHECK_NULL_VOID(tabBarNode);
544     auto tabBarFrameNode = AceType::DynamicCast<FrameNode>(tabBarNode);
545     CHECK_NULL_VOID(tabBarFrameNode);
546     auto tabBarPattern = tabBarFrameNode->GetPattern<TabBarPattern>();
547     CHECK_NULL_VOID(tabBarPattern);
548     tabBarPattern->RemoveTabBarItemInfo(tabBarItemId);
549     tabBarNode->RemoveChild(tabBarItemNode);
550     tabContentNode->ResetTabBarItemId();
551 
552     auto tabsNode = FindTabsNode(tabContentNode);
553     CHECK_NULL_VOID(tabsNode);
554     tabsNode->RemoveBuilderByContentId(tabContentNode->GetId());
555     tabBarFrameNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_PARENT);
556 }
557 
558 template<typename T>
ParseType(const RefPtr<ResourceObject> & resObj,const std::string & name,T & result)559 bool ParseType(const RefPtr<ResourceObject>& resObj, const std::string& name, T& result)
560 {
561     if constexpr (std::is_same_v<T, Color>) {
562         if (!ResourceParseUtils::ParseResColor(resObj, result)) {
563             auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
564             CHECK_NULL_RETURN(frameNode, false);
565             auto pipelineContext = frameNode->GetContext();
566             CHECK_NULL_RETURN(pipelineContext, false);
567             auto tabTheme = pipelineContext->GetTheme<TabTheme>();
568             CHECK_NULL_RETURN(tabTheme, false);
569             result = tabTheme->GetActiveIndicatorColor();
570             return false;
571         }
572         return true;
573     } else if constexpr (std::is_same_v<T, std::optional<Color>>) {
574         if (name == "selectedColor" || name == "unselectedColor") {
575             Color color;
576             if (ResourceParseUtils::ParseResColor(resObj, color)) {
577                 result = color;
578             }
579             return true;
580         }
581     } else if constexpr (std::is_same_v<T, std::optional<Dimension>>) {
582         if (name == "fontSize") {
583             CalcDimension fontSize;
584             if (ResourceParseUtils::ParseResDimensionFp(resObj, fontSize) && NonNegative(fontSize.Value()) &&
585                 fontSize.Unit() != DimensionUnit::PERCENT) {
586                 result = fontSize;
587             }
588             return true;
589         }
590     } else if constexpr (std::is_same_v<T, CalcDimension>) {
591         if (name == "height" || name == "borderRadius" || name == "width" || name == "marginTop") {
592             return ResourceParseUtils::ParseResDimensionVp(resObj, result);
593         } else if (name == "minFontSize" || name == "maxFontSize") {
594             return ResourceParseUtils::ParseResDimensionFp(resObj, result);
595         } else {
596             return ResourceParseUtils::ParseResDimensionNG(resObj, result, DimensionUnit::PX);
597         }
598     } else if constexpr (std::is_same_v<T, Dimension>) {
599         return ResourceParseUtils::ParseResDimensionFpNG(resObj, result);
600     } else if constexpr (std::is_same_v<T, std::vector<std::string>>) {
601         return ResourceParseUtils::ParseResFontFamilies(resObj, result);
602     } else if constexpr (std::is_same_v<T, std::string>) {
603         return ResourceParseUtils::ParseResString(resObj, result);
604     }
605     return false;
606 }
607 
608 #define REGISTER_RESOURCE_UPDATE_ATTR_FUNC(caseType, attrType, name, resObj, resultType)                          \
609     case caseType:                                                                                                \
610         do {                                                                                                      \
611             auto pattern = frameNode->GetPattern<TabContentPattern>();                                            \
612             CHECK_NULL_VOID(pattern);                                                                             \
613             const std::string key = "tabContent." #attrType #name;                                                \
614             pattern->RemoveResObj(key);                                                                           \
615             CHECK_NULL_VOID(resObj);                                                                              \
616             auto&& updateFunc = [weak = AceType::WeakClaim(frameNode)](const RefPtr<ResourceObject>& theResObj) { \
617                 auto frameNode = weak.Upgrade();                                                                  \
618                 CHECK_NULL_VOID(frameNode);                                                                       \
619                 auto pattern = frameNode->GetPattern<TabContentPattern>();                                        \
620                 CHECK_NULL_VOID(pattern);                                                                         \
621                 resultType result;                                                                                \
622                 ParseType(theResObj, #name, result);                                                              \
623                 auto attrs = pattern->Get##attrType();                                                            \
624                 attrs.name = result;                                                                              \
625                 pattern->Set##attrType(attrs);                                                                    \
626             };                                                                                                    \
627             pattern->AddResObj(key, resObj, std::move(updateFunc));                                               \
628         } while (false);                                                                                          \
629         break
630 
631 #define REGISTER_RESOURCE_UPDATE_ATTR_FONT_SIZE_FUNC(caseType, attrType, name, resObj, resultType)                \
632     case caseType:                                                                                                \
633         do {                                                                                                      \
634             auto pattern = frameNode->GetPattern<TabContentPattern>();                                            \
635             CHECK_NULL_VOID(pattern);                                                                             \
636             const std::string key = "tabContent." #attrType #name;                                                \
637             pattern->RemoveResObj(key);                                                                           \
638             CHECK_NULL_VOID(resObj);                                                                              \
639             auto&& updateFunc = [weak = AceType::WeakClaim(frameNode)](const RefPtr<ResourceObject>& theResObj) { \
640                 auto frameNode = weak.Upgrade();                                                                  \
641                 CHECK_NULL_VOID(frameNode);                                                                       \
642                 auto pattern = frameNode->GetPattern<TabContentPattern>();                                        \
643                 CHECK_NULL_VOID(pattern);                                                                         \
644                 resultType result;                                                                                \
645                 if (ParseType(theResObj, #name, result)) {                                                        \
646                     auto attrs = pattern->Get##attrType();                                                        \
647                     attrs.name = result;                                                                          \
648                     pattern->Set##attrType(attrs);                                                                \
649                 }                                                                                                 \
650             };                                                                                                    \
651             pattern->AddResObj(key, resObj, std::move(updateFunc));                                               \
652         } while (false);                                                                                          \
653         break
654 
CreateWithResourceObj(TabContentJsType jsType,const RefPtr<ResourceObject> & resObj)655 void TabContentModelNG::CreateWithResourceObj(TabContentJsType jsType, const RefPtr<ResourceObject>& resObj)
656 {
657     CHECK_NULL_VOID(SystemProperties::ConfigChangePerform());
658     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
659     CHECK_NULL_VOID(frameNode);
660     switch (jsType) {
661         REGISTER_RESOURCE_UPDATE_ATTR_FONT_SIZE_FUNC(
662             TabContentJsType::FONT_SIZE, LabelStyle, fontSize, resObj, std::optional<Dimension>);
663         REGISTER_RESOURCE_UPDATE_ATTR_FUNC(
664             TabContentJsType::FONT_FAMILY, LabelStyle, fontFamily, resObj, std::vector<std::string>);
665         REGISTER_RESOURCE_UPDATE_ATTR_FONT_SIZE_FUNC(
666             TabContentJsType::MIN_FONT_SIZE, LabelStyle, minFontSize, resObj, CalcDimension);
667         REGISTER_RESOURCE_UPDATE_ATTR_FONT_SIZE_FUNC(
668             TabContentJsType::MAX_FONT_SIZE, LabelStyle, maxFontSize, resObj, CalcDimension);
669         REGISTER_RESOURCE_UPDATE_ATTR_FUNC(
670             TabContentJsType::LABEL_SELECT_COLOR, LabelStyle, selectedColor, resObj, std::optional<Color>);
671         REGISTER_RESOURCE_UPDATE_ATTR_FUNC(
672             TabContentJsType::LABEL_UNSELECT_COLOR, LabelStyle, unselectedColor, resObj, std::optional<Color>);
673         REGISTER_RESOURCE_UPDATE_ATTR_FUNC(
674             TabContentJsType::ICON_SELECT_COLOR, IconStyle, selectedColor, resObj, std::optional<Color>);
675         REGISTER_RESOURCE_UPDATE_ATTR_FUNC(
676             TabContentJsType::ICON_UNSELECT_COLOR, IconStyle, unselectedColor, resObj, std::optional<Color>);
677         default:
678             CreateMoreWithResourceObj(jsType, frameNode, resObj);
679             break;
680     }
681 }
682 
CreateMoreWithResourceObj(TabContentJsType jsType,FrameNode * frameNode,const RefPtr<ResourceObject> & resObj)683 void TabContentModelNG::CreateMoreWithResourceObj(TabContentJsType jsType, FrameNode* frameNode,
684     const RefPtr<ResourceObject>& resObj)
685 {
686     CHECK_NULL_VOID(frameNode);
687     switch (jsType) {
688         case TabContentJsType::INDICATOR_COLOR:
689             CreateIndicatorColorWithResourceObj(frameNode, resObj);
690             break;
691         case TabContentJsType::INDICATOR_HEIGHT:
692             CreateIndicatorHeightWithResourceObj(frameNode, resObj);
693             break;
694         case TabContentJsType::INDICATOR_WIDTH:
695             CreateIndicatorWidthWithResourceObj(frameNode, resObj);
696             break;
697         case TabContentJsType::INDICATOR_RADIUS:
698             CreateIndicatorBorderRadiusWithResourceObj(frameNode, resObj);
699             break;
700         case TabContentJsType::INDICATOR_MARGIN_TOP:
701             CreateIndicatorMarginTopWithResourceObj(frameNode, resObj);
702             break;
703         case TabContentJsType::BORDER_RADIUS:
704             CreateBoardStyleBorderRadiusWithResourceObj(frameNode, resObj);
705             break;
706         case TabContentJsType::PADDING:
707             CreatePaddingWithResourceObj(frameNode, resObj);
708             break;
709         case TabContentJsType::TEXT_CONTENT:
710             CreateTextContentWithResourceObj(frameNode, resObj);
711             break;
712         case TabContentJsType::TAB_BAR_OPTIONS_ICON: {
713             CreateIconWithResourceObjWithKey(frameNode, "tabContent.tabBarOptions", resObj);
714             break;
715         }
716         case TabContentJsType::BOTTOM_TAB_BAR_STYLE_ICON: {
717             CreateIconWithResourceObjWithKey(frameNode, "tabContent.bottomTabBarStyle", resObj);
718             break;
719         }
720         default:
721             break;
722     }
723 }
724 
CreateIconWithResourceObjWithKey(FrameNode * frameNode,const std::string key,const RefPtr<ResourceObject> & resObj)725 bool TabContentModelNG::CreateIconWithResourceObjWithKey(FrameNode* frameNode, const std::string key,
726     const RefPtr<ResourceObject>& resObj)
727 {
728     CHECK_NULL_RETURN(frameNode, false);
729     auto pattern = frameNode->GetPattern<TabContentPattern>();
730     CHECK_NULL_RETURN(pattern, false);
731     pattern->RemoveResObj(key);
732     CHECK_NULL_RETURN(resObj, true);
733     auto&& updateFunc = [weak = AceType::WeakClaim(frameNode)](const RefPtr<ResourceObject>& resObj) {
734         auto frameNode = weak.Upgrade();
735         CHECK_NULL_VOID(frameNode);
736         auto pattern = frameNode->GetPattern<TabContentPattern>();
737         CHECK_NULL_VOID(pattern);
738         std::string result;
739         ResourceParseUtils::ParseResMedia(resObj, result);
740         ACE_UPDATE_NODE_LAYOUT_PROPERTY(TabContentLayoutProperty, Icon, result, frameNode);
741         pattern->UpdateTabBarParamIcon(result);
742     };
743     pattern->AddResObj(key, resObj, std::move(updateFunc));
744     return true;
745 }
746 
CreatePaddingHorWithResourceObj(const RefPtr<ResourceObject> & resObjLeft,const RefPtr<ResourceObject> & resObjRight,bool isSubTabStyle,bool useLocalizedPadding)747 void TabContentModelNG::CreatePaddingHorWithResourceObj(const RefPtr<ResourceObject>& resObjLeft,
748     const RefPtr<ResourceObject>& resObjRight, bool isSubTabStyle, bool useLocalizedPadding)
749 {
750     CHECK_NULL_VOID(SystemProperties::ConfigChangePerform());
751     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
752     CHECK_NULL_VOID(frameNode);
753     CreatePaddingLeftWithResourceObj(frameNode, resObjLeft, isSubTabStyle, useLocalizedPadding);
754     CreatePaddingRightWithResourceObj(frameNode, resObjRight, isSubTabStyle, useLocalizedPadding);
755 }
756 
CreatePaddingVerWithResourceObj(const RefPtr<ResourceObject> & resObjTop,const RefPtr<ResourceObject> & resObjBottom,bool isSubTabStyle,bool useLocalizedPadding)757 void TabContentModelNG::CreatePaddingVerWithResourceObj(const RefPtr<ResourceObject>& resObjTop,
758     const RefPtr<ResourceObject>& resObjBottom, bool isSubTabStyle, bool useLocalizedPadding)
759 {
760     CHECK_NULL_VOID(SystemProperties::ConfigChangePerform());
761     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
762     CHECK_NULL_VOID(frameNode);
763     CreatePaddingTopWithResourceObj(frameNode, resObjTop, isSubTabStyle, useLocalizedPadding);
764     CreatePaddingBottomWithResourceObj(frameNode, resObjBottom, isSubTabStyle, useLocalizedPadding);
765 }
766 
CreatePaddingWithResourceObj(FrameNode * frameNode,const RefPtr<ResourceObject> & resObj)767 bool TabContentModelNG::CreatePaddingWithResourceObj(FrameNode* frameNode, const RefPtr<ResourceObject>& resObj)
768 {
769     CHECK_NULL_RETURN(frameNode, false);
770     auto pattern = frameNode->GetPattern<TabContentPattern>();
771     CHECK_NULL_RETURN(pattern, false);
772     const std::string key = "tabContent.tabBarPadding";
773     pattern->RemoveResObj(key);
774     pattern->RemoveResObj(KEY_PADDING_LEFT);
775     pattern->RemoveResObj(KEY_PADDING_RIGHT);
776     pattern->RemoveResObj(KEY_PADDING_TOP);
777     pattern->RemoveResObj(KEY_PADDING_BOTTOM);
778     CHECK_NULL_RETURN(resObj, true);
779 
780     auto&& updateFunc = [weak = AceType::WeakClaim(frameNode)](const RefPtr<ResourceObject>& resObj) {
781         auto frameNode = weak.Upgrade();
782         CHECK_NULL_VOID(frameNode);
783         auto pattern = frameNode->GetPattern<TabContentPattern>();
784         CHECK_NULL_VOID(pattern);
785         CalcDimension result;
786         if (ResourceParseUtils::ParseResDimensionVp(resObj, result) && NonNegative(result.Value()) &&
787             result.Unit() != DimensionUnit::PERCENT) {
788             NG::PaddingProperty padding;
789             padding.left = NG::CalcLength(result);
790             padding.right = NG::CalcLength(result);
791             padding.top = NG::CalcLength(result);
792             padding.bottom = NG::CalcLength(result);
793             pattern->SetPadding(padding);
794         }
795     };
796     pattern->AddResObj(key, resObj, std::move(updateFunc));
797     return true;
798 }
799 
CreateTextContentWithResourceObj(FrameNode * frameNode,const RefPtr<ResourceObject> & resObj)800 bool TabContentModelNG::CreateTextContentWithResourceObj(FrameNode* frameNode, const RefPtr<ResourceObject>& resObj)
801 {
802     CHECK_NULL_RETURN(frameNode, false);
803     auto pattern = frameNode->GetPattern<TabContentPattern>();
804     CHECK_NULL_RETURN(pattern, false);
805     const std::string key = "tabContent.tabBarParamText";
806     pattern->RemoveResObj(key);
807     CHECK_NULL_RETURN(resObj, true);
808 
809     auto&& updateFunc = [weak = AceType::WeakClaim(frameNode)](const RefPtr<ResourceObject>& resObj) {
810         auto frameNode = weak.Upgrade();
811         CHECK_NULL_VOID(frameNode);
812         auto pattern = frameNode->GetPattern<TabContentPattern>();
813         CHECK_NULL_VOID(pattern);
814         std::string result;
815         ResourceParseUtils::ParseResString(resObj, result);
816         ACE_UPDATE_NODE_LAYOUT_PROPERTY(TabContentLayoutProperty, Text, result, frameNode);
817         pattern->UpdateTabBarParamText(result);
818     };
819     pattern->AddResObj(key, resObj, std::move(updateFunc));
820     return true;
821 }
822 
CreatePaddingLeftWithResourceObj(FrameNode * frameNode,const RefPtr<ResourceObject> & resObjLeft,bool isSubTabStyle,bool useLocalizedPadding)823 bool TabContentModelNG::CreatePaddingLeftWithResourceObj(FrameNode* frameNode,
824     const RefPtr<ResourceObject>& resObjLeft, bool isSubTabStyle, bool useLocalizedPadding)
825 {
826     CHECK_NULL_RETURN(frameNode, false);
827     auto pattern = frameNode->GetPattern<TabContentPattern>();
828     CHECK_NULL_RETURN(pattern, false);
829     pattern->RemoveResObj(KEY_PADDING);
830     pattern->RemoveResObj(KEY_PADDING_LEFT);
831     CHECK_NULL_RETURN(resObjLeft, true);
832 
833     auto&& updateFunc = [weakNode = AceType::WeakClaim(frameNode), isSubTabStyle](
834         const RefPtr<ResourceObject>& resObj) {
835         auto frameNode = weakNode.Upgrade();
836         CHECK_NULL_VOID(frameNode);
837         auto pattern = frameNode->GetPattern<TabContentPattern>();
838         CHECK_NULL_VOID(pattern);
839         CalcDimension left;
840         auto padding = pattern->GetPadding();
841         if (ResourceParseUtils::ParseResDimensionVp(resObj, left) && NonNegative(left.Value()) &&
842             left.Unit() != DimensionUnit::PERCENT) {
843             padding.left = NG::CalcLength(left);
844         } else {
845             auto pipelineContext = frameNode->GetContext();
846             CHECK_NULL_VOID(pipelineContext);
847             auto tabTheme = pipelineContext->GetTheme<TabTheme>();
848             CHECK_NULL_VOID(tabTheme);
849             padding.left = (isSubTabStyle) ? NG::CalcLength(tabTheme->GetSubTabHorizontalPadding()) :
850                 NG::CalcLength(tabTheme->GetBottomTabHorizontalPadding());
851         }
852         pattern->SetPadding(padding);
853     };
854     pattern->AddResObj(KEY_PADDING_LEFT, resObjLeft, std::move(updateFunc));
855     return true;
856 }
857 
CreatePaddingRightWithResourceObj(FrameNode * frameNode,const RefPtr<ResourceObject> & resObjRight,bool isSubTabStyle,bool useLocalizedPadding)858 bool TabContentModelNG::CreatePaddingRightWithResourceObj(FrameNode* frameNode,
859     const RefPtr<ResourceObject>& resObjRight, bool isSubTabStyle, bool useLocalizedPadding)
860 {
861     CHECK_NULL_RETURN(frameNode, false);
862     auto pattern = frameNode->GetPattern<TabContentPattern>();
863     CHECK_NULL_RETURN(pattern, false);
864     pattern->RemoveResObj(KEY_PADDING);
865     pattern->RemoveResObj(KEY_PADDING_RIGHT);
866     CHECK_NULL_RETURN(resObjRight, true);
867 
868     auto&& updateFunc = [weakNode = AceType::WeakClaim(frameNode), isSubTabStyle](
869         const RefPtr<ResourceObject>& resObj) {
870         auto frameNode = weakNode.Upgrade();
871         CHECK_NULL_VOID(frameNode);
872         auto pattern = frameNode->GetPattern<TabContentPattern>();
873         CHECK_NULL_VOID(pattern);
874         CalcDimension right;
875         auto padding = pattern->GetPadding();
876         if (ResourceParseUtils::ParseResDimensionVp(resObj, right) && NonNegative(right.Value()) &&
877             right.Unit() != DimensionUnit::PERCENT) {
878             padding.right = NG::CalcLength(right);
879         } else {
880             auto pipelineContext = frameNode->GetContext();
881             CHECK_NULL_VOID(pipelineContext);
882             auto tabTheme = pipelineContext->GetTheme<TabTheme>();
883             CHECK_NULL_VOID(tabTheme);
884             padding.right = (isSubTabStyle) ? NG::CalcLength(tabTheme->GetSubTabHorizontalPadding()) :
885                 NG::CalcLength(tabTheme->GetBottomTabHorizontalPadding());
886         }
887         pattern->SetPadding(padding);
888     };
889     pattern->AddResObj(KEY_PADDING_RIGHT, resObjRight, std::move(updateFunc));
890     return true;
891 }
892 
CreatePaddingTopWithResourceObj(FrameNode * frameNode,const RefPtr<ResourceObject> & resObjTop,bool isSubTabStyle,bool useLocalizedPadding)893 bool TabContentModelNG::CreatePaddingTopWithResourceObj(FrameNode* frameNode,
894     const RefPtr<ResourceObject>& resObjTop, bool isSubTabStyle, bool useLocalizedPadding)
895 {
896     CHECK_NULL_RETURN(frameNode, false);
897     auto pattern = frameNode->GetPattern<TabContentPattern>();
898     CHECK_NULL_RETURN(pattern, false);
899     pattern->RemoveResObj(KEY_PADDING);
900     pattern->RemoveResObj(KEY_PADDING_TOP);
901     CHECK_NULL_RETURN(resObjTop, true);
902 
903     auto&& updateFunc = [weakNode = AceType::WeakClaim(frameNode), isSubTabStyle](
904         const RefPtr<ResourceObject>& resObj) {
905         auto frameNode = weakNode.Upgrade();
906         CHECK_NULL_VOID(frameNode);
907         auto pattern = frameNode->GetPattern<TabContentPattern>();
908         CHECK_NULL_VOID(pattern);
909         CalcDimension top;
910         auto padding = pattern->GetPadding();
911         if (ResourceParseUtils::ParseResDimensionVp(resObj, top) && NonNegative(top.Value()) &&
912             top.Unit() != DimensionUnit::PERCENT) {
913             padding.top = NG::CalcLength(top);
914         } else {
915             auto pipelineContext = frameNode->GetContext();
916             CHECK_NULL_VOID(pipelineContext);
917             auto tabTheme = pipelineContext->GetTheme<TabTheme>();
918             CHECK_NULL_VOID(tabTheme);
919             padding.top = (isSubTabStyle) ? NG::CalcLength(tabTheme->GetSubTabTopPadding()) : NG::CalcLength(0.0_vp);
920         }
921         pattern->SetPadding(padding);
922     };
923     pattern->AddResObj(KEY_PADDING_TOP, resObjTop, std::move(updateFunc));
924     return true;
925 }
926 
CreatePaddingBottomWithResourceObj(FrameNode * frameNode,const RefPtr<ResourceObject> & resObjBottom,bool isSubTabStyle,bool useLocalizedPadding)927 bool TabContentModelNG::CreatePaddingBottomWithResourceObj(FrameNode* frameNode,
928     const RefPtr<ResourceObject>& resObjBottom, bool isSubTabStyle, bool useLocalizedPadding)
929 {
930     CHECK_NULL_RETURN(frameNode, false);
931     auto pattern = frameNode->GetPattern<TabContentPattern>();
932     CHECK_NULL_RETURN(pattern, false);
933     pattern->RemoveResObj(KEY_PADDING);
934     pattern->RemoveResObj(KEY_PADDING_BOTTOM);
935     CHECK_NULL_RETURN(resObjBottom, true);
936 
937     auto&& updateFunc = [weakNode = AceType::WeakClaim(frameNode), isSubTabStyle](
938         const RefPtr<ResourceObject>& resObj) {
939         auto frameNode = weakNode.Upgrade();
940         CHECK_NULL_VOID(frameNode);
941         auto pattern = frameNode->GetPattern<TabContentPattern>();
942         CHECK_NULL_VOID(pattern);
943         CalcDimension bottom;
944         auto padding = pattern->GetPadding();
945         if (ResourceParseUtils::ParseResDimensionVp(resObj, bottom) && NonNegative(bottom.Value()) &&
946             bottom.Unit() != DimensionUnit::PERCENT) {
947             padding.bottom = NG::CalcLength(bottom);
948         } else {
949             auto pipelineContext = frameNode->GetContext();
950             CHECK_NULL_VOID(pipelineContext);
951             auto tabTheme = pipelineContext->GetTheme<TabTheme>();
952             CHECK_NULL_VOID(tabTheme);
953             padding.bottom = (isSubTabStyle) ? NG::CalcLength(tabTheme->GetSubTabBottomPadding()) :
954                 NG::CalcLength(0.0_vp);
955         }
956         pattern->SetPadding(padding);
957     };
958     pattern->AddResObj(KEY_PADDING_BOTTOM, resObjBottom, std::move(updateFunc));
959     return true;
960 }
961 
CreateBoardStyleBorderRadiusWithResourceObj(FrameNode * frameNode,const RefPtr<ResourceObject> & resObj)962 bool TabContentModelNG::CreateBoardStyleBorderRadiusWithResourceObj(FrameNode* frameNode,
963     const RefPtr<ResourceObject>& resObj)
964 {
965     CHECK_NULL_RETURN(frameNode, false);
966     auto pattern = frameNode->GetPattern<TabContentPattern>();
967     CHECK_NULL_RETURN(pattern, false);
968     const std::string key = "tabContent.BoardStyle.borderRadius";
969     pattern->RemoveResObj(key);
970     CHECK_NULL_RETURN(resObj, true);
971 
972     auto&& updateFunc = [weak = AceType::WeakClaim(frameNode)](const RefPtr<ResourceObject>& resObj) {
973         auto frameNode = weak.Upgrade();
974         CHECK_NULL_VOID(frameNode);
975         auto pattern = frameNode->GetPattern<TabContentPattern>();
976         CHECK_NULL_VOID(pattern);
977         CalcDimension result;
978         auto attrs = pattern->GetBoardStyle();
979         if (!ParseType(resObj, "borderRadius", result) || result.Value() < 0.0f ||
980             result.Unit() == DimensionUnit::PERCENT) {
981             auto pipelineContext = frameNode->GetContext();
982             CHECK_NULL_VOID(pipelineContext);
983             auto tabTheme = pipelineContext->GetTheme<TabTheme>();
984             CHECK_NULL_VOID(tabTheme);
985             attrs.borderRadius = tabTheme->GetFocusIndicatorRadius();
986         } else {
987             attrs.borderRadius = result;
988         }
989         pattern->SetBoardStyle(attrs);
990     };
991     pattern->AddResObj(key, resObj, std::move(updateFunc));
992     return true;
993 }
994 
CreateIndicatorColorWithResourceObj(FrameNode * frameNode,const RefPtr<ResourceObject> & resObj)995 bool TabContentModelNG::CreateIndicatorColorWithResourceObj(FrameNode* frameNode, const RefPtr<ResourceObject>& resObj)
996 {
997     CHECK_NULL_RETURN(frameNode, false);
998     auto pattern = frameNode->GetPattern<TabContentPattern>();
999     CHECK_NULL_RETURN(pattern, false);
1000     const std::string key = "tabContent.IndicatorStyle.color";
1001     pattern->RemoveResObj(key);
1002     CHECK_NULL_RETURN(resObj, true);
1003 
1004     auto&& updateFunc = [weak = AceType::WeakClaim(frameNode)](const RefPtr<ResourceObject>& resObj) {
1005         auto frameNode = weak.Upgrade();
1006         CHECK_NULL_VOID(frameNode);
1007         auto pattern = frameNode->GetPattern<TabContentPattern>();
1008         CHECK_NULL_VOID(pattern);
1009         Color result;
1010         auto attrs = pattern->GetIndicatorStyle();
1011         if (!ParseType(resObj, "color", result)) {
1012             auto pipelineContext = frameNode->GetContext();
1013             CHECK_NULL_VOID(pipelineContext);
1014             auto tabTheme = pipelineContext->GetTheme<TabTheme>();
1015             CHECK_NULL_VOID(tabTheme);
1016             attrs.color = tabTheme->GetActiveIndicatorColor();
1017         } else {
1018             attrs.color = result;
1019         }
1020         pattern->SetIndicatorStyle(attrs);
1021     };
1022     pattern->AddResObj(key, resObj, std::move(updateFunc));
1023     return true;
1024 }
1025 
CreateIndicatorHeightWithResourceObj(FrameNode * frameNode,const RefPtr<ResourceObject> & resObj)1026 bool TabContentModelNG::CreateIndicatorHeightWithResourceObj(FrameNode* frameNode, const RefPtr<ResourceObject>& resObj)
1027 {
1028     CHECK_NULL_RETURN(frameNode, false);
1029     auto pattern = frameNode->GetPattern<TabContentPattern>();
1030     CHECK_NULL_RETURN(pattern, false);
1031     const std::string key = "tabContent.IndicatorStyle.height";
1032     pattern->RemoveResObj(key);
1033     CHECK_NULL_RETURN(resObj, true);
1034 
1035     auto&& updateFunc = [weak = AceType::WeakClaim(frameNode)](const RefPtr<ResourceObject>& resObj) {
1036         auto frameNode = weak.Upgrade();
1037         CHECK_NULL_VOID(frameNode);
1038         auto pattern = frameNode->GetPattern<TabContentPattern>();
1039         CHECK_NULL_VOID(pattern);
1040         CalcDimension result;
1041         auto attrs = pattern->GetIndicatorStyle();
1042         if (!ParseType(resObj, "height", result) || result.Value() < 0.0f ||
1043             result.Unit() == DimensionUnit::PERCENT) {
1044             auto pipelineContext = frameNode->GetContext();
1045             CHECK_NULL_VOID(pipelineContext);
1046             auto tabTheme = pipelineContext->GetTheme<TabTheme>();
1047             CHECK_NULL_VOID(tabTheme);
1048             attrs.height = tabTheme->GetActiveIndicatorWidth();
1049         } else {
1050             attrs.height = result;
1051         }
1052         pattern->SetIndicatorStyle(attrs);
1053     };
1054     pattern->AddResObj(key, resObj, std::move(updateFunc));
1055     return true;
1056 }
1057 
CreateIndicatorWidthWithResourceObj(FrameNode * frameNode,const RefPtr<ResourceObject> & resObj)1058 bool TabContentModelNG::CreateIndicatorWidthWithResourceObj(FrameNode* frameNode, const RefPtr<ResourceObject>& resObj)
1059 {
1060     CHECK_NULL_RETURN(frameNode, false);
1061     auto pattern = frameNode->GetPattern<TabContentPattern>();
1062     CHECK_NULL_RETURN(pattern, false);
1063     const std::string key = "tabContent.IndicatorStyle.width";
1064     pattern->RemoveResObj(key);
1065     CHECK_NULL_RETURN(resObj, true);
1066 
1067     auto&& updateFunc = [weak = AceType::WeakClaim(frameNode)](const RefPtr<ResourceObject>& resObj) {
1068         auto frameNode = weak.Upgrade();
1069         CHECK_NULL_VOID(frameNode);
1070         auto pattern = frameNode->GetPattern<TabContentPattern>();
1071         CHECK_NULL_VOID(pattern);
1072         CalcDimension result;
1073         auto attrs = pattern->GetIndicatorStyle();
1074         if (!ParseType(resObj, "width", result) || result.Value() < 0.0f || result.Unit() == DimensionUnit::PERCENT) {
1075             attrs.width = 0.0_vp;
1076         } else {
1077             attrs.width = result;
1078         }
1079         pattern->SetIndicatorStyle(attrs);
1080     };
1081     pattern->AddResObj(key, resObj, std::move(updateFunc));
1082     return true;
1083 }
1084 
CreateIndicatorBorderRadiusWithResourceObj(FrameNode * frameNode,const RefPtr<ResourceObject> & resObj)1085 bool TabContentModelNG::CreateIndicatorBorderRadiusWithResourceObj(FrameNode* frameNode,
1086     const RefPtr<ResourceObject>& resObj)
1087 {
1088     CHECK_NULL_RETURN(frameNode, false);
1089     auto pattern = frameNode->GetPattern<TabContentPattern>();
1090     CHECK_NULL_RETURN(pattern, false);
1091     const std::string key = "tabContent.IndicatorStyle.borderRadius";
1092     pattern->RemoveResObj(key);
1093     CHECK_NULL_RETURN(resObj, true);
1094 
1095     auto&& updateFunc = [weak = AceType::WeakClaim(frameNode)](const RefPtr<ResourceObject>& resObj) {
1096         auto frameNode = weak.Upgrade();
1097         CHECK_NULL_VOID(frameNode);
1098         auto pattern = frameNode->GetPattern<TabContentPattern>();
1099         CHECK_NULL_VOID(pattern);
1100         CalcDimension result;
1101         auto attrs = pattern->GetIndicatorStyle();
1102         if (!ParseType(resObj, "borderRadius", result) || result.Value() < 0.0f ||
1103             result.Unit() == DimensionUnit::PERCENT) {
1104             attrs.borderRadius = 0.0_vp;
1105         } else {
1106             attrs.borderRadius = result;
1107         }
1108         pattern->SetIndicatorStyle(attrs);
1109     };
1110     pattern->AddResObj(key, resObj, std::move(updateFunc));
1111     return true;
1112 }
1113 
CreateIndicatorMarginTopWithResourceObj(FrameNode * frameNode,const RefPtr<ResourceObject> & resObj)1114 bool TabContentModelNG::CreateIndicatorMarginTopWithResourceObj(FrameNode* frameNode,
1115     const RefPtr<ResourceObject>& resObj)
1116 {
1117     CHECK_NULL_RETURN(frameNode, false);
1118     auto pattern = frameNode->GetPattern<TabContentPattern>();
1119     CHECK_NULL_RETURN(pattern, false);
1120     const std::string key = "tabContent.IndicatorStyle.marginTop";
1121     pattern->RemoveResObj(key);
1122     CHECK_NULL_RETURN(resObj, true);
1123 
1124     auto&& updateFunc = [weak = AceType::WeakClaim(frameNode)](const RefPtr<ResourceObject>& resObj) {
1125         auto frameNode = weak.Upgrade();
1126         CHECK_NULL_VOID(frameNode);
1127         auto pattern = frameNode->GetPattern<TabContentPattern>();
1128         CHECK_NULL_VOID(pattern);
1129         CalcDimension result;
1130         auto attrs = pattern->GetIndicatorStyle();
1131         if (!ParseType(resObj, "marginTop", result) || result.Value() < 0.0f ||
1132             result.Unit() == DimensionUnit::PERCENT) {
1133             auto pipelineContext = frameNode->GetContext();
1134             CHECK_NULL_VOID(pipelineContext);
1135             auto tabTheme = pipelineContext->GetTheme<TabTheme>();
1136             CHECK_NULL_VOID(tabTheme);
1137             attrs.marginTop = tabTheme->GetSubTabIndicatorGap();
1138         } else {
1139             attrs.marginTop = result;
1140         }
1141         pattern->SetIndicatorStyle(attrs);
1142     };
1143     pattern->AddResObj(key, resObj, std::move(updateFunc));
1144     return true;
1145 }
1146 
SetTabBar(const std::optional<std::string> & text,const std::optional<std::string> & icon,const std::optional<TabBarSymbol> & tabBarSymbol,TabBarBuilderFunc && builder,bool)1147 void TabContentModelNG::SetTabBar(const std::optional<std::string>& text, const std::optional<std::string>& icon,
1148     const std::optional<TabBarSymbol>& tabBarSymbol, TabBarBuilderFunc&& builder, bool /*useContentOnly*/)
1149 {
1150     ACE_UPDATE_LAYOUT_PROPERTY(TabContentLayoutProperty, Icon, icon.value_or(""));
1151     ACE_UPDATE_LAYOUT_PROPERTY(TabContentLayoutProperty, Text, text.value_or(""));
1152     auto frameNodePattern = ViewStackProcessor::GetInstance()->GetMainFrameNodePattern<TabContentPattern>();
1153     CHECK_NULL_VOID(frameNodePattern);
1154     frameNodePattern->SetTabBar(text.value_or(""), icon.value_or(""), tabBarSymbol, std::move(builder));
1155     frameNodePattern->SetTabBarWithContent(nullptr);
1156 }
1157 
SetTabBarWithContent(const RefPtr<NG::UINode> & content)1158 void TabContentModelNG::SetTabBarWithContent(const RefPtr<NG::UINode>& content)
1159 {
1160     auto frameNodePattern = ViewStackProcessor::GetInstance()->GetMainFrameNodePattern<TabContentPattern>();
1161     CHECK_NULL_VOID(frameNodePattern);
1162     frameNodePattern->SetTabBarWithContent(content);
1163 }
1164 
SetTabBarStyle(TabBarStyle tabBarStyle)1165 void TabContentModelNG::SetTabBarStyle(TabBarStyle tabBarStyle)
1166 {
1167     auto frameNodePattern = ViewStackProcessor::GetInstance()->GetMainFrameNodePattern<TabContentPattern>();
1168     CHECK_NULL_VOID(frameNodePattern);
1169     frameNodePattern->SetTabBarStyle(tabBarStyle);
1170 }
1171 
SetIndicator(const IndicatorStyle & indicator)1172 void TabContentModelNG::SetIndicator(const IndicatorStyle& indicator)
1173 {
1174     auto frameNodePattern = ViewStackProcessor::GetInstance()->GetMainFrameNodePattern<TabContentPattern>();
1175     CHECK_NULL_VOID(frameNodePattern);
1176     frameNodePattern->SetIndicatorStyle(indicator);
1177 }
1178 
SetIndicatorColorByUser(bool isByUser)1179 void TabContentModelNG::SetIndicatorColorByUser(bool isByUser)
1180 {
1181     ACE_UPDATE_LAYOUT_PROPERTY(TabContentLayoutProperty, IndicatorColorSetByUser, isByUser);
1182 }
1183 
SetCustomTabBar(FrameNode * node,FrameNode * tabBar)1184 void TabContentModelNG::SetCustomTabBar(FrameNode* node, FrameNode* tabBar)
1185 {
1186     CHECK_NULL_VOID(node);
1187     CHECK_NULL_VOID(tabBar);
1188     auto frameNodePattern = node->GetPattern<TabContentPattern>();
1189     CHECK_NULL_VOID(frameNodePattern);
1190     frameNodePattern->SetTabBarStyle(TabBarStyle::NOSTYLE);
1191     frameNodePattern->SetCustomTabBar(tabBar);
1192 }
1193 
SetBoard(const BoardStyle & board)1194 void TabContentModelNG::SetBoard(const BoardStyle& board)
1195 {
1196     auto frameNodePattern = ViewStackProcessor::GetInstance()->GetMainFrameNodePattern<TabContentPattern>();
1197     CHECK_NULL_VOID(frameNodePattern);
1198     frameNodePattern->SetBoardStyle(board);
1199 }
1200 
SetSelectedMode(SelectedMode selectedMode)1201 void TabContentModelNG::SetSelectedMode(SelectedMode selectedMode)
1202 {
1203     auto frameNodePattern = ViewStackProcessor::GetInstance()->GetMainFrameNodePattern<TabContentPattern>();
1204     CHECK_NULL_VOID(frameNodePattern);
1205     frameNodePattern->SetSelectedMode(selectedMode);
1206 }
1207 
SetLabelStyle(const LabelStyle & labelStyle)1208 void TabContentModelNG::SetLabelStyle(const LabelStyle& labelStyle)
1209 {
1210     auto frameNodePattern = ViewStackProcessor::GetInstance()->GetMainFrameNodePattern<TabContentPattern>();
1211     CHECK_NULL_VOID(frameNodePattern);
1212     frameNodePattern->SetLabelStyle(labelStyle);
1213 }
1214 
SetLabelUnselectedColorByUser(bool isByUser)1215 void TabContentModelNG::SetLabelUnselectedColorByUser(bool isByUser)
1216 {
1217     ACE_UPDATE_LAYOUT_PROPERTY(TabContentLayoutProperty, LabelUnselectedColorSetByUser, isByUser);
1218 }
1219 
SetLabelSelectedColorByUser(bool isByUser)1220 void TabContentModelNG::SetLabelSelectedColorByUser(bool isByUser)
1221 {
1222     ACE_UPDATE_LAYOUT_PROPERTY(TabContentLayoutProperty, LabelSelectedColorSetByUser, isByUser);
1223 }
1224 
SetIconStyle(const IconStyle & iconStyle)1225 void TabContentModelNG::SetIconStyle(const IconStyle& iconStyle)
1226 {
1227     auto frameNodePattern = ViewStackProcessor::GetInstance()->GetMainFrameNodePattern<TabContentPattern>();
1228     CHECK_NULL_VOID(frameNodePattern);
1229     frameNodePattern->SetIconStyle(iconStyle);
1230 }
1231 
SetIconUnselectedColorByUser(bool isByUser)1232 void TabContentModelNG::SetIconUnselectedColorByUser(bool isByUser)
1233 {
1234     ACE_UPDATE_LAYOUT_PROPERTY(TabContentLayoutProperty, IconUnselectedColorSetByUser, isByUser);
1235 }
1236 
SetIconSelectedColorByUser(bool isByUser)1237 void TabContentModelNG::SetIconSelectedColorByUser(bool isByUser)
1238 {
1239     ACE_UPDATE_LAYOUT_PROPERTY(TabContentLayoutProperty, IconSelectedColorSetByUser, isByUser);
1240 }
1241 
SetPadding(const PaddingProperty & padding)1242 void TabContentModelNG::SetPadding(const PaddingProperty& padding)
1243 {
1244     auto frameNodePattern = ViewStackProcessor::GetInstance()->GetMainFrameNodePattern<TabContentPattern>();
1245     CHECK_NULL_VOID(frameNodePattern);
1246     frameNodePattern->SetPadding(padding);
1247 }
1248 
SetUseLocalizedPadding(bool useLocalizedPadding)1249 void TabContentModelNG::SetUseLocalizedPadding(bool useLocalizedPadding)
1250 {
1251     auto frameNodePattern = ViewStackProcessor::GetInstance()->GetMainFrameNodePattern<TabContentPattern>();
1252     CHECK_NULL_VOID(frameNodePattern);
1253     frameNodePattern->SetUseLocalizedPadding(useLocalizedPadding);
1254 }
1255 
SetLayoutMode(LayoutMode layoutMode)1256 void TabContentModelNG::SetLayoutMode(LayoutMode layoutMode)
1257 {
1258     auto frameNodePattern = ViewStackProcessor::GetInstance()->GetMainFrameNodePattern<TabContentPattern>();
1259     CHECK_NULL_VOID(frameNodePattern);
1260     frameNodePattern->SetLayoutMode(layoutMode);
1261 }
1262 
SetVerticalAlign(FlexAlign verticalAlign)1263 void TabContentModelNG::SetVerticalAlign(FlexAlign verticalAlign)
1264 {
1265     auto frameNodePattern = ViewStackProcessor::GetInstance()->GetMainFrameNodePattern<TabContentPattern>();
1266     CHECK_NULL_VOID(frameNodePattern);
1267     frameNodePattern->SetVerticalAlign(verticalAlign);
1268 }
1269 
SetSymmetricExtensible(bool isExtensible)1270 void TabContentModelNG::SetSymmetricExtensible(bool isExtensible)
1271 {
1272     auto frameNodePattern = ViewStackProcessor::GetInstance()->GetMainFrameNodePattern<TabContentPattern>();
1273     CHECK_NULL_VOID(frameNodePattern);
1274     frameNodePattern->SetSymmetricExtensible(isExtensible);
1275 }
1276 
SetId(const std::string & id)1277 void TabContentModelNG::SetId(const std::string& id)
1278 {
1279     auto frameNodePattern = ViewStackProcessor::GetInstance()->GetMainFrameNodePattern<TabContentPattern>();
1280     CHECK_NULL_VOID(frameNodePattern);
1281     frameNodePattern->SetId(id);
1282 }
1283 
UpdateLabelStyle(const LabelStyle & labelStyle,RefPtr<TextLayoutProperty> textLayoutProperty)1284 void TabContentModelNG::UpdateLabelStyle(const LabelStyle& labelStyle, RefPtr<TextLayoutProperty> textLayoutProperty)
1285 {
1286     CHECK_NULL_VOID(textLayoutProperty);
1287 
1288     if (labelStyle.fontSize.has_value()) {
1289         textLayoutProperty->UpdateFontSize(labelStyle.fontSize.value());
1290     }
1291     if (labelStyle.fontWeight.has_value()) {
1292         textLayoutProperty->UpdateFontWeight(labelStyle.fontWeight.value());
1293     }
1294     if (labelStyle.fontStyle.has_value()) {
1295         textLayoutProperty->UpdateItalicFontStyle(labelStyle.fontStyle.value());
1296     }
1297     if (labelStyle.fontFamily.has_value()) {
1298         textLayoutProperty->UpdateFontFamily(labelStyle.fontFamily.value());
1299     }
1300     if (labelStyle.textOverflow.has_value()) {
1301         textLayoutProperty->UpdateTextOverflow(labelStyle.textOverflow.value());
1302         if (labelStyle.textOverflow.value() == TextOverflow::MARQUEE) {
1303             textLayoutProperty->UpdateTextMarqueeStartPolicy(MarqueeStartPolicy::DEFAULT);
1304         }
1305     }
1306     if (labelStyle.maxLines.has_value()) {
1307         textLayoutProperty->UpdateMaxLines(labelStyle.maxLines.value());
1308     }
1309     if (labelStyle.minFontSize.has_value()) {
1310         textLayoutProperty->UpdateAdaptMinFontSize(labelStyle.minFontSize.value());
1311     }
1312     if (labelStyle.maxFontSize.has_value()) {
1313         textLayoutProperty->UpdateAdaptMaxFontSize(labelStyle.maxFontSize.value());
1314     }
1315     if (labelStyle.heightAdaptivePolicy.has_value()) {
1316         textLayoutProperty->UpdateHeightAdaptivePolicy(labelStyle.heightAdaptivePolicy.value());
1317     }
1318 }
1319 
UpdateDefaultSymbol(RefPtr<TabTheme> & tabTheme,RefPtr<TextLayoutProperty> symbolProperty)1320 void TabContentModelNG::UpdateDefaultSymbol(RefPtr<TabTheme>& tabTheme, RefPtr<TextLayoutProperty> symbolProperty)
1321 {
1322     symbolProperty->UpdateFontSize(tabTheme->GetBottomTabImageSize());
1323     symbolProperty->UpdateSymbolRenderingStrategy(DEFAULT_RENDERING_STRATEGY);
1324     UpdateSymbolEffect(symbolProperty, false);
1325 }
UpdateSymbolEffect(RefPtr<TextLayoutProperty> symbolProperty,bool isActive)1326 void TabContentModelNG::UpdateSymbolEffect(RefPtr<TextLayoutProperty> symbolProperty, bool isActive)
1327 {
1328     auto symbolEffectOptions = SymbolEffectOptions(SymbolEffectType::BOUNCE);
1329     symbolEffectOptions.SetIsTxtActive(isActive);
1330     symbolEffectOptions.SetIsTxtActiveSource(0);
1331     symbolProperty->UpdateSymbolEffectOptions(symbolEffectOptions);
1332 }
1333 
SetOnWillShow(std::function<void ()> && onWillShow)1334 void TabContentModelNG::SetOnWillShow(std::function<void()>&& onWillShow)
1335 {
1336     auto tabContentNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
1337     CHECK_NULL_VOID(tabContentNode);
1338     auto tabContentEventHub = tabContentNode->GetOrCreateEventHub<TabContentEventHub>();
1339     CHECK_NULL_VOID(tabContentEventHub);
1340     tabContentEventHub->SetOnWillShow(onWillShow);
1341 }
1342 
SetOnWillHide(std::function<void ()> && onWillHide)1343 void TabContentModelNG::SetOnWillHide(std::function<void()>&& onWillHide)
1344 {
1345     auto tabContentNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
1346     CHECK_NULL_VOID(tabContentNode);
1347     auto tabContentEventHub = tabContentNode->GetOrCreateEventHub<TabContentEventHub>();
1348     CHECK_NULL_VOID(tabContentEventHub);
1349     tabContentEventHub->SetOnWillHide(onWillHide);
1350 }
1351 
SetCustomStyleNode(const RefPtr<FrameNode> & customStyleNode)1352 void TabContentModelNG::SetCustomStyleNode(const RefPtr<FrameNode>& customStyleNode)
1353 {
1354     auto pattern = ViewStackProcessor::GetInstance()->GetMainFrameNodePattern<TabContentPattern>();
1355     CHECK_NULL_VOID(pattern);
1356     pattern->SetCustomStyleNode(customStyleNode);
1357 }
1358 
SetTabBarBuilder(FrameNode * node,TabBarBuilderFunc && builder)1359 void TabContentModelNG::SetTabBarBuilder(FrameNode* node, TabBarBuilderFunc&& builder)
1360 {
1361     CHECK_NULL_VOID(node);
1362     auto frameNodePattern = node->GetPattern<TabContentPattern>();
1363     CHECK_NULL_VOID(frameNodePattern);
1364     frameNodePattern->SetTabBar("", "", std::nullopt, std::move(builder));
1365     frameNodePattern->SetTabBarWithContent(nullptr);
1366 }
1367 
SetTabBarLabel(FrameNode * node,const std::string & label)1368 void TabContentModelNG::SetTabBarLabel(FrameNode* node, const std::string& label)
1369 {
1370     CHECK_NULL_VOID(node);
1371     auto frameNodePattern = node->GetPattern<TabContentPattern>();
1372     CHECK_NULL_VOID(frameNodePattern);
1373     frameNodePattern->SetTabBar(label, "", std::nullopt, nullptr);
1374     frameNodePattern->SetTabBarWithContent(nullptr);
1375 }
1376 
SetOnWillShow(FrameNode * tabContentNode,std::function<void ()> && onWillShow)1377 void TabContentModelNG::SetOnWillShow(FrameNode* tabContentNode, std::function<void()>&& onWillShow)
1378 {
1379     CHECK_NULL_VOID(tabContentNode);
1380     auto tabContentEventHub = tabContentNode->GetOrCreateEventHub<TabContentEventHub>();
1381     CHECK_NULL_VOID(tabContentEventHub);
1382     tabContentEventHub->SetOnWillShow(onWillShow);
1383 }
SetOnWillHide(FrameNode * tabContentNode,std::function<void ()> && onWillHide)1384 void TabContentModelNG::SetOnWillHide(FrameNode* tabContentNode, std::function<void()>&& onWillHide)
1385 {
1386     CHECK_NULL_VOID(tabContentNode);
1387     auto tabContentEventHub = tabContentNode->GetOrCreateEventHub<TabContentEventHub>();
1388     CHECK_NULL_VOID(tabContentEventHub);
1389     tabContentEventHub->SetOnWillHide(onWillHide);
1390 }
1391 } // namespace OHOS::Ace::NG
1392