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/components/common/layout/constants.h" 21 #include "core/components/common/properties/color.h" 22 #include "core/components_ng/pattern/gauge/gauge_theme.h" 23 #include "core/components_ng/render/paint_property.h" 24 #include "core/image/image_source_info.h" 25 26 namespace OHOS::Ace::NG { 27 using ColorStopArray = std::vector<std::pair<Color, Dimension>>; 28 enum class GaugeType : int32_t { 29 TYPE_CIRCULAR_MULTI_SEGMENT_GRADIENT = 0, 30 TYPE_CIRCULAR_SINGLE_SEGMENT_GRADIENT = 1, 31 TYPE_CIRCULAR_MONOCHROME = 2, 32 }; 33 34 struct GaugeShadowOptions { 35 bool isShadowVisible = true; 36 float radius = DEFAULT_GAUGE_SHADOW_RADIUS; 37 float offsetX = DEFAULT_GAUGE_SHADOW_OFFSETX; 38 float offsetY = DEFAULT_GAUGE_SHADOW_OFFSETY; 39 bool operator==(const GaugeShadowOptions& rhs) const 40 { 41 return radius == rhs.radius && offsetX == rhs.offsetX && offsetY == rhs.offsetY && 42 isShadowVisible == rhs.isShadowVisible; 43 } 44 }; 45 class GaugePaintProperty : public PaintProperty { 46 DECLARE_ACE_TYPE(GaugePaintProperty, PaintProperty) 47 48 public: 49 GaugePaintProperty() = default; 50 ~GaugePaintProperty() override = default; 51 Clone()52 RefPtr<PaintProperty> Clone() const override 53 { 54 auto paintProperty = MakeRefPtr<GaugePaintProperty>(); 55 paintProperty->UpdatePaintProperty(this); 56 paintProperty->propValue_ = CloneValue(); 57 paintProperty->propMin_ = CloneMin(); 58 paintProperty->propMax_ = CloneMax(); 59 paintProperty->propStartAngle_ = CloneStartAngle(); 60 paintProperty->propEndAngle_ = CloneEndAngle(); 61 paintProperty->propColors_ = CloneColors(); 62 paintProperty->propGradientColors_ = CloneGradientColors(); 63 paintProperty->propValues_ = CloneValues(); 64 paintProperty->propStrokeWidth_ = CloneStrokeWidth(); 65 paintProperty->propGaugeType_ = CloneGaugeType(); 66 paintProperty->propShadowOptions_ = CloneShadowOptions(); 67 paintProperty->propIsShowIndicator_ = CloneIsShowIndicator(); 68 paintProperty->propIndicatorIconSourceInfo_ = CloneIndicatorIconSourceInfo(); 69 paintProperty->propIndicatorSpace_ = CloneIndicatorSpace(); 70 return paintProperty; 71 } 72 Reset()73 void Reset() override 74 { 75 PaintProperty::Reset(); 76 ResetValue(); 77 ResetMin(); 78 ResetMax(); 79 ResetStartAngle(); 80 ResetEndAngle(); 81 ResetColors(); 82 ResetGradientColors(); 83 ResetValues(); 84 ResetStrokeWidth(); 85 ResetGaugeType(); 86 ResetShadowOptions(); 87 ResetIsShowIndicator(); 88 ResetIndicatorIconSourceInfo(); 89 ResetIndicatorSpace(); 90 } 91 ToJsonValue(std::unique_ptr<JsonValue> & json)92 void ToJsonValue(std::unique_ptr<JsonValue>& json) const override 93 { 94 PaintProperty::ToJsonValue(json); 95 json->Put("value", StringUtils::DoubleToString(propValue_.value_or(0)).c_str()); 96 json->Put("max", StringUtils::DoubleToString(propMax_.value_or(100)).c_str()); 97 json->Put("min", StringUtils::DoubleToString(propMin_.value_or(0)).c_str()); 98 json->Put("startAngle", StringUtils::DoubleToString(propStartAngle_.value_or(0)).c_str()); 99 json->Put("endAngle", StringUtils::DoubleToString(propEndAngle_.value_or(360)).c_str()); 100 if (propStrokeWidth_.has_value()) { 101 json->Put("strokeWidth", propStrokeWidth_.value().ToString().c_str()); 102 } else { 103 json->Put("strokeWidth", ""); 104 } 105 106 if (Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN)) { 107 auto jsonColors = JsonUtil::CreateArray(true); 108 if (propColors_.has_value() && propColors_.has_value()) { 109 for (size_t i = 0; i < propValues_.value().size(); i++) { 110 auto jsonObject = JsonUtil::CreateArray(true); 111 jsonObject->Put("0", propColors_.value()[i].ColorToString().c_str()); 112 jsonObject->Put("1", propValues_.value()[i]); 113 auto index = std::to_string(i); 114 jsonColors->Put(index.c_str(), jsonObject); 115 } 116 } 117 json->Put("colors", jsonColors->ToString().c_str()); 118 } else { 119 ToJsonColor(json); 120 ToJsonIndicator(json); 121 ToJsonTrackShadow(json); 122 } 123 } 124 ToJsonColor(std::unique_ptr<JsonValue> & json)125 void ToJsonColor(std::unique_ptr<JsonValue>& json) const 126 { 127 if (!propGaugeType_.has_value()) { 128 auto jsonColor = JsonUtil::CreateArray(true); 129 for (size_t j = 0; j < GAUGE_DEFAULT_COLOR.size(); j++) { 130 jsonColor->Put(std::to_string(j).c_str(), GAUGE_DEFAULT_COLOR[j].ColorToString().c_str()); 131 } 132 json->Put("colors", jsonColor->ToString().c_str()); 133 return; 134 } 135 136 if (propGaugeType_.value() == GaugeType::TYPE_CIRCULAR_MONOCHROME) { 137 if (propGradientColors_.has_value()) { 138 json->Put("colors", propGradientColors_.value().at(0).at(0).first.ColorToString().c_str()); 139 } 140 return; 141 } 142 143 if (propGaugeType_.value() == GaugeType::TYPE_CIRCULAR_SINGLE_SEGMENT_GRADIENT) { 144 if (propGradientColors_.has_value()) { 145 auto jsonColor = JsonUtil::CreateArray(true); 146 auto colorStopArray = propGradientColors_.value().at(0); 147 for (size_t j = 0; j < colorStopArray.size(); j++) { 148 auto jsonColorObject = JsonUtil::CreateArray(true); 149 jsonColorObject->Put("0", colorStopArray[j].first.ColorToString().c_str()); 150 jsonColorObject->Put("1", std::to_string(colorStopArray[j].second.Value()).c_str()); 151 auto indexStr = std::to_string(j); 152 jsonColor->Put(indexStr.c_str(), jsonColorObject); 153 } 154 json->Put("colors", jsonColor->ToString().c_str()); 155 } 156 return; 157 } 158 auto jsonGradientColors = JsonUtil::CreateArray(true); 159 if (propGradientColors_.has_value() && propValues_.has_value() && 160 (propGradientColors_.value().size() == propValues_.value().size())) { 161 for (size_t i = 0; i < propValues_.value().size(); i++) { 162 auto jsonObject = JsonUtil::CreateArray(true); 163 auto jsonColor = JsonUtil::CreateArray(true); 164 auto colorStopArray = propGradientColors_.value()[i]; 165 for (size_t j = 0; j < colorStopArray.size(); j++) { 166 auto jsonColorObject = JsonUtil::CreateArray(true); 167 jsonColorObject->Put("0", colorStopArray[j].first.ColorToString().c_str()); 168 jsonColorObject->Put("1", std::to_string(colorStopArray[j].second.Value()).c_str()); 169 auto indexStr = std::to_string(j); 170 jsonColor->Put(indexStr.c_str(), jsonColorObject); 171 } 172 jsonObject->Put("0", jsonColor); 173 jsonObject->Put("1", propValues_.value()[i]); 174 auto index = std::to_string(i); 175 jsonGradientColors->Put(index.c_str(), jsonObject); 176 } 177 } 178 json->Put("colors", jsonGradientColors->ToString().c_str()); 179 } 180 ToJsonIndicator(std::unique_ptr<JsonValue> & json)181 void ToJsonIndicator(std::unique_ptr<JsonValue>& json) const 182 { 183 if (!propIsShowIndicator_.value_or(true)) { 184 json->Put("indicator", "null"); 185 return; 186 } 187 auto indicatorJsonValue = JsonUtil::Create(true); 188 if (propIndicatorIconSourceInfo_.has_value()) { 189 indicatorJsonValue->Put("icon", propIndicatorIconSourceInfo_.value().GetSrc().c_str()); 190 } else { 191 indicatorJsonValue->Put("icon", "SystemStyle"); 192 } 193 194 if (propIndicatorSpace_.has_value()) { 195 indicatorJsonValue->Put("space", propIndicatorSpace_.value().ToString().c_str()); 196 } else { 197 indicatorJsonValue->Put("space", INDICATOR_DISTANCE_TO_TOP.ToString().c_str()); 198 } 199 json->Put("indicator", indicatorJsonValue); 200 } 201 ToJsonTrackShadow(std::unique_ptr<JsonValue> & json)202 void ToJsonTrackShadow(std::unique_ptr<JsonValue>& json) const 203 { 204 GaugeShadowOptions trackShadow; 205 if (propShadowOptions_.has_value()) { 206 trackShadow.radius = propShadowOptions_.value().radius; 207 trackShadow.offsetX = propShadowOptions_.value().offsetX; 208 trackShadow.offsetY = propShadowOptions_.value().offsetY; 209 trackShadow.isShadowVisible = propShadowOptions_.value().isShadowVisible; 210 } else { 211 trackShadow.radius = DEFAULT_GAUGE_SHADOW_RADIUS; 212 trackShadow.offsetX = DEFAULT_GAUGE_SHADOW_OFFSETX; 213 trackShadow.offsetY = DEFAULT_GAUGE_SHADOW_OFFSETY; 214 } 215 216 if (!trackShadow.isShadowVisible) { 217 json->Put("trackShadow", "null"); 218 return; 219 } 220 221 auto shadowOptionJson = JsonUtil::Create(true); 222 shadowOptionJson->Put("radius", std::to_string(trackShadow.radius).c_str()); 223 shadowOptionJson->Put("offsetX", std::to_string(trackShadow.offsetX).c_str()); 224 shadowOptionJson->Put("offsetY", std::to_string(trackShadow.offsetY).c_str()); 225 226 json->Put("trackShadow", shadowOptionJson); 227 } 228 229 ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(Value, float, PROPERTY_UPDATE_RENDER); 230 ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(Min, float, PROPERTY_UPDATE_RENDER); 231 ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(Max, float, PROPERTY_UPDATE_RENDER); 232 ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(StartAngle, float, PROPERTY_UPDATE_RENDER); 233 ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(EndAngle, float, PROPERTY_UPDATE_RENDER); 234 ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(GaugeType, GaugeType, PROPERTY_UPDATE_RENDER); 235 ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(Colors, std::vector<Color>, PROPERTY_UPDATE_RENDER); 236 ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(GradientColors, std::vector<ColorStopArray>, PROPERTY_UPDATE_RENDER); 237 ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(Values, std::vector<float>, PROPERTY_UPDATE_RENDER); 238 ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(StrokeWidth, Dimension, PROPERTY_UPDATE_RENDER); 239 ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(ShadowOptions, GaugeShadowOptions, PROPERTY_UPDATE_RENDER); 240 ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(IsShowIndicator, bool, PROPERTY_UPDATE_RENDER); 241 ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(IndicatorIconSourceInfo, ImageSourceInfo, PROPERTY_UPDATE_RENDER); 242 ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(IndicatorSpace, Dimension, PROPERTY_UPDATE_RENDER); 243 ACE_DISALLOW_COPY_AND_MOVE(GaugePaintProperty); 244 }; 245 246 } // namespace OHOS::Ace::NG 247 248 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_GAUGE_GAUGE_PAINT_PROPERTY_H