• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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