* Copyright (c) 2025 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 "shape.h"
namespace OHOS::Ace {
namespace {
const char* ANI_SHAPE_NAME = "@ohos.arkui.shape.CircleShape";
}
void ANICreateCircleShapeWithParam(ani_env* env, [[maybe_unused]] ani_object object,
[[maybe_unused]] ani_object aniOption)
{
if (GetIsUndefinedObject(env, aniOption)) {
return;
}
if (!IsInstanceOfCls(env, object, ANI_SHAPE_NAME)) {
return;
}
CirclePeer* shapePeer = new CirclePeer();
auto circle = AceType::MakeRefPtr<Circle>();
std::optional<OHOS::Ace::CalcDimension> width;
ParseStringNumberUndefinedOption(env, aniOption, width, "width", "@ohos.arkui.shape.ShapeSize");
if (width.has_value() && width->IsValid()) {
circle->SetWidth(width.value());
}
std::optional<OHOS::Ace::CalcDimension> height;
ParseStringNumberUndefinedOption(env, aniOption, height, "height", "@ohos.arkui.shape.ShapeSize");
if (height.has_value() && height->IsValid()) {
circle->SetHeight(height.value());
}
shapePeer->circleShape = circle;
ani_status status;
if ((status = env->Object_SetPropertyByName_Long(
object, "basicShapeResult", reinterpret_cast<ani_long>(shapePeer))) != ANI_OK) {
LOGE("CircleShape set addr failed, status:%{public}d", status);
delete shapePeer;
return;
}
}
CirclePeer* GetCircleShape(ani_env* env, ani_object obj)
{
ani_long circleAni;
if (ANI_OK != env->Object_GetFieldByName_Long(obj, "basicShapeResult", &circleAni)) {
return nullptr;
}
auto circle = reinterpret_cast<CirclePeer*>(circleAni);
return circle;
}
ani_object ANICircleShapeWidth(ani_env* env, [[maybe_unused]] ani_object object, [[maybe_unused]] ani_object aniOption)
{
if (GetIsUndefinedObject(env, aniOption)) {
return object;
}
ani_class cls;
if (ANI_OK != env->FindClass(ANI_SHAPE_NAME, &cls)) {
return nullptr;
}
CirclePeer* circleObj = GetCircleShape(env, object);
if (!circleObj) {
return object;
}
CalcDimension width;
if (!ParseLength(env, object, aniOption, width)) {
return object;
}
if (circleObj->circleShape) {
circleObj->circleShape->SetWidth(width);
}
return object;
}
ani_object ANICircleShapeHeight(ani_env* env, [[maybe_unused]] ani_object object, [[maybe_unused]] ani_object aniOption)
{
if (GetIsUndefinedObject(env, aniOption)) {
return object;
}
ani_class cls;
if (ANI_OK != env->FindClass(ANI_SHAPE_NAME, &cls)) {
return nullptr;
}
CirclePeer* circleObj = GetCircleShape(env, object);
if (!circleObj) {
return object;
}
CalcDimension width;
if (!ParseLength(env, object, aniOption, width)) {
return object;
}
if (circleObj->circleShape) {
circleObj->circleShape->SetHeight(width);
}
return object;
}
ani_object ANICircleShapeSize(ani_env* env, [[maybe_unused]] ani_object object, [[maybe_unused]] ani_object aniOption)
{
if (GetIsUndefinedObject(env, aniOption)) {
return object;
}
CirclePeer* circleObj = GetCircleShape(env, object);
if (!circleObj) {
return object;
}
CalcDimension width;
ParseOption(env, aniOption, width, "width", "arkui.component.units.SizeOptions");
if (circleObj->circleShape) {
circleObj->circleShape->SetWidth(width);
}
CalcDimension height;
ParseOption(env, aniOption, height, "height", "arkui.component.units.SizeOptions");
if (circleObj->circleShape) {
circleObj->circleShape->SetHeight(height);
}
return object;
}
ani_object ANICircleShapePosition(
ani_env* env, [[maybe_unused]] ani_object object, [[maybe_unused]] ani_object aniOption)
{
if (GetIsUndefinedObject(env, aniOption)) {
return object;
}
CirclePeer* circleObj = GetCircleShape(env, object);
if (!circleObj) {
return object;
}
CalcDimension dx;
ParseOption(env, aniOption, dx, "x", "arkui.component.units.Position");
CalcDimension dy;
ParseOption(env, aniOption, dy, "y", "arkui.component.units.Position");
DimensionOffset position(dx, dy);
if (circleObj->circleShape) {
circleObj->circleShape->SetPosition(position);
}
return object;
}
ani_object ANICircleShapeOffset(ani_env* env, [[maybe_unused]] ani_object object, [[maybe_unused]] ani_object aniOption)
{
if (GetIsUndefinedObject(env, aniOption)) {
return object;
}
CirclePeer* circleObj = GetCircleShape(env, object);
if (!circleObj) {
return object;
}
CalcDimension dx;
ParseOption(env, aniOption, dx, "x", "arkui.component.units.Position");
CalcDimension dy;
ParseOption(env, aniOption, dy, "y", "arkui.component.units.Position");
DimensionOffset position(dx, dy);
if (circleObj->circleShape) {
circleObj->circleShape->SetOffset(position);
}
return object;
}
ani_object ANICircleShapeColor(ani_env* env, ani_object object, [[maybe_unused]] ani_object aniOption)
{
if (GetIsUndefinedObject(env, aniOption)) {
return object;
}
OHOS::Ace::Color resourceColor;
if (!ParseAniColor(env, aniOption, resourceColor)) {
return object;
}
CirclePeer* circleObj = GetCircleShape(env, object);
if (!circleObj) {
return object;
}
if (circleObj->circleShape) {
circleObj->circleShape->SetColor(resourceColor);
}
return object;
}
ani_object CircleShape::ANICircleShapeFromPtr(ani_env* env, [[maybe_unused]] ani_object aniClass, ani_long ptr)
{
return ANIShapeFromPtr<CirclePeer>(env, ptr, ANI_SHAPE_NAME, "basicShapeResult");
}
ani_status CircleShape::BindCircleShape(ani_env* env)
{
ani_class cls;
ani_status status;
if ((status = env->FindClass(ANI_SHAPE_NAME, &cls)) != ANI_OK) {
LOGW("find CircleShape class error, status:%{public}d", status);
return ANI_ERROR;
}
std::array methods = {
ani_native_function {
"<ctor>", "C{@ohos.arkui.shape.ShapeSize}:", reinterpret_cast<void*>(ANICreateCircleShapeWithParam) },
ani_native_function { "width", nullptr, reinterpret_cast<void*>(ANICircleShapeWidth) },
ani_native_function { "height", nullptr, reinterpret_cast<void*>(ANICircleShapeHeight) },
ani_native_function { "size", nullptr, reinterpret_cast<void*>(ANICircleShapeSize) },
ani_native_function { "position", nullptr, reinterpret_cast<void*>(ANICircleShapePosition) },
ani_native_function { "offset", nullptr, reinterpret_cast<void*>(ANICircleShapeOffset) },
ani_native_function { "fill", nullptr, reinterpret_cast<void*>(ANICircleShapeColor) },
};
status = env->Class_BindNativeMethods(cls, methods.data(), methods.size());
if (ANI_OK != status) {
LOGW("bind CircleShape methods error, status:%{public}d", status);
return ANI_ERROR;
}
return ANI_OK;
}
}