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_RADIO_RADIO_PATTERN_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_RADIO_RADIO_PATTERN_H
18 
19 #include "base/memory/referenced.h"
20 #include "core/components_ng/base/inspector_filter.h"
21 #include "core/components_ng/event/event_hub.h"
22 #include "core/components_ng/pattern/pattern.h"
23 #include "core/components_ng/pattern/radio/radio_accessibility_property.h"
24 #include "core/components_ng/pattern/radio/radio_event_hub.h"
25 #include "core/components_ng/pattern/radio/radio_layout_algorithm.h"
26 #include "core/components_ng/pattern/radio/radio_model_ng.h"
27 #include "core/components_ng/pattern/radio/radio_paint_method.h"
28 #include "core/components_ng/pattern/radio/radio_paint_property.h"
29 
30 namespace OHOS::Ace::NG {
31 class RadioPattern : public Pattern {
32     DECLARE_ACE_TYPE(RadioPattern, Pattern);
33 
34 public:
35     RadioPattern() = default;
36     ~RadioPattern() override = default;
37 
IsAtomicNode()38     bool IsAtomicNode() const override
39     {
40         return true;
41     }
42 
CreatePaintProperty()43     RefPtr<PaintProperty> CreatePaintProperty() override
44     {
45         return MakeRefPtr<RadioPaintProperty>();
46     }
47 
CreateLayoutAlgorithm()48     RefPtr<LayoutAlgorithm> CreateLayoutAlgorithm() override
49     {
50         return MakeRefPtr<RadioLayoutAlgorithm>();
51     }
52 
CreateNodePaintMethod()53     RefPtr<NodePaintMethod> CreateNodePaintMethod() override
54     {
55         if (!GetHost() || !GetHost()->IsActive()) {
56             return nullptr;
57         }
58         if (!radioModifier_) {
59             radioModifier_ = AceType::MakeRefPtr<RadioModifier>();
60         }
61         radioModifier_->SetUseContentModifier(UseContentModifier());
62         auto paintMethod = MakeRefPtr<RadioPaintMethod>(radioModifier_);
63         paintMethod->SetTotalScale(totalScale_);
64         paintMethod->SetPointScale(pointScale_);
65         paintMethod->SetRingPointScale(ringPointScale_);
66         paintMethod->SetUIStatus(uiStatus_);
67         paintMethod->SetEnabled(enabled_);
68         paintMethod->SetIsOnAnimationFlag(isOnAnimationFlag_);
69         paintMethod->SetTouchHoverAnimationType(touchHoverType_);
70         paintMethod->SetIsFirstCreated(isFirstCreated_);
71         paintMethod->SetShowHoverEffect(showHoverEffect_);
72         isFirstCreated_ = false;
73         return paintMethod;
74     }
75 
76     bool OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& /*config*/) override;
77 
CreateEventHub()78     RefPtr<EventHub> CreateEventHub() override
79     {
80         return MakeRefPtr<RadioEventHub>();
81     }
82 
CreateAccessibilityProperty()83     RefPtr<AccessibilityProperty> CreateAccessibilityProperty() override
84     {
85         return MakeRefPtr<RadioAccessibilityProperty>();
86     }
87 
GetPreValue()88     const std::optional<std::string>& GetPreValue()
89     {
90         return preValue_;
91     }
92 
GetPreGroup()93     const std::optional<std::string>& GetPreGroup()
94     {
95         return preGroup_;
96     }
97 
GetPrePageId()98     int32_t GetPrePageId() const
99     {
100         return prePageId_;
101     }
102 
SetPreValue(const std::string & value)103     void SetPreValue(const std::string& value)
104     {
105         preValue_ = value;
106     }
107 
SetPreGroup(const std::string & group)108     void SetPreGroup(const std::string& group)
109     {
110         preGroup_ = group;
111     }
112 
SetPrePageId(int32_t pageId)113     void SetPrePageId(int32_t pageId)
114     {
115         prePageId_ = pageId;
116     }
117 
SetIsUserSetResponseRegion(bool isUserSetResponseRegion)118     void SetIsUserSetResponseRegion(bool isUserSetResponseRegion)
119     {
120         isUserSetResponseRegion_ = isUserSetResponseRegion;
121     }
122 
SetShowHoverEffect(bool showHoverEffect)123     void SetShowHoverEffect(bool showHoverEffect)
124     {
125         showHoverEffect_ = showHoverEffect;
126     }
127 
SetBuilder(const std::function<void ()> && builder)128     void SetBuilder(const std::function<void()>&& builder)
129     {
130         builder_ = std::move(builder);
131     }
132 
133     FocusPattern GetFocusPattern() const override;
134 
135     void UpdateUncheckStatus(const RefPtr<FrameNode>& frameNode);
136 
137     void MarkIsSelected(bool isSelected);
138 
ToJsonValue(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter)139     void ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const override
140     {
141         Pattern::ToJsonValue(json, filter);
142         /* no fixed attr below, just return */
143         if (filter.IsFastFilter()) {
144             return;
145         }
146         auto host = GetHost();
147         CHECK_NULL_VOID(host);
148         auto radioEventHub = host->GetEventHub<NG::RadioEventHub>();
149         auto value = radioEventHub ? radioEventHub->GetValue() : "";
150         auto group = radioEventHub ? radioEventHub->GetGroup() : "";
151         json->PutExtAttr("value", value.c_str(), filter);
152         json->PutExtAttr("group", group.c_str(), filter);
153     }
154     std::string ProvideRestoreInfo() override;
155     void OnRestoreInfo(const std::string& restoreInfo) override;
SetBuilderFunc(RadioMakeCallback && makeFunc)156     void SetBuilderFunc(RadioMakeCallback&& makeFunc)
157     {
158         if (makeFunc == nullptr) {
159             makeFunc_ = std::nullopt;
160             customNode_ = nullptr;
161             OnModifyDone();
162             return;
163         }
164         makeFunc_ = std::move(makeFunc);
165     }
166 
UseContentModifier()167     bool UseContentModifier()
168     {
169         return customNode_ != nullptr;
170     }
171 
172     void SetRadioChecked(bool check);
173     RefPtr<GroupManager> GetGroupManager();
174 
175 private:
176     void OnAttachToFrameNode() override;
177     void OnDetachFromFrameNode(FrameNode* frameNode) override;
178     void OnModifyDone() override;
179     void OnAfterModifyDone() override;
180     void InitClickEvent();
181     void InitTouchEvent();
182     void InitMouseEvent();
183     void OnClick();
184     CalcSize GetChildContentSize();
185     void InitializeParam(
186         Dimension& defaultWidth, Dimension& defaultHeight, Dimension& horizontalPadding, Dimension& verticalPadding);
187     void LoadBuilder();
188     void SetBuilderState();
189     void UpdateIndicatorType();
190     void UpdateState();
191     void UpdateGroupCheckStatus(
192         const RefPtr<FrameNode>& frameNode, const RefPtr<GroupManager>& groupManager, bool check);
193     void OnTouchDown();
194     void OnTouchUp();
195     void CheckPageNode();
196     void HandleEnabled();
197     void HandleMouseEvent(bool isHover);
198     void UpdateUIStatus(bool check);
199     // Init key event
200     void InitOnKeyEvent(const RefPtr<FocusHub>& focusHub);
201     void GetInnerFocusPaintRect(RoundRect& paintRect);
202     void AddHotZoneRect();
203     void RemoveLastHotZoneRect() const;
204     void SetAccessibilityAction();
205     void UpdateSelectStatus(bool isSelected);
206     void FireBuilder();
207 
208     void ImageNodeCreate();
209     void startEnterAnimation();
210     void startExitAnimation();
211     ImageSourceInfo GetImageSourceInfoFromTheme(int32_t RadioIndicator);
212     void UpdateInternalResource(ImageSourceInfo& sourceInfo);
213     void SetPrePageIdToLastPageId();
214     RefPtr<FrameNode> BuildContentModifierNode();
215     RefPtr<ClickEvent> clickListener_;
216     RefPtr<TouchEventImpl> touchListener_;
217     RefPtr<InputEvent> mouseEvent_;
218     RefPtr<FrameNode> customNode_;
219     WeakPtr<GroupManager> groupManager_;
220 
221     std::function<void()> builder_;
222     bool isFirstCreated_ = true;
223     bool preCheck_ = false;
224     std::optional<std::string> preValue_;
225     std::optional<std::string> preGroup_;
226     int32_t prePageId_ = 0;
227     bool isTouch_ = false;
228     bool isHover_ = false;
229     float totalScale_ = 1.0f;
230     float pointScale_ = 0.5f;
231     float ringPointScale_ = 0.0f;
232     UIStatus uiStatus_ = UIStatus::UNSELECTED;
233     Dimension hotZoneHorizontalPadding_;
234     Dimension hotZoneVerticalPadding_;
235     OffsetF offset_;
236     SizeF size_;
237     OffsetF hotZoneOffset_;
238     SizeF hotZoneSize_;
239     bool isGroupChanged_ = false;
240     TouchHoverAnimationType touchHoverType_ = TouchHoverAnimationType::NONE;
241     bool isOnAnimationFlag_ = false;
242     bool preTypeIsBuilder_ = false;
243     RefPtr<FrameNode> builderChildNode_;
244     bool isUserSetResponseRegion_ = false;
245     bool showHoverEffect_ = true;
246     bool enabled_ = true;
247     std::optional<RadioMakeCallback> makeFunc_;
248 
249     RefPtr<RadioModifier> radioModifier_;
250     ACE_DISALLOW_COPY_AND_MOVE(RadioPattern);
251 };
252 } // namespace OHOS::Ace::NG
253 
254 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_RADIO_RADIO_PATTERN_H
255