• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "frameworks/core/components/declaration/button/button_declaration.h"
17 
18 #include "base/log/event_report.h"
19 #include "core/common/ace_application_info.h"
20 #include "core/components/button/button_theme.h"
21 #include "frameworks/bridge/common/utils/utils.h"
22 #include "frameworks/core/components/declaration/common/declaration_constants.h"
23 
24 namespace OHOS::Ace {
25 namespace {
26 
27 constexpr uint32_t METHOD_SET_PROGRESS_ARGS_SIZE = 1;
28 
29 } // namespace
30 
31 using namespace Framework;
32 
InitSpecialized()33 void ButtonDeclaration::InitSpecialized()
34 {
35     AddSpecializedAttribute(DeclarationConstants::DEFAULT_BUTTON_ATTR);
36     AddSpecializedStyle(DeclarationConstants::DEFAULT_BUTTON_STYLE);
37     AddSpecializedEvent(DeclarationConstants::DEFAULT_BUTTON_EVENT);
38     AddSpecializedRemoteMessageEvent(DeclarationConstants::DEFAULT_BUTTON_EVENT);
39     AddSpecializedMethod(DeclarationConstants::DEFAULT_BUTTON_METHOD);
40 }
41 
InitializeStyle()42 void ButtonDeclaration::InitializeStyle()
43 {
44     buttonController_ = AceType::MakeRefPtr<ButtonProgressController>();
45     auto& style = MaybeResetStyle<ButtonStyle>(StyleTag::SPECIALIZED_STYLE);
46     if (!style.IsValid()) {
47         return;
48     }
49     RefPtr<ButtonTheme> buttonTheme = GetTheme<ButtonTheme>();
50     if (!buttonTheme) {
51         return;
52     }
53     style.padding = buttonTheme->GetPadding();
54     style.blendOpacity = buttonTheme->GetBgDisabledAlpha();
55     style.borderEdge.SetColor(buttonTheme->GetDownloadBorderColor());
56     style.progressColor = buttonTheme->GetProgressColor();
57     style.diameter = buttonTheme->GetProgressDiameter();
58     style.innerLeftPadding = buttonTheme->GetInnerPadding();
59     style.minWidth = buttonTheme->GetMinWidth();
60     style.radius = buttonTheme->GetRadius();
61     style.backgroundColor = buttonTheme->GetBgColor();
62     style.clickedColor = buttonTheme->GetClickedColor();
63     style.focusColor = buttonTheme->GetBgFocusColor();
64     style.hoverColor = buttonTheme->GetHoverColor();
65     style.focusAnimationColor = buttonTheme->GetBgFocusColor();
66     style.progressFocusColor = buttonTheme->GetProgressFocusColor();
67     style.textFocusColor = buttonTheme->GetTextFocusColor();
68     style.textStyle = buttonTheme->GetTextStyle();
69     style.textStyle.SetAdaptTextSize(style.textStyle.GetFontSize(), buttonTheme->GetMinFontSize());
70     style.textStyle.SetMaxLines(buttonTheme->GetTextMaxLines());
71     style.textStyle.SetTextOverflow(TextOverflow::ELLIPSIS);
72     style.textStyle.SetTextAlign(TextAlign::LEFT);
73 }
74 
SetSpecializedAttr(const std::pair<std::string,std::string> & attr)75 bool ButtonDeclaration::SetSpecializedAttr(const std::pair<std::string, std::string>& attr)
76 {
77     static const LinearMapNode<void (*)(ButtonDeclaration&, const std::string&)> buttonAttrOperators[] = {
78         { DOM_BUTTON_AUTO_FOCUS, [](ButtonDeclaration& button, const std::string& value) {
79             auto& buttonAttr = button.MaybeResetAttribute<ButtonAttribute>(AttributeTag::SPECIALIZED_ATTR);
80             buttonAttr.isAutoFocus = StringToBool(value);
81         } },
82         { DOM_DISABLED, [](ButtonDeclaration& button, const std::string& value) {
83             auto& buttonAttr = button.MaybeResetAttribute<ButtonAttribute>(AttributeTag::SPECIALIZED_ATTR);
84             buttonAttr.isDisabled = StringToBool(value);
85         } },
86         { DOM_BUTTON_ICON, [](ButtonDeclaration& button, const std::string& value) {
87             auto& buttonAttr = button.MaybeResetAttribute<ButtonAttribute>(AttributeTag::SPECIALIZED_ATTR);
88             buttonAttr.iconSrc = value;
89         } },
90         { DOM_PLACEMENT, [](ButtonDeclaration& button, const std::string& value) {
91             auto& buttonAttr = button.MaybeResetAttribute<ButtonAttribute>(AttributeTag::SPECIALIZED_ATTR);
92             buttonAttr.placement = value;
93         } },
94         { DOM_BUTTON_TYPE, [](ButtonDeclaration& button, const std::string& value) {
95             auto& buttonAttr = button.MaybeResetAttribute<ButtonAttribute>(AttributeTag::SPECIALIZED_ATTR);
96             buttonAttr.buttonType = value;
97         } },
98         { DOM_BUTTON_TEXT_DATA, [](ButtonDeclaration& button, const std::string& value) {
99             auto& buttonAttr = button.MaybeResetAttribute<ButtonAttribute>(AttributeTag::SPECIALIZED_ATTR);
100             buttonAttr.textData = value;
101         } },
102         { DOM_BUTTON_WAITING, [](ButtonDeclaration& button, const std::string& value) {
103             auto& buttonAttr = button.MaybeResetAttribute<ButtonAttribute>(AttributeTag::SPECIALIZED_ATTR);
104             buttonAttr.isWaiting = StringToBool(value);
105         } },
106     };
107     auto operatorIter = BinarySearchFindIndex(buttonAttrOperators, ArraySize(buttonAttrOperators), attr.first.c_str());
108     if (operatorIter != -1) {
109         LOGD("Button attrs : %{public}s = %{public}s", attr.first.c_str(), attr.second.c_str());
110         buttonAttrOperators[operatorIter].value(*this, attr.second);
111         return true;
112     }
113     return false;
114 }
115 
SetSpecializedStyle(const std::pair<std::string,std::string> & style)116 bool ButtonDeclaration::SetSpecializedStyle(const std::pair<std::string, std::string>& style)
117 {
118     // Static linear map should be sorted by key.
119     const static LinearMapNode<void (*)(ButtonDeclaration&, const std::string&)> buttonStyleOperators[] = {
120         { DOM_TEXT_ALLOW_SCALE, [](ButtonDeclaration& button, const std::string& value) {
121             auto& buttonStyle = button.MaybeResetStyle<ButtonStyle>(StyleTag::SPECIALIZED_STYLE);
122             buttonStyle.textStyle.SetAllowScale(StringToBool(value));
123         } },
124         { DOM_BUTTON_DEFAULT_COLOR, [](ButtonDeclaration& button, const std::string& value) {
125             auto& buttonStyle = button.MaybeResetStyle<ButtonStyle>(StyleTag::SPECIALIZED_STYLE);
126             buttonStyle.backgroundColor = button.ParseColor(value);
127             buttonStyle.bgColorDefined = true;
128         } },
129         { DOM_BUTTON_BORDER_COLOR, [](ButtonDeclaration& button, const std::string& value) {
130             auto& buttonStyle = button.MaybeResetStyle<ButtonStyle>(StyleTag::SPECIALIZED_STYLE);
131             buttonStyle.borderEdge.SetColor(button.ParseColor(value));
132         } },
133         { DOM_BUTTON_BORDER_WIDTH, [](ButtonDeclaration& button, const std::string& value) {
134             auto& buttonStyle = button.MaybeResetStyle<ButtonStyle>(StyleTag::SPECIALIZED_STYLE);
135             buttonStyle.borderEdge.SetWidth(button.ParseDimension(value));
136         } },
137         { DOM_BUTTON_ICON_DIRECTION, [](ButtonDeclaration& button, const std::string& value) {
138             auto& buttonStyle = button.MaybeResetStyle<ButtonStyle>(StyleTag::SPECIALIZED_STYLE);
139             buttonStyle.matchTextDirection = StringToBool(value);
140         } },
141         { DOM_BUTTON_CLICKED_COLOR, [](ButtonDeclaration& button, const std::string& value) {
142             auto& buttonStyle = button.MaybeResetStyle<ButtonStyle>(StyleTag::SPECIALIZED_STYLE);
143             buttonStyle.clickedColor = button.ParseColor(value);
144         } },
145         { DOM_BUTTON_PROGRESS_DIAMETER, [](ButtonDeclaration& button, const std::string& value) {
146             auto& buttonStyle = button.MaybeResetStyle<ButtonStyle>(StyleTag::SPECIALIZED_STYLE);
147             buttonStyle.diameter = button.ParseDimension(value);
148         } },
149         { DOM_BUTTON_DISABLE_COLOR, [](ButtonDeclaration& button, const std::string& value) {
150             auto& buttonStyle = button.MaybeResetStyle<ButtonStyle>(StyleTag::SPECIALIZED_STYLE);
151             buttonStyle.disabledColor = button.ParseColor(value);
152         } },
153         { DOM_BUTTON_TEXT_DISABLE_COLOR, [](ButtonDeclaration& button, const std::string& value) {
154             auto& buttonStyle = button.MaybeResetStyle<ButtonStyle>(StyleTag::SPECIALIZED_STYLE);
155             buttonStyle.disabledTextColor = button.ParseColor(value);
156         } },
157         { DOM_BUTTON_FOCUS_COLOR, [](ButtonDeclaration& button, const std::string& value) {
158             auto& buttonStyle = button.MaybeResetStyle<ButtonStyle>(StyleTag::SPECIALIZED_STYLE);
159             buttonStyle.focusColor = button.ParseColor(value);
160         } },
161         { DOM_BUTTON_FONT_FAMILY, [](ButtonDeclaration& button, const std::string& value) {
162             auto& buttonStyle = button.MaybeResetStyle<ButtonStyle>(StyleTag::SPECIALIZED_STYLE);
163             buttonStyle.textStyle.SetFontFamilies(button.ParseFontFamilies(value));
164         } },
165         { DOM_BUTTON_FONT_SIZE, [](ButtonDeclaration& button, const std::string& value) {
166             auto& buttonStyle = button.MaybeResetStyle<ButtonStyle>(StyleTag::SPECIALIZED_STYLE);
167             buttonStyle.textStyle.SetFontSize(button.ParseDimension(value));
168             buttonStyle.fontSizeDefined = true;
169         } },
170         { DOM_BUTTON_FONT_STYLE, [](ButtonDeclaration& button, const std::string& value) {
171             auto& buttonStyle = button.MaybeResetStyle<ButtonStyle>(StyleTag::SPECIALIZED_STYLE);
172             buttonStyle.textStyle.SetFontStyle(ConvertStrToFontStyle(value));
173         } },
174         { DOM_BUTTON_FONT_WEIGHT, [](ButtonDeclaration& button, const std::string& value) {
175             auto& buttonStyle = button.MaybeResetStyle<ButtonStyle>(StyleTag::SPECIALIZED_STYLE);
176             buttonStyle.textStyle.SetFontWeight(ConvertStrToFontWeight(value));
177         } },
178         { DOM_BUTTON_HEIGHT, [](ButtonDeclaration& button, const std::string& value) {
179             auto& buttonStyle = button.MaybeResetStyle<ButtonStyle>(StyleTag::SPECIALIZED_STYLE);
180             buttonStyle.height = button.ParseDimension(value);
181             buttonStyle.heightDefined = true;
182         } },
183         { DOM_BUTTON_ICON_HEIGHT, [](ButtonDeclaration& button, const std::string& value) {
184             auto& buttonStyle = button.MaybeResetStyle<ButtonStyle>(StyleTag::SPECIALIZED_STYLE);
185             buttonStyle.iconHeight = button.ParseDimension(value);
186         } },
187         { DOM_BUTTON_ICON_WIDTH, [](ButtonDeclaration& button, const std::string& value) {
188             auto& buttonStyle = button.MaybeResetStyle<ButtonStyle>(StyleTag::SPECIALIZED_STYLE);
189             buttonStyle.iconWidth = button.ParseDimension(value);
190         } },
191         { DOM_BUTTON_INNER_PADDING, [](ButtonDeclaration& button, const std::string& value) {
192             auto& buttonStyle = button.MaybeResetStyle<ButtonStyle>(StyleTag::SPECIALIZED_STYLE);
193             buttonStyle.innerLeftPadding = button.ParseDimension(value);
194         } },
195         { DOM_BUTTON_MIN_WIDTH, [](ButtonDeclaration& button, const std::string& value) {
196             auto& buttonStyle = button.MaybeResetStyle<ButtonStyle>(StyleTag::SPECIALIZED_STYLE);
197             buttonStyle.minWidth = button.ParseDimension(value);
198         } },
199         { DOM_BUTTON_PROGRESS_COLOR, [](ButtonDeclaration& button, const std::string& value) {
200             auto& buttonStyle = button.MaybeResetStyle<ButtonStyle>(StyleTag::SPECIALIZED_STYLE);
201             buttonStyle.progressColor = button.ParseColor(value);
202         } },
203         { DOM_BUTTON_PROGRESS_FOCUS_COLOR, [](ButtonDeclaration& button, const std::string& value) {
204             auto& buttonStyle = button.MaybeResetStyle<ButtonStyle>(StyleTag::SPECIALIZED_STYLE);
205             buttonStyle.progressFocusColor = button.ParseColor(value);
206         } },
207         { DOM_BUTTON_RRECT_RADIUS, [](ButtonDeclaration& button, const std::string& value) {
208             auto& buttonStyle = button.MaybeResetStyle<ButtonStyle>(StyleTag::SPECIALIZED_STYLE);
209             buttonStyle.radius = button.ParseDimension(value);
210             buttonStyle.radiusDefined = true;
211         } },
212         { DOM_BUTTON_TEXT_COLOR, [](ButtonDeclaration& button, const std::string& value) {
213             auto& buttonStyle = button.MaybeResetStyle<ButtonStyle>(StyleTag::SPECIALIZED_STYLE);
214             buttonStyle.textStyle.SetTextColor(button.ParseColor(value));
215             buttonStyle.textColorDefined = true;
216         } },
217         { DOM_BUTTON_WIDTH, [](ButtonDeclaration& button, const std::string& value) {
218             auto& buttonStyle = button.MaybeResetStyle<ButtonStyle>(StyleTag::SPECIALIZED_STYLE);
219             buttonStyle.width = button.ParseDimension(value);
220         } },
221     };
222     auto operatorIter =
223         BinarySearchFindIndex(buttonStyleOperators, ArraySize(buttonStyleOperators), style.first.c_str());
224     if (operatorIter != -1) {
225         LOGD("Button styles : %{public}s = %{public}s", style.first.c_str(), style.second.c_str());
226         buttonStyleOperators[operatorIter].value(*this, style.second);
227         return true;
228     }
229     return false;
230 }
231 
SetSpecializedEvent(int32_t pageId,const std::string & eventId,const std::string & event)232 bool ButtonDeclaration::SetSpecializedEvent(int32_t pageId, const std::string& eventId, const std::string& event)
233 {
234     if (event == DOM_CLICK) {
235         EventMarker eventMarker(eventId, event, pageId);
236         eventMarker.SetCatchMode(false);
237         SetClickedEventId(eventMarker);
238         return true;
239     } else if (event == DOM_CATCH_BUBBLE_CLICK) {
240         EventMarker eventMarker(eventId, event, pageId);
241         eventMarker.SetCatchMode(true);
242         SetClickedEventId(eventMarker);
243         return true;
244     }
245     return false;
246 }
247 
CallSpecializedMethod(const std::string & method,const std::string & args)248 void ButtonDeclaration::CallSpecializedMethod(const std::string& method, const std::string& args)
249 {
250     if (!buttonController_) {
251         EventReport::SendComponentException(ComponentExcepType::BUTTON_COMPONENT_ERR);
252         return;
253     }
254     if (method == DOM_BUTTON_METHOD_SET_PROGRESS) {
255         std::unique_ptr<JsonValue> argsValue = JsonUtil::ParseJsonString(args);
256         if ((!argsValue) || (!argsValue->IsArray()) || (argsValue->GetArraySize() != METHOD_SET_PROGRESS_ARGS_SIZE)) {
257             return;
258         }
259         std::unique_ptr<JsonValue> progressValue = argsValue->GetArrayItem(0)->GetValue("progress");
260         if ((!progressValue) || (!progressValue->IsNumber())) {
261             return;
262         }
263         uint32_t progress = progressValue->GetUInt();
264         buttonController_->SetProgress(progress);
265     }
266 }
267 
268 } // namespace OHOS::Ace
269