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