Browse Source

Added MaxLines property to TextBlock.

pull/4055/head
José Pedro 6 years ago
parent
commit
48177eddb7
No known key found for this signature in database GPG Key ID: B8247B9301707B83
  1. 22
      src/Avalonia.Controls/TextBlock.cs
  2. 14
      src/Avalonia.Visuals/Media/TextFormatting/TextLayout.cs
  3. 21
      tests/Avalonia.Skia.UnitTests/TextLayoutTests.cs

22
src/Avalonia.Controls/TextBlock.cs

@ -70,6 +70,14 @@ namespace Avalonia.Controls
Brushes.Black,
inherits: true);
/// <summary>
/// Defines the <see cref="MaxLines"/> property.
/// </summary>
public static readonly StyledProperty<int> MaxLinesProperty =
AvaloniaProperty.Register<TextBlock, int>(
nameof(MaxLines),
validate: IsValidMaxLines);
/// <summary>
/// Defines the <see cref="Text"/> property.
/// </summary>
@ -222,6 +230,15 @@ namespace Avalonia.Controls
set { SetValue(ForegroundProperty, value); }
}
/// <summary>
/// Gets or sets the maximum number of text lines.
/// </summary>
public int MaxLines
{
get => GetValue(MaxLinesProperty);
set => SetValue(MaxLinesProperty, value);
}
/// <summary>
/// Gets or sets the control's text wrapping mode.
/// </summary>
@ -404,7 +421,8 @@ namespace Avalonia.Controls
TextTrimming,
TextDecorations,
constraint.Width,
constraint.Height);
constraint.Height,
MaxLines);
}
/// <summary>
@ -451,5 +469,7 @@ namespace Avalonia.Controls
InvalidateMeasure();
}
private static bool IsValidMaxLines(int maxLines) => maxLines >= 0;
}
}

14
src/Avalonia.Visuals/Media/TextFormatting/TextLayout.cs

@ -32,6 +32,7 @@ namespace Avalonia.Media.TextFormatting
/// <param name="textDecorations">The text decorations.</param>
/// <param name="maxWidth">The maximum width.</param>
/// <param name="maxHeight">The maximum height.</param>
/// <param name="maxLines">The maximum number of text lines.</param>
/// <param name="textStyleOverrides">The text style overrides.</param>
public TextLayout(
string text,
@ -44,6 +45,7 @@ namespace Avalonia.Media.TextFormatting
TextDecorationCollection textDecorations = null,
double maxWidth = double.PositiveInfinity,
double maxHeight = double.PositiveInfinity,
int maxLines = 0,
IReadOnlyList<TextStyleRun> textStyleOverrides = null)
{
_text = string.IsNullOrEmpty(text) ?
@ -59,6 +61,8 @@ namespace Avalonia.Media.TextFormatting
MaxHeight = maxHeight;
MaxLines = maxLines;
UpdateLayout();
}
@ -73,6 +77,12 @@ namespace Avalonia.Media.TextFormatting
/// </summary>
public double MaxHeight { get; }
/// <summary>
/// Gets the maximum number of text lines.
/// </summary>
public double MaxLines { get; }
/// <summary>
/// Gets the text lines.
/// </summary>
@ -192,7 +202,7 @@ namespace Avalonia.Media.TextFormatting
var currentPosition = 0;
while (currentPosition < _text.Length)
while (currentPosition < _text.Length && (MaxLines == 0 || textLines.Count < MaxLines))
{
int length;
@ -222,7 +232,7 @@ namespace Avalonia.Media.TextFormatting
var remainingLength = length;
while (remainingLength > 0)
while (remainingLength > 0 && (MaxLines == 0 || textLines.Count < MaxLines))
{
var textSlice = _text.AsSlice(currentPosition, remainingLength);

21
tests/Avalonia.Skia.UnitTests/TextLayoutTests.cs

@ -506,6 +506,27 @@ namespace Avalonia.Skia.UnitTests
}
}
[InlineData("0123456789\r\n0123456789\r\n0123456789", 1, 1)]
[InlineData("0123456789\r\n0123456789\r\n0123456789", 2, 2)]
[InlineData("0123456789\r\n0123456789\r\n0123456789", 3, 3)]
[InlineData("0123456789\r\n0123456789\r\n0123456789", 4, 3)]
[Theory]
public void Should_Not_Exceed_MaxLines(string text, int maxLines, int expectedLines)
{
using (Start())
{
var layout = new TextLayout(
text,
Typeface.Default,
12,
Brushes.Black,
maxWidth: 50,
maxLines: maxLines);
Assert.Equal(expectedLines, layout.TextLines.Count);
}
}
private const string Text = "日本でTest一番読まれている英字新聞・ジャパンタイムズが発信する国内外ニュースと、様々なジャンルの特集記事。";
[Fact(Skip= "Only used for profiling.")]

Loading…
Cancel
Save