Setup listening for window events.

This commit is contained in:
Olle Håkansson 2014-04-19 12:17:14 +02:00 committed by thefiddler
parent 5e1b7c82ab
commit 6c6beae4fc
2 changed files with 56 additions and 3 deletions

View file

@ -5,9 +5,21 @@ namespace OpenTK.Platform.MacOS
{
static class Class
{
[DllImport (Cocoa.LibObjC)]
extern static IntPtr class_getName(IntPtr handle);
[DllImport (Cocoa.LibObjC)]
extern static bool class_addMethod(IntPtr classHandle, IntPtr selector, IntPtr method, string types);
[DllImport (Cocoa.LibObjC)]
extern static IntPtr objc_getClass(string name);
[DllImport (Cocoa.LibObjC)]
extern static IntPtr objc_allocateClassPair(IntPtr parentClass, string name, int extraBytes);
[DllImport (Cocoa.LibObjC)]
extern static void objc_registerClassPair(IntPtr classToRegister);
public static IntPtr Get(string name)
{
var id = objc_getClass(name);
@ -17,5 +29,29 @@ namespace OpenTK.Platform.MacOS
}
return id;
}
public static IntPtr AllocateClass(string className, string parentClass)
{
return objc_allocateClassPair(Get(parentClass), className, 0);
}
public static void RegisterClass(IntPtr handle)
{
objc_registerClassPair(handle);
}
public static void RegisterMethod(IntPtr handle, Delegate d, string selector, string typeString)
{
// TypeString info:
// https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html
IntPtr p = Marshal.GetFunctionPointerForDelegate(d);
bool r = class_addMethod(handle, Selector.Get(selector), p, typeString);
if (!r)
{
throw new ArgumentException("Could not register method " + d + " in class + " + class_getName(handle));
}
}
}
}

View file

@ -1,5 +1,6 @@
using System;
using OpenTK.Graphics;
using System.Drawing;
namespace OpenTK.Platform.MacOS
{
@ -22,8 +23,6 @@ namespace OpenTK.Platform.MacOS
public event System.EventHandler<System.EventArgs> MouseLeave;
public event System.EventHandler<System.EventArgs> MouseEnter;
private CocoaWindowInfo windowInfo;
static readonly IntPtr nextEventMatchingMask = Selector.Get("nextEventMatchingMask:untilDate:inMode:dequeue:");
static readonly IntPtr sendEvent = Selector.Get("sendEvent:");
static readonly IntPtr updateWindows = Selector.Get("updateWindows");
@ -36,17 +35,28 @@ namespace OpenTK.Platform.MacOS
NSDefaultRunLoopMode = Cocoa.GetStringConstant(Cocoa.FoundationLibrary, "NSDefaultRunLoopMode");
}
private CocoaWindowInfo windowInfo;
private IntPtr windowClass;
public CocoaNativeWindow(int x, int y, int width, int height, string title, GraphicsMode mode, GameWindowFlags options, DisplayDevice device)
{
// Create the window class
windowClass = Class.AllocateClass("OpenTKWindow", "NSWindow");
Class.RegisterMethod(windowClass, new WindowDidResizeDelegate(WindowDidResize), "windowDidResize:", "v@:@");
Class.RegisterClass(windowClass);
// Create window instance
var contentRect = new System.Drawing.RectangleF(x, y, width, height);
var style = NSWindowStyle.Titled | NSWindowStyle.Resizable;
var bufferingType = NSBackingStore.Buffered;
IntPtr windowPtr;
windowPtr = Cocoa.SendIntPtr(Class.Get("NSWindow"), Selector.Alloc);
windowPtr = Cocoa.SendIntPtr(windowClass, Selector.Alloc);
windowPtr = Cocoa.SendIntPtr(windowPtr, Selector.Get("initWithContentRect:styleMask:backing:defer:"), contentRect, (int)style, (int)bufferingType, false);
windowPtr = Cocoa.SendIntPtr(windowPtr, Selector.Autorelease);
// Set up behavior
Cocoa.SendIntPtr(windowPtr, Selector.Get("setDelegate:"), windowPtr); // The window class acts as its own delegate
Cocoa.SendVoid(windowPtr, Selector.Get("cascadeTopLeftFromPoint:"), new System.Drawing.PointF(20, 20));
Cocoa.SendVoid(windowPtr, Selector.Get("setTitle:"), Cocoa.ToNative(title));
Cocoa.SendVoid(windowPtr, Selector.Get("makeKeyAndOrderFront:"), IntPtr.Zero);
@ -54,6 +64,13 @@ namespace OpenTK.Platform.MacOS
windowInfo = new CocoaWindowInfo(windowPtr);
}
delegate void WindowDidResizeDelegate(IntPtr self, IntPtr cmd, IntPtr notification);
void WindowDidResize(IntPtr self, IntPtr cmd, IntPtr notification)
{
GraphicsContext.CurrentContext.Update(windowInfo);
}
public static IntPtr GetView(IntPtr windowHandle)
{
return Cocoa.SendIntPtr(windowHandle, contentView);