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