diff --git a/src/Markup/Avalonia.Markup.Xaml/IAddChild.cs b/src/Avalonia.Base/Metadata/IAddChild.cs similarity index 61% rename from src/Markup/Avalonia.Markup.Xaml/IAddChild.cs rename to src/Avalonia.Base/Metadata/IAddChild.cs index 993eb6142d..8ef02912a6 100644 --- a/src/Markup/Avalonia.Markup.Xaml/IAddChild.cs +++ b/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 : IAddChild + public interface IAddChild { void AddChild(T child); } diff --git a/src/Avalonia.Controls/Documents/Inline.cs b/src/Avalonia.Controls/Documents/Inline.cs index b400625903..47581e87f1 100644 --- a/src/Avalonia.Controls/Documents/Inline.cs +++ b/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) diff --git a/src/Avalonia.Controls/Documents/InlineCollection.cs b/src/Avalonia.Controls/Documents/InlineCollection.cs index dc688fc359..565ed75ad9 100644 --- a/src/Avalonia.Controls/Documents/InlineCollection.cs +++ b/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; /// /// Initializes a new instance of the 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; - /// /// Gets or adds the text held by the inlines collection. /// @@ -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; - } - } + } /// @@ -110,36 +92,46 @@ namespace Avalonia.Controls.Documents /// 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); } /// @@ -152,7 +144,7 @@ namespace Avalonia.Controls.Documents /// 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); } diff --git a/src/Avalonia.Controls/Documents/Span.cs b/src/Avalonia.Controls/Documents/Span.cs index c7289dbc3f..363ce1011b 100644 --- a/src/Avalonia.Controls/Documents/Span.cs +++ b/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 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; } diff --git a/src/Avalonia.Controls/Documents/TextElement.cs b/src/Avalonia.Controls/Documents/TextElement.cs index 5bac3642ed..2034f05fc0 100644 --- a/src/Avalonia.Controls/Documents/TextElement.cs +++ b/src/Avalonia.Controls/Documents/TextElement.cs @@ -18,7 +18,7 @@ namespace Avalonia.Controls.Documents /// Defines the property. /// public static readonly AttachedProperty FontFamilyProperty = - AvaloniaProperty.RegisterAttached( + AvaloniaProperty.RegisterAttached( nameof(FontFamily), defaultValue: FontFamily.Default, inherits: true); @@ -27,7 +27,7 @@ namespace Avalonia.Controls.Documents /// Defines the property. /// public static readonly AttachedProperty FontSizeProperty = - AvaloniaProperty.RegisterAttached( + AvaloniaProperty.RegisterAttached( nameof(FontSize), defaultValue: 12, inherits: true); @@ -36,7 +36,7 @@ namespace Avalonia.Controls.Documents /// Defines the property. /// public static readonly AttachedProperty FontStyleProperty = - AvaloniaProperty.RegisterAttached( + AvaloniaProperty.RegisterAttached( nameof(FontStyle), inherits: true); @@ -44,7 +44,7 @@ namespace Avalonia.Controls.Documents /// Defines the property. /// public static readonly AttachedProperty FontWeightProperty = - AvaloniaProperty.RegisterAttached( + AvaloniaProperty.RegisterAttached( nameof(FontWeight), inherits: true, defaultValue: FontWeight.Normal); @@ -53,7 +53,7 @@ namespace Avalonia.Controls.Documents /// Defines the property. /// public static readonly AttachedProperty FontStretchProperty = - AvaloniaProperty.RegisterAttached( + AvaloniaProperty.RegisterAttached( nameof(FontStretch), inherits: true, defaultValue: FontStretch.Normal); @@ -62,7 +62,7 @@ namespace Avalonia.Controls.Documents /// Defines the property. /// public static readonly AttachedProperty ForegroundProperty = - AvaloniaProperty.RegisterAttached( + AvaloniaProperty.RegisterAttached( nameof(Foreground), Brushes.Black, inherits: true); diff --git a/src/Avalonia.Controls/RichTextBlock.cs b/src/Avalonia.Controls/RichTextBlock.cs index 2b84113497..9b5afaef5d 100644 --- a/src/Avalonia.Controls/RichTextBlock.cs +++ b/src/Avalonia.Controls/RichTextBlock.cs @@ -170,6 +170,8 @@ namespace Avalonia.Controls remove => RemoveHandler(CopyingToClipboardEvent, value); } + internal bool HasComplexContent => Inlines.Count > 0; + /// /// Copies the current selection to the Clipboard. /// @@ -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(); diff --git a/src/Avalonia.Controls/TextBlock.cs b/src/Avalonia.Controls/TextBlock.cs index 52261d1c76..80edaf4f26 100644 --- a/src/Avalonia.Controls/TextBlock.cs +++ b/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 /// /// A control that displays a block of text. /// - public class TextBlock : Control + public class TextBlock : Control, IAddChild { /// /// Defines the property. @@ -128,7 +129,7 @@ namespace Avalonia.Controls public static readonly StyledProperty TextDecorationsProperty = AvaloniaProperty.Register(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; - } - /// /// Renders the to a drawing context. /// @@ -512,6 +508,11 @@ namespace Avalonia.Controls TextLayout.Draw(context, new Point(padding.Left, top)); } + void IAddChild.AddChild(string text) + { + _text = text; + } + protected virtual string? GetText() { return _text; diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlLanguage.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlLanguage.cs index 54eac8f59e..c8fced515d 100644 --- a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlLanguage.cs +++ b/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); diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/xamlil.github b/src/Markup/Avalonia.Markup.Xaml.Loader/xamlil.github index a4e6be2d14..d990d63774 160000 --- a/src/Markup/Avalonia.Markup.Xaml.Loader/xamlil.github +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/xamlil.github @@ -1 +1 @@ -Subproject commit a4e6be2d1407abec4f35fcb208848830ce513ead +Subproject commit d990d63774a04d2a4b3d52e626a90ee68e19e2b6 diff --git a/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj b/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj index c35cbc35c0..30d321426f 100644 --- a/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj +++ b/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj @@ -15,7 +15,6 @@ - diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/BasicTests.cs b/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/BasicTests.cs index bed5f19ecb..9635ab285d 100644 --- a/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/BasicTests.cs +++ b/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 + public class ObjectWithAddChildOfT : IAddChild, IAddChild { public string Text { get; set; }