committed by
GitHub
29 changed files with 799 additions and 382 deletions
@ -0,0 +1,10 @@ |
|||
using System; |
|||
|
|||
namespace Avalonia.Metadata |
|||
{ |
|||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)] |
|||
public class TrimSurroundingWhitespaceAttribute : Attribute |
|||
{ |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
using System; |
|||
|
|||
namespace Avalonia.Metadata |
|||
{ |
|||
/// <summary>
|
|||
/// Indicates that a collection type should be processed as being whitespace significant by a XAML processor.
|
|||
/// </summary>
|
|||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)] |
|||
public class WhitespaceSignificantCollectionAttribute : Attribute |
|||
{ |
|||
} |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
using Avalonia.Media; |
|||
|
|||
namespace Avalonia.Controls.Documents |
|||
{ |
|||
/// <summary>
|
|||
/// Bold element - markup helper for indicating bolded content.
|
|||
/// Equivalent to a Span with FontWeight property set to FontWeights.Bold.
|
|||
/// Can contain other inline elements.
|
|||
/// </summary>
|
|||
public sealed class Bold : Span |
|||
{ |
|||
static Bold() |
|||
{ |
|||
FontWeightProperty.OverrideDefaultValue<Bold>(FontWeight.Bold); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,71 @@ |
|||
using System.Collections.Generic; |
|||
using System.Text; |
|||
using Avalonia.Media; |
|||
using Avalonia.Media.TextFormatting; |
|||
using Avalonia.Utilities; |
|||
|
|||
namespace Avalonia.Controls.Documents |
|||
{ |
|||
/// <summary>
|
|||
/// Inline element.
|
|||
/// </summary>
|
|||
public abstract class Inline : TextElement |
|||
{ |
|||
/// <summary>
|
|||
/// AvaloniaProperty for <see cref="TextDecorations" /> property.
|
|||
/// </summary>
|
|||
public static readonly StyledProperty<TextDecorationCollection> TextDecorationsProperty = |
|||
AvaloniaProperty.Register<Inline, TextDecorationCollection>( |
|||
nameof(TextDecorations)); |
|||
|
|||
/// <summary>
|
|||
/// AvaloniaProperty for <see cref="BaselineAlignment" /> property.
|
|||
/// </summary>
|
|||
public static readonly StyledProperty<BaselineAlignment> BaselineAlignmentProperty = |
|||
AvaloniaProperty.Register<Inline, BaselineAlignment>( |
|||
nameof(BaselineAlignment), |
|||
BaselineAlignment.Baseline); |
|||
|
|||
/// <summary>
|
|||
/// The TextDecorations property specifies decorations that are added to the text of an element.
|
|||
/// </summary>
|
|||
public TextDecorationCollection TextDecorations |
|||
{ |
|||
get { return GetValue(TextDecorationsProperty); } |
|||
set { SetValue(TextDecorationsProperty, value); } |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Describes how the baseline for a text-based element is positioned on the vertical axis,
|
|||
/// relative to the established baseline for text.
|
|||
/// </summary>
|
|||
public BaselineAlignment BaselineAlignment |
|||
{ |
|||
get { return GetValue(BaselineAlignmentProperty); } |
|||
set { SetValue(BaselineAlignmentProperty, value); } |
|||
} |
|||
|
|||
internal abstract int BuildRun(StringBuilder stringBuilder, IList<ValueSpan<TextRunProperties>> textStyleOverrides, int firstCharacterIndex); |
|||
|
|||
internal abstract int AppendText(StringBuilder stringBuilder); |
|||
|
|||
protected TextRunProperties CreateTextRunProperties() |
|||
{ |
|||
return new GenericTextRunProperties(new Typeface(FontFamily, FontStyle, FontWeight), FontSize, |
|||
TextDecorations, Foreground, Background, BaselineAlignment); |
|||
} |
|||
|
|||
protected override void OnPropertyChanged<T>(AvaloniaPropertyChangedEventArgs<T> change) |
|||
{ |
|||
base.OnPropertyChanged(change); |
|||
|
|||
switch (change.Property.Name) |
|||
{ |
|||
case nameof(TextDecorations): |
|||
case nameof(BaselineAlignment): |
|||
Invalidate(); |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,123 @@ |
|||
using System; |
|||
using System.Text; |
|||
using Avalonia.Collections; |
|||
using Avalonia.LogicalTree; |
|||
using Avalonia.Metadata; |
|||
|
|||
namespace Avalonia.Controls.Documents |
|||
{ |
|||
/// <summary>
|
|||
/// A collection of <see cref="Inline"/>s.
|
|||
/// </summary>
|
|||
[WhitespaceSignificantCollection] |
|||
public class InlineCollection : AvaloniaList<Inline> |
|||
{ |
|||
private string? _text = string.Empty; |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="InlineCollection"/> class.
|
|||
/// </summary>
|
|||
public InlineCollection(ILogical parent) : base(0) |
|||
{ |
|||
ResetBehavior = ResetBehavior.Remove; |
|||
|
|||
this.ForEachItem( |
|||
x => |
|||
{ |
|||
((ISetLogicalParent)x).SetParent(parent); |
|||
x.Invalidated += Invalidate; |
|||
Invalidate(); |
|||
}, |
|||
x => |
|||
{ |
|||
((ISetLogicalParent)x).SetParent(null); |
|||
x.Invalidated -= Invalidate; |
|||
Invalidate(); |
|||
}, |
|||
() => throw new NotSupportedException()); |
|||
} |
|||
|
|||
public bool HasComplexContent => Count > 0; |
|||
|
|||
/// <summary>
|
|||
/// Gets or adds the text held by the inlines collection.
|
|||
/// <remarks>
|
|||
/// Can be null for complex content.
|
|||
/// </remarks>
|
|||
/// </summary>
|
|||
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; |
|||
} |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Add a text segment to the collection.
|
|||
/// <remarks>
|
|||
/// For non complex content this appends the text to the end of currently held text.
|
|||
/// For complex content this adds a <see cref="Run"/> to the collection.
|
|||
/// </remarks>
|
|||
/// </summary>
|
|||
/// <param name="text"></param>
|
|||
public void Add(string text) |
|||
{ |
|||
if (HasComplexContent) |
|||
{ |
|||
Add(new Run(text)); |
|||
} |
|||
else |
|||
{ |
|||
_text += text; |
|||
} |
|||
} |
|||
|
|||
public override void Add(Inline item) |
|||
{ |
|||
if (!HasComplexContent) |
|||
{ |
|||
base.Add(new Run(_text)); |
|||
|
|||
_text = string.Empty; |
|||
} |
|||
|
|||
base.Add(item); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Raised when an inline in the collection changes.
|
|||
/// </summary>
|
|||
public event EventHandler? Invalidated; |
|||
|
|||
/// <summary>
|
|||
/// Raises the <see cref="Invalidated"/> event.
|
|||
/// </summary>
|
|||
protected void Invalidate() => Invalidated?.Invoke(this, EventArgs.Empty); |
|||
|
|||
private void Invalidate(object? sender, EventArgs e) => Invalidate(); |
|||
} |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
using Avalonia.Media; |
|||
|
|||
namespace Avalonia.Controls.Documents |
|||
{ |
|||
/// <summary>
|
|||
/// Italic element - markup helper for indicating italicized content.
|
|||
/// Equivalent to a Span with FontStyle property set to FontStyles.Italic.
|
|||
/// Can contain other inline elements.
|
|||
/// </summary>
|
|||
public sealed class Italic : Span |
|||
{ |
|||
static Italic() |
|||
{ |
|||
FontStyleProperty.OverrideDefaultValue<Italic>(FontStyle.Italic); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,44 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Text; |
|||
using Avalonia.Media.TextFormatting; |
|||
using Avalonia.Metadata; |
|||
using Avalonia.Utilities; |
|||
|
|||
namespace Avalonia.Controls.Documents |
|||
{ |
|||
/// <summary>
|
|||
/// LineBreak element that forces a line breaking.
|
|||
/// </summary>
|
|||
[TrimSurroundingWhitespace] |
|||
public class LineBreak : Inline |
|||
{ |
|||
/// <summary>
|
|||
/// Creates a new LineBreak instance.
|
|||
/// </summary>
|
|||
public LineBreak() |
|||
{ |
|||
} |
|||
|
|||
internal override int BuildRun(StringBuilder stringBuilder, |
|||
IList<ValueSpan<TextRunProperties>> textStyleOverrides, int firstCharacterIndex) |
|||
{ |
|||
var length = AppendText(stringBuilder); |
|||
|
|||
textStyleOverrides.Add(new ValueSpan<TextRunProperties>(firstCharacterIndex, length, |
|||
CreateTextRunProperties())); |
|||
|
|||
return length; |
|||
} |
|||
|
|||
internal override int AppendText(StringBuilder stringBuilder) |
|||
{ |
|||
var text = Environment.NewLine; |
|||
|
|||
stringBuilder.Append(text); |
|||
|
|||
return text.Length; |
|||
} |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,86 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Text; |
|||
using Avalonia.Data; |
|||
using Avalonia.Media.TextFormatting; |
|||
using Avalonia.Metadata; |
|||
using Avalonia.Utilities; |
|||
|
|||
namespace Avalonia.Controls.Documents |
|||
{ |
|||
/// <summary>
|
|||
/// A terminal element in text flow hierarchy - contains a uniformatted run of unicode characters
|
|||
/// </summary>
|
|||
public class Run : Inline |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes an instance of Run class.
|
|||
/// </summary>
|
|||
public Run() |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes an instance of Run class specifying its text content.
|
|||
/// </summary>
|
|||
/// <param name="text">
|
|||
/// Text content assigned to the Run.
|
|||
/// </param>
|
|||
public Run(string? text) |
|||
{ |
|||
Text = text; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Dependency property backing Text.
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// Note that when a TextRange that intersects with this Run gets modified (e.g. by editing
|
|||
/// a selection in RichTextBox), we will get two changes to this property since we delete
|
|||
/// and then insert when setting the content of a TextRange.
|
|||
/// </remarks>
|
|||
public static readonly StyledProperty<string?> TextProperty = AvaloniaProperty.Register<Run, string?> ( |
|||
nameof (Text), defaultBindingMode: BindingMode.TwoWay); |
|||
|
|||
/// <summary>
|
|||
/// The content spanned by this TextElement.
|
|||
/// </summary>
|
|||
[Content] |
|||
public string? Text { |
|||
get { return GetValue (TextProperty); } |
|||
set { SetValue (TextProperty, value); } |
|||
} |
|||
|
|||
internal override int BuildRun(StringBuilder stringBuilder, |
|||
IList<ValueSpan<TextRunProperties>> textStyleOverrides, int firstCharacterIndex) |
|||
{ |
|||
var length = AppendText(stringBuilder); |
|||
|
|||
textStyleOverrides.Add(new ValueSpan<TextRunProperties>(firstCharacterIndex, length, |
|||
CreateTextRunProperties())); |
|||
|
|||
return length; |
|||
} |
|||
|
|||
internal override int AppendText(StringBuilder stringBuilder) |
|||
{ |
|||
var text = Text ?? ""; |
|||
|
|||
stringBuilder.Append(text); |
|||
|
|||
return text.Length; |
|||
} |
|||
|
|||
protected override void OnPropertyChanged<T>(AvaloniaPropertyChangedEventArgs<T> change) |
|||
{ |
|||
base.OnPropertyChanged(change); |
|||
|
|||
switch (change.Property.Name) |
|||
{ |
|||
case nameof(Text): |
|||
Invalidate(); |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,95 @@ |
|||
using System.Collections.Generic; |
|||
using System.Text; |
|||
using Avalonia.Media.TextFormatting; |
|||
using Avalonia.Metadata; |
|||
using Avalonia.Utilities; |
|||
|
|||
namespace Avalonia.Controls.Documents |
|||
{ |
|||
/// <summary>
|
|||
/// Span element used for grouping other Inline elements.
|
|||
/// </summary>
|
|||
public class Span : Inline |
|||
{ |
|||
/// <summary>
|
|||
/// Defines the <see cref="Inlines"/> property.
|
|||
/// </summary>
|
|||
public static readonly DirectProperty<Span, InlineCollection> InlinesProperty = |
|||
AvaloniaProperty.RegisterDirect<Span, InlineCollection>( |
|||
nameof(Inlines), |
|||
o => o.Inlines); |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of a Span element.
|
|||
/// </summary>
|
|||
public Span() |
|||
{ |
|||
Inlines = new InlineCollection(this); |
|||
|
|||
Inlines.Invalidated += (s, e) => Invalidate(); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the inlines.
|
|||
/// </summary>
|
|||
[Content] |
|||
public InlineCollection Inlines { get; } |
|||
|
|||
internal override int BuildRun(StringBuilder stringBuilder, IList<ValueSpan<TextRunProperties>> textStyleOverrides, int firstCharacterIndex) |
|||
{ |
|||
var length = 0; |
|||
|
|||
if (Inlines.HasComplexContent) |
|||
{ |
|||
foreach (var inline in Inlines) |
|||
{ |
|||
var inlineLength = inline.BuildRun(stringBuilder, textStyleOverrides, firstCharacterIndex); |
|||
|
|||
firstCharacterIndex += inlineLength; |
|||
|
|||
length += inlineLength; |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
if (Inlines.Text == null) |
|||
{ |
|||
return length; |
|||
} |
|||
|
|||
stringBuilder.Append(Inlines.Text); |
|||
|
|||
length = Inlines.Text.Length; |
|||
|
|||
textStyleOverrides.Add(new ValueSpan<TextRunProperties>(firstCharacterIndex, length, |
|||
CreateTextRunProperties())); |
|||
} |
|||
|
|||
return length; |
|||
} |
|||
|
|||
internal override int AppendText(StringBuilder stringBuilder) |
|||
{ |
|||
if (Inlines.HasComplexContent) |
|||
{ |
|||
var length = 0; |
|||
|
|||
foreach (var inline in Inlines) |
|||
{ |
|||
length += inline.AppendText(stringBuilder); |
|||
} |
|||
|
|||
return length; |
|||
} |
|||
|
|||
if (Inlines.Text == null) |
|||
{ |
|||
return 0; |
|||
} |
|||
|
|||
stringBuilder.Append(Inlines.Text); |
|||
|
|||
return Inlines.Text.Length; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,129 @@ |
|||
using System; |
|||
using Avalonia.Media; |
|||
|
|||
namespace Avalonia.Controls.Documents |
|||
{ |
|||
/// <summary>
|
|||
/// TextElement is an base class for content in text based controls.
|
|||
/// TextElements span other content, applying property values or providing structural information.
|
|||
/// </summary>
|
|||
public abstract class TextElement : StyledElement |
|||
{ |
|||
/// <summary>
|
|||
/// Defines the <see cref="Background"/> property.
|
|||
/// </summary>
|
|||
public static readonly StyledProperty<IBrush?> BackgroundProperty = |
|||
AvaloniaProperty.Register<TextElement, IBrush?>(nameof(Background), inherits: true); |
|||
|
|||
/// <summary>
|
|||
/// Defines the <see cref="FontFamily"/> property.
|
|||
/// </summary>
|
|||
public static readonly AttachedProperty<FontFamily> FontFamilyProperty = |
|||
TextBlock.FontFamilyProperty.AddOwner<TextElement>(); |
|||
|
|||
/// <summary>
|
|||
/// Defines the <see cref="FontSize"/> property.
|
|||
/// </summary>
|
|||
public static readonly AttachedProperty<double> FontSizeProperty = |
|||
TextBlock.FontSizeProperty.AddOwner<TextElement>(); |
|||
|
|||
/// <summary>
|
|||
/// Defines the <see cref="FontStyle"/> property.
|
|||
/// </summary>
|
|||
public static readonly AttachedProperty<FontStyle> FontStyleProperty = |
|||
TextBlock.FontStyleProperty.AddOwner<TextElement>(); |
|||
|
|||
/// <summary>
|
|||
/// Defines the <see cref="FontWeight"/> property.
|
|||
/// </summary>
|
|||
public static readonly AttachedProperty<FontWeight> FontWeightProperty = |
|||
TextBlock.FontWeightProperty.AddOwner<TextElement>(); |
|||
|
|||
/// <summary>
|
|||
/// Defines the <see cref="Foreground"/> property.
|
|||
/// </summary>
|
|||
public static readonly AttachedProperty<IBrush?> ForegroundProperty = |
|||
TextBlock.ForegroundProperty.AddOwner<TextElement>(); |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets a brush used to paint the control's background.
|
|||
/// </summary>
|
|||
public IBrush? Background |
|||
{ |
|||
get { return GetValue(BackgroundProperty); } |
|||
set { SetValue(BackgroundProperty, value); } |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the font family.
|
|||
/// </summary>
|
|||
public FontFamily FontFamily |
|||
{ |
|||
get { return GetValue(FontFamilyProperty); } |
|||
set { SetValue(FontFamilyProperty, value); } |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the font size.
|
|||
/// </summary>
|
|||
public double FontSize |
|||
{ |
|||
get { return GetValue(FontSizeProperty); } |
|||
set { SetValue(FontSizeProperty, value); } |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the font style.
|
|||
/// </summary>
|
|||
public FontStyle FontStyle |
|||
{ |
|||
get { return GetValue(FontStyleProperty); } |
|||
set { SetValue(FontStyleProperty, value); } |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the font weight.
|
|||
/// </summary>
|
|||
public FontWeight FontWeight |
|||
{ |
|||
get { return GetValue(FontWeightProperty); } |
|||
set { SetValue(FontWeightProperty, value); } |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets a brush used to paint the text.
|
|||
/// </summary>
|
|||
public IBrush? Foreground |
|||
{ |
|||
get { return GetValue(ForegroundProperty); } |
|||
set { SetValue(ForegroundProperty, value); } |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Raised when the visual representation of the text element changes.
|
|||
/// </summary>
|
|||
public event EventHandler? Invalidated; |
|||
|
|||
protected override void OnPropertyChanged<T>(AvaloniaPropertyChangedEventArgs<T> change) |
|||
{ |
|||
base.OnPropertyChanged(change); |
|||
|
|||
switch (change.Property.Name) |
|||
{ |
|||
case nameof(Background): |
|||
case nameof(FontFamily): |
|||
case nameof(FontSize): |
|||
case nameof(FontStyle): |
|||
case nameof(FontWeight): |
|||
case nameof(Foreground): |
|||
Invalidate(); |
|||
break; |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Raises the <see cref="Invalidate"/> event.
|
|||
/// </summary>
|
|||
protected void Invalidate() => Invalidated?.Invoke(this, EventArgs.Empty); |
|||
} |
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
namespace Avalonia.Controls.Documents |
|||
{ |
|||
/// <summary>
|
|||
/// Underline element - markup helper for indicating superscript content.
|
|||
/// Equivalent to a Span with TextDecorations property set to TextDecorations.Underlined.
|
|||
/// Can contain other inline elements.
|
|||
/// </summary>
|
|||
public sealed class Underline : Span |
|||
{ |
|||
static Underline() |
|||
{ |
|||
TextDecorationsProperty.OverrideDefaultValue<Underline>(Media.TextDecorations.Underline); |
|||
} |
|||
} |
|||
} |
|||
@ -1,344 +0,0 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using Avalonia.Controls.Platform; |
|||
using Avalonia.Controls.Primitives.PopupPositioning; |
|||
using Avalonia.Input; |
|||
using Avalonia.Input.Raw; |
|||
using Avalonia.Input.TextInput; |
|||
using Avalonia.Platform; |
|||
using Avalonia.Rendering; |
|||
|
|||
namespace Avalonia.Controls; |
|||
|
|||
internal class ValidatingToplevelImpl : ITopLevelImpl, ITopLevelImplWithNativeControlHost, |
|||
ITopLevelImplWithNativeMenuExporter, ITopLevelImplWithTextInputMethod |
|||
{ |
|||
private readonly ITopLevelImpl _impl; |
|||
private bool _disposed; |
|||
|
|||
public ValidatingToplevelImpl(ITopLevelImpl impl) |
|||
{ |
|||
_impl = impl ?? throw new InvalidOperationException( |
|||
"Could not create TopLevel implementation: maybe no windowing subsystem was initialized?"); |
|||
} |
|||
|
|||
public void Dispose() |
|||
{ |
|||
_disposed = true; |
|||
_impl.Dispose(); |
|||
} |
|||
|
|||
protected void CheckDisposed() |
|||
{ |
|||
if (_disposed) |
|||
throw new ObjectDisposedException(_impl.GetType().FullName); |
|||
} |
|||
|
|||
protected ITopLevelImpl Inner |
|||
{ |
|||
get |
|||
{ |
|||
CheckDisposed(); |
|||
return _impl; |
|||
} |
|||
} |
|||
|
|||
public static ITopLevelImpl Wrap(ITopLevelImpl impl) |
|||
{ |
|||
#if DEBUG
|
|||
if (impl is ValidatingToplevelImpl) |
|||
return impl; |
|||
return new ValidatingToplevelImpl(impl); |
|||
#else
|
|||
return impl; |
|||
#endif
|
|||
} |
|||
|
|||
public Size ClientSize => Inner.ClientSize; |
|||
public Size? FrameSize => Inner.FrameSize; |
|||
public double RenderScaling => Inner.RenderScaling; |
|||
public IEnumerable<object> Surfaces => Inner.Surfaces; |
|||
|
|||
public Action<RawInputEventArgs>? Input |
|||
{ |
|||
get => Inner.Input; |
|||
set => Inner.Input = value; |
|||
} |
|||
|
|||
public Action<Rect>? Paint |
|||
{ |
|||
get => Inner.Paint; |
|||
set => Inner.Paint = value; |
|||
} |
|||
|
|||
public Action<Size, PlatformResizeReason>? Resized |
|||
{ |
|||
get => Inner.Resized; |
|||
set => Inner.Resized = value; |
|||
} |
|||
|
|||
public Action<double>? ScalingChanged |
|||
{ |
|||
get => Inner.ScalingChanged; |
|||
set => Inner.ScalingChanged = value; |
|||
} |
|||
|
|||
public Action<WindowTransparencyLevel>? TransparencyLevelChanged |
|||
{ |
|||
get => Inner.TransparencyLevelChanged; |
|||
set => Inner.TransparencyLevelChanged = value; |
|||
} |
|||
|
|||
public IRenderer CreateRenderer(IRenderRoot root) => Inner.CreateRenderer(root); |
|||
|
|||
public void Invalidate(Rect rect) => Inner.Invalidate(rect); |
|||
|
|||
public void SetInputRoot(IInputRoot inputRoot) => Inner.SetInputRoot(inputRoot); |
|||
|
|||
public Point PointToClient(PixelPoint point) => Inner.PointToClient(point); |
|||
|
|||
public PixelPoint PointToScreen(Point point) => Inner.PointToScreen(point); |
|||
|
|||
public void SetCursor(ICursorImpl? cursor) => Inner.SetCursor(cursor); |
|||
|
|||
public Action? Closed |
|||
{ |
|||
get => Inner.Closed; |
|||
set => Inner.Closed = value; |
|||
} |
|||
|
|||
public Action? LostFocus |
|||
{ |
|||
get => Inner.LostFocus; |
|||
set => Inner.LostFocus = value; |
|||
} |
|||
|
|||
// Exception: for some reason we are notifying platform mouse device from TopLevel.cs
|
|||
public IMouseDevice MouseDevice => _impl.MouseDevice; |
|||
public IPopupImpl? CreatePopup() => Inner.CreatePopup(); |
|||
|
|||
public void SetTransparencyLevelHint(WindowTransparencyLevel transparencyLevel) => |
|||
Inner.SetTransparencyLevelHint(transparencyLevel); |
|||
|
|||
|
|||
public WindowTransparencyLevel TransparencyLevel => Inner.TransparencyLevel; |
|||
public AcrylicPlatformCompensationLevels AcrylicCompensationLevels => Inner.AcrylicCompensationLevels; |
|||
public INativeControlHostImpl? NativeControlHost => (Inner as ITopLevelImplWithNativeControlHost)?.NativeControlHost; |
|||
|
|||
public ITopLevelNativeMenuExporter? NativeMenuExporter => |
|||
(Inner as ITopLevelImplWithNativeMenuExporter)?.NativeMenuExporter; |
|||
|
|||
public ITextInputMethodImpl? TextInputMethod => (Inner as ITopLevelImplWithTextInputMethod)?.TextInputMethod; |
|||
} |
|||
|
|||
internal class ValidatingWindowBaseImpl : ValidatingToplevelImpl, IWindowBaseImpl |
|||
{ |
|||
private readonly IWindowBaseImpl _impl; |
|||
|
|||
public ValidatingWindowBaseImpl(IWindowBaseImpl impl) : base(impl) |
|||
{ |
|||
_impl = impl; |
|||
} |
|||
|
|||
protected new IWindowBaseImpl Inner |
|||
{ |
|||
get |
|||
{ |
|||
CheckDisposed(); |
|||
return _impl; |
|||
} |
|||
} |
|||
|
|||
public static IWindowBaseImpl Wrap(IWindowBaseImpl impl) |
|||
{ |
|||
#if DEBUG
|
|||
if (impl is ValidatingToplevelImpl) |
|||
return impl; |
|||
return new ValidatingWindowBaseImpl(impl); |
|||
#else
|
|||
return impl; |
|||
#endif
|
|||
} |
|||
|
|||
public void Show(bool activate, bool isDialog) => Inner.Show(activate, isDialog); |
|||
|
|||
public void Hide() => Inner.Hide(); |
|||
|
|||
public double DesktopScaling => Inner.DesktopScaling; |
|||
public PixelPoint Position => Inner.Position; |
|||
|
|||
public Action<PixelPoint>? PositionChanged |
|||
{ |
|||
get => Inner.PositionChanged; |
|||
set => Inner.PositionChanged = value; |
|||
} |
|||
|
|||
public void Activate() => Inner.Activate(); |
|||
|
|||
public Action? Deactivated |
|||
{ |
|||
get => Inner.Deactivated; |
|||
set => Inner.Deactivated = value; |
|||
} |
|||
|
|||
public Action? Activated |
|||
{ |
|||
get => Inner.Activated; |
|||
set => Inner.Activated = value; |
|||
} |
|||
|
|||
public IPlatformHandle Handle => Inner.Handle; |
|||
public Size MaxAutoSizeHint => Inner.MaxAutoSizeHint; |
|||
public void SetTopmost(bool value) => Inner.SetTopmost(value); |
|||
public IScreenImpl Screen => Inner.Screen; |
|||
} |
|||
|
|||
internal class ValidatingWindowImpl : ValidatingWindowBaseImpl, IWindowImpl |
|||
{ |
|||
private readonly IWindowImpl _impl; |
|||
|
|||
public ValidatingWindowImpl(IWindowImpl impl) : base(impl) |
|||
{ |
|||
_impl = impl; |
|||
} |
|||
|
|||
protected new IWindowImpl Inner |
|||
{ |
|||
get |
|||
{ |
|||
CheckDisposed(); |
|||
return _impl; |
|||
} |
|||
} |
|||
|
|||
public static IWindowImpl Unwrap(IWindowImpl impl) |
|||
{ |
|||
if (impl is ValidatingWindowImpl v) |
|||
return v.Inner; |
|||
return impl; |
|||
} |
|||
|
|||
public static IWindowImpl Wrap(IWindowImpl impl) |
|||
{ |
|||
#if DEBUG
|
|||
if (impl is ValidatingToplevelImpl) |
|||
return impl; |
|||
return new ValidatingWindowImpl(impl); |
|||
#else
|
|||
return impl; |
|||
#endif
|
|||
} |
|||
|
|||
public WindowState WindowState |
|||
{ |
|||
get => Inner.WindowState; |
|||
set => Inner.WindowState = value; |
|||
} |
|||
|
|||
public Action<WindowState> WindowStateChanged |
|||
{ |
|||
get => Inner.WindowStateChanged; |
|||
set => Inner.WindowStateChanged = value; |
|||
} |
|||
|
|||
public void SetTitle(string? title) => Inner.SetTitle(title); |
|||
|
|||
public void SetParent(IWindowImpl parent) |
|||
{ |
|||
//Workaround. SetParent will cast IWindowImpl to WindowImpl but ValidatingWindowImpl isn't actual WindowImpl so it will fail with InvalidCastException.
|
|||
if (parent is ValidatingWindowImpl validatingToplevelImpl) |
|||
{ |
|||
Inner.SetParent(validatingToplevelImpl.Inner); |
|||
} |
|||
else |
|||
{ |
|||
Inner.SetParent(parent); |
|||
} |
|||
} |
|||
|
|||
public void SetEnabled(bool enable) => Inner.SetEnabled(enable); |
|||
|
|||
public Action GotInputWhenDisabled |
|||
{ |
|||
get => Inner.GotInputWhenDisabled; |
|||
set => Inner.GotInputWhenDisabled = value; |
|||
} |
|||
|
|||
public void SetSystemDecorations(SystemDecorations enabled) => Inner.SetSystemDecorations(enabled); |
|||
|
|||
public void SetIcon(IWindowIconImpl? icon) => Inner.SetIcon(icon); |
|||
|
|||
public void ShowTaskbarIcon(bool value) => Inner.ShowTaskbarIcon(value); |
|||
|
|||
public void CanResize(bool value) => Inner.CanResize(value); |
|||
|
|||
public Func<bool> Closing |
|||
{ |
|||
get => Inner.Closing; |
|||
set => Inner.Closing = value; |
|||
} |
|||
|
|||
public bool IsClientAreaExtendedToDecorations => Inner.IsClientAreaExtendedToDecorations; |
|||
|
|||
public Action<bool> ExtendClientAreaToDecorationsChanged |
|||
{ |
|||
get => Inner.ExtendClientAreaToDecorationsChanged; |
|||
set => Inner.ExtendClientAreaToDecorationsChanged = value; |
|||
} |
|||
|
|||
public bool NeedsManagedDecorations => Inner.NeedsManagedDecorations; |
|||
public Thickness ExtendedMargins => Inner.ExtendedMargins; |
|||
public Thickness OffScreenMargin => Inner.OffScreenMargin; |
|||
public void BeginMoveDrag(PointerPressedEventArgs e) => Inner.BeginMoveDrag(e); |
|||
|
|||
public void BeginResizeDrag(WindowEdge edge, PointerPressedEventArgs e) => Inner.BeginResizeDrag(edge, e); |
|||
|
|||
public void Resize(Size clientSize, PlatformResizeReason reason) => |
|||
Inner.Resize(clientSize, reason); |
|||
|
|||
public void Move(PixelPoint point) => Inner.Move(point); |
|||
|
|||
public void SetMinMaxSize(Size minSize, Size maxSize) => Inner.SetMinMaxSize(minSize, maxSize); |
|||
|
|||
public void SetExtendClientAreaToDecorationsHint(bool extendIntoClientAreaHint) => |
|||
Inner.SetExtendClientAreaToDecorationsHint(extendIntoClientAreaHint); |
|||
|
|||
public void SetExtendClientAreaChromeHints(ExtendClientAreaChromeHints hints) => |
|||
Inner.SetExtendClientAreaChromeHints(hints); |
|||
|
|||
public void SetExtendClientAreaTitleBarHeightHint(double titleBarHeight) => |
|||
Inner.SetExtendClientAreaTitleBarHeightHint(titleBarHeight); |
|||
} |
|||
|
|||
internal class ValidatingPopupImpl : ValidatingWindowBaseImpl, IPopupImpl |
|||
{ |
|||
private readonly IPopupImpl _impl; |
|||
|
|||
public ValidatingPopupImpl(IPopupImpl impl) : base(impl) |
|||
{ |
|||
_impl = impl; |
|||
} |
|||
|
|||
protected new IPopupImpl Inner |
|||
{ |
|||
get |
|||
{ |
|||
CheckDisposed(); |
|||
return _impl; |
|||
} |
|||
} |
|||
|
|||
public static IPopupImpl Wrap(IPopupImpl impl) |
|||
{ |
|||
#if DEBUG
|
|||
if (impl is ValidatingToplevelImpl) |
|||
return impl; |
|||
return new ValidatingPopupImpl(impl); |
|||
#else
|
|||
return impl; |
|||
#endif
|
|||
} |
|||
|
|||
public IPopupPositioner PopupPositioner => Inner.PopupPositioner; |
|||
public void SetWindowManagerAddShadowHint(bool enabled) => Inner.SetWindowManagerAddShadowHint(enabled); |
|||
} |
|||
Loading…
Reference in new issue