1 /*
2 * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "core/components_ng/pattern/tabs/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/swiper/swiper_layout_property.h"
36 #include "core/components_ng/pattern/swiper/swiper_paint_property.h"
37 #include "core/components_ng/pattern/swiper/swiper_pattern.h"
38 #include "core/components_ng/pattern/tabs/tab_bar_paint_property.h"
39 #include "core/components_ng/pattern/tabs/tab_bar_pattern.h"
40 #include "core/components_ng/pattern/tabs/tabs_controller.h"
41 #include "core/components_ng/pattern/tabs/tabs_node.h"
42 #include "core/components_ng/pattern/tabs/tabs_pattern.h"
43 #include "core/components_ng/pattern/text/text_pattern.h"
44 #include "core/components_ng/property/measure_utils.h"
45 #include "core/components_ng/property/safe_area_insets.h"
46 #include "core/components_v2/inspector/inspector_constants.h"
47
48 namespace OHOS::Ace::NG {
49 namespace {
50 constexpr uint16_t PIXEL_ROUND = static_cast<uint16_t>(PixelRoundPolicy::FORCE_FLOOR_START) |
51 static_cast<uint16_t>(PixelRoundPolicy::FORCE_FLOOR_TOP) |
52 static_cast<uint16_t>(PixelRoundPolicy::FORCE_CEIL_END) |
53 static_cast<uint16_t>(PixelRoundPolicy::FORCE_CEIL_BOTTOM);
54 } // namespace
55
Create(BarPosition barPosition,int32_t index,const RefPtr<TabController> &,const RefPtr<SwiperController> & swiperController)56 void TabsModelNG::Create(BarPosition barPosition, int32_t index, const RefPtr<TabController>& /*tabController*/,
57 const RefPtr<SwiperController>& swiperController)
58 {
59 auto* stack = ViewStackProcessor::GetInstance();
60 auto nodeId = stack->ClaimNodeId();
61 ACE_LAYOUT_SCOPED_TRACE("Create[%s][self:%d]", V2::TABS_ETS_TAG, nodeId);
62 auto tabsNode = GetOrCreateTabsNode(V2::TABS_ETS_TAG, nodeId, []() { return AceType::MakeRefPtr<TabsPattern>(); });
63 InitTabsNode(tabsNode, swiperController);
64 ViewStackProcessor::GetInstance()->Push(tabsNode);
65
66 SetTabBarPosition(barPosition);
67 auto tabsLayoutProperty = tabsNode->GetLayoutProperty<TabsLayoutProperty>();
68 CHECK_NULL_VOID(tabsLayoutProperty);
69 if (tabsLayoutProperty->GetIndex().has_value()) {
70 auto preIndex = tabsLayoutProperty->GetIndex().value();
71 if (preIndex == index || index < 0) {
72 return;
73 }
74 }
75 tabsLayoutProperty->UpdateIndexSetByUser(index);
76 }
77
GetSwiperController(const RefPtr<FrameNode> & swiperNode,const RefPtr<SwiperController> & swiperController)78 RefPtr<SwiperController> TabsModelNG::GetSwiperController(const RefPtr<FrameNode>& swiperNode,
79 const RefPtr<SwiperController>& swiperController)
80 {
81 auto swiperPaintProperty = swiperNode->GetPaintProperty<SwiperPaintProperty>();
82 swiperPaintProperty->UpdateEdgeEffect(EdgeEffect::SPRING);
83 auto pipelineContext = PipelineContext::GetCurrentContext();
84 CHECK_NULL_RETURN(pipelineContext, nullptr);
85 auto tabTheme = pipelineContext->GetTheme<TabTheme>();
86 CHECK_NULL_RETURN(tabTheme, nullptr);
87 swiperPaintProperty->UpdateDuration(tabTheme->GetTabContentAnimationDuration());
88 swiperPaintProperty->UpdateCurve(TabBarPhysicalCurve);
89 auto swiperLayoutProperty = swiperNode->GetLayoutProperty<SwiperLayoutProperty>();
90 swiperLayoutProperty->UpdateLoop(false);
91 swiperLayoutProperty->UpdateCachedCount(0);
92 swiperLayoutProperty->UpdateShowIndicator(false);
93 swiperLayoutProperty->UpdateSafeAreaExpandOpts(
94 { .type = SAFE_AREA_TYPE_SYSTEM, .edges = SAFE_AREA_EDGE_TOP + SAFE_AREA_EDGE_BOTTOM });
95 auto swiperPattern = swiperNode->GetPattern<SwiperPattern>();
96 CHECK_NULL_RETURN(swiperPattern, nullptr);
97 RefPtr<SwiperController> controller;
98 if (swiperController) {
99 controller = swiperController;
100 } else {
101 controller = AceType::MakeRefPtr<TabsControllerNG>();
102 }
103 swiperPattern->SetSwiperController(controller);
104 swiperPattern->SetFinishCallbackType(FinishCallbackType::LOGICALLY);
105 swiperPattern->SetHasTabsAncestor(true);
106 return controller;
107 }
108
InitSelectedMaskNode(const RefPtr<FrameNode> & selectedMaskNode)109 void TabsModelNG::InitSelectedMaskNode(const RefPtr<FrameNode>& selectedMaskNode)
110 {
111 auto selectedImageNode = FrameNode::GetOrCreateFrameNode(V2::IMAGE_ETS_TAG,
112 ElementRegister::GetInstance()->MakeUniqueId(), []() { return AceType::MakeRefPtr<ImagePattern>(); });
113 selectedImageNode->MountToParent(selectedMaskNode);
114 auto selectedMaskRenderContext = selectedMaskNode->GetRenderContext();
115 auto selectedMaskProperty = selectedMaskNode->GetLayoutProperty<LinearLayoutProperty>();
116 selectedMaskProperty->UpdateCrossAxisAlign(FlexAlign::FLEX_START);
117 selectedMaskRenderContext->SetClipToBounds(true);
118 }
119
InitUnselectedMaskNode(const RefPtr<FrameNode> & unselectedMaskNode)120 void TabsModelNG::InitUnselectedMaskNode(const RefPtr<FrameNode>& unselectedMaskNode)
121 {
122 auto unselectedImageNode = FrameNode::GetOrCreateFrameNode(V2::IMAGE_ETS_TAG,
123 ElementRegister::GetInstance()->MakeUniqueId(), []() { return AceType::MakeRefPtr<ImagePattern>(); });
124 unselectedImageNode->MountToParent(unselectedMaskNode);
125 auto unselectedMaskRenderContext = unselectedMaskNode->GetRenderContext();
126 auto unselectedMaskProperty = unselectedMaskNode->GetLayoutProperty<LinearLayoutProperty>();
127 unselectedMaskProperty->UpdateCrossAxisAlign(FlexAlign::FLEX_START);
128 unselectedMaskRenderContext->SetClipToBounds(true);
129 }
130
InitTabsNode(RefPtr<TabsNode> tabsNode,const RefPtr<SwiperController> & swiperController)131 void TabsModelNG::InitTabsNode(RefPtr<TabsNode> tabsNode, const RefPtr<SwiperController>& swiperController)
132 {
133 bool hasSwiperNode = tabsNode->HasSwiperNode();
134 bool hasTabBarNode = tabsNode->HasTabBarNode();
135 bool hasDividerNode = tabsNode->HasDividerNode();
136 bool hasSelectedMaskNode = tabsNode->HasSelectedMaskNode();
137 bool hasUnselectedMaskNode = tabsNode->HasUnselectedMaskNode();
138 auto swiperId = tabsNode->GetSwiperId();
139 auto tabBarId = tabsNode->GetTabBarId();
140 auto dividerId = tabsNode->GetDividerId();
141 auto selectedMaskId = tabsNode->GetSelectedMaskId();
142 auto unselectedMaskId = tabsNode->GetUnselectedMaskId();
143
144 // Create Swiper node to contain TabContent.
145 auto swiperNode = FrameNode::GetOrCreateFrameNode(
146 V2::SWIPER_ETS_TAG, swiperId, []() { return AceType::MakeRefPtr<SwiperPattern>(); });
147 auto controller = GetSwiperController(swiperNode, swiperController);
148 auto dividerNode = FrameNode::GetOrCreateFrameNode(
149 V2::DIVIDER_ETS_TAG, dividerId, []() { return AceType::MakeRefPtr<DividerPattern>(); });
150
151 // Create TabBar to contain TabBar of TabContent.
152 auto tabBarNode = FrameNode::GetOrCreateFrameNode(
153 V2::TAB_BAR_ETS_TAG, tabBarId, [controller]() { return AceType::MakeRefPtr<TabBarPattern>(controller); });
154
155 auto tabBarLayoutProperty = tabBarNode->GetLayoutProperty();
156 CHECK_NULL_VOID(tabBarLayoutProperty);
157 if (tabBarLayoutProperty->GetPixelRound() == static_cast<uint16_t>(PixelRoundPolicy::ALL_FORCE_ROUND)) {
158 tabBarLayoutProperty->UpdatePixelRound(PIXEL_ROUND);
159 }
160
161 auto selectedMaskNode = FrameNode::GetOrCreateFrameNode(
162 V2::COLUMN_ETS_TAG, selectedMaskId, []() { return AceType::MakeRefPtr<LinearLayoutPattern>(true); });
163
164 auto unselectedMaskNode = FrameNode::GetOrCreateFrameNode(
165 V2::COLUMN_ETS_TAG, unselectedMaskId, []() { return AceType::MakeRefPtr<LinearLayoutPattern>(true); });
166
167 if (!hasSwiperNode) {
168 swiperNode->MountToParent(tabsNode);
169 }
170 if (!hasDividerNode) {
171 dividerNode->MountToParent(tabsNode);
172 }
173 if (!hasTabBarNode) {
174 tabBarNode->MountToParent(tabsNode);
175 }
176 if (!hasSelectedMaskNode) {
177 selectedMaskNode->MountToParent(tabBarNode);
178 InitSelectedMaskNode(selectedMaskNode);
179 }
180 if (!hasUnselectedMaskNode) {
181 unselectedMaskNode->MountToParent(tabBarNode);
182 InitUnselectedMaskNode(unselectedMaskNode);
183 }
184 }
185
CreateFrameNode(int32_t nodeId)186 RefPtr<FrameNode> TabsModelNG::CreateFrameNode(int32_t nodeId)
187 {
188 auto tabsNode = GetOrCreateTabsNode(V2::TABS_ETS_TAG, nodeId, []() { return AceType::MakeRefPtr<TabsPattern>(); });
189 InitTabsNode(tabsNode, nullptr);
190 auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
191 tabBarNode->MarkModifyDone();
192 return tabsNode;
193 }
194
SetTabBarPosition(BarPosition tabBarPosition)195 void TabsModelNG::SetTabBarPosition(BarPosition tabBarPosition)
196 {
197 ACE_UPDATE_LAYOUT_PROPERTY(TabsLayoutProperty, TabBarPosition, tabBarPosition);
198 }
199
SetBarBackgroundBlurStyle(BlurStyle tabBarBlurStyle)200 void TabsModelNG::SetBarBackgroundBlurStyle(BlurStyle tabBarBlurStyle)
201 {
202 auto tabsNode = AceType::DynamicCast<TabsNode>(ViewStackProcessor::GetInstance()->GetMainFrameNode());
203 CHECK_NULL_VOID(tabsNode);
204 auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
205 CHECK_NULL_VOID(tabBarNode);
206 auto tabBarPaintProperty = tabBarNode->GetPaintProperty<TabBarPaintProperty>();
207 CHECK_NULL_VOID(tabBarPaintProperty);
208 tabBarPaintProperty->UpdateTabBarBlurStyle(tabBarBlurStyle);
209 }
210
SetTabBarMode(TabBarMode tabBarMode)211 void TabsModelNG::SetTabBarMode(TabBarMode tabBarMode)
212 {
213 ACE_UPDATE_LAYOUT_PROPERTY(TabsLayoutProperty, TabBarMode, tabBarMode);
214 auto tabBarLayoutProperty = GetTabBarLayoutProperty();
215 CHECK_NULL_VOID(tabBarLayoutProperty);
216 tabBarLayoutProperty->UpdateTabBarMode(tabBarMode);
217 }
218
SetTabBarWidth(const Dimension & tabBarWidth)219 void TabsModelNG::SetTabBarWidth(const Dimension& tabBarWidth)
220 {
221 ACE_UPDATE_LAYOUT_PROPERTY(TabsLayoutProperty, BarWidth, tabBarWidth);
222 auto tabsNode = AceType::DynamicCast<TabsNode>(ViewStackProcessor::GetInstance()->GetMainFrameNode());
223 CHECK_NULL_VOID(tabsNode);
224 auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
225 CHECK_NULL_VOID(tabBarNode);
226 auto tabBarLayoutProperty = tabBarNode->GetLayoutProperty<TabBarLayoutProperty>();
227 CHECK_NULL_VOID(tabBarLayoutProperty);
228 auto scaleProperty = ScaleProperty::CreateScaleProperty();
229 auto tabBarWidthToPx =
230 ConvertToPx(tabBarWidth, scaleProperty, tabBarLayoutProperty->GetLayoutConstraint()->percentReference.Width());
231 if (LessNotEqual(tabBarWidthToPx.value_or(0.0), 0.0)) {
232 tabBarLayoutProperty->ClearUserDefinedIdealSize(true, false);
233 } else {
234 tabBarLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(NG::CalcLength(tabBarWidth), std::nullopt));
235 }
236 tabBarLayoutProperty->UpdateTabBarWidth(tabBarWidth);
237 }
238
SetTabBarHeight(const Dimension & tabBarHeight)239 void TabsModelNG::SetTabBarHeight(const Dimension& tabBarHeight)
240 {
241 ACE_UPDATE_LAYOUT_PROPERTY(TabsLayoutProperty, BarHeight, tabBarHeight);
242 auto tabsNode = AceType::DynamicCast<TabsNode>(ViewStackProcessor::GetInstance()->GetMainFrameNode());
243 CHECK_NULL_VOID(tabsNode);
244 auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
245 CHECK_NULL_VOID(tabBarNode);
246 auto tabBarLayoutProperty = tabBarNode->GetLayoutProperty<TabBarLayoutProperty>();
247 CHECK_NULL_VOID(tabBarLayoutProperty);
248 auto scaleProperty = ScaleProperty::CreateScaleProperty();
249 auto tabBarHeightToPx = ConvertToPx(
250 tabBarHeight, scaleProperty, tabBarLayoutProperty->GetLayoutConstraint()->percentReference.Height());
251 if (LessNotEqual(tabBarHeightToPx.value_or(0.0), 0.0)) {
252 tabBarLayoutProperty->ClearUserDefinedIdealSize(false, true);
253 } else {
254 tabBarLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(std::nullopt, NG::CalcLength(tabBarHeight)));
255 }
256 tabBarLayoutProperty->UpdateTabBarHeight(tabBarHeight);
257 }
258
SetBarModifier(std::function<void (WeakPtr<NG::FrameNode>)> && onApply)259 void TabsModelNG::SetBarModifier(std::function<void(WeakPtr<NG::FrameNode>)>&& onApply)
260 {
261 CHECK_NULL_VOID(onApply);
262 auto tabsNode = AceType::DynamicCast<TabsNode>(ViewStackProcessor::GetInstance()->GetMainFrameNode());
263 CHECK_NULL_VOID(tabsNode);
264 auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
265 CHECK_NULL_VOID(tabBarNode);
266 onApply(tabBarNode);
267 }
268
SetWidthAuto(bool isAuto)269 void TabsModelNG::SetWidthAuto(bool isAuto)
270 {
271 auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
272 CHECK_NULL_VOID(frameNode);
273 ACE_UPDATE_LAYOUT_PROPERTY(TabsLayoutProperty, WidthAuto, isAuto);
274 }
275
SetWidthAuto(FrameNode * frameNode,bool isAuto)276 void TabsModelNG::SetWidthAuto(FrameNode* frameNode, bool isAuto)
277 {
278 CHECK_NULL_VOID(frameNode);
279 ACE_UPDATE_NODE_LAYOUT_PROPERTY(TabsLayoutProperty, WidthAuto, isAuto, frameNode);
280 }
281
SetHeightAuto(bool isAuto)282 void TabsModelNG::SetHeightAuto(bool isAuto)
283 {
284 auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
285 CHECK_NULL_VOID(frameNode);
286 ACE_UPDATE_LAYOUT_PROPERTY(TabsLayoutProperty, HeightAuto, isAuto);
287 }
288
SetHeightAuto(FrameNode * frameNode,bool isAuto)289 void TabsModelNG::SetHeightAuto(FrameNode* frameNode, bool isAuto)
290 {
291 CHECK_NULL_VOID(frameNode);
292 ACE_UPDATE_NODE_LAYOUT_PROPERTY(TabsLayoutProperty, HeightAuto, isAuto, frameNode);
293 }
294
SetBarAdaptiveHeight(bool barAdaptiveHeight)295 void TabsModelNG::SetBarAdaptiveHeight(bool barAdaptiveHeight)
296 {
297 auto tabBarLayoutProperty = GetTabBarLayoutProperty();
298 CHECK_NULL_VOID(tabBarLayoutProperty);
299 tabBarLayoutProperty->UpdateBarAdaptiveHeight(barAdaptiveHeight);
300 }
301
SetIsVertical(bool isVertical)302 void TabsModelNG::SetIsVertical(bool isVertical)
303 {
304 auto axis = isVertical ? Axis::VERTICAL : Axis::HORIZONTAL;
305 ACE_UPDATE_LAYOUT_PROPERTY(TabsLayoutProperty, Axis, axis);
306
307 auto tabBarLayoutProperty = GetTabBarLayoutProperty();
308 CHECK_NULL_VOID(tabBarLayoutProperty);
309 if (tabBarLayoutProperty->GetAxis().value_or(Axis::HORIZONTAL) != axis) {
310 auto tabsNode = AceType::DynamicCast<TabsNode>(ViewStackProcessor::GetInstance()->GetMainFrameNode());
311 CHECK_NULL_VOID(tabsNode);
312 auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
313 CHECK_NULL_VOID(tabBarNode);
314 auto tabBarPattern = tabBarNode->GetPattern<TabBarPattern>();
315 CHECK_NULL_VOID(tabBarPattern);
316 tabBarPattern->UpdateCurrentOffset(0.0f);
317 }
318 tabBarLayoutProperty->UpdateAxis(axis);
319 auto swiperLayoutProperty = GetSwiperLayoutProperty();
320 CHECK_NULL_VOID(swiperLayoutProperty);
321 swiperLayoutProperty->UpdateDirection(axis);
322 }
323
SetIndex(int32_t index)324 void TabsModelNG::SetIndex(int32_t index)
325 {
326 auto tabsNode = AceType::DynamicCast<TabsNode>(ViewStackProcessor::GetInstance()->GetMainFrameNode());
327 CHECK_NULL_VOID(tabsNode);
328 auto swiperNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabs());
329 CHECK_NULL_VOID(swiperNode);
330 auto swiperLayoutProperty = swiperNode->GetLayoutProperty<SwiperLayoutProperty>();
331 CHECK_NULL_VOID(swiperLayoutProperty);
332 swiperLayoutProperty->UpdateIndex(index);
333 auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
334 CHECK_NULL_VOID(tabBarNode);
335 auto tabBarPattern = tabBarNode->GetPattern<TabBarPattern>();
336 CHECK_NULL_VOID(tabBarPattern);
337 if (index < 0) {
338 index = 0;
339 }
340 tabBarPattern->UpdateIndicator(index);
341 tabBarPattern->UpdateTextColorAndFontWeight(index);
342 swiperLayoutProperty->UpdateIndex(index);
343 auto tabsFrameNode = AceType::DynamicCast<FrameNode>(tabsNode);
344 CHECK_NULL_VOID(tabsFrameNode);
345 auto tabsLayoutProperty = tabsFrameNode->GetLayoutProperty<TabsLayoutProperty>();
346 tabsLayoutProperty->UpdateIndex(index);
347 tabsLayoutProperty->UpdateIndexSetByUser(index);
348 swiperNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
349 }
350
SetScrollable(bool scrollable)351 void TabsModelNG::SetScrollable(bool scrollable)
352 {
353 auto props = GetSwiperLayoutProperty();
354 CHECK_NULL_VOID(props);
355 props->UpdateDisableSwipe(!scrollable);
356 auto tabsNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
357 CHECK_NULL_VOID(tabsNode);
358 auto tabPattern = tabsNode->GetPattern<TabsPattern>();
359 CHECK_NULL_VOID(tabPattern);
360 tabPattern->SetIsDisableSwipe(!scrollable);
361 }
362
SetAnimationDuration(float duration)363 void TabsModelNG::SetAnimationDuration(float duration)
364 {
365 auto tabsNode = AceType::DynamicCast<TabsNode>(ViewStackProcessor::GetInstance()->GetMainFrameNode());
366 CHECK_NULL_VOID(tabsNode);
367 auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
368 CHECK_NULL_VOID(tabBarNode);
369 auto tabBarPattern = tabBarNode->GetPattern<TabBarPattern>();
370 CHECK_NULL_VOID(tabBarPattern);
371 tabBarPattern->SetAnimationDuration(static_cast<int32_t>(duration));
372 if (static_cast<int32_t>(duration) < 0) {
373 return;
374 }
375 auto swiperPaintProperty = GetSwiperPaintProperty();
376 CHECK_NULL_VOID(swiperPaintProperty);
377 swiperPaintProperty->UpdateDuration(static_cast<int32_t>(duration));
378 }
379
SetFadingEdge(bool fadingEdge)380 void TabsModelNG::SetFadingEdge(bool fadingEdge)
381 {
382 auto tabBarPaintProperty = GetTabBarPaintProperty();
383 CHECK_NULL_VOID(tabBarPaintProperty);
384 tabBarPaintProperty->UpdateFadingEdge(fadingEdge);
385 }
386
SetBarOverlap(bool barOverlap)387 void TabsModelNG::SetBarOverlap(bool barOverlap)
388 {
389 ACE_UPDATE_LAYOUT_PROPERTY(TabsLayoutProperty, BarOverlap, barOverlap);
390
391 if (barOverlap) {
392 SetBarBackgroundBlurStyle(BlurStyle::COMPONENT_THICK);
393 } else {
394 SetBarBackgroundBlurStyle(BlurStyle::NO_MATERIAL);
395 }
396 }
397
SetOnChange(std::function<void (const BaseEventInfo *)> && onChange)398 void TabsModelNG::SetOnChange(std::function<void(const BaseEventInfo*)>&& onChange)
399 {
400 auto tabsNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
401 CHECK_NULL_VOID(tabsNode);
402 auto tabPattern = tabsNode->GetPattern<TabsPattern>();
403 CHECK_NULL_VOID(tabPattern);
404 tabPattern->SetOnChangeEvent(std::move(onChange));
405 }
406
SetOnTabBarClick(std::function<void (const BaseEventInfo *)> && onTabBarClick)407 void TabsModelNG::SetOnTabBarClick(std::function<void(const BaseEventInfo*)>&& onTabBarClick)
408 {
409 auto tabsNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
410 CHECK_NULL_VOID(tabsNode);
411 auto tabPattern = tabsNode->GetPattern<TabsPattern>();
412 CHECK_NULL_VOID(tabPattern);
413 tabPattern->SetOnTabBarClickEvent(std::move(onTabBarClick));
414 }
415
SetOnAnimationStart(AnimationStartEvent && onAnimationStart)416 void TabsModelNG::SetOnAnimationStart(AnimationStartEvent&& onAnimationStart)
417 {
418 auto tabsNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
419 CHECK_NULL_VOID(tabsNode);
420 auto tabPattern = tabsNode->GetPattern<TabsPattern>();
421 CHECK_NULL_VOID(tabPattern);
422 tabPattern->SetAnimationStartEvent(std::move(onAnimationStart));
423 }
424
SetOnAnimationEnd(AnimationEndEvent && onAnimationEnd)425 void TabsModelNG::SetOnAnimationEnd(AnimationEndEvent&& onAnimationEnd)
426 {
427 auto tabsNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
428 CHECK_NULL_VOID(tabsNode);
429 auto tabPattern = tabsNode->GetPattern<TabsPattern>();
430 CHECK_NULL_VOID(tabPattern);
431 tabPattern->SetAnimationEndEvent(std::move(onAnimationEnd));
432 }
433
SetOnGestureSwipe(GestureSwipeEvent && onGestureSwipe)434 void TabsModelNG::SetOnGestureSwipe(GestureSwipeEvent&& onGestureSwipe)
435 {
436 auto tabsNode = AceType::DynamicCast<TabsNode>(ViewStackProcessor::GetInstance()->GetMainFrameNode());
437 CHECK_NULL_VOID(tabsNode);
438 auto swiperNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabs());
439 CHECK_NULL_VOID(swiperNode);
440 auto eventHub = swiperNode->GetEventHub<SwiperEventHub>();
441 CHECK_NULL_VOID(eventHub);
442 eventHub->SetGestureSwipeEvent(std::move(onGestureSwipe));
443 }
444
SetDivider(const TabsItemDivider & divider)445 void TabsModelNG::SetDivider(const TabsItemDivider& divider)
446 {
447 auto tabsNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
448 CHECK_NULL_VOID(tabsNode);
449 auto dividerNode = AceType::DynamicCast<FrameNode>(tabsNode->GetChildAtIndex(1));
450 CHECK_NULL_VOID(dividerNode);
451 auto dividerRenderContext = dividerNode->GetRenderContext();
452 CHECK_NULL_VOID(dividerRenderContext);
453 if (divider.isNull) {
454 dividerRenderContext->UpdateOpacity(0.0f);
455 auto tabsLayoutProperty = tabsNode->GetLayoutProperty<TabsLayoutProperty>();
456 CHECK_NULL_VOID(tabsLayoutProperty);
457 auto currentDivider = tabsLayoutProperty->GetDivider().value_or(TabsItemDivider());
458 currentDivider.strokeWidth = Dimension(1.0f);
459 currentDivider.isNull = true;
460 ACE_UPDATE_LAYOUT_PROPERTY(TabsLayoutProperty, Divider, currentDivider);
461 } else {
462 dividerRenderContext->UpdateOpacity(1.0f);
463 ACE_UPDATE_LAYOUT_PROPERTY(TabsLayoutProperty, Divider, divider);
464 }
465 }
466
SetBarBackgroundColor(const Color & backgroundColor)467 void TabsModelNG::SetBarBackgroundColor(const Color& backgroundColor)
468 {
469 auto tabsNode = AceType::DynamicCast<TabsNode>(ViewStackProcessor::GetInstance()->GetMainFrameNode());
470 CHECK_NULL_VOID(tabsNode);
471 auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
472 CHECK_NULL_VOID(tabBarNode);
473 auto tabBarRenderContext = tabBarNode->GetRenderContext();
474 CHECK_NULL_VOID(tabBarRenderContext);
475 tabBarRenderContext->UpdateBackgroundColor(backgroundColor);
476 }
477
GetTabBarLayoutProperty()478 RefPtr<TabBarLayoutProperty> TabsModelNG::GetTabBarLayoutProperty()
479 {
480 auto tabsNode = AceType::DynamicCast<TabsNode>(ViewStackProcessor::GetInstance()->GetMainFrameNode());
481 CHECK_NULL_RETURN(tabsNode, nullptr);
482 auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
483 CHECK_NULL_RETURN(tabBarNode, nullptr);
484 auto tabBarLayoutProperty = tabBarNode->GetLayoutProperty<TabBarLayoutProperty>();
485 CHECK_NULL_RETURN(tabBarLayoutProperty, nullptr);
486 return tabBarLayoutProperty;
487 }
488
GetTabBarPaintProperty()489 RefPtr<TabBarPaintProperty> TabsModelNG::GetTabBarPaintProperty()
490 {
491 auto tabsNode = AceType::DynamicCast<TabsNode>(ViewStackProcessor::GetInstance()->GetMainFrameNode());
492 CHECK_NULL_RETURN(tabsNode, nullptr);
493 auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
494 CHECK_NULL_RETURN(tabBarNode, nullptr);
495 auto tabBarPaintProperty = tabBarNode->GetPaintProperty<TabBarPaintProperty>();
496 CHECK_NULL_RETURN(tabBarPaintProperty, nullptr);
497 return tabBarPaintProperty;
498 }
499
GetSwiperLayoutProperty()500 RefPtr<SwiperLayoutProperty> TabsModelNG::GetSwiperLayoutProperty()
501 {
502 auto tabsNode = AceType::DynamicCast<TabsNode>(ViewStackProcessor::GetInstance()->GetMainFrameNode());
503 CHECK_NULL_RETURN(tabsNode, nullptr);
504 auto swiperNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabs());
505 CHECK_NULL_RETURN(swiperNode, nullptr);
506 auto swiperLayoutProperty = swiperNode->GetLayoutProperty<SwiperLayoutProperty>();
507 CHECK_NULL_RETURN(swiperLayoutProperty, nullptr);
508 return swiperLayoutProperty;
509 }
510
GetSwiperPaintProperty()511 RefPtr<SwiperPaintProperty> TabsModelNG::GetSwiperPaintProperty()
512 {
513 auto tabsNode = AceType::DynamicCast<TabsNode>(ViewStackProcessor::GetInstance()->GetMainFrameNode());
514 CHECK_NULL_RETURN(tabsNode, nullptr);
515 auto swiperNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabs());
516 CHECK_NULL_RETURN(swiperNode, nullptr);
517 auto swiperPaintProperty = swiperNode->GetPaintProperty<SwiperPaintProperty>();
518 CHECK_NULL_RETURN(swiperPaintProperty, nullptr);
519 return swiperPaintProperty;
520 }
521
Pop()522 void TabsModelNG::Pop()
523 {
524 auto tabsNode = AceType::DynamicCast<TabsNode>(ViewStackProcessor::GetInstance()->GetMainFrameNode());
525 CHECK_NULL_VOID(tabsNode);
526 auto tabsLayoutProperty = tabsNode->GetLayoutProperty<TabsLayoutProperty>();
527 CHECK_NULL_VOID(tabsLayoutProperty);
528 auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
529 CHECK_NULL_VOID(tabBarNode);
530 auto swiperNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabs());
531 CHECK_NULL_VOID(swiperNode);
532
533 tabBarNode->MarkModifyDone();
534 tabBarNode->MarkDirtyNode(PROPERTY_UPDATE_LAYOUT);
535 auto dividerNode = AceType::DynamicCast<FrameNode>(tabsNode->GetDivider());
536 CHECK_NULL_VOID(dividerNode);
537 auto layoutProperty = tabsNode->GetLayoutProperty<TabsLayoutProperty>();
538 CHECK_NULL_VOID(layoutProperty);
539
540 auto axis = layoutProperty->GetAxis().value_or((Axis::HORIZONTAL));
541 TabsItemDivider defaultDivider;
542 auto divider = layoutProperty->GetDivider().value_or(defaultDivider);
543 auto dividerColor = divider.color;
544 auto dividerStrokeWidth = divider.strokeWidth;
545
546 auto dividerHub = dividerNode->GetEventHub<EventHub>();
547 CHECK_NULL_VOID(dividerHub);
548
549 auto dividerRenderProperty = dividerNode->GetPaintProperty<DividerRenderProperty>();
550 CHECK_NULL_VOID(dividerRenderProperty);
551 dividerRenderProperty->UpdateDividerColor(dividerColor);
552 dividerRenderProperty->UpdateLineCap(LineCap::BUTT);
553
554 auto dividerLayoutProperty = dividerNode->GetLayoutProperty<DividerLayoutProperty>();
555 CHECK_NULL_VOID(dividerLayoutProperty);
556 dividerLayoutProperty->UpdateVertical(axis == Axis::VERTICAL);
557 dividerLayoutProperty->UpdateStrokeWidth(dividerStrokeWidth);
558 dividerLayoutProperty->UpdateStrokeWidthLimitation(false);
559 CHECK_NULL_VOID(dividerNode);
560 dividerNode->MarkModifyDone();
561
562 swiperNode->MarkModifyDone();
563 swiperNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
564
565 ViewStackProcessor::GetInstance()->PopContainer();
566 }
567
GetOrCreateTabsNode(const std::string & tag,int32_t nodeId,const std::function<RefPtr<Pattern> (void)> & patternCreator)568 RefPtr<TabsNode> TabsModelNG::GetOrCreateTabsNode(
569 const std::string& tag, int32_t nodeId, const std::function<RefPtr<Pattern>(void)>& patternCreator)
570 {
571 auto tabsNode = ElementRegister::GetInstance()->GetSpecificItemById<TabsNode>(nodeId);
572 if (tabsNode) {
573 if (tabsNode->GetTag() == tag) {
574 return tabsNode;
575 }
576 ElementRegister::GetInstance()->RemoveItemSilently(nodeId);
577 auto parent = tabsNode->GetParent();
578 if (parent) {
579 parent->RemoveChild(tabsNode);
580 }
581 }
582
583 auto pattern = patternCreator ? patternCreator() : AceType::MakeRefPtr<Pattern>();
584 tabsNode = AceType::MakeRefPtr<TabsNode>(tag, nodeId, pattern, false);
585 tabsNode->InitializePatternAndContext();
586 ElementRegister::GetInstance()->AddUINode(tabsNode);
587 return tabsNode;
588 }
589
SetOnChangeEvent(std::function<void (const BaseEventInfo *)> && onChangeEvent)590 void TabsModelNG::SetOnChangeEvent(std::function<void(const BaseEventInfo*)>&& onChangeEvent)
591 {
592 auto tabsNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
593 CHECK_NULL_VOID(tabsNode);
594 auto tabPattern = tabsNode->GetPattern<TabsPattern>();
595 CHECK_NULL_VOID(tabPattern);
596 tabPattern->SetOnIndexChangeEvent(std::move(onChangeEvent));
597 }
598
SetClipEdge(bool clipEdge)599 void TabsModelNG::SetClipEdge(bool clipEdge)
600 {
601 auto tabsNode = AceType::DynamicCast<TabsNode>(ViewStackProcessor::GetInstance()->GetMainFrameNode());
602 CHECK_NULL_VOID(tabsNode);
603 ViewAbstract::SetClipEdge(clipEdge);
604 auto swiperNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabs());
605 CHECK_NULL_VOID(swiperNode);
606 auto swiperRenderContext = swiperNode->GetRenderContext();
607 CHECK_NULL_VOID(swiperRenderContext);
608 swiperRenderContext->UpdateClipEdge(clipEdge);
609 auto dividerNode = AceType::DynamicCast<FrameNode>(tabsNode->GetDivider());
610 CHECK_NULL_VOID(dividerNode);
611 auto dividerRenderContext = dividerNode->GetRenderContext();
612 CHECK_NULL_VOID(dividerRenderContext);
613 dividerRenderContext->UpdateClipEdge(clipEdge);
614 }
615
SetScrollableBarModeOptions(const ScrollableBarModeOptions & option)616 void TabsModelNG::SetScrollableBarModeOptions(const ScrollableBarModeOptions& option)
617 {
618 auto tabBarLayoutProperty = GetTabBarLayoutProperty();
619 CHECK_NULL_VOID(tabBarLayoutProperty);
620 tabBarLayoutProperty->UpdateScrollableBarModeOptions(option);
621 }
622
SetBarGridAlign(const BarGridColumnOptions & BarGridColumnOptions)623 void TabsModelNG::SetBarGridAlign(const BarGridColumnOptions& BarGridColumnOptions)
624 {
625 auto tabBarLayoutProperty = GetTabBarLayoutProperty();
626 CHECK_NULL_VOID(tabBarLayoutProperty);
627 tabBarLayoutProperty->UpdateBarGridAlign(BarGridColumnOptions);
628 }
629
GetTabBarLayoutProperty(FrameNode * frameNode)630 RefPtr<TabBarLayoutProperty> TabsModelNG::GetTabBarLayoutProperty(FrameNode* frameNode)
631 {
632 auto tabsNode = AceType::DynamicCast<TabsNode>(frameNode);
633 CHECK_NULL_RETURN(tabsNode, nullptr);
634 auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
635 CHECK_NULL_RETURN(tabBarNode, nullptr);
636 auto tabBarLayoutProperty = tabBarNode->GetLayoutProperty<TabBarLayoutProperty>();
637 CHECK_NULL_RETURN(tabBarLayoutProperty, nullptr);
638 return tabBarLayoutProperty;
639 }
640
GetTabBarPaintProperty(FrameNode * frameNode)641 RefPtr<TabBarPaintProperty> TabsModelNG::GetTabBarPaintProperty(FrameNode* frameNode)
642 {
643 auto tabsNode = AceType::DynamicCast<TabsNode>(frameNode);
644 CHECK_NULL_RETURN(tabsNode, nullptr);
645 auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
646 CHECK_NULL_RETURN(tabBarNode, nullptr);
647 auto tabBarPaintProperty = tabBarNode->GetPaintProperty<TabBarPaintProperty>();
648 CHECK_NULL_RETURN(tabBarPaintProperty, nullptr);
649 return tabBarPaintProperty;
650 }
651
GetSwiperLayoutProperty(FrameNode * frameNode)652 RefPtr<SwiperLayoutProperty> TabsModelNG::GetSwiperLayoutProperty(FrameNode* frameNode)
653 {
654 auto tabsNode = AceType::DynamicCast<TabsNode>(frameNode);
655 CHECK_NULL_RETURN(tabsNode, nullptr);
656 auto swiperNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabs());
657 CHECK_NULL_RETURN(swiperNode, nullptr);
658 auto swiperLayoutProperty = swiperNode->GetLayoutProperty<SwiperLayoutProperty>();
659 CHECK_NULL_RETURN(swiperLayoutProperty, nullptr);
660 return swiperLayoutProperty;
661 }
662
GetSwiperPaintProperty(FrameNode * frameNode)663 RefPtr<SwiperPaintProperty> TabsModelNG::GetSwiperPaintProperty(FrameNode* frameNode)
664 {
665 auto tabsNode = AceType::DynamicCast<TabsNode>(frameNode);
666 CHECK_NULL_RETURN(tabsNode, nullptr);
667 auto swiperNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabs());
668 CHECK_NULL_RETURN(swiperNode, nullptr);
669 auto swiperPaintProperty = swiperNode->GetPaintProperty<SwiperPaintProperty>();
670 CHECK_NULL_RETURN(swiperPaintProperty, nullptr);
671 return swiperPaintProperty;
672 }
673
SetTabBarMode(FrameNode * frameNode,TabBarMode tabBarMode)674 void TabsModelNG::SetTabBarMode(FrameNode* frameNode, TabBarMode tabBarMode)
675 {
676 ACE_UPDATE_NODE_LAYOUT_PROPERTY(TabsLayoutProperty, TabBarMode, tabBarMode, frameNode);
677 auto tabBarLayoutProperty = GetTabBarLayoutProperty(frameNode);
678 CHECK_NULL_VOID(tabBarLayoutProperty);
679 tabBarLayoutProperty->UpdateTabBarMode(tabBarMode);
680 }
681
SetBarGridAlign(FrameNode * frameNode,const BarGridColumnOptions & BarGridColumnOptions)682 void TabsModelNG::SetBarGridAlign(FrameNode* frameNode, const BarGridColumnOptions& BarGridColumnOptions)
683 {
684 CHECK_NULL_VOID(frameNode);
685 auto tabBarLayoutProperty = GetTabBarLayoutProperty(frameNode);
686 CHECK_NULL_VOID(tabBarLayoutProperty);
687 tabBarLayoutProperty->UpdateBarGridAlign(BarGridColumnOptions);
688 }
689
SetDivider(FrameNode * frameNode,const TabsItemDivider & divider)690 void TabsModelNG::SetDivider(FrameNode* frameNode, const TabsItemDivider& divider)
691 {
692 CHECK_NULL_VOID(frameNode);
693 auto dividerNode = AceType::DynamicCast<FrameNode>(frameNode->GetChildAtIndex(1));
694 CHECK_NULL_VOID(dividerNode);
695 auto dividerRenderContext = dividerNode->GetRenderContext();
696 CHECK_NULL_VOID(dividerRenderContext);
697 if (divider.isNull) {
698 dividerRenderContext->UpdateOpacity(0.0f);
699 auto tabsLayoutProperty = frameNode->GetLayoutProperty<TabsLayoutProperty>();
700 CHECK_NULL_VOID(tabsLayoutProperty);
701 auto currentDivider = tabsLayoutProperty->GetDivider().value_or(TabsItemDivider());
702 currentDivider.strokeWidth = Dimension(1.0f);
703 currentDivider.isNull = true;
704 ACE_UPDATE_NODE_LAYOUT_PROPERTY(TabsLayoutProperty, Divider, currentDivider, frameNode);
705 } else {
706 dividerRenderContext->UpdateOpacity(1.0f);
707 ACE_UPDATE_NODE_LAYOUT_PROPERTY(TabsLayoutProperty, Divider, divider, frameNode);
708 }
709 }
710
SetFadingEdge(FrameNode * frameNode,bool fadingEdge)711 void TabsModelNG::SetFadingEdge(FrameNode* frameNode, bool fadingEdge)
712 {
713 CHECK_NULL_VOID(frameNode);
714 auto tabBarPaintProperty = GetTabBarPaintProperty(frameNode);
715 CHECK_NULL_VOID(tabBarPaintProperty);
716 tabBarPaintProperty->UpdateFadingEdge(fadingEdge);
717 }
718
SetBarBackgroundColor(FrameNode * frameNode,const Color & backgroundColor)719 void TabsModelNG::SetBarBackgroundColor(FrameNode* frameNode, const Color& backgroundColor)
720 {
721 CHECK_NULL_VOID(frameNode);
722 auto tabsNode = AceType::DynamicCast<TabsNode>(frameNode);
723 CHECK_NULL_VOID(tabsNode);
724 auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
725 CHECK_NULL_VOID(tabBarNode);
726 auto tabBarRenderContext = tabBarNode->GetRenderContext();
727 CHECK_NULL_VOID(tabBarRenderContext);
728 tabBarRenderContext->UpdateBackgroundColor(backgroundColor);
729 }
730
SetBarBackgroundBlurStyle(FrameNode * frameNode,BlurStyle tabBarBlurStyle)731 void TabsModelNG::SetBarBackgroundBlurStyle(FrameNode* frameNode, BlurStyle tabBarBlurStyle)
732 {
733 CHECK_NULL_VOID(frameNode);
734 auto tabsNode = AceType::DynamicCast<TabsNode>(frameNode);
735 CHECK_NULL_VOID(tabsNode);
736 auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
737 CHECK_NULL_VOID(tabBarNode);
738 auto tabBarPaintProperty = tabBarNode->GetPaintProperty<TabBarPaintProperty>();
739 CHECK_NULL_VOID(tabBarPaintProperty);
740 tabBarPaintProperty->UpdateTabBarBlurStyle(tabBarBlurStyle);
741 }
742
SetBarOverlap(FrameNode * frameNode,bool barOverlap)743 void TabsModelNG::SetBarOverlap(FrameNode* frameNode, bool barOverlap)
744 {
745 ACE_UPDATE_NODE_LAYOUT_PROPERTY(TabsLayoutProperty, BarOverlap, barOverlap, frameNode);
746
747 if (barOverlap) {
748 SetBarBackgroundBlurStyle(frameNode, BlurStyle::COMPONENT_THICK);
749 } else {
750 SetBarBackgroundBlurStyle(frameNode, BlurStyle::NO_MATERIAL);
751 }
752 }
753
SetIsVertical(FrameNode * frameNode,bool isVertical)754 void TabsModelNG::SetIsVertical(FrameNode* frameNode, bool isVertical)
755 {
756 auto axis = isVertical ? Axis::VERTICAL : Axis::HORIZONTAL;
757 ACE_UPDATE_NODE_LAYOUT_PROPERTY(TabsLayoutProperty, Axis, axis, frameNode);
758
759 auto tabBarLayoutProperty = GetTabBarLayoutProperty(frameNode);
760 CHECK_NULL_VOID(tabBarLayoutProperty);
761 if (tabBarLayoutProperty->GetAxis().value_or(Axis::HORIZONTAL) != axis) {
762 auto tabsNode = AceType::DynamicCast<TabsNode>(frameNode);
763 CHECK_NULL_VOID(tabsNode);
764 auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
765 CHECK_NULL_VOID(tabBarNode);
766 auto tabBarPattern = tabBarNode->GetPattern<TabBarPattern>();
767 CHECK_NULL_VOID(tabBarPattern);
768 tabBarPattern->UpdateCurrentOffset(0.0f);
769 }
770 tabBarLayoutProperty->UpdateAxis(axis);
771 auto swiperLayoutProperty = GetSwiperLayoutProperty(frameNode);
772 CHECK_NULL_VOID(swiperLayoutProperty);
773 swiperLayoutProperty->UpdateDirection(axis);
774 }
775
SetTabBarPosition(FrameNode * frameNode,BarPosition tabBarPosition)776 void TabsModelNG::SetTabBarPosition(FrameNode* frameNode, BarPosition tabBarPosition)
777 {
778 ACE_UPDATE_NODE_LAYOUT_PROPERTY(TabsLayoutProperty, TabBarPosition, tabBarPosition, frameNode);
779 }
780
SetScrollable(FrameNode * frameNode,bool scrollable)781 void TabsModelNG::SetScrollable(FrameNode* frameNode, bool scrollable)
782 {
783 CHECK_NULL_VOID(frameNode);
784 auto props = GetSwiperLayoutProperty(frameNode);
785 CHECK_NULL_VOID(props);
786 props->UpdateDisableSwipe(!scrollable);
787 auto tabPattern = frameNode->GetPattern<TabsPattern>();
788 CHECK_NULL_VOID(tabPattern);
789 tabPattern->SetIsDisableSwipe(!scrollable);
790 }
791
SetTabBarWidth(FrameNode * frameNode,const Dimension & tabBarWidth)792 void TabsModelNG::SetTabBarWidth(FrameNode* frameNode, const Dimension& tabBarWidth)
793 {
794 ACE_UPDATE_NODE_LAYOUT_PROPERTY(TabsLayoutProperty, BarWidth, tabBarWidth, frameNode);
795 auto tabsNode = AceType::DynamicCast<TabsNode>(frameNode);
796 CHECK_NULL_VOID(tabsNode);
797 auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
798 CHECK_NULL_VOID(tabBarNode);
799 auto tabBarLayoutProperty = tabBarNode->GetLayoutProperty<TabBarLayoutProperty>();
800 CHECK_NULL_VOID(tabBarLayoutProperty);
801 auto scaleProperty = ScaleProperty::CreateScaleProperty();
802 auto tabBarWidthToPx =
803 ConvertToPx(tabBarWidth, scaleProperty, tabBarLayoutProperty->GetLayoutConstraint()->percentReference.Width());
804 if (LessNotEqual(tabBarWidthToPx.value_or(0.0), 0.0)) {
805 tabBarLayoutProperty->ClearUserDefinedIdealSize(true, false);
806 } else {
807 tabBarLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(NG::CalcLength(tabBarWidth), std::nullopt));
808 }
809 tabBarLayoutProperty->UpdateTabBarWidth(tabBarWidth);
810 }
811
SetTabBarHeight(FrameNode * frameNode,const Dimension & tabBarHeight)812 void TabsModelNG::SetTabBarHeight(FrameNode* frameNode, const Dimension& tabBarHeight)
813 {
814 ACE_UPDATE_NODE_LAYOUT_PROPERTY(TabsLayoutProperty, BarHeight, tabBarHeight, frameNode);
815 auto tabsNode = AceType::DynamicCast<TabsNode>(frameNode);
816 CHECK_NULL_VOID(tabsNode);
817 auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
818 CHECK_NULL_VOID(tabBarNode);
819 auto tabBarLayoutProperty = tabBarNode->GetLayoutProperty<TabBarLayoutProperty>();
820 CHECK_NULL_VOID(tabBarLayoutProperty);
821 auto scaleProperty = ScaleProperty::CreateScaleProperty();
822 auto tabBarHeightToPx = ConvertToPx(
823 tabBarHeight, scaleProperty, tabBarLayoutProperty->GetLayoutConstraint()->percentReference.Height());
824 if (LessNotEqual(tabBarHeightToPx.value_or(0.0), 0.0)) {
825 tabBarLayoutProperty->ClearUserDefinedIdealSize(false, true);
826 } else {
827 tabBarLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(std::nullopt, NG::CalcLength(tabBarHeight)));
828 }
829 tabBarLayoutProperty->UpdateTabBarHeight(tabBarHeight);
830 }
831
SetAnimationDuration(FrameNode * frameNode,float duration)832 void TabsModelNG::SetAnimationDuration(FrameNode* frameNode, float duration)
833 {
834 CHECK_NULL_VOID(frameNode);
835 auto tabsNode = AceType::DynamicCast<TabsNode>(frameNode);
836 CHECK_NULL_VOID(tabsNode);
837 auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
838 CHECK_NULL_VOID(tabBarNode);
839 auto tabBarPattern = tabBarNode->GetPattern<TabBarPattern>();
840 CHECK_NULL_VOID(tabBarPattern);
841 tabBarPattern->SetAnimationDuration(static_cast<int32_t>(duration));
842 if (static_cast<int32_t>(duration) < 0) {
843 return;
844 }
845 auto swiperPaintProperty = GetSwiperPaintProperty(frameNode);
846 CHECK_NULL_VOID(swiperPaintProperty);
847 swiperPaintProperty->UpdateDuration(static_cast<int32_t>(duration));
848 }
849
SetScrollableBarModeOptions(FrameNode * frameNode,const ScrollableBarModeOptions & option)850 void TabsModelNG::SetScrollableBarModeOptions(FrameNode* frameNode, const ScrollableBarModeOptions& option)
851 {
852 CHECK_NULL_VOID(frameNode);
853 auto tabBarLayoutProperty = GetTabBarLayoutProperty(frameNode);
854 CHECK_NULL_VOID(tabBarLayoutProperty);
855 tabBarLayoutProperty->UpdateScrollableBarModeOptions(option);
856 }
857
SetBarAdaptiveHeight(FrameNode * frameNode,bool barAdaptiveHeight)858 void TabsModelNG::SetBarAdaptiveHeight(FrameNode* frameNode, bool barAdaptiveHeight)
859 {
860 CHECK_NULL_VOID(frameNode);
861 auto tabBarLayoutProperty = GetTabBarLayoutProperty(frameNode);
862 CHECK_NULL_VOID(tabBarLayoutProperty);
863 tabBarLayoutProperty->UpdateBarAdaptiveHeight(barAdaptiveHeight);
864 }
865
SetIsCustomAnimation(bool isCustom)866 void TabsModelNG::SetIsCustomAnimation(bool isCustom)
867 {
868 auto swiperLayoutProperty = GetSwiperLayoutProperty();
869 CHECK_NULL_VOID(swiperLayoutProperty);
870 swiperLayoutProperty->UpdateIsCustomAnimation(isCustom);
871 auto tabsNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
872 CHECK_NULL_VOID(tabsNode);
873 auto tabPattern = tabsNode->GetPattern<TabsPattern>();
874 CHECK_NULL_VOID(tabPattern);
875 tabPattern->SetIsCustomAnimation(isCustom);
876 }
877
SetOnCustomAnimation(TabsCustomAnimationEvent && onCustomAnimation)878 void TabsModelNG::SetOnCustomAnimation(TabsCustomAnimationEvent&& onCustomAnimation)
879 {
880 auto tabsNode = AceType::DynamicCast<TabsNode>(ViewStackProcessor::GetInstance()->GetMainFrameNode());
881 CHECK_NULL_VOID(tabsNode);
882 auto swiperNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabs());
883 CHECK_NULL_VOID(swiperNode);
884 auto swiperPattern = swiperNode->GetPattern<SwiperPattern>();
885 CHECK_NULL_VOID(swiperPattern);
886 swiperPattern->SetTabsCustomContentTransition(std::move(onCustomAnimation));
887 }
888
SetClipEdge(FrameNode * frameNode,bool clipEdge)889 void TabsModelNG::SetClipEdge(FrameNode* frameNode, bool clipEdge)
890 {
891 auto tabsNode = AceType::DynamicCast<TabsNode>(frameNode);
892 CHECK_NULL_VOID(tabsNode);
893 ViewAbstract::SetClipEdge(tabsNode, clipEdge);
894 auto swiperNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabs());
895 CHECK_NULL_VOID(swiperNode);
896 auto swiperRenderContext = swiperNode->GetRenderContext();
897 CHECK_NULL_VOID(swiperRenderContext);
898 swiperRenderContext->UpdateClipEdge(clipEdge);
899 auto dividerNode = AceType::DynamicCast<FrameNode>(tabsNode->GetDivider());
900 CHECK_NULL_VOID(dividerNode);
901 auto dividerRenderContext = dividerNode->GetRenderContext();
902 CHECK_NULL_VOID(dividerRenderContext);
903 dividerRenderContext->UpdateClipEdge(clipEdge);
904 }
905
SetOnContentWillChange(std::function<bool (int32_t,int32_t)> && callback)906 void TabsModelNG::SetOnContentWillChange(std::function<bool(int32_t, int32_t)>&& callback)
907 {
908 auto tabsNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
909 CHECK_NULL_VOID(tabsNode);
910 auto tabPattern = tabsNode->GetPattern<TabsPattern>();
911 CHECK_NULL_VOID(tabPattern);
912 tabPattern->SetInterceptStatus(true);
913 tabPattern->SetOnContentWillChange(std::move(callback));
914 }
915
SetAnimateMode(TabAnimateMode mode)916 void TabsModelNG::SetAnimateMode(TabAnimateMode mode)
917 {
918 auto tabsNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
919 CHECK_NULL_VOID(tabsNode);
920 auto tabPattern = tabsNode->GetPattern<TabsPattern>();
921 CHECK_NULL_VOID(tabPattern);
922 tabPattern->SetAnimateMode(mode);
923 }
924
SetAnimateMode(FrameNode * frameNode,TabAnimateMode mode)925 void TabsModelNG::SetAnimateMode(FrameNode* frameNode, TabAnimateMode mode)
926 {
927 CHECK_NULL_VOID(frameNode);
928 auto tabsNode = AceType::DynamicCast<TabsNode>(frameNode);
929 CHECK_NULL_VOID(tabsNode);
930 auto tabPattern = tabsNode->GetPattern<TabsPattern>();
931 CHECK_NULL_VOID(tabPattern);
932 tabPattern->SetAnimateMode(mode);
933 }
934
SetEdgeEffect(EdgeEffect edgeEffect)935 void TabsModelNG::SetEdgeEffect(EdgeEffect edgeEffect)
936 {
937 auto swiperPaintProperty = GetSwiperPaintProperty();
938 CHECK_NULL_VOID(swiperPaintProperty);
939 swiperPaintProperty->UpdateEdgeEffect(edgeEffect);
940 }
941
SetEdgeEffect(FrameNode * frameNode,int32_t edgeEffect)942 void TabsModelNG::SetEdgeEffect(FrameNode* frameNode, int32_t edgeEffect)
943 {
944 auto swiperPaintProperty = GetSwiperPaintProperty(frameNode);
945 CHECK_NULL_VOID(swiperPaintProperty);
946 swiperPaintProperty->UpdateEdgeEffect(static_cast<EdgeEffect>(edgeEffect));
947 }
948
SetPageFlipMode(int32_t pageFlipMode)949 void TabsModelNG::SetPageFlipMode(int32_t pageFlipMode)
950 {
951 auto tabsNode = AceType::DynamicCast<TabsNode>(ViewStackProcessor::GetInstance()->GetMainFrameNode());
952 CHECK_NULL_VOID(tabsNode);
953 auto swiperNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabs());
954 CHECK_NULL_VOID(swiperNode);
955 auto swiperPattern = swiperNode->GetPattern<SwiperPattern>();
956 CHECK_NULL_VOID(swiperPattern);
957 swiperPattern->SetPageFlipMode(pageFlipMode);
958 }
959
SetPageFlipMode(FrameNode * frameNode,int32_t options)960 void TabsModelNG::SetPageFlipMode(FrameNode* frameNode, int32_t options)
961 {
962 CHECK_NULL_VOID(frameNode);
963 auto tabsNode = AceType::DynamicCast<TabsNode>(frameNode);
964 CHECK_NULL_VOID(tabsNode);
965 auto swiperNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabs());
966 CHECK_NULL_VOID(swiperNode);
967 auto swiperPattern = swiperNode->GetPattern<SwiperPattern>();
968 CHECK_NULL_VOID(swiperPattern);
969 swiperPattern->SetPageFlipMode(options);
970 }
971 } // namespace OHOS::Ace::NG
972