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/pipeline_ng/ui_task_scheduler.h" 43 44 namespace OHOS::Ace::NG { 45 46 class FrameNode; 47 48 class ACE_EXPORT LayoutProperty : public Property { 49 DECLARE_ACE_TYPE(LayoutProperty, Property); 50 51 public: 52 LayoutProperty() = default; 53 54 ~LayoutProperty() override = default; 55 56 virtual RefPtr<LayoutProperty> Clone() const; 57 58 virtual void Reset(); 59 60 virtual void ToJsonValue(std::unique_ptr<JsonValue>& json) const; 61 GetLayoutConstraint()62 const std::optional<LayoutConstraintF>& GetLayoutConstraint() const 63 { 64 return layoutConstraint_; 65 } 66 GetContentLayoutConstraint()67 const std::optional<LayoutConstraintF>& GetContentLayoutConstraint() const 68 { 69 return contentConstraint_; 70 } 71 GetMagicItemProperty()72 const std::unique_ptr<MagicItemProperty>& GetMagicItemProperty() const 73 { 74 return magicItemProperty_; 75 } 76 GetPaddingProperty()77 const std::unique_ptr<PaddingProperty>& GetPaddingProperty() const 78 { 79 return padding_; 80 } 81 GetMarginProperty()82 const std::unique_ptr<MarginProperty>& GetMarginProperty() const 83 { 84 return margin_; 85 } 86 GetBorderWidthProperty()87 const std::unique_ptr<BorderWidthProperty>& GetBorderWidthProperty() const 88 { 89 return borderWidth_; 90 } 91 GetPositionProperty()92 const std::unique_ptr<PositionProperty>& GetPositionProperty() const 93 { 94 return positionProperty_; 95 } 96 GetCalcLayoutConstraint()97 const std::unique_ptr<MeasureProperty>& GetCalcLayoutConstraint() const 98 { 99 return calcLayoutConstraint_; 100 } 101 GetFlexItemProperty()102 const std::unique_ptr<FlexItemProperty>& GetFlexItemProperty() const 103 { 104 return flexItemProperty_; 105 } 106 GetLayoutDirection()107 TextDirection GetLayoutDirection() const 108 { 109 return layoutDirection_.value_or(TextDirection::AUTO); 110 } 111 112 MeasureType GetMeasureType(MeasureType defaultType = MeasureType::MATCH_CONTENT) const 113 { 114 return measureType_.value_or(defaultType); 115 } 116 UpdatePadding(const PaddingProperty & value)117 void UpdatePadding(const PaddingProperty& value) 118 { 119 if (!padding_) { 120 padding_ = std::make_unique<PaddingProperty>(); 121 } 122 if (padding_->UpdateWithCheck(value)) { 123 propertyChangeFlag_ = propertyChangeFlag_ | PROPERTY_UPDATE_LAYOUT | PROPERTY_UPDATE_MEASURE; 124 } 125 } 126 UpdateMargin(const MarginProperty & value)127 void UpdateMargin(const MarginProperty& value) 128 { 129 if (!margin_) { 130 margin_ = std::make_unique<MarginProperty>(); 131 } 132 if (margin_->UpdateWithCheck(value)) { 133 propertyChangeFlag_ = propertyChangeFlag_ | PROPERTY_UPDATE_LAYOUT | PROPERTY_UPDATE_MEASURE; 134 } 135 } 136 UpdateBorderWidth(const BorderWidthProperty & value)137 void UpdateBorderWidth(const BorderWidthProperty& value) 138 { 139 if (!borderWidth_) { 140 borderWidth_ = std::make_unique<BorderWidthProperty>(); 141 } 142 if (borderWidth_->UpdateWithCheck(value)) { 143 propertyChangeFlag_ = propertyChangeFlag_ | PROPERTY_UPDATE_LAYOUT | PROPERTY_UPDATE_MEASURE; 144 } 145 } 146 UpdateAlignment(Alignment value)147 void UpdateAlignment(Alignment value) 148 { 149 if (!positionProperty_) { 150 positionProperty_ = std::make_unique<PositionProperty>(); 151 } 152 if (positionProperty_->UpdateAlignment(value)) { 153 propertyChangeFlag_ = propertyChangeFlag_ | PROPERTY_UPDATE_LAYOUT; 154 } 155 } 156 UpdateLayoutWeight(float value)157 void UpdateLayoutWeight(float value) 158 { 159 if (!magicItemProperty_) { 160 magicItemProperty_ = std::make_unique<MagicItemProperty>(); 161 } 162 if (magicItemProperty_->UpdateLayoutWeight(value)) { 163 propertyChangeFlag_ = propertyChangeFlag_ | PROPERTY_UPDATE_MEASURE; 164 } 165 } 166 UpdateLayoutDirection(TextDirection value)167 void UpdateLayoutDirection(TextDirection value) 168 { 169 if (layoutDirection_ == value) { 170 return; 171 } 172 layoutDirection_ = value; 173 propertyChangeFlag_ = propertyChangeFlag_ | PROPERTY_UPDATE_MEASURE; 174 } 175 UpdateAspectRatio(float ratio)176 void UpdateAspectRatio(float ratio) 177 { 178 if (!magicItemProperty_) { 179 magicItemProperty_ = std::make_unique<MagicItemProperty>(); 180 } 181 if (magicItemProperty_->UpdateAspectRatio(ratio)) { 182 propertyChangeFlag_ = propertyChangeFlag_ | PROPERTY_UPDATE_MEASURE; 183 } 184 } 185 UpdateMeasureType(MeasureType measureType)186 void UpdateMeasureType(MeasureType measureType) 187 { 188 if (measureType_ == measureType) { 189 return; 190 } 191 propertyChangeFlag_ = propertyChangeFlag_ | PROPERTY_UPDATE_MEASURE; 192 measureType_ = measureType; 193 } 194 195 // user defined max, min, self size. 196 void UpdateCalcLayoutProperty(const MeasureProperty& constraint); 197 UpdateUserDefinedIdealSize(const CalcSize & value)198 void UpdateUserDefinedIdealSize(const CalcSize& value) 199 { 200 if (!calcLayoutConstraint_) { 201 calcLayoutConstraint_ = std::make_unique<MeasureProperty>(); 202 } 203 if (calcLayoutConstraint_->UpdateSelfIdealSizeWithCheck(value)) { 204 propertyChangeFlag_ = propertyChangeFlag_ | PROPERTY_UPDATE_MEASURE; 205 } 206 } 207 ClearUserDefinedIdealSize(bool clearWidth,bool clearHeight)208 void ClearUserDefinedIdealSize(bool clearWidth, bool clearHeight) 209 { 210 if (!calcLayoutConstraint_) { 211 return; 212 } 213 if (calcLayoutConstraint_->ClearSelfIdealSize(clearWidth, clearHeight)) { 214 propertyChangeFlag_ = propertyChangeFlag_ | PROPERTY_UPDATE_MEASURE; 215 } 216 } 217 UpdateCalcMinSize(const CalcSize & value)218 void UpdateCalcMinSize(const CalcSize& value) 219 { 220 if (!calcLayoutConstraint_) { 221 calcLayoutConstraint_ = std::make_unique<MeasureProperty>(); 222 } 223 if (calcLayoutConstraint_->UpdateMinSizeWithCheck(value)) { 224 propertyChangeFlag_ = propertyChangeFlag_ | PROPERTY_UPDATE_MEASURE; 225 } 226 } 227 UpdateCalcMaxSize(const CalcSize & value)228 void UpdateCalcMaxSize(const CalcSize& value) 229 { 230 if (!calcLayoutConstraint_) { 231 calcLayoutConstraint_ = std::make_unique<MeasureProperty>(); 232 } 233 if (calcLayoutConstraint_->UpdateMaxSizeWithCheck(value)) { 234 propertyChangeFlag_ = propertyChangeFlag_ | PROPERTY_UPDATE_MEASURE; 235 } 236 } 237 238 void UpdateLayoutConstraint(const LayoutConstraintF& parentConstraint); 239 UpdateMarginSelfIdealSize(const SizeF & value)240 void UpdateMarginSelfIdealSize(const SizeF& value) 241 { 242 if (!layoutConstraint_.has_value()) { 243 layoutConstraint_ = LayoutConstraintF(); 244 } 245 if (layoutConstraint_->UpdateSelfMarginSizeWithCheck(OptionalSizeF(value))) { 246 propertyChangeFlag_ = propertyChangeFlag_ | PROPERTY_UPDATE_MEASURE; 247 } 248 } 249 UpdateFlexGrow(float flexGrow)250 void UpdateFlexGrow(float flexGrow) 251 { 252 if (!flexItemProperty_) { 253 flexItemProperty_ = std::make_unique<FlexItemProperty>(); 254 } 255 if (flexItemProperty_->UpdateFlexGrow(flexGrow)) { 256 propertyChangeFlag_ = propertyChangeFlag_ | PROPERTY_UPDATE_MEASURE; 257 } 258 } 259 UpdateFlexShrink(float flexShrink)260 void UpdateFlexShrink(float flexShrink) 261 { 262 if (!flexItemProperty_) { 263 flexItemProperty_ = std::make_unique<FlexItemProperty>(); 264 } 265 if (flexItemProperty_->UpdateFlexShrink(flexShrink)) { 266 propertyChangeFlag_ = propertyChangeFlag_ | PROPERTY_UPDATE_MEASURE; 267 } 268 } 269 UpdateFlexBasis(const Dimension & flexBasis)270 void UpdateFlexBasis(const Dimension& flexBasis) 271 { 272 if (!flexItemProperty_) { 273 flexItemProperty_ = std::make_unique<FlexItemProperty>(); 274 } 275 if (flexItemProperty_->UpdateFlexBasis(flexBasis)) { 276 propertyChangeFlag_ = propertyChangeFlag_ | PROPERTY_UPDATE_MEASURE; 277 } 278 } 279 UpdateAlignSelf(const FlexAlign & flexAlign)280 void UpdateAlignSelf(const FlexAlign& flexAlign) 281 { 282 if (!flexItemProperty_) { 283 flexItemProperty_ = std::make_unique<FlexItemProperty>(); 284 } 285 if (flexItemProperty_->UpdateAlignSelf(flexAlign)) { 286 propertyChangeFlag_ = propertyChangeFlag_ | PROPERTY_UPDATE_MEASURE; 287 } 288 } 289 UpdateAlignRules(const std::map<AlignDirection,AlignRule> & alignRules)290 void UpdateAlignRules(const std::map<AlignDirection, AlignRule>& alignRules) 291 { 292 if (!flexItemProperty_) { 293 flexItemProperty_ = std::make_unique<FlexItemProperty>(); 294 } 295 if (flexItemProperty_->UpdateAlignRules(alignRules)) { 296 propertyChangeFlag_ = propertyChangeFlag_ | PROPERTY_UPDATE_MEASURE; 297 } 298 } 299 UpdateDisplayIndex(int32_t displayIndex)300 void UpdateDisplayIndex(int32_t displayIndex) 301 { 302 if (!flexItemProperty_) { 303 flexItemProperty_ = std::make_unique<FlexItemProperty>(); 304 } 305 if (flexItemProperty_->UpdateDisplayIndex(displayIndex)) { 306 propertyChangeFlag_ = propertyChangeFlag_ | PROPERTY_UPDATE_MEASURE; 307 } 308 } 309 310 void UpdateGridProperty( 311 std::optional<int32_t> span, std::optional<int32_t> offset, GridSizeType type = GridSizeType::UNDEFINED); 312 313 bool UpdateGridOffset(const RefPtr<FrameNode>& host); 314 315 void BuildGridProperty(const RefPtr<FrameNode>& host); 316 317 void UpdateContentConstraint(); 318 319 LayoutConstraintF CreateChildConstraint() const; 320 CreateContentConstraint()321 LayoutConstraintF CreateContentConstraint() const 322 { 323 auto layoutConstraint = contentConstraint_.value_or(LayoutConstraintF()); 324 layoutConstraint.maxSize.UpdateSizeWhenSmaller(layoutConstraint.selfIdealSize.ConvertToSizeT()); 325 return layoutConstraint; 326 } 327 328 PaddingPropertyF CreatePaddingWithoutBorder(); 329 PaddingPropertyF CreatePaddingAndBorder(); 330 PaddingPropertyF CreatePaddingAndBorderWithDefault(float paddingHorizontalDefault, float paddingVerticalDefault, 331 float borderHorizontalDefault, float borderVerticalDefault); 332 333 MarginPropertyF CreateMargin(); 334 335 void SetHost(const WeakPtr<FrameNode>& host); 336 RefPtr<FrameNode> GetHost() const; 337 338 ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP_AND_USING_CALLBACK(Visibility, VisibleType, PROPERTY_UPDATE_MEASURE); 339 void OnVisibilityUpdate(VisibleType visible) const; 340 UpdateLayoutConstraint(const RefPtr<LayoutProperty> & layoutProperty)341 void UpdateLayoutConstraint(const RefPtr<LayoutProperty>& layoutProperty) 342 { 343 layoutConstraint_ = layoutProperty->layoutConstraint_; 344 contentConstraint_ = layoutProperty->contentConstraint_; 345 gridProperty_ = 346 (layoutProperty->gridProperty_) ? std::make_unique<GridProperty>(*layoutProperty->gridProperty_) : nullptr; 347 } 348 349 protected: 350 void UpdateLayoutProperty(const LayoutProperty* layoutProperty); 351 352 virtual void Clone(RefPtr<LayoutProperty> layoutProperty) const; 353 354 private: 355 // This will call after ModifyLayoutConstraint. 356 void CheckSelfIdealSize(); 357 358 void CheckAspectRatio(); 359 void CheckBorderAndPadding(); 360 361 // available in measure process. 362 std::optional<LayoutConstraintF> layoutConstraint_; 363 std::optional<LayoutConstraintF> contentConstraint_; 364 365 std::unique_ptr<MeasureProperty> calcLayoutConstraint_; 366 std::unique_ptr<PaddingProperty> padding_; 367 std::unique_ptr<MarginProperty> margin_; 368 std::unique_ptr<BorderWidthProperty> borderWidth_; 369 std::unique_ptr<MagicItemProperty> magicItemProperty_; 370 std::unique_ptr<PositionProperty> positionProperty_; 371 std::unique_ptr<FlexItemProperty> flexItemProperty_; 372 std::unique_ptr<GridProperty> gridProperty_; 373 std::optional<MeasureType> measureType_; 374 std::optional<TextDirection> layoutDirection_; 375 376 WeakPtr<FrameNode> host_; 377 378 ACE_DISALLOW_COPY_AND_MOVE(LayoutProperty); 379 }; 380 } // namespace OHOS::Ace::NG 381 382 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_LAYOUTS_LAYOUT_PROPERTY_H 383