Implement Font properties in TimePickerHandlers (#583)

* Implement Font properties in TimePickerHandlers

* Fix build error
This commit is contained in:
Javier Suárez 2021-03-25 01:28:41 +01:00 коммит произвёл GitHub
Родитель 69eaa116ce
Коммит 55922dcaed
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
14 изменённых файлов: 163 добавлений и 11 удалений

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

@ -172,6 +172,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Android
Element.InvalidateMeasureNonVirtual(Internals.InvalidationTrigger.MeasureChanged); Element.InvalidateMeasureNonVirtual(Internals.InvalidationTrigger.MeasureChanged);
} }
[PortHandler]
void UpdateFont() void UpdateFont()
{ {
EditText.Typeface = Element.ToTypeface(); EditText.Typeface = Element.ToTypeface();

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

@ -176,6 +176,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.iOS
(Control as UITextField).UpdateTextAlignment(Element); (Control as UITextField).UpdateTextAlignment(Element);
} }
[PortHandler]
protected internal virtual void UpdateFont() protected internal virtual void UpdateFont()
{ {
Control.Font = Element.ToUIFont(); Control.Font = Element.ToUIFont();

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

@ -2,6 +2,8 @@
{ {
public partial class TimePicker : ITimePicker public partial class TimePicker : ITimePicker
{ {
Font? _font;
Font ITimePicker.Font => _font ??= Font.OfSize(FontFamily, FontSize).WithAttributes(FontAttributes);
} }
} }

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

@ -21,5 +21,10 @@ namespace Microsoft.Maui
/// Gets the spacing between characters of the text. /// Gets the spacing between characters of the text.
/// </summary> /// </summary>
double CharacterSpacing { get; } double CharacterSpacing { get; }
/// <summary>
/// Gets the font family, style and size of the font.
/// </summary>
Font Font { get; }
} }
} }

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

@ -1,6 +1,7 @@
using System; using System;
using Android.App; using Android.App;
using Android.Text.Format; using Android.Text.Format;
using Microsoft.Extensions.DependencyInjection;
namespace Microsoft.Maui.Handlers namespace Microsoft.Maui.Handlers
{ {
@ -59,6 +60,15 @@ namespace Microsoft.Maui.Handlers
handler.TypedNativeView?.UpdateCharacterSpacing(timePicker); handler.TypedNativeView?.UpdateCharacterSpacing(timePicker);
} }
public static void MapFont(TimePickerHandler handler, ITimePicker timePicker)
{
_ = handler.Services ?? throw new InvalidOperationException($"{nameof(Services)} should have been set by base class.");
var fontManager = handler.Services.GetRequiredService<IFontManager>();
handler.TypedNativeView?.UpdateFont(timePicker, fontManager);
}
void ShowPickerDialog() void ShowPickerDialog()
{ {
if (VirtualView == null) if (VirtualView == null)

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

@ -9,5 +9,6 @@ namespace Microsoft.Maui.Handlers
public static void MapFormat(TimePickerHandler handler, ITimePicker view) { } public static void MapFormat(TimePickerHandler handler, ITimePicker view) { }
public static void MapTime(TimePickerHandler handler, ITimePicker view) { } public static void MapTime(TimePickerHandler handler, ITimePicker view) { }
public static void MapCharacterSpacing(TimePickerHandler handler, ITimePicker view) { } public static void MapCharacterSpacing(TimePickerHandler handler, ITimePicker view) { }
public static void MapFont(TimePickerHandler handler, ITimePicker view) { }
} }
} }

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

@ -6,7 +6,8 @@
{ {
[nameof(ITimePicker.Format)] = MapFormat, [nameof(ITimePicker.Format)] = MapFormat,
[nameof(ITimePicker.Time)] = MapTime, [nameof(ITimePicker.Time)] = MapTime,
[nameof(ITimePicker.CharacterSpacing)] = MapCharacterSpacing [nameof(ITimePicker.CharacterSpacing)] = MapCharacterSpacing,
[nameof(ITimePicker.Font)] = MapFont
}; };
public TimePickerHandler() : base(TimePickerMapper) public TimePickerHandler() : base(TimePickerMapper)

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

@ -1,4 +1,5 @@
using System; using System;
using Microsoft.Extensions.DependencyInjection;
namespace Microsoft.Maui.Handlers namespace Microsoft.Maui.Handlers
{ {
@ -44,6 +45,15 @@ namespace Microsoft.Maui.Handlers
handler.TypedNativeView?.UpdateCharacterSpacing(timePicker); handler.TypedNativeView?.UpdateCharacterSpacing(timePicker);
} }
public static void MapFont(TimePickerHandler handler, ITimePicker timePicker)
{
_ = handler.Services ?? throw new InvalidOperationException($"{nameof(Services)} should have been set by base class.");
var fontManager = handler.Services.GetRequiredService<IFontManager>();
handler.TypedNativeView?.UpdateFont(timePicker, fontManager);
}
void OnValueChanged(object? sender, EventArgs e) void OnValueChanged(object? sender, EventArgs e)
{ {
SetVirtualViewTime(); SetVirtualViewTime();

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

@ -17,6 +17,9 @@
mauiTimePicker.LetterSpacing = timePicker.CharacterSpacing.ToEm(); mauiTimePicker.LetterSpacing = timePicker.CharacterSpacing.ToEm();
} }
public static void UpdateFont(this MauiTimePicker mauiTimePicker, ITimePicker timePicker, IFontManager fontManager) =>
mauiTimePicker.UpdateFont(timePicker.Font, fontManager);
internal static void SetTime(this MauiTimePicker mauiTimePicker, ITimePicker timePicker) internal static void SetTime(this MauiTimePicker mauiTimePicker, ITimePicker timePicker)
{ {
var time = timePicker.Time; var time = timePicker.Time;

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

@ -7,19 +7,19 @@ namespace Microsoft.Maui
{ {
public static class TimePickerExtensions public static class TimePickerExtensions
{ {
public static void UpdateFormat(this MauiTimePicker mauiTimePicker, ITimePicker view) public static void UpdateFormat(this MauiTimePicker mauiTimePicker, ITimePicker timePicker)
{ {
mauiTimePicker.UpdateTime(view, null); mauiTimePicker.UpdateTime(timePicker, null);
} }
public static void UpdateFormat(this MauiTimePicker mauiTimePicker, ITimePicker view, UIDatePicker? picker) public static void UpdateFormat(this MauiTimePicker mauiTimePicker, ITimePicker timePicker, UIDatePicker? picker)
{ {
mauiTimePicker.UpdateTime(view, picker); mauiTimePicker.UpdateTime(timePicker, picker);
} }
public static void UpdateTime(this MauiTimePicker mauiTimePicker, ITimePicker view) public static void UpdateTime(this MauiTimePicker mauiTimePicker, ITimePicker timePicker)
{ {
mauiTimePicker.UpdateTime(view, null); mauiTimePicker.UpdateTime(timePicker, null);
} }
public static void UpdateTime(this MauiTimePicker mauiTimePicker, ITimePicker timePicker, UIDatePicker? picker) public static void UpdateTime(this MauiTimePicker mauiTimePicker, ITimePicker timePicker, UIDatePicker? picker)
@ -62,12 +62,18 @@ namespace Microsoft.Maui
mauiTimePicker.UpdateCharacterSpacing(timePicker); mauiTimePicker.UpdateCharacterSpacing(timePicker);
} }
public static void UpdateCharacterSpacing(this MauiTimePicker mauiTimePicker, ITimePicker view) public static void UpdateCharacterSpacing(this MauiTimePicker mauiTimePicker, ITimePicker timePicker)
{ {
var textAttr = mauiTimePicker.AttributedText?.WithCharacterSpacing(view.CharacterSpacing); var textAttr = mauiTimePicker.AttributedText?.WithCharacterSpacing(timePicker.CharacterSpacing);
if (textAttr != null) if (textAttr != null)
mauiTimePicker.AttributedText = textAttr; mauiTimePicker.AttributedText = textAttr;
} }
public static void UpdateFont(this MauiTimePicker mauiTimePicker, ITimePicker timePicker, IFontManager fontManager)
{
var uiFont = fontManager.GetFont(timePicker.Font);
mauiTimePicker.Font = uiFont;
}
} }
} }

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

@ -1,5 +1,6 @@
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Maui.DeviceTests.Stubs; using Microsoft.Maui.DeviceTests.Stubs;
using Microsoft.Maui.Handlers; using Microsoft.Maui.Handlers;
using Xunit; using Xunit;
@ -34,6 +35,33 @@ namespace Microsoft.Maui.DeviceTests
Assert.Equal(expectedValue, values.NativeViewValue, EmCoefficientPrecision); Assert.Equal(expectedValue, values.NativeViewValue, EmCoefficientPrecision);
} }
[Theory(DisplayName = "Font Family Initializes Correctly")]
[InlineData(null)]
[InlineData("monospace")]
[InlineData("Dokdo")]
public async Task FontFamilyInitializesCorrectly(string family)
{
var timePicker = new TimePickerStub()
{
Time = TimeSpan.FromHours(7),
Font = Font.OfSize(family, 10)
};
var handler = await CreateHandlerAsync(timePicker);
var nativeEntry = GetNativeTimePicker(handler);
var fontManager = handler.Services.GetRequiredService<IFontManager>();
var nativeFont = fontManager.GetTypeface(Font.OfSize(family, 0.0));
Assert.Equal(nativeFont, nativeEntry.Typeface);
if (string.IsNullOrEmpty(family))
Assert.Equal(fontManager.DefaultTypeface, nativeEntry.Typeface);
else
Assert.NotEqual(fontManager.DefaultTypeface, nativeEntry.Typeface);
}
MauiTimePicker GetNativeTimePicker(TimePickerHandler timePickerHandler) => MauiTimePicker GetNativeTimePicker(TimePickerHandler timePickerHandler) =>
(MauiTimePicker)timePickerHandler.View; (MauiTimePicker)timePickerHandler.View;
@ -62,5 +90,17 @@ namespace Microsoft.Maui.DeviceTests
return -1; return -1;
} }
double GetNativeUnscaledFontSize(TimePickerHandler timePickerHandler)
{
var mauiTimePicker = GetNativeTimePicker(timePickerHandler);
return mauiTimePicker.TextSize / mauiTimePicker.Resources.DisplayMetrics.Density;
}
bool GetNativeIsBold(TimePickerHandler timePickerHandler) =>
GetNativeTimePicker(timePickerHandler).Typeface.IsBold;
bool GetNativeIsItalic(TimePickerHandler timePickerHandler) =>
GetNativeTimePicker(timePickerHandler).Typeface.IsItalic;
} }
} }

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

@ -2,6 +2,7 @@
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Maui.DeviceTests.Stubs; using Microsoft.Maui.DeviceTests.Stubs;
using Microsoft.Maui.Handlers; using Microsoft.Maui.Handlers;
using Xunit;
namespace Microsoft.Maui.DeviceTests namespace Microsoft.Maui.DeviceTests
{ {
@ -11,11 +12,44 @@ namespace Microsoft.Maui.DeviceTests
[Fact(DisplayName = "Time Initializes Correctly")] [Fact(DisplayName = "Time Initializes Correctly")]
public async Task IsToggledInitializesCorrectly() public async Task IsToggledInitializesCorrectly()
{ {
var timePickerStub = new TimePickerStub(); var timePicker = new TimePickerStub();
var time = new TimeSpan(17, 0, 0); var time = new TimeSpan(17, 0, 0);
await ValidateTime(timePickerStub, () => timePickerStub.Time = time); await ValidateTime(timePicker, () => timePicker.Time = time);
}
[Theory(DisplayName = "Font Size Initializes Correctly")]
[InlineData(1)]
[InlineData(10)]
[InlineData(20)]
[InlineData(100)]
public async Task FontSizeInitializesCorrectly(int fontSize)
{
var timePicker = new TimePickerStub()
{
Time = new TimeSpan(17, 0, 0),
Font = Font.OfSize("Arial", fontSize)
};
await ValidatePropertyInitValue(timePicker, () => timePicker.Font.FontSize, GetNativeUnscaledFontSize, timePicker.Font.FontSize);
}
[Theory(DisplayName = "Font Attributes Initialize Correctly")]
[InlineData(FontAttributes.None, false, false)]
[InlineData(FontAttributes.Bold, true, false)]
[InlineData(FontAttributes.Italic, false, true)]
[InlineData(FontAttributes.Bold | FontAttributes.Italic, true, true)]
public async Task FontAttributesInitializeCorrectly(FontAttributes attributes, bool isBold, bool isItalic)
{
var timePicker = new TimePickerStub()
{
Time = new TimeSpan(17, 0, 0),
Font = Font.OfSize("Arial", 10).WithAttributes(attributes)
};
await ValidatePropertyInitValue(timePicker, () => timePicker.Font.FontAttributes.HasFlag(FontAttributes.Bold), GetNativeIsBold, isBold);
await ValidatePropertyInitValue(timePicker, () => timePicker.Font.FontAttributes.HasFlag(FontAttributes.Italic), GetNativeIsItalic, isItalic);
} }
} }
} }

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

@ -1,7 +1,9 @@
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Maui.DeviceTests.Stubs; using Microsoft.Maui.DeviceTests.Stubs;
using Microsoft.Maui.Handlers; using Microsoft.Maui.Handlers;
using UIKit;
using Xunit; using Xunit;
namespace Microsoft.Maui.DeviceTests namespace Microsoft.Maui.DeviceTests
@ -32,6 +34,31 @@ namespace Microsoft.Maui.DeviceTests
Assert.Equal(xplatCharacterSpacing, values.NativeViewValue); Assert.Equal(xplatCharacterSpacing, values.NativeViewValue);
} }
[Theory(DisplayName = "Font Family Initializes Correctly")]
[InlineData(null)]
[InlineData("Times New Roman")]
[InlineData("Dokdo")]
public async Task FontFamilyInitializesCorrectly(string family)
{
var timePicker = new TimePickerStub
{
Time = TimeSpan.FromHours(8),
Font = Font.OfSize(family, 10)
};
var (services, nativeFont) = await GetValueAsync(timePicker, handler => (handler.Services, GetNativeTimePicker(handler).Font));
var fontManager = services.GetRequiredService<IFontManager>();
var expectedNativeFont = fontManager.GetFont(Font.OfSize(family, 0.0));
Assert.Equal(expectedNativeFont.FamilyName, nativeFont.FamilyName);
if (string.IsNullOrEmpty(family))
Assert.Equal(fontManager.DefaultFont.FamilyName, nativeFont.FamilyName);
else
Assert.NotEqual(fontManager.DefaultFont.FamilyName, nativeFont.FamilyName);
}
MauiTimePicker GetNativeTimePicker(TimePickerHandler timePickerHandler) => MauiTimePicker GetNativeTimePicker(TimePickerHandler timePickerHandler) =>
(MauiTimePicker)timePickerHandler.View; (MauiTimePicker)timePickerHandler.View;
@ -55,5 +82,14 @@ namespace Microsoft.Maui.DeviceTests
var mauiTimePicker = GetNativeTimePicker(timePickerHandler); var mauiTimePicker = GetNativeTimePicker(timePickerHandler);
return mauiTimePicker.AttributedText.GetCharacterSpacing(); return mauiTimePicker.AttributedText.GetCharacterSpacing();
} }
double GetNativeUnscaledFontSize(TimePickerHandler timePickerHandler) =>
GetNativeTimePicker(timePickerHandler).Font.PointSize;
bool GetNativeIsBold(TimePickerHandler timePickerHandler) =>
GetNativeTimePicker(timePickerHandler).Font.FontDescriptor.SymbolicTraits.HasFlag(UIFontDescriptorSymbolicTraits.Bold);
bool GetNativeIsItalic(TimePickerHandler timePickerHandler) =>
GetNativeTimePicker(timePickerHandler).Font.FontDescriptor.SymbolicTraits.HasFlag(UIFontDescriptorSymbolicTraits.Italic);
} }
} }

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

@ -15,5 +15,7 @@ namespace Microsoft.Maui.DeviceTests.Stubs
} }
public double CharacterSpacing { get; set; } public double CharacterSpacing { get; set; }
public Font Font { get; set; }
} }
} }