1 /*
2  * Copyright (c) 2023 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_ng/pattern/waterflow/water_flow_layout_property.h"
17 
18 #include "base/geometry/dimension.h"
19 #include "base/utils/system_properties.h"
20 #include "base/utils/utils.h"
21 #include "core/components_ng/base/frame_node.h"
22 #include "core/components_ng/base/inspector_filter.h"
23 #include "core/components_ng/pattern/waterflow/water_flow_pattern.h"
24 #include "core/components_v2/inspector/utils.h"
25 
26 namespace OHOS::Ace::NG {
ResetWaterflowLayoutInfoAndMeasure() const27 void WaterFlowLayoutProperty::ResetWaterflowLayoutInfoAndMeasure() const
28 {
29     auto host = GetHost();
30     CHECK_NULL_VOID(host);
31     auto pattern = host->GetPattern<WaterFlowPattern>();
32     CHECK_NULL_VOID(pattern);
33     pattern->ResetLayoutInfo();
34     host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD);
35 }
36 
ToJsonValue(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter) const37 void WaterFlowLayoutProperty::ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
38 {
39     LayoutProperty::ToJsonValue(json, filter);
40     /* no fixed attr below, just return */
41     if (filter.IsFastFilter()) {
42         return;
43     }
44     json->PutExtAttr("columnsTemplate", propColumnsTemplate_.value_or("").c_str(), filter);
45     json->PutExtAttr("rowsTemplate", propRowsTemplate_.value_or("").c_str(), filter);
46     json->PutExtAttr("columnsGap", propColumnsGap_.value_or(0.0_vp).ToString().c_str(), filter);
47     json->PutExtAttr("rowsGap", propRowsGap_.value_or(0.0_vp).ToString().c_str(), filter);
48     json->PutExtAttr("layoutDirection ", GetWaterflowDirectionStr().c_str(), filter);
49     auto jsonConstraintSize = JsonUtil::Create(true);
50     if (itemLayoutConstraint_) {
51         jsonConstraintSize->Put("minWidth", itemLayoutConstraint_->minSize.value_or(CalcSize())
52                                                 .Width()
53                                                 .value_or(CalcLength(0, DimensionUnit::VP))
54                                                 .ToString()
55                                                 .c_str());
56         jsonConstraintSize->Put("minHeight", itemLayoutConstraint_->minSize.value_or(CalcSize())
57                                                 .Height()
58                                                 .value_or(CalcLength(0, DimensionUnit::VP))
59                                                 .ToString()
60                                                 .c_str());
61         jsonConstraintSize->Put("maxWidth", itemLayoutConstraint_->maxSize.value_or(CalcSize())
62                                                 .Width()
63                                                 .value_or(CalcLength(Infinity<double>(), DimensionUnit::VP))
64                                                 .ToString()
65                                                 .c_str());
66         jsonConstraintSize->Put("maxHeight", itemLayoutConstraint_->maxSize.value_or(CalcSize())
67                                                 .Height()
68                                                 .value_or(CalcLength(Infinity<double>(), DimensionUnit::VP))
69                                                 .ToString()
70                                                 .c_str());
71         json->PutExtAttr("itemConstraintSize", jsonConstraintSize->ToString().c_str(), filter);
72     } else {
73         json->PutExtAttr("itemConstraintSize", "0", filter);
74     }
75     json->PutExtAttr("enableScrollInteraction", propScrollEnabled_.value_or(true), filter);
76 }
77 
GetWaterflowDirectionStr() const78 std::string WaterFlowLayoutProperty::GetWaterflowDirectionStr() const
79 {
80     auto WaterflowDirection = propWaterflowDirection_.value_or(FlexDirection::COLUMN);
81     return V2::ConvertFlexDirectionToStirng(WaterflowDirection);
82 }
83 
Clone() const84 RefPtr<LayoutProperty> WaterFlowLayoutProperty::Clone() const
85 {
86     auto value = MakeRefPtr<WaterFlowLayoutProperty>();
87     value->LayoutProperty::UpdateLayoutProperty(DynamicCast<LayoutProperty>(this));
88     value->propRowsTemplate_ = CloneRowsTemplate();
89     value->propColumnsTemplate_ = CloneColumnsTemplate();
90     value->propRowsGap_ = CloneRowsGap();
91     value->propColumnsGap_ = CloneColumnsGap();
92     value->propWaterflowDirection_ = CloneWaterflowDirection();
93     value->propScrollEnabled_ = CloneScrollEnabled();
94     if (itemLayoutConstraint_) {
95         value->itemLayoutConstraint_ = std::make_unique<MeasureProperty>(*itemLayoutConstraint_);
96     }
97     return value;
98 }
99 
100 namespace {
UseSegmentedLayout(const RefPtr<FrameNode> & host)101 inline bool UseSegmentedLayout(const RefPtr<FrameNode>& host)
102 {
103     CHECK_NULL_RETURN(host, false);
104     auto pattern = host->GetPattern<WaterFlowPattern>();
105     return SystemProperties::WaterFlowUseSegmentedLayout() || (pattern && pattern->GetSections());
106 }
107 
SWLayout(const RefPtr<FrameNode> & host)108 inline bool SWLayout(const RefPtr<FrameNode>& host)
109 {
110     CHECK_NULL_RETURN(host, false);
111     auto pattern = host->GetPattern<WaterFlowPattern>();
112     return pattern && pattern->GetLayoutMode() == WaterFlowLayoutMode::SLIDING_WINDOW;
113 }
114 } // namespace
115 
OnRowsGapUpdate(Dimension) const116 void WaterFlowLayoutProperty::OnRowsGapUpdate(Dimension /* rowsGap */) const
117 {
118     auto host = GetHost();
119     if (GetAxis() == Axis::VERTICAL || UseSegmentedLayout(host) || SWLayout(host)) {
120         ResetWaterflowLayoutInfoAndMeasure();
121     }
122 }
OnColumnsGapUpdate(Dimension) const123 void WaterFlowLayoutProperty::OnColumnsGapUpdate(Dimension /* columnsGap */) const
124 {
125     auto host = GetHost();
126     if (GetAxis() == Axis::HORIZONTAL || UseSegmentedLayout(host) || SWLayout(host)) {
127         ResetWaterflowLayoutInfoAndMeasure();
128     }
129 }
130 } // namespace OHOS::Ace::NG
131