Fixed: #1011 Switch nlWindow from NSWindow* to NSView*

This commit is contained in:
rti 2010-07-06 21:50:22 +02:00
parent d702b92726
commit e4acb111a8

View file

@ -98,6 +98,59 @@ static void setupApplicationMenu()
[[NSApp mainMenu] addItem:menuItem]; [[NSApp mainMenu] addItem:menuItem];
} }
static void setupGLView(NSView* superview)
{
/*
TODO use mode.Depth
TODO NSOpenGLPFAOffScreen
*/
// setup opengl settings
NSOpenGLPixelFormatAttribute att[] =
{
NSOpenGLPFADoubleBuffer,
NSOpenGLPFAColorSize, 24,
NSOpenGLPFADepthSize, 24,
NSOpenGLPFAAlphaSize, 8,
NSOpenGLPFAStencilSize, 8,
NSOpenGLPFANoRecovery,
NSOpenGLPFAAccelerated,
NSOpenGLPFABackingStore,
0
};
// put the settings into a format object
NSOpenGLPixelFormat* format =
[[NSOpenGLPixelFormat alloc] initWithAttributes:att];
if(!format)
nlerror("cannot create NSOpenGLPixelFormat");
// create a opengl view with the created format
NSOpenGLView* view = [[CocoaOpenGLView alloc]
initWithFrame:NSMakeRect(0, 0, 0, 0) pixelFormat: format];
if(!view)
nlerror("cannot create view");
// make the view automatically fit the super view
[view setAutoresizingMask: NSViewHeightSizable | NSViewWidthSizable];
// put the view into the superview
[superview addSubview:view];
[view setFrame: [superview frame]];
// create a opengl context for the view
NSOpenGLContext* ctx = [view openGLContext];
if(!ctx)
nlerror("cannot create context");
// free the pixel format object
[format release];
}
void ctor() void ctor()
{ {
// create a pool, cocoa code would leak memory otherwise // create a pool, cocoa code would leak memory otherwise
@ -160,81 +213,33 @@ nlWindow createWindow(const GfxMode& mode)
// this is our main window // this is our main window
[window makeMainWindow]; [window makeMainWindow];
return window; NSView* view = [[NSView alloc] init];
[window setContentView: view];
return view;
} }
bool destroyWindow(nlWindow wnd) bool destroyWindow(nlWindow wnd)
{ {
NSWindow* window = (NSWindow*)wnd; NSView* view = (NSView*)wnd;
NSOpenGLView* view = [window contentView];
// release the view we alloced // release the window
[view release]; [[view window] release];
// release the window we alloced
[window release];
return true; return true;
} }
nlWindow setDisplay(nlWindow wnd, const GfxMode& mode, bool show, bool resizeable) nlWindow setDisplay(nlWindow wnd, const GfxMode& mode, bool show, bool resizeable)
{ {
/* NSView* view = (NSView*)wnd;
TODO use show
call showWindow()
*/
NSWindow* window = (NSWindow*)wnd; if(view == EmptyWindow)
view = (NSView*)createWindow(mode);
if(wnd == EmptyWindow) setupGLView(view);
window = (NSWindow*)createWindow(mode);
/* return view;
TODO use mode.Depth
TODO NSOpenGLPFAOffScreen
*/
// setup opengl settings
NSOpenGLPixelFormatAttribute att[] =
{
NSOpenGLPFADoubleBuffer,
NSOpenGLPFAColorSize, 24,
NSOpenGLPFADepthSize, 24,
NSOpenGLPFAAlphaSize, 8,
NSOpenGLPFAStencilSize, 8,
NSOpenGLPFANoRecovery,
NSOpenGLPFAAccelerated,
NSOpenGLPFABackingStore,
0
};
// put the settings into a format object
NSOpenGLPixelFormat* format =
[[NSOpenGLPixelFormat alloc] initWithAttributes:att];
if(!format)
nlerror("cannot create NSOpenGLPixelFormat");
// create a opengl view with the created format
NSOpenGLView* view = [[CocoaOpenGLView alloc]
initWithFrame:NSMakeRect(0, 0, 0, 0) pixelFormat: format];
if(!view)
nlerror("cannot create view");
// put the view into the window
[window setContentView:view];
// create a opengl context for the view
NSOpenGLContext* ctx = [view openGLContext];
if(!ctx)
nlerror("cannot create context");
// free the pixel format object
[format release];
return window;
} }
bool setWindowStyle(nlWindow wnd, bool fullscreen) bool setWindowStyle(nlWindow wnd, bool fullscreen)
@ -245,16 +250,16 @@ bool setWindowStyle(nlWindow wnd, bool fullscreen)
return false; return false;
} }
NSWindow* window = (NSWindow*)wnd; NSView* superview = (NSView*)wnd;
NSOpenGLView* view = [window contentView]; NSOpenGLView* view = [[superview subviews] lastObject];
NSOpenGLContext* ctx = [view openGLContext];
// leave fullscreen mode, enter windowed mode // leave fullscreen mode, enter windowed mode
if(!fullscreen && [view isInFullScreenMode]) if(!fullscreen && [superview 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 // automatically as soon as the view gets resized
CGLError error = CGLDisable((CGLContextObj)[ctx CGLContextObj], CGLError error = CGLDisable(
(CGLContextObj)[[view openGLContext] CGLContextObj],
kCGLCESurfaceBackingSize); kCGLCESurfaceBackingSize);
if(error != kCGLNoError) if(error != kCGLNoError)
@ -262,14 +267,15 @@ bool setWindowStyle(nlWindow wnd, bool fullscreen)
CGLErrorString(error)); CGLErrorString(error));
// pull the view back from fullscreen restoring window options // pull the view back from fullscreen restoring window options
[view exitFullScreenModeWithOptions:nil]; [superview exitFullScreenModeWithOptions:nil];
} }
// enter fullscreen, leave windowed mode // enter fullscreen, leave windowed mode
else if(fullscreen && ![view isInFullScreenMode]) else if(fullscreen && ![superview isInFullScreenMode])
{ {
// enable manual back buffer size for mode setting in fullscreen // enable manual back buffer size for mode setting in fullscreen
CGLError error = CGLEnable((CGLContextObj)[ctx CGLContextObj], CGLError error = CGLEnable(
(CGLContextObj)[[view openGLContext] CGLContextObj],
kCGLCESurfaceBackingSize); kCGLCESurfaceBackingSize);
if(error != kCGLNoError) if(error != kCGLNoError)
@ -279,7 +285,7 @@ bool setWindowStyle(nlWindow wnd, bool fullscreen)
// put the view in fullscreen mode, hiding the dock but enabling the menubar // put the view in fullscreen mode, hiding the dock but enabling the menubar
// to pop up if the mouse hits the top screen border. // to pop up if the mouse hits the top screen border.
// NOTE: withOptions:nil disables <CMD>+<Tab> application switching! // NOTE: withOptions:nil disables <CMD>+<Tab> application switching!
[view enterFullScreenMode:[NSScreen mainScreen] withOptions: [superview enterFullScreenMode:[NSScreen mainScreen] withOptions:
[NSDictionary dictionaryWithObjectsAndKeys: [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt: [NSNumber numberWithInt:
NSApplicationPresentationHideDock | NSApplicationPresentationHideDock |
@ -298,8 +304,8 @@ bool setWindowStyle(nlWindow wnd, bool fullscreen)
void getCurrentScreenMode(nlWindow wnd, GfxMode& mode) void getCurrentScreenMode(nlWindow wnd, GfxMode& mode)
{ {
NSWindow* window = (NSWindow*)wnd; NSView* superview = (NSView*)wnd;
NSOpenGLView* view = [window contentView]; NSOpenGLView* view = [[superview subviews] lastObject];
// the sceen with the menu bar // the sceen with the menu bar
NSScreen* screen = [[NSScreen screens] objectAtIndex:0]; NSScreen* screen = [[NSScreen screens] objectAtIndex:0];
@ -309,7 +315,7 @@ void getCurrentScreenMode(nlWindow wnd, GfxMode& mode)
mode.Depth = NSBitsPerPixelFromDepth([screen depth]); mode.Depth = NSBitsPerPixelFromDepth([screen depth]);
// in fullscreen mode // in fullscreen mode
if([view isInFullScreenMode]) if([superview isInFullScreenMode])
{ {
// return the size of the back buffer (like having switched monitor mode) // return the size of the back buffer (like having switched monitor mode)
mode.Windowed = false; mode.Windowed = false;
@ -329,9 +335,8 @@ void getCurrentScreenMode(nlWindow wnd, GfxMode& mode)
void getWindowSize(nlWindow wnd, uint32 &width, uint32 &height) void getWindowSize(nlWindow wnd, uint32 &width, uint32 &height)
{ {
NSWindow* window = (NSWindow*)wnd; NSView* superview = (NSView*)wnd;
NSOpenGLView* view = [window contentView]; NSOpenGLView* view = [[superview subviews] lastObject];
NSOpenGLContext* ctx = [view openGLContext];
// A cocoa fullscreen view stays at the native resolution of the display. // A cocoa fullscreen view stays at the native resolution of the display.
// When changing the rendering resolution, the size of the back buffer gets // When changing the rendering resolution, the size of the back buffer gets
@ -342,7 +347,7 @@ void getWindowSize(nlWindow wnd, uint32 &width, uint32 &height)
// not the one from the window. // not the one from the window.
// in fullscreen mode // in fullscreen mode
if([view isInFullScreenMode]) if([superview isInFullScreenMode])
{ {
// use the size stored in setWindowSize() // use the size stored in setWindowSize()
width = g_bufferSize[0]; width = g_bufferSize[0];
@ -361,16 +366,16 @@ void getWindowSize(nlWindow wnd, uint32 &width, uint32 &height)
void setWindowSize(nlWindow wnd, uint32 width, uint32 height) void setWindowSize(nlWindow wnd, uint32 width, uint32 height)
{ {
NSWindow* window = (NSWindow*)wnd; NSView* superview = (NSView*)wnd;
NSOpenGLView* view = [window contentView]; NSOpenGLView* view = [[superview subviews] lastObject];
NSOpenGLContext* ctx = [view openGLContext];
// for fullscreen mode, adjust the back buffer size to the desired resolution // for fullscreen mode, adjust the back buffer size to the desired resolution
if([view isInFullScreenMode]) if([superview isInFullScreenMode])
{ {
// set the back buffer manually to match the desired rendering resolution // set the back buffer manually to match the desired rendering resolution
GLint dim[2] = { width, height }; GLint dim[2] = { width, height };
CGLError error = CGLSetParameter((CGLContextObj)[ctx CGLContextObj], CGLError error = CGLSetParameter(
(CGLContextObj)[[view openGLContext] CGLContextObj],
kCGLCPSurfaceBackingSize, dim); kCGLCPSurfaceBackingSize, dim);
if(error != kCGLNoError) if(error != kCGLNoError)
@ -379,6 +384,8 @@ void setWindowSize(nlWindow wnd, uint32 width, uint32 height)
} }
else else
{ {
NSWindow* window = [view window];
// get the windows current frame // get the windows current frame
NSRect rect = [window frame]; NSRect rect = [window frame];
@ -398,11 +405,12 @@ void setWindowSize(nlWindow wnd, uint32 width, uint32 height)
void getWindowPos(nlWindow wnd, sint32 &x, sint32 &y) void getWindowPos(nlWindow wnd, sint32 &x, sint32 &y)
{ {
NSWindow* window = (NSWindow*)wnd; NSView* superview = (NSView*)wnd;
NSOpenGLView* view = [window contentView]; NSOpenGLView* view = [[superview subviews] lastObject];
NSWindow* window = [view window];
// for IDriver conformity // for IDriver conformity
if([view isInFullScreenMode]) if([superview isInFullScreenMode])
{ {
x = y = 0; x = y = 0;
return; return;
@ -423,7 +431,8 @@ void getWindowPos(nlWindow wnd, sint32 &x, sint32 &y)
void setWindowPos(nlWindow wnd, sint32 x, sint32 y) void setWindowPos(nlWindow wnd, sint32 x, sint32 y)
{ {
NSWindow* window = (NSWindow*)wnd; NSView* superview = (NSView*)wnd;
NSWindow* window = [superview window];
// get the rect (position, size) of the screen with menu bar // get the rect (position, size) of the screen with menu bar
NSRect screenRect = [[[NSScreen screens] objectAtIndex:0] frame]; NSRect screenRect = [[[NSScreen screens] objectAtIndex:0] frame];
@ -440,7 +449,8 @@ void setWindowPos(nlWindow wnd, sint32 x, sint32 y)
void setWindowTitle(nlWindow wnd, const ucstring& title) void setWindowTitle(nlWindow wnd, const ucstring& title)
{ {
NSWindow* window = (NSWindow*)wnd; NSView* superview = (NSView*)wnd;
NSWindow* window = [superview window];
// well... set the title of the window // well... set the title of the window
[window setTitle:[NSString stringWithUTF8String:title.toUtf8().c_str()]]; [window setTitle:[NSString stringWithUTF8String:title.toUtf8().c_str()]];
@ -453,8 +463,9 @@ void showWindow(bool show)
bool activate(nlWindow wnd) bool activate(nlWindow wnd)
{ {
NSWindow* window = (NSWindow*)wnd; NSView* superview = (NSView*)wnd;
NSOpenGLContext* ctx = [[window contentView] openGLContext]; NSOpenGLView* view = [[superview subviews] lastObject];
NSOpenGLContext* ctx = [view openGLContext];
// if our context is not the current one, make it the current // if our context is not the current one, make it the current
if([NSOpenGLContext currentContext] != ctx) if([NSOpenGLContext currentContext] != ctx)
@ -465,8 +476,8 @@ bool activate(nlWindow wnd)
void swapBuffers(nlWindow wnd) void swapBuffers(nlWindow wnd)
{ {
NSWindow* window = (NSWindow*)wnd; NSView* superview = (NSView*)wnd;
NSOpenGLView* view = [window contentView]; NSOpenGLView* view = [[superview subviews] lastObject];
NSOpenGLContext* ctx = [view openGLContext]; NSOpenGLContext* ctx = [view openGLContext];
// make cocoa draw buffer contents to the view // make cocoa draw buffer contents to the view
@ -507,8 +518,9 @@ void showCursor(bool show)
void setMousePos(nlWindow wnd, float x, float y) void setMousePos(nlWindow wnd, float x, float y)
{ {
NSWindow* window = (NSWindow*)wnd; NSView* superview = (NSView*)wnd;
NSOpenGLView* view = [window contentView]; NSOpenGLView* view = [[superview subviews] lastObject];
NSWindow* window = [view window];
// CG wants absolute coordinates related to first screen's top left // CG wants absolute coordinates related to first screen's top left
@ -517,7 +529,7 @@ void setMousePos(nlWindow wnd, float x, float y)
// get the rect (position, size) of the window // get the rect (position, size) of the window
NSRect windowRect; NSRect windowRect;
if([view isInFullScreenMode]) if([superview isInFullScreenMode])
windowRect = [[window screen] frame]; windowRect = [[window screen] frame];
else else
windowRect = [window frame]; windowRect = [window frame];
@ -757,7 +769,8 @@ void submitEvents(NLMISC::CEventServer& server,
if(!event) if(!event)
break; break;
NSRect viewRect = [[[event window] contentView] frame]; NSRect viewRect =
[[[[[event window] contentView] subviews] lastObject] frame];
// TODO this code assumes, that the view fills the window // TODO this code assumes, that the view fills the window
// convert the mouse position to NeL style (relative) // convert the mouse position to NeL style (relative)