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 constexpr int32_t ANIMATION_DURATION_DEFAULT = 200;
33 const std::string BAR_BLURSTYLE[] = {
34 "BlurStyle.NONE",
35 "BlurStyle.Thin",
36 "BlurStyle.Regular",
37 "BlurStyle.Thick",
38 "BlurStyle.BACKGROUND_THIN",
39 "BlurStyle.BACKGROUND_REGULAR",
40 "BlurStyle.BACKGROUND_THICK",
41 "BlurStyle.BACKGROUND_ULTRA_THICK",
42 "BlurStyle.COMPONENT_ULTRA_THIN",
43 "BlurStyle.COMPONENT_THIN",
44 "BlurStyle.COMPONENT_REGULAR",
45 "BlurStyle.COMPONENT_THICK",
46 "BlurStyle.COMPONENT_ULTRA_THICK"
47 };
48
49 } // namespace
50
AddChildToGroup(const RefPtr<UINode> & child,int32_t slot)51 void TabsNode::AddChildToGroup(const RefPtr<UINode>& child, int32_t slot)
52 {
53 if (swiperChildren_.find(child->GetId()) != swiperChildren_.end()) {
54 return;
55 }
56
57 swiperChildren_.emplace(child->GetId());
58 auto swiperNode = GetTabs();
59 if (swiperNode) {
60 child->MountToParent(swiperNode);
61 }
62 }
63
ToJsonValue(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter) const64 void TabsNode::ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
65 {
66 FrameNode::ToJsonValue(json, filter);
67 json->PutFixedAttr("scrollable", Scrollable(), filter, FIXED_ATTR_SCROLLABLE);
68 /* no fixed attr below, just return */
69 if (filter.IsFastFilter()) {
70 return;
71 }
72 json->PutExtAttr("index", std::to_string(GetIndex()).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 == LayoutStyle::ALWAYS_AVERAGE_SPLIT) {
79 optionsJson->Put("nonScrollableLayoutStyle", "LayoutStyle.ALWAYS_AVERAGE_SPLIT");
80 } else if (options.nonScrollableLayoutStyle == LayoutStyle::SPACE_BETWEEN_OR_CENTER) {
81 optionsJson->Put("nonScrollableLayoutStyle", "LayoutStyle.SPACE_BETWEEN_OR_CENTER");
82 } else {
83 optionsJson->Put("nonScrollableLayoutStyle", "LayoutStyle.ALWAYS_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("animationMode", GetAnimationMode().c_str(), filter);
98 json->PutExtAttr("edgeEffect", GetEdgeEffect().c_str(), filter);
99
100 auto barGridAlignJson = JsonUtil::Create(true);
101 auto barGridAlign = GetBarGridAlign();
102 barGridAlignJson->Put("gutter", barGridAlign.gutter.ToString().c_str());
103 barGridAlignJson->Put("margin", barGridAlign.margin.ToString().c_str());
104 barGridAlignJson->Put("sm", std::to_string(barGridAlign.sm).c_str());
105 barGridAlignJson->Put("md", std::to_string(barGridAlign.md).c_str());
106 barGridAlignJson->Put("lg", std::to_string(barGridAlign.lg).c_str());
107
108 json->PutExtAttr("barGridAlign", barGridAlignJson, filter);
109 }
110
Scrollable() const111 bool TabsNode::Scrollable() const
112 {
113 if (!swiperId_.has_value()) {
114 return true;
115 }
116 auto swiperNode = GetFrameNode(V2::SWIPER_ETS_TAG, swiperId_.value());
117 CHECK_NULL_RETURN(swiperNode, true);
118 auto props = swiperNode->GetLayoutProperty<SwiperLayoutProperty>();
119 CHECK_NULL_RETURN(props, true);
120 return !props->GetDisableSwipe().value_or(false);
121 }
122
GetAnimationDuration() const123 int32_t TabsNode::GetAnimationDuration() const
124 {
125 if (!swiperId_.has_value()) {
126 return ANIMATION_DURATION_DEFAULT;
127 }
128 auto swiperNode = GetFrameNode(V2::SWIPER_ETS_TAG, swiperId_.value());
129 CHECK_NULL_RETURN(swiperNode, ANIMATION_DURATION_DEFAULT);
130 auto paintProperty = swiperNode->GetPaintProperty<SwiperPaintProperty>();
131 CHECK_NULL_RETURN(paintProperty, ANIMATION_DURATION_DEFAULT);
132 return paintProperty->GetDuration().value_or(ANIMATION_DURATION_DEFAULT);
133 }
134
GetIndex() const135 int32_t TabsNode::GetIndex() const
136 {
137 if (!swiperId_.has_value()) {
138 return 0;
139 }
140 auto swiperNode = GetFrameNode(V2::SWIPER_ETS_TAG, swiperId_.value());
141 CHECK_NULL_RETURN(swiperNode, 0);
142 auto layoutProperty = swiperNode->GetLayoutProperty<SwiperLayoutProperty>();
143 CHECK_NULL_RETURN(layoutProperty, 0);
144 return layoutProperty->GetIndex().value_or(0);
145 }
146
GetTabBarMode() const147 TabBarMode TabsNode::GetTabBarMode() const
148 {
149 if (!tabBarId_.has_value()) {
150 return TabBarMode::FIXED;
151 }
152 auto tabBarNode = GetFrameNode(V2::TAB_BAR_ETS_TAG, tabBarId_.value());
153 CHECK_NULL_RETURN(tabBarNode, TabBarMode::FIXED);
154 auto tabBarProperty = tabBarNode->GetLayoutProperty<TabBarLayoutProperty>();
155 CHECK_NULL_RETURN(tabBarProperty, TabBarMode::FIXED);
156 return tabBarProperty->GetTabBarMode().value_or(TabBarMode::FIXED);
157 }
158
GetBarWidth() const159 Dimension TabsNode::GetBarWidth() const
160 {
161 if (!tabBarId_.has_value()) {
162 return 0.0_vp;
163 }
164 auto tabBarNode = GetFrameNode(V2::TAB_BAR_ETS_TAG, tabBarId_.value());
165 CHECK_NULL_RETURN(tabBarNode, 0.0_vp);
166 auto geometryNode = tabBarNode->GetGeometryNode();
167 CHECK_NULL_RETURN(geometryNode, 0.0_vp);
168 auto frameSize = geometryNode->GetFrameSize();
169 return Dimension(PipelineBase::Px2VpWithCurrentDensity(frameSize.Width()), DimensionUnit::VP);
170 }
171
GetBarAdaptiveHeight() const172 bool TabsNode::GetBarAdaptiveHeight() const
173 {
174 if (!tabBarId_.has_value()) {
175 return false;
176 }
177 auto tabBarNode = GetFrameNode(V2::TAB_BAR_ETS_TAG, tabBarId_.value());
178 CHECK_NULL_RETURN(tabBarNode, false);
179 auto tabBarProperty = tabBarNode->GetLayoutProperty<TabBarLayoutProperty>();
180 CHECK_NULL_RETURN(tabBarProperty, false);
181 return tabBarProperty->GetBarAdaptiveHeight().value_or(false);
182 }
183
GetBarHeight() const184 Dimension TabsNode::GetBarHeight() const
185 {
186 if (!tabBarId_.has_value()) {
187 return 0.0_vp;
188 }
189 auto tabBarNode = GetFrameNode(V2::TAB_BAR_ETS_TAG, tabBarId_.value());
190 CHECK_NULL_RETURN(tabBarNode, 0.0_vp);
191 auto geometryNode = tabBarNode->GetGeometryNode();
192 CHECK_NULL_RETURN(geometryNode, 0.0_vp);
193 auto frameSize = geometryNode->GetFrameSize();
194 return Dimension(PipelineBase::Px2VpWithCurrentDensity(frameSize.Height()), DimensionUnit::VP);
195 }
196
GetBarBackgroundColor() const197 Color TabsNode::GetBarBackgroundColor() const
198 {
199 auto backgroundColor = Color::BLACK.BlendOpacity(0.0f);
200 if (!tabBarId_.has_value()) {
201 return backgroundColor;
202 }
203 auto tabBarNode = GetFrameNode(V2::TAB_BAR_ETS_TAG, tabBarId_.value());
204 CHECK_NULL_RETURN(tabBarNode, backgroundColor);
205 auto tabBarPaintProperty = tabBarNode->GetPaintProperty<TabBarPaintProperty>();
206 CHECK_NULL_RETURN(tabBarPaintProperty, backgroundColor);
207 return tabBarPaintProperty->GetBarBackgroundColor().value_or(backgroundColor);
208 }
209
GetBarBackgroundBlurStyle() const210 BlurStyle TabsNode::GetBarBackgroundBlurStyle() const
211 {
212 auto barBackgroundBlurStyle = BlurStyle::NO_MATERIAL;
213 if (!tabBarId_.has_value()) {
214 return barBackgroundBlurStyle;
215 }
216 auto tabBarNode = GetFrameNode(V2::TAB_BAR_ETS_TAG, tabBarId_.value());
217 CHECK_NULL_RETURN(tabBarNode, barBackgroundBlurStyle);
218 auto tabBarPaintProperty = tabBarNode->GetPaintProperty<TabBarPaintProperty>();
219 CHECK_NULL_RETURN(tabBarPaintProperty, barBackgroundBlurStyle);
220 return tabBarPaintProperty->GetTabBarBlurStyle().value_or(barBackgroundBlurStyle);
221 }
222
GetFadingEdge() const223 bool TabsNode::GetFadingEdge() const
224 {
225 if (!tabBarId_.has_value()) {
226 return true;
227 }
228 auto tabBarNode = GetFrameNode(V2::TAB_BAR_ETS_TAG, tabBarId_.value());
229 CHECK_NULL_RETURN(tabBarNode, true);
230 auto tabBarProperty = tabBarNode->GetPaintProperty<TabBarPaintProperty>();
231 CHECK_NULL_RETURN(tabBarProperty, true);
232 return tabBarProperty->GetFadingEdge().value_or(true);
233 }
234
GetBarGridAlign() const235 BarGridColumnOptions TabsNode::GetBarGridAlign() const
236 {
237 BarGridColumnOptions option;
238 if (!tabBarId_.has_value()) {
239 return option;
240 }
241 auto tabBarNode = GetFrameNode(V2::TAB_BAR_ETS_TAG, tabBarId_.value());
242 CHECK_NULL_RETURN(tabBarNode, option);
243 auto tabBarProperty = tabBarNode->GetLayoutProperty<TabBarLayoutProperty>();
244 CHECK_NULL_RETURN(tabBarProperty, option);
245 return tabBarProperty->GetBarGridAlign().value_or(option);
246 }
247
GetScrollableBarModeOptions() const248 ScrollableBarModeOptions TabsNode::GetScrollableBarModeOptions() const
249 {
250 ScrollableBarModeOptions option;
251 if (!tabBarId_.has_value()) {
252 return option;
253 }
254 auto tabBarNode = GetFrameNode(V2::TAB_BAR_ETS_TAG, tabBarId_.value());
255 CHECK_NULL_RETURN(tabBarNode, option);
256 auto tabBarProperty = tabBarNode->GetLayoutProperty<TabBarLayoutProperty>();
257 CHECK_NULL_RETURN(tabBarProperty, option);
258 return tabBarProperty->GetScrollableBarModeOptions().value_or(option);
259 }
260
GetAnimationMode() const261 std::string TabsNode::GetAnimationMode() const
262 {
263 std::string ret = "AnimationMode.CONTENT_FIRST";
264 auto tabsPattern = GetPattern<TabsPattern>();
265 CHECK_NULL_RETURN(tabsPattern, ret);
266 TabAnimateMode mode = tabsPattern->GetAnimateMode();
267 switch (mode) {
268 case TabAnimateMode::CONTENT_FIRST:
269 ret = "AnimationMode.CONTENT_FIRST";
270 break;
271 case TabAnimateMode::ACTION_FIRST:
272 ret = "AnimationMode.ACTION_FIRST";
273 break;
274 case TabAnimateMode::NO_ANIMATION:
275 ret = "AnimationMode.NO_ANIMATION";
276 break;
277 default:
278 ret = "AnimationMode.CONTENT_FIRST";
279 break;
280 }
281 return ret;
282 }
283
GetEdgeEffect() const284 std::string TabsNode::GetEdgeEffect() const
285 {
286 std::string ret = "EdgeEffect::SPRING";
287 if (!swiperId_.has_value()) {
288 return ret;
289 }
290 auto swiperNode = GetFrameNode(V2::SWIPER_ETS_TAG, swiperId_.value());
291 CHECK_NULL_RETURN(swiperNode, ret);
292 auto paintProperty = swiperNode->GetPaintProperty<SwiperPaintProperty>();
293 CHECK_NULL_RETURN(paintProperty, ret);
294 EdgeEffect edgeEffect = paintProperty->GetEdgeEffect().value();
295 switch (edgeEffect) {
296 case EdgeEffect::SPRING:
297 ret = "EdgeEffect::SPRING";
298 break;
299 case EdgeEffect::FADE:
300 ret = "EdgeEffect::FADE";
301 break;
302 case EdgeEffect::NONE:
303 ret = "EdgeEffect::NONE";
304 break;
305 default:
306 ret = "EdgeEffect::SPRING";
307 break;
308 }
309 return ret;
310 }
311 } // namespace OHOS::Ace::NG
312