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