From 62b5de85e59a04d5abd7dd72a9b2cc381532589f Mon Sep 17 00:00:00 2001 From: Linkxu Date: Wed, 20 Aug 2025 10:11:58 +0800 Subject: [PATCH] Add contentModifier for checkboxgroup Signed-off-by: Linkxu --- .../ark_component/src/ArkCheckboxGroup.ts | 54 +++- .../engine/arkComponent.js | 47 +++ .../arkts_native_api_impl_bridge.cpp | 2 + .../arkts_native_checkboxgroup_bridge.cpp | 79 ++++- .../arkts_native_checkboxgroup_bridge.h | 3 +- .../checkboxgroup_layout_algorithm.cpp | 15 +- .../checkboxgroup/checkboxgroup_model_ng.cpp | 18 +- .../checkboxgroup/checkboxgroup_model_ng.h | 18 +- .../checkboxgroup/checkboxgroup_modifier.cpp | 3 +- .../checkboxgroup/checkboxgroup_modifier.h | 13 +- .../checkboxgroup_paint_property.h | 5 +- .../checkboxgroup/checkboxgroup_pattern.cpp | 76 ++++- .../checkboxgroup/checkboxgroup_pattern.h | 27 +- ...checkboxgroup_layout_algorithm_test_ng.cpp | 67 +++- .../checkboxgroup_paint_property_test_ng.cpp | 4 +- .../checkboxgroup_pattern_test_ng.cpp | 291 +++++++++++++++++- .../checkboxgroup/checkboxgroup_test_ng.cpp | 52 ++-- 17 files changed, 734 insertions(+), 40 deletions(-) diff --git a/frameworks/bridge/declarative_frontend/ark_component/src/ArkCheckboxGroup.ts b/frameworks/bridge/declarative_frontend/ark_component/src/ArkCheckboxGroup.ts index d7e30a15b9f..00c90a6bd7c 100644 --- a/frameworks/bridge/declarative_frontend/ark_component/src/ArkCheckboxGroup.ts +++ b/frameworks/bridge/declarative_frontend/ark_component/src/ArkCheckboxGroup.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Huawei Device Co., Ltd. + * Copyright (c) 2023-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 @@ -191,6 +191,10 @@ class CheckboxGroupOnChangeModifier extends ModifierWithKey | null = null; + checkboxgroupNode: BuilderNode<[CheckBoxGroupConfiguration]> | null = null; + modifier: ContentModifier; + needRebuild: boolean = false; constructor(nativePtr: KNode, classType?: ModifierType) { super(nativePtr, classType); } @@ -249,6 +253,45 @@ class ArkCheckboxGroupComponent extends ArkComponent implements CheckboxGroupAtt modifierWithKey(this._modifiersWithKeys, CheckboxGroupStyleModifier.identity, CheckboxGroupStyleModifier, value); return this; } + contentModifier(value: ContentModifier): this { + modifierWithKey(this._modifiersWithKeys, CheckBoxGroupContentModifier.identity, CheckBoxGroupContentModifier, value); + return this; + } + setContentModifier(modifier: ContentModifier): this { + if (modifier === undefined || modifier === null) { + getUINativeModule().checkboxgroup.setContentModifierBuilder(this.nativePtr, false); + return; + } + this.needRebuild = false; + if (this.builder !== modifier.applyContent()) { + this.needRebuild = true; + } + this.builder = modifier.applyContent(); + this.modifier = modifier; + getUINativeModule().checkboxgroup.setContentModifierBuilder(this.nativePtr, this); + } + makeContentModifierNode(context: UIContext, CheckBoxGroupConfiguration: CheckBoxGroupConfiguration): FrameNode | null { + CheckBoxGroupConfiguration.contentModifier = this.modifier; + if (isUndefined(this.checkboxgroupNode) || this.needRebuild) { + const xNode = globalThis.requireNapi('arkui.node'); + this.checkboxgroupNode = new xNode.BuilderNode(context); + this.checkboxgroupNode.build(this.builder, CheckBoxGroupConfiguration); + this.needRebuild = false; + } else { + this.checkboxgroupNode.update(CheckBoxGroupConfiguration); + } + return this.checkboxgroupNode.getFrameNode(); + } +} +class CheckBoxGroupContentModifier extends ModifierWithKey> { + constructor(value: ContentModifier) { + super(value); + } + static identity: Symbol = Symbol('checkBoxGroupContentModifier'); + applyPeer(node: KNode, reset: boolean, component: ArkComponent): void { + let checkboxGroupComponent = component as ArkCheckboxGroupComponent; + checkboxGroupComponent.setContentModifier(this.value); + } } // @ts-ignore globalThis.CheckboxGroup.attributeModifier = function (modifier: ArkComponent): void { @@ -258,3 +301,12 @@ globalThis.CheckboxGroup.attributeModifier = function (modifier: ArkComponent): return new modifierJS.CheckboxGroupModifier(nativePtr, classType); }); }; +// @ts-ignore +globalThis.CheckboxGroup.contentModifier = function (modifier: ContentModifier): void { + const elmtId = ViewStackProcessor.GetElmtIdToAccountFor(); + let nativeNode = getUINativeModule().getFrameNodeById(elmtId); + let component = this.createOrGetNode(elmtId, () => { + return new ArkCheckboxGroupComponent(nativeNode); + }); + component.setContentModifier(modifier); +}; \ No newline at end of file diff --git a/frameworks/bridge/declarative_frontend/engine/arkComponent.js b/frameworks/bridge/declarative_frontend/engine/arkComponent.js index 2e3acd31b6c..d85d756f15c 100755 --- a/frameworks/bridge/declarative_frontend/engine/arkComponent.js +++ b/frameworks/bridge/declarative_frontend/engine/arkComponent.js @@ -25968,6 +25968,33 @@ class ArkCheckboxGroupComponent extends ArkComponent { modifierWithKey(this._modifiersWithKeys, CheckboxGroupStyleModifier.identity, CheckboxGroupStyleModifier, value); return this; } + setContentModifier(modifier) { + if (modifier === undefined || modifier === null) { + getUINativeModule().checkboxgroup.setContentModifierBuilder(this.nativePtr, false); + this.builder = undefined; + this.modifier = undefined; + return; + } + this.needRebuild = false; + if (this.builder !== modifier.applyContent()) { + this.needRebuild = true; + } + this.builder = modifier.applyContent(); + this.modifier = modifier; + getUINativeModule().checkboxgroup.setContentModifierBuilder(this.nativePtr, this); + } + makeContentModifierNode(context, checkBoxGroupConfiguration) { + checkBoxGroupConfiguration.contentModifier = this.modifier; + if (this.checkboxgroupNode === undefined || this.needRebuild) { + const xNode = globalThis.requireNapi('arkui.node'); + this.checkboxgroupNode = new xNode.BuilderNode(context); + this.checkboxgroupNode.build(this.builder, checkBoxGroupConfiguration); + this.needRebuild = false; + } else { + this.checkboxgroupNode.update(checkBoxGroupConfiguration); + } + return this.checkboxgroupNode.getFrameNode(); + } } class CheckBoxGroupOptionsModifier extends ModifierWithKey { @@ -25988,6 +26015,17 @@ class CheckBoxGroupOptionsModifier extends ModifierWithKey { } CheckBoxGroupOptionsModifier.identity = Symbol('checkBoxGroupOptions'); +class CheckBoxGroupContentModifier extends ModifierWithKey { + constructor(value) { + super(value); + } + applyPeer(node, reset, component) { + let checkboxgroupComponent = component; + checkboxgroupComponent.setContentModifier(this.value); + } +} +CheckBoxGroupContentModifier.identity = Symbol('checkBoxGroupContentModifier'); + // @ts-ignore if (globalThis.CheckboxGroup !== undefined) { globalThis.CheckboxGroup.attributeModifier = function (modifier) { @@ -25999,6 +26037,15 @@ if (globalThis.CheckboxGroup !== undefined) { }; } + globalThis.CheckboxGroup.contentModifier = function (modifier) { + const elmtId = ViewStackProcessor.GetElmtIdToAccountFor(); + let nativeNode = getUINativeModule().getFrameNodeById(elmtId); + let component = this.createOrGetNode(elmtId, () => { + return new ArkCheckboxGroupComponent(nativeNode); + }); + component.setContentModifier(modifier); + }; + /// class ArkPanelComponent extends ArkComponent { constructor(nativePtr, classType) { diff --git a/frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_api_impl_bridge.cpp b/frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_api_impl_bridge.cpp index 512ea402251..0e4a17cbf76 100644 --- a/frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_api_impl_bridge.cpp +++ b/frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_api_impl_bridge.cpp @@ -1399,6 +1399,8 @@ ArkUINativeModuleValue ArkUINativeModule::GetArkUINativeModule(ArkUIRuntimeCallI panda::FunctionRef::New(const_cast(vm), CheckboxGroupBridge::SetCheckboxGroupOnChange)); checkboxgroup->Set(vm, panda::StringRef::NewFromUtf8(vm, "resetCheckboxGroupOnChange"), panda::FunctionRef::New(const_cast(vm), CheckboxGroupBridge::ResetCheckboxGroupOnChange)); + checkboxgroup->Set(vm, panda::StringRef::NewFromUtf8(vm, "setContentModifierBuilder"), + panda::FunctionRef::New(const_cast(vm), CheckboxGroupBridge::SetContentModifierBuilder)); object->Set(vm, panda::StringRef::NewFromUtf8(vm, "checkboxgroup"), checkboxgroup); auto panel = panda::ObjectRef::New(vm); diff --git a/frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_checkboxgroup_bridge.cpp b/frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_checkboxgroup_bridge.cpp index b52e83afe31..edc5b1da07a 100644 --- a/frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_checkboxgroup_bridge.cpp +++ b/frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_checkboxgroup_bridge.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Huawei Device Co., Ltd. + * Copyright (c) 2023-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 @@ -15,6 +15,8 @@ #include "bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_checkboxgroup_bridge.h" #include "frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_utils.h" +#include "core/components_ng/base/frame_node.h" +#include "core/components_ng/pattern/checkboxgroup/checkboxgroup_model_ng.h" namespace OHOS::Ace::NG { namespace { @@ -23,8 +25,33 @@ constexpr int NUM_1 = 1; constexpr int NUM_2 = 2; constexpr int NUM_3 = 3; constexpr int PARAM_ARR_LENGTH_1 = 1; +constexpr int PARAM_ARR_LENGTH_2 = 2; constexpr float DEFAULT_SIZE_VALUE = -1.0f; +const char* CHECKBOXGROUP_NODEPTR_OF_UINODE = "nodePtr_"; } // namespace +panda::Local JsCheckboxgroupChangeCallback(panda::JsiRuntimeCallInfo* runtimeCallInfo) +{ + auto vm = runtimeCallInfo->GetVM(); + int32_t argc = static_cast(runtimeCallInfo->GetArgsNumber()); + if (argc != 1) { + return panda::JSValueRef::Undefined(vm); + } + auto firstArg = runtimeCallInfo->GetCallArgRef(0); + if (!firstArg->IsBoolean()) { + return panda::JSValueRef::Undefined(vm); + } + bool value = firstArg->ToBoolean(vm)->Value(); + auto ref = runtimeCallInfo->GetThisRef(); + auto obj = ref->ToObject(vm); + if (obj->GetNativePointerFieldCount(vm) < 1) { + return panda::JSValueRef::Undefined(vm); + } + auto frameNode = static_cast(obj->GetNativePointerField(vm, 0)); + CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm)); + CheckBoxGroupModelNG::SetChangeValue(frameNode, value); + return panda::JSValueRef::Undefined(vm); +} + ArkUINativeModuleValue CheckboxGroupBridge::SetCheckboxGroupSelectedColor(ArkUIRuntimeCallInfo* runtimeCallInfo) { EcmaVM* vm = runtimeCallInfo->GetVM(); @@ -373,4 +400,54 @@ ArkUINativeModuleValue CheckboxGroupBridge::ResetCheckboxGroupOnChange(ArkUIRunt GetArkUINodeModifiers()->getCheckboxGroupModifier()->resetCheckboxGroupOnChange(nativeNode); return panda::JSValueRef::Undefined(vm); } + +ArkUINativeModuleValue CheckboxGroupBridge::SetContentModifierBuilder(ArkUIRuntimeCallInfo* runtimeCallInfo) +{ + EcmaVM* vm = runtimeCallInfo->GetVM(); + CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr)); + Local firstArg = runtimeCallInfo->GetCallArgRef(0); + Local secondArg = runtimeCallInfo->GetCallArgRef(1); + if (firstArg->IsNull() || firstArg->IsUndefined()) { + return panda::JSValueRef::Undefined(vm); + } + auto* frameNode = reinterpret_cast(firstArg->ToNativePointer(vm)->Value()); + if (secondArg->IsNull() || secondArg->IsUndefined() || !secondArg->IsObject(vm)) { + CheckBoxGroupModelNG::SetBuilderFunc(frameNode, nullptr); + return panda::JSValueRef::Undefined(vm); + } + panda::CopyableGlobal obj(vm, secondArg); + CheckBoxGroupModelNG::SetBuilderFunc(frameNode, + [vm, frameNode, obj = std::move(obj), containerId = Container::CurrentId()]( + CheckBoxGroupConfiguration config) -> RefPtr { + ContainerScope scope(containerId); + auto context = ArkTSUtils::GetContext(vm); + CHECK_EQUAL_RETURN(context->IsUndefined(), true, nullptr); + const char* keysOfCheckboxgroup[] = { "name", "status", "enabled", "triggerChange"}; + Local valuesOfCheckboxgroup[] = { panda::StringRef::NewFromUtf8(vm, config.name_.c_str()), + panda::NumberRef::New(vm, int32_t(config.status_)), panda::BooleanRef::New(vm, config.enabled_), + panda::FunctionRef::New(vm, JsCheckboxgroupChangeCallback)}; + auto checkboxgroup = panda::ObjectRef::NewWithNamedProperties(vm, + ArraySize(keysOfCheckboxgroup), keysOfCheckboxgroup, valuesOfCheckboxgroup); + checkboxgroup->SetNativePointerFieldCount(vm, 1); + checkboxgroup->SetNativePointerField(vm, 0, static_cast(frameNode)); + panda::Local params[PARAM_ARR_LENGTH_2] = { context, checkboxgroup }; + LocalScope pandaScope(vm); + panda::TryCatch trycatch(vm); + auto jsObject = obj.ToLocal(); + auto makeFunc = jsObject->Get(vm, panda::StringRef::NewFromUtf8(vm, "makeContentModifierNode")); + CHECK_EQUAL_RETURN(makeFunc->IsFunction(vm), false, nullptr); + panda::Local func = makeFunc; + auto result = func->Call(vm, jsObject, params, PARAM_ARR_LENGTH_2); + JSNApi::ExecutePendingJob(vm); + CHECK_EQUAL_RETURN(result.IsEmpty() || trycatch.HasCaught() || !result->IsObject(vm), true, nullptr); + auto resultObj = result->ToObject(vm); + panda::Local nodeptr = + resultObj->Get(vm, panda::StringRef::NewFromUtf8(vm, CHECKBOXGROUP_NODEPTR_OF_UINODE)); + CHECK_EQUAL_RETURN(nodeptr.IsEmpty() || nodeptr->IsUndefined() || nodeptr->IsNull(), true, nullptr); + auto* newFrameNode = reinterpret_cast(nodeptr->ToNativePointer(vm)->Value()); + CHECK_NULL_RETURN(newFrameNode, nullptr); + return AceType::Claim(newFrameNode); + }); + return panda::JSValueRef::Undefined(vm); +} } // namespace OHOS::Ace::NG diff --git a/frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_checkboxgroup_bridge.h b/frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_checkboxgroup_bridge.h index cc8cda7700b..ce611a2d8e3 100644 --- a/frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_checkboxgroup_bridge.h +++ b/frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_checkboxgroup_bridge.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Huawei Device Co., Ltd. + * Copyright (c) 2023-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 @@ -39,6 +39,7 @@ public: static ArkUINativeModuleValue SetCheckboxGroupOptions(ArkUIRuntimeCallInfo* runtimeCallInfo); static ArkUINativeModuleValue SetCheckboxGroupOnChange(ArkUIRuntimeCallInfo* runtimeCallInfo); static ArkUINativeModuleValue ResetCheckboxGroupOnChange(ArkUIRuntimeCallInfo* runtimeCallInfo); + static ArkUINativeModuleValue SetContentModifierBuilder(ArkUIRuntimeCallInfo* runtimeCallInfo); }; } // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/pattern/checkboxgroup/checkboxgroup_layout_algorithm.cpp b/frameworks/core/components_ng/pattern/checkboxgroup/checkboxgroup_layout_algorithm.cpp index b1a08f5ddb8..d0f811bafcc 100644 --- a/frameworks/core/components_ng/pattern/checkboxgroup/checkboxgroup_layout_algorithm.cpp +++ b/frameworks/core/components_ng/pattern/checkboxgroup/checkboxgroup_layout_algorithm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022-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 @@ -17,6 +17,7 @@ #include "core/components/checkable/checkable_theme.h" #include "core/pipeline/pipeline_base.h" +#include "core/components_ng/pattern/checkboxgroup/checkboxgroup_pattern.h" #include "core/components_ng/property/measure_utils.h" namespace OHOS::Ace::NG { @@ -24,6 +25,18 @@ namespace OHOS::Ace::NG { std::optional CheckBoxGroupLayoutAlgorithm::MeasureContent( const LayoutConstraintF& contentConstraint, LayoutWrapper* layoutWrapper) { + auto host = layoutWrapper->GetHostNode(); + CHECK_NULL_RETURN(host, std::nullopt); + auto pattern = host->GetPattern(); + CHECK_NULL_RETURN(pattern, std::nullopt); + if (pattern->UseContentModifier()) { + if (host->GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_EIGHTEEN)) { + host->GetGeometryNode()->ResetContent(); + } else { + host->GetGeometryNode()->Reset(); + } + return std::nullopt; + } auto themeScopeId = layoutWrapper->GetHostNode() ? layoutWrapper->GetHostNode()->GetThemeScopeId() : 0; InitializeParam(themeScopeId); auto layoutPolicy = GetLayoutPolicy(layoutWrapper); diff --git a/frameworks/core/components_ng/pattern/checkboxgroup/checkboxgroup_model_ng.cpp b/frameworks/core/components_ng/pattern/checkboxgroup/checkboxgroup_model_ng.cpp index 821180d040c..afe68a6f841 100644 --- a/frameworks/core/components_ng/pattern/checkboxgroup/checkboxgroup_model_ng.cpp +++ b/frameworks/core/components_ng/pattern/checkboxgroup/checkboxgroup_model_ng.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Copyright (c) 2022-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 @@ -432,4 +432,20 @@ void CheckBoxGroupModelNG::ResetUnSelectedColor(FrameNode* frameNode) ACE_RESET_NODE_PAINT_PROPERTY_WITH_FLAG( CheckBoxGroupPaintProperty, CheckBoxGroupUnSelectedColorFlagByUser, PROPERTY_UPDATE_RENDER, frameNode); } + +void CheckBoxGroupModelNG::SetBuilderFunc(FrameNode* frameNode, NG::CheckBoxGroupMakeCallback&& makeFunc) +{ + CHECK_NULL_VOID(frameNode); + auto pattern = frameNode->GetPattern(); + CHECK_NULL_VOID(pattern); + pattern->SetBuilderFunc(std::move(makeFunc)); +} + +void CheckBoxGroupModelNG::SetChangeValue(FrameNode* frameNode, bool value) +{ + CHECK_NULL_VOID(frameNode); + auto pattern = frameNode->GetPattern(); + CHECK_NULL_VOID(pattern); + pattern->SetCheckBoxGroupSelect(value); +} } // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/pattern/checkboxgroup/checkboxgroup_model_ng.h b/frameworks/core/components_ng/pattern/checkboxgroup/checkboxgroup_model_ng.h index 43ebddcc2fa..aecdc704401 100644 --- a/frameworks/core/components_ng/pattern/checkboxgroup/checkboxgroup_model_ng.h +++ b/frameworks/core/components_ng/pattern/checkboxgroup/checkboxgroup_model_ng.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Copyright (c) 2022-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 @@ -16,9 +16,23 @@ #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_CHECKBOXGROUP_CHECKBOXGROUP_MODEL_NG_H #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_CHECKBOXGROUP_CHECKBOXGROUP_MODEL_NG_H +#include "core/components_ng/base/common_configuration.h" +#include "core/components_ng/base/frame_node.h" #include "core/components_ng/pattern/checkboxgroup/checkboxgroup_model.h" +#include "core/components_ng/pattern/checkboxgroup/checkboxgroup_paint_property.h" namespace OHOS::Ace::NG { +class CheckBoxGroupConfiguration : public CommonConfiguration { + public: + CheckBoxGroupConfiguration(const std::string& name, + CheckBoxGroupPaintProperty::SelectStatus status, bool enabled) + : CommonConfiguration(enabled), name_(name), status_(status) + {} + std::string name_; + CheckBoxGroupPaintProperty::SelectStatus status_; +}; +using CheckBoxGroupMakeCallback = + std::function(const CheckBoxGroupConfiguration& checkBoxGroupConfiguration)>; class ACE_EXPORT CheckBoxGroupModelNG : public OHOS::Ace::CheckBoxGroupModel { public: void Create(const std::optional& groupName) override; @@ -69,6 +83,8 @@ public: static void SetSelectedColorByUser(FrameNode* frameNode, bool flag); static void ResetSelectedColor(FrameNode* frameNode); static void ResetUnSelectedColor(FrameNode* frameNode); + static void SetBuilderFunc(FrameNode* frameNode, NG::CheckBoxGroupMakeCallback&& jsMake); + static void SetChangeValue(FrameNode* frameNode, bool value); private: static std::string ColorTypeToString(const CheckBoxGroupColorType& checkBoxGroupColorType); diff --git a/frameworks/core/components_ng/pattern/checkboxgroup/checkboxgroup_modifier.cpp b/frameworks/core/components_ng/pattern/checkboxgroup/checkboxgroup_modifier.cpp index 4733469c734..077361e0c3a 100644 --- a/frameworks/core/components_ng/pattern/checkboxgroup/checkboxgroup_modifier.cpp +++ b/frameworks/core/components_ng/pattern/checkboxgroup/checkboxgroup_modifier.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Huawei Device Co., Ltd. + * Copyright (c) 2023-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 @@ -42,6 +42,7 @@ CheckBoxGroupModifier::CheckBoxGroupModifier(const Parameters& parameters) checkMarkPaintSize_ = AceType::MakeRefPtr(parameters.checkMarkPaintSize); checkStroke_ = AceType::MakeRefPtr(parameters.checkStroke); enabled_ = AceType::MakeRefPtr(true); + useContentModifier_ = AceType::MakeRefPtr(false); uiStatus_ = AceType::MakeRefPtr(static_cast(parameters.uiStatus)); status_ = AceType::MakeRefPtr(static_cast(UIStatus::UNSELECTED)); offset_ = AceType::MakeRefPtr(OffsetF()); diff --git a/frameworks/core/components_ng/pattern/checkboxgroup/checkboxgroup_modifier.h b/frameworks/core/components_ng/pattern/checkboxgroup/checkboxgroup_modifier.h index d213ec99949..c170cbc9d2f 100644 --- a/frameworks/core/components_ng/pattern/checkboxgroup/checkboxgroup_modifier.h +++ b/frameworks/core/components_ng/pattern/checkboxgroup/checkboxgroup_modifier.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Huawei Device Co., Ltd. + * Copyright (c) 2023-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 @@ -60,6 +60,9 @@ public: ~CheckBoxGroupModifier() override = default; void onDraw(DrawingContext& context) override { + if (useContentModifier_->Get()) { + return; + } PaintCheckBox(context, offset_->Get(), size_->Get()); } @@ -224,6 +227,13 @@ public: } } + void SetUseContentModifier(bool useContentModifier) + { + if (useContentModifier_) { + useContentModifier_->Set(useContentModifier); + } + } + void SetSize(SizeF& size) { if (size_) { @@ -253,6 +263,7 @@ private: TouchHoverAnimationType touchHoverType_ = TouchHoverAnimationType::NONE; HoverEffectType hoverEffectType_ = HoverEffectType::AUTO; RefPtr enabled_; + RefPtr useContentModifier_; RefPtr uiStatus_; RefPtr status_; RefPtr offset_; diff --git a/frameworks/core/components_ng/pattern/checkboxgroup/checkboxgroup_paint_property.h b/frameworks/core/components_ng/pattern/checkboxgroup/checkboxgroup_paint_property.h index c9647771178..e0d39ec3c52 100644 --- a/frameworks/core/components_ng/pattern/checkboxgroup/checkboxgroup_paint_property.h +++ b/frameworks/core/components_ng/pattern/checkboxgroup/checkboxgroup_paint_property.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Copyright (c) 2022-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 @@ -20,8 +20,7 @@ #include "core/components/common/layout/constants.h" #include "core/components/common/properties/color.h" #include "core/components_ng/render/paint_property.h" -#include "core/components_ng/pattern/checkboxgroup/checkboxgroup_model_ng.h" - +#include "core/components_ng/pattern/checkbox/checkbox_model.h" namespace OHOS::Ace::NG { class InspectorFilter; diff --git a/frameworks/core/components_ng/pattern/checkboxgroup/checkboxgroup_pattern.cpp b/frameworks/core/components_ng/pattern/checkboxgroup/checkboxgroup_pattern.cpp index 4fe1ef2ef82..5b6f76e19cf 100644 --- a/frameworks/core/components_ng/pattern/checkboxgroup/checkboxgroup_pattern.cpp +++ b/frameworks/core/components_ng/pattern/checkboxgroup/checkboxgroup_pattern.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Copyright (c) 2022-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 @@ -58,6 +58,7 @@ void CheckBoxGroupPattern::OnDetachFromFrameNode(FrameNode* frameNode) void CheckBoxGroupPattern::OnModifyDone() { Pattern::OnModifyDone(); + FireBuilder(); UpdateState(); auto host = GetHost(); CHECK_NULL_VOID(host); @@ -230,6 +231,9 @@ void CheckBoxGroupPattern::HandleMouseEvent(bool isHover) void CheckBoxGroupPattern::OnClick() { + if (UseContentModifier()) { + return; + } auto host = GetHost(); CHECK_NULL_VOID(host); auto paintProperty = host->GetPaintProperty(); @@ -246,6 +250,9 @@ void CheckBoxGroupPattern::OnClick() void CheckBoxGroupPattern::OnTouchDown() { TAG_LOGD(AceLogTag::ACE_SELECT_COMPONENT, "checkboxgroup touch down %{public}d", isHover_); + if (UseContentModifier()) { + return; + } if (isHover_) { touchHoverType_ = TouchHoverAnimationType::HOVER_TO_PRESS; } else { @@ -259,6 +266,9 @@ void CheckBoxGroupPattern::OnTouchDown() void CheckBoxGroupPattern::OnTouchUp() { TAG_LOGD(AceLogTag::ACE_SELECT_COMPONENT, "checkboxgroup touch up %{public}d", isHover_); + if (UseContentModifier()) { + return; + } if (isHover_) { touchHoverType_ = TouchHoverAnimationType::PRESS_TO_HOVER; } else { @@ -294,6 +304,10 @@ void CheckBoxGroupPattern::UpdateUIStatus(bool check) } else { uiStatus_ = check ? UIStatus::OFF_TO_ON : UIStatus::ON_TO_OFF; } + if (UseContentModifier()) { + paintProperty->UpdateCheckBoxGroupSelect(check); + FireBuilder(); + } host->MarkDirtyNode(PROPERTY_UPDATE_RENDER); } @@ -642,6 +656,66 @@ void CheckBoxGroupPattern::UpdateModifierParam(CheckBoxGroupModifier::Parameters } } +void CheckBoxGroupPattern::SetCheckBoxGroupSelect(bool select) +{ + auto host = GetHost(); + CHECK_NULL_VOID(host); + auto eventHub = host->GetEventHub(); + CHECK_NULL_VOID(eventHub); + auto enabled = eventHub->IsEnabled(); + if (!enabled) { + return; + } + auto paintProperty = host->GetPaintProperty(); + CHECK_NULL_VOID(paintProperty); + paintProperty->UpdateCheckBoxGroupSelect(select); + updateFlag_ = true; + UpdateState(); + OnModifyDone(); +} + +void CheckBoxGroupPattern::FireBuilder() +{ + auto host = GetHost(); + CHECK_NULL_VOID(host); + if (!makeFunc_.has_value()) { + host->RemoveChildAndReturnIndex(contentModifierNode_); + contentModifierNode_ = nullptr; + host->MarkNeedFrameFlushDirty(PROPERTY_UPDATE_MEASURE); + return; + } + auto node = BuildContentModifierNode(); + if (contentModifierNode_ == node) { + return; + } + auto renderContext = host->GetRenderContext(); + CHECK_NULL_VOID(renderContext); + renderContext->UpdateBackgroundColor(Color::TRANSPARENT); + host->RemoveChildAndReturnIndex(contentModifierNode_); + contentModifierNode_ = node; + CHECK_NULL_VOID(contentModifierNode_); + host->AddChild(contentModifierNode_, 0); + host->MarkNeedFrameFlushDirty(PROPERTY_UPDATE_MEASURE); +} + +RefPtr CheckBoxGroupPattern::BuildContentModifierNode() +{ + if (!makeFunc_.has_value()) { + return nullptr; + } + auto host = GetHost(); + CHECK_NULL_RETURN(host, nullptr); + auto eventHub = host->GetEventHub(); + CHECK_NULL_RETURN(eventHub, nullptr); + auto name = eventHub->GetGroupName(); + auto enabled = eventHub->IsEnabled(); + auto paintProperty = host->GetPaintProperty(); + CHECK_NULL_RETURN(paintProperty, nullptr); + auto selectStatus = paintProperty->GetSelectStatus(); + CheckBoxGroupConfiguration checkBoxGroupConfiguration(name, selectStatus, enabled); + return (makeFunc_.value())(checkBoxGroupConfiguration); +} + void CheckBoxGroupPattern::OnColorConfigurationUpdate() { auto host = GetHost(); diff --git a/frameworks/core/components_ng/pattern/checkboxgroup/checkboxgroup_pattern.h b/frameworks/core/components_ng/pattern/checkboxgroup/checkboxgroup_pattern.h index ed1951ce6f4..679a3d8060f 100644 --- a/frameworks/core/components_ng/pattern/checkboxgroup/checkboxgroup_pattern.h +++ b/frameworks/core/components_ng/pattern/checkboxgroup/checkboxgroup_pattern.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Copyright (c) 2022-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 @@ -25,6 +25,7 @@ #include "core/components_ng/pattern/checkboxgroup/checkboxgroup_accessibility_property.h" #include "core/components_ng/pattern/checkboxgroup/checkboxgroup_event_hub.h" #include "core/components_ng/pattern/checkboxgroup/checkboxgroup_layout_algorithm.h" +#include "core/components_ng/pattern/checkboxgroup/checkboxgroup_model_ng.h" #include "core/components_ng/pattern/checkboxgroup/checkboxgroup_modifier.h" #include "core/components_ng/pattern/checkboxgroup/checkboxgroup_paint_method.h" #include "core/components_ng/pattern/checkboxgroup/checkboxgroup_paint_property.h" @@ -76,6 +77,7 @@ public: checkboxStyle = paintProperty->GetCheckBoxGroupSelectedStyleValue(CheckBoxStyle::CIRCULAR_STYLE); } checkBoxGroupModifier_->SetCheckboxGroupStyle(checkboxStyle); + checkBoxGroupModifier_->SetUseContentModifier(UseContentModifier()); } auto paintMethod = MakeRefPtr(checkBoxGroupModifier_); paintMethod->SetEnabled(enabled); @@ -163,6 +165,9 @@ public: void ResetUIStatus() { uiStatus_ = UIStatus::UNSELECTED; + if (UseContentModifier()) { + FireBuilder(); + } } RefPtr GetGroupManager(); @@ -185,6 +190,22 @@ public: { return true; } + void SetBuilderFunc(CheckBoxGroupMakeCallback&& makeFunc) + { + if (makeFunc == nullptr) { + makeFunc_ = std::nullopt; + OnModifyDone(); + return; + } + makeFunc_ = std::move(makeFunc); + } + + bool UseContentModifier() + { + return contentModifierNode_ != nullptr; + } + + void SetCheckBoxGroupSelect(bool value); private: void OnAttachToFrameNode() override; @@ -219,6 +240,10 @@ private: CheckBoxStyle checkBoxGroupStyle); void GetCheckBoxGroupStyle(const RefPtr& frameNode, CheckBoxStyle& checkboxGroupStyle); void InnerFocusPaintCircle(RoundRect& paintRect); + void FireBuilder(); + RefPtr BuildContentModifierNode(); + std::optional makeFunc_; + RefPtr contentModifierNode_; std::optional preGroup_; bool isAddToMap_ = true; RefPtr clickListener_; diff --git a/test/unittest/core/pattern/checkboxgroup/checkboxgroup_layout_algorithm_test_ng.cpp b/test/unittest/core/pattern/checkboxgroup/checkboxgroup_layout_algorithm_test_ng.cpp index c20a530d59b..1c884ff3f25 100644 --- a/test/unittest/core/pattern/checkboxgroup/checkboxgroup_layout_algorithm_test_ng.cpp +++ b/test/unittest/core/pattern/checkboxgroup/checkboxgroup_layout_algorithm_test_ng.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -48,6 +48,8 @@ constexpr Dimension DEFAULT_HEIGHT = Dimension(300.0); constexpr Dimension HORIZONTAL_PADDING = Dimension(48.0); constexpr Dimension VERTICAL_PADDING = Dimension(24.0); constexpr Dimension DEFAULT_PADDING_SIZE = Dimension(96.0); +const std::string CHECKBOXGROUP_NAME = "checkboxGroup"; +constexpr int CHILD_NODE_ID = 100; } // namespace @@ -340,11 +342,17 @@ HWTEST_F(CheckBoxGroupLayoutAlgorithmTestNG, CheckBoxGroupLayoutAlgorithmTest009 /** * @tc.steps: step1. Create contentConstraint and layoutWrapper */ + CheckBoxGroupModelNG checkBoxGroupModelNG; + checkBoxGroupModelNG.Create(CHECKBOXGROUP_NAME); + auto frameNode = AceType::DynamicCast(ViewStackProcessor::GetInstance()->Finish()); + ASSERT_NE(frameNode, nullptr); + RefPtr geometryNode = AceType::MakeRefPtr(); + ASSERT_NE(geometryNode, nullptr); std::optional nullLength; LayoutConstraintF contentConstraint; contentConstraint.selfIdealSize = OptionalSizeF(nullLength, nullLength); LayoutWrapperNode layoutWrapper = - LayoutWrapperNode(nullptr, nullptr, AccessibilityManager::MakeRefPtr()); + LayoutWrapperNode(frameNode, geometryNode, AccessibilityManager::MakeRefPtr()); /** * @tc.steps: step2. Create mock theme manager @@ -381,7 +389,12 @@ HWTEST_F(CheckBoxGroupLayoutAlgorithmTestNG, CheckBoxGroupLayoutAlgorithmTest001 { int32_t backupApiVersion = AceApplicationInfo::GetInstance().GetApiTargetVersion(); AceApplicationInfo::GetInstance().SetApiTargetVersion(static_cast(PlatformVersion::VERSION_TWELVE)); - + CheckBoxGroupModelNG checkBoxGroupModelNG; + checkBoxGroupModelNG.Create(CHECKBOXGROUP_NAME); + auto frameNode = AceType::DynamicCast(ViewStackProcessor::GetInstance()->Finish()); + ASSERT_NE(frameNode, nullptr); + RefPtr geometryNode = AceType::MakeRefPtr(); + ASSERT_NE(geometryNode, nullptr); /** * @tc.steps: step1. Create contentConstraint and layoutWrapper */ @@ -389,7 +402,7 @@ HWTEST_F(CheckBoxGroupLayoutAlgorithmTestNG, CheckBoxGroupLayoutAlgorithmTest001 LayoutConstraintF contentConstraint; contentConstraint.selfIdealSize = OptionalSizeF(nullLength, nullLength); LayoutWrapperNode layoutWrapper = - LayoutWrapperNode(nullptr, nullptr, AccessibilityManager::MakeRefPtr()); + LayoutWrapperNode(frameNode, geometryNode, AccessibilityManager::MakeRefPtr()); /** * @tc.steps: step2. Create mock theme manager @@ -417,4 +430,50 @@ HWTEST_F(CheckBoxGroupLayoutAlgorithmTestNG, CheckBoxGroupLayoutAlgorithmTest001 EXPECT_EQ(layoutAlgorithm->verticalPadding_, theme->GetDefaultPaddingSize().ConvertToPx()); AceApplicationInfo::GetInstance().SetApiTargetVersion(backupApiVersion); } + +/** + * @tc.name: CheckBoxGroupLayoutAlgorithmTest0010 + * @tc.desc: Test CheckBoxGroupLayoutAlgorithm MeasureContent. + * @tc.type: FUNC + */ +HWTEST_F(CheckBoxGroupLayoutAlgorithmTestNG, CheckBoxGroupLayoutAlgorithmTest011, TestSize.Level1) +{ + AceApplicationInfo::GetInstance().SetApiTargetVersion(static_cast(PlatformVersion::VERSION_TWELVE)); + CheckBoxGroupModelNG checkBoxGroupModelNG; + checkBoxGroupModelNG.Create(CHECKBOXGROUP_NAME); + auto frameNode = AceType::DynamicCast(ViewStackProcessor::GetInstance()->Finish()); + ASSERT_NE(frameNode, nullptr); + RefPtr geometryNode = AceType::MakeRefPtr(); + ASSERT_NE(geometryNode, nullptr); + auto pattern = frameNode->GetPattern(); + ASSERT_NE(pattern, nullptr); + /** + * @tc.steps: step1. Create contentConstraint and layoutWrapper + */ + LayoutConstraintF contentConstraint; + contentConstraint.selfIdealSize = OptionalSizeF(CHECKBOXGROUP_COMPONENT_WIDTH, CHECKBOXGROUP_COMPONENT_WIDTH); + LayoutWrapperNode layoutWrapper = + LayoutWrapperNode(frameNode, geometryNode, AccessibilityManager::MakeRefPtr()); + + /** + * @tc.steps: step2. Create mock theme manager + * @tc.expected: create successfully. + */ + auto eventHub = frameNode->GetOrCreateEventHub(); + CHECK_NULL_VOID(eventHub); + eventHub->SetGroupName(CHECKBOXGROUP_NAME); + eventHub->SetEnabled(true); + auto makeFunc = [](CheckBoxGroupConfiguration config) -> RefPtr { + EXPECT_EQ(CHECKBOXGROUP_NAME, config.name_); + EXPECT_EQ(CheckBoxGroupPaintProperty::SelectStatus::NONE, config.status_); + EXPECT_EQ(true, config.enabled_); + RefPtr child = + AceType::MakeRefPtr("child", CHILD_NODE_ID, AceType::MakeRefPtr()); + return child; + }; + pattern->SetBuilderFunc(makeFunc); + pattern->contentModifierNode_ = pattern->BuildContentModifierNode(); + auto layoutAlgorithm = AceType::MakeRefPtr(); + ASSERT_NE(layoutAlgorithm, nullptr); +} } // namespace OHOS::Ace::NG \ No newline at end of file diff --git a/test/unittest/core/pattern/checkboxgroup/checkboxgroup_paint_property_test_ng.cpp b/test/unittest/core/pattern/checkboxgroup/checkboxgroup_paint_property_test_ng.cpp index f81e8b17595..105c885ef94 100644 --- a/test/unittest/core/pattern/checkboxgroup/checkboxgroup_paint_property_test_ng.cpp +++ b/test/unittest/core/pattern/checkboxgroup/checkboxgroup_paint_property_test_ng.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -149,7 +149,7 @@ HWTEST_F(CheckBoxGroupPaintPropertyTestNG, CheckBoxGroupPaintPropertyTest001, Te auto json = JsonUtil::Create(true); paintProperty->ToJsonValue(json, filter); ASSERT_NE(json, nullptr); - EXPECT_EQ(json->GetString("checkboxShape"), ""); + EXPECT_EQ(json->GetString("checkboxShape"), "1"); } /** diff --git a/test/unittest/core/pattern/checkboxgroup/checkboxgroup_pattern_test_ng.cpp b/test/unittest/core/pattern/checkboxgroup/checkboxgroup_pattern_test_ng.cpp index ca383c470f4..1ff5ee2437c 100644 --- a/test/unittest/core/pattern/checkboxgroup/checkboxgroup_pattern_test_ng.cpp +++ b/test/unittest/core/pattern/checkboxgroup/checkboxgroup_pattern_test_ng.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -51,6 +51,7 @@ using namespace testing::ext; namespace OHOS::Ace::NG { namespace { const std::string CHECKBOXGROUP_NAME = "checkboxGroup"; +constexpr int CHILD_NODE_ID = 100; const Color DEFAULT_COLOR = Color::BLACK; } // namespace @@ -550,4 +551,292 @@ HWTEST_F(CheckBoxGroupPatternTestNG, OnInjectionEvent001, TestSize.Level1) selectStatus = status == CheckBoxGroupPaintProperty::SelectStatus::ALL ? true : false; EXPECT_EQ(selectStatus, true); } + +/** + * @tc.name: CheckBoxGroupContentModifierTest010 + * @tc.desc: SetBuilderFunc and get value + * @tc.type: FUNC + */ +HWTEST_F(CheckBoxGroupPatternTestNG, CheckBoxGroupContentModifierTest010, TestSize.Level1) +{ + /** + * @tc.steps: step1. Init CheckBoxGroup node + */ + CheckBoxGroupModelNG checkBoxGroupModelNG; + checkBoxGroupModelNG.Create(CHECKBOXGROUP_NAME); + auto frameNode = AceType::DynamicCast(ViewStackProcessor::GetInstance()->Finish()); + ASSERT_NE(frameNode, nullptr); + auto pattern = frameNode->GetPattern(); + ASSERT_NE(pattern, nullptr); + /** + * @tc.steps: step2. Set checkBoxGroupConfiguration + */ + checkBoxGroupModelNG.SetChangeValue(Referenced::RawPtr(frameNode), true); + auto eventHub = frameNode->GetOrCreateEventHub(); + CHECK_NULL_VOID(eventHub); + eventHub->SetGroupName(CHECKBOXGROUP_NAME); + eventHub->SetEnabled(true); + /** + * @tc.steps: step3. make builderFunc + */ + auto node = [](CheckBoxGroupConfiguration config) -> RefPtr { + EXPECT_EQ(CHECKBOXGROUP_NAME, config.name_); + EXPECT_EQ(CheckBoxGroupPaintProperty::SelectStatus::ALL, config.status_); + EXPECT_EQ(true, config.enabled_); + RefPtr child = + AceType::MakeRefPtr("child", CHILD_NODE_ID, AceType::MakeRefPtr()); + return child; + }; + /** + * @tc.steps: step4. Set parameters to pattern builderFunc + */ + checkBoxGroupModelNG.SetBuilderFunc(Referenced::RawPtr(frameNode), node); + pattern->BuildContentModifierNode(); +} + +/** + * @tc.name: CheckBoxGroupContentModifierTest011 + * @tc.desc: SetBuilderFunc and get value + * @tc.type: FUNC + */ +HWTEST_F(CheckBoxGroupPatternTestNG, CheckBoxGroupContentModifierTest011, TestSize.Level1) +{ + /** + * @tc.steps: step1. Init CheckBoxGroup node + */ + CheckBoxGroupModelNG checkBoxGroupModelNG; + checkBoxGroupModelNG.Create(CHECKBOXGROUP_NAME); + auto frameNode = AceType::DynamicCast(ViewStackProcessor::GetInstance()->Finish()); + ASSERT_NE(frameNode, nullptr); + auto pattern = frameNode->GetPattern(); + ASSERT_NE(pattern, nullptr); + /** + * @tc.steps: step2. Set checkBoxGroupConfiguration + */ + auto eventHub = frameNode->GetOrCreateEventHub(); + CHECK_NULL_VOID(eventHub); + eventHub->SetGroupName(CHECKBOXGROUP_NAME); + eventHub->SetEnabled(false); + pattern->SetCheckBoxGroupSelect(true); + /** + * @tc.steps: step3. make builderFunc + */ + auto makeFunc = [](CheckBoxGroupConfiguration config) -> RefPtr { + EXPECT_EQ(CHECKBOXGROUP_NAME, config.name_); + EXPECT_EQ(CheckBoxGroupPaintProperty::SelectStatus::NONE, config.status_); + EXPECT_EQ(false, config.enabled_); + RefPtr child = + AceType::MakeRefPtr("child", CHILD_NODE_ID, AceType::MakeRefPtr()); + return child; + }; + /** + * @tc.steps: step4. Set parameters to pattern builderFunc + */ + pattern->SetBuilderFunc(makeFunc); + pattern->FireBuilder(); + EXPECT_NE(pattern->contentModifierNode_, nullptr); +} + +/** + * @tc.name: CheckBoxGroupContentModifierTest012 + * @tc.desc: SetBuilderFunc and get value + * @tc.type: FUNC + */ +HWTEST_F(CheckBoxGroupPatternTestNG, CheckBoxGroupContentModifierTest012, TestSize.Level1) +{ + /** + * @tc.steps: step1. Init CheckBoxGroup node + */ + CheckBoxGroupModelNG checkBoxGroupModelNG; + checkBoxGroupModelNG.Create(CHECKBOXGROUP_NAME); + auto frameNode = AceType::DynamicCast(ViewStackProcessor::GetInstance()->Finish()); + ASSERT_NE(frameNode, nullptr); + auto pattern = frameNode->GetPattern(); + ASSERT_NE(pattern, nullptr); + /** + * @tc.steps: step2. Set checkBoxGroupConfiguration + */ + auto eventHub = frameNode->GetOrCreateEventHub(); + CHECK_NULL_VOID(eventHub); + eventHub->SetGroupName(CHECKBOXGROUP_NAME); + eventHub->SetEnabled(true); + pattern->OnClick(); + EXPECT_EQ(pattern->contentModifierNode_, nullptr); + /** + * @tc.steps: step3. make builderFunc + */ + auto makeFunc = [](CheckBoxGroupConfiguration config) -> RefPtr { + EXPECT_EQ(CHECKBOXGROUP_NAME, config.name_); + EXPECT_EQ(CheckBoxGroupPaintProperty::SelectStatus::ALL, config.status_); + EXPECT_EQ(true, config.enabled_); + RefPtr child = + AceType::MakeRefPtr("child", CHILD_NODE_ID, AceType::MakeRefPtr()); + return child; + }; + /** + * @tc.steps: step4. Set parameters to pattern builderFunc + */ + pattern->SetBuilderFunc(makeFunc); + pattern->FireBuilder(); + pattern->OnClick(); + EXPECT_NE(pattern->contentModifierNode_, nullptr); +} + +/** + * @tc.name: CheckBoxGroupContentModifierTest013 + * @tc.desc: Test CheckBoxGroup pattern method OnTouchUp. + * @tc.type: FUNC + */ +HWTEST_F(CheckBoxGroupPatternTestNG, CheckBoxGroupContentModifierTest013, TestSize.Level1) +{ + /** + * @tc.steps: step1. Init CheckBoxGroup node + */ + CheckBoxGroupModelNG CheckBoxGroupModelNG; + CheckBoxGroupModelNG.Create(CHECKBOXGROUP_NAME); + + /** + * @tc.steps: step2. Get CheckBoxGroup pattern object + */ + auto frameNode = AceType::DynamicCast(ViewStackProcessor::GetInstance()->Finish()); + ASSERT_NE(frameNode, nullptr); + auto pattern = frameNode->GetPattern(); + ASSERT_NE(pattern, nullptr); + + /** + * @tc.steps: step3. Set CheckBoxGroup pattern variable and call OnTouchUp + * @tc.expected: Check the CheckBoxGroup pattern value + */ + pattern->isHover_ = false; + pattern->OnTouchUp(); + EXPECT_EQ(pattern->touchHoverType_, TouchHoverAnimationType::NONE); + pattern->isHover_ = true; + pattern->OnTouchUp(); + EXPECT_EQ(pattern->touchHoverType_, TouchHoverAnimationType::PRESS_TO_HOVER); + + /** + * @tc.steps: step4. make builderFunc + */ + auto makeFunc = [](CheckBoxGroupConfiguration config) -> RefPtr { + EXPECT_EQ(CHECKBOXGROUP_NAME, config.name_); + EXPECT_EQ(CheckBoxGroupPaintProperty::SelectStatus::NONE, config.status_); + EXPECT_EQ(true, config.enabled_); + RefPtr child = + AceType::MakeRefPtr("child", CHILD_NODE_ID, AceType::MakeRefPtr()); + return child; + }; + /** + * @tc.steps: step5. Set parameters to pattern builderFunc + */ + pattern->SetBuilderFunc(makeFunc); + pattern->contentModifierNode_ = pattern->BuildContentModifierNode(); + pattern->touchHoverType_ = TouchHoverAnimationType::FOCUS; + pattern->isHover_ = false; + pattern->OnTouchUp(); + EXPECT_EQ(pattern->touchHoverType_, TouchHoverAnimationType::FOCUS); +} + +/** + * @tc.name: CheckBoxGroupContentModifierTest014 + * @tc.desc: Test CheckBoxGroup pattern method OnTouchDown. + * @tc.type: FUNC + */ +HWTEST_F(CheckBoxGroupPatternTestNG, CheckBoxGroupContentModifierTest014, TestSize.Level1) +{ + /** + * @tc.steps: step1. Init CheckBoxGroup node + */ + CheckBoxGroupModelNG CheckBoxGroupModelNG; + CheckBoxGroupModelNG.Create(CHECKBOXGROUP_NAME); + + /** + * @tc.steps: step2. Get CheckBoxGroup pattern object + */ + auto frameNode = AceType::DynamicCast(ViewStackProcessor::GetInstance()->Finish()); + ASSERT_NE(frameNode, nullptr); + auto pattern = frameNode->GetPattern(); + ASSERT_NE(pattern, nullptr); + + /** + * @tc.steps: step3. Set CheckBoxGroup pattern variable and call OnTouchDown + * @tc.expected: Check the CheckBoxGroup pattern value + */ + pattern->isHover_ = false; + pattern->touchHoverType_ = TouchHoverAnimationType::FOCUS; + pattern->OnTouchDown(); + EXPECT_EQ(pattern->touchHoverType_, TouchHoverAnimationType::PRESS); + pattern->isHover_ = true; + pattern->OnTouchDown(); + EXPECT_EQ(pattern->touchHoverType_, TouchHoverAnimationType::HOVER_TO_PRESS); + + /** + * @tc.steps: step4. make builderFunc + */ + auto makeFunc = [](CheckBoxGroupConfiguration config) -> RefPtr { + EXPECT_EQ(CHECKBOXGROUP_NAME, config.name_); + EXPECT_EQ(CheckBoxGroupPaintProperty::SelectStatus::NONE, config.status_); + EXPECT_EQ(true, config.enabled_); + RefPtr child = + AceType::MakeRefPtr("child", CHILD_NODE_ID, AceType::MakeRefPtr()); + return child; + }; + /** + * @tc.steps: step5. Set parameters to pattern builderFunc + */ + pattern->SetBuilderFunc(makeFunc); + pattern->contentModifierNode_ = pattern->BuildContentModifierNode(); + pattern->touchHoverType_ = TouchHoverAnimationType::FOCUS; + pattern->isHover_ = false; + pattern->OnTouchDown(); + EXPECT_EQ(pattern->touchHoverType_, TouchHoverAnimationType::FOCUS); +} + +/** + * @tc.name: CheckBoxGroupContentModifierTest015 + * @tc.desc: Test CheckBoxGroup pattern method UpdateUIStatus. + * @tc.type: FUNC + */ +HWTEST_F(CheckBoxGroupPatternTestNG, CheckBoxGroupContentModifierTest015, TestSize.Level1) +{ + /** + * @tc.steps: step1. Init CheckBoxGroup node + */ + CheckBoxGroupModelNG CheckBoxGroupModelNG; + CheckBoxGroupModelNG.Create(CHECKBOXGROUP_NAME); + + /** + * @tc.steps: step2. Get CheckBoxGroup pattern object + */ + auto frameNode = AceType::DynamicCast(ViewStackProcessor::GetInstance()->Finish()); + ASSERT_NE(frameNode, nullptr); + auto pattern = frameNode->GetPattern(); + ASSERT_NE(pattern, nullptr); + + /** + * @tc.steps: step3. Set CheckBoxGroup pattern variable and call UpdateUIStatus + * @tc.expected: Check the CheckBoxGroup pattern value + */ + pattern->uiStatus_ = UIStatus::ON_TO_OFF; + pattern->UpdateUIStatus(true); + EXPECT_EQ(pattern->uiStatus_, UIStatus::OFF_TO_ON); + EXPECT_EQ(pattern->contentModifierNode_, nullptr); + + /** + * @tc.steps: step4. make builderFunc + */ + auto makeFunc = [](CheckBoxGroupConfiguration config) -> RefPtr { + RefPtr child = + AceType::MakeRefPtr("child", CHILD_NODE_ID, AceType::MakeRefPtr()); + return child; + }; + /** + * @tc.steps: step5. Set parameters to pattern builderFunc + */ + pattern->SetBuilderFunc(makeFunc); + pattern->contentModifierNode_ = pattern->BuildContentModifierNode(); + + pattern->UpdateUIStatus(true); + EXPECT_EQ(pattern->uiStatus_, UIStatus::OFF_TO_ON); + EXPECT_TRUE(pattern->UseContentModifier()); +} } // namespace OHOS::Ace::NG diff --git a/test/unittest/core/pattern/checkboxgroup/checkboxgroup_test_ng.cpp b/test/unittest/core/pattern/checkboxgroup/checkboxgroup_test_ng.cpp index 06f0a401067..57637e2554d 100644 --- a/test/unittest/core/pattern/checkboxgroup/checkboxgroup_test_ng.cpp +++ b/test/unittest/core/pattern/checkboxgroup/checkboxgroup_test_ng.cpp @@ -1568,8 +1568,14 @@ HWTEST_F(CheckBoxGroupTestNG, CheckBoxGroupLayoutAlgorithmTest001, TestSize.Leve OptionalSizeF optionalSizeF(nullLength, nullLength); LayoutConstraintF contentConstraint; contentConstraint.selfIdealSize = optionalSizeF; + CheckBoxGroupModelNG checkBoxGroupModelNG; + checkBoxGroupModelNG.Create(GROUP_NAME); + auto frameNode = AceType::DynamicCast(ViewStackProcessor::GetInstance()->Finish()); + ASSERT_NE(frameNode, nullptr); + RefPtr geometryNode = AceType::MakeRefPtr(); + ASSERT_NE(geometryNode, nullptr); LayoutWrapperNode layoutWrapper = - LayoutWrapperNode(nullptr, nullptr, AccessibilityManager::MakeRefPtr()); + LayoutWrapperNode(frameNode, geometryNode, AccessibilityManager::MakeRefPtr()); auto themeManager = AceType::MakeRefPtr(); MockPipelineContext::GetCurrent()->SetThemeManager(themeManager); auto checkboxTheme = AceType::MakeRefPtr(); @@ -1587,12 +1593,12 @@ HWTEST_F(CheckBoxGroupTestNG, CheckBoxGroupLayoutAlgorithmTest001, TestSize.Leve * @tc.expected: Return sizeF base on default width and height. */ auto size = checkBoxGroupLayoutAlgorithm->MeasureContent(contentConstraint, &layoutWrapper); - EXPECT_FLOAT_EQ(size->Width(), COMPONENT_WIDTH / 2); - EXPECT_FLOAT_EQ(size->Height(), COMPONENT_WIDTH / 2); + EXPECT_FLOAT_EQ(size->Width(), COMPONENT_WIDTH); + EXPECT_FLOAT_EQ(size->Height(), COMPONENT_WIDTH); checkboxTheme->defaultHeight_ = Dimension(COMPONENT_HEIGHT); size = checkBoxGroupLayoutAlgorithm->MeasureContent(contentConstraint, &layoutWrapper); - EXPECT_FLOAT_EQ(size->Width(), COMPONENT_WIDTH / 2); - EXPECT_FLOAT_EQ(size->Height(), COMPONENT_WIDTH / 2); + EXPECT_FLOAT_EQ(size->Width(), COMPONENT_WIDTH); + EXPECT_FLOAT_EQ(size->Height(), COMPONENT_WIDTH); /** * @tc.steps: step3. Call method wile the width of contentConstraint is null. @@ -1600,8 +1606,8 @@ HWTEST_F(CheckBoxGroupTestNG, CheckBoxGroupLayoutAlgorithmTest001, TestSize.Leve */ contentConstraint.selfIdealSize.SetHeight(std::make_optional(-1)); size = checkBoxGroupLayoutAlgorithm->MeasureContent(contentConstraint, &layoutWrapper); - EXPECT_FLOAT_EQ(size->Width(), COMPONENT_WIDTH / 2); - EXPECT_FLOAT_EQ(size->Height(), COMPONENT_WIDTH / 2); + EXPECT_FLOAT_EQ(size->Width(), COMPONENT_WIDTH); + EXPECT_FLOAT_EQ(size->Height(), COMPONENT_WIDTH); contentConstraint.selfIdealSize.SetHeight(BORDER_RADIUS); size = checkBoxGroupLayoutAlgorithm->MeasureContent(contentConstraint, &layoutWrapper); EXPECT_FLOAT_EQ(size->Width(), BORDER_RADIUS); @@ -1614,8 +1620,8 @@ HWTEST_F(CheckBoxGroupTestNG, CheckBoxGroupLayoutAlgorithmTest001, TestSize.Leve contentConstraint.selfIdealSize.SetWidth(std::make_optional(-1)); contentConstraint.selfIdealSize.SetHeight(nullLength); size = checkBoxGroupLayoutAlgorithm->MeasureContent(contentConstraint, &layoutWrapper); - EXPECT_FLOAT_EQ(size->Width(), COMPONENT_WIDTH / 2); - EXPECT_FLOAT_EQ(size->Height(), COMPONENT_WIDTH / 2); + EXPECT_FLOAT_EQ(size->Width(), COMPONENT_WIDTH); + EXPECT_FLOAT_EQ(size->Height(), COMPONENT_WIDTH); contentConstraint.selfIdealSize.SetWidth(BORDER_WIDTH); size = checkBoxGroupLayoutAlgorithm->MeasureContent(contentConstraint, &layoutWrapper); EXPECT_FLOAT_EQ(size->Width(), BORDER_WIDTH); @@ -1628,8 +1634,8 @@ HWTEST_F(CheckBoxGroupTestNG, CheckBoxGroupLayoutAlgorithmTest001, TestSize.Leve contentConstraint.selfIdealSize.SetWidth(std::make_optional(-1)); contentConstraint.selfIdealSize.SetHeight(std::make_optional(-1)); size = checkBoxGroupLayoutAlgorithm->MeasureContent(contentConstraint, &layoutWrapper); - EXPECT_FLOAT_EQ(size->Width(), COMPONENT_WIDTH / 2); - EXPECT_FLOAT_EQ(size->Height(), COMPONENT_WIDTH / 2); + EXPECT_FLOAT_EQ(size->Width(), COMPONENT_WIDTH); + EXPECT_FLOAT_EQ(size->Height(), COMPONENT_WIDTH); contentConstraint.selfIdealSize.SetWidth(BORDER_WIDTH); contentConstraint.selfIdealSize.SetHeight(BORDER_RADIUS); size = checkBoxGroupLayoutAlgorithm->MeasureContent(contentConstraint, &layoutWrapper); @@ -1838,14 +1844,14 @@ HWTEST_F(CheckBoxGroupTestNG, CheckBoxGroupPatternTest025, TestSize.Level1) EXPECT_FLOAT_EQ(paintRect.GetRect().GetY(), COMPONENT_HEIGHT - COMPONENT_WIDTH); EXPECT_FLOAT_EQ(paintRect.GetRect().Width(), BORDER_RADIUS + COMPONENT_WIDTH * 2); EXPECT_FLOAT_EQ(paintRect.GetRect().Height(), BORDER_RADIUS + COMPONENT_WIDTH * 2); - EXPECT_FLOAT_EQ(paintRect.GetCornerRadius(RoundRect::CornerPos::TOP_LEFT_POS).x, BORDER_RADIUS); - EXPECT_FLOAT_EQ(paintRect.GetCornerRadius(RoundRect::CornerPos::TOP_LEFT_POS).y, BORDER_RADIUS); - EXPECT_FLOAT_EQ(paintRect.GetCornerRadius(RoundRect::CornerPos::TOP_RIGHT_POS).x, BORDER_RADIUS); - EXPECT_FLOAT_EQ(paintRect.GetCornerRadius(RoundRect::CornerPos::TOP_RIGHT_POS).y, BORDER_RADIUS); - EXPECT_FLOAT_EQ(paintRect.GetCornerRadius(RoundRect::CornerPos::BOTTOM_LEFT_POS).x, BORDER_RADIUS); - EXPECT_FLOAT_EQ(paintRect.GetCornerRadius(RoundRect::CornerPos::BOTTOM_LEFT_POS).y, BORDER_RADIUS); - EXPECT_FLOAT_EQ(paintRect.GetCornerRadius(RoundRect::CornerPos::BOTTOM_RIGHT_POS).x, BORDER_RADIUS); - EXPECT_FLOAT_EQ(paintRect.GetCornerRadius(RoundRect::CornerPos::BOTTOM_RIGHT_POS).y, BORDER_RADIUS); + EXPECT_FLOAT_EQ(paintRect.GetCornerRadius(RoundRect::CornerPos::TOP_LEFT_POS).x, BORDER_RADIUS * 2 + 50); + EXPECT_FLOAT_EQ(paintRect.GetCornerRadius(RoundRect::CornerPos::TOP_LEFT_POS).y, BORDER_RADIUS * 2 + 50); + EXPECT_FLOAT_EQ(paintRect.GetCornerRadius(RoundRect::CornerPos::TOP_RIGHT_POS).x, BORDER_RADIUS * 2 + 50); + EXPECT_FLOAT_EQ(paintRect.GetCornerRadius(RoundRect::CornerPos::TOP_RIGHT_POS).y, BORDER_RADIUS * 2 + 50); + EXPECT_FLOAT_EQ(paintRect.GetCornerRadius(RoundRect::CornerPos::BOTTOM_LEFT_POS).x, BORDER_RADIUS * 2 + 50); + EXPECT_FLOAT_EQ(paintRect.GetCornerRadius(RoundRect::CornerPos::BOTTOM_LEFT_POS).y, BORDER_RADIUS * 2 + 50); + EXPECT_FLOAT_EQ(paintRect.GetCornerRadius(RoundRect::CornerPos::BOTTOM_RIGHT_POS).x, BORDER_RADIUS * 2 + 50); + EXPECT_FLOAT_EQ(paintRect.GetCornerRadius(RoundRect::CornerPos::BOTTOM_RIGHT_POS).y, BORDER_RADIUS * 2 + 50); } /** @@ -2369,8 +2375,14 @@ HWTEST_F(CheckBoxGroupTestNG, CheckBoxGroupMeasureContentTest001, TestSize.Level * @tc.steps: step1. Create CheckBoxGroupLayoutAlgorithm. * @tc.expected: Create successfully. */ + CheckBoxGroupModelNG checkBoxGroupModelNG; + checkBoxGroupModelNG.Create(GROUP_NAME); + auto frameNode = AceType::DynamicCast(ViewStackProcessor::GetInstance()->Finish()); + ASSERT_NE(frameNode, nullptr); + RefPtr geometryNode = AceType::MakeRefPtr(); + ASSERT_NE(geometryNode, nullptr); LayoutWrapperNode layoutWrapper = - LayoutWrapperNode(nullptr, nullptr, AccessibilityManager::MakeRefPtr()); + LayoutWrapperNode(frameNode, geometryNode, AccessibilityManager::MakeRefPtr()); auto checkBoxGroupLayoutAlgorithm = AceType::MakeRefPtr(); ASSERT_NE(checkBoxGroupLayoutAlgorithm, nullptr); -- Gitee