Skip to content

Commit

Permalink
Implement LineBreakMode property in LabelHandlers (#458)
Browse files Browse the repository at this point in the history
  • Loading branch information
jsuarezruiz authored Mar 13, 2021
1 parent 6950c6b commit 991250a
Show file tree
Hide file tree
Showing 17 changed files with 297 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public static void SetLineBreakMode(this TextView textView, Label label)
public static void SetLineBreakMode(this TextView textView, Button button) =>
SetLineBreak(textView, button.LineBreakMode);


[PortHandler]
public static int SetLineBreak(TextView textView, LineBreakMode lineBreakMode)
{
int maxLines = Int32.MaxValue;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,7 @@ void UpdateCharacterSpacing()
}
}

[PortHandler]
void UpdateLineBreakMode()
{
this.SetLineBreakMode(Element);
Expand Down
1 change: 1 addition & 0 deletions src/Compatibility/Core/src/iOS/Renderers/LabelRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,7 @@ void UpdateHorizontalTextAlignment()
#endif
}

[PortHandler]
void UpdateLineBreakMode()
{
#if __MOBILE__
Expand Down
14 changes: 13 additions & 1 deletion src/Controls/samples/Controls.Sample/Pages/MainPage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

namespace Maui.Controls.Sample.Pages
{

public class MainPage : ContentPage, IPage
{
MainPageViewModel _viewModel;
Expand All @@ -24,6 +23,15 @@ public MainPage(MainPageViewModel viewModel)

void SetupMauiLayout()
{
const string loremIpsum =
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. " +
"Quisque ut dolor metus. Duis vel iaculis mauris, sit amet finibus mi. " +
"Etiam congue ornare risus, in facilisis libero tempor eget. " +
"Phasellus mattis mollis libero ut semper. In sit amet sapien odio. " +
"Sed interdum ullamcorper dui eu rutrum. Vestibulum non sagittis justo. " +
"Cras rutrum scelerisque elit, et porta est lobortis ac. " +
"Pellentesque eu ornare tortor. Sed bibendum a nisl at laoreet.";

var verticalStack = new VerticalStackLayout() { Spacing = 5, BackgroundColor = Color.AntiqueWhite };
var horizontalStack = new HorizontalStackLayout() { Spacing = 2, BackgroundColor = Color.CornflowerBlue };

Expand All @@ -35,6 +43,10 @@ void SetupMauiLayout()
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 });
verticalStack.Add(new Label { Text = loremIpsum });
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 });

var underlineLabel = new Label { Text = "underline", TextDecorations = TextDecorations.Underline };
verticalStack.Add(underlineLabel);
Expand Down
5 changes: 5 additions & 0 deletions src/Core/src/Core/ILabel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ namespace Microsoft.Maui
/// </summary>
public interface ILabel : IView, IText
{
/// <summary>
/// Gets the option for line breaking.
/// </summary>
LineBreakMode LineBreakMode { get; }

/// <summary>
/// Gets the maximum number of lines allowed in the Label.
/// </summary>
Expand Down
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 @@ -37,6 +37,11 @@ public static void MapCharacterSpacing(LabelHandler handler, ILabel label)
handler.TypedNativeView?.UpdateCharacterSpacing(label);
}

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

public static void MapMaxLines(LabelHandler handler, ILabel label)
{
handler.TypedNativeView?.UpdateMaxLines(label);
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 @@ -10,6 +10,7 @@ public static void MapText(IViewHandler handler, ILabel label) { }
public static void MapTextColor(IViewHandler handler, ILabel label) { }
public static void MapCharacterSpacing(IViewHandler handler, ILabel label) { }
public static void MapFont(LabelHandler handler, ILabel label) { }
public static void MapLineBreakMode(LabelHandler handler, ILabel label) { }
public static void MapTextDecorations(LabelHandler handler, ILabel label) { }
public static void MapMaxLines(IViewHandler handler, ILabel label) { }
public static void MapPadding(LabelHandler handler, ILabel label) { }
Expand Down
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.CharacterSpacing)] = MapCharacterSpacing,
[nameof(ILabel.MaxLines)] = MapMaxLines,
[nameof(ILabel.Font)] = MapFont,
[nameof(ILabel.LineBreakMode)] = MapLineBreakMode,
[nameof(ILabel.Padding)] = MapPadding,
[nameof(ILabel.TextDecorations)] = MapTextDecorations
};
Expand Down
5 changes: 5 additions & 0 deletions src/Core/src/Handlers/Label/LabelHandler.iOS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ public static void MapCharacterSpacing(LabelHandler handler, ILabel label)
handler.TypedNativeView?.UpdateCharacterSpacing(label);
}

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

public static void MapMaxLines(LabelHandler handler, ILabel label)
{
handler.TypedNativeView?.UpdateMaxLines(label);
Expand Down
48 changes: 48 additions & 0 deletions src/Core/src/Platform/Android/LabelExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Android.Graphics;
using Android.Text;
using Android.Util;
using Android.Widget;

Expand Down Expand Up @@ -39,6 +40,11 @@ public static void UpdateFont(this TextView textView, ILabel label, IFontManager
textView.SetTextSize(ComplexUnitType.Sp, sp);
}

public static void UpdateLineBreakMode(this TextView textView, ILabel label)
{
textView.SetLineBreakMode(label);
}

public static void UpdateMaxLines(this TextView textView, ILabel label)
{
int maxLinex = label.MaxLines;
Expand Down Expand Up @@ -76,5 +82,47 @@ public static void UpdateTextDecorations(this TextView textView, ILabel label)
else
textView.PaintFlags |= PaintFlags.UnderlineText;
}

internal static void SetLineBreakMode(this TextView textView, ILabel label)
{
var lineBreakMode = label.LineBreakMode;

int maxLines = label.MaxLines;
if (maxLines <= 0)
maxLines = int.MaxValue;

bool singleLine = false;

switch (lineBreakMode)
{
case LineBreakMode.NoWrap:
maxLines = 1;
textView.Ellipsize = null;
break;
case LineBreakMode.WordWrap:
textView.Ellipsize = null;
break;
case LineBreakMode.CharacterWrap:
textView.Ellipsize = null;
break;
case LineBreakMode.HeadTruncation:
maxLines = 1;
singleLine = true; // Workaround for bug in older Android API versions (https://bugzilla.xamarin.com/show_bug.cgi?id=49069)
textView.Ellipsize = TextUtils.TruncateAt.Start;
break;
case LineBreakMode.TailTruncation:
maxLines = 1;
textView.Ellipsize = TextUtils.TruncateAt.End;
break;
case LineBreakMode.MiddleTruncation:
maxLines = 1;
singleLine = true; // Workaround for bug in older Android API versions (https://bugzilla.xamarin.com/show_bug.cgi?id=49069)
textView.Ellipsize = TextUtils.TruncateAt.Middle;
break;
}

textView.SetSingleLine(singleLine);
textView.SetMaxLines(maxLines);
}
}
}
40 changes: 40 additions & 0 deletions src/Core/src/Platform/iOS/LabelExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ public static void UpdateFont(this UILabel nativeLabel, ILabel label, IFontManag
nativeLabel.UpdateCharacterSpacing(label);
}

public static void UpdateLineBreakMode(this UILabel nativeLabel, ILabel label)
{
SetLineBreakMode(nativeLabel, label);
}

public static void UpdateMaxLines(this UILabel nativeLabel, ILabel label)
{
int maxLines = label.MaxLines;
Expand All @@ -66,6 +71,41 @@ public static void UpdatePadding(this MauiLabel nativeLabel, ILabel label)
(float)label.Padding.Right);
}

internal static void SetLineBreakMode(this UILabel nativeLabel, ILabel label)
{
int maxLines = label.MaxLines;
if (maxLines < 0)
maxLines = 0;

switch (label.LineBreakMode)
{
case LineBreakMode.NoWrap:
nativeLabel.LineBreakMode = UILineBreakMode.Clip;
maxLines = 1;
break;
case LineBreakMode.WordWrap:
nativeLabel.LineBreakMode = UILineBreakMode.WordWrap;
break;
case LineBreakMode.CharacterWrap:
nativeLabel.LineBreakMode = UILineBreakMode.CharacterWrap;
break;
case LineBreakMode.HeadTruncation:
nativeLabel.LineBreakMode = UILineBreakMode.HeadTruncation;
maxLines = 1;
break;
case LineBreakMode.MiddleTruncation:
nativeLabel.LineBreakMode = UILineBreakMode.MiddleTruncation;
maxLines = 1;
break;
case LineBreakMode.TailTruncation:
nativeLabel.LineBreakMode = UILineBreakMode.TailTruncation;
maxLines = 1;
break;
}

nativeLabel.Lines = maxLines;
}

public static void UpdateTextDecorations(this UILabel nativeLabel, ILabel label)
{
if (nativeLabel.AttributedText != null && !(nativeLabel.AttributedText?.Length > 0))
Expand Down
13 changes: 13 additions & 0 deletions src/Core/tests/DeviceTests/AssertionExtensions.Android.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.IO;
using System.Threading.Tasks;
using Android.Graphics;
using Android.Text;
using Android.Views;
using Android.Widget;
using Xunit;
Expand Down Expand Up @@ -168,5 +169,17 @@ public static async Task<Bitmap> AssertColorAtTopRight(this AView view, AColor e
var bitmap = await view.ToBitmap();
return bitmap.AssertColorAtTopRight(expectedColor);
}

public static TextUtils.TruncateAt ToNative(this LineBreakMode mode) =>
mode switch
{
LineBreakMode.NoWrap => null,
LineBreakMode.WordWrap => null,
LineBreakMode.CharacterWrap => null,
LineBreakMode.HeadTruncation => TextUtils.TruncateAt.Start,
LineBreakMode.TailTruncation => TextUtils.TruncateAt.End,
LineBreakMode.MiddleTruncation => TextUtils.TruncateAt.Middle,
_ => throw new ArgumentOutOfRangeException(nameof(mode))
};
}
}
12 changes: 12 additions & 0 deletions src/Core/tests/DeviceTests/AssertionExtensions.iOS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -183,5 +183,17 @@ public static UIImage AssertContainsColor(this UIImage bitmap, UIColor expectedC
Assert.True(false, CreateColorError(bitmap, $"Color {expectedColor} not found."));
return bitmap;
}

public static UILineBreakMode ToNative(this LineBreakMode mode) =>
mode switch
{
LineBreakMode.NoWrap => UILineBreakMode.Clip,
LineBreakMode.WordWrap => UILineBreakMode.WordWrap,
LineBreakMode.CharacterWrap => UILineBreakMode.CharacterWrap,
LineBreakMode.HeadTruncation => UILineBreakMode.HeadTruncation,
LineBreakMode.TailTruncation => UILineBreakMode.TailTruncation,
LineBreakMode.MiddleTruncation => UILineBreakMode.MiddleTruncation,
_ => throw new ArgumentOutOfRangeException(nameof(mode))
};
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Threading.Tasks;
using Android.Graphics;
using Android.Text;
using Android.Widget;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Maui.DeviceTests.Stubs;
Expand Down Expand Up @@ -38,6 +39,21 @@ public async Task FontFamilyInitializesCorrectly(string family)
Assert.NotEqual(fontManager.DefaultTypeface, nativeLabel.Typeface);
}

[Fact(DisplayName = "Negative MaxLines value with wrap is correct")]
public async Task NegativeMaxValueWithWrapIsCorrect()
{
var label = new LabelStub()
{
Text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit",
MaxLines = -1,
LineBreakMode = LineBreakMode.WordWrap
};

var nativeValue = await GetValueAsync(label, GetNativeMaxLines);

Assert.Equal(int.MaxValue, nativeValue);
}

[Fact(DisplayName = "Padding Initializes Correctly")]
public async Task PaddingInitializesCorrectly()
{
Expand Down Expand Up @@ -128,6 +144,9 @@ Task ValidateNativeBackgroundColor(ILabel label, Color color)
double GetNativeCharacterSpacing(LabelHandler labelHandler) =>
Math.Round(GetNativeLabel(labelHandler).LetterSpacing / UnitExtensions.EmCoefficient, 4);

TextUtils.TruncateAt GetNativeLineBreakMode(LabelHandler labelHandler) =>
GetNativeLabel(labelHandler).Ellipsize;

PaintFlags GetNativeTextDecorations(LabelHandler labelHandler) =>
GetNativeLabel(labelHandler).PaintFlags;
}
Expand Down
Loading

0 comments on commit 991250a

Please sign in to comment.