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_MODIFIER_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_MODIFIER_H
18 
19 #include <atomic>
20 #include <cstdint>
21 #include <functional>
22 #include <optional>
23 #include <vector>
24 
25 #include "base/geometry/ng/rect_t.h"
26 #include "base/memory/ace_type.h"
27 #include "base/utils/utils.h"
28 #include "core/components/common/properties/animation_option.h"
29 #include "core/components_ng/animation/gradient_arithmetic.h"
30 #include "core/components_ng/base/linear_vector.h"
31 #include "core/components_ng/render/canvas_image.h"
32 #include "core/components_ng/render/drawing_forward.h"
33 #include "core/components_ng/render/modifier_adapter.h"
34 
35 enum class ThresholdType {
36     LAYOUT,  // 0.5f for properties like position, as the difference in properties by 0.5 appears visually unchanged
37     COARSE,  // 1.0f / 256.0f
38     MEDIUM,  // 1.0f / 1000.0f
39     FINE,    // 1.0f / 3072.0f
40     COLOR,   // 0.0f
41     DEFAULT, // 1.0f / 256.0f
42     ZERO,    // 0.0f for noanimatable property
43 };
44 
45 enum class PropertyUnit {
46     UNKNOWN,
47     PIXEL_POSITION, // animatable properties are related to position of the object, the unit is pixels
48 };
49 
50 namespace OHOS::Ace::NG {
51 
52 class ExtensionHandler;
53 
54 class ACE_FORCE_EXPORT Modifier : public virtual AceType {
55     DECLARE_ACE_TYPE(Modifier, AceType);
56 
57 public:
58     Modifier();
~Modifier()59     ~Modifier() override
60     {
61         ModifierAdapter::RemoveModifier(id_);
62     }
63 
GetId()64     int32_t GetId() const
65     {
66         return id_;
67     }
68 
69 private:
70     int32_t id_ = 0;
71     ACE_DISALLOW_COPY_AND_MOVE(Modifier);
72 };
73 
74 class PropertyBase : public virtual AceType {
75     DECLARE_ACE_TYPE(PropertyBase, AceType);
76 
77 public:
78     PropertyBase() = default;
79     ~PropertyBase() override = default;
80 
81 private:
82     ACE_DISALLOW_COPY_AND_MOVE(PropertyBase);
83 };
84 
85 struct DrawingContext {
86     RSCanvas& canvas;
87     float width = 0;
88     float height = 0;
89 };
90 
91 using DrawModifierFunc = std::function<void(NG::DrawingContext& drawingContext)>;
92 
93 class ACE_EXPORT DrawModifier : public virtual AceType {
94 public:
95     DECLARE_ACE_TYPE(DrawModifier, AceType);
96 
97 public:
98     DrawModifierFunc drawBehindFunc;
99     DrawModifierFunc drawContentFunc;
100     DrawModifierFunc drawFrontFunc;
101 };
102 
103 template<typename T>
104 class NormalProperty : public PropertyBase {
105     DECLARE_ACE_TYPE(NormalProperty, PropertyBase);
106 
107 public:
NormalProperty(const T & value)108     explicit NormalProperty(const T& value) : value_(value) {}
109     ~NormalProperty() override = default;
110 
111     void SetUpCallbacks(std::function<T()>&& getFunc, std::function<void(const T&)>&& setFunc,
112         std::function<T()>&& getStageFunc = nullptr)
113     {
114         getFunc_ = std::move(getFunc);
115         setFunc_ =  std::move(setFunc);
116         getStageFunc_ =  std::move(getStageFunc);
117     }
118 
Get()119     T Get()
120     {
121         if (getFunc_) {
122             return getFunc_();
123         } else {
124             return value_;
125         }
126     }
127 
Set(const T & value)128     void Set(const T& value)
129     {
130         if (setFunc_) {
131             setFunc_(value);
132         } else {
133             value_ = value;
134         }
135     }
136 
GetStagingValue()137     T GetStagingValue() const
138     {
139         if (getStageFunc_) {
140             return getStageFunc_();
141         } else {
142             return value_;
143         }
144     }
145 
SetUpdateCallback(std::function<void (const T &)> && callback)146     void SetUpdateCallback(std::function<void(const T&)>&& callback)
147     {
148         updateCallback_ = std::move(callback);
149     }
150 
GetUpdateCallback()151     std::function<void(const T&)> GetUpdateCallback() const
152     {
153         return updateCallback_;
154     }
155 
156 private:
157     T value_;
158     std::function<T()> getFunc_;
159     std::function<void(const T&)> setFunc_;
160     std::function<T()> getStageFunc_;
161     std::function<void(const T&)> updateCallback_;
162     ACE_DISALLOW_COPY_AND_MOVE(NormalProperty);
163 };
164 
165 template<typename T>
166 class AnimatableProperty : public NormalProperty<T> {
167     DECLARE_ACE_TYPE(AnimatableProperty, NormalProperty<T>);
168 
169 public:
AnimatableProperty(const T & value)170     explicit AnimatableProperty(const T& value) : NormalProperty<T>(value) {}
171     ~AnimatableProperty() override = default;
172 private:
173     ACE_DISALLOW_COPY_AND_MOVE(AnimatableProperty);
174 };
175 
176 #define DECLARE_PROP_TYPED_CLASS(classname, template_class, type)        \
177     class classname : public template_class<type> {                      \
178         DECLARE_ACE_TYPE(classname, template_class);                     \
179                                                                          \
180     public:                                                              \
181         explicit classname(const type& value) : template_class(value) {} \
182         ~classname() override = default;                                 \
183         ACE_DISALLOW_COPY_AND_MOVE(classname);                           \
184     }
185 
186 DECLARE_PROP_TYPED_CLASS(PropertyBool, NormalProperty, bool);
187 DECLARE_PROP_TYPED_CLASS(PropertySizeF, NormalProperty, SizeF);
188 DECLARE_PROP_TYPED_CLASS(PropertyOffsetF, NormalProperty, OffsetF);
189 DECLARE_PROP_TYPED_CLASS(PropertyInt, NormalProperty, int32_t);
190 DECLARE_PROP_TYPED_CLASS(PropertyFloat, NormalProperty, float);
191 DECLARE_PROP_TYPED_CLASS(PropertyString, NormalProperty, std::string);
192 DECLARE_PROP_TYPED_CLASS(PropertyColor, NormalProperty, Color);
193 DECLARE_PROP_TYPED_CLASS(PropertyRectF, NormalProperty, RectF);
194 DECLARE_PROP_TYPED_CLASS(AnimatablePropertyFloat, AnimatableProperty, float);
195 DECLARE_PROP_TYPED_CLASS(AnimatablePropertyUint8, AnimatableProperty, uint8_t);
196 DECLARE_PROP_TYPED_CLASS(AnimatablePropertyColor, AnimatableProperty, LinearColor);
197 DECLARE_PROP_TYPED_CLASS(AnimatablePropertyVectorFloat, AnimatableProperty, LinearVector<float>);
198 DECLARE_PROP_TYPED_CLASS(AnimatablePropertyVectorColor, AnimatableProperty, GradientArithmetic);
199 DECLARE_PROP_TYPED_CLASS(AnimatablePropertyOffsetF, AnimatableProperty, OffsetF);
200 DECLARE_PROP_TYPED_CLASS(AnimatablePropertySizeF, AnimatableProperty, SizeF);
201 DECLARE_PROP_TYPED_CLASS(AnimatableArithmeticProperty, AnimatableProperty, RefPtr<CustomAnimatableArithmetic>);
202 
203 class OverlayModifier : public Modifier {
204     DECLARE_ACE_TYPE(OverlayModifier, Modifier);
205 
206 public:
OverlayModifier()207     OverlayModifier()
208     {
209         changeCount_ = MakeRefPtr<PropertyInt>(0);
210         AttachProperty(changeCount_);
211     };
212     ~OverlayModifier() override = default;
213     virtual void onDraw(DrawingContext& Context) = 0;
214     void Draw(DrawingContext& Context);
215 
AttachProperty(const RefPtr<PropertyBase> & prop)216     void AttachProperty(const RefPtr<PropertyBase>& prop)
217     {
218         attachedProperties_.push_back(prop);
219     }
220 
GetAttachedProperties()221     const std::vector<RefPtr<PropertyBase>>& GetAttachedProperties()
222     {
223         return attachedProperties_;
224     }
225 
GetBoundsRect()226     const RectF& GetBoundsRect()
227     {
228         return rect_;
229     }
230 
SetBoundsRect(const RectF & rect)231     void SetBoundsRect(const RectF& rect)
232     {
233         rect_ = rect;
234     }
235 
236     void SetExtensionHandler(ExtensionHandler* extensionHandler);
237 
SetOverlayChange()238     void SetOverlayChange()
239     {
240         changeCount_->Set(changeCount_->Get() + 1);
241     }
242 
243 private:
244     std::vector<RefPtr<PropertyBase>> attachedProperties_;
245     RectF rect_;
246     ExtensionHandler* extensionHandler_ = nullptr;
247     RefPtr<PropertyInt> changeCount_;
248     ACE_DISALLOW_COPY_AND_MOVE(OverlayModifier);
249 };
250 
251 class ForegroundModifier : public Modifier {
252     DECLARE_ACE_TYPE(ForegroundModifier, Modifier);
253 
254 public:
ForegroundModifier()255     ForegroundModifier()
256     {
257         changeCount_ = MakeRefPtr<PropertyInt>(0);
258         AttachProperty(changeCount_);
259     };
260     ~ForegroundModifier() override = default;
261     virtual void onDraw(DrawingContext& Context) = 0;
262     void Draw(DrawingContext& Context);
263 
AttachProperty(const RefPtr<PropertyBase> & prop)264     void AttachProperty(const RefPtr<PropertyBase>& prop)
265     {
266         attachedProperties_.push_back(prop);
267     }
268 
GetAttachedProperties()269     const std::vector<RefPtr<PropertyBase>>& GetAttachedProperties() const
270     {
271         return attachedProperties_;
272     }
273 
GetBoundsRect()274     const RectF& GetBoundsRect() const
275     {
276         return rect_;
277     }
278 
SetBoundsRect(const RectF & rect)279     void SetBoundsRect(const RectF& rect)
280     {
281         rect_ = rect;
282     }
283 
284     void SetExtensionHandler(ExtensionHandler* extensionHandler);
285 
SetForegroundChange()286     void SetForegroundChange()
287     {
288         changeCount_->Set(changeCount_->Get() + 1);
289     }
290 
291 private:
292     std::vector<RefPtr<PropertyBase>> attachedProperties_;
293     RectF rect_;
294     ExtensionHandler* extensionHandler_ = nullptr;
295     RefPtr<PropertyInt> changeCount_;
296     ACE_DISALLOW_COPY_AND_MOVE(ForegroundModifier);
297 };
298 
299 class ContentModifier : public Modifier {
300     DECLARE_ACE_TYPE(ContentModifier, Modifier);
301 
302 public:
ContentModifier()303     ContentModifier()
304     {
305         changeCount_ = MakeRefPtr<PropertyInt>(0);
306         AttachProperty(changeCount_);
307     };
308     ~ContentModifier() override = default;
309     virtual void onDraw(DrawingContext& Context) = 0;
310 
311     void Draw(DrawingContext& Context);
312 
AttachProperty(const RefPtr<PropertyBase> & prop)313     void AttachProperty(const RefPtr<PropertyBase>& prop)
314     {
315         attachedProperties_.push_back(prop);
316     }
317 
GetAttachedProperties()318     const std::vector<RefPtr<PropertyBase>>& GetAttachedProperties()
319     {
320         return attachedProperties_;
321     }
322 
GetBoundsRect()323     const std::optional<RectF>& GetBoundsRect()
324     {
325         return rect_;
326     }
327 
SetBoundsRect(const std::optional<RectF> & rect)328     void SetBoundsRect(const std::optional<RectF>& rect)
329     {
330         rect_ = rect;
331     }
332 
SetIsCustomFont(bool isCustomFont)333     void SetIsCustomFont(bool isCustomFont)
334     {
335         isCustomFont_ = isCustomFont;
336     }
337 
GetIsCustomFont()338     bool GetIsCustomFont() const
339     {
340         return isCustomFont_;
341     }
342 
SetContentChange()343     void SetContentChange()
344     {
345         changeCount_->Set(changeCount_->Get() + 1);
346     }
347 
348     void SetExtensionHandler(ExtensionHandler* extensionHandler);
349 
350 private:
351     std::vector<RefPtr<PropertyBase>> attachedProperties_;
352     std::optional<RectF> rect_;
353     bool isCustomFont_ = false;
354     RefPtr<PropertyInt> changeCount_; // use to trigger rerendering
355     ExtensionHandler* extensionHandler_ = nullptr;
356 
357     ACE_DISALLOW_COPY_AND_MOVE(ContentModifier);
358 };
359 
360 class ModifierImpl {
361 };
362 
363 class NodeAnimatablePropertyBase : public AceType {
364     DECLARE_ACE_TYPE(NodeAnimatablePropertyBase, AceType);
365 
366 public:
367     NodeAnimatablePropertyBase() = default;
368     ~NodeAnimatablePropertyBase() override = default;
369 
GetModifyImpl()370     const std::shared_ptr<ModifierImpl>& GetModifyImpl() const
371     {
372         return modifyImpl_;
373     }
374 
SetModifyImpl(const std::shared_ptr<ModifierImpl> & impl)375     void SetModifyImpl(const std::shared_ptr<ModifierImpl>& impl)
376     {
377         modifyImpl_ = impl;
378     }
379 
GetProperty()380     const RefPtr<PropertyBase>& GetProperty() const
381     {
382         return property_;
383     }
384 
SetProperty(const RefPtr<PropertyBase> & property)385     void SetProperty(const RefPtr<PropertyBase>& property)
386     {
387         property_ = property;
388     }
389 
390 private:
391     std::shared_ptr<ModifierImpl> modifyImpl_;
392     RefPtr<PropertyBase> property_;
393 
394     ACE_DISALLOW_COPY_AND_MOVE(NodeAnimatablePropertyBase);
395 };
396 
397 using FinishCallback = std::function<void()>;
398 
399 template<typename T, typename S>
400 class NodeAnimatableProperty : public NodeAnimatablePropertyBase {
401     DECLARE_ACE_TYPE(NodeAnimatableProperty, NodeAnimatablePropertyBase);
402 
403 public:
NodeAnimatableProperty(const T & value,std::function<void (const T &)> && updateCallback)404     NodeAnimatableProperty(const T& value, std::function<void(const T&)>&& updateCallback)
405     {
406         auto property = AceType::MakeRefPtr<S>(value);
407         property->SetUpdateCallback(std::move(updateCallback));
408         SetProperty(property);
409     }
410     ~NodeAnimatableProperty() override = default;
411 
Set(const T & value)412     void Set(const T& value)
413     {
414         auto property = AceType::DynamicCast<S>(GetProperty());
415         if (property) {
416             property->Set(value);
417         }
418     }
419 
420     void SetThresholdType(ThresholdType type);
421 
422     void SetPropertyUnit(PropertyUnit unit);
423 
Get()424     T Get() const
425     {
426         auto property = AceType::DynamicCast<S>(GetProperty());
427         if (property) {
428             return property->Get();
429         }
430         return {};
431     }
432     void AnimateWithVelocity(const AnimationOption& option, T value, T velocity,
433         const FinishCallback& finishCallback);
434 private:
435     ACE_DISALLOW_COPY_AND_MOVE(NodeAnimatableProperty);
436 };
437 
438 using NodeAnimatablePropertyFloat = NodeAnimatableProperty<float, AnimatablePropertyFloat>;
439 using NodeAnimatableArithmeticProperty =
440     NodeAnimatableProperty<RefPtr<CustomAnimatableArithmetic>, AnimatableArithmeticProperty>;
441 } // namespace OHOS::Ace::NG
442 
443 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_MODIFIER_H
444