Skip to content

Commit

Permalink
CheckBoxHandlers (#432)
Browse files Browse the repository at this point in the history
  • Loading branch information
jsuarezruiz authored Mar 16, 2021
1 parent 3630d42 commit 71d7d56
Show file tree
Hide file tree
Showing 21 changed files with 674 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public class CheckBoxRendererBase :
IPlatformElementConfiguration<PlatformConfiguration.Android, CheckBox> _platformElementConfiguration;
CheckBox _checkBox;

[PortHandler]
static int[][] _checkedStates = new int[][]
{
new int[] { AAttribute.StateEnabled, AAttribute.StateChecked },
Expand Down Expand Up @@ -185,6 +186,7 @@ void IOnCheckedChangeListener.OnCheckedChanged(CompoundButton buttonView, bool i
((IElementController)Element).SetValueFromRenderer(CheckBox.IsCheckedProperty, isChecked);
}

[PortHandler]
void UpdateIsChecked()
{
if (Element == null || Control == null)
Expand All @@ -210,6 +212,7 @@ protected virtual ColorStateList GetColorStateList()
return list;
}

[PortHandler]
void UpdateBackgroundColor()
{
if (Element.BackgroundColor == Color.Default)
Expand All @@ -225,6 +228,7 @@ void UpdateBackground()
this.UpdateBackground(background);
}

[PortHandler]
void UpdateOnColor()
{
if (Element == null || Control == null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ protected override void OnElementChanged(ElementChangedEventArgs<CheckBox> e)
base.OnElementChanged(e);
}

[PortHandler]
protected virtual void UpdateTintColor()
{
if (Element == null)
Expand All @@ -129,6 +130,7 @@ protected virtual void UpdateTintColor()
Control.CheckBoxTintColor = Element.Color;
}

[PortHandler]
void OnControlCheckedChanged(object sender, EventArgs e)
{
Element.IsChecked = Control.IsChecked;
Expand Down
1 change: 1 addition & 0 deletions src/Compatibility/Core/src/iOS/Renderers/FormsCheckBox.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Microsoft.Maui.Controls.Compatibility.Platform.iOS
{
[PortHandler("NativeCheckBox")]
public class FormsCheckBox : UIButton
{
static UIImage _checked;
Expand Down
5 changes: 5 additions & 0 deletions src/Controls/samples/Controls.Sample/Pages/MainPage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ void SetupMauiLayout()

verticalStack.Add(horizontalStack);

verticalStack.Add(new CheckBox());
verticalStack.Add(new CheckBox { BackgroundColor = Color.LightPink });
verticalStack.Add(new CheckBox { IsChecked = true, Color = Color.Aquamarine });

verticalStack.Add(new Editor());
verticalStack.Add(new Editor { Text = "Editor" });

Expand All @@ -89,6 +93,7 @@ void SetupMauiLayout()
};

verticalStack.Add(entry);

verticalStack.Add(new Entry { Text = "Entry", TextColor = Color.DarkRed });
verticalStack.Add(new Entry { IsPassword = true, TextColor = Color.Black });
verticalStack.Add(new Entry { IsTextPredictionEnabled = false });
Expand Down
2 changes: 1 addition & 1 deletion src/Controls/src/Core/CheckBox.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Microsoft.Maui.Controls
{
public class CheckBox : View, IElementConfiguration<CheckBox>, IBorderElement, IColorElement
public partial class CheckBox : View, IElementConfiguration<CheckBox>, IBorderElement, IColorElement
{
readonly Lazy<PlatformConfigurationRegistry<CheckBox>> _platformConfigurationRegistry;
public const string IsCheckedVisualState = "IsChecked";
Expand Down
7 changes: 7 additions & 0 deletions src/Controls/src/Core/HandlerImpl/CheckBox.Impl.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Microsoft.Maui.Controls
{
public partial class CheckBox : ICheck
{

}
}
8 changes: 8 additions & 0 deletions src/Core/src/Core/ICheck.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace Microsoft.Maui
{
public interface ICheck : IView
{
bool IsChecked { get; set; }
Color Color { get; }
}
}
57 changes: 57 additions & 0 deletions src/Core/src/Handlers/CheckBox/CheckBoxHandler.Android.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
using Android.Widget;
using AndroidX.AppCompat.Widget;

namespace Microsoft.Maui.Handlers
{
public partial class CheckBoxHandler : AbstractViewHandler<ICheck, AppCompatCheckBox>
{
CheckedChangeListener ChangeListener { get; } = new CheckedChangeListener();

protected override AppCompatCheckBox CreateNativeView()
{
var nativeCheckBox = new AppCompatCheckBox(Context)
{
SoundEffectsEnabled = false
};

nativeCheckBox.SetClipToOutline(true);

return nativeCheckBox;
}

protected override void ConnectHandler(AppCompatCheckBox nativeView)
{
ChangeListener.Handler = this;
nativeView.SetOnCheckedChangeListener(ChangeListener);
}

protected override void DisconnectHandler(AppCompatCheckBox nativeView)
{
ChangeListener.Handler = null;
nativeView.SetOnCheckedChangeListener(null);
}

void OnCheckedChanged(bool isChecked)
{
if (VirtualView != null)
VirtualView.IsChecked = isChecked;
}

internal class CheckedChangeListener : Java.Lang.Object, CompoundButton.IOnCheckedChangeListener
{
public CheckBoxHandler? Handler { get; set; }

public CheckedChangeListener()
{
}

public void OnCheckedChanged(CompoundButton? nativeCheckBox, bool isChecked)
{
if (Handler == null || nativeCheckBox == null)
return;

Handler.OnCheckedChanged(isChecked);
}
}
}
}
9 changes: 9 additions & 0 deletions src/Core/src/Handlers/CheckBox/CheckBoxHandler.Standard.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using System;

namespace Microsoft.Maui.Handlers
{
public partial class CheckBoxHandler : AbstractViewHandler<ICheck, object>
{
protected override object CreateNativeView() => throw new NotImplementedException();
}
}
39 changes: 39 additions & 0 deletions src/Core/src/Handlers/CheckBox/CheckBoxHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
namespace Microsoft.Maui.Handlers
{
public partial class CheckBoxHandler
{
public static PropertyMapper<ICheck, CheckBoxHandler> CheckBoxMapper = new PropertyMapper<ICheck, CheckBoxHandler>(ViewHandler.ViewMapper)
{
#if MONOANDROID
[nameof(ICheck.BackgroundColor)] = MapBackgroundColor,
#endif
[nameof(ICheck.IsChecked)] = MapIsChecked,
[nameof(ICheck.Color)] = MapColor
};

public CheckBoxHandler() : base(CheckBoxMapper)
{

}

public CheckBoxHandler(PropertyMapper mapper) : base(mapper ?? CheckBoxMapper)
{

}
#if MONOANDROID
public static void MapBackgroundColor(CheckBoxHandler handler, ICheck check)
{
handler.TypedNativeView?.UpdateBackgroundColor(check);
}
#endif
public static void MapIsChecked(CheckBoxHandler handler, ICheck check)
{
handler.TypedNativeView?.UpdateIsChecked(check);
}

public static void MapColor(CheckBoxHandler handler, ICheck check)
{
handler.TypedNativeView?.UpdateColor(check);
}
}
}
74 changes: 74 additions & 0 deletions src/Core/src/Handlers/CheckBox/CheckBoxHandler.iOS.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
using System;

namespace Microsoft.Maui.Handlers
{
public partial class CheckBoxHandler : AbstractViewHandler<ICheck, NativeCheckBox>
{
protected virtual float MinimumSize => 44f;

protected override NativeCheckBox CreateNativeView()
{
return new NativeCheckBox
{
MinimumViewSize = MinimumSize
};
}

protected override void ConnectHandler(NativeCheckBox nativeView)
{
base.ConnectHandler(nativeView);

nativeView.CheckedChanged += OnCheckedChanged;
}

protected override void DisconnectHandler(NativeCheckBox nativeView)
{
base.DisconnectHandler(nativeView);

nativeView.CheckedChanged -= OnCheckedChanged;
}

public override Size GetDesiredSize(double widthConstraint, double heightConstraint)
{
var size = base.GetDesiredSize(widthConstraint, heightConstraint);

var set = false;

var width = widthConstraint;
var height = heightConstraint;

if (size.Width == 0)
{
if (widthConstraint <= 0 || double.IsInfinity(widthConstraint))
{
width = MinimumSize;
set = true;
}
}

if (size.Height == 0)
{
if (heightConstraint <= 0 || double.IsInfinity(heightConstraint))
{
height = MinimumSize;
set = true;
}
}

if (set)
{
size = new Size(width, height);
}

return size;
}

void OnCheckedChanged(object? sender, EventArgs e)
{
if (sender is NativeCheckBox nativeView && VirtualView != null)
{
VirtualView.IsChecked = nativeView.IsChecked;
}
}
}
}
1 change: 1 addition & 0 deletions src/Core/src/Hosting/AppHostBuilderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public static IAppHostBuilder UseMauiHandlers(this IAppHostBuilder builder)
builder.RegisterHandlers(new Dictionary<Type, Type>
{
{ typeof(IButton), typeof(ButtonHandler) },
{ typeof(ICheck), typeof(CheckBoxHandler) },
{ typeof(IEditor), typeof(EditorHandler) },
{ typeof(IEntry), typeof(EntryHandler) },
{ typeof(ILayout), typeof(LayoutHandler) },
Expand Down
57 changes: 57 additions & 0 deletions src/Core/src/Platform/Android/CheckBoxExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
using Android.Content.Res;
using Android.Graphics;
using AndroidX.AppCompat.Widget;
using AndroidX.Core.Widget;
using AAttribute = Android.Resource.Attribute;
using AColor = Android.Graphics.Color;
using XColor = Microsoft.Maui.Color;

namespace Microsoft.Maui
{
public static class CheckBoxExtensions
{
static readonly int[][] CheckedStates = new int[][]
{
new int[] { AAttribute.StateEnabled, AAttribute.StateChecked },
new int[] { AAttribute.StateEnabled, -AAttribute.StateChecked },
new int[] { -AAttribute.StateEnabled, AAttribute.StateChecked },
new int[] { -AAttribute.StateEnabled, -AAttribute.StatePressed },
};

public static void UpdateBackgroundColor(this AppCompatCheckBox nativeCheckBox, ICheck check)
{
if (check.BackgroundColor == XColor.Default)
nativeCheckBox.SetBackgroundColor(AColor.Transparent);
else
nativeCheckBox.SetBackgroundColor(check.BackgroundColor.ToNative());
}

public static void UpdateIsChecked(this AppCompatCheckBox nativeCheckBox, ICheck check)
{
nativeCheckBox.Checked = check.IsChecked;
}

public static void UpdateColor(this AppCompatCheckBox nativeCheckBox, ICheck check)
{
// TODO: Delete when implementing the logic to set the system accent color.
XColor accent = XColor.FromHex("#ff33b5e5");

var tintColor = check.Color == XColor.Default ? accent.ToNative() : check.Color.ToNative();

var tintList = new ColorStateList(
CheckedStates,
new int[]
{
tintColor,
tintColor,
tintColor,
tintColor
});

var tintMode = PorterDuff.Mode.SrcIn;

CompoundButtonCompat.SetButtonTintList(nativeCheckBox, tintList);
CompoundButtonCompat.SetButtonTintMode(nativeCheckBox, tintMode);
}
}
}
14 changes: 10 additions & 4 deletions src/Core/src/Platform/Android/ViewExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
using System;
using Android.Content.Res;
using Android.Graphics.Drawables;
using Microsoft.Maui;
using AView = Android.Views.View;

namespace Microsoft.Maui
Expand All @@ -24,6 +20,16 @@ public static void UpdateBackgroundColor(this AView nativeView, IView view)
nativeView?.SetBackgroundColor(backgroundColor.ToNative());
}

public static bool GetClipToOutline(this AView view)
{
return view.ClipToOutline;
}

public static void SetClipToOutline(this AView view, bool value)
{
view.ClipToOutline = value;
}

public static void UpdateAutomationId(this AView nativeView, IView view)
{
if (AutomationTagId == DefaultAutomationTagId)
Expand Down
15 changes: 15 additions & 0 deletions src/Core/src/Platform/Standard/CheckBoxExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace Microsoft.Maui
{
public static class CheckBoxExtensions
{
public static void UpdateIsChecked(this object nothing, ICheck check)
{

}

public static void UpdateColor(this object nothing, ICheck check)
{

}
}
}
Loading

0 comments on commit 71d7d56

Please sign in to comment.