• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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_ng/pattern/checkbox/checkbox_pattern.h"
17 
18 #include "core/components/checkable/checkable_component.h"
19 #include "core/components/checkable/checkable_theme.h"
20 #include "core/components_ng/pattern/checkbox/checkbox_layout_algorithm.h"
21 #include "core/components_ng/pattern/checkbox/checkbox_paint_property.h"
22 #include "core/components_ng/pattern/checkboxgroup/checkboxgroup_paint_property.h"
23 #include "core/components_ng/pattern/checkboxgroup/checkboxgroup_pattern.h"
24 #include "core/components_ng/pattern/stage/page_event_hub.h"
25 #include "core/components_ng/property/calc_length.h"
26 #include "core/components_ng/property/property.h"
27 #include "core/components_v2/inspector/inspector_constants.h"
28 #include "core/event/touch_event.h"
29 #include "core/pipeline/base/constants.h"
30 #include "core/pipeline_ng/pipeline_context.h"
31 
32 namespace OHOS::Ace::NG {
33 
OnAttachToFrameNode()34 void CheckBoxPattern::OnAttachToFrameNode()
35 {
36     auto host = GetHost();
37     CHECK_NULL_VOID(host);
38     host->GetLayoutProperty()->UpdateAlignment(Alignment::CENTER);
39 }
40 
OnModifyDone()41 void CheckBoxPattern::OnModifyDone()
42 {
43     Pattern::OnModifyDone();
44     UpdateState();
45     auto host = GetHost();
46     CHECK_NULL_VOID(host);
47     auto pipeline = PipelineBase::GetCurrentContext();
48     CHECK_NULL_VOID(pipeline);
49     auto checkBoxTheme = pipeline->GetTheme<CheckboxTheme>();
50     CHECK_NULL_VOID(checkBoxTheme);
51     auto layoutProperty = host->GetLayoutProperty();
52     CHECK_NULL_VOID(layoutProperty);
53     MarginProperty margin;
54     margin.left = CalcLength(checkBoxTheme->GetHotZoneHorizontalPadding().Value());
55     margin.right = CalcLength(checkBoxTheme->GetHotZoneHorizontalPadding().Value());
56     margin.top = CalcLength(checkBoxTheme->GetHotZoneVerticalPadding().Value());
57     margin.bottom = CalcLength(checkBoxTheme->GetHotZoneVerticalPadding().Value());
58     auto& setMargin = layoutProperty->GetMarginProperty();
59     if (setMargin) {
60         if (setMargin->left.has_value()) {
61             margin.left = setMargin->left;
62         }
63         if (setMargin->right.has_value()) {
64             margin.right = setMargin->right;
65         }
66         if (setMargin->top.has_value()) {
67             margin.top = setMargin->top;
68         }
69         if (setMargin->bottom.has_value()) {
70             margin.bottom = setMargin->bottom;
71         }
72     }
73     layoutProperty->UpdateMargin(margin);
74     hotZoneHorizontalPadding_ = checkBoxTheme->GetHotZoneHorizontalPadding();
75     hotZoneVerticalPadding_ = checkBoxTheme->GetHotZoneVerticalPadding();
76     InitClickEvent();
77     InitTouchEvent();
78     InitMouseEvent();
79     auto focusHub = host->GetFocusHub();
80     CHECK_NULL_VOID(focusHub);
81     InitOnKeyEvent(focusHub);
82 }
83 
InitClickEvent()84 void CheckBoxPattern::InitClickEvent()
85 {
86     if (clickListener_) {
87         return;
88     }
89     auto host = GetHost();
90     CHECK_NULL_VOID(host);
91     auto gesture = host->GetOrCreateGestureEventHub();
92     CHECK_NULL_VOID(gesture);
93     auto clickCallback = [weak = WeakClaim(this)](GestureEvent& info) {
94         auto checkboxPattern = weak.Upgrade();
95         CHECK_NULL_VOID(checkboxPattern);
96         checkboxPattern->OnClick();
97     };
98     clickListener_ = MakeRefPtr<ClickEvent>(std::move(clickCallback));
99     gesture->AddClickEvent(clickListener_);
100 }
101 
InitTouchEvent()102 void CheckBoxPattern::InitTouchEvent()
103 {
104     if (touchListener_) {
105         return;
106     }
107     auto host = GetHost();
108     CHECK_NULL_VOID(host);
109     auto gesture = host->GetOrCreateGestureEventHub();
110     CHECK_NULL_VOID(gesture);
111     auto touchCallback = [weak = WeakClaim(this)](const TouchEventInfo& info) {
112         auto checkboxPattern = weak.Upgrade();
113         CHECK_NULL_VOID(checkboxPattern);
114         if (info.GetTouches().front().GetTouchType() == TouchType::DOWN) {
115             checkboxPattern->OnTouchDown();
116         }
117         if (info.GetTouches().front().GetTouchType() == TouchType::UP ||
118             info.GetTouches().front().GetTouchType() == TouchType::CANCEL) {
119             checkboxPattern->OnTouchUp();
120         }
121     };
122     touchListener_ = MakeRefPtr<TouchEventImpl>(std::move(touchCallback));
123     gesture->AddTouchEvent(touchListener_);
124 }
125 
InitMouseEvent()126 void CheckBoxPattern::InitMouseEvent()
127 {
128     if (mouseEvent_) {
129         return;
130     }
131     auto host = GetHost();
132     CHECK_NULL_VOID(host);
133     auto gesture = host->GetOrCreateGestureEventHub();
134     CHECK_NULL_VOID(gesture);
135     auto eventHub = host->GetEventHub<CheckBoxEventHub>();
136     auto inputHub = eventHub->GetOrCreateInputEventHub();
137 
138     auto mouseTask = [weak = WeakClaim(this)](bool isHover) {
139         auto pattern = weak.Upgrade();
140         if (pattern) {
141             pattern->HandleMouseEvent(isHover);
142         }
143     };
144     mouseEvent_ = MakeRefPtr<InputEvent>(std::move(mouseTask));
145     inputHub->AddOnHoverEvent(mouseEvent_);
146 }
147 
HandleMouseEvent(bool isHover)148 void CheckBoxPattern::HandleMouseEvent(bool isHover)
149 {
150     isHover_ = isHover;
151     if (isHover) {
152         touchHoverType_ = TouchHoverAnimationType::HOVER;
153     } else {
154         touchHoverType_ = TouchHoverAnimationType::NONE;
155     }
156     auto host = GetHost();
157     CHECK_NULL_VOID(host);
158     host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
159 }
160 
OnClick()161 void CheckBoxPattern::OnClick()
162 {
163     auto host = GetHost();
164     CHECK_NULL_VOID(host);
165     auto paintProperty = host->GetPaintProperty<CheckBoxPaintProperty>();
166     CHECK_NULL_VOID(paintProperty);
167     bool isSelected = false;
168     if (paintProperty->HasCheckBoxSelect()) {
169         isSelected = paintProperty->GetCheckBoxSelectValue();
170     } else {
171         isSelected = false;
172     }
173     paintProperty->UpdateCheckBoxSelect(!isSelected);
174     UpdateState();
175 }
176 
OnTouchDown()177 void CheckBoxPattern::OnTouchDown()
178 {
179     if (isHover_) {
180         touchHoverType_ = TouchHoverAnimationType::HOVER_TO_PRESS;
181     } else {
182         touchHoverType_ = TouchHoverAnimationType::PRESS;
183     }
184     auto host = GetHost();
185     CHECK_NULL_VOID(host);
186     isTouch_ = true;
187     host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
188 }
189 
OnTouchUp()190 void CheckBoxPattern::OnTouchUp()
191 {
192     if (isHover_) {
193         touchHoverType_ = TouchHoverAnimationType::PRESS_TO_HOVER;
194     } else {
195         touchHoverType_ = TouchHoverAnimationType::NONE;
196     }
197     auto host = GetHost();
198     CHECK_NULL_VOID(host);
199     isTouch_ = false;
200     host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
201 }
202 
UpdateUnSelect()203 void CheckBoxPattern::UpdateUnSelect()
204 {
205     auto host = GetHost();
206     CHECK_NULL_VOID(host);
207     auto paintProperty = host->GetPaintProperty<CheckBoxPaintProperty>();
208     CHECK_NULL_VOID(paintProperty);
209     if (paintProperty->HasCheckBoxSelect() && !paintProperty->GetCheckBoxSelectValue()) {
210         uiStatus_ = UIStatus::UNSELECTED;
211         host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
212     }
213 }
214 
UpdateUIStatus(bool check)215 void CheckBoxPattern::UpdateUIStatus(bool check)
216 {
217     uiStatus_ = check ? UIStatus::OFF_TO_ON : UIStatus::ON_TO_OFF;
218     auto host = GetHost();
219     CHECK_NULL_VOID(host);
220     host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
221 }
222 
OnDetachFromFrameNode(FrameNode * frameNode)223 void CheckBoxPattern::OnDetachFromFrameNode(FrameNode* frameNode)
224 {
225     CHECK_NULL_VOID(frameNode);
226     auto pipelineContext = PipelineContext::GetCurrentContext();
227     CHECK_NULL_VOID(pipelineContext);
228     auto stageManager = pipelineContext->GetStageManager();
229     CHECK_NULL_VOID(stageManager);
230     auto pageNode = stageManager->GetLastPage();
231     CHECK_NULL_VOID(pageNode);
232     auto pageEventHub = pageNode->GetEventHub<NG::PageEventHub>();
233     CHECK_NULL_VOID(pageEventHub);
234     auto checkBoxEventHub = frameNode->GetEventHub<NG::CheckBoxEventHub>();
235     CHECK_NULL_VOID(checkBoxEventHub);
236     auto checkBoxGroupMap = pageEventHub->GetCheckBoxGroupMap();
237     UpdateCheckBoxGroupStatusWhenDetach(frameNode, checkBoxGroupMap);
238     pageEventHub->RemoveCheckBoxFromGroup(checkBoxEventHub->GetGroupName(), frameNode->GetId());
239 }
240 
CheckPageNode()241 void CheckBoxPattern::CheckPageNode()
242 {
243     auto host = GetHost();
244     CHECK_NULL_VOID(host);
245     auto prePageId = GetPrePageId();
246     auto pipelineContext = PipelineContext::GetCurrentContext();
247     CHECK_NULL_VOID(pipelineContext);
248     auto stageManager = pipelineContext->GetStageManager();
249     CHECK_NULL_VOID(stageManager);
250     auto pageNode = stageManager->GetPageById(host->GetPageId());
251     CHECK_NULL_VOID_NOLOG(pageNode);
252     if (pageNode->GetId() != prePageId) {
253         auto eventHub = host->GetEventHub<CheckBoxEventHub>();
254         CHECK_NULL_VOID(eventHub);
255         auto pageEventHub = pageNode->GetEventHub<NG::PageEventHub>();
256         CHECK_NULL_VOID(pageEventHub);
257         auto group = eventHub->GetGroupName();
258 
259         pageEventHub->AddCheckBoxToGroup(group, host->GetId());
260         SetPrePageId(pageNode->GetId());
261     }
262 }
263 
UpdateState()264 void CheckBoxPattern::UpdateState()
265 {
266     auto host = GetHost();
267     CHECK_NULL_VOID(host);
268     auto eventHub = host->GetEventHub<CheckBoxEventHub>();
269     CHECK_NULL_VOID(eventHub);
270     auto pipelineContext = PipelineContext::GetCurrentContext();
271     CHECK_NULL_VOID(pipelineContext);
272     auto stageManager = pipelineContext->GetStageManager();
273     CHECK_NULL_VOID(stageManager);
274     auto pageNode = stageManager->GetLastPage();
275     CHECK_NULL_VOID(pageNode);
276     auto pageEventHub = pageNode->GetEventHub<NG::PageEventHub>();
277     CHECK_NULL_VOID(pageEventHub);
278     auto paintProperty = host->GetPaintProperty<CheckBoxPaintProperty>();
279     CHECK_NULL_VOID(paintProperty);
280     auto checkBoxGroupMap = pageEventHub->GetCheckBoxGroupMap();
281     auto preGroup = GetPreGroup();
282     auto group = eventHub->GetGroupName();
283     if (!preGroup.has_value()) {
284         pageEventHub->AddCheckBoxToGroup(group, host->GetId());
285         SetPrePageId(pageNode->GetId());
286         auto callback = [weak = WeakClaim(this)]() {
287             auto checkbox = weak.Upgrade();
288             if (checkbox) {
289                 checkbox->CheckPageNode();
290                 checkbox->CheckBoxGroupIsTrue();
291             }
292         };
293         pipelineContext->AddBuildFinishCallBack(callback);
294         if (paintProperty->HasCheckBoxSelect()) {
295             auto isSelected = paintProperty->GetCheckBoxSelectValue();
296             SetLastSelect(isSelected);
297         }
298         isFirstCreated_ = false;
299         SetPreGroup(group);
300         return;
301     }
302     if (preGroup.has_value() && preGroup.value() != group) {
303         pageEventHub->RemoveCheckBoxFromGroup(preGroup.value(), host->GetId());
304         pageEventHub->AddCheckBoxToGroup(group, host->GetId());
305         SetPrePageId(pageNode->GetId());
306     }
307     SetPreGroup(group);
308     bool isSelected = false;
309     if (paintProperty->HasCheckBoxSelect()) {
310         isSelected = paintProperty->GetCheckBoxSelectValue();
311         if (lastSelect_ != isSelected) {
312             UpdateUIStatus(isSelected);
313             SetLastSelect(isSelected);
314             auto checkboxEventHub = GetEventHub<CheckBoxEventHub>();
315             CHECK_NULL_VOID(checkboxEventHub);
316             checkboxEventHub->UpdateChangeEvent(isSelected);
317         }
318     }
319     UpdateCheckBoxGroupStatus(host, checkBoxGroupMap, isSelected);
320 }
321 
UpdateCheckBoxGroupStatus(const RefPtr<FrameNode> & checkBoxFrameNode,std::unordered_map<std::string,std::list<WeakPtr<FrameNode>>> & checkBoxGroupMap,bool select)322 void CheckBoxPattern::UpdateCheckBoxGroupStatus(const RefPtr<FrameNode>& checkBoxFrameNode,
323     std::unordered_map<std::string, std::list<WeakPtr<FrameNode>>>& checkBoxGroupMap, bool select)
324 {
325     checkBoxFrameNode->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
326     auto checkBoxEventHub = checkBoxFrameNode->GetEventHub<CheckBoxEventHub>();
327     CHECK_NULL_VOID(checkBoxEventHub);
328     auto group = checkBoxEventHub->GetGroupName();
329     std::vector<std::string> vec;
330     RefPtr<FrameNode> checkBoxGroupNode;
331     bool isSameAsSelf = true;
332     const auto& list = checkBoxGroupMap[group];
333     for (auto&& item : list) {
334         auto node = item.Upgrade();
335         if (!node) {
336             continue;
337         }
338         if (node == checkBoxFrameNode) {
339             if (select) {
340                 auto eventHub = node->GetEventHub<CheckBoxEventHub>();
341                 CHECK_NULL_VOID(eventHub);
342                 vec.push_back(eventHub->GetName());
343             }
344             continue;
345         }
346         if (node->GetTag() == V2::CHECKBOXGROUP_ETS_TAG) {
347             checkBoxGroupNode = node;
348             continue;
349         }
350         auto paintProperty = node->GetPaintProperty<CheckBoxPaintProperty>();
351         CHECK_NULL_VOID(paintProperty);
352         if (!paintProperty->HasCheckBoxSelect()) {
353             if (select) {
354                 isSameAsSelf = false;
355             }
356         }
357         if (paintProperty->HasCheckBoxSelect() && paintProperty->GetCheckBoxSelectValue() != select) {
358             isSameAsSelf = false;
359         }
360         if (paintProperty->HasCheckBoxSelect() && paintProperty->GetCheckBoxSelectValue()) {
361             auto eventHub = node->GetEventHub<CheckBoxEventHub>();
362             CHECK_NULL_VOID(eventHub);
363             vec.push_back(eventHub->GetName());
364         }
365     }
366     CHECK_NULL_VOID(checkBoxGroupNode);
367     auto groupPaintProperty = checkBoxGroupNode->GetPaintProperty<CheckBoxGroupPaintProperty>();
368     CHECK_NULL_VOID(groupPaintProperty);
369     auto pattern = checkBoxGroupNode->GetPattern<CheckBoxGroupPattern>();
370     CHECK_NULL_VOID(pattern);
371     if (isSameAsSelf) {
372         if (select) {
373             groupPaintProperty->SetSelectStatus(CheckBoxGroupPaintProperty::SelectStatus::ALL);
374             pattern->UpdateUIStatus(select);
375         } else {
376             groupPaintProperty->SetSelectStatus(CheckBoxGroupPaintProperty::SelectStatus::NONE);
377             pattern->ResetUIStatus();
378         }
379         checkBoxGroupNode->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
380     } else {
381         auto checkBoxGroupStatus = groupPaintProperty->GetSelectStatus();
382         if (checkBoxGroupStatus == CheckBoxGroupPaintProperty::SelectStatus::ALL ||
383             checkBoxGroupStatus == CheckBoxGroupPaintProperty::SelectStatus::NONE) {
384             groupPaintProperty->SetSelectStatus(CheckBoxGroupPaintProperty::SelectStatus::PART);
385             checkBoxGroupNode->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
386         }
387     }
388 
389     auto status = groupPaintProperty->GetSelectStatus();
390     CheckboxGroupResult groupResult(vec, int(status));
391     auto eventHub = checkBoxGroupNode->GetEventHub<CheckBoxGroupEventHub>();
392     CHECK_NULL_VOID(eventHub);
393     eventHub->UpdateChangeEvent(&groupResult);
394 }
395 
UpdateCheckBoxGroupStatusWhenDetach(const FrameNode * checkBoxFrameNode,std::unordered_map<std::string,std::list<WeakPtr<FrameNode>>> & checkBoxGroupMap)396 void CheckBoxPattern::UpdateCheckBoxGroupStatusWhenDetach(const FrameNode* checkBoxFrameNode,
397     std::unordered_map<std::string, std::list<WeakPtr<FrameNode>>>& checkBoxGroupMap)
398 {
399     auto checkBoxEventHub = checkBoxFrameNode->GetEventHub<CheckBoxEventHub>();
400     CHECK_NULL_VOID(checkBoxEventHub);
401     auto group = checkBoxEventHub->GetGroupName();
402     std::vector<std::string> vec;
403     RefPtr<FrameNode> checkBoxGroupNode;
404     bool haveCheckBoxSelected = false;
405     bool isAllCheckBoxSelected = true;
406     const auto& list = checkBoxGroupMap[group];
407     for (auto&& item : list) {
408         auto node = item.Upgrade();
409         if (!node) {
410             continue;
411         }
412         if (node->GetTag() == V2::CHECKBOXGROUP_ETS_TAG) {
413             checkBoxGroupNode = node;
414             continue;
415         }
416         auto paintProperty = node->GetPaintProperty<CheckBoxPaintProperty>();
417         CHECK_NULL_VOID(paintProperty);
418         if (paintProperty->HasCheckBoxSelect() && paintProperty->GetCheckBoxSelectValue()) {
419             auto eventHub = node->GetEventHub<CheckBoxEventHub>();
420             CHECK_NULL_VOID(eventHub);
421             vec.push_back(eventHub->GetName());
422             haveCheckBoxSelected = true;
423         } else {
424             isAllCheckBoxSelected = false;
425         }
426     }
427     CHECK_NULL_VOID_NOLOG(checkBoxGroupNode);
428     auto groupPaintProperty = checkBoxGroupNode->GetPaintProperty<CheckBoxGroupPaintProperty>();
429     CHECK_NULL_VOID(groupPaintProperty);
430     auto pattern = checkBoxGroupNode->GetPattern<CheckBoxGroupPattern>();
431     CHECK_NULL_VOID(pattern);
432     if (haveCheckBoxSelected) {
433         if (isAllCheckBoxSelected) {
434             groupPaintProperty->SetSelectStatus(CheckBoxGroupPaintProperty::SelectStatus::ALL);
435             pattern->UpdateUIStatus(true);
436         } else {
437             groupPaintProperty->SetSelectStatus(CheckBoxGroupPaintProperty::SelectStatus::PART);
438             pattern->ResetUIStatus();
439         }
440     } else {
441         groupPaintProperty->SetSelectStatus(CheckBoxGroupPaintProperty::SelectStatus::NONE);
442         pattern->UpdateUIStatus(false);
443     }
444     checkBoxGroupNode->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
445     auto status = groupPaintProperty->GetSelectStatus();
446     CheckboxGroupResult groupResult(vec, int(status));
447     auto eventHub = checkBoxGroupNode->GetEventHub<CheckBoxGroupEventHub>();
448     CHECK_NULL_VOID(eventHub);
449     eventHub->UpdateChangeEvent(&groupResult);
450 }
451 
CheckBoxGroupIsTrue()452 void CheckBoxPattern::CheckBoxGroupIsTrue()
453 {
454     auto checkBoxFrameNode = GetHost();
455     CHECK_NULL_VOID(checkBoxFrameNode);
456     auto pipelineContext = PipelineContext::GetCurrentContext();
457     CHECK_NULL_VOID(pipelineContext);
458     auto stageManager = pipelineContext->GetStageManager();
459     CHECK_NULL_VOID(stageManager);
460     auto pageNode = stageManager->GetLastPage();
461     CHECK_NULL_VOID(pageNode);
462     auto pageEventHub = pageNode->GetEventHub<NG::PageEventHub>();
463     CHECK_NULL_VOID(pageEventHub);
464     auto paintProperty = checkBoxFrameNode->GetPaintProperty<CheckBoxPaintProperty>();
465     CHECK_NULL_VOID(paintProperty);
466     auto checkBoxGroupMap = pageEventHub->GetCheckBoxGroupMap();
467     auto checkBoxEventHub = checkBoxFrameNode->GetEventHub<CheckBoxEventHub>();
468     CHECK_NULL_VOID(checkBoxEventHub);
469     auto group = checkBoxEventHub->GetGroupName();
470     std::vector<std::string> vec;
471     RefPtr<FrameNode> checkBoxGroupNode;
472     bool allSelectIsNull = true;
473     const auto& list = checkBoxGroupMap[group];
474     for (auto&& item : list) {
475         auto node = item.Upgrade();
476         if (!node) {
477             continue;
478         }
479         if (node->GetTag() == V2::CHECKBOXGROUP_ETS_TAG) {
480             checkBoxGroupNode = node;
481             continue;
482         }
483         auto paintProperty = node->GetPaintProperty<CheckBoxPaintProperty>();
484         CHECK_NULL_VOID(paintProperty);
485 
486         if (paintProperty->HasCheckBoxSelect()) {
487             allSelectIsNull = false;
488         } else {
489             paintProperty->UpdateCheckBoxSelect(false);
490         }
491     }
492 
493     CHECK_NULL_VOID_NOLOG(checkBoxGroupNode);
494     auto groupPaintProperty = checkBoxGroupNode->GetPaintProperty<CheckBoxGroupPaintProperty>();
495     if (groupPaintProperty->GetIsCheckBoxCallbackDealed()) {
496         return;
497     }
498     // All checkboxes do not set select status.
499     if (allSelectIsNull) {
500         if (groupPaintProperty->HasCheckBoxGroupSelect() && groupPaintProperty->GetCheckBoxGroupSelectValue()) {
501             groupPaintProperty->SetSelectStatus(CheckBoxGroupPaintProperty::SelectStatus::ALL);
502             groupPaintProperty->UpdateCheckBoxGroupSelect(true);
503             checkBoxGroupNode->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
504             for (auto&& item : list) {
505                 auto node = item.Upgrade();
506                 if (!node) {
507                     continue;
508                 }
509                 if (node->GetTag() == V2::CHECKBOXGROUP_ETS_TAG) {
510                     continue;
511                 }
512                 auto paintProperty = node->GetPaintProperty<CheckBoxPaintProperty>();
513                 CHECK_NULL_VOID(paintProperty);
514                 paintProperty->UpdateCheckBoxSelect(true);
515                 auto checkBoxPattern = node->GetPattern<CheckBoxPattern>();
516                 CHECK_NULL_VOID(checkBoxPattern);
517                 checkBoxPattern->UpdateUIStatus(true);
518                 checkBoxPattern->SetLastSelect(true);
519             }
520         }
521     }
522     // Some checkboxes set select status.
523     if (!allSelectIsNull) {
524         bool allIsSame = true;
525         bool selfSelect = paintProperty->GetCheckBoxSelectValue();
526         for (auto&& item : list) {
527             auto node = item.Upgrade();
528             if (node == checkBoxFrameNode) {
529                 continue;
530             }
531             if (!node) {
532                 continue;
533             }
534             if (node->GetTag() == V2::CHECKBOXGROUP_ETS_TAG) {
535                 continue;
536             }
537             auto paintProperty = node->GetPaintProperty<CheckBoxPaintProperty>();
538             CHECK_NULL_VOID(paintProperty);
539             if (selfSelect != paintProperty->GetCheckBoxSelectValue()) {
540                 allIsSame = false;
541             }
542             node->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
543         }
544         auto checkBoxGroupPattern = checkBoxGroupNode->GetPattern<CheckBoxGroupPattern>();
545         CHECK_NULL_VOID(checkBoxGroupPattern);
546         if (allIsSame && paintProperty->GetCheckBoxSelectValue()) {
547             groupPaintProperty->SetSelectStatus(CheckBoxGroupPaintProperty::SelectStatus::ALL);
548             checkBoxGroupPattern->UpdateUIStatus(true);
549         } else if (allIsSame && !paintProperty->GetCheckBoxSelectValue()) {
550             groupPaintProperty->SetSelectStatus(CheckBoxGroupPaintProperty::SelectStatus::NONE);
551             checkBoxGroupPattern->ResetUIStatus();
552         } else {
553             groupPaintProperty->SetSelectStatus(CheckBoxGroupPaintProperty::SelectStatus::PART);
554             checkBoxGroupPattern->ResetUIStatus();
555         }
556         checkBoxGroupNode->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
557     }
558     groupPaintProperty->SetIsCheckBoxCallbackDealed(true);
559 }
560 
InitOnKeyEvent(const RefPtr<FocusHub> & focusHub)561 void CheckBoxPattern::InitOnKeyEvent(const RefPtr<FocusHub>& focusHub)
562 {
563     auto getInnerPaintRectCallback = [wp = WeakClaim(this)](RoundRect& paintRect) {
564         auto pattern = wp.Upgrade();
565         if (pattern) {
566             pattern->GetInnerFocusPaintRect(paintRect);
567         }
568     };
569     focusHub->SetInnerFocusPaintRectCallback(getInnerPaintRectCallback);
570 }
571 
GetInnerFocusPaintRect(RoundRect & paintRect)572 void CheckBoxPattern::GetInnerFocusPaintRect(RoundRect& paintRect)
573 {
574     auto pipelineContext = PipelineBase::GetCurrentContext();
575     CHECK_NULL_VOID(pipelineContext);
576     auto checkBoxTheme = pipelineContext->GetTheme<CheckboxTheme>();
577     CHECK_NULL_VOID(checkBoxTheme);
578     auto borderRadius = checkBoxTheme->GetFocusRadius().ConvertToPx();
579     auto focusPaintPadding = checkBoxTheme->GetFocusPaintPadding().ConvertToPx();
580     float originX = offset_.GetX() - focusPaintPadding;
581     float originY = offset_.GetY() - focusPaintPadding;
582     float width = size_.Width() + 2 * focusPaintPadding;
583     float height = size_.Height() + 2 * focusPaintPadding;
584     paintRect.SetRect({ originX, originY, width, height });
585     paintRect.SetCornerRadius(RoundRect::CornerPos::TOP_LEFT_POS, borderRadius, borderRadius);
586     paintRect.SetCornerRadius(RoundRect::CornerPos::TOP_RIGHT_POS, borderRadius, borderRadius);
587     paintRect.SetCornerRadius(RoundRect::CornerPos::BOTTOM_LEFT_POS, borderRadius, borderRadius);
588     paintRect.SetCornerRadius(RoundRect::CornerPos::BOTTOM_RIGHT_POS, borderRadius, borderRadius);
589 }
590 
GetFocusPattern() const591 FocusPattern CheckBoxPattern::GetFocusPattern() const
592 {
593     auto pipeline = PipelineBase::GetCurrentContext();
594     CHECK_NULL_RETURN(pipeline, FocusPattern());
595     auto checkBoxTheme = pipeline->GetTheme<CheckboxTheme>();
596     CHECK_NULL_RETURN(checkBoxTheme, FocusPattern());
597     auto activeColor = checkBoxTheme->GetActiveColor();
598     FocusPaintParam focusPaintParam;
599     focusPaintParam.SetPaintColor(activeColor);
600     return { FocusType::NODE, true, FocusStyleType::CUSTOM_REGION, focusPaintParam };
601 }
602 
603 // Set the default hot zone for the component.
AddHotZoneRect()604 void CheckBoxPattern::AddHotZoneRect()
605 {
606     hotZoneOffset_.SetX(offset_.GetX() - hotZoneHorizontalPadding_.ConvertToPx());
607     hotZoneOffset_.SetY(offset_.GetY() - hotZoneVerticalPadding_.ConvertToPx());
608     hotZoneSize_.SetWidth(size_.Width() + 2 * hotZoneHorizontalPadding_.ConvertToPx());
609     hotZoneSize_.SetHeight(size_.Height() + 2 * hotZoneVerticalPadding_.ConvertToPx());
610     DimensionRect hotZoneRegion;
611     hotZoneRegion.SetSize(DimensionSize(Dimension(hotZoneSize_.Width()), Dimension(hotZoneSize_.Height())));
612     hotZoneRegion.SetOffset(DimensionOffset(Dimension(hotZoneOffset_.GetX()), Dimension(hotZoneOffset_.GetY())));
613     auto host = GetHost();
614     CHECK_NULL_VOID(host);
615     auto gestureHub = host->GetOrCreateGestureEventHub();
616     CHECK_NULL_VOID(gestureHub);
617     std::vector<DimensionRect> hotZoneRegions;
618     hotZoneRegions.emplace_back(hotZoneRegion);
619     gestureHub->SetResponseRegion(hotZoneRegions);
620 }
621 
RemoveLastHotZoneRect() const622 void CheckBoxPattern::RemoveLastHotZoneRect() const
623 {
624     auto host = GetHost();
625     CHECK_NULL_VOID(host);
626     host->RemoveLastHotZoneRect();
627 }
628 
ProvideRestoreInfo()629 std::string CheckBoxPattern::ProvideRestoreInfo()
630 {
631     auto jsonObj = JsonUtil::Create(true);
632     auto checkBoxPaintProperty = GetPaintProperty<CheckBoxPaintProperty>();
633     CHECK_NULL_RETURN(checkBoxPaintProperty, "");
634     jsonObj->Put("isOn", checkBoxPaintProperty->GetCheckBoxSelect().value_or(false));
635     return jsonObj->ToString();
636 }
637 
OnRestoreInfo(const std::string & restoreInfo)638 void CheckBoxPattern::OnRestoreInfo(const std::string& restoreInfo)
639 {
640     auto checkBoxPaintProperty = GetPaintProperty<CheckBoxPaintProperty>();
641     CHECK_NULL_VOID(checkBoxPaintProperty);
642     auto info = JsonUtil::ParseJsonString(restoreInfo);
643     if (!info->IsValid() || !info->IsObject()) {
644         return;
645     }
646     auto jsonCheckBoxSelect = info->GetValue("isOn");
647     checkBoxPaintProperty->UpdateCheckBoxSelect(jsonCheckBoxSelect->GetBool());
648 }
649 
OnColorConfigurationUpdate()650 void CheckBoxPattern::OnColorConfigurationUpdate()
651 {
652     auto host = GetHost();
653     CHECK_NULL_VOID(host);
654     auto pipeline = PipelineBase::GetCurrentContext();
655     CHECK_NULL_VOID(pipeline);
656     auto checkBoxTheme = pipeline->GetTheme<CheckboxTheme>();
657     CHECK_NULL_VOID(checkBoxTheme);
658     auto checkBoxPaintProperty = host->GetPaintProperty<CheckBoxPaintProperty>();
659     CHECK_NULL_VOID(checkBoxPaintProperty);
660     checkBoxPaintProperty->UpdateCheckBoxSelectedColor(checkBoxTheme->GetActiveColor());
661     checkBoxPaintProperty->UpdateCheckBoxUnSelectedColor(checkBoxTheme->GetInactiveColor());
662     checkBoxPaintProperty->UpdateCheckBoxCheckMarkColor(checkBoxTheme->GetPointColor());
663     host->MarkModifyDone();
664     host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
665 }
666 
667 } // namespace OHOS::Ace::NG
668