A cross-platform UI framework for .NET
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

135 lines
4.4 KiB

using System;
using Avalonia.Controls.Platform;
using Avalonia.Native.Interop;
using Avalonia.Platform;
using Avalonia.VisualTree;
namespace Avalonia.Native
{
class NativeControlHostImpl : IDisposable, INativeControlHostImpl
{
private IAvnNativeControlHost _host;
public NativeControlHostImpl(IAvnNativeControlHost host)
{
_host = host;
}
public void Dispose()
{
_host?.Dispose();
_host = null;
}
class DestroyableNSView : INativeControlHostDestroyableControlHandle
{
private IAvnNativeControlHost _impl;
private IntPtr _nsView;
public DestroyableNSView(IAvnNativeControlHost impl)
{
_impl = new IAvnNativeControlHost(impl.NativePointer);
_impl.AddRef();
_nsView = _impl.CreateDefaultChild(IntPtr.Zero);
}
public IntPtr Handle => _nsView;
public string HandleDescriptor => "NSView";
public void Destroy()
{
if (_impl != null)
{
_impl.DestroyDefaultChild(_nsView);
_impl.Dispose();
_impl = null;
_nsView = IntPtr.Zero;
}
}
}
public INativeControlHostDestroyableControlHandle CreateDefaultChild(IPlatformHandle parent)
=> new DestroyableNSView(_host);
public INativeControlHostControlTopLevelAttachment CreateNewAttachment(
Func<IPlatformHandle, IPlatformHandle> create)
{
var a = new Attachment(_host.CreateAttachment());
try
{
var child = create(a.GetParentHandle());
a.InitWithChild(child);
a.AttachedTo = this;
return a;
}
catch
{
a.Dispose();
throw;
}
}
public INativeControlHostControlTopLevelAttachment CreateNewAttachment(IPlatformHandle handle)
{
var a = new Attachment(_host.CreateAttachment());
a.InitWithChild(handle);
a.AttachedTo = this;
return a;
}
public bool IsCompatibleWith(IPlatformHandle handle) => handle.HandleDescriptor == "NSView";
class Attachment : INativeControlHostControlTopLevelAttachment
{
private IAvnNativeControlHostTopLevelAttachment _native;
private NativeControlHostImpl _attachedTo;
public IPlatformHandle GetParentHandle() => new PlatformHandle(_native.ParentHandle, "NSView");
public Attachment(IAvnNativeControlHostTopLevelAttachment native)
{
_native = native;
}
public void Dispose()
{
if (_native != null)
{
_native.ReleaseChild();
_native.Dispose();
_native = null;
}
}
public INativeControlHostImpl AttachedTo
{
get => _attachedTo;
set
{
var host = (NativeControlHostImpl)value;
if(host == null)
_native.AttachTo(null);
else
_native.AttachTo(host._host);
_attachedTo = host;
}
}
public bool IsCompatibleWith(INativeControlHostImpl host) => host is NativeControlHostImpl;
public void HideWithSize(Size size)
{
_native.HideWithSize(Math.Max(1, (float)size.Width), Math.Max(1, (float)size.Height));
}
public void ShowInBounds(Rect bounds)
{
if (_attachedTo == null)
throw new InvalidOperationException("Native control isn't attached to a toplevel");
bounds = new Rect(bounds.X, bounds.Y, Math.Max(1, bounds.Width),
Math.Max(1, bounds.Height));
_native.ShowInBounds((float) bounds.X, (float) bounds.Y, (float) bounds.Width, (float) bounds.Height);
}
public void InitWithChild(IPlatformHandle handle)
=> _native.InitializeWithChildHandle(handle.Handle);
}
}
}