@@ -41,25 +41,35 @@ public partial class PullRequestStatusCircle : UserControl
4141 "InnerRadius" , typeof ( double ) , typeof ( PullRequestStatusCircle ) ,
4242 new PropertyMetadata ( ( double ) 200 , ( d , args ) => ( ( PullRequestStatusCircle ) d ) . InnerRadius = ( double ) args . NewValue ) ) ;
4343
44- public static IEnumerable < Point > GeneratePoints ( double diameter , float percentage )
44+ public IEnumerable < Point > GeneratePoints ( float percentage )
4545 {
46+ double ToRadians ( float val )
47+ {
48+ return ( Math . PI / 180 ) * val ;
49+ }
50+
4651 if ( float . IsNaN ( percentage ) )
4752 {
4853 return Array . Empty < Point > ( ) ;
4954 }
5055
5156 if ( percentage < 0 || percentage > 1 )
5257 {
53- throw new ArgumentException ( $@ "` { nameof ( percentage ) } ` must be >=0 and <=1" , nameof ( percentage ) ) ;
58+ throw new ArgumentException ( ) ;
5459 }
5560
56- var radius = diameter / 2 ;
57- var origin = new Point ( radius , radius ) ;
58- var topMiddle = new Point ( radius , 0 ) ;
59- var topRight = new Point ( diameter , 0 ) ;
60- var bottomRight = new Point ( diameter , diameter ) ;
61- var bottomLeft = new Point ( 0 , diameter ) ;
62- var topLeft = new Point ( 0 , 0 ) ;
61+ var diameter = Diameter ;
62+
63+ var leftEdge = XAdjust ;
64+ var rightEdge = diameter + XAdjust ;
65+ var topEdge = YAdjust ;
66+ var bottomEdge = diameter + YAdjust ;
67+
68+ var topMiddle = new Point ( Origin . X , topEdge ) ;
69+ var topRight = new Point ( rightEdge , topEdge ) ;
70+ var bottomRight = new Point ( rightEdge , bottomEdge ) ;
71+ var bottomLeft = new Point ( leftEdge , bottomEdge ) ;
72+ var topLeft = new Point ( leftEdge , topEdge ) ;
6373
6474 if ( percentage == 1 )
6575 {
@@ -74,118 +84,118 @@ public static IEnumerable<Point> GeneratePoints(double diameter, float percentag
7484 var angleDegrees = adjustedDegrees - 90 ;
7585 var angleRadians = ToRadians ( angleDegrees ) ;
7686 var tan = Math . Tan ( angleRadians ) ;
77- var oppositeEdge = tan * radius ;
78- return new [ ] { origin , topMiddle , new Point ( radius + oppositeEdge , 0 ) } ;
87+ var oppositeEdge = tan * Radius ;
88+ return new [ ] { Origin , topMiddle , new Point ( topMiddle . X + oppositeEdge , topMiddle . Y ) } ;
7989 }
8090
8191 if ( adjustedDegrees >= 135 && adjustedDegrees < 180 )
8292 {
8393 var angleDegrees = adjustedDegrees - 135 ;
8494 var angleRadians = ToRadians ( angleDegrees ) ;
8595 var tan = Math . Tan ( angleRadians ) ;
86- var oppositeEdge = tan * radius ;
87- return new [ ] { origin , topMiddle , topRight , new Point ( diameter , oppositeEdge ) } ;
96+ var oppositeEdge = tan * Radius ;
97+ return new [ ] { Origin , topMiddle , topRight , new Point ( topRight . X , topRight . Y + oppositeEdge ) } ;
8898 }
8999
90100 if ( adjustedDegrees >= 180 && adjustedDegrees < 225 )
91101 {
92102 var angleDegrees = adjustedDegrees - 180 ;
93103 var angleRadians = ToRadians ( angleDegrees ) ;
94104 var tan = Math . Tan ( angleRadians ) ;
95- var oppositeEdge = tan * radius ;
96- return new [ ] { origin , topMiddle , topRight , new Point ( diameter , radius + oppositeEdge ) } ;
105+ var oppositeEdge = tan * Radius ;
106+ return new [ ] { Origin , topMiddle , topRight , new Point ( topRight . X , topRight . Y + Radius + oppositeEdge ) } ;
97107 }
98108
99109 if ( adjustedDegrees >= 225 && adjustedDegrees < 270 )
100110 {
101111 var angleDegrees = adjustedDegrees - 225 ;
102112 var angleRadians = ToRadians ( angleDegrees ) ;
103113 var tan = Math . Tan ( angleRadians ) ;
104- var oppositeEdge = tan * radius ;
105- return new [ ] { origin , topMiddle , topRight , bottomRight , new Point ( diameter - oppositeEdge , diameter ) } ;
114+ var oppositeEdge = tan * Radius ;
115+ return new [ ] { Origin , topMiddle , topRight , bottomRight , new Point ( bottomRight . X - oppositeEdge , bottomRight . Y ) } ;
106116 }
107117
108118 if ( adjustedDegrees >= 270 && adjustedDegrees < 315 )
109119 {
110120 var angleDegrees = adjustedDegrees - 270 ;
111121 var angleRadians = ToRadians ( angleDegrees ) ;
112122 var tan = Math . Tan ( angleRadians ) ;
113- var oppositeEdge = tan * radius ;
114- return new [ ] { origin , topMiddle , topRight , bottomRight , new Point ( radius - oppositeEdge , diameter ) } ;
123+ var oppositeEdge = tan * Radius ;
124+ return new [ ] { Origin , topMiddle , topRight , bottomRight , new Point ( bottomRight . X - Radius - oppositeEdge , bottomRight . Y ) } ;
115125 }
116126
117127 if ( adjustedDegrees >= 315 && adjustedDegrees < 360 )
118128 {
119129 var angleDegrees = adjustedDegrees - 315 ;
120130 var angleRadians = ToRadians ( angleDegrees ) ;
121131 var tan = Math . Tan ( angleRadians ) ;
122- var oppositeEdge = tan * radius ;
123- return new [ ] { origin , topMiddle , topRight , bottomRight , bottomLeft , new Point ( 0 , diameter - oppositeEdge ) } ;
132+ var oppositeEdge = tan * Radius ;
133+ return new [ ] { Origin , topMiddle , topRight , bottomRight , bottomLeft , new Point ( bottomLeft . X , bottomLeft . Y - oppositeEdge ) } ;
124134 }
125135
126136 if ( adjustedDegrees >= 0 && adjustedDegrees < 45 )
127137 {
128138 var angleDegrees = adjustedDegrees ;
129139 var angleRadians = ToRadians ( angleDegrees ) ;
130140 var tan = Math . Tan ( angleRadians ) ;
131- var oppositeEdge = tan * radius ;
132- return new [ ] { origin , topMiddle , topRight , bottomRight , bottomLeft , new Point ( 0 , radius - oppositeEdge ) } ;
141+ var oppositeEdge = tan * Radius ;
142+ return new [ ] { Origin , topMiddle , topRight , bottomRight , bottomLeft , new Point ( bottomLeft . X , bottomLeft . Y - Radius - oppositeEdge ) } ;
133143 }
134144
135145 if ( adjustedDegrees >= 45 && adjustedDegrees < 90 )
136146 {
137147 var angleDegrees = adjustedDegrees - 45 ;
138148 var angleRadians = ToRadians ( angleDegrees ) ;
139149 var tan = Math . Tan ( angleRadians ) ;
140- var oppositeEdge = tan * radius ;
141- return new [ ] { origin , topMiddle , topRight , bottomRight , bottomLeft , topLeft , new Point ( oppositeEdge , 0 ) } ;
150+ var oppositeEdge = tan * Radius ;
151+ return new [ ] { Origin , topMiddle , topRight , bottomRight , bottomLeft , topLeft , new Point ( topLeft . X + oppositeEdge , topLeft . Y ) } ;
142152 }
143153
144154 throw new InvalidOperationException ( ) ;
145155 }
146156
147- public static double ToRadians ( float val )
148- {
149- return ( Math . PI / 180 ) * val ;
150- }
151-
152157 public PullRequestStatusCircle ( )
153158 {
154159 InitializeComponent ( ) ;
155160 GeneratePolygons ( ) ;
156- ComputeMask ( ) ;
161+ GenerateMask ( ) ;
157162 }
158163
159164 private void GeneratePolygons ( )
160165 {
161- ErrorPolygon . Points = new PointCollection ( GeneratePoints ( Radius * 2 , ( float ) ErrorCount / TotalCount ) ) ;
162- SuccessPolygon . Points = new PointCollection ( GeneratePoints ( Radius * 2 , ( float ) ( SuccessCount + ErrorCount ) / TotalCount ) ) ;
163- PendingPolygon . Points = new PointCollection ( GeneratePoints ( Radius * 2 , ( float ) ( SuccessCount + ErrorCount + PendingCount ) / TotalCount ) ) ;
166+ ErrorPolygon . Points = new PointCollection ( GeneratePoints ( ( float ) ErrorCount / TotalCount ) ) ;
167+ SuccessPolygon . Points = new PointCollection ( GeneratePoints ( ( float ) ( SuccessCount + ErrorCount ) / TotalCount ) ) ;
168+ PendingPolygon . Points = new PointCollection ( GeneratePoints ( ( float ) ( SuccessCount + ErrorCount + PendingCount ) / TotalCount ) ) ;
164169 }
165170
166- private void ComputeMask ( )
171+ private void GenerateMask ( )
167172 {
168173 var pendingPolygonClip = new CombinedGeometry (
169174 GeometryCombineMode . Exclude ,
170- new EllipseGeometry ( Center , Radius , Radius ) ,
171- new EllipseGeometry ( Center , InnerRadius , InnerRadius ) ) ;
175+ new EllipseGeometry ( Origin , Radius , Radius ) ,
176+ new EllipseGeometry ( Origin , InnerRadius , InnerRadius ) ) ;
172177
173178 PendingPolygon . Clip = pendingPolygonClip ;
174179 SuccessPolygon . Clip = pendingPolygonClip ;
175180 ErrorPolygon . Clip = pendingPolygonClip ;
176181 }
177182
178- private int TotalCount => ErrorCount + SuccessCount + PendingCount ;
183+ private Point Origin => new Point ( Radius + XAdjust , Radius + YAdjust ) ;
184+
185+ private double Diameter => Radius * 2 ;
179186
180- private Point Center => new Point ( Radius , Radius ) ;
187+ private double XAdjust => ( ActualWidth - Diameter ) / 2 ;
188+
189+ private double YAdjust => ( ActualHeight - Diameter ) / 2 ;
190+
191+ private int TotalCount => ErrorCount + SuccessCount + PendingCount ;
181192
182193 public int ErrorCount
183194 {
184195 get => ( int ) GetValue ( ErrorCountProperty ) ;
185196 set
186197 {
187198 SetValue ( ErrorCountProperty , value ) ;
188- ComputeMask ( ) ;
189199 GeneratePolygons ( ) ;
190200 }
191201 }
@@ -196,7 +206,6 @@ public int SuccessCount
196206 set
197207 {
198208 SetValue ( SuccessCountProperty , value ) ;
199- ComputeMask ( ) ;
200209 GeneratePolygons ( ) ;
201210 }
202211 }
@@ -207,7 +216,6 @@ public int PendingCount
207216 set
208217 {
209218 SetValue ( PendingCountProperty , value ) ;
210- ComputeMask ( ) ;
211219 GeneratePolygons ( ) ;
212220 }
213221 }
@@ -218,7 +226,7 @@ public double Radius
218226 set
219227 {
220228 SetValue ( RadiusProperty , value ) ;
221- ComputeMask ( ) ;
229+ GenerateMask ( ) ;
222230 GeneratePolygons ( ) ;
223231 }
224232 }
@@ -229,7 +237,17 @@ public double InnerRadius
229237 set
230238 {
231239 SetValue ( InnerRadiusProperty , value ) ;
232- ComputeMask ( ) ;
240+ GenerateMask ( ) ;
241+ GeneratePolygons ( ) ;
242+ }
243+ }
244+
245+ protected override void OnRenderSizeChanged ( SizeChangedInfo sizeInfo )
246+ {
247+ base . OnRenderSizeChanged ( sizeInfo ) ;
248+ if ( sizeInfo . WidthChanged || sizeInfo . HeightChanged )
249+ {
250+ GenerateMask ( ) ;
233251 GeneratePolygons ( ) ;
234252 }
235253 }
0 commit comments