Implemented INativeWindow.MouseEnter/MouseLeave events on Win32 and X11.

This commit is contained in:
the_fiddler 2009-10-27 23:57:44 +00:00
parent 852fdc3662
commit 3d0a3dfb4e
6 changed files with 158 additions and 21 deletions

View file

@ -223,8 +223,17 @@ namespace OpenTK
/// Occurs whenever a character is typed.
/// </summary>
event EventHandler<KeyPressEventArgs> KeyPress;
//event EventHandler<EventArgs> MouseEnter;
/// <summary>
/// Occurs whenever the mouse cursor leaves the window <see cref="Bounds"/>.
/// </summary>
event EventHandler<EventArgs> MouseLeave;
/// <summary>
/// Occurs whenever the mouse cursor enters the window <see cref="Bounds"/>.
/// </summary>
event EventHandler<EventArgs> MouseEnter;
//event EventHandler<MouseEventArgs> MouseMove;
//event EventHandler<MouseEventArgs> MouseWheel;
//event EventHandler<MouseEventArgs> MouseDown;

View file

@ -565,6 +565,16 @@ namespace OpenTK
/// </summary>
public event EventHandler<EventArgs> Move;
/// <summary>
/// Occurs whenever the mouse cursor enters the window <see cref="Bounds"/>.
/// </summary>
public event EventHandler<EventArgs> MouseEnter;
/// <summary>
/// Occurs whenever the mouse cursor leaves the window <see cref="Bounds"/>.
/// </summary>
public event EventHandler<EventArgs> MouseLeave;
/// <summary>
/// Occurs whenever the window is resized.
/// </summary>
@ -747,6 +757,32 @@ namespace OpenTK
#endregion
#region OnMouseEnter
/// <summary>
/// Called whenever the mouse cursor reenters the window <see cref="Bounds"/>.
/// </summary>
/// <param name="e">Not used.</param>
protected virtual void OnMouseEnter(EventArgs e)
{
if (MouseEnter != null) MouseEnter(this, e);
}
#endregion
#region OnMouseLeave
/// <summary>
/// Called whenever the mouse cursor leaves the window <see cref="Bounds"/>.
/// </summary>
/// <param name="e">Not used.</param>
protected virtual void OnMouseLeave(EventArgs e)
{
if (MouseLeave != null) MouseLeave(this, e);
}
#endregion
#region OnResize
/// <summary>
@ -875,6 +911,18 @@ namespace OpenTK
#endregion
#region OnMouseEnterInternal
private void OnMouseEnterInternal(object sender, EventArgs e) { OnMouseEnter(e); }
#endregion
#region OnMouseLeaveInternal
private void OnMouseLeaveInternal(object sender, EventArgs e) { OnMouseLeave(e); }
#endregion
#region OnMoveInternal
private void OnMoveInternal(object sender, EventArgs e) { OnMove(e); }
@ -933,6 +981,8 @@ namespace OpenTK
implementation.FocusedChanged += OnFocusedChangedInternal;
implementation.IconChanged += OnIconChangedInternal;
implementation.KeyPress += OnKeyPressInternal;
implementation.MouseEnter += OnMouseEnterInternal;
implementation.MouseLeave += OnMouseLeaveInternal;
implementation.Move += OnMoveInternal;
implementation.Resize += OnResizeInternal;
implementation.TitleChanged += OnTitleChangedInternal;
@ -949,6 +999,8 @@ namespace OpenTK
implementation.FocusedChanged -= OnFocusedChangedInternal;
implementation.IconChanged -= OnIconChangedInternal;
implementation.KeyPress -= OnKeyPressInternal;
implementation.MouseEnter -= OnMouseEnterInternal;
implementation.MouseLeave -= OnMouseLeaveInternal;
implementation.Move -= OnMoveInternal;
implementation.Resize -= OnResizeInternal;
implementation.TitleChanged -= OnTitleChangedInternal;

View file

@ -954,6 +954,10 @@ namespace OpenTK.Platform.MacOS
public event EventHandler<KeyPressEventArgs> KeyPress;
public event EventHandler<EventArgs> MouseEnter;
public event EventHandler<EventArgs> MouseLeave;
#endregion
}
}

View file

@ -928,6 +928,18 @@ namespace OpenTK.Platform.Windows
#region Input functions
[DllImport("user32.dll", SetLastError=true)]
public static extern BOOL TrackMouseEvent(ref TrackMouseEventStructure lpEventTrack);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]
public static extern bool ReleaseCapture();
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern IntPtr SetCapture(IntPtr hwnd);
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern IntPtr GetCapture();
#region Async input
#region GetCursorPos
@ -2755,6 +2767,20 @@ namespace OpenTK.Platform.Windows
#endregion
#region TrackMouseEventStructure
struct TrackMouseEventStructure
{
public DWORD Size;
public TrackMouseEventFlags Flags;
public HWND TrackWindowHandle;
public DWORD HoverTime;
public static readonly int SizeInBytes = Marshal.SizeOf(typeof(TrackMouseEventStructure));
}
#endregion
#endregion
#region --- Enums ---
@ -4063,6 +4089,20 @@ namespace OpenTK.Platform.Windows
#endregion
#region TrackMouseEventFlags
[Flags]
enum TrackMouseEventFlags : uint
{
HOVER = 0x00000001,
LEAVE = 0x00000002,
NONCLIENT = 0x00000010,
QUERY = 0x40000000,
CANCEL = 0x80000000,
}
#endregion
#endregion
#region --- Callbacks ---

View file

@ -131,6 +131,8 @@ namespace OpenTK.Platform.Windows
keyboards.Add(keyboard);
mice.Add(mouse);
EnableMouseLeaveNotifications();
}
#endregion
@ -141,7 +143,7 @@ namespace OpenTK.Platform.Windows
IntPtr WindowProcedure(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
{
bool mouse_about_to_enter = false;
bool mouse_left = false;
switch (message)
{
@ -289,27 +291,26 @@ namespace OpenTK.Platform.Windows
KeyPress(this, key_press);
break;
//case WindowMessage.MOUSELEAVE:
// Cursor.Current = Cursors.Default;
// break;
//case WindowMessage.MOUSE_ENTER:
// Cursor.Current = Cursors.Default;
// break;
// Mouse events:
case WindowMessage.NCMOUSEMOVE:
mouse_about_to_enter = true; // Used to simulate a mouse enter event.
break;
case WindowMessage.MOUSEMOVE:
mouse.Position = new System.Drawing.Point(
System.Drawing.Point point = new System.Drawing.Point(
(int)(lParam.ToInt32() & 0x0000FFFF),
(int)(lParam.ToInt32() & 0xFFFF0000) >> 16);
if (mouse_about_to_enter)
mouse.Position = point;
{
//Cursor.Current = Cursors.Default;
mouse_about_to_enter = false;
Rectangle rect;
Functions.GetClientRect(window.WindowHandle, out rect);
if (!rect.ToRectangle().Contains(point))
{
Functions.ReleaseCapture();
if (MouseLeave != null)
MouseLeave(this, EventArgs.Empty);
}
else if (Functions.GetCapture() != window.WindowHandle)
{
Functions.SetCapture(window.WindowHandle);
if (MouseEnter != null)
MouseEnter(this, EventArgs.Empty);
}
}
break;
@ -619,6 +620,18 @@ namespace OpenTK.Platform.Windows
#endregion
void EnableMouseLeaveNotifications()
{
TrackMouseEventStructure tme = new TrackMouseEventStructure();
tme.Size = TrackMouseEventStructure.SizeInBytes;
tme.Flags |= TrackMouseEventFlags.LEAVE;
tme.TrackWindowHandle = child_window.WindowHandle;
tme.HoverTime = -1; // HOVER_DEFAULT
if (!Functions.TrackMouseEvent(ref tme))
Debug.Print("[Error] Failed to enable mouse event tracking. Error: {0}",
Marshal.GetLastWin32Error());
}
#endregion
#region INativeWindow Members
@ -1052,6 +1065,10 @@ namespace OpenTK.Platform.Windows
public event EventHandler<EventArgs> WindowStateChanged;
public event EventHandler<KeyPressEventArgs> KeyPress;
public event EventHandler<EventArgs> MouseEnter;
public event EventHandler<EventArgs> MouseLeave;
#endregion

View file

@ -142,7 +142,8 @@ namespace OpenTK.Platform.X11
window.EventMask = EventMask.StructureNotifyMask | EventMask.SubstructureNotifyMask | EventMask.ExposureMask |
EventMask.KeyReleaseMask | EventMask.KeyPressMask |
EventMask.PointerMotionMask | EventMask.FocusChangeMask |
EventMask.ButtonPressMask | EventMask.ButtonReleaseMask;
EventMask.ButtonPressMask | EventMask.ButtonReleaseMask |
EventMask.EnterWindowMask | EventMask.LeaveWindowMask;
attributes.event_mask = (IntPtr)window.EventMask;
uint mask = (uint)SetWindowValuemask.ColorMap | (uint)SetWindowValuemask.EventMask |
@ -678,6 +679,16 @@ namespace OpenTK.Platform.X11
FocusedChanged(this, EventArgs.Empty);
}
break;
case XEventName.LeaveNotify:
if (MouseLeave != null)
MouseLeave(this, EventArgs.Empty);
break;
case XEventName.EnterNotify:
if (MouseEnter != null)
MouseEnter(this, EventArgs.Empty);
break;
default:
//Debug.WriteLine(String.Format("{0} event was not handled", e.type));
@ -1092,6 +1103,10 @@ namespace OpenTK.Platform.X11
public event EventHandler<EventArgs> WindowStateChanged;
public event EventHandler<KeyPressEventArgs> KeyPress;
public event EventHandler<EventArgs> MouseEnter;
public event EventHandler<EventArgs> MouseLeave;
#endregion