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_piece.h"
17 
18 #include "base/log/ace_scoring_log.h"
19 #include "bridge/declarative_frontend/engine/functions/js_click_function.h"
20 #include "bridge/declarative_frontend/jsview/js_view_common_def.h"
21 #include "bridge/declarative_frontend/view_stack_processor.h"
22 #include "core/components/box/box_component.h"
23 #include "core/components/piece/piece_component.h"
24 #include "core/components/piece/piece_theme.h"
25 
26 namespace OHOS::Ace::Framework {
27 
28 const std::vector<FontStyle> FONT_STYLES = { FontStyle::NORMAL, FontStyle::ITALIC };
29 
Create(const JSCallbackInfo & info)30 void JSPiece::Create(const JSCallbackInfo& info)
31 {
32     if (info.Length() < 1 || !info[0]->IsObject()) {
33         return;
34     }
35     auto paramObject = JSRef<JSObject>::Cast(info[0]);
36     auto getContent = paramObject->GetProperty("content");
37     auto getIcon = paramObject->GetProperty("icon");
38     std::string content;
39     std::string icon;
40     if (getContent->IsString()) {
41         content = getContent->ToString();
42     }
43     if (getIcon->IsString()) {
44         icon = getIcon->ToString();
45     }
46     auto component = AceType::MakeRefPtr<PieceComponent>();
47     component->SetContent(content);
48     component->SetIcon(icon);
49     auto theme = GetTheme<PieceTheme>();
50     if (!theme) {
51         return;
52     }
53     component->InitializeStyle(theme);
54     Border border;
55     border.SetBorderRadius(Radius(theme->GetHeight() / 2.0));
56     component->SetBorder(border);
57     ViewStackProcessor::GetInstance()->Push(component);
58 
59     auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
60     AnimationOption option = ViewStackProcessor::GetInstance()->GetImplicitAnimationOption();
61     box->SetHeight(theme->GetHeight(), option);
62     Edge edge;
63     edge.SetLeft(theme->GetPaddingHorizontal());
64     edge.SetRight(theme->GetPaddingHorizontal());
65     edge.SetTop(theme->GetPaddingVertical());
66     edge.SetBottom(theme->GetPaddingVertical());
67     box->SetPadding(edge);
68 }
69 
JSBind(BindingTarget globalObj)70 void JSPiece::JSBind(BindingTarget globalObj)
71 {
72     JSClass<JSPiece>::Declare("Piece");
73     MethodOptions opt = MethodOptions::NONE;
74     JSClass<JSPiece>::StaticMethod("create", &JSPiece::Create, opt);
75     JSClass<JSPiece>::StaticMethod("iconPosition", &JSPiece::SetIconPosition, opt);
76     JSClass<JSPiece>::StaticMethod("showDelete", &JSPiece::SetShowDelete, opt);
77     JSClass<JSPiece>::StaticMethod("fontColor", &JSPiece::SetTextColor, opt);
78     JSClass<JSPiece>::StaticMethod("fontSize", &JSPiece::SetFontSize, opt);
79     JSClass<JSPiece>::StaticMethod("fontStyle", &JSPiece::SetFontStyle, opt);
80     JSClass<JSPiece>::StaticMethod("fontWeight", &JSPiece::SetFontWeight, opt);
81     JSClass<JSPiece>::StaticMethod("fontFamily", &JSPiece::SetFontFamily, opt);
82     JSClass<JSPiece>::StaticMethod("onClick", &JSInteractableView::JsOnClick);
83     JSClass<JSPiece>::StaticMethod("onClose", &JSPiece::JsOnClose);
84     JSClass<JSPiece>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
85     JSClass<JSPiece>::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey);
86     JSClass<JSPiece>::StaticMethod("onDeleteEvent", &JSInteractableView::JsOnDelete);
87     JSClass<JSPiece>::StaticMethod("onAttach", &JSInteractableView::JsOnAttach);
88     JSClass<JSPiece>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
89     JSClass<JSPiece>::StaticMethod("onDetach", &JSInteractableView::JsOnDetach);
90     JSClass<JSPiece>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
91     JSClass<JSPiece>::InheritAndBind<JSViewAbstract>(globalObj);
92 }
93 
94 // showDelete Parameters should be bool type,but after click event triggering,
95 // The callback function transfers parameters, and the parameter type changes to number.
SetShowDelete(const JSCallbackInfo & info)96 void JSPiece::SetShowDelete(const JSCallbackInfo& info)
97 {
98     bool showDelete = false;
99     auto stack = ViewStackProcessor::GetInstance();
100     auto component = AceType::DynamicCast<PieceComponent>(stack->GetMainComponent());
101     if (!component) {
102         return;
103     }
104     if (info[0]->IsBoolean()) {
105         showDelete = info[0]->ToBoolean();
106         component->SetShowDelete(showDelete);
107     } else if (info[0]->IsNumber()) {
108         int32_t arg = info[0]->ToNumber<int32_t>();
109         if (arg == 0 || arg == 1) {
110             showDelete = static_cast<bool>(arg);
111             component->SetShowDelete(showDelete);
112         }
113     } else {
114         component->SetShowDelete(showDelete);
115     }
116 }
117 
JsOnClose(const JSCallbackInfo & info)118 void JSPiece::JsOnClose(const JSCallbackInfo& info)
119 {
120     if (info[0]->IsFunction()) {
121         JSRef<JSFunc> clickFunction = JSRef<JSFunc>::Cast(info[0]);
122         auto onClickFunc = AceType::MakeRefPtr<JsClickFunction>(clickFunction);
123         EventMarker clickEventId(
124             [execCtx = info.GetExecutionContext(), func = std::move(onClickFunc)](const BaseEventInfo* info) {
125                 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
126                 ACE_SCORING_EVENT("Piece.onClose");
127                 func->Execute();
128             });
129         auto pieceComponent =
130             AceType::DynamicCast<PieceComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
131         if (pieceComponent) {
132             pieceComponent->SetOnDelete(clickEventId);
133         }
134     }
135 }
136 
SetTextColor(const JSCallbackInfo & info)137 void JSPiece::SetTextColor(const JSCallbackInfo& info)
138 {
139     Color textColor;
140     if (!ParseJsColor(info[0], textColor)) {
141         return;
142     }
143     auto stack = ViewStackProcessor::GetInstance();
144     auto component = AceType::DynamicCast<PieceComponent>(stack->GetMainComponent());
145     if (!component) {
146         return;
147     }
148     auto textStyle = component->GetTextStyle();
149     textStyle.SetTextColor(textColor);
150     component->SetTextStyle(std::move(textStyle));
151 }
152 
SetFontSize(const JSCallbackInfo & info)153 void JSPiece::SetFontSize(const JSCallbackInfo& info)
154 {
155     CalcDimension fontSize;
156     if (!ParseJsDimensionFp(info[0], fontSize)) {
157         return;
158     }
159     auto stack = ViewStackProcessor::GetInstance();
160     auto component = AceType::DynamicCast<PieceComponent>(stack->GetMainComponent());
161     if (!component) {
162         return;
163     }
164     auto textStyle = component->GetTextStyle();
165     textStyle.SetFontSize(fontSize);
166     component->SetTextStyle(std::move(textStyle));
167 }
168 
SetFontStyle(int32_t value)169 void JSPiece::SetFontStyle(int32_t value)
170 {
171     auto stack = ViewStackProcessor::GetInstance();
172     auto component = AceType::DynamicCast<PieceComponent>(stack->GetMainComponent());
173     if (!component) {
174         return;
175     }
176     if (value >= 0 && value < static_cast<int32_t>(FONT_STYLES.size())) {
177         auto textStyle = component->GetTextStyle();
178         textStyle.SetFontStyle(FONT_STYLES[value]);
179         component->SetTextStyle(std::move(textStyle));
180     }
181 }
182 
SetFontWeight(const std::string & value)183 void JSPiece::SetFontWeight(const std::string& value)
184 {
185     auto stack = ViewStackProcessor::GetInstance();
186     auto component = AceType::DynamicCast<PieceComponent>(stack->GetMainComponent());
187     if (!component) {
188         return;
189     }
190 
191     auto textStyle = component->GetTextStyle();
192     textStyle.SetFontWeight(ConvertStrToFontWeight(value));
193     component->SetTextStyle(std::move(textStyle));
194 }
195 
SetFontFamily(const JSCallbackInfo & info)196 void JSPiece::SetFontFamily(const JSCallbackInfo& info)
197 {
198     std::vector<std::string> fontFamilies;
199     if (!ParseJsFontFamilies(info[0], fontFamilies)) {
200         return;
201     }
202     auto stack = ViewStackProcessor::GetInstance();
203     auto component = AceType::DynamicCast<PieceComponent>(stack->GetMainComponent());
204     if (!component) {
205         return;
206     }
207     auto textStyle = component->GetTextStyle();
208     textStyle.SetFontFamilies(fontFamilies);
209     component->SetTextStyle(std::move(textStyle));
210 }
211 
SetIconPosition(const JSCallbackInfo & info)212 void JSPiece::SetIconPosition(const JSCallbackInfo& info)
213 {
214     if (!info[0]->IsNumber()) {
215         return;
216     }
217 
218     auto stack = ViewStackProcessor::GetInstance();
219     auto component = AceType::DynamicCast<PieceComponent>(stack->GetMainComponent());
220     if (!component) {
221         return;
222     }
223 
224     auto pieceIconPosition = static_cast<OHOS::Ace::IconPosition>(info[0]->ToNumber<int32_t>());
225     component->SetIconPosition(pieceIconPosition);
226 }
227 
228 } // namespace OHOS::Ace::Framework
229