• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "core/components_ng/pattern/checkboxgroup/checkboxgroup_pattern.h"
16 
17 #include "core/components_ng/pattern/checkbox/checkbox_pattern.h"
18 #include "core/pipeline_ng/pipeline_context.h"
19 
20 namespace OHOS::Ace::NG {
21 namespace {
22 const Color ITEM_FILL_COLOR = Color::TRANSPARENT;
23 }
24 
OnAttachToFrameNode()25 void CheckBoxGroupPattern::OnAttachToFrameNode()
26 {
27     auto host = GetHost();
28     CHECK_NULL_VOID(host);
29     host->GetLayoutProperty()->UpdateAlignment(Alignment::CENTER);
30 }
31 
OnDetachFromFrameNode(FrameNode * frameNode)32 void CheckBoxGroupPattern::OnDetachFromFrameNode(FrameNode* frameNode)
33 {
34     CHECK_NULL_VOID(frameNode);
35     auto groupManager = GetGroupManager();
36     CHECK_NULL_VOID(groupManager);
37     groupManager->RemoveCheckBoxGroup(GetGroupNameWithNavId(), frameNode->GetId());
38 }
39 
OnModifyDone()40 void CheckBoxGroupPattern::OnModifyDone()
41 {
42     Pattern::OnModifyDone();
43     UpdateState();
44     auto host = GetHost();
45     CHECK_NULL_VOID(host);
46     auto pipeline = PipelineBase::GetCurrentContext();
47     CHECK_NULL_VOID(pipeline);
48     auto checkBoxTheme = pipeline->GetTheme<CheckboxTheme>(host->GetThemeScopeId());
49     CHECK_NULL_VOID(checkBoxTheme);
50     auto layoutProperty = host->GetLayoutProperty();
51     CHECK_NULL_VOID(layoutProperty);
52     if (!layoutProperty->GetMarginProperty()) {
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         layoutProperty->UpdateMargin(margin);
59     }
60     hotZoneHorizontalPadding_ = checkBoxTheme->GetHotZoneHorizontalPadding();
61     hotZoneVerticalPadding_ = checkBoxTheme->GetHotZoneVerticalPadding();
62     InitClickEvent();
63     InitTouchEvent();
64     InitMouseEvent();
65     auto focusHub = host->GetFocusHub();
66     CHECK_NULL_VOID(focusHub);
67     InitOnKeyEvent(focusHub);
68     SetAccessibilityAction();
69 
70     auto checkBoxGroupPaintProperty = host->GetPaintProperty<CheckBoxGroupPaintProperty>();
71     CHECK_NULL_VOID(checkBoxGroupPaintProperty);
72     if (!checkBoxGroupPaintProperty->HasCheckBoxGroupSelectedColorFlagByUser()) {
73         checkBoxGroupPaintProperty->UpdateCheckBoxGroupSelectedColor(checkBoxTheme->GetActiveColor());
74     }
75     if (!checkBoxGroupPaintProperty->HasCheckBoxGroupUnSelectedColorFlagByUser()) {
76         checkBoxGroupPaintProperty->UpdateCheckBoxGroupUnSelectedColor(checkBoxTheme->GetInactiveColor());
77     }
78     if (!checkBoxGroupPaintProperty->HasCheckBoxGroupCheckMarkColorFlagByUser()) {
79         checkBoxGroupPaintProperty->UpdateCheckBoxGroupCheckMarkColor(checkBoxTheme->GetPointColor());
80     }
81 }
82 
SetAccessibilityAction()83 void CheckBoxGroupPattern::SetAccessibilityAction()
84 {
85     auto host = GetHost();
86     CHECK_NULL_VOID(host);
87     auto accessibilityProperty = host->GetAccessibilityProperty<AccessibilityProperty>();
88     CHECK_NULL_VOID(accessibilityProperty);
89     accessibilityProperty->SetActionSelect([weakPtr = WeakClaim(this)]() {
90         const auto& pattern = weakPtr.Upgrade();
91         CHECK_NULL_VOID(pattern);
92         pattern->UpdateSelectStatus(true);
93     });
94 
95     accessibilityProperty->SetActionClearSelection([weakPtr = WeakClaim(this)]() {
96         const auto& pattern = weakPtr.Upgrade();
97         CHECK_NULL_VOID(pattern);
98         pattern->UpdateSelectStatus(false);
99     });
100 }
101 
UpdateSelectStatus(bool isSelected)102 void CheckBoxGroupPattern::UpdateSelectStatus(bool isSelected)
103 {
104     auto host = GetHost();
105     CHECK_NULL_VOID(host);
106     auto context = host->GetRenderContext();
107     CHECK_NULL_VOID(context);
108     MarkIsSelected(isSelected);
109     context->OnMouseSelectUpdate(isSelected, ITEM_FILL_COLOR, ITEM_FILL_COLOR);
110 }
111 
MarkIsSelected(bool isSelected)112 void CheckBoxGroupPattern::MarkIsSelected(bool isSelected)
113 {
114     if (updateFlag_ == isSelected) {
115         return;
116     }
117     updateFlag_ = isSelected;
118     auto eventHub = GetEventHub<CheckBoxGroupEventHub>();
119     std::vector<std::string> vec;
120     CheckboxGroupResult groupResult(vec, int(isSelected));
121     eventHub->UpdateChangeEvent(&groupResult);
122     auto host = GetHost();
123     CHECK_NULL_VOID(host);
124     if (isSelected) {
125         eventHub->UpdateCurrentUIState(UI_STATE_SELECTED);
126         host->OnAccessibilityEvent(AccessibilityEventType::SELECTED);
127     } else {
128         eventHub->ResetCurrentUIState(UI_STATE_SELECTED);
129         host->OnAccessibilityEvent(AccessibilityEventType::CHANGE);
130     }
131 }
132 
InitClickEvent()133 void CheckBoxGroupPattern::InitClickEvent()
134 {
135     if (clickListener_) {
136         return;
137     }
138     auto host = GetHost();
139     CHECK_NULL_VOID(host);
140     auto gesture = host->GetOrCreateGestureEventHub();
141     CHECK_NULL_VOID(gesture);
142     auto clickCallback = [weak = WeakClaim(this)](GestureEvent& info) {
143         auto checkboxPattern = weak.Upgrade();
144         CHECK_NULL_VOID(checkboxPattern);
145         checkboxPattern->OnClick();
146     };
147     clickListener_ = MakeRefPtr<ClickEvent>(std::move(clickCallback));
148     gesture->AddClickEvent(clickListener_);
149 }
150 
InitTouchEvent()151 void CheckBoxGroupPattern::InitTouchEvent()
152 {
153     if (touchListener_) {
154         return;
155     }
156     auto host = GetHost();
157     CHECK_NULL_VOID(host);
158     auto gesture = host->GetOrCreateGestureEventHub();
159     CHECK_NULL_VOID(gesture);
160     auto touchCallback = [weak = WeakClaim(this)](const TouchEventInfo& info) {
161         auto checkboxPattern = weak.Upgrade();
162         CHECK_NULL_VOID(checkboxPattern);
163         if (info.GetTouches().empty()) {
164             return;
165         }
166         if (info.GetTouches().front().GetTouchType() == TouchType::DOWN) {
167             checkboxPattern->OnTouchDown();
168         }
169         if (info.GetTouches().front().GetTouchType() == TouchType::UP ||
170             info.GetTouches().front().GetTouchType() == TouchType::CANCEL) {
171             checkboxPattern->OnTouchUp();
172         }
173     };
174     touchListener_ = MakeRefPtr<TouchEventImpl>(std::move(touchCallback));
175     gesture->AddTouchEvent(touchListener_);
176 }
177 
InitMouseEvent()178 void CheckBoxGroupPattern::InitMouseEvent()
179 {
180     if (mouseEvent_) {
181         return;
182     }
183     auto host = GetHost();
184     CHECK_NULL_VOID(host);
185     auto gesture = host->GetOrCreateGestureEventHub();
186     CHECK_NULL_VOID(gesture);
187     auto eventHub = host->GetEventHub<CheckBoxGroupEventHub>();
188     auto inputHub = eventHub->GetOrCreateInputEventHub();
189 
190     auto mouseTask = [weak = WeakClaim(this)](bool isHover) {
191         auto pattern = weak.Upgrade();
192         if (pattern) {
193             pattern->HandleMouseEvent(isHover);
194         }
195     };
196     mouseEvent_ = MakeRefPtr<InputEvent>(std::move(mouseTask));
197     inputHub->AddOnHoverEvent(mouseEvent_);
198 }
199 
HandleMouseEvent(bool isHover)200 void CheckBoxGroupPattern::HandleMouseEvent(bool isHover)
201 {
202     isHover_ = isHover;
203     if (isHover) {
204         touchHoverType_ = TouchHoverAnimationType::HOVER;
205     } else {
206         touchHoverType_ = TouchHoverAnimationType::NONE;
207     }
208     auto host = GetHost();
209     CHECK_NULL_VOID(host);
210     host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
211 }
212 
OnClick()213 void CheckBoxGroupPattern::OnClick()
214 {
215     auto host = GetHost();
216     CHECK_NULL_VOID(host);
217     auto paintProperty = host->GetPaintProperty<CheckBoxGroupPaintProperty>();
218     CHECK_NULL_VOID(paintProperty);
219     bool isSelected = false;
220     auto status = paintProperty->GetSelectStatus();
221     isSelected = status == CheckBoxGroupPaintProperty::SelectStatus::NONE;
222     paintProperty->UpdateCheckBoxGroupSelect(isSelected);
223     updateFlag_ = true;
224     UpdateState();
225 }
226 
OnTouchDown()227 void CheckBoxGroupPattern::OnTouchDown()
228 {
229     TAG_LOGD(AceLogTag::ACE_SELECT_COMPONENT, "checkboxgroup touch down %{public}d", isHover_);
230     if (isHover_) {
231         touchHoverType_ = TouchHoverAnimationType::HOVER_TO_PRESS;
232     } else {
233         touchHoverType_ = TouchHoverAnimationType::PRESS;
234     }
235     auto host = GetHost();
236     CHECK_NULL_VOID(host);
237     host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
238 }
239 
OnTouchUp()240 void CheckBoxGroupPattern::OnTouchUp()
241 {
242     TAG_LOGD(AceLogTag::ACE_SELECT_COMPONENT, "checkboxgroup touch up %{public}d", isHover_);
243     if (isHover_) {
244         touchHoverType_ = TouchHoverAnimationType::PRESS_TO_HOVER;
245     } else {
246         touchHoverType_ = TouchHoverAnimationType::NONE;
247     }
248     auto host = GetHost();
249     CHECK_NULL_VOID(host);
250     host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
251 }
252 
UpdateUnSelect()253 void CheckBoxGroupPattern::UpdateUnSelect()
254 {
255     auto host = GetHost();
256     CHECK_NULL_VOID(host);
257     auto paintProperty = host->GetPaintProperty<CheckBoxGroupPaintProperty>();
258     CHECK_NULL_VOID(paintProperty);
259     if (paintProperty->GetSelectStatus() == CheckBoxGroupPaintProperty::SelectStatus::NONE) {
260         uiStatus_ = UIStatus::UNSELECTED;
261         host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
262     }
263 }
264 
UpdateUIStatus(bool check)265 void CheckBoxGroupPattern::UpdateUIStatus(bool check)
266 {
267     auto host = GetHost();
268     CHECK_NULL_VOID(host);
269     auto paintProperty = host->GetPaintProperty<CheckBoxGroupPaintProperty>();
270     CHECK_NULL_VOID(paintProperty);
271     auto selectStatus = paintProperty->GetSelectStatus();
272     TAG_LOGI(AceLogTag::ACE_SELECT_COMPONENT, "checkboxgroup update status %{public}d %{public}d", check, selectStatus);
273     if (selectStatus == CheckBoxGroupPaintProperty::SelectStatus::PART) {
274         uiStatus_ = check ? UIStatus::PART_TO_ON : UIStatus::PART_TO_OFF;
275     } else {
276         uiStatus_ = check ? UIStatus::OFF_TO_ON : UIStatus::ON_TO_OFF;
277     }
278     host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
279 }
280 
UpdateState()281 void CheckBoxGroupPattern::UpdateState()
282 {
283     auto host = GetHost();
284     CHECK_NULL_VOID(host);
285     if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
286         UpdateCheckBoxStyle();
287     }
288     auto eventHub = host->GetEventHub<CheckBoxGroupEventHub>();
289     CHECK_NULL_VOID(eventHub);
290     auto preGroup = GetPreGroup();
291     if (!preGroup.has_value()) {
292         InitPreGroup();
293         return;
294     }
295     auto groupManager = GetGroupManager();
296     CHECK_NULL_VOID(groupManager);
297     auto group = GetGroupNameWithNavId();
298     if (preGroup.value() != group) {
299         groupManager->RemoveCheckBoxGroup(preGroup.value(), host->GetId());
300         groupManager->AddCheckBoxGroup(group, host);
301         SetPreGroup(group);
302         return;
303     }
304     auto paintProperty = host->GetPaintProperty<CheckBoxGroupPaintProperty>();
305     CHECK_NULL_VOID(paintProperty);
306     if (!paintProperty->HasCheckBoxGroupSelect()) {
307         return;
308     }
309     bool isSelected = paintProperty->GetCheckBoxGroupSelectValue();
310     paintProperty->ResetCheckBoxGroupSelect();
311     if (eventHub->HasChangeEvent() && skipFlag_) {
312         skipFlag_ = false;
313         return;
314     }
315 
316     // Setting selectAll to false when clicked requires processing, changing selectAll to false dynamically does
317     // not require processing
318     if (updateFlag_ || isSelected) {
319         if (GetIsAddToMap()) {
320             UpdateGroupCheckStatus(host, isSelected);
321         } else {
322             UpdateRepeatedGroupStatus(host, isSelected);
323         }
324     }
325     updateFlag_ = false;
326 }
327 
InitPreGroup()328 void CheckBoxGroupPattern::InitPreGroup()
329 {
330     auto host = GetHost();
331     CHECK_NULL_VOID(host);
332     auto groupManager = GetGroupManager();
333     CHECK_NULL_VOID(groupManager);
334     auto group = GetGroupNameWithNavId();
335     groupManager->AddCheckBoxGroup(group, host);
336     auto paintProperty = host->GetPaintProperty<CheckBoxGroupPaintProperty>();
337     CHECK_NULL_VOID(paintProperty);
338     if (paintProperty->GetCheckBoxGroupSelect().value_or(false)) {
339         paintProperty->SetSelectStatus(CheckBoxGroupPaintProperty::SelectStatus::ALL);
340         UpdateUIStatus(true);
341         initSelected_ = true;
342     }
343     isFirstCreated_ = false;
344     SetPreGroup(group);
345 }
346 
OnAfterModifyDone()347 void CheckBoxGroupPattern::OnAfterModifyDone()
348 {
349     auto host = GetHost();
350     CHECK_NULL_VOID(host);
351     auto inspectorId = host->GetInspectorId().value_or("");
352     if (inspectorId.empty()) {
353         return;
354     }
355 
356     auto eventHub = host->GetEventHub<CheckBoxGroupEventHub>();
357     CHECK_NULL_VOID(eventHub);
358     std::vector<std::string> vec;
359     if (initSelected_) {
360         auto groupManager = GetGroupManager();
361         CHECK_NULL_VOID(groupManager);
362         auto list = groupManager->GetCheckboxList(GetGroupNameWithNavId());
363         for (auto node : list) {
364             if (!node) {
365                 continue;
366             }
367             auto paintProperty = node->GetPaintProperty<CheckBoxPaintProperty>();
368             CHECK_NULL_VOID(paintProperty);
369             auto eventHub = node->GetEventHub<CheckBoxEventHub>();
370             CHECK_NULL_VOID(eventHub);
371             vec.push_back(eventHub->GetName());
372         }
373     }
374     Recorder::NodeDataCache::Get().PutMultiple(host, inspectorId, eventHub->GetGroupName(), vec);
375 }
376 
UpdateGroupCheckStatus(const RefPtr<FrameNode> & frameNode,bool select)377 void CheckBoxGroupPattern::UpdateGroupCheckStatus(const RefPtr<FrameNode>& frameNode, bool select)
378 {
379     auto paintProperty = frameNode->GetPaintProperty<CheckBoxGroupPaintProperty>();
380     CHECK_NULL_VOID(paintProperty);
381     auto pattern = frameNode->GetPattern<CheckBoxGroupPattern>();
382     CHECK_NULL_VOID(pattern);
383     pattern->UpdateUIStatus(select);
384     if (select) {
385         paintProperty->SetSelectStatus(CheckBoxGroupPaintProperty::SelectStatus::ALL);
386     } else {
387         paintProperty->SetSelectStatus(CheckBoxGroupPaintProperty::SelectStatus::NONE);
388     }
389     frameNode->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
390     UpdateCheckBoxStatus(frameNode, select);
391 }
392 
UpdateCheckBoxStatus(const RefPtr<FrameNode> & frameNode,bool select)393 void CheckBoxGroupPattern::UpdateCheckBoxStatus(const RefPtr<FrameNode>& frameNode, bool select)
394 {
395     auto groupManager = GetGroupManager();
396     CHECK_NULL_VOID(groupManager);
397     auto group = GetGroupNameWithNavId();
398     auto list = groupManager->GetCheckboxList(group);
399     std::vector<std::string> vec;
400     auto status =
401         select ? CheckBoxGroupPaintProperty::SelectStatus::ALL : CheckBoxGroupPaintProperty::SelectStatus::NONE;
402     for (auto && node : list) {
403         if (!node) {
404             continue;
405         }
406         auto paintProperty = node->GetPaintProperty<CheckBoxPaintProperty>();
407         CHECK_NULL_VOID(paintProperty);
408         auto eventHub = node->GetEventHub<CheckBoxEventHub>();
409         CHECK_NULL_VOID(eventHub);
410         if (select) {
411             vec.push_back(eventHub->GetName());
412         }
413         if (paintProperty->GetCheckBoxSelectValue(false) != select) {
414             paintProperty->UpdateCheckBoxSelect(select);
415             auto pattern = node->GetPattern<CheckBoxPattern>();
416             pattern->StartCustomNodeAnimation(select);
417             pattern->UpdateUIStatus(select);
418             pattern->SetLastSelect(select);
419             eventHub->UpdateChangeEvent(select);
420         }
421     }
422     CheckboxGroupResult groupResult(vec, int(status));
423     auto eventHub = frameNode->GetEventHub<CheckBoxGroupEventHub>();
424     eventHub->UpdateChangeEvent(&groupResult);
425 }
426 
UpdateRepeatedGroupStatus(const RefPtr<FrameNode> & frameNode,bool select)427 void CheckBoxGroupPattern::UpdateRepeatedGroupStatus(const RefPtr<FrameNode>& frameNode, bool select)
428 {
429     std::vector<std::string> vec;
430     auto status =
431         select ? CheckBoxGroupPaintProperty::SelectStatus::ALL : CheckBoxGroupPaintProperty::SelectStatus::NONE;
432     auto pattern = frameNode->GetPattern<CheckBoxGroupPattern>();
433     CHECK_NULL_VOID(pattern);
434     pattern->UpdateUIStatus(select);
435     auto paintProperty = frameNode->GetPaintProperty<CheckBoxGroupPaintProperty>();
436     CHECK_NULL_VOID(paintProperty);
437     paintProperty->SetSelectStatus(
438         select ? CheckBoxGroupPaintProperty::SelectStatus::ALL : CheckBoxGroupPaintProperty::SelectStatus::NONE);
439     auto checkBoxGroupEventHub = GetEventHub<CheckBoxGroupEventHub>();
440     CHECK_NULL_VOID(checkBoxGroupEventHub);
441     frameNode->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
442     CheckboxGroupResult groupResult(vec, int(status));
443     auto eventHub = frameNode->GetEventHub<CheckBoxGroupEventHub>();
444     eventHub->UpdateChangeEvent(&groupResult);
445 }
446 
InitOnKeyEvent(const RefPtr<FocusHub> & focusHub)447 void CheckBoxGroupPattern::InitOnKeyEvent(const RefPtr<FocusHub>& focusHub)
448 {
449     CHECK_NULL_VOID(focusHub);
450     auto getInnerPaintRectCallback = [wp = WeakClaim(this)](RoundRect& paintRect) {
451         auto pattern = wp.Upgrade();
452         if (pattern) {
453             pattern->GetInnerFocusPaintRect(paintRect);
454         }
455     };
456     focusHub->SetInnerFocusPaintRectCallback(getInnerPaintRectCallback);
457 
458     auto onKeyEvent = [wp = WeakClaim(this)](const KeyEvent& event) -> bool {
459         auto pattern = wp.Upgrade();
460         if (pattern) {
461             return pattern->OnKeyEvent(event);
462         }
463         return false;
464     };
465     focusHub->SetOnKeyEventInternal(std::move(onKeyEvent));
466 }
467 
OnKeyEvent(const KeyEvent & event)468 bool CheckBoxGroupPattern::OnKeyEvent(const KeyEvent& event)
469 {
470     if (event.action == KeyAction::DOWN && event.code == KeyCode::KEY_FUNCTION) {
471         OnClick();
472         return true;
473     }
474     return false;
475 }
476 
GetInnerFocusPaintRect(RoundRect & paintRect)477 void CheckBoxGroupPattern::GetInnerFocusPaintRect(RoundRect& paintRect)
478 {
479     auto groupPaintProperty = GetPaintProperty<CheckBoxGroupPaintProperty>();
480     CHECK_NULL_VOID(groupPaintProperty);
481     if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
482         auto checkboxGroupStyle = groupPaintProperty->GetCheckBoxGroupSelectedStyleValue(CheckBoxStyle::CIRCULAR_STYLE);
483         if (checkboxGroupStyle == CheckBoxStyle::CIRCULAR_STYLE) {
484             InnerFocusPaintCircle(paintRect);
485             return;
486         }
487     }
488     auto pipelineContext = PipelineBase::GetCurrentContext();
489     CHECK_NULL_VOID(pipelineContext);
490     auto checkBoxTheme = pipelineContext->GetTheme<CheckboxTheme>();
491     CHECK_NULL_VOID(checkBoxTheme);
492     auto borderRadius = checkBoxTheme->GetFocusRadius().ConvertToPx();
493     auto focusPaintPadding = checkBoxTheme->GetFocusPaintPadding().ConvertToPx();
494     float originX = offset_.GetX() - focusPaintPadding;
495     float originY = offset_.GetY() - focusPaintPadding;
496     float width = size_.Width() + 2 * focusPaintPadding;
497     float height = size_.Height() + 2 * focusPaintPadding;
498     paintRect.SetRect({ originX, originY, width, height });
499     paintRect.SetCornerRadius(RoundRect::CornerPos::TOP_LEFT_POS, borderRadius, borderRadius);
500     paintRect.SetCornerRadius(RoundRect::CornerPos::TOP_RIGHT_POS, borderRadius, borderRadius);
501     paintRect.SetCornerRadius(RoundRect::CornerPos::BOTTOM_LEFT_POS, borderRadius, borderRadius);
502     paintRect.SetCornerRadius(RoundRect::CornerPos::BOTTOM_RIGHT_POS, borderRadius, borderRadius);
503 }
504 
InnerFocusPaintCircle(RoundRect & paintRect)505 void CheckBoxGroupPattern::InnerFocusPaintCircle(RoundRect& paintRect)
506 {
507     auto pipeline = PipelineBase::GetCurrentContext();
508     CHECK_NULL_VOID(pipeline);
509     auto radioTheme = pipeline->GetTheme<CheckboxTheme>();
510     CHECK_NULL_VOID(radioTheme);
511     auto focusPaintPadding = radioTheme->GetFocusPaintPadding().ConvertToPx();
512     float outCircleRadius = size_.Width() / 2 + focusPaintPadding;
513     float originX = offset_.GetX() - focusPaintPadding;
514     float originY = offset_.GetY() - focusPaintPadding;
515     float width = size_.Width() + 2 * focusPaintPadding;
516     float height = size_.Height() + 2 * focusPaintPadding;
517     paintRect.SetRect({ originX, originY, width, height });
518     paintRect.SetCornerRadius(RoundRect::CornerPos::TOP_LEFT_POS, outCircleRadius, outCircleRadius);
519     paintRect.SetCornerRadius(RoundRect::CornerPos::TOP_RIGHT_POS, outCircleRadius, outCircleRadius);
520     paintRect.SetCornerRadius(RoundRect::CornerPos::BOTTOM_LEFT_POS, outCircleRadius, outCircleRadius);
521     paintRect.SetCornerRadius(RoundRect::CornerPos::BOTTOM_RIGHT_POS, outCircleRadius, outCircleRadius);
522 }
523 
GetFocusPattern() const524 FocusPattern CheckBoxGroupPattern::GetFocusPattern() const
525 {
526     auto pipeline = PipelineBase::GetCurrentContext();
527     CHECK_NULL_RETURN(pipeline, FocusPattern());
528     auto host = GetHost();
529     CHECK_NULL_RETURN(host, FocusPattern());
530     auto checkBoxTheme = pipeline->GetTheme<CheckboxTheme>(host->GetThemeScopeId());
531     CHECK_NULL_RETURN(checkBoxTheme, FocusPattern());
532     auto activeColor = checkBoxTheme->GetActiveColor();
533     FocusPaintParam focusPaintParam;
534     focusPaintParam.SetPaintColor(activeColor);
535     return { FocusType::NODE, true, FocusStyleType::CUSTOM_REGION, focusPaintParam };
536 }
537 
538 // Set the default hot zone for the component.
AddHotZoneRect()539 void CheckBoxGroupPattern::AddHotZoneRect()
540 {
541     hotZoneOffset_.SetX(offset_.GetX() - hotZoneHorizontalPadding_.ConvertToPx());
542     hotZoneOffset_.SetY(offset_.GetY() - hotZoneVerticalPadding_.ConvertToPx());
543     hotZoneSize_.SetWidth(size_.Width() + 2 * hotZoneHorizontalPadding_.ConvertToPx());
544     hotZoneSize_.SetHeight(size_.Height() + 2 * hotZoneVerticalPadding_.ConvertToPx());
545     DimensionRect hotZoneRegion;
546     hotZoneRegion.SetSize(DimensionSize(Dimension(hotZoneSize_.Width()), Dimension(hotZoneSize_.Height())));
547     hotZoneRegion.SetOffset(DimensionOffset(Dimension(hotZoneOffset_.GetX()), Dimension(hotZoneOffset_.GetY())));
548     auto host = GetHost();
549     CHECK_NULL_VOID(host);
550     auto gestureHub = host->GetOrCreateGestureEventHub();
551     CHECK_NULL_VOID(gestureHub);
552     std::vector<DimensionRect> hotZoneRegions;
553     hotZoneRegions.emplace_back(hotZoneRegion);
554     gestureHub->SetResponseRegion(hotZoneRegions);
555 }
556 
RemoveLastHotZoneRect() const557 void CheckBoxGroupPattern::RemoveLastHotZoneRect() const
558 {
559     auto host = GetHost();
560     CHECK_NULL_VOID(host);
561     host->RemoveLastHotZoneRect();
562 }
563 
InitializeModifierParam(CheckBoxGroupModifier::Parameters & paintParameters)564 void CheckBoxGroupPattern::InitializeModifierParam(CheckBoxGroupModifier::Parameters& paintParameters)
565 {
566     auto pipeline = PipelineBase::GetCurrentContext();
567     CHECK_NULL_VOID(pipeline);
568     auto host = GetHost();
569     CHECK_NULL_VOID(host);
570     auto checkBoxTheme = pipeline->GetTheme<CheckboxTheme>(host->GetThemeScopeId());
571     CHECK_NULL_VOID(checkBoxTheme);
572     paintParameters.borderWidth = checkBoxTheme->GetBorderWidth().ConvertToPx();
573     paintParameters.borderRadius = checkBoxTheme->GetBorderRadius().ConvertToPx();
574     paintParameters.checkStroke = checkBoxTheme->GetCheckStroke().ConvertToPx();
575     paintParameters.pointColor = checkBoxTheme->GetPointColor();
576     paintParameters.activeColor = checkBoxTheme->GetActiveColor();
577     paintParameters.inactiveColor = checkBoxTheme->GetInactiveColor();
578     paintParameters.inactivePointColor = checkBoxTheme->GetInactivePointColor();
579     paintParameters.shadowColor = checkBoxTheme->GetShadowColor();
580     paintParameters.clickEffectColor = checkBoxTheme->GetClickEffectColor();
581     paintParameters.hoverColor = checkBoxTheme->GetHoverColor();
582     paintParameters.hoverRadius = checkBoxTheme->GetHoverRadius();
583     paintParameters.hotZoneHorizontalPadding = checkBoxTheme->GetHotZoneHorizontalPadding();
584     paintParameters.hotZoneVerticalPadding = checkBoxTheme->GetHotZoneVerticalPadding();
585     paintParameters.shadowWidth = checkBoxTheme->GetShadowWidth();
586     paintParameters.checkMarkPaintSize = checkBoxTheme->GetDefaultWidth().ConvertToPx();
587     paintParameters.hoverDuration = checkBoxTheme->GetHoverDuration();
588     paintParameters.hoverToTouchDuration = checkBoxTheme->GetHoverToTouchDuration();
589     paintParameters.uiStatus = UIStatus::UNSELECTED;
590     paintParameters.status = CheckBoxGroupPaintProperty::SelectStatus::NONE;
591     paintParameters.defaultPaddingSize = checkBoxTheme->GetDefaultPaddingSize();
592 }
593 
UpdateModifierParam(CheckBoxGroupModifier::Parameters & paintParameters)594 void CheckBoxGroupPattern::UpdateModifierParam(CheckBoxGroupModifier::Parameters& paintParameters)
595 {
596     auto host = GetHost();
597     CHECK_NULL_VOID(host);
598     auto paintProperty = host->GetPaintProperty<CheckBoxGroupPaintProperty>();
599     CHECK_NULL_VOID(paintProperty);
600     auto geometryNode = host->GetGeometryNode();
601     CHECK_NULL_VOID(geometryNode);
602     auto contentSize = geometryNode->GetContentSize();
603 
604     if (paintProperty->HasCheckBoxGroupSelectedColor()) {
605         paintParameters.activeColor = paintProperty->GetCheckBoxGroupSelectedColorValue();
606     }
607     if (paintProperty->HasCheckBoxGroupUnSelectedColor()) {
608         paintParameters.inactiveColor = paintProperty->GetCheckBoxGroupUnSelectedColorValue();
609     }
610     if (paintProperty->HasCheckBoxGroupCheckMarkColor()) {
611         paintParameters.pointColor = paintProperty->GetCheckBoxGroupCheckMarkColorValue();
612     }
613     if (paintProperty->HasCheckBoxGroupCheckMarkSize()) {
614         if (paintProperty->GetCheckBoxGroupCheckMarkSizeValue().ConvertToPx() >= 0) {
615             paintParameters.checkMarkPaintSize = paintProperty->GetCheckBoxGroupCheckMarkSizeValue().ConvertToPx();
616         } else {
617             paintParameters.checkMarkPaintSize = contentSize.Width();
618         }
619     }
620     if (paintProperty->HasCheckBoxGroupCheckMarkWidth()) {
621         paintParameters.checkStroke =
622             static_cast<float>(paintProperty->GetCheckBoxGroupCheckMarkWidthValue().ConvertToPx());
623     }
624 }
625 
OnColorConfigurationUpdate()626 void CheckBoxGroupPattern::OnColorConfigurationUpdate()
627 {
628     auto host = GetHost();
629     CHECK_NULL_VOID(host);
630     OnThemeScopeUpdate(host->GetThemeScopeId());
631     host->MarkModifyDone();
632     host->MarkDirtyNode();
633 }
634 
OnThemeScopeUpdate(int32_t themeScopeId)635 bool CheckBoxGroupPattern::OnThemeScopeUpdate(int32_t themeScopeId)
636 {
637     auto result = false;
638     auto host = GetHost();
639     CHECK_NULL_RETURN(host, result);
640     auto pipeline = host->GetContext();
641     CHECK_NULL_RETURN(pipeline, result);
642     auto checkBoxTheme = pipeline->GetTheme<CheckboxTheme>(themeScopeId);
643     CHECK_NULL_RETURN(checkBoxTheme, result);
644     auto checkBoxGroupPaintProperty = host->GetPaintProperty<CheckBoxGroupPaintProperty>();
645     CHECK_NULL_RETURN(checkBoxGroupPaintProperty, result);
646     if (!checkBoxGroupPaintProperty->HasCheckBoxGroupSelectedColorFlagByUser()) {
647         checkBoxGroupPaintProperty->UpdateCheckBoxGroupSelectedColor(checkBoxTheme->GetActiveColor());
648         result = true;
649     }
650     if (!checkBoxGroupPaintProperty->HasCheckBoxGroupUnSelectedColorFlagByUser()) {
651         checkBoxGroupPaintProperty->UpdateCheckBoxGroupUnSelectedColor(checkBoxTheme->GetInactiveColor());
652         result = true;
653     }
654     if (!checkBoxGroupPaintProperty->HasCheckBoxGroupCheckMarkColorFlagByUser()) {
655         checkBoxGroupPaintProperty->UpdateCheckBoxGroupCheckMarkColor(checkBoxTheme->GetPointColor());
656         result = true;
657     }
658     return result;
659 }
660 
OnAttachToMainTree()661 void CheckBoxGroupPattern::OnAttachToMainTree()
662 {
663     auto host = GetHost();
664     CHECK_NULL_VOID(host);
665     auto groupManager = GetGroupManager();
666     CHECK_NULL_VOID(groupManager);
667     auto parent = host->GetParent();
668     while (parent) {
669         if (parent->GetTag() == V2::NAVDESTINATION_CONTENT_ETS_TAG) {
670             currentNavId_ = std::to_string(parent->GetId());
671             groupManager->SetLastNavId(currentNavId_);
672             UpdateState();
673             return;
674         }
675         parent = parent->GetParent();
676     }
677     if (!currentNavId_.value_or("").empty()) {
678         currentNavId_ = "";
679         groupManager->SetLastNavId(std::nullopt);
680         UpdateState();
681     }
682 }
683 
GetGroupNameWithNavId()684 std::string CheckBoxGroupPattern::GetGroupNameWithNavId()
685 {
686     auto host = GetHost();
687     CHECK_NULL_RETURN(host, "");
688     auto eventHub = host->GetEventHub<CheckBoxGroupEventHub>();
689     CHECK_NULL_RETURN(eventHub, "");
690     if (currentNavId_.has_value()) {
691         return eventHub->GetGroupName() + currentNavId_.value();
692     }
693     auto groupManager = GetGroupManager();
694     CHECK_NULL_RETURN(groupManager, eventHub->GetGroupName());
695     return eventHub->GetGroupName() + groupManager->GetLastNavId();
696 }
697 
GetGroupManager()698 RefPtr<GroupManager> CheckBoxGroupPattern::GetGroupManager()
699 {
700     auto manager = groupManager_.Upgrade();
701     if (manager) {
702         return manager;
703     }
704     groupManager_ = GroupManager::GetGroupManager();
705     return groupManager_.Upgrade();
706 }
707 
UpdateCheckBoxStyle()708 void CheckBoxGroupPattern::UpdateCheckBoxStyle()
709 {
710     auto host = GetHost();
711     CHECK_NULL_VOID(host);
712     auto groupManager = GetGroupManager();
713     CHECK_NULL_VOID(groupManager);
714     auto checkBoxGroupEventHub = GetEventHub<CheckBoxGroupEventHub>();
715     CHECK_NULL_VOID(checkBoxGroupEventHub);
716     auto group = checkBoxGroupEventHub->GetGroupName();
717     auto list = groupManager->GetCheckboxList(group);
718     CheckBoxStyle groupStyle;
719     GetCheckBoxGroupStyle(host, groupStyle);
720     for (auto node : list) {
721         if (!node) {
722             continue;
723         }
724         auto paintProperty = node->GetPaintProperty<CheckBoxPaintProperty>();
725         CHECK_NULL_VOID(paintProperty);
726         SetCheckBoxStyle(paintProperty, node, groupStyle);
727     }
728     host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
729 }
730 
GetCheckBoxGroupStyle(const RefPtr<FrameNode> & frameNode,CheckBoxStyle & checkboxGroupStyle)731 void CheckBoxGroupPattern::GetCheckBoxGroupStyle(const RefPtr<FrameNode>& frameNode, CheckBoxStyle& checkboxGroupStyle)
732 {
733     auto groupPaintProperty = frameNode->GetPaintProperty<CheckBoxGroupPaintProperty>();
734     CHECK_NULL_VOID(groupPaintProperty);
735     checkboxGroupStyle = groupPaintProperty->GetCheckBoxGroupSelectedStyleValue(CheckBoxStyle::CIRCULAR_STYLE);
736 }
737 
SetCheckBoxStyle(const RefPtr<CheckBoxPaintProperty> & paintProperty,const RefPtr<FrameNode> & checkboxNode,CheckBoxStyle checkBoxGroupStyle)738 void CheckBoxGroupPattern::SetCheckBoxStyle(const RefPtr<CheckBoxPaintProperty>& paintProperty,
739     const RefPtr<FrameNode>& checkboxNode, CheckBoxStyle checkBoxGroupStyle)
740 {
741     CHECK_NULL_VOID(paintProperty);
742     CHECK_NULL_VOID(checkboxNode);
743     auto pattern = checkboxNode->GetPattern<CheckBoxPattern>();
744     CHECK_NULL_VOID(pattern);
745     if (!paintProperty->HasCheckBoxSelectedStyle() ||
746         pattern->GetOriginalCheckboxStyle() == OriginalCheckBoxStyle::NONE) {
747         pattern->SetOriginalCheckboxStyle(OriginalCheckBoxStyle::NONE);
748         paintProperty->UpdateCheckBoxSelectedStyle(checkBoxGroupStyle);
749         checkboxNode->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
750     }
751 }
752 } // namespace OHOS::Ace::NG
753