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