Browse Source

Merge pull request #8541 from Gillibald/fixes/MoveIAddChild

Move IAddChild to Avalonia.Metadata and use it for Rich./TextBlock
pull/8580/head
Benedikt Stebner 4 years ago
committed by GitHub
parent
commit
d56a92514e
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      src/Avalonia.Base/Metadata/IAddChild.cs
  2. 34
      src/Avalonia.Controls/Documents/Inline.cs
  3. 78
      src/Avalonia.Controls/Documents/InlineCollection.cs
  4. 35
      src/Avalonia.Controls/Documents/Span.cs
  5. 12
      src/Avalonia.Controls/Documents/TextElement.cs
  6. 41
      src/Avalonia.Controls/RichTextBlock.cs
  7. 15
      src/Avalonia.Controls/TextBlock.cs
  8. 4
      src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlLanguage.cs
  9. 2
      src/Markup/Avalonia.Markup.Xaml.Loader/xamlil.github
  10. 1
      src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj
  11. 3
      tests/Avalonia.Markup.Xaml.UnitTests/Xaml/BasicTests.cs

4
src/Markup/Avalonia.Markup.Xaml/IAddChild.cs → src/Avalonia.Base/Metadata/IAddChild.cs

@ -1,11 +1,11 @@
namespace Avalonia.Markup.Xaml
namespace Avalonia.Metadata
{
public interface IAddChild
{
void AddChild(object child);
}
public interface IAddChild<T> : IAddChild
public interface IAddChild<T>
{
void AddChild(T child);
}

34
src/Avalonia.Controls/Documents/Inline.cs

@ -50,8 +50,38 @@ namespace Avalonia.Controls.Documents
protected TextRunProperties CreateTextRunProperties()
{
return new GenericTextRunProperties(new Typeface(FontFamily, FontStyle, FontWeight), FontSize,
TextDecorations, Foreground, Background, BaselineAlignment);
var textDecorations = TextDecorations;
var background = Background;
if(Parent is Inline inline)
{
if(textDecorations == null)
{
textDecorations = inline.TextDecorations;
}
if(background == null)
{
background = inline.Background;
}
}
var fontStyle = FontStyle;
if(Parent is Italic)
{
fontStyle = FontStyle.Italic;
}
var fontWeight = FontWeight;
if(Parent is Bold)
{
fontWeight = FontWeight.Bold;
}
return new GenericTextRunProperties(new Typeface(FontFamily, fontStyle, fontWeight), FontSize,
textDecorations, Foreground, background, BaselineAlignment);
}
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)

78
src/Avalonia.Controls/Documents/InlineCollection.cs

@ -14,7 +14,6 @@ namespace Avalonia.Controls.Documents
{
private ILogical? _parent;
private IInlineHost? _inlineHost;
private string? _text = string.Empty;
/// <summary>
/// Initializes a new instance of the <see cref="InlineCollection"/> class.
@ -22,7 +21,7 @@ namespace Avalonia.Controls.Documents
public InlineCollection()
{
ResetBehavior = ResetBehavior.Remove;
this.ForEachItem(
x =>
{
@ -36,16 +35,16 @@ namespace Avalonia.Controls.Documents
x.InlineHost = InlineHost;
Invalidate();
},
() => throw new NotSupportedException());
() => throw new NotSupportedException());
}
internal ILogical? Parent
internal ILogical? Parent
{
get => _parent;
set
{
_parent = value;
OnParentChanged(value);
}
}
@ -61,8 +60,6 @@ namespace Avalonia.Controls.Documents
}
}
public bool HasComplexContent => Count > 0;
/// <summary>
/// Gets or adds the text held by the inlines collection.
/// <remarks>
@ -73,11 +70,6 @@ namespace Avalonia.Controls.Documents
{
get
{
if (!HasComplexContent)
{
return _text;
}
var builder = new StringBuilder();
foreach (var inline in this)
@ -87,17 +79,7 @@ namespace Avalonia.Controls.Documents
return builder.ToString();
}
set
{
if (HasComplexContent)
{
Add(new Run(value));
}
else
{
_text = value;
}
}
}
/// <summary>
@ -110,36 +92,46 @@ namespace Avalonia.Controls.Documents
/// <param name="text"></param>
public void Add(string text)
{
if (HasComplexContent)
{
Add(new Run(text));
}
else
{
_text = text;
}
AddText(text);
}
public override void Add(Inline inline)
{
OnAdd();
base.Add(inline);
}
public void Add(IControl child)
{
var implicitRun = new InlineUIContainer(child);
OnAdd();
base.Add(new InlineUIContainer(child));
}
Add(implicitRun);
private void AddText(string text)
{
if(Parent is RichTextBlock textBlock && !textBlock.HasComplexContent)
{
textBlock._text += text;
}
else
{
base.Add(new Run(text));
}
}
public override void Add(Inline item)
private void OnAdd()
{
if (!HasComplexContent)
if (Parent is RichTextBlock textBlock)
{
if (!string.IsNullOrEmpty(_text))
if (!textBlock.HasComplexContent && !string.IsNullOrEmpty(textBlock._text))
{
base.Add(new Run(_text));
base.Add(new Run(textBlock._text));
textBlock._text = null;
}
_text = null;
}
base.Add(item);
}
/// <summary>
@ -152,7 +144,7 @@ namespace Avalonia.Controls.Documents
/// </summary>
protected void Invalidate()
{
if(InlineHost != null)
if (InlineHost != null)
{
InlineHost.Invalidate();
}
@ -162,7 +154,7 @@ namespace Avalonia.Controls.Documents
private void OnParentChanged(ILogical? parent)
{
foreach(var child in this)
foreach (var child in this)
{
((ISetLogicalParent)child).SetParent(parent);
}

35
src/Avalonia.Controls/Documents/Span.cs

@ -1,4 +1,3 @@
using System;
using System.Collections.Generic;
using System.Text;
using Avalonia.Media.TextFormatting;
@ -38,41 +37,17 @@ namespace Avalonia.Controls.Documents
internal override void BuildTextRun(IList<TextRun> textRuns)
{
if (Inlines.HasComplexContent)
foreach (var inline in Inlines)
{
foreach (var inline in Inlines)
{
inline.BuildTextRun(textRuns);
}
}
else
{
if (Inlines.Text is string text)
{
var textRunProperties = CreateTextRunProperties();
var textCharacters = new TextCharacters(text.AsMemory(), textRunProperties);
textRuns.Add(textCharacters);
}
inline.BuildTextRun(textRuns);
}
}
internal override void AppendText(StringBuilder stringBuilder)
{
if (Inlines.HasComplexContent)
{
foreach (var inline in Inlines)
{
inline.AppendText(stringBuilder);
}
}
else
foreach (var inline in Inlines)
{
if (Inlines.Text is string text)
{
stringBuilder.Append(text);
}
inline.AppendText(stringBuilder);
}
}
@ -93,7 +68,7 @@ namespace Avalonia.Controls.Documents
{
base.OnInlineHostChanged(oldValue, newValue);
if(Inlines is not null)
if (Inlines is not null)
{
Inlines.InlineHost = newValue;
}

12
src/Avalonia.Controls/Documents/TextElement.cs

@ -18,7 +18,7 @@ namespace Avalonia.Controls.Documents
/// Defines the <see cref="FontFamily"/> property.
/// </summary>
public static readonly AttachedProperty<FontFamily> FontFamilyProperty =
AvaloniaProperty.RegisterAttached<TextElement, Control, FontFamily>(
AvaloniaProperty.RegisterAttached<TextElement, TextElement, FontFamily>(
nameof(FontFamily),
defaultValue: FontFamily.Default,
inherits: true);
@ -27,7 +27,7 @@ namespace Avalonia.Controls.Documents
/// Defines the <see cref="FontSize"/> property.
/// </summary>
public static readonly AttachedProperty<double> FontSizeProperty =
AvaloniaProperty.RegisterAttached<TextElement, Control, double>(
AvaloniaProperty.RegisterAttached<TextElement, TextElement, double>(
nameof(FontSize),
defaultValue: 12,
inherits: true);
@ -36,7 +36,7 @@ namespace Avalonia.Controls.Documents
/// Defines the <see cref="FontStyle"/> property.
/// </summary>
public static readonly AttachedProperty<FontStyle> FontStyleProperty =
AvaloniaProperty.RegisterAttached<TextElement, Control, FontStyle>(
AvaloniaProperty.RegisterAttached<TextElement, TextElement, FontStyle>(
nameof(FontStyle),
inherits: true);
@ -44,7 +44,7 @@ namespace Avalonia.Controls.Documents
/// Defines the <see cref="FontWeight"/> property.
/// </summary>
public static readonly AttachedProperty<FontWeight> FontWeightProperty =
AvaloniaProperty.RegisterAttached<TextElement, Control, FontWeight>(
AvaloniaProperty.RegisterAttached<TextElement, TextElement, FontWeight>(
nameof(FontWeight),
inherits: true,
defaultValue: FontWeight.Normal);
@ -53,7 +53,7 @@ namespace Avalonia.Controls.Documents
/// Defines the <see cref="FontStretch"/> property.
/// </summary>
public static readonly AttachedProperty<FontStretch> FontStretchProperty =
AvaloniaProperty.RegisterAttached<TextElement, Control, FontStretch>(
AvaloniaProperty.RegisterAttached<TextElement, TextElement, FontStretch>(
nameof(FontStretch),
inherits: true,
defaultValue: FontStretch.Normal);
@ -62,7 +62,7 @@ namespace Avalonia.Controls.Documents
/// Defines the <see cref="Foreground"/> property.
/// </summary>
public static readonly AttachedProperty<IBrush?> ForegroundProperty =
AvaloniaProperty.RegisterAttached<TextElement, Control, IBrush?>(
AvaloniaProperty.RegisterAttached<TextElement, TextElement, IBrush?>(
nameof(Foreground),
Brushes.Black,
inherits: true);

41
src/Avalonia.Controls/RichTextBlock.cs

@ -170,6 +170,8 @@ namespace Avalonia.Controls
remove => RemoveHandler(CopyingToClipboardEvent, value);
}
internal bool HasComplexContent => Inlines.Count > 0;
/// <summary>
/// Copies the current selection to the Clipboard.
/// </summary>
@ -251,6 +253,30 @@ namespace Avalonia.Controls
SelectionEnd = SelectionStart;
}
protected void AddText(string? text)
{
if (string.IsNullOrEmpty(text))
{
return;
}
if (!HasComplexContent && string.IsNullOrEmpty(_text))
{
_text = text;
}
else
{
if (!string.IsNullOrEmpty(_text))
{
Inlines.Add(_text);
_text = null;
}
Inlines.Add(text);
}
}
protected override string? GetText()
{
return _text ?? Inlines.Text;
@ -259,17 +285,8 @@ namespace Avalonia.Controls
protected override void SetText(string? text)
{
var oldValue = _text ?? Inlines?.Text;
if (Inlines is not null && Inlines.HasComplexContent)
{
Inlines.Text = text;
_text = null;
}
else
{
_text = text;
}
AddText(text);
RaisePropertyChanged(TextProperty, oldValue, text);
}
@ -293,7 +310,7 @@ namespace Avalonia.Controls
var inlines = Inlines;
if (inlines is not null && inlines.HasComplexContent)
if (HasComplexContent)
{
var textRuns = new List<TextRun>();

15
src/Avalonia.Controls/TextBlock.cs

@ -4,6 +4,7 @@ using Avalonia.Controls.Documents;
using Avalonia.Layout;
using Avalonia.Media;
using Avalonia.Media.TextFormatting;
using Avalonia.Metadata;
using Avalonia.Utilities;
namespace Avalonia.Controls
@ -11,7 +12,7 @@ namespace Avalonia.Controls
/// <summary>
/// A control that displays a block of text.
/// </summary>
public class TextBlock : Control
public class TextBlock : Control, IAddChild<string>
{
/// <summary>
/// Defines the <see cref="Background"/> property.
@ -128,7 +129,7 @@ namespace Avalonia.Controls
public static readonly StyledProperty<TextDecorationCollection?> TextDecorationsProperty =
AvaloniaProperty.Register<TextBlock, TextDecorationCollection?>(nameof(TextDecorations));
protected string? _text;
internal string? _text;
protected TextLayout? _textLayout;
protected Size _constraint;
@ -473,11 +474,6 @@ namespace Avalonia.Controls
control.SetValue(MaxLinesProperty, maxLines);
}
public void Add(string text)
{
_text = text;
}
/// <summary>
/// Renders the <see cref="TextBlock"/> to a drawing context.
/// </summary>
@ -512,6 +508,11 @@ namespace Avalonia.Controls
TextLayout.Draw(context, new Point(padding.Left, top));
}
void IAddChild<string>.AddChild(string text)
{
_text = text;
}
protected virtual string? GetText()
{
return _text;

4
src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlLanguage.cs

@ -70,8 +70,8 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
},
InnerServiceProviderFactoryMethod =
runtimeHelpers.FindMethod(m => m.Name == "CreateInnerServiceProviderV1"),
IAddChild = typeSystem.GetType("Avalonia.Markup.Xaml.IAddChild"),
IAddChildOfT = typeSystem.GetType("Avalonia.Markup.Xaml.IAddChild`1")
IAddChild = typeSystem.GetType("Avalonia.Metadata.IAddChild"),
IAddChildOfT = typeSystem.GetType("Avalonia.Metadata.IAddChild`1")
};
rv.CustomAttributeResolver = new AttributeResolver(typeSystem, rv);

2
src/Markup/Avalonia.Markup.Xaml.Loader/xamlil.github

@ -1 +1 @@
Subproject commit a4e6be2d1407abec4f35fcb208848830ce513ead
Subproject commit d990d63774a04d2a4b3d52e626a90ee68e19e2b6

1
src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj

@ -15,7 +15,6 @@
<Compile Include="Converters\FontFamilyTypeConverter.cs" />
<Compile Include="Converters\TimeSpanTypeConverter.cs" />
<Compile Include="Extensions.cs" />
<Compile Include="IAddChild.cs" />
<Compile Include="MarkupExtension.cs" />
<Compile Include="MarkupExtensions\CompiledBindingExtension.cs" />
<Compile Include="MarkupExtensions\CompiledBindings\ArrayElementPlugin.cs" />

3
tests/Avalonia.Markup.Xaml.UnitTests/Xaml/BasicTests.cs

@ -17,6 +17,7 @@ using System.Linq;
using System.Xml;
using Xunit;
using Avalonia.Controls.Documents;
using Avalonia.Metadata;
namespace Avalonia.Markup.Xaml.UnitTests.Xaml
{
@ -1011,7 +1012,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.Xaml
}
}
public class ObjectWithAddChildOfT : IAddChild<string>
public class ObjectWithAddChildOfT : IAddChild, IAddChild<string>
{
public string Text { get; set; }

Loading…
Cancel
Save