diff --git a/examples/common/entry/entry.h b/examples/common/entry/entry.h index 7f6524b8a..be1d35d75 100644 --- a/examples/common/entry/entry.h +++ b/examples/common/entry/entry.h @@ -211,6 +211,7 @@ namespace entry void setWindowSize(WindowHandle _handle, uint32_t _width, uint32_t _height); void setWindowTitle(WindowHandle _handle, const char* _title); void toggleWindowFrame(WindowHandle _handle); + void toggleFullscreen(WindowHandle _handle); void setMouseLock(WindowHandle _handle, bool _lock); struct WindowState diff --git a/examples/common/entry/entry_android.cpp b/examples/common/entry/entry_android.cpp index 5ad35d1c1..2d7c852c8 100644 --- a/examples/common/entry/entry_android.cpp +++ b/examples/common/entry/entry_android.cpp @@ -440,6 +440,11 @@ namespace entry BX_UNUSED(_handle); } + void toggleFullscreen(WindowHandle _handle) + { + BX_UNUSED(_handle); + } + void setMouseLock(WindowHandle _handle, bool _lock) { BX_UNUSED(_handle, _lock); diff --git a/examples/common/entry/entry_asmjs.cpp b/examples/common/entry/entry_asmjs.cpp index 6c221246e..3ac5497b1 100644 --- a/examples/common/entry/entry_asmjs.cpp +++ b/examples/common/entry/entry_asmjs.cpp @@ -59,6 +59,11 @@ namespace entry BX_UNUSED(_handle); } + void toggleFullscreen(WindowHandle _handle) + { + BX_UNUSED(_handle); + } + void setMouseLock(WindowHandle _handle, bool _lock) { BX_UNUSED(_handle, _lock); diff --git a/examples/common/entry/entry_ios.mm b/examples/common/entry/entry_ios.mm index 9a9a2d6aa..8fc67ffe8 100644 --- a/examples/common/entry/entry_ios.mm +++ b/examples/common/entry/entry_ios.mm @@ -126,6 +126,11 @@ namespace entry BX_UNUSED(_handle); } + void toggleFullscreen(WindowHandle _handle) + { + BX_UNUSED(_handle); + } + void setMouseLock(WindowHandle _handle, bool _lock) { BX_UNUSED(_handle, _lock); diff --git a/examples/common/entry/entry_nacl.cpp b/examples/common/entry/entry_nacl.cpp index fca37180c..8d6fac7ba 100644 --- a/examples/common/entry/entry_nacl.cpp +++ b/examples/common/entry/entry_nacl.cpp @@ -94,6 +94,11 @@ namespace entry BX_UNUSED(_handle); } + void toggleFullscreen(WindowHandle _handle) + { + BX_UNUSED(_handle); + } + void setMouseLock(WindowHandle _handle, bool _lock) { BX_UNUSED(_handle, _lock); diff --git a/examples/common/entry/entry_osx.mm b/examples/common/entry/entry_osx.mm index 51e9d86be..8b1a7004f 100644 --- a/examples/common/entry/entry_osx.mm +++ b/examples/common/entry/entry_osx.mm @@ -81,7 +81,9 @@ namespace entry , m_mx(0) , m_my(0) , m_scroll(0) + , m_style(0) , m_exit(false) + , m_fullscreen(false) { s_translateKey[27] = Key::Esc; s_translateKey[13] = Key::Return; @@ -138,7 +140,7 @@ namespace entry NSWindow* window = m_window[handle.idx]; NSRect originalFrame = [window frame]; NSPoint location = [window mouseLocationOutsideOfEventStream]; - NSRect adjustFrame = [NSWindow contentRectForFrameRect: originalFrame styleMask: NSTitledWindowMask]; + NSRect adjustFrame = [window contentRectForFrameRect: originalFrame]; int x = location.x; int y = (int)adjustFrame.size.height - (int)location.y; @@ -246,9 +248,9 @@ namespace entry case NSLeftMouseDown: { // TODO: remove! - // Shift + Left Mouse Button acts as middle! This just a temporary solution! + // Command + Left Mouse Button acts as middle! This just a temporary solution! // This is becase the average OSX user doesn't have middle mouse click. - MouseButton::Enum mb = ([event modifierFlags] & NSShiftKeyMask) ? MouseButton::Middle : MouseButton::Left; + MouseButton::Enum mb = ([event modifierFlags] & NSCommandKeyMask) ? MouseButton::Middle : MouseButton::Left; m_eventQueue.postMouseEvent(s_defaultWindow, m_mx, m_my, m_scroll, mb, true); break; } @@ -306,16 +308,22 @@ namespace entry { m_eventQueue.postExitEvent(); } - else if ( (Key::Key0 <= key && key <= Key::KeyZ) - || (Key::Esc <= key && key <= Key::Minus) ) - { - m_eventQueue.postCharEvent(s_defaultWindow, 1, pressedChar); - return false; - } else { - m_eventQueue.postKeyEvent(s_defaultWindow, key, modifiers, true); - return false; + enum { ShiftMask = Modifier::LeftShift|Modifier::RightShift }; + const bool nonShiftModifiers = (0 != (modifiers&(~ShiftMask) ) ); + const bool isCharPressed = (Key::Key0 <= key && key <= Key::KeyZ) || (Key::Esc <= key && key <= Key::Minus) ; + const bool isText = isCharPressed && !nonShiftModifiers; + if (isText) + { + m_eventQueue.postCharEvent(s_defaultWindow, 1, pressedChar); + return false; + } + else + { + m_eventQueue.postKeyEvent(s_defaultWindow, key, modifiers, true); + return false; + } } } @@ -354,7 +362,7 @@ namespace entry WindowHandle handle = { 0 }; NSWindow* window = m_window[handle.idx]; NSRect originalFrame = [window frame]; - NSRect rect = [NSWindow contentRectForFrameRect: originalFrame styleMask: NSTitledWindowMask]; + NSRect rect = [window contentRectForFrameRect: originalFrame]; uint32_t width = uint32_t(rect.size.width); uint32_t height = uint32_t(rect.size.height); m_eventQueue.postSizeEvent(handle, width, height); @@ -398,26 +406,33 @@ namespace entry [menubar addItem:appMenuItem]; [NSApp setMainMenu:menubar]; + m_style = 0 + | NSTitledWindowMask + | NSClosableWindowMask + | NSMiniaturizableWindowMask + | NSResizableWindowMask + ; + + NSRect screenRect = [[NSScreen mainScreen] frame]; + const float centerX = (screenRect.size.width - (float)ENTRY_DEFAULT_WIDTH )*0.5f; + const float centerY = (screenRect.size.height - (float)ENTRY_DEFAULT_HEIGHT)*0.5f; + m_windowAlloc.alloc(); - NSRect rect = NSMakeRect(0, 0, ENTRY_DEFAULT_WIDTH, ENTRY_DEFAULT_HEIGHT); + NSRect rect = NSMakeRect(centerX, centerY, (float)ENTRY_DEFAULT_WIDTH, (float)ENTRY_DEFAULT_HEIGHT); NSWindow* window = [[NSWindow alloc] initWithContentRect:rect - styleMask:0 - |NSTitledWindowMask - |NSClosableWindowMask - |NSMiniaturizableWindowMask - |NSResizableWindowMask + styleMask:m_style backing:NSBackingStoreBuffered defer:NO ]; NSString* appName = [[NSProcessInfo processInfo] processName]; [window setTitle:appName]; - [window cascadeTopLeftFromPoint:NSMakePoint(20,20)]; [window makeKeyAndOrderFront:window]; [window setAcceptsMouseMovedEvents:YES]; [window setBackgroundColor:[NSColor blackColor]]; [[Window sharedDelegate] windowCreated:window]; m_window[0] = window; + m_windowFrame = [window frame]; bgfx::osxSetNSWindow(window); @@ -448,16 +463,24 @@ namespace entry return 0; } + bool isValid(WindowHandle _handle) + { + return m_windowAlloc.isValid(_handle.idx); + } + EventQueue m_eventQueue; bx::HandleAllocT m_windowAlloc; NSWindow* m_window[ENTRY_CONFIG_MAX_WINDOWS]; + NSRect m_windowFrame; float m_scrollf; int32_t m_mx; int32_t m_my; int32_t m_scroll; + int32_t m_style; bool m_exit; + bool m_fullscreen; }; static Context s_ctx; @@ -486,27 +509,104 @@ namespace entry void destroyWindow(WindowHandle _handle) { - BX_UNUSED(_handle); + if (s_ctx.isValid(_handle) ) + { + dispatch_async(dispatch_get_main_queue() + , ^{ + [s_ctx.m_window[_handle.idx] performClose: nil]; + }); + } } void setWindowPos(WindowHandle _handle, int32_t _x, int32_t _y) { - BX_UNUSED(_handle, _x, _y); + if (s_ctx.isValid(_handle) ) + { + NSWindow* window = s_ctx.m_window[_handle.idx]; + NSScreen* screen = [window screen]; + + NSRect screenRect = [screen frame]; + CGFloat menuBarHeight = [[[NSApplication sharedApplication] mainMenu] menuBarHeight]; + + NSPoint position = { float(_x), screenRect.size.height - menuBarHeight - float(_y) }; + + dispatch_async(dispatch_get_main_queue() + , ^{ + [window setFrameTopLeftPoint: position]; + }); + } } void setWindowSize(WindowHandle _handle, uint32_t _width, uint32_t _height) { - BX_UNUSED(_handle, _width, _height); + if (s_ctx.isValid(_handle) ) + { + NSSize size = { float(_width), float(_height) }; + dispatch_async(dispatch_get_main_queue() + , ^{ + [s_ctx.m_window[_handle.idx] setContentSize: size]; + }); + } } void setWindowTitle(WindowHandle _handle, const char* _title) { - BX_UNUSED(_handle, _title); + if (s_ctx.isValid(_handle) ) + { + NSString* title = [[NSString alloc] initWithCString:_title encoding:1]; + dispatch_async(dispatch_get_main_queue() + , ^{ + [s_ctx.m_window[_handle.idx] setTitle: title]; + }); + [title release]; + } } void toggleWindowFrame(WindowHandle _handle) { - BX_UNUSED(_handle); + if (s_ctx.isValid(_handle) ) + { + s_ctx.m_style ^= NSTitledWindowMask; + dispatch_async(dispatch_get_main_queue() + , ^{ + [s_ctx.m_window[_handle.idx] setStyleMask: s_ctx.m_style]; + }); + } + } + + void toggleFullscreen(WindowHandle _handle) + { + if (s_ctx.isValid(_handle) ) + { + NSWindow* window = s_ctx.m_window[_handle.idx]; + NSScreen* screen = [window screen]; + NSRect screenRect = [screen frame]; + + if (!s_ctx.m_fullscreen) + { + [NSMenu setMenuBarVisible: false]; + s_ctx.m_style &= ~NSTitledWindowMask; + dispatch_async(dispatch_get_main_queue() + , ^{ + [window setStyleMask: s_ctx.m_style]; + [window setFrame:screenRect display:YES]; + }); + + s_ctx.m_fullscreen = true; + } + else + { + [NSMenu setMenuBarVisible: true]; + s_ctx.m_style |= NSTitledWindowMask; + dispatch_async(dispatch_get_main_queue() + , ^{ + [window setStyleMask: s_ctx.m_style]; + [window setFrame:s_ctx.m_windowFrame display:YES]; + }); + + s_ctx.m_fullscreen = false; + } + } } void setMouseLock(WindowHandle _handle, bool _lock) @@ -610,6 +710,7 @@ namespace entry using namespace entry; s_ctx.windowDidResize(); } + @end int main(int _argc, char** _argv) diff --git a/examples/common/entry/entry_qnx.cpp b/examples/common/entry/entry_qnx.cpp index 0ec4da6e1..c99393bb3 100644 --- a/examples/common/entry/entry_qnx.cpp +++ b/examples/common/entry/entry_qnx.cpp @@ -59,6 +59,11 @@ namespace entry BX_UNUSED(_handle); } + void toggleFullscreen(WindowHandle _handle) + { + BX_UNUSED(_handle); + } + void setMouseLock(WindowHandle _handle, bool _lock) { BX_UNUSED(_handle, _lock); diff --git a/examples/common/entry/entry_sdl.cpp b/examples/common/entry/entry_sdl.cpp index e44ebcefd..1f7469247 100644 --- a/examples/common/entry/entry_sdl.cpp +++ b/examples/common/entry/entry_sdl.cpp @@ -179,6 +179,7 @@ namespace entry SDL_USER_WINDOW_SET_POS, SDL_USER_WINDOW_SET_SIZE, SDL_USER_WINDOW_TOGGLE_FRAME, + SDL_USER_WINDOW_TOGGLE_FULL_SCREEN, SDL_USER_WINDOW_MOUSE_LOCK, }; @@ -211,6 +212,7 @@ namespace entry , m_height(ENTRY_DEFAULT_HEIGHT) , m_aspectRatio(16.0f/9.0f) , m_mouseLock(false) + , m_fullscreen(false) { memset(s_translateKey, 0, sizeof(s_translateKey) ); initTranslateKey(SDL_SCANCODE_ESCAPE, Key::Esc); @@ -615,6 +617,13 @@ namespace entry } break; + case SDL_USER_WINDOW_TOGGLE_FULL_SCREEN: + { + m_fullscreen = !m_fullscreen; + SDL_SetWindowFullscreen(m_window[handle.idx], m_fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0); + } + break; + case SDL_USER_WINDOW_MOUSE_LOCK: { SDL_SetRelativeMouseMode(!!uev.code ? SDL_TRUE : SDL_FALSE); @@ -723,6 +732,7 @@ namespace entry int32_t m_mx; int32_t m_my; bool m_mouseLock; + bool m_fullscreen; }; static Context s_ctx; @@ -805,6 +815,11 @@ namespace entry sdlPostEvent(SDL_USER_WINDOW_TOGGLE_FRAME, _handle); } + void toggleFullscreen(WindowHandle _handle) + { + sdlPostEvent(SDL_USER_WINDOW_TOGGLE_FULL_SCREEN, _handle); + } + void setMouseLock(WindowHandle _handle, bool _lock) { sdlPostEvent(SDL_USER_WINDOW_MOUSE_LOCK, _handle, NULL, _lock); diff --git a/examples/common/entry/entry_winrt.cpp b/examples/common/entry/entry_winrt.cpp index f50b58a39..e7cf8214d 100644 --- a/examples/common/entry/entry_winrt.cpp +++ b/examples/common/entry/entry_winrt.cpp @@ -175,6 +175,11 @@ namespace entry BX_UNUSED(_handle); } + void toggleFullscreen(WindowHandle _handle) + { + BX_UNUSED(_handle); + } + void setMouseLock(WindowHandle _handle, bool _lock) { BX_UNUSED(_handle, _lock); diff --git a/examples/common/entry/entry_x11.cpp b/examples/common/entry/entry_x11.cpp index 627263faa..249b8a048 100644 --- a/examples/common/entry/entry_x11.cpp +++ b/examples/common/entry/entry_x11.cpp @@ -664,6 +664,11 @@ namespace entry BX_UNUSED(_handle); } + void toggleFullscreen(WindowHandle _handle) + { + BX_UNUSED(_handle); + } + void setMouseLock(WindowHandle _handle, bool _lock) { BX_UNUSED(_handle, _lock);