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 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_CHECKABLE_CHECKABLE_COMPONENT_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_CHECKABLE_CHECKABLE_COMPONENT_H
18 
19 #include "base/geometry/dimension.h"
20 #include "base/utils/label_target.h"
21 #include "core/components/checkable/checkable_theme.h"
22 #include "core/components/declaration/common/attribute.h"
23 #include "core/components_v2/common/common_def.h"
24 #include "core/pipeline/base/render_component.h"
25 #include "core/pipeline/base/render_node.h"
26 #ifndef WEARABLE_PRODUCT
27 #include "core/event/multimodal/multimodal_properties.h"
28 #endif
29 
30 namespace OHOS::Ace {
31 
32 enum class CheckableType {
33     RADIO,
34     CHECKBOX,
35     SWITCH,
36     UNKNOWN,
37 };
38 
39 enum class CheckableStatus {
40     ALL,
41     PART,
42     NONE,
43 };
44 
45 template<class T>
46 class CheckableValue {
47 public:
48     CheckableValue() = default;
CheckableValue(T value)49     explicit CheckableValue(T value) : value_(value) {}
50     virtual ~CheckableValue() = default;
51 
GetValue()52     T GetValue() const
53     {
54         return value_;
55     }
56 
SetValue(T value)57     void SetValue(T value)
58     {
59         value_ = value;
60         hasValue_ = true;
61     }
62 
HasValue()63     bool HasValue() const
64     {
65         return hasValue_;
66     }
67 
68 private:
69     T value_;
70     bool hasValue_ = false;
71 };
72 
73 class ACE_EXPORT CheckableComponent : public RenderComponent {
74     DECLARE_ACE_TYPE(CheckableComponent, RenderComponent);
75 
76 public:
77     CheckableComponent(CheckableType type, const RefPtr<CheckableTheme>& theme);
78     ~CheckableComponent() override = default;
79 
80     RefPtr<RenderNode> CreateRenderNode() override;
81     RefPtr<Element> CreateElement() override;
82 
83     void ApplyTheme(const RefPtr<CheckableTheme>& theme);
84 
GetChangeEvent()85     EventMarker& GetChangeEvent()
86     {
87         return changeEvent_;
88     }
89 
SetChangeEvent(const EventMarker & changeEvent)90     void SetChangeEvent(const EventMarker& changeEvent)
91     {
92         changeEvent_ = changeEvent;
93     }
94 
GetClickEvent()95     const EventMarker& GetClickEvent() const
96     {
97         return clickEvent_;
98     }
99 
SetClickEvent(const EventMarker & clickEvent)100     void SetClickEvent(const EventMarker& clickEvent)
101     {
102         clickEvent_ = clickEvent;
103     }
104 
GetDomChangeEvent()105     const EventMarker& GetDomChangeEvent() const
106     {
107         return domChangeEvent_;
108     }
109 
SetDomChangeEvent(const EventMarker & domChangeEvent)110     void SetDomChangeEvent(const EventMarker& domChangeEvent)
111     {
112         domChangeEvent_ = domChangeEvent;
113     }
114 
GetWidth()115     const Dimension& GetWidth() const
116     {
117         return width_;
118     }
119 
GetHeight()120     const Dimension& GetHeight() const
121     {
122         return height_;
123     }
124 
SetWidth(const Dimension & width)125     void SetWidth(const Dimension& width)
126     {
127         width_ = width;
128     }
129 
SetHeight(const Dimension & height)130     void SetHeight(const Dimension& height)
131     {
132         height_ = height;
133     }
134 
SetHorizontalPadding(const Dimension & hotZoneHorizontalPadding)135     void SetHorizontalPadding(const Dimension& hotZoneHorizontalPadding)
136     {
137         hotZoneHorizontalPadding_ = hotZoneHorizontalPadding;
138     }
139 
GetHotZoneHorizontalPadding()140     const Dimension& GetHotZoneHorizontalPadding() const
141     {
142         return hotZoneHorizontalPadding_;
143     }
144 
SetHotZoneVerticalPadding(const Dimension & hotZoneVerticalPadding)145     void SetHotZoneVerticalPadding(const Dimension& hotZoneVerticalPadding)
146     {
147         hotZoneVerticalPadding_ = hotZoneVerticalPadding;
148     }
149 
GetHotZoneVerticalPadding()150     const Dimension& GetHotZoneVerticalPadding() const
151     {
152         return hotZoneVerticalPadding_;
153     }
154 
SetAspectRatio(double aspectRatio)155     void SetAspectRatio(double aspectRatio)
156     {
157         aspectRatio_ = aspectRatio;
158     }
159 
GetAspectRatio()160     double GetAspectRatio() const
161     {
162         return aspectRatio_;
163     }
164 
GetRadioInnerSizeRatio()165     double GetRadioInnerSizeRatio() const
166     {
167         return radioInnerSizeRatio_;
168     }
169 
IsBackgroundSolid()170     bool IsBackgroundSolid() const
171     {
172         return backgroundSolid_;
173     }
174 
SetBackgroundSolid(bool backgroundSolid)175     void SetBackgroundSolid(bool backgroundSolid)
176     {
177         backgroundSolid_ = backgroundSolid;
178     }
179 
IsDisabled()180     bool IsDisabled() const
181     {
182         return disabled_;
183     }
184 
SetDisabled(bool disabled)185     void SetDisabled(bool disabled)
186     {
187         disabled_ = disabled;
188     }
189 
GetPointColor()190     const Color& GetPointColor() const
191     {
192         return pointColor_;
193     }
194 
SetPointColor(const Color & pointColor)195     void SetPointColor(const Color& pointColor)
196     {
197         pointColor_ = pointColor;
198     }
199 
GetActiveColor()200     const Color& GetActiveColor() const
201     {
202         return activeColor_;
203     }
204 
SetActiveColor(const Color & activeColor)205     void SetActiveColor(const Color& activeColor)
206     {
207         activeColor_ = activeColor;
208     }
209 
GetInactiveColor()210     const Color& GetInactiveColor() const
211     {
212         return inactiveColor_;
213     }
214 
SetInactiveColor(const Color & inactiveColor)215     void SetInactiveColor(const Color& inactiveColor)
216     {
217         inactiveColor_ = inactiveColor;
218     }
219 
GetFocusColor()220     const Color& GetFocusColor() const
221     {
222         return focusColor_;
223     }
224 
SetFocusColor(const Color & focusColor)225     void SetFocusColor(const Color& focusColor)
226     {
227         focusColor_ = focusColor;
228     }
229 
SetDefaultWidth(const Dimension & defaultWidth)230     void SetDefaultWidth(const Dimension& defaultWidth)
231     {
232         defaultWidth_ = defaultWidth;
233     }
234 
GetDefaultWidth()235     const Dimension& GetDefaultWidth() const
236     {
237         return defaultWidth_;
238     }
239 
SetDefaultHeight(const Dimension & defaultHeight)240     void SetDefaultHeight(const Dimension& defaultHeight)
241     {
242         defaultHeight_ = defaultHeight;
243     }
244 
GetDefaultHeight()245     const Dimension& GetDefaultHeight() const
246     {
247         return defaultHeight_;
248     }
249 
SetNeedFocus(bool needFocus)250     void SetNeedFocus(bool needFocus)
251     {
252         needFocus_ = needFocus;
253     }
254 
GetNeedFocus()255     bool GetNeedFocus() const
256     {
257         return needFocus_;
258     }
259 
SetHoverColor(const Color & hoverColor)260     void SetHoverColor(const Color& hoverColor)
261     {
262         hoverColor_ = hoverColor;
263     }
264 
GetHoverColor()265     const Color& GetHoverColor() const
266     {
267         return hoverColor_;
268     }
269 
GetInactivePointColor()270     const Color& GetInactivePointColor() const
271     {
272         return inactivePointColor_;
273     }
274 
GetShadowColor()275     const Color& GetShadowColor() const
276     {
277         return shadowColor_;
278     }
279 
GetShadowWidth()280     const Dimension& GetShadowWidth() const
281     {
282         return shadowWidth_;
283     }
284 
GetHoverRadius()285     const Dimension& GetHoverRadius() const
286     {
287         return hoverRadius_;
288     }
289 
GetBorderWidth()290     const Dimension& GetBorderWidth() const
291     {
292         return borderWidth_;
293     }
294 
GetMouseAnimationType()295     HoverAnimationType GetMouseAnimationType() const
296     {
297         return animationType_;
298     }
299 
SetMouseAnimationType(HoverAnimationType animationType)300     void SetMouseAnimationType(HoverAnimationType animationType)
301     {
302         animationType_ = animationType;
303     }
304 
305     ACE_DEFINE_COMPONENT_EVENT(OnChange, void(bool));
306     ACE_DEFINE_COMPONENT_EVENT(OnClick, void());
307 
308 protected:
309     CheckableType checkableType_ = CheckableType::UNKNOWN;
310     Dimension width_;
311     Dimension height_;
312     Dimension hotZoneHorizontalPadding_;
313     Dimension hotZoneVerticalPadding_;
314     Dimension defaultWidth_;
315     Dimension defaultHeight_;
316     Dimension shadowWidth_;
317     Dimension hoverRadius_;
318     Dimension borderWidth_;
319     bool backgroundSolid_ = true;
320     bool disabled_ = false;
321     bool needFocus_ = true;
322     Color pointColor_;
323     Color activeColor_;
324     Color inactiveColor_;
325     Color inactivePointColor_;
326     Color focusColor_;
327     Color hoverColor_;
328     Color shadowColor_;
329     EventMarker changeEvent_;
330     EventMarker clickEvent_;
331     EventMarker domChangeEvent_;
332     double aspectRatio_ = 1.0;
333     double radioInnerSizeRatio_ = 0.5;
334     HoverAnimationType animationType_ = HoverAnimationType::UNKNOWN;
335 };
336 
337 class ACE_EXPORT CheckboxGroupResult : public BaseEventInfo {
338     DECLARE_RELATIONSHIP_OF_CLASSES(CheckboxGroupResult, BaseEventInfo);
339 
340 public:
CheckboxGroupResult(const std::vector<std::string> & vec,int32_t status)341     CheckboxGroupResult(const std::vector<std::string>& vec, int32_t status) :
342         BaseEventInfo("CheckboxGroupResult"), status_(status) {
343         for (int i = 0; i < static_cast<int32_t>(vec.size()); ++i) {
344             nameVector_.push_back(vec[i]);
345         }
346     }
347 
348     ~CheckboxGroupResult() = default;
349 
GetNameList()350     const std::vector<std::string>& GetNameList() const
351     {
352         return nameVector_;
353     }
354 
GetStatus()355     int32_t GetStatus() const
356     {
357         return status_;
358     }
359 
360 private:
361     std::vector<std::string> nameVector_;
362     int32_t status_ = 0;
363 };
364 
365 class ACE_EXPORT CheckboxComponent : public CheckableComponent, public CheckableValue<bool>, public LabelTarget {
366     DECLARE_ACE_TYPE(CheckboxComponent, CheckableComponent, LabelTarget);
367 
368 public:
369     explicit CheckboxComponent(const RefPtr<CheckboxTheme>& theme);
370     ~CheckboxComponent() override = default;
SetGroupName(const std::string & groupName)371     void SetGroupName(const std::string& groupName)
372     {
373         groupName_ = groupName;
374     }
375 
GetGroupName()376     const std::string& GetGroupName() const
377     {
378         return groupName_;
379     }
380 
SetGroupValue(const CheckableStatus value)381     void SetGroupValue(const CheckableStatus value)
382     {
383         groupValue_ = value;
384     }
385 
GetGroupValue()386     CheckableStatus GetGroupValue() const
387     {
388         return groupValue_;
389     }
390 
SetGroup(const RefPtr<CheckboxComponent> & groupComponent)391     void SetGroup(const RefPtr<CheckboxComponent>& groupComponent)
392     {
393         group_ = groupComponent;
394     }
395 
GetGroup()396     RefPtr<CheckboxComponent> GetGroup() const
397     {
398         return group_;
399     }
400 
SetCheckboxName(const std::string & checkboxName)401     void SetCheckboxName(const std::string& checkboxName)
402     {
403         checkboxName_ = checkboxName;
404     }
405 
GetCheckboxName()406     const std::string& GetCheckboxName() const
407     {
408         return checkboxName_;
409     }
410 
SetBelongGroup(const std::string & group)411     void SetBelongGroup(const std::string& group)
412     {
413         belongGroup_ = group;
414     }
415 
GetBelongGroup()416     const std::string& GetBelongGroup() const
417     {
418         return belongGroup_;
419     }
420 
SetGroupValueUpdateHandler(const std::function<void (CheckableStatus)> & value)421     void SetGroupValueUpdateHandler(const std::function<void(CheckableStatus)>& value)
422     {
423         groupValueUpdateHandler_ = value;
424     }
425 
UpdateRenderChecked(CheckableStatus checked)426     void UpdateRenderChecked(CheckableStatus checked)
427     {
428         if (groupValueUpdateHandler_) {
429             groupValueUpdateHandler_(checked);
430         }
431     }
432 
AddCheckbox(RefPtr<CheckboxComponent> checkboxComponent)433     void AddCheckbox(RefPtr<CheckboxComponent> checkboxComponent)
434     {
435         checkboxList_.push_back(checkboxComponent);
436     }
437 
SetItemValueUpdateHandler(const std::function<void (bool)> & value)438     void SetItemValueUpdateHandler(const std::function<void(bool)>& value)
439     {
440         itemValueUpdateHandler_ = value;
441     }
442 
UpdateItemChecked(bool checked)443     void UpdateItemChecked(bool checked)
444     {
445         if (itemValueUpdateHandler_) {
446             itemValueUpdateHandler_(checked);
447         }
448     }
449 
SetMember(bool isAllSelect)450     void SetMember(bool isAllSelect)
451     {
452         for (auto& item : checkboxList_) {
453             if (item->GetValue() == isAllSelect) {
454                 continue;
455             }
456             item->SetValue(isAllSelect);
457             item->UpdateItemChecked(isAllSelect);
458         }
459     }
460 
SetGroupStatus()461     void SetGroupStatus()
462     {
463         size_t count = 0;
464         for (auto& item : checkboxList_) {
465             if (item->GetValue()) {
466                 ++count;
467             }
468         }
469 
470         if (count == checkboxList_.size()) {
471             UpdateRenderChecked(CheckableStatus::ALL);
472         } else if (count ==0) {
473             UpdateRenderChecked(CheckableStatus::NONE);
474         } else {
475             UpdateRenderChecked(CheckableStatus::PART);
476         }
477     }
478 
GetCheckboxList()479     std::list<RefPtr<CheckboxComponent>> GetCheckboxList()
480     {
481         return checkboxList_;
482     }
483 
SetOnGroupChange(const EventMarker & OnGroupChange)484     void SetOnGroupChange(const EventMarker& OnGroupChange)
485     {
486         OnGroupChange_ = OnGroupChange;
487     }
488 
GetOnGroupChange()489     const EventMarker& GetOnGroupChange() const
490     {
491         return OnGroupChange_;
492     }
493 
GetSelectedCheckBoxName(std::vector<std::string> & result)494     void GetSelectedCheckBoxName(std::vector<std::string>& result)
495     {
496         for (auto& item : checkboxList_) {
497             if (item->GetValue()) {
498                 result.push_back(item->GetCheckboxName());
499             }
500         }
501     }
502 
GetUngroupedCheckboxs()503     static std::unordered_map<std::string, std::list<WeakPtr<CheckboxComponent>>>& GetUngroupedCheckboxs()
504     {
505         return ungroupedCheckboxs_;
506     }
507 
GetCheckboxGroupComponent()508     static std::unordered_map<std::string, RefPtr<CheckboxComponent>>& GetCheckboxGroupComponent()
509     {
510         return checkboxGroups_;
511     }
512 
513 private:
514     CheckableStatus groupValue_ = CheckableStatus::NONE;
515     std::list<RefPtr<CheckboxComponent>> checkboxList_;
516     RefPtr<CheckboxComponent> group_;
517     std::string groupName_ = "";
518     std::string checkboxName_ = "";
519     std::string belongGroup_ = "";
520     std::function<void(bool)> itemValueUpdateHandler_;
521     std::function<void(CheckableStatus)> groupValueUpdateHandler_;
522     EventMarker OnGroupChange_;
523     static std::unordered_map<std::string, std::list<WeakPtr<CheckboxComponent>>> ungroupedCheckboxs_;
524     static std::unordered_map<std::string, RefPtr<CheckboxComponent>> checkboxGroups_;
525 };
526 
527 class ACE_EXPORT SwitchComponent : public CheckableComponent, public CheckableValue<bool> {
528     DECLARE_ACE_TYPE(SwitchComponent, CheckableComponent);
529 
530 public:
531     explicit SwitchComponent(const RefPtr<SwitchTheme>& theme);
532     ~SwitchComponent() override = default;
533 
SetTextStyle(const TextStyle & textStyle)534     void SetTextStyle(const TextStyle& textStyle)
535     {
536         textStyle_ = textStyle;
537     }
538 
GetTextStyle()539     const TextStyle& GetTextStyle() const
540     {
541         return textStyle_;
542     }
543 
GetTextOn()544     const std::string& GetTextOn() const
545     {
546         return textOn_;
547     }
548 
SetTextOn(const std::string & textOn)549     void SetTextOn(const std::string& textOn)
550     {
551         textOn_ = textOn;
552     }
553 
GetTextOff()554     const std::string& GetTextOff() const
555     {
556         return textOff_;
557     }
558 
SetTextOff(const std::string & textOff)559     void SetTextOff(const std::string& textOff)
560     {
561         textOff_ = textOff;
562     }
563 
GetShowText()564     bool GetShowText() const
565     {
566         return showText_;
567     }
568 
SetShowText(bool showText)569     void SetShowText(bool showText)
570     {
571         showText_ = showText;
572     }
573 
GetTextColorOn()574     const Color& GetTextColorOn() const
575     {
576         return textColorOn_;
577     }
578 
SetTextColorOn(const Color & textColorOn)579     void SetTextColorOn(const Color& textColorOn)
580     {
581         textColorOn_ = textColorOn;
582     }
583 
GetTextColorOff()584     const Color& GetTextColorOff() const
585     {
586         return textColorOff_;
587     }
588 
SetTextColorOff(const Color & textColorOff)589     void SetTextColorOff(const Color& textColorOff)
590     {
591         textColorOff_ = textColorOff;
592     }
593 
GetTextPadding()594     const Dimension& GetTextPadding() const
595     {
596         return textPadding_;
597     }
598 
SetTextPadding(const Dimension & textPadding)599     void SetTextPadding(const Dimension& textPadding)
600     {
601         textPadding_ = textPadding;
602     }
603 
604 #ifndef WEARABLE_PRODUCT
GetMultimodalProperties()605     const CommonMultimodalAttribute& GetMultimodalProperties() const
606     {
607         return multimodalProperties_;
608     }
609 
SetMultimodalProperties(const CommonMultimodalAttribute & multimodalProperties)610     void SetMultimodalProperties(const CommonMultimodalAttribute& multimodalProperties)
611     {
612         multimodalProperties_ = multimodalProperties;
613     }
614 #endif
615 
616 private:
617     std::string textOn_ = "On";
618     std::string textOff_ = "Off";
619     Color textColorOn_ = Color::BLACK;
620     Color textColorOff_ = Color::BLACK;
621     bool showText_ = false;
622     TextStyle textStyle_;
623 #ifndef WEARABLE_PRODUCT
624     CommonMultimodalAttribute multimodalProperties_;
625 #endif
626     Dimension textPadding_ { 0, DimensionUnit::PX };
627 };
628 
629 template<class VALUE_TYPE>
630 class ACE_EXPORT RadioComponent : public CheckableComponent, public CheckableValue<VALUE_TYPE>, public LabelTarget {
631     DECLARE_ACE_TYPE(RadioComponent<VALUE_TYPE>, CheckableComponent, LabelTarget);
632 
633 public:
RadioComponent(const RefPtr<RadioTheme> & theme)634     explicit RadioComponent(const RefPtr<RadioTheme>& theme) : CheckableComponent(CheckableType::RADIO, theme) {}
635     ~RadioComponent() override = default;
636 
GetGroupValue()637     VALUE_TYPE GetGroupValue() const
638     {
639         return groupValue_;
640     }
641 
SetGroupValue(VALUE_TYPE groupValue)642     void SetGroupValue(VALUE_TYPE groupValue)
643     {
644         groupValue_ = groupValue;
645     }
646 
GetOriginChecked()647     bool GetOriginChecked()
648     {
649         return originChecked_;
650     }
651 
SetOriginChecked(bool checked)652     void SetOriginChecked(bool checked)
653     {
654         originChecked_ = checked;
655     }
656 
GetGroupValueChangedListener()657     const std::function<void(VALUE_TYPE)>& GetGroupValueChangedListener() const
658     {
659         return groupValueChangedListener_;
660     }
661 
SetGroupValueChangedListener(const std::function<void (VALUE_TYPE)> & groupValueChangedListener)662     void SetGroupValueChangedListener(const std::function<void(VALUE_TYPE)>& groupValueChangedListener)
663     {
664         groupValueChangedListener_ = groupValueChangedListener;
665     }
666 
SetGroupValueUpdateHandler(const std::function<void (VALUE_TYPE)> & groupValueUpdateHandler)667     void SetGroupValueUpdateHandler(const std::function<void(VALUE_TYPE)>& groupValueUpdateHandler)
668     {
669         groupValueUpdateHandler_ = groupValueUpdateHandler;
670     }
671 
UpdateGroupValue(VALUE_TYPE groupValue)672     void UpdateGroupValue(VALUE_TYPE groupValue)
673     {
674         if (groupValueUpdateHandler_) {
675             groupValueUpdateHandler_(groupValue);
676         }
677     }
678 
GetGroupName()679     const std::string& GetGroupName() const
680     {
681         return groupName_;
682     }
SetGroupName(const std::string & groupName)683     void SetGroupName(const std::string& groupName)
684     {
685         groupName_ = groupName;
686     }
687 
688 private:
689     VALUE_TYPE groupValue_;
690     std::string groupName_;
691     std::function<void(VALUE_TYPE)> groupValueChangedListener_;
692     std::function<void(VALUE_TYPE)> groupValueUpdateHandler_;
693     bool originChecked_ = false;
694 };
695 
696 } // namespace OHOS::Ace
697 
698 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_CHECKABLE_CHECKABLE_COMPONENT_H
699