Skip to content

Commit a28a26c

Browse files
committed
Adapt RadioButton to v4
1 parent 2874337 commit a28a26c

File tree

1 file changed

+67
-32
lines changed

1 file changed

+67
-32
lines changed

src/Xamarin.Forms.InputKit/Shared/Controls/RadioButton.cs

Lines changed: 67 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99
using System.Windows.Input;
1010
using Xamarin.Forms;
1111
using 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

1317
namespace 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

Comments
 (0)