Changed: #947 mouse wheel, resizable flag
This commit is contained in:
parent
db99233b0f
commit
265650262d
1 changed files with 87 additions and 75 deletions
|
@ -52,7 +52,7 @@ void ctor()
|
|||
{
|
||||
// create a pool, cocoa code would leak memory otherwise
|
||||
g_pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
|
||||
// init the application object
|
||||
g_app = [NSApplication sharedApplication];
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ void dtor()
|
|||
/*
|
||||
TODO there might be some more stuff to release ;)
|
||||
*/
|
||||
|
||||
|
||||
// release the pool
|
||||
[g_pool release];
|
||||
}
|
||||
|
@ -78,20 +78,23 @@ bool init(uint windowIcon, emptyProc exitFunc)
|
|||
bool setDisplay(nlWindow wnd, const GfxMode& mode, bool show, bool resizeable)
|
||||
{
|
||||
/*
|
||||
TODO use show and resizable flags
|
||||
TODO use show
|
||||
*/
|
||||
|
||||
/*
|
||||
TODO add menu, on quit send EventDestroyWindowId
|
||||
*/
|
||||
|
||||
|
||||
unsigned int styleMask = NSTitledWindowMask | NSClosableWindowMask |
|
||||
NSMiniaturizableWindowMask;
|
||||
|
||||
if(resizeable)
|
||||
styleMask |= NSResizableWindowMask;
|
||||
|
||||
// create a cocoa window with the size provided by the mode parameter
|
||||
g_window = [[CocoaWindow alloc]
|
||||
g_window = [[CocoaWindow alloc]
|
||||
initWithContentRect:NSMakeRect(0, 0, mode.Width, mode.Height)
|
||||
styleMask:NSTitledWindowMask | NSResizableWindowMask |
|
||||
NSClosableWindowMask | NSMiniaturizableWindowMask
|
||||
backing:NSBackingStoreBuffered
|
||||
defer:NO];
|
||||
styleMask:styleMask backing:NSBackingStoreBuffered defer:NO];
|
||||
|
||||
if(!g_window)
|
||||
nlerror("cannot create window");
|
||||
|
@ -117,7 +120,7 @@ bool setDisplay(nlWindow wnd, const GfxMode& mode, bool show, bool resizeable)
|
|||
// put the settings into a format object
|
||||
NSOpenGLPixelFormat* format =
|
||||
[[NSOpenGLPixelFormat alloc] initWithAttributes:att];
|
||||
|
||||
|
||||
if(!format)
|
||||
nlerror("cannot create NSOpenGLPixelFormat");
|
||||
|
||||
|
@ -160,7 +163,7 @@ bool setDisplay(nlWindow wnd, const GfxMode& mode, bool show, bool resizeable)
|
|||
|
||||
// free the pixel format object
|
||||
[format release];
|
||||
|
||||
|
||||
// further mode setting, like switching to fullscreen and resolution setup
|
||||
setMode(mode);
|
||||
|
||||
|
@ -174,24 +177,24 @@ bool setMode(const GfxMode& mode)
|
|||
{
|
||||
// set the back buffer manually to match the desired rendering resolution
|
||||
GLint dim[2] = { mode.Width, mode.Height };
|
||||
CGLError error = CGLSetParameter((CGLContextObj)[g_glctx CGLContextObj],
|
||||
CGLError error = CGLSetParameter((CGLContextObj)[g_glctx CGLContextObj],
|
||||
kCGLCPSurfaceBackingSize, dim);
|
||||
|
||||
if(error != kCGLNoError)
|
||||
nlerror("cannot set kCGLCPSurfaceBackingSize parameter (%s)",
|
||||
nlerror("cannot set kCGLCPSurfaceBackingSize parameter (%s)",
|
||||
CGLErrorString(error));
|
||||
}
|
||||
|
||||
// leave fullscreen mode, enter windowed mode
|
||||
if(mode.Windowed && [g_glview isInFullScreenMode])
|
||||
{
|
||||
// disable manual setting of back buffer size, cocoa handles this
|
||||
// disable manual setting of back buffer size, cocoa handles this
|
||||
// automatically as soon as the view gets resized
|
||||
CGLError error = CGLDisable((CGLContextObj)[g_glctx CGLContextObj],
|
||||
CGLError error = CGLDisable((CGLContextObj)[g_glctx CGLContextObj],
|
||||
kCGLCESurfaceBackingSize);
|
||||
|
||||
if(error != kCGLNoError)
|
||||
nlerror("cannot disable kCGLCESurfaceBackingSize (%s)",
|
||||
nlerror("cannot disable kCGLCESurfaceBackingSize (%s)",
|
||||
CGLErrorString(error));
|
||||
|
||||
// pull the view back from fullscreen restoring window options
|
||||
|
@ -202,20 +205,20 @@ bool setMode(const GfxMode& mode)
|
|||
else if(!mode.Windowed && ![g_glview isInFullScreenMode])
|
||||
{
|
||||
// enable manual back buffer size for mode setting in fullscreen
|
||||
CGLError error = CGLEnable((CGLContextObj)[g_glctx CGLContextObj],
|
||||
CGLError error = CGLEnable((CGLContextObj)[g_glctx CGLContextObj],
|
||||
kCGLCESurfaceBackingSize);
|
||||
|
||||
if(error != kCGLNoError)
|
||||
nlerror("cannot enable kCGLCESurfaceBackingSize (%s)",
|
||||
nlerror("cannot enable kCGLCESurfaceBackingSize (%s)",
|
||||
CGLErrorString(error));
|
||||
|
||||
// put the view in fullscreen mode, hiding the dock but enabling the menubar
|
||||
// to pop up if the mouse hits the top screen border.
|
||||
// NOTE: withOptions:nil disables <CMD>+<Tab> application switching!
|
||||
[g_glview enterFullScreenMode:[NSScreen mainScreen] withOptions:
|
||||
[g_glview enterFullScreenMode:[NSScreen mainScreen] withOptions:
|
||||
[NSDictionary dictionaryWithObjectsAndKeys:
|
||||
[NSNumber numberWithInt:
|
||||
NSApplicationPresentationHideDock |
|
||||
NSApplicationPresentationHideDock |
|
||||
NSApplicationPresentationAutoHideMenuBar],
|
||||
NSFullScreenModeApplicationPresentationOptions, nil]];
|
||||
|
||||
|
@ -223,8 +226,8 @@ bool setMode(const GfxMode& mode)
|
|||
TODO check if simply using NSView enterFullScreenMode is a good idea.
|
||||
the context can be set to full screen as well, performance differences?
|
||||
*/
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#ifdef UGLY_BACKBUFFER_SIZE_WORKAROUND
|
||||
// due to a back buffer size reading problem, just store the size
|
||||
g_bufferSize[0] = mode.Width;
|
||||
|
@ -238,15 +241,15 @@ void getWindowSize(uint32 &width, uint32 &height)
|
|||
{
|
||||
if(!g_glctx)
|
||||
return;
|
||||
|
||||
|
||||
// A cocoa fullscreen view stays at the native resolution of the display.
|
||||
// When changing the rendering resolution, the size of the back buffer gets
|
||||
// changed, but the view still stays at full resolution. So the scaling of
|
||||
// changed, but the view still stays at full resolution. So the scaling of
|
||||
// the image from the rendered resolution to the view's resolution is done
|
||||
// by cocoa automatically while flushing buffers.
|
||||
// That's why, in fullscreen mode, return the resolution of the back buffer,
|
||||
// not the one from the window.
|
||||
|
||||
|
||||
#ifdef UGLY_BACKBUFFER_SIZE_WORKAROUND
|
||||
// in fullscreen mode
|
||||
if([g_glview isInFullScreenMode])
|
||||
|
@ -270,13 +273,13 @@ void getWindowSize(uint32 &width, uint32 &height)
|
|||
*/
|
||||
// check if manual back buffer sizing is enabled (thats only in fullscreen)
|
||||
GLint surfaceBackingSizeSet = 0;
|
||||
CGLError error = CGLIsEnabled((CGLContextObj)[g_glctx CGLContextObj],
|
||||
CGLError error = CGLIsEnabled((CGLContextObj)[g_glctx CGLContextObj],
|
||||
kCGLCESurfaceBackingSize, &surfaceBackingSizeSet);
|
||||
|
||||
|
||||
if(error != kCGLNoError)
|
||||
nlerror("cannot check kCGLCESurfaceBackingSize state (%s)",
|
||||
nlerror("cannot check kCGLCESurfaceBackingSize state (%s)",
|
||||
CGLErrorString(error));
|
||||
|
||||
|
||||
// if in fullscreen mode (only in fullscreen back buffer sizing is used)
|
||||
if(surfaceBackingSizeSet)
|
||||
{
|
||||
|
@ -285,18 +288,18 @@ void getWindowSize(uint32 &width, uint32 &height)
|
|||
*/
|
||||
// get the back buffer size
|
||||
GLint dim[2];
|
||||
CGLError error = CGLGetParameter((CGLContextObj)[g_glctx CGLContextObj],
|
||||
CGLError error = CGLGetParameter((CGLContextObj)[g_glctx CGLContextObj],
|
||||
kCGLCPSurfaceBackingSize, dim);
|
||||
|
||||
|
||||
if(error != kCGLNoError)
|
||||
nlerror("cannot get kCGLCPSurfaceBackingSize value (%s)",
|
||||
nlerror("cannot get kCGLCPSurfaceBackingSize value (%s)",
|
||||
CGLErrorString(error));
|
||||
|
||||
|
||||
// put size into ref params
|
||||
width = dim[0];
|
||||
height = dim[1];
|
||||
}
|
||||
|
||||
|
||||
// if in windowed mode
|
||||
else
|
||||
{
|
||||
|
@ -334,7 +337,7 @@ void setWindowPos(uint32 x, uint32 y)
|
|||
NSRect windowRect = [g_window frame];
|
||||
|
||||
// convert y from NeL coordinates to cocoa coordinates
|
||||
y = screenRect.size.height - y;
|
||||
y = screenRect.size.height - y;
|
||||
|
||||
// tell cocoa to move the window
|
||||
[g_window setFrameTopLeftPoint:NSMakePoint(x, y)];
|
||||
|
@ -365,9 +368,9 @@ void showCursor(bool b)
|
|||
// by only calling hide if the cursor is visible and only calling show if
|
||||
// the cursor was hidden.
|
||||
|
||||
CGDisplayErr error = kCGErrorSuccess;
|
||||
CGDisplayErr error = kCGErrorSuccess;
|
||||
static bool visible = true;
|
||||
|
||||
|
||||
if(b && !visible)
|
||||
{
|
||||
error = CGDisplayShowCursor(kCGDirectMainDisplay);
|
||||
|
@ -378,17 +381,17 @@ void showCursor(bool b)
|
|||
error = CGDisplayHideCursor(kCGDirectMainDisplay);
|
||||
visible = false;
|
||||
}
|
||||
|
||||
|
||||
if(error != kCGErrorSuccess)
|
||||
nlerror("cannot capture / un-capture cursor");
|
||||
}
|
||||
|
||||
void setMousePos(float x, float y)
|
||||
void setMousePos(float x, float y)
|
||||
{
|
||||
/*
|
||||
TODO FIXME for windows placed on non primary monitor
|
||||
*/
|
||||
|
||||
|
||||
// CG wants absolute coordinates related to screen top left
|
||||
CGFloat fromScreenLeft = 0.0;
|
||||
CGFloat fromScreenTop = 0.0;
|
||||
|
@ -409,11 +412,11 @@ void setMousePos(float x, float y)
|
|||
fromScreenLeft = windowRect.origin.x;
|
||||
|
||||
// TODO this code assumes, that the view fills the window
|
||||
|
||||
|
||||
// map window bottom to view top
|
||||
fromScreenTop = screenRect.size.height -
|
||||
fromScreenTop = screenRect.size.height -
|
||||
viewRect.size.height - windowRect.origin.y;
|
||||
}
|
||||
}
|
||||
|
||||
// position inside the view
|
||||
fromScreenLeft += (viewRect.size.width * x);
|
||||
|
@ -547,8 +550,8 @@ NLMISC::TKey virtualKeycodeToNelKey(unsigned short keycode)
|
|||
case kVK_RightArrow: return NLMISC::KeyRIGHT;
|
||||
case kVK_DownArrow: return NLMISC::KeyDOWN;
|
||||
case kVK_UpArrow: return NLMISC::KeyUP;
|
||||
case kVK_Command:break;
|
||||
case kVK_Option:break;
|
||||
case kVK_Command:break;
|
||||
case kVK_Option:break;
|
||||
case kVK_RightOption:break;
|
||||
case kVK_Function:break;
|
||||
case kVK_VolumeUp:break;
|
||||
|
@ -597,33 +600,33 @@ bool isTextKeyEvent(NSEvent* event)
|
|||
|
||||
// get the character reported by cocoa
|
||||
unsigned int character = [[event characters] characterAtIndex:0];
|
||||
|
||||
|
||||
// printable ascii characters
|
||||
if(isprint(character))
|
||||
return true;
|
||||
|
||||
|
||||
/*
|
||||
TODO check why iswprint(character) does not solve it.
|
||||
TODO check why iswprint(character) does not solve it.
|
||||
it always returns false, even for π, é, ...
|
||||
*/
|
||||
// characters > 127 but not printable
|
||||
if( nelKey == NLMISC::KeyF1 || nelKey == NLMISC::KeyF2 ||
|
||||
nelKey == NLMISC::KeyF3 || nelKey == NLMISC::KeyF4 ||
|
||||
nelKey == NLMISC::KeyF5 || nelKey == NLMISC::KeyF6 ||
|
||||
nelKey == NLMISC::KeyF7 || nelKey == NLMISC::KeyF8 ||
|
||||
if( nelKey == NLMISC::KeyF1 || nelKey == NLMISC::KeyF2 ||
|
||||
nelKey == NLMISC::KeyF3 || nelKey == NLMISC::KeyF4 ||
|
||||
nelKey == NLMISC::KeyF5 || nelKey == NLMISC::KeyF6 ||
|
||||
nelKey == NLMISC::KeyF7 || nelKey == NLMISC::KeyF8 ||
|
||||
nelKey == NLMISC::KeyF9 || nelKey == NLMISC::KeyF10 ||
|
||||
nelKey == NLMISC::KeyF11 || nelKey == NLMISC::KeyF12 ||
|
||||
nelKey == NLMISC::KeyF13 || nelKey == NLMISC::KeyF14 ||
|
||||
nelKey == NLMISC::KeyF15 || nelKey == NLMISC::KeyF16 ||
|
||||
nelKey == NLMISC::KeyF17 || nelKey == NLMISC::KeyF18 ||
|
||||
nelKey == NLMISC::KeyF11 || nelKey == NLMISC::KeyF12 ||
|
||||
nelKey == NLMISC::KeyF13 || nelKey == NLMISC::KeyF14 ||
|
||||
nelKey == NLMISC::KeyF15 || nelKey == NLMISC::KeyF16 ||
|
||||
nelKey == NLMISC::KeyF17 || nelKey == NLMISC::KeyF18 ||
|
||||
nelKey == NLMISC::KeyF19 || nelKey == NLMISC::KeyF20 ||
|
||||
nelKey == NLMISC::KeyUP || nelKey == NLMISC::KeyDOWN ||
|
||||
nelKey == NLMISC::KeyUP || nelKey == NLMISC::KeyDOWN ||
|
||||
nelKey == NLMISC::KeyLEFT || nelKey == NLMISC::KeyRIGHT ||
|
||||
nelKey == NLMISC::KeyHOME || nelKey == NLMISC::KeyEND ||
|
||||
nelKey == NLMISC::KeyPRIOR || nelKey == NLMISC::KeyNEXT ||
|
||||
nelKey == NLMISC::KeyDELETE)
|
||||
return false;
|
||||
|
||||
|
||||
// all the fancy wide characters
|
||||
if(character > 127)
|
||||
return true;
|
||||
|
@ -716,15 +719,15 @@ void submitEvents(NLMISC::CEventServer& server,
|
|||
TODO modifiers with mouse events
|
||||
*/
|
||||
NLMISC::CEvent* nelEvent;
|
||||
|
||||
// when emulating raw mode, send the delta in a CGDMouseMove event
|
||||
|
||||
// when emulating raw mode, send the delta in a CGDMouseMove event
|
||||
if(g_emulateRawMode)
|
||||
nelEvent = new NLMISC::CGDMouseMove(
|
||||
eventEmitter, NULL /* no mouse device */, event.deltaX, -event.deltaY);
|
||||
|
||||
// normally send position in a CEventMouseMove
|
||||
else
|
||||
nelEvent = new NLMISC::CEventMouseMove(mouseX, mouseY,
|
||||
nelEvent = new NLMISC::CEventMouseMove(mouseX, mouseY,
|
||||
(NLMISC::TMouseButton)0 /* modifiers */, eventEmitter);
|
||||
|
||||
|
||||
|
@ -738,14 +741,14 @@ void submitEvents(NLMISC::CEventServer& server,
|
|||
*/
|
||||
NLMISC::CEvent* nelEvent;
|
||||
|
||||
// when emulating raw mode, send the delta in a CGDMouseMove event
|
||||
// when emulating raw mode, send the delta in a CGDMouseMove event
|
||||
if(g_emulateRawMode)
|
||||
nelEvent = new NLMISC::CGDMouseMove(
|
||||
eventEmitter, NULL /* no mouse device */, event.deltaX, -event.deltaY);
|
||||
|
||||
// normally send position in a CEventMouseMove
|
||||
else
|
||||
nelEvent = new NLMISC::CEventMouseMove(mouseX, mouseY,
|
||||
nelEvent = new NLMISC::CEventMouseMove(mouseX, mouseY,
|
||||
NLMISC::leftButton /* modifiers */, eventEmitter);
|
||||
|
||||
server.postEvent(nelEvent);
|
||||
|
@ -758,14 +761,14 @@ void submitEvents(NLMISC::CEventServer& server,
|
|||
*/
|
||||
NLMISC::CEvent* nelEvent;
|
||||
|
||||
// when emulating raw mode, send the delta in a CGDMouseMove event
|
||||
// when emulating raw mode, send the delta in a CGDMouseMove event
|
||||
if(g_emulateRawMode)
|
||||
nelEvent = new NLMISC::CGDMouseMove(
|
||||
eventEmitter, NULL /* no mouse device */, event.deltaX, -event.deltaY);
|
||||
|
||||
// normally send position in a CEventMouseMove
|
||||
else
|
||||
nelEvent = new NLMISC::CEventMouseMove(mouseX, mouseY,
|
||||
nelEvent = new NLMISC::CEventMouseMove(mouseX, mouseY,
|
||||
NLMISC::rightButton /* modifiers */, eventEmitter);
|
||||
|
||||
server.postEvent(nelEvent);
|
||||
|
@ -777,13 +780,13 @@ void submitEvents(NLMISC::CEventServer& server,
|
|||
{
|
||||
// push the key press event to the event server
|
||||
server.postEvent(new NLMISC::CEventKeyDown(
|
||||
virtualKeycodeToNelKey([event keyCode]),
|
||||
modifierFlagsToNelKeyButton([event modifierFlags]),
|
||||
[event isARepeat] == NO,
|
||||
virtualKeycodeToNelKey([event keyCode]),
|
||||
modifierFlagsToNelKeyButton([event modifierFlags]),
|
||||
[event isARepeat] == NO,
|
||||
eventEmitter));
|
||||
|
||||
|
||||
// if this was a text event
|
||||
if(isTextKeyEvent(event))
|
||||
if(isTextKeyEvent(event))
|
||||
{
|
||||
ucstring ucstr;
|
||||
|
||||
|
@ -792,8 +795,8 @@ void submitEvents(NLMISC::CEventServer& server,
|
|||
|
||||
// push the text event to event server as well
|
||||
server.postEvent(new NLMISC::CEventChar(
|
||||
ucstr[0],
|
||||
NLMISC::noKeyButton,
|
||||
ucstr[0],
|
||||
NLMISC::noKeyButton,
|
||||
eventEmitter));
|
||||
}
|
||||
break;
|
||||
|
@ -802,8 +805,8 @@ void submitEvents(NLMISC::CEventServer& server,
|
|||
{
|
||||
// push the key release event to the event server
|
||||
server.postEvent(new NLMISC::CEventKeyUp(
|
||||
virtualKeycodeToNelKey([event keyCode]),
|
||||
modifierFlagsToNelKeyButton([event modifierFlags]),
|
||||
virtualKeycodeToNelKey([event keyCode]),
|
||||
modifierFlagsToNelKeyButton([event modifierFlags]),
|
||||
eventEmitter));
|
||||
break;
|
||||
}
|
||||
|
@ -813,7 +816,16 @@ void submitEvents(NLMISC::CEventServer& server,
|
|||
case NSApplicationDefined:break;
|
||||
case NSPeriodic:break;
|
||||
case NSCursorUpdate:break;
|
||||
case NSScrollWheel:break;
|
||||
case NSScrollWheel:
|
||||
{
|
||||
/*
|
||||
TODO modifiers with mouse events
|
||||
*/
|
||||
server.postEvent(new NLMISC::CEventMouseWheel(
|
||||
mouseX, mouseY, (NLMISC::TMouseButton)0 /* modifiers */,
|
||||
(event.deltaY > 0), eventEmitter));
|
||||
break;
|
||||
}
|
||||
case NSTabletPoint:break;
|
||||
case NSTabletProximity:break;
|
||||
case NSOtherMouseDown:break;
|
||||
|
|
Loading…
Reference in a new issue