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