Ticket #31974: patch-src_mac_CocoaMouse.mm.diff

File patch-src_mac_CocoaMouse.mm.diff, 11.3 KB (added by marin.saric@…, 12 years ago)
  • src/mac/CocoaMouse.mm

     
     1/*
     2 The zlib/libpng License
     3 
     4 Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
     5 
     6 This software is provided 'as-is', without any express or implied warranty. In no event will
     7 the authors be held liable for any damages arising from the use of this software.
     8 
     9 Permission is granted to anyone to use this software for any purpose, including commercial
     10 applications, and to alter it and redistribute it freely, subject to the following
     11 restrictions:
     12 
     13 1. The origin of this software must not be misrepresented; you must not claim that
     14 you wrote the original software. If you use this software in a product,
     15 an acknowledgment in the product documentation would be appreciated but is
     16 not required.
     17 
     18 2. Altered source versions must be plainly marked as such, and must not be
     19 misrepresented as being the original software.
     20 
     21 3. This notice may not be removed or altered from any source distribution.
     22 */
     23#include "mac/CocoaMouse.h"
     24#include "mac/CocoaInputManager.h"
     25#include "mac/CocoaHelpers.h"
     26#include "OISException.h"
     27#include "OISEvents.h"
     28
     29using namespace OIS;
     30
     31//-------------------------------------------------------------------//
     32CocoaMouse::CocoaMouse( InputManager* creator, bool buffered )
     33        : Mouse(creator->inputSystemName(), buffered, 0, creator)
     34{
     35    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
     36
     37        CocoaInputManager *man = static_cast<CocoaInputManager*>(mCreator);
     38    mResponder = [[CocoaMouseView alloc] initWithFrame:[[man->_getWindow() contentView] frame]];
     39    if(!mResponder)
     40        OIS_EXCEPT( E_General, "CocoaMouseView::CocoaMouseView >> Error creating event responder" );
     41   
     42    [[man->_getWindow() contentView] addSubview:mResponder];
     43    [mResponder setOISMouseObj:this];
     44   
     45        static_cast<CocoaInputManager*>(mCreator)->_setMouseUsed(true);
     46
     47    [pool drain];
     48}
     49
     50CocoaMouse::~CocoaMouse()
     51{
     52        // Restore Mouse
     53//      CGAssociateMouseAndMouseCursorPosition(true);
     54        CGDisplayShowCursor(kCGDirectMainDisplay);
     55
     56    if (mResponder)
     57    {
     58        [mResponder release];
     59        mResponder = nil;
     60    }
     61   
     62        static_cast<CocoaInputManager*>(mCreator)->_setMouseUsed(false);
     63}
     64
     65void CocoaMouse::_initialize()
     66{
     67        mState.clear();
     68        CGAssociateMouseAndMouseCursorPosition(false);
     69}
     70
     71void CocoaMouse::setBuffered( bool buffered )
     72{
     73        mBuffered = buffered;
     74}
     75
     76void CocoaMouse::capture()
     77{
     78    [mResponder capture];
     79}
     80
     81@implementation CocoaMouseView
     82
     83- (id)initWithFrame:(NSRect)frame
     84{
     85    self = [super initWithFrame:frame];
     86    if (self) {
     87        mTempState.clear();
     88        mMouseWarped = false;
     89        mNeedsToRegainFocus = false;
     90       
     91        // Hide OS Mouse
     92        CGDisplayHideCursor(kCGDirectMainDisplay);
     93
     94        NSRect clipRect = NSMakeRect(0.0f, 0.0f, 0.0f, 0.0f);
     95        clipRect = [[[self window] contentView] frame];
     96
     97        CGPoint warpPoint;
     98                warpPoint.x = (((frame.origin.x + frame.size.width) - frame.origin.x) / 2) + frame.origin.x;
     99                warpPoint.y = (((frame.origin.y + frame.size.height) - frame.origin.y) / 2) - frame.origin.y;
     100//        warpPoint = CGPointMake(clipRect.size.height, clipRect.size.width);
     101        CGDisplayMoveCursorToPoint(kCGDirectMainDisplay, warpPoint);
     102
     103        // Use NSTrackingArea to track mouse move events
     104        NSTrackingAreaOptions trackingOptions =
     105            NSTrackingMouseMoved | NSTrackingEnabledDuringMouseDrag |
     106            NSTrackingMouseEnteredAndExited | NSTrackingActiveInActiveApp;
     107       
     108        NSDictionary *trackerData = [NSDictionary dictionaryWithObjectsAndKeys:
     109                                     [NSNumber numberWithInt:0], @"OISMouseTrackingKey", nil];
     110        NSTrackingArea *trackingArea = [[NSTrackingArea alloc]
     111                                        initWithRect:[self frame]// in our case track the entire view
     112                                        options:trackingOptions
     113                                        owner:self
     114                                        userInfo:trackerData];
     115        [self addTrackingArea:trackingArea];
     116        [[self window] setAcceptsMouseMovedEvents:YES];
     117        [trackingArea release];
     118    }
     119    return self;
     120}
     121
     122- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent
     123{
     124    return YES;
     125}
     126
     127- (void)setOISMouseObj:(CocoaMouse *)obj
     128{
     129    oisMouseObj = obj;
     130}
     131
     132- (void)capture
     133{
     134        MouseState *state = oisMouseObj->getMouseStatePtr();
     135    state->X.rel = 0;
     136    state->Y.rel = 0;
     137    state->Z.rel = 0;
     138   
     139        if(mTempState.X.rel || mTempState.Y.rel || mTempState.Z.rel)
     140        {
     141//              NSLog(@"%i %i %i", mTempState.X.rel, mTempState.Y.rel, mTempState.Z.rel);
     142       
     143                // Set new relative motion values
     144                state->X.rel = mTempState.X.rel;
     145                state->Y.rel = mTempState.Y.rel;
     146                state->Z.rel = mTempState.Z.rel;
     147               
     148                // Update absolute position
     149                state->X.abs += mTempState.X.rel;
     150                state->Y.abs += mTempState.Y.rel;
     151               
     152                if(state->X.abs > state->width)
     153                        state->X.abs = state->width;
     154                else if(state->X.abs < 0)
     155                        state->X.abs = 0;
     156       
     157                if(state->Y.abs > state->height)
     158                        state->Y.abs = state->height;
     159                else if(state->Y.abs < 0)
     160                        state->Y.abs = 0;
     161       
     162                state->Z.abs += mTempState.Z.rel;
     163               
     164                //Fire off event
     165        if ( oisMouseObj->buffered() && oisMouseObj->getEventCallback() )
     166                        oisMouseObj->getEventCallback()->mouseMoved(MouseEvent(oisMouseObj, *state));
     167        }
     168   
     169        mTempState.clear();
     170}
     171
     172#pragma mark Left Mouse Event overrides
     173- (void)mouseDown:(NSEvent *)theEvent
     174{
     175    int mouseButton = MB_Left;
     176    NSEventType type = [theEvent type];
     177    MouseState *state = oisMouseObj->getMouseStatePtr();
     178
     179    if(mNeedsToRegainFocus)
     180        return;
     181
     182    if((type == NSLeftMouseDown) && ([theEvent modifierFlags] & NSAlternateKeyMask))
     183    {
     184        mouseButton = MB_Middle;
     185    }
     186    else if((type == NSLeftMouseDown) && ([theEvent modifierFlags] & NSControlKeyMask))
     187    {
     188        mouseButton = MB_Right;
     189    }
     190    else if(type == NSLeftMouseDown)
     191    {
     192        mouseButton = MB_Left;
     193    }
     194    state->buttons |= 1 << mouseButton;
     195    if ( oisMouseObj->buffered() && oisMouseObj->getEventCallback() )
     196        oisMouseObj->getEventCallback()->mousePressed( MouseEvent( oisMouseObj, *state ), (MouseButtonID)mouseButton );
     197}
     198
     199- (void)mouseUp:(NSEvent *)theEvent {
     200    int mouseButton = MB_Left;
     201    NSEventType type = [theEvent type];
     202    MouseState *state = oisMouseObj->getMouseStatePtr();
     203
     204    if((type == NSLeftMouseUp) && ([theEvent modifierFlags] & NSAlternateKeyMask))
     205    {
     206        mouseButton = MB_Middle;
     207    }
     208    else if((type == NSLeftMouseUp) && ([theEvent modifierFlags] & NSControlKeyMask))
     209    {
     210        mouseButton = MB_Right;
     211    }
     212    else if(type == NSLeftMouseUp)
     213    {
     214        mouseButton = MB_Left;
     215    }
     216    state->buttons &= ~(1 << mouseButton);
     217
     218    if ( oisMouseObj->buffered() && oisMouseObj->getEventCallback() )
     219        oisMouseObj->getEventCallback()->mouseReleased( MouseEvent( oisMouseObj, *state ), (MouseButtonID)mouseButton );
     220}
     221
     222
     223- (void)mouseDragged:(NSEvent *)theEvent
     224{
     225    CGPoint delta = CGPointMake([theEvent deltaX], [theEvent deltaY]);
     226    if(mNeedsToRegainFocus)
     227        return;
     228   
     229    // Relative positioning
     230    if(!mMouseWarped)
     231    {
     232        mTempState.X.rel += delta.x;
     233        mTempState.Y.rel += delta.y;
     234    }
     235   
     236    mMouseWarped = false;
     237}
     238
     239#pragma mark Right Mouse Event overrides
     240- (void)rightMouseDown:(NSEvent *)theEvent
     241{
     242    int mouseButton = MB_Right;
     243    NSEventType type = [theEvent type];
     244    MouseState *state = oisMouseObj->getMouseStatePtr();
     245   
     246    if(mNeedsToRegainFocus)
     247        return;
     248   
     249    if(type == NSRightMouseDown)
     250    {   
     251        state->buttons |= 1 << mouseButton;
     252    }
     253
     254    if ( oisMouseObj->buffered() && oisMouseObj->getEventCallback() )
     255        oisMouseObj->getEventCallback()->mousePressed( MouseEvent( oisMouseObj, *state ), (MouseButtonID)mouseButton );
     256}
     257
     258- (void)rightMouseUp:(NSEvent *)theEvent {
     259    int mouseButton = MB_Right;
     260    NSEventType type = [theEvent type];
     261    MouseState *state = oisMouseObj->getMouseStatePtr();
     262   
     263    if(type == NSRightMouseUp)
     264    {   
     265        state->buttons &= ~(1 << mouseButton);
     266    }
     267
     268    if ( oisMouseObj->buffered() && oisMouseObj->getEventCallback() )
     269        oisMouseObj->getEventCallback()->mouseReleased( MouseEvent( oisMouseObj, *state ), (MouseButtonID)mouseButton );
     270}
     271
     272- (void)rightMouseDragged:(NSEvent *)theEvent
     273{
     274    CGPoint delta = CGPointMake([theEvent deltaX], [theEvent deltaY]);
     275    if(mNeedsToRegainFocus)
     276        return;
     277   
     278    // Relative positioning
     279    if(!mMouseWarped)
     280    {
     281        mTempState.X.rel += delta.x;
     282        mTempState.Y.rel += delta.y;
     283    }
     284   
     285    mMouseWarped = false;
     286}
     287
     288#pragma mark Other Mouse Event overrides
     289- (void)otherMouseDown:(NSEvent *)theEvent
     290{
     291    int mouseButton = MB_Middle;
     292    NSEventType type = [theEvent type];
     293    MouseState *state = oisMouseObj->getMouseStatePtr();
     294   
     295    if(mNeedsToRegainFocus)
     296        return;
     297   
     298    if(type == NSOtherMouseDown)
     299    {
     300        state->buttons |= 1 << mouseButton;
     301    }
     302
     303    if ( oisMouseObj->buffered() && oisMouseObj->getEventCallback() )
     304        oisMouseObj->getEventCallback()->mousePressed( MouseEvent( oisMouseObj, *state ), (MouseButtonID)mouseButton );
     305}
     306
     307- (void)otherMouseUp:(NSEvent *)theEvent {
     308    int mouseButton = MB_Middle;
     309    NSEventType type = [theEvent type];
     310    MouseState *state = oisMouseObj->getMouseStatePtr();
     311   
     312    if(type == NSOtherMouseUp)
     313    {
     314        state->buttons &= ~(1 << mouseButton);
     315    }
     316
     317    if ( oisMouseObj->buffered() && oisMouseObj->getEventCallback() )
     318        oisMouseObj->getEventCallback()->mouseReleased( MouseEvent( oisMouseObj, *state ), (MouseButtonID)mouseButton );
     319}
     320
     321- (void)otherMouseDragged:(NSEvent *)theEvent
     322{
     323    CGPoint delta = CGPointMake([theEvent deltaX], [theEvent deltaY]);
     324    if(mNeedsToRegainFocus)
     325        return;
     326   
     327    // Relative positioning
     328    if(!mMouseWarped)
     329    {
     330        mTempState.X.rel += delta.x;
     331        mTempState.Y.rel += delta.y;
     332    }
     333   
     334    mMouseWarped = false;
     335}
     336
     337- (void)scrollWheel:(NSEvent *)theEvent
     338{
     339    if([theEvent deltaY] != 0.0)
     340        mTempState.Z.rel += ([theEvent deltaY] * 60);
     341}
     342
     343- (void)mouseMoved:(NSEvent *)theEvent
     344{
     345    CGPoint delta = CGPointMake([theEvent deltaX], [theEvent deltaY]);
     346    if(mNeedsToRegainFocus)
     347        return;
     348   
     349    // Relative positioning
     350    if(!mMouseWarped)
     351    {
     352        mTempState.X.rel += delta.x;
     353        mTempState.Y.rel += delta.y;
     354    }
     355   
     356    mMouseWarped = false;
     357}
     358
     359- (void)mouseEntered:(NSEvent *)theEvent
     360{
     361        CGDisplayHideCursor(kCGDirectMainDisplay);
     362        CGAssociateMouseAndMouseCursorPosition(false);
     363    if(!mMouseWarped)
     364    {
     365        NSPoint pos = [[self window] mouseLocationOutsideOfEventStream];
     366        NSRect frame = [[[self window] contentView] frame];
     367
     368        // Clear the previous mouse state
     369        MouseState *state = oisMouseObj->getMouseStatePtr();
     370        state->clear();
     371
     372        // Cocoa's coordinate system has the origin in the bottom left so we need to transform the height
     373        mTempState.X.rel = pos.x;
     374        mTempState.Y.rel = frame.size.height - pos.y;
     375    }
     376}
     377
     378- (void)mouseExited:(NSEvent *)theEvent
     379{
     380        CGDisplayShowCursor(kCGDirectMainDisplay);
     381        CGAssociateMouseAndMouseCursorPosition(true);
     382}
     383
     384@end