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