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
16 #include "base/i18n/localization.h"
17 #include "core/components_ng/pattern/patternlock/patternlock_pattern.h"
18
19 #include "core/components_ng/pattern/stage/page_event_hub.h"
20 #include "core/components_ng/pattern/text/text_pattern.h"
21 #include "core/components_ng/property/calc_length.h"
22 #include "core/components_ng/property/property.h"
23 #include "core/components_v2/inspector/inspector_constants.h"
24 #include "core/components_v2/pattern_lock/pattern_lock_component.h"
25 #include "core/event/touch_event.h"
26 #include "core/pipeline/base/constants.h"
27 #include "core/pipeline_ng/pipeline_context.h"
28
29 namespace OHOS::Ace::NG {
30 namespace {
31 constexpr int32_t PATTERN_LOCK_COL_COUNT = 3;
32 constexpr int32_t RADIUS_TO_DIAMETER = 2;
33 constexpr int32_t RADIUS_COUNT = 6;
34 } // namespace
35
OnAttachToFrameNode()36 void PatternLockPattern::OnAttachToFrameNode()
37 {
38 auto host = GetHost();
39 CHECK_NULL_VOID(host);
40 host->GetLayoutProperty()->UpdateAlignment(Alignment::CENTER);
41 }
42
OnModifyDone()43 void PatternLockPattern::OnModifyDone()
44 {
45 Pattern::OnModifyDone();
46 auto host = GetHost();
47 CHECK_NULL_VOID(host);
48
49 auto gestureHub = host->GetOrCreateGestureEventHub();
50 InitTouchEvent(gestureHub, touchDownListener_);
51 InitPatternLockController();
52 InitFocusEvent();
53 InitMouseEvent();
54 InitAccessibilityHoverEvent();
55 InitSkipUnselectedPoint();
56 if (isInitVirtualNode_) {
57 auto pipeline = host->GetContext();
58 CHECK_NULL_VOID(pipeline);
59 pipeline->AddAfterRenderTask([weak = WeakClaim(this)]() {
60 auto patternLock = weak.Upgrade();
61 CHECK_NULL_VOID(patternLock);
62 patternLock->ModifyAccessibilityVirtualNode();
63 });
64 }
65 }
66
InitTouchEvent(RefPtr<GestureEventHub> & gestureHub,RefPtr<TouchEventImpl> & touchDownListener)67 void PatternLockPattern::InitTouchEvent(RefPtr<GestureEventHub>& gestureHub, RefPtr<TouchEventImpl>& touchDownListener)
68 {
69 if (touchDownListener) {
70 return;
71 }
72 auto touchDownTask = [weak = WeakClaim(this)](const TouchEventInfo& info) {
73 auto pattern = weak.Upgrade();
74 CHECK_NULL_VOID(pattern);
75 pattern->HandleTouchEvent(info);
76 };
77 touchDownListener = MakeRefPtr<TouchEventImpl>(std::move(touchDownTask));
78 gestureHub->AddTouchEvent(touchDownListener);
79 gestureHub->SetHitTestMode(HitTestMode::HTMBLOCK);
80 }
81
SetChallengeResult(V2::PatternLockChallengeResult challengeResult)82 void PatternLockPattern::SetChallengeResult(V2::PatternLockChallengeResult challengeResult)
83 {
84 if (!isMoveEventValid_) {
85 CHECK_NULL_VOID(patternLockModifier_);
86 std::optional<NG::PatternLockChallengeResult> ngChallengeResult;
87 if (challengeResult == V2::PatternLockChallengeResult::CORRECT) {
88 ngChallengeResult = NG::PatternLockChallengeResult::CORRECT;
89 } else if (challengeResult == V2::PatternLockChallengeResult::WRONG) {
90 ngChallengeResult = NG::PatternLockChallengeResult::WRONG;
91 }
92 patternLockModifier_->SetChallengeResult(ngChallengeResult);
93 }
94 }
95
InitPatternLockController()96 void PatternLockPattern::InitPatternLockController()
97 {
98 patternLockController_->SetResetImpl([weak = WeakClaim(this)]() {
99 auto patternLock = weak.Upgrade();
100 CHECK_NULL_VOID(patternLock);
101 patternLock->HandleReset();
102 });
103 patternLockController_->SetChallengeResultImpl(
104 [weak = WeakClaim(this)](V2::PatternLockChallengeResult challengeResult) {
105 auto patternLock = weak.Upgrade();
106 CHECK_NULL_VOID(patternLock);
107 patternLock->SetChallengeResult(challengeResult);
108 });
109 }
110
InitAccessibilityHoverEvent()111 void PatternLockPattern::InitAccessibilityHoverEvent()
112 {
113 auto host = GetHost();
114 CHECK_NULL_VOID(host);
115 auto eventHub = host->GetOrCreateInputEventHub();
116 eventHub->SetAccessibilityHoverEvent([weak = WeakClaim(this)](bool isHover, AccessibilityHoverInfo& info) {
117 auto patternLock = weak.Upgrade();
118 CHECK_NULL_VOID(patternLock);
119 patternLock->HandleAccessibilityHoverEvent(isHover, info);
120 });
121 }
122
HandleAccessibilityHoverEvent(bool isHover,AccessibilityHoverInfo & info)123 void PatternLockPattern::HandleAccessibilityHoverEvent(bool isHover, AccessibilityHoverInfo& info)
124 {
125 auto accessibilityHoverAction = info.GetActionType();
126 if (isHover && (accessibilityHoverAction == AccessibilityHoverAction::HOVER_ENTER ||
127 accessibilityHoverAction == AccessibilityHoverAction::HOVER_MOVE)) {
128 for (const auto& accessibilityProperty : accessibilityPropertyVec_) {
129 accessibilityProperty->SetAccessibilityLevel(AccessibilityProperty::Level::YES_STR);
130 }
131 if (!CheckAutoReset()) {
132 return;
133 }
134 HandleReset();
135 } else if (!isHover) {
136 for (const auto& accessibilityProperty : accessibilityPropertyVec_) {
137 accessibilityProperty->SetAccessibilityLevel(AccessibilityProperty::Level::NO_STR);
138 }
139 AddPointEnd();
140 auto host = GetHost();
141 auto accessibilityProperty = host->GetAccessibilityProperty<AccessibilityProperty>();
142 accessibilityProperty->SetAccessibilityLevel(AccessibilityProperty::Level::YES_STR);
143 }
144 }
145
InitVirtualNode()146 bool PatternLockPattern::InitVirtualNode()
147 {
148 auto host = GetHost();
149 CHECK_NULL_RETURN(host, false);
150 float handleCircleRadius = 0.0f;
151 if (!GetHandleCircleRadius(handleCircleRadius)) {
152 return false;
153 }
154 auto lineNode = FrameNode::CreateFrameNode(V2::COLUMN_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
155 AceType::MakeRefPtr<LinearLayoutPattern>(true));
156 auto renderContext = lineNode->GetRenderContext();
157 CHECK_NULL_RETURN(renderContext, false);
158 renderContext->UpdatePosition(OffsetT(Dimension(0.0f), Dimension(0.0f)));
159 for (int32_t y = 0; y < PATTERN_LOCK_COL_COUNT; y++) {
160 for (int32_t x = 0; x < PATTERN_LOCK_COL_COUNT; x++) {
161 auto textNode = AddTextNodeIntoVirtual(x + 1, y + 1, handleCircleRadius);
162 lineNode->AddChild(textNode);
163 textAccessibilityNodeVec_.emplace_back(textNode);
164 }
165 }
166 auto accessibilityProperty = host->GetAccessibilityProperty<AccessibilityProperty>();
167 accessibilityProperty->SetAccessibilityText(" ");
168 auto virtualFrameNode = AceType::DynamicCast<NG::FrameNode>(lineNode);
169 CHECK_NULL_RETURN(virtualFrameNode, false);
170 virtualFrameNode->SetAccessibilityNodeVirtual();
171 virtualFrameNode->SetAccessibilityVirtualNodeParent(AceType::DynamicCast<NG::UINode>(host));
172 virtualFrameNode->SetFirstAccessibilityVirtualNode();
173 FrameNode::ProcessOffscreenNode(virtualFrameNode);
174 accessibilityProperty->SaveAccessibilityVirtualNode(lineNode);
175 host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD);
176 ModifyAccessibilityVirtualNode();
177 return true;
178 }
179
AddTextNodeIntoVirtual(int32_t x,int32_t y,float handleCircleRadius)180 RefPtr<FrameNode> PatternLockPattern::AddTextNodeIntoVirtual(int32_t x, int32_t y, float handleCircleRadius)
181 {
182 auto textNode = FrameNode::CreateFrameNode(
183 V2::TEXT_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<TextPattern>());
184 UpdateAccessibilityTextNode(textNode, handleCircleRadius, x, y);
185 auto textAccessibilityProperty = textNode->GetAccessibilityProperty<AccessibilityProperty>();
186 accessibilityPropertyVec_.emplace_back(textAccessibilityProperty);
187 textAccessibilityProperty->SetOnAccessibilityFocusCallback([weak = WeakClaim(this), x, y](bool focus) {
188 if (focus) {
189 auto patternLock = weak.Upgrade();
190 CHECK_NULL_VOID(patternLock);
191 patternLock->HandleTextOnAccessibilityFocusCallback(x, y);
192 }
193 });
194 return textNode;
195 }
196
197
HandleTextOnAccessibilityFocusCallback(int32_t x,int32_t y)198 void PatternLockPattern::HandleTextOnAccessibilityFocusCallback(int32_t x, int32_t y)
199 {
200 if (!CheckChoosePoint(x, y)) {
201 AddPassPoint(x, y);
202 choosePoint_.emplace_back(x, y);
203 StartModifierConnectedAnimate(x, y);
204 auto host = GetHost();
205 auto accessibilityProperty = host->GetAccessibilityProperty<AccessibilityProperty>();
206 accessibilityProperty->SetAccessibilityLevel(AccessibilityProperty::Level::NO_STR);
207 host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
208 }
209 }
210
211
ModifyAccessibilityVirtualNode()212 void PatternLockPattern::ModifyAccessibilityVirtualNode()
213 {
214 if (textAccessibilityNodeVec_.size() < 1) {
215 return;
216 }
217 float handleCircleRadius = 0.0f;
218 if (!GetHandleCircleRadius(handleCircleRadius)) {
219 return;
220 }
221 for (int32_t y = 0; y < PATTERN_LOCK_COL_COUNT; y++) {
222 for (int32_t x = 0; x < PATTERN_LOCK_COL_COUNT; x++) {
223 auto textNode = textAccessibilityNodeVec_[y * PATTERN_LOCK_COL_COUNT + x];
224 UpdateAccessibilityTextNode(textNode, handleCircleRadius, x, y);
225 }
226 }
227 auto host = GetHost();
228 host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD);
229 }
230
ReplacePlaceHolder(const std::string & str,int32_t number)231 std::string PatternLockPattern::ReplacePlaceHolder(const std::string& str, int32_t number)
232 {
233 std::string result = str;
234 std::string numberStr = std::to_string(number);
235
236 size_t pos = result.find("%d");
237 if (pos != std::string::npos) {
238 result.replace(pos, 2, numberStr); // 2: "%d" length
239 } else {
240 result = str + numberStr;
241 }
242
243 return result;
244 }
245
UpdateAccessibilityTextNode(RefPtr<FrameNode> frameNode,float handleCircleRadius,int32_t x,int32_t y)246 void PatternLockPattern::UpdateAccessibilityTextNode(
247 RefPtr<FrameNode> frameNode, float handleCircleRadius, int32_t x, int32_t y)
248 {
249 auto host = GetHost();
250 CHECK_NULL_VOID(host);
251 OffsetF contentOffset = host->GetGeometryNode()->GetContentOffset();
252 float sideLength = host->GetGeometryNode()->GetContentSize().Width();
253 int32_t scale = RADIUS_TO_DIAMETER;
254 float offsetX = sideLength / PATTERN_LOCK_COL_COUNT / scale * (scale * (x + 1) - 1);
255 float offsetY = sideLength / PATTERN_LOCK_COL_COUNT / scale * (scale * (y + 1) - 1);
256 int32_t index = y * PATTERN_LOCK_COL_COUNT + x + 1;
257 auto pipeline = host->GetContext();
258 CHECK_NULL_VOID(pipeline);
259 auto patternLockTheme = pipeline->GetTheme<V2::PatternLockTheme>();
260 CHECK_NULL_VOID(patternLockTheme);
261 auto message = patternLockTheme->GetPassPointTxt();
262 std::string text = ReplacePlaceHolder(message, index);
263 CHECK_NULL_VOID(frameNode);
264 auto textLayoutProperty = frameNode->GetLayoutProperty<TextLayoutProperty>();
265 CHECK_NULL_VOID(textLayoutProperty);
266 textLayoutProperty->UpdateContent(text);
267 Dimension focusPaddingRadius = Dimension(handleCircleRadius * RADIUS_TO_DIAMETER);
268 CalcLength width = CalcLength(focusPaddingRadius);
269 CalcLength height = CalcLength(focusPaddingRadius);
270 textLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(width, height));
271 auto renderContext = frameNode->GetRenderContext();
272 CHECK_NULL_VOID(renderContext);
273 Dimension textOffsetX = Dimension(offsetX - handleCircleRadius + contentOffset.GetX());
274 Dimension textOffsetY = Dimension(offsetY - handleCircleRadius + contentOffset.GetY());
275 renderContext->UpdatePosition(OffsetT(textOffsetX, textOffsetY));
276 frameNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
277 }
278
HandleTouchEvent(const TouchEventInfo & info)279 void PatternLockPattern::HandleTouchEvent(const TouchEventInfo& info)
280 {
281 auto touchList = info.GetChangedTouches();
282 CHECK_NULL_VOID(!touchList.empty());
283 if (fingerId_ == -1) {
284 fingerId_ = touchList.front().GetFingerId();
285 }
286 for (const auto& touchInfo : touchList) {
287 if (touchInfo.GetFingerId() == fingerId_) {
288 auto touchType = touchInfo.GetTouchType();
289 if (touchType == TouchType::DOWN) {
290 OnTouchDown(touchInfo);
291 } else if (touchType == TouchType::MOVE) {
292 OnTouchMove(touchInfo);
293 } else if (touchType == TouchType::UP) {
294 OnTouchUp();
295 } else if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_FOURTEEN) &&
296 touchType == TouchType::CANCEL) {
297 OnTouchUp();
298 }
299 break;
300 }
301 }
302 }
303
GetHandleCircleRadius(float & handleCircleRadius)304 bool PatternLockPattern::GetHandleCircleRadius(float& handleCircleRadius)
305 {
306 auto host = GetHost();
307 CHECK_NULL_RETURN(host, false);
308 auto patternLockPaintProperty = host->GetPaintProperty<PatternLockPaintProperty>();
309 float sideLength = host->GetGeometryNode()->GetContentSize().Width();
310 auto pipelineContext = PipelineBase::GetCurrentContext();
311 CHECK_NULL_RETURN(pipelineContext, false);
312 auto patternLockTheme = pipelineContext->GetTheme<V2::PatternLockTheme>();
313 CHECK_NULL_RETURN(patternLockTheme, false);
314 circleRadius_ = patternLockTheme->GetCircleRadius();
315 if (patternLockPaintProperty->HasCircleRadius()) {
316 circleRadius_ = patternLockPaintProperty->GetCircleRadiusValue();
317 }
318 auto backgroundRadiusScale = patternLockTheme->GetBackgroundRadiusScale();
319 if (NearZero(backgroundRadiusScale)) {
320 return false;
321 }
322 auto activeCircleRadiusScale = patternLockTheme->GetActiveCircleRadiusScale();
323 handleCircleRadius = std::min(static_cast<float>(circleRadius_.ConvertToPxWithSize(sideLength)),
324 sideLength / backgroundRadiusScale / RADIUS_COUNT);
325 auto hotSpotCircleRadius = patternLockTheme->GetHotSpotCircleRadius();
326 handleCircleRadius = std::max(handleCircleRadius * activeCircleRadiusScale,
327 std::min(
328 static_cast<float>(hotSpotCircleRadius.ConvertToPx()) / RADIUS_TO_DIAMETER, sideLength / RADIUS_COUNT));
329 return true;
330 }
331
332
CheckInHotSpot(const OffsetF & offset,int32_t x,int32_t y)333 bool PatternLockPattern::CheckInHotSpot(const OffsetF& offset, int32_t x, int32_t y)
334 {
335 auto host = GetHost();
336 CHECK_NULL_RETURN(host, false);
337 float sideLength = host->GetGeometryNode()->GetContentSize().Width();
338 OffsetF contentOffset = host->GetGeometryNode()->GetContentOffset();
339 auto handleCircleRadius = 0.0f;
340 if (!GetHandleCircleRadius(handleCircleRadius)) {
341 return false;
342 }
343 const int32_t scale = RADIUS_TO_DIAMETER;
344 float offsetX = sideLength / PATTERN_LOCK_COL_COUNT / scale * (scale * x - 1);
345 float offsetY = sideLength / PATTERN_LOCK_COL_COUNT / scale * (scale * y - 1);
346 offsetX += contentOffset.GetX();
347 offsetY += contentOffset.GetY();
348 OffsetF centerOffset;
349 centerOffset.SetX(offsetX);
350 centerOffset.SetY(offsetY);
351 auto X = (offset - centerOffset).GetX();
352 auto Y = (offset - centerOffset).GetY();
353 float distance = std::sqrt((X * X) + (Y * Y));
354 return LessOrEqual(distance, handleCircleRadius);
355 }
356
AddChoosePoint(const OffsetF & offset,int32_t x,int32_t y)357 bool PatternLockPattern::AddChoosePoint(const OffsetF& offset, int32_t x, int32_t y)
358 {
359 if (CheckInHotSpot(offset, x, y)) {
360 if (!CheckChoosePoint(x, y)) {
361 AddPassPoint(x, y);
362 choosePoint_.emplace_back(x, y);
363 StartModifierConnectedAnimate(x, y);
364 UpdateDotConnectEvent();
365 }
366 return true;
367 }
368 return false;
369 }
370
CheckChoosePoint(int32_t x,int32_t y) const371 bool PatternLockPattern::CheckChoosePoint(int32_t x, int32_t y) const
372 {
373 for (auto it : choosePoint_) {
374 if (it.GetColumn() == x && it.GetRow() == y) {
375 return true;
376 }
377 }
378 return false;
379 }
380
UpdateDotConnectEvent()381 void PatternLockPattern::UpdateDotConnectEvent()
382 {
383 auto host = GetHost();
384 CHECK_NULL_VOID(host);
385 auto eventHub = host->GetOrCreateEventHub<PatternLockEventHub>();
386 CHECK_NULL_VOID(eventHub);
387 eventHub->UpdateDotConnectEvent(choosePoint_.back().GetCode());
388 }
389
AddPassPointToChoosePoint(int32_t lastCode,int32_t nowCode,std::vector<PatternLockCell> passPointVec)390 void PatternLockPattern::AddPassPointToChoosePoint(
391 int32_t lastCode, int32_t nowCode, std::vector<PatternLockCell> passPointVec)
392 {
393 passPointCount_ = static_cast<int32_t>(passPointVec.size());
394 if (nowCode > lastCode) {
395 choosePoint_.emplace_back(passPointVec.front());
396 UpdateDotConnectEvent();
397 StartModifierAddPassPointAnimate(passPointVec.front().GetColumn(), passPointVec.front().GetRow());
398 if (passPointCount_ > 1) {
399 choosePoint_.emplace_back(passPointVec.back());
400 UpdateDotConnectEvent();
401 StartModifierAddPassPointAnimate(passPointVec.back().GetColumn(), passPointVec.back().GetRow());
402 }
403 } else {
404 choosePoint_.emplace_back(passPointVec.back());
405 UpdateDotConnectEvent();
406 StartModifierAddPassPointAnimate(passPointVec.back().GetColumn(), passPointVec.back().GetRow());
407 if (passPointCount_ > 1) {
408 choosePoint_.emplace_back(passPointVec.front());
409 UpdateDotConnectEvent();
410 StartModifierAddPassPointAnimate(passPointVec.front().GetColumn(), passPointVec.front().GetRow());
411 }
412 }
413 }
414
AddPassPoint(int32_t x,int32_t y)415 void PatternLockPattern::AddPassPoint(int32_t x, int32_t y)
416 {
417 if (choosePoint_.empty() || skipUnselectedPoint_) {
418 return;
419 }
420 passPointCount_ = 0;
421 PatternLockCell lastCell = choosePoint_.back();
422 int32_t lastX = lastCell.GetColumn();
423 int32_t lastY = lastCell.GetRow();
424 int32_t lastCode = lastCell.GetCode();
425 int32_t nowCode = PATTERN_LOCK_COL_COUNT * (y - 1) + (x - 1);
426 std::vector<PatternLockCell> passPointVec;
427 for (int32_t i = 1; i <= PATTERN_LOCK_COL_COUNT; i++) {
428 for (int32_t j = 1; j <= PATTERN_LOCK_COL_COUNT; j++) {
429 PatternLockCell passPoint = PatternLockCell(i, j);
430 if ((passPoint.GetCode() >= nowCode && passPoint.GetCode() >= lastCode) ||
431 (passPoint.GetCode() <= nowCode && passPoint.GetCode() <= lastCode)) {
432 continue;
433 }
434 if ((j != y) && (j != lastY) &&
435 (NearEqual(static_cast<float>(lastX - i) / (lastY - j), static_cast<float>(i - x) / (j - y)) &&
436 !CheckChoosePoint(i, j))) {
437 passPointVec.emplace_back(passPoint);
438 }
439 if ((j == lastY) && (j == y) && !CheckChoosePoint(i, j)) {
440 passPointVec.emplace_back(passPoint);
441 }
442 }
443 }
444 size_t passPointLength = passPointVec.size();
445 if (passPointLength == 0) {
446 return;
447 }
448 AddPassPointToChoosePoint(lastCode, nowCode, passPointVec);
449 }
450
HandleReset()451 void PatternLockPattern::HandleReset()
452 {
453 isMoveEventValid_ = false;
454 isOnKeyEventState_ = false;
455 choosePoint_.clear();
456 cellCenter_.Reset();
457 if (patternLockModifier_) {
458 patternLockModifier_->Reset();
459 }
460 auto host = GetHost();
461 CHECK_NULL_VOID(host);
462 host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
463 }
464
CheckAutoReset() const465 bool PatternLockPattern::CheckAutoReset() const
466 {
467 auto host = GetHost();
468 CHECK_NULL_RETURN(host, false);
469 auto patternLockPaintProperty = host->GetPaintProperty<PatternLockPaintProperty>();
470 if (patternLockPaintProperty->HasAutoReset()) {
471 autoReset_ = patternLockPaintProperty->GetAutoResetValue();
472 }
473 return !(!autoReset_ && !choosePoint_.empty() && !isMoveEventValid_);
474 }
475
OnTouchDown(const TouchLocationInfo & info)476 void PatternLockPattern::OnTouchDown(const TouchLocationInfo& info)
477 {
478 auto locationX = static_cast<float>(info.GetLocalLocation().GetX());
479 auto locationY = static_cast<float>(info.GetLocalLocation().GetY());
480 screenTouchPoint_.SetX(locationX);
481 screenTouchPoint_.SetY(locationY);
482
483 if (!CheckAutoReset()) {
484 return;
485 }
486 HandleReset();
487 CalculateCellCenter();
488 bool isAdd = false;
489 for (int32_t i = 0; i < PATTERN_LOCK_COL_COUNT && !isAdd; i++) {
490 for (int32_t j = 0; j < PATTERN_LOCK_COL_COUNT && !isAdd; j++) {
491 isAdd = AddChoosePoint(cellCenter_, i + 1, j + 1);
492 }
493 }
494
495 if (patternLockModifier_) {
496 patternLockModifier_->SetIsTouchDown(true);
497 }
498 auto host = GetHost();
499 CHECK_NULL_VOID(host);
500 host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
501 isMoveEventValid_ = true;
502 }
503
OnTouchMove(const TouchLocationInfo & info)504 void PatternLockPattern::OnTouchMove(const TouchLocationInfo& info)
505 {
506 auto locationX = static_cast<float>(info.GetLocalLocation().GetX());
507 auto locationY = static_cast<float>(info.GetLocalLocation().GetY());
508 screenTouchPoint_.SetX(locationX);
509 screenTouchPoint_.SetY(locationY);
510 if (!isMoveEventValid_) {
511 return;
512 }
513 CalculateCellCenter();
514 bool isAdd = false;
515 for (int32_t i = 0; i < PATTERN_LOCK_COL_COUNT && !isAdd; i++) {
516 for (int32_t j = 0; j < PATTERN_LOCK_COL_COUNT && !isAdd; j++) {
517 isAdd = AddChoosePoint(cellCenter_, i + 1, j + 1);
518 }
519 }
520
521 auto host = GetHost();
522 CHECK_NULL_VOID(host);
523 host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
524 }
525
AddPointEnd()526 void PatternLockPattern::AddPointEnd()
527 {
528 if (!CheckAutoReset()) {
529 return;
530 }
531 isMoveEventValid_ = false;
532 std::vector<int> chooseCellVec;
533 for (auto& it : choosePoint_) {
534 chooseCellVec.emplace_back(it.GetCode());
535 }
536 auto host = GetHost();
537 CHECK_NULL_VOID(host);
538 auto eventHub = host->GetOrCreateEventHub<PatternLockEventHub>();
539 CHECK_NULL_VOID(eventHub);
540
541 auto patternCompleteEvent = V2::PatternCompleteEvent(chooseCellVec);
542 eventHub->UpdateCompleteEvent(&patternCompleteEvent);
543 host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
544 }
545
OnTouchUp()546 void PatternLockPattern::OnTouchUp()
547 {
548 CHECK_NULL_VOID(patternLockModifier_);
549 patternLockModifier_->SetIsTouchDown(false);
550 size_t count = patternLockModifier_->GetChoosePointCount();
551 if (count < 1) {
552 return;
553 }
554 StartModifierCanceledAnimate();
555 AddPointEnd();
556 fingerId_ = -1;
557 }
558
InitFocusEvent()559 void PatternLockPattern::InitFocusEvent()
560 {
561 auto host = GetHost();
562 CHECK_NULL_VOID(host);
563 auto focusHub = host->GetOrCreateFocusHub();
564 CHECK_NULL_VOID(focusHub);
565
566 auto focusTask = [weak = WeakClaim(this)](FocusReason reason) {
567 auto pattern = weak.Upgrade();
568 CHECK_NULL_VOID(pattern);
569 pattern->HandleFocusEvent();
570 };
571 focusHub->SetOnFocusInternal(focusTask);
572 auto blurTask = [weak = WeakClaim(this)]() {
573 auto pattern = weak.Upgrade();
574 CHECK_NULL_VOID(pattern);
575 pattern->HandleBlurEvent();
576 };
577 focusHub->SetOnBlurInternal(blurTask);
578 auto keyTask = [weak = WeakClaim(this)](const KeyEvent& keyEvent) -> bool {
579 auto pattern = weak.Upgrade();
580 CHECK_NULL_RETURN(pattern, false);
581 return pattern->OnKeyEvent(keyEvent);
582 };
583 focusHub->SetOnKeyEventInternal(keyTask);
584 auto getInnerPaintRectCallback = [wp = WeakClaim(this)](RoundRect& paintRect) {
585 auto pattern = wp.Upgrade();
586 CHECK_NULL_VOID(pattern);
587 pattern->GetInnerFocusPaintRect(paintRect);
588 };
589 focusHub->SetInnerFocusPaintRectCallback(getInnerPaintRectCallback);
590 }
591
HandleFocusEvent()592 void PatternLockPattern::HandleFocusEvent()
593 {
594 HandleReset();
595 currentPoint_ = { 1, 1 };
596 isMoveEventValid_ = true;
597 }
598
HandleBlurEvent()599 void PatternLockPattern::HandleBlurEvent()
600 {
601 isMoveEventValid_ = false;
602 }
603
GetInnerFocusPaintRect(RoundRect & paintRect)604 void PatternLockPattern::GetInnerFocusPaintRect(RoundRect& paintRect)
605 {
606 auto host = GetHost();
607 CHECK_NULL_VOID(host);
608 auto pipelineContext = PipelineBase::GetCurrentContext();
609 CHECK_NULL_VOID(pipelineContext);
610 auto patternLockTheme = pipelineContext->GetTheme<V2::PatternLockTheme>();
611 CHECK_NULL_VOID(patternLockTheme);
612 auto patternLockPaintProperty = host->GetPaintProperty<PatternLockPaintProperty>();
613 CHECK_NULL_VOID(patternLockPaintProperty);
614 auto geometryNode = host->GetGeometryNode();
615 CHECK_NULL_VOID(geometryNode);
616 OffsetF contentOffset = geometryNode->GetContentOffset();
617 float sideLength = geometryNode->GetContentSize().Width();
618 float offset = sideLength / PATTERN_LOCK_COL_COUNT;
619 float circleRadius = patternLockPaintProperty->GetCircleRadius()
620 .value_or(patternLockTheme->GetCircleRadius())
621 .ConvertToPxWithSize(sideLength);
622 auto backgroundRadiusScale = patternLockTheme->GetBackgroundRadiusScale();
623 auto focusPaddingRadius = patternLockTheme->GetFocusPaddingRadius();
624 auto focusPaintWidth = patternLockTheme->GetFocusPaintWidth();
625 float foucusCircleRadius = std::min(circleRadius * backgroundRadiusScale, offset / RADIUS_TO_DIAMETER) +
626 (focusPaddingRadius).ConvertToPx() + focusPaintWidth.ConvertToPx() / RADIUS_TO_DIAMETER;
627 float outRadius = offset / RADIUS_TO_DIAMETER - foucusCircleRadius;
628 float offsetX = contentOffset.GetX() + (currentPoint_.first - 1) * offset + outRadius;
629 float offsetY = contentOffset.GetY() + (currentPoint_.second - 1) * offset + outRadius;
630
631 paintRect.SetRect(
632 { offsetX, offsetY, foucusCircleRadius * RADIUS_TO_DIAMETER, foucusCircleRadius * RADIUS_TO_DIAMETER });
633 paintRect.SetCornerRadius(RoundRect::CornerPos::TOP_LEFT_POS, foucusCircleRadius, foucusCircleRadius);
634 paintRect.SetCornerRadius(RoundRect::CornerPos::TOP_RIGHT_POS, foucusCircleRadius, foucusCircleRadius);
635 paintRect.SetCornerRadius(RoundRect::CornerPos::BOTTOM_RIGHT_POS, foucusCircleRadius, foucusCircleRadius);
636 paintRect.SetCornerRadius(RoundRect::CornerPos::BOTTOM_LEFT_POS, foucusCircleRadius, foucusCircleRadius);
637 }
638
OnFocusClick()639 void PatternLockPattern::OnFocusClick()
640 {
641 if (!CheckAutoReset()) {
642 return;
643 }
644 if (!isMoveEventValid_) {
645 HandleReset();
646 }
647 if (CheckChoosePoint(currentPoint_.first, currentPoint_.second)) {
648 return;
649 }
650
651 auto host = GetHost();
652 CHECK_NULL_VOID(host);
653 OffsetF touchPoint;
654 auto geometryNode = host->GetGeometryNode();
655 CHECK_NULL_VOID(geometryNode);
656 OffsetF contentOffset = geometryNode->GetContentOffset();
657 float sideLength = geometryNode->GetContentSize().Width();
658 float offset = sideLength / PATTERN_LOCK_COL_COUNT / RADIUS_TO_DIAMETER;
659 float offsetX = contentOffset.GetX() + offset * (currentPoint_.first * 2 - 1);
660 float offsetY = contentOffset.GetY() + offset * (currentPoint_.second * 2 - 1);
661 touchPoint.SetX(offsetX);
662 touchPoint.SetY(offsetY);
663 cellCenter_ = touchPoint;
664
665 AddPassPoint(currentPoint_.first, currentPoint_.second);
666 choosePoint_.emplace_back(currentPoint_.first, currentPoint_.second);
667 StartModifierConnectedAnimate(currentPoint_.first, currentPoint_.second);
668 UpdateDotConnectEvent();
669 isOnKeyEventState_ = true;
670
671 isMoveEventValid_ = true;
672 host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
673 }
674
PaintFocusState()675 void PatternLockPattern::PaintFocusState()
676 {
677 auto host = GetHost();
678 CHECK_NULL_VOID(host);
679 auto focusHub = host->GetFocusHub();
680 CHECK_NULL_VOID(focusHub);
681 focusHub->PaintFocusState(true);
682
683 host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
684 }
685
OnKeyDrapUp()686 void PatternLockPattern::OnKeyDrapUp()
687 {
688 if (currentPoint_.second != 1) {
689 currentPoint_ = { currentPoint_.first, currentPoint_.second - 1 };
690 PaintFocusState();
691 }
692 }
693
OnKeyDrapDown()694 void PatternLockPattern::OnKeyDrapDown()
695 {
696 if (currentPoint_.second != PATTERN_LOCK_COL_COUNT) {
697 currentPoint_ = { currentPoint_.first, currentPoint_.second + 1 };
698 PaintFocusState();
699 }
700 }
701
OnKeyDrapLeft()702 void PatternLockPattern::OnKeyDrapLeft()
703 {
704 if (currentPoint_.first != 1) {
705 currentPoint_ = { currentPoint_.first - 1, currentPoint_.second };
706 PaintFocusState();
707 }
708 }
709
OnKeyDrapRight()710 void PatternLockPattern::OnKeyDrapRight()
711 {
712 if (currentPoint_.first != PATTERN_LOCK_COL_COUNT) {
713 currentPoint_ = { currentPoint_.first + 1, currentPoint_.second };
714 PaintFocusState();
715 }
716 }
717
OnKeyEvent(const KeyEvent & event)718 bool PatternLockPattern::OnKeyEvent(const KeyEvent& event)
719 {
720 if (event.action != KeyAction::DOWN) {
721 return false;
722 }
723 switch (event.code) {
724 case KeyCode::KEY_SPACE:
725 OnFocusClick();
726 return true;
727 case KeyCode::KEY_ENTER:
728 if (isMoveEventValid_) {
729 AddPointEnd();
730 isOnKeyEventState_ = false;
731 }
732 return true;
733 case KeyCode::KEY_DPAD_UP:
734 OnKeyDrapUp();
735 return true;
736 case KeyCode::KEY_DPAD_DOWN:
737 OnKeyDrapDown();
738 return true;
739 case KeyCode::KEY_DPAD_LEFT:
740 OnKeyDrapLeft();
741 return true;
742 case KeyCode::KEY_DPAD_RIGHT:
743 OnKeyDrapRight();
744 return true;
745 case KeyCode::KEY_MOVE_HOME:
746 currentPoint_ = { 1, 1 };
747 PaintFocusState();
748 return true;
749 case KeyCode::KEY_MOVE_END:
750 currentPoint_ = { PATTERN_LOCK_COL_COUNT, PATTERN_LOCK_COL_COUNT };
751 PaintFocusState();
752 return true;
753 case KeyCode::KEY_ESCAPE:
754 HandleReset();
755 return true;
756 default:
757 break;
758 }
759 return false;
760 }
761
InitMouseEvent()762 void PatternLockPattern::InitMouseEvent()
763 {
764 auto host = GetHost();
765 CHECK_NULL_VOID(host);
766 auto eventHub = host->GetOrCreateEventHub<EventHub>();
767 CHECK_NULL_VOID(eventHub);
768 auto inputEventHub = eventHub->GetOrCreateInputEventHub();
769 CHECK_NULL_VOID(inputEventHub);
770 auto hoverTask = [weak = WeakClaim(this)](bool isHover) {
771 auto pattern = weak.Upgrade();
772 CHECK_NULL_VOID(pattern);
773 pattern->HandleHoverEvent(isHover);
774 };
775 auto hoverEvent = MakeRefPtr<InputEvent>(std::move(hoverTask));
776 CHECK_NULL_VOID(hoverEvent);
777 inputEventHub->AddOnHoverEvent(hoverEvent);
778
779 auto mouseTask = [weak = WeakClaim(this)](MouseInfo& info) {
780 auto pattern = weak.Upgrade();
781 CHECK_NULL_VOID(pattern);
782 pattern->HandleMouseEvent(info);
783 };
784 auto mouseEvent_ = MakeRefPtr<InputEvent>(std::move(mouseTask));
785 inputEventHub->AddOnMouseEvent(mouseEvent_);
786 }
787
HandleHoverEvent(bool isHover)788 void PatternLockPattern::HandleHoverEvent(bool isHover)
789 {
790 CHECK_NULL_VOID(patternLockModifier_);
791 patternLockModifier_->SetIsHover(isHover);
792 }
793
HandleMouseEvent(const MouseInfo & info)794 void PatternLockPattern::HandleMouseEvent(const MouseInfo& info)
795 {
796 OffsetF hoverPoint;
797 hoverPoint.SetX(info.GetLocalLocation().GetX());
798 hoverPoint.SetY(info.GetLocalLocation().GetY());
799 cellCenter_ = hoverPoint;
800 bool isPointHover = false;
801 for (int32_t i = 0; i < PATTERN_LOCK_COL_COUNT; i++) {
802 for (int32_t j = 0; j < PATTERN_LOCK_COL_COUNT; j++) {
803 if (CheckInHotSpot(hoverPoint, i + 1, j + 1)) {
804 CHECK_NULL_VOID(patternLockModifier_);
805 patternLockModifier_->SetHoverIndex(i * PATTERN_LOCK_COL_COUNT + j);
806 isPointHover = true;
807 break;
808 }
809 }
810 }
811 if (!isPointHover) {
812 patternLockModifier_->SetHoverIndex(-1);
813 }
814 }
815
StartModifierConnectedAnimate(int32_t x,int32_t y)816 void PatternLockPattern::StartModifierConnectedAnimate(int32_t x, int32_t y)
817 {
818 CHECK_NULL_VOID(patternLockModifier_);
819 patternLockModifier_->StartConnectedCircleAnimate(x, y);
820 patternLockModifier_->StartConnectedLineAnimate(x, y);
821 }
822
StartModifierAddPassPointAnimate(int32_t x,int32_t y)823 void PatternLockPattern::StartModifierAddPassPointAnimate(int32_t x, int32_t y)
824 {
825 CHECK_NULL_VOID(patternLockModifier_);
826 patternLockModifier_->StartConnectedCircleAnimate(x, y);
827 }
828
StartModifierCanceledAnimate()829 void PatternLockPattern::StartModifierCanceledAnimate()
830 {
831 CHECK_NULL_VOID(patternLockModifier_);
832 if (isMoveEventValid_) {
833 patternLockModifier_->StartCanceledAnimate();
834 }
835 }
836
GetLastChoosePointOffset()837 OffsetF PatternLockPattern::GetLastChoosePointOffset()
838 {
839 OffsetF cellCenter;
840 auto host = GetHost();
841 CHECK_NULL_RETURN(host, cellCenter);
842 auto geometryNode = host->GetGeometryNode();
843 CHECK_NULL_RETURN(geometryNode, cellCenter);
844 float sideLength = geometryNode->GetContentSize().Width();
845 auto offset = geometryNode->GetContentOffset();
846 auto lastPoint = choosePoint_.back();
847 cellCenter.SetX(offset.GetX() + sideLength / PATTERN_LOCK_COL_COUNT / RADIUS_TO_DIAMETER *
848 (lastPoint.GetColumn() * RADIUS_TO_DIAMETER - 1));
849 cellCenter.SetY(offset.GetY() + sideLength / PATTERN_LOCK_COL_COUNT / RADIUS_TO_DIAMETER *
850 (lastPoint.GetRow() * RADIUS_TO_DIAMETER - 1));
851 return cellCenter;
852 }
853
CalculateCellCenter()854 void PatternLockPattern::CalculateCellCenter()
855 {
856 if (isOnKeyEventState_) {
857 size_t count = choosePoint_.size();
858 if (count < 1) {
859 return;
860 }
861 cellCenter_ = GetLastChoosePointOffset();
862 } else {
863 cellCenter_ = screenTouchPoint_;
864 }
865 }
866
GetTouchOffsetToNode()867 OffsetF PatternLockPattern::GetTouchOffsetToNode()
868 {
869 auto host = GetHost();
870 CHECK_NULL_RETURN(host, OffsetF());
871 auto pipelineContext = PipelineBase::GetCurrentContext();
872 CHECK_NULL_RETURN(pipelineContext, OffsetF());
873 auto windowOffset = pipelineContext->GetCurrentWindowRect().GetOffset();
874 OffsetF nodeOffset = host->GetPositionToWindowWithTransform();
875 auto container = Container::CurrentSafely();
876 auto windowScale = container->GetWindowScale();
877 nodeOffset = nodeOffset * windowScale;
878 OffsetF offset(windowOffset.GetX() + nodeOffset.GetX(), windowOffset.GetY() + nodeOffset.GetY());
879 offset = screenTouchPoint_ - offset;
880 if (windowScale != 0) {
881 offset = offset / windowScale;
882 }
883 return offset;
884 }
885
InitSkipUnselectedPoint()886 void PatternLockPattern::InitSkipUnselectedPoint()
887 {
888 auto host = GetHost();
889 CHECK_NULL_VOID(host);
890 auto patternLockPaintProperty = host->GetPaintProperty<PatternLockPaintProperty>();
891 CHECK_NULL_VOID(patternLockPaintProperty);
892 if (patternLockPaintProperty->HasSkipUnselectedPoint()) {
893 skipUnselectedPoint_ = patternLockPaintProperty->GetSkipUnselectedPointValue();
894 }
895 }
896
UpdateSelectedColor(const Color & color,bool isFristLoad)897 void PatternLockPattern::UpdateSelectedColor(const Color& color, bool isFristLoad)
898 {
899 auto host = GetHost();
900 CHECK_NULL_VOID(host);
901 auto pipelineContext = host->GetContext();
902 CHECK_NULL_VOID(pipelineContext);
903 auto paintProperty = host->GetPaintProperty<PatternLockPaintProperty>();
904 CHECK_NULL_VOID(paintProperty);
905 if (pipelineContext->IsSystmColorChange() || isFristLoad) {
906 paintProperty->UpdateSelectedColor(color);
907 }
908 if (host->GetRerenderable()) {
909 host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
910 }
911 }
912
UpdatePathColor(const Color & color,bool isFristLoad)913 void PatternLockPattern::UpdatePathColor(const Color& color, bool isFristLoad)
914 {
915 auto host = GetHost();
916 CHECK_NULL_VOID(host);
917 auto pipelineContext = host->GetContext();
918 CHECK_NULL_VOID(pipelineContext);
919 auto paintProperty = host->GetPaintProperty<PatternLockPaintProperty>();
920 CHECK_NULL_VOID(paintProperty);
921 if (pipelineContext->IsSystmColorChange() || isFristLoad) {
922 paintProperty->UpdatePathColor(color);
923 }
924 if (host->GetRerenderable()) {
925 host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
926 }
927 }
928
UpdateActiveColor(const Color & color,bool isFristLoad)929 void PatternLockPattern::UpdateActiveColor(const Color& color, bool isFristLoad)
930 {
931 auto host = GetHost();
932 CHECK_NULL_VOID(host);
933 auto pipelineContext = host->GetContext();
934 CHECK_NULL_VOID(pipelineContext);
935 auto paintProperty = host->GetPaintProperty<PatternLockPaintProperty>();
936 CHECK_NULL_VOID(paintProperty);
937 if (pipelineContext->IsSystmColorChange() || isFristLoad) {
938 paintProperty->UpdateActiveColor(color);
939 }
940 if (host->GetRerenderable()) {
941 host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
942 }
943 }
944
UpdateRegularColor(const Color & color,bool isFristLoad)945 void PatternLockPattern::UpdateRegularColor(const Color& color, bool isFristLoad)
946 {
947 auto host = GetHost();
948 CHECK_NULL_VOID(host);
949 auto pipelineContext = host->GetContext();
950 CHECK_NULL_VOID(pipelineContext);
951 auto paintProperty = host->GetPaintProperty<PatternLockPaintProperty>();
952 CHECK_NULL_VOID(paintProperty);
953 if (pipelineContext->IsSystmColorChange() || isFristLoad) {
954 paintProperty->UpdateRegularColor(color);
955 }
956 if (host->GetRerenderable()) {
957 host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
958 }
959 }
960
UpdateCircleRadius(const CalcDimension & radius,bool isFristLoad)961 void PatternLockPattern::UpdateCircleRadius(const CalcDimension& radius, bool isFristLoad)
962 {
963 auto host = GetHost();
964 CHECK_NULL_VOID(host);
965 auto pipelineContext = host->GetContext();
966 CHECK_NULL_VOID(pipelineContext);
967 auto paintProperty = host->GetPaintProperty<PatternLockPaintProperty>();
968 CHECK_NULL_VOID(paintProperty);
969 if (pipelineContext->IsSystmColorChange() || isFristLoad) {
970 paintProperty->UpdateCircleRadius(radius);
971 }
972 if (host->GetRerenderable()) {
973 host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
974 }
975 }
976
UpdateSideLength(const CalcDimension & sideLength,bool isFristLoad)977 void PatternLockPattern::UpdateSideLength(const CalcDimension& sideLength, bool isFristLoad)
978 {
979 auto host = GetHost();
980 CHECK_NULL_VOID(host);
981 auto pipelineContext = host->GetContext();
982 CHECK_NULL_VOID(pipelineContext);
983 auto layoutProperty = host->GetLayoutProperty<PatternLockLayoutProperty>();
984 CHECK_NULL_VOID(layoutProperty);
985 if (pipelineContext->IsSystmColorChange() || isFristLoad) {
986 layoutProperty->UpdateSideLength(sideLength);
987 }
988 if (host->GetRerenderable()) {
989 host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
990 }
991 }
992
UpdateActiveCircleColor(const Color & color,bool isFristLoad)993 void PatternLockPattern::UpdateActiveCircleColor(const Color& color, bool isFristLoad)
994 {
995 auto host = GetHost();
996 CHECK_NULL_VOID(host);
997 auto pipelineContext = host->GetContext();
998 CHECK_NULL_VOID(pipelineContext);
999 auto paintProperty = host->GetPaintProperty<PatternLockPaintProperty>();
1000 CHECK_NULL_VOID(paintProperty);
1001 if (pipelineContext->IsSystmColorChange() || isFristLoad) {
1002 paintProperty->UpdateActiveCircleColor(color);
1003 }
1004 if (host->GetRerenderable()) {
1005 host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
1006 }
1007 }
OnColorConfigurationUpdate()1008 void PatternLockPattern::OnColorConfigurationUpdate()
1009 {
1010 if (!SystemProperties::ConfigChangePerform()) {
1011 return;
1012 }
1013 auto host = GetHost();
1014 CHECK_NULL_VOID(host);
1015 auto pipeline = host->GetContext();
1016 CHECK_NULL_VOID(pipeline);
1017 auto theme = pipeline->GetTheme<V2::PatternLockTheme>();
1018 CHECK_NULL_VOID(theme);
1019 auto pops = host->GetPaintProperty<PatternLockPaintProperty>();
1020 CHECK_NULL_VOID(pops);
1021 if (!pops->HasPathColorSetByUser() || (pops->HasPathColorSetByUser() && !pops->GetPathColorSetByUserValue())) {
1022 pops->UpdatePathColor(theme->GetPathColor());
1023 }
1024 if (!pops->HasRegularColorSetByUser() ||
1025 (pops->HasRegularColorSetByUser() && !pops->GetRegularColorSetByUserValue())) {
1026 pops->UpdateRegularColor(theme->GetRegularColor());
1027 }
1028 if (!pops->HasActiveColorSetByUser() ||
1029 (pops->HasActiveColorSetByUser() && !pops->GetActiveColorSetByUserValue())) {
1030 pops->UpdateActiveColor(theme->GetActiveColor());
1031 }
1032 if (!pops->HasSelectedColorSetByUser() ||
1033 (pops->HasSelectedColorSetByUser() && !pops->GetSelectedColorSetByUserValue())) {
1034 UpdateSelectedColor(theme->GetSelectedColor());
1035 }
1036 if (!pops->HasActiveCircleColorSetByUser() ||
1037 (pops->HasActiveCircleColorSetByUser() && !pops->GetActiveCircleColorSetByUserValue())) {
1038 UpdateActiveCircleColor(Color::TRANSPARENT);
1039 }
1040 }
1041 } // namespace OHOS::Ace::NG
1042