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