1 /*
2  * Copyright (c) 2021-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 #include "core/components/declaration/swiper/swiper_declaration.h"
17 
18 #include "core/components/declaration/common/declaration_constants.h"
19 #include "frameworks/bridge/common/utils/utils.h"
20 
21 namespace OHOS::Ace {
22 namespace {
23 
24 constexpr uint32_t METHOD_SWIPE_TO_ARGS_SIZE = 1;
25 constexpr double INDICATOR_POINT_SCALE = 1.33;
26 
27 } // namespace
28 
29 using namespace Framework;
30 
SwiperDeclaration()31 SwiperDeclaration::SwiperDeclaration()
32 {
33     indicator_ = AceType::MakeRefPtr<SwiperIndicator>();
34     swiperController_ = AceType::MakeRefPtr<SwiperController>();
35     rotationController_ = AceType::MakeRefPtr<RotationController>();
36 }
37 
InitializeStyle()38 void SwiperDeclaration::InitializeStyle()
39 {
40     RefPtr<SwiperIndicatorTheme> theme = GetTheme<SwiperIndicatorTheme>();
41     if (theme) {
42         indicator_->InitStyle(theme);
43     }
44 }
InitSpecialized()45 void SwiperDeclaration::InitSpecialized()
46 {
47     AddSpecializedAttribute(DeclarationConstants::DEFAULT_SWIPER_ATTR);
48     AddSpecializedStyle(DeclarationConstants::DEFAULT_SWIPER_STYLE);
49     AddSpecializedEvent(DeclarationConstants::DEFAULT_SWIPER_EVENT);
50     AddSpecializedMethod(DeclarationConstants::DEFAULT_SWIPER_METHOD);
51     AddSpecializedRemoteMessageEvent(DeclarationConstants::DEFAULT_SWIPER_EVENT);
52 }
53 
SetSpecializedAttr(const std::pair<std::string,std::string> & attr)54 bool SwiperDeclaration::SetSpecializedAttr(const std::pair<std::string, std::string>& attr)
55 {
56     static const LinearMapNode<void (*)(const std::string&, SwiperDeclaration&)> swiperAttrsOperators[] = {
57         { DOM_SWIPER_ANIMATION_OPACITY,
58             [](const std::string& val, SwiperDeclaration& swiper) { swiper.SetAnimationOpacity(StringToBool(val)); } },
59         { DOM_AUTOPLAY,
60             [](const std::string& val, SwiperDeclaration& swiper) { swiper.SetAutoPlay(StringToBool(val)); } },
61         { DOM_CACHED_SIZE,
62             [](const std::string& val, SwiperDeclaration& swiper) {
63                 swiper.SetCachedSize(StringUtils::StringToInt(val));
64             } },
65         { DOM_DIGITAL_INDICATOR,
66             [](const std::string& val, SwiperDeclaration& swiper) { swiper.SetDigitalIndicator(StringToBool(val)); } },
67         { DOM_DISPLAY_MODE,
68             [](const std::string& val, SwiperDeclaration& swiper) {
69                 if (val == DOM_DISPLAY_MODE_AUTO_LINEAR) {
70                     swiper.SetDisplayMode(SwiperDisplayMode::AUTO_LINEAR);
71                 } else {
72                     swiper.SetDisplayMode(SwiperDisplayMode::STRETCH);
73                 }
74             } },
75         { DOM_DURATION,
76             [](const std::string& val, SwiperDeclaration& swiper) { swiper.SetDuration(StringToDouble(val)); } },
77         { DOM_INDEX,
78             [](const std::string& val, SwiperDeclaration& swiper) { swiper.SetIndex(StringUtils::StringToInt(val)); } },
79         { DOM_INDICATOR,
80             [](const std::string& val, SwiperDeclaration& swiper) { swiper.showIndicator_ = StringToBool(val); } },
81         { DOM_INDICATOR_DISABLED,
82             [](const std::string& val, SwiperDeclaration& swiper) {
83                 swiper.indicator_->SetIndicatorDisabled(StringToBool(val));
84             } },
85         { DOM_INDICATOR_MASK,
86             [](const std::string& val, SwiperDeclaration& swiper) {
87                 swiper.indicator_->SetIndicatorMask(StringToBool(val));
88             } },
89         { DOM_INTERVAL, [](const std::string& val,
90                             SwiperDeclaration& swiper) { swiper.SetAutoPlayInterval(StringToDouble(val)); } },
91         { DOM_LOOP, [](const std::string& val, SwiperDeclaration& swiper) { swiper.SetLoop(StringToBool(val)); } },
92         { DOM_SCROLL_EFFECT, [](const std::string& val, SwiperDeclaration& swiper) {
93             if (val == DOM_SCROLL_EFFECT_SPRING) {
94                 swiper.SetEdgeEffect(EdgeEffect::SPRING);
95             } else if (val == DOM_SCROLL_EFFECT_FADE) {
96                 swiper.SetEdgeEffect(EdgeEffect::FADE);
97             } else {
98                 swiper.SetEdgeEffect(EdgeEffect::NONE);
99             }
100         } },
101         { DOM_VERTICAL,
102             [](const std::string& val, SwiperDeclaration& swiper) {
103                 swiper.SetAxis(StringToBool(val) ? Axis::VERTICAL : Axis::HORIZONTAL);
104             } },
105     };
106     auto operatorIter =
107         BinarySearchFindIndex(swiperAttrsOperators, ArraySize(swiperAttrsOperators), attr.first.c_str());
108     if (operatorIter != -1) {
109         swiperAttrsOperators[operatorIter].value(attr.second, *this);
110         return true;
111     } else {
112         return false;
113     }
114 }
115 
SetSpecializedStyle(const std::pair<std::string,std::string> & style)116 bool SwiperDeclaration::SetSpecializedStyle(const std::pair<std::string, std::string>& style)
117 {
118     // static linear map must be sorted buy key.
119     static const LinearMapNode<void (*)(const std::string&, SwiperDeclaration&)> swiperStylesOperators[] = {
120         { DOM_ANIMATION_CURVE,
121             [](const std::string& val, SwiperDeclaration& swiper) {
122                 swiper.SetAnimationCurve(ConvertStrToAnimationCurve(val));
123             } },
124         { DOM_FADE_COLOR,
125             [](const std::string& val, SwiperDeclaration& swiper) {
126                 swiper.SetFadeColor(swiper.ParseColor(val));
127             } },
128         { DOM_INDICATOR_BOTTOM,
129             [](const std::string& val, SwiperDeclaration& swiper) {
130                 swiper.indicator_->SetBottom(swiper.ParseDimension(val));
131             } },
132         { DOM_INDICATOR_COLOR,
133             [](const std::string& val, SwiperDeclaration& swiper) {
134                 swiper.indicator_->SetColor(swiper.ParseColor(val));
135             } },
136         { DOM_INDICATOR_LEFT,
137             [](const std::string& val, SwiperDeclaration& swiper) {
138                 swiper.indicator_->SetLeft(swiper.ParseDimension(val));
139             } },
140         { DOM_INDICATOR_RIGHT,
141             [](const std::string& val, SwiperDeclaration& swiper) {
142                 swiper.indicator_->SetRight(swiper.ParseDimension(val));
143             } },
144         { DOM_INDICATOR_SELECTEDCOLOR,
145             [](const std::string& val, SwiperDeclaration& swiper) {
146                 swiper.indicator_->SetSelectedColor(swiper.ParseColor(val));
147             } },
148         { DOM_INDICATOR_SIZE,
149             [](const std::string& val, SwiperDeclaration& swiper) {
150                 Dimension indicatorSize = swiper.ParseDimension(val);
151                 swiper.indicator_->SetSize(indicatorSize);
152                 swiper.indicator_->SetSelectedSize(indicatorSize);
153                 swiper.indicator_->SetPressSize(indicatorSize * INDICATOR_POINT_SCALE);
154                 swiper.indicator_->SetHoverSize(indicatorSize * INDICATOR_POINT_SCALE * INDICATOR_POINT_SCALE);
155             } },
156         { DOM_INDICATOR_TOP,
157             [](const std::string& val, SwiperDeclaration& swiper) {
158                 swiper.indicator_->SetTop(swiper.ParseDimension(val));
159             } },
160         { DOM_NEXT_MARGIN,
161             [](const std::string& val, SwiperDeclaration& swiper) {
162                 swiper.SetNextMargin(swiper.ParseDimension(val));
163             } },
164         { DOM_PREVIOUS_MARGIN,
165             [](const std::string& val, SwiperDeclaration& swiper) {
166                 swiper.SetPreviousMargin(swiper.ParseDimension(val));
167             } },
168     };
169     auto operatorIter =
170         BinarySearchFindIndex(swiperStylesOperators, ArraySize(swiperStylesOperators), style.first.c_str());
171     if (operatorIter != -1) {
172         swiperStylesOperators[operatorIter].value(style.second, *this);
173         return true;
174     } else {
175         return false;
176     }
177 }
178 
SetSpecializedEvent(int32_t pageId,const std::string & eventId,const std::string & event)179 bool SwiperDeclaration::SetSpecializedEvent(int32_t pageId, const std::string& eventId, const std::string& event)
180 {
181     if (event == DOM_CHANGE) {
182         SetChangeEventId(EventMarker(eventId, event, pageId));
183         return true;
184     } else if (event == DOM_ROTATION) {
185         SetRotationEventId(EventMarker(eventId, event, pageId));
186         return true;
187     } else if (event == DOM_CLICK) {
188         SetClickEventId(EventMarker(eventId, event, pageId));
189         return true;
190     } else if (event == DOM_CATCH_BUBBLE_CLICK) {
191         EventMarker eventMarker(eventId, event, pageId);
192         eventMarker.SetCatchMode(true);
193         SetClickEventId(eventMarker);
194         return true;
195     } else if (event == DOM_ANIMATION_FINISH) {
196         SetAnimationFinishEventId(EventMarker(eventId, event, pageId));
197         return true;
198     } else {
199         return false;
200     }
201 }
202 
CallSpecializedMethod(const std::string & method,const std::string & args)203 void SwiperDeclaration::CallSpecializedMethod(const std::string& method, const std::string& args)
204 {
205     if (method == DOM_METHOD_SWIPE_TO) {
206         auto controller = GetSwiperController();
207         if (!controller) {
208             LOGE("get controller failed");
209             return;
210         }
211 
212         std::unique_ptr<JsonValue> argsValue = JsonUtil::ParseJsonString(args);
213         if (!argsValue || !argsValue->IsArray() || argsValue->GetArraySize() != METHOD_SWIPE_TO_ARGS_SIZE) {
214             LOGE("parse args error");
215             return;
216         }
217 
218         std::unique_ptr<JsonValue> indexValue = argsValue->GetArrayItem(0)->GetValue("index");
219         if (!indexValue || !indexValue->IsNumber()) {
220             LOGE("get index failed");
221             return;
222         }
223         int32_t index = indexValue->GetInt();
224         controller->SwipeTo(index);
225     } else if (method == DOM_METHOD_SHOW_PREVIOUS) {
226         auto controller = GetSwiperController();
227         if (!controller) {
228             return;
229         }
230         controller->ShowPrevious();
231     } else if (method == DOM_METHOD_SHOW_NEXT) {
232         auto controller = GetSwiperController();
233         if (!controller) {
234             return;
235         }
236         controller->ShowNext();
237     } else if (method == DOM_ROTATION) {
238         auto controller = GetRotationController();
239         if (controller) {
240             controller->RequestRotation(true);
241         }
242     } else {
243         LOGW("unsupported method: %{public}s", method.c_str());
244     }
245 }
246 
247 } // namespace OHOS::Ace
248