1 /*
2  * Copyright (c) 2022-2023 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_NG_PATTERNS_CHECKBOX_CHECKBOX_PATTERN_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_CHECKBOX_CHECKBOX_PATTERN_H
18 
19 #include "base/geometry/axis.h"
20 #include "base/memory/referenced.h"
21 #include "base/utils/utils.h"
22 #include "core/components/checkable/checkable_theme.h"
23 #include "core/components/common/layout/constants.h"
24 #include "core/components_ng/base/inspector_filter.h"
25 #include "core/components_ng/event/event_hub.h"
26 #include "core/components_ng/pattern/toggle/toggle_model_ng.h"
27 #include "core/components_ng/pattern/checkbox/checkbox_accessibility_property.h"
28 #include "core/components_ng/pattern/checkbox/checkbox_event_hub.h"
29 #include "core/components_ng/pattern/checkbox/checkbox_layout_algorithm.h"
30 #include "core/components_ng/pattern/checkbox/checkbox_model_ng.h"
31 #include "core/components_ng/pattern/checkbox/checkbox_paint_method.h"
32 #include "core/components_ng/pattern/checkbox/checkbox_paint_property.h"
33 #include "core/components_ng/pattern/checkboxgroup/checkboxgroup_paint_property.h"
34 #include "core/components_ng/pattern/pattern.h"
35 #include "core/components_ng/pattern/picker/picker_type_define.h"
36 #include "core/pipeline_ng/pipeline_context.h"
37 
38 namespace OHOS::Ace::NG {
39 class CheckBoxPattern : public Pattern {
40     DECLARE_ACE_TYPE(CheckBoxPattern, Pattern);
41 
42 public:
43     CheckBoxPattern() = default;
44     ~CheckBoxPattern() override = default;
45 
IsAtomicNode()46     bool IsAtomicNode() const override
47     {
48         return true;
49     }
50 
CreatePaintProperty()51     RefPtr<PaintProperty> CreatePaintProperty() override
52     {
53         return MakeRefPtr<CheckBoxPaintProperty>();
54     }
55 
CreateLayoutAlgorithm()56     RefPtr<LayoutAlgorithm> CreateLayoutAlgorithm() override
57     {
58         return MakeRefPtr<CheckBoxLayoutAlgorithm>();
59     }
60 
CreateNodePaintMethod()61     RefPtr<NodePaintMethod> CreateNodePaintMethod() override
62     {
63         auto host = GetHost();
64         CHECK_NULL_RETURN(host, nullptr);
65         auto paintProperty = host->GetPaintProperty<CheckBoxPaintProperty>();
66         paintProperty->SetHost(host);
67         if (!paintMethod_) {
68             paintMethod_ = MakeRefPtr<CheckBoxPaintMethod>();
69         }
70         CheckBoxStyle checkboxStyle = CheckBoxStyle::CIRCULAR_STYLE;
71         if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
72             checkboxStyle = CheckBoxStyle::CIRCULAR_STYLE;
73         } else {
74             checkboxStyle = CheckBoxStyle::SQUARE_STYLE;
75         }
76         if (paintProperty->HasCheckBoxSelectedStyle()) {
77             checkboxStyle = paintProperty->GetCheckBoxSelectedStyleValue(CheckBoxStyle::CIRCULAR_STYLE);
78         }
79         paintMethod_->SetCheckboxStyle(checkboxStyle);
80         paintMethod_->SetUseContentModifier(UseContentModifier());
81         paintMethod_->SetHasBuilder(builder_.has_value());
82         host->SetCheckboxFlag(true);
83         auto eventHub = host->GetEventHub<EventHub>();
84         CHECK_NULL_RETURN(eventHub, nullptr);
85         auto enabled = eventHub->IsEnabled();
86         paintMethod_->SetEnabled(enabled);
87         paintMethod_->SetTouchHoverAnimationType(touchHoverType_);
88         return paintMethod_;
89     }
90 
OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper> & dirty,bool,bool)91     bool OnDirtyLayoutWrapperSwap(
92         const RefPtr<LayoutWrapper>& dirty, bool /*skipMeasure*/, bool /*skipLayout*/) override
93     {
94         auto geometryNode = dirty->GetGeometryNode();
95         offset_ = geometryNode->GetContentOffset();
96         size_ = geometryNode->GetContentSize();
97         if (!isUserSetResponseRegion_) {
98             AddHotZoneRect();
99         }
100         return true;
101     }
102 
CreateEventHub()103     RefPtr<EventHub> CreateEventHub() override
104     {
105         return MakeRefPtr<CheckBoxEventHub>();
106     }
107 
CreateAccessibilityProperty()108     RefPtr<AccessibilityProperty> CreateAccessibilityProperty() override
109     {
110         return MakeRefPtr<CheckBoxAccessibilityProperty>();
111     }
112 
GetPreName()113     const std::optional<std::string>& GetPreName()
114     {
115         return preName_;
116     }
117 
GetPreGroup()118     const std::optional<std::string>& GetPreGroup()
119     {
120         return preGroup_;
121     }
122 
GetPrePageId()123     int32_t GetPrePageId() const
124     {
125         return prePageId_;
126     }
127 
SetPreName(const std::string & name)128     void SetPreName(const std::string& name)
129     {
130         preName_ = name;
131     }
132 
SetPreGroup(const std::string & group)133     void SetPreGroup(const std::string& group)
134     {
135         preGroup_ = group;
136     }
137 
SetPrePageId(int32_t pageId)138     void SetPrePageId(int32_t pageId)
139     {
140         prePageId_ = pageId;
141     }
142 
143     void MarkIsSelected(bool isSelected);
SetLastSelect(bool select)144     void SetLastSelect(bool select)
145     {
146         lastSelect_ = select;
147     }
148 
SetBuilderFunc(CheckBoxMakeCallback && makeFunc)149     void SetBuilderFunc(CheckBoxMakeCallback&& makeFunc)
150     {
151         if (makeFunc == nullptr) {
152             makeFunc_ = std::nullopt;
153             OnModifyDone();
154             return;
155         }
156         makeFunc_ = std::move(makeFunc);
157     }
158 
GetContentModifierNode()159     RefPtr<FrameNode> GetContentModifierNode()
160     {
161         return contentModifierNode_;
162     }
163 
SetToggleBuilderFunc(SwitchMakeCallback && toggleMakeFunc)164     void SetToggleBuilderFunc(SwitchMakeCallback&& toggleMakeFunc)
165     {
166         if (toggleMakeFunc == nullptr) {
167             toggleMakeFunc_ = std::nullopt;
168             OnModifyDone();
169             return;
170         }
171         toggleMakeFunc_ = std::move(toggleMakeFunc);
172     }
173 
UseContentModifier()174     bool UseContentModifier()
175     {
176         return contentModifierNode_ != nullptr;
177     }
178 
179     void SetCheckBoxSelect(bool value);
180 
SetIsUserSetResponseRegion(bool isUserSetResponseRegion)181     void SetIsUserSetResponseRegion(bool isUserSetResponseRegion)
182     {
183         isUserSetResponseRegion_ = isUserSetResponseRegion;
184     }
185 
SetIndicatorBuilder(const std::optional<std::function<void ()>> & buildFunc)186     void SetIndicatorBuilder(const std::optional<std::function<void()>>& buildFunc)
187     {
188         builder_ = buildFunc;
189     }
190 
ToJsonValue(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter)191     void ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const override
192     {
193         Pattern::ToJsonValue(json, filter);
194         /* no fixed attr below, just return */
195         if (filter.IsFastFilter()) {
196             return;
197         }
198         auto host = GetHost();
199         CHECK_NULL_VOID(host);
200         auto checkBoxEventHub = host->GetEventHub<NG::CheckBoxEventHub>();
201         auto name = checkBoxEventHub ? checkBoxEventHub->GetName() : "";
202         auto group = checkBoxEventHub ? checkBoxEventHub->GetGroupName() : "";
203         json->PutExtAttr("name", name.c_str(), filter);
204         json->PutExtAttr("group", group.c_str(), filter);
205         json->PutExtAttr("type", "ToggleType.Checkbox", filter);
206         auto paintProperty = host->GetPaintProperty<CheckBoxPaintProperty>();
207         auto select = paintProperty->GetCheckBoxSelectValue(false);
208         json->PutExtAttr("select", select ? "true" : "false", filter);
209     }
210 
SetOriginalCheckboxStyle(OriginalCheckBoxStyle style)211     void SetOriginalCheckboxStyle(OriginalCheckBoxStyle style)
212     {
213         originalStyle_ = style;
214     }
215 
GetOriginalCheckboxStyle()216     OriginalCheckBoxStyle GetOriginalCheckboxStyle()
217     {
218         return originalStyle_;
219     }
220 
221     FocusPattern GetFocusPattern() const override;
222     void UpdateUIStatus(bool check);
223 
224     std::string ProvideRestoreInfo() override;
225     void OnRestoreInfo(const std::string& restoreInfo) override;
226     void OnColorConfigurationUpdate() override;
227     void OnAttachToMainTree() override;
228     void StartCustomNodeAnimation(bool select);
229     RefPtr<GroupManager> GetGroupManager();
230 
SaveCheckboxSettingData(const CheckboxSettingData & checkboxSettingData)231     void SaveCheckboxSettingData(const CheckboxSettingData& checkboxSettingData)
232     {
233         checkboxSettingData_ = checkboxSettingData;
234     }
235 
236 private:
237     void OnAttachToFrameNode() override;
238     void OnDetachFromFrameNode(FrameNode* frameNode) override;
239     void OnModifyDone() override;
240     void OnAfterModifyDone() override;
241     void InitClickEvent();
242     void InitTouchEvent();
243     void InitMouseEvent();
244     void OnClick();
245     void OnTouchDown();
246     void OnTouchUp();
247     void HandleMouseEvent(bool isHover);
248     void CheckPageNode();
249     void LoadBuilder();
250     void UpdateIndicator();
251     void SetBuilderNodeHidden();
252     void StartEnterAnimation();
253     void StartExitAnimation();
254     void UpdateState();
255     void UpdateUnSelect();
256     void CheckBoxGroupIsTrue();
257     void SetPrePageIdToLastPageId();
258     // Init key event
259     void InitOnKeyEvent(const RefPtr<FocusHub>& focusHub);
260     void GetInnerFocusPaintRect(RoundRect& paintRect);
261     void AddHotZoneRect();
262     void RemoveLastHotZoneRect() const;
263     void SetAccessibilityAction();
264     void UpdateSelectStatus(bool isSelected);
265     void ChangeSelfStatusAndNotify(const RefPtr<CheckBoxPaintProperty>& paintProperty);
266     void ChangeGroupStatusAndNotify(const RefPtr<FrameNode>& checkBoxGroupNode, const std::vector<std::string>& vec,
267         bool haveCheckBoxSelected, bool isAllCheckBoxSelected);
268     std::string GetGroupNameWithNavId();
269     void FireBuilder();
270     RefPtr<FrameNode> BuildContentModifierNode();
271     void InitCheckBoxStatusByGroup(RefPtr<FrameNode> checkBoxGroupNode,
272         const RefPtr<CheckBoxGroupPaintProperty>& groupPaintProperty, const std::list<RefPtr<FrameNode>>& list);
273     void UpdateCheckBoxGroupStatus(RefPtr<FrameNode> checkBoxGroupNode, const std::list<RefPtr<FrameNode>>& list);
274     void UpdatePaintPropertyBySettingData(RefPtr<CheckBoxPaintProperty> paintProp);
275 
276     CheckboxSettingData checkboxSettingData_;
277 
278     std::optional<CheckBoxMakeCallback> makeFunc_;
279     std::optional<SwitchMakeCallback> toggleMakeFunc_;
280     RefPtr<FrameNode> contentModifierNode_;
281     std::optional<std::string> preName_;
282     std::optional<std::string> preGroup_;
283     int32_t prePageId_ = 0;
284     bool lastSelect_ = false;
285     std::optional<std::string> currentNavId_ = std::nullopt;
286 
287     RefPtr<ClickEvent> clickListener_;
288     RefPtr<TouchEventImpl> touchListener_;
289     RefPtr<InputEvent> mouseEvent_;
290     bool isTouch_ = false;
291     bool isHover_ = false;
292     bool isFirstCreated_ = true;
293     bool isUserSetResponseRegion_ = false;
294     UIStatus uiStatus_ = UIStatus::UNSELECTED;
295     Dimension hotZoneHorizontalPadding_;
296     Dimension hotZoneVerticalPadding_;
297     OffsetF offset_;
298     SizeF size_;
299     OffsetF hotZoneOffset_;
300     SizeF hotZoneSize_;
301     TouchHoverAnimationType touchHoverType_ = TouchHoverAnimationType::NONE;
302     OriginalCheckBoxStyle originalStyle_ = OriginalCheckBoxStyle::CIRCULAR_STYLE;
303     RefPtr<FrameNode> builderNode_;
304     std::optional<std::function<void()>> builder_;
305 
306     RefPtr<CheckBoxPaintMethod> paintMethod_;
307     WeakPtr<GroupManager> groupManager_;
308 
309     ACE_DISALLOW_COPY_AND_MOVE(CheckBoxPattern);
310 };
311 } // namespace OHOS::Ace::NG
312 
313 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_CHECKBOX_CHECKBOX_PATTERN_H
314