/* * Copyright (c) 2021 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "frameworks/bridge/declarative_frontend/jsview/js_rect.h" #include "base/log/ace_trace.h" #include "bridge/declarative_frontend/jsview/models/rect_model_impl.h" #include "bridge/declarative_frontend/view_stack_processor.h" #include "core/components_ng/pattern/shape/rect_model.h" #include "core/components_ng/pattern/shape/rect_model_ng.h" namespace OHOS::Ace { std::unique_ptr RectModel::instance_ = nullptr; RectModel* RectModel::GetInstance() { if (!instance_) { #ifdef NG_BUILD instance_.reset(new NG::RectModelNG()); #else if (Container::IsCurrentUseNewPipeline()) { instance_.reset(new NG::RectModelNG()); } else { instance_.reset(new Framework::RectModelImpl()); } #endif } return instance_.get(); } } // namespace OHOS::Ace namespace OHOS::Ace::Framework { void JSRect::Create(const JSCallbackInfo& info) { RectModel::GetInstance()->Create(); JSShapeAbstract::SetSize(info); if (info.Length() > 0 && info[0]->IsObject()) { JSRef obj = JSRef::Cast(info[0]); JSRef radiusWidth = obj->GetProperty("radiusWidth"); Dimension widthValue; if (ParseJsDimensionVp(radiusWidth, widthValue)) { RectModel::GetInstance()->SetRadiusWidth(widthValue); } JSRef radiusHeight = obj->GetProperty("radiusHeight"); Dimension heightValue; if (ParseJsDimensionVp(radiusHeight, heightValue)) { RectModel::GetInstance()->SetRadiusHeight(heightValue); } JSRef radius = obj->GetProperty("radius"); if (radius->IsNumber() || radius->IsString()) { SetRadiusWithJsVal(nullptr, radius); } if (radius->IsArray()) { SetRadiusWithArrayValue(nullptr, radius); } info.SetReturnValue(info.This()); } } void JSRect::SetRadiusWidth(const JSCallbackInfo& info) { if (info.Length() < 1) { LOGE("The arg is wrong, it is supposed to have at least 1 argument"); return; } if (!info[0]->IsNumber() && !info[0]->IsString()) { LOGE("arg is not Number or String."); return; } Dimension value; if (!ParseJsDimensionVp(info[0], value)) { return; } RectModel::GetInstance()->SetRadiusWidth(value); } void JSRect::SetRadiusHeight(const JSCallbackInfo& info) { if (info.Length() < 1) { LOGE("The arg is wrong, it is supposed to have at least 1 argument"); return; } Dimension value; if (!ParseJsDimensionVp(info[0], value)) { return; } RectModel::GetInstance()->SetRadiusHeight(value); } void JSRect::SetRadius(const JSCallbackInfo& info) { if (info.Length() < 1) { LOGE("The arg is wrong, it is supposed to have at least 1 argument"); return; } if (info[0]->IsArray()) { SetRadiusWithArrayValue(nullptr, info[0]); info.SetReturnValue(info.This()); return; } if (info[0]->IsNumber() || info[0]->IsString() || info[0]->IsObject()) { SetRadiusWithJsVal(nullptr, info[0]); info.SetReturnValue(info.This()); } } template void JSRect::SetRadiusWithJsVal(const RefPtr& component, const JSRef& jsVal) { Dimension value; if (!ParseJsDimensionVp(jsVal, value)) { return; } if (component) { AnimationOption option = ViewStackProcessor::GetInstance()->GetImplicitAnimationOption(); component->SetRadiusWidth(value, option); component->SetRadiusHeight(value, option); return; } RectModel::GetInstance()->SetRadiusWidth(value); RectModel::GetInstance()->SetRadiusHeight(value); } template void JSRect::SetRadiusWithArrayValue(const RefPtr& component, const JSRef& jsVal) { JSRef array = JSRef::Cast(jsVal); int32_t length = static_cast(array->Length()); if (length <= 0) { LOGE("info is invalid"); return; } length = std::min(length, 4); for (int32_t i = 0; i < length; i++) { JSRef radiusItem = array->GetValueAt(i); if (!radiusItem->IsArray()) { break; } JSRef radiusArray = JSRef::Cast(radiusItem); if (radiusArray->Length() != 2) { break; } JSRef radiusX = radiusArray->GetValueAt(0); JSRef radiusY = radiusArray->GetValueAt(1); Dimension radiusXValue; Dimension radiusYValue; if (ParseJsDimensionVp(radiusX, radiusXValue) && ParseJsDimensionVp(radiusY, radiusYValue)) { SetRadiusValue(component, radiusXValue, radiusYValue, i); } } } template void JSRect::SetRadiusValue( const RefPtr& component, const Dimension& radiusX, const Dimension& radiusY, int32_t index) { if (component) { RectModel::GetInstance()->SetCallbackRadius(component, radiusX, radiusY, index); } else { RectModel::GetInstance()->SetRadiusValue(radiusX, radiusY, index); } } void JSRect::ObjectRadiusWidth(const JSCallbackInfo& info) { info.ReturnSelf(); if (info.Length() < 1) { LOGE("The argv is wrong, it is supposed to have at least 1 argument"); return; } Dimension value; if (!ParseJsDimensionVp(info[0], value)) { return; } if (LessNotEqual(value.Value(), 0.0)) { LOGE("Value is less than zero"); return; } auto rect = AceType::DynamicCast(basicShape_); if (rect) { rect->SetRadiusWidth(value); } } void JSRect::ObjectRadiusHeight(const JSCallbackInfo& info) { info.ReturnSelf(); if (info.Length() < 1) { LOGE("The argv is wrong, it is supposed to have at least 1 argument"); return; } Dimension value; if (!ParseJsDimensionVp(info[0], value)) { return; } if (LessNotEqual(value.Value(), 0.0)) { LOGE("Value is less than zero"); return; } auto rect = AceType::DynamicCast(basicShape_); if (rect) { rect->SetRadiusHeight(value); } } void JSRect::ObjectRadius(const JSCallbackInfo& info) { info.ReturnSelf(); if (info.Length() < 1) { LOGE("arg is invalid"); return; } auto rect = AceType::DynamicCast(basicShape_); if (!rect) { LOGE("rect is null"); return; } if (info[0]->IsNumber() || info[0]->IsString()) { SetRadiusWithJsVal(rect, info[0]); } if (info[0]->IsArray()) { SetRadiusWithArrayValue(rect, info[0]); } } void JSRect::ConstructorCallback(const JSCallbackInfo& info) { auto jsRect = AceType::MakeRefPtr(); auto rect = AceType::MakeRefPtr(); if (info.Length() > 0 && info[0]->IsObject()) { JSRef obj = JSRef::Cast(info[0]); Dimension width; if (ParseJsDimensionVp(obj->GetProperty("width"), width) && width.IsValid()) { rect->SetWidth(width); } Dimension height; if (ParseJsDimensionVp(obj->GetProperty("height"), height) && height.IsValid()) { rect->SetHeight(height); } Dimension radiusWidth; if (ParseJsDimensionVp(obj->GetProperty("radiusWidth"), radiusWidth) && radiusWidth.IsValid()) { rect->SetRadiusWidth(radiusWidth); } Dimension radiusHeight; if (ParseJsDimensionVp(obj->GetProperty("radiusHeight"), radiusHeight) && radiusHeight.IsValid()) { rect->SetRadiusHeight(radiusHeight); } JSRef radius = obj->GetProperty("radius"); if (radius->IsNumber() || radius->IsString()) { SetRadiusWithJsVal(rect, radius); } if (radius->IsArray()) { SetRadiusWithArrayValue(rect, radius); } info.SetReturnValue(info.This()); } jsRect->SetBasicShape(rect); jsRect->IncRefCount(); info.SetReturnValue(AceType::RawPtr(jsRect)); } void JSRect::DestructorCallback(JSRect* jsRect) { if (jsRect != nullptr) { jsRect->DecRefCount(); } } void JSRect::JSBind(BindingTarget globalObj) { JSClass::Declare("Rect"); JSClass::StaticMethod("create", &JSRect::Create); JSClass::StaticMethod("radiusWidth", &JSRect::SetRadiusWidth); JSClass::StaticMethod("radiusHeight", &JSRect::SetRadiusHeight); JSClass::StaticMethod("radius", &JSRect::SetRadius); JSClass::CustomMethod("width", &JSShapeAbstract::ObjectWidth); JSClass::CustomMethod("height", &JSShapeAbstract::ObjectHeight); JSClass::CustomMethod("size", &JSShapeAbstract::ObjectSize); JSClass::CustomMethod("offset", &JSShapeAbstract::ObjectOffset); JSClass::CustomMethod("radiusWidth", &JSRect::ObjectRadiusWidth); JSClass::CustomMethod("radiusHeight", &JSRect::ObjectRadiusHeight); JSClass::CustomMethod("radius", &JSRect::ObjectRadius); JSClass::CustomMethod("fill", &JSShapeAbstract::ObjectFill); JSClass::StaticMethod("onTouch", &JSInteractableView::JsOnTouch); JSClass::StaticMethod("onHover", &JSInteractableView::JsOnHover); JSClass::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey); JSClass::StaticMethod("onDeleteEvent", &JSInteractableView::JsOnDelete); JSClass::StaticMethod("onClick", &JSInteractableView::JsOnClick); JSClass::Inherit(); JSClass::Bind(globalObj, JSRect::ConstructorCallback, JSRect::DestructorCallback); } } // namespace OHOS::Ace::Framework