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