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

Implement Padding in ILabel Handlers #421

Merged
merged 6 commits into from
Mar 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/Controls/samples/Controls.Sample/Pages/MainPage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ void SetupMauiLayout()
verticalStack.Add(new Label { Text = "This should be BIG text!", FontSize = 24 });
verticalStack.Add(new Label { Text = "This should be BOLD text!", FontAttributes = FontAttributes.Bold });
verticalStack.Add(new Label { Text = "This should be a CUSTOM font!", FontFamily = "Dokdo" });
verticalStack.Add(new Label { Text = "This should have padding", Padding = new Thickness(40), BackgroundColor = Color.LightBlue });
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Adds an example of the property to the sample project.


var button = new Button() { Text = _viewModel.Text, WidthRequest = 200 };
var button2 = new Button()
Expand Down
1 change: 1 addition & 0 deletions src/Core/src/Core/ILabel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ namespace Microsoft.Maui
{
public interface ILabel : IView, IText, IFont
{
Thickness Padding { get; }
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Adds the property to the interface.

}
}
5 changes: 5 additions & 0 deletions src/Core/src/Handlers/Label/LabelHandler.Android.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ public static void MapFontAttributes(LabelHandler handler, ILabel label)
MapFont(handler, label);
}

public static void MapPadding(LabelHandler handler, ILabel label)
{
handler.TypedNativeView?.UpdatePadding(label);
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Add a mapping method to the Android aspect of the handler.

static void MapFont(LabelHandler handler, ILabel label)
{
var services = App.Current?.Services ?? throw new InvalidOperationException($"Unable to find service provider, the App.Current.Services was null.");
Expand Down
1 change: 1 addition & 0 deletions src/Core/src/Handlers/Label/LabelHandler.Standard.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@ public static void MapTextColor(IViewHandler handler, ILabel label) { }
public static void MapFontFamily(LabelHandler handler, ILabel label) { }
public static void MapFontSize(LabelHandler handler, ILabel label) { }
public static void MapFontAttributes(LabelHandler handler, ILabel label) { }
public static void MapPadding(LabelHandler handler, ILabel label) { }
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Add a mapping method to the Standard aspect of the handler; the Standard aspect is just a placeholder and is never actually called.

}
}
1 change: 1 addition & 0 deletions src/Core/src/Handlers/Label/LabelHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ public partial class LabelHandler
[nameof(ILabel.FontFamily)] = MapFontFamily,
[nameof(ILabel.FontSize)] = MapFontSize,
[nameof(ILabel.FontAttributes)] = MapFontAttributes,
[nameof(ILabel.Padding)] = MapPadding,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Add the mapping to the PropertyMapper for the handler.

};

public LabelHandler() : base(LabelMapper)
Expand Down
10 changes: 8 additions & 2 deletions src/Core/src/Handlers/Label/LabelHandler.iOS.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
using System;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Maui.Platform.iOS;
using UIKit;

namespace Microsoft.Maui.Handlers
{
public partial class LabelHandler : AbstractViewHandler<ILabel, UILabel>
public partial class LabelHandler : AbstractViewHandler<ILabel, MauiLabel>
{
protected override UILabel CreateNativeView() => new UILabel();
protected override MauiLabel CreateNativeView() => new MauiLabel();

public static void MapText(LabelHandler handler, ILabel label)
{
Expand All @@ -33,6 +34,11 @@ public static void MapFontAttributes(LabelHandler handler, ILabel label)
MapFont(handler, label);
}

public static void MapPadding(LabelHandler handler, ILabel label)
{
handler.TypedNativeView?.UpdatePadding(label);
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Add a mapping method to the iOS aspect of the handler.

static void MapFont(LabelHandler handler, ILabel label)
{
var services = App.Current?.Services ?? throw new InvalidOperationException($"Unable to find service provider, the App.Current.Services was null.");
Expand Down
16 changes: 16 additions & 0 deletions src/Core/src/Platform/Android/LabelExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,21 @@ public static void UpdateFont(this TextView textView, ILabel label, IFontManager
var sp = fontManager.GetScaledPixel(font);
textView.SetTextSize(ComplexUnitType.Sp, sp);
}

public static void UpdatePadding(this TextView textView, ILabel label)
{
var context = textView.Context;

if (context == null)
{
return;
}

textView.SetPadding(
(int)context.ToPixels(label.Padding.Left),
(int)context.ToPixels(label.Padding.Top),
(int)context.ToPixels(label.Padding.Right),
(int)context.ToPixels(label.Padding.Bottom));
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Add an extension method to handle the actual update for the native Android control. This logic is ported directly from the Forms Label renderer for Android.

}
}
5 changes: 5 additions & 0 deletions src/Core/src/Platform/Standard/LabelExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,10 @@ public static void UpdateTextColor(this object nothing, ILabel label)
{

}

public static void UpdatePadding(this object nothing, ILabel label)
{

}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The placeholder extension method for Standard; this is never actually called.

}
}
11 changes: 11 additions & 0 deletions src/Core/src/Platform/iOS/LabelExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using Microsoft.Maui.Platform.iOS;
using UIKit;

namespace Microsoft.Maui
Expand Down Expand Up @@ -31,5 +32,15 @@ public static void UpdateFont(this UILabel nativeLabel, ILabel label, IFontManag
var uiFont = fontManager.GetFont(font);
nativeLabel.Font = uiFont;
}

public static void UpdatePadding(this MauiLabel nativeLabel, ILabel label)
{
nativeLabel.TextInsets = new UIEdgeInsets(
(float)label.Padding.Top,
(float)label.Padding.Left,
(float)label.Padding.Bottom,
(float)label.Padding.Right);

}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Add an extension method to handle the actual update for the native iOS control. This logic is ported directly from the Forms Label renderer for iOS.

}
}
26 changes: 26 additions & 0 deletions src/Core/src/Platform/iOS/MauiLabel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using CoreGraphics;
using UIKit;

namespace Microsoft.Maui.Platform.iOS
{
public class MauiLabel : UILabel
{
public UIEdgeInsets TextInsets { get; set; }

public MauiLabel(CGRect frame) : base(frame)
{
}

public MauiLabel()
{
}

public override void DrawText(CGRect rect) => base.DrawText(TextInsets.InsetRect(rect));

public override CGSize SizeThatFits(CGSize size) => AddInsets(base.SizeThatFits(size));

CGSize AddInsets(CGSize size) => new CGSize(
width: size.Width + TextInsets.Left + TextInsets.Right,
height: size.Height + TextInsets.Top + TextInsets.Bottom);
}
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

For this particular property, we needed to extend the UILabel class with some custom logic because Padding doesn't exist natively. This class was ported from the Forms iOS platform project.

Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,31 @@ public async Task FontFamilyInitializesCorrectly(string family)
Assert.NotEqual(fontManager.DefaultTypeface, nativeLabel.Typeface);
}

[Fact]
public async Task PaddingInitializesCorrectly()
{
var label = new LabelStub()
{
Text = "Test",
Padding = new Thickness(5, 10, 15, 20)
};

var handler = await CreateHandlerAsync(label);
var (left, top, right, bottom) = GetNativePadding((TextView)handler.NativeView);

var context = handler.View.Context;

var expectedLeft = context.ToPixels(5);
var expectedTop = context.ToPixels(10);
var expectedRight = context.ToPixels(15);
var expectedBottom = context.ToPixels(20);

Assert.Equal(expectedLeft, left);
Assert.Equal(expectedTop, top);
Assert.Equal(expectedRight, right);
Assert.Equal(expectedBottom, bottom);
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Adds an on-device test to verify that the property is being set on the native Android control. This test will be run on an Android device as part of the CI process.

TextView GetNativeLabel(LabelHandler labelHandler) =>
(TextView)labelHandler.View;

Expand Down Expand Up @@ -64,5 +89,10 @@ Task ValidateNativeBackgroundColor(ILabel label, Color color)
return GetNativeLabel(CreateHandler(label)).AssertContainsColor(color);
});
}

(double left, double top, double right, double bottom) GetNativePadding(Android.Views.View view)
{
return (view.PaddingLeft, view.PaddingTop, view.PaddingRight, view.PaddingBottom);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Maui.DeviceTests.Stubs;
using Microsoft.Maui.Handlers;
using Microsoft.Maui.Platform.iOS;
using UIKit;
using Xunit;

Expand Down Expand Up @@ -34,6 +35,24 @@ public async Task FontFamilyInitializesCorrectly(string family)
Assert.NotEqual(fontManager.DefaultFont.FamilyName, nativeFont.FamilyName);
}

[Fact]
public async Task PaddingInitializesCorrectly()
{
var label = new LabelStub()
{
Text = "Test",
Padding = new Thickness(5, 10, 15, 20)
};

var handler = await CreateHandlerAsync(label);
var insets = ((MauiLabel)handler.NativeView).TextInsets;

Assert.Equal(5, insets.Left);
Assert.Equal(10, insets.Top);
Assert.Equal(15, insets.Right);
Assert.Equal(20, insets.Bottom);
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Adds an on-device test to verify that the property is being set on the native iOS control. This test will be run on an iOS device as part of the CI process.

UILabel GetNativeLabel(LabelHandler labelHandler) =>
(UILabel)labelHandler.View;

Expand Down
2 changes: 2 additions & 0 deletions src/Core/tests/DeviceTests/Stubs/LabelStub.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,7 @@ public partial class LabelStub : StubBase, ILabel
public string FontFamily { get; set; }

public double FontSize { get; set; }

public Thickness Padding { get; set; }
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The stub classes are implementations of the MAUI interfaces used for on-device testing.

}
}