1 /* 2 * Copyright (c) 2021-2022 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_BASE_PROPERTIES_EDGE_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_BASE_PROPERTIES_EDGE_H 18 19 #include "base/geometry/animatable_dimension.h" 20 #include "base/geometry/calc_dimension.h" 21 #include "base/geometry/dimension.h" 22 #include "base/geometry/offset.h" 23 #include "base/geometry/size.h" 24 #include "base/utils/macros.h" 25 #include "base/utils/utils.h" 26 #include "core/pipeline/base/constants.h" 27 28 namespace OHOS::Ace { 29 30 // Types of padding and margin. Contains four directions: left, top, right and bottom. 31 class ACE_EXPORT Edge { 32 public: 33 Edge() = default; Edge(double value)34 explicit Edge(double value) : Edge(value, value, value, value) {} Edge(const Dimension & value)35 explicit Edge(const Dimension& value) : Edge(value, value, value, value) {} Edge(const std::string & value)36 explicit Edge(const std::string& value) : Edge(value, value, value, value) {} Edge(const CalcDimension & value)37 explicit Edge(const CalcDimension& value) : Edge(value, value, value, value) {} 38 Edge(double left, double top, double right, double bottom, DimensionUnit unit = DimensionUnit::PX) 39 : left_(Dimension(left, unit)), top_(Dimension(top, unit)), right_(Dimension(right, unit)), 40 bottom_(Dimension(bottom, unit)) {} 41 Edge(const std::string& left, const std::string& top, const std::string& right, const std::string& bottom, 42 DimensionUnit unit = DimensionUnit::CALC) : left_(CalcDimension(left, unit)), top_(CalcDimension(top, unit)), 43 right_(CalcDimension(right, unit)), bottom_(CalcDimension(bottom, unit)) {} Edge(const CalcDimension & left,const CalcDimension & top,const CalcDimension & right,const CalcDimension & bottom)44 Edge(const CalcDimension& left, const CalcDimension& top, const CalcDimension& right, const CalcDimension& bottom) 45 : left_(left), top_(top), right_(right), bottom_(bottom) {} Edge(const Dimension & left,const Dimension & top,const Dimension & right,const Dimension & bottom,const AnimationOption & option)46 Edge(const Dimension& left, const Dimension& top, const Dimension& right, const Dimension& bottom, 47 const AnimationOption& option) 48 : left_(AnimatableDimension(left, option)), top_(AnimatableDimension(top, option)), 49 right_(AnimatableDimension(right, option)), bottom_(AnimatableDimension(bottom, option)) {} Edge(const CalcDimension & left,const CalcDimension & top,const CalcDimension & right,const CalcDimension & bottom,const AnimationOption & option)50 Edge(const CalcDimension& left, const CalcDimension& top, const CalcDimension& right, const CalcDimension& bottom, 51 const AnimationOption& option) 52 : left_(AnimatableDimension(left, option)), top_(AnimatableDimension(top, option)), 53 right_(AnimatableDimension(right, option)), bottom_(AnimatableDimension(bottom, option)) {} 54 55 virtual ~Edge() = default; 56 57 static const Edge NONE; 58 59 // Parse string to edge, support four formats(value separated by one space): 60 // 1. 1px, edge has same value. 61 // 2. 1px 2px, top and bottom are 1px, left and right are 2px. 62 // 3. 1px 2px 3px, top is 1px, left and right are 2px, bottom is 3px. 63 // 4. 1px 2px 3px 4px, top is 1px, right is 2px, bottom is 3px and left is 4px. 64 static bool FromString(const std::string& value, Edge& edge); 65 66 bool IsValid() const; 67 bool IsEffective() const; 68 Size GetLayoutSizeInPx(double dipScale) const; 69 Offset GetOffsetInPx(double dipScale) const; 70 double HorizontalInPx(double dipScale) const; 71 double VerticalInPx(double dipScale) const; 72 Left()73 const AnimatableDimension& Left() const 74 { 75 return left_; 76 } 77 SetLeft(const AnimatableDimension & left)78 virtual void SetLeft(const AnimatableDimension& left) 79 { 80 left_ = left; 81 } 82 SetLeft(const CalcDimension & left)83 virtual void SetLeft(const CalcDimension& left) 84 { 85 left_ = AnimatableDimension(left); 86 } 87 88 SetLeft(const Dimension & left)89 virtual void SetLeft(const Dimension& left) 90 { 91 left_ = AnimatableDimension(left); 92 } 93 Top()94 const AnimatableDimension& Top() const 95 { 96 return top_; 97 } 98 SetTop(const AnimatableDimension & top)99 virtual void SetTop(const AnimatableDimension& top) 100 { 101 top_ = top; 102 } 103 SetTop(const CalcDimension & top)104 virtual void SetTop(const CalcDimension& top) 105 { 106 top_ = AnimatableDimension(top); 107 } 108 109 SetTop(const Dimension & top)110 virtual void SetTop(const Dimension& top) 111 { 112 top_ = AnimatableDimension(top); 113 } 114 Right()115 const AnimatableDimension& Right() const 116 { 117 return right_; 118 } 119 SetRight(const AnimatableDimension & right)120 virtual void SetRight(const AnimatableDimension& right) 121 { 122 right_ = right; 123 } 124 SetRight(const CalcDimension & right)125 virtual void SetRight(const CalcDimension& right) 126 { 127 right_ = AnimatableDimension(right); 128 } 129 SetRight(const Dimension & right)130 virtual void SetRight(const Dimension& right) 131 { 132 right_ = AnimatableDimension(right); 133 } 134 Bottom()135 const AnimatableDimension& Bottom() const 136 { 137 return bottom_; 138 } 139 SetBottom(const AnimatableDimension & bottom)140 virtual void SetBottom(const AnimatableDimension& bottom) 141 { 142 bottom_ = bottom; 143 } 144 SetBottom(const CalcDimension & bottom)145 virtual void SetBottom(const CalcDimension& bottom) 146 { 147 bottom_ = AnimatableDimension(bottom); 148 } 149 SetBottom(const Dimension & bottom)150 virtual void SetBottom(const Dimension& bottom) 151 { 152 bottom_ = AnimatableDimension(bottom); 153 } 154 155 Edge operator+(const Edge& edge) const 156 { 157 return Edge(left_ + edge.left_, top_ + edge.top_, right_ + edge.right_, bottom_ + edge.bottom_); 158 } 159 160 Edge operator-(const Edge& edge) const 161 { 162 return Edge(left_ - edge.left_, top_ - edge.top_, right_ - edge.right_, bottom_ - edge.bottom_); 163 } 164 165 Edge operator*(const double factor) const 166 { 167 return Edge(left_ * factor, top_ * factor, right_ * factor, bottom_ * factor); 168 } 169 170 Edge operator/(const double factor) const 171 { 172 if (NearZero(factor)) { 173 return NONE; 174 } 175 return Edge(left_ / factor, top_ / factor, right_ / factor, bottom_ / factor); 176 } 177 178 bool operator==(const Edge& edge) const 179 { 180 return (edge.left_ == left_) && (edge.top_ == top_) && (edge.right_ == right_) && (edge.bottom_ == bottom_); 181 } 182 SetContextAndCallback(const WeakPtr<PipelineBase> & context,const RenderNodeAnimationCallback & callback)183 void SetContextAndCallback(const WeakPtr<PipelineBase>& context, const RenderNodeAnimationCallback& callback) 184 { 185 left_.SetContextAndCallback(context, callback); 186 top_.SetContextAndCallback(context, callback); 187 right_.SetContextAndCallback(context, callback); 188 bottom_.SetContextAndCallback(context, callback); 189 } 190 191 protected: 192 AnimatableDimension left_; 193 AnimatableDimension top_; 194 AnimatableDimension right_; 195 AnimatableDimension bottom_; 196 }; 197 198 class EdgePx : public Edge { 199 public: 200 EdgePx() = default; EdgePx(double value)201 explicit EdgePx(double value) : EdgePx(value, value, value, value) {} EdgePx(const std::string & value)202 explicit EdgePx(const std::string& value) : EdgePx(value, value, value, value) {} EdgePx(double left,double top,double right,double bottom)203 EdgePx(double left, double top, double right, double bottom) : Edge(left, top, right, bottom) {} EdgePx(const std::string & left,const std::string & top,const std::string & right,const std::string & bottom)204 EdgePx(const std::string& left, const std::string& top, const std::string& right, const std::string& bottom) 205 : Edge(left, top, right, bottom) {} 206 ~EdgePx() override = default; 207 LeftPx()208 double LeftPx() const 209 { 210 return left_.Value(); 211 } 212 TopPx()213 double TopPx() const 214 { 215 return top_.Value(); 216 } 217 RightPx()218 double RightPx() const 219 { 220 return right_.Value(); 221 } 222 BottomPx()223 double BottomPx() const 224 { 225 return bottom_.Value(); 226 } 227 SetLeft(const AnimatableDimension & left)228 void SetLeft(const AnimatableDimension& left) override 229 { 230 if (left.Unit() != DimensionUnit::PX && left.Unit() != DimensionUnit::CALC) { 231 return; 232 } 233 left_ = left; 234 } 235 SetLeft(const Dimension & left)236 void SetLeft(const Dimension& left) override 237 { 238 if (left.Unit() != DimensionUnit::PX) { 239 return; 240 } 241 left_ = AnimatableDimension(left); 242 } 243 SetLeft(const CalcDimension & left)244 void SetLeft(const CalcDimension& left) override 245 { 246 if (left.Unit() != DimensionUnit::CALC) { 247 return; 248 } 249 left_ = AnimatableDimension(left); 250 } 251 SetTop(const AnimatableDimension & top)252 void SetTop(const AnimatableDimension& top) override 253 { 254 if (top.Unit() != DimensionUnit::PX && top.Unit() != DimensionUnit::CALC) { 255 return; 256 } 257 top_ = top; 258 } 259 SetTop(const Dimension & top)260 void SetTop(const Dimension& top) override 261 { 262 if (top.Unit() != DimensionUnit::PX) { 263 return; 264 } 265 top_ = AnimatableDimension(top); 266 } 267 SetTop(const CalcDimension & top)268 void SetTop(const CalcDimension& top) override 269 { 270 if (top.Unit() != DimensionUnit::CALC) { 271 return; 272 } 273 top_ = AnimatableDimension(top); 274 } 275 SetRight(const AnimatableDimension & right)276 void SetRight(const AnimatableDimension& right) override 277 { 278 if (right.Unit() != DimensionUnit::PX && right.Unit() != DimensionUnit::CALC) { 279 return; 280 } 281 right_ = right; 282 } 283 SetRight(const Dimension & right)284 void SetRight(const Dimension& right) override 285 { 286 if (right.Unit() != DimensionUnit::PX) { 287 return; 288 } 289 right_ = AnimatableDimension(right); 290 } 291 SetRight(const CalcDimension & right)292 void SetRight(const CalcDimension& right) override 293 { 294 if (right.Unit() != DimensionUnit::CALC) { 295 return; 296 } 297 right_ = AnimatableDimension(right); 298 } 299 SetBottom(const AnimatableDimension & bottom)300 void SetBottom(const AnimatableDimension& bottom) override 301 { 302 if (bottom.Unit() != DimensionUnit::PX && bottom.Unit() != DimensionUnit::CALC) { 303 return; 304 } 305 bottom_ = bottom; 306 } 307 SetBottom(const Dimension & bottom)308 void SetBottom(const Dimension& bottom) override 309 { 310 if (bottom.Unit() != DimensionUnit::PX) { 311 return; 312 } 313 bottom_ = AnimatableDimension(bottom); 314 } 315 SetBottom(const CalcDimension & bottom)316 void SetBottom(const CalcDimension& bottom) override 317 { 318 if (bottom.Unit() != DimensionUnit::CALC) { 319 return; 320 } 321 bottom_ = AnimatableDimension(bottom); 322 } 323 GetLayoutSize()324 Size GetLayoutSize() const 325 { 326 return Size(left_.Value() + right_.Value(), top_.Value() + bottom_.Value()); 327 } 328 GetOffset()329 Offset GetOffset() const 330 { 331 return Offset(left_.Value(), top_.Value()); 332 } 333 334 EdgePx operator+(const EdgePx& edge) const 335 { 336 return EdgePx(LeftPx() + edge.LeftPx(), TopPx() + edge.TopPx(), RightPx() + edge.RightPx(), 337 BottomPx() + edge.BottomPx()); 338 } 339 }; 340 341 } // namespace OHOS::Ace 342 343 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_BASE_PROPERTIES_EDGE_H 344