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_LAYOUTS_LAYOUT_PROPERTY_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_LAYOUTS_LAYOUT_PROPERTY_H 18 19 #include <cstddef> 20 #include <memory> 21 #include <optional> 22 23 #include "base/geometry/dimension.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/noncopyable.h" 29 #include "base/utils/utils.h" 30 #include "core/components/common/layout/constants.h" 31 #include "core/components_ng/event/focus_hub.h" 32 #include "core/components_ng/property/border_property.h" 33 #include "core/components_ng/property/calc_length.h" 34 #include "core/components_ng/property/flex_property.h" 35 #include "core/components_ng/property/geometry_property.h" 36 #include "core/components_ng/property/grid_property.h" 37 #include "core/components_ng/property/layout_constraint.h" 38 #include "core/components_ng/property/magic_layout_property.h" 39 #include "core/components_ng/property/measure_property.h" 40 #include "core/components_ng/property/position_property.h" 41 #include "core/components_ng/property/property.h" 42 #include "core/components_ng/property/safe_area_insets.h" 43 #include "core/pipeline/base/element_register.h" 44 #include "core/pipeline_ng/ui_task_scheduler.h" 45 46 namespace OHOS::Ace::NG { 47 48 class FrameNode; 49 class InspectorFilter; 50 51 class ACE_FORCE_EXPORT LayoutProperty : public Property { 52 DECLARE_ACE_TYPE(LayoutProperty, Property); 53 54 public: 55 LayoutProperty() = default; 56 57 ~LayoutProperty() override = default; 58 59 virtual RefPtr<LayoutProperty> Clone() const; 60 61 virtual void Reset(); 62 63 virtual void ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const; 64 65 virtual void FromJson(const std::unique_ptr<JsonValue>& json); 66 GetLayoutConstraint()67 const std::optional<LayoutConstraintF>& GetLayoutConstraint() const 68 { 69 return layoutConstraint_; 70 } 71 GetContentLayoutConstraint()72 const std::optional<LayoutConstraintF>& GetContentLayoutConstraint() const 73 { 74 return contentConstraint_; 75 } 76 GetParentLayoutConstraint()77 const std::optional<LayoutConstraintF>& GetParentLayoutConstraint() const 78 { 79 return parentLayoutConstraint_; 80 } 81 GetMagicItemProperty()82 MagicItemProperty& GetMagicItemProperty() 83 { 84 return magicItemProperty_; 85 } 86 GetPaddingProperty()87 const std::unique_ptr<PaddingProperty>& GetPaddingProperty() const 88 { 89 return padding_; 90 } 91 GetSafeAreaPaddingProperty()92 const std::unique_ptr<PaddingProperty>& GetSafeAreaPaddingProperty() const 93 { 94 return safeAreaPadding_; 95 } 96 GetMarginProperty()97 const std::unique_ptr<MarginProperty>& GetMarginProperty() const 98 { 99 return margin_; 100 } 101 GetBorderWidthProperty()102 const std::unique_ptr<BorderWidthProperty>& GetBorderWidthProperty() const 103 { 104 return borderWidth_; 105 } 106 GetOuterBorderWidthProperty()107 const std::unique_ptr<BorderWidthProperty>& GetOuterBorderWidthProperty() const 108 { 109 return outerBorderWidth_; 110 } 111 GetPositionProperty()112 const std::unique_ptr<PositionProperty>& GetPositionProperty() const 113 { 114 return positionProperty_; 115 } 116 GetCalcLayoutConstraint()117 const std::unique_ptr<MeasureProperty>& GetCalcLayoutConstraint() const 118 { 119 return calcLayoutConstraint_; 120 } 121 GetFlexItemProperty()122 const std::unique_ptr<FlexItemProperty>& GetFlexItemProperty() const 123 { 124 return flexItemProperty_; 125 } 126 GetLayoutDirection()127 TextDirection GetLayoutDirection() const 128 { 129 return layoutDirection_.value_or(TextDirection::AUTO); 130 } 131 132 TextDirection GetNonAutoLayoutDirection() const; 133 GetGeometryTransition()134 RefPtr<GeometryTransition> GetGeometryTransition() const 135 { 136 return geometryTransition_.Upgrade(); 137 } 138 139 MeasureType GetMeasureType(MeasureType defaultType = MeasureType::MATCH_CONTENT) const 140 { 141 return measureType_.value_or(defaultType); 142 } 143 144 void LocalizedPaddingOrMarginChange(const PaddingProperty& value, std::unique_ptr<PaddingProperty>& padding); 145 146 void UpdatePadding(const PaddingProperty& value); 147 void UpdateSafeAreaPadding(const PaddingProperty& value); 148 void ResetSafeAreaPadding(); 149 150 void UpdateMargin(const MarginProperty& value); 151 152 void UpdateBorderWidth(const BorderWidthProperty& value); 153 154 void UpdateOuterBorderWidth(const BorderWidthProperty& value); 155 156 void UpdateAlignment(Alignment value); 157 158 void UpdateLayoutWeight(float value); 159 160 void UpdateChainWeight(const LayoutWeightPair& value); 161 UpdatePixelRound(uint16_t value)162 void UpdatePixelRound(uint16_t value) 163 { 164 pixelRoundFlag_ = value; 165 } 166 GetPixelRound()167 uint16_t GetPixelRound() const { 168 return pixelRoundFlag_; 169 } 170 171 void UpdateLayoutDirection(TextDirection value); 172 173 void UpdateGeometryTransition(const std::string& id, 174 bool followWithoutTransition = false, bool doRegisterSharedTransition = true); 175 176 void ResetGeometryTransition(); 177 178 void UpdateAspectRatio(float ratio); 179 void ResetAspectRatio(); 180 181 bool HasAspectRatio() const; 182 float GetAspectRatio() const; 183 184 bool HasFixedWidth(bool checkPercent = true) const; 185 bool HasFixedHeight(bool checkPercent = true) const; 186 UpdateMeasureType(MeasureType measureType)187 void UpdateMeasureType(MeasureType measureType) 188 { 189 if (measureType_ == measureType) { 190 return; 191 } 192 propertyChangeFlag_ = propertyChangeFlag_ | PROPERTY_UPDATE_MEASURE; 193 measureType_ = measureType; 194 } 195 196 // user defined max, min, self size. 197 void UpdateCalcLayoutProperty(const MeasureProperty& constraint); 198 199 void UpdateUserDefinedIdealSize(const CalcSize& value); 200 201 void ClearUserDefinedIdealSize(bool clearWidth, bool clearHeight); 202 203 virtual void UpdateCalcMinSize(const CalcSize& value); 204 205 virtual void UpdateCalcMaxSize(const CalcSize& value); 206 207 void UpdateLayoutConstraint(const LayoutConstraintF& parentConstraint); 208 UpdateParentLayoutConstraint(const LayoutConstraintF & parentConstraint)209 void UpdateParentLayoutConstraint(const LayoutConstraintF& parentConstraint) 210 { 211 parentLayoutConstraint_ = parentConstraint; 212 } 213 214 void UpdateMarginSelfIdealSize(const SizeF& value); 215 216 void ResetCalcMinSize(); 217 218 void ResetCalcMaxSize(); 219 220 void ResetCalcMinSize(bool resetWidth); 221 222 void ResetCalcMaxSize(bool resetWidth); 223 224 void UpdateFlexGrow(float flexGrow); 225 226 void ResetFlexGrow(); 227 228 void UpdateFlexShrink(float flexShrink); 229 230 void ResetFlexShrink(); 231 232 void UpdateFlexBasis(const Dimension& flexBasis); 233 234 void UpdateAlignSelf(const FlexAlign& flexAlign); 235 236 void ResetAlignSelf(); 237 238 void UpdateAlignRules(const std::map<AlignDirection, AlignRule>& alignRules); 239 240 void UpdateChainStyle(const ChainInfo& chainInfo); 241 242 void UpdateBias(const BiasPair& biasPair); 243 244 void UpdateDisplayIndex(int32_t displayIndex); 245 246 void UpdateGridProperty( 247 std::optional<int32_t> span, std::optional<int32_t> offset, GridSizeType type = GridSizeType::UNDEFINED); 248 249 bool UpdateGridOffset(const RefPtr<FrameNode>& host); 250 SetLayoutRect(const NG::RectF & rect)251 void SetLayoutRect(const NG::RectF& rect) 252 { 253 if (layoutRect_ != rect) { 254 propertyChangeFlag_ |= PROPERTY_UPDATE_MEASURE_SELF; 255 layoutRect_ = rect; 256 } 257 } 258 ResetLayoutRect()259 void ResetLayoutRect() 260 { 261 if (layoutRect_) { 262 propertyChangeFlag_ |= PROPERTY_UPDATE_MEASURE_SELF; 263 layoutRect_.reset(); 264 } 265 } 266 GetLayoutRect()267 std::optional<NG::RectF> GetLayoutRect() const 268 { 269 return layoutRect_; 270 } 271 272 void BuildGridProperty(const RefPtr<FrameNode>& host); 273 274 void UpdateContentConstraint(); 275 void UpdateLayoutConstraintWithLayoutRect(); 276 277 LayoutConstraintF CreateChildConstraint() const; 278 279 LayoutConstraintF CreateContentConstraint() const; 280 281 PaddingPropertyF CreatePaddingWithoutBorder(bool useRootConstraint = true, bool roundPixel = true); 282 PaddingPropertyF CreatePaddingAndBorder(bool includeSafeAreaPadding = true, bool forceReCreate = false); 283 PaddingPropertyF CreatePaddingAndBorderWithDefault(float paddingHorizontalDefault, float paddingVerticalDefault, 284 float borderHorizontalDefault, float borderVerticalDefault); 285 BorderWidthPropertyF CreateBorder(); 286 287 MarginPropertyF CreateMargin(); 288 MarginPropertyF CreateMarginWithoutCache(); 289 290 void SetHost(const WeakPtr<FrameNode>& host); 291 RefPtr<FrameNode> GetHost() const; 292 ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(IsBindOverlay, bool, PROPERTY_UPDATE_MEASURE); 293 ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP_GET(Visibility, VisibleType); 294 295 public: 296 void UpdateVisibility(const VisibleType& value, bool allowTransition = false); 297 void OnVisibilityUpdate(VisibleType visible, bool allowTransition = false); 298 299 void UpdateLayoutConstraint(const RefPtr<LayoutProperty>& layoutProperty); 300 GetSafeAreaInsets()301 const std::unique_ptr<SafeAreaInsets>& GetSafeAreaInsets() const 302 { 303 return safeAreaInsets_; 304 } 305 306 void UpdateSafeAreaInsets(const SafeAreaInsets& safeArea); 307 GetSafeAreaExpandOpts()308 const std::unique_ptr<SafeAreaExpandOpts>& GetSafeAreaExpandOpts() const 309 { 310 return safeAreaExpandOpts_; 311 } 312 313 void UpdateSafeAreaExpandOpts(const SafeAreaExpandOpts& opts); 314 IsUsingPosition()315 bool IsUsingPosition() const 316 { 317 return usingPosition_; 318 } 319 SetUsingPosition(bool usingPosition)320 void SetUsingPosition(bool usingPosition) 321 { 322 usingPosition_ = usingPosition; 323 } 324 SetIsOverlayNode(bool isOverlayNode)325 void SetIsOverlayNode(bool isOverlayNode) 326 { 327 isOverlayNode_ = isOverlayNode; 328 } 329 IsOverlayNode()330 bool IsOverlayNode() const 331 { 332 return isOverlayNode_; 333 } 334 335 void SetOverlayOffset( 336 const std::optional<Dimension>& overlayOffsetX, const std::optional<Dimension>& overlayOffsetY); 337 338 void GetOverlayOffset(Dimension& overlayOffsetX, Dimension& overlayOffsetY); 339 340 static void UpdateAllGeometryTransition(const RefPtr<UINode>& parent); 341 342 // the returned value represents whether to compare percent reference when comparing old and new layout constrains. 343 // the first of returned value represents width, and the second of returned value represents height. 344 virtual std::pair<bool, bool> GetPercentSensitive(); 345 std::pair<bool, bool> UpdatePercentSensitive(bool width, bool height); 346 bool ConstraintEqual(const std::optional<LayoutConstraintF>& preLayoutConstraint, 347 const std::optional<LayoutConstraintF>& preContentConstraint); 348 349 PaddingPropertyF GetOrCreateSafeAreaPadding(bool forceReCreate = false); 350 UpdateNeedPositionLocalizedEdges(bool needPositionLocalizedEdges)351 void UpdateNeedPositionLocalizedEdges(bool needPositionLocalizedEdges) 352 { 353 needPositionLocalizedEdges_ = needPositionLocalizedEdges; 354 } 355 IsPositionLocalizedEdges()356 bool IsPositionLocalizedEdges() const 357 { 358 return needPositionLocalizedEdges_; 359 } 360 UpdatNeedMarkAnchorPosition(bool needMarkAnchorPosition)361 void UpdatNeedMarkAnchorPosition(bool needMarkAnchorPosition) 362 { 363 needMarkAnchorPosition_ = needMarkAnchorPosition; 364 } 365 IsMarkAnchorPosition()366 bool IsMarkAnchorPosition() const 367 { 368 return needMarkAnchorPosition_; 369 } 370 UpdateNeedOffsetLocalizedEdges(bool needOffsetLocalizedEdges)371 void UpdateNeedOffsetLocalizedEdges(bool needOffsetLocalizedEdges) 372 { 373 needOffsetLocalizedEdges_ = needOffsetLocalizedEdges; 374 } 375 IsOffsetLocalizedEdges()376 bool IsOffsetLocalizedEdges() const 377 { 378 return needOffsetLocalizedEdges_; 379 } 380 381 void CheckPositionLocalizedEdges(TextDirection layoutDirection); 382 void CheckMarkAnchorPosition(TextDirection layoutDirection); 383 void CheckOffsetLocalizedEdges(TextDirection layoutDirection); 384 void CheckLocalizedBorderRadiuses(const TextDirection& direction); 385 void CheckLocalizedOuterBorderColor(const TextDirection& direction); 386 void CheckLocalizedPadding(const RefPtr<LayoutProperty>& layoutProperty, const TextDirection& direction); 387 void CheckLocalizedMargin(const RefPtr<LayoutProperty>& layoutProperty, const TextDirection& direction); 388 void CheckLocalizedEdgeWidths(const RefPtr<LayoutProperty>& layoutProperty, const TextDirection& direction); 389 void CheckLocalizedEdgeColors(const TextDirection& direction); 390 void CheckLocalizedBorderImageSlice(const TextDirection& direction); 391 void CheckLocalizedBorderImageWidth(const TextDirection& direction); 392 void CheckLocalizedBorderImageOutset(const TextDirection& direction); 393 void CheckLocalizedSafeAreaPadding(const TextDirection& direction); 394 395 protected: 396 void UpdateLayoutProperty(const LayoutProperty* layoutProperty); 397 398 virtual void Clone(RefPtr<LayoutProperty> layoutProperty) const; 399 400 private: 401 // This will call after ModifyLayoutConstraint. 402 void CheckSelfIdealSize(const LayoutConstraintF& parentConstraint, const SizeF& originMax); 403 404 void CheckAspectRatio(); 405 void CheckBorderAndPadding(); 406 void ConstraintContentByPadding(); 407 void ConstraintContentByBorder(); 408 void ConstraintContentBySafeAreaPadding(); 409 PaddingPropertyF CreateSafeAreaPadding(); 410 bool DecideMirror(); 411 412 const std::string PixelRoundToJsonValue() const; 413 414 void PaddingToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const; 415 void MarginToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const; 416 417 // available in measure process. 418 std::optional<LayoutConstraintF> layoutConstraint_; 419 std::optional<LayoutConstraintF> contentConstraint_; 420 421 // layoutConstraint_ set by builderNode 422 std::optional<LayoutConstraintF> parentLayoutConstraint_; 423 424 std::unique_ptr<MeasureProperty> calcLayoutConstraint_; 425 std::unique_ptr<PaddingProperty> safeAreaPadding_; 426 std::unique_ptr<PaddingProperty> padding_; 427 std::unique_ptr<MarginProperty> margin_; 428 std::optional<MarginPropertyF> marginResult_; 429 430 std::unique_ptr<SafeAreaExpandOpts> safeAreaExpandOpts_; 431 std::unique_ptr<SafeAreaInsets> safeAreaInsets_; 432 433 std::unique_ptr<BorderWidthProperty> borderWidth_; 434 std::unique_ptr<BorderWidthProperty> outerBorderWidth_; 435 MagicItemProperty magicItemProperty_; 436 std::unique_ptr<PositionProperty> positionProperty_; 437 std::unique_ptr<FlexItemProperty> flexItemProperty_; 438 std::unique_ptr<GridProperty> gridProperty_; 439 std::optional<MeasureType> measureType_; 440 std::optional<TextDirection> layoutDirection_; 441 std::optional<RectF> layoutRect_; 442 443 WeakPtr<GeometryTransition> geometryTransition_; 444 445 WeakPtr<FrameNode> host_; 446 447 bool usingPosition_ = true; 448 449 uint16_t pixelRoundFlag_ = 0; 450 451 bool isOverlayNode_ = false; 452 Dimension overlayOffsetX_; 453 Dimension overlayOffsetY_; 454 455 bool heightPercentSensitive_ = false; 456 bool widthPercentSensitive_ = false; 457 bool needPositionLocalizedEdges_ = false; 458 bool needMarkAnchorPosition_ = false; 459 bool needOffsetLocalizedEdges_ = false; 460 461 ACE_DISALLOW_COPY_AND_MOVE(LayoutProperty); 462 }; 463 } // namespace OHOS::Ace::NG 464 465 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_LAYOUTS_LAYOUT_PROPERTY_H 466