Skip to content
This repository has been archived by the owner on May 1, 2024. It is now read-only.

[Handlers] Map CornerRadius property in ButtonHandlers #13865

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

namespace Microsoft.Maui.Controls.Compatibility.Platform.Android
{
[PortHandler("Partially ported to ButtonBorderBackgroundManager")]
internal class BorderBackgroundManager : IDisposable
{
Drawable _defaultDrawable;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

namespace Microsoft.Maui.Controls.Compatibility.Platform.Android
{
[PortHandler("Partially ported to ButtonBorderDrawable")]
internal class BorderDrawable : Drawable
{
public const int DefaultCornerRadius = 2; // Default value for Android material button.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Microsoft.Maui.Controls.Compatibility.Platform.iOS
{
[PortHandler("Partially ported")]
internal static class BorderElementManager
{
static nfloat _defaultCornerRadius = 5;
Expand Down
2 changes: 2 additions & 0 deletions src/Controls/samples/Controls.Sample/Pages/MainPage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,13 @@ public MainPage(MainPageViewModel viewModel)
verticalStack.Add(label);

var button = new Button() { Text = _viewModel.Text, WidthRequest = 200 };

var button2 = new Button()
{
TextColor = Color.Green,
Text = "Hello I'm a button",
BackgroundColor = Color.Purple,
CornerRadius = 12,
Margin = new Thickness(12)
};

Expand Down
7 changes: 7 additions & 0 deletions src/Core/src/Core/IBorder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Microsoft.Maui
{
public interface IBorder : IView
{
int CornerRadius { get; }
}
}
2 changes: 1 addition & 1 deletion src/Core/src/Core/IButton.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace Microsoft.Maui
{
public interface IButton : IView, IText
public interface IButton : IView, IText, IBorder
{
void Pressed();
void Released();
Expand Down
16 changes: 15 additions & 1 deletion src/Core/src/Handlers/Button/ButtonHandler.Android.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ namespace Microsoft.Maui.Handlers
{
public partial class ButtonHandler : AbstractViewHandler<IButton, AppCompatButton>
{
static ButtonBorderBackgroundManager? BackgroundTracker;

ButtonClickListener ClickListener { get; } = new ButtonClickListener();
ButtonTouchListener TouchListener { get; } = new ButtonTouchListener();

Expand All @@ -27,6 +29,8 @@ protected override void ConnectHandler(AppCompatButton nativeView)
TouchListener.Handler = this;
nativeView.SetOnTouchListener(TouchListener);

BackgroundTracker = new ButtonBorderBackgroundManager(nativeView, VirtualView);

base.ConnectHandler(nativeView);
}

Expand All @@ -38,6 +42,9 @@ protected override void DisconnectHandler(AppCompatButton nativeView)
TouchListener.Handler = null;
nativeView.SetOnTouchListener(null);

BackgroundTracker?.Dispose();
BackgroundTracker = null;

base.DisconnectHandler(nativeView);
}

Expand All @@ -55,6 +62,13 @@ public static void MapTextColor(ButtonHandler handler, IButton button)
handler.TypedNativeView?.UpdateTextColor(button);
}

public static void MapCornerRadius(ButtonHandler handler, IButton button)
{
ViewHandler.CheckParameters(handler, button);

handler.TypedNativeView?.UpdateCornerRadius(button, BackgroundTracker);
}

public bool OnTouch(IButton? button, AView? v, MotionEvent? e)
{
switch (e?.ActionMasked)
Expand Down Expand Up @@ -89,7 +103,7 @@ public class ButtonTouchListener : Java.Lang.Object, AView.IOnTouchListener
{
public ButtonHandler? Handler { get; set; }

public bool OnTouch(AView? v, global::Android.Views.MotionEvent? e) =>
public bool OnTouch(AView? v, MotionEvent? e) =>
Handler?.OnTouch(Handler?.VirtualView, v, e) ?? false;
}
}
Expand Down
1 change: 1 addition & 0 deletions src/Core/src/Handlers/Button/ButtonHandler.Standard.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ public partial class ButtonHandler : AbstractViewHandler<IButton, object>

public static void MapText(ButtonHandler handler, IButton button) { }
public static void MapTextColor(ButtonHandler handler, IButton button) { }
public static void MapCornerRadius(ButtonHandler handler, IButton button) { }
}
}
3 changes: 2 additions & 1 deletion src/Core/src/Handlers/Button/ButtonHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ public partial class ButtonHandler
public static PropertyMapper<IButton, ButtonHandler> ButtonMapper = new PropertyMapper<IButton, ButtonHandler>(ViewHandler.ViewMapper)
{
[nameof(IButton.Text)] = MapText,
[nameof(IButton.TextColor)] = MapTextColor
[nameof(IButton.TextColor)] = MapTextColor,
[nameof(IButton.CornerRadius)] = MapCornerRadius
};

public ButtonHandler() : base(ButtonMapper)
Expand Down
7 changes: 7 additions & 0 deletions src/Core/src/Handlers/Button/ButtonHandler.iOS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,13 @@ public static void MapTextColor(ButtonHandler handler, IButton button)
handler.TypedNativeView?.UpdateTextColor(button, ButtonTextColorDefaultNormal, ButtonTextColorDefaultHighlighted, ButtonTextColorDefaultDisabled);
}

public static void MapCornerRadius(ButtonHandler handler, IButton button)
{
ViewHandler.CheckParameters(handler, button);

handler.TypedNativeView?.UpdateCornerRadius(button);
}

void SetControlPropertiesFromProxy()
{
if (TypedNativeView == null)
Expand Down
105 changes: 105 additions & 0 deletions src/Core/src/Platform/Android/ButtonBorderBackgroundManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
using Android.Content.Res;
using Android.Graphics.Drawables;
using Android.Views;
using System;

namespace Microsoft.Maui
{
public class ButtonBorderBackgroundManager : IDisposable
{
Drawable? _defaultDrawable;
ButtonBorderDrawable? _backgroundDrawable;
RippleDrawable? _rippleDrawable;
bool _drawableEnabled;

View? _nativeView;
IBorder? _border;

public ButtonBorderBackgroundManager(View nativeView, IBorder? border)
{
_nativeView = nativeView;
_border = border;
}

public static Color ColorButtonNormalOverride { get; set; }

public void UpdateDrawable()
{
// TODO: Set BorderColor and BorderWidth

if (_border == null || _nativeView == null)
return;

bool cornerRadiusIsDefault = _border.CornerRadius == -1;
bool backgroundColorIsDefault = _border.BackgroundColor == Color.Default;

if (backgroundColorIsDefault
&& cornerRadiusIsDefault)
{
if (!_drawableEnabled)
return;

if (_defaultDrawable != null)
_nativeView?.SetBackground(_defaultDrawable);

_drawableEnabled = false;
Reset();
}
else
{
if (_nativeView != null && _backgroundDrawable == null)
_backgroundDrawable = new ButtonBorderDrawable(_nativeView.Context!.ToPixels, _nativeView.GetColorButtonNormal());

if (_backgroundDrawable != null)
_backgroundDrawable.BorderElement = _border;

if (_drawableEnabled)
return;

if (_defaultDrawable == null)
_defaultDrawable = _nativeView?.Background;

if (!backgroundColorIsDefault)
{
var rippleColor = _backgroundDrawable?.PressedBackgroundColor.ToNative();

if (rippleColor.HasValue)
{
_rippleDrawable = new RippleDrawable(ColorStateList.ValueOf(rippleColor.Value), _backgroundDrawable, null);
_nativeView?.SetBackground(_rippleDrawable);
}
}

_drawableEnabled = true;
}

_nativeView?.Invalidate();
}

public void Reset()
{
if (_drawableEnabled)
{
_drawableEnabled = false;
_backgroundDrawable?.Reset();
_backgroundDrawable = null;
_rippleDrawable = null;
}
}

public void Dispose()
{
_backgroundDrawable?.Dispose();
_backgroundDrawable = null;

_defaultDrawable?.Dispose();
_defaultDrawable = null;

_rippleDrawable?.Dispose();
_rippleDrawable = null;

_border = null;
_nativeView = null;
}
}
}
Loading