committed by
GitHub
405 changed files with 16326 additions and 6112 deletions
@ -1,35 +1,18 @@ |
|||||
using System; |
|
||||
using System.Reactive.Linq; |
|
||||
using Avalonia; |
|
||||
using Avalonia.Animation; |
|
||||
using Avalonia.Controls; |
using Avalonia.Controls; |
||||
using Avalonia.Data; |
|
||||
using Avalonia.Markup.Xaml; |
using Avalonia.Markup.Xaml; |
||||
using Avalonia.Media; |
|
||||
|
|
||||
namespace RenderDemo.Pages |
namespace RenderDemo.Pages |
||||
{ |
{ |
||||
public class ClippingPage : UserControl |
public class ClippingPage : UserControl |
||||
{ |
{ |
||||
private Geometry _clip; |
|
||||
|
|
||||
public ClippingPage() |
public ClippingPage() |
||||
{ |
{ |
||||
InitializeComponent(); |
InitializeComponent(); |
||||
WireUpCheckbox(); |
|
||||
} |
} |
||||
|
|
||||
private void InitializeComponent() |
private void InitializeComponent() |
||||
{ |
{ |
||||
AvaloniaXamlLoader.Load(this); |
AvaloniaXamlLoader.Load(this); |
||||
} |
} |
||||
|
|
||||
private void WireUpCheckbox() |
|
||||
{ |
|
||||
var useMask = this.FindControl<CheckBox>("useMask"); |
|
||||
var clipped = this.FindControl<Border>("clipped"); |
|
||||
_clip = clipped.Clip; |
|
||||
useMask.Click += (s, e) => clipped.Clip = clipped.Clip == null ? _clip : null; |
|
||||
} |
|
||||
} |
} |
||||
} |
} |
||||
|
|||||
@ -0,0 +1,7 @@ |
|||||
|
<UserControl xmlns="https://github.com/avaloniaui" |
||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" |
||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" |
||||
|
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" |
||||
|
x:Class="RenderDemo.Pages.FormattedTextPage"> |
||||
|
</UserControl> |
||||
@ -0,0 +1,60 @@ |
|||||
|
using System.Globalization; |
||||
|
using Avalonia; |
||||
|
using Avalonia.Controls; |
||||
|
using Avalonia.Markup.Xaml; |
||||
|
using Avalonia.Media; |
||||
|
|
||||
|
namespace RenderDemo.Pages |
||||
|
{ |
||||
|
public class FormattedTextPage : UserControl |
||||
|
{ |
||||
|
public FormattedTextPage() |
||||
|
{ |
||||
|
this.InitializeComponent(); |
||||
|
} |
||||
|
|
||||
|
private void InitializeComponent() |
||||
|
{ |
||||
|
AvaloniaXamlLoader.Load(this); |
||||
|
} |
||||
|
|
||||
|
public override void Render(DrawingContext context) |
||||
|
{ |
||||
|
const string testString = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor"; |
||||
|
|
||||
|
// Create the initial formatted text string.
|
||||
|
var formattedText = new FormattedText( |
||||
|
testString, |
||||
|
CultureInfo.GetCultureInfo("en-us"), |
||||
|
FlowDirection.LeftToRight, |
||||
|
new Typeface("Verdana"), |
||||
|
32, |
||||
|
Brushes.Black) { MaxTextWidth = 300, MaxTextHeight = 240 }; |
||||
|
|
||||
|
// Set a maximum width and height. If the text overflows these values, an ellipsis "..." appears.
|
||||
|
|
||||
|
// Use a larger font size beginning at the first (zero-based) character and continuing for 5 characters.
|
||||
|
// The font size is calculated in terms of points -- not as device-independent pixels.
|
||||
|
formattedText.SetFontSize(36 * (96.0 / 72.0), 0, 5); |
||||
|
|
||||
|
// Use a Bold font weight beginning at the 6th character and continuing for 11 characters.
|
||||
|
formattedText.SetFontWeight(FontWeight.Bold, 6, 11); |
||||
|
|
||||
|
var gradient = new LinearGradientBrush |
||||
|
{ |
||||
|
GradientStops = |
||||
|
new GradientStops { new GradientStop(Colors.Orange, 0), new GradientStop(Colors.Teal, 1) }, |
||||
|
StartPoint = new RelativePoint(0,0, RelativeUnit.Relative), |
||||
|
EndPoint = new RelativePoint(0,1, RelativeUnit.Relative) |
||||
|
}; |
||||
|
|
||||
|
// Use a linear gradient brush beginning at the 6th character and continuing for 11 characters.
|
||||
|
formattedText.SetForegroundBrush(gradient, 6, 11); |
||||
|
|
||||
|
// Use an Italic font style beginning at the 28th character and continuing for 28 characters.
|
||||
|
formattedText.SetFontStyle(FontStyle.Italic, 28, 28); |
||||
|
|
||||
|
context.DrawText(formattedText, new Point(10, 0)); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,18 +0,0 @@ |
|||||
using Avalonia.Platform; |
|
||||
|
|
||||
namespace Avalonia.Shared.PlatformSupport |
|
||||
{ |
|
||||
internal partial class StandardRuntimePlatform |
|
||||
{ |
|
||||
public RuntimePlatformInfo GetRuntimeInfo() => new RuntimePlatformInfo |
|
||||
{ |
|
||||
IsCoreClr = false, |
|
||||
IsDesktop = false, |
|
||||
IsMobile = true, |
|
||||
IsDotNetFramework = false, |
|
||||
IsMono = true, |
|
||||
IsUnix = true, |
|
||||
OperatingSystem = OperatingSystemType.Android |
|
||||
}; |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,12 @@ |
|||||
|
using System; |
||||
|
|
||||
|
namespace Avalonia.Utilities; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Defines a listener to a event subscribed vis the <see cref="WeakEvent{TTarget, TEventArgs}"/>.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TEventArgs">The type of the event arguments.</typeparam>
|
||||
|
public interface IWeakEventSubscriber<in TEventArgs> where TEventArgs : EventArgs |
||||
|
{ |
||||
|
void OnEvent(object? sender, WeakEvent ev, TEventArgs e); |
||||
|
} |
||||
@ -0,0 +1,187 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Reflection; |
||||
|
using System.Runtime.CompilerServices; |
||||
|
using Avalonia.Threading; |
||||
|
|
||||
|
namespace Avalonia.Utilities; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Manages subscriptions to events using weak listeners.
|
||||
|
/// </summary>
|
||||
|
public class WeakEvent<TSender, TEventArgs> : WeakEvent where TEventArgs : EventArgs where TSender : class |
||||
|
{ |
||||
|
private readonly Func<TSender, EventHandler<TEventArgs>, Action> _subscribe; |
||||
|
|
||||
|
readonly ConditionalWeakTable<object, Subscription> _subscriptions = new(); |
||||
|
|
||||
|
internal WeakEvent( |
||||
|
Action<TSender, EventHandler<TEventArgs>> subscribe, |
||||
|
Action<TSender, EventHandler<TEventArgs>> unsubscribe) |
||||
|
{ |
||||
|
_subscribe = (t, s) => |
||||
|
{ |
||||
|
subscribe(t, s); |
||||
|
return () => unsubscribe(t, s); |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
internal WeakEvent(Func<TSender, EventHandler<TEventArgs>, Action> subscribe) |
||||
|
{ |
||||
|
_subscribe = subscribe; |
||||
|
} |
||||
|
|
||||
|
public void Subscribe(TSender target, IWeakEventSubscriber<TEventArgs> subscriber) |
||||
|
{ |
||||
|
if (!_subscriptions.TryGetValue(target, out var subscription)) |
||||
|
_subscriptions.Add(target, subscription = new Subscription(this, target)); |
||||
|
subscription.Add(new WeakReference<IWeakEventSubscriber<TEventArgs>>(subscriber)); |
||||
|
} |
||||
|
|
||||
|
public void Unsubscribe(TSender target, IWeakEventSubscriber<TEventArgs> subscriber) |
||||
|
{ |
||||
|
if (_subscriptions.TryGetValue(target, out var subscription)) |
||||
|
subscription.Remove(subscriber); |
||||
|
} |
||||
|
|
||||
|
private class Subscription |
||||
|
{ |
||||
|
private readonly WeakEvent<TSender, TEventArgs> _ev; |
||||
|
private readonly TSender _target; |
||||
|
private readonly Action _compact; |
||||
|
|
||||
|
private WeakReference<IWeakEventSubscriber<TEventArgs>>?[] _data = |
||||
|
new WeakReference<IWeakEventSubscriber<TEventArgs>>[16]; |
||||
|
private int _count; |
||||
|
private readonly Action _unsubscribe; |
||||
|
private bool _compactScheduled; |
||||
|
|
||||
|
public Subscription(WeakEvent<TSender, TEventArgs> ev, TSender target) |
||||
|
{ |
||||
|
_ev = ev; |
||||
|
_target = target; |
||||
|
_compact = Compact; |
||||
|
_unsubscribe = ev._subscribe(target, OnEvent); |
||||
|
} |
||||
|
|
||||
|
void Destroy() |
||||
|
{ |
||||
|
_unsubscribe(); |
||||
|
_ev._subscriptions.Remove(_target); |
||||
|
} |
||||
|
|
||||
|
public void Add(WeakReference<IWeakEventSubscriber<TEventArgs>> s) |
||||
|
{ |
||||
|
if (_count == _data.Length) |
||||
|
{ |
||||
|
//Extend capacity
|
||||
|
var extendedData = new WeakReference<IWeakEventSubscriber<TEventArgs>>?[_data.Length * 2]; |
||||
|
Array.Copy(_data, extendedData, _data.Length); |
||||
|
_data = extendedData; |
||||
|
} |
||||
|
|
||||
|
_data[_count] = s; |
||||
|
_count++; |
||||
|
} |
||||
|
|
||||
|
public void Remove(IWeakEventSubscriber<TEventArgs> s) |
||||
|
{ |
||||
|
var removed = false; |
||||
|
|
||||
|
for (int c = 0; c < _count; ++c) |
||||
|
{ |
||||
|
var reference = _data[c]; |
||||
|
|
||||
|
if (reference != null && reference.TryGetTarget(out var instance) && instance == s) |
||||
|
{ |
||||
|
_data[c] = null; |
||||
|
removed = true; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (removed) |
||||
|
{ |
||||
|
ScheduleCompact(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void ScheduleCompact() |
||||
|
{ |
||||
|
if(_compactScheduled) |
||||
|
return; |
||||
|
_compactScheduled = true; |
||||
|
Dispatcher.UIThread.Post(_compact, DispatcherPriority.Background); |
||||
|
} |
||||
|
|
||||
|
void Compact() |
||||
|
{ |
||||
|
_compactScheduled = false; |
||||
|
int empty = -1; |
||||
|
for (var c = 0; c < _count; c++) |
||||
|
{ |
||||
|
var r = _data[c]; |
||||
|
//Mark current index as first empty
|
||||
|
if (r == null && empty == -1) |
||||
|
empty = c; |
||||
|
//If current element isn't null and we have an empty one
|
||||
|
if (r != null && empty != -1) |
||||
|
{ |
||||
|
_data[c] = null; |
||||
|
_data[empty] = r; |
||||
|
empty++; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (empty != -1) |
||||
|
_count = empty; |
||||
|
if (_count == 0) |
||||
|
Destroy(); |
||||
|
} |
||||
|
|
||||
|
void OnEvent(object? sender, TEventArgs eventArgs) |
||||
|
{ |
||||
|
var needCompact = false; |
||||
|
for (var c = 0; c < _count; c++) |
||||
|
{ |
||||
|
var r = _data[c]; |
||||
|
if (r?.TryGetTarget(out var sub) == true) |
||||
|
sub!.OnEvent(_target, _ev, eventArgs); |
||||
|
else |
||||
|
needCompact = true; |
||||
|
} |
||||
|
|
||||
|
if (needCompact) |
||||
|
ScheduleCompact(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public class WeakEvent |
||||
|
{ |
||||
|
public static WeakEvent<TSender, TEventArgs> Register<TSender, TEventArgs>( |
||||
|
Action<TSender, EventHandler<TEventArgs>> subscribe, |
||||
|
Action<TSender, EventHandler<TEventArgs>> unsubscribe) where TSender : class where TEventArgs : EventArgs |
||||
|
{ |
||||
|
return new WeakEvent<TSender, TEventArgs>(subscribe, unsubscribe); |
||||
|
} |
||||
|
|
||||
|
public static WeakEvent<TSender, TEventArgs> Register<TSender, TEventArgs>( |
||||
|
Func<TSender, EventHandler<TEventArgs>, Action> subscribe) where TSender : class where TEventArgs : EventArgs |
||||
|
{ |
||||
|
return new WeakEvent<TSender, TEventArgs>(subscribe); |
||||
|
} |
||||
|
|
||||
|
public static WeakEvent<TSender, EventArgs> Register<TSender>( |
||||
|
Action<TSender, EventHandler> subscribe, |
||||
|
Action<TSender, EventHandler> unsubscribe) where TSender : class |
||||
|
{ |
||||
|
return Register<TSender, EventArgs>((s, h) => |
||||
|
{ |
||||
|
EventHandler handler = (_, e) => h(s, e); |
||||
|
subscribe(s, handler); |
||||
|
return () => unsubscribe(s, handler); |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,40 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Specialized; |
||||
|
using System.ComponentModel; |
||||
|
using System.Windows.Input; |
||||
|
|
||||
|
namespace Avalonia.Utilities; |
||||
|
|
||||
|
public class WeakEvents |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Represents CollectionChanged event from <see cref="INotifyCollectionChanged"/>
|
||||
|
/// </summary>
|
||||
|
public static readonly WeakEvent<INotifyCollectionChanged, NotifyCollectionChangedEventArgs> |
||||
|
CollectionChanged = WeakEvent.Register<INotifyCollectionChanged, NotifyCollectionChangedEventArgs>( |
||||
|
(c, s) => |
||||
|
{ |
||||
|
NotifyCollectionChangedEventHandler handler = (_, e) => s(c, e); |
||||
|
c.CollectionChanged += handler; |
||||
|
return () => c.CollectionChanged -= handler; |
||||
|
}); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents PropertyChanged event from <see cref="INotifyPropertyChanged"/>
|
||||
|
/// </summary>
|
||||
|
public static readonly WeakEvent<INotifyPropertyChanged, PropertyChangedEventArgs> |
||||
|
PropertyChanged = WeakEvent.Register<INotifyPropertyChanged, PropertyChangedEventArgs>( |
||||
|
(s, h) => |
||||
|
{ |
||||
|
PropertyChangedEventHandler handler = (_, e) => h(s, e); |
||||
|
s.PropertyChanged += handler; |
||||
|
return () => s.PropertyChanged -= handler; |
||||
|
}); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents CanExecuteChanged event from <see cref="ICommand"/>
|
||||
|
/// </summary>
|
||||
|
public static readonly WeakEvent<ICommand, EventArgs> CommandCanExecuteChanged = |
||||
|
WeakEvent.Register<ICommand>((s, h) => s.CanExecuteChanged += h, |
||||
|
(s, h) => s.CanExecuteChanged -= h); |
||||
|
} |
||||
@ -0,0 +1,344 @@ |
|||||
|
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); |
||||
|
} |
||||
@ -0,0 +1,3 @@ |
|||||
|
Compat issues with assembly Avalonia.DesktopRuntime: |
||||
|
TypesMustExist : Type 'Avalonia.Shared.PlatformSupport.AssetLoader' does not exist in the implementation but it does exist in the contract. |
||||
|
Total Issues: 1 |
||||
@ -1,40 +0,0 @@ |
|||||
using System; |
|
||||
using System.Runtime.InteropServices; |
|
||||
using Avalonia.Platform; |
|
||||
|
|
||||
|
|
||||
namespace Avalonia.Shared.PlatformSupport |
|
||||
{ |
|
||||
internal partial class StandardRuntimePlatform |
|
||||
{ |
|
||||
private static readonly Lazy<RuntimePlatformInfo> Info = new Lazy<RuntimePlatformInfo>(() => |
|
||||
{ |
|
||||
OperatingSystemType os; |
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) |
|
||||
os = OperatingSystemType.OSX; |
|
||||
else if(RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) |
|
||||
os = OperatingSystemType.Linux; |
|
||||
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) |
|
||||
os = OperatingSystemType.WinNT; |
|
||||
else |
|
||||
throw new Exception("Unknown OS platform " + RuntimeInformation.OSDescription); |
|
||||
|
|
||||
return new RuntimePlatformInfo |
|
||||
{ |
|
||||
#if NETCOREAPP2_0
|
|
||||
IsCoreClr = true, |
|
||||
#elif NET461
|
|
||||
IsDotNetFramework = false, |
|
||||
#endif
|
|
||||
IsDesktop = true, |
|
||||
IsMono = false, |
|
||||
IsMobile = false, |
|
||||
IsUnix = os != OperatingSystemType.WinNT, |
|
||||
OperatingSystem = os, |
|
||||
}; |
|
||||
}); |
|
||||
|
|
||||
|
|
||||
public RuntimePlatformInfo GetRuntimeInfo() => Info.Value; |
|
||||
} |
|
||||
} |
|
||||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue