Changed: #947 added fullscreen and mode switching support
This commit is contained in:
parent
76c34e285d
commit
23cbfdbb60
5 changed files with 254 additions and 49 deletions
|
@ -1594,8 +1594,7 @@ bool CDriverGL::setMode(const GfxMode& mode)
|
||||||
_FullScreen = !mode.Windowed;
|
_FullScreen = !mode.Windowed;
|
||||||
|
|
||||||
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
|
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
|
||||||
# warning "OpenGL Driver: Missing Mac Implementation"
|
NL3D::MAC::setMode(mode);
|
||||||
nlwarning("OpenGL Driver: Missing Mac Implementation");
|
|
||||||
#elif defined(NL_OS_UNIX)
|
#elif defined(NL_OS_UNIX)
|
||||||
|
|
||||||
#ifdef XF86VIDMODE
|
#ifdef XF86VIDMODE
|
||||||
|
|
|
@ -55,6 +55,9 @@ bool init(uint windowIcon = 0, emptyProc exitFunc = 0);
|
||||||
/// mac specific stuff while calling CDriverGL::setDisplay()
|
/// mac specific stuff while calling CDriverGL::setDisplay()
|
||||||
bool setDisplay(nlWindow wnd, const GfxMode& mode, bool show, bool resizeable);
|
bool setDisplay(nlWindow wnd, const GfxMode& mode, bool show, bool resizeable);
|
||||||
|
|
||||||
|
/// mac specific stuff while calling CDriverGL::setMode()
|
||||||
|
bool setMode(const GfxMode& mode);
|
||||||
|
|
||||||
/// mac specific stuff while calling CDriverGL::getWindowSize()
|
/// mac specific stuff while calling CDriverGL::getWindowSize()
|
||||||
void getWindowSize(uint32 &width, uint32 &height);
|
void getWindowSize(uint32 &width, uint32 &height);
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
#include "cocoa_opengl_view.h"
|
#include "cocoa_opengl_view.h"
|
||||||
#include "cocoa_window.h"
|
#include "cocoa_window.h"
|
||||||
|
|
||||||
// virtual key codes are only defined here. we still do not need to link carbon
|
// Virtual key codes are only defined here. We still do not need to link carbon.
|
||||||
// see: http://lists.apple.com/archives/Cocoa-dev/2009/May/msg01180.html
|
// see: http://lists.apple.com/archives/Cocoa-dev/2009/May/msg01180.html
|
||||||
#include <Carbon/Carbon.h>
|
#include <Carbon/Carbon.h>
|
||||||
|
|
||||||
|
@ -33,16 +33,20 @@
|
||||||
|
|
||||||
namespace NL3D { namespace MAC {
|
namespace NL3D { namespace MAC {
|
||||||
|
|
||||||
static NSApplication* g_app = 0;
|
static NSApplication* g_app = nil;
|
||||||
static NSAutoreleasePool* g_pool = 0;
|
static NSAutoreleasePool* g_pool = nil;
|
||||||
static CocoaWindow* g_window = 0;
|
static CocoaWindow* g_window = nil;
|
||||||
static CocoaOpenGLView* g_glview = 0;
|
static CocoaOpenGLView* g_glview = nil;
|
||||||
static NSOpenGLContext* g_glctx = 0;
|
static NSOpenGLContext* g_glctx = nil;
|
||||||
|
|
||||||
|
#define UGLY_BACKBUFFER_SIZE_WORKAROUND
|
||||||
|
|
||||||
|
#ifdef UGLY_BACKBUFFER_SIZE_WORKAROUND
|
||||||
|
static int g_bufferSize[2];
|
||||||
|
#endif
|
||||||
|
|
||||||
void ctor()
|
void ctor()
|
||||||
{
|
{
|
||||||
nldebug("mac cpp bridge called");
|
|
||||||
|
|
||||||
// create a pool, cocoa code would leak memory otherwise
|
// create a pool, cocoa code would leak memory otherwise
|
||||||
g_pool = [[NSAutoreleasePool alloc] init];
|
g_pool = [[NSAutoreleasePool alloc] init];
|
||||||
|
|
||||||
|
@ -52,7 +56,9 @@ void ctor()
|
||||||
|
|
||||||
void dtor()
|
void dtor()
|
||||||
{
|
{
|
||||||
nldebug("mac cpp bridge called");
|
/*
|
||||||
|
TODO there might be some more stuff to release ;)
|
||||||
|
*/
|
||||||
|
|
||||||
// release the pool
|
// release the pool
|
||||||
[g_pool release];
|
[g_pool release];
|
||||||
|
@ -60,32 +66,40 @@ void dtor()
|
||||||
|
|
||||||
bool init(uint windowIcon, emptyProc exitFunc)
|
bool init(uint windowIcon, emptyProc exitFunc)
|
||||||
{
|
{
|
||||||
nldebug("mac cpp bridge called with %u %u", windowIcon, exitFunc);
|
/*
|
||||||
|
TODO nothing to do here? split other stuff to match api cleanly.
|
||||||
|
*/
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool setDisplay(nlWindow wnd, const GfxMode& mode, bool show, bool resizeable)
|
bool setDisplay(nlWindow wnd, const GfxMode& mode, bool show, bool resizeable)
|
||||||
{
|
{
|
||||||
nldebug("mac cpp bridge called with %u %u %u %u", wnd, &mode, show, resizeable);
|
// create a cocoa window with the size provided by the mode parameter
|
||||||
|
g_window = [[CocoaWindow alloc]
|
||||||
// create a window
|
initWithContentRect:NSMakeRect(0, 0, mode.Width, mode.Height)
|
||||||
/* TODO: NSBackingStoreBuffered ??? */
|
|
||||||
g_window = [[CocoaWindow alloc] initWithContentRect:NSMakeRect(0, 0, 1024, 768)
|
|
||||||
styleMask:NSTitledWindowMask | NSResizableWindowMask |
|
styleMask:NSTitledWindowMask | NSResizableWindowMask |
|
||||||
NSClosableWindowMask | NSMiniaturizableWindowMask
|
NSClosableWindowMask | NSMiniaturizableWindowMask
|
||||||
backing:NSBackingStoreBuffered
|
backing:NSBackingStoreBuffered
|
||||||
defer:NO];
|
defer:NO];
|
||||||
|
|
||||||
|
if(!g_window)
|
||||||
|
nlerror("cannot create window");
|
||||||
|
|
||||||
|
/*
|
||||||
|
TODO use mode.Depth
|
||||||
|
TODO NSOpenGLPFAOffScreen
|
||||||
|
*/
|
||||||
// setup opengl settings
|
// setup opengl settings
|
||||||
NSOpenGLPixelFormatAttribute att[] =
|
NSOpenGLPixelFormatAttribute att[] =
|
||||||
{
|
{
|
||||||
NSOpenGLPFAWindow,
|
|
||||||
NSOpenGLPFADoubleBuffer,
|
NSOpenGLPFADoubleBuffer,
|
||||||
NSOpenGLPFAColorSize, 24,
|
NSOpenGLPFAColorSize, 24,
|
||||||
NSOpenGLPFAAlphaSize, 8,
|
NSOpenGLPFADepthSize, 24,
|
||||||
NSOpenGLPFADepthSize, 24,
|
NSOpenGLPFAAlphaSize, 8,
|
||||||
|
NSOpenGLPFAStencilSize, 8,
|
||||||
NSOpenGLPFANoRecovery,
|
NSOpenGLPFANoRecovery,
|
||||||
NSOpenGLPFAAccelerated,
|
NSOpenGLPFAAccelerated,
|
||||||
|
NSOpenGLPFABackingStore,
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -93,60 +107,227 @@ bool setDisplay(nlWindow wnd, const GfxMode& mode, bool show, bool resizeable)
|
||||||
NSOpenGLPixelFormat* format =
|
NSOpenGLPixelFormat* format =
|
||||||
[[NSOpenGLPixelFormat alloc] initWithAttributes:att];
|
[[NSOpenGLPixelFormat alloc] initWithAttributes:att];
|
||||||
|
|
||||||
|
if(!format)
|
||||||
|
nlerror("cannot create NSOpenGLPixelFormat");
|
||||||
|
|
||||||
// create a opengl view with the created format
|
// create a opengl view with the created format
|
||||||
g_glview = [[CocoaOpenGLView alloc]
|
g_glview = [[CocoaOpenGLView alloc]
|
||||||
initWithFrame:NSMakeRect(0, 0, 1024, 768) pixelFormat: format];
|
initWithFrame:NSMakeRect(0, 0, 0, 0) pixelFormat: format];
|
||||||
|
|
||||||
|
if(!g_glview)
|
||||||
|
nlerror("cannot create view");
|
||||||
|
|
||||||
|
// put the view into the window
|
||||||
|
[g_window setContentView:g_glview];
|
||||||
|
|
||||||
|
// set the window to non transparent
|
||||||
|
[g_window setOpaque:YES];
|
||||||
|
|
||||||
|
// enable mouse move events, NeL wants them
|
||||||
|
[g_window setAcceptsMouseMovedEvents:YES];
|
||||||
|
|
||||||
// create a opengl context for the view
|
// create a opengl context for the view
|
||||||
g_glctx = [g_glview openGLContext];
|
g_glctx = [g_glview openGLContext];
|
||||||
|
|
||||||
// setup some stuff in the window
|
if(!g_glctx)
|
||||||
[g_window setContentView:g_glview];
|
nlerror("cannot create context");
|
||||||
[g_window makeKeyAndOrderFront:nil];
|
|
||||||
[g_window setAcceptsMouseMovedEvents:YES];
|
|
||||||
|
|
||||||
// make the views opengl context the currrent one
|
// make the views opengl context the currrent one
|
||||||
[g_glctx makeCurrentContext];
|
[g_glctx makeCurrentContext];
|
||||||
|
|
||||||
|
// put the window to the front and make it the key window
|
||||||
|
[g_window makeKeyAndOrderFront:nil];
|
||||||
|
|
||||||
// tell the application that we are running now
|
// tell the application that we are running now
|
||||||
[g_app finishLaunching];
|
[g_app finishLaunching];
|
||||||
|
|
||||||
// free the pixel format object
|
// free the pixel format object
|
||||||
[format release];
|
[format release];
|
||||||
|
|
||||||
|
// further mode setting, like switching to fullscreen and resolution setup
|
||||||
|
setMode(mode);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool setMode(const GfxMode& mode)
|
||||||
|
{
|
||||||
|
// for fullscreen mode, adjust the back buffer size to the desired resolution
|
||||||
|
if(!mode.Windowed)
|
||||||
|
{
|
||||||
|
// 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],
|
||||||
|
kCGLCPSurfaceBackingSize, dim);
|
||||||
|
|
||||||
|
if(error != kCGLNoError)
|
||||||
|
nlerror("cannot set kCGLCPSurfaceBackingSize parameter (%s)",
|
||||||
|
CGLErrorString(error));
|
||||||
|
}
|
||||||
|
|
||||||
|
// leave fullscreen mode, enter windowed mode
|
||||||
|
if(mode.Windowed && [g_glview isInFullScreenMode])
|
||||||
|
{
|
||||||
|
// pull the view back from fullscreen restoring windows options
|
||||||
|
[g_glview exitFullScreenModeWithOptions:nil];
|
||||||
|
|
||||||
|
// disable manual setting of back buffer size, cocoa handles this
|
||||||
|
// automatically as soon as the window gets resized
|
||||||
|
CGLError error = CGLDisable((CGLContextObj)[g_glctx CGLContextObj],
|
||||||
|
kCGLCESurfaceBackingSize);
|
||||||
|
|
||||||
|
if(error != kCGLNoError)
|
||||||
|
nlerror("cannot disable kCGLCESurfaceBackingSize (%s)",
|
||||||
|
CGLErrorString(error));
|
||||||
|
}
|
||||||
|
|
||||||
|
// enter fullscreen, leave windowed 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],
|
||||||
|
kCGLCESurfaceBackingSize);
|
||||||
|
|
||||||
|
if(error != kCGLNoError)
|
||||||
|
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!
|
||||||
|
/*
|
||||||
|
TODO check if simply using NSView enterFullScreenMode is a good idea.
|
||||||
|
the context can be set to full screen as well? performance differences?
|
||||||
|
*/
|
||||||
|
[g_glview enterFullScreenMode:[NSScreen mainScreen] withOptions:
|
||||||
|
[NSDictionary dictionaryWithObjectsAndKeys:
|
||||||
|
[NSNumber numberWithInt:
|
||||||
|
NSApplicationPresentationHideDock |
|
||||||
|
NSApplicationPresentationAutoHideMenuBar],
|
||||||
|
NSFullScreenModeApplicationPresentationOptions, nil]];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef UGLY_BACKBUFFER_SIZE_WORKAROUND
|
||||||
|
g_bufferSize[0] = mode.Width;
|
||||||
|
g_bufferSize[1] = mode.Height;
|
||||||
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void getWindowSize(uint32 &width, uint32 &height)
|
void getWindowSize(uint32 &width, uint32 &height)
|
||||||
{
|
{
|
||||||
NSRect rect = [g_glview bounds];
|
if(!g_glctx)
|
||||||
width = rect.size.width;
|
return;
|
||||||
height = rect.size.height;
|
|
||||||
|
// 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
|
||||||
|
// 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 from the back buffer,
|
||||||
|
// not the one from the window.
|
||||||
|
|
||||||
|
// check if manual back buffer sizing is enabled (thats only in fullscreen)
|
||||||
|
|
||||||
|
#ifdef UGLY_BACKBUFFER_SIZE_WORKAROUND
|
||||||
|
if([g_glview isInFullScreenMode])
|
||||||
|
{
|
||||||
|
width = g_bufferSize[0];
|
||||||
|
height = g_bufferSize[1];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NSRect rect = [g_glview frame];
|
||||||
|
width = rect.size.width;
|
||||||
|
height = rect.size.height;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
|
||||||
|
/*
|
||||||
|
TODO does not work atm, "invalid enumeration"
|
||||||
|
*/
|
||||||
|
GLint surfaceBackingSizeSet = 0;
|
||||||
|
CGLError error = CGLIsEnabled((CGLContextObj)[g_glctx CGLContextObj],
|
||||||
|
kCGLCESurfaceBackingSize, &surfaceBackingSizeSet);
|
||||||
|
|
||||||
|
if(error != kCGLNoError)
|
||||||
|
nlerror("cannot check kCGLCESurfaceBackingSize state (%s)",
|
||||||
|
CGLErrorString(error));
|
||||||
|
|
||||||
|
// if in fullscreen mode
|
||||||
|
if(surfaceBackingSizeSet)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
TODO does not work atm, "invalid enumeration"
|
||||||
|
*/
|
||||||
|
// get the back buffer size
|
||||||
|
GLint dim[2];
|
||||||
|
CGLError error = CGLGetParameter((CGLContextObj)[g_glctx CGLContextObj],
|
||||||
|
kCGLCPSurfaceBackingSize, dim);
|
||||||
|
|
||||||
|
if(error != kCGLNoError)
|
||||||
|
nlerror("cannot get kCGLCPSurfaceBackingSize value (%s)",
|
||||||
|
CGLErrorString(error));
|
||||||
|
|
||||||
|
// put size into ref params
|
||||||
|
width = dim[0];
|
||||||
|
height = dim[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
// if in windowed mode
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// return the views size
|
||||||
|
NSRect rect = [g_glview frame];
|
||||||
|
|
||||||
|
// put size into ref params
|
||||||
|
width = rect.size.width;
|
||||||
|
height = rect.size.height;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void getWindowPos(uint32 &x, uint32 &y)
|
void getWindowPos(uint32 &x, uint32 &y)
|
||||||
{
|
{
|
||||||
|
// get the size of the screen
|
||||||
NSRect screenRect = [[g_window screen] frame];
|
NSRect screenRect = [[g_window screen] frame];
|
||||||
|
|
||||||
|
// get the size of the window
|
||||||
NSRect windowRect = [g_window frame];
|
NSRect windowRect = [g_window frame];
|
||||||
|
|
||||||
|
// simply return x
|
||||||
x = windowRect.origin.x;
|
x = windowRect.origin.x;
|
||||||
|
|
||||||
|
// map y from cocoa to NeL coordinates before returning
|
||||||
y = screenRect.size.height - windowRect.size.height - windowRect.origin.y;
|
y = screenRect.size.height - windowRect.size.height - windowRect.origin.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setWindowPos(uint32 x, uint32 y)
|
void setWindowPos(uint32 x, uint32 y)
|
||||||
{
|
{
|
||||||
|
// get the size of the screen
|
||||||
NSRect screenRect = [[g_window screen] frame];
|
NSRect screenRect = [[g_window screen] frame];
|
||||||
|
|
||||||
|
// get the size of the window
|
||||||
NSRect windowRect = [g_window frame];
|
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)];
|
[g_window setFrameTopLeftPoint:NSMakePoint(x, y)];
|
||||||
}
|
}
|
||||||
|
|
||||||
void setWindowTitle(const ucstring &title)
|
void setWindowTitle(const ucstring &title)
|
||||||
{
|
{
|
||||||
|
// well... set the title of the window
|
||||||
[g_window setTitle:[NSString stringWithUTF8String:title.toUtf8().c_str()]];
|
[g_window setTitle:[NSString stringWithUTF8String:title.toUtf8().c_str()]];
|
||||||
}
|
}
|
||||||
|
|
||||||
void swapBuffers()
|
void swapBuffers()
|
||||||
{
|
{
|
||||||
|
// make cocoa draw buffer contents to the view
|
||||||
[g_glctx flushBuffer];
|
[g_glctx flushBuffer];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -321,7 +502,7 @@ bool isTextKeyEvent(NSEvent* event)
|
||||||
TODO check why iswprint(character) does not solve it.
|
TODO check why iswprint(character) does not solve it.
|
||||||
it always returns false, even for π, é, ...
|
it always returns false, even for π, é, ...
|
||||||
*/
|
*/
|
||||||
// > 127 but not printable
|
// characters > 127 but not printable
|
||||||
if( nelKey == NLMISC::KeyF1 || nelKey == NLMISC::KeyF2 ||
|
if( nelKey == NLMISC::KeyF1 || nelKey == NLMISC::KeyF2 ||
|
||||||
nelKey == NLMISC::KeyF3 || nelKey == NLMISC::KeyF4 ||
|
nelKey == NLMISC::KeyF3 || nelKey == NLMISC::KeyF4 ||
|
||||||
nelKey == NLMISC::KeyF5 || nelKey == NLMISC::KeyF6 ||
|
nelKey == NLMISC::KeyF5 || nelKey == NLMISC::KeyF6 ||
|
||||||
|
@ -354,7 +535,7 @@ void submitEvents(NLMISC::CEventServer& server,
|
||||||
g_pool = [[NSAutoreleasePool alloc] init];
|
g_pool = [[NSAutoreleasePool alloc] init];
|
||||||
|
|
||||||
// we break if there was no event to handle
|
// we break if there was no event to handle
|
||||||
/* TODO maximum? */
|
/* TODO maximum number of events processed in one update? */
|
||||||
while(true)
|
while(true)
|
||||||
{
|
{
|
||||||
// get the next event to handle
|
// get the next event to handle
|
||||||
|
@ -368,53 +549,74 @@ void submitEvents(NLMISC::CEventServer& server,
|
||||||
|
|
||||||
// NSLog(@"%@", event);
|
// NSLog(@"%@", event);
|
||||||
|
|
||||||
uint32 width, height;
|
// get the views size
|
||||||
/* TODO cache? */
|
NSRect rect = [g_glview frame];
|
||||||
getWindowSize(width, height);
|
|
||||||
|
|
||||||
// get the mouse position in nel style (relative)
|
// convert the mouse position to NeL style (relative)
|
||||||
float mouseX = event.locationInWindow.x / (float)width;
|
float mouseX = event.locationInWindow.x / (float)rect.size.width;
|
||||||
float mouseY = event.locationInWindow.y / (float)height;
|
float mouseY = event.locationInWindow.y / (float)rect.size.height;
|
||||||
|
|
||||||
switch(event.type)
|
switch(event.type)
|
||||||
{
|
{
|
||||||
case NSLeftMouseDown:
|
case NSLeftMouseDown:
|
||||||
|
/*
|
||||||
|
TODO modifiers with mouse events
|
||||||
|
*/
|
||||||
server.postEvent(new NLMISC::CEventMouseDown(
|
server.postEvent(new NLMISC::CEventMouseDown(
|
||||||
mouseX, mouseY, NLMISC::leftButton /* modifiers */, eventEmitter));
|
mouseX, mouseY, NLMISC::leftButton /* modifiers */, eventEmitter));
|
||||||
break;
|
break;
|
||||||
case NSLeftMouseUp:
|
case NSLeftMouseUp:
|
||||||
|
/*
|
||||||
|
TODO modifiers with mouse events
|
||||||
|
*/
|
||||||
server.postEvent(new NLMISC::CEventMouseUp(
|
server.postEvent(new NLMISC::CEventMouseUp(
|
||||||
mouseX, mouseY, NLMISC::leftButton /* modifiers */, eventEmitter));
|
mouseX, mouseY, NLMISC::leftButton /* modifiers */, eventEmitter));
|
||||||
break;
|
break;
|
||||||
case NSRightMouseDown:
|
case NSRightMouseDown:
|
||||||
|
/*
|
||||||
|
TODO modifiers with mouse events
|
||||||
|
*/
|
||||||
server.postEvent(new NLMISC::CEventMouseDown(
|
server.postEvent(new NLMISC::CEventMouseDown(
|
||||||
mouseX, mouseY, NLMISC::rightButton /* modifiers */, eventEmitter));
|
mouseX, mouseY, NLMISC::rightButton /* modifiers */, eventEmitter));
|
||||||
break;
|
break;
|
||||||
case NSRightMouseUp:
|
case NSRightMouseUp:
|
||||||
|
/*
|
||||||
|
TODO modifiers with mouse events
|
||||||
|
*/
|
||||||
server.postEvent(new NLMISC::CEventMouseUp(
|
server.postEvent(new NLMISC::CEventMouseUp(
|
||||||
mouseX, mouseY, NLMISC::rightButton /* modifiers */, eventEmitter));
|
mouseX, mouseY, NLMISC::rightButton /* modifiers */, eventEmitter));
|
||||||
break;
|
break;
|
||||||
case NSMouseMoved:
|
case NSMouseMoved:
|
||||||
|
/*
|
||||||
|
TODO modifiers with mouse events
|
||||||
|
*/
|
||||||
server.postEvent(new NLMISC::CEventMouseMove(
|
server.postEvent(new NLMISC::CEventMouseMove(
|
||||||
mouseX, mouseY, (NLMISC::TMouseButton)0 /* modifiers */, eventEmitter));
|
mouseX, mouseY, (NLMISC::TMouseButton)0 /* modifiers */, eventEmitter));
|
||||||
break;
|
break;
|
||||||
case NSLeftMouseDragged:
|
case NSLeftMouseDragged:
|
||||||
|
/*
|
||||||
|
TODO modifiers with mouse events
|
||||||
|
*/
|
||||||
server.postEvent(new NLMISC::CEventMouseMove(
|
server.postEvent(new NLMISC::CEventMouseMove(
|
||||||
mouseX, mouseY, NLMISC::leftButton /* modifiers */, eventEmitter));
|
mouseX, mouseY, NLMISC::leftButton /* modifiers */, eventEmitter));
|
||||||
break;
|
break;
|
||||||
case NSRightMouseDragged:break;
|
case NSRightMouseDragged:break;
|
||||||
|
/*
|
||||||
|
TODO modifiers with mouse events
|
||||||
|
*/
|
||||||
server.postEvent(new NLMISC::CEventMouseMove(
|
server.postEvent(new NLMISC::CEventMouseMove(
|
||||||
mouseX, mouseY, NLMISC::rightButton /* modifiers */, eventEmitter));
|
mouseX, mouseY, NLMISC::rightButton /* modifiers */, eventEmitter));
|
||||||
case NSMouseEntered:break;
|
case NSMouseEntered:break;
|
||||||
case NSMouseExited:break;
|
case NSMouseExited:break;
|
||||||
case NSKeyDown:
|
case NSKeyDown:
|
||||||
// push the key press event to the new event server
|
// push the key press event to the event server
|
||||||
server.postEvent(new NLMISC::CEventKeyDown(
|
server.postEvent(new NLMISC::CEventKeyDown(
|
||||||
virtualKeycodeToNelKey([event keyCode]),
|
virtualKeycodeToNelKey([event keyCode]),
|
||||||
modifierFlagsToNelKeyButton([event modifierFlags]),
|
modifierFlagsToNelKeyButton([event modifierFlags]),
|
||||||
[event isARepeat] == NO,
|
[event isARepeat] == NO,
|
||||||
eventEmitter));
|
eventEmitter));
|
||||||
|
|
||||||
|
// if this was a text event
|
||||||
if(isTextKeyEvent(event))
|
if(isTextKeyEvent(event))
|
||||||
{
|
{
|
||||||
ucstring ucstr;
|
ucstring ucstr;
|
||||||
|
@ -422,7 +624,7 @@ void submitEvents(NLMISC::CEventServer& server,
|
||||||
// get the string associated with the key press event
|
// get the string associated with the key press event
|
||||||
ucstr.fromUtf8([[event characters] UTF8String]);
|
ucstr.fromUtf8([[event characters] UTF8String]);
|
||||||
|
|
||||||
// push to event server
|
// push the text event to event server as well
|
||||||
server.postEvent(new NLMISC::CEventChar(
|
server.postEvent(new NLMISC::CEventChar(
|
||||||
ucstr[0],
|
ucstr[0],
|
||||||
NLMISC::noKeyButton,
|
NLMISC::noKeyButton,
|
||||||
|
@ -430,6 +632,7 @@ void submitEvents(NLMISC::CEventServer& server,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NSKeyUp:
|
case NSKeyUp:
|
||||||
|
// push the key release event to the event server
|
||||||
server.postEvent(new NLMISC::CEventKeyUp(
|
server.postEvent(new NLMISC::CEventKeyUp(
|
||||||
virtualKeycodeToNelKey([event keyCode]),
|
virtualKeycodeToNelKey([event keyCode]),
|
||||||
modifierFlagsToNelKeyButton([event modifierFlags]),
|
modifierFlagsToNelKeyButton([event modifierFlags]),
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
*/
|
*/
|
||||||
@interface CocoaOpenGLView : NSOpenGLView<NSTextInputClient>
|
@interface CocoaOpenGLView : NSOpenGLView<NSTextInputClient>
|
||||||
{
|
{
|
||||||
NSMutableAttributedString* backingStore;
|
NSMutableAttributedString* characterStorage;
|
||||||
NSRange markedRange;
|
NSRange markedRange;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
{
|
{
|
||||||
if(self = [super initWithFrame:frame])
|
if(self = [super initWithFrame:frame])
|
||||||
{
|
{
|
||||||
backingStore = [[NSMutableAttributedString alloc] initWithString:@""];
|
characterStorage = [[NSMutableAttributedString alloc] initWithString:@""];
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
return nil;
|
return nil;
|
||||||
|
@ -32,7 +32,7 @@
|
||||||
|
|
||||||
- (void)dealloc
|
- (void)dealloc
|
||||||
{
|
{
|
||||||
[backingStore release];
|
[characterStorage release];
|
||||||
[super dealloc];
|
[super dealloc];
|
||||||
}
|
}
|
||||||
-(BOOL)acceptsFirstResponder
|
-(BOOL)acceptsFirstResponder
|
||||||
|
@ -77,13 +77,13 @@
|
||||||
|
|
||||||
if([aString length] == 0)
|
if([aString length] == 0)
|
||||||
{
|
{
|
||||||
[backingStore deleteCharactersInRange:replacementRange];
|
[characterStorage deleteCharactersInRange:replacementRange];
|
||||||
[self unmarkText];
|
[self unmarkText];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
markedRange = NSMakeRange(replacementRange.location, [aString length]);
|
markedRange = NSMakeRange(replacementRange.location, [aString length]);
|
||||||
[backingStore replaceCharactersInRange:replacementRange withString:aString];
|
[characterStorage replaceCharactersInRange:replacementRange withString:aString];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,7 +102,7 @@
|
||||||
-(NSAttributedString*)attributedSubstringForProposedRange:(NSRange)aRange
|
-(NSAttributedString*)attributedSubstringForProposedRange:(NSRange)aRange
|
||||||
actualRange:(NSRangePointer)actualRange
|
actualRange:(NSRangePointer)actualRange
|
||||||
{
|
{
|
||||||
return [backingStore attributedSubstringFromRange:aRange];
|
return [characterStorage attributedSubstringFromRange:aRange];
|
||||||
}
|
}
|
||||||
|
|
||||||
-(void)insertText:(id)aString
|
-(void)insertText:(id)aString
|
||||||
|
@ -111,7 +111,7 @@
|
||||||
if(replacementRange.location == NSNotFound)
|
if(replacementRange.location == NSNotFound)
|
||||||
replacementRange = markedRange;
|
replacementRange = markedRange;
|
||||||
|
|
||||||
[backingStore replaceCharactersInRange:replacementRange withString:aString];
|
[characterStorage replaceCharactersInRange:replacementRange withString:aString];
|
||||||
}
|
}
|
||||||
|
|
||||||
-(NSUInteger)characterIndexForPoint:(NSPoint)aPoint
|
-(NSUInteger)characterIndexForPoint:(NSPoint)aPoint
|
||||||
|
|
Loading…
Reference in a new issue