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