diff --git a/frameworks/bridge/declarative_frontend/jsview/js_particle.cpp b/frameworks/bridge/declarative_frontend/jsview/js_particle.cpp index 70211c6bac682a9df7acec7e3d8f3de233c4981b..c3e24477ff661df89ae0f51018bad61d72578f30 100644 --- a/frameworks/bridge/declarative_frontend/jsview/js_particle.cpp +++ b/frameworks/bridge/declarative_frontend/jsview/js_particle.cpp @@ -478,6 +478,85 @@ void ParseFloatOption(JSRef& floatJsObject, OHOS::Ace::NG::ParticleFlo floatOption.SetUpdater(updater); } +template +void AnnulusRegisterResourceObject(T& annulusRegionValue, + const RefPtr& centerXResObj, const RefPtr& centerYResObj, + const RefPtr& innerRadiusResObj, const RefPtr& outerRadiusResObj) +{ + if (centerXResObj) { + auto&& centerXUpdateFunc = [](const RefPtr& centerXResObj, + OHOS::Ace::NG::ParticleAnnulusRegion& annulusRegion) { + CalcDimension centerXValue; + ResourceParseUtils::ParseResDimensionVpNG(centerXResObj, centerXValue); + annulusRegion.SetCenterX(centerXValue); + }; + annulusRegionValue.AddResource( + "annulusRegion.centerX", centerXResObj, std::move(centerXUpdateFunc)); + } else { + annulusRegionValue.RemoveResource("annulusRegion.centerX"); + } + if (centerYResObj) { + auto&& centerYUpdateFunc = [](const RefPtr& centerYResObj, + OHOS::Ace::NG::ParticleAnnulusRegion& annulusRegion) { + CalcDimension centerYValue; + ResourceParseUtils::ParseResDimensionVpNG(centerYResObj, centerYValue); + annulusRegion.SetCenterY(centerYValue); + }; + annulusRegionValue.AddResource( + "annulusRegion.centerY", centerYResObj, std::move(centerYUpdateFunc)); + } else { + annulusRegionValue.RemoveResource("annulusRegion.centerY"); + } + if (innerRadiusResObj) { + auto&& innerRadiusUpdateFunc = [](const RefPtr& innerRadiusResObj, + OHOS::Ace::NG::ParticleAnnulusRegion& annulusRegion) { + CalcDimension innerRadiusValue; + ResourceParseUtils::ParseResDimensionVpNG(innerRadiusResObj, innerRadiusValue); + annulusRegion.SetInnerRadius(innerRadiusValue); + }; + annulusRegionValue.AddResource( + "annulusRegion.innerRadius", innerRadiusResObj, std::move(innerRadiusUpdateFunc)); + } else { + annulusRegionValue.RemoveResource("annulusRegion.innerRadius"); + } + if (outerRadiusResObj) { + auto&& outerRadiusUpdateFunc = [](const RefPtr& outerRadiusResObj, + OHOS::Ace::NG::ParticleAnnulusRegion& annulusRegion) { + CalcDimension outerRadiusValue; + ResourceParseUtils::ParseResDimensionVpNG(outerRadiusResObj, outerRadiusValue); + annulusRegion.SetOuterRadius(outerRadiusValue); + }; + annulusRegionValue.AddResource( + "annulusRegion.outerRadius", outerRadiusResObj, std::move(outerRadiusUpdateFunc)); + } else { + annulusRegionValue.RemoveResource("annulusRegion.outerRadius"); + } +} + +void ParseAnnulusCenter(const JSRef& centerJson, std::pair& center, + RefPtr& centerXResObj, RefPtr& centerYResObj) +{ + CalcDimension centerXValue; + CalcDimension centerYValue; + if (SystemProperties::ConfigChangePerform()) { + if (JSViewAbstract::ParseLengthMetricsToDimension(centerJson->GetProperty("x"), + centerXValue, centerXResObj)) { + center.first = centerXValue; + } + if (JSViewAbstract::ParseLengthMetricsToDimension(centerJson->GetProperty("y"), + centerYValue, centerYResObj)) { + center.second = centerYValue; + } + } else { + if (JSViewAbstract::ParseLengthMetricsToDimension(centerJson->GetProperty("x"), centerXValue)) { + center.first = centerXValue; + } + if (JSViewAbstract::ParseLengthMetricsToDimension(centerJson->GetProperty("y"), centerYValue)) { + center.second = centerYValue; + } + } +} + void ParseEmitterPropertyAnnulus(const JSRef& paramObj, EmitterProperty& emitterProperty) { auto annulusRegionProperty = paramObj->GetProperty("annulusRegion"); @@ -522,27 +601,40 @@ void ParseEmitterOptionAnnulus(JSRef& emitterJsObject, OHOS::Ace::NG:: std::pair center = { DEFAULT_CENTER_VALUE, DEFAULT_CENTER_VALUE }; + RefPtr centerXResObj; + RefPtr centerYResObj; if (centerProperty->IsObject()) { auto centerJson = JSRef::Cast(centerProperty); - CalcDimension centerXValue; - CalcDimension centerYValue; - if (JSViewAbstract::ParseLengthMetricsToDimension(centerJson->GetProperty("x"), centerXValue)) { - center.first = centerXValue; - } - if (JSViewAbstract::ParseLengthMetricsToDimension(centerJson->GetProperty("y"), centerYValue)) { - center.second = centerYValue; - } + ParseAnnulusCenter(centerJson, center, centerXResObj, centerYResObj); } CalcDimension innerRadiusValue; + RefPtr innerRadiusResObj; + if (SystemProperties::ConfigChangePerform()) { + JSViewAbstract::ParseLengthMetricsToDimension( + annulusRegion->GetProperty("innerRadius"), innerRadiusValue, innerRadiusResObj); + } else { + JSViewAbstract::ParseLengthMetricsToDimension( + annulusRegion->GetProperty("innerRadius"), innerRadiusValue); + } CalcDimension outerRadiusValue; - JSViewAbstract::ParseLengthMetricsToDimension(annulusRegion->GetProperty("innerRadius"), innerRadiusValue); - JSViewAbstract::ParseLengthMetricsToDimension(annulusRegion->GetProperty("outerRadius"), outerRadiusValue); + RefPtr outerRadiusResObj; + if (SystemProperties::ConfigChangePerform()) { + JSViewAbstract::ParseLengthMetricsToDimension( + annulusRegion->GetProperty("outerRadius"), outerRadiusValue, outerRadiusResObj); + } else { + JSViewAbstract::ParseLengthMetricsToDimension( + annulusRegion->GetProperty("outerRadius"), outerRadiusValue); + } auto startAngle = annulusRegion->GetProperty("startAngle"); auto startAngleValue = startAngle->IsNumber() ? startAngle->ToNumber() : DEFAULT_START_ANGLE_VALUE; auto endAngle = annulusRegion->GetProperty("endAngle"); auto endAngleValue = endAngle->IsNumber() ? endAngle->ToNumber() : DEFAULT_END_ANGLE_VALUE; auto annulusRegionValue = NG::ParticleAnnulusRegion(center, innerRadiusValue, outerRadiusValue, startAngleValue, endAngleValue); + if (SystemProperties::ConfigChangePerform()) { + AnnulusRegisterResourceObject(annulusRegionValue, centerXResObj, + centerYResObj, innerRadiusResObj, outerRadiusResObj); + } emitterOption.SetAnnulusRegion(annulusRegionValue); } } diff --git a/frameworks/core/components_ng/pattern/particle/particle_model_ng.cpp b/frameworks/core/components_ng/pattern/particle/particle_model_ng.cpp index af18ccfea48793e3b1c2615a2cbf158ef5b8adcf..5067a7cc8e4dc1fa66c955bb9a2ce86726f78fc0 100644 --- a/frameworks/core/components_ng/pattern/particle/particle_model_ng.cpp +++ b/frameworks/core/components_ng/pattern/particle/particle_model_ng.cpp @@ -31,12 +31,12 @@ void ReloadParticleResources(const ParticleOption& particleOption, std::list> animationArrayValue; // reloadResources ParticleColorPropertyOptions: range. - auto particlrColorOpt = particleOption.GetParticleColorOption(); - if (particlrColorOpt.has_value()) { - particlrColorOpt->ReloadResources(); + auto particleColorOpt = particleOption.GetParticleColorOption(); + if (particleColorOpt.has_value()) { + particleColorOpt->ReloadResources(); // reloadResources ParticleUpdater.CURVE: from、to. - updater = particlrColorOpt.value().GetUpdater(); + updater = particleColorOpt.value().GetUpdater(); if (updater.has_value()) { updaterConfig = updater.value().GetConfig(); auto animationArray = updaterConfig.GetAnimationArray(); @@ -53,22 +53,30 @@ void ReloadParticleResources(const ParticleOption& particleOption, auto imageParameter = particleConfig.GetImageParticleParameter(); imageParameter.ReloadResources(); + auto annulusRegion = emitterOptionOpt.GetAnnulusRegion(); + if (annulusRegion.has_value()) { + annulusRegion->ReloadResources(); + } + ParticleOption updatedParticleOption = particleOption; // set src and size after reloadResources. particleConfig.SetImageParticleParameter(imageParameter); particle.SetConfig(particleConfig); emitterOptionOpt.SetParticle(particle); + if (annulusRegion.has_value()) { + emitterOptionOpt.SetAnnulusRegion(annulusRegion.value()); + } // set position and size after reloadResources. updatedParticleOption.SetEmitterOption(emitterOptionOpt); // set range and from-to after reloadResources. - if (particlrColorOpt.has_value() && updater.has_value()) { + if (particleColorOpt.has_value() && updater.has_value()) { updaterConfig.SetAnimationArray(animationArrayValue); updater.value().SetConfig(updaterConfig); - particlrColorOpt.value().SetUpdater(updater.value()); - updatedParticleOption.SetParticleColorOption(particlrColorOpt.value()); + particleColorOpt.value().SetUpdater(updater.value()); + updatedParticleOption.SetParticleColorOption(particleColorOpt.value()); } updatedArrayValue.push_back(updatedParticleOption); } diff --git a/frameworks/core/components_ng/pattern/particle/particle_pattern.cpp b/frameworks/core/components_ng/pattern/particle/particle_pattern.cpp index 3e7eeed42b77cc6fd22749b2c2f88ec1de0da914..cd37be3adae9ba60331bed300bdb03dabf25ce38 100644 --- a/frameworks/core/components_ng/pattern/particle/particle_pattern.cpp +++ b/frameworks/core/components_ng/pattern/particle/particle_pattern.cpp @@ -67,15 +67,15 @@ std::unique_ptr ParticlePattern::ParseAnnulusRegionJson(const Particl { auto emitterOptionOpt = particleOption.GetEmitterOption(); auto objectAnnulusRegionJson = JsonUtil::Create(true); - auto center = annulusRegion.center_; + auto center = annulusRegion.GetCenter(); auto centerObj = JsonUtil::Create(true); centerObj->Put("x", center.first.ToString().c_str()); centerObj->Put("y", center.second.ToString().c_str()); objectAnnulusRegionJson->Put("center", centerObj); - objectAnnulusRegionJson->Put("innerRadius", std::to_string(annulusRegion.innerRadius_.ConvertToPx()).c_str()); - objectAnnulusRegionJson->Put("outerRadius", std::to_string(annulusRegion.outerRadius_.ConvertToPx()).c_str()); - objectAnnulusRegionJson->Put("startAngle", std::to_string(annulusRegion.startAngle_).c_str()); - objectAnnulusRegionJson->Put("endAngle", std::to_string(annulusRegion.endAngle_).c_str()); + objectAnnulusRegionJson->Put("innerRadius", std::to_string(annulusRegion.GetInnerRadius().ConvertToPx()).c_str()); + objectAnnulusRegionJson->Put("outerRadius", std::to_string(annulusRegion.GetOuterRadius().ConvertToPx()).c_str()); + objectAnnulusRegionJson->Put("startAngle", std::to_string(annulusRegion.GetStartAngle()).c_str()); + objectAnnulusRegionJson->Put("endAngle", std::to_string(annulusRegion.GetEndAngle()).c_str()); return objectAnnulusRegionJson; } diff --git a/frameworks/core/components_ng/property/particle_property.h b/frameworks/core/components_ng/property/particle_property.h index c26ec54710123d72e8d69381af4d369ff56a69a4..cc840a6309e31ab77880f2fc9a25c52302251de7 100644 --- a/frameworks/core/components_ng/property/particle_property.h +++ b/frameworks/core/components_ng/property/particle_property.h @@ -310,6 +310,99 @@ struct ParticleAnnulusRegion { return str; } + std::pair GetCenter() const + { + return center_; + } + + void SetCenter(const std::pair& center) + { + center_ = center; + } + + void SetCenterX(CalcDimension& centerX) + { + center_.first = centerX; + } + + void SetCenterY(CalcDimension& centerY) + { + center_.second = centerY; + } + + CalcDimension GetInnerRadius() const + { + return innerRadius_; + } + + void SetInnerRadius(const CalcDimension& innerRadius) + { + innerRadius_ = innerRadius; + } + + CalcDimension GetOuterRadius() const + { + return outerRadius_; + } + + void SetOuterRadius(const CalcDimension& outerRadius) + { + outerRadius_ = outerRadius; + } + + float GetStartAngle() const + { + return startAngle_; + } + + void SetStartAngle(float startAngle) + { + startAngle_ = startAngle; + } + + float GetEndAngle() const + { + return endAngle_; + } + + void SetEndAngle(float endAngle) + { + endAngle_ = endAngle; + } + + void AddResource( + const std::string& key, + const RefPtr& resObj, + std::function&, ParticleAnnulusRegion&)>&& updateFunc) + { + if (resObj == nullptr || !updateFunc) { + return; + } + AnnulusResMap_[key] = { resObj, std::move(updateFunc) }; + } + + void ReloadResources() + { + for (const auto& [key, resourceUpdater] : AnnulusResMap_) { + resourceUpdater.updateFunc(resourceUpdater.obj, *this); + } + } + + void RemoveResource(const std::string& key) + { + auto iter = AnnulusResMap_.find(key); + if (iter != AnnulusResMap_.end()) { + AnnulusResMap_.erase(iter); + } + } + +private: + struct ResourceUpdater { + RefPtr obj; + std::function&, ParticleAnnulusRegion&)> updateFunc; + }; + std::unordered_map AnnulusResMap_; + std::pair center_; CalcDimension innerRadius_; CalcDimension outerRadius_; diff --git a/frameworks/core/components_ng/render/adapter/rosen_particle_context.cpp b/frameworks/core/components_ng/render/adapter/rosen_particle_context.cpp index 5316a0f0b7e91c8cebda596911f384fab119b582..8fd959e0856c2ad5cd3ffe545d73590cf5c91ef2 100644 --- a/frameworks/core/components_ng/render/adapter/rosen_particle_context.cpp +++ b/frameworks/core/components_ng/render/adapter/rosen_particle_context.cpp @@ -71,19 +71,19 @@ void RosenRenderParticle::updateEmitterPosition( std::shared_ptr rsAnnulusRegion = nullptr; if (prop.annulusRegion) { auto annulusRegion = prop.annulusRegion; - auto center = annulusRegion->center_; + auto center = annulusRegion->GetCenter(); auto rect = renderContext->GetPaintRectWithoutTransform(); auto rsCenter = OHOS::Rosen::Vector2f(center.first.ConvertToPxWithSize(rect.Width()), center.second.ConvertToPxWithSize(rect.Height())); - auto innerRadius = annulusRegion->innerRadius_; + auto innerRadius = annulusRegion->GetInnerRadius(); auto rsInnerRadius = (LessOrEqual(innerRadius.ConvertToPx(), 0.0) || innerRadius.Unit() == DimensionUnit::PERCENT) ? 0.0 : innerRadius.ConvertToPx(); - auto outerRadius = annulusRegion->outerRadius_; + auto outerRadius = annulusRegion->GetOuterRadius(); auto rsOuterRadius = (LessOrEqual(outerRadius.ConvertToPx(), 0.0) || outerRadius.Unit() == DimensionUnit::PERCENT) ? 0.0 : outerRadius.ConvertToPx(); rsAnnulusRegion = std::make_shared(rsCenter, rsInnerRadius, - rsOuterRadius, annulusRegion->startAngle_, annulusRegion->endAngle_); + rsOuterRadius, annulusRegion->GetStartAngle(), annulusRegion->GetEndAngle()); } updater->SetShape(rsAnnulusRegion); emitUpdater.push_back(updater); diff --git a/frameworks/core/components_ng/render/adapter/rosen_render_context.cpp b/frameworks/core/components_ng/render/adapter/rosen_render_context.cpp index 1cef90ed1abe0473a32f57033b4a23aab3f86601..e96af24f38f2e0e85f8a0a9215938641aff393b9 100755 --- a/frameworks/core/components_ng/render/adapter/rosen_render_context.cpp +++ b/frameworks/core/components_ng/render/adapter/rosen_render_context.cpp @@ -1339,8 +1339,8 @@ void RosenRenderContext::OnEmitterPropertyUpdate() continue; } const auto& annulusRegion = prop.annulusRegion.value(); - if (annulusRegion.center_.first.Unit() == DimensionUnit::PERCENT || - annulusRegion.center_.second.Unit() == DimensionUnit::PERCENT) { + if (annulusRegion.GetCenter().first.Unit() == DimensionUnit::PERCENT || + annulusRegion.GetCenter().second.Unit() == DimensionUnit::PERCENT) { particlePattern->updateEmitterPosition(property); return; } @@ -1503,21 +1503,21 @@ Rosen::EmitterConfig RosenRenderContext::ConvertParticleEmitterOption( auto annulusRegionOpt = emitterOption.GetAnnulusRegion(); if (annulusRegionOpt.has_value() && shapeInt == static_cast(ParticleEmitterShape::ANNULUS)) { auto annulusRegion = annulusRegionOpt.value(); - auto center = annulusRegion.center_; + auto center = annulusRegion.GetCenter(); auto rsCenter = OHOS::Rosen::Vector2f(center.first.ConvertToPxWithSize(rect.Width()), center.second.ConvertToPxWithSize(rect.Height())); - auto innerRadius = annulusRegion.innerRadius_; + auto innerRadius = annulusRegion.GetInnerRadius(); auto rsInnerRadius = (LessOrEqual(innerRadius.ConvertToPx(), 0.0) || innerRadius.Unit() == DimensionUnit::PERCENT) ? 0.0 : innerRadius.ConvertToPx(); - auto outerRadius = annulusRegion.outerRadius_; + auto outerRadius = annulusRegion.GetOuterRadius(); auto rsOuterRadius = (LessOrEqual(outerRadius.ConvertToPx(), 0.0) || outerRadius.Unit() == DimensionUnit::PERCENT) ? 0.0 : outerRadius.ConvertToPx(); rsAnnulusRegion = std::make_shared(rsCenter, rsInnerRadius, - rsOuterRadius, annulusRegion.startAngle_, annulusRegion.endAngle_); + rsOuterRadius, annulusRegion.GetStartAngle(), annulusRegion.GetEndAngle()); } if (particleType == ParticleType::IMAGE) { auto imageParameter = particleConfig.GetImageParticleParameter(); diff --git a/test/unittest/core/pattern/particle/particle_test_ng.cpp b/test/unittest/core/pattern/particle/particle_test_ng.cpp index 28c3ea25fd2e9764754a0e2a7900dcfe584d3dc1..6164b14848e2697eecf284f543b6301720dce760 100644 --- a/test/unittest/core/pattern/particle/particle_test_ng.cpp +++ b/test/unittest/core/pattern/particle/particle_test_ng.cpp @@ -375,6 +375,26 @@ HWTEST_F(ParticleTestNg, ParticleToJsonValue001, TestSize.Level1) EXPECT_EQ(radius, "6.000000"); } +/** + * @tc.name: ParticleResObj002 + * @tc.desc: Test CreateParticleResObj of particle + * @tc.type: FUNC + */ +HWTEST_F(ParticleTestNg, ParticleResObj002, TestSize.Level1) +{ + auto particleNode = FrameNode::GetOrCreateFrameNode( + V2::PARTICLE_ETS_TAG, 1, [count = 1]() { return AceType::MakeRefPtr(count); }); + ASSERT_NE(particleNode, nullptr); + auto pattern = AceType::DynamicCast(particleNode->GetPattern()); + ASSERT_NE(pattern, nullptr); + RefPtr resObj = AceType::MakeRefPtr("", "", -1);; + auto&& updateFunc = [](const RefPtr& resObj) {}; + updateFunc(resObj); + pattern->AddResObj("particle.Update", resObj, std::move(updateFunc)); + std::string particle = pattern->GetResCacheMapByKey("particle.Update"); + EXPECT_EQ(particle, ""); +} + /** * @tc.name: ParticleToJsonValue002 * @tc.desc: Test GetEmitterJson parse.