• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 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_PROPERTY_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PROPERTIES_PROPERTY_H
18 
19 #include <cstdint>
20 #include <optional>
21 
22 #include "ui/properties/dirty_flag.h"
23 
24 #include "base/memory/ace_type.h"
25 #include "base/utils/macros.h"
26 #include "base/utils/noncopyable.h"
27 #include "base/utils/utils.h"
28 
29 namespace OHOS::Ace::NG {
30 
31 using FrameNodeChangeInfoFlag = uint32_t;
32 inline constexpr FrameNodeChangeInfoFlag FRAME_NODE_CHANGE_INFO_NONE = 0;
33 inline constexpr FrameNodeChangeInfoFlag FRAME_NODE_CHANGE_START_SCROLL = 1 << 1;
34 inline constexpr FrameNodeChangeInfoFlag FRAME_NODE_CHANGE_END_SCROLL = 1 << 2;
35 inline constexpr FrameNodeChangeInfoFlag FRAME_NODE_CHANGE_START_ANIMATION = 1 << 3;
36 inline constexpr FrameNodeChangeInfoFlag FRAME_NODE_CHANGE_GEOMETRY_CHANGE = 1 << 4;
37 inline constexpr FrameNodeChangeInfoFlag FRAME_NODE_CHANGE_TRANSFORM_CHANGE = 1 << 5;
38 inline constexpr FrameNodeChangeInfoFlag FRAME_NODE_CHANGE_TRANSITION_START = 1 << 6;
39 inline constexpr FrameNodeChangeInfoFlag FRAME_NODE_CONTENT_CLIP_CHANGE = 1 << 7;
40 inline constexpr FrameNodeChangeInfoFlag FRAME_NODE_CHANGE_ALL =
41     FRAME_NODE_CHANGE_INFO_NONE | FRAME_NODE_CHANGE_START_SCROLL | FRAME_NODE_CHANGE_END_SCROLL |
42     FRAME_NODE_CHANGE_START_ANIMATION | FRAME_NODE_CHANGE_GEOMETRY_CHANGE | FRAME_NODE_CHANGE_TRANSFORM_CHANGE |
43     FRAME_NODE_CHANGE_TRANSITION_START | FRAME_NODE_CONTENT_CLIP_CHANGE;
44 
CheckNeedMakePropertyDiff(PropertyChangeFlag flag)45 inline bool CheckNeedMakePropertyDiff(PropertyChangeFlag flag)
46 {
47     return (flag & PROPERTY_UPDATE_DIFF) == PROPERTY_UPDATE_DIFF;
48 }
49 
50 bool CheckNeedRender(PropertyChangeFlag propertyChangeFlag);
51 
52 bool CheckNeedRequestMeasureAndLayout(PropertyChangeFlag propertyChangeFlag);
53 
54 bool CheckNeedRequestParentMeasure(PropertyChangeFlag propertyChangeFlag);
55 
56 bool CheckNeedMeasure(PropertyChangeFlag propertyChangeFlag);
57 
58 bool CheckNeedLayout(PropertyChangeFlag propertyChangeFlag);
59 
60 bool CheckMeasureFlag(PropertyChangeFlag propertyChangeFlag);
61 
62 bool CheckForceParentMeasureFlag(PropertyChangeFlag propertyChangeFlag);
63 
64 bool CheckLayoutFlag(PropertyChangeFlag propertyChangeFlag);
65 
66 bool CheckMeasureSelfFlag(PropertyChangeFlag propertyChangeFlag);
67 
68 bool CheckMeasureSelfAndParentFlag(PropertyChangeFlag propertyChangeFlag);
69 
70 bool CheckMeasureSelfAndChildFlag(PropertyChangeFlag propertyChangeFlag);
71 
72 bool CheckUpdateByChildRequest(PropertyChangeFlag propertyChangeFlag);
73 
74 bool CheckNoChanged(PropertyChangeFlag propertyChangeFlag);
75 
76 // For XXXProperty Class
77 #define ACE_DEFINE_PROPERTY_GROUP(group, type)              \
78 public:                                                     \
79     const std::unique_ptr<type>& GetOrCreate##group()       \
80     {                                                       \
81         if (!prop##group##_) {                              \
82             prop##group##_ = std::make_unique<type>();      \
83         }                                                   \
84         return prop##group##_;                              \
85     }                                                       \
86     const std::unique_ptr<type>& Get##group() const         \
87     {                                                       \
88         return prop##group##_;                              \
89     }                                                       \
90     std::unique_ptr<type> Clone##group() const              \
91     {                                                       \
92         if (prop##group##_) {                               \
93             return std::make_unique<type>(*prop##group##_); \
94         }                                                   \
95         return nullptr;                                     \
96     }                                                       \
97     void Reset##group()                                     \
98     {                                                       \
99         return prop##group##_.reset();                      \
100     }                                                       \
101                                                             \
102 protected:                                                  \
103     std::unique_ptr<type> prop##group##_;
104 
105 #define ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP_GET(group, name, type) \
106 public:                                                            \
107     std::optional<type> Get##name() const                          \
108     {                                                              \
109         auto& groupProperty = Get##group();                        \
110         if (groupProperty) {                                       \
111             return groupProperty->Get##name();                     \
112         }                                                          \
113         return std::nullopt;                                       \
114     }                                                              \
115     bool Has##name() const                                         \
116     {                                                              \
117         auto& groupProperty = Get##group();                        \
118         if (groupProperty) {                                       \
119             return groupProperty->Has##name();                     \
120         }                                                          \
121         return false;                                              \
122     }                                                              \
123     type Get##name##Value(const type& defaultValue) const          \
124     {                                                              \
125         auto& groupProperty = Get##group();                        \
126         if (groupProperty) {                                       \
127             if (groupProperty->Has##name()) {                      \
128                 return groupProperty->Get##name##Value();          \
129             }                                                      \
130         }                                                          \
131         return defaultValue;                                       \
132     }                                                              \
133     void Reset##name()                                             \
134     {                                                              \
135         auto& groupProperty = Get##group();                        \
136         if (groupProperty) {                                       \
137             groupProperty->Reset##name();                          \
138         }                                                          \
139     }
140 
141 // For different members of the same type, such as the same foreground and background color types, but the interface
142 // names provided to the outside world need to be different.
143 #define ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP_ITEM_GET(group, groupItem, name, type) \
144 public:                                                                            \
145     std::optional<type> Get##name() const                                          \
146     {                                                                              \
147         auto& groupProperty = Get##group();                                        \
148         if (groupProperty) {                                                       \
149             return groupProperty->Get##groupItem();                                \
150         }                                                                          \
151         return std::nullopt;                                                       \
152     }                                                                              \
153     bool Has##name() const                                                         \
154     {                                                                              \
155         auto& groupProperty = Get##group();                                        \
156         if (groupProperty) {                                                       \
157             return groupProperty->Has##groupItem();                                \
158         }                                                                          \
159         return false;                                                              \
160     }                                                                              \
161     type Get##name##Value(const type& defaultValue) const                          \
162     {                                                                              \
163         auto& groupProperty = Get##group();                                        \
164         if (groupProperty) {                                                       \
165             if (groupProperty->Has##groupItem()) {                                 \
166                 return groupProperty->Get##groupItem##Value();                     \
167             }                                                                      \
168         }                                                                          \
169         return defaultValue;                                                       \
170     }
171 
172 #define ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP(group, name, type, changeFlag) \
173     ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP_GET(group, name, type)             \
174     void Update##name(const type& value)                                   \
175     {                                                                      \
176         auto& groupProperty = GetOrCreate##group();                        \
177         if (groupProperty->Check##name(value)) {                           \
178             return;                                                        \
179         }                                                                  \
180         groupProperty->Update##name(value);                                \
181         UpdatePropertyChangeFlag(changeFlag);                              \
182     }
183 
184 #define ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP_ITEM(group, groupItem, name, type, changeFlag) \
185     ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP_ITEM_GET(group, groupItem, name, type)             \
186     void Update##name(const type& value)                                                   \
187     {                                                                                      \
188         auto& groupProperty = GetOrCreate##group();                                        \
189         if (groupProperty->Check##groupItem(value)) {                                      \
190             return;                                                                        \
191         }                                                                                  \
192         groupProperty->Update##groupItem(value);                                           \
193         UpdatePropertyChangeFlag(changeFlag);                                              \
194     }
195 
196 #define ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP_AND_CALLBACK(group, name, type, changeFlag) \
197     ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP_GET(group, name, type)                          \
198     void Update##name(const type& value)                                                \
199     {                                                                                   \
200         auto& groupProperty = GetOrCreate##group();                                     \
201         if (groupProperty->Check##name(value)) {                                        \
202             return;                                                                     \
203         }                                                                               \
204         groupProperty->Update##name(value);                                             \
205         UpdatePropertyChangeFlag(changeFlag);                                           \
206         On##name##Update(value);                                                        \
207     }
208 
209 #define ACE_DEFINE_PROPERTY_FUNC_WITH_GROUP(group, name, type) \
210     ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP_GET(group, name, type) \
211     void Update##name(const type& value)                       \
212     {                                                          \
213         auto& groupProperty = GetOrCreate##group();            \
214         if (groupProperty->Check##name(value)) {               \
215             return;                                            \
216         }                                                      \
217         groupProperty->Update##name(value);                    \
218         On##name##Update(value);                               \
219     }
220 
221 #define ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP_GET(name, type)   \
222 public:                                                          \
223     const std::optional<type>& Get##name() const                 \
224     {                                                            \
225         return prop##name##_;                                    \
226     }                                                            \
227     bool Has##name() const                                       \
228     {                                                            \
229         return prop##name##_.has_value();                        \
230     }                                                            \
231     const type& Get##name##Value() const                         \
232     {                                                            \
233         return prop##name##_.value();                            \
234     }                                                            \
235     const type& Get##name##Value(const type& defaultValue) const \
236     {                                                            \
237         if (!Has##name()) {                                      \
238             return defaultValue;                                 \
239         }                                                        \
240         return prop##name##_.value();                            \
241     }                                                            \
242     std::optional<type> Clone##name() const                      \
243     {                                                            \
244         return prop##name##_;                                    \
245     }                                                            \
246     void Reset##name()                                           \
247     {                                                            \
248         return prop##name##_.reset();                            \
249     }                                                            \
250                                                                  \
251 protected:                                                       \
252     std::optional<type> prop##name##_;
253 
254 #define ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(name, type, changeFlag) \
255     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP_GET(name, type)             \
256 public:                                                                \
257     void Update##name(const type& value)                               \
258     {                                                                  \
259         if (prop##name##_.has_value()) {                               \
260             if (NearEqual(prop##name##_.value(), value)) {             \
261                 return;                                                \
262             }                                                          \
263         }                                                              \
264         prop##name##_ = value;                                         \
265         UpdatePropertyChangeFlag(changeFlag);                          \
266     }
267 
268 #define ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP_AND_USING_CALLBACK(name, type, changeFlag) \
269     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP_GET(name, type)                                \
270 public:                                                                                   \
271     void Update##name(const type& value)                                                  \
272     {                                                                                     \
273         if (prop##name##_.has_value()) {                                                  \
274             if (NearEqual(prop##name##_.value(), value)) {                                \
275                 return;                                                                   \
276             }                                                                             \
277         }                                                                                 \
278         prop##name##_ = value;                                                            \
279         UpdatePropertyChangeFlag(changeFlag);                                             \
280         On##name##Update(value);                                                          \
281     }
282 
283 #define ACE_DEFINE_PROPERTY_ITEM_FUNC_WITHOUT_GROUP(name, type) \
284     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP_GET(name, type)      \
285 public:                                                         \
286     void Update##name(const type& value)                        \
287     {                                                           \
288         if (prop##name##_.has_value()) {                        \
289             if (NearEqual(prop##name##_.value(), value)) {      \
290                 return;                                         \
291             }                                                   \
292         }                                                       \
293         prop##name##_ = value;                                  \
294         On##name##Update(value);                                \
295     }
296 
297 #define ACE_DEFINE_PROPERTY_ITEM_FUNC_WITHOUT_GROUP_FOR_VIRTUAL_NODE(name, type)                 \
298     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP_GET(name, type)                                       \
299 public:                                                                                          \
300     void Update##name(const type& value, const int64_t accessibilityIdForVirtualNode = -2100000) \
301     {                                                                                            \
302         if (prop##name##_.has_value()) {                                                         \
303             if (NearEqual(prop##name##_.value(), value)) {                                       \
304                 return;                                                                          \
305             }                                                                                    \
306         }                                                                                        \
307         prop##name##_ = value;                                                                   \
308         On##name##Update(value, accessibilityIdForVirtualNode);                                  \
309     }
310 
311 // For Property Group Struct
312 #define ACE_DEFINE_PROPERTY_GROUP_ITEM(name, type)      \
313     std::optional<type> prop##name;                     \
314                                                         \
315     const std::optional<type>& Get##name() const        \
316     {                                                   \
317         return prop##name;                              \
318     }                                                   \
319     bool Has##name() const                              \
320     {                                                   \
321         return prop##name.has_value();                  \
322     }                                                   \
323     type Get##name##Value() const                       \
324     {                                                   \
325         return prop##name.value();                      \
326     }                                                   \
327     bool Update##name(const type& value)                \
328     {                                                   \
329         if (prop##name.has_value()) {                   \
330             if (NearEqual(prop##name.value(), value)) { \
331                 return false;                           \
332             }                                           \
333         }                                               \
334         prop##name = value;                             \
335         return true;                                    \
336     }                                                   \
337     bool Update##name(const std::optional<type>& value) \
338     {                                                   \
339         if (value.has_value()) {                        \
340             return Update##name(value.value());         \
341         }                                               \
342         return false;                                   \
343     }                                                   \
344     bool Check##name(const type& value) const           \
345     {                                                   \
346         if (!prop##name.has_value()) {                  \
347             return false;                               \
348         }                                               \
349         return NearEqual(prop##name.value(), value);    \
350     }                                                   \
351     void Reset##name()                                  \
352     {                                                   \
353         prop##name.reset();                             \
354     }
355 
356 #define ACE_DEFINE_PROPERTY_GROUP_ITEM_WITH_CALLBACK(name, type) \
357     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP_GET(name, type)       \
358 public:                                                          \
359     bool Update##name(const type& value)                         \
360     {                                                            \
361         if (prop##name##_.has_value()) {                         \
362             if (NearEqual(prop##name##_.value(), value)) {       \
363                 return false;                                    \
364             }                                                    \
365         }                                                        \
366         On##name##Update(value);                                 \
367         prop##name##_ = value;                                   \
368         return true;                                             \
369     }
370 
371 #define ACE_PROPERTY_TO_JSON_VALUE(target, type) \
372     do {                                         \
373         if (target) {                            \
374             (target)->ToJsonValue(json, filter); \
375         } else {                                 \
376             type p;                              \
377             p.ToJsonValue(json, filter);         \
378         }                                        \
379     } while (false)
380 
381 class ACE_EXPORT Property : public virtual AceType {
382     DECLARE_ACE_TYPE(Property, AceType);
383 
384 public:
385     Property() = default;
386 
387     ~Property() override = default;
388 
GetPropertyChangeFlag()389     PropertyChangeFlag GetPropertyChangeFlag() const
390     {
391         return propertyChangeFlag_;
392     }
393 
CleanDirty()394     void CleanDirty()
395     {
396         propertyChangeFlag_ = PROPERTY_UPDATE_NORMAL;
397     }
398 
UpdatePropertyChangeFlag(PropertyChangeFlag propertyChangeFlag)399     void UpdatePropertyChangeFlag(PropertyChangeFlag propertyChangeFlag)
400     {
401         propertyChangeFlag_ = propertyChangeFlag_ | propertyChangeFlag;
402     }
403 
404 protected:
405     PropertyChangeFlag propertyChangeFlag_ = PROPERTY_UPDATE_NORMAL;
406 
407     ACE_DISALLOW_COPY_AND_MOVE(Property);
408 };
409 } // namespace OHOS::Ace::NG
410 
411 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PROPERTIES_PROPERTY_H
412