зеркало из https://github.com/DeGsoft/maui-linux.git
Implement CharacterSpacing property in ButtonHandlers (#607)
This commit is contained in:
Родитель
5039e5d4e6
Коммит
b51a6a3dac
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче