1 /*
2  * Copyright (c) 2021-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_BOX_RENDER_BOX_BASE_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_BOX_RENDER_BOX_BASE_H
18 
19 #include "base/geometry/offset.h"
20 #include "base/geometry/size.h"
21 #include "core/animation/property_animatable.h"
22 #include "core/animation/property_animatable_helper.h"
23 #include "core/components/box/box_base_component.h"
24 #include "core/components/box/box_component.h"
25 #include "core/components/box/mask.h"
26 #include "core/components/common/layout/grid_column_info.h"
27 #include "core/components/common/properties/edge.h"
28 #include "core/pipeline/base/render_node.h"
29 
30 namespace OHOS::Ace {
31 
32 class RenderBoxBase : public RenderNode {
33     DECLARE_ACE_TYPE(RenderBoxBase, RenderNode);
34 
35 public:
36     using LayoutCallback = std::function<void()>;
37 
38     void Update(const RefPtr<Component>& component) override;
39     void PerformLayout() override;
40     void Dump() override;
41 
42     Offset GetPaintPosition() const;
43     const Size& GetPaintSize() const;
44     void SetPaintSize(const Size& paintSize);
45     virtual Size GetBorderSize() const;
46     double CalculateHeightPercent(double percent) const; // add for text filed
DrawOnPixelMap()47     virtual void DrawOnPixelMap() {}
48 
49     FloatPropertyAnimatable::SetterMap GetFloatPropertySetterMap() override;
50     FloatPropertyAnimatable::GetterMap GetFloatPropertyGetterMap() override;
51 
OnAttachContext()52     void OnAttachContext() override
53     {
54         width_.SetContextAndCallback(context_, [weak = WeakClaim(this)] {
55             auto renderBox = weak.Upgrade();
56             if (renderBox) {
57                 renderBox->OnAnimationCallback();
58             }
59         });
60         height_.SetContextAndCallback(context_, [weak = WeakClaim(this)] {
61             auto renderBox = weak.Upgrade();
62             if (renderBox) {
63                 renderBox->OnAnimationCallback();
64             }
65         });
66         marginOrigin_.SetContextAndCallback(context_, [weak = WeakClaim(this)] {
67             auto renderBox = weak.Upgrade();
68             if (renderBox) {
69                 renderBox->OnAnimationCallback();
70             }
71         });
72         paddingOrigin_.SetContextAndCallback(context_, [weak = WeakClaim(this)] {
73             auto renderBox = weak.Upgrade();
74             if (renderBox) {
75                 renderBox->OnAnimationCallback();
76             }
77         });
78         aspectRatio_.SetContextAndCallback(context_, [weak = WeakClaim(this)] {
79             auto renderBox = weak.Upgrade();
80             if (renderBox) {
81                 renderBox->OnAnimationCallback();
82             }
83         });
84     }
85 
GetColor()86     virtual const Color& GetColor() const
87     {
88         return Color::TRANSPARENT;
89     }
90 
UpdateStyleFromRenderNode(PropertyAnimatableType type)91     virtual void UpdateStyleFromRenderNode(PropertyAnimatableType type) {}
92 
GetMargin(const DimensionHelper & helper)93     AnimatableDimension GetMargin(const DimensionHelper& helper) const
94     {
95         return helper.Get(marginOrigin_);
96     }
97 
SetMargin(const AnimatableDimension & value,const DimensionHelper & helper)98     void SetMargin(const AnimatableDimension& value, const DimensionHelper& helper) // add for animation
99     {
100         if (helper.Set(value, &marginOrigin_)) {
101             MarkNeedLayout();
102         }
103     }
104 
GetPadding(const DimensionHelper & helper)105     AnimatableDimension GetPadding(const DimensionHelper& helper) const
106     {
107         return helper.Get(paddingOrigin_);
108     }
109 
SetPadding(const AnimatableDimension & value,const DimensionHelper & helper)110     void SetPadding(const AnimatableDimension& value, const DimensionHelper& helper) // add for animation
111     {
112         if (helper.Set(value, &paddingOrigin_)) {
113             MarkNeedLayout();
114         }
115     }
116 
SetPadding(const Edge & padding)117     void SetPadding(const Edge& padding)
118     {
119         paddingOrigin_ = padding;
120         MarkNeedLayout();
121     }
122 
GetWidth()123     double GetWidth() const // add for animation
124     {
125         return width_.Value();
126     }
127 
GetHeight()128     double GetHeight() const // add for animation
129     {
130         return height_.Value();
131     }
132 
SetWidth(double width)133     virtual void SetWidth(double width) // add for animation
134     {
135         if (GreatOrEqual(width, 0.0) && !NearEqual(width_.Value(), width)) {
136             width_.SetValue(width);
137             MarkNeedLayout();
138         }
139     }
140 
SetHeight(double height)141     virtual void SetHeight(double height) // add for animation
142     {
143         if (GreatOrEqual(height, 0.0) && !NearEqual(height_.Value(), height)) {
144             height_.SetValue(height);
145             MarkNeedLayout();
146         }
147     }
148 
SetWidth(const Dimension & width)149     virtual void SetWidth(const Dimension& width) // add for animation
150     {
151         if (width_ != width) {
152             width_ = width;
153             MarkNeedLayout();
154         }
155     }
156 
GetWidthDimension()157     Dimension GetWidthDimension() const
158     {
159         return width_;
160     }
161 
SetHeight(const Dimension & height)162     virtual void SetHeight(const Dimension& height) // add for animation
163     {
164         if (height_ != height) {
165             height_ = height;
166             MarkNeedLayout();
167         }
168     }
169 
GetHeightDimension()170     Dimension GetHeightDimension() const
171     {
172         return height_;
173     }
174 
GetMargin()175     EdgePx GetMargin() const
176     {
177         return margin_;
178     }
179 
GetPadding()180     EdgePx GetPadding() const
181     {
182         return padding_;
183     }
184 
GetMarginSize()185     Size GetMarginSize() const
186     {
187         return margin_.GetLayoutSize();
188     }
189 
GetPaddingSize()190     Size GetPaddingSize() const
191     {
192         return padding_.GetLayoutSize();
193     }
194 
SetLayoutCallback(LayoutCallback && layoutCallback)195     void SetLayoutCallback(LayoutCallback&& layoutCallback)
196     {
197         layoutCallback_ = layoutCallback;
198     }
199 
GetTouchArea()200     const Rect& GetTouchArea() const
201     {
202         return touchArea_;
203     }
204 
SetConstraints(const LayoutParam & constraints)205     void SetConstraints(const LayoutParam& constraints)
206     {
207         constraints_ = constraints;
208         MarkNeedLayout();
209     }
GetConstraints()210     const LayoutParam& GetConstraints()
211     {
212         return constraints_;
213     }
214 
SetBoxFlex(BoxFlex flex)215     void SetBoxFlex(BoxFlex flex)
216     {
217         flex_ = flex;
218     }
219 
GetAlignDeclarationPtr()220     AlignDeclarationPtr GetAlignDeclarationPtr() const
221     {
222         return alignPtr_;
223     }
224 
GetUseAlignSide()225     AlignDeclaration::Edge GetUseAlignSide() const
226     {
227         return alignSide_;
228     }
229 
GetUseAlignOffset()230     const Dimension& GetUseAlignOffset() const
231     {
232         return alignItemOffset_;
233     }
234 
235     virtual void CalculateAlignDeclaration();
236 
GetAlign()237     const Alignment& GetAlign() const
238     {
239         return align_;
240     }
241 
GetAspectRatio()242     double GetAspectRatio() const
243     {
244         return aspectRatio_.Value();
245     }
246 
SetAspectRatio(const Dimension & aspectRatio)247     void SetAspectRatio(const Dimension& aspectRatio)
248     {
249         aspectRatio_ = aspectRatio;
250     }
251 
GetClipPath()252     const RefPtr<ClipPath>& GetClipPath() const
253     {
254         return clipPath_;
255     }
256 
GetBoxClipFlag()257     bool GetBoxClipFlag() const
258     {
259         return boxClipFlag_;
260     }
261 
GetMask()262     const RefPtr<Mask>& GetMask() const
263     {
264         return mask_;
265     }
266 
GetGridColumnInfo()267     const RefPtr<GridColumnInfo>& GetGridColumnInfo() const
268     {
269         return gridColumnInfo_;
270     }
271 
GetGridContainerInfo()272     const RefPtr<GridContainerInfo>& GetGridContainerInfo() const
273     {
274         return gridContainerInfo_;
275     }
276 
GetPixelMap()277     const RefPtr<PixelMap>& GetPixelMap() const
278     {
279         return pixelMap_;
280     }
281 
GetPaintRectExcludeMargin()282     Rect GetPaintRectExcludeMargin() const
283     {
284         Rect rect;
285         rect.SetSize(paintSize_);
286         rect.SetOffset(GetPaintRect().GetOffset() + Offset(margin_.LeftPx(), margin_.TopPx()));
287         return rect;
288     }
289 
GetBoxComponent()290     const  WeakPtr<BoxComponent> GetBoxComponent() const
291     {
292         return boxComponent_;
293     }
294 
295 protected:
296     void ClearRenderObject() override;
297     virtual Offset GetBorderOffset() const;
298     virtual Radius GetBorderRadius() const;
299 
300     EdgePx ConvertEdgeToPx(const Edge& edge, bool additional);
301     double ConvertMarginToPx(CalcDimension dimension, bool vertical, bool additional) const;
302     double ConvertDimensionToPx(CalcDimension dimension, bool vertical, bool defaultZero = false) const;
303     double ConvertHorizontalDimensionToPx(CalcDimension dimension, bool defaultZero = false) const;
304     double ConvertVerticalDimensionToPx(CalcDimension dimension, bool defaultZero = false) const;
305     void CalculateWidth();
306     void CalculateHeight();
307     Edge SetAutoMargin(FlexDirection flexDir, double freeSpace, bool isFirst);
308     void CalculateAutoMargin();
309     void ConvertMarginPaddingToPx();
310     void ConvertConstraintsToPx();
311     void CalculateGridLayoutSize();
312     void CalculateSelfLayoutParam();
313     void SetChildLayoutParam();
314     void ConvertPaddingForLayoutInBox();
315     void CalculateSelfLayoutSize();
316     void CalculateChildPosition();
317     void AdjustSizeByAspectRatio();
318     virtual void OnAnimationCallback();
319 
320     AnimatableDimension width_ { AnimatableDimension(-1.0, DimensionUnit::PX) };  // exclude margin
321     AnimatableDimension height_ { AnimatableDimension(-1.0, DimensionUnit::PX) }; // exclude margin
322     AnimatableDimension aspectRatio_ = AnimatableDimension();
323 
324     BoxFlex flex_ = BoxFlex::FLEX_NO;
325     LayoutParam constraints_ = LayoutParam(Size(), Size()); // exclude margin
326     EdgePx padding_;
327     EdgePx margin_;
328     Alignment align_;
329     Size paintSize_; // exclude margin
330     Rect touchArea_; // exclude margin
331     bool deliverMinToChild_ = true;
332     bool scrollPage_ = false;
333     uint32_t percentFlag_ = 0;
334     bool layoutInBox_ = false;
335     Edge paddingOrigin_;
336     Edge marginOrigin_;
337     DisplayType displayType_;
338     LayoutCallback layoutCallback_;
339     bool useLiteStyle_ = false;
340     Overflow overflow_ = Overflow::OBSERVABLE;
341     bool isChildOverflow_ = false;
342     RefPtr<ClipPath> clipPath_;
343     RefPtr<Mask> mask_;
344     BoxSizing boxSizing_ = BoxSizing::BORDER_BOX;
345     WeakPtr<BoxComponent> boxComponent_;
346 
347     bool isUseAlign_ = false;
348     AlignDeclarationPtr alignPtr_ = nullptr;
349     AlignDeclaration::Edge alignSide_ { AlignDeclaration::Edge::AUTO };
350     Dimension alignItemOffset_;
351     Offset alignOffset_;
352     bool boxClipFlag_ = false;
353     RefPtr<PixelMap> pixelMap_ = nullptr;
354 
355 private:
356     bool IsSizeValid(const Dimension& value, double maxLimit);
357     bool IsDeclarativePara();
358 
359     Edge additionalPadding_;
360     bool useFlexWidth_ = false;
361     bool useFlexHeight_ = false;
362     bool selfDefineWidth_ = false;
363     bool selfDefineHeight_ = false;
364     double selfMaxWidth_ = Size::INFINITE_SIZE;  // exclude margin
365     double selfMinWidth_ = 0.0;                  // exclude margin
366     double selfMaxHeight_ = Size::INFINITE_SIZE; // exclude margin
367     double selfMinHeight_ = 0.0;                 // exclude margin
368     CalcDimension minWidth_ = Dimension();
369     CalcDimension minHeight_ = Dimension();
370     CalcDimension maxWidth_ = Dimension();
371     CalcDimension maxHeight_ = Dimension();
372 
373     // result for layout
374     LayoutParam selfLayoutParam_; // include margin
375     Size selfLayoutSize_;         // include margin
376     LayoutParam childLayoutParam_;
377     Size childSize_;
378     Offset childPosition_;
379 
380     bool needReCalc_ = false;
381     Edge marginBackup_;
382     double childWidth_ = 0.0;
383     double childHeight_ = 0.0;
384 
385     // grid layout
386     RefPtr<GridColumnInfo> gridColumnInfo_;
387     RefPtr<GridContainerInfo> gridContainerInfo_;
388 };
389 
390 } // namespace OHOS::Ace
391 
392 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_BOX_RENDER_BOX_BASE_H
393