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/button/button_component.h"
17 
18 #include "core/components/button/button_element.h"
19 #include "core/components/padding/padding_component.h"
20 #include "core/components/text/text_component.h"
21 
22 namespace OHOS::Ace {
23 
24 constexpr uint32_t WATCH_BACKGROUND_COLOR = 0xff007dff;
25 constexpr uint32_t WATCH_TEXT_COLOR = 0xffffffff;
26 
ButtonComponent(const std::list<RefPtr<Component>> & children)27 ButtonComponent::ButtonComponent(const std::list<RefPtr<Component>>& children) : ComponentGroup(children)
28 {
29     if (!declaration_) {
30         declaration_ = AceType::MakeRefPtr<ButtonDeclaration>();
31         declaration_->Init();
32     }
33 }
34 
CreateRenderNode()35 RefPtr<RenderNode> ButtonComponent::CreateRenderNode()
36 {
37     return RenderButton::Create();
38 }
39 
CreateElement()40 RefPtr<Element> ButtonComponent::CreateElement()
41 {
42     return AceType::MakeRefPtr<ButtonElement>();
43 }
44 
Build(const RefPtr<ThemeManager> & themeManager,const std::string & text)45 RefPtr<ButtonComponent> ButtonBuilder::Build(const RefPtr<ThemeManager>& themeManager, const std::string& text)
46 {
47     auto buttonTheme = AceType::DynamicCast<ButtonTheme>(themeManager->GetTheme(ButtonTheme::TypeId()));
48     if (!buttonTheme) {
49         TextStyle defaultStyle;
50         return ButtonBuilder::Build(themeManager, text, defaultStyle);
51     }
52     TextStyle textStyle = buttonTheme->GetTextStyle();
53     textStyle.SetAdaptTextSize(buttonTheme->GetMaxFontSize(), buttonTheme->GetMinFontSize());
54     textStyle.SetMaxLines(buttonTheme->GetTextMaxLines());
55     textStyle.SetTextOverflow(TextOverflow::ELLIPSIS);
56     return ButtonBuilder::Build(themeManager, text, textStyle);
57 }
58 
Build(const RefPtr<ThemeManager> & themeManager,const std::string & text,TextStyle & textStyle,const Color & textFocusColor,bool useTextFocus)59 RefPtr<ButtonComponent> ButtonBuilder::Build(const RefPtr<ThemeManager>& themeManager, const std::string& text,
60     TextStyle& textStyle, const Color& textFocusColor, bool useTextFocus)
61 {
62     auto textComponent = AceType::MakeRefPtr<TextComponent>(text);
63     auto padding = AceType::MakeRefPtr<PaddingComponent>();
64     padding->SetChild(textComponent);
65     Component::MergeRSNode(padding, textComponent);
66     std::list<RefPtr<Component>> buttonChildren;
67     buttonChildren.emplace_back(padding);
68     auto buttonComponent = AceType::MakeRefPtr<ButtonComponent>(buttonChildren);
69     buttonComponent->SetHasCustomChild(false);
70     auto buttonTheme = AceType::DynamicCast<ButtonTheme>(themeManager->GetTheme(ButtonTheme::TypeId()));
71     if (!buttonTheme) {
72         return buttonComponent;
73     }
74     if (useTextFocus) {
75         textComponent->SetFocusColor(textFocusColor);
76     } else {
77         textComponent->SetFocusColor(buttonTheme->GetTextFocusColor());
78     }
79     textComponent->SetTextStyle(textStyle);
80     padding->SetPadding(buttonTheme->GetPadding());
81     buttonComponent->SetHeight(buttonTheme->GetHeight());
82     buttonComponent->SetRectRadius(buttonTheme->GetHeight() / 2.0);
83     buttonComponent->SetBackgroundColor(buttonTheme->GetBgColor());
84     buttonComponent->SetClickedColor(buttonTheme->GetClickedColor());
85     buttonComponent->SetFocusColor(buttonTheme->GetBgFocusColor());
86     buttonComponent->SetFocusAnimationColor(buttonTheme->GetBgFocusColor());
87     return buttonComponent;
88 }
89 
GetDisabledState() const90 bool ButtonComponent::GetDisabledState() const
91 {
92     return declaration_->GetDisabledState();
93 }
94 
GetWaitingState() const95 bool ButtonComponent::GetWaitingState() const
96 {
97     return declaration_->GetWaitingState();
98 }
99 
GetAutoFocusState() const100 bool ButtonComponent::GetAutoFocusState() const
101 {
102     return declaration_->GetAutoFocusState();
103 }
104 
GetRadiusState() const105 bool ButtonComponent::GetRadiusState() const
106 {
107     return declaration_->GetRadiusState();
108 }
109 
GetCatchMode() const110 bool ButtonComponent::GetCatchMode() const
111 {
112     return isCatchMode_;
113 }
114 
GetMinWidth() const115 const Dimension& ButtonComponent::GetMinWidth() const
116 {
117     return declaration_->GetMinWidth();
118 }
119 
GetRectRadius() const120 const Dimension& ButtonComponent::GetRectRadius() const
121 {
122     return declaration_->GetRectRadius();
123 }
124 
GetProgressDiameter() const125 const Dimension& ButtonComponent::GetProgressDiameter() const
126 {
127     return declaration_->GetProgressDiameter();
128 }
129 
GetBackgroundColor() const130 const Color& ButtonComponent::GetBackgroundColor() const
131 {
132     return declaration_->GetBackgroundColor();
133 }
134 
GetClickedColor() const135 const Color& ButtonComponent::GetClickedColor() const
136 {
137     return declaration_->GetClickedColor();
138 }
139 
GetDisabledColor() const140 const Color& ButtonComponent::GetDisabledColor() const
141 {
142     return declaration_->GetDisabledColor();
143 }
144 
GetFocusColor() const145 const Color& ButtonComponent::GetFocusColor() const
146 {
147     return declaration_->GetFocusColor();
148 }
149 
GetHoverColor() const150 const Color& ButtonComponent::GetHoverColor() const
151 {
152     return declaration_->GetHoverColor();
153 }
154 
GetProgressColor() const155 const Color& ButtonComponent::GetProgressColor() const
156 {
157     return declaration_->GetProgressColor();
158 }
159 
GetProgressFocusColor() const160 const Color& ButtonComponent::GetProgressFocusColor() const
161 {
162     return declaration_->GetProgressFocusColor();
163 }
164 
GetFocusAnimationColor() const165 const Color& ButtonComponent::GetFocusAnimationColor() const
166 {
167     return declaration_->GetFocusAnimationColor();
168 }
169 
GetBorderEdge() const170 const BorderEdge& ButtonComponent::GetBorderEdge() const
171 {
172     return declaration_->GetBorderEdge();
173 }
174 
GetClickedEventId() const175 const EventMarker& ButtonComponent::GetClickedEventId() const
176 {
177     return declaration_->GetClickedEventId();
178 }
179 
GetKeyEnterEventId() const180 const EventMarker& ButtonComponent::GetKeyEnterEventId() const
181 {
182     return keyEnterId_;
183 }
184 
GetRemoteMessageEventId() const185 const EventMarker& ButtonComponent::GetRemoteMessageEventId() const
186 {
187     return declaration_->GetRemoteMessageEventId();
188 }
189 
GetButtonController() const190 RefPtr<ButtonProgressController> ButtonComponent::GetButtonController() const
191 {
192     return declaration_->GetButtonController();
193 }
194 
SetDisabledState(bool state)195 void ButtonComponent::SetDisabledState(bool state)
196 {
197     declaration_->SetDisabledState(state);
198 }
199 
SetWaitingState(bool state)200 void ButtonComponent::SetWaitingState(bool state)
201 {
202     declaration_->SetWaitingState(state);
203 }
204 
SetAutoFocusState(bool state)205 void ButtonComponent::SetAutoFocusState(bool state)
206 {
207     declaration_->SetAutoFocusState(state);
208 }
209 
SetRadiusState(bool state)210 void ButtonComponent::SetRadiusState(bool state)
211 {
212     declaration_->SetRadiusState(state);
213 }
214 
SetCatchMode(bool catchMode)215 void ButtonComponent::SetCatchMode(bool catchMode)
216 {
217     isCatchMode_ = catchMode;
218 }
219 
SetMinWidth(const Dimension & width)220 void ButtonComponent::SetMinWidth(const Dimension& width)
221 {
222     declaration_->SetMinWidth(width);
223 }
224 
SetRectRadius(const Dimension & radius)225 void ButtonComponent::SetRectRadius(const Dimension& radius)
226 {
227     declaration_->SetRectRadius(radius);
228 }
229 
SetProgressDiameter(const Dimension & diameter)230 void ButtonComponent::SetProgressDiameter(const Dimension& diameter)
231 {
232     declaration_->SetProgressDiameter(diameter);
233 }
234 
SetBackgroundColor(const Color & color)235 void ButtonComponent::SetBackgroundColor(const Color& color)
236 {
237     declaration_->SetBackgroundColor(color);
238 }
239 
SetClickedColor(const Color & color)240 void ButtonComponent::SetClickedColor(const Color& color)
241 {
242     declaration_->SetClickedColor(color);
243 }
244 
SetDisabledColor(const Color & color)245 void ButtonComponent::SetDisabledColor(const Color& color)
246 {
247     declaration_->SetDisabledColor(color);
248 }
249 
SetFocusColor(const Color & color)250 void ButtonComponent::SetFocusColor(const Color& color)
251 {
252     declaration_->SetFocusColor(color);
253 }
254 
SetHoverColor(const Color & color)255 void ButtonComponent::SetHoverColor(const Color& color)
256 {
257     declaration_->SetHoverColor(color);
258 }
259 
SetProgressColor(const Color & color)260 void ButtonComponent::SetProgressColor(const Color& color)
261 {
262     declaration_->SetProgressColor(color);
263 }
264 
SetProgressFocusColor(const Color & color)265 void ButtonComponent::SetProgressFocusColor(const Color& color)
266 {
267     declaration_->SetProgressFocusColor(color);
268 }
269 
SetFocusAnimationColor(const Color & color)270 void ButtonComponent::SetFocusAnimationColor(const Color& color)
271 {
272     declaration_->SetFocusAnimationColor(color);
273 }
274 
SetBorderEdge(const BorderEdge & borderEdge)275 void ButtonComponent::SetBorderEdge(const BorderEdge& borderEdge)
276 {
277     declaration_->SetBorderEdge(borderEdge);
278 }
279 
SetClickedEventId(const EventMarker & eventId)280 void ButtonComponent::SetClickedEventId(const EventMarker& eventId)
281 {
282     declaration_->SetClickedEventId(eventId);
283 }
284 
SetKeyEnterEventId(const EventMarker & eventId)285 void ButtonComponent::SetKeyEnterEventId(const EventMarker& eventId)
286 {
287     keyEnterId_ = eventId;
288 }
289 
SetRemoteMessageEventId(const EventMarker & eventId)290 void ButtonComponent::SetRemoteMessageEventId(const EventMarker& eventId)
291 {
292     declaration_->SetRemoteMessageEventId(eventId);
293 }
294 
SetClickFunction(std::function<void ()> && clickCallback)295 void ButtonComponent::SetClickFunction(std::function<void()>&& clickCallback)
296 {
297     declaration_->SetClickedFunction(std::move(clickCallback));
298 }
299 
SetDeclaration(const RefPtr<ButtonDeclaration> & declaration)300 void ButtonComponent::SetDeclaration(const RefPtr<ButtonDeclaration>& declaration)
301 {
302     if (declaration) {
303         declaration_ = declaration;
304     }
305 }
306 
ApplyTheme(const RefPtr<ButtonTheme> & theme)307 void ButtonComponent::ApplyTheme(const RefPtr<ButtonTheme>& theme)
308 {
309         height_ = theme->GetHeight();
310         SetLayoutFlag(LAYOUT_FLAG_EXTEND_TO_PARENT);
311         SetBackgroundColor(theme->GetBgColor());
312         SetFocusColor(theme->GetBgColor());
313         SetFocusAnimationColor(theme->GetBgFocusColor());
314         SetHoverColor(theme->GetHoverColor());
315         auto padding = AceType::DynamicCast<PaddingComponent>(GetChildren().front());
316         if (!padding) {
317             return;
318         }
319         padding->SetPadding(theme->GetPadding());
320         auto text = AceType::DynamicCast<TextComponent>(padding->GetChild());
321         if (!text) {
322             return;
323         }
324         auto textStyle = theme->GetTextStyle();
325         textStyle.SetAdaptTextSize(textStyle.GetFontSize(), theme->GetMinFontSize());
326         textStyle.SetTextAlign(TextAlign::CENTER);
327         textStyle.SetMaxLines(theme->GetTextMaxLines());
328         textStyle.SetTextOverflow(TextOverflow::ELLIPSIS);
329         if (SystemProperties::GetDeviceType() == DeviceType::WATCH) {
330         SetBackgroundColor(Color(WATCH_BACKGROUND_COLOR));
331         textStyle.SetTextColor(Color(WATCH_TEXT_COLOR));
332         text->SetFocusColor(Color(WATCH_TEXT_COLOR));
333         }
334         text->SetTextStyle(textStyle);
335 }
336 
FitTextHeight(AnimatableDimension & height)337 void ButtonComponent::FitTextHeight(AnimatableDimension& height)
338 {
339     if (isDeclareHeight_) {
340         return;
341     }
342     auto padding = AceType::DynamicCast<PaddingComponent>(GetChildren().front());
343     if (padding == nullptr) {
344         return;
345     }
346     auto text = AceType::DynamicCast<TextComponent>(padding->GetChild());
347     if (text == nullptr) {
348         LOGW("Text component get failed");
349         return;
350     }
351     auto fontSize = text->GetTextStyle().GetFontSize();
352     if (height.Value() < fontSize.Value()) {
353         height = fontSize;
354     }
355 }
356 
Compare(const RefPtr<Component> & component) const357 uint32_t ButtonComponent::Compare(const RefPtr<Component>& component) const
358 {
359     auto button = AceType::DynamicCast<ButtonComponent>(component);
360     if (!button) {
361         return static_cast<uint32_t>(UpdateRenderType::LAYOUT);
362     }
363     uint32_t updateType = static_cast<uint32_t>(UpdateRenderType::NONE);
364     updateType |= static_cast<uint32_t>(button->GetWidth() == width_ ? UpdateRenderType::NONE :
365         UpdateRenderType::LAYOUT);
366     updateType |= static_cast<uint32_t>(button->GetHeight() == height_ ? UpdateRenderType::NONE :
367         UpdateRenderType::LAYOUT);
368     updateType |= static_cast<uint32_t>(button->GetMinWidth() == declaration_->GetMinWidth() ? UpdateRenderType::NONE :
369         UpdateRenderType::LAYOUT);
370     updateType |= static_cast<uint32_t>(button->GetType() == type_ ? UpdateRenderType::NONE : UpdateRenderType::LAYOUT);
371     updateType |= static_cast<uint32_t>(button->GetRadiusState() == declaration_->GetRadiusState() ?
372         UpdateRenderType::NONE : UpdateRenderType::LAYOUT);
373     updateType |= static_cast<uint32_t>(button->GetStateEffect() == stateEffect_ ?
374         UpdateRenderType::NONE : UpdateRenderType::LAYOUT);
375     if (updateType == static_cast<uint32_t>(UpdateRenderType::LAYOUT)) {
376         return updateType;
377     }
378     updateType |= static_cast<uint32_t>(button->GetBackgroundColor() == declaration_->GetBackgroundColor() ?
379         UpdateRenderType::NONE : UpdateRenderType::PAINT);
380     updateType |= static_cast<uint32_t>(button->GetClickedColor() == declaration_->GetClickedColor() ?
381         UpdateRenderType::NONE : UpdateRenderType::PAINT);
382     updateType |= static_cast<uint32_t>(button->GetDisabledColor() == declaration_->GetDisabledColor() ?
383         UpdateRenderType::NONE : UpdateRenderType::PAINT);
384     updateType |= static_cast<uint32_t>(button->GetFocusColor() == declaration_->GetFocusColor() ?
385         UpdateRenderType::NONE : UpdateRenderType::PAINT);
386     updateType |= static_cast<uint32_t>(button->GetHoverColor() == declaration_->GetHoverColor() ?
387         UpdateRenderType::NONE : UpdateRenderType::PAINT);
388     updateType |= static_cast<uint32_t>(button->GetProgressColor() == declaration_->GetProgressColor() ?
389         UpdateRenderType::NONE : UpdateRenderType::PAINT);
390     updateType |= static_cast<uint32_t>(button->GetProgressFocusColor() == declaration_->GetProgressFocusColor() ?
391         UpdateRenderType::NONE : UpdateRenderType::PAINT);
392     updateType |= static_cast<uint32_t>(button->GetFocusAnimationColor() == declaration_->GetFocusAnimationColor() ?
393         UpdateRenderType::NONE : UpdateRenderType::PAINT);
394     return updateType;
395 }
396 
397 } // namespace OHOS::Ace
398