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_PATTERN_FLEX_FLEX_LAYOUT_PATTERN_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_FLEX_FLEX_LAYOUT_PATTERN_H
18 
19 #include <string>
20 
21 #include "base/log/dump_log.h"
22 #include "core/components_ng/base/inspector_filter.h"
23 #include "core/components_ng/pattern/flex/flex_layout_algorithm.h"
24 #include "core/components_ng/pattern/flex/flex_layout_property.h"
25 #include "core/components_ng/pattern/flex/wrap_layout_algorithm.h"
26 #include "core/components_ng/pattern/pattern.h"
27 
28 namespace OHOS::Ace::NG {
29 class FlexLayoutPattern : public Pattern {
30     DECLARE_ACE_TYPE(FlexLayoutPattern, Pattern);
31 
32 public:
33     FlexLayoutPattern() = default;
FlexLayoutPattern(bool wrap)34     explicit FlexLayoutPattern(bool wrap) : isWrap_(wrap) {};
35     ~FlexLayoutPattern() override = default;
36 
CreateLayoutProperty()37     RefPtr<LayoutProperty> CreateLayoutProperty() override
38     {
39         return MakeRefPtr<FlexLayoutProperty>();
40     }
41 
CreateLayoutAlgorithm()42     RefPtr<LayoutAlgorithm> CreateLayoutAlgorithm() override
43     {
44         if (isWrap_) {
45             return MakeRefPtr<WrapLayoutAlgorithm>(isDialogStretch_);
46         }
47         return MakeRefPtr<FlexLayoutAlgorithm>();
48     }
49 
IsAtomicNode()50     bool IsAtomicNode() const override
51     {
52         return false;
53     }
54 
IsNeedPercent()55     bool IsNeedPercent() const override
56     {
57         return true;
58     }
59 
GetFocusPattern()60     FocusPattern GetFocusPattern() const override
61     {
62         return { FocusType::SCOPE, true };
63     }
64 
GetScopeFocusAlgorithm()65     ScopeFocusAlgorithm GetScopeFocusAlgorithm() override
66     {
67         auto property = GetLayoutProperty<FlexLayoutProperty>();
68         if (!property) {
69             return {};
70         }
71         bool isVertical = false;
72         if (property->GetFlexDirection().has_value()) {
73             isVertical = property->GetFlexDirection().value() == FlexDirection::COLUMN ||
74                          property->GetFlexDirection().value() == FlexDirection::COLUMN_REVERSE;
75         }
76         return { isVertical, true, isWrap_ ? ScopeType::PROJECT_AREA : ScopeType::FLEX };
77     }
78 
SetDialogStretch(bool stretch)79     void SetDialogStretch(bool stretch)
80     {
81         isDialogStretch_ = stretch;
82     }
83 
DumpInfo()84     void DumpInfo() override
85     {
86         DumpLog::GetInstance().AddDesc(std::string("Type: ").append(isWrap_ ? "Wrap" : "NoWrap"));
87     }
88 
DumpSimplifyInfo(std::unique_ptr<JsonValue> & json)89     void DumpSimplifyInfo(std::unique_ptr<JsonValue>& json) override
90     {
91         json->Put("Type", isWrap_ ? "Wrap" : "NoWrap");
92     }
93 
GetIsWrap()94     bool GetIsWrap() const
95     {
96         return isWrap_;
97     }
98 
SetIsWrap(bool isWrap)99     void SetIsWrap(bool isWrap)
100     {
101         isWrap_ = isWrap;
102     }
103 
ToJsonValue(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter)104     void ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const override
105     {
106         /* no fixed attr below, just return */
107         if (filter.IsFastFilter()) {
108             return;
109         }
110         auto property = GetLayoutProperty<FlexLayoutProperty>();
111         CHECK_NULL_VOID(property);
112         auto jsonConstructor = JsonUtil::Create(true);
113         auto direction = property->GetFlexDirection().value_or(FlexDirection::ROW);
114         jsonConstructor->Put("direction", V2::ConvertFlexDirectionToStirng(direction).c_str());
115         if (!isWrap_) {
116             jsonConstructor->Put("wrap", "FlexWrap.NoWrap");
117             jsonConstructor->Put("justifyContent",
118                 V2::ConvertFlexAlignToStirng(property->GetMainAxisAlign().value_or(FlexAlign::FLEX_START)).c_str());
119             jsonConstructor->Put("alignItems",
120                 V2::ConvertItemAlignToStirng(property->GetCrossAxisAlign().value_or(FlexAlign::FLEX_START)).c_str());
121             jsonConstructor->Put("alignContent", "FlexAlign.Start");
122         } else {
123             auto wrapDirection = property->GetWrapDirection().value_or(WrapDirection::HORIZONTAL);
124             if (static_cast<int32_t>(direction) <= 1) {
125                 auto wrap = (static_cast<int32_t>(wrapDirection) - static_cast<int32_t>(direction)) / 2 + 1;
126                 jsonConstructor->Put("wrap", wrap == 1 ? "FlexWrap.Wrap" : "FlexWrap.WrapReverse");
127             } else {
128                 auto wrap = (static_cast<int32_t>(wrapDirection) + static_cast<int32_t>(direction)) / 2 + 1;
129                 jsonConstructor->Put("wrap", wrap == 1 ? "FlexWrap.Wrap" : "FlexWrap.WrapReverse");
130             }
131             jsonConstructor->Put("justifyContent",
132                 V2::ConvertWrapAlignmentToStirng(property->GetMainAlignment().value_or(WrapAlignment::START)).c_str());
133             jsonConstructor->Put("alignItems",
134                 V2::ConvertItemAlignToStirng(property->GetCrossAlignment().value_or(WrapAlignment::START)).c_str());
135             jsonConstructor->Put("alignContent",
136                 V2::ConvertWrapAlignmentToStirng(property->GetAlignment().value_or(WrapAlignment::START)).c_str());
137         }
138         json->PutExtAttr("constructor", jsonConstructor, filter);
139         json->PutExtAttr("space", SpaceToString().c_str(), filter);
140     }
141 
FromJson(const std::unique_ptr<JsonValue> & json)142     void FromJson(const std::unique_ptr<JsonValue>& json) override
143     {
144         auto property = GetLayoutProperty<FlexLayoutProperty>();
145         CHECK_NULL_VOID(property);
146         if (json->Contains("constructor")) {
147             auto constructor = json->GetValue("constructor");
148             property->UpdateFlexDirection(V2::ConvertStringToFlexDirection(constructor->GetString("direction")));
149             property->UpdateMainAxisAlign(V2::ConvertStringToFlexAlign(constructor->GetString("justifyContent")));
150             property->UpdateCrossAxisAlign(V2::ConvertStringToFlexAlign(constructor->GetString("alignItems")));
151             if (constructor->GetString("wrap") == "FlexWrap.NoWrap") {
152                 SetIsWrap(false);
153                 property->UpdateMainAxisAlign(V2::ConvertStringToFlexAlign(constructor->GetString("justifyContent")));
154                 property->UpdateCrossAxisAlign(V2::ConvertStringToItemAlign(constructor->GetString("alignItems")));
155             }
156         }
157         Pattern::FromJson(json);
158     }
159 
SpaceToString()160     std::string SpaceToString() const
161     {
162         auto host = GetHost();
163         CHECK_NULL_RETURN(host, Dimension().ToString());
164         auto layoutProperty = host->GetLayoutProperty<FlexLayoutProperty>();
165         CHECK_NULL_RETURN(layoutProperty, Dimension().ToString());
166         return layoutProperty->GetSpaceValue(Dimension()).ToString();
167     }
168 
IsNeedInitClickEventRecorder()169     bool IsNeedInitClickEventRecorder() const override
170     {
171         return true;
172     }
173 
174 private:
175     bool isWrap_ = false;
176     bool isDialogStretch_ = false;
177 
178     ACE_DISALLOW_COPY_AND_MOVE(FlexLayoutPattern);
179 };
180 } // namespace OHOS::Ace::NG
181 
182 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_FLEX_FLEX_LAYOUT_PATTERN_H
183