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