Skip to content

Commit 817d68b

Browse files
jsuarezruizrmarinhohartez
authored
Implement CharacterSpacing property in WinUI ButtonHandler (#1009)
* Implement CharacterSpacing property in WinUI ButtonHandler * Fix extension method * Use MauiButton * Add missing ToEm() call Co-authored-by: Rui Marinho <me@ruimarinho.net> Co-authored-by: E.Z. Hart <hartez@gmail.com>
1 parent 9f51e12 commit 817d68b

File tree

8 files changed

+257
-17
lines changed

8 files changed

+257
-17
lines changed

src/Compatibility/Core/src/WinUI/FormsButton.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
namespace Microsoft.Maui.Controls.Compatibility.Platform.UWP
1010
{
11+
[PortHandler]
1112
public class FormsButton : Microsoft.UI.Xaml.Controls.Button
1213
{
1314
public static readonly DependencyProperty BorderRadiusProperty = DependencyProperty.Register(nameof(BorderRadius), typeof(int), typeof(FormsButton),

src/Compatibility/Core/src/WinUI/WinUIHelpers.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
namespace Microsoft.Maui.Controls.Compatibility.Platform.UWP
1212
{
13+
[PortHandler]
1314
static class WinUIHelpers
1415
{
1516
public static WThickness CreateThickness(double left, double top, double right, double bottom)

src/Core/src/Handlers/Button/ButtonHandler.Windows.cs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,20 @@
11
#nullable enable
2-
using System;
3-
using Microsoft.Extensions.DependencyInjection;
4-
using Microsoft.UI.Xaml.Controls;
52
using Microsoft.UI.Xaml.Input;
63

74
namespace Microsoft.Maui.Handlers
85
{
9-
public partial class ButtonHandler : ViewHandler<IButton, Button>
6+
public partial class ButtonHandler : ViewHandler<IButton, MauiButton>
107
{
118
static UI.Xaml.Thickness? DefaultPadding;
129
static UI.Xaml.Media.Brush? DefaultForeground;
1310
static UI.Xaml.Media.Brush? DefaultBackground;
1411

1512
PointerEventHandler? _pointerPressedHandler;
1613

17-
protected override Button CreateNativeView() => new Button();
14+
protected override MauiButton CreateNativeView()
15+
=> new MauiButton();
1816

19-
protected override void SetupDefaults(Button nativeView)
17+
protected override void SetupDefaults(MauiButton nativeView)
2018
{
2119
DefaultPadding = (UI.Xaml.Thickness)MauiWinUIApplication.Current.Resources["ButtonPadding"];
2220
DefaultForeground = (UI.Xaml.Media.Brush)MauiWinUIApplication.Current.Resources["ButtonForegroundThemeBrush"];
@@ -25,7 +23,7 @@ protected override void SetupDefaults(Button nativeView)
2523
base.SetupDefaults(nativeView);
2624
}
2725

28-
protected override void ConnectHandler(Button nativeView)
26+
protected override void ConnectHandler(MauiButton nativeView)
2927
{
3028
_pointerPressedHandler = new PointerEventHandler(OnPointerPressed);
3129

@@ -35,7 +33,7 @@ protected override void ConnectHandler(Button nativeView)
3533
base.ConnectHandler(nativeView);
3634
}
3735

38-
protected override void DisconnectHandler(Button nativeView)
36+
protected override void DisconnectHandler(MauiButton nativeView)
3937
{
4038
nativeView.Click -= OnClick;
4139
nativeView.RemoveHandler(UI.Xaml.UIElement.PointerPressedEvent, _pointerPressedHandler);
@@ -61,8 +59,10 @@ public static void MapTextColor(ButtonHandler handler, IButton button)
6159
handler.NativeView?.UpdateTextColor(button, DefaultForeground);
6260
}
6361

64-
[MissingMapper]
65-
public static void MapCharacterSpacing(ButtonHandler handler, IButton button) { }
62+
public static void MapCharacterSpacing(ButtonHandler handler, IButton button)
63+
{
64+
handler.NativeView?.UpdateCharacterSpacing(button.CharacterSpacing);
65+
}
6666

6767
public static void MapFont(ButtonHandler handler, IButton button)
6868
{
Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,24 @@
11
#nullable enable
2-
using Microsoft.UI.Xaml.Controls;
3-
42
namespace Microsoft.Maui
53
{
64
public static class ButtonExtensions
75
{
8-
public static void UpdateBackground(this Button nativeButton, IButton button, UI.Xaml.Media.Brush? defaultBrush = null) =>
6+
public static void UpdateBackground(this MauiButton nativeButton, IButton button, UI.Xaml.Media.Brush? defaultBrush = null) =>
97
nativeButton.UpdateBackground(button.Background, defaultBrush);
108

11-
public static void UpdateText(this Button nativeButton, IButton button) =>
9+
public static void UpdateText(this MauiButton nativeButton, IButton button) =>
1210
nativeButton.Content = button.Text;
1311

14-
public static void UpdateTextColor(this Button nativeButton, IButton button, UI.Xaml.Media.Brush? defaultBrush = null) =>
12+
public static void UpdateTextColor(this MauiButton nativeButton, IButton button, UI.Xaml.Media.Brush? defaultBrush = null) =>
1513
nativeButton.UpdateForegroundColor(button.TextColor, defaultBrush);
1614

17-
public static void UpdatePadding(this Button nativeButton, IButton button, UI.Xaml.Thickness? defaultThickness = null) =>
15+
public static void UpdateCharacterSpacing(this MauiButton nativeButton, IButton button) =>
16+
nativeButton.UpdateCharacterSpacing((int)button.CharacterSpacing);
17+
18+
public static void UpdatePadding(this MauiButton nativeButton, IButton button, UI.Xaml.Thickness? defaultThickness = null) =>
1819
nativeButton.UpdatePadding(button.Padding, defaultThickness);
1920

20-
public static void UpdateFont(this Button nativeButton, IButton button, IFontManager fontManager) =>
21+
public static void UpdateFont(this MauiButton nativeButton, IButton button, IFontManager fontManager) =>
2122
nativeButton.UpdateFont(button.Font, fontManager);
2223
}
2324
}
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
#nullable enable
2+
using Microsoft.UI.Xaml;
3+
using Microsoft.UI.Xaml.Controls;
4+
using WBrush = Microsoft.UI.Xaml.Media.Brush;
5+
using WContentPresenter = Microsoft.UI.Xaml.Controls.ContentPresenter;
6+
7+
namespace Microsoft.Maui
8+
{
9+
public class MauiButton : Button
10+
{
11+
public static readonly DependencyProperty BorderRadiusProperty =
12+
DependencyProperty.Register(nameof(BorderRadius), typeof(int), typeof(MauiButton),
13+
new PropertyMetadata(default(int), OnBorderRadiusChanged));
14+
15+
public static readonly DependencyProperty BackgroundColorProperty =
16+
DependencyProperty.Register(nameof(BackgroundColor), typeof(WBrush), typeof(MauiButton),
17+
new PropertyMetadata(default(WBrush), OnBackgroundColorChanged));
18+
19+
WContentPresenter? _contentPresenter;
20+
Grid? _rootGrid;
21+
22+
public WBrush BackgroundColor
23+
{
24+
get
25+
{
26+
return (WBrush)GetValue(BackgroundColorProperty);
27+
}
28+
set
29+
{
30+
SetValue(BackgroundColorProperty, value);
31+
}
32+
}
33+
34+
public int BorderRadius
35+
{
36+
get
37+
{
38+
return (int)GetValue(BorderRadiusProperty);
39+
}
40+
set
41+
{
42+
SetValue(BorderRadiusProperty, value);
43+
}
44+
}
45+
46+
protected override void OnApplyTemplate()
47+
{
48+
base.OnApplyTemplate();
49+
50+
_contentPresenter = GetTemplateChild("ContentPresenter") as WContentPresenter;
51+
_rootGrid = GetTemplateChild("RootGrid") as Grid;
52+
53+
UpdateBackgroundColor();
54+
UpdateBorderRadius();
55+
}
56+
57+
static void OnBackgroundColorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
58+
{
59+
((MauiButton)d).UpdateBackgroundColor();
60+
}
61+
62+
static void OnBorderRadiusChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
63+
{
64+
((MauiButton)d).UpdateBorderRadius();
65+
}
66+
67+
void UpdateBackgroundColor()
68+
{
69+
if (BackgroundColor == null)
70+
BackgroundColor = Background;
71+
72+
if (_contentPresenter != null)
73+
_contentPresenter.Background = BackgroundColor;
74+
75+
Background = new UI.Xaml.Media.SolidColorBrush(UI.Colors.Transparent);
76+
}
77+
78+
void UpdateBorderRadius()
79+
{
80+
var radius = BorderRadius == -1 ? 0 : BorderRadius;
81+
var cornerRadius = WinUIHelpers.CreateCornerRadius(radius);
82+
83+
if (_contentPresenter != null)
84+
_contentPresenter.CornerRadius = cornerRadius;
85+
86+
if (_rootGrid != null)
87+
_rootGrid.CornerRadius = cornerRadius;
88+
}
89+
90+
public void UpdateCharacterSpacing(double characterSpacing)
91+
{
92+
CharacterSpacing = characterSpacing.ToEm();
93+
94+
if (_contentPresenter != null)
95+
_contentPresenter.CharacterSpacing = CharacterSpacing;
96+
97+
var textBlock = GetTextBlock(Content);
98+
99+
if (textBlock != null)
100+
textBlock.CharacterSpacing = CharacterSpacing;
101+
}
102+
103+
public TextBlock? GetTextBlock(object content)
104+
{
105+
if (content is TextBlock tb)
106+
{
107+
return tb;
108+
}
109+
110+
if (content is StackPanel sp)
111+
{
112+
foreach (var item in sp.Children)
113+
{
114+
if (item is TextBlock textBlock)
115+
{
116+
return textBlock;
117+
}
118+
}
119+
}
120+
121+
return null;
122+
}
123+
}
124+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<ResourceDictionary
2+
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4+
xmlns:uwp="using:Microsoft.Maui">
5+
6+
<Style TargetType="uwp:MauiButton">
7+
<Setter Property="Background" Value="{ThemeResource ButtonBackground}"/>
8+
<Setter Property="Foreground" Value="{ThemeResource ButtonForeground}"/>
9+
<Setter Property="BorderBrush" Value="{ThemeResource ButtonBorderBrush}"/>
10+
<Setter Property="BorderThickness" Value="{ThemeResource ButtonBorderThemeThickness}"/>
11+
<Setter Property="Padding" Value="{StaticResource ButtonPadding}"/>
12+
<Setter Property="HorizontalAlignment" Value="Left"/>
13+
<Setter Property="VerticalAlignment" Value="Center"/>
14+
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}"/>
15+
<Setter Property="FontWeight" Value="Normal"/>
16+
<Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}"/>
17+
<Setter Property="UseSystemFocusVisuals" Value="{StaticResource UseSystemFocusVisuals}"/>
18+
<Setter Property="FocusVisualMargin" Value="-3"/>
19+
<Setter Property="Template">
20+
<Setter.Value>
21+
<ControlTemplate TargetType="Button">
22+
<ContentPresenter
23+
x:Name="ContentPresenter" AutomationProperties.AccessibilityView="Raw"
24+
Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}"
25+
BorderBrush="{TemplateBinding BorderBrush}" ContentTemplate="{TemplateBinding ContentTemplate}"
26+
Content="{TemplateBinding Content}" CornerRadius="{TemplateBinding CornerRadius}"
27+
ContentTransitions="{TemplateBinding ContentTransitions}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
28+
Padding="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}">
29+
<VisualStateManager.VisualStateGroups>
30+
<VisualStateGroup x:Name="CommonStates">
31+
<VisualState x:Name="Normal">
32+
<Storyboard>
33+
<PointerUpThemeAnimation Storyboard.TargetName="ContentPresenter"/>
34+
</Storyboard>
35+
</VisualState>
36+
<VisualState x:Name="PointerOver">
37+
<Storyboard>
38+
<PointerUpThemeAnimation Storyboard.TargetName="ContentPresenter"/>
39+
</Storyboard>
40+
</VisualState>
41+
<VisualState x:Name="Pressed">
42+
<Storyboard>
43+
<PointerDownThemeAnimation Storyboard.TargetName="ContentPresenter"/>
44+
</Storyboard>
45+
</VisualState>
46+
</VisualStateGroup>
47+
</VisualStateManager.VisualStateGroups>
48+
</ContentPresenter>
49+
</ControlTemplate>
50+
</Setter.Value>
51+
</Setter>
52+
</Style>
53+
54+
</ResourceDictionary>

src/Core/src/Platform/Windows/Styles/Resources.xaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
<ResourceDictionary.MergedDictionaries>
88
<ResourceDictionary Source="MauiActivityIndicatorStyle.xaml" />
9+
<ResourceDictionary Source="MauiButtonStyle.xaml" />
910
<ResourceDictionary Source="MauiComboBoxStyle.xaml" />
1011
<ResourceDictionary Source="MauiTextBoxStyle.xaml" />
1112
</ResourceDictionary.MergedDictionaries>
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
using WThickness = Microsoft.UI.Xaml.Thickness;
2+
using WCornerRadius = Microsoft.UI.Xaml.CornerRadius;
3+
using WGridLength = Microsoft.UI.Xaml.GridLength;
4+
using UwpGridUnitType = Microsoft.UI.Xaml.GridUnitType;
5+
6+
namespace Microsoft.Maui
7+
{
8+
internal static class WinUIHelpers
9+
{
10+
public static WThickness CreateThickness(double left, double top, double right, double bottom)
11+
{
12+
return new WThickness
13+
{
14+
Left = left,
15+
Top = top,
16+
Right = right,
17+
Bottom = bottom
18+
};
19+
}
20+
21+
public static WThickness CreateThickness(double all)
22+
{
23+
return new WThickness
24+
{
25+
Left = all,
26+
Top = all,
27+
Right = all,
28+
Bottom = all
29+
};
30+
}
31+
public static WCornerRadius CreateCornerRadius(double left, double top, double right, double bottom)
32+
{
33+
return new WCornerRadius
34+
{
35+
TopLeft = left,
36+
TopRight = top,
37+
BottomRight = right,
38+
BottomLeft = bottom
39+
};
40+
}
41+
42+
public static WCornerRadius CreateCornerRadius(double all)
43+
{
44+
return new WCornerRadius
45+
{
46+
TopLeft = all,
47+
TopRight = all,
48+
BottomRight = all,
49+
BottomLeft = all
50+
};
51+
}
52+
53+
public static WGridLength CreateGridLength(int v, UwpGridUnitType auto)
54+
{
55+
return new WGridLength(v, auto);
56+
}
57+
}
58+
}

0 commit comments

Comments
 (0)