Implement CharacterSpacing property in ButtonHandlers (#607)

This commit is contained in:
Javier Suárez 2021-04-06 05:35:57 +02:00 коммит произвёл GitHub
Родитель 5039e5d4e6
Коммит b51a6a3dac
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
14 изменённых файлов: 156 добавлений и 35 удалений

Просмотреть файл

@ -32,10 +32,6 @@
<ItemGroup Condition="$(TargetFramework.Contains('-windows')) != true ">
<Compile Remove="**\*.Windows.cs" />
<None Include="**\*.Windows.cs" />
<Compile Remove="**\*.xaml.cs" />
<None Include="**\*.xaml.cs" />
<Compile Remove="**\*.xaml" />
<None Include="**\*.xaml" />
<Compile Remove="**\Windows\*.cs" />
<None Include="**\Windows\*.cs" />
</ItemGroup>

Просмотреть файл

@ -361,6 +361,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Android.FastRenderers
_textColorSwitcher.Value.UpdateTextColor(this, Button.TextColor);
}
[PortHandler]
void UpdateCharacterSpacing()
{
if (Forms.IsLollipopOrNewer)

Просмотреть файл

@ -39,7 +39,6 @@ namespace Maui.Controls.Sample.Pages
var verticalStack = new VerticalStackLayout() { Spacing = 5, BackgroundColor = Color.AntiqueWhite };
var horizontalStack = new HorizontalStackLayout() { Spacing = 2, BackgroundColor = Color.CornflowerBlue };
verticalStack.Add(CreateSampleGrid());
verticalStack.Add(new Label { Text = " ", Padding = new Thickness(10) });
@ -55,7 +54,7 @@ namespace Maui.Controls.Sample.Pages
verticalStack.Add(new Label { Text = loremIpsum, MaxLines = 2 });
verticalStack.Add(new Label { Text = loremIpsum, LineBreakMode = LineBreakMode.TailTruncation });
verticalStack.Add(new Label { Text = loremIpsum, MaxLines = 2, LineBreakMode = LineBreakMode.TailTruncation });
verticalStack.Add(new Label { Text = "This should have five times the line height!", LineHeight = 5 });
verticalStack.Add(new Label { Text = "This should have five times the line height! " + loremIpsum, LineHeight = 5, MaxLines = 2 });
var visibleClearButtonEntry = new Entry() { ClearButtonVisibility = ClearButtonVisibility.WhileEditing, Placeholder = "This Entry will show clear button if has input." };
var hiddenClearButtonEntry = new Entry() { ClearButtonVisibility = ClearButtonVisibility.Never, Placeholder = "This Entry will not..." };
@ -64,14 +63,6 @@ namespace Maui.Controls.Sample.Pages
verticalStack.Add(hiddenClearButtonEntry);
verticalStack.Add(new Editor { Placeholder = "This is an editor placeholder." });
var paddingButton = new Button
{
Padding = new Thickness(40),
Text = "This button has a padding!!",
BackgroundColor = Color.Purple,
};
verticalStack.Add(paddingButton);
var underlineLabel = new Label { Text = "underline", TextDecorations = TextDecorations.Underline };
verticalStack.Add(underlineLabel);
@ -99,10 +90,22 @@ namespace Maui.Controls.Sample.Pages
horizontalStack.Add(button);
horizontalStack.Add(button2);
horizontalStack.Add(new Label { Text = "And these buttons are in a HorizontalStackLayout", VerticalOptions = LayoutOptions.Center });
verticalStack.Add(horizontalStack);
var paddingButton = new Button
{
Padding = new Thickness(40),
Text = "This button has a padding!!",
BackgroundColor = Color.Purple,
};
verticalStack.Add(paddingButton);
verticalStack.Add(new Button { Text = "CharacterSpacing" });
verticalStack.Add(new Button { CharacterSpacing = 8, Text = "CharacterSpacing" });
verticalStack.Add(new CheckBox());
verticalStack.Add(new CheckBox { BackgroundColor = Color.LightPink });
verticalStack.Add(new CheckBox { IsChecked = true, Color = Color.Aquamarine });

Просмотреть файл

@ -8,6 +8,8 @@ namespace Microsoft.Maui.Handlers
{
public partial class ButtonHandler : AbstractViewHandler<IButton, AppCompatButton>
{
static Thickness? DefaultPadding;
ButtonClickListener ClickListener { get; } = new ButtonClickListener();
ButtonTouchListener TouchListener { get; } = new ButtonTouchListener();
@ -21,6 +23,17 @@ namespace Microsoft.Maui.Handlers
return nativeButton;
}
protected override void SetupDefaults(AppCompatButton nativeView)
{
DefaultPadding = new Thickness(
nativeView.PaddingLeft,
nativeView.PaddingTop,
nativeView.PaddingRight,
nativeView.PaddingBottom);
base.SetupDefaults(nativeView);
}
protected override void ConnectHandler(AppCompatButton nativeView)
{
ClickListener.Handler = this;
@ -58,6 +71,11 @@ namespace Microsoft.Maui.Handlers
handler.TypedNativeView?.UpdateTextColor(button);
}
public static void MapCharacterSpacing(ButtonHandler handler, IButton button)
{
handler.TypedNativeView?.UpdateCharacterSpacing(button);
}
public static void MapFont(ButtonHandler handler, IButton button)
{
_ = handler.Services ?? throw new InvalidOperationException($"{nameof(Services)} should have been set by base class.");
@ -69,10 +87,10 @@ namespace Microsoft.Maui.Handlers
public static void MapPadding(ButtonHandler handler, IButton button)
{
handler.TypedNativeView?.UpdatePadding(button);
handler.TypedNativeView?.UpdatePadding(button, DefaultPadding);
}
public bool OnTouch(IButton? button, AView? v, MotionEvent? e)
bool OnTouch(IButton? button, AView? v, MotionEvent? e)
{
switch (e?.ActionMasked)
{
@ -87,12 +105,12 @@ namespace Microsoft.Maui.Handlers
return false;
}
public void OnClick(IButton? button, AView? v)
void OnClick(IButton? button, AView? v)
{
button?.Clicked();
}
public class ButtonClickListener : Java.Lang.Object, AView.IOnClickListener
class ButtonClickListener : Java.Lang.Object, AView.IOnClickListener
{
public ButtonHandler? Handler { get; set; }
@ -102,7 +120,7 @@ namespace Microsoft.Maui.Handlers
}
}
public class ButtonTouchListener : Java.Lang.Object, AView.IOnTouchListener
class ButtonTouchListener : Java.Lang.Object, AView.IOnTouchListener
{
public ButtonHandler? Handler { get; set; }

Просмотреть файл

@ -9,6 +9,7 @@ namespace Microsoft.Maui.Handlers
public static void MapBackgroundColor(ButtonHandler handler, IButton button) { }
public static void MapText(ButtonHandler handler, IButton button) { }
public static void MapTextColor(ButtonHandler handler, IButton button) { }
public static void MapCharacterSpacing(ButtonHandler handler, IButton button) { }
public static void MapFont(ButtonHandler handler, IButton button) { }
public static void MapPadding(ButtonHandler handler, IButton button) { }
}

Просмотреть файл

@ -59,6 +59,8 @@ namespace Microsoft.Maui.Handlers
handler.TypedNativeView?.UpdateTextColor(button, DefaultForeground);
}
public static void MapCharacterSpacing(ButtonHandler handler, IButton button) { }
public static void MapFont(ButtonHandler handler, IButton button)
{
_ = handler.Services ?? throw new InvalidOperationException($"{nameof(Services)} should have been set by base class.");

Просмотреть файл

@ -7,6 +7,7 @@ namespace Microsoft.Maui.Handlers
[nameof(IButton.BackgroundColor)] = MapBackgroundColor,
[nameof(IButton.Text)] = MapText,
[nameof(IButton.TextColor)] = MapTextColor,
[nameof(IButton.CharacterSpacing)] = MapCharacterSpacing,
[nameof(IButton.Font)] = MapFont,
[nameof(IButton.Padding)] = MapPadding,
};

Просмотреть файл

@ -59,6 +59,12 @@ namespace Microsoft.Maui.Handlers
{
handler.TypedNativeView?.UpdateTextColor(button, ButtonTextColorDefaultNormal, ButtonTextColorDefaultHighlighted, ButtonTextColorDefaultDisabled);
}
public static void MapCharacterSpacing(ButtonHandler handler, IButton button)
{
handler.TypedNativeView?.UpdateCharacterSpacing(button);
}
public static void MapPadding(ButtonHandler handler, IButton button)
{
handler.TypedNativeView?.UpdatePadding(button);

Просмотреть файл

@ -74,6 +74,7 @@ namespace Microsoft.Maui.Handlers
handler.TypedNativeView?.UpdateFont(label, fontManager);
}
public static void MapLineHeight(LabelHandler handler, ILabel label)
{
handler.TypedNativeView?.UpdateLineHeight(label, LineSpacingAddDefault, LineSpacingMultDefault);

Просмотреть файл

@ -24,6 +24,9 @@ namespace Microsoft.Maui
public static void UpdateTextColor(this AppCompatButton appCompatButton, IButton button, XColor defaultColor) =>
appCompatButton.SetTextColor(button.TextColor.Cleanse(defaultColor).ToNative());
public static void UpdateCharacterSpacing(this AppCompatButton appCompatButton, IButton button) =>
appCompatButton.LetterSpacing = button.CharacterSpacing.ToEm();
public static void UpdateFont(this AppCompatButton appCompatButton, IButton button, IFontManager fontManager)
{
var font = button.Font;
@ -35,21 +38,26 @@ namespace Microsoft.Maui
appCompatButton.SetTextSize(ComplexUnitType.Sp, sp);
}
public static void UpdatePadding(this AppCompatButton appCompatButton, IButton button)
public static void UpdatePadding(this AppCompatButton appCompatButton, IButton button, Thickness? defaultPadding = null)
{
var context = appCompatButton.Context;
if (context == null)
{
return;
}
var padding = button.Padding;
// TODO: have a way to use default padding
// Windows keeps the default as a base but this is also wrong.
// var padding = defaultPadding ?? new Thickness();
var padding = new Thickness();
padding.Left += context.ToPixels(button.Padding.Left);
padding.Top += context.ToPixels(button.Padding.Top);
padding.Right += context.ToPixels(button.Padding.Right);
padding.Bottom += context.ToPixels(button.Padding.Bottom);
appCompatButton.SetPadding(
(int)context.ToPixels(padding.Left),
(int)context.ToPixels(padding.Top),
(int)context.ToPixels(padding.Right),
(int)context.ToPixels(padding.Bottom));
(int)padding.Left,
(int)padding.Top,
(int)padding.Right,
(int)padding.Bottom);
}
static XColor Cleanse(this XColor color, XColor defaultColor) => color.IsDefault ? defaultColor : color;

Просмотреть файл

@ -23,6 +23,8 @@ namespace Microsoft.Maui
public static void UpdatePadding(this Control nativeControl, Thickness padding, UI.Xaml.Thickness? defaultThickness = null)
{
// TODO: have a way to reset the padding
// This is used for button, but this also means there can never be a 0 padding button
var newPadding = defaultThickness ?? new UI.Xaml.Thickness();
newPadding.Left += padding.Left;

Просмотреть файл

@ -1,4 +1,3 @@
using Microsoft.Maui;
using UIKit;
namespace Microsoft.Maui
@ -8,8 +7,8 @@ namespace Microsoft.Maui
public static void UpdateText(this UIButton nativeButton, IButton button) =>
nativeButton.SetTitle(button.Text, UIControlState.Normal);
public static void UpdateTextColor(this UIButton nativeButton, IButton button)
=> nativeButton.UpdateTextColor(button);
public static void UpdateTextColor(this UIButton nativeButton, IButton button) =>
nativeButton.UpdateTextColor(button);
public static void UpdateTextColor(this UIButton nativeButton, IButton button, UIColor? buttonTextColorDefaultNormal, UIColor? buttonTextColorDefaultHighlighted, UIColor? buttonTextColorDefaultDisabled)
{
@ -31,6 +30,17 @@ namespace Microsoft.Maui
}
}
public static void UpdateCharacterSpacing(this UIButton nativeButton, IButton button)
{
if (string.IsNullOrEmpty(button.Text))
return;
var textAttr = nativeButton.TitleLabel.AttributedText?.WithCharacterSpacing(button.CharacterSpacing);
if (textAttr != null)
nativeButton.TitleLabel.AttributedText = textAttr;
}
public static void UpdateFont(this UIButton nativeButton, IButton button, IFontManager fontManager)
{
var uiFont = fontManager.GetFont(button.Font);
@ -40,10 +50,10 @@ namespace Microsoft.Maui
public static void UpdatePadding(this UIButton nativeButton, IButton button)
{
nativeButton.ContentEdgeInsets = new UIEdgeInsets(
(float)button.Padding.Top,
(float)button.Padding.Left,
(float)button.Padding.Bottom,
(float)button.Padding.Right);
(float)button.Padding.Top,
(float)button.Padding.Left,
(float)button.Padding.Bottom,
(float)button.Padding.Right);
}
}
}

Просмотреть файл

@ -10,6 +10,32 @@ namespace Microsoft.Maui.DeviceTests
{
public partial class ButtonHandlerTests
{
[Fact(DisplayName = "CharacterSpacing Initializes Correctly")]
public async Task CharacterSpacingInitializesCorrectly()
{
var xplatCharacterSpacing = 4;
var button = new ButtonStub()
{
CharacterSpacing = xplatCharacterSpacing,
Text = "Test"
};
float expectedValue = button.CharacterSpacing.ToEm();
var values = await GetValueAsync(button, (handler) =>
{
return new
{
ViewValue = button.CharacterSpacing,
NativeViewValue = GetNativeCharacterSpacing(handler)
};
});
Assert.Equal(xplatCharacterSpacing, values.ViewValue);
Assert.Equal(expectedValue, values.NativeViewValue, EmCoefficientPrecision);
}
[Theory(DisplayName = "Font Family Initializes Correctly")]
[InlineData(null)]
[InlineData("monospace")]
@ -111,5 +137,17 @@ namespace Microsoft.Maui.DeviceTests
bool GetNativeIsItalic(ButtonHandler buttonHandler) =>
GetNativeButton(buttonHandler).Typeface.IsItalic;
double GetNativeCharacterSpacing(ButtonHandler buttonHandler)
{
var button = GetNativeButton(buttonHandler);
if (button != null)
{
return button.LetterSpacing;
}
return -1;
}
}
}

Просмотреть файл

@ -9,6 +9,31 @@ namespace Microsoft.Maui.DeviceTests
{
public partial class ButtonHandlerTests
{
[Fact(DisplayName = "CharacterSpacing Initializes Correctly")]
public async Task CharacterSpacingInitializesCorrectly()
{
string originalText = "Test";
var xplatCharacterSpacing = 4;
var button = new ButtonStub()
{
CharacterSpacing = xplatCharacterSpacing,
Text = originalText
};
var values = await GetValueAsync(button, (handler) =>
{
return new
{
ViewValue = button.CharacterSpacing,
NativeViewValue = GetNativeCharacterSpacing(handler)
};
});
Assert.Equal(xplatCharacterSpacing, values.ViewValue);
Assert.Equal(xplatCharacterSpacing, values.NativeViewValue);
}
[Theory(DisplayName = "Font Family Initializes Correctly")]
[InlineData(null)]
[InlineData("Times New Roman")]
@ -79,5 +104,14 @@ namespace Microsoft.Maui.DeviceTests
bool GetNativeIsItalic(ButtonHandler buttonHandler) =>
GetNativeButton(buttonHandler).TitleLabel.Font.FontDescriptor.SymbolicTraits.HasFlag(UIFontDescriptorSymbolicTraits.Italic);
double GetNativeCharacterSpacing(ButtonHandler buttonHandler)
{
var button = GetNativeButton(buttonHandler);
var attributedText = button.TitleLabel.AttributedText;
return attributedText.GetCharacterSpacing();
}
}
}