123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494 |
- //-----------------------------------------------------------------------------
- // Copyright (c) 2013 GarageGames, LLC
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to
- // deal in the Software without restriction, including without limitation the
- // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- // sell copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- // IN THE SOFTWARE.
- //-----------------------------------------------------------------------------
- #import "platformOSX/platformOSX.h"
- #import "platformOSX/osxTorqueView.h"
- #import "game/gameInterface.h"
- #import "gui/guiCanvas.h"
- #pragma mark ---- OSXTorqueView Implementation ----
- @interface OSXTorqueView (PrivateMethods)
- - (void)windowFinishedLiveResize:(NSNotification *)notification;
- - (void)getModifierKey:(U32&)modifiers event:(NSEvent *)event;
- - (void)processMouseButton:(NSEvent *)event button:(KeyCodes)button action:(U8)action;
- - (void)processKeyEvent:(NSEvent *)event make:(BOOL)make;
- @end
- @implementation OSXTorqueView
- @synthesize contextInitialized = _contextInitialized;
- //-----------------------------------------------------------------------------
- // Custom initialization method for OSXTorqueView
- - (void)initialize
- {
- if (self)
- {
- // Make absolutely sure _openGLContext is nil
- _openGLContext = nil;
- NSTrackingAreaOptions trackingOptions = NSTrackingCursorUpdate |
- NSTrackingMouseMoved |
- NSTrackingMouseEnteredAndExited |
- NSTrackingInVisibleRect |
- NSTrackingActiveInActiveApp;
- _trackingArea = [[NSTrackingArea alloc] initWithRect:[self bounds] options:trackingOptions owner:self userInfo:nil];
- [self addTrackingArea:_trackingArea];
- inputManager = (osxInputManager *) Input::getManager();
- }
- }
- //-----------------------------------------------------------------------------
- // Default dealloc override
- - (void)dealloc
- {
- // End notifications
- [[NSNotificationCenter defaultCenter] removeObserver:self];
- // Drop the tracking rectangle for mouse events
- if (_trackingArea != nil)
- {
- [self removeTrackingArea:_trackingArea];
- [_trackingArea release];
- }
- // Custom memory cleanup
- if (_openGLContext != nil)
- {
- [_openGLContext release];
- _openGLContext = nil;
- }
- // "Parent" cleanup
- [super dealloc];
- }
- //-----------------------------------------------------------------------------
- // This view an always be a first responder
- - (BOOL)acceptsFirstResponder
- {
- return YES;
- }
- //-----------------------------------------------------------------------------
- // Called whent the parent finishes its live resizing
- - (void)windowFinishedLiveResize:(NSNotification *)notification
- {
- NSSize actualWindowSize = [[self window] frame].size;
- NSRect frame = NSMakeRect(0, 0, actualWindowSize.width, actualWindowSize.height);
- frame = [NSWindow frameRectForContentRect:frame styleMask:NSWindowStyleMaskTitled];
- S32 barHeight = frame.size.height - actualWindowSize.height;
- S32 heightWithoutTitle = actualWindowSize.height - barHeight;
- [[osxPlatState sharedPlatState] setWindowSize:(S32)actualWindowSize.width height:heightWithoutTitle];
-
- NSRect viewFrame = NSMakeRect(0, 0, frame.size.width, heightWithoutTitle);
- [self setFrame:viewFrame];
- [self updateContext];
- }
- #pragma mark ---- OSXTorqueView OpenGL Handling ----
- //-----------------------------------------------------------------------------
- // Allocates a new NSOpenGLContext with the specified pixel format and makes
- // it the current OpenGL context automatically
- - (void)createContextWithPixelFormat:(NSOpenGLPixelFormat *)pixelFormat
- {
- _openGLContext = [[[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:nil] retain];
- AssertFatal(_openGLContext, "We could not create a valid NSOpenGL rendering context.");
- [_openGLContext setView:self];
- [_openGLContext makeCurrentContext];
- _contextInitialized = YES;
- }
- //-----------------------------------------------------------------------------
- // Clears the current context, releases control from this view, and deallocates
- // the NSOpenGLContext
- - (void)clearContext
- {
- if (_openGLContext != nil)
- {
- [NSOpenGLContext clearCurrentContext];
- [_openGLContext clearDrawable];
- [_openGLContext release];
- _openGLContext = nil;
- _contextInitialized = NO;
- }
- }
- //-----------------------------------------------------------------------------
- // Perform an update on the NSOpenGLContext, which will match the surface
- // size to the view's frame
- - (void)updateContext
- {
- if (_openGLContext != nil)
- [_openGLContext update];
- }
- //-----------------------------------------------------------------------------
- // Perform a swap buffer if the NSOpenGLContext is initialized
- - (void)flushBuffer
- {
- if (_openGLContext != nil)
- [_openGLContext flushBuffer];
- }
- //-----------------------------------------------------------------------------
- - (int)getVerticalSync
- {
- if (_openGLContext != nil)
- {
- GLint swapInterval = 0;
- [_openGLContext getValues:&swapInterval forParameter:NSOpenGLCPSwapInterval];
- return swapInterval;
- }
- else
- {
- return 0;
- }
- }
- //-----------------------------------------------------------------------------
- - (void)setVerticalSync:(bool)sync
- {
- if (_openGLContext != nil)
- {
- GLint swapInterval = sync ? 1 : 0;
- [_openGLContext setValues:&swapInterval forParameter:NSOpenGLCPSwapInterval];
- }
- }
- #pragma mark ---- OSXTorqueView Input Handling ----
- //-----------------------------------------------------------------------------
- // Fills out the modifiers based on key presses such as shift, alt, etc
- - (void)getModifierKey:(U32&)modifiers event:(NSEvent *)event;
- {
- /*
- NSAlphaShiftKeyMask = 1 << 16,
- NSShiftKeyMask = 1 << 17,
- NSControlKeyMask = 1 << 18,
- NSAlternateKeyMask = 1 << 19,
- NSCommandKeyMask = 1 << 20,
- NSNumericPadKeyMask = 1 << 21,
- NSHelpKeyMask = 1 << 22,
- NSFunctionKeyMask = 1 << 23,
- NSDeviceIndependentModifierFlagsMask = 0xffff0000U
- */
-
- U32 keyMods = (U32)[event modifierFlags];
-
- if (keyMods & NSEventModifierFlagShift)
- modifiers |= SI_SHIFT;
-
- if (keyMods & NSEventModifierFlagCommand)
- modifiers |= SI_ALT;
-
- if (keyMods & NSEventModifierFlagOption)
- modifiers |= SI_MAC_OPT;
-
- if (keyMods & NSEventModifierFlagControl)
- modifiers |= SI_CTRL;
- }
- //-----------------------------------------------------------------------------
- // Processes mouse up and down events, posts to the event system
- - (void)processMouseButton:(NSEvent *)event button:(KeyCodes)button action:(U8)action
- {
- // Get the click location
- NSPoint clickLocation = [self convertPoint:[event locationInWindow] fromView:nil];
-
- NSRect bounds = [self bounds];
-
- clickLocation.y = bounds.size.height - clickLocation.y;
-
- // Move the cursor
- Canvas->setCursorPos(Point2I((S32) clickLocation.x, (S32) clickLocation.y));
-
- // Grab any modifiers
- U32 modifiers = 0;
- [self getModifierKey:modifiers event:event];
-
- // Build the input event
- InputEvent torqueEvent;
-
- torqueEvent.deviceType = MouseDeviceType;
- torqueEvent.deviceInst = 0;
- torqueEvent.objType = SI_BUTTON;
- torqueEvent.objInst = button;
- torqueEvent.modifier = modifiers;
- torqueEvent.ascii = 0;
- torqueEvent.action = action;
- if (action == SI_BREAK)
- torqueEvent.fValues[0] = 0.0;
- else
- torqueEvent.fValues[0] = 1.0;
-
- // Post the input event
- Game->postEvent(torqueEvent);
- }
- //-----------------------------------------------------------------------------
- // Processes keyboard up and down events, posts to the event system
- - (void)processKeyEvent:(NSEvent *)event make:(BOOL)make
- {
- // If input and keyboard are enabled
- if (!Input::isEnabled() && !Input::isKeyboardEnabled())
- return;
-
- unichar chars = [[event charactersIgnoringModifiers] characterAtIndex:0];
-
- // Get the key code for the event
- U32 keyCode = [event keyCode];
-
- U16 objInst = TranslateOSKeyCode(keyCode);
-
- // Grab any modifiers
- U32 modifiers = 0;
- [self getModifierKey:modifiers event:event];
-
- // Build the input event
- InputEvent torqueEvent;
-
- F32 fValue = 1.0f;
- U8 action = SI_MAKE;
-
- if (!make)
- {
- action = SI_BREAK;
- fValue = 0.0f;
- }
- else if(make && [event isARepeat])
- {
- action = SI_REPEAT;
- }
-
- torqueEvent.deviceType = KeyboardDeviceType;
- torqueEvent.deviceInst = 0;
- torqueEvent.objType = SI_KEY;
- torqueEvent.objInst = objInst;
- torqueEvent.modifier = modifiers;
- torqueEvent.ascii = 0;
- torqueEvent.action = action;
- torqueEvent.fValues[0] = fValue;
- torqueEvent.ascii = chars;
-
- // Post the input event
- Game->postEvent(torqueEvent);
- }
- //-----------------------------------------------------------------------------
- // Default mouseDown override
- - (void)mouseDown:(NSEvent *)event
- {
- if (!Input::isEnabled() && !Input::isMouseEnabled())
- return;
-
- [self processMouseButton:event button:KEY_BUTTON0 action:SI_MAKE];
- }
- //-----------------------------------------------------------------------------
- // Default rightMouseDown override
- - (void)rightMouseDown:(NSEvent *)event
- {
- if (!Input::isEnabled() && !Input::isMouseEnabled())
- return;
-
- [self processMouseButton:event button:KEY_BUTTON1 action:SI_MAKE];
- }
- //-----------------------------------------------------------------------------
- // Default otherMouseDown override
- - (void)otherMouseDown:(NSEvent *)event
- {
- if (!Input::isEnabled() && !Input::isMouseEnabled())
- return;
-
- [self processMouseButton:event button:KEY_BUTTON2 action:SI_MAKE];
- }
- //-----------------------------------------------------------------------------
- // Default mouseUp override
- - (void)mouseUp:(NSEvent *)event
- {
- if (!Input::isEnabled() && !Input::isMouseEnabled())
- return;
-
- [self processMouseButton:event button:KEY_BUTTON0 action:SI_BREAK];
- }
- //-----------------------------------------------------------------------------
- // Default rightMouseUp override
- - (void)rightMouseUp:(NSEvent *)event
- {
- if (!Input::isEnabled() && !Input::isMouseEnabled())
- return;
-
- [self processMouseButton:event button:KEY_BUTTON1 action:SI_BREAK];
- }
- //-----------------------------------------------------------------------------
- // Default otherMouseUp override
- - (void)otherMouseUp:(NSEvent *)event
- {
- if (!Input::isEnabled() && !Input::isMouseEnabled())
- return;
-
- [self processMouseButton:event button:KEY_BUTTON2 action:SI_BREAK];
- }
- //-----------------------------------------------------------------------------
- - (void)mouseEntered:(NSEvent *)event
- {
- if (!Canvas->getUseNativeCursor())
- {
- Input::setCursorState(false);
- }
- }
- -(void)mouseExited:(NSEvent *)event
- {
- Input::setCursorState(true);
- }
- // Default otherMouseDown override
- - (void)mouseMoved:(NSEvent *)event
- {
- if (!Input::isEnabled() && !Input::isMouseEnabled())
- return;
-
- // Get the mouse location
- NSPoint location = [self convertPoint:[event locationInWindow] fromView:nil];
-
- // NSViews increase the Y the higher the cursor
- // Torque needs that to be inverted
- NSRect bounds = [self bounds];
- location.y = bounds.size.height - location.y;
-
- // Grab any modifiers
- U32 modifiers = 0;
- [self getModifierKey:modifiers event:event];
-
-
- // Move the cursor
- Canvas->setCursorPos(Point2I((S32) location.x, (S32) location.y));
-
- // Build the mouse event
- MouseMoveEvent TorqueEvent;
- TorqueEvent.xPos = (S32) location.x;
- TorqueEvent.yPos = (S32) location.y;
- TorqueEvent.modifier = modifiers;
-
- // Post the event
- Game->postEvent(TorqueEvent);
- }
- //-----------------------------------------------------------------------------
- // Default mouseDragged override
- - (void)mouseDragged:(NSEvent *)event
- {
- if (!Input::isEnabled() && !Input::isMouseEnabled())
- return;
-
- [self mouseMoved:event];
- }
- //-----------------------------------------------------------------------------
- // Default rightMouseDragged override
- - (void)rightMouseDragged:(NSEvent *)event
- {
- if (!Input::isEnabled() && !Input::isMouseEnabled())
- return;
-
- [self mouseMoved:event];
- }
- //-----------------------------------------------------------------------------
- // Default otherMouseDragged override
- - (void)otherMouseDragged:(NSEvent *)event
- {
- if (!Input::isEnabled() && !Input::isMouseEnabled())
- return;
-
- [self mouseMoved:event];
- }
- //-----------------------------------------------------------------------------
- // Default scrollWheel override
- - (void)scrollWheel:(NSEvent *)event
- {
- if (!Input::isEnabled() && !Input::isMouseEnabled())
- return;
-
- F32 deltaY = [event deltaY];
-
- if (deltaY == 0)
- return;
-
- // Grab any modifiers
- U32 modifiers = 0;
- [self getModifierKey:modifiers event:event];
-
- InputEvent torqueEvent;
-
- torqueEvent.deviceType = MouseDeviceType;
- torqueEvent.deviceInst = 0;
- torqueEvent.objType = SI_ZAXIS;
- torqueEvent.objInst = 0;
- torqueEvent.modifier = modifiers;
- torqueEvent.ascii = 0;
- torqueEvent.action = SI_MOVE;
- torqueEvent.fValues[0] = deltaY;
- Game->postEvent(torqueEvent);
- }
- //-----------------------------------------------------------------------------
- // Default keyDown override
- - (void)keyDown:(NSEvent *)event
- {
- // If input and keyboard are enabled
- if (!Input::isEnabled() && !Input::isKeyboardEnabled())
- return;
-
- [self processKeyEvent:event make:YES];
- }
- //-----------------------------------------------------------------------------
- // Default keyUp override
- - (void)keyUp:(NSEvent *)event
- {
- // If input and keyboard are enabled
- if (!Input::isEnabled() && !Input::isKeyboardEnabled())
- return;
-
- [self processKeyEvent:event make:NO];
- }
- @end
|