1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "core/components_ng/pattern/checkboxgroup/checkboxgroup_pattern.h"
17
18 #include <algorithm>
19 #include <cmath>
20 #include <cstdint>
21
22 #include "base/geometry/axis.h"
23 #include "base/geometry/dimension.h"
24 #include "base/utils/utils.h"
25 #include "core/animation/curve.h"
26 #include "core/animation/curves.h"
27 #include "core/components/common/layout/constants.h"
28 #include "core/components/scroll/scrollable.h"
29 #include "core/components/test/unittest/image/image_test_utils.h"
30 #include "core/components_ng/pattern/checkbox/checkbox_paint_property.h"
31 #include "core/components_ng/pattern/checkbox/checkbox_pattern.h"
32 #include "core/components_ng/pattern/checkboxgroup/checkboxgroup_layout_algorithm.h"
33 #include "core/components_ng/pattern/checkboxgroup/checkboxgroup_paint_property.h"
34 #include "core/components_ng/pattern/stage/page_event_hub.h"
35 #include "core/components_ng/property/calc_length.h"
36 #include "core/components_ng/property/property.h"
37 #include "core/components_v2/inspector/inspector_constants.h"
38 #include "core/event/touch_event.h"
39 #include "core/pipeline/base/constants.h"
40 #include "core/pipeline_ng/pipeline_context.h"
41
42 namespace OHOS::Ace::NG {
43
44 namespace {
45 constexpr int32_t DEFUALT_CHECKBOX_ANIMATION_DURATION = 150;
46 constexpr float DEFAULT_MAX_CHECKBOX_SHAPE_SCALE = 1.0;
47 constexpr float DEFAULT_MIN_CHECKBOX_SHAPE_SCALE = 0.0;
48 } // namespace
49
OnAttachToFrameNode()50 void CheckBoxGroupPattern::OnAttachToFrameNode()
51 {
52 auto host = GetHost();
53 CHECK_NULL_VOID(host);
54 host->GetLayoutProperty()->UpdateAlignment(Alignment::CENTER);
55 }
56
OnDetachFromFrameNode(FrameNode * frameNode)57 void CheckBoxGroupPattern::OnDetachFromFrameNode(FrameNode* frameNode)
58 {
59 CHECK_NULL_VOID(frameNode);
60 auto pipelineContext = PipelineContext::GetCurrentContext();
61 CHECK_NULL_VOID(pipelineContext);
62 auto stageManager = pipelineContext->GetStageManager();
63 CHECK_NULL_VOID(stageManager);
64 auto pageNode = stageManager->GetLastPage();
65 CHECK_NULL_VOID(pageNode);
66 auto pageEventHub = pageNode->GetEventHub<NG::PageEventHub>();
67 CHECK_NULL_VOID(pageEventHub);
68 auto checkBoxGroupEventHub = frameNode->GetEventHub<NG::CheckBoxGroupEventHub>();
69 CHECK_NULL_VOID(checkBoxGroupEventHub);
70 pageEventHub->RemoveCheckBoxFromGroup(checkBoxGroupEventHub->GetGroupName(), frameNode->GetId());
71 }
72
OnModifyDone()73 void CheckBoxGroupPattern::OnModifyDone()
74 {
75 UpdateState();
76 auto host = GetHost();
77 CHECK_NULL_VOID(host);
78 auto pipeline = host->GetContext();
79 CHECK_NULL_VOID(pipeline);
80 auto checkBoxTheme = pipeline->GetTheme<CheckboxTheme>();
81 CHECK_NULL_VOID(checkBoxTheme);
82 auto layoutProperty = host->GetLayoutProperty();
83 CHECK_NULL_VOID(layoutProperty);
84 if (!layoutProperty->GetMarginProperty()) {
85 MarginProperty margin;
86 margin.left = CalcLength(checkBoxTheme->GetHotZoneHorizontalPadding().Value());
87 margin.right = CalcLength(checkBoxTheme->GetHotZoneHorizontalPadding().Value());
88 margin.top = CalcLength(checkBoxTheme->GetHotZoneVerticalPadding().Value());
89 margin.bottom = CalcLength(checkBoxTheme->GetHotZoneVerticalPadding().Value());
90 layoutProperty->UpdateMargin(margin);
91 }
92 hotZoneHorizontalPadding_ = checkBoxTheme->GetHotZoneHorizontalPadding();
93 hotZoneVerticalPadding_ = checkBoxTheme->GetHotZoneVerticalPadding();
94 InitClickEvent();
95 InitTouchEvent();
96 InitMouseEvent();
97 auto focusHub = host->GetFocusHub();
98 CHECK_NULL_VOID(focusHub);
99 InitOnKeyEvent(focusHub);
100 }
101
InitClickEvent()102 void CheckBoxGroupPattern::InitClickEvent()
103 {
104 if (clickListener_) {
105 return;
106 }
107 auto host = GetHost();
108 CHECK_NULL_VOID(host);
109 auto gesture = host->GetOrCreateGestureEventHub();
110 CHECK_NULL_VOID(gesture);
111 auto clickCallback = [weak = WeakClaim(this)](GestureEvent& info) {
112 auto checkboxPattern = weak.Upgrade();
113 CHECK_NULL_VOID(checkboxPattern);
114 checkboxPattern->OnClick();
115 };
116 clickListener_ = MakeRefPtr<ClickEvent>(std::move(clickCallback));
117 gesture->AddClickEvent(clickListener_);
118 }
119
InitTouchEvent()120 void CheckBoxGroupPattern::InitTouchEvent()
121 {
122 if (touchListener_) {
123 return;
124 }
125 auto host = GetHost();
126 CHECK_NULL_VOID(host);
127 auto gesture = host->GetOrCreateGestureEventHub();
128 CHECK_NULL_VOID(gesture);
129 auto touchCallback = [weak = WeakClaim(this)](const TouchEventInfo& info) {
130 auto checkboxPattern = weak.Upgrade();
131 CHECK_NULL_VOID(checkboxPattern);
132 if (info.GetTouches().front().GetTouchType() == TouchType::DOWN) {
133 checkboxPattern->OnTouchDown();
134 }
135 if (info.GetTouches().front().GetTouchType() == TouchType::UP ||
136 info.GetTouches().front().GetTouchType() == TouchType::CANCEL) {
137 checkboxPattern->OnTouchUp();
138 }
139 };
140 touchListener_ = MakeRefPtr<TouchEventImpl>(std::move(touchCallback));
141 gesture->AddTouchEvent(touchListener_);
142 }
143
InitMouseEvent()144 void CheckBoxGroupPattern::InitMouseEvent()
145 {
146 if (mouseEvent_) {
147 return;
148 }
149 auto host = GetHost();
150 CHECK_NULL_VOID(host);
151 auto gesture = host->GetOrCreateGestureEventHub();
152 CHECK_NULL_VOID(gesture);
153 auto eventHub = host->GetEventHub<CheckBoxGroupEventHub>();
154 auto inputHub = eventHub->GetOrCreateInputEventHub();
155
156 auto mouseTask = [weak = WeakClaim(this)](bool isHover) {
157 auto pattern = weak.Upgrade();
158 if (pattern) {
159 pattern->HandleMouseEvent(isHover);
160 }
161 };
162 mouseEvent_ = MakeRefPtr<InputEvent>(std::move(mouseTask));
163 inputHub->AddOnHoverEvent(mouseEvent_);
164 }
165
HandleMouseEvent(bool isHover)166 void CheckBoxGroupPattern::HandleMouseEvent(bool isHover)
167 {
168 isHover_ = isHover;
169 auto host = GetHost();
170 CHECK_NULL_VOID(host);
171 host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
172 }
173
OnClick()174 void CheckBoxGroupPattern::OnClick()
175 {
176 auto host = GetHost();
177 CHECK_NULL_VOID(host);
178 auto paintProperty = host->GetPaintProperty<CheckBoxGroupPaintProperty>();
179 CHECK_NULL_VOID(paintProperty);
180 bool isSelected = false;
181 auto status = paintProperty->GetSelectStatus();
182 isSelected = status == CheckBoxGroupPaintProperty::SelectStatus::NONE;
183 paintProperty->UpdateCheckBoxGroupSelect(isSelected);
184 isClick_ = true;
185 UpdateState();
186 }
187
OnTouchDown()188 void CheckBoxGroupPattern::OnTouchDown()
189 {
190 auto host = GetHost();
191 CHECK_NULL_VOID(host);
192 isTouch_ = true;
193 host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
194 }
195
OnTouchUp()196 void CheckBoxGroupPattern::OnTouchUp()
197 {
198 auto host = GetHost();
199 CHECK_NULL_VOID(host);
200 isTouch_ = false;
201 host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
202 }
203
UpdateAnimation(bool check)204 void CheckBoxGroupPattern::UpdateAnimation(bool check)
205 {
206 auto host = GetHost();
207 CHECK_NULL_VOID(host);
208 if (!controller_) {
209 controller_ = AceType::MakeRefPtr<Animator>(host->GetContext());
210 auto weak = AceType::WeakClaim(this);
211 controller_->AddStopListener(Animator::StatusCallback([weak]() {
212 auto checkBox = weak.Upgrade();
213 if (checkBox) {
214 checkBox->UpdateUnSelect();
215 }
216 }));
217 }
218 float from = 0.0;
219 float to = 0.0;
220 if (!check) {
221 from = DEFAULT_MAX_CHECKBOX_SHAPE_SCALE;
222 to = DEFAULT_MIN_CHECKBOX_SHAPE_SCALE;
223 } else {
224 from = DEFAULT_MIN_CHECKBOX_SHAPE_SCALE;
225 to = DEFAULT_MAX_CHECKBOX_SHAPE_SCALE;
226 }
227
228 if (translate_) {
229 controller_->RemoveInterpolator(translate_);
230 }
231 translate_ = AceType::MakeRefPtr<CurveAnimation<float>>(from, to, Curves::FRICTION);
232 auto weak = AceType::WeakClaim(this);
233 translate_->AddListener(Animation<float>::ValueCallback([weak](float value) {
234 auto checkBox = weak.Upgrade();
235 if (checkBox) {
236 checkBox->UpdateCheckBoxShape(value);
237 }
238 }));
239 controller_->SetDuration(DEFUALT_CHECKBOX_ANIMATION_DURATION);
240 controller_->AddInterpolator(translate_);
241 controller_->Play();
242 }
243
UpdateUnSelect()244 void CheckBoxGroupPattern::UpdateUnSelect()
245 {
246 auto host = GetHost();
247 CHECK_NULL_VOID(host);
248 auto paintProperty = host->GetPaintProperty<CheckBoxGroupPaintProperty>();
249 CHECK_NULL_VOID(paintProperty);
250 if (paintProperty->GetSelectStatus() == CheckBoxGroupPaintProperty::SelectStatus::NONE) {
251 uiStatus_ = UIStatus::UNSELECTED;
252 host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
253 }
254 }
255
UpdateUIStatus(bool check)256 void CheckBoxGroupPattern::UpdateUIStatus(bool check)
257 {
258 auto host = GetHost();
259 CHECK_NULL_VOID(host);
260 auto paintProperty = host->GetPaintProperty<CheckBoxGroupPaintProperty>();
261 CHECK_NULL_VOID(paintProperty);
262 auto selectStatus = paintProperty->GetSelectStatus();
263 if (selectStatus == CheckBoxGroupPaintProperty::SelectStatus::PART) {
264 uiStatus_ = check ? UIStatus::PART_TO_ON : UIStatus::PART_TO_OFF;
265 } else {
266 uiStatus_ = check ? UIStatus::OFF_TO_ON : UIStatus::ON_TO_OFF;
267 }
268 shapeScale_ = 1.0f;
269 host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
270 }
271
UpdateCheckBoxShape(const float value)272 void CheckBoxGroupPattern::UpdateCheckBoxShape(const float value)
273 {
274 if (value < DEFAULT_MIN_CHECKBOX_SHAPE_SCALE || value > DEFAULT_MAX_CHECKBOX_SHAPE_SCALE) {
275 return;
276 }
277 shapeScale_ = value;
278 auto host = GetHost();
279 CHECK_NULL_VOID(host);
280 host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
281 }
282
UpdateState()283 void CheckBoxGroupPattern::UpdateState()
284 {
285 auto host = GetHost();
286 CHECK_NULL_VOID(host);
287 auto pattern = host->GetPattern<CheckBoxGroupPattern>();
288 CHECK_NULL_VOID(pattern);
289 auto eventHub = host->GetEventHub<CheckBoxGroupEventHub>();
290 CHECK_NULL_VOID(eventHub);
291
292 auto pipelineContext = PipelineContext::GetCurrentContext();
293 CHECK_NULL_VOID(pipelineContext);
294 auto stageManager = pipelineContext->GetStageManager();
295 CHECK_NULL_VOID(stageManager);
296 auto pageNode = stageManager->GetLastPage();
297 CHECK_NULL_VOID(pageNode);
298 auto pageEventHub = pageNode->GetEventHub<NG::PageEventHub>();
299 CHECK_NULL_VOID(pageEventHub);
300
301 auto preGroup = pattern->GetPreGroup();
302 auto group = eventHub->GetGroupName();
303 if (!preGroup.has_value()) {
304 pageEventHub->AddCheckBoxGroupToGroup(group, host->GetId());
305 auto paintProperty = host->GetPaintProperty<CheckBoxGroupPaintProperty>();
306 CHECK_NULL_VOID(paintProperty);
307 if (paintProperty->HasCheckBoxGroupSelect() && paintProperty->GetCheckBoxGroupSelectValue()) {
308 auto selectAll = paintProperty->GetCheckBoxGroupSelectValue();
309 if (selectAll) {
310 paintProperty->SetSelectStatus(CheckBoxGroupPaintProperty::SelectStatus::ALL);
311 }
312 if (selectAll || (!selectAll && !isFirstCreated_)) {
313 UpdateUIStatus(selectAll);
314 }
315 }
316 isFirstCreated_ = false;
317 pattern->SetPreGroup(group);
318 return;
319 }
320 if (preGroup.value() != group) {
321 pageEventHub->RemoveCheckBoxFromGroup(preGroup.value(), host->GetId());
322 pageEventHub->AddCheckBoxGroupToGroup(group, host->GetId());
323 pattern->SetPreGroup(group);
324 return;
325 }
326 auto paintProperty = host->GetPaintProperty<CheckBoxGroupPaintProperty>();
327 CHECK_NULL_VOID(paintProperty);
328 if (!paintProperty->HasCheckBoxGroupSelect()) {
329 return;
330 }
331 bool isSelected = paintProperty->GetCheckBoxGroupSelectValue();
332 paintProperty->ResetCheckBoxGroupSelect();
333
334 // Setting selectAll to false when clicked requires processing, changing selectAll to false dynamically does
335 // not require processing
336 if (isClick_ || isSelected) {
337 if (pattern->GetIsAddToMap()) {
338 UpdateGroupCheckStatus(host, isSelected);
339 } else {
340 UpdateRepeatedGroupStatus(host, isSelected);
341 }
342 }
343 isClick_ = false;
344 }
345
UpdateGroupCheckStatus(const RefPtr<FrameNode> & frameNode,bool select)346 void CheckBoxGroupPattern::UpdateGroupCheckStatus(const RefPtr<FrameNode>& frameNode, bool select)
347 {
348 auto paintProperty = frameNode->GetPaintProperty<CheckBoxGroupPaintProperty>();
349 CHECK_NULL_VOID(paintProperty);
350 auto pattern = frameNode->GetPattern<CheckBoxGroupPattern>();
351 CHECK_NULL_VOID(pattern);
352 pattern->UpdateUIStatus(select);
353 pattern->UpdateAnimation(select);
354 if (select) {
355 paintProperty->SetSelectStatus(CheckBoxGroupPaintProperty::SelectStatus::ALL);
356 } else {
357 paintProperty->SetSelectStatus(CheckBoxGroupPaintProperty::SelectStatus::NONE);
358 }
359 frameNode->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
360 auto pipelineContext = PipelineContext::GetCurrentContext();
361 CHECK_NULL_VOID(pipelineContext);
362 auto stageManager = pipelineContext->GetStageManager();
363 CHECK_NULL_VOID(stageManager);
364 auto pageNode = stageManager->GetLastPage();
365 CHECK_NULL_VOID(pageNode);
366 auto pageEventHub = pageNode->GetEventHub<NG::PageEventHub>();
367 CHECK_NULL_VOID(pageEventHub);
368 auto checkBoxGroupEventHub = GetEventHub<CheckBoxGroupEventHub>();
369 CHECK_NULL_VOID(checkBoxGroupEventHub);
370 auto checkBoxGroupMap = pageEventHub->GetCheckBoxGroupMap();
371 auto group = checkBoxGroupEventHub->GetGroupName();
372 UpdateCheckBoxStatus(frameNode, checkBoxGroupMap, group, select);
373 }
374
UpdateCheckBoxStatus(const RefPtr<FrameNode> & frameNode,std::unordered_map<std::string,std::list<WeakPtr<FrameNode>>> checkBoxGroupMap,const std::string & group,bool select)375 void CheckBoxGroupPattern::UpdateCheckBoxStatus(const RefPtr<FrameNode>& frameNode,
376 std::unordered_map<std::string, std::list<WeakPtr<FrameNode>>> checkBoxGroupMap, const std::string& group,
377 bool select)
378 {
379 std::vector<std::string> vec;
380 auto status =
381 select ? CheckBoxGroupPaintProperty::SelectStatus::ALL : CheckBoxGroupPaintProperty::SelectStatus::NONE;
382 const auto& list = checkBoxGroupMap[group];
383 for (auto&& item : list) {
384 auto node = item.Upgrade();
385 if (node == frameNode) {
386 continue;
387 }
388 if (!node) {
389 continue;
390 }
391 if (node->GetTag() == V2::CHECKBOXGROUP_ETS_TAG) {
392 continue;
393 }
394 auto paintProperty = node->GetPaintProperty<CheckBoxPaintProperty>();
395 CHECK_NULL_VOID(paintProperty);
396 auto eventHub = node->GetEventHub<CheckBoxEventHub>();
397 CHECK_NULL_VOID(eventHub);
398 if (select) {
399 vec.push_back(eventHub->GetName());
400 }
401 }
402 CheckboxGroupResult groupResult(vec, int(status));
403 auto eventHub = frameNode->GetEventHub<CheckBoxGroupEventHub>();
404 eventHub->UpdateChangeEvent(&groupResult);
405 for (auto&& item : list) {
406 auto node = item.Upgrade();
407 if (node == frameNode) {
408 continue;
409 }
410 if (!node) {
411 continue;
412 }
413 if (node->GetTag() == V2::CHECKBOXGROUP_ETS_TAG) {
414 continue;
415 } else {
416 auto paintProperty = node->GetPaintProperty<CheckBoxPaintProperty>();
417 CHECK_NULL_VOID(paintProperty);
418 auto eventHub = node->GetEventHub<CheckBoxEventHub>();
419 CHECK_NULL_VOID(eventHub);
420
421 if (!paintProperty->HasCheckBoxSelect()) {
422 if (select) {
423 paintProperty->UpdateCheckBoxSelect(select);
424 auto pattern = node->GetPattern<CheckBoxPattern>();
425 pattern->UpdateUIStatus(select);
426 pattern->SetLastSelect(select);
427 eventHub->UpdateChangeEvent(select);
428 }
429 }
430 if (paintProperty->HasCheckBoxSelect() && paintProperty->GetCheckBoxSelectValue() != select) {
431 paintProperty->UpdateCheckBoxSelect(select);
432 auto pattern = node->GetPattern<CheckBoxPattern>();
433 pattern->UpdateUIStatus(select);
434 pattern->SetLastSelect(select);
435 eventHub->UpdateChangeEvent(select);
436 }
437 }
438 }
439 }
440
UpdateRepeatedGroupStatus(const RefPtr<FrameNode> & frameNode,bool select)441 void CheckBoxGroupPattern::UpdateRepeatedGroupStatus(const RefPtr<FrameNode>& frameNode, bool select)
442 {
443 std::vector<std::string> vec;
444 auto status =
445 select ? CheckBoxGroupPaintProperty::SelectStatus::ALL : CheckBoxGroupPaintProperty::SelectStatus::NONE;
446 auto pattern = frameNode->GetPattern<CheckBoxGroupPattern>();
447 CHECK_NULL_VOID(pattern);
448 pattern->UpdateUIStatus(select);
449 pattern->UpdateAnimation(select);
450 auto paintProperty = frameNode->GetPaintProperty<CheckBoxGroupPaintProperty>();
451 CHECK_NULL_VOID(paintProperty);
452 paintProperty->SetSelectStatus(
453 select ? CheckBoxGroupPaintProperty::SelectStatus::ALL : CheckBoxGroupPaintProperty::SelectStatus::NONE);
454 auto checkBoxGroupEventHub = GetEventHub<CheckBoxGroupEventHub>();
455 CHECK_NULL_VOID(checkBoxGroupEventHub);
456 frameNode->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
457 CheckboxGroupResult groupResult(vec, int(status));
458 auto eventHub = frameNode->GetEventHub<CheckBoxGroupEventHub>();
459 eventHub->UpdateChangeEvent(&groupResult);
460 }
461
InitOnKeyEvent(const RefPtr<FocusHub> & focusHub)462 void CheckBoxGroupPattern::InitOnKeyEvent(const RefPtr<FocusHub>& focusHub)
463 {
464 auto onKeyEvent = [wp = WeakClaim(this)](const KeyEvent& event) -> bool {
465 auto pattern = wp.Upgrade();
466 if (!pattern) {
467 return false;
468 }
469 return pattern->OnKeyEvent(event);
470 };
471 focusHub->SetOnKeyEventInternal(std::move(onKeyEvent));
472
473 auto getInnerPaintRectCallback = [wp = WeakClaim(this)](RoundRect& paintRect) {
474 auto pattern = wp.Upgrade();
475 if (pattern) {
476 pattern->GetInnerFocusPaintRect(paintRect);
477 }
478 };
479 focusHub->SetInnerFocusPaintRectCallback(getInnerPaintRectCallback);
480 }
481
OnKeyEvent(const KeyEvent & event)482 bool CheckBoxGroupPattern::OnKeyEvent(const KeyEvent& event)
483 {
484 if (event.action != KeyAction::DOWN) {
485 return false;
486 }
487 if (event.code == KeyCode::KEY_ENTER) {
488 OnClick();
489 return true;
490 }
491 return false;
492 }
493
GetInnerFocusPaintRect(RoundRect & paintRect)494 void CheckBoxGroupPattern::GetInnerFocusPaintRect(RoundRect& paintRect)
495 {
496 auto pipelineContext = PipelineBase::GetCurrentContext();
497 CHECK_NULL_VOID(pipelineContext);
498 auto checkBoxTheme = pipelineContext->GetTheme<CheckboxTheme>();
499 CHECK_NULL_VOID(checkBoxTheme);
500 auto borderRadius = checkBoxTheme->GetFocusRadius().ConvertToPx();
501 auto focusPaintPadding = checkBoxTheme->GetFocusPaintPadding().ConvertToPx();
502 float originX = offset_.GetX() - focusPaintPadding;
503 float originY = offset_.GetY() - focusPaintPadding;
504 float width = size_.Width() + 2 * focusPaintPadding;
505 float height = size_.Height() + 2 * focusPaintPadding;
506 paintRect.SetRect({ originX, originY, width, height });
507 paintRect.SetCornerRadius(RoundRect::CornerPos::TOP_LEFT_POS, borderRadius, borderRadius);
508 paintRect.SetCornerRadius(RoundRect::CornerPos::TOP_RIGHT_POS, borderRadius, borderRadius);
509 paintRect.SetCornerRadius(RoundRect::CornerPos::BOTTOM_LEFT_POS, borderRadius, borderRadius);
510 paintRect.SetCornerRadius(RoundRect::CornerPos::BOTTOM_RIGHT_POS, borderRadius, borderRadius);
511 }
512
GetFocusPattern() const513 FocusPattern CheckBoxGroupPattern::GetFocusPattern() const
514 {
515 auto pipeline = PipelineBase::GetCurrentContext();
516 CHECK_NULL_RETURN(pipeline, FocusPattern());
517 auto checkBoxTheme = pipeline->GetTheme<CheckboxTheme>();
518 CHECK_NULL_RETURN(checkBoxTheme, FocusPattern());
519 auto activeColor = checkBoxTheme->GetActiveColor();
520 FocusPaintParam focusPaintParam;
521 focusPaintParam.SetPaintColor(activeColor);
522 return { FocusType::NODE, true, FocusStyleType::CUSTOM_REGION, focusPaintParam };
523 }
524
525 // Set the default hot zone for the component.
AddHotZoneRect()526 void CheckBoxGroupPattern::AddHotZoneRect()
527 {
528 hotZoneOffset_.SetX(offset_.GetX() - hotZoneHorizontalPadding_.ConvertToPx());
529 hotZoneOffset_.SetY(offset_.GetY() - hotZoneVerticalPadding_.ConvertToPx());
530 hotZoneSize_.SetWidth(size_.Width() + 2 * hotZoneHorizontalPadding_.ConvertToPx());
531 hotZoneSize_.SetHeight(size_.Height() + 2 * hotZoneVerticalPadding_.ConvertToPx());
532 DimensionRect hotZoneRegion;
533 hotZoneRegion.SetSize(DimensionSize(Dimension(hotZoneSize_.Width()), Dimension(hotZoneSize_.Height())));
534 hotZoneRegion.SetOffset(DimensionOffset(Dimension(hotZoneOffset_.GetX()), Dimension(hotZoneOffset_.GetY())));
535 auto host = GetHost();
536 CHECK_NULL_VOID(host);
537 host->AddHotZoneRect(hotZoneRegion);
538 }
539
540 } // namespace OHOS::Ace::NG
541