1
1
using System ;
2
+ using System . Collections . Generic ;
2
3
using System . Globalization ;
3
4
using System . IO ;
4
5
using System . Security . Cryptography ;
5
6
using System . Text ;
6
7
7
8
using Avalonia ;
8
9
using Avalonia . Controls ;
10
+ using Avalonia . Data ;
9
11
using Avalonia . Interactivity ;
10
12
using Avalonia . Media ;
11
13
using Avalonia . Media . Imaging ;
@@ -24,9 +26,25 @@ public Models.User User
24
26
set => SetValue ( UserProperty , value ) ;
25
27
}
26
28
29
+ public static readonly StyledProperty < bool > UseGitHubStyleAvatarProperty =
30
+ AvaloniaProperty . Register < Avatar , bool > ( nameof ( UseGitHubStyleAvatar ) ) ;
31
+
32
+ public bool UseGitHubStyleAvatar
33
+ {
34
+ get => GetValue ( UseGitHubStyleAvatarProperty ) ;
35
+ set => SetValue ( UseGitHubStyleAvatarProperty , value ) ;
36
+ }
37
+
27
38
public Avatar ( )
28
39
{
29
40
RenderOptions . SetBitmapInterpolationMode ( this , BitmapInterpolationMode . HighQuality ) ;
41
+
42
+ this . Bind ( UseGitHubStyleAvatarProperty , new Binding ( )
43
+ {
44
+ Mode = BindingMode . OneWay ,
45
+ Source = ViewModels . Preferences . Instance ,
46
+ Path = "UseGitHubStyleAvatar"
47
+ } ) ;
30
48
}
31
49
32
50
public override void Render ( DrawingContext context )
@@ -42,6 +60,34 @@ public override void Render(DrawingContext context)
42
60
{
43
61
context . DrawImage ( _img , rect ) ;
44
62
}
63
+ else if ( ! UseGitHubStyleAvatar )
64
+ {
65
+ var fallback = GetFallbackString ( User . Name ) ;
66
+ var typeface = new Typeface ( "fonts:SourceGit#JetBrains Mono" ) ;
67
+ var label = new FormattedText (
68
+ fallback ,
69
+ CultureInfo . CurrentCulture ,
70
+ FlowDirection . LeftToRight ,
71
+ typeface ,
72
+ Bounds . Width * 0.65 ,
73
+ Brushes . White ) ;
74
+
75
+ var chars = fallback . ToCharArray ( ) ;
76
+ var sum = 0 ;
77
+ foreach ( var c in chars )
78
+ sum += Math . Abs ( c ) ;
79
+
80
+ var bg = new LinearGradientBrush ( )
81
+ {
82
+ GradientStops = FALLBACK_GRADIENTS [ sum % FALLBACK_GRADIENTS . Length ] ,
83
+ StartPoint = new RelativePoint ( 0 , 0 , RelativeUnit . Relative ) ,
84
+ EndPoint = new RelativePoint ( 0 , 1 , RelativeUnit . Relative ) ,
85
+ } ;
86
+
87
+ Point textOrigin = new Point ( ( Bounds . Width - label . Width ) * 0.5 , ( Bounds . Height - label . Height ) * 0.5 ) ;
88
+ context . DrawRectangle ( bg , null , new Rect ( 0 , 0 , Bounds . Width , Bounds . Height ) , corner , corner ) ;
89
+ context . DrawText ( label , textOrigin ) ;
90
+ }
45
91
else
46
92
{
47
93
context . DrawRectangle ( Brushes . White , new Pen ( new SolidColorBrush ( Colors . Black , 0.3f ) , 0.65f ) , rect , corner , corner ) ;
@@ -130,6 +176,11 @@ protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs chang
130
176
_img = Models . AvatarManager . Instance . Request ( User . Email , false ) ;
131
177
InvalidateVisual ( ) ;
132
178
}
179
+ else if ( change . Property == UseGitHubStyleAvatarProperty )
180
+ {
181
+ if ( _img == null )
182
+ InvalidateVisual ( ) ;
183
+ }
133
184
}
134
185
135
186
private void OnContextRequested ( object sender , ContextRequestedEventArgs e )
@@ -220,6 +271,30 @@ private void OnContextRequested(object sender, ContextRequestedEventArgs e)
220
271
menu . Open ( this ) ;
221
272
}
222
273
274
+ private string GetFallbackString ( string name )
275
+ {
276
+ if ( string . IsNullOrWhiteSpace ( name ) )
277
+ return "?" ;
278
+
279
+ var parts = name . Split ( ' ' , StringSplitOptions . RemoveEmptyEntries ) ;
280
+ var chars = new List < char > ( ) ;
281
+ foreach ( var part in parts )
282
+ chars . Add ( part [ 0 ] ) ;
283
+
284
+ if ( chars . Count >= 2 && char . IsAsciiLetterOrDigit ( chars [ 0 ] ) && char . IsAsciiLetterOrDigit ( chars [ ^ 1 ] ) )
285
+ return string . Format ( "{0}{1}" , chars [ 0 ] , chars [ ^ 1 ] ) ;
286
+
287
+ return name . Substring ( 0 , 1 ) ;
288
+ }
289
+
290
+ private static readonly GradientStops [ ] FALLBACK_GRADIENTS = [
291
+ new GradientStops ( ) { new GradientStop ( Colors . Orange , 0 ) , new GradientStop ( Color . FromRgb ( 255 , 213 , 134 ) , 1 ) } ,
292
+ new GradientStops ( ) { new GradientStop ( Colors . DodgerBlue , 0 ) , new GradientStop ( Colors . LightSkyBlue , 1 ) } ,
293
+ new GradientStops ( ) { new GradientStop ( Colors . LimeGreen , 0 ) , new GradientStop ( Color . FromRgb ( 124 , 241 , 124 ) , 1 ) } ,
294
+ new GradientStops ( ) { new GradientStop ( Colors . Orchid , 0 ) , new GradientStop ( Color . FromRgb ( 248 , 161 , 245 ) , 1 ) } ,
295
+ new GradientStops ( ) { new GradientStop ( Colors . Tomato , 0 ) , new GradientStop ( Color . FromRgb ( 252 , 165 , 150 ) , 1 ) } ,
296
+ ] ;
297
+
223
298
private Bitmap _img = null ;
224
299
}
225
300
}
0 commit comments