• 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_node.h"
17 
18 #include "base/utils/utils.h"
19 #include "core/components/common/layout/constants.h"
20 #include "core/components_ng/base/inspector_filter.h"
21 #include "core/components_ng/pattern/swiper/swiper_layout_property.h"
22 #include "core/components_ng/pattern/swiper/swiper_paint_property.h"
23 #include "core/components_ng/pattern/tabs/tab_bar_layout_algorithm.h"
24 #include "core/components_ng/pattern/tabs/tab_bar_pattern.h"
25 #include "core/components_ng/pattern/tabs/tabs_pattern.h"
26 #include "core/components_v2/inspector/inspector_constants.h"
27 #include "core/pipeline_ng/pipeline_context.h"
28 
29 namespace OHOS::Ace::NG {
30 namespace {
31 
32 const std::string BAR_BLURSTYLE[] = {
33     "BlurStyle.NONE",
34     "BlurStyle.Thin",
35     "BlurStyle.Regular",
36     "BlurStyle.Thick",
37     "BlurStyle.BACKGROUND_THIN",
38     "BlurStyle.BACKGROUND_REGULAR",
39     "BlurStyle.BACKGROUND_THICK",
40     "BlurStyle.BACKGROUND_ULTRA_THICK",
41     "BlurStyle.COMPONENT_ULTRA_THIN",
42     "BlurStyle.COMPONENT_THIN",
43     "BlurStyle.COMPONENT_REGULAR",
44     "BlurStyle.COMPONENT_THICK",
45     "BlurStyle.COMPONENT_ULTRA_THICK"
46 };
47 
48 } // namespace
49 
AddChildToGroup(const RefPtr<UINode> & child,int32_t slot)50 void TabsNode::AddChildToGroup(const RefPtr<UINode>& child, int32_t slot)
51 {
52     if (swiperChildren_.find(child->GetId()) != swiperChildren_.end()) {
53         return;
54     }
55 
56     swiperChildren_.emplace(child->GetId());
57     auto swiperNode = GetTabs();
58     if (swiperNode) {
59         child->MountToParent(swiperNode);
60     }
61 }
62 
ToJsonValue(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter) const63 void TabsNode::ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
64 {
65     FrameNode::ToJsonValue(json, filter);
66     json->PutFixedAttr("scrollable", Scrollable(), filter, FIXED_ATTR_SCROLLABLE);
67     /* no fixed attr below, just return */
68     if (filter.IsFastFilter()) {
69         return;
70     }
71     json->PutExtAttr("index", std::to_string(GetIndex()).c_str(), filter);
72     json->PutExtAttr("animationCurve", GetAnimationCurveStr(TabBarPhysicalCurve).c_str(), filter);
73     json->PutExtAttr("animationDuration", GetAnimationDuration(), filter);
74     if (GetTabBarMode() == TabBarMode::SCROLLABLE) {
75         auto optionsJson = JsonUtil::Create(true);
76         auto options = GetScrollableBarModeOptions();
77         optionsJson->Put("margin", options.margin.ToString().c_str());
78         if (options.nonScrollableLayoutStyle.value_or(LayoutStyle::ALWAYS_CENTER) == LayoutStyle::ALWAYS_CENTER) {
79             optionsJson->Put("nonScrollableLayoutStyle", "LayoutStyle.ALWAYS_CENTER");
80         } else if (options.nonScrollableLayoutStyle.value() == LayoutStyle::ALWAYS_AVERAGE_SPLIT) {
81             optionsJson->Put("nonScrollableLayoutStyle", "LayoutStyle.ALWAYS_AVERAGE_SPLIT");
82         } else if (options.nonScrollableLayoutStyle.value() == LayoutStyle::SPACE_BETWEEN_OR_CENTER) {
83             optionsJson->Put("nonScrollableLayoutStyle", "LayoutStyle.SPACE_BETWEEN_OR_CENTER");
84         }
85         std::string barMode = "BarMode.Scrollable," + optionsJson->ToString();
86         json->PutExtAttr("barMode", barMode.c_str(), filter);
87     } else {
88         json->PutExtAttr("barMode", "BarMode.Fixed", filter);
89     }
90     json->PutExtAttr("barWidth", std::to_string(GetBarWidth().Value()).c_str(), filter);
91     json->PutExtAttr("barHeight",
92         GetBarAdaptiveHeight() ? "auto" : std::to_string(GetBarHeight().Value()).c_str(), filter);
93     json->PutExtAttr("fadingEdge", GetFadingEdge() ? "true" : "false", filter);
94     json->PutExtAttr("barBackgroundColor", GetBarBackgroundColor().ColorToString().c_str(), filter);
95     json->PutExtAttr("barBackgroundBlurStyle",
96         BAR_BLURSTYLE[static_cast<int32_t>(GetBarBackgroundBlurStyle())].c_str(), filter);
97     json->PutExtAttr("barBackgroundBlurStyleOptions", GetBarBackgroundBlurStyleOptions(), filter);
98     json->PutExtAttr("animationMode", GetAnimationMode().c_str(), filter);
99     json->PutExtAttr("edgeEffect", GetEdgeEffect().c_str(), filter);
100     json->PutExtAttr("barBackgroundEffect", GetBarBackgroundEffect(), filter);
101 
102     auto barGridAlignJson = JsonUtil::Create(true);
103     auto barGridAlign = GetBarGridAlign();
104     barGridAlignJson->Put("gutter", barGridAlign.gutter.ToString().c_str());
105     barGridAlignJson->Put("margin", barGridAlign.margin.ToString().c_str());
106     barGridAlignJson->Put("sm", std::to_string(barGridAlign.sm).c_str());
107     barGridAlignJson->Put("md", std::to_string(barGridAlign.md).c_str());
108     barGridAlignJson->Put("lg", std::to_string(barGridAlign.lg).c_str());
109 
110     json->PutExtAttr("barGridAlign", barGridAlignJson, filter);
111 }
112 
Scrollable() const113 bool TabsNode::Scrollable() const
114 {
115     if (!swiperId_.has_value()) {
116         return true;
117     }
118     auto swiperNode = GetFrameNode(V2::SWIPER_ETS_TAG, swiperId_.value());
119     CHECK_NULL_RETURN(swiperNode, true);
120     auto props = swiperNode->GetLayoutProperty<SwiperLayoutProperty>();
121     CHECK_NULL_RETURN(props, true);
122     return !props->GetDisableSwipe().value_or(false);
123 }
124 
GetAnimationCurve(const RefPtr<Curve> & defaultCurve) const125 const RefPtr<Curve> TabsNode::GetAnimationCurve(const RefPtr<Curve>& defaultCurve) const
126 {
127     if (!swiperId_.has_value()) {
128         return defaultCurve;
129     }
130     auto swiperNode = GetFrameNode(V2::SWIPER_ETS_TAG, swiperId_.value());
131     CHECK_NULL_RETURN(swiperNode, defaultCurve);
132     auto swiperPaintProperty = swiperNode->GetPaintProperty<SwiperPaintProperty>();
133     CHECK_NULL_RETURN(swiperPaintProperty, defaultCurve);
134     auto curve = swiperPaintProperty->GetCurve().value_or(nullptr);
135     CHECK_NULL_RETURN(curve, defaultCurve);
136     return curve;
137 }
138 
GetAnimationCurveStr(const RefPtr<Curve> & defaultCurve) const139 std::string TabsNode::GetAnimationCurveStr(const RefPtr<Curve>& defaultCurve) const
140 {
141     auto curve = GetAnimationCurve(defaultCurve);
142     return curve ? curve->ToString() : "null";
143 }
144 
GetAnimationDuration() const145 int32_t TabsNode::GetAnimationDuration() const
146 {
147     int32_t duration = 0;
148     if (!tabBarId_.has_value()) {
149         return duration;
150     }
151     auto tabBarNode = GetFrameNode(V2::TAB_BAR_ETS_TAG, tabBarId_.value());
152     CHECK_NULL_RETURN(tabBarNode, duration);
153     auto tabBarPattern = tabBarNode->GetPattern<TabBarPattern>();
154     CHECK_NULL_RETURN(tabBarPattern, duration);
155     tabBarPattern->UpdateAnimationDuration();
156     return tabBarPattern->GetAnimationDuration().value_or(duration);
157 }
158 
GetIndex() const159 int32_t TabsNode::GetIndex() const
160 {
161     if (!swiperId_.has_value()) {
162         return 0;
163     }
164     auto swiperNode = GetFrameNode(V2::SWIPER_ETS_TAG, swiperId_.value());
165     CHECK_NULL_RETURN(swiperNode, 0);
166     auto layoutProperty = swiperNode->GetLayoutProperty<SwiperLayoutProperty>();
167     CHECK_NULL_RETURN(layoutProperty, 0);
168     return layoutProperty->GetIndex().value_or(0);
169 }
170 
GetTabBarMode() const171 TabBarMode TabsNode::GetTabBarMode() const
172 {
173     if (!tabBarId_.has_value()) {
174         return TabBarMode::FIXED;
175     }
176     auto tabBarNode = GetFrameNode(V2::TAB_BAR_ETS_TAG, tabBarId_.value());
177     CHECK_NULL_RETURN(tabBarNode, TabBarMode::FIXED);
178     auto tabBarProperty = tabBarNode->GetLayoutProperty<TabBarLayoutProperty>();
179     CHECK_NULL_RETURN(tabBarProperty, TabBarMode::FIXED);
180     return tabBarProperty->GetTabBarMode().value_or(TabBarMode::FIXED);
181 }
182 
GetBarWidth() const183 Dimension TabsNode::GetBarWidth() const
184 {
185     if (!tabBarId_.has_value()) {
186         return 0.0_vp;
187     }
188     auto tabBarNode = GetFrameNode(V2::TAB_BAR_ETS_TAG, tabBarId_.value());
189     CHECK_NULL_RETURN(tabBarNode, 0.0_vp);
190     auto geometryNode = tabBarNode->GetGeometryNode();
191     CHECK_NULL_RETURN(geometryNode, 0.0_vp);
192     auto frameSize = geometryNode->GetFrameSize();
193     return Dimension(PipelineBase::Px2VpWithCurrentDensity(frameSize.Width()), DimensionUnit::VP);
194 }
195 
GetBarAdaptiveHeight() const196 bool TabsNode::GetBarAdaptiveHeight() const
197 {
198     if (!tabBarId_.has_value()) {
199         return false;
200     }
201     auto tabBarNode = GetFrameNode(V2::TAB_BAR_ETS_TAG, tabBarId_.value());
202     CHECK_NULL_RETURN(tabBarNode, false);
203     auto tabBarProperty = tabBarNode->GetLayoutProperty<TabBarLayoutProperty>();
204     CHECK_NULL_RETURN(tabBarProperty, false);
205     return tabBarProperty->GetBarAdaptiveHeight().value_or(false);
206 }
207 
GetBarHeight() const208 Dimension TabsNode::GetBarHeight() const
209 {
210     if (!tabBarId_.has_value()) {
211         return 0.0_vp;
212     }
213     auto tabBarNode = GetFrameNode(V2::TAB_BAR_ETS_TAG, tabBarId_.value());
214     CHECK_NULL_RETURN(tabBarNode, 0.0_vp);
215     auto geometryNode = tabBarNode->GetGeometryNode();
216     CHECK_NULL_RETURN(geometryNode, 0.0_vp);
217     auto frameSize = geometryNode->GetFrameSize();
218     return Dimension(PipelineBase::Px2VpWithCurrentDensity(frameSize.Height()), DimensionUnit::VP);
219 }
220 
GetBarBackgroundColor() const221 Color TabsNode::GetBarBackgroundColor() const
222 {
223     auto backgroundColor = Color::BLACK.BlendOpacity(0.0f);
224     if (!tabBarId_.has_value()) {
225         return backgroundColor;
226     }
227     auto tabBarNode = GetFrameNode(V2::TAB_BAR_ETS_TAG, tabBarId_.value());
228     CHECK_NULL_RETURN(tabBarNode, backgroundColor);
229     auto tabBarRenderContext = tabBarNode->GetRenderContext();
230     CHECK_NULL_RETURN(tabBarRenderContext, backgroundColor);
231     return tabBarRenderContext->GetBackgroundColor().value_or(backgroundColor);
232 }
233 
GetBarBackgroundBlurStyle() const234 BlurStyle TabsNode::GetBarBackgroundBlurStyle() const
235 {
236     auto barBackgroundBlurStyle = BlurStyle::NO_MATERIAL;
237     if (!tabBarId_.has_value()) {
238         return barBackgroundBlurStyle;
239     }
240     auto tabBarNode = GetFrameNode(V2::TAB_BAR_ETS_TAG, tabBarId_.value());
241     CHECK_NULL_RETURN(tabBarNode, barBackgroundBlurStyle);
242     auto tabBarRenderContext = tabBarNode->GetRenderContext();
243     CHECK_NULL_RETURN(tabBarRenderContext, barBackgroundBlurStyle);
244     auto styleOption = tabBarRenderContext->GetBackBlurStyle().value_or(BlurStyleOption{});
245     return styleOption.blurStyle;
246 }
247 
GetBarBackgroundBlurStyleOptions() const248 std::unique_ptr<JsonValue> TabsNode::GetBarBackgroundBlurStyleOptions() const
249 {
250     auto jsonBlurStyle = JsonUtil::Create(true);
251     if (!tabBarId_.has_value()) {
252         return jsonBlurStyle;
253     }
254     static const char* COLOR_MODE[] = { "ThemeColorMode.System", "ThemeColorMode.Light", "ThemeColorMode.Dark" };
255     static const char* ADAPTIVE_COLOR[] = { "AdaptiveColor.Default", "AdaptiveColor.Average" };
256     static const char* POLICY[] = { "BlurStyleActivePolicy.FOLLOWS_WINDOW_ACTIVE_STATE",
257         "BlurStyleActivePolicy.ALWAYS_ACTIVE", "BlurStyleActivePolicy.ALWAYS_INACTIVE" };
258     static const char* BLUR_TYPE[] = { "BlurType.WITHIN_WINDOW", "BlurType.BEHIND_WINDOW" };
259     auto tabBarNode = GetFrameNode(V2::TAB_BAR_ETS_TAG, tabBarId_.value());
260     CHECK_NULL_RETURN(tabBarNode, jsonBlurStyle);
261     auto tabBarRenderContext = tabBarNode->GetRenderContext();
262     CHECK_NULL_RETURN(tabBarRenderContext, jsonBlurStyle);
263     auto styleOption = tabBarRenderContext->GetBackBlurStyle().value_or(BlurStyleOption{});
264     jsonBlurStyle->Put("colorMode", COLOR_MODE[static_cast<int>(styleOption.colorMode)]);
265     jsonBlurStyle->Put("adaptiveColor",
266         ADAPTIVE_COLOR[static_cast<int>(styleOption.adaptiveColor)]);
267     jsonBlurStyle->Put("policy", POLICY[static_cast<int>(styleOption.policy)]);
268     jsonBlurStyle->Put("type", BLUR_TYPE[static_cast<int>(styleOption.blurType)]);
269     jsonBlurStyle->Put("inactiveColor", styleOption.inactiveColor.ColorToString().c_str());
270     jsonBlurStyle->Put("scale", styleOption.scale);
271     return jsonBlurStyle;
272 }
273 
GetFadingEdge() const274 bool TabsNode::GetFadingEdge() const
275 {
276     if (!tabBarId_.has_value()) {
277         return true;
278     }
279     auto tabBarNode = GetFrameNode(V2::TAB_BAR_ETS_TAG, tabBarId_.value());
280     CHECK_NULL_RETURN(tabBarNode, true);
281     auto tabBarProperty = tabBarNode->GetPaintProperty<TabBarPaintProperty>();
282     CHECK_NULL_RETURN(tabBarProperty, true);
283     return tabBarProperty->GetFadingEdge().value_or(true);
284 }
285 
GetBarGridAlign() const286 BarGridColumnOptions TabsNode::GetBarGridAlign() const
287 {
288     BarGridColumnOptions option;
289     if (!tabBarId_.has_value()) {
290         return option;
291     }
292     auto tabBarNode = GetFrameNode(V2::TAB_BAR_ETS_TAG, tabBarId_.value());
293     CHECK_NULL_RETURN(tabBarNode, option);
294     auto tabBarProperty = tabBarNode->GetLayoutProperty<TabBarLayoutProperty>();
295     CHECK_NULL_RETURN(tabBarProperty, option);
296     return tabBarProperty->GetBarGridAlign().value_or(option);
297 }
298 
GetScrollableBarModeOptions() const299 ScrollableBarModeOptions TabsNode::GetScrollableBarModeOptions() const
300 {
301     ScrollableBarModeOptions option;
302     if (!tabBarId_.has_value()) {
303         return option;
304     }
305     auto tabBarNode = GetFrameNode(V2::TAB_BAR_ETS_TAG, tabBarId_.value());
306     CHECK_NULL_RETURN(tabBarNode, option);
307     auto tabBarProperty = tabBarNode->GetLayoutProperty<TabBarLayoutProperty>();
308     CHECK_NULL_RETURN(tabBarProperty, option);
309     return tabBarProperty->GetScrollableBarModeOptions().value_or(option);
310 }
311 
GetAnimationMode() const312 std::string TabsNode::GetAnimationMode() const
313 {
314     std::string ret = "AnimationMode.CONTENT_FIRST";
315     auto tabsPattern = GetPattern<TabsPattern>();
316     CHECK_NULL_RETURN(tabsPattern, ret);
317     TabAnimateMode mode = tabsPattern->GetAnimateMode();
318     switch (mode) {
319         case TabAnimateMode::CONTENT_FIRST:
320             ret = "AnimationMode.CONTENT_FIRST";
321             break;
322         case TabAnimateMode::ACTION_FIRST:
323             ret = "AnimationMode.ACTION_FIRST";
324             break;
325         case TabAnimateMode::NO_ANIMATION:
326             ret = "AnimationMode.NO_ANIMATION";
327             break;
328         case TabAnimateMode::CONTENT_FIRST_WITH_JUMP:
329             ret = "AnimationMode.CONTENT_FIRST_WITH_JUMP";
330             break;
331         case TabAnimateMode::ACTION_FIRST_WITH_JUMP:
332             ret = "AnimationMode.ACTION_FIRST_WITH_JUMP";
333             break;
334         default:
335             ret = "AnimationMode.CONTENT_FIRST";
336             break;
337     }
338     return ret;
339 }
340 
GetEdgeEffect() const341 std::string TabsNode::GetEdgeEffect() const
342 {
343     std::string ret = "EdgeEffect::SPRING";
344     if (!swiperId_.has_value()) {
345         return ret;
346     }
347     auto swiperNode = GetFrameNode(V2::SWIPER_ETS_TAG, swiperId_.value());
348     CHECK_NULL_RETURN(swiperNode, ret);
349     auto paintProperty = swiperNode->GetPaintProperty<SwiperPaintProperty>();
350     CHECK_NULL_RETURN(paintProperty, ret);
351     EdgeEffect edgeEffect = paintProperty->GetEdgeEffect().value();
352     switch (edgeEffect) {
353         case EdgeEffect::SPRING:
354             ret = "EdgeEffect::SPRING";
355             break;
356         case EdgeEffect::FADE:
357             ret = "EdgeEffect::FADE";
358             break;
359         case EdgeEffect::NONE:
360             ret = "EdgeEffect::NONE";
361             break;
362         default:
363             ret = "EdgeEffect::SPRING";
364             break;
365     }
366     return ret;
367 }
368 
GetBarBackgroundEffect() const369 std::unique_ptr<JsonValue> TabsNode::GetBarBackgroundEffect() const
370 {
371     auto jsonEffect = JsonUtil::Create(true);
372     if (!tabBarId_.has_value()) {
373         return jsonEffect;
374     }
375     static const char* ADAPTIVE_COLOR[] = { "AdaptiveColor.Default", "AdaptiveColor.Average" };
376     static const char* POLICY[] = { "BlurStyleActivePolicy.FOLLOWS_WINDOW_ACTIVE_STATE",
377         "BlurStyleActivePolicy.ALWAYS_ACTIVE", "BlurStyleActivePolicy.ALWAYS_INACTIVE" };
378     static const char* BLUR_TYPE[] = { "WITHIN_WINDOW", "BEHIND_WINDOW" };
379     auto tabBarNode = GetFrameNode(V2::TAB_BAR_ETS_TAG, tabBarId_.value());
380     CHECK_NULL_RETURN(tabBarNode, jsonEffect);
381     auto tabBarRenderContext = tabBarNode->GetRenderContext();
382     CHECK_NULL_RETURN(tabBarRenderContext, jsonEffect);
383     EffectOption effectOption = tabBarRenderContext->GetBackgroundEffect().value_or(effectOption);
384     jsonEffect->Put("radius", effectOption.radius.Value());
385     jsonEffect->Put("saturation", effectOption.saturation);
386     jsonEffect->Put("brightness", effectOption.brightness);
387     jsonEffect->Put("color", effectOption.color.ColorToString().c_str());
388     jsonEffect->Put("adaptiveColor", ADAPTIVE_COLOR[static_cast<int32_t>(effectOption.adaptiveColor)]);
389     jsonEffect->Put("policy", POLICY[static_cast<int>(effectOption.policy)]);
390     jsonEffect->Put("type", BLUR_TYPE[static_cast<int>(effectOption.blurType)]);
391     jsonEffect->Put("inactiveColor", effectOption.inactiveColor.ColorToString().c_str());
392     auto grayscale = "[0,0]";
393     if (effectOption.blurOption.grayscale.size() > 1) {
394         grayscale = ("[" + std::to_string(effectOption.blurOption.grayscale[0]) + "," +
395             std::to_string(effectOption.blurOption.grayscale[1]) + "]").c_str();
396     }
397     jsonEffect->Put("blurOption", grayscale);
398     return jsonEffect;
399 }
400 } // namespace OHOS::Ace::NG
401