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/tab_content_node.h"
17
18 #include "core/components_ng/base/inspector_filter.h"
19 #include "core/components_ng/pattern/swiper/swiper_pattern.h"
20 #include "core/components_ng/pattern/tabs/tab_content_model_ng.h"
21 #include "core/components_ng/pattern/tabs/tab_content_pattern.h"
22
23 namespace OHOS::Ace::NG {
24 namespace {
25 constexpr int DEFAULT_MAXLINES = 1;
26 } // namespace
27
OnAttachToMainTree(bool recursive)28 void TabContentNode::OnAttachToMainTree(bool recursive)
29 {
30 FrameNode::OnAttachToMainTree(recursive);
31 if (!UseOffscreenProcess()) {
32 ProcessTabBarItem();
33 }
34 FrameNode::OnOffscreenProcess(recursive);
35 }
36
OnDetachFromMainTree(bool recursive,PipelineContext * context)37 void TabContentNode::OnDetachFromMainTree(bool recursive, PipelineContext* context)
38 {
39 FrameNode::OnDetachFromMainTree(recursive, context);
40 auto tabs = TabContentModelNG::FindTabsNode(Referenced::Claim(this));
41 CHECK_NULL_VOID(tabs);
42
43 if (!tabs->IsOnMainTree()) {
44 return;
45 }
46
47 TabContentModelNG::RemoveTabBarItem(Referenced::Claim(this));
48 }
49
OnOffscreenProcess(bool recursive)50 void TabContentNode::OnOffscreenProcess(bool recursive)
51 {
52 ProcessTabBarItem();
53 FrameNode::OnOffscreenProcess(recursive);
54 }
55
ProcessTabBarItem()56 void TabContentNode::ProcessTabBarItem()
57 {
58 auto tabs = TabContentModelNG::FindTabsNode(Referenced::Claim(this));
59 CHECK_NULL_VOID(tabs);
60 auto swiper = tabs->GetTabs();
61 CHECK_NULL_VOID(swiper);
62 auto myIndex = swiper->GetChildFlatIndex(GetId()).second;
63 bool update = false;
64 #ifdef UICAST_COMPONENT_SUPPORTED
65 do {
66 auto container = Container::Current();
67 CHECK_NULL_BREAK(container);
68 auto distributedUI = container->GetDistributedUI();
69 CHECK_NULL_BREAK(distributedUI);
70 if (distributedUI->IsSinkMode()) {
71 update = true;
72 }
73 } while (false);
74 #endif
75 TabContentModelNG::AddTabBarItem(Referenced::Claim(this), myIndex, update);
76 }
77
GetOrCreateTabContentNode(const std::string & tag,int32_t nodeId,const std::function<RefPtr<Pattern> (void)> & patternCreator)78 RefPtr<TabContentNode> TabContentNode::GetOrCreateTabContentNode(
79 const std::string& tag, int32_t nodeId, const std::function<RefPtr<Pattern>(void)>& patternCreator)
80 {
81 auto node = GetFrameNode(tag, nodeId);
82 auto tabContentNode = AceType::DynamicCast<TabContentNode>(node);
83
84 if (tabContentNode) {
85 return tabContentNode;
86 }
87
88 auto pattern = patternCreator ? patternCreator() : AceType::MakeRefPtr<Pattern>();
89 tabContentNode = AceType::MakeRefPtr<TabContentNode>(tag, nodeId, pattern, false);
90 tabContentNode->InitializePatternAndContext();
91 ElementRegister::GetInstance()->AddUINode(tabContentNode);
92 return tabContentNode;
93 }
94
ToJsonValue(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter) const95 void TabContentNode::ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
96 {
97 FrameNode::ToJsonValue(json, filter);
98 /* no fixed attr below, just return */
99 if (filter.IsFastFilter()) {
100 return;
101 }
102 auto pipelineContext = GetContext();
103 CHECK_NULL_VOID(pipelineContext);
104 auto tabTheme = pipelineContext->GetTheme<TabTheme>();
105 CHECK_NULL_VOID(tabTheme);
106 auto tabBar = JsonUtil::Create(true);
107 auto tabContentPattern = GetPattern<TabContentPattern>();
108 CHECK_NULL_VOID(tabContentPattern);
109
110 auto indicator = JsonUtil::Create(true);
111 auto indicatorStyle = tabContentPattern->GetIndicatorStyle();
112 indicator->Put("color", indicatorStyle.color.ColorToString().c_str());
113 indicator->Put("height", indicatorStyle.height.ToString().c_str());
114 indicator->Put("width", indicatorStyle.width.ToString().c_str());
115 indicator->Put("borderRadius", indicatorStyle.borderRadius.ToString().c_str());
116 indicator->Put("marginTop", indicatorStyle.marginTop.ToString().c_str());
117 tabBar->Put("indicator", indicator);
118
119 auto board = JsonUtil::Create(true);
120 auto boardStyle = tabContentPattern->GetBoardStyle();
121 board->Put("borderRadius", boardStyle.borderRadius.ToString().c_str());
122 tabBar->Put("board", board);
123
124 tabBar->Put("selectedMode", tabContentPattern->GetSelectedMode() == SelectedMode::INDICATOR ?
125 "SelectedMode.INDICATOR" : "SelectedMode.BOARD");
126
127 auto font = JsonUtil::Create(true);
128 auto labelStyle = tabContentPattern->GetLabelStyle();
129 auto layoutMode = tabContentPattern->GetBottomTabBarStyle().layoutMode;
130 Dimension fontSize;
131 if (labelStyle.fontSize.has_value()) {
132 fontSize = labelStyle.fontSize.value();
133 } else if (layoutMode == LayoutMode::VERTICAL) {
134 fontSize = tabTheme->GetBottomTabTextSize();
135 } else if (layoutMode == LayoutMode::HORIZONTAL) {
136 fontSize = tabTheme->GetBottomTabHorizontalTextSize();
137 } else {
138 fontSize = GetDefaultFontSize();
139 }
140 font->Put("size", fontSize.ToString().c_str());
141 font->Put("weight",
142 V2::ConvertWrapFontWeightToStirng(labelStyle.fontWeight.value_or(FontWeight::NORMAL)).c_str());
143 std::vector<std::string> emptyFontFamily = { "HarmonyOS Sans" };
144 auto fontFamilyVector = labelStyle.fontFamily.value_or(emptyFontFamily);
145 std::string fontFamily = fontFamilyVector.at(0);
146 for (uint32_t i = 1; i < fontFamilyVector.size(); ++i) {
147 fontFamily += ',' + fontFamilyVector.at(i);
148 }
149 font->Put("family", fontFamily.c_str());
150 font->Put("style", labelStyle.fontStyle.value_or(Ace::FontStyle::NORMAL) == Ace::FontStyle::NORMAL
151 ? "FontStyle.Normal"
152 : "FontStyle.Italic");
153
154 auto label = JsonUtil::Create(true);
155 label->Put("overflow",
156 V2::ConvertWrapTextOverflowToString(labelStyle.textOverflow.value_or(TextOverflow::ELLIPSIS)).c_str());
157 label->Put("maxLines", std::to_string(labelStyle.maxLines.value_or(DEFAULT_MAXLINES)).c_str());
158 label->Put("minFontSize", labelStyle.minFontSize.value_or(Dimension(0)).ToString().c_str());
159 label->Put("maxFontSize", labelStyle.maxFontSize.value_or(Dimension(0)).ToString().c_str());
160 label->Put("heightAdaptivePolicy", V2::ConvertWrapTextHeightAdaptivePolicyToString(
161 labelStyle.heightAdaptivePolicy.value_or(TextHeightAdaptivePolicy::MAX_LINES_FIRST)).c_str());
162 label->Put("font", font);
163 label->Put("unselectedColor", labelStyle.unselectedColor.value_or(
164 tabTheme->GetSubTabTextOffColor()).ColorToString().c_str());
165 auto selectColor = tabContentPattern->GetSelectedMode() == SelectedMode::BOARD &&
166 GetTabBarAxis() == Axis::HORIZONTAL ? tabTheme->GetSubTabBoardTextOnColor() : tabTheme->GetSubTabTextOnColor();
167 label->Put("selectedColor", labelStyle.selectedColor.value_or(selectColor).ColorToString().c_str());
168 tabBar->Put("labelStyle", label);
169
170 auto iconStyle = tabContentPattern->GetIconStyle();
171 auto icon = JsonUtil::Create(true);
172 icon->Put("unselectedColor", iconStyle.unselectedColor.value_or(
173 tabTheme->GetBottomTabIconOff()).ColorToString().c_str());
174 icon->Put("selectedColor", iconStyle.selectedColor.value_or(
175 tabTheme->GetBottomTabIconOn()).ColorToString().c_str());
176 tabBar->Put("iconStyle", icon);
177
178 tabBar->Put("padding", tabContentPattern->GetPadding().ToJsonString().c_str());
179 tabBar->Put(
180 "verticalAlign", ConvertFlexAlignToString(tabContentPattern->GetBottomTabBarStyle().verticalAlign).c_str());
181 tabBar->Put("layoutMode", ConvertLayoutModeToString(layoutMode).c_str());
182 tabBar->Put(
183 "symmetricExtensible", tabContentPattern->GetBottomTabBarStyle().symmetricExtensible ? "true" : "false");
184 tabBar->Put("id", tabContentPattern->GetId().c_str());
185
186 json->PutExtAttr("tabBar", tabBar, filter);
187 }
188
GetTabBarAxis() const189 Axis TabContentNode::GetTabBarAxis() const
190 {
191 if (!tabBarItemId_.has_value()) {
192 return Axis::HORIZONTAL;
193 }
194 auto columnNode = GetFrameNode(V2::COLUMN_ETS_TAG, tabBarItemId_.value());
195 CHECK_NULL_RETURN(columnNode, Axis::HORIZONTAL);
196 auto tabBarNode = AceType::DynamicCast<FrameNode>(columnNode->GetParent());
197 CHECK_NULL_RETURN(tabBarNode, Axis::HORIZONTAL);
198 auto tabBarLayoutProperty = tabBarNode->GetLayoutProperty<TabBarLayoutProperty>();
199 CHECK_NULL_RETURN(tabBarLayoutProperty, Axis::HORIZONTAL);
200 return tabBarLayoutProperty->GetAxis().value_or(Axis::HORIZONTAL);
201 }
202
ConvertFlexAlignToString(FlexAlign verticalAlign) const203 std::string TabContentNode::ConvertFlexAlignToString(FlexAlign verticalAlign) const
204 {
205 if (verticalAlign == FlexAlign::FLEX_START) {
206 return "VerticalAlign.Top";
207 } else if (verticalAlign == FlexAlign::FLEX_END) {
208 return "VerticalAlign.Bottom";
209 }
210 return "VerticalAlign.Center";
211 }
212
ConvertLayoutModeToString(LayoutMode layoutMode) const213 std::string TabContentNode::ConvertLayoutModeToString(LayoutMode layoutMode) const
214 {
215 if (layoutMode == LayoutMode::VERTICAL) {
216 return "LayoutMode.VERTICAL";
217 } else if (layoutMode == LayoutMode::HORIZONTAL) {
218 return "LayoutMode.HORIZONTAL";
219 }
220 return "LayoutMode.AUTO";
221 }
222
GetDefaultFontSize() const223 Dimension TabContentNode::GetDefaultFontSize() const
224 {
225 if (!tabBarItemId_.has_value()) {
226 return Dimension(0);
227 }
228 auto columnNode = GetFrameNode(V2::COLUMN_ETS_TAG, tabBarItemId_.value());
229 CHECK_NULL_RETURN(columnNode, Dimension(0));
230 auto textNode = AceType::DynamicCast<FrameNode>(columnNode->GetChildAtIndex(1));
231 CHECK_NULL_RETURN(textNode, Dimension(0));
232 auto textLayoutProperty = AceType::DynamicCast<TextLayoutProperty>(textNode->GetLayoutProperty());
233 CHECK_NULL_RETURN(textLayoutProperty, Dimension(0));
234 return textLayoutProperty->GetFontSizeValue(Dimension(0));
235 }
236
UpdataTabBarItem()237 void TabContentNode::UpdataTabBarItem()
238 {
239 TabContentModelNG::AddTabBarItem(Referenced::Claim(this), DEFAULT_NODE_SLOT, true);
240 }
241 } // namespace OHOS::Ace::NG
242