• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_PROPERTIES_LAYOUT_CONSTRAINT_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PROPERTIES_LAYOUT_CONSTRAINT_H
18 
19 #include <algorithm>
20 #include <optional>
21 #include <string>
22 
23 #include "base/geometry/ng/size_t.h"
24 #include "core/components_ng/property/calc_length.h"
25 #include "core/components_ng/property/layout_policy_property.h"
26 #include "core/components_ng/property/measure_property.h"
27 
28 namespace OHOS::Ace::NG {
29 enum class ReferenceEdge {
30     START,
31     END,
32 };
33 struct ViewPosReference {
34     float viewPosStart;
35     float viewPosEnd;
36     float referencePos;
37     ReferenceEdge referenceEdge;
38     Axis axis;
39 
40     bool operator==(const ViewPosReference &other) const
41     {
42         return NearEqual(viewPosStart, other.viewPosStart) &&
43                NearEqual(viewPosEnd, other.viewPosEnd) &&
44                NearEqual(referencePos, other.referencePos) &&
45                referenceEdge == other.referenceEdge &&
46                axis == other.axis;
47     }
48 };
49 template<typename T>
50 struct LayoutConstraintT {
51     ScaleProperty scaleProperty = ScaleProperty::CreateScaleProperty();
52     SizeT<T> minSize { 0, 0 };
53     SizeT<T> maxSize { Infinity<T>(), Infinity<T>() };
54     SizeT<T> percentReference { 0, 0 };
55     OptionalSize<T> parentIdealSize;
56     OptionalSize<T> selfIdealSize;
57     std::optional<ViewPosReference> viewPosRef;
58 
CompareWithInfinityCheckLayoutConstraintT59     static bool CompareWithInfinityCheck(const OptionalSize<float>& first, const OptionalSize<float>& second)
60     {
61         if (first.Width().has_value() ^ second.Width().has_value()) {
62             return false;
63         }
64         auto widthBothInf = GreaterOrEqualToInfinity(first.Width().value_or(0.0f)) &&
65                             GreaterOrEqualToInfinity(second.Width().value_or(0.0f));
66         if (!widthBothInf && !NearEqual(first.Width().value_or(0), second.Width().value_or(0))) {
67             return false;
68         }
69         if (first.Height().has_value() ^ second.Height().has_value()) {
70             return false;
71         }
72         auto heightBothInf = GreaterOrEqualToInfinity(first.Height().value_or(0.0f)) &&
73                             GreaterOrEqualToInfinity(second.Height().value_or(0.0f));
74         if (!heightBothInf && !NearEqual(first.Height().value_or(0), second.Height().value_or(0))) {
75             return false;
76         }
77         return true;
78     }
79 
CompareWithInfinityCheckLayoutConstraintT80     static bool CompareWithInfinityCheck(const SizeT<float>& first, const SizeT<float>& second)
81     {
82         auto widthBothInf = GreaterOrEqualToInfinity(first.Width()) && GreaterOrEqualToInfinity(second.Width());
83         auto heightBothInf = GreaterOrEqualToInfinity(first.Height()) && GreaterOrEqualToInfinity(second.Height());
84         if (widthBothInf && heightBothInf) {
85             return true;
86         }
87         return NearEqual(first.Width(), second.Width()) && NearEqual(first.Height(), second.Height());
88     }
89 
CompareWithInfinityCheckLayoutConstraintT90     static bool CompareWithInfinityCheck(float first, float second)
91     {
92         auto bothInf = GreaterOrEqualToInfinity(first) && GreaterOrEqualToInfinity(second);
93         if (bothInf) {
94             return true;
95         }
96         return NearEqual(first, second);
97     }
98 
99     void ApplyAspectRatio(float ratio, const std::optional<CalcSize>& calcSize,
100         const std::optional<NG::LayoutPolicyProperty>& layoutPolicy = std::nullopt, bool greaterThanApiTen = false);
101 
102     void ApplyAspectRatioToParentIdealSize(bool useWidth, float ratio);
103 
104     void ApplyAspectRatioByMaxSize(float ratio, std::optional<bool> useDefinedWidth, bool greaterThanApiTen = false);
105 
106     void ApplyAspectRatioWithCalcSize(float ratio, bool useDefinedWidth);
107 
108     void ApplyAspectRatioWithoutCalcSize(float ratio, bool greaterThanApiTen = false);
109 
110     void Reset();
111 
112     void MinusPadding(const std::optional<T>& left, const std::optional<T>& right, const std::optional<T>& top,
113         const std::optional<T>& bottom);
114 
115     void MinusPaddingToNonNegativeSize(const std::optional<T>& left, const std::optional<T>& right,
116         const std::optional<T>& top, const std::optional<T>& bottom);
117 
118     bool operator==(const LayoutConstraintT& layoutConstraint) const
119     {
120         return (scaleProperty == layoutConstraint.scaleProperty) && (minSize == layoutConstraint.minSize) &&
121                (maxSize == layoutConstraint.maxSize) && (percentReference == layoutConstraint.percentReference) &&
122                (parentIdealSize == layoutConstraint.parentIdealSize) &&
123                (selfIdealSize == layoutConstraint.selfIdealSize) && (viewPosRef == layoutConstraint.viewPosRef);
124     }
125 
126     bool operator!=(const LayoutConstraintT& layoutConstraint) const
127     {
128         return !(*this == layoutConstraint);
129     }
130 
EqualWithoutPercentWidthLayoutConstraintT131     bool EqualWithoutPercentWidth(const LayoutConstraintT& layoutConstraint) const
132     {
133         return (scaleProperty == layoutConstraint.scaleProperty) &&
134                CompareWithInfinityCheck(minSize, layoutConstraint.minSize) &&
135                CompareWithInfinityCheck(maxSize, layoutConstraint.maxSize) &&
136                CompareWithInfinityCheck(parentIdealSize, layoutConstraint.parentIdealSize) &&
137                CompareWithInfinityCheck(percentReference.Height(), layoutConstraint.percentReference.Height()) &&
138                CompareWithInfinityCheck(selfIdealSize, layoutConstraint.selfIdealSize) &&
139                (viewPosRef == layoutConstraint.viewPosRef);
140     }
141 
EqualWithoutPercentHeightLayoutConstraintT142     bool EqualWithoutPercentHeight(const LayoutConstraintT& layoutConstraint) const
143     {
144         return (scaleProperty == layoutConstraint.scaleProperty) &&
145                CompareWithInfinityCheck(minSize, layoutConstraint.minSize) &&
146                CompareWithInfinityCheck(maxSize, layoutConstraint.maxSize) &&
147                CompareWithInfinityCheck(parentIdealSize, layoutConstraint.parentIdealSize) &&
148                CompareWithInfinityCheck(percentReference.Width(), layoutConstraint.percentReference.Width()) &&
149                CompareWithInfinityCheck(selfIdealSize, layoutConstraint.selfIdealSize) &&
150                (viewPosRef == layoutConstraint.viewPosRef);
151     }
152 
UpdateSelfMarginSizeWithCheckLayoutConstraintT153     bool UpdateSelfMarginSizeWithCheck(const OptionalSize<T>& size)
154     {
155         if (selfIdealSize == size) {
156             return false;
157         }
158         return selfIdealSize.UpdateSizeWithCheck(size);
159     }
160 
UpdateIllegalSelfMarginSizeWithCheckLayoutConstraintT161     bool UpdateIllegalSelfMarginSizeWithCheck(const OptionalSize<T>& size)
162     {
163         if (selfIdealSize == size) {
164             return false;
165         }
166         return selfIdealSize.UpdateIllegalSizeWithCheck(size);
167     }
168 
UpdateIllegalSelfIdealSizeWithCheckLayoutConstraintT169     bool UpdateIllegalSelfIdealSizeWithCheck(const OptionalSize<T>& size)
170     {
171         if (selfIdealSize == size) {
172             return false;
173         }
174         return selfIdealSize.UpdateIllegalSizeWithCheck(size);
175     }
176 
UpdateParentIdealSizeWithCheckLayoutConstraintT177     bool UpdateParentIdealSizeWithCheck(const OptionalSize<T>&& size)
178     {
179         if (parentIdealSize == size) {
180             return false;
181         }
182         return parentIdealSize.UpdateSizeWithCheck(size);
183     }
184 
UpdateIllegalParentIdealSizeWithCheckLayoutConstraintT185     bool UpdateIllegalParentIdealSizeWithCheck(const OptionalSize<T>&& size)
186     {
187         if (parentIdealSize == size) {
188             return false;
189         }
190         return parentIdealSize.UpdateIllegalSizeWithCheck(size);
191     }
192 
UpdateParentIdealSizeByLayoutPolicyLayoutConstraintT193     bool UpdateParentIdealSizeByLayoutPolicy(const SizeT<T>& size, bool isMax, NG::LayoutPolicyProperty layoutPolicy)
194     {
195         bool widthUpdated = false;
196         bool heightUpdated = false;
197         if (layoutPolicy.IsWidthMatch()) {
198             if (isMax) {
199                 widthUpdated = parentIdealSize.UpdateWidthWhenSmaller(size);
200             } else {
201                 widthUpdated = parentIdealSize.UpdateWidthWhenLarger(size);
202             }
203         }
204         if (layoutPolicy.IsHeightMatch()) {
205             if (isMax) {
206                 heightUpdated = parentIdealSize.UpdateHeightWhenSmaller(size);
207             } else {
208                 heightUpdated = parentIdealSize.UpdateHeightWhenLarger(size);
209             }
210         }
211         return widthUpdated || heightUpdated;
212     }
213 
UpdateMaxSizeWithCheckLayoutConstraintT214     bool UpdateMaxSizeWithCheck(const SizeT<T>& size)
215     {
216         if (maxSize == size) {
217             return false;
218         }
219         return maxSize.UpdateSizeWhenSmaller(size);
220     }
221 
UpdateMaxWidthWithCheckLayoutConstraintT222     bool UpdateMaxWidthWithCheck(const SizeT<T>& size)
223     {
224         if (maxSize == size) {
225             return false;
226         }
227         return maxSize.UpdateWidthWhenSmaller(size);
228     }
229 
UpdateMaxHeightWithCheckLayoutConstraintT230     bool UpdateMaxHeightWithCheck(const SizeT<T>& size)
231     {
232         if (maxSize == size) {
233             return false;
234         }
235         return maxSize.UpdateHeightWhenSmaller(size);
236     }
237 
UpdateMinSizeWithCheckLayoutConstraintT238     bool UpdateMinSizeWithCheck(const SizeT<T>& size)
239     {
240         if (minSize == size) {
241             return false;
242         }
243         return minSize.UpdateSizeWhenLarger(size);
244     }
245 
UpdatePercentReferenceLayoutConstraintT246     bool UpdatePercentReference(const SizeT<T>& size)
247     {
248         if (percentReference == size) {
249             return false;
250         }
251         percentReference.SetSizeT(size);
252         return true;
253     }
254 
255     std::string ToString() const;
256 
257     SizeF Constrain(const SizeF& size) const;
258 };
259 
260 using LayoutConstraintF = LayoutConstraintT<float>;
261 } // namespace OHOS::Ace::NG
262 
263 #include "layout_constraint.inl"
264 
265 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PROPERTIES_LAYOUT_CONSTRAINT_H
266