From feaa4e6fe7a6eb936f68b2252cd0a7e68530c32d Mon Sep 17 00:00:00 2001 From: Curtis Wensley Date: Fri, 14 Jul 2023 12:57:12 -0700 Subject: [PATCH] Mac: Add ability to auto attach/detach a control --- src/Eto.Mac/Forms/MacView.cs | 26 ++++++++++++++++++++++++++ src/Eto.Mac/MacHelpers.cs | 16 ++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/src/Eto.Mac/Forms/MacView.cs b/src/Eto.Mac/Forms/MacView.cs index 7d35a3e15..f3225cc08 100644 --- a/src/Eto.Mac/Forms/MacView.cs +++ b/src/Eto.Mac/Forms/MacView.cs @@ -128,6 +128,7 @@ static partial class MacView public static readonly object AcceptsFirstMouse_Key = new object(); public static readonly object TextInputCancelled_Key = new object(); public static readonly object TextInputImplemented_Key = new object(); + public static readonly object AutoAttachNative_Key = new object(); public static readonly IntPtr selMouseDown = Selector.GetHandle("mouseDown:"); public static readonly IntPtr selMouseUp = Selector.GetHandle("mouseUp:"); public static readonly IntPtr selMouseDragged = Selector.GetHandle("mouseDragged:"); @@ -1575,6 +1576,31 @@ public virtual void UpdateLayout() { ContainerControl?.Window?.LayoutIfNeeded(); } + + public bool AutoAttachNative + { + get => Widget.Properties.Get(MacView.AutoAttachNative_Key); + set + { + if (Widget.Properties.TrySet(MacView.AutoAttachNative_Key, value) && value) + { + // ensure method is added to the container control's class + AddMethod(MacView.selViewDidMoveToWindow, MacView.TriggerViewDidMoveToWindow_Delegate, "v@:@", ContainerControl); + } + } + } + + public virtual void OnViewDidMoveToWindow() + { + if (!AutoAttachNative) + return; + + // ensure load/unload get called appropriately. + if (ContainerControl.Window == null) + Widget.DetachNative(); + else + Widget.AttachNative(); + } } } diff --git a/src/Eto.Mac/MacHelpers.cs b/src/Eto.Mac/MacHelpers.cs index 6f89c7258..a0f66a84c 100644 --- a/src/Eto.Mac/MacHelpers.cs +++ b/src/Eto.Mac/MacHelpers.cs @@ -40,6 +40,22 @@ public static NSView ToNative(this Control control, bool attach = false) } return control.GetContainerView(); } + + /// + /// Sets a value indicating that the control should auto attach/detach when added to a native window. + /// + /// + /// This is an alternative to using AttachNative/DetachNative manually, and will automatically be called when the view + /// is added/removed to/from a native Window. This ensures that both Load and UnLoad are triggered on the Eto control(s). + /// + /// Control to auto attach + /// true to auto attach, false otherwise. + public static void SetAutoAttach(this Control control, bool autoAttach) + { + var handler = control.GetMacViewHandler(); + if (handler != null) + handler.AutoAttachNative = true; + } /// /// Wraps the specified to an Eto control that can be used directly in Eto.Forms code.