99using System . Windows . Input ;
1010using Xamarin . Forms ;
1111using Xamarin . Forms . Internals ;
12+ using Xamarin . Forms . Shapes ;
13+ using Plugin . InputKit . Shared . Helpers ;
14+ using TypeConverter = Xamarin . Forms . TypeConverter ;
15+ using TypeConverterAttribute = Xamarin . Forms . TypeConverterAttribute ;
1216
1317namespace Plugin . InputKit . Shared . Controls
1418{
@@ -24,25 +28,46 @@ public class RadioButton : StatefulStackLayout
2428 public static GlobalSetting GlobalSetting { get ; private set ; } = new GlobalSetting
2529 {
2630 Color = InputKitOptions . GetAccentColor ( ) ,
27- BorderColor = Color . Black ,
31+ BorderColor = Application . Current . RequestedTheme == OSAppTheme . Dark ? Color . WhiteSmoke : Color . Black ,
2832 TextColor = ( Color ) Label . TextColorProperty . DefaultValue ,
29- Size = Device . GetNamedSize ( Device . RuntimePlatform == Device . iOS ? NamedSize . Large : NamedSize . Medium , typeof ( Label ) ) * 1.2 ,
33+ Size = 25 ,
3034 CornerRadius = - 1 ,
31- FontSize = Device . GetNamedSize ( Device . RuntimePlatform == Device . iOS ? NamedSize . Medium : NamedSize . Small , typeof ( Label ) ) ,
35+ FontSize = 14 ,
3236 LabelPosition = LabelPosition . After
3337 } ;
3438 #endregion
3539
36- #region Constants
37- public const string RESOURCE_CIRCLE = "Plugin.InputKit.Shared.Resources.circle.png" ;
38- public const string RESOURCE_DOT = "Plugin.InputKit.Shared.Resources.dot.png" ;
39- #endregion
40-
4140 #region Fields
42- internal Grid IconLayout ;
43- internal IconView iconCircle = new IconView { Source = ImageSource . FromResource ( RESOURCE_CIRCLE ) , FillColor = GlobalSetting . BorderColor , VerticalOptions = LayoutOptions . CenterAndExpand , HorizontalOptions = LayoutOptions . Center , HeightRequest = GlobalSetting . Size , WidthRequest = GlobalSetting . Size } ;
44- internal IconView iconChecked = new IconView { Source = ImageSource . FromResource ( RESOURCE_DOT ) , FillColor = GlobalSetting . Color , IsVisible = false , VerticalOptions = LayoutOptions . CenterAndExpand , HorizontalOptions = LayoutOptions . Center , HeightRequest = GlobalSetting . Size , WidthRequest = GlobalSetting . Size } ;
45- internal Label lblText = new Label { VerticalTextAlignment = TextAlignment . Center , VerticalOptions = LayoutOptions . CenterAndExpand , HorizontalOptions = LayoutOptions . Fill , TextColor = GlobalSetting . TextColor , FontSize = GlobalSetting . FontSize , FontFamily = GlobalSetting . FontFamily , MaxLines = 3 , LineBreakMode = LineBreakMode . WordWrap } ;
41+ protected internal Grid IconLayout ;
42+ protected internal Ellipse iconCircle = new Ellipse
43+ {
44+ StrokeThickness = 2 ,
45+ Stroke = GlobalSetting . BorderColor . ToBrush ( ) ,
46+ VerticalOptions = LayoutOptions . Center ,
47+ HorizontalOptions = LayoutOptions . Center ,
48+ HeightRequest = GlobalSetting . Size ,
49+ WidthRequest = GlobalSetting . Size
50+ } ;
51+ protected internal Path iconChecked = new Path
52+ {
53+ Fill = GlobalSetting . Color . ToBrush ( ) ,
54+ Scale = 0 ,
55+ VerticalOptions = LayoutOptions . Center ,
56+ HorizontalOptions = LayoutOptions . Center ,
57+ HeightRequest = GlobalSetting . Size ,
58+ WidthRequest = GlobalSetting . Size
59+ } ;
60+ protected internal Label lblText = new Label
61+ {
62+ VerticalTextAlignment = TextAlignment . Center ,
63+ VerticalOptions = LayoutOptions . Center ,
64+ HorizontalOptions = LayoutOptions . Start ,
65+ TextColor = GlobalSetting . TextColor ,
66+ FontSize = GlobalSetting . FontSize ,
67+ FontFamily = GlobalSetting . FontFamily ,
68+ MaxLines = 3 ,
69+ LineBreakMode = LineBreakMode . WordWrap
70+ } ;
4671 private bool _isDisabled ;
4772 #endregion
4873
@@ -55,9 +80,6 @@ public RadioButton()
5580 InitVisualStates ( ) ;
5681
5782 Orientation = StackOrientation . Horizontal ;
58- if ( Device . RuntimePlatform != Device . iOS )
59- lblText . FontSize = lblText . FontSize *= 1.5 ;
60-
6183
6284 ApplyIsCheckedAction = ApplyIsChecked ;
6385 ApplyIsPressedAction = ApplyIsPressed ;
@@ -66,20 +88,20 @@ public RadioButton()
6688 {
6789 VerticalOptions = LayoutOptions . Center ,
6890 Children =
69- {
70- iconCircle ,
71- iconChecked
72- } ,
91+ {
92+ iconCircle ,
93+ iconChecked
94+ } ,
7395 MinimumWidthRequest = GlobalSetting . Size * 1.66 ,
7496 } ;
7597
7698 ApplyLabelPosition ( LabelPosition ) ;
99+ UpdateShape ( ) ;
77100
78101 GestureRecognizers . Add ( new TapGestureRecognizer { Command = new Command ( Tapped ) } ) ;
79102 }
80103 #endregion
81104
82-
83105 /// <summary>
84106 /// Click event, triggered when clicked
85107 /// </summary>
@@ -145,9 +167,14 @@ public bool IsChecked
145167 /// <summary>
146168 /// Set your own background image instead of default circle.
147169 /// </summary>
148- public ImageSource CircleImage { get => ( ImageSource ) GetValue ( CircleImageProperty ) ; set => SetValue ( CircleImageProperty , value ) ; }
170+ [ Obsolete ( "This option is removed." ) ]
171+ public ImageSource CircleImage { get => default ; set { } }
172+
173+ [ Obsolete ( "This option is removed." ) ]
174+ public ImageSource CheckedImage { get => default ; set { } }
149175
150- public ImageSource CheckedImage { get => ( ImageSource ) GetValue ( CheckedImageProperty ) ; set => SetValue ( CheckedImageProperty , value ) ; }
176+ [ TypeConverter ( typeof ( PathGeometryConverter ) ) ]
177+ public Geometry SelectedIconGeomerty { get => ( Geometry ) GetValue ( SelectedIconGeomertyProperty ) ; set => SetValue ( SelectedIconGeomertyProperty , value ) ; }
151178
152179 /// <summary>
153180 /// To be added.
@@ -168,10 +195,11 @@ public bool IsChecked
168195 /// Color of description text of Radio Button
169196 /// </summary>
170197 public Color TextColor { get => ( Color ) GetValue ( TextColorProperty ) ; set => SetValue ( TextColorProperty , value ) ; }
171-
172198 /// <summary>
173199 /// Internal use only. Applies effect when pressed.
174200 /// </summary>
201+
202+ [ Browsable ( false ) ]
175203 public bool IsPressed { get => ( bool ) GetValue ( IsPressedProperty ) ; set => SetValue ( IsPressedProperty , value ) ; }
176204 /// <summary>
177205 /// Gets or sets the label position.
@@ -190,14 +218,13 @@ public LabelPosition LabelPosition
190218 public static readonly BindableProperty TextProperty = BindableProperty . Create ( nameof ( Text ) , typeof ( string ) , typeof ( RadioButton ) , "" , propertyChanged : ( bo , ov , nv ) => ( bo as RadioButton ) . Text = ( string ) nv ) ;
191219 public static readonly BindableProperty TextFontSizeProperty = BindableProperty . Create ( nameof ( TextFontSize ) , typeof ( double ) , typeof ( RadioButton ) , 20.0 , propertyChanged : ( bo , ov , nv ) => ( bo as RadioButton ) . TextFontSize = ( double ) nv ) ;
192220 public static readonly BindableProperty ColorProperty = BindableProperty . Create ( nameof ( Color ) , typeof ( Color ) , typeof ( RadioButton ) , GlobalSetting . Color , propertyChanged : ( bo , ov , nv ) => ( bo as RadioButton ) . UpdateColors ( ) ) ;
193- public static readonly BindableProperty CircleImageProperty = BindableProperty . Create ( nameof ( CircleImage ) , typeof ( ImageSource ) , typeof ( RadioButton ) , default ( ImageSource ) , propertyChanged : ( bo , ov , nv ) => ( bo as RadioButton ) . iconCircle . Source = nv as ImageSource ?? nv ? . ToString ( ) ) ;
194- public static readonly BindableProperty CheckedImageProperty = BindableProperty . Create ( nameof ( CheckedImage ) , typeof ( ImageSource ) , typeof ( RadioButton ) , default ( ImageSource ) , propertyChanged : ( bo , ov , nv ) => ( bo as RadioButton ) . iconChecked . Source = nv as ImageSource ?? nv ? . ToString ( ) ) ;
195221 public static readonly BindableProperty CircleColorProperty = BindableProperty . Create ( nameof ( CircleColor ) , typeof ( Color ) , typeof ( RadioButton ) , GlobalSetting . BorderColor , propertyChanged : ( bo , ov , nv ) => ( bo as RadioButton ) . UpdateColors ( ) ) ;
196222 public static readonly BindableProperty TextColorProperty = BindableProperty . Create ( nameof ( TextColor ) , typeof ( Color ) , typeof ( RadioButton ) , GlobalSetting . TextColor , propertyChanged : ( bo , ov , nv ) => ( bo as RadioButton ) . UpdateColors ( ) ) ;
197223 public static readonly BindableProperty ClickCommandProperty = BindableProperty . Create ( nameof ( ClickCommand ) , typeof ( ICommand ) , typeof ( RadioButton ) , null , propertyChanged : ( bo , ov , nv ) => ( bo as RadioButton ) . ClickCommand = ( ICommand ) nv ) ;
198224 public static readonly BindableProperty CommandParameterProperty = BindableProperty . Create ( nameof ( CommandParameter ) , typeof ( object ) , typeof ( RadioButton ) , propertyChanged : ( bo , ov , nv ) => ( bo as RadioButton ) . CommandParameter = nv ) ;
199225 public static readonly BindableProperty IsPressedProperty = BindableProperty . Create ( nameof ( IsPressed ) , typeof ( bool ) , typeof ( RadioButton ) , propertyChanged : ( bo , ov , nv ) => ( bo as RadioButton ) . ApplyIsPressedAction ( ( bool ) nv ) ) ;
200226 public static readonly BindableProperty FontFamilyProperty = BindableProperty . Create ( nameof ( FontFamily ) , typeof ( string ) , typeof ( RadioButton ) , propertyChanged : ( bo , ov , nv ) => ( bo as RadioButton ) . FontFamily = ( string ) nv ) ;
227+ public static readonly BindableProperty SelectedIconGeomertyProperty = BindableProperty . Create ( nameof ( SelectedIconGeomerty ) , typeof ( Geometry ) , typeof ( RadioButton ) , PredefinedShapes . Dot , propertyChanged : ( bo , ov , nv ) => ( bo as RadioButton ) . UpdateShape ( ) ) ;
201228 public static readonly BindableProperty LabelPositionProperty = BindableProperty . Create (
202229 propertyName : nameof ( LabelPosition ) , declaringType : typeof ( RadioButton ) ,
203230 returnType : typeof ( LabelPosition ) , defaultBindingMode : BindingMode . TwoWay ,
@@ -212,18 +239,23 @@ private void ApplyLabelPosition(LabelPosition position)
212239 Children . Clear ( ) ;
213240 if ( position == LabelPosition . After )
214241 {
215- IconLayout . HorizontalOptions = LayoutOptions . Center ;
242+ lblText . HorizontalOptions = LayoutOptions . Start ;
216243 Children . Add ( IconLayout ) ;
217244 Children . Add ( lblText ) ;
218245 }
219246 else
220247 {
221- IconLayout . HorizontalOptions = LayoutOptions . Center ;
248+ lblText . HorizontalOptions = LayoutOptions . FillAndExpand ;
222249 Children . Add ( lblText ) ;
223250 Children . Add ( IconLayout ) ;
224251 }
225252 }
226253
254+ private protected virtual void UpdateShape ( )
255+ {
256+ iconChecked . Data = SelectedIconGeomerty ;
257+ }
258+
227259 /// <summary>
228260 /// That handles tapps and triggers event, commands etc.
229261 /// </summary>
@@ -241,18 +273,21 @@ void Tapped()
241273
242274 void UpdateColors ( )
243275 {
244- iconChecked . FillColor = Color ;
245- iconCircle . FillColor = IsChecked ? Color : CircleColor ;
276+ iconChecked . Fill = Color . ToBrush ( ) ;
277+ iconCircle . Stroke = IsChecked ? Color . ToBrush ( ) : CircleColor . ToBrush ( ) ;
246278 lblText . TextColor = TextColor ;
247279 }
248280
249281 public virtual void ApplyIsChecked ( bool isChecked )
250282 {
251- var changed = iconChecked . IsVisible != isChecked ;
252- iconChecked . IsVisible = isChecked ;
253- UpdateColors ( ) ;
283+ var isCheckedInLastState = iconChecked . Scale == 1 ;
284+
285+ var changed = isCheckedInLastState != isChecked ;
286+
254287 if ( changed )
255288 {
289+ iconChecked . ScaleTo ( Convert . ToDouble ( isChecked ) , 180 ) ;
290+ UpdateColors ( ) ;
256291 Checked ? . Invoke ( this , null ) ;
257292 }
258293 }
0 commit comments