• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2025 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/tabs_model_ng.h"
17 
18 #include <type_traits>
19 
20 #include "base/log/ace_trace.h"
21 #include "base/memory/ace_type.h"
22 #include "base/memory/referenced.h"
23 #include "base/utils/utils.h"
24 #include "core/animation/animation_pub.h"
25 #include "core/components/common/layout/constants.h"
26 #include "core/components/common/properties/decoration.h"
27 #include "core/components/swiper/swiper_controller.h"
28 #include "core/components_ng/base/group_node.h"
29 #include "core/components_ng/base/view_stack_processor.h"
30 #include "core/components_ng/pattern/divider/divider_layout_property.h"
31 #include "core/components_ng/pattern/divider/divider_pattern.h"
32 #include "core/components_ng/pattern/divider/divider_render_property.h"
33 #include "core/components_ng/pattern/image/image_pattern.h"
34 #include "core/components_ng/pattern/linear_layout/linear_layout_pattern.h"
35 #include "core/components_ng/pattern/stack/stack_pattern.h"
36 #include "core/components_ng/pattern/swiper/swiper_layout_property.h"
37 #include "core/components_ng/pattern/swiper/swiper_paint_property.h"
38 #include "core/components_ng/pattern/swiper/swiper_pattern.h"
39 #include "core/components_ng/pattern/tabs/tab_bar_paint_property.h"
40 #include "core/components_ng/pattern/tabs/tab_bar_pattern.h"
41 #include "core/components_ng/pattern/tabs/tabs_controller.h"
42 #include "core/components_ng/pattern/tabs/tabs_node.h"
43 #include "core/components_ng/pattern/tabs/tabs_pattern.h"
44 #include "core/components_ng/pattern/text/text_pattern.h"
45 #include "core/components_ng/property/measure_utils.h"
46 #include "core/common/resource/resource_parse_utils.h"
47 
48 namespace OHOS::Ace::NG {
49 namespace {
50 constexpr uint16_t PIXEL_ROUND = static_cast<uint16_t>(PixelRoundPolicy::NO_FORCE_ROUND_START) |
51                                 static_cast<uint16_t>(PixelRoundPolicy::NO_FORCE_ROUND_TOP) |
52                                 static_cast<uint16_t>(PixelRoundPolicy::NO_FORCE_ROUND_END) |
53                                 static_cast<uint16_t>(PixelRoundPolicy::NO_FORCE_ROUND_BOTTOM);
54 
55 constexpr int32_t SWIPER_Z_INDEX = 0;
56 constexpr int32_t DIVIDER_Z_INDEX = 2;
57 constexpr int32_t TAB_BAR_Z_INDEX = 3;
58 constexpr int32_t EFFECT_Z_INDEX = 1;
59 } // namespace
60 
Create(BarPosition barPosition,int32_t index,const RefPtr<TabController> &,const RefPtr<SwiperController> & swiperController)61 void TabsModelNG::Create(BarPosition barPosition, int32_t index, const RefPtr<TabController>& /*tabController*/,
62     const RefPtr<SwiperController>& swiperController)
63 {
64     auto* stack = ViewStackProcessor::GetInstance();
65     auto nodeId = stack->ClaimNodeId();
66     ACE_LAYOUT_SCOPED_TRACE("Create[%s][self:%d][index:%d]", V2::TABS_ETS_TAG, nodeId, index);
67     auto tabsNode = GetOrCreateTabsNode(V2::TABS_ETS_TAG, nodeId, []() { return AceType::MakeRefPtr<TabsPattern>(); });
68     InitTabsNode(tabsNode, swiperController);
69     ViewStackProcessor::GetInstance()->Push(tabsNode);
70 
71     SetTabBarPosition(barPosition);
72     auto tabsLayoutProperty = tabsNode->GetLayoutProperty<TabsLayoutProperty>();
73     CHECK_NULL_VOID(tabsLayoutProperty);
74     if (tabsLayoutProperty->GetIndex().has_value()) {
75         auto preIndex = tabsLayoutProperty->GetIndex().value();
76         if (preIndex == index || index < 0) {
77             return;
78         }
79     }
80     tabsLayoutProperty->UpdateIndexSetByUser(index);
81     if (SystemProperties::ConfigChangePerform()) {
82         tabsLayoutProperty->ResetDividerColorSetByUser();
83         tabsLayoutProperty->ResetBarBackgroundColorSetByUser();
84     }
85 }
86 
GetSwiperController(const RefPtr<FrameNode> & swiperNode,const RefPtr<SwiperController> & swiperController)87 RefPtr<SwiperController> TabsModelNG::GetSwiperController(const RefPtr<FrameNode>& swiperNode,
88     const RefPtr<SwiperController>& swiperController)
89 {
90     auto swiperPaintProperty = swiperNode->GetPaintProperty<SwiperPaintProperty>();
91     swiperPaintProperty->UpdateEdgeEffect(EdgeEffect::SPRING);
92     auto pipelineContext = PipelineContext::GetCurrentContextSafelyWithCheck();
93     CHECK_NULL_RETURN(pipelineContext, nullptr);
94     auto tabTheme = pipelineContext->GetTheme<TabTheme>();
95     CHECK_NULL_RETURN(tabTheme, nullptr);
96     swiperPaintProperty->UpdateDuration(tabTheme->GetTabContentAnimationDuration());
97     swiperPaintProperty->UpdateCurve(TabBarPhysicalCurve);
98     auto swiperLayoutProperty = swiperNode->GetLayoutProperty<SwiperLayoutProperty>();
99     swiperLayoutProperty->UpdateLoop(false);
100     swiperLayoutProperty->UpdateCachedCount(0);
101     swiperLayoutProperty->UpdateShowIndicator(false);
102     swiperLayoutProperty->UpdateSafeAreaExpandOpts(
103         { .type = SAFE_AREA_TYPE_SYSTEM, .edges = SAFE_AREA_EDGE_TOP + SAFE_AREA_EDGE_BOTTOM });
104     auto swiperPattern = swiperNode->GetPattern<SwiperPattern>();
105     CHECK_NULL_RETURN(swiperPattern, nullptr);
106     RefPtr<SwiperController> controller;
107     if (swiperController) {
108         controller = swiperController;
109     } else {
110         controller = AceType::MakeRefPtr<TabsControllerNG>();
111     }
112     swiperPattern->SetSwiperController(controller);
113     swiperPattern->SetFinishCallbackType(FinishCallbackType::LOGICALLY);
114     swiperPattern->SetHasTabsAncestor(true);
115     return controller;
116 }
117 
InitSelectedMaskNode(const RefPtr<FrameNode> & selectedMaskNode)118 void TabsModelNG::InitSelectedMaskNode(const RefPtr<FrameNode>& selectedMaskNode)
119 {
120     auto selectedImageNode = FrameNode::GetOrCreateFrameNode(V2::IMAGE_ETS_TAG,
121         ElementRegister::GetInstance()->MakeUniqueId(), []() { return AceType::MakeRefPtr<ImagePattern>(); });
122     selectedImageNode->MountToParent(selectedMaskNode);
123     auto selectedMaskRenderContext = selectedMaskNode->GetRenderContext();
124     auto selectedMaskProperty = selectedMaskNode->GetLayoutProperty<LinearLayoutProperty>();
125     selectedMaskProperty->UpdateCrossAxisAlign(FlexAlign::FLEX_START);
126     selectedMaskRenderContext->SetClipToBounds(true);
127 }
128 
InitUnselectedMaskNode(const RefPtr<FrameNode> & unselectedMaskNode)129 void TabsModelNG::InitUnselectedMaskNode(const RefPtr<FrameNode>& unselectedMaskNode)
130 {
131     auto unselectedImageNode = FrameNode::GetOrCreateFrameNode(V2::IMAGE_ETS_TAG,
132         ElementRegister::GetInstance()->MakeUniqueId(), []() { return AceType::MakeRefPtr<ImagePattern>(); });
133     unselectedImageNode->MountToParent(unselectedMaskNode);
134     auto unselectedMaskRenderContext = unselectedMaskNode->GetRenderContext();
135     auto unselectedMaskProperty = unselectedMaskNode->GetLayoutProperty<LinearLayoutProperty>();
136     unselectedMaskProperty->UpdateCrossAxisAlign(FlexAlign::FLEX_START);
137     unselectedMaskRenderContext->SetClipToBounds(true);
138 }
139 
InitEffectNode(RefPtr<TabsNode> tabsNode)140 RefPtr<OHOS::Ace::NG::FrameNode> InitEffectNode(RefPtr<TabsNode> tabsNode)
141 {
142     auto effectNode = FrameNode::GetOrCreateFrameNode(
143         V2::STACK_ETS_TAG, tabsNode->GetEffectId(), []() { return AceType::MakeRefPtr<StackPattern>(); });
144 
145     auto accessibilityProperty = effectNode->GetAccessibilityProperty<NG::AccessibilityProperty>();
146     CHECK_NULL_RETURN(accessibilityProperty, effectNode);
147     accessibilityProperty->SetAccessibilityLevel(AccessibilityProperty::Level::NO_STR);
148 
149     auto effectNodeLayoutProperty = effectNode->GetLayoutProperty();
150     CHECK_NULL_RETURN(effectNodeLayoutProperty, effectNode);
151     if (!effectNodeLayoutProperty->GetSafeAreaExpandOpts()) {
152         effectNodeLayoutProperty->UpdateSafeAreaExpandOpts(
153             { .type = SAFE_AREA_TYPE_SYSTEM, .edges = SAFE_AREA_EDGE_BOTTOM });
154     }
155     auto effectNodeContext = effectNode->GetRenderContext();
156     CHECK_NULL_RETURN(effectNodeContext, effectNode);
157     effectNodeContext->UpdateClipEdge(false);
158     return effectNode;
159 }
160 
InitTabsNode(RefPtr<TabsNode> tabsNode,const RefPtr<SwiperController> & swiperController)161 void TabsModelNG::InitTabsNode(RefPtr<TabsNode> tabsNode, const RefPtr<SwiperController>& swiperController)
162 {
163     bool hasSwiperNode = tabsNode->HasSwiperNode();
164     bool hasTabBarNode = tabsNode->HasTabBarNode();
165     bool hasDividerNode = tabsNode->HasDividerNode();
166     bool hasSelectedMaskNode = tabsNode->HasSelectedMaskNode();
167     bool hasUnselectedMaskNode = tabsNode->HasUnselectedMaskNode();
168 
169     // Create Swiper node to contain TabContent.
170     auto swiperNode = FrameNode::GetOrCreateFrameNode(
171         V2::SWIPER_ETS_TAG, tabsNode->GetSwiperId(), []() { return AceType::MakeRefPtr<SwiperPattern>(); });
172     auto dividerNode = FrameNode::GetOrCreateFrameNode(
173         V2::DIVIDER_ETS_TAG, tabsNode->GetDividerId(), []() { return AceType::MakeRefPtr<DividerPattern>(); });
174 
175     // Create TabBar to contain TabBar of TabContent.
176     auto tabBarNode = FrameNode::GetOrCreateFrameNode(
177         V2::TAB_BAR_ETS_TAG, tabsNode->GetTabBarId(), []() { return AceType::MakeRefPtr<TabBarPattern>(); });
178     if (auto tabBarPattern = tabBarNode->GetPattern<TabBarPattern>(); tabBarPattern) {
179         tabBarPattern->SetController(GetSwiperController(swiperNode, swiperController));
180     }
181 
182     auto tabBarLayoutProperty = tabBarNode->GetLayoutProperty();
183     CHECK_NULL_VOID(tabBarLayoutProperty);
184     if (tabBarLayoutProperty->GetPixelRound() == static_cast<uint16_t>(PixelRoundPolicy::ALL_FORCE_ROUND)) {
185         tabBarLayoutProperty->UpdatePixelRound(PIXEL_ROUND);
186     }
187 
188     auto selectedMaskNode = FrameNode::GetOrCreateFrameNode(V2::COLUMN_ETS_TAG, tabsNode->GetSelectedMaskId(),
189         []() { return AceType::MakeRefPtr<LinearLayoutPattern>(true); });
190 
191     auto unselectedMaskNode = FrameNode::GetOrCreateFrameNode(V2::COLUMN_ETS_TAG, tabsNode->GetUnselectedMaskId(),
192         []() { return AceType::MakeRefPtr<LinearLayoutPattern>(true); });
193 
194     if (!hasSwiperNode) {
195         swiperNode->MountToParent(tabsNode);
196     }
197     if (!hasDividerNode) {
198         dividerNode->MountToParent(tabsNode);
199     }
200     if (!hasTabBarNode) {
201         tabBarNode->MountToParent(tabsNode);
202     }
203     if (!hasSelectedMaskNode) {
204         selectedMaskNode->MountToParent(tabBarNode);
205         InitSelectedMaskNode(selectedMaskNode);
206     }
207     if (!hasUnselectedMaskNode) {
208         unselectedMaskNode->MountToParent(tabBarNode);
209         InitUnselectedMaskNode(unselectedMaskNode);
210     }
211 }
212 
CreateFrameNode(int32_t nodeId)213 RefPtr<FrameNode> TabsModelNG::CreateFrameNode(int32_t nodeId)
214 {
215     auto tabsNode = GetOrCreateTabsNode(V2::TABS_ETS_TAG, nodeId, []() { return AceType::MakeRefPtr<TabsPattern>(); });
216     InitTabsNode(tabsNode, nullptr);
217     auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
218     tabBarNode->MarkModifyDone();
219     return tabsNode;
220 }
221 
SetTabBarPosition(BarPosition tabBarPosition)222 void TabsModelNG::SetTabBarPosition(BarPosition tabBarPosition)
223 {
224     SetTabBarPosition(ViewStackProcessor::GetInstance()->GetMainFrameNode(), tabBarPosition);
225 }
226 
SetBarBackgroundBlurStyle(const BlurStyleOption & styleOption)227 void TabsModelNG::SetBarBackgroundBlurStyle(const BlurStyleOption& styleOption)
228 {
229     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
230     CHECK_NULL_VOID(frameNode);
231     SetBarBackgroundBlurStyle(frameNode, styleOption);
232 }
233 
SetTabBarMode(TabBarMode tabBarMode)234 void TabsModelNG::SetTabBarMode(TabBarMode tabBarMode)
235 {
236     ACE_UPDATE_LAYOUT_PROPERTY(TabsLayoutProperty, TabBarMode, tabBarMode);
237     auto tabBarLayoutProperty = GetTabBarLayoutProperty();
238     CHECK_NULL_VOID(tabBarLayoutProperty);
239     tabBarLayoutProperty->UpdateTabBarMode(tabBarMode);
240 }
241 
SetTabBarWidth(const Dimension & tabBarWidth)242 void TabsModelNG::SetTabBarWidth(const Dimension& tabBarWidth)
243 {
244     ACE_UPDATE_LAYOUT_PROPERTY(TabsLayoutProperty, BarWidth, tabBarWidth);
245     auto tabsNode = AceType::DynamicCast<TabsNode>(ViewStackProcessor::GetInstance()->GetMainFrameNode());
246     CHECK_NULL_VOID(tabsNode);
247     auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
248     CHECK_NULL_VOID(tabBarNode);
249     auto tabBarLayoutProperty = tabBarNode->GetLayoutProperty<TabBarLayoutProperty>();
250     CHECK_NULL_VOID(tabBarLayoutProperty);
251     auto scaleProperty = ScaleProperty::CreateScaleProperty();
252     auto tabBarWidthToPx =
253         ConvertToPx(tabBarWidth, scaleProperty, tabBarLayoutProperty->GetLayoutConstraint()->percentReference.Width());
254     if (LessNotEqual(tabBarWidthToPx.value_or(0.0), 0.0)) {
255         tabBarLayoutProperty->ClearUserDefinedIdealSize(true, false);
256     } else {
257         tabBarLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(NG::CalcLength(tabBarWidth), std::nullopt));
258     }
259     tabBarLayoutProperty->UpdateTabBarWidth(tabBarWidth);
260 }
261 
SetTabBarHeight(const Dimension & tabBarHeight)262 void TabsModelNG::SetTabBarHeight(const Dimension& tabBarHeight)
263 {
264     ACE_UPDATE_LAYOUT_PROPERTY(TabsLayoutProperty, BarHeight, tabBarHeight);
265     auto tabsNode = AceType::DynamicCast<TabsNode>(ViewStackProcessor::GetInstance()->GetMainFrameNode());
266     CHECK_NULL_VOID(tabsNode);
267     auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
268     CHECK_NULL_VOID(tabBarNode);
269     auto tabBarLayoutProperty = tabBarNode->GetLayoutProperty<TabBarLayoutProperty>();
270     CHECK_NULL_VOID(tabBarLayoutProperty);
271     auto scaleProperty = ScaleProperty::CreateScaleProperty();
272     auto tabBarHeightToPx = ConvertToPx(
273         tabBarHeight, scaleProperty, tabBarLayoutProperty->GetLayoutConstraint()->percentReference.Height());
274     if (LessNotEqual(tabBarHeightToPx.value_or(0.0), 0.0)) {
275         tabBarLayoutProperty->ClearUserDefinedIdealSize(false, true);
276     } else {
277         tabBarLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(std::nullopt, NG::CalcLength(tabBarHeight)));
278     }
279     tabBarLayoutProperty->UpdateTabBarHeight(tabBarHeight);
280 }
281 
SetBarModifier(std::function<void (WeakPtr<NG::FrameNode>)> && onApply)282 void TabsModelNG::SetBarModifier(std::function<void(WeakPtr<NG::FrameNode>)>&& onApply)
283 {
284     CHECK_NULL_VOID(onApply);
285     auto tabsNode = AceType::DynamicCast<TabsNode>(ViewStackProcessor::GetInstance()->GetMainFrameNode());
286     CHECK_NULL_VOID(tabsNode);
287     auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
288     CHECK_NULL_VOID(tabBarNode);
289     onApply(tabBarNode);
290 }
291 
SetWidthAuto(bool isAuto)292 void TabsModelNG::SetWidthAuto(bool isAuto)
293 {
294     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
295     CHECK_NULL_VOID(frameNode);
296     ACE_UPDATE_LAYOUT_PROPERTY(TabsLayoutProperty, WidthAuto, isAuto);
297 }
298 
SetWidthAuto(FrameNode * frameNode,bool isAuto)299 void TabsModelNG::SetWidthAuto(FrameNode* frameNode, bool isAuto)
300 {
301     CHECK_NULL_VOID(frameNode);
302     ACE_UPDATE_NODE_LAYOUT_PROPERTY(TabsLayoutProperty, WidthAuto, isAuto, frameNode);
303 }
304 
SetHeightAuto(bool isAuto)305 void TabsModelNG::SetHeightAuto(bool isAuto)
306 {
307     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
308     CHECK_NULL_VOID(frameNode);
309     ACE_UPDATE_LAYOUT_PROPERTY(TabsLayoutProperty, HeightAuto, isAuto);
310 }
311 
SetHeightAuto(FrameNode * frameNode,bool isAuto)312 void TabsModelNG::SetHeightAuto(FrameNode* frameNode, bool isAuto)
313 {
314     CHECK_NULL_VOID(frameNode);
315     ACE_UPDATE_NODE_LAYOUT_PROPERTY(TabsLayoutProperty, HeightAuto, isAuto, frameNode);
316 }
317 
SetBarAdaptiveHeight(bool barAdaptiveHeight)318 void TabsModelNG::SetBarAdaptiveHeight(bool barAdaptiveHeight)
319 {
320     auto tabBarLayoutProperty = GetTabBarLayoutProperty();
321     CHECK_NULL_VOID(tabBarLayoutProperty);
322     tabBarLayoutProperty->UpdateBarAdaptiveHeight(barAdaptiveHeight);
323 }
324 
SetNoMinHeightLimit(bool noMinHeightLimit)325 void TabsModelNG::SetNoMinHeightLimit(bool noMinHeightLimit)
326 {
327     auto tabBarLayoutProperty = GetTabBarLayoutProperty();
328     CHECK_NULL_VOID(tabBarLayoutProperty);
329     tabBarLayoutProperty->UpdateNoMinHeightLimit(noMinHeightLimit);
330 }
331 
SetIsVertical(bool isVertical)332 void TabsModelNG::SetIsVertical(bool isVertical)
333 {
334     auto axis = isVertical ? Axis::VERTICAL : Axis::HORIZONTAL;
335     ACE_UPDATE_LAYOUT_PROPERTY(TabsLayoutProperty, Axis, axis);
336 
337     auto tabBarLayoutProperty = GetTabBarLayoutProperty();
338     CHECK_NULL_VOID(tabBarLayoutProperty);
339     if (tabBarLayoutProperty->GetAxis().value_or(Axis::HORIZONTAL) != axis) {
340         auto tabsNode = AceType::DynamicCast<TabsNode>(ViewStackProcessor::GetInstance()->GetMainFrameNode());
341         CHECK_NULL_VOID(tabsNode);
342         auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
343         CHECK_NULL_VOID(tabBarNode);
344         auto tabBarPattern = tabBarNode->GetPattern<TabBarPattern>();
345         CHECK_NULL_VOID(tabBarPattern);
346         tabBarPattern->UpdateCurrentOffset(0.0f);
347     }
348     tabBarLayoutProperty->UpdateAxis(axis);
349     auto swiperLayoutProperty = GetSwiperLayoutProperty();
350     CHECK_NULL_VOID(swiperLayoutProperty);
351     swiperLayoutProperty->UpdateDirection(axis);
352 }
353 
SetIndex(int32_t index)354 void TabsModelNG::SetIndex(int32_t index)
355 {
356     auto tabsNode = AceType::DynamicCast<TabsNode>(ViewStackProcessor::GetInstance()->GetMainFrameNode());
357     CHECK_NULL_VOID(tabsNode);
358     auto swiperNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabs());
359     CHECK_NULL_VOID(swiperNode);
360     auto swiperLayoutProperty = swiperNode->GetLayoutProperty<SwiperLayoutProperty>();
361     CHECK_NULL_VOID(swiperLayoutProperty);
362     swiperLayoutProperty->UpdateIndex(index);
363     auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
364     CHECK_NULL_VOID(tabBarNode);
365     auto tabBarPattern = tabBarNode->GetPattern<TabBarPattern>();
366     CHECK_NULL_VOID(tabBarPattern);
367     if (index < 0) {
368         index = 0;
369     }
370     tabBarPattern->UpdateIndicator(index);
371     tabBarPattern->UpdateTextColorAndFontWeight(index);
372     swiperLayoutProperty->UpdateIndex(index);
373     auto tabsFrameNode = AceType::DynamicCast<FrameNode>(tabsNode);
374     CHECK_NULL_VOID(tabsFrameNode);
375     auto tabsLayoutProperty = tabsFrameNode->GetLayoutProperty<TabsLayoutProperty>();
376     tabsLayoutProperty->UpdateIndex(index);
377     swiperNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
378 }
379 
SetScrollable(bool scrollable)380 void TabsModelNG::SetScrollable(bool scrollable)
381 {
382     auto props = GetSwiperLayoutProperty();
383     CHECK_NULL_VOID(props);
384     props->UpdateDisableSwipe(!scrollable);
385     auto tabsNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
386     CHECK_NULL_VOID(tabsNode);
387     auto tabPattern = tabsNode->GetPattern<TabsPattern>();
388     CHECK_NULL_VOID(tabPattern);
389     tabPattern->SetIsDisableSwipe(!scrollable);
390 }
391 
SetAnimationCurve(const RefPtr<Curve> & curve)392 void TabsModelNG::SetAnimationCurve(const RefPtr<Curve>& curve)
393 {
394     SetAnimationCurve(ViewStackProcessor::GetInstance()->GetMainFrameNode(), curve);
395 }
396 
SetAnimationDuration(float duration)397 void TabsModelNG::SetAnimationDuration(float duration)
398 {
399     auto tabsNode = AceType::DynamicCast<TabsNode>(ViewStackProcessor::GetInstance()->GetMainFrameNode());
400     CHECK_NULL_VOID(tabsNode);
401     auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
402     CHECK_NULL_VOID(tabBarNode);
403     auto tabBarPattern = tabBarNode->GetPattern<TabBarPattern>();
404     CHECK_NULL_VOID(tabBarPattern);
405     tabBarPattern->SetAnimationDuration(static_cast<int32_t>(duration));
406     if (static_cast<int32_t>(duration) < 0) {
407         return;
408     }
409     auto swiperPaintProperty = GetSwiperPaintProperty();
410     CHECK_NULL_VOID(swiperPaintProperty);
411     swiperPaintProperty->UpdateDuration(static_cast<int32_t>(duration));
412 }
413 
SetFadingEdge(bool fadingEdge)414 void TabsModelNG::SetFadingEdge(bool fadingEdge)
415 {
416     auto tabBarPaintProperty = GetTabBarPaintProperty();
417     CHECK_NULL_VOID(tabBarPaintProperty);
418     tabBarPaintProperty->UpdateFadingEdge(fadingEdge);
419 }
420 
SetBarOverlap(bool barOverlap)421 void TabsModelNG::SetBarOverlap(bool barOverlap)
422 {
423     ACE_UPDATE_LAYOUT_PROPERTY(TabsLayoutProperty, BarOverlap, barOverlap);
424 
425     BlurStyleOption option;
426     if (barOverlap) {
427         option.blurStyle = BlurStyle::COMPONENT_THICK;
428     }
429     SetBarBackgroundBlurStyle(option);
430 }
431 
SetOnChange(std::function<void (const BaseEventInfo *)> && onChange)432 void TabsModelNG::SetOnChange(std::function<void(const BaseEventInfo*)>&& onChange)
433 {
434     auto tabsNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
435     CHECK_NULL_VOID(tabsNode);
436     auto tabPattern = tabsNode->GetPattern<TabsPattern>();
437     CHECK_NULL_VOID(tabPattern);
438     tabPattern->SetOnChangeEvent(std::move(onChange));
439 }
440 
SetOnTabBarClick(std::function<void (const BaseEventInfo *)> && onTabBarClick)441 void TabsModelNG::SetOnTabBarClick(std::function<void(const BaseEventInfo*)>&& onTabBarClick)
442 {
443     auto tabsNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
444     CHECK_NULL_VOID(tabsNode);
445     auto tabPattern = tabsNode->GetPattern<TabsPattern>();
446     CHECK_NULL_VOID(tabPattern);
447     tabPattern->SetOnTabBarClickEvent(std::move(onTabBarClick));
448 }
449 
SetOnUnselected(std::function<void (const BaseEventInfo * info)> && onUnselected)450 void TabsModelNG::SetOnUnselected(std::function<void(const BaseEventInfo* info)>&& onUnselected)
451 {
452     auto tabsNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
453     CHECK_NULL_VOID(tabsNode);
454     auto tabPattern = tabsNode->GetPattern<TabsPattern>();
455     CHECK_NULL_VOID(tabPattern);
456     tabPattern->SetOnUnselectedEvent(std::move(onUnselected));
457 }
458 
SetOnAnimationStart(AnimationStartEvent && onAnimationStart)459 void TabsModelNG::SetOnAnimationStart(AnimationStartEvent&& onAnimationStart)
460 {
461     auto tabsNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
462     CHECK_NULL_VOID(tabsNode);
463     auto tabPattern = tabsNode->GetPattern<TabsPattern>();
464     CHECK_NULL_VOID(tabPattern);
465     tabPattern->SetAnimationStartEvent(std::move(onAnimationStart));
466 }
467 
SetOnAnimationEnd(AnimationEndEvent && onAnimationEnd)468 void TabsModelNG::SetOnAnimationEnd(AnimationEndEvent&& onAnimationEnd)
469 {
470     auto tabsNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
471     CHECK_NULL_VOID(tabsNode);
472     auto tabPattern = tabsNode->GetPattern<TabsPattern>();
473     CHECK_NULL_VOID(tabPattern);
474     tabPattern->SetAnimationEndEvent(std::move(onAnimationEnd));
475 }
476 
SetOnGestureSwipe(GestureSwipeEvent && onGestureSwipe)477 void TabsModelNG::SetOnGestureSwipe(GestureSwipeEvent&& onGestureSwipe)
478 {
479     auto tabsNode = AceType::DynamicCast<TabsNode>(ViewStackProcessor::GetInstance()->GetMainFrameNode());
480     CHECK_NULL_VOID(tabsNode);
481     auto swiperNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabs());
482     CHECK_NULL_VOID(swiperNode);
483     auto eventHub = swiperNode->GetOrCreateEventHub<SwiperEventHub>();
484     CHECK_NULL_VOID(eventHub);
485     eventHub->SetGestureSwipeEvent(std::move(onGestureSwipe));
486 }
487 
SetOnSelected(std::function<void (const BaseEventInfo * info)> && onSelected)488 void TabsModelNG::SetOnSelected(std::function<void(const BaseEventInfo* info)>&& onSelected)
489 {
490     auto tabsNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
491     CHECK_NULL_VOID(tabsNode);
492     auto tabPattern = tabsNode->GetPattern<TabsPattern>();
493     CHECK_NULL_VOID(tabPattern);
494     tabPattern->SetOnSelectedEvent(std::move(onSelected));
495 }
496 
SetOnSelected(FrameNode * frameNode,std::function<void (const BaseEventInfo * info)> && onSelected)497 void TabsModelNG::SetOnSelected(FrameNode* frameNode, std::function<void(const BaseEventInfo* info)>&& onSelected)
498 {
499     CHECK_NULL_VOID(frameNode);
500     auto pattern = frameNode->GetPattern<TabsPattern>();
501     CHECK_NULL_VOID(pattern);
502     pattern->SetOnSelectedEvent(std::move(onSelected));
503 }
504 
SetDivider(const TabsItemDivider & divider)505 void TabsModelNG::SetDivider(const TabsItemDivider& divider)
506 {
507     auto tabsNode = AceType::DynamicCast<TabsNode>(ViewStackProcessor::GetInstance()->GetMainFrameNode());
508     CHECK_NULL_VOID(tabsNode);
509     auto dividerNode = AceType::DynamicCast<FrameNode>(tabsNode->GetDivider());
510     CHECK_NULL_VOID(dividerNode);
511     auto dividerRenderContext = dividerNode->GetRenderContext();
512     CHECK_NULL_VOID(dividerRenderContext);
513     if (divider.isNull) {
514         dividerRenderContext->UpdateOpacity(0.0f);
515         auto tabsLayoutProperty = tabsNode->GetLayoutProperty<TabsLayoutProperty>();
516         CHECK_NULL_VOID(tabsLayoutProperty);
517         auto currentDivider = tabsLayoutProperty->GetDivider().value_or(TabsItemDivider());
518         currentDivider.strokeWidth = Dimension(1.0f);
519         currentDivider.isNull = true;
520         ACE_UPDATE_LAYOUT_PROPERTY(TabsLayoutProperty, Divider, currentDivider);
521     } else {
522         dividerRenderContext->UpdateOpacity(1.0f);
523         ACE_UPDATE_LAYOUT_PROPERTY(TabsLayoutProperty, Divider, divider);
524     }
525 }
526 
SetDividerColorByUser(bool isByUser)527 void TabsModelNG::SetDividerColorByUser(bool isByUser)
528 {
529     ACE_UPDATE_LAYOUT_PROPERTY(TabsLayoutProperty, DividerColorSetByUser, isByUser);
530 }
531 
SetDividerColorByUser(FrameNode * frameNode,bool isByUser)532 void TabsModelNG::SetDividerColorByUser(FrameNode* frameNode, bool isByUser)
533 {
534     ACE_UPDATE_NODE_LAYOUT_PROPERTY(TabsLayoutProperty, DividerColorSetByUser, isByUser, frameNode);
535 }
536 
SetBarBackgroundColor(const Color & backgroundColor)537 void TabsModelNG::SetBarBackgroundColor(const Color& backgroundColor)
538 {
539     auto tabsNode = AceType::DynamicCast<TabsNode>(ViewStackProcessor::GetInstance()->GetMainFrameNode());
540     CHECK_NULL_VOID(tabsNode);
541     auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
542     CHECK_NULL_VOID(tabBarNode);
543     auto tabBarRenderContext = tabBarNode->GetRenderContext();
544     CHECK_NULL_VOID(tabBarRenderContext);
545     tabBarRenderContext->UpdateBackgroundColor(backgroundColor);
546 }
547 
SetBarBackgroundColorByUser(bool isByUser)548 void TabsModelNG::SetBarBackgroundColorByUser(bool isByUser)
549 {
550     ACE_UPDATE_LAYOUT_PROPERTY(TabsLayoutProperty, BarBackgroundColorSetByUser, isByUser);
551 }
552 
GetTabBarLayoutProperty()553 RefPtr<TabBarLayoutProperty> TabsModelNG::GetTabBarLayoutProperty()
554 {
555     auto tabsNode = AceType::DynamicCast<TabsNode>(ViewStackProcessor::GetInstance()->GetMainFrameNode());
556     CHECK_NULL_RETURN(tabsNode, nullptr);
557     auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
558     CHECK_NULL_RETURN(tabBarNode, nullptr);
559     auto tabBarLayoutProperty = tabBarNode->GetLayoutProperty<TabBarLayoutProperty>();
560     CHECK_NULL_RETURN(tabBarLayoutProperty, nullptr);
561     return tabBarLayoutProperty;
562 }
563 
GetTabBarPaintProperty()564 RefPtr<TabBarPaintProperty> TabsModelNG::GetTabBarPaintProperty()
565 {
566     auto tabsNode = AceType::DynamicCast<TabsNode>(ViewStackProcessor::GetInstance()->GetMainFrameNode());
567     CHECK_NULL_RETURN(tabsNode, nullptr);
568     auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
569     CHECK_NULL_RETURN(tabBarNode, nullptr);
570     auto tabBarPaintProperty = tabBarNode->GetPaintProperty<TabBarPaintProperty>();
571     CHECK_NULL_RETURN(tabBarPaintProperty, nullptr);
572     return tabBarPaintProperty;
573 }
574 
GetSwiperLayoutProperty()575 RefPtr<SwiperLayoutProperty> TabsModelNG::GetSwiperLayoutProperty()
576 {
577     auto tabsNode = AceType::DynamicCast<TabsNode>(ViewStackProcessor::GetInstance()->GetMainFrameNode());
578     CHECK_NULL_RETURN(tabsNode, nullptr);
579     auto swiperNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabs());
580     CHECK_NULL_RETURN(swiperNode, nullptr);
581     auto swiperLayoutProperty = swiperNode->GetLayoutProperty<SwiperLayoutProperty>();
582     CHECK_NULL_RETURN(swiperLayoutProperty, nullptr);
583     return swiperLayoutProperty;
584 }
585 
GetSwiperPaintProperty()586 RefPtr<SwiperPaintProperty> TabsModelNG::GetSwiperPaintProperty()
587 {
588     auto tabsNode = AceType::DynamicCast<TabsNode>(ViewStackProcessor::GetInstance()->GetMainFrameNode());
589     CHECK_NULL_RETURN(tabsNode, nullptr);
590     auto swiperNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabs());
591     CHECK_NULL_RETURN(swiperNode, nullptr);
592     auto swiperPaintProperty = swiperNode->GetPaintProperty<SwiperPaintProperty>();
593     CHECK_NULL_RETURN(swiperPaintProperty, nullptr);
594     return swiperPaintProperty;
595 }
596 
Pop()597 void TabsModelNG::Pop()
598 {
599     auto tabsNode = AceType::DynamicCast<TabsNode>(ViewStackProcessor::GetInstance()->GetMainFrameNode());
600     CHECK_NULL_VOID(tabsNode);
601     auto tabsLayoutProperty = tabsNode->GetLayoutProperty<TabsLayoutProperty>();
602     CHECK_NULL_VOID(tabsLayoutProperty);
603     auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
604     CHECK_NULL_VOID(tabBarNode);
605     auto swiperNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabs());
606     CHECK_NULL_VOID(swiperNode);
607 
608     tabBarNode->MarkModifyDone();
609     tabBarNode->MarkDirtyNode(PROPERTY_UPDATE_LAYOUT);
610     auto dividerNode = AceType::DynamicCast<FrameNode>(tabsNode->GetDivider());
611     CHECK_NULL_VOID(dividerNode);
612     auto layoutProperty = tabsNode->GetLayoutProperty<TabsLayoutProperty>();
613     CHECK_NULL_VOID(layoutProperty);
614 
615     auto axis = layoutProperty->GetAxis().value_or((Axis::HORIZONTAL));
616     TabsItemDivider defaultDivider;
617     auto divider = layoutProperty->GetDivider().value_or(defaultDivider);
618     auto dividerColor = divider.color;
619     auto dividerStrokeWidth = divider.strokeWidth;
620 
621     auto dividerHub = dividerNode->GetOrCreateEventHub<EventHub>();
622     CHECK_NULL_VOID(dividerHub);
623 
624     auto dividerRenderProperty = dividerNode->GetPaintProperty<DividerRenderProperty>();
625     CHECK_NULL_VOID(dividerRenderProperty);
626     dividerRenderProperty->UpdateDividerColor(dividerColor);
627     dividerRenderProperty->UpdateLineCap(LineCap::BUTT);
628 
629     auto dividerLayoutProperty = dividerNode->GetLayoutProperty<DividerLayoutProperty>();
630     CHECK_NULL_VOID(dividerLayoutProperty);
631     dividerLayoutProperty->UpdateVertical(axis == Axis::VERTICAL);
632     dividerLayoutProperty->UpdateStrokeWidth(dividerStrokeWidth);
633     dividerLayoutProperty->UpdateStrokeWidthLimitation(false);
634     CHECK_NULL_VOID(dividerNode);
635     dividerNode->MarkModifyDone();
636 
637     swiperNode->MarkModifyDone();
638     swiperNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
639 
640     ViewStackProcessor::GetInstance()->PopContainer();
641 }
642 
GetOrCreateTabsNode(const std::string & tag,int32_t nodeId,const std::function<RefPtr<Pattern> (void)> & patternCreator)643 RefPtr<TabsNode> TabsModelNG::GetOrCreateTabsNode(
644     const std::string& tag, int32_t nodeId, const std::function<RefPtr<Pattern>(void)>& patternCreator)
645 {
646     auto tabsNode = ElementRegister::GetInstance()->GetSpecificItemById<TabsNode>(nodeId);
647     if (tabsNode) {
648         if (tabsNode->GetTag() == tag) {
649             return tabsNode;
650         }
651         ElementRegister::GetInstance()->RemoveItemSilently(nodeId);
652         auto parent = tabsNode->GetParent();
653         if (parent) {
654             parent->RemoveChild(tabsNode);
655         }
656     }
657 
658     auto pattern = patternCreator ? patternCreator() : AceType::MakeRefPtr<Pattern>();
659     tabsNode = AceType::MakeRefPtr<TabsNode>(tag, nodeId, pattern, false);
660     tabsNode->InitializePatternAndContext();
661     ElementRegister::GetInstance()->AddUINode(tabsNode);
662     return tabsNode;
663 }
664 
SetOnChangeEvent(std::function<void (const BaseEventInfo *)> && onChangeEvent)665 void TabsModelNG::SetOnChangeEvent(std::function<void(const BaseEventInfo*)>&& onChangeEvent)
666 {
667     auto tabsNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
668     CHECK_NULL_VOID(tabsNode);
669     auto tabPattern = tabsNode->GetPattern<TabsPattern>();
670     CHECK_NULL_VOID(tabPattern);
671     tabPattern->SetOnIndexChangeEvent(std::move(onChangeEvent));
672 }
673 
SetClipEdge(bool clipEdge)674 void TabsModelNG::SetClipEdge(bool clipEdge)
675 {
676     auto tabsNode = AceType::DynamicCast<TabsNode>(ViewStackProcessor::GetInstance()->GetMainFrameNode());
677     CHECK_NULL_VOID(tabsNode);
678     ViewAbstract::SetClipEdge(clipEdge);
679     auto swiperNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabs());
680     CHECK_NULL_VOID(swiperNode);
681     auto swiperRenderContext = swiperNode->GetRenderContext();
682     CHECK_NULL_VOID(swiperRenderContext);
683     swiperRenderContext->UpdateClipEdge(clipEdge);
684     auto dividerNode = AceType::DynamicCast<FrameNode>(tabsNode->GetDivider());
685     CHECK_NULL_VOID(dividerNode);
686     auto dividerRenderContext = dividerNode->GetRenderContext();
687     CHECK_NULL_VOID(dividerRenderContext);
688     dividerRenderContext->UpdateClipEdge(clipEdge);
689 }
690 
SetScrollableBarModeOptions(const ScrollableBarModeOptions & option)691 void TabsModelNG::SetScrollableBarModeOptions(const ScrollableBarModeOptions& option)
692 {
693     auto tabBarLayoutProperty = GetTabBarLayoutProperty();
694     CHECK_NULL_VOID(tabBarLayoutProperty);
695     tabBarLayoutProperty->UpdateScrollableBarModeOptions(option);
696 }
697 
ResetScrollableBarModeOptions()698 void TabsModelNG::ResetScrollableBarModeOptions()
699 {
700     auto tabBarLayoutProperty = GetTabBarLayoutProperty();
701     CHECK_NULL_VOID(tabBarLayoutProperty);
702     tabBarLayoutProperty->ResetScrollableBarModeOptions();
703 }
704 
SetBarGridAlign(const BarGridColumnOptions & BarGridColumnOptions)705 void TabsModelNG::SetBarGridAlign(const BarGridColumnOptions& BarGridColumnOptions)
706 {
707     auto tabBarLayoutProperty = GetTabBarLayoutProperty();
708     CHECK_NULL_VOID(tabBarLayoutProperty);
709     tabBarLayoutProperty->UpdateBarGridAlign(BarGridColumnOptions);
710 }
711 
GetTabBarLayoutProperty(FrameNode * frameNode)712 RefPtr<TabBarLayoutProperty> TabsModelNG::GetTabBarLayoutProperty(FrameNode* frameNode)
713 {
714     auto tabsNode = AceType::DynamicCast<TabsNode>(frameNode);
715     CHECK_NULL_RETURN(tabsNode, nullptr);
716     auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
717     CHECK_NULL_RETURN(tabBarNode, nullptr);
718     auto tabBarLayoutProperty = tabBarNode->GetLayoutProperty<TabBarLayoutProperty>();
719     CHECK_NULL_RETURN(tabBarLayoutProperty, nullptr);
720     return tabBarLayoutProperty;
721 }
722 
GetTabBarPaintProperty(FrameNode * frameNode)723 RefPtr<TabBarPaintProperty> TabsModelNG::GetTabBarPaintProperty(FrameNode* frameNode)
724 {
725     auto tabsNode = AceType::DynamicCast<TabsNode>(frameNode);
726     CHECK_NULL_RETURN(tabsNode, nullptr);
727     auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
728     CHECK_NULL_RETURN(tabBarNode, nullptr);
729     auto tabBarPaintProperty = tabBarNode->GetPaintProperty<TabBarPaintProperty>();
730     CHECK_NULL_RETURN(tabBarPaintProperty, nullptr);
731     return tabBarPaintProperty;
732 }
733 
GetSwiperLayoutProperty(FrameNode * frameNode)734 RefPtr<SwiperLayoutProperty> TabsModelNG::GetSwiperLayoutProperty(FrameNode* frameNode)
735 {
736     auto tabsNode = AceType::DynamicCast<TabsNode>(frameNode);
737     CHECK_NULL_RETURN(tabsNode, nullptr);
738     auto swiperNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabs());
739     CHECK_NULL_RETURN(swiperNode, nullptr);
740     auto swiperLayoutProperty = swiperNode->GetLayoutProperty<SwiperLayoutProperty>();
741     CHECK_NULL_RETURN(swiperLayoutProperty, nullptr);
742     return swiperLayoutProperty;
743 }
744 
GetSwiperPaintProperty(FrameNode * frameNode)745 RefPtr<SwiperPaintProperty> TabsModelNG::GetSwiperPaintProperty(FrameNode* frameNode)
746 {
747     auto tabsNode = AceType::DynamicCast<TabsNode>(frameNode);
748     CHECK_NULL_RETURN(tabsNode, nullptr);
749     auto swiperNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabs());
750     CHECK_NULL_RETURN(swiperNode, nullptr);
751     auto swiperPaintProperty = swiperNode->GetPaintProperty<SwiperPaintProperty>();
752     CHECK_NULL_RETURN(swiperPaintProperty, nullptr);
753     return swiperPaintProperty;
754 }
755 
SetTabBarMode(FrameNode * frameNode,TabBarMode tabBarMode)756 void TabsModelNG::SetTabBarMode(FrameNode* frameNode, TabBarMode tabBarMode)
757 {
758     ACE_UPDATE_NODE_LAYOUT_PROPERTY(TabsLayoutProperty, TabBarMode, tabBarMode, frameNode);
759     auto tabBarLayoutProperty = GetTabBarLayoutProperty(frameNode);
760     CHECK_NULL_VOID(tabBarLayoutProperty);
761     tabBarLayoutProperty->UpdateTabBarMode(tabBarMode);
762 }
763 
SetBarGridAlign(FrameNode * frameNode,const BarGridColumnOptions & BarGridColumnOptions)764 void TabsModelNG::SetBarGridAlign(FrameNode* frameNode, const BarGridColumnOptions& BarGridColumnOptions)
765 {
766     CHECK_NULL_VOID(frameNode);
767     auto tabBarLayoutProperty = GetTabBarLayoutProperty(frameNode);
768     CHECK_NULL_VOID(tabBarLayoutProperty);
769     tabBarLayoutProperty->UpdateBarGridAlign(BarGridColumnOptions);
770 }
771 
SetOnUnselected(FrameNode * frameNode,std::function<void (const BaseEventInfo * info)> && onUnselected)772 void TabsModelNG::SetOnUnselected(FrameNode* frameNode, std::function<void(const BaseEventInfo* info)>&& onUnselected)
773 {
774     CHECK_NULL_VOID(frameNode);
775     auto pattern = frameNode->GetPattern<TabsPattern>();
776     CHECK_NULL_VOID(pattern);
777     pattern->SetOnUnselectedEvent(std::move(onUnselected));
778 }
779 
SetDivider(FrameNode * frameNode,const TabsItemDivider & divider)780 void TabsModelNG::SetDivider(FrameNode* frameNode, const TabsItemDivider& divider)
781 {
782     CHECK_NULL_VOID(frameNode);
783     auto tabsNode = AceType::DynamicCast<TabsNode>(frameNode);
784     CHECK_NULL_VOID(tabsNode);
785     auto dividerNode = AceType::DynamicCast<FrameNode>(tabsNode->GetDivider());
786     CHECK_NULL_VOID(dividerNode);
787     auto dividerRenderContext = dividerNode->GetRenderContext();
788     CHECK_NULL_VOID(dividerRenderContext);
789     if (divider.isNull) {
790         dividerRenderContext->UpdateOpacity(0.0f);
791         auto tabsLayoutProperty = frameNode->GetLayoutProperty<TabsLayoutProperty>();
792         CHECK_NULL_VOID(tabsLayoutProperty);
793         auto currentDivider = tabsLayoutProperty->GetDivider().value_or(TabsItemDivider());
794         currentDivider.strokeWidth = Dimension(1.0f);
795         currentDivider.isNull = true;
796         ACE_UPDATE_NODE_LAYOUT_PROPERTY(TabsLayoutProperty, Divider, currentDivider, frameNode);
797     } else {
798         dividerRenderContext->UpdateOpacity(1.0f);
799         ACE_UPDATE_NODE_LAYOUT_PROPERTY(TabsLayoutProperty, Divider, divider, frameNode);
800     }
801 }
802 
SetEffectNodeOption(FrameNode * frameNode,const TabsEffectNodeOption & option)803 void TabsModelNG::SetEffectNodeOption(FrameNode* frameNode, const TabsEffectNodeOption& option)
804 {
805     CHECK_NULL_VOID(frameNode);
806     auto tabsNode = AceType::DynamicCast<TabsNode>(AceType::Claim(frameNode));
807     CHECK_NULL_VOID(tabsNode);
808     auto effectNode = AceType::DynamicCast<FrameNode>(tabsNode->GetEffectNode());
809     if (option.isNull) {
810         if (effectNode) {
811             tabsNode->RemoveChild(effectNode);
812         }
813     } else {
814         if (!effectNode) {
815             effectNode = InitEffectNode(tabsNode);
816             effectNode->MountToParent(tabsNode);
817             ViewAbstract::SetZIndex(AceType::RawPtr(effectNode), EFFECT_Z_INDEX);
818 
819             auto swiperNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabs());
820             CHECK_NULL_VOID(swiperNode);
821             ViewAbstract::SetZIndex(AceType::RawPtr(swiperNode), SWIPER_Z_INDEX);
822 
823             auto dividerNode = AceType::DynamicCast<FrameNode>(tabsNode->GetDivider());
824             CHECK_NULL_VOID(dividerNode);
825             ViewAbstract::SetZIndex(AceType::RawPtr(dividerNode), DIVIDER_Z_INDEX);
826 
827             auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
828             CHECK_NULL_VOID(tabBarNode);
829             ViewAbstract::SetZIndex(AceType::RawPtr(tabBarNode), TAB_BAR_Z_INDEX);
830         }
831     }
832     ACE_UPDATE_NODE_LAYOUT_PROPERTY(TabsLayoutProperty, EffectNodeOption, option, frameNode);
833 }
834 
SetFadingEdge(FrameNode * frameNode,bool fadingEdge)835 void TabsModelNG::SetFadingEdge(FrameNode* frameNode, bool fadingEdge)
836 {
837     CHECK_NULL_VOID(frameNode);
838     auto tabBarPaintProperty = GetTabBarPaintProperty(frameNode);
839     CHECK_NULL_VOID(tabBarPaintProperty);
840     tabBarPaintProperty->UpdateFadingEdge(fadingEdge);
841 }
842 
SetBarBackgroundColor(FrameNode * frameNode,const Color & backgroundColor)843 void TabsModelNG::SetBarBackgroundColor(FrameNode* frameNode, const Color& backgroundColor)
844 {
845     CHECK_NULL_VOID(frameNode);
846     auto tabsNode = AceType::DynamicCast<TabsNode>(frameNode);
847     CHECK_NULL_VOID(tabsNode);
848     auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
849     CHECK_NULL_VOID(tabBarNode);
850     auto tabBarRenderContext = tabBarNode->GetRenderContext();
851     CHECK_NULL_VOID(tabBarRenderContext);
852     tabBarRenderContext->UpdateBackgroundColor(backgroundColor);
853 }
854 
SetBarBackgroundColorByUser(FrameNode * frameNode,bool isByUser)855 void TabsModelNG::SetBarBackgroundColorByUser(FrameNode* frameNode, bool isByUser)
856 {
857     ACE_UPDATE_NODE_LAYOUT_PROPERTY(TabsLayoutProperty, BarBackgroundColorSetByUser, isByUser, frameNode);
858 }
859 
SetBarBackgroundBlurStyle(FrameNode * frameNode,const BlurStyleOption & styleOption)860 void TabsModelNG::SetBarBackgroundBlurStyle(FrameNode* frameNode, const BlurStyleOption& styleOption)
861 {
862     CHECK_NULL_VOID(frameNode);
863     auto tabsNode = AceType::DynamicCast<TabsNode>(frameNode);
864     CHECK_NULL_VOID(tabsNode);
865     auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
866     CHECK_NULL_VOID(tabBarNode);
867     auto pipeline = tabBarNode->GetContext();
868     CHECK_NULL_VOID(pipeline);
869     if (styleOption.policy == BlurStyleActivePolicy::FOLLOWS_WINDOW_ACTIVE_STATE) {
870         pipeline->AddWindowFocusChangedCallback(tabBarNode->GetId());
871     } else {
872         pipeline->RemoveWindowFocusChangedCallback(tabBarNode->GetId());
873     }
874     auto target = tabBarNode->GetRenderContext();
875     if (target) {
876         if (target->GetBackgroundEffect().has_value()) {
877             target->UpdateBackgroundEffect(std::nullopt);
878         }
879         target->UpdateBackBlurStyle(styleOption);
880         if (target->GetBackBlurRadius().has_value()) {
881             target->UpdateBackBlurRadius(Dimension());
882         }
883     }
884 }
885 
SetBarOverlap(FrameNode * frameNode,bool barOverlap)886 void TabsModelNG::SetBarOverlap(FrameNode* frameNode, bool barOverlap)
887 {
888     ACE_UPDATE_NODE_LAYOUT_PROPERTY(TabsLayoutProperty, BarOverlap, barOverlap, frameNode);
889 
890     BlurStyleOption option;
891     if (barOverlap) {
892         option.blurStyle = BlurStyle::COMPONENT_THICK;
893     }
894     SetBarBackgroundBlurStyle(frameNode, option);
895 }
896 
SetIsVertical(FrameNode * frameNode,bool isVertical)897 void TabsModelNG::SetIsVertical(FrameNode* frameNode, bool isVertical)
898 {
899     auto axis = isVertical ? Axis::VERTICAL : Axis::HORIZONTAL;
900     ACE_UPDATE_NODE_LAYOUT_PROPERTY(TabsLayoutProperty, Axis, axis, frameNode);
901 
902     auto tabBarLayoutProperty = GetTabBarLayoutProperty(frameNode);
903     CHECK_NULL_VOID(tabBarLayoutProperty);
904     if (tabBarLayoutProperty->GetAxis().value_or(Axis::HORIZONTAL) != axis) {
905         auto tabsNode = AceType::DynamicCast<TabsNode>(frameNode);
906         CHECK_NULL_VOID(tabsNode);
907         auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
908         CHECK_NULL_VOID(tabBarNode);
909         auto tabBarPattern = tabBarNode->GetPattern<TabBarPattern>();
910         CHECK_NULL_VOID(tabBarPattern);
911         tabBarPattern->UpdateCurrentOffset(0.0f);
912     }
913     tabBarLayoutProperty->UpdateAxis(axis);
914     auto swiperLayoutProperty = GetSwiperLayoutProperty(frameNode);
915     CHECK_NULL_VOID(swiperLayoutProperty);
916     swiperLayoutProperty->UpdateDirection(axis);
917 }
918 
SetTabBarPosition(FrameNode * frameNode,BarPosition tabBarPosition)919 void TabsModelNG::SetTabBarPosition(FrameNode* frameNode, BarPosition tabBarPosition)
920 {
921     CHECK_NULL_VOID(frameNode);
922     auto tabsLayoutProperty = frameNode->GetLayoutProperty<TabsLayoutProperty>();
923     CHECK_NULL_VOID(tabsLayoutProperty);
924     auto oldTabBarPosition = tabsLayoutProperty->GetTabBarPosition();
925     ACE_UPDATE_NODE_LAYOUT_PROPERTY(TabsLayoutProperty, TabBarPosition, tabBarPosition, frameNode);
926 
927     if ((!oldTabBarPosition.has_value() && tabBarPosition == BarPosition::END) ||
928         (oldTabBarPosition.has_value() && oldTabBarPosition.value() == tabBarPosition)) {
929         return;
930     }
931 
932     auto tabsNode = AceType::DynamicCast<TabsNode>(frameNode);
933     CHECK_NULL_VOID(tabsNode);
934     auto tabsFocusNode = tabsNode->GetFocusHub();
935     CHECK_NULL_VOID(tabsFocusNode);
936     if (!tabsFocusNode->IsCurrentFocus()) {
937         auto tabBarPosition = tabsLayoutProperty->GetTabBarPosition().value_or(BarPosition::START);
938         if (tabBarPosition == BarPosition::START) {
939             auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
940             CHECK_NULL_VOID(tabBarNode);
941             auto tabBarFocusNode = tabBarNode->GetFocusHub();
942             CHECK_NULL_VOID(tabBarFocusNode);
943             tabsFocusNode->SetLastWeakFocusNode(AceType::WeakClaim(AceType::RawPtr(tabBarFocusNode)));
944         } else {
945             auto swiperNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabs());
946             CHECK_NULL_VOID(swiperNode);
947             auto swiperFocusNode = swiperNode->GetFocusHub();
948             CHECK_NULL_VOID(swiperFocusNode);
949             tabsFocusNode->SetLastWeakFocusNode(AceType::WeakClaim(AceType::RawPtr(swiperFocusNode)));
950         }
951     }
952 }
953 
SetScrollable(FrameNode * frameNode,bool scrollable)954 void TabsModelNG::SetScrollable(FrameNode* frameNode, bool scrollable)
955 {
956     CHECK_NULL_VOID(frameNode);
957     auto props = GetSwiperLayoutProperty(frameNode);
958     CHECK_NULL_VOID(props);
959     props->UpdateDisableSwipe(!scrollable);
960     auto tabPattern = frameNode->GetPattern<TabsPattern>();
961     CHECK_NULL_VOID(tabPattern);
962     tabPattern->SetIsDisableSwipe(!scrollable);
963 }
964 
SetTabBarWidth(FrameNode * frameNode,const Dimension & tabBarWidth)965 void TabsModelNG::SetTabBarWidth(FrameNode* frameNode, const Dimension& tabBarWidth)
966 {
967     ACE_UPDATE_NODE_LAYOUT_PROPERTY(TabsLayoutProperty, BarWidth, tabBarWidth, frameNode);
968     auto tabsNode = AceType::DynamicCast<TabsNode>(frameNode);
969     CHECK_NULL_VOID(tabsNode);
970     auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
971     CHECK_NULL_VOID(tabBarNode);
972     auto tabBarLayoutProperty = tabBarNode->GetLayoutProperty<TabBarLayoutProperty>();
973     CHECK_NULL_VOID(tabBarLayoutProperty);
974     auto scaleProperty = ScaleProperty::CreateScaleProperty();
975     auto tabBarWidthToPx =
976         ConvertToPx(tabBarWidth, scaleProperty, tabBarLayoutProperty->GetLayoutConstraint()->percentReference.Width());
977     if (LessNotEqual(tabBarWidthToPx.value_or(0.0), 0.0)) {
978         tabBarLayoutProperty->ClearUserDefinedIdealSize(true, false);
979     } else {
980         tabBarLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(NG::CalcLength(tabBarWidth), std::nullopt));
981     }
982     tabBarLayoutProperty->UpdateTabBarWidth(tabBarWidth);
983 }
984 
SetTabBarHeight(FrameNode * frameNode,const Dimension & tabBarHeight)985 void TabsModelNG::SetTabBarHeight(FrameNode* frameNode, const Dimension& tabBarHeight)
986 {
987     ACE_UPDATE_NODE_LAYOUT_PROPERTY(TabsLayoutProperty, BarHeight, tabBarHeight, frameNode);
988     auto tabsNode = AceType::DynamicCast<TabsNode>(frameNode);
989     CHECK_NULL_VOID(tabsNode);
990     auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
991     CHECK_NULL_VOID(tabBarNode);
992     auto tabBarLayoutProperty = tabBarNode->GetLayoutProperty<TabBarLayoutProperty>();
993     CHECK_NULL_VOID(tabBarLayoutProperty);
994     auto scaleProperty = ScaleProperty::CreateScaleProperty();
995     auto tabBarHeightToPx = ConvertToPx(
996         tabBarHeight, scaleProperty, tabBarLayoutProperty->GetLayoutConstraint()->percentReference.Height());
997     if (LessNotEqual(tabBarHeightToPx.value_or(0.0), 0.0)) {
998         tabBarLayoutProperty->ClearUserDefinedIdealSize(false, true);
999     } else {
1000         tabBarLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(std::nullopt, NG::CalcLength(tabBarHeight)));
1001     }
1002     tabBarLayoutProperty->UpdateTabBarHeight(tabBarHeight);
1003 }
1004 
SetAnimationCurve(FrameNode * frameNode,const RefPtr<Curve> & curve)1005 void TabsModelNG::SetAnimationCurve(FrameNode* frameNode, const RefPtr<Curve>& curve)
1006 {
1007     CHECK_NULL_VOID(frameNode);
1008     auto tabsNode = AceType::DynamicCast<TabsNode>(frameNode);
1009     CHECK_NULL_VOID(tabsNode);
1010     auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
1011     CHECK_NULL_VOID(tabBarNode);
1012     auto tabBarPattern = tabBarNode->GetPattern<TabBarPattern>();
1013     CHECK_NULL_VOID(tabBarPattern);
1014     tabBarPattern->SetAnimationCurve(curve);
1015     auto swiperPaintProperty = GetSwiperPaintProperty(frameNode);
1016     CHECK_NULL_VOID(swiperPaintProperty);
1017     swiperPaintProperty->UpdateCurve(tabBarPattern->GetAnimationCurve(TabBarPhysicalCurve));
1018 }
1019 
SetAnimationDuration(FrameNode * frameNode,float duration)1020 void TabsModelNG::SetAnimationDuration(FrameNode* frameNode, float duration)
1021 {
1022     CHECK_NULL_VOID(frameNode);
1023     auto tabsNode = AceType::DynamicCast<TabsNode>(frameNode);
1024     CHECK_NULL_VOID(tabsNode);
1025     auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
1026     CHECK_NULL_VOID(tabBarNode);
1027     auto tabBarPattern = tabBarNode->GetPattern<TabBarPattern>();
1028     CHECK_NULL_VOID(tabBarPattern);
1029     tabBarPattern->SetAnimationDuration(static_cast<int32_t>(duration));
1030     if (static_cast<int32_t>(duration) < 0) {
1031         return;
1032     }
1033     auto swiperPaintProperty = GetSwiperPaintProperty(frameNode);
1034     CHECK_NULL_VOID(swiperPaintProperty);
1035     swiperPaintProperty->UpdateDuration(static_cast<int32_t>(duration));
1036 }
1037 
SetScrollableBarModeOptions(FrameNode * frameNode,const ScrollableBarModeOptions & option)1038 void TabsModelNG::SetScrollableBarModeOptions(FrameNode* frameNode, const ScrollableBarModeOptions& option)
1039 {
1040     CHECK_NULL_VOID(frameNode);
1041     auto tabBarLayoutProperty = GetTabBarLayoutProperty(frameNode);
1042     CHECK_NULL_VOID(tabBarLayoutProperty);
1043     tabBarLayoutProperty->UpdateScrollableBarModeOptions(option);
1044 }
1045 
SetBarAdaptiveHeight(FrameNode * frameNode,bool barAdaptiveHeight)1046 void TabsModelNG::SetBarAdaptiveHeight(FrameNode* frameNode, bool barAdaptiveHeight)
1047 {
1048     CHECK_NULL_VOID(frameNode);
1049     auto tabBarLayoutProperty = GetTabBarLayoutProperty(frameNode);
1050     CHECK_NULL_VOID(tabBarLayoutProperty);
1051     tabBarLayoutProperty->UpdateBarAdaptiveHeight(barAdaptiveHeight);
1052 }
1053 
SetNoMinHeightLimit(FrameNode * frameNode,bool noMinHeightLimit)1054 void TabsModelNG::SetNoMinHeightLimit(FrameNode* frameNode, bool noMinHeightLimit)
1055 {
1056     CHECK_NULL_VOID(frameNode);
1057     auto tabBarLayoutProperty = GetTabBarLayoutProperty(frameNode);
1058     CHECK_NULL_VOID(tabBarLayoutProperty);
1059     tabBarLayoutProperty->UpdateNoMinHeightLimit(noMinHeightLimit);
1060 }
1061 
SetIsCustomAnimation(bool isCustom)1062 void TabsModelNG::SetIsCustomAnimation(bool isCustom)
1063 {
1064     auto swiperLayoutProperty = GetSwiperLayoutProperty();
1065     CHECK_NULL_VOID(swiperLayoutProperty);
1066     swiperLayoutProperty->UpdateIsCustomAnimation(isCustom);
1067     auto tabsNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
1068     CHECK_NULL_VOID(tabsNode);
1069     auto tabPattern = tabsNode->GetPattern<TabsPattern>();
1070     CHECK_NULL_VOID(tabPattern);
1071     tabPattern->SetIsCustomAnimation(isCustom);
1072 }
1073 
SetOnCustomAnimation(TabsCustomAnimationEvent && onCustomAnimation)1074 void TabsModelNG::SetOnCustomAnimation(TabsCustomAnimationEvent&& onCustomAnimation)
1075 {
1076     auto tabsNode = AceType::DynamicCast<TabsNode>(ViewStackProcessor::GetInstance()->GetMainFrameNode());
1077     CHECK_NULL_VOID(tabsNode);
1078     auto swiperNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabs());
1079     CHECK_NULL_VOID(swiperNode);
1080     auto swiperPattern = swiperNode->GetPattern<SwiperPattern>();
1081     CHECK_NULL_VOID(swiperPattern);
1082     swiperPattern->SetTabsCustomContentTransition(std::move(onCustomAnimation));
1083 }
1084 
SetClipEdge(FrameNode * frameNode,bool clipEdge)1085 void TabsModelNG::SetClipEdge(FrameNode* frameNode, bool clipEdge)
1086 {
1087     auto tabsNode = AceType::DynamicCast<TabsNode>(frameNode);
1088     CHECK_NULL_VOID(tabsNode);
1089     ViewAbstract::SetClipEdge(tabsNode, clipEdge);
1090     auto swiperNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabs());
1091     CHECK_NULL_VOID(swiperNode);
1092     auto swiperRenderContext = swiperNode->GetRenderContext();
1093     CHECK_NULL_VOID(swiperRenderContext);
1094     swiperRenderContext->UpdateClipEdge(clipEdge);
1095     auto dividerNode = AceType::DynamicCast<FrameNode>(tabsNode->GetDivider());
1096     CHECK_NULL_VOID(dividerNode);
1097     auto dividerRenderContext = dividerNode->GetRenderContext();
1098     CHECK_NULL_VOID(dividerRenderContext);
1099     dividerRenderContext->UpdateClipEdge(clipEdge);
1100 }
1101 
SetOnContentWillChange(std::function<bool (int32_t,int32_t)> && callback)1102 void TabsModelNG::SetOnContentWillChange(std::function<bool(int32_t, int32_t)>&& callback)
1103 {
1104     auto tabsNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
1105     CHECK_NULL_VOID(tabsNode);
1106     auto tabPattern = tabsNode->GetPattern<TabsPattern>();
1107     CHECK_NULL_VOID(tabPattern);
1108     tabPattern->SetInterceptStatus(true);
1109     tabPattern->SetOnContentWillChange(std::move(callback));
1110 }
1111 
SetAnimateMode(TabAnimateMode mode)1112 void TabsModelNG::SetAnimateMode(TabAnimateMode mode)
1113 {
1114     auto tabsNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
1115     CHECK_NULL_VOID(tabsNode);
1116     auto tabPattern = tabsNode->GetPattern<TabsPattern>();
1117     CHECK_NULL_VOID(tabPattern);
1118     tabPattern->SetAnimateMode(mode);
1119 }
1120 
SetAnimateMode(FrameNode * frameNode,TabAnimateMode mode)1121 void TabsModelNG::SetAnimateMode(FrameNode* frameNode, TabAnimateMode mode)
1122 {
1123     CHECK_NULL_VOID(frameNode);
1124     auto tabsNode = AceType::DynamicCast<TabsNode>(frameNode);
1125     CHECK_NULL_VOID(tabsNode);
1126     auto tabPattern = tabsNode->GetPattern<TabsPattern>();
1127     CHECK_NULL_VOID(tabPattern);
1128     tabPattern->SetAnimateMode(mode);
1129 }
1130 
SetEdgeEffect(EdgeEffect edgeEffect)1131 void TabsModelNG::SetEdgeEffect(EdgeEffect edgeEffect)
1132 {
1133     auto swiperPaintProperty = GetSwiperPaintProperty();
1134     CHECK_NULL_VOID(swiperPaintProperty);
1135     swiperPaintProperty->UpdateEdgeEffect(edgeEffect);
1136 }
1137 
SetEdgeEffect(FrameNode * frameNode,int32_t edgeEffect)1138 void TabsModelNG::SetEdgeEffect(FrameNode* frameNode, int32_t edgeEffect)
1139 {
1140     auto swiperPaintProperty = GetSwiperPaintProperty(frameNode);
1141     CHECK_NULL_VOID(swiperPaintProperty);
1142     swiperPaintProperty->UpdateEdgeEffect(static_cast<EdgeEffect>(edgeEffect));
1143 }
1144 
SetTabBarIndex(FrameNode * frameNode,int32_t index)1145 void TabsModelNG::SetTabBarIndex(FrameNode* frameNode, int32_t index)
1146 {
1147     CHECK_NULL_VOID(frameNode);
1148     auto tabsNode = AceType::DynamicCast<TabsNode>(frameNode);
1149     CHECK_NULL_VOID(tabsNode);
1150     auto tabsLayoutProperty = tabsNode->GetLayoutProperty<TabsLayoutProperty>();
1151     CHECK_NULL_VOID(tabsLayoutProperty);
1152     if (tabsLayoutProperty->GetIndex().has_value()) {
1153         auto preIndex = tabsLayoutProperty->GetIndex().value();
1154         if (preIndex == index || index < 0) {
1155             return;
1156         }
1157     }
1158     tabsLayoutProperty->UpdateIndexSetByUser(index);
1159 }
1160 
SetTabsController(FrameNode * frameNode,const RefPtr<SwiperController> & tabsController)1161 void TabsModelNG::SetTabsController(FrameNode* frameNode, const RefPtr<SwiperController>& tabsController)
1162 {
1163     CHECK_NULL_VOID(frameNode);
1164     auto nodeId = frameNode->GetId();
1165     auto tabsNode = GetOrCreateTabsNode(V2::TABS_ETS_TAG, nodeId, []() { return AceType::MakeRefPtr<TabsPattern>(); });
1166     CHECK_NULL_VOID(tabsNode);
1167     InitTabsNode(tabsNode, tabsController);
1168 }
1169 
SetBarModifier(FrameNode * frameNode,std::function<void (WeakPtr<NG::FrameNode>)> && onApply)1170 void TabsModelNG::SetBarModifier(FrameNode* frameNode, std::function<void(WeakPtr<NG::FrameNode>)>&& onApply)
1171 {
1172     CHECK_NULL_VOID(onApply);
1173     CHECK_NULL_VOID(frameNode);
1174     auto tabsNode = AceType::DynamicCast<TabsNode>(frameNode);
1175     CHECK_NULL_VOID(tabsNode);
1176     auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
1177     CHECK_NULL_VOID(tabBarNode);
1178     onApply(tabBarNode);
1179 }
1180 
SetBarBackgroundEffect(const EffectOption & effectOption)1181 void TabsModelNG::SetBarBackgroundEffect(const EffectOption& effectOption)
1182 {
1183     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
1184     CHECK_NULL_VOID(frameNode);
1185     SetBarBackgroundEffect(frameNode, effectOption);
1186 }
1187 
SetBarBackgroundEffect(FrameNode * frameNode,const EffectOption & effectOption)1188 void TabsModelNG::SetBarBackgroundEffect(FrameNode* frameNode, const EffectOption& effectOption)
1189 {
1190     CHECK_NULL_VOID(frameNode);
1191     auto tabsNode = AceType::DynamicCast<TabsNode>(frameNode);
1192     CHECK_NULL_VOID(tabsNode);
1193     auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
1194     CHECK_NULL_VOID(tabBarNode);
1195     auto pipeline = tabBarNode->GetContext();
1196     CHECK_NULL_VOID(pipeline);
1197     if (effectOption.policy == BlurStyleActivePolicy::FOLLOWS_WINDOW_ACTIVE_STATE) {
1198         pipeline->AddWindowFocusChangedCallback(tabBarNode->GetId());
1199     } else {
1200         pipeline->RemoveWindowFocusChangedCallback(tabBarNode->GetId());
1201     }
1202     auto target = tabBarNode->GetRenderContext();
1203     if (target) {
1204         if (target->GetBackBlurRadius().has_value()) {
1205             target->UpdateBackBlurRadius(Dimension());
1206         }
1207         if (target->GetBackBlurStyle().has_value()) {
1208             target->UpdateBackBlurStyle(std::nullopt);
1209         }
1210         target->UpdateBackgroundEffect(effectOption);
1211     }
1212 }
1213 
SetPageFlipMode(int32_t pageFlipMode)1214 void TabsModelNG::SetPageFlipMode(int32_t pageFlipMode)
1215 {
1216     auto tabsNode = AceType::DynamicCast<TabsNode>(ViewStackProcessor::GetInstance()->GetMainFrameNode());
1217     CHECK_NULL_VOID(tabsNode);
1218     auto swiperNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabs());
1219     CHECK_NULL_VOID(swiperNode);
1220     auto swiperPattern = swiperNode->GetPattern<SwiperPattern>();
1221     CHECK_NULL_VOID(swiperPattern);
1222     swiperPattern->SetPageFlipMode(pageFlipMode);
1223 }
1224 
SetPageFlipMode(FrameNode * frameNode,int32_t options)1225 void TabsModelNG::SetPageFlipMode(FrameNode* frameNode, int32_t options)
1226 {
1227     CHECK_NULL_VOID(frameNode);
1228     auto tabsNode = AceType::DynamicCast<TabsNode>(frameNode);
1229     CHECK_NULL_VOID(tabsNode);
1230     auto swiperNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabs());
1231     CHECK_NULL_VOID(swiperNode);
1232     auto swiperPattern = swiperNode->GetPattern<SwiperPattern>();
1233     CHECK_NULL_VOID(swiperPattern);
1234     swiperPattern->SetPageFlipMode(options);
1235 }
1236 
SetCachedMaxCount(std::optional<int32_t> cachedMaxCount,TabsCacheMode cacheMode)1237 void TabsModelNG::SetCachedMaxCount(std::optional<int32_t> cachedMaxCount, TabsCacheMode cacheMode)
1238 {
1239     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
1240     CHECK_NULL_VOID(frameNode);
1241     SetCachedMaxCount(frameNode, cachedMaxCount, cacheMode);
1242 }
1243 
SetCachedMaxCount(FrameNode * frameNode,std::optional<int32_t> cachedMaxCount,TabsCacheMode cacheMode)1244 void TabsModelNG::SetCachedMaxCount(
1245     FrameNode* frameNode, std::optional<int32_t> cachedMaxCount, TabsCacheMode cacheMode)
1246 {
1247     CHECK_NULL_VOID(frameNode);
1248     if (cachedMaxCount.has_value()) {
1249         ACE_UPDATE_NODE_LAYOUT_PROPERTY(TabsLayoutProperty, CachedMaxCount, cachedMaxCount.value(), frameNode);
1250         ACE_UPDATE_NODE_LAYOUT_PROPERTY(TabsLayoutProperty, CacheMode, cacheMode, frameNode);
1251     } else {
1252         ACE_RESET_NODE_LAYOUT_PROPERTY(TabsLayoutProperty, CachedMaxCount, frameNode);
1253         ACE_RESET_NODE_LAYOUT_PROPERTY(TabsLayoutProperty, CacheMode, frameNode);
1254     }
1255 }
1256 
SetOnChange(FrameNode * frameNode,std::function<void (const BaseEventInfo *)> && onChange)1257 void TabsModelNG::SetOnChange(FrameNode* frameNode, std::function<void(const BaseEventInfo*)>&& onChange)
1258 {
1259     CHECK_NULL_VOID(frameNode);
1260     auto tabsNode = AceType::DynamicCast<TabsNode>(frameNode);
1261     CHECK_NULL_VOID(tabsNode);
1262     auto tabPattern = tabsNode->GetPattern<TabsPattern>();
1263     CHECK_NULL_VOID(tabPattern);
1264     tabPattern->SetOnChangeEvent(std::move(onChange));
1265 }
SetOnTabBarClick(FrameNode * frameNode,std::function<void (const BaseEventInfo *)> && onTabBarClick)1266 void TabsModelNG::SetOnTabBarClick(FrameNode* frameNode, std::function<void(const BaseEventInfo*)>&& onTabBarClick)
1267 {
1268     CHECK_NULL_VOID(frameNode);
1269     auto tabsNode = AceType::DynamicCast<TabsNode>(frameNode);
1270     CHECK_NULL_VOID(tabsNode);
1271     auto tabPattern = tabsNode->GetPattern<TabsPattern>();
1272     CHECK_NULL_VOID(tabPattern);
1273     tabPattern->SetOnTabBarClickEvent(std::move(onTabBarClick));
1274 }
SetOnAnimationStart(FrameNode * frameNode,AnimationStartEvent && onAnimationStart)1275 void TabsModelNG::SetOnAnimationStart(FrameNode* frameNode, AnimationStartEvent&& onAnimationStart)
1276 {
1277     CHECK_NULL_VOID(frameNode);
1278     auto tabsNode = AceType::DynamicCast<TabsNode>(frameNode);
1279     CHECK_NULL_VOID(tabsNode);
1280     auto tabPattern = tabsNode->GetPattern<TabsPattern>();
1281     CHECK_NULL_VOID(tabPattern);
1282     tabPattern->SetAnimationStartEvent(std::move(onAnimationStart));
1283 }
SetOnAnimationEnd(FrameNode * frameNode,AnimationEndEvent && onAnimationEnd)1284 void TabsModelNG::SetOnAnimationEnd(FrameNode* frameNode, AnimationEndEvent&& onAnimationEnd)
1285 {
1286     CHECK_NULL_VOID(frameNode);
1287     auto tabsNode = AceType::DynamicCast<TabsNode>(frameNode);
1288     CHECK_NULL_VOID(tabsNode);
1289     auto tabPattern = tabsNode->GetPattern<TabsPattern>();
1290     CHECK_NULL_VOID(tabPattern);
1291     tabPattern->SetAnimationEndEvent(std::move(onAnimationEnd));
1292 }
SetOnGestureSwipe(FrameNode * frameNode,GestureSwipeEvent && gestureSwipe)1293 void TabsModelNG::SetOnGestureSwipe(FrameNode* frameNode, GestureSwipeEvent&& gestureSwipe)
1294 {
1295     CHECK_NULL_VOID(frameNode);
1296     auto tabsNode = AceType::DynamicCast<TabsNode>(frameNode);
1297     CHECK_NULL_VOID(tabsNode);
1298     auto swiperNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabs());
1299     CHECK_NULL_VOID(swiperNode);
1300     auto eventHub = swiperNode->GetOrCreateEventHub<SwiperEventHub>();
1301     CHECK_NULL_VOID(eventHub);
1302     eventHub->SetGestureSwipeEvent(std::move(gestureSwipe));
1303 }
SetIsCustomAnimation(FrameNode * frameNode,bool isCustom)1304 void TabsModelNG::SetIsCustomAnimation(FrameNode* frameNode, bool isCustom)
1305 {
1306     CHECK_NULL_VOID(frameNode);
1307     auto swiperLayoutProperty = GetSwiperLayoutProperty();
1308     CHECK_NULL_VOID(swiperLayoutProperty);
1309     swiperLayoutProperty->UpdateIsCustomAnimation(isCustom);
1310     auto tabsNode = AceType::DynamicCast<TabsNode>(frameNode);
1311     CHECK_NULL_VOID(tabsNode);
1312     auto tabPattern = tabsNode->GetPattern<TabsPattern>();
1313     CHECK_NULL_VOID(tabPattern);
1314     tabPattern->SetIsCustomAnimation(isCustom);
1315 }
SetOnContentWillChange(FrameNode * frameNode,std::function<bool (int32_t,int32_t)> && callback)1316 void TabsModelNG::SetOnContentWillChange(
1317     FrameNode* frameNode, std::function<bool(int32_t, int32_t)>&& callback)
1318 {
1319     CHECK_NULL_VOID(frameNode);
1320     auto tabsNode = AceType::DynamicCast<TabsNode>(frameNode);
1321     CHECK_NULL_VOID(tabsNode);
1322     auto tabPattern = tabsNode->GetPattern<TabsPattern>();
1323     CHECK_NULL_VOID(tabPattern);
1324     tabPattern->SetInterceptStatus(true);
1325     tabPattern->SetOnContentWillChange(std::move(callback));
1326 }
CreateWithResourceObj(TabJsResType jsResourceType,const RefPtr<ResourceObject> & resObj)1327 void TabsModelNG::CreateWithResourceObj(TabJsResType jsResourceType, const RefPtr<ResourceObject>& resObj)
1328 {
1329     CHECK_NULL_VOID(SystemProperties::ConfigChangePerform());
1330     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
1331     CHECK_NULL_VOID(frameNode);
1332     if (SystemProperties::ConfigChangePerform()) {
1333         auto pattern = frameNode->GetPattern<TabsPattern>();
1334         CHECK_NULL_VOID(pattern);
1335         std::string key = "tabs." + std::to_string(static_cast<int32_t>(jsResourceType));
1336         pattern->RemoveResObj(key);
1337     }
1338     switch (jsResourceType) {
1339         case TabJsResType::BAR_BACKGROUND_COLOR:
1340             HandleBarBackgroundColor(frameNode, resObj);
1341             break;
1342         case TabJsResType::BAR_WIDTH:
1343             HandleBarWidth(frameNode, resObj);
1344             break;
1345         case TabJsResType::BAR_HEIGHT:
1346             HandleBarHeight(frameNode, resObj);
1347             break;
1348         case TabJsResType::BAR_GRID_GUTTER:
1349             HandleBarGridGutter(frameNode, resObj);
1350             break;
1351         case TabJsResType::BAR_GRID_MARGIN:
1352             HandleBarGridMargin(frameNode, resObj);
1353             break;
1354         case TabJsResType::DIVIDER_STROKE_WIDTH:
1355             HandleDividerStrokeWidth(frameNode, resObj);
1356             break;
1357         case TabJsResType::DIVIDER_COLOR:
1358             HandleDividerColor(frameNode, resObj);
1359             break;
1360         case TabJsResType::DIVIDER_START_MARGIN:
1361             HandleDividerStartMargin(frameNode, resObj);
1362             break;
1363         case TabJsResType::DIVIDER_END_MARGIN:
1364             HandleDividerEndMargin(frameNode, resObj);
1365             break;
1366         case TabJsResType::SCROLLABLE_BAR_MARGIN:
1367             HandleScrollableBarMargin(frameNode, resObj);
1368             break;
1369         case TabJsResType::COLOR:
1370             HandleBackgroundEffectColor(frameNode, resObj);
1371             break;
1372         case TabJsResType::INACTIVE_COLOR:
1373             HandleBackgroundEffectInactiveColor(frameNode, resObj);
1374             break;
1375         case TabJsResType::BlurStyle_INACTIVE_COLOR:
1376             HandleBackgroundBlurStyleInactiveColor(frameNode, resObj);
1377             break;
1378         default:
1379             break;
1380     }
1381 }
1382 
HandleBarBackgroundColor(FrameNode * frameNode,const RefPtr<ResourceObject> & resObj,bool isModifier)1383 void TabsModelNG::HandleBarBackgroundColor(FrameNode* frameNode, const RefPtr<ResourceObject>& resObj,
1384     bool isModifier)
1385 {
1386     CHECK_NULL_VOID(frameNode);
1387     auto pattern = frameNode->GetPattern<TabsPattern>();
1388     CHECK_NULL_VOID(pattern);
1389     const std::string key = "tabsBarBackgroundColor";
1390     pattern->RemoveResObj(key);
1391     CHECK_NULL_VOID(resObj);
1392     auto&& updateFunc = [weak = AceType::WeakClaim(frameNode)](const RefPtr<ResourceObject>& resObj) {
1393         auto node = weak.Upgrade();
1394         CHECK_NULL_VOID(node);
1395         Color result = Color::BLACK.BlendOpacity(0.0f);
1396         ResourceParseUtils::ParseResColor(resObj, result);
1397         TabsModelNG::SetBarBackgroundColor(AceType::RawPtr(node), result);
1398     };
1399     pattern->AddResObj(key, resObj, std::move(updateFunc));
1400 }
1401 
HandleBarWidth(FrameNode * frameNode,const RefPtr<ResourceObject> & resObj,bool isModifier)1402 void TabsModelNG::HandleBarWidth(FrameNode* frameNode, const RefPtr<ResourceObject>& resObj,
1403     bool isModifier)
1404 {
1405     CHECK_NULL_VOID(frameNode);
1406     auto pattern = frameNode->GetPattern<TabsPattern>();
1407     CHECK_NULL_VOID(pattern);
1408     const std::string key = "tabsBarWidth";
1409     pattern->RemoveResObj(key);
1410     CHECK_NULL_VOID(resObj);
1411     auto&& updateFunc = [weak = AceType::WeakClaim(frameNode)](const RefPtr<ResourceObject>& resObj) {
1412         auto tabsNode = AceType::DynamicCast<TabsNode>(weak.Upgrade());
1413         CHECK_NULL_VOID(tabsNode);
1414         auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
1415         CHECK_NULL_VOID(tabBarNode);
1416         CalcDimension result = Dimension(-1.0, DimensionUnit::VP);
1417         ResourceParseUtils::ParseResDimensionVpNG(resObj, result);
1418         TabsModelNG::SetTabBarWidth(AceType::RawPtr(tabsNode), result);
1419     };
1420     pattern->AddResObj(key, resObj, std::move(updateFunc));
1421 }
1422 
HandleBarHeight(FrameNode * frameNode,const RefPtr<ResourceObject> & resObj,bool isModifier)1423 void TabsModelNG::HandleBarHeight(FrameNode* frameNode, const RefPtr<ResourceObject>& resObj,
1424     bool isModifier)
1425 {
1426     CHECK_NULL_VOID(frameNode);
1427     auto pattern = frameNode->GetPattern<TabsPattern>();
1428     CHECK_NULL_VOID(pattern);
1429     const std::string key = "tabsBarHeight";
1430     pattern->RemoveResObj(key);
1431     CHECK_NULL_VOID(resObj);
1432     auto&& updateFunc = [weak = AceType::WeakClaim(frameNode)](const RefPtr<ResourceObject>& resObj) {
1433         auto tabsNode = AceType::DynamicCast<TabsNode>(weak.Upgrade());
1434         CHECK_NULL_VOID(tabsNode);
1435         auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
1436         CHECK_NULL_VOID(tabBarNode);
1437         CalcDimension result = Dimension(-1.0, DimensionUnit::VP);
1438         ResourceParseUtils::ParseResDimensionVpNG(resObj, result);
1439         TabsModelNG::SetTabBarHeight(AceType::RawPtr(tabsNode), result);
1440     };
1441     pattern->AddResObj(key, resObj, std::move(updateFunc));
1442 }
1443 
HandleBarGridGutter(FrameNode * frameNode,const RefPtr<ResourceObject> & resObj,bool isModifier)1444 void TabsModelNG::HandleBarGridGutter(FrameNode* frameNode, const RefPtr<ResourceObject>& resObj,
1445     bool isModifier)
1446 {
1447     CHECK_NULL_VOID(frameNode);
1448     auto pattern = frameNode->GetPattern<TabsPattern>();
1449     CHECK_NULL_VOID(pattern);
1450     const std::string key = "tabsBarGridGutter";
1451     pattern->RemoveResObj(key);
1452     CHECK_NULL_VOID(resObj);
1453     auto&& updateFunc = [weak = AceType::WeakClaim(frameNode)](const RefPtr<ResourceObject>& resObj) {
1454         auto tabsNode = AceType::DynamicCast<TabsNode>(weak.Upgrade());
1455         CHECK_NULL_VOID(tabsNode);
1456         auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
1457         CHECK_NULL_VOID(tabBarNode);
1458         CalcDimension result;
1459         BarGridColumnOptions tempUsed;
1460         if (ResourceParseUtils::ParseResDimensionVp(resObj, result) && NonNegative(result.Value()) &&
1461             result.Unit() != DimensionUnit::PERCENT) {
1462             tempUsed.gutter = result;
1463         }
1464         BarGridColumnOptions columnOption;
1465         ACE_GET_NODE_LAYOUT_PROPERTY(TabBarLayoutProperty, BarGridAlign, columnOption, tabBarNode);
1466         columnOption.gutter = tempUsed.gutter;
1467         ACE_UPDATE_NODE_LAYOUT_PROPERTY(TabBarLayoutProperty, BarGridAlign, columnOption, tabBarNode);
1468     };
1469     pattern->AddResObj(key, resObj, std::move(updateFunc));
1470 }
1471 
HandleBarGridMargin(FrameNode * frameNode,const RefPtr<ResourceObject> & resObj,bool isModifier)1472 void TabsModelNG::HandleBarGridMargin(FrameNode* frameNode, const RefPtr<ResourceObject>& resObj,
1473     bool isModifier)
1474 {
1475     CHECK_NULL_VOID(frameNode);
1476     auto pattern = frameNode->GetPattern<TabsPattern>();
1477     CHECK_NULL_VOID(pattern);
1478     const std::string key = "tabsBarGridMargin";
1479     pattern->RemoveResObj(key);
1480     CHECK_NULL_VOID(resObj);
1481     auto&& updateFunc = [weak = AceType::WeakClaim(frameNode)](const RefPtr<ResourceObject>& resObj) {
1482         auto tabsNode = AceType::DynamicCast<TabsNode>(weak.Upgrade());
1483         CHECK_NULL_VOID(tabsNode);
1484         auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
1485         CHECK_NULL_VOID(tabBarNode);
1486         CalcDimension result;
1487         BarGridColumnOptions tempUsed;
1488         if (ResourceParseUtils::ParseResDimensionVp(resObj, result) && NonNegative(result.Value()) &&
1489             result.Unit() != DimensionUnit::PERCENT) {
1490             tempUsed.margin = result;
1491         }
1492         BarGridColumnOptions columnOption;
1493         ACE_GET_NODE_LAYOUT_PROPERTY(TabBarLayoutProperty, BarGridAlign, columnOption, tabBarNode);
1494         columnOption.margin = tempUsed.margin;
1495         ACE_UPDATE_NODE_LAYOUT_PROPERTY(TabBarLayoutProperty, BarGridAlign, columnOption, tabBarNode);
1496     };
1497     pattern->AddResObj(key, resObj, std::move(updateFunc));
1498 }
1499 
HandleDividerStrokeWidth(FrameNode * frameNode,const RefPtr<ResourceObject> & resObj,bool isModifier)1500 void TabsModelNG::HandleDividerStrokeWidth(FrameNode* frameNode, const RefPtr<ResourceObject>& resObj,
1501     bool isModifier)
1502 {
1503     CHECK_NULL_VOID(frameNode);
1504     auto pattern = frameNode->GetPattern<TabsPattern>();
1505     CHECK_NULL_VOID(pattern);
1506     const std::string key = "tabsDividerStrokeWidth";
1507     pattern->RemoveResObj(key);
1508     CHECK_NULL_VOID(resObj);
1509     auto &&updateFunc = [weak = AceType::WeakClaim(frameNode),
1510                             weakPattern = AceType::WeakClaim(AceType::RawPtr(pattern))](
1511                             const RefPtr<ResourceObject> &resObj) {
1512         auto node = weak.Upgrade();
1513         CHECK_NULL_VOID(node);
1514         auto tabsPattern = weakPattern.Upgrade();
1515         CHECK_NULL_VOID(tabsPattern);
1516         CalcDimension result;
1517         TabsItemDivider divider;
1518         ACE_GET_NODE_LAYOUT_PROPERTY(TabsLayoutProperty, Divider, divider, node);
1519         ResourceParseUtils::ParseResDimensionVp(resObj, result);
1520         if (result.Value() < 0.0f || result.Unit() == DimensionUnit::PERCENT) {
1521             divider.strokeWidth.Reset();
1522         } else {
1523             divider.strokeWidth = result;
1524         }
1525         TabsModelNG::SetDivider(AceType::RawPtr(node), divider);
1526         tabsPattern->UpdateDividerStrokeWidth();
1527     };
1528     pattern->AddResObj(key, resObj, std::move(updateFunc));
1529 }
1530 
HandleDividerColor(FrameNode * frameNode,const RefPtr<ResourceObject> & resObj,bool isModifier)1531 void TabsModelNG::HandleDividerColor(FrameNode* frameNode, const RefPtr<ResourceObject>& resObj,
1532     bool isModifier)
1533 {
1534     CHECK_NULL_VOID(frameNode);
1535     auto pattern = frameNode->GetPattern<TabsPattern>();
1536     CHECK_NULL_VOID(pattern);
1537     const std::string key = "tabsDividerColor";
1538     pattern->RemoveResObj(key);
1539     CHECK_NULL_VOID(resObj);
1540     auto &&updateFunc = [weak = AceType::WeakClaim(frameNode),
1541                             weakPattern = AceType::WeakClaim(AceType::RawPtr(pattern))](
1542                             const RefPtr<ResourceObject> &resObj) {
1543         auto node = weak.Upgrade();
1544         CHECK_NULL_VOID(node);
1545         auto tabsPattern = weakPattern.Upgrade();
1546         CHECK_NULL_VOID(tabsPattern);
1547         Color result;
1548         TabsItemDivider divider;
1549         ACE_GET_NODE_LAYOUT_PROPERTY(TabsLayoutProperty, Divider, divider, node);
1550         if (ResourceParseUtils::ParseResColor(resObj, result)) {
1551             divider.color = result;
1552             TabsModelNG::SetDividerColorByUser(AceType::RawPtr(node), true);
1553         } else {
1554             auto pipelineContext = PipelineContext::GetCurrentContextSafelyWithCheck();
1555             CHECK_NULL_VOID(pipelineContext);
1556             auto tabTheme = pipelineContext->GetTheme<TabTheme>();
1557             CHECK_NULL_VOID(tabTheme);
1558             divider.color = tabTheme->GetDividerColor();
1559             TabsModelNG::SetDividerColorByUser(AceType::RawPtr(node), false);
1560         }
1561         TabsModelNG::SetDivider(AceType::RawPtr(node), divider);
1562         tabsPattern->UpdateDividerColor();
1563     };
1564     pattern->AddResObj(key, resObj, std::move(updateFunc));
1565 }
1566 
HandleDividerStartMargin(FrameNode * frameNode,const RefPtr<ResourceObject> & resObj,bool isModifier)1567 void TabsModelNG::HandleDividerStartMargin(FrameNode* frameNode, const RefPtr<ResourceObject>& resObj,
1568     bool isModifier)
1569 {
1570     CHECK_NULL_VOID(frameNode);
1571     auto pattern = frameNode->GetPattern<TabsPattern>();
1572     CHECK_NULL_VOID(pattern);
1573     const std::string key = "tabsDividerStartMargin";
1574     pattern->RemoveResObj(key);
1575     CHECK_NULL_VOID(resObj);
1576     auto&& updateFunc = [weak = AceType::WeakClaim(frameNode)](const RefPtr<ResourceObject>& resObj) {
1577         auto node = weak.Upgrade();
1578         CHECK_NULL_VOID(node);
1579         CalcDimension result;
1580         TabsItemDivider divider;
1581         ACE_GET_NODE_LAYOUT_PROPERTY(TabsLayoutProperty, Divider, divider, node);
1582         ResourceParseUtils::ParseResDimensionVp(resObj, result);
1583         if (result.Value() < 0.0f || result.Unit() == DimensionUnit::PERCENT) {
1584             divider.startMargin.Reset();
1585         } else {
1586             divider.startMargin = result;
1587         }
1588         TabsModelNG::SetDivider(AceType::RawPtr(node), divider);
1589     };
1590     pattern->AddResObj(key, resObj, std::move(updateFunc));
1591 }
1592 
HandleDividerEndMargin(FrameNode * frameNode,const RefPtr<ResourceObject> & resObj,bool isModifier)1593 void TabsModelNG::HandleDividerEndMargin(FrameNode* frameNode, const RefPtr<ResourceObject>& resObj,
1594     bool isModifier)
1595 {
1596     CHECK_NULL_VOID(frameNode);
1597     auto pattern = frameNode->GetPattern<TabsPattern>();
1598     CHECK_NULL_VOID(pattern);
1599     const std::string key = "tabsDividerEndMargin";
1600     pattern->RemoveResObj(key);
1601     CHECK_NULL_VOID(resObj);
1602     auto&& updateFunc = [weak = AceType::WeakClaim(frameNode)](const RefPtr<ResourceObject>& resObj) {
1603         auto node = weak.Upgrade();
1604         CHECK_NULL_VOID(node);
1605         CalcDimension result;
1606         TabsItemDivider divider;
1607         ACE_GET_NODE_LAYOUT_PROPERTY(TabsLayoutProperty, Divider, divider, node);
1608         ResourceParseUtils::ParseResDimensionVp(resObj, result);
1609         if (result.Value() < 0.0f || result.Unit() == DimensionUnit::PERCENT) {
1610             divider.endMargin.Reset();
1611         } else {
1612             divider.endMargin = result;
1613         }
1614         TabsModelNG::SetDivider(AceType::RawPtr(node), divider);
1615     };
1616     pattern->AddResObj(key, resObj, std::move(updateFunc));
1617 }
1618 
HandleScrollableBarMargin(FrameNode * frameNode,const RefPtr<ResourceObject> & resObj,bool isModifier)1619 void TabsModelNG::HandleScrollableBarMargin(FrameNode* frameNode, const RefPtr<ResourceObject>& resObj,
1620     bool isModifier)
1621 {
1622     CHECK_NULL_VOID(frameNode);
1623     auto pattern = frameNode->GetPattern<TabsPattern>();
1624     CHECK_NULL_VOID(pattern);
1625     const std::string key = "tabsScrollableBarMargin";
1626     pattern->RemoveResObj(key);
1627     CHECK_NULL_VOID(resObj);
1628     auto&& updateFunc = [weak = AceType::WeakClaim(frameNode)](const RefPtr<ResourceObject>& resObj) {
1629         auto tabsNode = AceType::DynamicCast<TabsNode>(weak.Upgrade());
1630         CHECK_NULL_VOID(tabsNode);
1631         auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
1632         CHECK_NULL_VOID(tabBarNode);
1633         CalcDimension result;
1634         ScrollableBarModeOptions option;
1635         ACE_GET_NODE_LAYOUT_PROPERTY(TabBarLayoutProperty, ScrollableBarModeOptions, option, tabBarNode);
1636         if (!ResourceParseUtils::ParseResDimensionVp(resObj, result) || Negative(result.Value()) ||
1637             result.Unit() == DimensionUnit::PERCENT) {
1638             option.margin = 0.0_vp;
1639         } else {
1640             option.margin = result;
1641         }
1642         ACE_UPDATE_NODE_LAYOUT_PROPERTY(TabBarLayoutProperty, ScrollableBarModeOptions, option, tabBarNode);
1643     };
1644     pattern->AddResObj(key, resObj, std::move(updateFunc));
1645 }
1646 
HandleBackgroundEffectColor(FrameNode * frameNode,const RefPtr<ResourceObject> & resObj,bool isModifier)1647 void TabsModelNG::HandleBackgroundEffectColor(FrameNode* frameNode, const RefPtr<ResourceObject>& resObj,
1648     bool isModifier)
1649 {
1650     CHECK_NULL_VOID(frameNode);
1651     auto pattern = frameNode->GetPattern<TabsPattern>();
1652     CHECK_NULL_VOID(pattern);
1653     const std::string key = "tabsBackGroundEffectColor";
1654     pattern->RemoveResObj(key);
1655     CHECK_NULL_VOID(resObj);
1656     auto&& updateFunc = [weak = AceType::WeakClaim(frameNode),
1657                                         weakPattern = AceType::WeakClaim(AceType::RawPtr(pattern))](
1658                                         const RefPtr<ResourceObject>& resObj) {
1659         auto tabsNode = AceType::DynamicCast<TabsNode>(weak.Upgrade());
1660         CHECK_NULL_VOID(tabsNode);
1661         auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
1662         CHECK_NULL_VOID(tabBarNode);
1663         auto target = tabBarNode->GetRenderContext();
1664         CHECK_NULL_VOID(target);
1665         EffectOption option = target->GetBackgroundEffect().value_or(EffectOption{});
1666         option.isWindowFocused = true; // set to default value
1667         Color result = Color::TRANSPARENT;
1668         ResourceParseUtils::ParseResColor(resObj, result);
1669         option.color = result;
1670         TabsModelNG::SetBarBackgroundEffect(AceType::RawPtr(tabsNode), option);
1671     };
1672     pattern->AddResObj(key, resObj, std::move(updateFunc));
1673 }
1674 
HandleBackgroundEffectInactiveColor(FrameNode * frameNode,const RefPtr<ResourceObject> & resObj,bool isModifier)1675 void TabsModelNG::HandleBackgroundEffectInactiveColor(FrameNode* frameNode, const RefPtr<ResourceObject>& resObj,
1676     bool isModifier)
1677 {
1678     CHECK_NULL_VOID(frameNode);
1679     auto pattern = frameNode->GetPattern<TabsPattern>();
1680     CHECK_NULL_VOID(pattern);
1681     const std::string key = "tabsBackGroundEffectInactiveColor";
1682     pattern->RemoveResObj(key);
1683     auto&& updateFunc = [weak = AceType::WeakClaim(frameNode), resObj](const RefPtr<ResourceObject>& dummyResObj) {
1684         auto tabsNode = AceType::DynamicCast<TabsNode>(weak.Upgrade());
1685         CHECK_NULL_VOID(tabsNode);
1686         auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
1687         CHECK_NULL_VOID(tabBarNode);
1688         auto target = tabBarNode->GetRenderContext();
1689         CHECK_NULL_VOID(target);
1690         EffectOption option = target->GetBackgroundEffect().value_or(EffectOption{});
1691         option.isWindowFocused = true; // set to default value
1692         if (!resObj) {
1693             TabsModelNG::SetBarBackgroundEffect(AceType::RawPtr(tabsNode), option);
1694             return;
1695         }
1696         Color result = Color::TRANSPARENT;
1697         option.isValidColor = ResourceParseUtils::ParseResColor(resObj, result);
1698         option.inactiveColor = result;
1699         TabsModelNG::SetBarBackgroundEffect(AceType::RawPtr(tabsNode), option);
1700     };
1701     RefPtr<ResourceObject> dummyResObj = AceType::MakeRefPtr<ResourceObject>("", "", -1);
1702     pattern->AddResObj(key, dummyResObj, std::move(updateFunc));
1703 }
1704 
HandleBackgroundBlurStyleInactiveColor(FrameNode * frameNode,const RefPtr<ResourceObject> & resObj,bool isModifier)1705 void TabsModelNG::HandleBackgroundBlurStyleInactiveColor(FrameNode* frameNode, const RefPtr<ResourceObject>& resObj,
1706     bool isModifier)
1707 {
1708     CHECK_NULL_VOID(frameNode);
1709     auto pattern = frameNode->GetPattern<TabsPattern>();
1710     CHECK_NULL_VOID(pattern);
1711     const std::string key = "tabsBackGroundBlurStyle";
1712     pattern->RemoveResObj(key);
1713     auto&& updateFunc = [weak = AceType::WeakClaim(frameNode), resObj](const RefPtr<ResourceObject>& dummyResObj) {
1714         auto tabsNode = AceType::DynamicCast<TabsNode>(weak.Upgrade());
1715         CHECK_NULL_VOID(tabsNode);
1716         auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
1717         CHECK_NULL_VOID(tabBarNode);
1718         auto target = tabBarNode->GetRenderContext();
1719         CHECK_NULL_VOID(target);
1720         BlurStyleOption styleOption = target->GetBackBlurStyle().value_or(BlurStyleOption{});
1721         styleOption.isWindowFocused = true; // set to default value
1722         if (!resObj) {
1723             TabsModelNG::SetBarBackgroundBlurStyle(AceType::RawPtr(tabsNode), styleOption);
1724             return;
1725         }
1726         Color result = Color::TRANSPARENT;
1727         styleOption.isValidColor = ResourceParseUtils::ParseResColor(resObj, result);
1728         styleOption.inactiveColor = result;
1729         TabsModelNG::SetBarBackgroundBlurStyle(AceType::RawPtr(tabsNode), styleOption);
1730     };
1731     RefPtr<ResourceObject> dummyResObj = AceType::MakeRefPtr<ResourceObject>("", "", -1);
1732     pattern->AddResObj(key, dummyResObj, std::move(updateFunc));
1733 }
1734 } // namespace OHOS::Ace::NG
1735