• 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 
16 #include "core/components_ng/pattern/checkbox/checkbox_pattern.h"
17 
18 #include "core/components/checkable/checkable_theme.h"
19 #include "core/components_ng/pattern/checkboxgroup/checkboxgroup_paint_property.h"
20 #include "core/components_ng/pattern/checkboxgroup/checkboxgroup_pattern.h"
21 #include "core/components_ng/pattern/stage/page_event_hub.h"
22 #include "core/pipeline_ng/pipeline_context.h"
23 
24 namespace OHOS::Ace::NG {
25 namespace {
26 const Color ITEM_FILL_COLOR = Color::TRANSPARENT;
27 constexpr int32_t DEFAULT_CHECKBOX_ANIMATION_DURATION = 100;
28 } // namespace
29 
CreateNodePaintMethod()30 RefPtr<NodePaintMethod> CheckBoxPattern::CreateNodePaintMethod()
31 {
32     auto host = GetHost();
33     CHECK_NULL_RETURN(host, nullptr);
34     auto paintProperty = host->GetPaintProperty<CheckBoxPaintProperty>();
35     paintProperty->SetHost(host);
36     if (!paintMethod_) {
37         paintMethod_ = MakeRefPtr<CheckBoxPaintMethod>();
38     }
39     CheckBoxStyle checkboxStyle = CheckBoxStyle::CIRCULAR_STYLE;
40     if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
41         checkboxStyle = CheckBoxStyle::CIRCULAR_STYLE;
42     } else {
43         checkboxStyle = CheckBoxStyle::SQUARE_STYLE;
44     }
45     if (paintProperty->HasCheckBoxSelectedStyle()) {
46         checkboxStyle = paintProperty->GetCheckBoxSelectedStyleValue(CheckBoxStyle::CIRCULAR_STYLE);
47     }
48     paintMethod_->SetCheckboxStyle(checkboxStyle);
49     paintMethod_->SetUseContentModifier(UseContentModifier());
50     paintMethod_->SetHasBuilder(builder_.has_value());
51     host->SetCheckboxFlag(true);
52     auto eventHub = host->GetEventHub<EventHub>();
53     CHECK_NULL_RETURN(eventHub, nullptr);
54     auto enabled = eventHub->IsEnabled();
55     paintMethod_->SetEnabled(enabled);
56     paintMethod_->SetTouchHoverAnimationType(touchHoverType_);
57     return paintMethod_;
58 }
59 
OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper> & dirty,bool,bool)60 bool CheckBoxPattern::OnDirtyLayoutWrapperSwap(
61     const RefPtr<LayoutWrapper>& dirty, bool /*skipMeasure*/, bool /*skipLayout*/)
62 {
63     auto geometryNode = dirty->GetGeometryNode();
64     offset_ = geometryNode->GetContentOffset();
65     size_ = geometryNode->GetContentSize();
66     if (!isUserSetResponseRegion_) {
67         AddHotZoneRect();
68     }
69     return true;
70 }
71 
SetBuilderFunc(CheckBoxMakeCallback && makeFunc)72 void CheckBoxPattern::SetBuilderFunc(CheckBoxMakeCallback&& makeFunc)
73 {
74     if (makeFunc == nullptr) {
75         makeFunc_ = std::nullopt;
76         OnModifyDone();
77         return;
78     }
79     makeFunc_ = std::move(makeFunc);
80 }
81 
SetToggleBuilderFunc(SwitchMakeCallback && toggleMakeFunc)82 void CheckBoxPattern::SetToggleBuilderFunc(SwitchMakeCallback&& toggleMakeFunc)
83 {
84     if (toggleMakeFunc == nullptr) {
85         toggleMakeFunc_ = std::nullopt;
86         OnModifyDone();
87         return;
88     }
89     toggleMakeFunc_ = std::move(toggleMakeFunc);
90 }
91 
ToJsonValue(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter) const92 void CheckBoxPattern::ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
93 {
94     Pattern::ToJsonValue(json, filter);
95     /* no fixed attr below, just return */
96     if (filter.IsFastFilter()) {
97         return;
98     }
99     auto host = GetHost();
100     CHECK_NULL_VOID(host);
101     auto checkBoxEventHub = host->GetEventHub<NG::CheckBoxEventHub>();
102     auto name = checkBoxEventHub ? checkBoxEventHub->GetName() : "";
103     auto group = checkBoxEventHub ? checkBoxEventHub->GetGroupName() : "";
104     json->PutExtAttr("name", name.c_str(), filter);
105     json->PutExtAttr("group", group.c_str(), filter);
106     json->PutExtAttr("type", "ToggleType.Checkbox", filter);
107     auto paintProperty = host->GetPaintProperty<CheckBoxPaintProperty>();
108     auto select = paintProperty->GetCheckBoxSelectValue(false);
109     json->PutExtAttr("select", select ? "true" : "false", filter);
110 }
111 
ToTreeJson(std::unique_ptr<JsonValue> & json,const InspectorConfig & config) const112 void CheckBoxPattern::ToTreeJson(std::unique_ptr<JsonValue>& json, const InspectorConfig& config) const
113 {
114     Pattern::ToTreeJson(json, config);
115     auto host = GetHost();
116     CHECK_NULL_VOID(host);
117     auto paintProperty = host->GetPaintProperty<CheckBoxPaintProperty>();
118     CHECK_NULL_VOID(paintProperty);
119     auto select = paintProperty->GetCheckBoxSelectValue(false);
120     json->Put(TreeKey::CHECKED, select ? "true" : "false");
121 }
122 
OnAttachToFrameNode()123 void CheckBoxPattern::OnAttachToFrameNode()
124 {
125     auto host = GetHost();
126     CHECK_NULL_VOID(host);
127     host->GetLayoutProperty()->UpdateAlignment(Alignment::CENTER);
128 }
129 
SetBuilderNodeHidden()130 void CheckBoxPattern::SetBuilderNodeHidden()
131 {
132     CHECK_NULL_VOID(builderNode_);
133     auto layoutProperty = builderNode_->GetLayoutProperty();
134     CHECK_NULL_VOID(layoutProperty);
135     layoutProperty->UpdateVisibility(VisibleType::GONE);
136 }
137 
UpdateIndicator()138 void CheckBoxPattern::UpdateIndicator()
139 {
140     auto host = GetHost();
141     CHECK_NULL_VOID(host);
142     if (builder_.has_value() && !UseContentModifier()) {
143         LoadBuilder();
144         auto paintProperty = host->GetPaintProperty<CheckBoxPaintProperty>();
145         CHECK_NULL_VOID(paintProperty);
146         bool isSelected = false;
147         if (paintProperty->HasCheckBoxSelect()) {
148             isSelected = paintProperty->GetCheckBoxSelectValue();
149             if (!isSelected) {
150                 SetBuilderNodeHidden();
151             }
152         } else {
153             SetBuilderNodeHidden();
154         }
155     } else if (builderNode_) {
156         host->RemoveChildAndReturnIndex(builderNode_);
157         builderNode_ = nullptr;
158     }
159 }
160 
OnModifyDone()161 void CheckBoxPattern::OnModifyDone()
162 {
163     Pattern::OnModifyDone();
164     FireBuilder();
165     UpdateIndicator();
166     UpdateState();
167     auto host = GetHost();
168     CHECK_NULL_VOID(host);
169     auto pipeline = GetContext();
170     CHECK_NULL_VOID(pipeline);
171     auto checkBoxTheme = pipeline->GetTheme<CheckboxTheme>(host->GetThemeScopeId());
172     CHECK_NULL_VOID(checkBoxTheme);
173     auto layoutProperty = host->GetLayoutProperty();
174     CHECK_NULL_VOID(layoutProperty);
175     MarginProperty margin;
176     margin.left = CalcLength(checkBoxTheme->GetHotZoneHorizontalPadding().Value());
177     margin.right = CalcLength(checkBoxTheme->GetHotZoneHorizontalPadding().Value());
178     margin.top = CalcLength(checkBoxTheme->GetHotZoneVerticalPadding().Value());
179     margin.bottom = CalcLength(checkBoxTheme->GetHotZoneVerticalPadding().Value());
180     auto& setMargin = layoutProperty->GetMarginProperty();
181     if (setMargin) {
182         if (setMargin->left.has_value()) {
183             margin.left = setMargin->left;
184         }
185         if (setMargin->right.has_value()) {
186             margin.right = setMargin->right;
187         }
188         if (setMargin->top.has_value()) {
189             margin.top = setMargin->top;
190         }
191         if (setMargin->bottom.has_value()) {
192             margin.bottom = setMargin->bottom;
193         }
194     }
195     layoutProperty->UpdateMargin(margin);
196     hotZoneHorizontalPadding_ = checkBoxTheme->GetHotZoneHorizontalPadding();
197     hotZoneVerticalPadding_ = checkBoxTheme->GetHotZoneVerticalPadding();
198     InitClickEvent();
199     InitTouchEvent();
200     InitMouseEvent();
201     InitFocusEvent();
202     auto focusHub = host->GetFocusHub();
203     CHECK_NULL_VOID(focusHub);
204     InitOnKeyEvent(focusHub);
205     SetAccessibilityAction();
206 }
207 
SetAccessibilityAction()208 void CheckBoxPattern::SetAccessibilityAction()
209 {
210     auto host = GetHost();
211     CHECK_NULL_VOID(host);
212     auto accessibilityProperty = host->GetAccessibilityProperty<AccessibilityProperty>();
213     CHECK_NULL_VOID(accessibilityProperty);
214     accessibilityProperty->SetActionSelect([weakPtr = WeakClaim(this)]() {
215         const auto& pattern = weakPtr.Upgrade();
216         CHECK_NULL_VOID(pattern);
217         pattern->UpdateSelectStatus(true);
218     });
219 
220     accessibilityProperty->SetActionClearSelection([weakPtr = WeakClaim(this)]() {
221         const auto& pattern = weakPtr.Upgrade();
222         CHECK_NULL_VOID(pattern);
223         pattern->UpdateSelectStatus(false);
224     });
225 }
226 
UpdateSelectStatus(bool isSelected)227 void CheckBoxPattern::UpdateSelectStatus(bool isSelected)
228 {
229     auto host = GetHost();
230     CHECK_NULL_VOID(host);
231     auto context = host->GetRenderContext();
232     CHECK_NULL_VOID(context);
233     MarkIsSelected(isSelected);
234     context->OnMouseSelectUpdate(isSelected, ITEM_FILL_COLOR, ITEM_FILL_COLOR);
235 }
236 
MarkIsSelected(bool isSelected)237 void CheckBoxPattern::MarkIsSelected(bool isSelected)
238 {
239     if (lastSelect_ == isSelected) {
240         return;
241     }
242     lastSelect_ = isSelected;
243     auto eventHub = GetEventHub<CheckBoxEventHub>();
244     CHECK_NULL_VOID(eventHub);
245     eventHub->UpdateChangeEvent(isSelected);
246     auto host = GetHost();
247     CHECK_NULL_VOID(host);
248     if (isSelected) {
249         eventHub->UpdateCurrentUIState(UI_STATE_SELECTED);
250         host->OnAccessibilityEvent(AccessibilityEventType::SELECTED);
251     } else {
252         eventHub->ResetCurrentUIState(UI_STATE_SELECTED);
253         host->OnAccessibilityEvent(AccessibilityEventType::CHANGE);
254     }
255 }
256 
OnAfterModifyDone()257 void CheckBoxPattern::OnAfterModifyDone()
258 {
259     auto host = GetHost();
260     CHECK_NULL_VOID(host);
261     auto inspectorId = host->GetInspectorId().value_or("");
262     if (inspectorId.empty()) {
263         return;
264     }
265     auto eventHub = host->GetEventHub<CheckBoxEventHub>();
266     CHECK_NULL_VOID(eventHub);
267     Recorder::NodeDataCache::Get().PutMultiple(host, inspectorId, eventHub->GetName(), lastSelect_);
268 }
269 
InitClickEvent()270 void CheckBoxPattern::InitClickEvent()
271 {
272     if (clickListener_) {
273         return;
274     }
275     auto host = GetHost();
276     CHECK_NULL_VOID(host);
277     auto gesture = host->GetOrCreateGestureEventHub();
278     CHECK_NULL_VOID(gesture);
279     auto clickCallback = [weak = WeakClaim(this)](GestureEvent& info) {
280         auto checkboxPattern = weak.Upgrade();
281         CHECK_NULL_VOID(checkboxPattern);
282         checkboxPattern->OnClick();
283     };
284     clickListener_ = MakeRefPtr<ClickEvent>(std::move(clickCallback));
285     gesture->AddClickEvent(clickListener_);
286 }
287 
InitTouchEvent()288 void CheckBoxPattern::InitTouchEvent()
289 {
290     if (touchListener_) {
291         return;
292     }
293     auto host = GetHost();
294     CHECK_NULL_VOID(host);
295     auto gesture = host->GetOrCreateGestureEventHub();
296     CHECK_NULL_VOID(gesture);
297     auto touchCallback = [weak = WeakClaim(this)](const TouchEventInfo& info) {
298         auto checkboxPattern = weak.Upgrade();
299         CHECK_NULL_VOID(checkboxPattern);
300         if (info.GetTouches().empty()) {
301             return;
302         }
303         if (info.GetTouches().front().GetTouchType() == TouchType::DOWN) {
304             checkboxPattern->OnTouchDown();
305         }
306         if (info.GetTouches().front().GetTouchType() == TouchType::UP ||
307             info.GetTouches().front().GetTouchType() == TouchType::CANCEL) {
308             checkboxPattern->OnTouchUp();
309         }
310     };
311     touchListener_ = MakeRefPtr<TouchEventImpl>(std::move(touchCallback));
312     gesture->AddTouchEvent(touchListener_);
313 }
314 
InitMouseEvent()315 void CheckBoxPattern::InitMouseEvent()
316 {
317     if (mouseEvent_) {
318         return;
319     }
320     auto host = GetHost();
321     CHECK_NULL_VOID(host);
322     auto gesture = host->GetOrCreateGestureEventHub();
323     CHECK_NULL_VOID(gesture);
324     auto eventHub = host->GetEventHub<CheckBoxEventHub>();
325     auto inputHub = eventHub->GetOrCreateInputEventHub();
326 
327     auto mouseTask = [weak = WeakClaim(this)](bool isHover) {
328         auto pattern = weak.Upgrade();
329         if (pattern) {
330             pattern->HandleMouseEvent(isHover);
331         }
332     };
333     mouseEvent_ = MakeRefPtr<InputEvent>(std::move(mouseTask));
334     inputHub->AddOnHoverEvent(mouseEvent_);
335 }
336 
HandleMouseEvent(bool isHover)337 void CheckBoxPattern::HandleMouseEvent(bool isHover)
338 {
339     TAG_LOGI(AceLogTag::ACE_SELECT_COMPONENT, "checkbox on hover %{public}d", isHover);
340     isHover_ = isHover;
341     if (isHover) {
342         touchHoverType_ = TouchHoverAnimationType::HOVER;
343     } else {
344         touchHoverType_ = TouchHoverAnimationType::NONE;
345     }
346     auto host = GetHost();
347     CHECK_NULL_VOID(host);
348     host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
349 }
350 
InitFocusEvent()351 void CheckBoxPattern::InitFocusEvent()
352 {
353     if (focusEventInitialized_) {
354         return;
355     }
356     auto host = GetHost();
357     CHECK_NULL_VOID(host);
358     auto focusHub = host->GetOrCreateFocusHub();
359     auto focusTask = [weak = WeakClaim(this)]() {
360         auto pattern = weak.Upgrade();
361         CHECK_NULL_VOID(pattern);
362         pattern->HandleFocusEvent();
363     };
364     focusHub->SetOnFocusInternal(focusTask);
365     auto blurTask = [weak = WeakClaim(this)]() {
366         auto pattern = weak.Upgrade();
367         CHECK_NULL_VOID(pattern);
368         pattern->HandleBlurEvent();
369     };
370     focusHub->SetOnBlurInternal(blurTask);
371 
372     focusEventInitialized_ = true;
373 }
374 
HandleFocusEvent()375 void CheckBoxPattern::HandleFocusEvent()
376 {
377     CHECK_NULL_VOID(paintMethod_);
378     AddIsFocusActiveUpdateEvent();
379     OnIsFocusActiveUpdate(true);
380 }
381 
HandleBlurEvent()382 void CheckBoxPattern::HandleBlurEvent()
383 {
384     CHECK_NULL_VOID(paintMethod_);
385     RemoveIsFocusActiveUpdateEvent();
386     OnIsFocusActiveUpdate(false);
387 }
388 
AddIsFocusActiveUpdateEvent()389 void CheckBoxPattern::AddIsFocusActiveUpdateEvent()
390 {
391     if (!isFocusActiveUpdateEvent_) {
392         isFocusActiveUpdateEvent_ = [weak = WeakClaim(this)](bool isFocusAcitve) {
393             auto pattern = weak.Upgrade();
394             CHECK_NULL_VOID(pattern);
395             pattern->OnIsFocusActiveUpdate(isFocusAcitve);
396         };
397     }
398     auto host = GetHost();
399     CHECK_NULL_VOID(host);
400     auto pipline = host->GetContextRefPtr();
401     CHECK_NULL_VOID(pipline);
402     pipline->AddIsFocusActiveUpdateEvent(host, isFocusActiveUpdateEvent_);
403 }
404 
RemoveIsFocusActiveUpdateEvent()405 void CheckBoxPattern::RemoveIsFocusActiveUpdateEvent()
406 {
407     auto host = GetHost();
408     CHECK_NULL_VOID(host);
409     auto pipline = host->GetContextRefPtr();
410     CHECK_NULL_VOID(pipline);
411     pipline->RemoveIsFocusActiveUpdateEvent(host);
412 }
413 
OnIsFocusActiveUpdate(bool isFocusAcitve)414 void CheckBoxPattern::OnIsFocusActiveUpdate(bool isFocusAcitve)
415 {
416     CHECK_NULL_VOID(paintMethod_);
417     auto modifier = paintMethod_->GetCheckBoxModifier();
418     CHECK_NULL_VOID(modifier);
419     modifier->SetIsFocused(isFocusAcitve);
420 }
421 
OnClick()422 void CheckBoxPattern::OnClick()
423 {
424     if (UseContentModifier()) {
425         return;
426     }
427     TAG_LOGI(AceLogTag::ACE_SELECT_COMPONENT, "checkbox onclick");
428     auto host = GetHost();
429     CHECK_NULL_VOID(host);
430     auto paintProperty = host->GetPaintProperty<CheckBoxPaintProperty>();
431     CHECK_NULL_VOID(paintProperty);
432     bool isSelected = false;
433     if (paintProperty->HasCheckBoxSelect()) {
434         isSelected = paintProperty->GetCheckBoxSelectValue();
435     } else {
436         isSelected = false;
437     }
438     paintProperty->UpdateCheckBoxSelect(!isSelected);
439     UpdateState();
440 }
441 
OnTouchDown()442 void CheckBoxPattern::OnTouchDown()
443 {
444     if (UseContentModifier()) {
445         return;
446     }
447     TAG_LOGI(AceLogTag::ACE_SELECT_COMPONENT, "checkbox touch down %{public}d", isHover_);
448     if (isHover_) {
449         touchHoverType_ = TouchHoverAnimationType::HOVER_TO_PRESS;
450     } else {
451         touchHoverType_ = TouchHoverAnimationType::PRESS;
452     }
453     auto host = GetHost();
454     CHECK_NULL_VOID(host);
455     isTouch_ = true;
456     host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
457 }
458 
OnTouchUp()459 void CheckBoxPattern::OnTouchUp()
460 {
461     if (UseContentModifier()) {
462         return;
463     }
464     TAG_LOGI(AceLogTag::ACE_SELECT_COMPONENT, "checkbox touch up %{public}d", isHover_);
465     if (isHover_) {
466         touchHoverType_ = TouchHoverAnimationType::PRESS_TO_HOVER;
467     } else {
468         touchHoverType_ = TouchHoverAnimationType::NONE;
469     }
470     auto host = GetHost();
471     CHECK_NULL_VOID(host);
472     isTouch_ = false;
473     host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
474 }
475 
UpdateUnSelect()476 void CheckBoxPattern::UpdateUnSelect()
477 {
478     auto host = GetHost();
479     CHECK_NULL_VOID(host);
480     auto paintProperty = host->GetPaintProperty<CheckBoxPaintProperty>();
481     CHECK_NULL_VOID(paintProperty);
482     if (paintProperty->HasCheckBoxSelect() && !paintProperty->GetCheckBoxSelectValue()) {
483         uiStatus_ = UIStatus::UNSELECTED;
484         host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
485     }
486 }
487 
UpdateUIStatus(bool check)488 void CheckBoxPattern::UpdateUIStatus(bool check)
489 {
490     TAG_LOGI(AceLogTag::ACE_SELECT_COMPONENT, "checkbox update status %{public}d", check);
491     uiStatus_ = check ? UIStatus::OFF_TO_ON : UIStatus::ON_TO_OFF;
492     auto host = GetHost();
493     CHECK_NULL_VOID(host);
494     if (UseContentModifier()) {
495         auto paintProperty = host->GetPaintProperty<CheckBoxPaintProperty>();
496         CHECK_NULL_VOID(paintProperty);
497         paintProperty->UpdateCheckBoxSelect(check);
498         FireBuilder();
499     }
500     host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
501 }
502 
OnDetachFromFrameNode(FrameNode * frameNode)503 void CheckBoxPattern::OnDetachFromFrameNode(FrameNode* frameNode)
504 {
505     CHECK_NULL_VOID(frameNode);
506     auto groupManager = GetGroupManager();
507     CHECK_NULL_VOID(groupManager);
508     auto eventHub = frameNode->GetEventHub<CheckBoxEventHub>();
509     CHECK_NULL_VOID(eventHub);
510     auto group = eventHub->GetGroupName() + currentNavId_.value_or(groupManager->GetLastNavId());
511     groupManager->RemoveCheckBoxFromGroup(group, frameNode->GetId());
512     auto groupNode = groupManager->GetCheckboxGroup(group);
513     CHECK_NULL_VOID(groupNode);
514     auto checkboxList = groupManager->GetCheckboxList(group);
515     UpdateCheckBoxGroupStatus(groupNode, checkboxList);
516 }
517 
CheckPageNode()518 void CheckBoxPattern::CheckPageNode()
519 {
520     if (Container::IsInSubContainer()) {
521         return;
522     }
523     auto host = GetHost();
524     CHECK_NULL_VOID(host);
525     auto prePageId = GetPrePageId();
526     auto pipelineContext = GetContext();
527     CHECK_NULL_VOID(pipelineContext);
528     auto stageManager = pipelineContext->GetStageManager();
529     CHECK_NULL_VOID(stageManager);
530     auto pageNode = stageManager->GetPageById(host->GetPageId());
531     CHECK_NULL_VOID(pageNode);
532     if (pageNode->GetId() != prePageId) {
533         auto pageEventHub = pageNode->GetEventHub<NG::PageEventHub>();
534         CHECK_NULL_VOID(pageEventHub);
535         auto groupManager = pageEventHub->GetGroupManager();
536         CHECK_NULL_VOID(groupManager);
537         groupManager_ = groupManager;
538         auto group = GetGroupNameWithNavId();
539         groupManager->AddCheckBoxToGroup(group, host);
540         SetPrePageId(pageNode->GetId());
541     }
542 }
543 
UpdateState()544 void CheckBoxPattern::UpdateState()
545 {
546     auto host = GetHost();
547     CHECK_NULL_VOID(host);
548     auto pipelineContext = GetContext();
549     CHECK_NULL_VOID(pipelineContext);
550     auto groupManager = GetGroupManager();
551     CHECK_NULL_VOID(groupManager);
552     auto paintProperty = host->GetPaintProperty<CheckBoxPaintProperty>();
553     CHECK_NULL_VOID(paintProperty);
554     auto preGroup = GetPreGroup();
555     auto group = GetGroupNameWithNavId();
556     if (!preGroup.has_value()) {
557         groupManager->AddCheckBoxToGroup(group, host);
558         SetPrePageIdToLastPageId();
559         auto callback = [weak = WeakClaim(this)]() {
560             auto checkbox = weak.Upgrade();
561             if (checkbox) {
562                 checkbox->CheckPageNode();
563                 checkbox->CheckBoxGroupIsTrue();
564             }
565         };
566         pipelineContext->AddBuildFinishCallBack(callback);
567         if (paintProperty->HasCheckBoxSelect()) {
568             auto isSelected = paintProperty->GetCheckBoxSelectValue();
569             SetLastSelect(isSelected);
570         }
571         isFirstCreated_ = false;
572         SetPreGroup(group);
573         return;
574     }
575     if (preGroup.has_value() && preGroup.value() != group) {
576         groupManager->RemoveCheckBoxFromGroup(preGroup.value(), host->GetId());
577         groupManager->AddCheckBoxToGroup(group, host);
578         SetPrePageIdToLastPageId();
579     }
580     SetPreGroup(group);
581     ChangeSelfStatusAndNotify(paintProperty);
582     auto groupNode = groupManager->GetCheckboxGroup(group);
583     CHECK_NULL_VOID(groupNode);
584     auto checkboxList = groupManager->GetCheckboxList(group);
585     UpdateCheckBoxGroupStatus(groupNode, checkboxList);
586 }
587 
ChangeSelfStatusAndNotify(const RefPtr<CheckBoxPaintProperty> & paintProperty)588 void CheckBoxPattern::ChangeSelfStatusAndNotify(const RefPtr<CheckBoxPaintProperty>& paintProperty)
589 {
590     auto host = GetHost();
591     CHECK_NULL_VOID(host);
592     bool isSelected = false;
593     if (paintProperty->HasCheckBoxSelect()) {
594         isSelected = paintProperty->GetCheckBoxSelectValue();
595         if (lastSelect_ != isSelected) {
596             UpdateUIStatus(isSelected);
597             SetLastSelect(isSelected);
598             auto checkboxEventHub = GetEventHub<CheckBoxEventHub>();
599             CHECK_NULL_VOID(checkboxEventHub);
600             TAG_LOGI(AceLogTag::ACE_SELECT_COMPONENT, "checkbox node %{public}d update change event %{public}d",
601                 host->GetId(), isSelected);
602             checkboxEventHub->UpdateChangeEvent(isSelected);
603         }
604     }
605     StartCustomNodeAnimation(isSelected);
606     host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
607     FireBuilder();
608 }
609 
StartEnterAnimation()610 void CheckBoxPattern::StartEnterAnimation()
611 {
612     AnimationOption option;
613     option.SetCurve(Curves::FAST_OUT_SLOW_IN);
614     option.SetDuration(DEFAULT_CHECKBOX_ANIMATION_DURATION);
615     CHECK_NULL_VOID(builderNode_);
616     const auto& renderContext = builderNode_->GetRenderContext();
617     CHECK_NULL_VOID(renderContext);
618     renderContext->UpdateOpacity(0);
619     const auto& layoutProperty = builderNode_->GetLayoutProperty();
620     CHECK_NULL_VOID(layoutProperty);
621     layoutProperty->UpdateVisibility(VisibleType::VISIBLE);
622     const auto& eventHub = builderNode_->GetEventHub<EventHub>();
623     if (eventHub) {
624         eventHub->SetEnabled(true);
625     }
626     AnimationUtils::Animate(
627         option,
628         [&]() {
629             TAG_LOGI(AceLogTag::ACE_SELECT_COMPONENT, "check enter animation");
630             renderContext->UpdateOpacity(1);
631         },
632         nullptr);
633 }
634 
StartExitAnimation()635 void CheckBoxPattern::StartExitAnimation()
636 {
637     AnimationOption option;
638     option.SetCurve(Curves::FAST_OUT_SLOW_IN);
639     option.SetDuration(DEFAULT_CHECKBOX_ANIMATION_DURATION);
640     CHECK_NULL_VOID(builderNode_);
641     const auto& renderContext = builderNode_->GetRenderContext();
642     CHECK_NULL_VOID(renderContext);
643     AnimationUtils::Animate(
644         option,
645         [&]() {
646             TAG_LOGI(AceLogTag::ACE_SELECT_COMPONENT, "check exit animation");
647             renderContext->UpdateOpacity(0);
648         },
649         nullptr);
650     const auto& eventHub = builderNode_->GetEventHub<EventHub>();
651     if (eventHub) {
652         eventHub->SetEnabled(false);
653     }
654 }
655 
LoadBuilder()656 void CheckBoxPattern::LoadBuilder()
657 {
658     RefPtr<UINode> customNode;
659     if (builder_.has_value()) {
660         auto host = GetHost();
661         CHECK_NULL_VOID(host);
662         if (builderNode_) {
663             host->RemoveChildAndReturnIndex(builderNode_);
664         }
665         NG::ScopedViewStackProcessor builderViewStackProcessor;
666         builder_.value()();
667         customNode = NG::ViewStackProcessor::GetInstance()->Finish();
668         CHECK_NULL_VOID(customNode);
669         builderNode_ = AceType::DynamicCast<FrameNode>(customNode);
670         CHECK_NULL_VOID(builderNode_);
671         builderNode_->MountToParent(host);
672         host->MarkDirtyNode(PROPERTY_UPDATE_BY_CHILD_REQUEST);
673     }
674 }
675 
StartCustomNodeAnimation(bool select)676 void CheckBoxPattern::StartCustomNodeAnimation(bool select)
677 {
678     if (!isFirstCreated_ && builder_.has_value()) {
679         if (select) {
680             StartEnterAnimation();
681         } else {
682             StartExitAnimation();
683         }
684     }
685 }
686 
UpdateCheckBoxGroupStatus(RefPtr<FrameNode> checkBoxGroupNode,const std::list<RefPtr<FrameNode>> & list)687 void CheckBoxPattern::UpdateCheckBoxGroupStatus(
688     RefPtr<FrameNode> checkBoxGroupNode, const std::list<RefPtr<FrameNode>>& list)
689 {
690     std::vector<std::string> vec;
691     bool haveCheckBoxSelected = false;
692     bool isAllCheckBoxSelected = true;
693     for (auto node : list) {
694         if (!node) {
695             continue;
696         }
697         auto paintProperty = node->GetPaintProperty<CheckBoxPaintProperty>();
698         CHECK_NULL_VOID(paintProperty);
699         if (paintProperty->GetCheckBoxSelectValue(false)) {
700             auto eventHub = node->GetEventHub<CheckBoxEventHub>();
701             CHECK_NULL_VOID(eventHub);
702             vec.push_back(eventHub->GetName());
703             haveCheckBoxSelected = true;
704         } else {
705             isAllCheckBoxSelected = false;
706         }
707     }
708     ChangeGroupStatusAndNotify(checkBoxGroupNode, vec, haveCheckBoxSelected, isAllCheckBoxSelected);
709 }
710 
ChangeGroupStatusAndNotify(const RefPtr<FrameNode> & checkBoxGroupNode,const std::vector<std::string> & vec,bool haveCheckBoxSelected,bool isAllCheckBoxSelected)711 void CheckBoxPattern::ChangeGroupStatusAndNotify(const RefPtr<FrameNode>& checkBoxGroupNode,
712     const std::vector<std::string>& vec, bool haveCheckBoxSelected, bool isAllCheckBoxSelected)
713 {
714     CHECK_NULL_VOID(checkBoxGroupNode);
715     auto groupPaintProperty = checkBoxGroupNode->GetPaintProperty<CheckBoxGroupPaintProperty>();
716     CHECK_NULL_VOID(groupPaintProperty);
717     auto pattern = checkBoxGroupNode->GetPattern<CheckBoxGroupPattern>();
718     CHECK_NULL_VOID(pattern);
719     auto preStatus = groupPaintProperty->GetSelectStatus();
720     if (haveCheckBoxSelected) {
721         if (isAllCheckBoxSelected) {
722             groupPaintProperty->SetSelectStatus(CheckBoxGroupPaintProperty::SelectStatus::ALL);
723             pattern->UpdateUIStatus(true);
724         } else {
725             groupPaintProperty->SetSelectStatus(CheckBoxGroupPaintProperty::SelectStatus::PART);
726             pattern->ResetUIStatus();
727         }
728     } else {
729         groupPaintProperty->SetSelectStatus(CheckBoxGroupPaintProperty::SelectStatus::NONE);
730         pattern->UpdateUIStatus(false);
731     }
732     checkBoxGroupNode->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
733     auto status = groupPaintProperty->GetSelectStatus();
734     if (preStatus != status && (preStatus == CheckBoxGroupPaintProperty::SelectStatus::ALL ||
735                                    status == CheckBoxGroupPaintProperty::SelectStatus::ALL)) {
736         pattern->SetSkipFlag(true);
737     }
738     CheckboxGroupResult groupResult(vec, int(status));
739     auto eventHub = checkBoxGroupNode->GetEventHub<CheckBoxGroupEventHub>();
740     CHECK_NULL_VOID(eventHub);
741     TAG_LOGI(AceLogTag::ACE_SELECT_COMPONENT, "update checkboxgroup result %d", groupResult.GetStatus());
742     eventHub->UpdateChangeEvent(&groupResult);
743 }
744 
CheckBoxGroupIsTrue()745 void CheckBoxPattern::CheckBoxGroupIsTrue()
746 {
747     auto host = GetHost();
748     CHECK_NULL_VOID(host);
749     auto groupManager = GetGroupManager();
750     CHECK_NULL_VOID(groupManager);
751     auto paintProperty = host->GetPaintProperty<CheckBoxPaintProperty>();
752     CHECK_NULL_VOID(paintProperty);
753     auto group = GetGroupNameWithNavId();
754     RefPtr<FrameNode> checkBoxGroupNode = groupManager->GetCheckboxGroup(group);
755     CHECK_NULL_VOID(checkBoxGroupNode);
756     std::vector<std::string> vec;
757     bool allSelectIsNull = true;
758     const auto& list = groupManager->GetCheckboxList(group);
759     for (auto node : list) {
760         if (!node) {
761             continue;
762         }
763         auto paintProperty = node->GetPaintProperty<CheckBoxPaintProperty>();
764         CHECK_NULL_VOID(paintProperty);
765         if (paintProperty->HasCheckBoxSelect()) {
766             allSelectIsNull = false;
767         } else {
768             paintProperty->UpdateCheckBoxSelect(false);
769         }
770     }
771     const auto& groupPaintProperty = checkBoxGroupNode->GetPaintProperty<CheckBoxGroupPaintProperty>();
772     CHECK_NULL_VOID(groupPaintProperty);
773     if (!groupManager->GetCheckboxGroupIsChange(group) && groupPaintProperty->GetIsCheckBoxCallbackDealed()) {
774         return;
775     }
776     // All checkboxes do not set select status.
777     if (allSelectIsNull && groupPaintProperty->GetCheckBoxGroupSelectValue(false)) {
778         InitCheckBoxStatusByGroup(checkBoxGroupNode, groupPaintProperty, list);
779     }
780     // Some checkboxes set select status.
781     if (!allSelectIsNull) {
782         UpdateCheckBoxGroupStatus(checkBoxGroupNode, list);
783     }
784     groupPaintProperty->SetIsCheckBoxCallbackDealed(true);
785     groupManager->SetCheckboxGroupIsChange(group, false);
786 }
787 
InitCheckBoxStatusByGroup(RefPtr<FrameNode> checkBoxGroupNode,const RefPtr<CheckBoxGroupPaintProperty> & groupPaintProperty,const std::list<RefPtr<FrameNode>> & list)788 void CheckBoxPattern::InitCheckBoxStatusByGroup(RefPtr<FrameNode> checkBoxGroupNode,
789     const RefPtr<CheckBoxGroupPaintProperty>& groupPaintProperty, const std::list<RefPtr<FrameNode>>& list)
790 {
791     if (groupPaintProperty->GetCheckBoxGroupSelectValue(false)) {
792         groupPaintProperty->SetSelectStatus(CheckBoxGroupPaintProperty::SelectStatus::ALL);
793         groupPaintProperty->UpdateCheckBoxGroupSelect(true);
794         checkBoxGroupNode->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
795         for (auto node : list) {
796             if (!node) {
797                 continue;
798             }
799             auto paintProperty = node->GetPaintProperty<CheckBoxPaintProperty>();
800             CHECK_NULL_VOID(paintProperty);
801             paintProperty->UpdateCheckBoxSelect(true);
802             auto checkBoxPattern = node->GetPattern<CheckBoxPattern>();
803             CHECK_NULL_VOID(checkBoxPattern);
804             checkBoxPattern->StartCustomNodeAnimation(true);
805             checkBoxPattern->UpdateUIStatus(true);
806             checkBoxPattern->SetLastSelect(true);
807         }
808     }
809 }
810 
InitOnKeyEvent(const RefPtr<FocusHub> & focusHub)811 void CheckBoxPattern::InitOnKeyEvent(const RefPtr<FocusHub>& focusHub)
812 {
813     CHECK_NULL_VOID(focusHub);
814     auto getInnerPaintRectCallback = [wp = WeakClaim(this)](RoundRect& paintRect) {
815         auto pattern = wp.Upgrade();
816         if (pattern) {
817             pattern->GetInnerFocusPaintRect(paintRect);
818         }
819     };
820     focusHub->SetInnerFocusPaintRectCallback(getInnerPaintRectCallback);
821 
822     auto onKeyEvent = [wp = WeakClaim(this)](const KeyEvent& event) -> bool {
823         auto pattern = wp.Upgrade();
824         if (pattern) {
825             return pattern->OnKeyEvent(event);
826         }
827         return false;
828     };
829     focusHub->SetOnKeyEventInternal(std::move(onKeyEvent));
830 }
831 
OnKeyEvent(const KeyEvent & event)832 bool CheckBoxPattern::OnKeyEvent(const KeyEvent& event)
833 {
834     if (event.action == KeyAction::DOWN && event.code == KeyCode::KEY_FUNCTION) {
835         OnClick();
836         return true;
837     }
838     return false;
839 }
840 
IsSquareStyleBox()841 bool CheckBoxPattern::IsSquareStyleBox()
842 {
843     auto host = GetHost();
844     CHECK_NULL_RETURN(host, false);
845     auto paintProperty = host->GetPaintProperty<CheckBoxPaintProperty>();
846     CHECK_NULL_RETURN(paintProperty, false);
847     CheckBoxStyle checkboxStyle = CheckBoxStyle::CIRCULAR_STYLE;
848     if (paintProperty->HasCheckBoxSelectedStyle()) {
849         checkboxStyle = paintProperty->GetCheckBoxSelectedStyleValue(CheckBoxStyle::CIRCULAR_STYLE);
850     } else {
851         checkboxStyle = Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_ELEVEN) ?
852             CheckBoxStyle::CIRCULAR_STYLE : CheckBoxStyle::SQUARE_STYLE;
853     }
854     return checkboxStyle == CheckBoxStyle::SQUARE_STYLE;
855 }
856 
GetInnerFocusPaintRect(RoundRect & paintRect)857 void CheckBoxPattern::GetInnerFocusPaintRect(RoundRect& paintRect)
858 {
859     auto host = GetHost();
860     CHECK_NULL_VOID(host);
861     auto* pipelineContext = host->GetContextWithCheck();
862     CHECK_NULL_VOID(pipelineContext);
863     auto checkBoxTheme = pipelineContext->GetTheme<CheckboxTheme>(GetThemeScopeId());
864     CHECK_NULL_VOID(checkBoxTheme);
865     auto borderRadius = checkBoxTheme->GetFocusRadius().ConvertToPx();
866     auto focusPaintPadding = checkBoxTheme->GetFocusPaintPadding().ConvertToPx();
867     auto isSquare = IsSquareStyleBox();
868     auto squareFocusBoardSize = checkBoxTheme->GetFocusBoardSize();
869     auto roundFocusBoardSize = checkBoxTheme->GetRoundFocusBoardSize();
870     if ((squareFocusBoardSize > roundFocusBoardSize) && isSquare) {
871         focusPaintPadding += (squareFocusBoardSize.ConvertToPx() - roundFocusBoardSize.ConvertToPx());
872     }
873     float originX = offset_.GetX() - focusPaintPadding;
874     float originY = offset_.GetY() - focusPaintPadding;
875     float width = size_.Width() + 2 * focusPaintPadding;
876     float height = size_.Height() + 2 * focusPaintPadding;
877     paintRect.SetRect({ originX, originY, width, height });
878     paintRect.SetCornerRadius(RoundRect::CornerPos::TOP_LEFT_POS, borderRadius, borderRadius);
879     paintRect.SetCornerRadius(RoundRect::CornerPos::TOP_RIGHT_POS, borderRadius, borderRadius);
880     paintRect.SetCornerRadius(RoundRect::CornerPos::BOTTOM_LEFT_POS, borderRadius, borderRadius);
881     paintRect.SetCornerRadius(RoundRect::CornerPos::BOTTOM_RIGHT_POS, borderRadius, borderRadius);
882 }
883 
GetFocusPattern() const884 FocusPattern CheckBoxPattern::GetFocusPattern() const
885 {
886     auto host = GetHost();
887     CHECK_NULL_RETURN(host, FocusPattern());
888     auto* pipeline = host->GetContextWithCheck();
889     CHECK_NULL_RETURN(pipeline, FocusPattern());
890     auto checkBoxTheme = pipeline->GetTheme<CheckboxTheme>(GetThemeScopeId());
891     CHECK_NULL_RETURN(checkBoxTheme, FocusPattern());
892     auto activeColor = checkBoxTheme->GetFocusLineColor();
893     FocusPaintParam focusPaintParam;
894     focusPaintParam.SetPaintColor(activeColor);
895     return { FocusType::NODE, true, FocusStyleType::CUSTOM_REGION, focusPaintParam };
896 }
897 
898 // Set the default hot zone for the component.
AddHotZoneRect()899 void CheckBoxPattern::AddHotZoneRect()
900 {
901     hotZoneOffset_.SetX(offset_.GetX() - hotZoneHorizontalPadding_.ConvertToPx());
902     hotZoneOffset_.SetY(offset_.GetY() - hotZoneVerticalPadding_.ConvertToPx());
903     hotZoneSize_.SetWidth(size_.Width() + 2 * hotZoneHorizontalPadding_.ConvertToPx());
904     hotZoneSize_.SetHeight(size_.Height() + 2 * hotZoneVerticalPadding_.ConvertToPx());
905     DimensionRect hotZoneRegion;
906     hotZoneRegion.SetSize(DimensionSize(Dimension(hotZoneSize_.Width()), Dimension(hotZoneSize_.Height())));
907     hotZoneRegion.SetOffset(DimensionOffset(Dimension(hotZoneOffset_.GetX()), Dimension(hotZoneOffset_.GetY())));
908     auto host = GetHost();
909     CHECK_NULL_VOID(host);
910     auto gestureHub = host->GetOrCreateGestureEventHub();
911     CHECK_NULL_VOID(gestureHub);
912     std::vector<DimensionRect> hotZoneRegions;
913     hotZoneRegions.emplace_back(hotZoneRegion);
914     gestureHub->SetResponseRegion(hotZoneRegions);
915 }
916 
RemoveLastHotZoneRect() const917 void CheckBoxPattern::RemoveLastHotZoneRect() const
918 {
919     auto host = GetHost();
920     CHECK_NULL_VOID(host);
921     host->RemoveLastHotZoneRect();
922 }
923 
ProvideRestoreInfo()924 std::string CheckBoxPattern::ProvideRestoreInfo()
925 {
926     auto jsonObj = JsonUtil::Create(true);
927     auto checkBoxPaintProperty = GetPaintProperty<CheckBoxPaintProperty>();
928     CHECK_NULL_RETURN(checkBoxPaintProperty, "");
929     jsonObj->Put("isOn", checkBoxPaintProperty->GetCheckBoxSelect().value_or(false));
930     return jsonObj->ToString();
931 }
932 
OnRestoreInfo(const std::string & restoreInfo)933 void CheckBoxPattern::OnRestoreInfo(const std::string& restoreInfo)
934 {
935     auto checkBoxPaintProperty = GetPaintProperty<CheckBoxPaintProperty>();
936     CHECK_NULL_VOID(checkBoxPaintProperty);
937     auto info = JsonUtil::ParseJsonString(restoreInfo);
938     if (!info->IsValid() || !info->IsObject()) {
939         return;
940     }
941     auto jsonCheckBoxSelect = info->GetValue("isOn");
942     checkBoxPaintProperty->UpdateCheckBoxSelect(jsonCheckBoxSelect->GetBool());
943 }
944 
SetCheckBoxSelect(bool select)945 void CheckBoxPattern::SetCheckBoxSelect(bool select)
946 {
947     auto host = GetHost();
948     CHECK_NULL_VOID(host);
949     auto eventHub = host->GetEventHub<EventHub>();
950     CHECK_NULL_VOID(eventHub);
951     auto enabled = eventHub->IsEnabled();
952     if (!enabled) {
953         return;
954     }
955     auto paintProperty = host->GetPaintProperty<CheckBoxPaintProperty>();
956     CHECK_NULL_VOID(paintProperty);
957     paintProperty->UpdateCheckBoxSelect(select);
958     UpdateState();
959     OnModifyDone();
960 }
961 
FireBuilder()962 void CheckBoxPattern::FireBuilder()
963 {
964     auto host = GetHost();
965     CHECK_NULL_VOID(host);
966     if (!makeFunc_.has_value() && !toggleMakeFunc_.has_value()) {
967         host->RemoveChildAndReturnIndex(contentModifierNode_);
968         contentModifierNode_ = nullptr;
969         host->MarkNeedFrameFlushDirty(PROPERTY_UPDATE_MEASURE);
970         return;
971     }
972     auto node = BuildContentModifierNode();
973     if (contentModifierNode_ == node) {
974         return;
975     }
976     auto renderContext = host->GetRenderContext();
977     CHECK_NULL_VOID(renderContext);
978     renderContext->UpdateBackgroundColor(Color::TRANSPARENT);
979     host->RemoveChildAndReturnIndex(contentModifierNode_);
980     contentModifierNode_ = node;
981     CHECK_NULL_VOID(contentModifierNode_);
982     host->AddChild(contentModifierNode_, 0);
983     host->MarkNeedFrameFlushDirty(PROPERTY_UPDATE_MEASURE);
984 }
985 
BuildContentModifierNode()986 RefPtr<FrameNode> CheckBoxPattern::BuildContentModifierNode()
987 {
988     auto host = GetHost();
989     CHECK_NULL_RETURN(host, nullptr);
990     auto eventHub = host->GetEventHub<CheckBoxEventHub>();
991     CHECK_NULL_RETURN(eventHub, nullptr);
992     auto name = eventHub->GetName();
993     auto enabled = eventHub->IsEnabled();
994     auto paintProperty = host->GetPaintProperty<CheckBoxPaintProperty>();
995     CHECK_NULL_RETURN(paintProperty, nullptr);
996     bool isSelected = false;
997     if (paintProperty->HasCheckBoxSelect()) {
998         isSelected = paintProperty->GetCheckBoxSelectValue();
999     } else {
1000         isSelected = false;
1001     }
1002     if (host->GetHostTag() == V2::CHECKBOX_ETS_TAG && toggleMakeFunc_.has_value()) {
1003         return (toggleMakeFunc_.value())(ToggleConfiguration(enabled, isSelected));
1004     }
1005     CheckBoxConfiguration checkBoxConfiguration(name, isSelected, enabled);
1006     return (makeFunc_.value())(checkBoxConfiguration);
1007 }
1008 
UpdatePaintPropertyBySettingData(RefPtr<CheckBoxPaintProperty> paintProp)1009 void CheckBoxPattern::UpdatePaintPropertyBySettingData(RefPtr<CheckBoxPaintProperty> paintProp)
1010 {
1011     if (checkboxSettingData_.selectedColor.has_value()) {
1012         paintProp->UpdateCheckBoxSelectedColor(checkboxSettingData_.selectedColor.value());
1013     }
1014     if (checkboxSettingData_.unselectedColor.has_value()) {
1015         paintProp->UpdateCheckBoxUnSelectedColor(checkboxSettingData_.unselectedColor.value());
1016     }
1017     if (checkboxSettingData_.strokeColor.has_value()) {
1018         paintProp->UpdateCheckBoxCheckMarkColor(checkboxSettingData_.strokeColor.value());
1019     }
1020 }
1021 
OnColorConfigurationUpdate()1022 void CheckBoxPattern::OnColorConfigurationUpdate()
1023 {
1024     auto host = GetHost();
1025     CHECK_NULL_VOID(host);
1026     auto checkBoxPaintProperty = host->GetPaintProperty<CheckBoxPaintProperty>();
1027     CHECK_NULL_VOID(checkBoxPaintProperty);
1028     OnThemeScopeUpdate(host->GetThemeScopeId());
1029     UpdatePaintPropertyBySettingData(checkBoxPaintProperty);
1030     host->MarkModifyDone();
1031     host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
1032 }
1033 
OnThemeScopeUpdate(int32_t themeScopeId)1034 bool CheckBoxPattern::OnThemeScopeUpdate(int32_t themeScopeId)
1035 {
1036     auto host = GetHost();
1037     CHECK_NULL_RETURN(host, false);
1038     auto* pipeline = host->GetContext();
1039     CHECK_NULL_RETURN(pipeline, false);
1040     auto checkBoxTheme = pipeline->GetTheme<CheckboxTheme>(themeScopeId);
1041     CHECK_NULL_RETURN(checkBoxTheme, false);
1042     auto result = false;
1043     auto checkBoxPaintProperty = host->GetPaintProperty<CheckBoxPaintProperty>();
1044     CHECK_NULL_RETURN(checkBoxPaintProperty, false);
1045     if (!checkBoxPaintProperty->HasCheckBoxSelectedColorFlagByUser()) {
1046         checkBoxPaintProperty->UpdateCheckBoxSelectedColor(checkBoxTheme->GetActiveColor());
1047         result = true;
1048     }
1049     if (!checkBoxPaintProperty->HasCheckBoxUnSelectedColorFlagByUser()) {
1050         checkBoxPaintProperty->UpdateCheckBoxUnSelectedColor(checkBoxTheme->GetInactiveColor());
1051         result = true;
1052     }
1053 
1054     if (!checkBoxPaintProperty->HasCheckBoxCheckMarkColorFlagByUser()) {
1055         checkBoxPaintProperty->UpdateCheckBoxCheckMarkColor(checkBoxTheme->GetPointColor());
1056         result = true;
1057     }
1058     return result;
1059 }
1060 
SetPrePageIdToLastPageId()1061 void CheckBoxPattern::SetPrePageIdToLastPageId()
1062 {
1063     if (!Container::IsInSubContainer()) {
1064         auto pipelineContext = PipelineContext::GetCurrentContext();
1065         CHECK_NULL_VOID(pipelineContext);
1066         auto stageManager = pipelineContext->GetStageManager();
1067         CHECK_NULL_VOID(stageManager);
1068         auto pageNode = stageManager->GetLastPage();
1069         CHECK_NULL_VOID(pageNode);
1070         SetPrePageId(pageNode->GetId());
1071     }
1072 }
1073 
OnAttachToMainTree()1074 void CheckBoxPattern::OnAttachToMainTree()
1075 {
1076     auto host = GetHost();
1077     CHECK_NULL_VOID(host);
1078     auto groupManager = GetGroupManager();
1079     CHECK_NULL_VOID(groupManager);
1080     auto parent = host->GetParent();
1081     while (parent) {
1082         if (parent->GetTag() == V2::NAVDESTINATION_CONTENT_ETS_TAG) {
1083             currentNavId_ = std::to_string(parent->GetId());
1084             groupManager->SetLastNavId(currentNavId_);
1085             UpdateState();
1086             return;
1087         }
1088         parent = parent->GetParent();
1089     }
1090     if (!currentNavId_.value_or("").empty()) {
1091         currentNavId_ = "";
1092         groupManager->SetLastNavId(std::nullopt);
1093         UpdateState();
1094     }
1095 }
1096 
GetGroupNameWithNavId()1097 std::string CheckBoxPattern::GetGroupNameWithNavId()
1098 {
1099     auto host = GetHost();
1100     CHECK_NULL_RETURN(host, "");
1101     auto eventHub = host->GetEventHub<CheckBoxEventHub>();
1102     CHECK_NULL_RETURN(eventHub, "");
1103     if (currentNavId_.has_value()) {
1104         return eventHub->GetGroupName() + currentNavId_.value();
1105     }
1106     auto groupManager = GetGroupManager();
1107     CHECK_NULL_RETURN(groupManager, eventHub->GetGroupName());
1108     return eventHub->GetGroupName() + groupManager->GetLastNavId();
1109 }
1110 
GetGroupManager()1111 RefPtr<GroupManager> CheckBoxPattern::GetGroupManager()
1112 {
1113     auto manager = groupManager_.Upgrade();
1114     if (manager) {
1115         return manager;
1116     }
1117     groupManager_ = GroupManager::GetGroupManager();
1118     return groupManager_.Upgrade();
1119 }
1120 } // namespace OHOS::Ace::NG
1121