1
+ using System ;
2
+ using Unity . UIWidgets . animation ;
3
+ using Unity . UIWidgets . foundation ;
4
+ using Unity . UIWidgets . ui ;
5
+ using Unity . UIWidgets . widgets ;
6
+ using UnityEngine ;
7
+ using Canvas = Unity . UIWidgets . ui . Canvas ;
8
+ using Color = Unity . UIWidgets . ui . Color ;
9
+
10
+ namespace Unity . UIWidgets . cupertino {
11
+ static class CupertinoActivityIndicatorUtils {
12
+ public const float _kDefaultIndicatorRadius = 10.0f ;
13
+ public const float _kTwoPI = Mathf . PI * 2.0f ;
14
+ public const int _kTickCount = 12 ;
15
+ public const int _kHalfTickCount = _kTickCount / 2 ;
16
+ public static readonly Color _kTickColor = CupertinoColors . lightBackgroundGray ;
17
+ public static readonly Color _kActiveTickColor = new Color ( 0xFF9D9D9D ) ;
18
+ }
19
+
20
+ public class CupertinoActivityIndicator : StatefulWidget {
21
+ public CupertinoActivityIndicator (
22
+ Key key = null ,
23
+ bool animating = true ,
24
+ float radius = CupertinoActivityIndicatorUtils . _kDefaultIndicatorRadius
25
+ ) : base ( key : key ) {
26
+ D . assert ( radius > 0 ) ;
27
+ this . animating = animating ;
28
+ this . radius = radius ;
29
+ }
30
+
31
+ public readonly bool animating ;
32
+ public readonly float radius ;
33
+
34
+ public override State createState ( ) {
35
+ return new _CupertinoActivityIndicatorState ( ) ;
36
+ }
37
+ }
38
+
39
+ class _CupertinoActivityIndicatorState : TickerProviderStateMixin < CupertinoActivityIndicator > {
40
+ AnimationController _controller ;
41
+
42
+ public override void initState ( ) {
43
+ base . initState ( ) ;
44
+ this . _controller = new AnimationController (
45
+ duration : TimeSpan . FromSeconds ( 1 ) ,
46
+ vsync : this
47
+ ) ;
48
+
49
+ if ( this . widget . animating ) {
50
+ this . _controller . repeat ( ) ;
51
+ }
52
+ }
53
+
54
+ public override void didUpdateWidget ( StatefulWidget oldWidget ) {
55
+ base . didUpdateWidget ( oldWidget : oldWidget ) ;
56
+ if ( oldWidget is CupertinoActivityIndicator _oldWidget ) {
57
+ if ( this . widget . animating != _oldWidget . animating ) {
58
+ if ( this . widget . animating ) {
59
+ this . _controller . repeat ( ) ;
60
+ }
61
+ else {
62
+ this . _controller . stop ( ) ;
63
+ }
64
+ }
65
+ }
66
+ }
67
+
68
+ public override void dispose ( ) {
69
+ this . _controller . dispose ( ) ;
70
+ base . dispose ( ) ;
71
+ }
72
+
73
+ public override Widget build ( BuildContext context ) {
74
+ return new SizedBox (
75
+ height : this . widget . radius * 2 ,
76
+ width : this . widget . radius * 2 ,
77
+ child : new CustomPaint (
78
+ painter : new _CupertinoActivityIndicatorPainter (
79
+ position : this . _controller ,
80
+ radius : this . widget . radius
81
+ )
82
+ )
83
+ ) ;
84
+ }
85
+ }
86
+
87
+ class _CupertinoActivityIndicatorPainter : AbstractCustomPainter {
88
+ public _CupertinoActivityIndicatorPainter (
89
+ Animation < float > position ,
90
+ float radius
91
+ ) : base ( repaint : position ) {
92
+ this . tickFundamentalRRect = RRect . fromLTRBXY (
93
+ left : - radius ,
94
+ top : 1.0f * radius / CupertinoActivityIndicatorUtils . _kDefaultIndicatorRadius ,
95
+ right : - radius / 2.0f ,
96
+ bottom : - 1.0f * radius / CupertinoActivityIndicatorUtils . _kDefaultIndicatorRadius ,
97
+ radiusX : 1.0f ,
98
+ radiusY : 1.0f
99
+ ) ;
100
+ this . position = position ;
101
+ }
102
+
103
+ readonly Animation < float > position ;
104
+ readonly RRect tickFundamentalRRect ;
105
+
106
+ public override void paint ( Canvas canvas , Size size ) {
107
+ Paint paint = new Paint ( ) ;
108
+
109
+ canvas . save ( ) ;
110
+ canvas . translate ( size . width / 2.0f , size . height / 2.0f ) ;
111
+
112
+ int activeTick = ( CupertinoActivityIndicatorUtils . _kTickCount * this . position . value ) . floor ( ) ;
113
+
114
+ for ( int i = 0 ; i < CupertinoActivityIndicatorUtils . _kTickCount ; ++ i ) {
115
+ float t = ( ( ( i + activeTick ) % CupertinoActivityIndicatorUtils . _kTickCount ) /
116
+ CupertinoActivityIndicatorUtils . _kHalfTickCount ) . clamp ( 0 , 1 ) ;
117
+ paint . color = Color . lerp ( a : CupertinoActivityIndicatorUtils . _kActiveTickColor ,
118
+ b : CupertinoActivityIndicatorUtils . _kTickColor , t : t ) ;
119
+ canvas . drawRRect ( rect : this . tickFundamentalRRect , paint : paint ) ;
120
+ canvas . rotate ( - CupertinoActivityIndicatorUtils . _kTwoPI / CupertinoActivityIndicatorUtils . _kTickCount ) ;
121
+ }
122
+
123
+ canvas . restore ( ) ;
124
+ }
125
+
126
+ public override bool shouldRepaint ( CustomPainter oldPainter ) {
127
+ return ( oldPainter as _CupertinoActivityIndicatorPainter ) . position != this . position ;
128
+ }
129
+ }
130
+ }
0 commit comments