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_FLEX_RENDER_FLEX_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_FLEX_RENDER_FLEX_H
18 
19 #include "core/components/common/layout/constants.h"
20 #include "core/components/common/properties/text_style.h"
21 #include "core/components/flex/render_flex_item.h"
22 #include "core/pipeline/base/render_node.h"
23 
24 namespace OHOS::Ace {
25 
26 class FlexComponent;
27 
28 struct FlexItemProperties {
29     double totalShrink = 0.0;
30     double totalGrow = 0.0;
31     RefPtr<RenderFlexItem> lastShrinkChild;
32     RefPtr<RenderFlexItem> lastGrowChild;
33 };
34 
35 struct BaselineProperties {
36     double maxBaselineDistance = 0.0;
37     double maxDistanceAboveBaseline = 0.0;
38     double maxDistanceBelowBaseline = 0.0;
39 };
40 
41 struct MagicLayoutNode {
42     LayoutParam innerLayout = LayoutParam(Size(), Size());
43     RefPtr<RenderNode> node;
44 };
45 
46 class ACE_EXPORT RenderFlex : public RenderNode {
47     DECLARE_ACE_TYPE(RenderFlex, RenderNode);
48 
49 public:
50     static RefPtr<RenderNode> Create();
51 
52     void Update(const RefPtr<Component>& component) override;
53 
54     void PerformLayout() override;
55 
GetDirection()56     FlexDirection GetDirection() const
57     {
58         return direction_;
59     }
60 
GetJustifyContent()61     FlexAlign GetJustifyContent() const
62     {
63         return mainAxisAlign_;
64     }
65 
GetAlignItems()66     FlexAlign GetAlignItems() const
67     {
68         return crossAxisAlign_;
69     }
70 
GetSpace()71     double GetSpace() const
72     {
73         return space_;
74     }
75 
GetInspectorSpace()76     Dimension GetInspectorSpace() const
77     {
78         return inspectorSpace_;
79     }
80 
GetBaseline()81     TextBaseline GetBaseline() const
82     {
83         return textBaseline_;
84     }
85 
IsStretchToParent()86     bool IsStretchToParent() const
87     {
88         return stretchToParent_;
89     }
90 
GetAlignItem()91     FlexAlign GetAlignItem() const
92     {
93         return crossAxisAlign_;
94     }
95 
GetAlignPtr()96     AlignDeclarationPtr GetAlignPtr() const
97     {
98         return alignPtr_;
99     }
100     double GetBaselineDistance(TextBaseline baseline) override;
101 
102     Size GetChildViewPort() override;
103 
104     void OnChildRemoved(const RefPtr<RenderNode>& child) override;
105 
106     void Dump() override;
107 
IsChildOverflow()108     bool IsChildOverflow() const
109     {
110         return isChildOverflow_;
111     }
112 
113     bool GetAlignDeclarationOffset(AlignDeclarationPtr alignDeclarationPtr, Offset& offset) const override;
114 
115     bool CheckIfNeedLayoutAgain() override;
116 
117     void OnVisibleChanged() override;
118 
119     std::string ProvideRestoreInfo() override;
120 
121 protected:
122     void ClearRenderObject() override;
123     bool MaybeRelease() override;
124 
125     Overflow overflow_ = Overflow::CLIP;
126     bool isChildOverflow_ = false;
127 
128     bool isTabs_ = false;
129     bool isTabContent_ = false;
130 
131 private:
132     void PerformLayoutInWeightMode();
133     void PerformLayoutInIndexMode();
134     void PerformLayoutInItemMode();
135 
136     void LayoutMagicNodes(BaselineProperties& baselineProperties);
137     void RelayoutForStretchMagicNode();
138     void RelayoutForStretchFlexNode(const FlexItemProperties& flexItemProperties);
139     void LayoutHiddenNodes();
140 
141     /**
142      * This function is used to travel a single flex item in the first time layout to determine the flexItemProperties.
143      *
144      * @param flexItem The item under operation.
145      * @param flexItemProperties Store all the flex item properties.
146      */
147     void LayoutFlexItem(RefPtr<RenderFlexItem>& flexItem, FlexItemProperties& flexItemProperties);
148 
149     void RedoLayoutFlexItem(const RefPtr<RenderFlexItem>& flexItem, double flexSize, BaselineProperties& baselineProps,
150         double& allocatedFlexSpace);
151 
152     void LayoutInfinityChild(const RefPtr<RenderNode>& item, double mainSize, BaselineProperties& baselineProperties);
153 
154     /**
155      * This function is used to determine all the items' sizes in the second time layout according to the
156      * flexItemProperties. The size of Flex(Row/Column) will be resized by the flex item.
157      *
158      * @param flexItemProps FlexItemProperties.
159      * @param baselineProps The distance properties of baseline.
160      */
161     void ResizeItems(const FlexItemProperties& flexItemProps, BaselineProperties& baselineProps);
162 
163     void DetermineSelfSize(MainAxisSize mainAxisSize, bool useViewPort);
164 
165     void DetermineItemsPosition(const BaselineProperties& baselineProperties);
166 
167     /**
168      * This function is used to calculate the frontSpace and the betweenSpace according to mainAxisAlign and
169      * remainSpace. Only when the allocated size is smaller than the maxMainSize, it can be effective. In other word, it
170      * requires all the items are not flex items.
171      *
172      * @param remainSpace Remain space.
173      * @param frontSpace The space before the first item.
174      * @param betweenSpace The space between two items.
175      */
176     void CalculateSpace(double remainSpace, double& frontSpace, double& betweenSpace) const;
177 
178     /**
179      * This function is used to place all the items according to the size and the space.
180      *
181      * @param frontSpace The space before the first item.
182      * @param betweenSpace The space between two items.
183      * @param baselineProperties The distance properties of baseline.
184      */
185     void PlaceChildren(double frontSpace, double betweenSpace, const BaselineProperties& baselineProperties);
186 
187     void LayoutAbsoluteChildren();
188 
189     void CheckBaselineProperties(const RefPtr<RenderNode>& item, BaselineProperties& baselineProperties);
190 
191     LayoutParam MakeStretchInnerLayoutParam(const RefPtr<RenderNode>& item) const;
192     LayoutParam MakeLayoutParamWithLimit(double minMainLimit, double maxMainLimit, bool isStretch) const;
193     LayoutParam MakeConstrainedLayoutParam(
194         double mainFlexExtent, const LayoutParam& constraint, bool isStretch, bool supportZerolayout = false) const;
195 
196     void ResizeByItem(const RefPtr<RenderNode>& item, double& allocatedSize);
197     void CheckSizeValidity(const RefPtr<RenderNode>& item);
198     Size GetConstrainedSize(double mainSize);
199     double GetAvailableMainSize();
200     double GetMainSize(const RefPtr<RenderNode>& item) const;
201     double GetCrossSize(const RefPtr<RenderNode>& item) const;
202     double GetStretchCrossLimit() const;
203     void InitFlexProperties();
204     void TravelChildrenFlexProps();
205     void ClearChildrenLists();
206     FlexAlign GetSelfAlign(const RefPtr<RenderNode>& item) const;
207     TextDirection AdjustTextDirectionByDir();
208     void UpdateAccessibilityAttr();
209     void OnPaintFinish() override;
210 
211     bool IsStartTopLeft(FlexDirection direction, TextDirection textDir) const;
212 
213     void PerformItemAlign(std::list<RefPtr<RenderNode>>& nodelist);
214 
215     FlexDirection direction_ = FlexDirection::ROW;
216     FlexAlign mainAxisAlign_ = FlexAlign::FLEX_START;
217     FlexAlign crossAxisAlign_ = FlexAlign::FLEX_START;
218     MainAxisSize mainAxisSize_ = MainAxisSize::MAX;
219     CrossAxisSize crossAxisSize_ = CrossAxisSize::MIN;
220     TextBaseline textBaseline_ = TextBaseline::ALPHABETIC;
221     FlexLayoutMode layoutMode_ = FlexLayoutMode::FLEX_ITEM_MODE;
222     bool stretchToParent_ = false;
223 
224     double mainSize_ = 0.0;
225     double crossSize_ = 0.0;
226     double allocatedSize_ = 0.0;
227 
228     double space_ = 0.0;
229     Dimension inspectorSpace_;
230 
231     std::set<RefPtr<RenderNode>> infinityLayoutNodes_;
232     std::set<RefPtr<RenderNode>> absoluteNodes_;
233     std::list<RefPtr<RenderNode>> relativeNodes_;
234     std::list<RefPtr<RenderFlexItem>> stretchNodes_;
235     // use map to order the magic Nodes
236     std::map<int32_t, std::list<MagicLayoutNode>> magicNodes_;
237     std::map<int32_t, double> magicWeightMaps_;
238     std::set<RefPtr<RenderNode>> displayNodes_; // displayNodes_ used to record all display nodes in magic layout
239 
240     RefPtr<RenderNode> scrollNode;
241     bool isMainInfinite_ = false;
242     bool isCrossInfinite_ = false;
243     bool useViewPort_ = false;
244     bool containsNavigation_ = false;
245     double navigationMainSize_ = 0.0;
246     int32_t validSizeCount_ = 0;
247     double totalFlexWeight_ = 0.0;
248     int32_t maxDisplayIndex_ = 0;
249     bool useOldLayoutVersion_ = false;
250     bool isDeclarative_ = false;
251     bool needRelayoutCross_ = false;
252 
253     AlignDeclarationPtr alignPtr_ = nullptr;
254 };
255 
256 } // namespace OHOS::Ace
257 
258 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_FLEX_RENDER_FLEX_H
259