1 /*
2  * Copyright (c) 2021 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 "frameworks/bridge/common/dom/dom_stepper.h"
17 
18 #include "core/components/stepper/stepper_theme.h"
19 #include "frameworks/bridge/common/dom/dom_stepper_item.h"
20 
21 namespace OHOS::Ace::Framework {
22 namespace {
23 
24 constexpr int32_t DEFAULT_NODE_INDEX = -1;
25 constexpr int32_t METHOD_TO_ARGS_SIZE = 1;
26 
27 } // namespace
28 
DOMStepper(NodeId nodeId,const std::string & nodeName)29 DOMStepper::DOMStepper(NodeId nodeId, const std::string& nodeName) : DOMNode(nodeId, nodeName)
30 {
31     stepperComponent_ = AceType::MakeRefPtr<StepperComponent>(std::list<RefPtr<Component>>());
32 }
33 
SetSpecializedAttr(const std::pair<std::string,std::string> & attr)34 bool DOMStepper::SetSpecializedAttr(const std::pair<std::string, std::string>& attr)
35 {
36     // static linear map must be sorted by key.
37     static const LinearMapNode<void (*)(const std::string&, DOMStepper&)> attrsOperators[] = {
38         { DOM_STEPPER_INDEX,
39             [](const std::string& val, DOMStepper& stepper) {
40                 stepper.stepperComponent_->SetIndex(StringUtils::StringToInt(val));
41             } },
42     };
43     auto iter = BinarySearchFindIndex(attrsOperators, ArraySize(attrsOperators), attr.first.c_str());
44     if (iter != -1) {
45         attrsOperators[iter].value(attr.second, *this);
46         return true;
47     } else {
48         return false;
49     }
50 }
51 
SetSpecializedStyle(const std::pair<std::string,std::string> & style)52 bool DOMStepper::SetSpecializedStyle(const std::pair<std::string, std::string>& style)
53 {
54     return false;
55 }
56 
AddSpecializedEvent(int32_t pageId,const std::string & event)57 bool DOMStepper::AddSpecializedEvent(int32_t pageId, const std::string& event)
58 {
59     // static linear map must be sorted by key.
60     static const LinearMapNode<void (*)(int32_t, DOMStepper&)> eventOperators[] = {
61         {
62             DOM_STEPPER_EVENT_BACK,
63             [](int32_t pageId, DOMStepper& stepper) {
64                 stepper.backEventId_ = EventMarker(stepper.GetNodeIdForEvent(), DOM_STEPPER_EVENT_BACK, pageId);
65                 stepper.stepperComponent_->SetBackEventId(stepper.backEventId_);
66             },
67         },
68         {
69             DOM_STEPPER_EVENT_CHANGE,
70             [](int32_t pageId, DOMStepper& stepper) {
71                 stepper.changeEventId_ = EventMarker(stepper.GetNodeIdForEvent(), DOM_STEPPER_EVENT_CHANGE, pageId);
72                 stepper.stepperComponent_->SetChangeEventId(stepper.changeEventId_);
73             },
74         },
75         {
76             DOM_STEPPER_EVENT_FINISH,
77             [](int32_t pageId, DOMStepper& stepper) {
78                 stepper.finishEventId_ = EventMarker(stepper.GetNodeIdForEvent(), DOM_STEPPER_EVENT_FINISH, pageId);
79                 stepper.stepperComponent_->SetFinishEventId(stepper.finishEventId_);
80             },
81         },
82         {
83             DOM_STEPPER_EVENT_NEXT,
84             [](int32_t pageId, DOMStepper& stepper) {
85                 stepper.nextEventId_ = EventMarker(stepper.GetNodeIdForEvent(), DOM_STEPPER_EVENT_NEXT, pageId);
86                 stepper.stepperComponent_->SetNextEventId(stepper.nextEventId_);
87             },
88         },
89         {
90             DOM_STEPPER_EVENT_SKIP,
91             [](int32_t pageId, DOMStepper& stepper) {
92                 stepper.skipEventId_ = EventMarker(stepper.GetNodeIdForEvent(), DOM_STEPPER_EVENT_SKIP, pageId);
93                 stepper.stepperComponent_->SetSkipEventId(stepper.skipEventId_);
94             },
95         },
96     };
97     auto iter = BinarySearchFindIndex(eventOperators, ArraySize(eventOperators), event.c_str());
98     if (iter != -1) {
99         eventOperators[iter].value(pageId, *this);
100         return true;
101     }
102     return false;
103 }
104 
CallSpecializedMethod(const std::string & method,const std::string & args)105 void DOMStepper::CallSpecializedMethod(const std::string& method, const std::string& args)
106 {
107     if (method == DOM_STEPPER_SET_RIGHT_BUTTON_STATUS) {
108         auto controller = stepperComponent_->GetStepperController();
109         if (!controller) {
110             return;
111         }
112         std::unique_ptr<JsonValue> argsValue = JsonUtil::ParseJsonString(args);
113         if (!argsValue || !argsValue->IsArray() || argsValue->GetArraySize() != METHOD_TO_ARGS_SIZE) {
114             LOGW("stepper parse args error");
115             return;
116         }
117         std::unique_ptr<JsonValue> valueParams = argsValue->GetArrayItem(0);
118 
119         std::string status;
120         std::unique_ptr<JsonValue> statusValue = valueParams->GetValue("status");
121         if (statusValue && statusValue->IsString()) {
122             status = statusValue->GetString();
123         }
124 
125         std::string label;
126         std::unique_ptr<JsonValue> labelValue = valueParams->GetValue("label");
127         if (labelValue && labelValue->IsString()) {
128             label = labelValue->GetString();
129         }
130         controller->SetRightButtonStatus(status, label);
131     }
132 }
133 
OnChildNodeAdded(const RefPtr<DOMNode> & child,int32_t slot)134 void DOMStepper::OnChildNodeAdded(const RefPtr<DOMNode>& child, int32_t slot)
135 {
136     auto domStepperItem = AceType::DynamicCast<DOMStepperItem>(child);
137     if (!domStepperItem) {
138         return;
139     }
140     auto childIndex = domStepperItem->GetItemIndex();
141     if (childIndex != DEFAULT_NODE_INDEX) {
142         stepperComponent_->InsertChild(childIndex, child->GetRootComponent());
143     } else {
144         stepperComponent_->AppendChild(child->GetRootComponent());
145     }
146 }
147 
OnChildNodeRemoved(const RefPtr<DOMNode> & child)148 void DOMStepper::OnChildNodeRemoved(const RefPtr<DOMNode>& child)
149 {
150     if (!stepperComponent_ || !child) {
151         return;
152     }
153     stepperComponent_->RemoveChild(child->GetRootComponent());
154 }
155 
InitializeStyle()156 void DOMStepper::InitializeStyle()
157 {
158     ResetInitializedStyle();
159 }
160 
ResetInitializedStyle()161 void DOMStepper::ResetInitializedStyle()
162 {
163     auto theme = GetTheme<StepperTheme>();
164     if (!theme) {
165         return;
166     }
167     stepperComponent_->SetDefaultPaddingStart(theme->GetDefaultPaddingStart());
168     stepperComponent_->SetDefaultPaddingEnd(theme->GetDefaultPaddingEnd());
169     stepperComponent_->SetProgressColor(theme->GetProgressColor());
170     stepperComponent_->SetProgressDiameter(theme->GetProgressDiameter());
171     stepperComponent_->SetArrowWidth(theme->GetArrowWidth());
172     stepperComponent_->SetArrowHeight(theme->GetArrowHeight());
173     stepperComponent_->SetArrowColor(theme->GetArrowColor());
174     stepperComponent_->SetDisabledColor(theme->GetDisabledColor());
175     stepperComponent_->SetRadius(theme->GetRadius());
176     stepperComponent_->SetButtonPressedColor(theme->GetButtonPressedColor());
177     stepperComponent_->SetButtonPressedHeight(theme->GetButtonPressedHeight());
178     stepperComponent_->SetControlHeight(theme->GetControlHeight());
179     stepperComponent_->SetControlMargin(theme->GetControlMargin());
180     stepperComponent_->SetControlPadding(theme->GetControlPadding());
181     stepperComponent_->SetFocusColor(theme->GetFocusColor());
182     stepperComponent_->SetFocusBorderWidth(theme->GetFocusBorderWidth());
183     stepperComponent_->SetMouseHoverColor(theme->GetMouseHoverColor());
184     stepperComponent_->SetDisabledAlpha(theme->GetDisabledAlpha());
185 }
186 
PrepareSpecializedComponent()187 void DOMStepper::PrepareSpecializedComponent()
188 {
189     stepperComponent_->SetTextDirection(IsRightToLeft() ? TextDirection::RTL : TextDirection::LTR);
190 }
191 
192 } // namespace OHOS::Ace::Framework
193