• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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 "frameworks/bridge/declarative_frontend/jsview/js_tabs.h"
17 
18 #include "core/components/tab_bar/tab_bar_component.h"
19 #include "core/components/tab_bar/tab_content_component.h"
20 #include "core/components_v2/tabs/tabs_component.h"
21 #include "frameworks/bridge/declarative_frontend/jsview/js_tabs_controller.h"
22 #include "frameworks/bridge/declarative_frontend/view_stack_processor.h"
23 
24 namespace OHOS::Ace::Framework {
25 namespace {
26 
27 constexpr Dimension DEFAULT_TAB_BAR_HEIGHT = 56.0_vp;
28 const std::vector<BarPosition> BAR_POSITIONS = { BarPosition::START, BarPosition::END };
29 
TabContentChangeEventToJSValue(const TabContentChangeEvent & eventInfo)30 JSRef<JSVal> TabContentChangeEventToJSValue(const TabContentChangeEvent& eventInfo)
31 {
32     return JSRef<JSVal>::Make(ToJSValue(eventInfo.GetIndex()));
33 }
34 
35 } // namespace
36 
SetOnChange(const JSCallbackInfo & args)37 void JSTabs::SetOnChange(const JSCallbackInfo& args)
38 {
39     if (args[0]->IsFunction()) {
40         auto changeHandler = AceType::MakeRefPtr<JsEventFunction<TabContentChangeEvent, 1>>(
41             JSRef<JSFunc>::Cast(args[0]), TabContentChangeEventToJSValue);
42         auto onChange = EventMarker([executionContext = args.GetExecutionContext(), func = std::move(changeHandler)](
43                                         const BaseEventInfo* info) {
44             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(executionContext);
45             auto TabsInfo = TypeInfoHelper::DynamicCast<TabContentChangeEvent>(info);
46             if (!TabsInfo) {
47                 LOGE("HandleChangeEvent TabsInfo == nullptr");
48                 return;
49             }
50             ACE_SCORING_EVENT("Tabs.onChange");
51             func->Execute(*TabsInfo);
52         });
53         auto component = AceType::DynamicCast<V2::TabsComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
54         if (component) {
55             auto tabContent = component->GetTabContentChild();
56             if (tabContent) {
57                 tabContent->SetChangeEventId(onChange);
58             }
59         }
60     }
61     args.ReturnSelf();
62 }
63 
Create(const JSCallbackInfo & info)64 void JSTabs::Create(const JSCallbackInfo& info)
65 {
66     BarPosition barVal = BarPosition::START;
67     RefPtr<TabController> tabController;
68     if (info[0]->IsObject()) {
69         JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
70         JSRef<JSVal> val = obj->GetProperty("barPosition");
71         if (val->IsNumber()) {
72             auto barPositionVal = val->ToNumber<int32_t>();
73             if (barPositionVal >= 0 && barPositionVal < static_cast<int32_t>(BAR_POSITIONS.size())) {
74                 barVal = BAR_POSITIONS[barPositionVal];
75             }
76         }
77         JSRef<JSVal> controller = obj->GetProperty("controller");
78         if (controller->IsObject()) {
79             auto jsTabsController = JSRef<JSObject>::Cast(controller)->Unwrap<JSTabsController>();
80             if (jsTabsController) {
81                 tabController = jsTabsController->GetController();
82             }
83         }
84         JSRef<JSVal> index = obj->GetProperty("index");
85         if (index->IsNumber()) {
86             if (!tabController) {
87                 tabController = JSTabsController::CreateController();
88             }
89             tabController->SetInitialIndex(index->ToNumber<int32_t>());
90         }
91     }
92     std::list<RefPtr<Component>> children;
93     auto tabsComponent = AceType::MakeRefPtr<V2::TabsComponent>(children, barVal, tabController);
94     auto tabBar = tabsComponent->GetTabBarChild();
95     if (tabBar) {
96         auto theme = GetTheme<TabTheme>();
97         tabBar->InitStyle(theme);
98         auto box = AceType::DynamicCast<BoxComponent>(tabBar->GetParent().Upgrade());
99         if (box) {
100             box->SetHeight(DEFAULT_TAB_BAR_HEIGHT);
101         }
102     }
103     ViewStackProcessor::GetInstance()->PushTabs(tabsComponent);
104     ViewStackProcessor::GetInstance()->Push(tabsComponent);
105 }
106 
Pop()107 void JSTabs::Pop()
108 {
109     ViewStackProcessor::GetInstance()->PopTabs();
110     JSContainerBase::Pop();
111 }
112 
SetVertical(const std::string & value)113 void JSTabs::SetVertical(const std::string& value)
114 {
115     auto tabsComponent = AceType::DynamicCast<V2::TabsComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
116     if (!tabsComponent) {
117         return;
118     }
119     bool isVertical = StringToBool(value);
120     if (isVertical) {
121         tabsComponent->SetDirection(FlexDirection::ROW);
122     } else {
123         tabsComponent->SetDirection(FlexDirection::COLUMN);
124     }
125     auto tabBar = tabsComponent->GetTabBarChild();
126     if (tabBar) {
127         tabBar->SetVertical(isVertical);
128     }
129     auto tabContent = tabsComponent->GetTabContentChild();
130     if (tabContent) {
131         tabContent->SetVertical(isVertical);
132     }
133 }
134 
SetScrollable(const std::string & value)135 void JSTabs::SetScrollable(const std::string& value)
136 {
137     auto component = AceType::DynamicCast<V2::TabsComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
138     if (!component) {
139         return;
140     }
141     auto tabContent = component->GetTabContentChild();
142     if (tabContent) {
143         tabContent->SetScrollable(StringToBool(value));
144     }
145 }
146 
SetBarMode(const std::string & value)147 void JSTabs::SetBarMode(const std::string& value)
148 {
149     auto component = AceType::DynamicCast<V2::TabsComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
150     if (!component) {
151         return;
152     }
153     auto tabBar = component->GetTabBarChild();
154     if (tabBar) {
155         tabBar->SetMode(ConvertStrToTabBarMode(value));
156     }
157 }
158 
SetBarWidth(const JSCallbackInfo & info)159 void JSTabs::SetBarWidth(const JSCallbackInfo& info)
160 {
161     auto component = AceType::DynamicCast<V2::TabsComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
162     if (!component) {
163         return;
164     }
165     if (info.Length() < 1) {
166         LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
167         return;
168     }
169     Dimension width;
170     if (!ParseJsDimensionVp(info[0], width)) {
171         LOGE("The arg is wrong, fail to parse dimension");
172         return;
173     }
174     auto tabBar = component->GetTabBarChild();
175     if (!tabBar) {
176         LOGE("can not find tab bar component");
177         return;
178     }
179     auto box = AceType::DynamicCast<BoxComponent>(tabBar->GetParent().Upgrade());
180     if (box) {
181         box->SetWidth(width);
182     } else {
183         LOGE("can not find box component");
184     }
185 }
186 
SetBarHeight(const JSCallbackInfo & info)187 void JSTabs::SetBarHeight(const JSCallbackInfo& info)
188 {
189     auto component = AceType::DynamicCast<V2::TabsComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
190     if (!component) {
191         return;
192     }
193     if (info.Length() < 1) {
194         LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
195         return;
196     }
197     Dimension height;
198     if (!ParseJsDimensionVp(info[0], height)) {
199         LOGE("The arg is wrong, fail to parse dimension");
200         return;
201     }
202     auto tabBar = component->GetTabBarChild();
203     if (!tabBar) {
204         LOGE("can not find tab bar component");
205         return;
206     }
207     auto box = AceType::DynamicCast<BoxComponent>(tabBar->GetParent().Upgrade());
208     if (box) {
209         box->SetHeight(height);
210     } else {
211         LOGE("can not find box component");
212     }
213 }
214 
SetIndex(int32_t index)215 void JSTabs::SetIndex(int32_t index)
216 {
217     auto component = AceType::DynamicCast<V2::TabsComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
218     if (!component) {
219         LOGE("can not find tabs component");
220         return;
221     }
222     auto controller = component->GetTabsController();
223     if (controller) {
224         controller->SetPendingIndex(index);
225     } else {
226         LOGE("can not find controller");
227     }
228 }
229 
SetAnimationDuration(float value)230 void JSTabs::SetAnimationDuration(float value)
231 {
232     auto component = AceType::DynamicCast<V2::TabsComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
233     if (!component) {
234         return;
235     }
236     auto tabContent = component->GetTabContentChild();
237     if (!tabContent) {
238         return;
239     }
240     tabContent->SetScrollDuration(value);
241 }
242 
JSBind(BindingTarget globalObj)243 void JSTabs::JSBind(BindingTarget globalObj)
244 {
245     JSClass<JSTabs>::Declare("Tabs");
246     JSClass<JSTabs>::StaticMethod("create", &JSTabs::Create);
247     JSClass<JSTabs>::StaticMethod("pop", &JSTabs::Pop);
248     JSClass<JSTabs>::StaticMethod("vertical", &JSTabs::SetVertical);
249     JSClass<JSTabs>::StaticMethod("scrollable", &JSTabs::SetScrollable);
250     JSClass<JSTabs>::StaticMethod("barMode", &JSTabs::SetBarMode);
251     JSClass<JSTabs>::StaticMethod("barWidth", &JSTabs::SetBarWidth);
252     JSClass<JSTabs>::StaticMethod("barHeight", &JSTabs::SetBarHeight);
253     JSClass<JSTabs>::StaticMethod("index", &JSTabs::SetIndex);
254     JSClass<JSTabs>::StaticMethod("animationDuration", &JSTabs::SetAnimationDuration);
255     JSClass<JSTabs>::StaticMethod("onChange", &JSTabs::SetOnChange);
256     JSClass<JSTabs>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
257     JSClass<JSTabs>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
258     JSClass<JSTabs>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
259     JSClass<JSTabs>::StaticMethod("onHover", &JSInteractableView::JsOnHover);
260     JSClass<JSTabs>::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey);
261     JSClass<JSTabs>::StaticMethod("onDeleteEvent", &JSInteractableView::JsOnDelete);
262     JSClass<JSTabs>::StaticMethod("onClick", &JSInteractableView::JsOnClick);
263     JSClass<JSTabs>::StaticMethod("remoteMessage", &JSInteractableView::JsCommonRemoteMessage);
264     JSClass<JSTabs>::Inherit<JSContainerBase>();
265     JSClass<JSTabs>::Bind<>(globalObj);
266 }
267 
268 } // namespace OHOS::Ace::Framework
269