Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use the Default Button Styles (Windows 11 Styles) #3363

Merged
merged 4 commits into from Nov 17, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -30,6 +30,12 @@
BackgroundColor="Red"
TextColor="White"
Text="Button"/>
<Label
Text="Character Spacing"
Style="{StaticResource Headline}"/>
<Button
CharacterSpacing="20"
Text="Button"/>
<Label
Text="Image Source"
Style="{StaticResource Headline}"/>
Expand Down
@@ -1,26 +1,19 @@
#nullable enable

using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media.Imaging;
using WImage = Microsoft.UI.Xaml.Controls.Image;
using WStretch = Microsoft.UI.Xaml.Media.Stretch;
using WThickness = Microsoft.UI.Xaml.Thickness;
using WImageSource = Microsoft.UI.Xaml.Media.ImageSource;

namespace Microsoft.Maui.Controls.Platform
{
public static class ButtonExtensions
{
public static void UpdateContentLayout(this MauiButton mauiButton, Button button)
public static void UpdateContentLayout(this UI.Xaml.Controls.Button mauiButton, Button button)
{
// If the Content isn't the StackPanel setup by Maui.Core then
// The user has set a custom Content or the content isn't a mix of text/images
if (mauiButton.Content is not StackPanel container)
return;

var image = mauiButton.GetImage();
var textBlock = mauiButton.GetTextBlock();
var image = mauiButton.GetContent<UI.Xaml.Controls.Image>();
var textBlock = mauiButton.GetContent<UI.Xaml.Controls.TextBlock>();

// If either of these are null then the user has taken control of the content
// and we don't know how to apply our changes
Expand All @@ -31,14 +24,11 @@ public static void UpdateContentLayout(this MauiButton mauiButton, Button button
var layout = button.ContentLayout;
var spacing = layout.Spacing;

container.HorizontalAlignment = Microsoft.UI.Xaml.HorizontalAlignment.Center;
container.VerticalAlignment = Microsoft.UI.Xaml.VerticalAlignment.Center;

switch (layout.Position)
{
case Button.ButtonContentLayout.ImagePosition.Top:
container.Orientation = Orientation.Vertical;
image.Margin = WinUIHelpers.CreateThickness(0, 0, 0, spacing);
image.Margin = WinUIHelpers.CreateThickness(0, 0, 0, spacing);
container.Children.Add(image);
container.Children.Add(textBlock);
break;
Expand Down
75 changes: 46 additions & 29 deletions src/Core/src/Handlers/Button/ButtonHandler.Windows.cs
@@ -1,46 +1,63 @@
#nullable enable
using System.Threading.Tasks;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Media;

namespace Microsoft.Maui.Handlers
{
public partial class ButtonHandler : ViewHandler<IButton, MauiButton>
public partial class ButtonHandler : ViewHandler<IButton, Button>
{
static UI.Xaml.Thickness? DefaultPadding;
static UI.Xaml.Media.Brush? DefaultForeground;
static UI.Xaml.Media.Brush? DefaultBackground;

PointerEventHandler? _pointerPressedHandler;
PointerEventHandler? _pointerReleasedHandler;

protected override MauiButton CreateNativeView()
=> new MauiButton();

void SetupDefaults(MauiButton nativeView)
{
DefaultPadding = (UI.Xaml.Thickness)MauiWinUIApplication.Current.Resources["ButtonPadding"];
DefaultForeground = (UI.Xaml.Media.Brush)MauiWinUIApplication.Current.Resources["ButtonForegroundThemeBrush"];
DefaultBackground = (UI.Xaml.Media.Brush)MauiWinUIApplication.Current.Resources["ButtonBackgroundThemeBrush"];
}

protected override void ConnectHandler(MauiButton nativeView)
protected override Button CreateNativeView() =>
new Button
{
Content = new StackPanel
{
HorizontalAlignment = HorizontalAlignment.Center,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we simplified all this properties using Styles?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose we could create a style for the maui buttons, but is it necessary?

VerticalAlignment = VerticalAlignment.Center,
Orientation = Orientation.Horizontal,
Margin = WinUIHelpers.CreateThickness(0),
Children =
{
new Image
{
VerticalAlignment = VerticalAlignment.Center,
HorizontalAlignment = HorizontalAlignment.Center,
Stretch = Stretch.Uniform,
Margin = WinUIHelpers.CreateThickness(0),
Visibility = UI.Xaml.Visibility.Collapsed,
},
new TextBlock
{
VerticalAlignment = VerticalAlignment.Center,
HorizontalAlignment = HorizontalAlignment.Center,
Margin = WinUIHelpers.CreateThickness(0),
Visibility = UI.Xaml.Visibility.Collapsed,
}
}
}
};

protected override void ConnectHandler(Button nativeView)
{
_pointerPressedHandler = new PointerEventHandler(OnPointerPressed);
_pointerReleasedHandler = new PointerEventHandler(OnPointerReleased);

nativeView.Click += OnClick;
nativeView.AddHandler(UI.Xaml.UIElement.PointerPressedEvent, _pointerPressedHandler, true);
nativeView.AddHandler(UI.Xaml.UIElement.PointerReleasedEvent, _pointerReleasedHandler, true);
nativeView.AddHandler(UIElement.PointerPressedEvent, _pointerPressedHandler, true);
nativeView.AddHandler(UIElement.PointerReleasedEvent, _pointerReleasedHandler, true);

base.ConnectHandler(nativeView);
}

protected override void DisconnectHandler(MauiButton nativeView)
protected override void DisconnectHandler(Button nativeView)
{
nativeView.Click -= OnClick;
nativeView.RemoveHandler(UI.Xaml.UIElement.PointerPressedEvent, _pointerPressedHandler);
nativeView.RemoveHandler(UI.Xaml.UIElement.PointerReleasedEvent, _pointerReleasedHandler);
nativeView.RemoveHandler(UIElement.PointerPressedEvent, _pointerPressedHandler);
nativeView.RemoveHandler(UIElement.PointerReleasedEvent, _pointerReleasedHandler);

_pointerPressedHandler = null;
_pointerReleasedHandler = null;
Expand All @@ -51,7 +68,7 @@ protected override void DisconnectHandler(MauiButton nativeView)
// This is a Windows-specific mapping
public static void MapBackground(IButtonHandler handler, IButton button)
{
handler.TypedNativeView?.UpdateBackground(button, DefaultBackground);
handler.TypedNativeView?.UpdateBackground(button);
}

public static void MapText(IButtonHandler handler, IText button)
Expand All @@ -61,12 +78,12 @@ public static void MapText(IButtonHandler handler, IText button)

public static void MapTextColor(IButtonHandler handler, ITextStyle button)
{
handler.TypedNativeView?.UpdateTextColor(button, DefaultForeground);
handler.TypedNativeView?.UpdateTextColor(button);
}

public static void MapCharacterSpacing(IButtonHandler handler, ITextStyle button)
{
handler.TypedNativeView?.UpdateCharacterSpacing(button.CharacterSpacing);
handler.TypedNativeView?.UpdateCharacterSpacing(button);
}

public static void MapFont(IButtonHandler handler, ITextStyle button)
Expand All @@ -78,7 +95,7 @@ public static void MapFont(IButtonHandler handler, ITextStyle button)

public static void MapPadding(IButtonHandler handler, IButton button)
{
handler.TypedNativeView?.UpdatePadding(button, DefaultPadding);
handler.TypedNativeView?.UpdatePadding(button);
}

public static void MapImageSource(IButtonHandler handler, IButton image) =>
Expand All @@ -87,12 +104,12 @@ public static void MapPadding(IButtonHandler handler, IButton button)
.UpdateImageSourceAsync()
.FireAndForget(handler);

void OnSetImageSource(ImageSource? obj)
void OnSetImageSource(ImageSource? nativeImageSource)
{
NativeView.UpdateImageSource(VirtualView, obj);
NativeView.UpdateImageSource(nativeImageSource);
}

void OnClick(object sender, UI.Xaml.RoutedEventArgs e)
void OnClick(object sender, RoutedEventArgs e)
{
VirtualView?.Clicked();
VirtualView?.Released();
Expand Down
2 changes: 1 addition & 1 deletion src/Core/src/Handlers/Button/ButtonHandler.cs
Expand Up @@ -3,7 +3,7 @@
#elif MONOANDROID
using NativeView = Google.Android.Material.Button.MaterialButton;
#elif WINDOWS
using NativeView = Microsoft.Maui.MauiButton;
using NativeView = Microsoft.UI.Xaml.Controls.Button;
#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID)
using NativeView = System.Object;
#endif
Expand Down
2 changes: 1 addition & 1 deletion src/Core/src/Handlers/Button/IButtonHandler.cs
Expand Up @@ -3,7 +3,7 @@
#elif MONOANDROID
using NativeView = Google.Android.Material.Button.MaterialButton;
#elif WINDOWS
using NativeView = Microsoft.Maui.MauiButton;
using NativeView = Microsoft.UI.Xaml.Controls.Button;
#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID)
using NativeView = System.Object;
#endif
Expand Down
94 changes: 18 additions & 76 deletions src/Core/src/Handlers/ImageButton/ImageButtonHandler.Windows.cs
@@ -1,111 +1,53 @@
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Media;

namespace Microsoft.Maui.Handlers
{
public partial class ImageButtonHandler : ViewHandler<IImageButton, MauiButton>
public partial class ImageButtonHandler : ViewHandler<IImageButton, Button>
{

PointerEventHandler? _pointerPressedHandler;
Image? _image;
protected override MauiButton CreateNativeView()
{
_image = new Image()
{
VerticalAlignment = Microsoft.UI.Xaml.VerticalAlignment.Center,
HorizontalAlignment = Microsoft.UI.Xaml.HorizontalAlignment.Center,
Stretch = Stretch.Uniform,
};

var mauiButton = new MauiButton()
protected override Button CreateNativeView() =>
new Button
{
Content = _image
Content = new Image
{
VerticalAlignment = VerticalAlignment.Center,
HorizontalAlignment = HorizontalAlignment.Center,
Stretch = Stretch.Uniform,
}
};

mauiButton.Padding = WinUIHelpers.CreateThickness(0);
mauiButton.BorderThickness = WinUIHelpers.CreateThickness(0);
mauiButton.Background = null;

return mauiButton;
}

protected override void ConnectHandler(MauiButton nativeView)
protected override void ConnectHandler(Button nativeView)
{
_pointerPressedHandler = new PointerEventHandler(OnPointerPressed);

nativeView.Click += OnClick;
nativeView.AddHandler(UI.Xaml.UIElement.PointerPressedEvent, _pointerPressedHandler, true);

if (_image != null)
{
_image.ImageFailed += OnImageFailed;
_image.ImageOpened += OnImageOpened;
}
nativeView.AddHandler(UIElement.PointerPressedEvent, _pointerPressedHandler, true);

base.ConnectHandler(nativeView);

nativeView.Loaded += OnNativeViewLoaded;
nativeView.Unloaded += OnNativeViewUnloaded;
}

protected override void DisconnectHandler(MauiButton nativeView)
protected override void DisconnectHandler(Button nativeView)
{
nativeView.Click -= OnClick;
nativeView.RemoveHandler(UI.Xaml.UIElement.PointerPressedEvent, _pointerPressedHandler);
nativeView.RemoveHandler(UIElement.PointerPressedEvent, _pointerPressedHandler);

_pointerPressedHandler = null;

base.DisconnectHandler(nativeView);

if (nativeView.XamlRoot != null)
nativeView.XamlRoot.Changed -= OnXamlRootChanged;

nativeView.Loaded -= OnNativeViewLoaded;
nativeView.Unloaded -= OnNativeViewUnloaded;

SourceLoader.Reset();
}

void OnImageOpened(object sender, RoutedEventArgs e)
{

}

void OnImageFailed(object sender, ExceptionRoutedEventArgs e)
{
}

void OnSetImageSource(ImageSource? obj)
{
if (NativeView.Content is Image i)
i.Source = obj;
}

void OnNativeViewLoaded(object sender = null!, RoutedEventArgs e = null!)
{
if (NativeView?.XamlRoot != null)
{
NativeView.XamlRoot.Changed += OnXamlRootChanged;
}
}

void OnNativeViewUnloaded(object sender = null!, RoutedEventArgs e = null!)
{
if (NativeView?.XamlRoot != null)
NativeView.XamlRoot.Changed -= OnXamlRootChanged;
}

void OnXamlRootChanged(XamlRoot sender, XamlRootChangedEventArgs args)
void OnSetImageSource(ImageSource? nativeImageSource)
{
UpdateValue(nameof(IImage.Source));
NativeView.UpdateImageSource(nativeImageSource);
}

void OnClick(object sender, UI.Xaml.RoutedEventArgs e)
void OnClick(object sender, RoutedEventArgs e)
{
VirtualView?.Clicked();
VirtualView?.Released();
Expand All @@ -116,4 +58,4 @@ void OnPointerPressed(object sender, PointerRoutedEventArgs e)
VirtualView?.Pressed();
}
}
}
}
19 changes: 10 additions & 9 deletions src/Core/src/Handlers/ImageButton/ImageButtonHandler.cs
@@ -1,18 +1,20 @@
using System;
using System.Collections.Generic;
using System.Text;
#if __IOS__ || MACCATALYST
using NativeImage = UIKit.UIImage;
using NativeImageView = UIKit.UIImageView;
using NativeView = UIKit.UIButton;
#elif MONOANDROID
using NativeImage = Android.Graphics.Drawables.Drawable;
using NativeImageView = Android.Widget.ImageView;
using NativeView = AndroidX.AppCompat.Widget.AppCompatImageButton;
#elif WINDOWS
using NativeImage = Microsoft.UI.Xaml.Media.ImageSource;
using NativeImageView = Microsoft.UI.Xaml.Controls.Image;
using NativeView = Microsoft.UI.Xaml.FrameworkElement;
#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID)
using NativeView = System.Object;
using NativeImage = System.Object;
using NativeImageView = System.Object;
using NativeView = System.Object;
#endif

namespace Microsoft.Maui.Handlers
Expand All @@ -38,15 +40,14 @@ public ImageButtonHandler(IPropertyMapper mapper) : base(mapper ?? Mapper)

IImage IImageHandler.TypedVirtualView => VirtualView;

NativeImageView IImageHandler.TypedNativeView =>
#if __IOS__
UIKit.UIImageView IImageHandler.TypedNativeView => NativeView.ImageView;
NativeView.ImageView;
#elif WINDOWS
UI.Xaml.Controls.Image IImageHandler.TypedNativeView => NativeView.GetImage() ?? (UI.Xaml.Controls.Image)NativeView.Content;
#elif __ANDROID__
Android.Widget.ImageView IImageHandler.TypedNativeView => NativeView;
NativeView.GetContent<NativeImageView>() ?? throw new InvalidOperationException("ImageButton did not contain an Image element.");
#else
object IImageHandler.TypedNativeView => NativeView;
NativeView;
#endif
ImageSourcePartLoader IImageHandler.SourceLoader => SourceLoader;
}
}
}