MacOS: Implement mouse enter / leave events.

This commit is contained in:
kanato 2009-11-15 03:55:29 +00:00
parent 52e89c13b1
commit 103190ebf4
2 changed files with 109 additions and 8 deletions

View file

@ -11,6 +11,8 @@ using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Diagnostics; using System.Diagnostics;
using System.Drawing; using System.Drawing;
using EventTime = System.Double;
namespace OpenTK.Platform.MacOS.Carbon namespace OpenTK.Platform.MacOS.Carbon
{ {
@ -121,6 +123,13 @@ namespace OpenTK.Platform.MacOS.Carbon
#region --- Types defined in CarbonEvents.h --- #region --- Types defined in CarbonEvents.h ---
enum EventAttributes : uint
{
kEventAttributeNone = 0,
kEventAttributeUserEvent = (1 << 0),
kEventAttributeMonitored = 1 << 3,
}
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
internal struct EventTypeSpec internal struct EventTypeSpec
{ {
@ -238,6 +247,8 @@ namespace OpenTK.Platform.MacOS.Carbon
internal enum EventParamName : int internal enum EventParamName : int
{ {
WindowRef = 0x77696e64, // typeWindowRef,
// Mouse Events // Mouse Events
MouseLocation = 0x6d6c6f63, // typeHIPoint MouseLocation = 0x6d6c6f63, // typeHIPoint
WindowMouseLocation = 0x776d6f75, // typeHIPoint WindowMouseLocation = 0x776d6f75, // typeHIPoint
@ -255,6 +266,8 @@ namespace OpenTK.Platform.MacOS.Carbon
} }
internal enum EventParamType : int internal enum EventParamType : int
{ {
typeWindowRef = 0x77696e64,
typeMouseButton = 0x6d62746e, typeMouseButton = 0x6d62746e,
typeMouseWheelAxis = 0x6d776178, typeMouseWheelAxis = 0x6d776178,
typeHIPoint = 0x68697074, typeHIPoint = 0x68697074,
@ -409,7 +422,7 @@ namespace OpenTK.Platform.MacOS.Carbon
ScreenPixel = 2, ScreenPixel = 2,
Window = 3, Window = 3,
View = 4 View = 4
}; };
#region --- Carbon API Methods --- #region --- Carbon API Methods ---
@ -502,6 +515,12 @@ namespace OpenTK.Platform.MacOS.Carbon
[DllImport(carbon)] [DllImport(carbon)]
static extern void ReleaseEvent(IntPtr theEvent); static extern void ReleaseEvent(IntPtr theEvent);
internal static void SendEvent(IntPtr theEvent)
{
IntPtr theTarget = GetEventDispatcherTarget();
SendEventToEventTarget(theEvent, theTarget);
}
// Processes events in the queue and then returns. // Processes events in the queue and then returns.
internal static void ProcessEvents() internal static void ProcessEvents()
{ {
@ -572,6 +591,26 @@ namespace OpenTK.Platform.MacOS.Carbon
#endregion #endregion
#region --- Getting Event Parameters --- #region --- Getting Event Parameters ---
[DllImport(carbon,EntryPoint="CreateEvent")]
static extern OSStatus _CreateEvent( IntPtr inAllocator,
EventClass inClassID, UInt32 kind, EventTime when,
EventAttributes flags,out IntPtr outEvent);
internal static IntPtr CreateWindowEvent(WindowEventKind kind)
{
IntPtr retval;
OSStatus stat = _CreateEvent(IntPtr.Zero, EventClass.Window, (uint)kind,
0, EventAttributes.kEventAttributeNone, out retval);
if (stat != OSStatus.NoError)
{
throw new MacOSException(stat);
}
return retval;
}
[DllImport(carbon)] [DllImport(carbon)]
static extern OSStatus GetEventParameter( static extern OSStatus GetEventParameter(
IntPtr inEvent, EventParamName inName, EventParamType inDesiredType, IntPtr inEvent, EventParamName inName, EventParamType inDesiredType,
@ -678,6 +717,24 @@ namespace OpenTK.Platform.MacOS.Carbon
} }
} }
static internal OSStatus GetEventWindowRef(IntPtr inEvent, out IntPtr windowRef)
{
IntPtr retval;
unsafe
{
IntPtr* parm = &retval;
OSStatus result = API.GetEventParameter(inEvent,
EventParamName.WindowRef, EventParamType.typeWindowRef, IntPtr.Zero,
(uint)sizeof(IntPtr), IntPtr.Zero, (IntPtr)parm);
windowRef = retval;
return result;
}
}
static internal OSStatus GetEventMouseLocation(IntPtr inEvent, out HIPoint pt) static internal OSStatus GetEventMouseLocation(IntPtr inEvent, out HIPoint pt)
{ {
HIPoint point; HIPoint point;

View file

@ -66,6 +66,8 @@ namespace OpenTK.Platform.MacOS
KeyPressEventArgs mKeyPressArgs = new KeyPressEventArgs((char)0); KeyPressEventArgs mKeyPressArgs = new KeyPressEventArgs((char)0);
bool mMouseIn = false;
#endregion #endregion
#region AGL Device Hack #region AGL Device Hack
@ -421,12 +423,13 @@ namespace OpenTK.Platform.MacOS
System.Diagnostics.Debug.Assert(evt.EventClass == EventClass.Mouse); System.Diagnostics.Debug.Assert(evt.EventClass == EventClass.Mouse);
MouseButton button = MouseButton.Primary; MouseButton button = MouseButton.Primary;
HIPoint pt = new HIPoint(); HIPoint pt = new HIPoint();
HIPoint screenLoc = new HIPoint();
OSStatus err; OSStatus err = API.GetEventMouseLocation(inEvent, out screenLoc);
if (this.windowState == WindowState.Fullscreen) if (this.windowState == WindowState.Fullscreen)
{ {
err = API.GetEventMouseLocation(inEvent, out pt); pt = screenLoc;
} }
else else
{ {
@ -442,6 +445,17 @@ namespace OpenTK.Platform.MacOS
} }
} }
Point mousePosInClient = new Point((int)pt.X, (int)pt.Y);
if (this.windowState != WindowState.Fullscreen)
{
mousePosInClient.Y -= mTitlebarHeight;
}
// check for enter/leave events
IntPtr thisEventWindow;
API.GetEventWindowRef(inEvent, out thisEventWindow);
CheckEnterLeaveEvents(thisEventWindow, mousePosInClient);
switch (evt.MouseEventKind) switch (evt.MouseEventKind)
{ {
case MouseEventKind.MouseDown: case MouseEventKind.MouseDown:
@ -497,11 +511,11 @@ namespace OpenTK.Platform.MacOS
case MouseEventKind.MouseMoved: case MouseEventKind.MouseMoved:
case MouseEventKind.MouseDragged: case MouseEventKind.MouseDragged:
//Debug.Print("Mouse Location: {0}, {1}", pt.X, pt.Y);
if (this.windowState == WindowState.Fullscreen) if (this.windowState == WindowState.Fullscreen)
{ {
Point mousePosInClient = new Point((int)pt.X, (int)pt.Y);
if (mousePosInClient.X != InputDriver.Mouse[0].X || if (mousePosInClient.X != InputDriver.Mouse[0].X ||
mousePosInClient.Y != InputDriver.Mouse[0].Y) mousePosInClient.Y != InputDriver.Mouse[0].Y)
{ {
@ -511,11 +525,9 @@ namespace OpenTK.Platform.MacOS
else else
{ {
// ignore clicks in the title bar // ignore clicks in the title bar
if (pt.Y < mTitlebarHeight) if (pt.Y < 0)
return OSStatus.EventNotHandled; return OSStatus.EventNotHandled;
Point mousePosInClient = new Point((int)pt.X, (int)(pt.Y - mTitlebarHeight));
if (mousePosInClient.X != InputDriver.Mouse[0].X || if (mousePosInClient.X != InputDriver.Mouse[0].X ||
mousePosInClient.Y != InputDriver.Mouse[0].Y) mousePosInClient.Y != InputDriver.Mouse[0].Y)
{ {
@ -532,6 +544,24 @@ namespace OpenTK.Platform.MacOS
} }
} }
private void CheckEnterLeaveEvents(IntPtr eventWindowRef, Point pt)
{
bool thisIn = eventWindowRef == window.WindowRef;
if (pt.Y < 0)
thisIn = false;
if (thisIn != mMouseIn)
{
mMouseIn = thisIn;
if (mMouseIn)
OnMouseEnter();
else
OnMouseLeave();
}
}
private static void GetCharCodes(IntPtr inEvent, out MacOSKeyCode code, out char charCode) private static void GetCharCodes(IntPtr inEvent, out MacOSKeyCode code, out char charCode)
{ {
code = API.GetEventKeyboardKeyCode(inEvent); code = API.GetEventKeyboardKeyCode(inEvent);
@ -984,6 +1014,20 @@ namespace OpenTK.Platform.MacOS
Closed(this, EventArgs.Empty); Closed(this, EventArgs.Empty);
} }
private void OnMouseLeave()
{
if (MouseLeave != null)
MouseLeave(this, EventArgs.Empty);
}
private void OnMouseEnter()
{
if (MouseEnter != null)
MouseEnter(this, EventArgs.Empty);
}
#endregion #endregion
public event EventHandler<EventArgs> Idle; public event EventHandler<EventArgs> Idle;