1 /*
2  * Copyright (c) 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 #include "core/interfaces/native/node/tabs_modifier.h"
16 
17 #include "base/utils/string_utils.h"
18 #include "core/components/common/layout/constants.h"
19 #include "core/components/tab_bar/tab_theme.h"
20 #include "core/components_ng/base/frame_node.h"
21 #include "core/components_ng/base/view_abstract.h"
22 #include "core/components_ng/base/view_abstract_model_ng.h"
23 #include "core/components_ng/pattern/tabs/tabs_model.h"
24 #include "core/components_ng/pattern/tabs/tabs_model_ng.h"
25 #include "core/pipeline/base/element_register.h"
26 #include "frameworks/bridge/common/utils/utils.h"
27 
28 namespace OHOS::Ace::NG {
29 constexpr int NUM_0 = 0;
30 constexpr int NUM_1 = 1;
31 constexpr int NUM_2 = 2;
32 constexpr int NUM_3 = 3;
33 constexpr int NUM_4 = 4;
34 constexpr int DEFAULT_LENGTH = 3;
35 constexpr int DEFAULT_LENGTH_OF_BAR_GRID_ALIGN = 5;
36 constexpr int DEFAULT_LENGTH_OF_BAR_GRID_ALIGN_VALUES = 2;
37 constexpr int DEFAULT_ANIMATION_DURATION = 300;
38 
SetTabBarMode(ArkUINodeHandle node,ArkUI_Int32 tabsBarMode)39 void SetTabBarMode(ArkUINodeHandle node, ArkUI_Int32 tabsBarMode)
40 {
41     auto* frameNode = reinterpret_cast<FrameNode*>(node);
42     CHECK_NULL_VOID(frameNode);
43     auto barMode = static_cast<TabBarMode>(tabsBarMode);
44     TabsModelNG::SetTabBarMode(frameNode, barMode);
45 }
SetScrollableBarModeOptions(ArkUINodeHandle node,const ArkUI_Float32 value,ArkUI_Int32 unit,ArkUI_Int32 layoutStyle)46 void SetScrollableBarModeOptions(ArkUINodeHandle node, const ArkUI_Float32 value,
47     ArkUI_Int32 unit, ArkUI_Int32 layoutStyle)
48 {
49     auto* frameNode = reinterpret_cast<FrameNode*>(node);
50     CHECK_NULL_VOID(frameNode);
51     ScrollableBarModeOptions option;
52     CalcDimension margin = Dimension(value, static_cast<OHOS::Ace::DimensionUnit>(unit));
53     option.margin = margin;
54     option.nonScrollableLayoutStyle = (static_cast<LayoutStyle>(layoutStyle));
55     TabsModelNG::SetScrollableBarModeOptions(frameNode, option);
56 }
SetBarGridAlign(ArkUINodeHandle node,const ArkUI_Float32 * values,ArkUI_Int32 valuesLength,const ArkUI_Int32 * units,ArkUI_Int32 unitsLength)57 void SetBarGridAlign(ArkUINodeHandle node, const ArkUI_Float32* values, ArkUI_Int32 valuesLength,
58     const ArkUI_Int32* units, ArkUI_Int32 unitsLength)
59 {
60     auto* frameNode = reinterpret_cast<FrameNode*>(node);
61     CHECK_NULL_VOID(frameNode);
62 
63     if (unitsLength != DEFAULT_LENGTH_OF_BAR_GRID_ALIGN || valuesLength != DEFAULT_LENGTH_OF_BAR_GRID_ALIGN_VALUES) {
64         return;
65     }
66     BarGridColumnOptions columnOption;
67     columnOption.sm = units[NUM_2];
68     columnOption.md = units[NUM_3];
69     columnOption.lg = units[NUM_4];
70     columnOption.gutter = Dimension(values[NUM_0], static_cast<OHOS::Ace::DimensionUnit>(units[NUM_0]));
71     columnOption.margin = Dimension(values[NUM_1], static_cast<OHOS::Ace::DimensionUnit>(units[NUM_1]));
72 
73     TabsModelNG::SetBarGridAlign(frameNode, columnOption);
74 }
SetDivider(ArkUINodeHandle node,ArkUI_Uint32 color,const ArkUI_Float32 * values,const ArkUI_Int32 * units,ArkUI_Int32 length)75 void SetDivider(ArkUINodeHandle node, ArkUI_Uint32 color, const ArkUI_Float32* values, const ArkUI_Int32* units,
76     ArkUI_Int32 length)
77 {
78     auto* frameNode = reinterpret_cast<FrameNode*>(node);
79     CHECK_NULL_VOID(frameNode);
80 
81     if (length != DEFAULT_LENGTH) {
82         return;
83     }
84     TabsItemDivider divider;
85     divider.strokeWidth = Dimension(values[NUM_0], static_cast<OHOS::Ace::DimensionUnit>(units[NUM_0]));
86     divider.startMargin = Dimension(values[NUM_1], static_cast<OHOS::Ace::DimensionUnit>(units[NUM_1]));
87     divider.endMargin = Dimension(values[NUM_2], static_cast<OHOS::Ace::DimensionUnit>(units[NUM_2]));
88     divider.color = Color(color);
89 
90     TabsModelNG::SetDivider(frameNode, divider);
91 }
SetFadingEdge(ArkUINodeHandle node,ArkUI_Bool fadingEdge)92 void SetFadingEdge(ArkUINodeHandle node, ArkUI_Bool fadingEdge)
93 {
94     auto* frameNode = reinterpret_cast<FrameNode*>(node);
95     CHECK_NULL_VOID(frameNode);
96     TabsModelNG::SetFadingEdge(frameNode, fadingEdge);
97 }
SetBarBackgroundColor(ArkUINodeHandle node,ArkUI_Uint32 color)98 void SetBarBackgroundColor(ArkUINodeHandle node, ArkUI_Uint32 color)
99 {
100     auto* frameNode = reinterpret_cast<FrameNode*>(node);
101     CHECK_NULL_VOID(frameNode);
102     TabsModelNG::SetBarBackgroundColor(frameNode, Color(color));
103 }
SetBarBackgroundBlurStyle(ArkUINodeHandle node,ArkUI_Int32 blurStyle)104 void SetBarBackgroundBlurStyle(ArkUINodeHandle node, ArkUI_Int32 blurStyle)
105 {
106     auto* frameNode = reinterpret_cast<FrameNode*>(node);
107     CHECK_NULL_VOID(frameNode);
108     TabsModelNG::SetBarBackgroundBlurStyle(frameNode, static_cast<BlurStyle>(blurStyle));
109 }
SetBarOverlap(ArkUINodeHandle node,ArkUI_Bool barOverlap)110 void SetBarOverlap(ArkUINodeHandle node, ArkUI_Bool barOverlap)
111 {
112     auto* frameNode = reinterpret_cast<FrameNode*>(node);
113     CHECK_NULL_VOID(frameNode);
114     TabsModelNG::SetBarOverlap(frameNode, barOverlap);
115 }
SetIsVertical(ArkUINodeHandle node,ArkUI_Bool isVertical)116 void SetIsVertical(ArkUINodeHandle node, ArkUI_Bool isVertical)
117 {
118     auto* frameNode = reinterpret_cast<FrameNode*>(node);
119     CHECK_NULL_VOID(frameNode);
120     TabsModelNG::SetIsVertical(frameNode, isVertical);
121 }
SetTabBarPosition(ArkUINodeHandle node,ArkUI_Int32 barVal)122 void SetTabBarPosition(ArkUINodeHandle node, ArkUI_Int32 barVal)
123 {
124     auto* frameNode = reinterpret_cast<FrameNode*>(node);
125     CHECK_NULL_VOID(frameNode);
126     TabsModelNG::SetTabBarPosition(frameNode, static_cast<BarPosition>(barVal));
127 }
SetScrollable(ArkUINodeHandle node,ArkUI_Bool scrollable)128 void SetScrollable(ArkUINodeHandle node, ArkUI_Bool scrollable)
129 {
130     auto* frameNode = reinterpret_cast<FrameNode*>(node);
131     CHECK_NULL_VOID(frameNode);
132     TabsModelNG::SetScrollable(frameNode, scrollable);
133 }
SetBarAdaptiveHeight(ArkUINodeHandle node,ArkUI_Bool value)134 void SetBarAdaptiveHeight(ArkUINodeHandle node, ArkUI_Bool value)
135 {
136     auto* frameNode = reinterpret_cast<FrameNode*>(node);
137     CHECK_NULL_VOID(frameNode);
138     TabsModelNG::SetBarAdaptiveHeight(frameNode, value);
139 }
SetTabBarWidth(ArkUINodeHandle node,ArkUI_Float32 value,ArkUI_Int32 unit)140 void SetTabBarWidth(ArkUINodeHandle node, ArkUI_Float32 value, ArkUI_Int32 unit)
141 {
142     auto* frameNode = reinterpret_cast<FrameNode*>(node);
143     CHECK_NULL_VOID(frameNode);
144     CalcDimension width = Dimension(value, static_cast<OHOS::Ace::DimensionUnit>(unit));
145     TabsModelNG::SetTabBarWidth(frameNode, width);
146 }
SetTabBarHeight(ArkUINodeHandle node,ArkUI_Float32 value,ArkUI_Int32 unit)147 void SetTabBarHeight(ArkUINodeHandle node, ArkUI_Float32 value, ArkUI_Int32 unit)
148 {
149     auto* frameNode = reinterpret_cast<FrameNode*>(node);
150     CHECK_NULL_VOID(frameNode);
151     CalcDimension width = Dimension(value, static_cast<OHOS::Ace::DimensionUnit>(unit));
152     TabsModelNG::SetTabBarHeight(frameNode, width);
153 }
154 
SetAnimationDuration(ArkUINodeHandle node,ArkUI_Float32 duration)155 void SetAnimationDuration(ArkUINodeHandle node, ArkUI_Float32 duration)
156 {
157     auto* frameNode = reinterpret_cast<FrameNode*>(node);
158     CHECK_NULL_VOID(frameNode);
159     if (std::isnan(duration)) {
160         auto pipelineContext = PipelineContext::GetCurrentContext();
161         CHECK_NULL_VOID(pipelineContext);
162         auto tabTheme = pipelineContext->GetTheme<TabTheme>();
163         CHECK_NULL_VOID(tabTheme);
164         TabsModelNG::SetAnimationDuration(frameNode,
165             static_cast<ArkUI_Float32>(tabTheme->GetTabContentAnimationDuration()));
166     }
167     TabsModelNG::SetAnimationDuration(frameNode, duration);
168 }
ResetTabBarMode(ArkUINodeHandle node)169 void ResetTabBarMode(ArkUINodeHandle node)
170 {
171     auto* frameNode = reinterpret_cast<FrameNode*>(node);
172     CHECK_NULL_VOID(frameNode);
173     TabBarMode barMode = TabBarMode::FIXED;
174     TabsModelNG::SetTabBarMode(frameNode, barMode);
175 }
ResetScrollableBarModeOptions(ArkUINodeHandle node)176 void ResetScrollableBarModeOptions(ArkUINodeHandle node)
177 {
178     auto* frameNode = reinterpret_cast<FrameNode*>(node);
179     CHECK_NULL_VOID(frameNode);
180     ScrollableBarModeOptions defaultOption;
181     CalcDimension margin = Dimension(0.0, DimensionUnit::VP);
182     defaultOption.margin = margin;
183     defaultOption.nonScrollableLayoutStyle = LayoutStyle::ALWAYS_CENTER;
184     TabsModelNG::SetScrollableBarModeOptions(frameNode, defaultOption);
185 }
ResetBarGridAlign(ArkUINodeHandle node)186 void ResetBarGridAlign(ArkUINodeHandle node)
187 {
188     auto* frameNode = reinterpret_cast<FrameNode*>(node);
189     CHECK_NULL_VOID(frameNode);
190     BarGridColumnOptions columnOption;
191     TabsModelNG::SetBarGridAlign(frameNode, columnOption);
192 }
ResetDivider(ArkUINodeHandle node)193 void ResetDivider(ArkUINodeHandle node)
194 {
195     auto* frameNode = reinterpret_cast<FrameNode*>(node);
196     CHECK_NULL_VOID(frameNode);
197 
198     TabsItemDivider divider;
199     divider.isNull = true;
200 
201     TabsModelNG::SetDivider(frameNode, divider);
202 }
203 
ResetFadingEdge(ArkUINodeHandle node)204 void ResetFadingEdge(ArkUINodeHandle node)
205 {
206     auto* frameNode = reinterpret_cast<FrameNode*>(node);
207     CHECK_NULL_VOID(frameNode);
208     TabsModelNG::SetFadingEdge(frameNode, true);
209 }
ResetBarBackgroundColor(ArkUINodeHandle node)210 void ResetBarBackgroundColor(ArkUINodeHandle node)
211 {
212     auto* frameNode = reinterpret_cast<FrameNode*>(node);
213     CHECK_NULL_VOID(frameNode);
214     TabsModelNG::SetBarBackgroundColor(frameNode, Color::BLACK.BlendOpacity(0.0f));
215 }
ResetBarBackgroundBlurStyle(ArkUINodeHandle node)216 void ResetBarBackgroundBlurStyle(ArkUINodeHandle node)
217 {
218     auto* frameNode = reinterpret_cast<FrameNode*>(node);
219     CHECK_NULL_VOID(frameNode);
220     TabsModelNG::SetBarBackgroundBlurStyle(frameNode, BlurStyle::NO_MATERIAL);
221 }
ResetBarOverlap(ArkUINodeHandle node)222 void ResetBarOverlap(ArkUINodeHandle node)
223 {
224     auto* frameNode = reinterpret_cast<FrameNode*>(node);
225     CHECK_NULL_VOID(frameNode);
226     TabsModelNG::SetBarOverlap(frameNode, false);
227 }
ResetIsVertical(ArkUINodeHandle node)228 void ResetIsVertical(ArkUINodeHandle node)
229 {
230     auto* frameNode = reinterpret_cast<FrameNode*>(node);
231     CHECK_NULL_VOID(frameNode);
232     TabsModelNG::SetIsVertical(frameNode, false);
233 }
234 
ResetTabBarPosition(ArkUINodeHandle node)235 void ResetTabBarPosition(ArkUINodeHandle node)
236 {
237     auto* frameNode = reinterpret_cast<FrameNode*>(node);
238     CHECK_NULL_VOID(frameNode);
239     TabsModelNG::SetTabBarPosition(frameNode, BarPosition::START);
240 }
241 
ResetScrollable(ArkUINodeHandle node)242 void ResetScrollable(ArkUINodeHandle node)
243 {
244     auto* frameNode = reinterpret_cast<FrameNode*>(node);
245     CHECK_NULL_VOID(frameNode);
246     TabsModelNG::SetScrollable(frameNode, true);
247 }
ResetTabBarWidth(ArkUINodeHandle node)248 void ResetTabBarWidth(ArkUINodeHandle node)
249 {
250     auto* frameNode = reinterpret_cast<FrameNode*>(node);
251     CHECK_NULL_VOID(frameNode);
252     CalcDimension width = Dimension(-1.0, DimensionUnit::VP);
253     TabsModelNG::SetTabBarWidth(frameNode, width);
254 }
ResetTabBarHeight(ArkUINodeHandle node)255 void ResetTabBarHeight(ArkUINodeHandle node)
256 {
257     auto* frameNode = reinterpret_cast<FrameNode*>(node);
258     CHECK_NULL_VOID(frameNode);
259     CalcDimension width = Dimension(-1.0, DimensionUnit::VP);
260     TabsModelNG::SetTabBarHeight(frameNode, width);
261 }
262 
ResetAnimationDuration(ArkUINodeHandle node)263 void ResetAnimationDuration(ArkUINodeHandle node)
264 {
265     auto* frameNode = reinterpret_cast<FrameNode*>(node);
266     CHECK_NULL_VOID(frameNode);
267     TabsModelNG::SetAnimationDuration(frameNode, DEFAULT_ANIMATION_DURATION);
268 }
269 
ResetBarAdaptiveHeight(ArkUINodeHandle node)270 void ResetBarAdaptiveHeight(ArkUINodeHandle node)
271 {
272     auto* frameNode = reinterpret_cast<FrameNode*>(node);
273     CHECK_NULL_VOID(frameNode);
274     TabsModelNG::SetBarAdaptiveHeight(frameNode, false);
275 }
276 
SetTabClip(ArkUINodeHandle node,ArkUI_Bool clipEdge)277 void SetTabClip(ArkUINodeHandle node, ArkUI_Bool clipEdge)
278 {
279     auto* frameNode = reinterpret_cast<FrameNode*>(node);
280     CHECK_NULL_VOID(frameNode);
281     TabsModelNG::SetClipEdge(frameNode, clipEdge);
282 }
283 
ResetTabClip(ArkUINodeHandle node)284 void ResetTabClip(ArkUINodeHandle node)
285 {
286     auto* frameNode = reinterpret_cast<FrameNode*>(node);
287     CHECK_NULL_VOID(frameNode);
288     TabsModelNG::SetClipEdge(frameNode, false);
289 }
290 
SetTabEdgeEffect(ArkUINodeHandle node,ArkUI_Uint32 edgeEffect)291 void SetTabEdgeEffect(ArkUINodeHandle node, ArkUI_Uint32 edgeEffect)
292 {
293     auto* frameNode = reinterpret_cast<FrameNode*>(node);
294     CHECK_NULL_VOID(frameNode);
295     TabsModelNG::SetEdgeEffect(frameNode, edgeEffect);
296 }
297 
ResetTabEdgeEffect(ArkUINodeHandle node)298 void ResetTabEdgeEffect(ArkUINodeHandle node)
299 {
300     auto* frameNode = reinterpret_cast<FrameNode*>(node);
301     CHECK_NULL_VOID(frameNode);
302     TabsModelNG::SetEdgeEffect(frameNode, NUM_0);
303 }
304 
SetTabWidthAuto(ArkUINodeHandle node)305 void SetTabWidthAuto(ArkUINodeHandle node)
306 {
307     auto* frameNode = reinterpret_cast<FrameNode*>(node);
308     CHECK_NULL_VOID(frameNode);
309     ViewAbstract::ClearWidthOrHeight(frameNode, true);
310     TabsModelNG::SetWidthAuto(frameNode, true);
311 }
312 
ResetTabWidthAuto(ArkUINodeHandle node)313 void ResetTabWidthAuto(ArkUINodeHandle node)
314 {
315     auto* frameNode = reinterpret_cast<FrameNode*>(node);
316     CHECK_NULL_VOID(frameNode);
317     TabsModelNG::SetWidthAuto(frameNode, false);
318 }
319 
SetTabHeightAuto(ArkUINodeHandle node)320 void SetTabHeightAuto(ArkUINodeHandle node)
321 {
322     auto* frameNode = reinterpret_cast<FrameNode*>(node);
323     CHECK_NULL_VOID(frameNode);
324     ViewAbstract::ClearWidthOrHeight(frameNode, false);
325     TabsModelNG::SetHeightAuto(frameNode, true);
326 }
327 
ResetTabHeightAuto(ArkUINodeHandle node)328 void ResetTabHeightAuto(ArkUINodeHandle node)
329 {
330     auto* frameNode = reinterpret_cast<FrameNode*>(node);
331     CHECK_NULL_VOID(frameNode);
332     TabsModelNG::SetHeightAuto(frameNode, false);
333 }
334 
SetAnimateMode(ArkUINodeHandle node,ArkUI_Uint32 mode)335 void SetAnimateMode(ArkUINodeHandle node, ArkUI_Uint32 mode)
336 {
337     auto* frameNode = reinterpret_cast<FrameNode*>(node);
338     CHECK_NULL_VOID(frameNode);
339     TabsModelNG::SetAnimateMode(frameNode, static_cast<TabAnimateMode>(mode));
340 }
341 
ResetAnimateMode(ArkUINodeHandle node)342 void ResetAnimateMode(ArkUINodeHandle node)
343 {
344     auto* frameNode = reinterpret_cast<FrameNode*>(node);
345     CHECK_NULL_VOID(frameNode);
346     TabsModelNG::SetAnimateMode(frameNode, TabAnimateMode::CONTENT_FIRST);
347 }
348 
349 namespace NodeModifier {
GetTabsModifier()350 const ArkUITabsModifier* GetTabsModifier()
351 {
352     static const ArkUITabsModifier modifier = {
353         SetTabBarMode,
354         SetScrollableBarModeOptions,
355         SetBarGridAlign,
356         SetDivider,
357         SetFadingEdge,
358         SetBarBackgroundColor,
359         SetBarBackgroundBlurStyle,
360         SetBarOverlap,
361         SetIsVertical,
362         SetTabBarPosition,
363         SetScrollable,
364         SetTabBarWidth,
365         SetTabBarHeight,
366         SetBarAdaptiveHeight,
367         SetAnimationDuration,
368         ResetTabBarMode,
369         ResetScrollableBarModeOptions,
370         ResetBarGridAlign,
371         ResetDivider,
372         ResetFadingEdge,
373         ResetBarBackgroundColor,
374         ResetBarBackgroundBlurStyle,
375         ResetBarOverlap,
376         ResetIsVertical,
377         ResetTabBarPosition,
378         ResetScrollable,
379         ResetTabBarWidth,
380         ResetTabBarHeight,
381         ResetBarAdaptiveHeight,
382         ResetAnimationDuration,
383         SetTabClip,
384         ResetTabClip,
385         SetTabEdgeEffect,
386         ResetTabEdgeEffect,
387         SetTabWidthAuto,
388         ResetTabWidthAuto,
389         SetTabHeightAuto,
390         ResetTabHeightAuto,
391         SetAnimateMode,
392         ResetAnimateMode,
393     };
394 
395     return &modifier;
396 }
397 
GetCJUITabsModifier()398 const CJUITabsModifier* GetCJUITabsModifier()
399 {
400     static const CJUITabsModifier modifier = {
401         SetTabBarMode,
402         SetScrollableBarModeOptions,
403         SetBarGridAlign,
404         SetDivider,
405         SetFadingEdge,
406         SetBarBackgroundColor,
407         SetBarBackgroundBlurStyle,
408         SetBarOverlap,
409         SetIsVertical,
410         SetTabBarPosition,
411         SetScrollable,
412         SetTabBarWidth,
413         SetTabBarHeight,
414         SetBarAdaptiveHeight,
415         SetAnimationDuration,
416         ResetTabBarMode,
417         ResetScrollableBarModeOptions,
418         ResetBarGridAlign,
419         ResetDivider,
420         ResetFadingEdge,
421         ResetBarBackgroundColor,
422         ResetBarBackgroundBlurStyle,
423         ResetBarOverlap,
424         ResetIsVertical,
425         ResetTabBarPosition,
426         ResetScrollable,
427         ResetTabBarWidth,
428         ResetTabBarHeight,
429         ResetBarAdaptiveHeight,
430         ResetAnimationDuration,
431         SetTabClip,
432         ResetTabClip,
433         SetTabWidthAuto,
434         ResetTabWidthAuto,
435         SetTabHeightAuto,
436         ResetTabHeightAuto,
437         SetAnimateMode,
438         ResetAnimateMode,
439     };
440 
441     return &modifier;
442 }
443 }
444 } // namespace OHOS::Ace::NG