1 /* 2 * Copyright (c) 2022-2023 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_GAUGE_GAUGE_PAINT_PROPERTY_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_GAUGE_GAUGE_PAINT_PROPERTY_H 18 19 #include "core/common/container.h" 20 #include "core/common/resource/resource_object.h" 21 #include "core/components/common/layout/constants.h" 22 #include "core/components/common/properties/color.h" 23 #include "core/components_ng/base/inspector_filter.h" 24 #include "core/components_ng/pattern/gauge/gauge_theme.h" 25 #include "core/components_ng/render/paint_property.h" 26 #include "core/image/image_source_info.h" 27 28 namespace OHOS::Ace::NG { 29 using ColorStopArray = std::vector<std::pair<Color, Dimension>>; 30 enum class GaugeType : int32_t { 31 TYPE_CIRCULAR_MULTI_SEGMENT_GRADIENT = 0, 32 TYPE_CIRCULAR_SINGLE_SEGMENT_GRADIENT = 1, 33 TYPE_CIRCULAR_MONOCHROME = 2, 34 }; 35 36 struct GaugeShadowOptions { 37 bool isShadowVisible = true; 38 float radius = DEFAULT_GAUGE_SHADOW_RADIUS; 39 float offsetX = DEFAULT_GAUGE_SHADOW_OFFSETX; 40 float offsetY = DEFAULT_GAUGE_SHADOW_OFFSETY; 41 bool operator==(const GaugeShadowOptions& rhs) const 42 { 43 return radius == rhs.radius && offsetX == rhs.offsetX && offsetY == rhs.offsetY && 44 isShadowVisible == rhs.isShadowVisible; 45 } 46 using UpdateFunc = std::function<void(const RefPtr<ResourceObject>&, GaugeShadowOptions&)>; AddResourceGaugeShadowOptions47 void AddResource(const std::string& key, const RefPtr<ResourceObject>& resObj, UpdateFunc&& updateFunc) 48 { 49 if (resObj == nullptr || !updateFunc) { 50 return; 51 } 52 resMap_[key] = { resObj, std::move(updateFunc) }; 53 } 54 ReloadResourcesGaugeShadowOptions55 void ReloadResources() 56 { 57 for (const auto& [key, resourceUpdater] : resMap_) { 58 resourceUpdater.updateFunc(resourceUpdater.obj, *this); 59 } 60 } 61 62 private: 63 struct ResourceUpdater { 64 RefPtr<ResourceObject> obj; 65 UpdateFunc updateFunc; 66 }; 67 68 std::unordered_map<std::string, ResourceUpdater> resMap_; 69 }; 70 class GaugePaintProperty : public PaintProperty { 71 DECLARE_ACE_TYPE(GaugePaintProperty, PaintProperty); 72 73 public: 74 GaugePaintProperty() = default; 75 ~GaugePaintProperty() override = default; 76 Clone()77 RefPtr<PaintProperty> Clone() const override 78 { 79 auto paintProperty = MakeRefPtr<GaugePaintProperty>(); 80 paintProperty->UpdatePaintProperty(this); 81 paintProperty->propValue_ = CloneValue(); 82 paintProperty->propMin_ = CloneMin(); 83 paintProperty->propMax_ = CloneMax(); 84 paintProperty->propStartAngle_ = CloneStartAngle(); 85 paintProperty->propEndAngle_ = CloneEndAngle(); 86 paintProperty->propColors_ = CloneColors(); 87 paintProperty->propGradientColors_ = CloneGradientColors(); 88 paintProperty->propValues_ = CloneValues(); 89 paintProperty->propStrokeWidth_ = CloneStrokeWidth(); 90 paintProperty->propGaugeType_ = CloneGaugeType(); 91 paintProperty->propShadowOptions_ = CloneShadowOptions(); 92 paintProperty->propIsShowIndicator_ = CloneIsShowIndicator(); 93 paintProperty->propIndicatorIconSourceInfo_ = CloneIndicatorIconSourceInfo(); 94 paintProperty->propIndicatorSpace_ = CloneIndicatorSpace(); 95 paintProperty->propIndicatorChange_ = CloneIndicatorChange(); 96 paintProperty->propIsSensitive_ = CloneIsSensitive(); 97 return paintProperty; 98 } 99 Reset()100 void Reset() override 101 { 102 PaintProperty::Reset(); 103 ResetValue(); 104 ResetMin(); 105 ResetMax(); 106 ResetStartAngle(); 107 ResetEndAngle(); 108 ResetColors(); 109 ResetGradientColors(); 110 ResetValues(); 111 ResetStrokeWidth(); 112 ResetGaugeType(); 113 ResetShadowOptions(); 114 ResetIsShowIndicator(); 115 ResetIndicatorIconSourceInfo(); 116 ResetIndicatorSpace(); 117 ResetIsSensitive(); 118 } 119 ToJsonValue(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter)120 void ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const override 121 { 122 PaintProperty::ToJsonValue(json, filter); 123 /* no fixed attr below, just return */ 124 if (filter.IsFastFilter()) { 125 if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_ELEVEN)) { 126 ToJsonColor(json, filter); 127 ToJsonIndicator(json, filter); 128 ToJsonTrackShadow(json, filter); 129 } 130 return; 131 } 132 json->PutExtAttr("value", StringUtils::DoubleToString(propValue_.value_or(0)).c_str(), filter); 133 json->PutExtAttr("max", StringUtils::DoubleToString(propMax_.value_or(100)).c_str(), filter); 134 json->PutExtAttr("min", StringUtils::DoubleToString(propMin_.value_or(0)).c_str(), filter); 135 json->PutExtAttr("startAngle", StringUtils::DoubleToString(propStartAngle_.value_or(0)).c_str(), filter); 136 json->PutExtAttr("endAngle", StringUtils::DoubleToString(propEndAngle_.value_or(360)).c_str(), filter); 137 json->PutExtAttr("isSensitive", std::to_string(GetIsSensitive().value_or(false)).c_str(), filter); 138 json->PutExtAttr("privacySensitive", GetIsSensitive().value_or(false)? "true": "false", filter); 139 if (propStrokeWidth_.has_value()) { 140 json->PutExtAttr("strokeWidth", propStrokeWidth_.value().ToString().c_str(), filter); 141 } else { 142 json->PutExtAttr("strokeWidth", "", filter); 143 } 144 145 if (Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN)) { 146 auto jsonColors = JsonUtil::CreateArray(true); 147 if (propColors_.has_value() && propColors_.has_value()) { 148 for (size_t i = 0; i < propValues_.value().size(); i++) { 149 auto jsonObject = JsonUtil::CreateArray(true); 150 jsonObject->Put("0", propColors_.value()[i].ColorToString().c_str()); 151 jsonObject->Put("1", propValues_.value()[i]); 152 auto index = std::to_string(i); 153 jsonColors->Put(index.c_str(), jsonObject); 154 } 155 } 156 json->PutExtAttr("colors", jsonColors->ToString().c_str(), filter); 157 } else { 158 ToJsonColor(json, filter); 159 ToJsonIndicator(json, filter); 160 ToJsonTrackShadow(json, filter); 161 } 162 } 163 ToJsonColor(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter)164 void ToJsonColor(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const 165 { 166 /* no fixed attr below, just return */ 167 if (filter.IsFastFilter()) { 168 return; 169 } 170 if (!propGaugeType_.has_value()) { 171 auto jsonColor = JsonUtil::CreateArray(true); 172 for (size_t j = 0; j < GAUGE_DEFAULT_COLOR.size(); j++) { 173 jsonColor->Put(std::to_string(j).c_str(), GAUGE_DEFAULT_COLOR[j].ColorToString().c_str()); 174 } 175 json->PutExtAttr("colors", jsonColor->ToString().c_str(), filter); 176 return; 177 } 178 179 if (propGaugeType_.value() == GaugeType::TYPE_CIRCULAR_MONOCHROME) { 180 if (propGradientColors_.has_value()) { 181 json->PutExtAttr("colors", 182 propGradientColors_.value().at(0).at(0).first.ColorToString().c_str(), filter); 183 } 184 return; 185 } 186 187 if (propGaugeType_.value() == GaugeType::TYPE_CIRCULAR_SINGLE_SEGMENT_GRADIENT) { 188 if (propGradientColors_.has_value()) { 189 auto jsonColor = JsonUtil::CreateArray(true); 190 auto colorStopArray = propGradientColors_.value().at(0); 191 for (size_t j = 0; j < colorStopArray.size(); j++) { 192 auto jsonColorObject = JsonUtil::CreateArray(true); 193 jsonColorObject->Put("0", colorStopArray[j].first.ColorToString().c_str()); 194 jsonColorObject->Put("1", std::to_string(colorStopArray[j].second.Value()).c_str()); 195 auto indexStr = std::to_string(j); 196 jsonColor->Put(indexStr.c_str(), jsonColorObject); 197 } 198 json->PutExtAttr("colors", jsonColor->ToString().c_str(), filter); 199 } 200 return; 201 } 202 ToJsonColorHasValue(json, filter); 203 } 204 ToJsonColorHasValue(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter)205 void ToJsonColorHasValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const 206 { 207 auto jsonGradientColors = JsonUtil::CreateArray(true); 208 if (propGradientColors_.has_value() && propValues_.has_value() && 209 (propGradientColors_.value().size() == propValues_.value().size())) { 210 for (size_t i = 0; i < propValues_.value().size(); i++) { 211 auto jsonObject = JsonUtil::CreateArray(true); 212 auto jsonColor = JsonUtil::CreateArray(true); 213 auto colorStopArray = propGradientColors_.value()[i]; 214 for (size_t j = 0; j < colorStopArray.size(); j++) { 215 auto jsonColorObject = JsonUtil::CreateArray(true); 216 jsonColorObject->Put("0", colorStopArray[j].first.ColorToString().c_str()); 217 jsonColorObject->Put("1", std::to_string(colorStopArray[j].second.Value()).c_str()); 218 auto indexStr = std::to_string(j); 219 jsonColor->Put(indexStr.c_str(), jsonColorObject); 220 } 221 jsonObject->Put("0", jsonColor); 222 jsonObject->Put("1", propValues_.value()[i]); 223 auto index = std::to_string(i); 224 jsonGradientColors->Put(index.c_str(), jsonObject); 225 } 226 } 227 json->PutExtAttr("colors", jsonGradientColors->ToString().c_str(), filter); 228 } 229 ToJsonIndicator(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter)230 void ToJsonIndicator(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const 231 { 232 /* no fixed attr below, just return */ 233 if (filter.IsFastFilter()) { 234 return; 235 } 236 if (!propIsShowIndicator_.value_or(true)) { 237 json->PutExtAttr("indicator", "null", filter); 238 return; 239 } 240 auto indicatorJsonValue = JsonUtil::Create(true); 241 if (propIndicatorIconSourceInfo_.has_value()) { 242 indicatorJsonValue->Put("icon", propIndicatorIconSourceInfo_.value().GetSrc().c_str()); 243 } else { 244 indicatorJsonValue->Put("icon", "SystemStyle"); 245 } 246 247 if (propIndicatorSpace_.has_value()) { 248 indicatorJsonValue->Put("space", propIndicatorSpace_.value().ToString().c_str()); 249 } else { 250 indicatorJsonValue->Put("space", INDICATOR_DISTANCE_TO_TOP.ToString().c_str()); 251 } 252 json->PutExtAttr("indicator", indicatorJsonValue, filter); 253 } 254 ToJsonTrackShadow(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter)255 void ToJsonTrackShadow(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const 256 { 257 /* no fixed attr below, just return */ 258 if (filter.IsFastFilter()) { 259 return; 260 } 261 GaugeShadowOptions trackShadow; 262 if (propShadowOptions_.has_value()) { 263 trackShadow.radius = propShadowOptions_.value().radius; 264 trackShadow.offsetX = propShadowOptions_.value().offsetX; 265 trackShadow.offsetY = propShadowOptions_.value().offsetY; 266 trackShadow.isShadowVisible = propShadowOptions_.value().isShadowVisible; 267 } else { 268 trackShadow.radius = DEFAULT_GAUGE_SHADOW_RADIUS; 269 trackShadow.offsetX = DEFAULT_GAUGE_SHADOW_OFFSETX; 270 trackShadow.offsetY = DEFAULT_GAUGE_SHADOW_OFFSETY; 271 } 272 273 if (!trackShadow.isShadowVisible) { 274 json->PutExtAttr("trackShadow", "null", filter); 275 return; 276 } 277 278 auto shadowOptionJson = JsonUtil::Create(true); 279 shadowOptionJson->Put("radius", std::to_string(trackShadow.radius).c_str()); 280 shadowOptionJson->Put("offsetX", std::to_string(trackShadow.offsetX).c_str()); 281 shadowOptionJson->Put("offsetY", std::to_string(trackShadow.offsetY).c_str()); 282 283 json->PutExtAttr("trackShadow", shadowOptionJson, filter); 284 } 285 286 ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(Value, float, PROPERTY_UPDATE_RENDER); 287 ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(Min, float, PROPERTY_UPDATE_RENDER); 288 ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(Max, float, PROPERTY_UPDATE_RENDER); 289 ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(StartAngle, float, PROPERTY_UPDATE_RENDER); 290 ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(EndAngle, float, PROPERTY_UPDATE_RENDER); 291 ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(GaugeType, GaugeType, PROPERTY_UPDATE_RENDER); 292 ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(Colors, std::vector<Color>, PROPERTY_UPDATE_RENDER); 293 ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(GradientColors, std::vector<ColorStopArray>, PROPERTY_UPDATE_RENDER); 294 ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(Values, std::vector<float>, PROPERTY_UPDATE_RENDER); 295 ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(StrokeWidth, Dimension, PROPERTY_UPDATE_RENDER); 296 ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(ShadowOptions, GaugeShadowOptions, PROPERTY_UPDATE_RENDER); 297 ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(IsShowIndicator, bool, PROPERTY_UPDATE_RENDER); 298 ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(IndicatorIconSourceInfo, ImageSourceInfo, PROPERTY_UPDATE_RENDER); 299 ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(IndicatorSpace, Dimension, PROPERTY_UPDATE_RENDER); 300 ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(IndicatorChange, bool, PROPERTY_UPDATE_RENDER); 301 ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(IsSensitive, bool, PROPERTY_UPDATE_RENDER); 302 ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(UseJsLinearGradient, bool, PROPERTY_UPDATE_RENDER); 303 ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(UseSpecialDefaultIndicator, bool, PROPERTY_UPDATE_RENDER); 304 ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(GradientColorsInit, std::vector<ColorStopArray>, PROPERTY_UPDATE_RENDER); 305 ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(ColorModeInit, int, PROPERTY_UPDATE_RENDER); 306 ACE_DISALLOW_COPY_AND_MOVE(GaugePaintProperty); 307 }; 308 309 } // namespace OHOS::Ace::NG 310 311 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_GAUGE_GAUGE_PAINT_PROPERTY_H 312