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