• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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_rect.h"
17 
18 #include "base/log/ace_trace.h"
19 #include "frameworks/bridge/declarative_frontend/view_stack_processor.h"
20 
21 namespace OHOS::Ace::Framework {
22 
Create(const JSCallbackInfo & info)23 void JSRect::Create(const JSCallbackInfo& info)
24 {
25     RefPtr<ShapeComponent> rectComponent = AceType::MakeRefPtr<OHOS::Ace::ShapeComponent>(ShapeType::RECT);
26     ViewStackProcessor::GetInstance()->Push(rectComponent);
27     JSShapeAbstract::SetSize(info);
28     if (info.Length() > 0 && info[0]->IsObject()) {
29         JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
30         JSRef<JSVal> radiusWidth = obj->GetProperty("radiusWidth");
31         Dimension widthValue;
32         if (ParseJsDimensionVp(radiusWidth, widthValue)) {
33             rectComponent->SetRadiusWidth(widthValue);
34         }
35 
36         JSRef<JSVal> radiusHeight = obj->GetProperty("radiusHeight");
37         Dimension heightValue;
38         if (ParseJsDimensionVp(radiusHeight, heightValue)) {
39             rectComponent->SetRadiusHeight(heightValue);
40         }
41 
42         JSRef<JSVal> radius = obj->GetProperty("radius");
43         if (radius->IsNumber() || radius->IsString()) {
44             SetRadiusWithJsVal<ShapeComponent>(rectComponent, radius);
45         }
46         if (radius->IsArray()) {
47             SetRadiusWithArrayValue<ShapeComponent>(rectComponent, radius);
48         }
49         info.SetReturnValue(info.This());
50     }
51 }
52 
SetRadiusWidth(const JSCallbackInfo & info)53 void JSRect::SetRadiusWidth(const JSCallbackInfo& info)
54 {
55     if (info.Length() < 1) {
56         LOGE("The arg is wrong, it is supposed to have at least 1 argument");
57         return;
58     }
59 
60     if (!info[0]->IsNumber() && !info[0]->IsString()) {
61         LOGE("arg is not Number or String.");
62         return;
63     }
64     auto stack = ViewStackProcessor::GetInstance();
65     auto component = AceType::DynamicCast<OHOS::Ace::ShapeComponent>(stack->GetMainComponent());
66     if (!component) {
67         LOGE("shapeComponent is null");
68         return;
69     }
70     Dimension value;
71     if (!ParseJsDimensionVp(info[0], value)) {
72         return;
73     }
74     AnimationOption option = stack->GetImplicitAnimationOption();
75     component->SetRadiusWidth(value, option);
76 }
77 
SetRadiusHeight(const JSCallbackInfo & info)78 void JSRect::SetRadiusHeight(const JSCallbackInfo& info)
79 {
80     if (info.Length() < 1) {
81         LOGE("The arg is wrong, it is supposed to have at least 1 argument");
82         return;
83     }
84     Dimension value;
85     if (!ParseJsDimensionVp(info[0], value)) {
86         return;
87     }
88     auto stack = ViewStackProcessor::GetInstance();
89     auto component = AceType::DynamicCast<OHOS::Ace::ShapeComponent>(stack->GetMainComponent());
90     if (!component) {
91         LOGE("shapeComponent is null");
92         return;
93     }
94     AnimationOption option = stack->GetImplicitAnimationOption();
95     component->SetRadiusHeight(value, option);
96 }
97 
SetRadius(const JSCallbackInfo & info)98 void JSRect::SetRadius(const JSCallbackInfo& info)
99 {
100     if (info.Length() < 1) {
101         LOGE("The arg is wrong, it is supposed to have at least 1 argument");
102         return;
103     }
104     auto stack = ViewStackProcessor::GetInstance();
105     auto component = AceType::DynamicCast<OHOS::Ace::ShapeComponent>(stack->GetMainComponent());
106     if (!component) {
107         LOGE("component is null");
108         return;
109     }
110 
111     if (info[0]->IsArray()) {
112         SetRadiusWithArrayValue<ShapeComponent>(component, info[0]);
113         info.SetReturnValue(info.This());
114         return;
115     }
116     if (info[0]->IsNumber() || info[0]->IsString() || info[0]->IsObject()) {
117         SetRadiusWithJsVal<ShapeComponent>(component, info[0]);
118         info.SetReturnValue(info.This());
119     }
120 }
121 
122 template<class T>
SetRadiusWithJsVal(const RefPtr<T> & component,const JSRef<JSVal> & jsVal)123 void JSRect::SetRadiusWithJsVal(const RefPtr<T>& component, const JSRef<JSVal>& jsVal)
124 {
125     Dimension value;
126     if (!ParseJsDimensionVp(jsVal, value)) {
127         return;
128     }
129     AnimationOption option = ViewStackProcessor::GetInstance()->GetImplicitAnimationOption();
130     component->SetRadiusWidth(value, option);
131     component->SetRadiusHeight(value, option);
132 }
133 
134 template<class T>
SetRadiusWithArrayValue(const RefPtr<T> & component,const JSRef<JSVal> & jsVal)135 void JSRect::SetRadiusWithArrayValue(const RefPtr<T>& component, const JSRef<JSVal>& jsVal)
136 {
137     JSRef<JSArray> array = JSRef<JSArray>::Cast(jsVal);
138     int32_t length = static_cast<int32_t>(array->Length());
139     if (length <= 0) {
140         LOGE("info is invalid");
141         return;
142     }
143     length = std::min(length, 4);
144     for (int32_t i = 0; i < length; i++) {
145         JSRef<JSVal> radiusItem = array->GetValueAt(i);
146         if (!radiusItem->IsArray()) {
147             break;
148         }
149         JSRef<JSArray> radiusArray = JSRef<JSArray>::Cast(radiusItem);
150         if (radiusArray->Length() != 2) {
151             break;
152         }
153         JSRef<JSVal> radiusX = radiusArray->GetValueAt(0);
154         JSRef<JSVal> radiusY = radiusArray->GetValueAt(1);
155         Dimension radiusXValue;
156         Dimension radiusYValue;
157         if (ParseJsDimensionVp(radiusX, radiusXValue) && ParseJsDimensionVp(radiusY, radiusYValue)) {
158             SetRadiusValue<T>(component, radiusXValue, radiusYValue, i);
159         }
160     }
161 }
162 
163 template<class T>
SetRadiusValue(const RefPtr<T> & component,const Dimension & radiusX,const Dimension & radiusY,int32_t index)164 void JSRect::SetRadiusValue(const RefPtr<T>& component, const Dimension& radiusX,
165     const Dimension& radiusY, int32_t index)
166 {
167     AnimationOption option = ViewStackProcessor::GetInstance()->GetImplicitAnimationOption();
168     Radius newRadius = Radius(AnimatableDimension(radiusX, option), AnimatableDimension(radiusY, option));
169     switch (index) {
170         case 0:
171             component->SetTopLeftRadius(newRadius);
172             break;
173         case 1:
174             component->SetTopRightRadius(newRadius);
175             break;
176         case 2:
177             component->SetBottomRightRadius(newRadius);
178             break;
179         case 3:
180             component->SetBottomLeftRadius(newRadius);
181             break;
182         default:
183             break;
184     }
185 }
186 
ObjectRadiusWidth(const JSCallbackInfo & info)187 void JSRect::ObjectRadiusWidth(const JSCallbackInfo& info)
188 {
189     info.ReturnSelf();
190     if (info.Length() < 1) {
191         LOGE("The argv is wrong, it is supposed to have at least 1 argument");
192         return;
193     }
194     Dimension value;
195     if (!ParseJsDimensionVp(info[0], value)) {
196         return;
197     }
198     if (LessNotEqual(value.Value(), 0.0)) {
199         LOGE("Value is less than zero");
200         return;
201     }
202     auto rect = AceType::DynamicCast<ShapeRect>(basicShape_);
203     if (rect) {
204         rect->SetRadiusWidth(value);
205     }
206 }
207 
ObjectRadiusHeight(const JSCallbackInfo & info)208 void JSRect::ObjectRadiusHeight(const JSCallbackInfo& info)
209 {
210     info.ReturnSelf();
211     if (info.Length() < 1) {
212         LOGE("The argv is wrong, it is supposed to have at least 1 argument");
213         return;
214     }
215     Dimension value;
216     if (!ParseJsDimensionVp(info[0], value)) {
217         return;
218     }
219     if (LessNotEqual(value.Value(), 0.0)) {
220         LOGE("Value is less than zero");
221         return;
222     }
223     auto rect = AceType::DynamicCast<ShapeRect>(basicShape_);
224     if (rect) {
225         rect->SetRadiusHeight(value);
226     }
227 }
228 
ObjectRadius(const JSCallbackInfo & info)229 void JSRect::ObjectRadius(const JSCallbackInfo& info)
230 {
231     info.ReturnSelf();
232     if (info.Length() < 1) {
233         LOGE("arg is invalid");
234         return;
235     }
236     auto rect = AceType::DynamicCast<ShapeRect>(basicShape_);
237     if (!rect) {
238         LOGE("rect is null");
239         return;
240     }
241     if (info[0]->IsNumber() || info[0]->IsString()) {
242         SetRadiusWithJsVal<ShapeRect>(rect, info[0]);
243     }
244     if (info[0]->IsArray()) {
245         SetRadiusWithArrayValue<ShapeRect>(rect, info[0]);
246     }
247 }
248 
ConstructorCallback(const JSCallbackInfo & info)249 void JSRect::ConstructorCallback(const JSCallbackInfo& info)
250 {
251     auto jsRect = AceType::MakeRefPtr<JSRect>();
252     auto rect = AceType::MakeRefPtr<ShapeRect>();
253     if (info.Length() > 0 && info[0]->IsObject()) {
254         JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
255         Dimension width;
256         if (ParseJsDimensionVp(obj->GetProperty("width"), width) && width.IsValid()) {
257             rect->SetWidth(width);
258         }
259         Dimension height;
260         if (ParseJsDimensionVp(obj->GetProperty("height"), height) && height.IsValid()) {
261             rect->SetHeight(height);
262         }
263         Dimension radiusWidth;
264         if (ParseJsDimensionVp(obj->GetProperty("radiusWidth"), radiusWidth) && radiusWidth.IsValid()) {
265             rect->SetRadiusWidth(radiusWidth);
266         }
267         Dimension radiusHeight;
268         if (ParseJsDimensionVp(obj->GetProperty("radiusHeight"), radiusHeight) && radiusHeight.IsValid()) {
269             rect->SetRadiusHeight(radiusHeight);
270         }
271         JSRef<JSVal> radius = obj->GetProperty("radius");
272         if (radius->IsNumber() || radius->IsString()) {
273             SetRadiusWithJsVal<ShapeRect>(rect, radius);
274         }
275         if (radius->IsArray()) {
276             SetRadiusWithArrayValue<ShapeRect>(rect, radius);
277         }
278         info.SetReturnValue(info.This());
279     }
280     jsRect->SetBasicShape(rect);
281     jsRect->IncRefCount();
282     info.SetReturnValue(AceType::RawPtr(jsRect));
283 }
284 
DestructorCallback(JSRect * jsRect)285 void JSRect::DestructorCallback(JSRect* jsRect)
286 {
287     if (jsRect != nullptr) {
288         jsRect->DecRefCount();
289     }
290 }
291 
JSBind(BindingTarget globalObj)292 void JSRect::JSBind(BindingTarget globalObj)
293 {
294     JSClass<JSRect>::Declare("Rect");
295     JSClass<JSRect>::StaticMethod("create", &JSRect::Create);
296     JSClass<JSRect>::StaticMethod("radiusWidth", &JSRect::SetRadiusWidth);
297     JSClass<JSRect>::StaticMethod("radiusHeight", &JSRect::SetRadiusHeight);
298     JSClass<JSRect>::StaticMethod("radius", &JSRect::SetRadius);
299 
300     JSClass<JSRect>::CustomMethod("width", &JSShapeAbstract::ObjectWidth);
301     JSClass<JSRect>::CustomMethod("height", &JSShapeAbstract::ObjectHeight);
302     JSClass<JSRect>::CustomMethod("size", &JSShapeAbstract::ObjectSize);
303     JSClass<JSRect>::CustomMethod("offset", &JSShapeAbstract::ObjectOffset);
304     JSClass<JSRect>::CustomMethod("radiusWidth", &JSRect::ObjectRadiusWidth);
305     JSClass<JSRect>::CustomMethod("radiusHeight", &JSRect::ObjectRadiusHeight);
306     JSClass<JSRect>::CustomMethod("radius", &JSRect::ObjectRadius);
307     JSClass<JSRect>::CustomMethod("fill", &JSShapeAbstract::ObjectFill);
308 
309     JSClass<JSRect>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
310     JSClass<JSRect>::StaticMethod("onHover", &JSInteractableView::JsOnHover);
311     JSClass<JSRect>::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey);
312     JSClass<JSRect>::StaticMethod("onDeleteEvent", &JSInteractableView::JsOnDelete);
313     JSClass<JSRect>::StaticMethod("onClick", &JSInteractableView::JsOnClick);
314 
315     JSClass<JSRect>::Inherit<JSShapeAbstract>();
316     JSClass<JSRect>::Bind(globalObj, JSRect::ConstructorCallback, JSRect::DestructorCallback);
317 }
318 
319 } // namespace OHOS::Ace::Framework
320