• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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_NG_PROPERTIES_FLEX_PROPERTIES_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PROPERTIES_FLEX_PROPERTIES_H
18 
19 #include <map>
20 
21 #include "base/geometry/dimension.h"
22 #include "base/json/json_util.h"
23 #include "core/components/common/layout/constants.h"
24 #include "core/components/common/layout/position_param.h"
25 #include "core/components_ng/base/inspector_filter.h"
26 #include "core/components_ng/property/property.h"
27 
28 namespace OHOS::Ace::NG {
29 using AlignRulesItem = std::map<AlignDirection, AlignRule>;
30 using BiasPair = std::pair<float, float>;
31 using GuidelineItem = std::vector<GuidelineInfo>;
32 using BarrierItem = std::vector<BarrierInfo>;
33 namespace {
34 constexpr int32_t HORIZONTAL_DIRECTION_RANGE = 3;
35 constexpr int32_t VERTICAL_DIRECTION_RANGE = 6;
HorizontalAlignToString(HorizontalAlign align)36 std::string HorizontalAlignToString(HorizontalAlign align)
37 {
38     switch (align) {
39         case HorizontalAlign::CENTER:
40             return "HorizontalAlign::Center";
41         case HorizontalAlign::START:
42             return "HorizontalAlign::Start";
43         case HorizontalAlign::END:
44             return "HorizontalAlign::End";
45         default:
46             return "Unknown";
47     }
48 }
49 
VerticalAlignToString(VerticalAlign align)50 std::string VerticalAlignToString(VerticalAlign align)
51 {
52     switch (align) {
53         case VerticalAlign::TOP:
54             return "VerticalAlign::Top";
55         case VerticalAlign::CENTER:
56             return "VerticalAlign::Center";
57         case VerticalAlign::BOTTOM:
58             return "VerticalAlign::Bottom";
59         case VerticalAlign::BASELINE:
60             return "VerticalAlign::BaseLine";
61         default:
62             return "Unknown";
63     }
64 }
65 
AlignDirectionToString(AlignDirection direction)66 std::string AlignDirectionToString(AlignDirection direction)
67 {
68     switch (direction) {
69         case AlignDirection::MIDDLE:
70             return "AlignDirection::Middle";
71         case AlignDirection::LEFT:
72             return "AlignDirection::Left";
73         case AlignDirection::RIGHT:
74             return "AlignDirection::Middle";
75         case AlignDirection::TOP:
76             return "AlignDirection::Top";
77         case AlignDirection::CENTER:
78             return "AlignDirection::Center";
79         case AlignDirection::BOTTOM:
80             return "AlignDirection::Bottom";
81         default:
82             return "Unknown";
83     }
84 }
85 
SingleAlignRuleToString(AlignDirection direction,AlignRule rule)86 std::string SingleAlignRuleToString(AlignDirection direction, AlignRule rule)
87 {
88     std::string result = AlignDirectionToString(direction) + ": {'" + rule.anchor + "', ";
89     if (static_cast<int32_t>(direction) < HORIZONTAL_DIRECTION_RANGE) {
90         result += HorizontalAlignToString(rule.horizontal);
91     } else if (static_cast<int32_t>(direction) < VERTICAL_DIRECTION_RANGE) {
92         result += VerticalAlignToString(rule.vertical);
93     } else {
94         result += "Unknown";
95     }
96     result += "}";
97     return result;
98 }
99 } // namespace
100 
101 struct FlexItemProperty {
102     ACE_DEFINE_PROPERTY_GROUP_ITEM(FlexGrow, float);
103     ACE_DEFINE_PROPERTY_GROUP_ITEM(FlexShrink, float);
104     ACE_DEFINE_PROPERTY_GROUP_ITEM(AlignSelf, FlexAlign);
105     ACE_DEFINE_PROPERTY_GROUP_ITEM(FlexBasis, Dimension);
106     ACE_DEFINE_PROPERTY_GROUP_ITEM(DisplayIndex, int32_t);
107     ACE_DEFINE_PROPERTY_GROUP_ITEM(AlignRules, AlignRulesItem);
108     ACE_DEFINE_PROPERTY_GROUP_ITEM(HorizontalChainStyle, ChainInfo);
109     ACE_DEFINE_PROPERTY_GROUP_ITEM(VerticalChainStyle, ChainInfo);
110     ACE_DEFINE_PROPERTY_GROUP_ITEM(AlignLeft, float);
111     ACE_DEFINE_PROPERTY_GROUP_ITEM(AlignMiddle, float);
112     ACE_DEFINE_PROPERTY_GROUP_ITEM(AlignRight, float);
113     ACE_DEFINE_PROPERTY_GROUP_ITEM(AlignTop, float);
114     ACE_DEFINE_PROPERTY_GROUP_ITEM(AlignCenter, float);
115     ACE_DEFINE_PROPERTY_GROUP_ITEM(AlignBottom, float);
116     ACE_DEFINE_PROPERTY_GROUP_ITEM(Bias, BiasPair);
117     ACE_DEFINE_PROPERTY_GROUP_ITEM(Barrier, BarrierItem);
118     ACE_DEFINE_PROPERTY_GROUP_ITEM(Guideline, GuidelineItem);
119 
ToJsonValueFlexItemProperty120     void ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
121     {
122         static const char* ITEM_ALIGN[] = { "ItemAlign.Auto", "ItemAlign.Start", "ItemAlign.Center", "ItemAlign.End",
123             "ItemAlign.Stretch", "ItemAlign.Baseline" };
124         /* no fixed attr below, just return */
125         if (filter.IsFastFilter()) {
126             return;
127         }
128         json->PutExtAttr("flexBasis",
129             propFlexBasis.has_value() ? propFlexBasis.value().ToString().c_str() : "auto", filter);
130         json->PutExtAttr("flexGrow", round(static_cast<double>(propFlexGrow.value_or(0.0)) * 100) / 100, filter);
131         json->PutExtAttr("flexShrink", round(static_cast<double>(propFlexShrink.value_or(1)) * 100) / 100, filter);
132         json->PutExtAttr("alignSelf",
133             ITEM_ALIGN[static_cast<int32_t>(propAlignSelf.value_or(FlexAlign::AUTO))], filter);
134         json->PutExtAttr("displayPriority", propDisplayIndex.value_or(1), filter);
135     }
136 
AlignRulesToStringFlexItemProperty137     std::string AlignRulesToString()
138     {
139         std::string result;
140         if (!HasAlignRules()) {
141             return result;
142         }
143         auto rules = GetAlignRules().value();
144         auto iter = rules.begin();
145         for (; iter != rules.end(); iter++) {
146             result.append(SingleAlignRuleToString(iter->first, iter->second));
147             result.append(", ");
148         }
149         return result;
150     }
151 
ClearAlignValueFlexItemProperty152     void ClearAlignValue()
153     {
154         ResetAlignLeft();
155         ResetAlignRight();
156         ResetAlignMiddle();
157         ResetAlignTop();
158         ResetAlignBottom();
159         ResetAlignCenter();
160     }
161 
GetTwoHorizontalDirectionAlignedFlexItemProperty162     bool GetTwoHorizontalDirectionAligned() const
163     {
164         return (HasAlignLeft() && HasAlignRight()) || (HasAlignRight() && HasAlignMiddle()) ||
165                (HasAlignLeft() && HasAlignMiddle());
166     }
167 
GetTwoVerticalDirectionAlignedFlexItemProperty168     bool GetTwoVerticalDirectionAligned() const
169     {
170         return (HasAlignTop() && HasAlignCenter()) || (HasAlignBottom() && HasAlignCenter()) ||
171                (HasAlignTop() && HasAlignBottom());
172     }
173 
SetAlignValueFlexItemProperty174     void SetAlignValue(const AlignDirection& alignDirection, float value)
175     {
176         static const std::unordered_map<AlignDirection, void (*)(float, FlexItemProperty&)> operators = {
177             { AlignDirection::LEFT,
178                 [](float inMapValue, FlexItemProperty& item) { item.UpdateAlignLeft(inMapValue); } },
179             { AlignDirection::RIGHT,
180                 [](float inMapValue, FlexItemProperty& item) { item.UpdateAlignRight(inMapValue); } },
181             { AlignDirection::MIDDLE,
182                 [](float inMapValue, FlexItemProperty& item) { item.UpdateAlignMiddle(inMapValue); } },
183             { AlignDirection::TOP, [](float inMapValue, FlexItemProperty& item) { item.UpdateAlignTop(inMapValue); } },
184             { AlignDirection::BOTTOM,
185                 [](float inMapValue, FlexItemProperty& item) { item.UpdateAlignBottom(inMapValue); } },
186             { AlignDirection::CENTER,
187                 [](float inMapValue, FlexItemProperty& item) { item.UpdateAlignCenter(inMapValue); } },
188         };
189         auto operatorIter = operators.find(alignDirection);
190         if (operatorIter != operators.end()) {
191             operatorIter->second(value, *this);
192             return;
193         }
194         LOGE("Unknown Align Direction");
195     }
196 
GetAlignedFlexItemProperty197     bool GetAligned(const AlignDirection& alignDirection)
198     {
199         static const std::unordered_map<AlignDirection, bool (*)(FlexItemProperty&)> operators = {
200             { AlignDirection::LEFT, [](FlexItemProperty& item) { return item.HasAlignLeft(); } },
201             { AlignDirection::RIGHT, [](FlexItemProperty& item) { return item.HasAlignRight(); } },
202             { AlignDirection::MIDDLE, [](FlexItemProperty& item) { return item.HasAlignMiddle(); } },
203             { AlignDirection::TOP, [](FlexItemProperty& item) { return item.HasAlignTop(); } },
204             { AlignDirection::BOTTOM, [](FlexItemProperty& item) { return item.HasAlignBottom(); } },
205             { AlignDirection::CENTER, [](FlexItemProperty& item) { return item.HasAlignCenter(); } },
206         };
207         auto operatorIter = operators.find(alignDirection);
208         if (operatorIter != operators.end()) {
209             return operatorIter->second(*this);
210         }
211         LOGE("Unknown Align Direction");
212         return false;
213     }
214 
GetAlignValueFlexItemProperty215     float GetAlignValue(const AlignDirection& alignDirection)
216     {
217         static const std::unordered_map<AlignDirection, float (*)(FlexItemProperty&)> operators = {
218             { AlignDirection::LEFT, [](FlexItemProperty& item) { return item.GetAlignLeft().value_or(0.0f); } },
219             { AlignDirection::RIGHT, [](FlexItemProperty& item) { return item.GetAlignRight().value_or(0.0f); } },
220             { AlignDirection::MIDDLE, [](FlexItemProperty& item) { return item.GetAlignMiddle().value_or(0.0f); } },
221             { AlignDirection::TOP, [](FlexItemProperty& item) { return item.GetAlignTop().value_or(0.0f); } },
222             { AlignDirection::BOTTOM, [](FlexItemProperty& item) { return item.GetAlignBottom().value_or(0.0f); } },
223             { AlignDirection::CENTER, [](FlexItemProperty& item) { return item.GetAlignCenter().value_or(0.0f); } },
224         };
225         auto operatorIter = operators.find(alignDirection);
226         if (operatorIter != operators.end()) {
227             return operatorIter->second(*this);
228         }
229         LOGE("Unknown Align Direction");
230         return 0.0f;
231     }
232 };
233 } // namespace OHOS::Ace::NG
234 
235 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PROPERTIES_FLEX_PROPERTIES_H
236