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