csharpc-sharpdotnetxamlavaloniauicross-platformcross-platform-xamlavaloniaguimulti-platformuser-interfacedotnetcore
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
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);
|
|
}
|
|
}
|
|
}
|
|
|