• 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("animationDuration", GetAnimationDuration(), filter);
73     if (GetTabBarMode() == TabBarMode::SCROLLABLE) {
74         auto optionsJson = JsonUtil::Create(true);
75         auto options = GetScrollableBarModeOptions();
76         optionsJson->Put("margin", options.margin.ToString().c_str());
77         if (options.nonScrollableLayoutStyle.value_or(LayoutStyle::ALWAYS_CENTER) == LayoutStyle::ALWAYS_CENTER) {
78             optionsJson->Put("nonScrollableLayoutStyle", "LayoutStyle.ALWAYS_CENTER");
79         } else if (options.nonScrollableLayoutStyle.value() == LayoutStyle::ALWAYS_AVERAGE_SPLIT) {
80             optionsJson->Put("nonScrollableLayoutStyle", "LayoutStyle.ALWAYS_AVERAGE_SPLIT");
81         } else if (options.nonScrollableLayoutStyle.value() == LayoutStyle::SPACE_BETWEEN_OR_CENTER) {
82             optionsJson->Put("nonScrollableLayoutStyle", "LayoutStyle.SPACE_BETWEEN_OR_CENTER");
83         }
84         std::string barMode = "BarMode.Scrollable," + optionsJson->ToString();
85         json->PutExtAttr("barMode", barMode.c_str(), filter);
86     } else {
87         json->PutExtAttr("barMode", "BarMode.Fixed", filter);
88     }
89     json->PutExtAttr("barWidth", std::to_string(GetBarWidth().Value()).c_str(), filter);
90     json->PutExtAttr("barHeight",
91         GetBarAdaptiveHeight() ? "auto" : std::to_string(GetBarHeight().Value()).c_str(), filter);
92     json->PutExtAttr("fadingEdge", GetFadingEdge() ? "true" : "false", filter);
93     json->PutExtAttr("barBackgroundColor", GetBarBackgroundColor().ColorToString().c_str(), filter);
94     json->PutExtAttr("barBackgroundBlurStyle",
95         BAR_BLURSTYLE[static_cast<int32_t>(GetBarBackgroundBlurStyle())].c_str(), filter);
96     json->PutExtAttr("barBackgroundBlurStyleOptions", GetBarBackgroundBlurStyleOptions(), filter);
97     json->PutExtAttr("animationMode", GetAnimationMode().c_str(), filter);
98     json->PutExtAttr("edgeEffect", GetEdgeEffect().c_str(), filter);
99     json->PutExtAttr("barBackgroundEffect", GetBarBackgroundEffect(), filter);
100 
101     auto barGridAlignJson = JsonUtil::Create(true);
102     auto barGridAlign = GetBarGridAlign();
103     barGridAlignJson->Put("gutter", barGridAlign.gutter.ToString().c_str());
104     barGridAlignJson->Put("margin", barGridAlign.margin.ToString().c_str());
105     barGridAlignJson->Put("sm", std::to_string(barGridAlign.sm).c_str());
106     barGridAlignJson->Put("md", std::to_string(barGridAlign.md).c_str());
107     barGridAlignJson->Put("lg", std::to_string(barGridAlign.lg).c_str());
108 
109     json->PutExtAttr("barGridAlign", barGridAlignJson, filter);
110 }
111 
ToTreeJson(std::unique_ptr<JsonValue> & json,const InspectorConfig & config) const112 void TabsNode::ToTreeJson(std::unique_ptr<JsonValue>& json, const InspectorConfig& config) const
113 {
114     FrameNode::ToTreeJson(json, config);
115     if (config.contentOnly) {
116         return;
117     }
118     json->Put(TreeKey::SCROLLABLE, Scrollable());
119 }
120 
Scrollable() const121 bool TabsNode::Scrollable() const
122 {
123     if (!swiperId_.has_value()) {
124         return true;
125     }
126     auto swiperNode = GetFrameNode(V2::SWIPER_ETS_TAG, swiperId_.value());
127     CHECK_NULL_RETURN(swiperNode, true);
128     auto props = swiperNode->GetLayoutProperty<SwiperLayoutProperty>();
129     CHECK_NULL_RETURN(props, true);
130     return !props->GetDisableSwipe().value_or(false);
131 }
132 
GetAnimationDuration() const133 int32_t TabsNode::GetAnimationDuration() const
134 {
135     int32_t duration = 0;
136     if (!tabBarId_.has_value()) {
137         return duration;
138     }
139     auto tabBarNode = GetFrameNode(V2::TAB_BAR_ETS_TAG, tabBarId_.value());
140     CHECK_NULL_RETURN(tabBarNode, duration);
141     auto tabBarPattern = tabBarNode->GetPattern<TabBarPattern>();
142     CHECK_NULL_RETURN(tabBarPattern, duration);
143     tabBarPattern->UpdateAnimationDuration();
144     return tabBarPattern->GetAnimationDuration().value_or(duration);
145 }
146 
GetIndex() const147 int32_t TabsNode::GetIndex() const
148 {
149     if (!swiperId_.has_value()) {
150         return 0;
151     }
152     auto swiperNode = GetFrameNode(V2::SWIPER_ETS_TAG, swiperId_.value());
153     CHECK_NULL_RETURN(swiperNode, 0);
154     auto layoutProperty = swiperNode->GetLayoutProperty<SwiperLayoutProperty>();
155     CHECK_NULL_RETURN(layoutProperty, 0);
156     return layoutProperty->GetIndex().value_or(0);
157 }
158 
GetTabBarMode() const159 TabBarMode TabsNode::GetTabBarMode() const
160 {
161     if (!tabBarId_.has_value()) {
162         return TabBarMode::FIXED;
163     }
164     auto tabBarNode = GetFrameNode(V2::TAB_BAR_ETS_TAG, tabBarId_.value());
165     CHECK_NULL_RETURN(tabBarNode, TabBarMode::FIXED);
166     auto tabBarProperty = tabBarNode->GetLayoutProperty<TabBarLayoutProperty>();
167     CHECK_NULL_RETURN(tabBarProperty, TabBarMode::FIXED);
168     return tabBarProperty->GetTabBarMode().value_or(TabBarMode::FIXED);
169 }
170 
GetBarWidth() const171 Dimension TabsNode::GetBarWidth() const
172 {
173     if (!tabBarId_.has_value()) {
174         return 0.0_vp;
175     }
176     auto tabBarNode = GetFrameNode(V2::TAB_BAR_ETS_TAG, tabBarId_.value());
177     CHECK_NULL_RETURN(tabBarNode, 0.0_vp);
178     auto geometryNode = tabBarNode->GetGeometryNode();
179     CHECK_NULL_RETURN(geometryNode, 0.0_vp);
180     auto frameSize = geometryNode->GetFrameSize();
181     return Dimension(PipelineBase::Px2VpWithCurrentDensity(frameSize.Width()), DimensionUnit::VP);
182 }
183 
GetBarAdaptiveHeight() const184 bool TabsNode::GetBarAdaptiveHeight() const
185 {
186     if (!tabBarId_.has_value()) {
187         return false;
188     }
189     auto tabBarNode = GetFrameNode(V2::TAB_BAR_ETS_TAG, tabBarId_.value());
190     CHECK_NULL_RETURN(tabBarNode, false);
191     auto tabBarProperty = tabBarNode->GetLayoutProperty<TabBarLayoutProperty>();
192     CHECK_NULL_RETURN(tabBarProperty, false);
193     return tabBarProperty->GetBarAdaptiveHeight().value_or(false);
194 }
195 
GetBarHeight() const196 Dimension TabsNode::GetBarHeight() const
197 {
198     if (!tabBarId_.has_value()) {
199         return 0.0_vp;
200     }
201     auto tabBarNode = GetFrameNode(V2::TAB_BAR_ETS_TAG, tabBarId_.value());
202     CHECK_NULL_RETURN(tabBarNode, 0.0_vp);
203     auto geometryNode = tabBarNode->GetGeometryNode();
204     CHECK_NULL_RETURN(geometryNode, 0.0_vp);
205     auto frameSize = geometryNode->GetFrameSize();
206     return Dimension(PipelineBase::Px2VpWithCurrentDensity(frameSize.Height()), DimensionUnit::VP);
207 }
208 
GetBarBackgroundColor() const209 Color TabsNode::GetBarBackgroundColor() const
210 {
211     auto backgroundColor = Color::BLACK.BlendOpacity(0.0f);
212     if (!tabBarId_.has_value()) {
213         return backgroundColor;
214     }
215     auto tabBarNode = GetFrameNode(V2::TAB_BAR_ETS_TAG, tabBarId_.value());
216     CHECK_NULL_RETURN(tabBarNode, backgroundColor);
217     auto tabBarRenderContext = tabBarNode->GetRenderContext();
218     CHECK_NULL_RETURN(tabBarRenderContext, backgroundColor);
219     return tabBarRenderContext->GetBackgroundColor().value_or(backgroundColor);
220 }
221 
GetBarBackgroundBlurStyle() const222 BlurStyle TabsNode::GetBarBackgroundBlurStyle() const
223 {
224     auto barBackgroundBlurStyle = BlurStyle::NO_MATERIAL;
225     if (!tabBarId_.has_value()) {
226         return barBackgroundBlurStyle;
227     }
228     auto tabBarNode = GetFrameNode(V2::TAB_BAR_ETS_TAG, tabBarId_.value());
229     CHECK_NULL_RETURN(tabBarNode, barBackgroundBlurStyle);
230     auto tabBarRenderContext = tabBarNode->GetRenderContext();
231     CHECK_NULL_RETURN(tabBarRenderContext, barBackgroundBlurStyle);
232     auto styleOption = tabBarRenderContext->GetBackBlurStyle().value_or(BlurStyleOption{});
233     return styleOption.blurStyle;
234 }
235 
GetBarBackgroundBlurStyleOptions() const236 std::unique_ptr<JsonValue> TabsNode::GetBarBackgroundBlurStyleOptions() const
237 {
238     auto jsonBlurStyle = JsonUtil::Create(true);
239     if (!tabBarId_.has_value()) {
240         return jsonBlurStyle;
241     }
242     static const char* COLOR_MODE[] = { "ThemeColorMode.System", "ThemeColorMode.Light", "ThemeColorMode.Dark" };
243     static const char* ADAPTIVE_COLOR[] = { "AdaptiveColor.Default", "AdaptiveColor.Average" };
244     static const char* POLICY[] = { "BlurStyleActivePolicy.FOLLOWS_WINDOW_ACTIVE_STATE",
245         "BlurStyleActivePolicy.ALWAYS_ACTIVE", "BlurStyleActivePolicy.ALWAYS_INACTIVE" };
246     static const char* BLUR_TYPE[] = { "BlurType.WITHIN_WINDOW", "BlurType.BEHIND_WINDOW" };
247     auto tabBarNode = GetFrameNode(V2::TAB_BAR_ETS_TAG, tabBarId_.value());
248     CHECK_NULL_RETURN(tabBarNode, jsonBlurStyle);
249     auto tabBarRenderContext = tabBarNode->GetRenderContext();
250     CHECK_NULL_RETURN(tabBarRenderContext, jsonBlurStyle);
251     auto styleOption = tabBarRenderContext->GetBackBlurStyle().value_or(BlurStyleOption{});
252     jsonBlurStyle->Put("colorMode", COLOR_MODE[static_cast<int>(styleOption.colorMode)]);
253     jsonBlurStyle->Put("adaptiveColor",
254         ADAPTIVE_COLOR[static_cast<int>(styleOption.adaptiveColor)]);
255     jsonBlurStyle->Put("policy", POLICY[static_cast<int>(styleOption.policy)]);
256     jsonBlurStyle->Put("type", BLUR_TYPE[static_cast<int>(styleOption.blurType)]);
257     jsonBlurStyle->Put("inactiveColor", styleOption.inactiveColor.ColorToString().c_str());
258     jsonBlurStyle->Put("scale", styleOption.scale);
259     return jsonBlurStyle;
260 }
261 
GetFadingEdge() const262 bool TabsNode::GetFadingEdge() const
263 {
264     if (!tabBarId_.has_value()) {
265         return true;
266     }
267     auto tabBarNode = GetFrameNode(V2::TAB_BAR_ETS_TAG, tabBarId_.value());
268     CHECK_NULL_RETURN(tabBarNode, true);
269     auto tabBarProperty = tabBarNode->GetPaintProperty<TabBarPaintProperty>();
270     CHECK_NULL_RETURN(tabBarProperty, true);
271     return tabBarProperty->GetFadingEdge().value_or(true);
272 }
273 
GetBarGridAlign() const274 BarGridColumnOptions TabsNode::GetBarGridAlign() const
275 {
276     BarGridColumnOptions option;
277     if (!tabBarId_.has_value()) {
278         return option;
279     }
280     auto tabBarNode = GetFrameNode(V2::TAB_BAR_ETS_TAG, tabBarId_.value());
281     CHECK_NULL_RETURN(tabBarNode, option);
282     auto tabBarProperty = tabBarNode->GetLayoutProperty<TabBarLayoutProperty>();
283     CHECK_NULL_RETURN(tabBarProperty, option);
284     return tabBarProperty->GetBarGridAlign().value_or(option);
285 }
286 
GetScrollableBarModeOptions() const287 ScrollableBarModeOptions TabsNode::GetScrollableBarModeOptions() const
288 {
289     ScrollableBarModeOptions option;
290     if (!tabBarId_.has_value()) {
291         return option;
292     }
293     auto tabBarNode = GetFrameNode(V2::TAB_BAR_ETS_TAG, tabBarId_.value());
294     CHECK_NULL_RETURN(tabBarNode, option);
295     auto tabBarProperty = tabBarNode->GetLayoutProperty<TabBarLayoutProperty>();
296     CHECK_NULL_RETURN(tabBarProperty, option);
297     return tabBarProperty->GetScrollableBarModeOptions().value_or(option);
298 }
299 
GetAnimationMode() const300 std::string TabsNode::GetAnimationMode() const
301 {
302     std::string ret = "AnimationMode.CONTENT_FIRST";
303     auto tabsPattern = GetPattern<TabsPattern>();
304     CHECK_NULL_RETURN(tabsPattern, ret);
305     TabAnimateMode mode = tabsPattern->GetAnimateMode();
306     switch (mode) {
307         case TabAnimateMode::CONTENT_FIRST:
308             ret = "AnimationMode.CONTENT_FIRST";
309             break;
310         case TabAnimateMode::ACTION_FIRST:
311             ret = "AnimationMode.ACTION_FIRST";
312             break;
313         case TabAnimateMode::NO_ANIMATION:
314             ret = "AnimationMode.NO_ANIMATION";
315             break;
316         case TabAnimateMode::CONTENT_FIRST_WITH_JUMP:
317             ret = "AnimationMode.CONTENT_FIRST_WITH_JUMP";
318             break;
319         case TabAnimateMode::ACTION_FIRST_WITH_JUMP:
320             ret = "AnimationMode.ACTION_FIRST_WITH_JUMP";
321             break;
322         default:
323             ret = "AnimationMode.CONTENT_FIRST";
324             break;
325     }
326     return ret;
327 }
328 
GetEdgeEffect() const329 std::string TabsNode::GetEdgeEffect() const
330 {
331     std::string ret = "EdgeEffect::SPRING";
332     if (!swiperId_.has_value()) {
333         return ret;
334     }
335     auto swiperNode = GetFrameNode(V2::SWIPER_ETS_TAG, swiperId_.value());
336     CHECK_NULL_RETURN(swiperNode, ret);
337     auto paintProperty = swiperNode->GetPaintProperty<SwiperPaintProperty>();
338     CHECK_NULL_RETURN(paintProperty, ret);
339     EdgeEffect edgeEffect = paintProperty->GetEdgeEffect().value();
340     switch (edgeEffect) {
341         case EdgeEffect::SPRING:
342             ret = "EdgeEffect::SPRING";
343             break;
344         case EdgeEffect::FADE:
345             ret = "EdgeEffect::FADE";
346             break;
347         case EdgeEffect::NONE:
348             ret = "EdgeEffect::NONE";
349             break;
350         default:
351             ret = "EdgeEffect::SPRING";
352             break;
353     }
354     return ret;
355 }
356 
GetBarBackgroundEffect() const357 std::unique_ptr<JsonValue> TabsNode::GetBarBackgroundEffect() const
358 {
359     auto jsonEffect = JsonUtil::Create(true);
360     if (!tabBarId_.has_value()) {
361         return jsonEffect;
362     }
363     static const char* ADAPTIVE_COLOR[] = { "AdaptiveColor.Default", "AdaptiveColor.Average" };
364     static const char* POLICY[] = { "BlurStyleActivePolicy.FOLLOWS_WINDOW_ACTIVE_STATE",
365         "BlurStyleActivePolicy.ALWAYS_ACTIVE", "BlurStyleActivePolicy.ALWAYS_INACTIVE" };
366     static const char* BLUR_TYPE[] = { "WITHIN_WINDOW", "BEHIND_WINDOW" };
367     auto tabBarNode = GetFrameNode(V2::TAB_BAR_ETS_TAG, tabBarId_.value());
368     CHECK_NULL_RETURN(tabBarNode, jsonEffect);
369     auto tabBarRenderContext = tabBarNode->GetRenderContext();
370     CHECK_NULL_RETURN(tabBarRenderContext, jsonEffect);
371     EffectOption effectOption = tabBarRenderContext->GetBackgroundEffect().value_or(effectOption);
372     jsonEffect->Put("radius", effectOption.radius.Value());
373     jsonEffect->Put("saturation", effectOption.saturation);
374     jsonEffect->Put("brightness", effectOption.brightness);
375     jsonEffect->Put("color", effectOption.color.ColorToString().c_str());
376     jsonEffect->Put("adaptiveColor", ADAPTIVE_COLOR[static_cast<int32_t>(effectOption.adaptiveColor)]);
377     jsonEffect->Put("policy", POLICY[static_cast<int>(effectOption.policy)]);
378     jsonEffect->Put("type", BLUR_TYPE[static_cast<int>(effectOption.blurType)]);
379     jsonEffect->Put("inactiveColor", effectOption.inactiveColor.ColorToString().c_str());
380     auto grayscale = "[0,0]";
381     if (effectOption.blurOption.grayscale.size() > 1) {
382         grayscale = ("[" + std::to_string(effectOption.blurOption.grayscale[0]) + "," +
383             std::to_string(effectOption.blurOption.grayscale[1]) + "]").c_str();
384     }
385     jsonEffect->Put("blurOption", grayscale);
386     return jsonEffect;
387 }
388 } // namespace OHOS::Ace::NG
389