• 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 "core/components_ng/pattern/patternlock/patternlock_pattern.h"
17 
18 #include "core/components/test/unittest/image/image_test_utils.h"
19 #include "core/components_ng/pattern/patternlock/patternlock_paint_property.h"
20 #include "core/components_ng/pattern/stage/page_event_hub.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     InitPanEvent(gestureHub);
52     InitPatternLockController();
53     InitFocusEvent();
54     InitMouseEvent();
55 }
56 
InitTouchEvent(RefPtr<GestureEventHub> & gestureHub,RefPtr<TouchEventImpl> & touchDownListener)57 void PatternLockPattern::InitTouchEvent(RefPtr<GestureEventHub>& gestureHub, RefPtr<TouchEventImpl>& touchDownListener)
58 {
59     if (touchDownListener) {
60         return;
61     }
62     auto touchDownTask = [weak = WeakClaim(this)](const TouchEventInfo& info) {
63         auto pattern = weak.Upgrade();
64         CHECK_NULL_VOID(pattern);
65         pattern->HandleTouchEvent(info);
66     };
67     touchDownListener = MakeRefPtr<TouchEventImpl>(std::move(touchDownTask));
68     gestureHub->AddTouchEvent(touchDownListener);
69 }
70 
SetChallengeResult(V2::PatternLockChallengeResult challengeResult)71 void PatternLockPattern::SetChallengeResult(V2::PatternLockChallengeResult challengeResult)
72 {
73     if (!isMoveEventValid_) {
74         CHECK_NULL_VOID(patternLockModifier_);
75         std::optional<NG::PatternLockChallengeResult> ngChallengeResult;
76         if (challengeResult == V2::PatternLockChallengeResult::CORRECT) {
77             ngChallengeResult = NG::PatternLockChallengeResult::CORRECT;
78         } else if (challengeResult == V2::PatternLockChallengeResult::WRONG) {
79             ngChallengeResult = NG::PatternLockChallengeResult::WRONG;
80         }
81         patternLockModifier_->SetChallengeResult(ngChallengeResult);
82     }
83 }
84 
InitPatternLockController()85 void PatternLockPattern::InitPatternLockController()
86 {
87     patternLockController_->SetResetImpl([weak = WeakClaim(this)]() {
88         auto patternLock = weak.Upgrade();
89         CHECK_NULL_VOID(patternLock);
90         patternLock->HandleReset();
91     });
92     patternLockController_->SetChallengeResultImpl(
93         [weak = WeakClaim(this)](V2::PatternLockChallengeResult challengeResult) {
94             auto patternLock = weak.Upgrade();
95             CHECK_NULL_VOID(patternLock);
96             patternLock->SetChallengeResult(challengeResult);
97         });
98 }
99 
HandleTouchEvent(const TouchEventInfo & info)100 void PatternLockPattern::HandleTouchEvent(const TouchEventInfo& info)
101 {
102     auto touchType = info.GetTouches().front().GetTouchType();
103     if (touchType == TouchType::DOWN) {
104         OnTouchDown(info);
105     } else if (touchType == TouchType::UP) {
106         OnTouchUp();
107     }
108 }
109 
CheckInHotSpot(const OffsetF & offset,int32_t x,int32_t y)110 bool PatternLockPattern::CheckInHotSpot(const OffsetF& offset, int32_t x, int32_t y)
111 {
112     auto host = GetHost();
113     CHECK_NULL_RETURN(host, false);
114     auto patternLockPaintProperty = host->GetPaintProperty<PatternLockPaintProperty>();
115     float sideLength = host->GetGeometryNode()->GetContentSize().Width();
116     OffsetF contentOffset = host->GetGeometryNode()->GetContentOffset();
117     auto pipelineContext = PipelineBase::GetCurrentContext();
118     CHECK_NULL_RETURN(pipelineContext, false);
119     auto patternLockTheme = pipelineContext->GetTheme<V2::PatternLockTheme>();
120     CHECK_NULL_RETURN(patternLockTheme, false);
121     circleRadius_ = patternLockTheme->GetCircleRadius();
122     if (patternLockPaintProperty->HasCircleRadius()) {
123         circleRadius_ = patternLockPaintProperty->GetCircleRadiusValue();
124     }
125     auto backgroundRadiusScale = patternLockTheme->GetBackgroundRadiusScale();
126     if (NearZero(backgroundRadiusScale)) {
127         return false;
128     }
129     auto activeCircleRadiusScale = patternLockTheme->GetActiveCircleRadiusScale();
130     auto handleCircleRadius = std::min(static_cast<float>(circleRadius_.ConvertToPxWithSize(sideLength)),
131         sideLength / backgroundRadiusScale / RADIUS_COUNT);
132     auto hotSpotCircleRadius = patternLockTheme->GetHotSpotCircleRadius();
133     handleCircleRadius = std::max(handleCircleRadius * activeCircleRadiusScale,
134         std::min(
135             static_cast<float>(hotSpotCircleRadius.ConvertToPx()) / RADIUS_TO_DIAMETER, sideLength / RADIUS_COUNT));
136     const int32_t scale = RADIUS_TO_DIAMETER;
137     float offsetX = sideLength / PATTERN_LOCK_COL_COUNT / scale * (scale * x - 1);
138     float offsetY = sideLength / PATTERN_LOCK_COL_COUNT / scale * (scale * y - 1);
139     offsetX += contentOffset.GetX();
140     offsetY += contentOffset.GetY();
141     OffsetF centerOffset;
142     centerOffset.SetX(offsetX);
143     centerOffset.SetY(offsetY);
144     auto X = (offset - centerOffset).GetX();
145     auto Y = (offset - centerOffset).GetY();
146     float distance = std::sqrt((X * X) + (Y * Y));
147     return LessOrEqual(distance, handleCircleRadius);
148 }
149 
AddChoosePoint(const OffsetF & offset,int32_t x,int32_t y)150 bool PatternLockPattern::AddChoosePoint(const OffsetF& offset, int32_t x, int32_t y)
151 {
152     if (CheckInHotSpot(offset, x, y)) {
153         if (!CheckChoosePoint(x, y)) {
154             AddPassPoint(x, y);
155             choosePoint_.emplace_back(x, y);
156             StartModifierConnectedAnimate(x, y);
157             auto host = GetHost();
158             CHECK_NULL_RETURN(host, false);
159             auto eventHub = host->GetEventHub<PatternLockEventHub>();
160             CHECK_NULL_RETURN(eventHub, false);
161             eventHub->UpdateDotConnectedEvent(choosePoint_.back().GetCode());
162         }
163         return true;
164     }
165     return false;
166 }
167 
CheckChoosePoint(int32_t x,int32_t y) const168 bool PatternLockPattern::CheckChoosePoint(int32_t x, int32_t y) const
169 {
170     for (auto it : choosePoint_) {
171         if (it.GetColumn() == x && it.GetRow() == y) {
172             return true;
173         }
174     }
175     return false;
176 }
177 
AddPassPoint(int32_t x,int32_t y)178 void PatternLockPattern::AddPassPoint(int32_t x, int32_t y)
179 {
180     if (choosePoint_.empty()) {
181         return;
182     }
183     passPointCount_ = 0;
184     PatternLockCell lastCell = choosePoint_.back();
185     int32_t lastX = lastCell.GetColumn();
186     int32_t lastY = lastCell.GetRow();
187     int32_t lastCode = lastCell.GetCode();
188     int32_t nowCode = PATTERN_LOCK_COL_COUNT * (y - 1) + (x - 1);
189     std::vector<PatternLockCell> passPointVec;
190     for (int32_t i = 1; i <= PATTERN_LOCK_COL_COUNT; i++) {
191         for (int32_t j = 1; j <= PATTERN_LOCK_COL_COUNT; j++) {
192             PatternLockCell passPoint = PatternLockCell(i, j);
193             if ((passPoint.GetCode() >= nowCode && passPoint.GetCode() >= lastCode) ||
194                 (passPoint.GetCode() <= nowCode && passPoint.GetCode() <= lastCode)) {
195                 continue;
196             }
197             if ((j != y) && (j != lastY) &&
198                 (NearEqual(static_cast<float>(lastX - i) / (lastY - j), static_cast<float>(i - x) / (j - y)) &&
199                     !CheckChoosePoint(i, j))) {
200                 passPointVec.emplace_back(passPoint);
201             }
202             if ((j == lastY) && (j == y) && !CheckChoosePoint(i, j)) {
203                 passPointVec.emplace_back(passPoint);
204             }
205         }
206     }
207     size_t passPointLength = passPointVec.size();
208     if (passPointLength == 0) {
209         return;
210     }
211     passPointCount_ = static_cast<int32_t>(passPointLength);
212     if (nowCode > lastCode) {
213         choosePoint_.emplace_back(passPointVec.front());
214         StartModifierAddPassPointAnimate(passPointVec.front().GetColumn(), passPointVec.front().GetRow());
215         if (passPointLength > 1) {
216             choosePoint_.emplace_back(passPointVec.back());
217             StartModifierAddPassPointAnimate(passPointVec.back().GetColumn(), passPointVec.back().GetRow());
218         }
219     } else {
220         choosePoint_.emplace_back(passPointVec.back());
221         StartModifierAddPassPointAnimate(passPointVec.back().GetColumn(), passPointVec.back().GetRow());
222         if (passPointLength > 1) {
223             choosePoint_.emplace_back(passPointVec.front());
224             StartModifierAddPassPointAnimate(passPointVec.front().GetColumn(), passPointVec.front().GetRow());
225         }
226     }
227 }
228 
HandleReset()229 void PatternLockPattern::HandleReset()
230 {
231     isMoveEventValid_ = false;
232     choosePoint_.clear();
233     cellCenter_.Reset();
234     if (patternLockModifier_) {
235         patternLockModifier_->Reset();
236     }
237     auto host = GetHost();
238     CHECK_NULL_VOID(host);
239     host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
240 }
241 
CheckAutoReset() const242 bool PatternLockPattern::CheckAutoReset() const
243 {
244     auto host = GetHost();
245     CHECK_NULL_RETURN(host, false);
246     auto patternLockPaintProperty = host->GetPaintProperty<PatternLockPaintProperty>();
247     if (patternLockPaintProperty->HasAutoReset()) {
248         autoReset_ = patternLockPaintProperty->GetAutoResetValue();
249     }
250     return !(!autoReset_ && !choosePoint_.empty() && !isMoveEventValid_);
251 }
252 
OnTouchDown(const TouchEventInfo & info)253 void PatternLockPattern::OnTouchDown(const TouchEventInfo& info)
254 {
255     const auto& locationInfo = info.GetTouches().front();
256     float moveDeltaX = locationInfo.GetLocalLocation().GetX();
257     float moveDeltaY = locationInfo.GetLocalLocation().GetY();
258     OffsetF touchPoint;
259     touchPoint.SetX(moveDeltaX);
260     touchPoint.SetY(moveDeltaY);
261 
262     if (!CheckAutoReset()) {
263         return;
264     }
265     HandleReset();
266     cellCenter_ = touchPoint;
267     bool isAdd = false;
268     for (int32_t i = 0; i < PATTERN_LOCK_COL_COUNT && !isAdd; i++) {
269         for (int32_t j = 0; j < PATTERN_LOCK_COL_COUNT && !isAdd; j++) {
270             isAdd = AddChoosePoint(touchPoint, i + 1, j + 1);
271         }
272     }
273 
274     if (patternLockModifier_) {
275         patternLockModifier_->SetIsTouchDown(true);
276     }
277     auto host = GetHost();
278     CHECK_NULL_VOID(host);
279     host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
280     isMoveEventValid_ = true;
281 }
282 
HandleGestureUpdate(const GestureEvent & info)283 void PatternLockPattern::HandleGestureUpdate(const GestureEvent& info)
284 {
285     if (info.GetInputEventType() == InputEventType::AXIS) {
286         return;
287     }
288     auto moveDeltaX = static_cast<float>(info.GetLocalLocation().GetX());
289     auto moveDeltaY = static_cast<float>(info.GetLocalLocation().GetY());
290     OffsetF touchPoint;
291     touchPoint.SetX(moveDeltaX);
292     touchPoint.SetY(moveDeltaY);
293 
294     if (!isMoveEventValid_) {
295         return;
296     }
297     cellCenter_ = touchPoint;
298     bool isAdd = false;
299     for (int32_t i = 0; i < PATTERN_LOCK_COL_COUNT && !isAdd; i++) {
300         for (int32_t j = 0; j < PATTERN_LOCK_COL_COUNT && !isAdd; j++) {
301             isAdd = AddChoosePoint(touchPoint, i + 1, j + 1);
302         }
303     }
304 
305     auto host = GetHost();
306     CHECK_NULL_VOID(host);
307     host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
308 }
309 
InitPanEvent(const RefPtr<GestureEventHub> & gestureHub)310 void PatternLockPattern::InitPanEvent(const RefPtr<GestureEventHub>& gestureHub)
311 {
312     auto actionStartTask = [weak = WeakClaim(this)](const GestureEvent& /* info */) { LOGD("Pan event start"); };
313 
314     auto actionUpdateTask = [weak = WeakClaim(this)](const GestureEvent& info) {
315         auto pattern = weak.Upgrade();
316         CHECK_NULL_VOID(pattern);
317         pattern->HandleGestureUpdate(info);
318     };
319 
320     auto actionEndTask = [weak = WeakClaim(this)](const GestureEvent& /* info */) { LOGD("Pan event End"); };
321 
322     auto actionCancelTask = [weak = WeakClaim(this)]() { LOGD("Pan event cancel"); };
323     if (panEvent_) {
324         gestureHub->RemovePanEvent(panEvent_);
325     }
326 
327     PanDirection panDirection;
328     panDirection.type = PanDirection::ALL;
329     panEvent_ = MakeRefPtr<PanEvent>(
330         std::move(actionStartTask), std::move(actionUpdateTask), std::move(actionEndTask), std::move(actionCancelTask));
331     gestureHub->AddPanEvent(panEvent_, panDirection, 1, DEFAULT_PAN_DISTANCE);
332 }
333 
AddPointEnd()334 void PatternLockPattern::AddPointEnd()
335 {
336     if (!CheckAutoReset()) {
337         return;
338     }
339     isMoveEventValid_ = false;
340     std::vector<int> chooseCellVec;
341     for (auto& it : choosePoint_) {
342         chooseCellVec.emplace_back(it.GetCode());
343     }
344     auto host = GetHost();
345     CHECK_NULL_VOID(host);
346     auto eventHub = host->GetEventHub<PatternLockEventHub>();
347     CHECK_NULL_VOID(eventHub);
348 
349     auto patternCompleteEvent = V2::PatternCompleteEvent(chooseCellVec);
350     eventHub->UpdateCompleteEvent(&patternCompleteEvent);
351     host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
352 }
353 
OnTouchUp()354 void PatternLockPattern::OnTouchUp()
355 {
356     CHECK_NULL_VOID(patternLockModifier_);
357     patternLockModifier_->SetIsTouchDown(false);
358     StartModifierCanceledAnimate();
359     AddPointEnd();
360 }
361 
InitFocusEvent()362 void PatternLockPattern::InitFocusEvent()
363 {
364     auto host = GetHost();
365     CHECK_NULL_VOID(host);
366     auto focusHub = host->GetOrCreateFocusHub();
367     CHECK_NULL_VOID(focusHub);
368 
369     auto focusTask = [weak = WeakClaim(this)]() {
370         auto pattern = weak.Upgrade();
371         CHECK_NULL_VOID_NOLOG(pattern);
372         pattern->HandleFocusEvent();
373     };
374     focusHub->SetOnFocusInternal(focusTask);
375     auto blurTask = [weak = WeakClaim(this)]() {
376         auto pattern = weak.Upgrade();
377         CHECK_NULL_VOID_NOLOG(pattern);
378         pattern->HandleBlurEvent();
379     };
380     focusHub->SetOnBlurInternal(blurTask);
381     auto keyTask = [weak = WeakClaim(this)](const KeyEvent& keyEvent) -> bool {
382         auto pattern = weak.Upgrade();
383         CHECK_NULL_RETURN(pattern, false);
384         return pattern->OnKeyEvent(keyEvent);
385     };
386     focusHub->SetOnKeyEventInternal(keyTask);
387     auto getInnerPaintRectCallback = [wp = WeakClaim(this)](RoundRect& paintRect) {
388         auto pattern = wp.Upgrade();
389         CHECK_NULL_VOID_NOLOG(pattern);
390         pattern->GetInnerFocusPaintRect(paintRect);
391     };
392     focusHub->SetInnerFocusPaintRectCallback(getInnerPaintRectCallback);
393 }
394 
HandleFocusEvent()395 void PatternLockPattern::HandleFocusEvent()
396 {
397     HandleReset();
398     currentPoint_ = { 1, 1 };
399     isMoveEventValid_ = true;
400 }
401 
HandleBlurEvent()402 void PatternLockPattern::HandleBlurEvent()
403 {
404     isMoveEventValid_ = false;
405 }
406 
GetInnerFocusPaintRect(RoundRect & paintRect)407 void PatternLockPattern::GetInnerFocusPaintRect(RoundRect& paintRect)
408 {
409     auto host = GetHost();
410     CHECK_NULL_VOID(host);
411     auto pipelineContext = PipelineBase::GetCurrentContext();
412     CHECK_NULL_VOID(pipelineContext);
413     auto patternLockTheme = pipelineContext->GetTheme<V2::PatternLockTheme>();
414     CHECK_NULL_VOID(patternLockTheme);
415     auto patternLockPaintProperty = host->GetPaintProperty<PatternLockPaintProperty>();
416     CHECK_NULL_VOID(patternLockPaintProperty);
417     auto geometryNode = host->GetGeometryNode();
418     CHECK_NULL_VOID(geometryNode);
419     OffsetF contentOffset = geometryNode->GetContentOffset();
420     float sideLength = geometryNode->GetContentSize().Width();
421     float offset = sideLength / PATTERN_LOCK_COL_COUNT;
422     float circleRadius = patternLockPaintProperty->GetCircleRadius()
423                              .value_or(patternLockTheme->GetCircleRadius())
424                              .ConvertToPxWithSize(sideLength);
425     auto backgroundRadiusScale = patternLockTheme->GetBackgroundRadiusScale();
426     auto focusPaddingRadius = patternLockTheme->GetFocusPaddingRadius();
427     auto focusPaintWidth = patternLockTheme->GetFocusPaintWidth();
428     float foucusCircleRadius = std::min(circleRadius * backgroundRadiusScale, offset / RADIUS_TO_DIAMETER) +
429                                (focusPaddingRadius).ConvertToPx() + focusPaintWidth.ConvertToPx() / RADIUS_TO_DIAMETER;
430     float outRadius = offset / RADIUS_TO_DIAMETER - foucusCircleRadius;
431     float offsetX = contentOffset.GetX() + (currentPoint_.first - 1) * offset + outRadius;
432     float offsetY = contentOffset.GetY() + (currentPoint_.second - 1) * offset + outRadius;
433 
434     paintRect.SetRect(
435         { offsetX, offsetY, foucusCircleRadius * RADIUS_TO_DIAMETER, foucusCircleRadius * RADIUS_TO_DIAMETER });
436     paintRect.SetCornerRadius(RoundRect::CornerPos::TOP_LEFT_POS, foucusCircleRadius, foucusCircleRadius);
437     paintRect.SetCornerRadius(RoundRect::CornerPos::TOP_RIGHT_POS, foucusCircleRadius, foucusCircleRadius);
438     paintRect.SetCornerRadius(RoundRect::CornerPos::BOTTOM_RIGHT_POS, foucusCircleRadius, foucusCircleRadius);
439     paintRect.SetCornerRadius(RoundRect::CornerPos::BOTTOM_LEFT_POS, foucusCircleRadius, foucusCircleRadius);
440 }
441 
OnFocusClick()442 void PatternLockPattern::OnFocusClick()
443 {
444     if (!CheckAutoReset()) {
445         return;
446     }
447     if (!isMoveEventValid_) {
448         HandleReset();
449     }
450     if (CheckChoosePoint(currentPoint_.first, currentPoint_.second)) {
451         return;
452     }
453 
454     auto host = GetHost();
455     CHECK_NULL_VOID(host);
456     OffsetF touchPoint;
457     auto geometryNode = host->GetGeometryNode();
458     CHECK_NULL_VOID(geometryNode);
459     OffsetF contentOffset = geometryNode->GetContentOffset();
460     float sideLength = geometryNode->GetContentSize().Width();
461     float offset = sideLength / PATTERN_LOCK_COL_COUNT / RADIUS_TO_DIAMETER;
462     float offsetX = contentOffset.GetX() + offset * (currentPoint_.first * 2 - 1);
463     float offsetY = contentOffset.GetY() + offset * (currentPoint_.second * 2 - 1);
464     touchPoint.SetX(offsetX);
465     touchPoint.SetY(offsetY);
466     cellCenter_ = touchPoint;
467 
468     AddPassPoint(currentPoint_.first, currentPoint_.second);
469     choosePoint_.emplace_back(currentPoint_.first, currentPoint_.second);
470     StartModifierConnectedAnimate(currentPoint_.first, currentPoint_.second);
471     auto eventHub = host->GetEventHub<PatternLockEventHub>();
472     CHECK_NULL_VOID(eventHub);
473     eventHub->UpdateDotConnectedEvent(choosePoint_.back().GetCode());
474     isMoveEventValid_ = true;
475     host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
476 }
477 
PaintFocusState()478 void PatternLockPattern::PaintFocusState()
479 {
480     auto host = GetHost();
481     CHECK_NULL_VOID(host);
482     auto focusHub = host->GetFocusHub();
483     CHECK_NULL_VOID(focusHub);
484     focusHub->PaintFocusState(true);
485 
486     host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
487 }
488 
OnKeyDrapUp()489 void PatternLockPattern::OnKeyDrapUp()
490 {
491     if (currentPoint_.second != 1) {
492         currentPoint_ = { currentPoint_.first, currentPoint_.second - 1 };
493         PaintFocusState();
494     }
495 }
496 
OnKeyDrapDown()497 void PatternLockPattern::OnKeyDrapDown()
498 {
499     if (currentPoint_.second != PATTERN_LOCK_COL_COUNT) {
500         currentPoint_ = { currentPoint_.first, currentPoint_.second + 1 };
501         PaintFocusState();
502     }
503 }
504 
OnKeyDrapLeft()505 void PatternLockPattern::OnKeyDrapLeft()
506 {
507     if (currentPoint_.first != 1) {
508         currentPoint_ = { currentPoint_.first - 1, currentPoint_.second };
509         PaintFocusState();
510     }
511 }
512 
OnKeyDrapRight()513 void PatternLockPattern::OnKeyDrapRight()
514 {
515     if (currentPoint_.first != PATTERN_LOCK_COL_COUNT) {
516         currentPoint_ = { currentPoint_.first + 1, currentPoint_.second };
517         PaintFocusState();
518     }
519 }
520 
OnKeyEvent(const KeyEvent & event)521 bool PatternLockPattern::OnKeyEvent(const KeyEvent& event)
522 {
523     if (event.action != KeyAction::DOWN) {
524         return false;
525     }
526     switch (event.code) {
527         case KeyCode::KEY_SPACE:
528             OnFocusClick();
529             return true;
530         case KeyCode::KEY_ENTER:
531             if (isMoveEventValid_) {
532                 AddPointEnd();
533             }
534             return true;
535         case KeyCode::KEY_DPAD_UP:
536             OnKeyDrapUp();
537             return true;
538         case KeyCode::KEY_DPAD_DOWN:
539             OnKeyDrapDown();
540             return true;
541         case KeyCode::KEY_DPAD_LEFT:
542             OnKeyDrapLeft();
543             return true;
544         case KeyCode::KEY_DPAD_RIGHT:
545             OnKeyDrapRight();
546             return true;
547         case KeyCode::KEY_MOVE_HOME:
548             currentPoint_ = { 1, 1 };
549             PaintFocusState();
550             return true;
551         case KeyCode::KEY_MOVE_END:
552             currentPoint_ = { PATTERN_LOCK_COL_COUNT, PATTERN_LOCK_COL_COUNT };
553             PaintFocusState();
554             return true;
555         case KeyCode::KEY_ESCAPE:
556             HandleReset();
557             return true;
558         default:
559             break;
560     }
561     return false;
562 }
563 
InitMouseEvent()564 void PatternLockPattern::InitMouseEvent()
565 {
566     auto host = GetHost();
567     CHECK_NULL_VOID(host);
568     auto eventHub = host->GetEventHub<EventHub>();
569     CHECK_NULL_VOID(eventHub);
570     auto inputEventHub = eventHub->GetOrCreateInputEventHub();
571     CHECK_NULL_VOID(inputEventHub);
572     auto hoverTask = [weak = WeakClaim(this)](bool isHover) {
573         auto pattern = weak.Upgrade();
574         CHECK_NULL_VOID_NOLOG(pattern);
575         pattern->HandleHoverEvent(isHover);
576     };
577     auto hoverEvent = MakeRefPtr<InputEvent>(std::move(hoverTask));
578     CHECK_NULL_VOID(hoverEvent);
579     inputEventHub->AddOnHoverEvent(hoverEvent);
580 
581     auto mouseTask = [weak = WeakClaim(this)](MouseInfo& info) {
582         auto pattern = weak.Upgrade();
583         CHECK_NULL_VOID_NOLOG(pattern);
584         pattern->HandleMouseEvent(info);
585     };
586     auto mouseEvent_ = MakeRefPtr<InputEvent>(std::move(mouseTask));
587     inputEventHub->AddOnMouseEvent(mouseEvent_);
588 }
589 
HandleHoverEvent(bool isHover)590 void PatternLockPattern::HandleHoverEvent(bool isHover)
591 {
592     CHECK_NULL_VOID(patternLockModifier_);
593     patternLockModifier_->SetIsHover(isHover);
594 }
595 
HandleMouseEvent(const MouseInfo & info)596 void PatternLockPattern::HandleMouseEvent(const MouseInfo& info)
597 {
598     OffsetF hoverPoint;
599     hoverPoint.SetX(info.GetLocalLocation().GetX());
600     hoverPoint.SetY(info.GetLocalLocation().GetY());
601     cellCenter_ = hoverPoint;
602     bool isPointHover = false;
603     for (int32_t i = 0; i < PATTERN_LOCK_COL_COUNT; i++) {
604         for (int32_t j = 0; j < PATTERN_LOCK_COL_COUNT; j++) {
605             if (CheckInHotSpot(hoverPoint, i + 1, j + 1)) {
606                 CHECK_NULL_VOID(patternLockModifier_);
607                 patternLockModifier_->SetHoverIndex(i * PATTERN_LOCK_COL_COUNT + j);
608                 isPointHover = true;
609                 break;
610             }
611         }
612     }
613     if (!isPointHover) {
614         patternLockModifier_->SetHoverIndex(-1);
615     }
616 }
617 
StartModifierConnectedAnimate(int32_t x,int32_t y)618 void PatternLockPattern::StartModifierConnectedAnimate(int32_t x, int32_t y)
619 {
620     CHECK_NULL_VOID(patternLockModifier_);
621     patternLockModifier_->StartConnectedCircleAnimate(x, y);
622     patternLockModifier_->StartConnectedLineAnimate(x, y);
623 }
624 
StartModifierAddPassPointAnimate(int32_t x,int32_t y)625 void PatternLockPattern::StartModifierAddPassPointAnimate(int32_t x, int32_t y)
626 {
627     CHECK_NULL_VOID(patternLockModifier_);
628     patternLockModifier_->StartConnectedCircleAnimate(x, y);
629 }
630 
StartModifierCanceledAnimate()631 void PatternLockPattern::StartModifierCanceledAnimate()
632 {
633     CHECK_NULL_VOID(patternLockModifier_);
634     if (isMoveEventValid_) {
635         patternLockModifier_->StartCanceledAnimate();
636     }
637 }
638 } // namespace OHOS::Ace::NG
639