diff --git a/samples/Sandbox/MainWindow.axaml b/samples/Sandbox/MainWindow.axaml
index 6929f192c7..03f80d8fc7 100644
--- a/samples/Sandbox/MainWindow.axaml
+++ b/samples/Sandbox/MainWindow.axaml
@@ -1,4 +1,13 @@
+
+ This is a
+ TextBlock
+ with several
+ Span elements,
+
+ using a variety of styles
+ .
+
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..3d7a4b58d1 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,12 @@ namespace Avalonia.Controls.Documents
///
public void Add(string text)
{
- if (HasComplexContent)
- {
- Add(new Run(text));
- }
- else
- {
- _text = text;
- }
+ Add(new Run(text));
}
public void Add(IControl child)
{
- var implicitRun = new InlineUIContainer(child);
-
- Add(implicitRun);
- }
-
- public override void Add(Inline item)
- {
- if (!HasComplexContent)
- {
- if (!string.IsNullOrEmpty(_text))
- {
- base.Add(new Run(_text));
- }
-
- _text = null;
- }
-
- base.Add(item);
+ Add(new InlineUIContainer(child));
}
///
@@ -152,7 +110,7 @@ namespace Avalonia.Controls.Documents
///
protected void Invalidate()
{
- if(InlineHost != null)
+ if (InlineHost != null)
{
InlineHost.Invalidate();
}
@@ -162,7 +120,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..3560996727 100644
--- a/src/Avalonia.Controls/Documents/Span.cs
+++ b/src/Avalonia.Controls/Documents/Span.cs
@@ -38,41 +38,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 +69,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..abd6e7e807 100644
--- a/src/Avalonia.Controls/RichTextBlock.cs
+++ b/src/Avalonia.Controls/RichTextBlock.cs
@@ -16,7 +16,7 @@ namespace Avalonia.Controls
///
/// A control that displays a block of formatted text.
///
- public class RichTextBlock : TextBlock, IInlineHost
+ public class RichTextBlock : TextBlock, IInlineHost, IAddChild, IAddChild, IAddChild
{
public static readonly StyledProperty IsTextSelectionEnabledProperty =
AvaloniaProperty.Register(nameof(IsTextSelectionEnabled), false);
@@ -148,7 +148,6 @@ namespace Avalonia.Controls
///
/// Gets or sets the inlines.
///
- [Content]
public InlineCollection Inlines
{
get => GetValue(InlinesProperty);
@@ -170,6 +169,8 @@ namespace Avalonia.Controls
remove => RemoveHandler(CopyingToClipboardEvent, value);
}
+ internal bool HasComplexContent => Inlines.Count > 0;
+
///
/// Copies the current selection to the Clipboard.
///
@@ -251,25 +252,69 @@ namespace Avalonia.Controls
SelectionEnd = SelectionStart;
}
- protected override string? GetText()
+ void IAddChild.AddChild(string text)
{
- return _text ?? Inlines.Text;
+ AddText(text);
}
- protected override void SetText(string? text)
+ void IAddChild.AddChild(Inline inline)
{
- var oldValue = _text ?? Inlines?.Text;
+ if (!HasComplexContent && !string.IsNullOrEmpty(_text))
+ {
+ Inlines.Add(_text);
+
+ _text = null;
+ }
+
+ Inlines.Add(inline);
+ }
- if (Inlines is not null && Inlines.HasComplexContent)
+ void IAddChild.AddChild(IControl child)
+ {
+ if (!HasComplexContent && !string.IsNullOrEmpty(_text))
{
- Inlines.Text = text;
+ Inlines.Add(_text);
_text = null;
}
- else
+
+ Inlines.Add(new InlineUIContainer(child));
+ }
+
+ 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;
+ }
+
+ protected override void SetText(string? text)
+ {
+ var oldValue = _text ?? Inlines?.Text;
+
+ AddText(text);
RaisePropertyChanged(TextProperty, oldValue, text);
}
@@ -293,7 +338,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..8077c00faf 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.
@@ -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/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 @@
-