1 /*
2 * Copyright (c) 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_modifier.h"
17
18 #include "core/components_ng/pattern/patternlock/patternlock_paint_property.h"
19 #include "core/components_ng/render/drawing_prop_convertor.h"
20 #include "core/pipeline_ng/pipeline_context.h"
21
22 namespace OHOS::Ace::NG {
23 namespace {
24 constexpr int32_t PATTERN_LOCK_COL_COUNT = 3;
25 constexpr int32_t PATTERN_LOCK_POINT_COUNT = 9;
26 constexpr int32_t RADIUS_TO_DIAMETER = 2;
27 constexpr float FLASH_POINT_OPACITY = 0.5f;
28 constexpr int32_t ACTIVE_RADIUS_ANIMATION_DURATION = 200;
29 constexpr int32_t LIGHT_RING_RADIUS_ANIMATION_DURATION = 500;
30 constexpr int32_t LIGHT_RING_ALPHAF_ANIMATION_DURATION_FIRST = 200;
31 constexpr int32_t LIGHT_RING_ALPHAF_ANIMATION_DURATION_SECOND = 300;
32 constexpr int32_t CONNECT_ANIMATION_DURATION_FIRST = 100;
33 constexpr int32_t WRONG_ANIMATION_DURATION_DIMMING = 150;
34 constexpr int32_t WRONG_ANIMATION_DURATION_BRIGHTENING = 200;
35 constexpr int32_t WRONG_ANIMATION_DURATION_FLASH_ONCE =
36 WRONG_ANIMATION_DURATION_DIMMING + WRONG_ANIMATION_DURATION_BRIGHTENING;
37 constexpr int32_t WRONG_ANIMATION_DURATION_FLASH_TWICE =
38 WRONG_ANIMATION_DURATION_FLASH_ONCE + WRONG_ANIMATION_DURATION_FLASH_ONCE;
39 constexpr float BACKGROUND_RADIUS_SPRING_RESPONSE = 0.347f;
40 constexpr float BACKGROUND_RADIUS_SPRING_DAMPING = 0.55f;
41 constexpr Dimension LIGHT_RING_LINE_WIDTH = 2.5_vp;
42 constexpr Dimension LIGHT_RING_MASK_RADIUS = 10.0_vp;
43 constexpr float LIGHT_RING_ALPHAF_START = 0.0f;
44 constexpr float LIGHT_RING_ALPHAF_END = 0.5f;
45 constexpr float CONNECTED_LINE_SPRING_RESPONSE = 0.22f;
46 constexpr float CONNECTED_LINE_SPRING_DAMPING = 0.88f;
47 constexpr float CANCELED_LINE_SPRING_RESPONSE = 0.22f;
48 constexpr float CANCELED_LINE_SPRING_DAMPING = 0.88f;
49 constexpr float CANCELED_LINE_MIN_POINT = 0.1f;
50 constexpr int32_t ANIMATABLE_POINT_COUNT = 2;
51 constexpr float DIAMETER_TO_RADIUS = 0.5f;
52 constexpr float GRADUAL_CHANGE_POINT = 0.5;
53 constexpr int32_t MAX_ALPHA = 255;
54 constexpr double EPSILON = 0.01f;
55 } // namespace
56
PatternLockCell(int32_t column,int32_t row)57 PatternLockCell::PatternLockCell(int32_t column, int32_t row)
58 {
59 column_ = column;
60 row_ = row;
61 code_ = PATTERN_LOCK_COL_COUNT * (row - 1) + (column - 1);
62 }
63
CreateProperties()64 void PatternLockModifier::CreateProperties()
65 {
66 sideLength_ = AceType::MakeRefPtr<PropertyFloat>(0.0f);
67 circleRadius_ = AceType::MakeRefPtr<PropertyFloat>(0.0f);
68 regularColor_ = AceType::MakeRefPtr<PropertyColor>(Color::BLACK);
69 selectedColor_ = AceType::MakeRefPtr<PropertyColor>(Color::BLACK);
70 activeColor_ = AceType::MakeRefPtr<PropertyColor>(Color::BLACK);
71 hoverColor_ = AceType::MakeRefPtr<PropertyColor>(Color::BLACK);
72 wrongColor_ = AceType::MakeRefPtr<PropertyColor>(Color::RED);
73 correctColor_ = AceType::MakeRefPtr<PropertyColor>(Color::BLUE);
74 pathColor_ = AceType::MakeRefPtr<AnimatablePropertyColor>(LinearColor(Color::BLUE));
75 pointAnimateColor_ = AceType::MakeRefPtr<AnimatablePropertyColor>(LinearColor(Color::BLACK));
76 pathStrokeWidth_ = AceType::MakeRefPtr<PropertyFloat>(0.0f);
77 offset_ = AceType::MakeRefPtr<PropertyOffsetF>(OffsetF());
78 cellCenter_ = AceType::MakeRefPtr<PropertyOffsetF>(OffsetF());
79 isMoveEventValid_ = AceType::MakeRefPtr<PropertyBool>(false);
80 isHover_ = AceType::MakeRefPtr<PropertyBool>(false);
81 hoverIndex_ = AceType::MakeRefPtr<PropertyInt>(-1);
82 connectedLineTailPoint_ = AceType::MakeRefPtr<AnimatablePropertyOffsetF>(OffsetF());
83 canceledLineTailPoint_ = AceType::MakeRefPtr<AnimatablePropertyOffsetF>(OffsetF());
84 activeCircleColor_ = AceType::MakeRefPtr<AnimatablePropertyColor>(LinearColor(Color::BLACK));
85 activeBackgroundRadius_ = AceType::MakeRefPtr<PropertyFloat>(0.0f);
86 enableWaveEffect_ = AceType::MakeRefPtr<PropertyBool>(false);
87 enableForeground_ = AceType::MakeRefPtr<PropertyBool>(false);
88 }
89
AttachProperties()90 void PatternLockModifier::AttachProperties()
91 {
92 AttachProperty(sideLength_);
93 AttachProperty(circleRadius_);
94 AttachProperty(regularColor_);
95 AttachProperty(selectedColor_);
96 AttachProperty(activeColor_);
97 AttachProperty(hoverColor_);
98 AttachProperty(wrongColor_);
99 AttachProperty(correctColor_);
100 AttachProperty(pathColor_);
101 AttachProperty(pointAnimateColor_);
102 AttachProperty(pathStrokeWidth_);
103 AttachProperty(cellCenter_);
104 AttachProperty(offset_);
105 AttachProperty(isMoveEventValid_);
106 AttachProperty(isHover_);
107 AttachProperty(hoverIndex_);
108 AttachProperty(connectedLineTailPoint_);
109 AttachProperty(canceledLineTailPoint_);
110 AttachProperty(activeCircleColor_);
111 AttachProperty(activeBackgroundRadius_);
112 AttachProperty(enableWaveEffect_);
113 AttachProperty(enableForeground_);
114 }
115
PatternLockModifier(const WeakPtr<Pattern> & pattern)116 PatternLockModifier::PatternLockModifier(const WeakPtr<Pattern>& pattern) : pattern_(pattern)
117 {
118 CreateProperties();
119 AttachProperties();
120 for (size_t count = 0; count < PATTERN_LOCK_POINT_COUNT; count++) {
121 auto backgroundRadius = AceType::MakeRefPtr<AnimatablePropertyFloat>(0.0f);
122 AttachProperty(backgroundRadius);
123 backgroundCircleRadius_.emplace_back(backgroundRadius);
124
125 auto activeRadius = AceType::MakeRefPtr<AnimatablePropertyFloat>(0.0f);
126 AttachProperty(activeRadius);
127 activeCircleRadius_.emplace_back(activeRadius);
128
129 auto lightRingRadius = AceType::MakeRefPtr<AnimatablePropertyFloat>(0.0f);
130 AttachProperty(lightRingRadius);
131 lightRingRadius_.emplace_back(lightRingRadius);
132
133 auto lightRingAlphaF = AceType::MakeRefPtr<AnimatablePropertyFloat>(0.0f);
134 AttachProperty(lightRingAlphaF);
135 lightRingAlphaF_.emplace_back(lightRingAlphaF);
136 }
137 }
138
onDraw(DrawingContext & context)139 void PatternLockModifier::onDraw(DrawingContext& context)
140 {
141 auto pipeline = PipelineBase::GetCurrentContext();
142 CHECK_NULL_VOID(pipeline);
143 if (Container::LessThanAPIVersion(PlatformVersion::VERSION_TEN)) {
144 DrawForApiNine(context);
145 return;
146 }
147 auto& canvas = context.canvas;
148 if (!enableForeground_->Get()) {
149 PaintLockLine(canvas, offset_->Get());
150 canvas.Save();
151 PaintActiveCircle(canvas, offset_->Get());
152 for (int i = 0; i < PATTERN_LOCK_COL_COUNT; i++) {
153 for (int j = 0; j < PATTERN_LOCK_COL_COUNT; j++) {
154 PaintLockCircle(canvas, offset_->Get(), i + 1, j + 1);
155 }
156 }
157 } else {
158 for (int i = 0; i < PATTERN_LOCK_COL_COUNT; i++) {
159 for (int j = 0; j < PATTERN_LOCK_COL_COUNT; j++) {
160 PaintLockCircle(canvas, offset_->Get(), i + 1, j + 1);
161 }
162 }
163 PaintLockLine(canvas, offset_->Get());
164 canvas.Save();
165 PaintActiveCircle(canvas, offset_->Get());
166 }
167 canvas.Restore();
168 }
169
DrawForApiNine(DrawingContext & context)170 void PatternLockModifier::DrawForApiNine(DrawingContext& context)
171 {
172 auto& canvas = context.canvas;
173 PaintLockLineForApiNine(canvas, offset_->Get());
174 canvas.Save();
175 for (int i = 0; i < PATTERN_LOCK_COL_COUNT; i++) {
176 for (int j = 0; j < PATTERN_LOCK_COL_COUNT; j++) {
177 PaintLockCircleForApiNine(canvas, offset_->Get(), i + 1, j + 1);
178 }
179 }
180 canvas.Restore();
181 }
182
PaintLockLineForApiNine(RSCanvas & canvas,const OffsetF & offset)183 void PatternLockModifier::PaintLockLineForApiNine(RSCanvas& canvas, const OffsetF& offset)
184 {
185 size_t count = choosePoint_.size();
186 if (count == 0) {
187 return;
188 }
189
190 float sideLength = sideLength_->Get();
191 float pathStrokeWidth = pathStrokeWidth_->Get();
192 if (LessOrEqual(pathStrokeWidth, 0.0)) {
193 return;
194 }
195 float handleStrokeWidth = std::min(pathStrokeWidth, sideLength / PATTERN_LOCK_COL_COUNT);
196 pathStrokeWidth = std::max(handleStrokeWidth, 0.0f);
197
198 auto pathColor = pathColor_->Get();
199 auto cellCenter = cellCenter_->Get();
200 RSPen pen;
201 pen.SetAntiAlias(true);
202 pen.SetColor(ToRSColor(pathColor));
203 pen.SetWidth(pathStrokeWidth);
204 pen.SetCapStyle(RSPen::CapStyle::ROUND_CAP);
205
206 Color pathColorAlpha255 = pathColor.ToColor().ChangeAlpha(MAX_ALPHA);
207 pen.SetColor(pathColorAlpha255.GetValue());
208 canvas.AttachPen(pen);
209 for (size_t i = 0; i < count - 1; i++) {
210 OffsetF pointBegin = GetCircleCenterByXY(offset, choosePoint_[i].GetColumn(), choosePoint_[i].GetRow());
211 OffsetF pointEnd = GetCircleCenterByXY(offset, choosePoint_[i + 1].GetColumn(), choosePoint_[i + 1].GetRow());
212 canvas.DrawLine(RSPoint(pointBegin.GetX(), pointBegin.GetY()), RSPoint(pointEnd.GetX(), pointEnd.GetY()));
213 }
214 if (isMoveEventValid_->Get()) {
215 OffsetF pointBegin =
216 GetCircleCenterByXY(offset, choosePoint_[count - 1].GetColumn(), choosePoint_[count - 1].GetRow());
217 float x1 = pointBegin.GetX();
218 float y1 = pointBegin.GetY();
219 float x2 = cellCenter.GetX();
220 float y2 = cellCenter.GetY();
221 x2 = x2 > offset.GetX() + sideLength ? offset.GetX() + sideLength : x2;
222 x2 = x2 < offset.GetX() ? offset.GetX() : x2;
223 y2 = y2 > offset.GetY() + sideLength ? offset.GetY() + sideLength : y2;
224 y2 = y2 < offset.GetY() ? offset.GetY() : y2;
225
226 std::vector<RSColorQuad> colors = { pathColorAlpha255.GetValue(), pathColorAlpha255.GetValue(),
227 pathColorAlpha255.ChangeOpacity(0.0).GetValue() };
228 std::vector<RSScalar> pos = { 0.0, GRADUAL_CHANGE_POINT, 1.0 };
229 auto shader = pen.GetShaderEffect();
230 shader->CreateLinearGradient(RSPoint(x1, y1), RSPoint(x2, y2), colors, pos, RSTileMode::CLAMP);
231 pen.SetShaderEffect(shader);
232 canvas.DrawLine(RSPoint(x1, y1), RSPoint(x2, y2));
233 }
234 canvas.DetachPen();
235 canvas.Restore();
236 }
237
PaintLockCircleForApiNine(RSCanvas & canvas,const OffsetF & offset,int32_t x,int32_t y)238 void PatternLockModifier::PaintLockCircleForApiNine(RSCanvas& canvas, const OffsetF& offset, int32_t x, int32_t y)
239 {
240 auto activeColor = activeColor_->Get();
241 auto regularColor = regularColor_->Get();
242 auto selectedColor = selectedColor_->Get();
243 auto sideLength = sideLength_->Get();
244 auto circleRadius = circleRadius_->Get();
245
246 RSBrush brush;
247 brush.SetAntiAlias(true);
248 brush.SetColor(ToRSColor(regularColor));
249 OffsetF cellcenter = GetCircleCenterByXY(offset, x, y);
250 OffsetF firstCellcenter = GetCircleCenterByXY(offset, 1, 1);
251 float offsetX = cellcenter.GetX();
252 float offsetY = cellcenter.GetY();
253 const int32_t radiusCount = RADIUS_TO_DIAMETER * PATTERN_LOCK_COL_COUNT;
254 float handleCircleRadius = std::min(circleRadius, sideLength / scaleBackgroundCircleRadius_ / radiusCount);
255 circleRadius = std::max(handleCircleRadius, 0.0f);
256 if (CheckChoosePoint(x, y)) {
257 const int32_t lastIndexFir = 1;
258 if (CheckChoosePointIsLastIndex(x, y, lastIndexFir)) {
259 if (isMoveEventValid_->Get()) {
260 brush.SetColor(ToRSColor(activeColor));
261 canvas.AttachBrush(brush);
262 auto radius = circleRadius * scaleBackgroundCircleRadius_;
263 canvas.DrawCircle(
264 RSPoint(offsetX, offsetY), std::min(static_cast<float>(radius), firstCellcenter.GetX()));
265 } else {
266 brush.SetColor(ToRSColor(selectedColor));
267 canvas.AttachBrush(brush);
268 canvas.DrawCircle(RSPoint(offsetX, offsetY), circleRadius * scaleActiveCircleRadius_);
269 }
270 } else {
271 brush.SetColor(ToRSColor(selectedColor));
272 canvas.AttachBrush(brush);
273 canvas.DrawCircle(RSPoint(offsetX, offsetY), circleRadius * scaleActiveCircleRadius_);
274 }
275 } else {
276 canvas.AttachBrush(brush);
277 canvas.DrawCircle(RSPoint(offsetX, offsetY), circleRadius);
278 }
279 canvas.DetachBrush();
280 }
281
PaintLockLine(RSCanvas & canvas,const OffsetF & offset)282 void PatternLockModifier::PaintLockLine(RSCanvas& canvas, const OffsetF& offset)
283 {
284 size_t count = choosePoint_.size();
285 if (count < 1) {
286 return;
287 }
288
289 float sideLength = sideLength_->Get();
290 float pathStrokeWidth = pathStrokeWidth_->Get();
291 if (LessOrEqual(pathStrokeWidth, 0.0)) {
292 return;
293 }
294 float handleStrokeWidth = std::min(pathStrokeWidth, sideLength / PATTERN_LOCK_COL_COUNT);
295 pathStrokeWidth = std::max(handleStrokeWidth, 0.0f);
296
297 auto pathColor = pathColor_->Get();
298 RSPen pen;
299 pen.SetAntiAlias(true);
300 pen.SetWidth(pathStrokeWidth);
301 pen.SetCapStyle(RSPen::CapStyle::ROUND_CAP);
302
303 pen.SetColor(pathColor.GetValue());
304 canvas.Save();
305 if (!enableForeground_->Get()) {
306 SetCircleClip(canvas);
307 }
308 canvas.AttachPen(pen);
309 RSPath path;
310 if (count > ANIMATABLE_POINT_COUNT) {
311 for (size_t i = 0; i < count - ANIMATABLE_POINT_COUNT; i++) {
312 OffsetF pointBegin = GetCircleCenterByXY(offset, choosePoint_[i].GetColumn(), choosePoint_[i].GetRow());
313 OffsetF pointEnd =
314 GetCircleCenterByXY(offset, choosePoint_[i + 1].GetColumn(), choosePoint_[i + 1].GetRow());
315 path.MoveTo(pointBegin.GetX(), pointBegin.GetY());
316 path.LineTo(pointEnd.GetX(), pointEnd.GetY());
317 }
318 }
319 AddConnectedLineToPath(path, offset);
320 if (isMoveEventValid_->Get()) {
321 OffsetF pointBegin =
322 GetCircleCenterByXY(offset, choosePoint_[count - 1].GetColumn(), choosePoint_[count - 1].GetRow());
323 OffsetF pointEnd = GetPointEndByCellCenter();
324 if (pointEnd != pointBegin) {
325 path.MoveTo(pointBegin.GetX(), pointBegin.GetY());
326 path.LineTo(pointEnd.GetX(), pointEnd.GetY());
327 }
328 }
329 AddCanceledLineToPath(path, offset);
330 canvas.DrawPath(path);
331 canvas.DetachPen();
332 canvas.Restore();
333 }
334
AddConnectedLineToPath(RSPath & path,const OffsetF & offset)335 void PatternLockModifier::AddConnectedLineToPath(RSPath& path, const OffsetF& offset)
336 {
337 size_t count = choosePoint_.size();
338 if (count < ANIMATABLE_POINT_COUNT) {
339 return;
340 }
341 OffsetF pointBegin = GetCircleCenterByXY(offset, choosePoint_[count - ANIMATABLE_POINT_COUNT].GetColumn(),
342 choosePoint_[count - ANIMATABLE_POINT_COUNT].GetRow());
343 OffsetF pointEnd = GetConnectedLineTailPoint();
344 if (pointEnd != pointBegin) {
345 path.MoveTo(pointBegin.GetX(), pointBegin.GetY());
346 path.LineTo(pointEnd.GetX(), pointEnd.GetY());
347 }
348 }
349
AddCanceledLineToPath(RSPath & path,const OffsetF & offset)350 void PatternLockModifier::AddCanceledLineToPath(RSPath& path, const OffsetF& offset)
351 {
352 if (!needCanceledLine_) {
353 return;
354 }
355 size_t count = choosePoint_.size();
356 OffsetF pointBegin =
357 GetCircleCenterByXY(offset, choosePoint_[count - 1].GetColumn(), choosePoint_[count - 1].GetRow());
358 OffsetF pointEnd = GetCanceledLineTailPoint();
359 if ((!NearEqual(pointBegin.GetX(), pointEnd.GetX(), EPSILON)
360 || !NearEqual(pointBegin.GetY(), pointEnd.GetY(), EPSILON))
361 && GreatOrEqual(pointEnd.GetY(), CANCELED_LINE_MIN_POINT)) {
362 path.MoveTo(pointBegin.GetX(), pointBegin.GetY());
363 path.LineTo(pointEnd.GetX(), pointEnd.GetY());
364 }
365 }
366
PaintLockCircle(RSCanvas & canvas,const OffsetF & offset,int32_t x,int32_t y)367 void PatternLockModifier::PaintLockCircle(RSCanvas& canvas, const OffsetF& offset, int32_t x, int32_t y)
368 {
369 auto activeColor = activeColor_->Get();
370 auto regularColor = regularColor_->Get();
371 auto selectedColor = selectedColor_->Get();
372 auto circleRadius = circleRadius_->Get();
373 auto pointAnimateColor = pointAnimateColor_->Get();
374
375 OffsetF cellcenter = GetCircleCenterByXY(offset, x, y);
376 float offsetX = cellcenter.GetX();
377 float offsetY = cellcenter.GetY();
378
379 auto index = (x - 1) * PATTERN_LOCK_COL_COUNT + y - 1;
380 if (CheckChoosePoint(x, y)) {
381 const int32_t lastIndexFir = 1;
382 CheckIsHoverAndPaint(canvas, offsetX, offsetY, GetActiveCircleRadius(index), index);
383 PaintLightRing(canvas, offsetX, offsetY, GetLightRingCircleRadius(index), GetLightRingAlphaF(index));
384 if (isMoveEventValid_->Get() && CheckChoosePointIsLastIndex(x, y, lastIndexFir)) {
385 PaintCircle(canvas, offsetX, offsetY, GetActiveCircleRadius(index), ToRSColor(activeColor));
386 } else {
387 if (challengeResult_.has_value()) {
388 PaintCircle(canvas, offsetX, offsetY, GetActiveCircleRadius(index), ToRSColor(pointAnimateColor));
389 } else {
390 PaintCircle(canvas, offsetX, offsetY, GetActiveCircleRadius(index), ToRSColor(selectedColor));
391 }
392 }
393 } else {
394 CheckIsHoverAndPaint(canvas, offsetX, offsetY, circleRadius, index);
395 PaintCircle(canvas, offsetX, offsetY, circleRadius, ToRSColor(regularColor));
396 }
397 }
398
PaintActiveCircle(RSCanvas & canvas,const OffsetF & offset)399 void PatternLockModifier::PaintActiveCircle(RSCanvas& canvas, const OffsetF& offset)
400 {
401 auto activeCircleColor = activeCircleColor_->Get();
402
403 for (int x = 1; x <= PATTERN_LOCK_COL_COUNT; x++) {
404 for (int y = 1; y <= PATTERN_LOCK_COL_COUNT; y++) {
405 OffsetF cellcenter = GetCircleCenterByXY(offset, x, y);
406 float offsetX = cellcenter.GetX();
407 float offsetY = cellcenter.GetY();
408 auto index = (x - 1) * PATTERN_LOCK_COL_COUNT + y - 1;
409 if (CheckChoosePoint(x, y)) {
410 PaintCircle(canvas, offsetX, offsetY, GetBackgroundCircleRadius(index), ToRSColor(activeCircleColor));
411 }
412 }
413 }
414 }
415
CheckIsHoverAndPaint(RSCanvas & canvas,float offsetX,float offsetY,float radius,int32_t index)416 void PatternLockModifier::CheckIsHoverAndPaint(
417 RSCanvas& canvas, float offsetX, float offsetY, float radius, int32_t index)
418 {
419 if (isHover_->Get() && hoverIndex_->Get() == index) {
420 PaintCircle(canvas, offsetX, offsetY, radius * hoverRadiusScale_, ToRSColor(hoverColor_->Get()));
421 }
422 }
423
PaintCircle(RSCanvas & canvas,float offsetX,float offsetY,float radius,const RSColor & circleColor)424 void PatternLockModifier::PaintCircle(
425 RSCanvas& canvas, float offsetX, float offsetY, float radius, const RSColor& circleColor)
426 {
427 RSBrush brush;
428 brush.SetAntiAlias(true);
429 brush.SetColor(circleColor);
430 canvas.AttachBrush(brush);
431 canvas.DrawCircle(RSPoint(offsetX, offsetY), radius);
432 canvas.DetachBrush();
433 }
434
PaintLightRing(RSCanvas & canvas,float offsetX,float offsetY,float radius,float alphaF)435 void PatternLockModifier::PaintLightRing(RSCanvas& canvas, float offsetX, float offsetY, float radius, float alphaF)
436 {
437 if (NearZero(alphaF)) {
438 return;
439 }
440 RSPen pen;
441 pen.SetWidth(LIGHT_RING_LINE_WIDTH.ConvertToPx());
442 pen.SetAntiAlias(true);
443 pen.SetColor(ToRSColor(activeColor_->Get()));
444 pen.SetAlphaF(alphaF);
445 RSFilter filter;
446 filter.SetMaskFilter(RSMaskFilter::CreateBlurMaskFilter(
447 RSBlurType::NORMAL, RSDrawing::ConvertRadiusToSigma(LIGHT_RING_MASK_RADIUS.ConvertToPx())));
448 pen.SetFilter(filter);
449
450 canvas.AttachPen(pen);
451 RSPath path;
452 path.AddCircle(offsetX, offsetY, radius);
453 canvas.DrawPath(path);
454 canvas.DetachPen();
455 }
456
CheckChoosePoint(int32_t x,int32_t y) const457 bool PatternLockModifier::CheckChoosePoint(int32_t x, int32_t y) const
458 {
459 for (auto it : choosePoint_) {
460 if (it.GetColumn() == x && it.GetRow() == y) {
461 return true;
462 }
463 }
464 return false;
465 }
466
CheckChoosePointIsLastIndex(int32_t x,int32_t y,int32_t index) const467 bool PatternLockModifier::CheckChoosePointIsLastIndex(int32_t x, int32_t y, int32_t index) const
468 {
469 if (!choosePoint_.empty() && static_cast<int32_t>(choosePoint_.size()) >= index) {
470 if (choosePoint_.at(choosePoint_.size() - static_cast<uint32_t>(index)).GetColumn() == x &&
471 choosePoint_.at(choosePoint_.size() - static_cast<uint32_t>(index)).GetRow() == y) {
472 return true;
473 }
474 }
475 return false;
476 }
477
GetCircleCenterByXY(const OffsetF & offset,int32_t x,int32_t y)478 OffsetF PatternLockModifier::GetCircleCenterByXY(const OffsetF& offset, int32_t x, int32_t y)
479 {
480 float sideLength = sideLength_->Get();
481 OffsetF cellCenter;
482 int32_t scale = RADIUS_TO_DIAMETER;
483 cellCenter.SetX(offset.GetX() + sideLength / PATTERN_LOCK_COL_COUNT / scale * (x * scale - 1));
484 cellCenter.SetY(offset.GetY() + sideLength / PATTERN_LOCK_COL_COUNT / scale * (y * scale - 1));
485 return cellCenter;
486 }
487
SetSideLength(float sideLength)488 void PatternLockModifier::SetSideLength(float sideLength)
489 {
490 CHECK_NULL_VOID(sideLength_);
491 if (!NearEqual(sideLength_->Get(), sideLength)) {
492 sideLength_->Set(sideLength);
493 size_t count = choosePoint_.size();
494 if (count > 0) {
495 OffsetF lastPoint = GetCircleCenterByXY(
496 offset_->Get(), choosePoint_[count - 1].GetColumn(), choosePoint_[count - 1].GetRow());
497 connectedLineTailPoint_->Set(lastPoint);
498 canceledLineTailPoint_->Set(lastPoint);
499 }
500 }
501 }
502
SetCircleRadius(float circleRadius)503 void PatternLockModifier::SetCircleRadius(float circleRadius)
504 {
505 CHECK_NULL_VOID(circleRadius_);
506 auto sideLength = sideLength_->Get();
507 if (NearZero(scaleBackgroundCircleRadius_)) {
508 return;
509 }
510 float handleCircleRadius =
511 std::min(circleRadius, sideLength / scaleBackgroundCircleRadius_ / PATTERN_LOCK_COL_COUNT * DIAMETER_TO_RADIUS);
512 circleRadius = std::max(handleCircleRadius, 0.0f);
513 if (!NearEqual(circleRadius_->Get(), circleRadius)) {
514 circleRadius_->Set(circleRadius);
515 for (const auto& cell : choosePoint_) {
516 auto index = (cell.GetColumn() - 1) * PATTERN_LOCK_COL_COUNT + cell.GetRow() - 1;
517 if (index < PATTERN_LOCK_POINT_COUNT && index >= 0) {
518 backgroundCircleRadius_.at(index)->Set(circleRadius * scaleBackgroundCircleRadius_);
519 activeCircleRadius_.at(index)->Set(circleRadius * scaleActiveCircleRadius_);
520 lightRingRadius_.at(index)->Set(circleRadius * scaleLightRingRadiusStart_);
521 }
522 }
523 }
524 }
525
SetRegularColor(const Color & regularColor)526 void PatternLockModifier::SetRegularColor(const Color& regularColor)
527 {
528 CHECK_NULL_VOID(regularColor_);
529 regularColor_->Set(regularColor);
530 }
531
SetSelectColor(const Color & selectedColor)532 void PatternLockModifier::SetSelectColor(const Color& selectedColor)
533 {
534 CHECK_NULL_VOID(selectedColor_);
535 if (selectedColor_->Get() != selectedColor) {
536 selectedColor_->Set(selectedColor);
537 }
538 }
539
SetActiveColor(const Color & activeColor)540 void PatternLockModifier::SetActiveColor(const Color& activeColor)
541 {
542 CHECK_NULL_VOID(activeColor_);
543 activeColor_->Set(activeColor);
544 }
545
SetPathColor(const LinearColor & pathColor)546 void PatternLockModifier::SetPathColor(const LinearColor& pathColor)
547 {
548 CHECK_NULL_VOID(pathColor_);
549 pathColor_->Set(pathColor);
550 }
551
SetHoverColor(const Color & hoverColor)552 void PatternLockModifier::SetHoverColor(const Color& hoverColor)
553 {
554 CHECK_NULL_VOID(hoverColor_);
555 if (hoverColor_->Get() != hoverColor) {
556 hoverColor_->Set(hoverColor);
557 }
558 }
559
SetWrongColor(const Color & wrongColor)560 void PatternLockModifier::SetWrongColor(const Color& wrongColor)
561 {
562 CHECK_NULL_VOID(wrongColor_);
563 if (wrongColor_->Get() != wrongColor) {
564 wrongColor_->Set(wrongColor);
565 }
566 }
567
SetCorrectColor(const Color & correctColor)568 void PatternLockModifier::SetCorrectColor(const Color& correctColor)
569 {
570 CHECK_NULL_VOID(correctColor_);
571 correctColor_->Set(correctColor);
572 }
573
SetPathStrokeWidth(float pathStrokeWidth)574 void PatternLockModifier::SetPathStrokeWidth(float pathStrokeWidth)
575 {
576 CHECK_NULL_VOID(pathStrokeWidth_);
577 pathStrokeWidth_->Set(pathStrokeWidth);
578 }
579
SetContentOffset(const OffsetF & offset)580 void PatternLockModifier::SetContentOffset(const OffsetF& offset)
581 {
582 CHECK_NULL_VOID(offset_);
583 if (!NearEqual(offset_->Get(), offset)) {
584 offset_->Set(offset);
585 size_t count = choosePoint_.size();
586 if (count > 0) {
587 OffsetF lastPoint =
588 GetCircleCenterByXY(offset, choosePoint_[count - 1].GetColumn(), choosePoint_[count - 1].GetRow());
589 connectedLineTailPoint_->Set(lastPoint);
590 canceledLineTailPoint_->Set(lastPoint);
591 }
592 }
593 }
594
SetIsMoveEventValid(bool isMoveEventValid)595 void PatternLockModifier::SetIsMoveEventValid(bool isMoveEventValid)
596 {
597 isMoveEventValid_->Set(isMoveEventValid);
598 }
599
SetIsHover(bool isHover)600 void PatternLockModifier::SetIsHover(bool isHover)
601 {
602 isHover_->Set(isHover);
603 }
604
SetHoverIndex(int32_t hoverIndex)605 void PatternLockModifier::SetHoverIndex(int32_t hoverIndex)
606 {
607 hoverIndex_->Set(hoverIndex);
608 }
609
SetActiveCircleColor(const LinearColor & activeCircleColor)610 void PatternLockModifier::SetActiveCircleColor(const LinearColor& activeCircleColor)
611 {
612 CHECK_NULL_VOID(activeCircleColor_);
613 activeCircleColor_->Set(activeCircleColor);
614 }
615
SetActiveBackgroundRadius(float activeBackgroundRadius)616 void PatternLockModifier::SetActiveBackgroundRadius(float activeBackgroundRadius)
617 {
618 CHECK_NULL_VOID(activeBackgroundRadius_);
619 activeBackgroundRadius_->Set(activeBackgroundRadius);
620 }
621
SetEnableWaveEffect(bool enableWaveEffect)622 void PatternLockModifier::SetEnableWaveEffect(bool enableWaveEffect)
623 {
624 CHECK_NULL_VOID(enableWaveEffect_);
625 enableWaveEffect_->Set(enableWaveEffect);
626 }
627
SetEnableForeground(bool enableForeground)628 void PatternLockModifier::SetEnableForeground(bool enableForeground)
629 {
630 CHECK_NULL_VOID(enableForeground_);
631 enableForeground_->Set(enableForeground);
632 }
633
StartChallengeResultAnimate()634 void PatternLockModifier::StartChallengeResultAnimate()
635 {
636 if (!challengeResult_.has_value()) {
637 return;
638 }
639 if (challengeResult_.value() == NG::PatternLockChallengeResult::CORRECT) {
640 pointAnimateColor_->Set(LinearColor(selectedColor_->Get()));
641 AnimationOption option = AnimationOption();
642 option.SetDuration(CONNECT_ANIMATION_DURATION_FIRST);
643 option.SetCurve(Curves::SHARP);
644 auto pattern = pattern_.Upgrade();
645 auto host = pattern? pattern->GetHost(): nullptr;
646 auto context = host? host->GetContextRefPtr(): nullptr;
647 AnimationUtils::Animate(
648 option, [&]() { pointAnimateColor_->Set(LinearColor(correctColor_->Get())); }, nullptr, nullptr, context);
649 } else if (challengeResult_.value() == NG::PatternLockChallengeResult::WRONG) {
650 pointAnimateColor_->Set(LinearColor(wrongColor_->Get()));
651 auto pathColor = pathColor_->Get();
652 auto activeCircleColor = activeCircleColor_->Get();
653 AnimationOption option = AnimationOption();
654 option.SetDuration(WRONG_ANIMATION_DURATION_FLASH_TWICE);
655 option.SetCurve(Curves::SHARP);
656 auto dimmingAnimation = [weak = WeakClaim(this)]() {
657 auto modifier = weak.Upgrade();
658 CHECK_NULL_VOID(modifier);
659 modifier->pointAnimateColor_->Set(
660 LinearColor(modifier->wrongColor_->Get().BlendOpacity(FLASH_POINT_OPACITY)));
661 modifier->SetPathColor(LinearColor(modifier->pathColor_->Get().BlendOpacity(FLASH_POINT_OPACITY)));
662 modifier->SetActiveCircleColor(
663 LinearColor(modifier->activeCircleColor_->Get().BlendOpacity(FLASH_POINT_OPACITY)));
664 };
665 auto brighteningAnimation = [weak = WeakClaim(this), pathColor, activeCircleColor]() {
666 auto modifier = weak.Upgrade();
667 CHECK_NULL_VOID(modifier);
668 modifier->pointAnimateColor_->Set(LinearColor(modifier->wrongColor_->Get()));
669 modifier->SetPathColor(pathColor);
670 modifier->SetActiveCircleColor(activeCircleColor);
671 };
672 AnimationUtils::OpenImplicitAnimation(option, Curves::SHARP, nullptr);
673 AnimationUtils::AddKeyFrame(((float)WRONG_ANIMATION_DURATION_DIMMING / WRONG_ANIMATION_DURATION_FLASH_TWICE),
674 Curves::SHARP, dimmingAnimation);
675 AnimationUtils::AddKeyFrame(((float)WRONG_ANIMATION_DURATION_FLASH_ONCE / WRONG_ANIMATION_DURATION_FLASH_TWICE),
676 Curves::SHARP, brighteningAnimation);
677 AnimationUtils::AddKeyFrame(((float)(WRONG_ANIMATION_DURATION_FLASH_ONCE + WRONG_ANIMATION_DURATION_DIMMING) /
678 WRONG_ANIMATION_DURATION_FLASH_TWICE),
679 Curves::SHARP, dimmingAnimation);
680 AnimationUtils::AddKeyFrame(1.0f, Curves::SHARP, brighteningAnimation);
681 AnimationUtils::CloseImplicitAnimation();
682 }
683 }
684
SetChallengeResult(std::optional<NG::PatternLockChallengeResult> & challengeResult)685 void PatternLockModifier::SetChallengeResult(std::optional<NG::PatternLockChallengeResult>& challengeResult)
686 {
687 if (challengeResult_ != challengeResult) {
688 challengeResult_ = challengeResult;
689 StartChallengeResultAnimate();
690 }
691 }
692
SetCellCenterOffset(const OffsetF & cellcenter)693 void PatternLockModifier::SetCellCenterOffset(const OffsetF& cellcenter)
694 {
695 CHECK_NULL_VOID(cellCenter_);
696 cellCenter_->Set(cellcenter);
697 }
698
SetChoosePoint(const std::vector<PatternLockCell> & choosePoint)699 void PatternLockModifier::SetChoosePoint(const std::vector<PatternLockCell>& choosePoint)
700 {
701 choosePoint_ = choosePoint;
702 }
703
SetActiveCircleRadiusScale(float scale)704 void PatternLockModifier::SetActiveCircleRadiusScale(float scale)
705 {
706 scaleActiveCircleRadius_ = scale;
707 }
708
SetBackgroundCircleRadiusScale(float scale)709 void PatternLockModifier::SetBackgroundCircleRadiusScale(float scale)
710 {
711 scaleBackgroundCircleRadius_ = scale;
712 }
713
SetLightRingRadiusStartScale(float scale)714 void PatternLockModifier::SetLightRingRadiusStartScale(float scale)
715 {
716 scaleLightRingRadiusStart_ = scale;
717 }
718
SetLightRingRadiusEndScale(float scale)719 void PatternLockModifier::SetLightRingRadiusEndScale(float scale)
720 {
721 scaleLightRingRadiusEnd_ = scale;
722 }
723
SetHoverRadiusScale(float scale)724 void PatternLockModifier::SetHoverRadiusScale(float scale)
725 {
726 hoverRadiusScale_ = scale;
727 }
728
SetBackgroundCircleRadius(int32_t index)729 void PatternLockModifier::SetBackgroundCircleRadius(int32_t index)
730 {
731 auto backgroundCircleRadius = GetBackgroundCircleRadius(index);
732 if (index < static_cast<int32_t>(backgroundCircleRadius_.size()) && index >= 0) {
733 if (enableWaveEffect_->Get()) {
734 backgroundCircleRadius_.at(index)->Set(0.0f);
735 AnimationOption option = AnimationOption();
736 auto curve = AceType::MakeRefPtr<ResponsiveSpringMotion>(
737 BACKGROUND_RADIUS_SPRING_RESPONSE, BACKGROUND_RADIUS_SPRING_DAMPING);
738 option.SetCurve(curve);
739 auto pattern = pattern_.Upgrade();
740 auto host = pattern? pattern->GetHost(): nullptr;
741 auto context = host? host->GetContextRefPtr(): nullptr;
742 AnimationUtils::Animate(option,
743 [&]() { backgroundCircleRadius_.at(index)->Set(backgroundCircleRadius); }, nullptr, nullptr, context);
744 } else {
745 backgroundCircleRadius_.at(index)->Set(backgroundCircleRadius);
746 }
747 }
748 }
749
GetBackgroundCircleRadius(int32_t index) const750 float PatternLockModifier::GetBackgroundCircleRadius(int32_t index) const
751 {
752 if ((index >= PATTERN_LOCK_POINT_COUNT || index < 0)) {
753 return 0;
754 }
755 auto activeBackgroundRadius = activeBackgroundRadius_->Get();
756 float handleCircleRadius = std::min(activeBackgroundRadius,
757 sideLength_->Get() / PATTERN_LOCK_COL_COUNT * DIAMETER_TO_RADIUS);
758 activeBackgroundRadius = std::max(handleCircleRadius, 0.0f);
759 if (Positive(activeBackgroundRadius)) {
760 backgroundCircleRadius_.at(index)->Set(activeBackgroundRadius);
761 } else {
762 backgroundCircleRadius_.at(index)->Set(circleRadius_->Get() * scaleBackgroundCircleRadius_);
763 }
764 return backgroundCircleRadius_.at(index)->Get();
765 }
766
SetActiveCircleRadius(int32_t index)767 void PatternLockModifier::SetActiveCircleRadius(int32_t index)
768 {
769 if (index < static_cast<int32_t>(activeCircleRadius_.size()) && index >= 0) {
770 activeCircleRadius_.at(index)->Set(circleRadius_->Get());
771 AnimationOption option = AnimationOption();
772 option.SetDuration(ACTIVE_RADIUS_ANIMATION_DURATION);
773 option.SetCurve(Curves::FRICTION);
774 auto pattern = pattern_.Upgrade();
775 auto host = pattern? pattern->GetHost(): nullptr;
776 auto context = host? host->GetContextRefPtr(): nullptr;
777 AnimationUtils::Animate(
778 option, [&]() { activeCircleRadius_.at(index)->Set(circleRadius_->Get() * scaleActiveCircleRadius_); },
779 nullptr, nullptr, context);
780 }
781 }
782
GetActiveCircleRadius(int32_t index) const783 float PatternLockModifier::GetActiveCircleRadius(int32_t index) const
784 {
785 if ((index >= PATTERN_LOCK_POINT_COUNT || index < 0)) {
786 return 0;
787 }
788 return activeCircleRadius_.at(index)->Get();
789 }
790
SetLightRingCircleRadius(int32_t index)791 void PatternLockModifier::SetLightRingCircleRadius(int32_t index)
792 {
793 if (index < static_cast<int32_t>(lightRingRadius_.size()) && index >= 0) {
794 auto circleRadius = circleRadius_->Get();
795 lightRingRadius_.at(index)->Set(circleRadius * scaleLightRingRadiusStart_);
796 AnimationOption option = AnimationOption();
797 option.SetDuration(LIGHT_RING_RADIUS_ANIMATION_DURATION);
798 option.SetCurve(Curves::LINEAR);
799 auto pattern = pattern_.Upgrade();
800 auto host = pattern? pattern->GetHost(): nullptr;
801 auto context = host? host->GetContextRefPtr(): nullptr;
802 AnimationUtils::Animate(
803 option, [&]() { lightRingRadius_.at(index)->Set(circleRadius * scaleLightRingRadiusEnd_); },
804 nullptr, nullptr, context);
805 }
806 }
807
GetLightRingCircleRadius(int32_t index) const808 float PatternLockModifier::GetLightRingCircleRadius(int32_t index) const
809 {
810 if ((index >= PATTERN_LOCK_POINT_COUNT || index < 0)) {
811 return 0;
812 }
813 return lightRingRadius_.at(index)->Get();
814 }
815
SetLightRingAlphaF(int32_t index)816 void PatternLockModifier::SetLightRingAlphaF(int32_t index)
817 {
818 if (index < static_cast<int32_t>(lightRingAlphaF_.size()) && index >= 0) {
819 auto singleLightRingAlphaF = lightRingAlphaF_.at(index);
820 singleLightRingAlphaF->Set(LIGHT_RING_ALPHAF_START);
821 AnimationOption optionFirst = AnimationOption();
822 optionFirst.SetDuration(LIGHT_RING_ALPHAF_ANIMATION_DURATION_FIRST);
823 optionFirst.SetCurve(Curves::SHARP);
824 auto pattern = pattern_.Upgrade();
825 auto host = pattern? pattern->GetHost(): nullptr;
826 auto context = host? host->GetContextRefPtr(): nullptr;
827 optionFirst.SetOnFinishEvent([=] {
828 AnimationOption optionSecond = AnimationOption();
829 optionSecond.SetDuration(LIGHT_RING_ALPHAF_ANIMATION_DURATION_SECOND);
830 optionSecond.SetCurve(Curves::SHARP);
831 AnimationUtils::Animate(optionSecond, [=]() { singleLightRingAlphaF->Set(LIGHT_RING_ALPHAF_START); },
832 nullptr, nullptr, context);
833 });
834 AnimationUtils::Animate(
835 optionFirst, [&]() { singleLightRingAlphaF->Set(LIGHT_RING_ALPHAF_END); }, optionFirst.GetOnFinishEvent(),
836 nullptr, context);
837 }
838 }
839
GetLightRingAlphaF(int32_t index) const840 float PatternLockModifier::GetLightRingAlphaF(int32_t index) const
841 {
842 if ((index >= PATTERN_LOCK_POINT_COUNT || index < 0)) {
843 return 0;
844 }
845 return lightRingAlphaF_.at(index)->Get();
846 }
847
SetConnectedLineTailPoint(int32_t x,int32_t y)848 void PatternLockModifier::SetConnectedLineTailPoint(int32_t x, int32_t y)
849 {
850 size_t count = choosePoint_.size();
851 if (count < 1) {
852 return;
853 }
854 OffsetF lastPoint = GetCircleCenterByXY(offset_->Get(), x, y);
855 if (isTouchDown_ && isMoveEventValid_) {
856 connectedLineTailPoint_->Set(cellCenter_->Get());
857 AnimationOption option = AnimationOption();
858 auto curve =
859 AceType::MakeRefPtr<ResponsiveSpringMotion>(CONNECTED_LINE_SPRING_RESPONSE, CONNECTED_LINE_SPRING_DAMPING);
860 option.SetCurve(curve);
861 auto pattern = pattern_.Upgrade();
862 auto host = pattern? pattern->GetHost(): nullptr;
863 auto context = host? host->GetContextRefPtr(): nullptr;
864 AnimationUtils::Animate(option, [&]() { connectedLineTailPoint_->Set(lastPoint); }, nullptr, nullptr, context);
865 } else {
866 connectedLineTailPoint_->Set(lastPoint);
867 }
868 }
869
GetConnectedLineTailPoint() const870 OffsetF PatternLockModifier::GetConnectedLineTailPoint() const
871 {
872 return connectedLineTailPoint_->Get();
873 }
874
SetCanceledLineTailPoint()875 void PatternLockModifier::SetCanceledLineTailPoint()
876 {
877 size_t count = choosePoint_.size();
878 if (count < 1) {
879 return;
880 }
881
882 canceledLineTailPoint_->Set(GetPointEndByCellCenter());
883 OffsetF pointEnd =
884 GetCircleCenterByXY(offset_->Get(), choosePoint_[count - 1].GetColumn(), choosePoint_[count - 1].GetRow());
885 AnimationOption option = AnimationOption();
886 auto curve =
887 AceType::MakeRefPtr<ResponsiveSpringMotion>(CANCELED_LINE_SPRING_RESPONSE, CANCELED_LINE_SPRING_DAMPING);
888 option.SetCurve(curve);
889 auto pattern = pattern_.Upgrade();
890 auto host = pattern? pattern->GetHost(): nullptr;
891 auto context = host? host->GetContextRefPtr(): nullptr;
892 AnimationUtils::Animate(option, [&]() { canceledLineTailPoint_->Set(pointEnd); }, nullptr, nullptr, context);
893 }
894
GetCanceledLineTailPoint() const895 OffsetF PatternLockModifier::GetCanceledLineTailPoint() const
896 {
897 return canceledLineTailPoint_->Get();
898 }
899
StartConnectedCircleAnimate(int32_t x,int32_t y)900 void PatternLockModifier::StartConnectedCircleAnimate(int32_t x, int32_t y)
901 {
902 auto index = (x - 1) * PATTERN_LOCK_COL_COUNT + y - 1;
903 SetBackgroundCircleRadius(index);
904 SetActiveCircleRadius(index);
905 if (enableWaveEffect_->Get()) {
906 SetLightRingCircleRadius(index);
907 SetLightRingAlphaF(index);
908 }
909 }
910
StartConnectedLineAnimate(int32_t x,int32_t y)911 void PatternLockModifier::StartConnectedLineAnimate(int32_t x, int32_t y)
912 {
913 SetConnectedLineTailPoint(x, y);
914 }
915
StartCanceledAnimate()916 void PatternLockModifier::StartCanceledAnimate()
917 {
918 SetCanceledLineTailPoint();
919 }
920
Reset()921 void PatternLockModifier::Reset()
922 {
923 SetIsTouchDown(false);
924 needCanceledLine_ = false;
925 challengeResult_.reset();
926 choosePoint_.clear();
927 connectedLineTailPoint_->Set(OffsetF());
928 canceledLineTailPoint_->Set(OffsetF());
929 for (auto& radius : backgroundCircleRadius_) {
930 radius->Set(0.0f);
931 }
932 for (auto& radius : activeCircleRadius_) {
933 radius->Set(circleRadius_->Get());
934 }
935 for (auto& radius : lightRingRadius_) {
936 radius->Set(circleRadius_->Get() * scaleLightRingRadiusStart_);
937 }
938 for (auto& alphaF : lightRingAlphaF_) {
939 alphaF->Set(LIGHT_RING_ALPHAF_START);
940 }
941 }
942
SetIsTouchDown(bool isTouchDown)943 void PatternLockModifier::SetIsTouchDown(bool isTouchDown)
944 {
945 if (isTouchDown_ && (!isTouchDown)) {
946 needCanceledLine_ = true;
947 } else if ((!isTouchDown_) && isTouchDown) {
948 needCanceledLine_ = false;
949 }
950 isTouchDown_ = isTouchDown;
951 }
952
GetPointEndByCellCenter() const953 OffsetF PatternLockModifier::GetPointEndByCellCenter() const
954 {
955 auto offset = offset_->Get();
956 float sideLength = sideLength_->Get();
957 auto cellCenter = cellCenter_->Get();
958 float x = cellCenter.GetX();
959 float y = cellCenter.GetY();
960 x = x > offset.GetX() + sideLength ? offset.GetX() + sideLength : x;
961 x = x < offset.GetX() ? offset.GetX() : x;
962 y = y > offset.GetY() + sideLength ? offset.GetY() + sideLength : y;
963 y = y < offset.GetY() ? offset.GetY() : y;
964 return OffsetF(x, y);
965 }
966
SetCircleClip(RSCanvas & canvas)967 void PatternLockModifier::SetCircleClip(RSCanvas& canvas)
968 {
969 int32_t x = 0;
970 int32_t y = 0;
971 int32_t index = 0;
972 OffsetF center;
973 float backgroundCircleRadius = 0.0f;
974 float activeCircleRadius = 0.0f;
975 float clipRadius = 0.0f;
976 RSPath path;
977 for (const auto& point : choosePoint_) {
978 x = point.GetColumn();
979 y = point.GetRow();
980 center = GetCircleCenterByXY(offset_->Get(), x, y);
981 index = (x - 1) * PATTERN_LOCK_COL_COUNT + y - 1;
982 backgroundCircleRadius = GetBackgroundCircleRadius(index);
983 activeCircleRadius = GetActiveCircleRadius(index);
984 clipRadius = backgroundCircleRadius > activeCircleRadius ? backgroundCircleRadius : activeCircleRadius;
985 path.AddCircle(center.GetX(), center.GetY(), clipRadius);
986 }
987 canvas.ClipPath(path, RSClipOp::DIFFERENCE, true);
988 }
989
UpdateBoundsRect()990 void PatternLockModifier::UpdateBoundsRect()
991 {
992 auto offset = offset_->Get();
993 auto pathStrokeWidth = pathStrokeWidth_->Get();
994 auto sideLength = sideLength_->Get();
995
996 float handleStrokeWidth = std::min(pathStrokeWidth, sideLength / PATTERN_LOCK_COL_COUNT);
997 pathStrokeWidth = std::max(handleStrokeWidth, 0.0f);
998
999 auto addDistance = circleRadius_->Get() * scaleLightRingRadiusEnd_ -
1000 sideLength_->Get() / PATTERN_LOCK_COL_COUNT / RADIUS_TO_DIAMETER;
1001 if (pathStrokeWidth / 2.0f > addDistance) {
1002 addDistance = pathStrokeWidth / 2.0f;
1003 }
1004
1005 RectF boundsRect;
1006 boundsRect.SetLeft((offset.GetX() - addDistance) < 0 ? (offset.GetX() - addDistance) : 0);
1007 boundsRect.SetTop((offset.GetY() - addDistance) < 0 ? (offset.GetY() - addDistance) : 0);
1008 boundsRect.SetWidth(sideLength + addDistance * 2.0f);
1009 boundsRect.SetHeight(sideLength + addDistance * 2.0f);
1010 SetBoundsRect(boundsRect);
1011 }
1012 } // namespace OHOS::Ace::NG
1013