diff --git a/MAUI.FreakyControls/MAUI.FreakyControls/Maui.FreakyControls.csproj b/MAUI.FreakyControls/MAUI.FreakyControls/Maui.FreakyControls.csproj
index 96d4f270..06b044a1 100644
--- a/MAUI.FreakyControls/MAUI.FreakyControls/Maui.FreakyControls.csproj
+++ b/MAUI.FreakyControls/MAUI.FreakyControls/Maui.FreakyControls.csproj
@@ -12,9 +12,9 @@
10.0.17763.0
10.0.17763.0
Maui.FreakyControls
- 0.4.2
- 0.4.2
- 0.4.2
+ 0.4.3
+ 0.4.3
+ 0.4.3-pre
en
FreakyControls
@@ -27,8 +27,8 @@
https://github.com/FreakyAli/MAUI.FreakyControls
- Maui dotnet.Maui .net Maui FreakyControls Checkbox uikit Signature SignatureView Svg SvgImageView CircularImage TextInputLayout
- Basic implementation for all Freaky Controls
+ Maui dotnet.Maui .net-Maui FreakyControls Checkbox uikit Signature Radiobutton SignatureView Svg SvgImageView CircularImage TextInputLayout
+ Say Hello to RadioButtons and RadioButtonGroup
Copyright 2023
true
false
@@ -42,12 +42,11 @@
latest
true
-
- false
- false
-
- false
+ false
+
+
+ false
@@ -84,6 +83,8 @@
+
+
@@ -114,6 +115,7 @@
+
diff --git a/MAUI.FreakyControls/MAUI.FreakyControls/Shared/EventArgs/FreakyRadioButtonEventArgs.cs b/MAUI.FreakyControls/MAUI.FreakyControls/Shared/EventArgs/FreakyRadioButtonEventArgs.cs
new file mode 100644
index 00000000..bc74774b
--- /dev/null
+++ b/MAUI.FreakyControls/MAUI.FreakyControls/Shared/EventArgs/FreakyRadioButtonEventArgs.cs
@@ -0,0 +1,14 @@
+//Make sure .EventArgs is never created as a namespace.
+namespace Maui.FreakyControls;
+
+public class FreakyRadioButtonEventArgs : EventArgs
+{
+ public string RadioButtonName { get; }
+ public int RadioButtonIndex { get; }
+
+ public FreakyRadioButtonEventArgs(string name, int index)
+ {
+ RadioButtonName = name;
+ RadioButtonIndex = index;
+ }
+}
\ No newline at end of file
diff --git a/MAUI.FreakyControls/MAUI.FreakyControls/Shared/Extensions/SkPathCheckExtensions.cs b/MAUI.FreakyControls/MAUI.FreakyControls/Shared/Extensions/SkPathCheckExtensions.cs
index dd110d1d..8eb839da 100644
--- a/MAUI.FreakyControls/MAUI.FreakyControls/Shared/Extensions/SkPathCheckExtensions.cs
+++ b/MAUI.FreakyControls/MAUI.FreakyControls/Shared/Extensions/SkPathCheckExtensions.cs
@@ -5,6 +5,12 @@ namespace Maui.FreakyControls.Shared.Extensions;
public static class SkPathCheckExtensions
{
+ public static void DrawNativeRadioButtonCheck(this SKPath checkPath, SKImageInfo imageInfo, double radii)
+ {
+ checkPath.AddCircle(.5f * imageInfo.Width, .5f * imageInfo.Height, (float)radii);
+ checkPath.Close();
+ }
+
public static void DrawNativeiOSCheck(this SKPath checkPath, SKImageInfo imageInfo)
{
checkPath.MoveTo(.2f * imageInfo.Width, .5f * imageInfo.Height);
diff --git a/MAUI.FreakyControls/MAUI.FreakyControls/Shared/FreakyCheckbox/FreakyCheckbox.cs b/MAUI.FreakyControls/MAUI.FreakyControls/Shared/FreakyCheckbox/FreakyCheckbox.cs
index 1ef55dc8..afbbba5e 100644
--- a/MAUI.FreakyControls/MAUI.FreakyControls/Shared/FreakyCheckbox/FreakyCheckbox.cs
+++ b/MAUI.FreakyControls/MAUI.FreakyControls/Shared/FreakyCheckbox/FreakyCheckbox.cs
@@ -199,35 +199,57 @@ void DrawCheckFilled(SKPaintSurfaceEventArgs e)
var imageInfo = e.Info;
var canvas = e?.Surface?.Canvas;
- using (var checkfill = new SKPaint()
+ var shape = Design == Design.Unified ? Shape : FreakyCheckbox.shape;
+ using var checkfill = new SKPaint()
{
Style = SKPaintStyle.Fill,
Color = FillColor.ToSKColor(),
StrokeJoin = SKStrokeJoin.Round,
IsAntialias = true
- })
+ };
+
+ using var checkBoxStroke = new SKPaint()
{
- var shape = Design == Design.Unified ? Shape : FreakyCheckbox.shape;
- if (shape == Shared.Enums.Shape.Circle)
- {
- canvas.DrawCircle(
- imageInfo.Width / 2,
- imageInfo.Height / 2,
- (imageInfo.Width / 2) - (OutlineWidth / 2),
- checkfill);
- }
- else
- {
- var cornerRadius = OutlineWidth;
- canvas.DrawRoundRect(
- OutlineWidth,
- OutlineWidth,
- imageInfo.Width - (OutlineWidth * 2),
- imageInfo.Height - (OutlineWidth * 2),
- cornerRadius,
- cornerRadius,
- checkfill);
- }
+ Style = SKPaintStyle.Stroke,
+ Color = OutlineColor.ToSKColor(),
+ StrokeWidth = OutlineWidth,
+ StrokeJoin = SKStrokeJoin.Round,
+ IsAntialias = true
+ };
+
+ if (shape == Shared.Enums.Shape.Circle)
+ {
+ canvas.DrawCircle(
+ imageInfo.Width / 2,
+ imageInfo.Height / 2,
+ (imageInfo.Width / 2) - (OutlineWidth / 2),
+ checkfill);
+
+ canvas.DrawCircle(
+ imageInfo.Width / 2,
+ imageInfo.Height / 2,
+ (imageInfo.Width / 2) - (OutlineWidth / 2),
+ checkBoxStroke);
+ }
+ else
+ {
+ canvas.DrawRoundRect(
+ OutlineWidth,
+ OutlineWidth,
+ imageInfo.Width - (OutlineWidth * 2),
+ imageInfo.Height - (OutlineWidth * 2),
+ OutlineWidth,
+ OutlineWidth,
+ checkfill);
+
+ canvas.DrawRoundRect(
+ OutlineWidth,
+ OutlineWidth,
+ imageInfo.Width - (OutlineWidth * 2),
+ imageInfo.Height - (OutlineWidth * 2),
+ OutlineWidth,
+ OutlineWidth,
+ checkBoxStroke);
}
using var checkPath = new SKPath();
@@ -369,7 +391,7 @@ public Color OutlineColor
nameof(FillColor),
typeof(Color),
typeof(FreakyCheckbox),
- Colors.Black);
+ Colors.White);
///
/// Gets or sets the color of the fill.
@@ -386,7 +408,7 @@ public Color FillColor
nameof(CheckColor),
typeof(Color),
typeof(FreakyCheckbox),
- Colors.White);
+ Colors.Black);
///
/// Gets or sets the color of the check.
diff --git a/MAUI.FreakyControls/MAUI.FreakyControls/Shared/FreakyRadioButton/FreakyRadioButton.cs b/MAUI.FreakyControls/MAUI.FreakyControls/Shared/FreakyRadioButton/FreakyRadioButton.cs
new file mode 100644
index 00000000..18bf2cb3
--- /dev/null
+++ b/MAUI.FreakyControls/MAUI.FreakyControls/Shared/FreakyRadioButton/FreakyRadioButton.cs
@@ -0,0 +1,351 @@
+using System;
+using System.Windows.Input;
+using Maui.FreakyControls.Extensions;
+using SkiaSharp;
+using SkiaSharp.Views.Maui;
+using SkiaSharp.Views.Maui.Controls;
+using Maui.FreakyControls.Shared.Extensions;
+
+namespace Maui.FreakyControls
+{
+ public class FreakyRadioButton : ContentView, IDisposable
+ {
+ #region Fields
+ bool isAnimating;
+ readonly SKCanvasView skiaView;
+ readonly TapGestureRecognizer tapped = new();
+ private const string defaultName = "RadioButton";
+ private static readonly float outlineWidth = 6.0f;
+ private static readonly double size = 24.0;
+ #endregion
+
+ public FreakyRadioButton()
+ {
+ skiaView = new SKCanvasView();
+ WidthRequest = HeightRequest = skiaView.WidthRequest = skiaView.HeightRequest = size;
+ HorizontalOptions = VerticalOptions = new LayoutOptions(LayoutAlignment.Center, false);
+ Content = skiaView;
+
+ skiaView.PaintSurface += Handle_PaintSurface;
+ tapped.Tapped += Radiobutton_Tapped;
+ GestureRecognizers.Add(tapped);
+ }
+
+ async Task ToggleAnimationAsync()
+ {
+ isAnimating = true;
+ await skiaView.ScaleTo(0.80, 100);
+ skiaView.InvalidateSurface();
+ await skiaView.ScaleTo(1, 100, Easing.BounceOut);
+ isAnimating = false;
+ }
+
+ private void Radiobutton_Tapped(object sender, EventArgs e)
+ {
+ if (IsEnabled)
+ {
+ if (isAnimating)
+ return;
+ if (!IsChecked)
+ IsChecked = true;
+ }
+ }
+
+ void Handle_PaintSurface(object sender, SKPaintSurfaceEventArgs e)
+ {
+ e?.Surface?.Canvas?.Clear();
+ DrawOutline(e);
+ if (IsChecked)
+ DrawCheckFilled(e);
+ }
+
+ ///
+ /// Method to create a checked version of the
+ /// This method creates a filled radiobutton that that uses two SKPaint objects to avoid design flaws when creating a filled radiobutton
+ ///
+ ///
+ void DrawCheckFilled(SKPaintSurfaceEventArgs e)
+ {
+ var imageInfo = e.Info;
+ var canvas = e?.Surface?.Canvas;
+
+ using (var checkfill = new SKPaint()
+ {
+ Style = SKPaintStyle.Fill,
+ Color = FillColor.ToSKColor(),
+ StrokeWidth = OutlineWidth,
+ StrokeJoin = SKStrokeJoin.Round,
+ IsAntialias = true,
+ })
+ {
+ canvas.DrawCircle(
+ imageInfo.Width / 2,
+ imageInfo.Height / 2,
+ (imageInfo.Width / 2) - (OutlineWidth / 2),
+ checkfill);
+ }
+
+ using (var fillPaint = new SKPaint()
+ {
+ Style = SKPaintStyle.Stroke,
+ Color = this.OutlineColor.ToSKColor(),
+ StrokeWidth = OutlineWidth,
+ StrokeJoin = SKStrokeJoin.Round,
+ IsAntialias = true,
+ })
+ {
+ canvas.DrawCircle(
+ imageInfo.Width / 2,
+ imageInfo.Height / 2,
+ (imageInfo.Width / 2) - (OutlineWidth / 2),
+ fillPaint);
+ }
+
+ using var checkPath = new SKPath();
+ checkPath.DrawNativeRadioButtonCheck(imageInfo, ((imageInfo.Width / 2) - (OutlineWidth / 2)) / 1.75);
+
+ using var checkStroke = new SKPaint
+ {
+ Style = SKPaintStyle.Fill,
+ Color = CheckColor.ToSKColor(),
+ IsAntialias = true,
+ StrokeCap = SKStrokeCap.Round
+ };
+
+ canvas.DrawPath(checkPath, checkStroke);
+ }
+
+ ///
+ /// Method to create a unchecked version of the
+ ///
+ ///
+ void DrawOutline(SKPaintSurfaceEventArgs e)
+ {
+ var imageInfo = e.Info;
+ var canvas = e?.Surface?.Canvas;
+
+ using (var outline = new SKPaint
+ {
+ Style = SKPaintStyle.Stroke,
+ Color = OutlineColor.ToSKColor(),
+ StrokeWidth = OutlineWidth,
+ StrokeJoin = SKStrokeJoin.Round,
+ IsAntialias = true
+ })
+ {
+ canvas.DrawCircle(
+ imageInfo.Width / 2,
+ imageInfo.Height / 2,
+ (imageInfo.Width / 2) - (OutlineWidth / 2),
+ outline);
+ }
+ }
+
+ #region Events
+ ///
+ /// Raised when changes.
+ ///
+ public event EventHandler CheckedChanged;
+ #endregion
+
+ #region Bindable Properties
+
+ public static readonly BindableProperty HasCheckAnimationProperty =
+ BindableProperty.Create(
+ nameof(HasCheckAnimation),
+ typeof(bool),
+ typeof(FreakyRadioButton),
+ true);
+
+ ///
+ /// Gets or sets the color of the outline.
+ ///
+ /// Color value of the outline
+ public bool HasCheckAnimation
+ {
+ get => (bool)GetValue(HasCheckAnimationProperty);
+ set => SetValue(HasCheckAnimationProperty, value);
+ }
+
+ public static readonly BindableProperty OutlineColorProperty =
+ BindableProperty.Create(
+ nameof(OutlineColor),
+ typeof(Color),
+ typeof(FreakyRadioButton),
+ Colors.Black);
+
+ ///
+ /// Gets or sets the color of the outline.
+ ///
+ /// Color value of the outline
+ public Color OutlineColor
+ {
+ get { return (Color)GetValue(OutlineColorProperty); }
+ set { SetValue(OutlineColorProperty, value); }
+ }
+
+ public static readonly BindableProperty FillColorProperty =
+ BindableProperty.Create(
+ nameof(FillColor),
+ typeof(Color),
+ typeof(FreakyRadioButton),
+ Colors.White);
+
+ ///
+ /// Gets or sets the color of the fill.
+ ///
+ /// Color value of the fill.
+ public Color FillColor
+ {
+ get { return (Color)GetValue(FillColorProperty); }
+ set { SetValue(FillColorProperty, value); }
+ }
+
+ public static readonly BindableProperty CheckColorProperty =
+ BindableProperty.Create(
+ nameof(CheckColor),
+ typeof(Color),
+ typeof(FreakyRadioButton),
+ Colors.Black);
+
+ ///
+ /// Gets or sets the color of the check.
+ ///
+ /// Color of the check.
+ public Color CheckColor
+ {
+ get { return (Color)GetValue(CheckColorProperty); }
+ set { SetValue(CheckColorProperty, value); }
+ }
+
+ public static readonly BindableProperty OutlineWidthProperty =
+ BindableProperty.Create(
+ nameof(OutlineWidth),
+ typeof(float),
+ typeof(FreakyRadioButton),
+ outlineWidth);
+
+ ///
+ /// Gets or sets the width of the outline.
+ ///
+ /// The width of the outline
+ public float OutlineWidth
+ {
+ get { return (float)GetValue(OutlineWidthProperty); }
+ set { SetValue(OutlineWidthProperty, value); }
+ }
+
+ public static readonly BindableProperty CheckedChangedCommandProperty =
+ BindableProperty.Create(
+ nameof(CheckedChangedCommand),
+ typeof(ICommand),
+ typeof(FreakyRadioButton));
+
+ ///
+ /// Triggered when changes.
+ ///
+ public ICommand CheckedChangedCommand
+ {
+ get { return (ICommand)GetValue(CheckedChangedCommandProperty); }
+ set { SetValue(CheckedChangedCommandProperty, value); }
+ }
+
+ public static readonly BindableProperty IsCheckedProperty =
+ BindableProperty.Create(
+ nameof(IsChecked),
+ typeof(bool),
+ typeof(FreakyRadioButton),
+ false,
+ BindingMode.TwoWay,
+ propertyChanged: OnCheckedChanged);
+
+ ///
+ /// Gets or sets a value indicating whether this is checked.
+ ///
+ /// true if is checked; otherwise, false.
+ public bool IsChecked
+ {
+ get { return (bool)GetValue(IsCheckedProperty); }
+ set { SetValue(IsCheckedProperty, value); }
+ }
+
+ static async void OnCheckedChanged(BindableObject bindable, object oldValue, object newValue)
+ {
+ if (!(bindable is FreakyRadioButton radioButton)) return;
+ radioButton.CheckedChanged?.Invoke(radioButton, new CheckedChangedEventArgs((bool)newValue));
+ radioButton.CheckedChangedCommand?.ExecuteCommandIfAvailable(newValue);
+ radioButton.ChangeVisualState();
+ await radioButton.ToggleAnimationAsync();
+ }
+
+ public static readonly BindableProperty SizeRequestProperty =
+ BindableProperty.Create(
+ nameof(SizeRequest),
+ typeof(double),
+ typeof(FreakyRadioButton),
+ size,
+ propertyChanged: SizeRequestChanged);
+
+ ///
+ /// Gets or sets a value indicating the size of this
+ ///
+ /// true if is checked; otherwise, false.
+ public double SizeRequest
+ {
+ get { return (double)GetValue(SizeRequestProperty); }
+ set { SetValue(SizeRequestProperty, value); }
+ }
+
+ static void SizeRequestChanged(BindableObject bindable, object oldValue, object newValue)
+ {
+ if (!(bindable is FreakyRadioButton RadioButton)) return;
+ RadioButton.WidthRequest = RadioButton.HeightRequest = (double)(newValue);
+ RadioButton.skiaView.WidthRequest = RadioButton.skiaView.HeightRequest = (double)(newValue);
+ }
+
+ public static readonly BindableProperty NameProperty =
+ BindableProperty.Create(
+ nameof(Name),
+ typeof(string),
+ typeof(FreakyRadioButton),
+ defaultName,
+ propertyChanged: SizeRequestChanged);
+
+ ///
+ /// Gets or sets a value indicating the identifier of this
+ ///
+ /// true if is checked; otherwise, false.
+ public string Name
+ {
+ get { return (string)GetValue(NameProperty); }
+ set { SetValue(NameProperty, value); }
+ }
+
+ #endregion
+
+ protected override void ChangeVisualState()
+ {
+ ApplyIsCheckedState();
+ base.ChangeVisualState();
+ }
+
+ void ApplyIsCheckedState()
+ {
+ if (IsChecked)
+ {
+ VisualStateManager.GoToState(this, RadioButton.CheckedVisualState);
+ }
+ else
+ {
+ VisualStateManager.GoToState(this, RadioButton.UncheckedVisualState);
+ }
+ }
+
+ public void Dispose()
+ {
+ tapped.Tapped -= Radiobutton_Tapped;
+ GestureRecognizers.Clear();
+ skiaView.PaintSurface -= Handle_PaintSurface;
+ }
+ }
+}
\ No newline at end of file
diff --git a/MAUI.FreakyControls/MAUI.FreakyControls/Shared/FreakyRadioButton/FreakyRadioGroup.cs b/MAUI.FreakyControls/MAUI.FreakyControls/Shared/FreakyRadioButton/FreakyRadioGroup.cs
new file mode 100644
index 00000000..0f827fc3
--- /dev/null
+++ b/MAUI.FreakyControls/MAUI.FreakyControls/Shared/FreakyRadioButton/FreakyRadioGroup.cs
@@ -0,0 +1,162 @@
+using System;
+using System.Windows.Input;
+using Maui.FreakyControls.Extensions;
+
+namespace Maui.FreakyControls;
+
+public class FreakyRadioGroup : StackLayout
+{
+ private List radioButtons = new List();
+
+ ///
+ /// Triggered when changes.
+ ///
+ public event EventHandler SelectedRadioButtonChanged;
+
+ public static readonly BindableProperty SelectedIndexProperty =
+ BindableProperty.Create(
+ nameof(SelectedIndex),
+ typeof(int),
+ typeof(FreakyRadioGroup),
+ -1,
+ defaultBindingMode: BindingMode.TwoWay,
+ propertyChanged: (bindable, oldValue, newValue) =>
+ {
+ ((FreakyRadioGroup)bindable).UpdateCheckedStates();
+ ((FreakyRadioGroup)bindable).SetDefaultCheckedRadioButton();
+ });
+
+ ///
+ /// Triggered when changes.
+ /// Has the as a Command Parameter
+ ///
+ public ICommand SelectedRadioButtonChangedCommand
+ {
+ get { return (ICommand)GetValue(SelectedRadioButtonChangedCommandProperty); }
+ set { SetValue(SelectedRadioButtonChangedCommandProperty, value); }
+ }
+
+ public static readonly BindableProperty SelectedRadioButtonChangedCommandProperty =
+ BindableProperty.Create(
+ nameof(SelectedRadioButtonChangedCommand),
+ typeof(ICommand),
+ typeof(FreakyRadioGroup));
+
+ ///
+ /// SelectedIndex of in this Group
+ ///
+ public int SelectedIndex
+ {
+ get => (int)GetValue(SelectedIndexProperty);
+ set => SetValue(SelectedIndexProperty, value);
+ }
+
+ private void UpdateCheckedStates()
+ {
+ int index = 0;
+ LoopChildren(Children, index);
+ }
+
+ private void SetDefaultCheckedRadioButton()
+ {
+ if (SelectedIndex < 0 || SelectedIndex >= radioButtons.Count)
+ {
+ return;
+ }
+
+ radioButtons[SelectedIndex].IsChecked = true;
+ }
+
+ protected override void OnChildAdded(Element child)
+ {
+ base.OnChildAdded(child);
+
+ if (child is FreakyRadioButton radioButton)
+ {
+ radioButtons.Add(radioButton);
+ radioButton.CheckedChanged += RadioButton_CheckedChanged;
+ }
+ else if (child is Layout layout)
+ {
+ foreach (var grandChild in layout.Children)
+ {
+ if (grandChild is FreakyRadioButton grandChildRadioButton)
+ {
+ radioButtons.Add(grandChildRadioButton);
+ grandChildRadioButton.CheckedChanged += RadioButton_CheckedChanged;
+ }
+ }
+ }
+ }
+
+ private void RadioButton_CheckedChanged(object sender, EventArgs e)
+ {
+ if (!(sender is FreakyRadioButton selectedRadioButton) || !selectedRadioButton.IsChecked)
+ {
+ return;
+ }
+
+ foreach (var radioButton in radioButtons)
+ {
+ if (radioButton != selectedRadioButton)
+ {
+ radioButton.IsChecked = false;
+ }
+ }
+
+ int index = FindIndex(selectedRadioButton);
+ string name = selectedRadioButton.Name;
+ var eventArgs = new FreakyRadioButtonEventArgs(name, index);
+ this.SelectedRadioButtonChangedCommand?.ExecuteCommandIfAvailable(eventArgs);
+ SelectedRadioButtonChanged?.Invoke(this,eventArgs);
+ }
+
+ private int FindIndex(FreakyRadioButton radioButton)
+ {
+ int index = 0;
+
+ return FindIndexRecursive(Children, radioButton, index);
+ }
+
+ private int FindIndexRecursive(IList children, FreakyRadioButton radioButton, int index)
+ {
+ foreach (var child in children)
+ {
+ if (child is FreakyRadioButton)
+ {
+ if (child == radioButton)
+ {
+ return index;
+ }
+ index++;
+ }
+ else if (child is Layout)
+ {
+ int childIndex = FindIndexRecursive(((Layout)child).Children, radioButton, index);
+ if (childIndex != -1)
+ {
+ return childIndex;
+ }
+ }
+ }
+
+ return -1;
+ }
+
+ private void LoopChildren(IList children, int index)
+ {
+ foreach (var child in children)
+ {
+ if (child is FreakyRadioButton)
+ {
+ FreakyRadioButton radioButton = (FreakyRadioButton)child;
+ radioButton.IsChecked = index == SelectedIndex;
+ index++;
+ }
+ else if (child is Layout)
+ {
+ LoopChildren(((Layout)child).Children, index);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/MAUI.FreakyControls/MAUI.FreakyControls/Shared/FreakySvgImageView/FreakySvgImageView.xaml.cs b/MAUI.FreakyControls/MAUI.FreakyControls/Shared/FreakySvgImageView/FreakySvgImageView.xaml.cs
index 8dc70053..d35bdb7d 100644
--- a/MAUI.FreakyControls/MAUI.FreakyControls/Shared/FreakySvgImageView/FreakySvgImageView.xaml.cs
+++ b/MAUI.FreakyControls/MAUI.FreakyControls/Shared/FreakySvgImageView/FreakySvgImageView.xaml.cs
@@ -152,7 +152,7 @@ private void TapGestureRecognizer_OnTapped(object sender, EventArgs e)
{
var time = Math.Round((DateTime.Now - firstTap).TotalMilliseconds, MidpointRounding.AwayFromZero);
- //Check to avoid handling multiple tap events at same time using treshold
+ //Check to avoid handling multiple tap events at same time using threshold
if (time > TAP_TIME_TRESHOLD)
{
firstTap = DateTime.Now;
diff --git a/MAUI.FreakyControls/Samples/AppShell.xaml.cs b/MAUI.FreakyControls/Samples/AppShell.xaml.cs
index e1ef3b98..d5881ae2 100644
--- a/MAUI.FreakyControls/Samples/AppShell.xaml.cs
+++ b/MAUI.FreakyControls/Samples/AppShell.xaml.cs
@@ -11,6 +11,7 @@ public partial class AppShell : Shell
internal const string signatureView = "SignatureView";
internal const string signaturePreview = "ImageDisplay";
internal const string checkboxes = "Checkboxes";
+ internal const string radioButtons= "RadioButtons";
public AppShell()
{
@@ -22,5 +23,6 @@ public AppShell()
Routing.RegisterRoute(signatureView, typeof(SignatureView.SignatureView));
Routing.RegisterRoute(signaturePreview, typeof(SignatureView.ImageDisplay));
Routing.RegisterRoute(checkboxes, typeof(Checkboxes.CheckboxesView));
+ Routing.RegisterRoute(radioButtons, typeof(RadioButtons.RadioButtonsView));
}
}
\ No newline at end of file
diff --git a/MAUI.FreakyControls/Samples/Checkboxes/CheckboxesView.xaml b/MAUI.FreakyControls/Samples/Checkboxes/CheckboxesView.xaml
index b30f94a4..a43049eb 100644
--- a/MAUI.FreakyControls/Samples/Checkboxes/CheckboxesView.xaml
+++ b/MAUI.FreakyControls/Samples/Checkboxes/CheckboxesView.xaml
@@ -1,4 +1,4 @@
-
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/MAUI.FreakyControls/Samples/RadioButtons/RadioButtonsView.xaml.cs b/MAUI.FreakyControls/Samples/RadioButtons/RadioButtonsView.xaml.cs
new file mode 100644
index 00000000..1bbb5bf6
--- /dev/null
+++ b/MAUI.FreakyControls/Samples/RadioButtons/RadioButtonsView.xaml.cs
@@ -0,0 +1,14 @@
+namespace Samples.RadioButtons;
+
+public partial class RadioButtonsView : ContentPage
+{
+ public RadioButtonsView()
+ {
+ InitializeComponent();
+ BindingContext = new RadioButtonsViewModel();
+ }
+
+ void FreakyRadioGroup_SelectedRadioButtonChanged(System.Object sender, Maui.FreakyControls.FreakyRadioButtonEventArgs e)
+ {
+ }
+}
diff --git a/MAUI.FreakyControls/Samples/RadioButtons/RadioButtonsViewModel.cs b/MAUI.FreakyControls/Samples/RadioButtons/RadioButtonsViewModel.cs
new file mode 100644
index 00000000..749535c2
--- /dev/null
+++ b/MAUI.FreakyControls/Samples/RadioButtons/RadioButtonsViewModel.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Windows.Input;
+using Maui.FreakyControls;
+
+namespace Samples.RadioButtons;
+
+public class RadioButtonsViewModel : MainViewModel
+{
+ private int checkedRadioButton;
+
+ public int CheckedRadioButton
+ {
+ get => checkedRadioButton;
+ set => SetProperty(ref checkedRadioButton, value);
+ }
+
+ public ICommand SelectedIndexCommand { get; set; }
+
+ public RadioButtonsViewModel()
+ {
+ CheckedRadioButton = 2;
+ SelectedIndexCommand = new Command(ExecuteSelectedIndexCommand) { };
+ }
+
+ private void ExecuteSelectedIndexCommand(FreakyRadioButtonEventArgs obj)
+ {
+ }
+}
\ No newline at end of file
diff --git a/MAUI.FreakyControls/Samples/Samples.csproj b/MAUI.FreakyControls/Samples/Samples.csproj
index 6a375dca..08394c06 100644
--- a/MAUI.FreakyControls/Samples/Samples.csproj
+++ b/MAUI.FreakyControls/Samples/Samples.csproj
@@ -63,6 +63,7 @@
+
@@ -76,9 +77,10 @@
+
-
+
diff --git a/README.md b/README.md
index 42a7cadc..70c7fab6 100644
--- a/README.md
+++ b/README.md
@@ -13,7 +13,7 @@
| Support | OS |
| ------------- |:-------------:|
| iOS | iOS 11.0 + |
-| Android | API 23+ (Marshmallow) |
+| Android | API 23+ (Marshmallow) |
## Documentation
@@ -23,7 +23,6 @@ For more details and API documentation check our [Wiki](https://github.com/Freak
### Like what you saw? Want to keep this repo alive?
[](https://www.buymeacoffee.com/FreakyAli)
-
## Previews:
| iOS | Android |
@@ -33,12 +32,14 @@ For more details and API documentation check our [Wiki](https://github.com/Freak
|
|
|
|
|
|
|
|
|
+|
|
|
## License
The license for this project can be found [here](https://github.com/FreakyAli/Maui.FreakyControls/blob/master/LICENSE)
+
## Installation
Add our [NuGet](https://www.nuget.org/packages/FreakyControls) package or
@@ -75,4 +76,10 @@ Now you can use the controls in your app.
## Activity
-
+Sparkline:
+
+[](https://stars.medv.io/FreakyAli/Maui.FreakyControls)
+
+RepoBeats:
+
+