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 LOGE("piece create error, info is non-valid");
34 return;
35 }
36 auto paramObject = JSRef<JSObject>::Cast(info[0]);
37 auto getContent = paramObject->GetProperty("content");
38 auto getIcon = paramObject->GetProperty("icon");
39 std::string content;
40 std::string icon;
41 if (getContent->IsString()) {
42 content = getContent->ToString();
43 }
44 if (getIcon->IsString()) {
45 icon = getIcon->ToString();
46 }
47 auto component = AceType::MakeRefPtr<PieceComponent>();
48 component->SetContent(content);
49 component->SetIcon(icon);
50 auto theme = GetTheme<PieceTheme>();
51 if (!theme) {
52 LOGE("piece theme is null");
53 return;
54 }
55 component->InitializeStyle(theme);
56 Border border;
57 border.SetBorderRadius(Radius(theme->GetHeight() / 2.0));
58 component->SetBorder(border);
59 ViewStackProcessor::GetInstance()->Push(component);
60
61 auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
62 AnimationOption option = ViewStackProcessor::GetInstance()->GetImplicitAnimationOption();
63 box->SetHeight(theme->GetHeight(), option);
64 Edge edge;
65 edge.SetLeft(theme->GetPaddingHorizontal());
66 edge.SetRight(theme->GetPaddingHorizontal());
67 edge.SetTop(theme->GetPaddingVertical());
68 edge.SetBottom(theme->GetPaddingVertical());
69 box->SetPadding(edge);
70 }
71
JSBind(BindingTarget globalObj)72 void JSPiece::JSBind(BindingTarget globalObj)
73 {
74 JSClass<JSPiece>::Declare("Piece");
75 MethodOptions opt = MethodOptions::NONE;
76 JSClass<JSPiece>::StaticMethod("create", &JSPiece::Create, opt);
77 JSClass<JSPiece>::StaticMethod("iconPosition", &JSPiece::SetIconPosition, opt);
78 JSClass<JSPiece>::StaticMethod("showDelete", &JSPiece::SetShowDelete, opt);
79 JSClass<JSPiece>::StaticMethod("fontColor", &JSPiece::SetTextColor, opt);
80 JSClass<JSPiece>::StaticMethod("fontSize", &JSPiece::SetFontSize, opt);
81 JSClass<JSPiece>::StaticMethod("fontStyle", &JSPiece::SetFontStyle, opt);
82 JSClass<JSPiece>::StaticMethod("fontWeight", &JSPiece::SetFontWeight, opt);
83 JSClass<JSPiece>::StaticMethod("fontFamily", &JSPiece::SetFontFamily, opt);
84 JSClass<JSPiece>::StaticMethod("onClick", &JSInteractableView::JsOnClick);
85 JSClass<JSPiece>::StaticMethod("onClose", &JSPiece::JsOnClose);
86 JSClass<JSPiece>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
87 JSClass<JSPiece>::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey);
88 JSClass<JSPiece>::StaticMethod("onDeleteEvent", &JSInteractableView::JsOnDelete);
89 JSClass<JSPiece>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
90 JSClass<JSPiece>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
91 JSClass<JSPiece>::Inherit<JSViewAbstract>();
92 JSClass<JSPiece>::Bind<>(globalObj);
93 }
94
95 // showDelete Parameters should be bool type,but after click event triggering,
96 // The callback function transfers parameters, and the parameter type changes to number.
SetShowDelete(const JSCallbackInfo & info)97 void JSPiece::SetShowDelete(const JSCallbackInfo& info)
98 {
99 bool showDelete = false;
100 if (info.Length() < 1) {
101 LOGE("The arg is wrong, it is supposed to have at least 1 arguments");
102 return;
103 }
104 auto stack = ViewStackProcessor::GetInstance();
105 auto component = AceType::DynamicCast<PieceComponent>(stack->GetMainComponent());
106 if (!component) {
107 LOGE("component is not valid");
108 return;
109 }
110 if (info[0]->IsBoolean()) {
111 showDelete = info[0]->ToBoolean();
112 component->SetShowDelete(showDelete);
113 } else if (info[0]->IsNumber()) {
114 int32_t arg = info[0]->ToNumber<int32_t>();
115 if (arg == 0 || arg == 1) {
116 showDelete = static_cast<bool>(arg);
117 component->SetShowDelete(showDelete);
118 }
119 } else {
120 component->SetShowDelete(showDelete);
121 }
122 }
123
JsOnClose(const JSCallbackInfo & info)124 void JSPiece::JsOnClose(const JSCallbackInfo& info)
125 {
126 if (info[0]->IsFunction()) {
127 JSRef<JSFunc> clickFunction = JSRef<JSFunc>::Cast(info[0]);
128 auto onClickFunc = AceType::MakeRefPtr<JsClickFunction>(clickFunction);
129 EventMarker clickEventId(
130 [execCtx = info.GetExecutionContext(), func = std::move(onClickFunc)](const BaseEventInfo* info) {
131 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
132 ACE_SCORING_EVENT("Piece.onClose");
133 func->Execute();
134 });
135 auto pieceComponent =
136 AceType::DynamicCast<PieceComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
137 if (pieceComponent) {
138 pieceComponent->SetOnDelete(clickEventId);
139 }
140 }
141 }
142
SetTextColor(const JSCallbackInfo & info)143 void JSPiece::SetTextColor(const JSCallbackInfo& info)
144 {
145 if (info.Length() < 1) {
146 LOGE("The argv is wrong, it is supposed to have at least 1 argument");
147 return;
148 }
149 Color textColor;
150 if (!ParseJsColor(info[0], textColor)) {
151 return;
152 }
153 auto stack = ViewStackProcessor::GetInstance();
154 auto component = AceType::DynamicCast<PieceComponent>(stack->GetMainComponent());
155 if (!component) {
156 LOGE("component is not valid");
157 return;
158 }
159 auto textStyle = component->GetTextStyle();
160 textStyle.SetTextColor(textColor);
161 component->SetTextStyle(std::move(textStyle));
162 }
163
SetFontSize(const JSCallbackInfo & info)164 void JSPiece::SetFontSize(const JSCallbackInfo& info)
165 {
166 if (info.Length() < 1) {
167 LOGE("The argv is wrong, it is supposed to have at least 1 argument");
168 return;
169 }
170 Dimension fontSize;
171 if (!ParseJsDimensionFp(info[0], fontSize)) {
172 return;
173 }
174 auto stack = ViewStackProcessor::GetInstance();
175 auto component = AceType::DynamicCast<PieceComponent>(stack->GetMainComponent());
176 if (!component) {
177 LOGE("component is not valid");
178 return;
179 }
180 auto textStyle = component->GetTextStyle();
181 textStyle.SetFontSize(fontSize);
182 component->SetTextStyle(std::move(textStyle));
183 }
184
SetFontStyle(int32_t value)185 void JSPiece::SetFontStyle(int32_t value)
186 {
187 auto stack = ViewStackProcessor::GetInstance();
188 auto component = AceType::DynamicCast<PieceComponent>(stack->GetMainComponent());
189 if (!component) {
190 LOGE("component is not valid");
191 return;
192 }
193 if (value >= 0 && value < static_cast<int32_t>(FONT_STYLES.size())) {
194 auto textStyle = component->GetTextStyle();
195 textStyle.SetFontStyle(FONT_STYLES[value]);
196 component->SetTextStyle(std::move(textStyle));
197 } else {
198 LOGE("Text fontStyle(%d) illegal value", value);
199 }
200 }
201
SetFontWeight(const std::string & value)202 void JSPiece::SetFontWeight(const std::string& value)
203 {
204 auto stack = ViewStackProcessor::GetInstance();
205 auto component = AceType::DynamicCast<PieceComponent>(stack->GetMainComponent());
206 if (!component) {
207 LOGE("component is not valid");
208 return;
209 }
210
211 auto textStyle = component->GetTextStyle();
212 textStyle.SetFontWeight(ConvertStrToFontWeight(value));
213 component->SetTextStyle(std::move(textStyle));
214 }
215
SetFontFamily(const JSCallbackInfo & info)216 void JSPiece::SetFontFamily(const JSCallbackInfo& info)
217 {
218 if (info.Length() < 1) {
219 LOGE("The argv is wrong, it is supposed to have at least 1 argument");
220 return;
221 }
222 std::vector<std::string> fontFamilies;
223 if (!ParseJsFontFamilies(info[0], fontFamilies)) {
224 LOGE("Parse FontFamilies failed");
225 return;
226 }
227 auto stack = ViewStackProcessor::GetInstance();
228 auto component = AceType::DynamicCast<PieceComponent>(stack->GetMainComponent());
229 if (!component) {
230 LOGE("component is not valid");
231 return;
232 }
233 auto textStyle = component->GetTextStyle();
234 textStyle.SetFontFamilies(fontFamilies);
235 component->SetTextStyle(std::move(textStyle));
236 }
237
SetIconPosition(const JSCallbackInfo & info)238 void JSPiece::SetIconPosition(const JSCallbackInfo& info)
239 {
240 if (info.Length() < 1) {
241 LOGE("The arg is wrong, it is supposed to have at least 1 arguments");
242 return;
243 }
244 if (!info[0]->IsNumber()) {
245 LOGE("arg is not number.");
246 return;
247 }
248
249 auto stack = ViewStackProcessor::GetInstance();
250 auto component = AceType::DynamicCast<PieceComponent>(stack->GetMainComponent());
251 if (!component) {
252 LOGE("pieceComponent is null");
253 return;
254 }
255
256 auto pieceIconPosition = static_cast<OHOS::Ace::IconPosition>(info[0]->ToNumber<int32_t>());
257 component->SetIconPosition(pieceIconPosition);
258 }
259
260 } // namespace OHOS::Ace::Framework
261