/* * Copyright (c) 2021-2023 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_button.h" #if !defined(PREVIEW) && defined(OHOS_PLATFORM) #include "interfaces/inner_api/ui_session/ui_session_manager.h" #endif #include "base/geometry/dimension.h" #include "base/log/ace_scoring_log.h" #include "base/log/ace_trace.h" #include "base/utils/utils.h" #include "core/components/button/button_component.h" #include "core/components/button/button_theme.h" #include "core/components_ng/base/view_stack_processor.h" #include "core/components_ng/pattern/button/button_model_ng.h" #include "frameworks/bridge/declarative_frontend/ark_theme/theme_apply/js_button_theme.h" #include "frameworks/bridge/declarative_frontend/engine/functions/js_click_function.h" #include "frameworks/bridge/declarative_frontend/jsview/js_utils.h" #include "frameworks/bridge/declarative_frontend/jsview/models/button_model_impl.h" #include "frameworks/bridge/declarative_frontend/view_stack_processor.h" namespace OHOS::Ace { std::unique_ptr ButtonModel::instance_ = nullptr; std::mutex ButtonModel::mutex_; ButtonModel* ButtonModel::GetInstance() { if (!instance_) { std::lock_guard lock(mutex_); if (!instance_) { #ifdef NG_BUILD instance_.reset(new NG::ButtonModelNG()); #else if (Container::IsCurrentUseNewPipeline()) { instance_.reset(new NG::ButtonModelNG()); } else { instance_.reset(new Framework::ButtonModelImpl()); } #endif } } return instance_.get(); } } // namespace OHOS::Ace namespace OHOS::Ace::Framework { const std::vector TEXT_OVERFLOWS = { TextOverflow::NONE, TextOverflow::CLIP, TextOverflow::ELLIPSIS, TextOverflow::MARQUEE }; const std::vector FONT_STYLES = { FontStyle::NORMAL, FontStyle::ITALIC }; const std::vector HEIGHT_ADAPTIVE_POLICY = { TextHeightAdaptivePolicy::MAX_LINES_FIRST, TextHeightAdaptivePolicy::MIN_FONT_SIZE_FIRST, TextHeightAdaptivePolicy::LAYOUT_CONSTRAINT_FIRST }; bool JSButton::isLabelButton_ = false; void JSButton::SetFontSize(const JSCallbackInfo& info) { auto buttonTheme = GetTheme(); CHECK_NULL_VOID(buttonTheme); CalcDimension fontSize = buttonTheme->GetTextStyle().GetFontSize(); if (ParseJsDimensionVpNG(info[0], fontSize) && fontSize.Unit() != DimensionUnit::PERCENT && GreatOrEqual(fontSize.Value(), 0.0)) { ParseJsDimensionFp(info[0], fontSize); } else { fontSize = buttonTheme->GetTextStyle().GetFontSize(); } ButtonModel::GetInstance()->SetFontSize(fontSize); } void JSButton::SetFontWeight(const std::string& value) { ButtonModel::GetInstance()->SetFontWeight(ConvertStrToFontWeight(value)); } void JSButton::SetFontStyle(int32_t value) { const std::vector fontStyles = { FontStyle::NORMAL, FontStyle::ITALIC }; if (value < 0 || value >= static_cast(fontStyles.size())) { return; } ButtonModel::GetInstance()->SetFontStyle(fontStyles[value]); } void JSButton::SetFontFamily(const JSCallbackInfo& info) { std::vector fontFamilies; if (!ParseJsFontFamilies(info[0], fontFamilies) || fontFamilies.empty()) { auto pipelineContext = PipelineBase::GetCurrentContext(); CHECK_NULL_VOID(pipelineContext); auto textTheme = pipelineContext->GetTheme(); CHECK_NULL_VOID(textTheme); fontFamilies = textTheme->GetTextStyle().GetFontFamilies(); } ButtonModel::GetInstance()->SetFontFamily(fontFamilies); } void JSButton::SetTextColor(const JSCallbackInfo& info) { Color textColor; if (!ParseJsColor(info[0], textColor)) { auto buttonTheme = PipelineBase::GetCurrentContext()->GetTheme(); textColor = buttonTheme->GetTextStyle().GetTextColor(); } ButtonModel::GetInstance()->SetFontColor(textColor); } void JSButton::SetType(const JSCallbackInfo& info) { int32_t value = 1; if (info[0]->IsNumber()) { value = info[0]->ToNumber(); } if ((ButtonType)value == ButtonType::CAPSULE || (ButtonType)value == ButtonType::CIRCLE || (ButtonType)value == ButtonType::ARC || (ButtonType)value == ButtonType::NORMAL) { ButtonModel::GetInstance()->SetType(value); } } void JSButton::SetButtonStyle(const JSCallbackInfo& info) { int32_t value = static_cast(ButtonStyleMode::EMPHASIZE); if (info[0]->IsNumber()) { auto valueT = info[0]->ToNumber(); if (valueT >= static_cast(ButtonStyleMode::NORMAL) && valueT <= static_cast(ButtonStyleMode::TEXT)) { value = valueT; } } auto buttonStyleMode = static_cast(value); if (!JSButtonTheme::ApplyTheme(buttonStyleMode, isLabelButton_)) { ButtonModel::GetInstance()->SetButtonStyle(buttonStyleMode); } } void JSButton::SetControlSize(const JSCallbackInfo& info) { int32_t value = static_cast(ControlSize::NORMAL); if (info[0]->IsNumber()) { auto valueT = info[0]->ToNumber(); if (valueT >= static_cast(ControlSize::SMALL) && valueT <= static_cast(ControlSize::NORMAL)) { value = valueT; } } ButtonModel::GetInstance()->SetControlSize(static_cast(value)); } void JSButton::SetRole(const JSCallbackInfo& info) { int32_t value = static_cast(ButtonRole::NORMAL); if (info[0]->IsNumber()) { auto valueT = info[0]->ToNumber(); if (valueT >= static_cast(ButtonRole::NORMAL) && valueT <= static_cast(ButtonRole::ERROR)) { value = valueT; } } auto buttonRole = static_cast(value); if (!JSButtonTheme::ApplyTheme(buttonRole, isLabelButton_)) { ButtonModel::GetInstance()->SetRole(buttonRole); } } void JSButton::SetStateEffect(const JSCallbackInfo& info) { bool value = info[0]->IsBoolean() ? info[0]->ToBoolean() : true; ButtonModel::GetInstance()->SetStateEffect(value); } void JSButton::HandleDifferentRadius(const JSRef& args) { std::optional radiusTopLeft; std::optional radiusTopRight; std::optional radiusBottomLeft; std::optional radiusBottomRight; if (args->IsObject()) { JSRef object = JSRef::Cast(args); CalcDimension topLeft; if (ParseJsDimensionVp(object->GetProperty("topLeft"), topLeft)) { radiusTopLeft = topLeft; } CalcDimension topRight; if (ParseJsDimensionVp(object->GetProperty("topRight"), topRight)) { radiusTopRight = topRight; } CalcDimension bottomLeft; if (ParseJsDimensionVp(object->GetProperty("bottomLeft"), bottomLeft)) { radiusBottomLeft = bottomLeft; } CalcDimension bottomRight; if (ParseJsDimensionVp(object->GetProperty("bottomRight"), bottomRight)) { radiusBottomRight = bottomRight; } if (!radiusTopLeft.has_value() && !radiusTopRight.has_value() && !radiusBottomLeft.has_value() && !radiusBottomRight.has_value()) { return; } ButtonModel::GetInstance()->SetBorderRadius(radiusTopLeft, radiusTopRight, radiusBottomLeft, radiusBottomRight); } } void JSButton::GetFontContent(JSRef& font, ButtonParameters& buttonParameters) { if (font->IsNull() || !font->IsObject()) { return; } JSRef obj = JSRef::Cast(font); JSRef size = obj->GetProperty("size"); CalcDimension fontSize; if (ParseJsDimensionFp(size, fontSize)) { buttonParameters.fontSize = fontSize; } JSRef weight = obj->GetProperty("weight"); if (weight->IsString() || weight->IsNumber()) { buttonParameters.fontWeight = ConvertStrToFontWeight(weight->ToString()); } JSRef family = obj->GetProperty("family"); std::vector fontFamilies; if (ParseJsFontFamilies(family, fontFamilies)) { buttonParameters.fontFamily = fontFamilies; } JSRef style = obj->GetProperty("style"); if (style->IsNumber()) { auto value = style->ToNumber(); if (value >= 0 && value < static_cast(FONT_STYLES.size())) { buttonParameters.fontStyle = FONT_STYLES[value]; } } } void JSButton::CompleteParameters(ButtonParameters& buttonParameters) { auto buttonTheme = GetTheme(); if (!buttonTheme) { return; } auto textStyle = buttonTheme->GetTextStyle(); if (!buttonParameters.maxLines.has_value()) { buttonParameters.maxLines = buttonTheme->GetTextMaxLines(); } if (!buttonParameters.fontSize.has_value()) { buttonParameters.fontSize = textStyle.GetFontSize(); } if (!buttonParameters.fontWeight.has_value()) { buttonParameters.fontWeight = textStyle.GetFontWeight(); } if (!buttonParameters.fontStyle.has_value()) { buttonParameters.fontStyle = textStyle.GetFontStyle(); } if (!buttonParameters.heightAdaptivePolicy.has_value()) { buttonParameters.heightAdaptivePolicy = TextHeightAdaptivePolicy::MAX_LINES_FIRST; } if (!buttonParameters.textOverflow.has_value()) { buttonParameters.textOverflow = TextOverflow::CLIP; } } void JSButton::SetLableStyle(const JSCallbackInfo& info) { if (!info[0]->IsObject()) { return; } ButtonParameters buttonParameters; JSRef obj = JSRef::Cast(info[0]); JSRef overflowValue = obj->GetProperty("overflow"); buttonParameters.textOverflow = TextOverflow::ELLIPSIS; if (!overflowValue->IsNull() && overflowValue->IsNumber()) { auto overflow = overflowValue->ToNumber(); if (overflow >= 0 && overflow < static_cast(TEXT_OVERFLOWS.size())) { buttonParameters.textOverflow = TEXT_OVERFLOWS[overflow]; } } JSRef maxLines = obj->GetProperty("maxLines"); if (!maxLines->IsNull() && maxLines->IsNumber()) { buttonParameters.maxLines = Positive(maxLines->ToNumber()) ? maxLines->ToNumber() : 1; } JSRef minFontSizeValue = obj->GetProperty("minFontSize"); CalcDimension minFontSize; if (ParseJsDimensionFp(minFontSizeValue, minFontSize)) { buttonParameters.minFontSize = minFontSize; } JSRef maxFontSizeValue = obj->GetProperty("maxFontSize"); CalcDimension maxFontSize; if (ParseJsDimensionFp(maxFontSizeValue, maxFontSize)) { buttonParameters.maxFontSize = maxFontSize; } JSRef adaptHeightValue = obj->GetProperty("heightAdaptivePolicy"); if (!adaptHeightValue->IsNull() && adaptHeightValue->IsNumber()) { auto adaptHeight = adaptHeightValue->ToNumber(); if (adaptHeight >= 0 && adaptHeight < static_cast(HEIGHT_ADAPTIVE_POLICY.size())) { buttonParameters.heightAdaptivePolicy = HEIGHT_ADAPTIVE_POLICY[adaptHeight]; } } JSRef font = obj->GetProperty("font"); GetFontContent(font, buttonParameters); CompleteParameters(buttonParameters); ButtonModel::GetInstance()->SetLabelStyle(buttonParameters); } void JSButton::JsRemoteMessage(const JSCallbackInfo& info) { RemoteCallback remoteCallback; JSInteractableView::JsRemoteMessage(info, remoteCallback); ButtonModel::GetInstance()->SetRemoteMessage(std::move(remoteCallback)); } void JSButton::JSBind(BindingTarget globalObj) { JSClass::Declare("Button"); JSClass::StaticMethod("fontColor", &JSButton::SetTextColor, MethodOptions::NONE); JSClass::StaticMethod("fontSize", &JSButton::SetFontSize, MethodOptions::NONE); JSClass::StaticMethod("fontWeight", &JSButton::SetFontWeight, MethodOptions::NONE); JSClass::StaticMethod("fontStyle", &JSButton::SetFontStyle, MethodOptions::NONE); JSClass::StaticMethod("fontFamily", &JSButton::SetFontFamily, MethodOptions::NONE); JSClass::StaticMethod("type", &JSButton::SetType, MethodOptions::NONE); JSClass::StaticMethod("stateEffect", &JSButton::SetStateEffect); JSClass::StaticMethod("labelStyle", &JSButton::SetLableStyle, MethodOptions::NONE); JSClass::StaticMethod("onClick", &JSButton::JsOnClick); JSClass::StaticMethod("remoteMessage", &JSButton::JsRemoteMessage); JSClass::StaticMethod("onTouch", &JSInteractableView::JsOnTouch); JSClass::StaticMethod("onHover", &JSInteractableView::JsOnHover); JSClass::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey); JSClass::StaticMethod("onDeleteEvent", &JSInteractableView::JsOnDelete); JSClass::StaticMethod("backgroundColor", &JSButton::JsBackgroundColor); JSClass::StaticMethod("width", &JSButton::JsWidth); JSClass::StaticMethod("height", &JSButton::JsHeight); JSClass::StaticMethod("aspectRatio", &JSButton::JsAspectRatio); JSClass::StaticMethod("borderRadius", &JSButton::JsRadius); JSClass::StaticMethod("border", &JSButton::JsBorder); JSClass::StaticMethod("onAttach", &JSInteractableView::JsOnAttach); JSClass::StaticMethod("onAppear", &JSInteractableView::JsOnAppear); JSClass::StaticMethod("onDetach", &JSInteractableView::JsOnDetach); JSClass::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear); JSClass::StaticMethod("size", &JSButton::JsSize); JSClass::StaticMethod("padding", &JSButton::JsPadding); JSClass::StaticMethod("buttonStyle", &JSButton::SetButtonStyle); JSClass::StaticMethod("controlSize", &JSButton::SetControlSize); JSClass::StaticMethod("role", &JSButton::SetRole); JSClass::StaticMethod("createWithLabel", &JSButton::CreateWithLabel, MethodOptions::NONE); JSClass::StaticMethod("createWithChild", &JSButton::CreateWithChild, MethodOptions::NONE); JSClass::InheritAndBind(globalObj); } void JSButton::CreateWithLabel(const JSCallbackInfo& info) { std::list> buttonChildren; CreateWithPara para = ParseCreatePara(info, true); ButtonModel::GetInstance()->CreateWithLabel(para, buttonChildren); ButtonModel::GetInstance()->Create(para, buttonChildren); isLabelButton_ = true; auto buttonRole = para.buttonRole.value_or(ButtonRole::NORMAL); auto buttonStyleMode = para.buttonStyleMode.value_or(ButtonStyleMode::EMPHASIZE); JSButtonTheme::ApplyTheme(buttonRole, buttonStyleMode, isLabelButton_); ButtonModel::GetInstance()->SetCreateWithLabel(true); } void JSButton::CreateWithChild(const JSCallbackInfo& info) { CreateWithPara para = ParseCreatePara(info, false); ButtonModel::GetInstance()->CreateWithChild(para); isLabelButton_ = false; auto buttonRole = para.buttonRole.value_or(ButtonRole::NORMAL); auto buttonStyleMode = para.buttonStyleMode.value_or(ButtonStyleMode::EMPHASIZE); JSButtonTheme::ApplyTheme(buttonRole, buttonStyleMode, isLabelButton_); ButtonModel::GetInstance()->SetCreateWithLabel(false); } void JSButton::JsPadding(const JSCallbackInfo& info) { NG::PaddingProperty paddingNew = GetNewPadding(info); Edge paddingOld = Edge(GetOldPadding(info)); ButtonModel::GetInstance()->Padding(paddingNew, paddingOld); } Edge JSButton::GetOldPadding(const JSCallbackInfo& info) { Edge padding; if (info[0]->IsNumber()) { CalcDimension edgeValue; if (ParseJsDimensionVp(info[0], edgeValue)) { padding = Edge(edgeValue); } } else if (info[0]->IsObject()) { JSRef jsObj = JSRef::Cast(info[0]); CalcDimension left = CalcDimension(0.0, DimensionUnit::VP); CalcDimension top = CalcDimension(0.0, DimensionUnit::VP); CalcDimension right = CalcDimension(0.0, DimensionUnit::VP); CalcDimension bottom = CalcDimension(0.0, DimensionUnit::VP); if (jsObj->HasProperty("top") || jsObj->HasProperty("bottom") || jsObj->HasProperty("left") || jsObj->HasProperty("right")) { ParseJsDimensionVp(jsObj->GetProperty("left"), left); ParseJsDimensionVp(jsObj->GetProperty("top"), top); ParseJsDimensionVp(jsObj->GetProperty("right"), right); ParseJsDimensionVp(jsObj->GetProperty("bottom"), bottom); } padding = Edge(left, top, right, bottom); } return padding; } NG::PaddingProperty JSButton::GetNewPadding(const JSCallbackInfo& info) { NG::PaddingProperty padding = { NG::CalcLength(0.0), NG::CalcLength(0.0), NG::CalcLength(0.0), NG::CalcLength(0.0) }; if (isLabelButton_) { auto buttonTheme = GetTheme(); CHECK_NULL_RETURN(buttonTheme, padding); auto defaultPadding = buttonTheme->GetPadding(); padding = { NG::CalcLength(defaultPadding.Left()), NG::CalcLength(defaultPadding.Right()), NG::CalcLength(defaultPadding.Top()), NG::CalcLength(defaultPadding.Bottom()) }; } if (info[0]->IsObject()) { CommonCalcDimension commonCalcDimension; JSRef paddingObj = JSRef::Cast(info[0]); JSViewAbstract::ParseCommonMarginOrPaddingCorner(paddingObj, commonCalcDimension); if (commonCalcDimension.left.has_value() || commonCalcDimension.right.has_value() || commonCalcDimension.top.has_value() || commonCalcDimension.bottom.has_value()) { return SetPaddings(commonCalcDimension.top, commonCalcDimension.bottom, commonCalcDimension.left, commonCalcDimension.right); } } CalcDimension length(-1); ParseJsDimensionVp(info[0], length); if (length.IsNonNegative()) { padding.SetEdges(NG::CalcLength(length)); } return padding; } NG::PaddingProperty JSButton::SetPaddings(const std::optional& top, const std::optional& bottom, const std::optional& left, const std::optional& right) { NG::PaddingProperty paddings; if (top.has_value()) { if (top.value().Unit() == DimensionUnit::CALC) { paddings.top = NG::CalcLength(top.value().IsNonNegative() ? top.value().CalcValue() : CalcDimension().CalcValue()); } else { paddings.top = NG::CalcLength(top.value().IsNonNegative() ? top.value() : CalcDimension()); } } if (bottom.has_value()) { if (bottom.value().Unit() == DimensionUnit::CALC) { paddings.bottom = NG::CalcLength( bottom.value().IsNonNegative() ? bottom.value().CalcValue() : CalcDimension().CalcValue()); } else { paddings.bottom = NG::CalcLength(bottom.value().IsNonNegative() ? bottom.value() : CalcDimension()); } } if (left.has_value()) { if (left.value().Unit() == DimensionUnit::CALC) { paddings.left = NG::CalcLength(left.value().IsNonNegative() ? left.value().CalcValue() : CalcDimension().CalcValue()); } else { paddings.left = NG::CalcLength(left.value().IsNonNegative() ? left.value() : CalcDimension()); } } if (right.has_value()) { if (right.value().Unit() == DimensionUnit::CALC) { paddings.right = NG::CalcLength(right.value().IsNonNegative() ? right.value().CalcValue() : CalcDimension().CalcValue()); } else { paddings.right = NG::CalcLength(right.value().IsNonNegative() ? right.value() : CalcDimension()); } } return paddings; } void JSButton::JsOnClick(const JSCallbackInfo& info) { if (info[0]->IsUndefined() && IsDisableEventVersion()) { ViewAbstractModel::GetInstance()->DisableOnClick(); return; } if (!info[0]->IsFunction()) { return; } auto jsOnClickFunc = AceType::MakeRefPtr(JSRef::Cast(info[0])); WeakPtr targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode()); auto onTap = [execCtx = info.GetExecutionContext(), func = jsOnClickFunc, node = targetNode](GestureEvent& info) { JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); ACE_SCORING_EVENT("onClick"); PipelineContext::SetCallBackNode(node); func->Execute(info); #if !defined(PREVIEW) && defined(OHOS_PLATFORM) JSInteractableView::ReportClickEvent(node); #endif }; auto onClick = [execCtx = info.GetExecutionContext(), func = jsOnClickFunc, node = targetNode]( const ClickInfo* info) { JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); ACE_SCORING_EVENT("onClick"); PipelineContext::SetCallBackNode(node); func->Execute(*info); #if !defined(PREVIEW) && defined(OHOS_PLATFORM) JSInteractableView::ReportClickEvent(node); #endif }; ButtonModel::GetInstance()->OnClick(std::move(onTap), std::move(onClick)); } void JSButton::JsBackgroundColor(const JSCallbackInfo& info) { Color backgroundColor; bool colorFlag = ParseJsColor(info[0], backgroundColor); if (!colorFlag) { auto buttonTheme = GetTheme(); if (buttonTheme) { backgroundColor = buttonTheme->GetBgColor(); } } ButtonModel::GetInstance()->BackgroundColor(backgroundColor, colorFlag); info.ReturnSelf(); } void JSButton::JsWidth(const JSCallbackInfo& info) { JSViewAbstract::JsWidth(info); CalcDimension value = GetSizeValue(info); if (LessNotEqual(value.Value(), 0.0)) { return; } ButtonModel::GetInstance()->SetWidth(value); } void JSButton::JsHeight(const JSCallbackInfo& info) { JSViewAbstract::JsHeight(info); CalcDimension value = GetSizeValue(info); if (LessNotEqual(value.Value(), 0.0)) { return; } ButtonModel::GetInstance()->SetHeight(value); } void JSButton::JsAspectRatio(const JSCallbackInfo& info) { JSViewAbstract::JsAspectRatio(info); double value = 0.0; if (!ParseJsDouble(info[0], value)) { return; } ButtonModel::GetInstance()->SetAspectRatio(value); } void JSButton::JsSize(const JSCallbackInfo& info) { if (!info[0]->IsObject()) { JSViewAbstract::JsWidth(JSVal::Undefined()); JSViewAbstract::JsHeight(JSVal::Undefined()); return; } JSRef sizeObj = JSRef::Cast(info[0]); JSViewAbstract::JsWidth(sizeObj->GetProperty("width")); JSViewAbstract::JsHeight(sizeObj->GetProperty("height")); } void JSButton::JsRadius(const JSCallbackInfo& info) { CalcDimension radius; if (ParseJsDimensionVpNG(info[0], radius)) { ButtonModel::GetInstance()->SetBorderRadius(radius); } else if (info[0]->IsObject()) { JSRef object = JSRef::Cast(info[0]); CalcDimension topLeft; CalcDimension topRight; CalcDimension bottomLeft; CalcDimension bottomRight; JSViewAbstract::ParseAllBorderRadiuses(object, topLeft, topRight, bottomLeft, bottomRight); ButtonModel::GetInstance()->SetBorderRadius(topLeft, topRight, bottomLeft, bottomRight); } else { ButtonModel::GetInstance()->ResetBorderRadius(); } } void JSButton::JsBorder(const JSCallbackInfo& info) { JSViewAbstract::JsBorder(info); if (!info[0]->IsObject()) { return; } JSRef object = JSRef::Cast(info[0]); CalcDimension borderRadius; auto valueRadius = object->GetProperty("radius"); ParseJsDimensionVp(valueRadius, borderRadius); ButtonModel::GetInstance()->SetBorderRadius(borderRadius); HandleDifferentRadius(valueRadius); } CalcDimension JSButton::GetSizeValue(const JSCallbackInfo& info) { CalcDimension value; if (!ParseJsDimensionVp(info[0], value)) { return { -1.0 }; } return value; } CreateWithPara JSButton::ParseCreatePara(const JSCallbackInfo& info, bool hasLabel) { std::string label; CreateWithPara para; para.parseSuccess = false; para.optionSetFirst = false; if (info.Length() < 1) { para.label = label; return para; } int32_t optionIndex = 0; if (hasLabel) { para.parseSuccess = ParseJsString(info[0], label); if (para.parseSuccess) { // resource string if (info[0]->IsObject() && JSRef::Cast(info[0])->HasProperty("id")) { optionIndex++; // string } else if (info[0]->IsString()) { optionIndex++; } } para.label = label; } if (optionIndex >= info.Length() || !info[optionIndex]->IsObject()) { return para; } if (optionIndex == 0) { para.optionSetFirst = true; } JSRef optionObj = JSRef::Cast(info[optionIndex]); if (optionObj->GetProperty(JSButton::TYPE)->IsNumber()) { para.type = static_cast(optionObj->GetProperty(JSButton::TYPE)->ToNumber()); } if (optionObj->GetProperty(JSButton::STATE_EFFECT)->IsBoolean()) { para.stateEffect = optionObj->GetProperty(JSButton::STATE_EFFECT)->ToBoolean(); } if (optionObj->HasProperty(JSButton::BUTTON_STYLE)) { para.buttonStyleMode = ButtonStyleMode::EMPHASIZE; } if (optionObj->GetProperty(JSButton::BUTTON_STYLE)->IsNumber()) { auto styleModeIntValue = optionObj->GetProperty(JSButton::BUTTON_STYLE)->ToNumber(); if (styleModeIntValue >= static_cast(ButtonStyleMode::NORMAL) && styleModeIntValue <= static_cast(ButtonStyleMode::TEXT)) { para.buttonStyleMode = static_cast(styleModeIntValue); } } if (optionObj->HasProperty(JSButton::CONTROL_SIZE)) { para.controlSize = ControlSize::NORMAL; } if (optionObj->GetProperty(JSButton::CONTROL_SIZE)->IsNumber()) { auto controlSizeIntValue = optionObj->GetProperty(JSButton::CONTROL_SIZE)->ToNumber(); if (controlSizeIntValue >= static_cast(ControlSize::SMALL) && controlSizeIntValue <= static_cast(ControlSize::NORMAL)) { para.controlSize = static_cast(controlSizeIntValue); } } ParseButtonRole(optionObj, para); return para; } void JSButton::ParseButtonRole(const JSRef& optionObj, CreateWithPara& param) { if (optionObj->HasProperty(JSButton::ROLE)) { param.buttonRole = ButtonRole::NORMAL; } if (optionObj->GetProperty(JSButton::ROLE)->IsNumber()) { auto buttonRoleIntValue = optionObj->GetProperty(JSButton::ROLE)->ToNumber(); if (buttonRoleIntValue >= static_cast(ButtonRole::NORMAL) && buttonRoleIntValue <= static_cast(ButtonRole::ERROR)) { param.buttonRole = static_cast(buttonRoleIntValue); } } } } // namespace OHOS::Ace::Framework