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