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>::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 if (info.Length() < 1) {
100 LOGE("The arg is wrong, it is supposed to have at least 1 arguments");
101 return;
102 }
103 auto stack = ViewStackProcessor::GetInstance();
104 auto component = AceType::DynamicCast<PieceComponent>(stack->GetMainComponent());
105 if (!component) {
106 LOGE("component is not valid");
107 return;
108 }
109 if (info[0]->IsBoolean()) {
110 showDelete = info[0]->ToBoolean();
111 component->SetShowDelete(showDelete);
112 } else if (info[0]->IsNumber()) {
113 int32_t arg = info[0]->ToNumber<int32_t>();
114 if (arg == 0 || arg == 1) {
115 showDelete = static_cast<bool>(arg);
116 component->SetShowDelete(showDelete);
117 }
118 } else {
119 component->SetShowDelete(showDelete);
120 }
121 }
122
JsOnClose(const JSCallbackInfo & info)123 void JSPiece::JsOnClose(const JSCallbackInfo& info)
124 {
125 if (info[0]->IsFunction()) {
126 JSRef<JSFunc> clickFunction = JSRef<JSFunc>::Cast(info[0]);
127 auto onClickFunc = AceType::MakeRefPtr<JsClickFunction>(clickFunction);
128 EventMarker clickEventId(
129 [execCtx = info.GetExecutionContext(), func = std::move(onClickFunc)](const BaseEventInfo* info) {
130 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
131 ACE_SCORING_EVENT("Piece.onClose");
132 func->Execute();
133 });
134 auto pieceComponent =
135 AceType::DynamicCast<PieceComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
136 if (pieceComponent) {
137 pieceComponent->SetOnDelete(clickEventId);
138 }
139 }
140 }
141
SetTextColor(const JSCallbackInfo & info)142 void JSPiece::SetTextColor(const JSCallbackInfo& info)
143 {
144 if (info.Length() < 1) {
145 LOGE("The argv is wrong, it is supposed to have at least 1 argument");
146 return;
147 }
148 Color textColor;
149 if (!ParseJsColor(info[0], textColor)) {
150 return;
151 }
152 auto stack = ViewStackProcessor::GetInstance();
153 auto component = AceType::DynamicCast<PieceComponent>(stack->GetMainComponent());
154 if (!component) {
155 LOGE("component is not valid");
156 return;
157 }
158 auto textStyle = component->GetTextStyle();
159 textStyle.SetTextColor(textColor);
160 component->SetTextStyle(std::move(textStyle));
161 }
162
SetFontSize(const JSCallbackInfo & info)163 void JSPiece::SetFontSize(const JSCallbackInfo& info)
164 {
165 if (info.Length() < 1) {
166 LOGE("The argv is wrong, it is supposed to have at least 1 argument");
167 return;
168 }
169 CalcDimension fontSize;
170 if (!ParseJsDimensionFp(info[0], fontSize)) {
171 return;
172 }
173 auto stack = ViewStackProcessor::GetInstance();
174 auto component = AceType::DynamicCast<PieceComponent>(stack->GetMainComponent());
175 if (!component) {
176 LOGE("component is not valid");
177 return;
178 }
179 auto textStyle = component->GetTextStyle();
180 textStyle.SetFontSize(fontSize);
181 component->SetTextStyle(std::move(textStyle));
182 }
183
SetFontStyle(int32_t value)184 void JSPiece::SetFontStyle(int32_t value)
185 {
186 auto stack = ViewStackProcessor::GetInstance();
187 auto component = AceType::DynamicCast<PieceComponent>(stack->GetMainComponent());
188 if (!component) {
189 LOGE("component is not valid");
190 return;
191 }
192 if (value >= 0 && value < static_cast<int32_t>(FONT_STYLES.size())) {
193 auto textStyle = component->GetTextStyle();
194 textStyle.SetFontStyle(FONT_STYLES[value]);
195 component->SetTextStyle(std::move(textStyle));
196 } else {
197 LOGE("Text fontStyle(%d) illegal value", value);
198 }
199 }
200
SetFontWeight(const std::string & value)201 void JSPiece::SetFontWeight(const std::string& value)
202 {
203 auto stack = ViewStackProcessor::GetInstance();
204 auto component = AceType::DynamicCast<PieceComponent>(stack->GetMainComponent());
205 if (!component) {
206 LOGE("component is not valid");
207 return;
208 }
209
210 auto textStyle = component->GetTextStyle();
211 textStyle.SetFontWeight(ConvertStrToFontWeight(value));
212 component->SetTextStyle(std::move(textStyle));
213 }
214
SetFontFamily(const JSCallbackInfo & info)215 void JSPiece::SetFontFamily(const JSCallbackInfo& info)
216 {
217 if (info.Length() < 1) {
218 LOGE("The argv is wrong, it is supposed to have at least 1 argument");
219 return;
220 }
221 std::vector<std::string> fontFamilies;
222 if (!ParseJsFontFamilies(info[0], fontFamilies)) {
223 LOGE("Parse FontFamilies failed");
224 return;
225 }
226 auto stack = ViewStackProcessor::GetInstance();
227 auto component = AceType::DynamicCast<PieceComponent>(stack->GetMainComponent());
228 if (!component) {
229 LOGE("component is not valid");
230 return;
231 }
232 auto textStyle = component->GetTextStyle();
233 textStyle.SetFontFamilies(fontFamilies);
234 component->SetTextStyle(std::move(textStyle));
235 }
236
SetIconPosition(const JSCallbackInfo & info)237 void JSPiece::SetIconPosition(const JSCallbackInfo& info)
238 {
239 if (info.Length() < 1) {
240 LOGE("The arg is wrong, it is supposed to have at least 1 arguments");
241 return;
242 }
243 if (!info[0]->IsNumber()) {
244 LOGE("arg is not number.");
245 return;
246 }
247
248 auto stack = ViewStackProcessor::GetInstance();
249 auto component = AceType::DynamicCast<PieceComponent>(stack->GetMainComponent());
250 if (!component) {
251 LOGE("pieceComponent is null");
252 return;
253 }
254
255 auto pieceIconPosition = static_cast<OHOS::Ace::IconPosition>(info[0]->ToNumber<int32_t>());
256 component->SetIconPosition(pieceIconPosition);
257 }
258
259 } // namespace OHOS::Ace::Framework
260