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 DumpLog::GetInstance().AddDesc(std::string("FlexMeasureLayoutPaired: ") 88 .append(std::to_string(static_cast<int>(GetMeasureLayoutPaired())).c_str())); 89 DumpLog::GetInstance().AddDesc(std::string("FlexFrontSpace: ") 90 .append(std::to_string(layoutResult_.frontSpace).c_str()) 91 .append(std::string(" FlexBetweenSpace: ")) 92 .append(std::to_string(layoutResult_.betweenSpace).c_str())); 93 auto host = GetHost(); 94 CHECK_NULL_VOID(host); 95 auto layoutProperty = DynamicCast<FlexLayoutProperty>(host->GetLayoutProperty()); 96 CHECK_NULL_VOID(layoutProperty); 97 auto space = layoutProperty->GetSpace(); 98 if (space.has_value()) { 99 DumpLog::GetInstance().AddDesc(std::string("space: ").append(space.value().ToString().c_str())); 100 } 101 } 102 DumpSimplifyInfo(std::shared_ptr<JsonValue> & json)103 void DumpSimplifyInfo(std::shared_ptr<JsonValue>& json) override 104 { 105 json->Put("Type", isWrap_ ? "Wrap" : "NoWrap"); 106 json->Put("FlexMeasureLayoutPaired", GetMeasureLayoutPaired()); 107 json->Put("FlexFrontSpace", static_cast<double>(layoutResult_.frontSpace)); 108 json->Put("FlexBetweenSpace", static_cast<double>(layoutResult_.betweenSpace)); 109 } 110 GetIsWrap()111 bool GetIsWrap() const 112 { 113 return isWrap_; 114 } 115 SetIsWrap(bool isWrap)116 void SetIsWrap(bool isWrap) 117 { 118 isWrap_ = isWrap; 119 } 120 ToJsonValue(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter)121 void ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const override 122 { 123 /* no fixed attr below, just return */ 124 if (filter.IsFastFilter()) { 125 return; 126 } 127 auto property = GetLayoutProperty<FlexLayoutProperty>(); 128 CHECK_NULL_VOID(property); 129 auto jsonConstructor = JsonUtil::Create(true); 130 auto direction = property->GetFlexDirection().value_or(FlexDirection::ROW); 131 jsonConstructor->Put("direction", V2::ConvertFlexDirectionToStirng(direction).c_str()); 132 if (!isWrap_) { 133 jsonConstructor->Put("wrap", "FlexWrap.NoWrap"); 134 jsonConstructor->Put("justifyContent", 135 V2::ConvertFlexAlignToStirng(property->GetMainAxisAlign().value_or(FlexAlign::FLEX_START)).c_str()); 136 jsonConstructor->Put("alignItems", 137 V2::ConvertItemAlignToStirng(property->GetCrossAxisAlign().value_or(FlexAlign::FLEX_START)).c_str()); 138 jsonConstructor->Put("alignContent", "FlexAlign.Start"); 139 } else { 140 auto wrapDirection = property->GetWrapDirection().value_or(WrapDirection::HORIZONTAL); 141 if (static_cast<int32_t>(direction) <= 1) { 142 auto wrap = (static_cast<int32_t>(wrapDirection) - static_cast<int32_t>(direction)) / 2 + 1; 143 jsonConstructor->Put("wrap", wrap == 1 ? "FlexWrap.Wrap" : "FlexWrap.WrapReverse"); 144 } else { 145 auto wrap = (static_cast<int32_t>(wrapDirection) + static_cast<int32_t>(direction)) / 2 + 1; 146 jsonConstructor->Put("wrap", wrap == 1 ? "FlexWrap.Wrap" : "FlexWrap.WrapReverse"); 147 } 148 jsonConstructor->Put("justifyContent", 149 V2::ConvertWrapAlignmentToStirng(property->GetMainAlignment().value_or(WrapAlignment::START)).c_str()); 150 jsonConstructor->Put("alignItems", 151 V2::ConvertItemAlignToStirng(property->GetCrossAlignment().value_or(WrapAlignment::START)).c_str()); 152 jsonConstructor->Put("alignContent", 153 V2::ConvertWrapAlignmentToStirng(property->GetAlignment().value_or(WrapAlignment::START)).c_str()); 154 } 155 json->PutExtAttr("constructor", jsonConstructor, filter); 156 json->PutExtAttr("space", SpaceToString().c_str(), filter); 157 } 158 FromJson(const std::unique_ptr<JsonValue> & json)159 void FromJson(const std::unique_ptr<JsonValue>& json) override 160 { 161 auto property = GetLayoutProperty<FlexLayoutProperty>(); 162 CHECK_NULL_VOID(property); 163 if (json->Contains("constructor")) { 164 auto constructor = json->GetValue("constructor"); 165 property->UpdateFlexDirection(V2::ConvertStringToFlexDirection(constructor->GetString("direction"))); 166 property->UpdateMainAxisAlign(V2::ConvertStringToFlexAlign(constructor->GetString("justifyContent"))); 167 property->UpdateCrossAxisAlign(V2::ConvertStringToFlexAlign(constructor->GetString("alignItems"))); 168 if (constructor->GetString("wrap") == "FlexWrap.NoWrap") { 169 SetIsWrap(false); 170 property->UpdateMainAxisAlign(V2::ConvertStringToFlexAlign(constructor->GetString("justifyContent"))); 171 property->UpdateCrossAxisAlign(V2::ConvertStringToItemAlign(constructor->GetString("alignItems"))); 172 } 173 } 174 Pattern::FromJson(json); 175 } 176 SpaceToString()177 std::string SpaceToString() const 178 { 179 auto host = GetHost(); 180 CHECK_NULL_RETURN(host, Dimension().ToString()); 181 auto layoutProperty = host->GetLayoutProperty<FlexLayoutProperty>(); 182 CHECK_NULL_RETURN(layoutProperty, Dimension().ToString()); 183 return layoutProperty->GetSpaceValue(Dimension()).ToString(); 184 } 185 SetFlexMeasureResult(FlexMeasureResult measureResult,uintptr_t addr)186 void SetFlexMeasureResult(FlexMeasureResult measureResult, uintptr_t addr) 187 { 188 measureResult_ = measureResult; 189 measuredAddress_ = addr; 190 } 191 GetFlexMeasureResult()192 FlexMeasureResult GetFlexMeasureResult() 193 { 194 return measureResult_; 195 } 196 SetFlexLayoutResult(FlexLayoutResult layoutResult,uintptr_t addr)197 void SetFlexLayoutResult(FlexLayoutResult layoutResult, uintptr_t addr) 198 { 199 layoutResult_ = layoutResult; 200 layoutedAddress_ = addr; 201 } 202 GetMeasureLayoutPaired()203 bool GetMeasureLayoutPaired() 204 { 205 return (measuredAddress_ && layoutedAddress_ && (measuredAddress_.value() == layoutedAddress_.value())); 206 } 207 208 private: 209 bool isWrap_ = false; 210 bool isDialogStretch_ = false; 211 FlexMeasureResult measureResult_; 212 FlexLayoutResult layoutResult_; 213 std::optional<uintptr_t> measuredAddress_; 214 std::optional<uintptr_t> layoutedAddress_; 215 216 ACE_DISALLOW_COPY_AND_MOVE(FlexLayoutPattern); 217 }; 218 } // namespace OHOS::Ace::NG 219 220 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_FLEX_FLEX_LAYOUT_PATTERN_H 221