1 /*
2  * Copyright (c) 2022-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 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_SWIPER_SWIPER_LAYOUT_PROPERTY_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_SWIPER_SWIPER_LAYOUT_PROPERTY_H
18 
19 #include "base/geometry/axis.h"
20 #include "base/geometry/dimension.h"
21 #include "base/utils/macros.h"
22 #include "base/utils/string_utils.h"
23 #include "core/components/common/layout/constants.h"
24 #include "core/components/common/properties/scroll_bar.h"
25 #include "core/components/declaration/swiper/swiper_declaration.h"
26 #include "core/components_ng/base/inspector_filter.h"
27 #include "core/components_ng/layout/layout_property.h"
28 #include "core/components_ng/property/property.h"
29 
30 namespace OHOS::Ace::NG {
31 class ACE_EXPORT SwiperLayoutProperty : public LayoutProperty {
32     DECLARE_ACE_TYPE(SwiperLayoutProperty, LayoutProperty);
33 
34 public:
35     SwiperLayoutProperty() = default;
36 
37     ~SwiperLayoutProperty() override = default;
38 
Clone()39     RefPtr<LayoutProperty> Clone() const override
40     {
41         auto value = MakeRefPtr<SwiperLayoutProperty>();
42         value->LayoutProperty::UpdateLayoutProperty(DynamicCast<LayoutProperty>(this));
43         value->propDirection_ = CloneDirection();
44         value->propIndex_ = CloneIndex();
45         value->propItemSpace_ = CloneItemSpace();
46         value->propCachedCount_ = CloneCachedCount();
47         value->propDisplayMode_ = CloneDisplayMode();
48         value->propDisplayCount_ = CloneDisplayCount();
49         value->propMinSize_ = CloneMinSize();
50         value->propShowIndicator_ = CloneShowIndicator();
51         value->propIndicatorType_ = CloneIndicatorType();
52         value->propLeft_ = CloneLeft();
53         value->propTop_ = CloneTop();
54         value->propRight_ = CloneRight();
55         value->propBottom_ = CloneBottom();
56         value->propPrevMargin_ = ClonePrevMargin();
57         value->propPrevMarginIgnoreBlank_ = ClonePrevMarginIgnoreBlank();
58         value->propNextMargin_ = CloneNextMargin();
59         value->propNextMarginIgnoreBlank_ = CloneNextMarginIgnoreBlank();
60         value->propDisplayArrow_ = CloneDisplayArrow();
61         value->propHoverShow_ = CloneHoverShow();
62         value->propIsShowBackground_ = CloneIsShowBackground();
63         value->propIsSidebarMiddle_ = CloneIsSidebarMiddle();
64         value->propBackgroundSize_ = CloneBackgroundSize();
65         value->propBackgroundColor_ = CloneBackgroundColor();
66         value->propArrowSize_ = CloneArrowSize();
67         value->propArrowColor_ = CloneArrowColor();
68         value->propLoop_ = CloneLoop();
69         value->propIndicatorInteractive_ = CloneIndicatorInteractive();
70         value->propDisableSwipe_ = CloneDisableSwipe();
71         value->ignoreItemSpace_ = ignoreItemSpace_;
72         return value;
73     }
74 
Reset()75     void Reset() override
76     {
77         LayoutProperty::Reset();
78         ResetDirection();
79         ResetIndex();
80         ResetItemSpace();
81         ResetCachedCount();
82         ResetDisplayMode();
83         ResetDisplayCount();
84         ResetMinSize();
85         ResetShowIndicator();
86         ResetIndicatorType();
87         ResetLeft();
88         ResetTop();
89         ResetRight();
90         ResetBottom();
91         ResetPrevMargin();
92         ResetPrevMarginIgnoreBlank();
93         ResetNextMargin();
94         ResetNextMarginIgnoreBlank();
95         ResetDisplayArrow();
96         ResetHoverShow();
97         ResetIsShowBackground();
98         ResetIsSidebarMiddle();
99         ResetBackgroundSize();
100         ResetBackgroundColor();
101         ResetArrowSize();
102         ResetArrowColor();
103         ResetLoop();
104         ResetIndicatorInteractive();
105         ResetDisableSwipe();
106         ignoreItemSpace_ = false;
107     }
108 
ToJsonValue(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter)109     void ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const override
110     {
111         LayoutProperty::ToJsonValue(json, filter);
112         /* no fixed attr below, just return */
113         if (filter.IsFastFilter()) {
114             return;
115         }
116         json->PutExtAttr("index", std::to_string(propIndex_.value_or(0)).c_str(), filter);
117         json->PutExtAttr("vertical",
118             propDirection_.value_or(Axis::HORIZONTAL) == Axis::VERTICAL ? "true" : "false", filter);
119         json->PutExtAttr("indicator", propShowIndicator_.value_or(true) ? "true" : "false", filter);
120         json->PutExtAttr("itemSpace",
121             propItemSpace_.value_or(Dimension(0, DimensionUnit::VP)).ToString().c_str(), filter);
122         json->PutExtAttr("cachedCount", propCachedCount_.value_or(1), filter);
123         json->PutExtAttr("displayMode",
124             propDisplayMode_.value_or(SwiperDisplayMode::STRETCH) == SwiperDisplayMode::AUTO_LINEAR ?
125             "SwiperDisplayMode.AutoLinear" : "SwiperDisplayMode.Stretch", filter);
126         json->PutExtAttr("displayCount", propDisplayCount_.value_or(1), filter);
127         json->PutExtAttr("minSize",
128             propMinSize_.value_or(Dimension(0, DimensionUnit::VP)).ToString().c_str(), filter);
129         json->PutExtAttr("prevMargin",
130             ignorePrevMarginAndNextMargin_
131                 ? Dimension(0.0_px).ToString().c_str()
132                 : propPrevMargin_.value_or(Dimension(0, DimensionUnit::VP)).ToString().c_str(), filter);
133         json->PutExtAttr("prevMarginIgnoreBlank",
134             propPrevMarginIgnoreBlank_.value_or(false) ? "true" : "false", filter);
135         json->PutExtAttr("nextMargin",
136             ignorePrevMarginAndNextMargin_
137                 ? Dimension(0.0_px).ToString().c_str()
138                 : propNextMargin_.value_or(Dimension(0, DimensionUnit::VP)).ToString().c_str(), filter);
139         json->PutExtAttr("nextMarginIgnoreBlank",
140             propNextMarginIgnoreBlank_.value_or(false) ? "true" : "false", filter);
141         json->PutExtAttr("displayArrow", propDisplayArrow_.value_or(false) ? "true" : "false", filter);
142         json->PutExtAttr("hoverShow", propHoverShow_.value_or(false) ? "true" : "false", filter);
143         json->PutExtAttr("showBackground", propIsShowBackground_.value_or(false) ? "true" : "false", filter);
144         json->PutExtAttr("isSidebarMiddle", propIsSidebarMiddle_.value_or(false) ? "true" : "false", filter);
145         json->PutExtAttr("arrowBackgroundSize",
146             propBackgroundSize_.value_or(Dimension(0, DimensionUnit::VP)).ToString().c_str(), filter);
147         json->PutExtAttr("arrowSize",
148             propArrowSize_.value_or(Dimension(0, DimensionUnit::VP)).ToString().c_str(), filter);
149         json->PutExtAttr("arrowBackgroundColor",
150             propBackgroundColor_.value_or(Color::TRANSPARENT).ColorToString().c_str(), filter);
151         json->PutExtAttr("arrowColor",
152             propArrowColor_.value_or(Color::TRANSPARENT).ColorToString().c_str(), filter);
153         json->PutExtAttr("loop", propLoop_.value_or(true) ? "true" : "false", filter);
154         json->PutExtAttr("indicatorInteractive", propIndicatorInteractive_.value_or(true) ? "true" : "false", filter);
155         json->PutExtAttr("disableSwipe", GetDisableSwipe().value_or(false) ? "true" : "false", filter);
156         json->PutExtAttr("swipeByGroup", propSwipeByGroup_.value_or(false) ? "true" : "false", filter);
157     }
158 
FromJson(const std::unique_ptr<JsonValue> & json)159     void FromJson(const std::unique_ptr<JsonValue>& json) override
160     {
161         static const std::unordered_map<std::string, SwiperDisplayMode> uMap {
162             { "SwiperDisplayMode.AutoLinear", SwiperDisplayMode::AUTO_LINEAR },
163             { "SwiperDisplayMode.Stretch", SwiperDisplayMode::STRETCH },
164         };
165 
166         UpdateLoop(json->GetBool("loop"));
167         UpdateIndex(StringUtils::StringToInt(json->GetString("index")));
168         UpdateDirection(json->GetString("vertical") == "true" ? Axis::VERTICAL : Axis::HORIZONTAL);
169         UpdateShowIndicator(json->GetString("indicator") == "true" ? true : false);
170         UpdateItemSpace(Dimension::FromString(json->GetString("itemSpace")));
171         UpdateCachedCount(json->GetInt("cachedCount"));
172         auto displayMode = json->GetString("displayMode");
173         SwiperDisplayMode swiperDisplayMode = SwiperDisplayMode::STRETCH;
174         auto iter = uMap.find(displayMode);
175         if (iter != uMap.end()) {
176             swiperDisplayMode = iter->second;
177         }
178         UpdateDisplayMode(swiperDisplayMode);
179         UpdateDisplayCount(json->GetInt("displayCount"));
180         UpdateDisableSwipe(json->GetBool("disableSwipe"));
181         LayoutProperty::FromJson(json);
182     }
183 
UpdateIndexWithoutMeasure(int32_t index)184     void UpdateIndexWithoutMeasure(int32_t index)
185     {
186         if (propIndex_ != index) {
187             propIndex_ = index;
188         }
189     }
190 
ResetIgnorePrevMarginAndNextMargin()191     void ResetIgnorePrevMarginAndNextMargin()
192     {
193         ignorePrevMarginAndNextMargin_ = false;
194     }
195 
MarkIgnorePrevMarginAndNextMargin()196     void MarkIgnorePrevMarginAndNextMargin()
197     {
198         ignorePrevMarginAndNextMargin_ = true;
199     }
200 
GetCalculatedPrevMargin()201     float GetCalculatedPrevMargin() const
202     {
203         if (!IsStretch() || ignorePrevMarginAndNextMargin_) {
204             return 0.0f;
205         }
206         return GetPrevMarginValue(0.0_vp).ConvertToPx();
207     }
208 
GetCalculatedNextMargin()209     float GetCalculatedNextMargin() const
210     {
211         if (!IsStretch() || ignorePrevMarginAndNextMargin_) {
212             return 0.0f;
213         }
214         return GetNextMarginValue(0.0_vp).ConvertToPx();
215     }
216 
IsStretch()217     bool IsStretch() const
218     {
219         // If display count is setted, use stretch mode.
220         if (HasDisplayCount() && !HasMinSize()) {
221             return true;
222         }
223 
224         return GetDisplayMode().value_or(SwiperDisplayMode::STRETCH) == SwiperDisplayMode::STRETCH;
225     }
226 
ResetIgnoreItemSpace()227     void ResetIgnoreItemSpace()
228     {
229         ignoreItemSpace_ = false;
230     }
231 
MarkIgnoreItemSpace()232     void MarkIgnoreItemSpace()
233     {
234         ignoreItemSpace_ = true;
235     }
236 
IgnoreItemSpace()237     bool IgnoreItemSpace() const
238     {
239         return ignoreItemSpace_;
240     }
241 
242     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(Direction, Axis, PROPERTY_UPDATE_MEASURE);
243     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(Index, int32_t, PROPERTY_UPDATE_MEASURE_SELF_AND_PARENT);
244     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(ItemSpace, Dimension, PROPERTY_UPDATE_MEASURE);
245     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(CachedCount, int32_t, PROPERTY_UPDATE_MEASURE_SELF);
246     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(DisplayMode, SwiperDisplayMode, PROPERTY_UPDATE_MEASURE);
247     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(DisplayCount, int32_t, PROPERTY_UPDATE_MEASURE);
248     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(MinSize, Dimension, PROPERTY_UPDATE_MEASURE);
249     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(ShowIndicator, bool, PROPERTY_UPDATE_MEASURE_SELF);
250     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(IndicatorType, SwiperIndicatorType, PROPERTY_UPDATE_MEASURE);
251     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(Left, Dimension, PROPERTY_UPDATE_MEASURE_SELF);
252     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(Top, Dimension, PROPERTY_UPDATE_MEASURE_SELF);
253     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(Right, Dimension, PROPERTY_UPDATE_MEASURE_SELF);
254     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(Bottom, Dimension, PROPERTY_UPDATE_MEASURE_SELF);
255     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(PrevMargin, Dimension, PROPERTY_UPDATE_MEASURE);
256     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(PrevMarginIgnoreBlank, bool, PROPERTY_UPDATE_MEASURE);
257     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(NextMargin, Dimension, PROPERTY_UPDATE_MEASURE);
258     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(NextMarginIgnoreBlank, bool, PROPERTY_UPDATE_MEASURE);
259     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(DisplayArrow, bool, PROPERTY_UPDATE_MEASURE);
260     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(HoverShow, bool, PROPERTY_UPDATE_MEASURE);
261     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(IsShowBackground, bool, PROPERTY_UPDATE_MEASURE);
262     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(IsSidebarMiddle, bool, PROPERTY_UPDATE_MEASURE);
263     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(BackgroundSize, Dimension, PROPERTY_UPDATE_MEASURE);
264     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(BackgroundColor, Color, PROPERTY_UPDATE_NORMAL);
265     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(ArrowSize, Dimension, PROPERTY_UPDATE_MEASURE);
266     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(ArrowColor, Color, PROPERTY_UPDATE_NORMAL);
267     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(Loop, bool, PROPERTY_UPDATE_MEASURE_SELF);
268     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(IndicatorInteractive, bool, PROPERTY_UPDATE_NORMAL);
269     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(IsCustomAnimation, bool, PROPERTY_UPDATE_MEASURE_SELF);
270     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(DisableSwipe, bool, PROPERTY_UPDATE_MEASURE_SELF);
271     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(SwipeByGroup, bool, PROPERTY_UPDATE_MEASURE_SELF);
272 
273 private:
274     bool ignoreItemSpace_ = false; // displayCount and prevMargin/nextMargin have higher priorities, so itemSpace might
275                                    // be ignored in some situations.
276     bool ignorePrevMarginAndNextMargin_ = false;
277 };
278 } // namespace OHOS::Ace::NG
279 
280 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_SWIPER_SWIPER_LAYOUT_PROPERTY_H
281