• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "core/components/flex/render_flex_item.h"
17 
18 #include "base/log/dump_log.h"
19 #include "base/utils/utils.h"
20 #include "core/components/flex/flex_item_component.h"
21 
22 namespace OHOS::Ace {
23 
Create()24 RefPtr<RenderNode> RenderFlexItem::Create()
25 {
26     return AceType::MakeRefPtr<RenderFlexItem>();
27 }
28 
Update(const RefPtr<Component> & component)29 void RenderFlexItem::Update(const RefPtr<Component>& component)
30 {
31     const RefPtr<FlexItemComponent> flexItem = AceType::DynamicCast<FlexItemComponent>(component);
32     if (!flexItem) {
33         return;
34     }
35     // check the validity of properties
36     SetId(flexItem->GetInspectorKey());
37     SetAlignRules(flexItem->GetAlignRules());
38     if (flexItem->GetFlexShrink() >= 0.0) {
39         flexShrink_ = flexItem->GetFlexShrink();
40     }
41     if (flexItem->GetFlexBasis().Value() >= 0.0) {
42         flexBasis_ = flexItem->GetFlexBasis();
43     }
44     if (flexItem->GetFlexGrow() >= 0.0) {
45         flexGrow_ = flexItem->GetFlexGrow();
46     }
47     gridColumnInfo_ = flexItem->GetGridColumnInfo();
48     canStretch_ = flexItem->GetStretchFlag();
49     mustStretch_ = flexItem->MustStretch();
50     alignSelf_ = flexItem->GetAlignSelf();
51     if (minWidth_ != flexItem->GetMinWidth() || maxWidth_ != flexItem->GetMaxWidth() ||
52         minHeight_ != flexItem->GetMinHeight() || maxHeight_ != flexItem->GetMaxHeight()) {
53         auto parentFlex = GetParent().Upgrade();
54         if (parentFlex) {
55             parentFlex->MarkNeedLayout();
56         }
57     }
58     minWidth_ = flexItem->GetMinWidth();
59     minHeight_ = flexItem->GetMinHeight();
60     maxWidth_ = flexItem->GetMaxWidth();
61     maxHeight_ = flexItem->GetMaxHeight();
62     isHidden_ = flexItem->IsHidden();
63     displayType_ = flexItem->GetDisplayType();
64     MarkNeedLayout();
65 }
66 
PerformLayout()67 void RenderFlexItem::PerformLayout()
68 {
69     RenderProxy::PerformLayout();
70     if (!gridColumnInfo_) {
71         return;
72     }
73     auto offset = gridColumnInfo_->GetOffset();
74     if (offset != UNDEFINED_DIMENSION) {
75         positionParam_.type = PositionType::PTSEMI_RELATIVE;
76         std::pair<AnimatableDimension, bool>& edge =
77             (GetTextDirection() == TextDirection::RTL) ? positionParam_.right : positionParam_.left;
78         edge.first = offset;
79         edge.second = true;
80     }
81 }
82 
MaybeRelease()83 bool RenderFlexItem::MaybeRelease()
84 {
85     auto context = GetContext().Upgrade();
86     if (context && context->GetRenderFactory() &&
87         context->GetRenderFactory()->GetRenderFlexItemFactory()->Recycle(this)) {
88         ClearRenderObject();
89         return false;
90     }
91     return true;
92 }
93 
ClearRenderObject()94 void RenderFlexItem::ClearRenderObject()
95 {
96     RenderNode::ClearRenderObject();
97     flexGrow_ = 0.0;
98     flexShrink_ = 0.0;
99     flexBasis_ = 0.0_px;
100     canStretch_ = true;
101     mustStretch_ = false;
102     minWidth_ = Dimension();
103     minHeight_ = Dimension();
104     maxWidth_ = Dimension(Size::INFINITE_SIZE);
105     maxHeight_ = Dimension(Size::INFINITE_SIZE);
106     alignSelf_ = FlexAlign::AUTO;
107     relativeLeftAligned_ = false;
108     relativeRightAligned_ = false;
109     relativeMiddleAligned_ = false;
110     relativeTopAligned_ = false;
111     relativeBottomAligned_ = false;
112     relativeCenterAligned_ = false;
113     relativeLeft_ = 0.0;
114     relativeRight_ = 0.0;
115     relativeMiddle_ = 0.0;
116     relativeTop_ = 0.0;
117     relativeBottom_ = 0.0;
118     relativeCenter_ = 0.0;
119 }
120 
SetAligned(const AlignDirection & alignDirection)121 void RenderFlexItem::SetAligned(const AlignDirection& alignDirection)
122 {
123     static const std::unordered_map<AlignDirection, void (*)(RenderFlexItem&)> operators = {
124         { AlignDirection::LEFT, [](RenderFlexItem& item) {
125             item.relativeLeftAligned_ = true;
126         }},
127         { AlignDirection::RIGHT, [](RenderFlexItem& item) {
128             item.relativeRightAligned_ = true;
129         }},
130         { AlignDirection::MIDDLE, [](RenderFlexItem& item) {
131             item.relativeMiddleAligned_ = true;
132         }},
133         { AlignDirection::TOP, [](RenderFlexItem& item) {
134             item.relativeTopAligned_ = true;
135         }},
136         { AlignDirection::BOTTOM, [](RenderFlexItem& item) {
137             item.relativeBottomAligned_ = true;
138         }},
139         { AlignDirection::CENTER, [](RenderFlexItem& item) {
140             item.relativeCenterAligned_ = true;
141         }},
142     };
143     auto operatorIter = operators.find(alignDirection);
144     if (operatorIter != operators.end()) {
145         operatorIter->second(*this);
146         return;
147     }
148     LOGE("Unknown Align Direction");
149 }
150 
GetAligned(AlignDirection & alignDirection)151 bool RenderFlexItem::GetAligned(AlignDirection& alignDirection)
152 {
153     static const std::unordered_map<AlignDirection, bool (*)(RenderFlexItem&)> operators = {
154         { AlignDirection::LEFT, [](RenderFlexItem& item) {
155             return item.relativeLeftAligned_;
156         }},
157         { AlignDirection::RIGHT, [](RenderFlexItem& item) {
158             return item.relativeRightAligned_;
159         }},
160         { AlignDirection::MIDDLE, [](RenderFlexItem& item) {
161             return item.relativeMiddleAligned_;
162         }},
163         { AlignDirection::TOP, [](RenderFlexItem& item) {
164             return item.relativeTopAligned_;
165         }},
166         { AlignDirection::BOTTOM, [](RenderFlexItem& item) {
167             return item.relativeBottomAligned_;
168         }},
169         { AlignDirection::CENTER, [](RenderFlexItem& item) {
170             return item.relativeCenterAligned_;
171         }},
172     };
173     auto operatorIter = operators.find(alignDirection);
174     if (operatorIter != operators.end()) {
175         return operatorIter->second(*this);
176     }
177     LOGE("Unknown Align Direction");
178     return false;
179 }
180 
GetAlignValue(AlignDirection & alignDirection)181 double RenderFlexItem::GetAlignValue(AlignDirection& alignDirection)
182 {
183     static const std::unordered_map<AlignDirection, double (*)(RenderFlexItem&)> operators = {
184         { AlignDirection::LEFT, [](RenderFlexItem& item) {
185             return item.relativeLeft_;
186         }},
187         { AlignDirection::RIGHT, [](RenderFlexItem& item) {
188             return item.relativeRight_;
189         }},
190         { AlignDirection::MIDDLE, [](RenderFlexItem& item) {
191             return item.relativeMiddle_;
192         }},
193         { AlignDirection::TOP, [](RenderFlexItem& item) {
194             return item.relativeTop_;
195         }},
196         { AlignDirection::BOTTOM, [](RenderFlexItem& item) {
197             return item.relativeBottom_;
198         }},
199         { AlignDirection::CENTER, [](RenderFlexItem& item) {
200             return item.relativeCenter_;
201         }},
202     };
203     auto operatorIter = operators.find(alignDirection);
204     if (operatorIter != operators.end()) {
205         return operatorIter->second(*this);
206     }
207     LOGE("Unknown Align Direction");
208     return 0.0;
209 }
210 
SetAlignValue(AlignDirection & alignDirection,double value)211 void RenderFlexItem::SetAlignValue(AlignDirection& alignDirection, double value)
212     {
213     static const std::unordered_map<AlignDirection, void (*)(double, RenderFlexItem&)> operators = {
214         { AlignDirection::LEFT, [](double inMapvalue, RenderFlexItem& item) {
215             item.relativeLeft_ = inMapvalue;
216             item.relativeLeftAligned_ = true;
217         }},
218         { AlignDirection::RIGHT, [](double inMapvalue, RenderFlexItem& item) {
219             item.relativeRight_ = inMapvalue;
220             item.relativeRightAligned_ = true;
221         }},
222         { AlignDirection::MIDDLE, [](double inMapvalue, RenderFlexItem& item) {
223             item.relativeMiddle_ = inMapvalue;
224             item.relativeMiddleAligned_ = true;
225         }},
226         { AlignDirection::TOP, [](double inMapvalue, RenderFlexItem& item) {
227             item.relativeTop_ = inMapvalue;
228             item.relativeTopAligned_ = true;
229         }},
230         { AlignDirection::BOTTOM, [](double inMapvalue, RenderFlexItem& item) {
231             item.relativeBottom_ = inMapvalue;
232             item.relativeBottomAligned_ = true;
233         }},
234         { AlignDirection::CENTER, [](double inMapvalue, RenderFlexItem& item) {
235             item.relativeCenter_ = inMapvalue;
236             item.relativeCenterAligned_ = true;
237         }},
238     };
239     auto operatorIter = operators.find(alignDirection);
240     if (operatorIter != operators.end()) {
241         operatorIter->second(value, *this);
242         return;
243     }
244     LOGE("Unknown Align Direction");
245 }
246 
Dump()247 void RenderFlexItem::Dump()
248 {
249     DumpLog::GetInstance().AddDesc(std::string("FlexGrow: ")
250                                        .append(std::to_string(flexGrow_))
251                                        .append(", FlexShrink: ")
252                                        .append(std::to_string(flexShrink_))
253                                        .append(", FlexBasis: ")
254                                        .append(std::to_string(flexBasis_.Value())));
255 }
256 
257 } // namespace OHOS::Ace
258