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