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