Skip to content

Commit

Permalink
Merge pull request #2523 from cwensley/curtis/mac-autoattach
Browse files Browse the repository at this point in the history
Mac: Add ability to auto attach/detach a control
  • Loading branch information
cwensley authored Jul 14, 2023
2 parents cc4937d + a9dad89 commit c217f19
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 0 deletions.
42 changes: 42 additions & 0 deletions src/Eto.Mac/Forms/MacView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ public interface IMacViewHandler : IMacControlHandler
MouseEventArgs TriggerMouseDown(NSObject obj, IntPtr sel, NSEvent theEvent);
MouseEventArgs TriggerMouseUp(NSObject obj, IntPtr sel, NSEvent theEvent);
void UpdateTrackingAreas();
void OnViewDidMoveToWindow();
bool AutoAttachNative { get; set; }
}

static partial class MacView
Expand All @@ -128,6 +130,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:");
Expand Down Expand Up @@ -556,6 +559,20 @@ static bool ValidateSystemUserInterfaceItem(IntPtr sender, IntPtr sel, IntPtr it
/// </summary>
public static bool InMouseTrackingLoop;

public static IntPtr selViewDidMoveToWindow = Selector.GetHandle("viewDidMoveToWindow");

internal static MarshalDelegates.Action_IntPtr_IntPtr TriggerViewDidMoveToWindow_Delegate = TriggerViewDidMoveToWindow;
static void TriggerViewDidMoveToWindow(IntPtr sender, IntPtr sel)
{
var obj = Runtime.GetNSObject(sender);

Messaging.void_objc_msgSendSuper(obj.SuperHandle, sel);

if (MacBase.GetHandler(obj) is IMacViewHandler handler)
{
handler.OnViewDidMoveToWindow();
}
}
}

public abstract partial class MacView<TControl, TWidget, TCallback> : MacObject<TControl, TWidget, TCallback>, Control.IHandler, IMacViewHandler
Expand Down Expand Up @@ -1575,6 +1592,31 @@ public virtual void UpdateLayout()
{
ContainerControl?.Window?.LayoutIfNeeded();
}

public bool AutoAttachNative
{
get => Widget.Properties.Get<bool>(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();
}
}
}

16 changes: 16 additions & 0 deletions src/Eto.Mac/MacHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,22 @@ public static NSView ToNative(this Control control, bool attach = false)
}
return control.GetContainerView();
}

/// <summary>
/// Sets a value indicating that the control should auto attach/detach when added to a native window.
/// </summary>
/// <remarks>
/// 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).
/// </remarks>
/// <param name="control">Control to auto attach</param>
/// <param name="autoAttach"><c>true</c> to auto attach, <c>false</c> otherwise.</param>
public static void SetAutoAttach(this Control control, bool autoAttach)
{
var handler = control.GetMacViewHandler();
if (handler != null)
handler.AutoAttachNative = true;
}

/// <summary>
/// Wraps the specified <paramref name="view"/> to an Eto control that can be used directly in Eto.Forms code.
Expand Down

0 comments on commit c217f19

Please sign in to comment.