using System;
using System.Text;
using Avalonia.Collections;
using Avalonia.LogicalTree;
using Avalonia.Metadata;
namespace Avalonia.Controls.Documents
{
///
/// A collection of s.
///
[WhitespaceSignificantCollection]
public class InlineCollection : AvaloniaList
{
private ILogical? _parent;
private IInlineHost? _inlineHost;
private string? _text = string.Empty;
///
/// Initializes a new instance of the class.
///
public InlineCollection()
{
ResetBehavior = ResetBehavior.Remove;
this.ForEachItem(
x =>
{
((ISetLogicalParent)x).SetParent(Parent);
x.InlineHost = InlineHost;
Invalidate();
},
x =>
{
((ISetLogicalParent)x).SetParent(null);
x.InlineHost = InlineHost;
Invalidate();
},
() => throw new NotSupportedException());
}
internal ILogical? Parent
{
get => _parent;
set
{
_parent = value;
OnParentChanged(value);
}
}
internal IInlineHost? InlineHost
{
get => _inlineHost;
set
{
_inlineHost = value;
OnInlineHostChanged(value);
}
}
public bool HasComplexContent => Count > 0;
///
/// Gets or adds the text held by the inlines collection.
///
/// Can be null for complex content.
///
///
public string? Text
{
get
{
if (!HasComplexContent)
{
return _text;
}
var builder = new StringBuilder();
foreach (var inline in this)
{
inline.AppendText(builder);
}
return builder.ToString();
}
set
{
if (HasComplexContent)
{
Add(new Run(value));
}
else
{
_text = value;
}
}
}
///
/// Add a text segment to the collection.
///
/// For non complex content this appends the text to the end of currently held text.
/// For complex content this adds a to the collection.
///
///
///
public void Add(string text)
{
if (HasComplexContent)
{
Add(new Run(text));
}
else
{
_text = 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);
}
///
/// Raised when an inline in the collection changes.
///
public event EventHandler? Invalidated;
///
/// Raises the event.
///
protected void Invalidate()
{
if(InlineHost != null)
{
InlineHost.Invalidate();
}
Invalidated?.Invoke(this, EventArgs.Empty);
}
private void OnParentChanged(ILogical? parent)
{
foreach(var child in this)
{
((ISetLogicalParent)child).SetParent(parent);
}
}
private void OnInlineHostChanged(IInlineHost? inlineHost)
{
foreach (var child in this)
{
child.InlineHost = inlineHost;
}
}
}
}