1 /* 2 * Copyright (c) 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_NG_BASE_GEOMETRY_NODE_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_BASE_GEOMETRY_NODE_H 18 19 #include <list> 20 #include <memory> 21 22 #include "base/geometry/ng/offset_t.h" 23 #include "base/geometry/ng/rect_t.h" 24 #include "base/geometry/ng/size_t.h" 25 #include "base/memory/ace_type.h" 26 #include "base/memory/referenced.h" 27 #include "base/utils/macros.h" 28 #include "base/utils/utils.h" 29 #include "core/components_ng/layout/box_layout_algorithm.h" 30 #include "core/components_ng/property/geometry_property.h" 31 #include "core/components_ng/property/layout_constraint.h" 32 #include "core/components_ng/property/magic_layout_property.h" 33 #include "core/components_ng/property/measure_property.h" 34 #include "core/components_ng/property/measure_utils.h" 35 #include "core/components_ng/property/position_property.h" 36 37 namespace OHOS::Ace::NG { 38 // GeometryNode acts as a physical property of the size and position of the component 39 class ACE_EXPORT GeometryNode : public AceType { 40 DECLARE_ACE_TYPE(GeometryNode, AceType) 41 public: 42 GeometryNode() = default; 43 ~GeometryNode() override = default; 44 45 void Reset(); 46 CheckUnchanged(const GeometryNode & geometryNode)47 bool CheckUnchanged(const GeometryNode& geometryNode) 48 { 49 return (frame_ == geometryNode.frame_) && (margin_ == geometryNode.margin_) && 50 (content_ == geometryNode.content_) && (parentGlobalOffset_ == geometryNode.parentGlobalOffset_) && 51 (parentLayoutConstraint_ == geometryNode.parentLayoutConstraint_); 52 } 53 54 RefPtr<GeometryNode> Clone() const; 55 GetMarginFrameSize()56 SizeF GetMarginFrameSize() const 57 { 58 // TODO: add margin in negative. 59 auto size = frame_.rect_.GetSize(); 60 if (margin_) { 61 AddPaddingToSize(*margin_, size); 62 } 63 return size; 64 } 65 GetMarginFrameOffset()66 OffsetF GetMarginFrameOffset() const 67 { 68 // TODO: add margin in negative. 69 auto offset = frame_.rect_.GetOffset(); 70 if (margin_) { 71 offset -= OffsetF(margin_->left.value_or(0), margin_->top.value_or(0)); 72 } 73 return offset; 74 } 75 SetMarginFrameOffset(const OffsetF & translate)76 void SetMarginFrameOffset(const OffsetF& translate) 77 { 78 OffsetF offset; 79 if (margin_) { 80 offset += OffsetF(margin_->left.value_or(0), margin_->top.value_or(0)); 81 } 82 frame_.rect_.SetOffset(translate + offset); 83 } 84 GetFrameRect()85 const RectF& GetFrameRect() const 86 { 87 return frame_.rect_; 88 } 89 GetFrameSize()90 SizeF GetFrameSize() const 91 { 92 return frame_.rect_.GetSize(); 93 } 94 GetFrameOffset()95 OffsetF GetFrameOffset() const 96 { 97 return frame_.rect_.GetOffset(); 98 } 99 SetFrameOffset(const OffsetF & offset)100 void SetFrameOffset(const OffsetF& offset) 101 { 102 frame_.rect_.SetOffset(offset); 103 } 104 SetFrameSize(const SizeF & size)105 void SetFrameSize(const SizeF& size) 106 { 107 frame_.rect_.SetSize(size); 108 } 109 GetPaddingSize()110 SizeF GetPaddingSize() const 111 { 112 auto size = frame_.rect_.GetSize(); 113 if (padding_) { 114 MinusPaddingToSize(*padding_, size); 115 } 116 return size; 117 } 118 GetPaddingOffset()119 OffsetF GetPaddingOffset() const 120 { 121 auto offset = frame_.rect_.GetOffset(); 122 if (padding_) { 123 offset += OffsetF(padding_->left.value_or(0), padding_->top.value_or(0)); 124 } 125 return offset; 126 } 127 GetPaddingRect()128 RectF GetPaddingRect() const 129 { 130 auto rect = frame_.rect_; 131 if (padding_) { 132 auto size = rect.GetSize(); 133 MinusPaddingToSize(*padding_, size); 134 rect.SetSize(size); 135 auto offset = rect.GetOffset(); 136 offset += OffsetF(padding_->left.value_or(0), padding_->top.value_or(0)); 137 rect.SetOffset(offset); 138 } 139 return rect; 140 } 141 SetContentSize(const SizeF & size)142 void SetContentSize(const SizeF& size) 143 { 144 if (!content_) { 145 content_ = std::make_unique<GeometryProperty>(); 146 } 147 content_->rect_.SetSize(size); 148 } 149 SetContentOffset(const OffsetF & translate)150 void SetContentOffset(const OffsetF& translate) 151 { 152 if (!content_) { 153 content_ = std::make_unique<GeometryProperty>(); 154 } 155 content_->rect_.SetOffset(translate); 156 } 157 GetContentRect()158 RectF GetContentRect() const 159 { 160 return content_ ? content_->rect_ : RectF(); 161 } 162 GetContentSize()163 SizeF GetContentSize() const 164 { 165 return content_ ? content_->rect_.GetSize() : SizeF(); 166 } 167 GetContentOffset()168 OffsetF GetContentOffset() const 169 { 170 return content_ ? content_->rect_.GetOffset() : OffsetF(); 171 } 172 GetPixelRoundContentSize()173 SizeF GetPixelRoundContentSize() const 174 { 175 auto deltaSize = GetPixelGridRoundSize() - GetFrameSize(); 176 return content_ ? (content_->rect_.GetSize() + deltaSize) : SizeF(); 177 } 178 GetPixelRoundContentOffset()179 OffsetF GetPixelRoundContentOffset() const 180 { 181 return content_ ? content_->rect_.GetOffset() : OffsetF(); 182 } 183 GetContent()184 const std::unique_ptr<GeometryProperty>& GetContent() const 185 { 186 return content_; 187 } 188 GetMargin()189 const std::unique_ptr<MarginPropertyF>& GetMargin() const 190 { 191 return margin_; 192 } 193 GetPadding()194 const std::unique_ptr<PaddingPropertyF>& GetPadding() const 195 { 196 return padding_; 197 } 198 UpdateMargin(const MarginPropertyF & margin)199 void UpdateMargin(const MarginPropertyF& margin) 200 { 201 if (!margin_) { 202 margin_ = std::make_unique<MarginPropertyF>(margin); 203 return; 204 } 205 if (margin.left) { 206 margin_->left = margin.left; 207 } 208 if (margin.right) { 209 margin_->right = margin.right; 210 } 211 if (margin.top) { 212 margin_->top = margin.top; 213 } 214 if (margin.bottom) { 215 margin_->bottom = margin.bottom; 216 } 217 } 218 UpdatePaddingWithBorder(const PaddingPropertyF & padding)219 void UpdatePaddingWithBorder(const PaddingPropertyF& padding) 220 { 221 if (!padding_) { 222 padding_ = std::make_unique<PaddingPropertyF>(padding); 223 return; 224 } 225 if (padding.left) { 226 padding_->left = padding.left; 227 } 228 if (padding.right) { 229 padding_->right = padding.right; 230 } 231 if (padding.top) { 232 padding_->top = padding.top; 233 } 234 if (padding.bottom) { 235 padding_->bottom = padding.bottom; 236 } 237 } 238 GetParentGlobalOffset()239 const OffsetF& GetParentGlobalOffset() const 240 { 241 return parentGlobalOffset_; 242 } 243 SetParentGlobalOffset(const OffsetF & parentGlobalOffset)244 void SetParentGlobalOffset(const OffsetF& parentGlobalOffset) 245 { 246 parentGlobalOffset_ = parentGlobalOffset; 247 } 248 GetPixelGridRoundOffset()249 const OffsetF& GetPixelGridRoundOffset() const 250 { 251 return pixelGridRoundOffset_; 252 } 253 SetPixelGridRoundOffset(const OffsetF & pixelGridRoundOffset)254 void SetPixelGridRoundOffset(const OffsetF& pixelGridRoundOffset) 255 { 256 pixelGridRoundOffset_ = pixelGridRoundOffset; 257 } 258 GetPixelGridRoundSize()259 const SizeF& GetPixelGridRoundSize() const 260 { 261 return pixelGridRoundSize_; 262 } 263 SetPixelGridRoundSize(const SizeF & pixelGridRoundSize)264 void SetPixelGridRoundSize(const SizeF& pixelGridRoundSize) 265 { 266 pixelGridRoundSize_ = pixelGridRoundSize; 267 } 268 GetParentAbsoluteOffset()269 const OffsetF& GetParentAbsoluteOffset() const 270 { 271 return parentAbsoluteOffset_; 272 } 273 SetParentAbsoluteOffset(const OffsetF & parentAbsoluteOffset)274 void SetParentAbsoluteOffset(const OffsetF& parentAbsoluteOffset) 275 { 276 parentAbsoluteOffset_ = parentAbsoluteOffset; 277 } 278 ResetParentLayoutConstraint()279 void ResetParentLayoutConstraint() 280 { 281 parentLayoutConstraint_ = std::nullopt; 282 } 283 SetParentLayoutConstraint(const LayoutConstraintF & layoutConstraint)284 void SetParentLayoutConstraint(const LayoutConstraintF& layoutConstraint) 285 { 286 parentLayoutConstraint_ = layoutConstraint; 287 } 288 GetParentLayoutConstraint()289 const std::optional<LayoutConstraintF>& GetParentLayoutConstraint() const 290 { 291 return parentLayoutConstraint_; 292 } 293 SetBaselineDistance(float baselineDistance)294 void SetBaselineDistance(float baselineDistance) 295 { 296 baselineDistance_ = baselineDistance; 297 } 298 GetBaselineDistance()299 float GetBaselineDistance() 300 { 301 return baselineDistance_.value_or(frame_.rect_.GetY()); 302 } 303 GetPreviousState()304 const std::unique_ptr<RectF>& GetPreviousState() const 305 { 306 return previousState_; 307 } 308 void Restore(); 309 bool RestoreCache(); 310 void Save(); 311 312 void ToJsonValue(std::unique_ptr<JsonValue>& json) const; 313 314 private: 315 // the layoutConstraint of prev measure task. 316 std::optional<LayoutConstraintF> parentLayoutConstraint_; 317 318 std::optional<float> baselineDistance_; 319 320 // the frame size in parent local coordinate. 321 GeometryProperty frame_; 322 // the size of margin property. 323 std::unique_ptr<MarginPropertyF> margin_; 324 // the size of padding property. 325 std::unique_ptr<MarginPropertyF> padding_; 326 // the size of content rect in current node local coordinate. 327 std::unique_ptr<GeometryProperty> content_; 328 329 // save node's state before SafeArea expansion 330 std::unique_ptr<RectF> previousState_; 331 std::unique_ptr<RectF> restoreCache_; 332 333 OffsetF parentGlobalOffset_; 334 OffsetF parentAbsoluteOffset_; 335 OffsetF pixelGridRoundOffset_; 336 SizeF pixelGridRoundSize_; 337 }; 338 } // namespace OHOS::Ace::NG 339 340 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_BASE_GEOMETRY_NODE_H 341