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