• 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/tab_content_node.h"
17 
18 #include "core/components_ng/pattern/swiper/swiper_pattern.h"
19 #include "core/components_ng/pattern/tabs/tab_content_model_ng.h"
20 #include "core/components_ng/pattern/tabs/tab_content_pattern.h"
21 
22 namespace OHOS::Ace::NG {
23 namespace {
24 constexpr int DEFAULT_MAXLINES = 1;
25 } // namespace
26 
OnAttachToMainTree(bool recursive)27 void TabContentNode::OnAttachToMainTree(bool recursive)
28 {
29     if (!UseOffscreenProcess()) {
30         ProcessTabBarItem();
31     }
32     FrameNode::OnOffscreenProcess(recursive);
33 }
34 
OnDetachFromMainTree(bool recursive)35 void TabContentNode::OnDetachFromMainTree(bool recursive)
36 {
37     auto tabs = TabContentModelNG::FindTabsNode(Referenced::Claim(this));
38     CHECK_NULL_VOID(tabs);
39 
40     // Change focus to the other tab if current is being deleted
41     auto swiper = AceType::DynamicCast<FrameNode>(tabs->GetTabs());
42     CHECK_NULL_VOID(swiper);
43 
44     auto swiperPattern = AceType::DynamicCast<SwiperPattern>(swiper->GetPattern());
45     CHECK_NULL_VOID(swiperPattern);
46 
47     auto deletedIdx = swiper->GetChildFlatIndex(GetId()).second;
48     auto currentIdx = swiperPattern->GetCurrentShownIndex();
49     LOGD("Deleting tab: %{public}d, currentTab: %{public}d", deletedIdx, swiperPattern->GetCurrentShownIndex());
50 
51     // Removing currently shown tab, focus on first after that
52     if (currentIdx == deletedIdx) {
53         swiperPattern->GetSwiperController()->SwipeToWithoutAnimation(0);
54     }
55     TabContentModelNG::RemoveTabBarItem(Referenced::Claim(this));
56 
57     // Removing tab before current, re-focus on the same tab with new index
58     if (currentIdx > deletedIdx) {
59         LOGD("RE-activate TAB with new IDX %{public}d from idx %{public}d", currentIdx - 1, deletedIdx);
60         swiperPattern->GetSwiperController()->SwipeToWithoutAnimation(currentIdx - 1);
61     }
62 }
63 
OnOffscreenProcess(bool recursive)64 void TabContentNode::OnOffscreenProcess(bool recursive)
65 {
66     ProcessTabBarItem();
67     FrameNode::OnOffscreenProcess(recursive);
68 }
69 
ProcessTabBarItem()70 void TabContentNode::ProcessTabBarItem()
71 {
72     auto tabs = TabContentModelNG::FindTabsNode(Referenced::Claim(this));
73     CHECK_NULL_VOID(tabs);
74     auto swiper = tabs->GetTabs();
75     CHECK_NULL_VOID(swiper);
76     auto myIndex = swiper->GetChildFlatIndex(GetId()).second;
77     bool update = false;
78 #ifdef UICAST_COMPONENT_SUPPORTED
79     do {
80         auto container = Container::Current();
81         CHECK_NULL_BREAK(container);
82         auto distributedUI = container->GetDistributedUI();
83         CHECK_NULL_BREAK(distributedUI);
84         if (distributedUI->IsSinkMode()) {
85             update = true;
86         }
87     } while (false);
88 #endif
89     TabContentModelNG::AddTabBarItem(Referenced::Claim(this), myIndex, update);
90 }
91 
GetOrCreateTabContentNode(const std::string & tag,int32_t nodeId,const std::function<RefPtr<Pattern> (void)> & patternCreator)92 RefPtr<TabContentNode> TabContentNode::GetOrCreateTabContentNode(
93     const std::string& tag, int32_t nodeId, const std::function<RefPtr<Pattern>(void)>& patternCreator)
94 {
95     auto node = GetFrameNode(tag, nodeId);
96     auto tabContentNode = AceType::DynamicCast<TabContentNode>(node);
97 
98     if (tabContentNode) {
99         LOGD("found existing");
100         return tabContentNode;
101     }
102 
103     auto pattern = patternCreator ? patternCreator() : AceType::MakeRefPtr<Pattern>();
104     tabContentNode = AceType::MakeRefPtr<TabContentNode>(tag, nodeId, pattern, false);
105     tabContentNode->InitializePatternAndContext();
106     ElementRegister::GetInstance()->AddUINode(tabContentNode);
107     return tabContentNode;
108 }
109 
ToJsonValue(std::unique_ptr<JsonValue> & json) const110 void TabContentNode::ToJsonValue(std::unique_ptr<JsonValue>& json) const
111 {
112     FrameNode::ToJsonValue(json);
113     auto tabBar = JsonUtil::Create(true);
114 
115     auto tabContentPattern = GetPattern<TabContentPattern>();
116     CHECK_NULL_VOID(tabContentPattern);
117 
118     auto indicator = JsonUtil::Create(true);
119     auto indicatorStyle = tabContentPattern->GetIndicatorStyle();
120     indicator->Put("color", indicatorStyle.color.ColorToString().c_str());
121     indicator->Put("height", indicatorStyle.height.ToString().c_str());
122     indicator->Put("width", indicatorStyle.width.ToString().c_str());
123     indicator->Put("borderRadius", indicatorStyle.borderRadius.ToString().c_str());
124     indicator->Put("marginTop", indicatorStyle.marginTop.ToString().c_str());
125     tabBar->Put("indicator", indicator);
126 
127     auto board = JsonUtil::Create(true);
128     auto boardStyle = tabContentPattern->GetBoardStyle();
129     board->Put("borderRadius", boardStyle.borderRadius.ToString().c_str());
130     tabBar->Put("board", board);
131 
132     tabBar->Put("selectedMode", tabContentPattern->GetSelectedMode() == SelectedMode::INDICATOR ?
133 		"SelectedMode.INDICATOR" : "SelectedMode.BOARD");
134 
135     auto font = JsonUtil::Create(true);
136     auto labelStyle = tabContentPattern->GetLabelStyle();
137     font->Put("size", labelStyle.fontSize.value_or(Dimension(0)).ToString().c_str());
138     font->Put("weight",
139         V2::ConvertWrapFontWeightToStirng(labelStyle.fontWeight.value_or(FontWeight::NORMAL)).c_str());
140     std::vector<std::string> emptyFontFamily = { "" };
141     auto fontFamilyVector = labelStyle.fontFamily.value_or(emptyFontFamily);
142     std::string fontFamily = fontFamilyVector.at(0);
143     for (uint32_t i = 1; i < fontFamilyVector.size(); ++i) {
144         fontFamily += ',' + fontFamilyVector.at(i);
145     }
146     font->Put("family", fontFamily.c_str());
147     font->Put("style", labelStyle.fontStyle.value_or(Ace::FontStyle::NORMAL) == Ace::FontStyle::NORMAL
148                                 ? "FontStyle.Normal"
149                                 : "FontStyle.Italic");
150 
151     auto label = JsonUtil::Create(true);
152     label->Put("overflow",
153         V2::ConvertWrapTextOverflowToString(labelStyle.textOverflow.value_or(TextOverflow::ELLIPSIS)).c_str());
154     label->Put("maxLines", std::to_string(labelStyle.maxLines.value_or(DEFAULT_MAXLINES)).c_str());
155     label->Put("minFontSize", labelStyle.minFontSize.value_or(Dimension(0)).ToString().c_str());
156     label->Put("maxFontSize", labelStyle.maxFontSize.value_or(Dimension(0)).ToString().c_str());
157     label->Put("heightAdaptivePolicy", V2::ConvertWrapTextHeightAdaptivePolicyToString(
158         labelStyle.heightAdaptivePolicy.value_or(TextHeightAdaptivePolicy::MAX_LINES_FIRST)).c_str());
159     label->Put("font", font);
160     tabBar->Put("labelStyle", label);
161 
162     tabBar->Put("padding", tabContentPattern->GetPadding().ToJsonString().c_str());
163     tabBar->Put(
164         "verticalAlign", ConvertFlexAlignToString(tabContentPattern->GetBottomTabBarStyle().verticalAlign).c_str());
165     tabBar->Put("layoutMode", ConvertLayoutModeToString(tabContentPattern->GetBottomTabBarStyle().layoutMode).c_str());
166     tabBar->Put(
167         "symmetricExtensible", tabContentPattern->GetBottomTabBarStyle().symmetricExtensible ? "true" : "false");
168 
169     json->Put("tabBar", tabBar);
170 }
171 
ConvertFlexAlignToString(FlexAlign verticalAlign) const172 std::string TabContentNode::ConvertFlexAlignToString(FlexAlign verticalAlign) const
173 {
174     if (verticalAlign == FlexAlign::FLEX_START) {
175         return "VerticalAlign.Top";
176     } else if (verticalAlign == FlexAlign::FLEX_END) {
177         return "VerticalAlign.Bottom";
178     }
179     return "VerticalAlign.Center";
180 }
181 
ConvertLayoutModeToString(LayoutMode layoutMode) const182 std::string TabContentNode::ConvertLayoutModeToString(LayoutMode layoutMode) const
183 {
184     if (layoutMode == LayoutMode::VERTICAL) {
185         return "LayoutMode.VERTICAL";
186     } else if (layoutMode == LayoutMode::HORIZONTAL) {
187         return "LayoutMode.HORIZONTAL";
188     }
189     return "LayoutMode.AUTO";
190 }
191 } // namespace OHOS::Ace::NG
192