33using Plugin . InputKit . Shared . Helpers ;
44using Plugin . InputKit . Shared . Layouts ;
55using System ;
6- using System . Runtime . CompilerServices ;
76using System . Windows . Input ;
87using Xamarin . Forms ;
8+ using Xamarin . Forms . Shapes ;
9+ using Rectangle = Xamarin . Forms . Shapes . Rectangle ;
910
1011namespace Plugin . InputKit . Shared . Controls
1112{
@@ -22,25 +23,46 @@ public partial class CheckBox : StatefulStackLayout, IValidatable
2223 {
2324 BackgroundColor = Color . Transparent ,
2425 Color = InputKitOptions . GetAccentColor ( ) ,
25- BorderColor = Color . Black ,
26+ BorderColor = Application . Current . RequestedTheme == OSAppTheme . Dark ? Color . WhiteSmoke : Color . Black ,
2627 TextColor = ( Color ) Label . TextColorProperty . DefaultValue ,
2728 Size = 25 ,
28- CornerRadius = 4 ,
29+ CornerRadius = 2 ,
2930 FontSize = 14 ,
3031 LabelPosition = LabelPosition . After
3132 } ;
3233
3334 #region Constants
34- public const string RESOURCE_CHECK = "Plugin.InputKit.Shared.Resources.check.png" ;
35- public const string RESOURCE_CROSS = "Plugin.InputKit.Shared.Resources.cross.png" ;
36- public const string RESOURCE_STAR = "Plugin.InputKit.Shared.Resources.star.png" ;
35+ internal const double CHECK_SIZE_RATIO = .65 ;
3736 #endregion
3837
3938 #region Fields
40- protected internal Frame frmBackground = new Frame { Padding = 0 , CornerRadius = GlobalSetting . CornerRadius , InputTransparent = true , HeightRequest = GlobalSetting . Size , WidthRequest = GlobalSetting . Size , BackgroundColor = GlobalSetting . BackgroundColor , MinimumWidthRequest = 35 , BorderColor = GlobalSetting . BorderColor , VerticalOptions = LayoutOptions . CenterAndExpand , HasShadow = false } ;
41- protected internal BoxView boxSelected = new BoxView { IsVisible = false , HeightRequest = GlobalSetting . Size * .60 , WidthRequest = GlobalSetting . Size * .60 , Color = GlobalSetting . Color , VerticalOptions = LayoutOptions . CenterAndExpand , HorizontalOptions = LayoutOptions . Center } ;
42- protected internal IconView imgSelected = new IconView { Source = ImageSource . FromResource ( RESOURCE_CHECK ) , FillColor = GlobalSetting . Color , VerticalOptions = LayoutOptions . CenterAndExpand , HorizontalOptions = LayoutOptions . Center , IsVisible = false } ;
43- internal Label lblOption = new Label { VerticalOptions = LayoutOptions . CenterAndExpand , FontSize = GlobalSetting . FontSize , TextColor = GlobalSetting . TextColor , FontFamily = GlobalSetting . FontFamily , IsVisible = false } ;
39+ protected internal Grid IconLayout ;
40+ protected Rectangle outlineBox = new Rectangle
41+ {
42+ Fill = GlobalSetting . BackgroundColor . ToBrush ( ) ,
43+ Stroke = GlobalSetting . BorderColor . ToBrush ( ) ,
44+ StrokeThickness = 2 ,
45+ WidthRequest = GlobalSetting . Size ,
46+ HeightRequest = GlobalSetting . Size ,
47+ RadiusX = GlobalSetting . CornerRadius ,
48+ } ;
49+ protected Path selectedIcon = new Path
50+ {
51+ Fill = GlobalSetting . Color . ToBrush ( ) ,
52+ Aspect = Stretch . Uniform ,
53+ HeightRequest = GlobalSetting . Size ,
54+ WidthRequest = GlobalSetting . Size ,
55+ Scale = 0 ,
56+ } ;
57+ protected internal Label lblOption = new Label
58+ {
59+ VerticalOptions = LayoutOptions . Center ,
60+ HorizontalOptions = LayoutOptions . Start ,
61+ FontSize = GlobalSetting . FontSize ,
62+ TextColor = GlobalSetting . TextColor ,
63+ FontFamily = GlobalSetting . FontFamily ,
64+ IsVisible = false
65+ } ;
4466 private CheckType _type = CheckType . Box ;
4567 private bool _isEnabled ;
4668 #endregion
@@ -53,18 +75,27 @@ public CheckBox()
5375 {
5476 InitVisualStates ( ) ;
5577 Orientation = StackOrientation . Horizontal ;
56- Padding = new Thickness ( 0 , 10 ) ;
5778 Spacing = 10 ;
58- frmBackground . Content = boxSelected ;
59- ApplyLabelPosition ( LabelPosition ) ;
79+ Padding = new Thickness ( 0 , 10 ) ;
6080 ApplyIsCheckedAction = ApplyIsChecked ;
6181 ApplyIsPressedAction = ApplyIsPressed ;
82+
83+ IconLayout = new Grid
84+ {
85+ Children =
86+ {
87+ outlineBox ,
88+ selectedIcon
89+ }
90+ } ;
91+
92+ ApplyLabelPosition ( LabelPosition ) ;
93+ UpdateType ( ) ;
94+ UpdateShape ( ) ;
6295 GestureRecognizers . Add ( new TapGestureRecognizer
6396 {
6497 Command = new Command ( ( ) => { if ( IsDisabled ) return ; IsChecked = ! IsChecked ; ExecuteCommand ( ) ; CheckChanged ? . Invoke ( this , new EventArgs ( ) ) ; ValidationChanged ? . Invoke ( this , new EventArgs ( ) ) ; } ) ,
6598 } ) ;
66-
67- imgSelected . WidthRequest = 15 ;
6899 }
69100
70101 /// <summary>
@@ -159,17 +190,17 @@ public Color Color
159190 /// <summary>
160191 /// Which icon will be shown when checkbox is checked
161192 /// </summary>
162- public CheckType Type { get => _type ; set { _type = value ; UpdateType ( value ) ; } }
193+ public CheckType Type { get => _type ; set { _type = value ; UpdateType ( ) ; } }
163194
164195 /// <summary>
165196 /// Size of Checkbox
166197 /// </summary>
167- public double BoxSize { get => frmBackground . Width ; }
198+ public double BoxSize { get => outlineBox . Width ; }
168199
169200 /// <summary>
170201 /// SizeRequest of CheckBox
171202 /// </summary>
172- public double BoxSizeRequest { get => frmBackground . WidthRequest ; set => SetBoxSize ( value ) ; }
203+ public double BoxSizeRequest { get => outlineBox . WidthRequest ; set => SetBoxSize ( value ) ; }
173204
174205 /// <summary>
175206 /// Fontsize of Checkbox text
@@ -200,7 +231,11 @@ public Color Color
200231 /// </summary>
201232 public string FontFamily { get => ( string ) GetValue ( FontFamilyProperty ) ; set => SetValue ( FontFamilyProperty , value ) ; }
202233
203- public ImageSource CustomIcon { get => ( ImageSource ) GetValue ( CustomIconProperty ) ; set => SetValue ( CustomIconProperty , value ) ; }
234+ [ Obsolete ( "This option is removed. Use CustomIconGeometry" ) ]
235+ public ImageSource CustomIcon { get => default ; set { } }
236+
237+ [ TypeConverter ( typeof ( PathGeometryConverter ) ) ]
238+ public Geometry IconGeometry { get => ( Geometry ) GetValue ( IconGeometryProperty ) ; set => SetValue ( IconGeometryProperty , value ) ; }
204239
205240 public bool IsPressed { get ; set ; }
206241 /// <summary>
@@ -232,9 +267,9 @@ public LabelPosition LabelPosition
232267 public static readonly BindableProperty TextFontSizeProperty = BindableProperty . Create ( nameof ( TextFontSize ) , typeof ( double ) , typeof ( CheckBox ) , GlobalSetting . FontSize , propertyChanged : ( bo , ov , nv ) => ( bo as CheckBox ) . TextFontSize = ( double ) nv ) ;
233268 public static readonly BindableProperty BorderColorProperty = BindableProperty . Create ( nameof ( BorderColor ) , typeof ( Color ) , typeof ( CheckBox ) , GlobalSetting . BorderColor , propertyChanged : ( bo , ov , nv ) => ( bo as CheckBox ) . UpdateBorderColor ( ) ) ;
234269 public static readonly BindableProperty FontFamilyProperty = BindableProperty . Create ( nameof ( FontFamily ) , typeof ( string ) , typeof ( CheckBox ) , Label . FontFamilyProperty . DefaultValue , propertyChanged : ( bo , ov , nv ) => ( bo as CheckBox ) . UpdateFontFamily ( nv ? . ToString ( ) ) ) ;
235- public static readonly BindableProperty CustomIconProperty = BindableProperty . Create ( nameof ( CustomIcon ) , typeof ( ImageSource ) , typeof ( CheckBox ) , default ( ImageSource ) , propertyChanged : ( bo , ov , nv ) => ( bo as CheckBox ) . UpdateType ( ( bo as CheckBox ) . Type ) ) ;
270+ public static readonly BindableProperty IconGeometryProperty = BindableProperty . Create ( nameof ( IconGeometry ) , typeof ( Geometry ) , typeof ( CheckBox ) , defaultValue : PredefinedShapes . Check , propertyChanged : ( bo , ov , nv ) => ( bo as CheckBox ) . UpdateShape ( ) ) ;
236271 public static readonly BindableProperty IsPressedProperty = BindableProperty . Create ( nameof ( IsPressed ) , typeof ( bool ) , typeof ( CheckBox ) , propertyChanged : ( bo , ov , nv ) => ( bo as CheckBox ) . ApplyIsPressedAction ( bo as CheckBox , ( bool ) nv ) ) ;
237- public static readonly BindableProperty CornerRadiusProperty = BindableProperty . Create ( nameof ( CornerRadius ) , typeof ( float ) , typeof ( CheckBox ) , GlobalSetting . CornerRadius , propertyChanged : ( bo , ov , nv ) => ( bo as CheckBox ) . frmBackground . CornerRadius = ( float ) nv ) ;
272+ public static readonly BindableProperty CornerRadiusProperty = BindableProperty . Create ( nameof ( CornerRadius ) , typeof ( float ) , typeof ( CheckBox ) , GlobalSetting . CornerRadius , propertyChanged : ( bo , ov , nv ) => ( bo as CheckBox ) . outlineBox . RadiusX = ( float ) nv ) ;
238273 public static readonly BindableProperty LabelPositionProperty = BindableProperty . Create (
239274 propertyName : nameof ( LabelPosition ) , declaringType : typeof ( CheckBox ) ,
240275 returnType : typeof ( LabelPosition ) , defaultBindingMode : BindingMode . TwoWay ,
@@ -250,14 +285,14 @@ void ApplyLabelPosition(LabelPosition position)
250285 if ( position == LabelPosition . After )
251286 {
252287 lblOption . HorizontalOptions = LayoutOptions . Start ;
253- Children . Add ( frmBackground ) ;
288+ Children . Add ( IconLayout ) ;
254289 Children . Add ( lblOption ) ;
255290 }
256291 else
257292 {
258- lblOption . HorizontalOptions = LayoutOptions . StartAndExpand ;
293+ lblOption . HorizontalOptions = LayoutOptions . FillAndExpand ;
259294 Children . Add ( lblOption ) ;
260- Children . Add ( frmBackground ) ;
295+ Children . Add ( IconLayout ) ;
261296 }
262297 }
263298
@@ -272,24 +307,34 @@ void UpdateBoxBackground()
272307 if ( Type == CheckType . Material )
273308 return ;
274309
275- frmBackground . BackgroundColor = BoxBackgroundColor ;
310+ outlineBox . Fill = BoxBackgroundColor . ToBrush ( ) ;
276311 }
277312
278313 void UpdateColors ( )
279314 {
280- boxSelected . Color = Color ;
315+ //selectedIcon.Fill = Color;
281316
282- if ( Type == CheckType . Material )
283- {
284- frmBackground . BorderColor = Color ;
285- frmBackground . BackgroundColor = IsChecked ? Color : Color . Transparent ;
286- imgSelected . FillColor = Color . ToSurfaceColor ( ) ;
287- }
288- else
317+ switch ( Type )
289318 {
290- frmBackground . BorderColor = IsChecked ? Color : BorderColor ;
291- frmBackground . BackgroundColor = BoxBackgroundColor ;
292- imgSelected . FillColor = IconColor == Color . Transparent ? Color : IconColor ;
319+ case CheckType . Regular :
320+ outlineBox . Stroke = IsChecked ? Color . ToBrush ( ) : BorderColor . ToBrush ( ) ;
321+ outlineBox . Fill = BoxBackgroundColor . ToBrush ( ) ;
322+ selectedIcon . Fill = IconColor == Color . Transparent ? Color . ToBrush ( ) : IconColor . ToBrush ( ) ;
323+ break ;
324+ case CheckType . Filled :
325+ outlineBox . Fill = IsChecked ? BorderColor . ToBrush ( ) : Color . Transparent . ToBrush ( ) ;
326+ selectedIcon . Fill = IsChecked ? Color . ToBrush ( ) : Color . Transparent . ToBrush ( ) ;
327+ break ;
328+ case CheckType . Material :
329+ outlineBox . Stroke = Color . ToBrush ( ) ;
330+ outlineBox . Fill = IsChecked ? Color . ToBrush ( ) : Color . Transparent . ToBrush ( ) ;
331+ selectedIcon . Fill = Color . ToSurfaceColor ( ) . ToBrush ( ) ;
332+ break ;
333+ default :
334+ outlineBox . Stroke = IsChecked ? Color . ToBrush ( ) : BorderColor . ToBrush ( ) ;
335+ outlineBox . Fill = BoxBackgroundColor . ToBrush ( ) ;
336+ selectedIcon . Fill = IconColor == Color . Transparent ? Color . ToBrush ( ) : IconColor . ToBrush ( ) ;
337+ break ;
293338 }
294339 }
295340
@@ -298,51 +343,24 @@ void UpdateBorderColor()
298343 if ( Type == CheckType . Material )
299344 return ;
300345
301- frmBackground . BorderColor = BorderColor ;
346+ outlineBox . Stroke = BorderColor . ToBrush ( ) ;
302347 }
303348
304- void SetBoxSize ( double value )
349+ void SetBoxSize ( double size )
305350 {
306- frmBackground . WidthRequest = value ;
307- frmBackground . HeightRequest = value ;
308- boxSelected . WidthRequest = value * .6 ; //old value 0.72
309- boxSelected . HeightRequest = value * 0.6 ;
310- //lblSelected.FontSize = value * 0.72; //old value 0.76 //TODO: Do something to resizing
311-
312- // TODO: Refactor after MAUI update
313- ( this . Children [ 0 ] as View ) . MinimumWidthRequest = value * 1.4 ;
351+ outlineBox . HeightRequest = size ;
352+ outlineBox . WidthRequest = size ;
353+ //selectedIcon.MaximumHeightRequest = size * CHECK_SIZE_RATIO;
354+ //selectedIcon.MaximumWidthRequest = size * CHECK_SIZE_RATIO;
314355 }
315356
316- void UpdateType ( CheckType _Type )
357+ void UpdateShape ( )
317358 {
318- switch ( _Type )
319- {
320- case CheckType . Box :
321- frmBackground . Content = boxSelected ;
322- break ;
323- case CheckType . Check :
324- imgSelected . Source = ImageSource . FromResource ( RESOURCE_CHECK ) ;
325- frmBackground . Content = imgSelected ;
326- break ;
327- case CheckType . Cross :
328- imgSelected . Source = ImageSource . FromResource ( RESOURCE_CROSS ) ;
329- frmBackground . Content = imgSelected ;
330- break ;
331- case CheckType . Star :
332- imgSelected . Source = ImageSource . FromResource ( RESOURCE_STAR ) ;
333- frmBackground . Content = imgSelected ;
334- break ;
335- case CheckType . Material :
336- imgSelected . Source = ImageSource . FromResource ( RESOURCE_CHECK ) ;
337- frmBackground . CornerRadius = 5 ;
338- frmBackground . Content = imgSelected ;
339- break ;
340- case CheckType . Custom :
341- imgSelected . Source = CustomIcon ;
342- frmBackground . Content = imgSelected ;
343- break ;
344- }
359+ selectedIcon . Data = IconGeometry ;
360+ }
345361
362+ void UpdateType ( )
363+ {
346364 UpdateColors ( ) ;
347365 }
348366
@@ -390,27 +408,37 @@ public void DisplayValidation()
390408 {
391409
392410 }
411+
393412 public static void ApplyIsChecked ( CheckBox checkBox , bool isChecked )
394413 {
395- checkBox . frmBackground . Content . IsVisible = isChecked ;
414+ checkBox . selectedIcon . ScaleTo ( isChecked ? CHECK_SIZE_RATIO : 0 , 160 ) ;
415+
396416 checkBox . UpdateColors ( ) ;
397417 }
418+
398419 public static async void ApplyIsPressed ( CheckBox checkBox , bool isPressed )
399420 {
400- await checkBox . frmBackground . ScaleTo ( isPressed ? .8 : 1 , 50 , Easing . BounceIn ) ;
401- var radiusVal = isPressed ? checkBox . frmBackground . CornerRadius * 2f : checkBox . CornerRadius ;
402- checkBox . frmBackground . CornerRadius = radiusVal ;
421+ await checkBox . outlineBox . ScaleTo ( isPressed ? .8 : 1 , 50 , Easing . BounceIn ) ;
422+ var radiusVal = isPressed ? checkBox . outlineBox . RadiusX * 2f : checkBox . CornerRadius ;
423+ checkBox . outlineBox . RadiusX = radiusVal ;
403424 }
404425 #endregion
405426
406427 public enum CheckType
407428 {
429+ [ Obsolete ( "This option is removed. Use IconGeometry instead." ) ]
408430 Box ,
431+ [ Obsolete ( "This option is removed. Use IconGeometry instead" ) ]
409432 Check ,
433+ [ Obsolete ( "This option is removed. Use IconGeometry instead" ) ]
410434 Cross ,
435+ [ Obsolete ( "This option is removed. Use IconGeometry instead" ) ]
411436 Star ,
437+ [ Obsolete ( "This option is removed. Use IconGeometry instead" ) ]
438+ Custom = 90 ,
439+ Regular ,
440+ Filled ,
412441 Material ,
413- Custom = 90
414442 }
415443 }
416444}
0 commit comments