GHOST Cocoa: some changes to Y coordinate conversion in previous commit,
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Sat, 25 Jun 2011 02:10:13 +0000 (02:10 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Sat, 25 Jun 2011 02:10:13 +0000 (02:10 +0000)
to fix continuous grab being broken (bug report #27760).

intern/ghost/intern/GHOST_SystemCocoa.h
intern/ghost/intern/GHOST_SystemCocoa.mm
intern/ghost/intern/GHOST_WindowCocoa.h
intern/ghost/intern/GHOST_WindowCocoa.mm

index 4779f1f056cf1db90b8f9bd880bdca558ef4f723..e7a8178a38259a2910a44e9b0901c3a3df280232 100644 (file)
@@ -272,17 +272,6 @@ protected:
         */
        GHOST_TSuccess setMouseCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y);
 
-       /**
-        * Push cursor event, with coordinate conversion to follow GHOST convention.
-        */
-       void pushEventCursor(GHOST_TUns64 msec, GHOST_TEventType type, GHOST_IWindow* window, GHOST_TInt32 x, GHOST_TInt32 y);
-
-       /**
-        * Push trackpad event, with coordinate conversion to follow GHOST convention.
-        */
-       void pushEventTrackpad(GHOST_TUns64 msec, GHOST_IWindow* window, GHOST_TTrackpadEventSubTypes subtype,
-               GHOST_TInt32 x, GHOST_TInt32 y, GHOST_TInt32 deltaX, GHOST_TInt32 deltaY);
-
        /** Start time at initialization. */
        GHOST_TUns64 m_start_time;
        
index 63c8f10971bc4c726d999180b2fa59ce2f5d598e..2649929713a449d255499e931ad024d68d4494e7 100644 (file)
@@ -806,37 +806,11 @@ GHOST_TSuccess GHOST_SystemCocoa::getCursorPosition(GHOST_TInt32& x, GHOST_TInt3
     return GHOST_kSuccess;
 }
 
-void GHOST_SystemCocoa::pushEventCursor(GHOST_TUns64 msec, GHOST_TEventType type, GHOST_IWindow* window, GHOST_TInt32 x, GHOST_TInt32 y)
-{
-       GHOST_Rect cBnds;
-       window->getClientBounds(cBnds);
-       y = (cBnds.getHeight() - 1) - y;
-
-       GHOST_TInt32 screen_x, screen_y;
-       window->clientToScreen(x, y, screen_x, screen_y);
-
-       pushEvent(new GHOST_EventCursor(msec, type, window, screen_x, screen_y));
-}
-
-void GHOST_SystemCocoa::pushEventTrackpad(GHOST_TUns64 msec, GHOST_IWindow* window, GHOST_TTrackpadEventSubTypes subtype, GHOST_TInt32 x, GHOST_TInt32 y, GHOST_TInt32 deltaX, GHOST_TInt32 deltaY)
-{
-       GHOST_Rect cBnds;
-       window->getClientBounds(cBnds);
-       y = (cBnds.getHeight() - 1) - y;
-       deltaY = -deltaY;
-
-       GHOST_TInt32 screen_x, screen_y;
-       window->clientToScreen(x, y, screen_x, screen_y);
-
-       pushEvent(new GHOST_EventTrackpad(msec, window, subtype, screen_x, screen_y, deltaX, deltaY));
-}
-
 /**
  * @note : expect Cocoa screen coordinates
  */
 GHOST_TSuccess GHOST_SystemCocoa::setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y)
 {
-       GHOST_TInt32 wx,wy;
        GHOST_WindowCocoa* window = (GHOST_WindowCocoa*)m_windowManager->getActiveWindow();
        if (!window) return GHOST_kFailure;
 
@@ -847,8 +821,7 @@ GHOST_TSuccess GHOST_SystemCocoa::setCursorPosition(GHOST_TInt32 x, GHOST_TInt32
        CGAssociateMouseAndMouseCursorPosition(true);
        
        //Force mouse move event (not pushed by Cocoa)
-       window->screenToClient(x, y, wx, wy);
-       pushEventCursor(getMilliSeconds(), GHOST_kEventCursorMove, window, wx,wy);
+       pushEvent(new GHOST_EventCursor(getMilliSeconds(), GHOST_kEventCursorMove, window, x, y));
        m_outsideLoopEventProcessed = true;
        
        return GHOST_kSuccess;
@@ -1460,9 +1433,9 @@ GHOST_TSuccess GHOST_SystemCocoa::handleTabletEvent(void *eventPtr, short eventT
 GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
 {
        NSEvent *event = (NSEvent *)eventPtr;
-    GHOST_Window* window;
+    GHOST_WindowCocoa* window;
        
-       window = (GHOST_Window*)m_windowManager->getWindowAssociatedWithOSWindow((void*)[event window]);
+       window = (GHOST_WindowCocoa*)m_windowManager->getWindowAssociatedWithOSWindow((void*)[event window]);
        if (!window) {
                //printf("\nW failure for event 0x%x",[event type]);
                return GHOST_kFailure;
@@ -1526,7 +1499,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
                                switch (window->getCursorGrabMode()) {
                                        case GHOST_kGrabHide: //Cursor hidden grab operation : no cursor move
                                        {
-                                               GHOST_TInt32 x_warp, y_warp, x_accum, y_accum;
+                                               GHOST_TInt32 x_warp, y_warp, x_accum, y_accum, x, y;
                                                
                                                window->getCursorGrabInitPos(x_warp, y_warp);
                                                
@@ -1535,7 +1508,8 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
                                                y_accum += -[event deltaY]; //Strange Apple implementation (inverted coordinates for the deltaY) ...
                                                window->setCursorGrabAccum(x_accum, y_accum);
                                                
-                                               pushEventCursor([event timestamp]*1000, GHOST_kEventCursorMove, window, x_warp+x_accum, y_warp+y_accum);
+                                               window->clientToScreenIntern(x_warp+x_accum, y_warp+y_accum, x, y);
+                                               pushEvent(new GHOST_EventCursor([event timestamp]*1000, GHOST_kEventCursorMove, window, x, y));
                                        }
                                                break;
                                        case GHOST_kGrabWrap: //Wrap cursor at area/window boundaries
@@ -1543,19 +1517,16 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
                                                NSPoint mousePos = [event locationInWindow];
                                                GHOST_TInt32 x_mouse= mousePos.x;
                                                GHOST_TInt32 y_mouse= mousePos.y;
-                                               GHOST_TInt32 x_accum, y_accum, x_cur, y_cur;
-                                               GHOST_Rect bounds, windowBounds, correctedBounds;
+                                               GHOST_TInt32 x_accum, y_accum, x_cur, y_cur, x, y;
+                                               GHOST_Rect bounds, correctedBounds;
                                                
                                                /* fallback to window bounds */
                                                if(window->getCursorGrabBounds(bounds)==GHOST_kFailure)
                                                        window->getClientBounds(bounds);
                                                
                                                //Switch back to Cocoa coordinates orientation (y=0 at botton,the same as blender internal btw!), and to client coordinates
-                                               window->getClientBounds(windowBounds);
-                                               window->screenToClient(bounds.m_l,bounds.m_b, correctedBounds.m_l, correctedBounds.m_t);
-                                               window->screenToClient(bounds.m_r, bounds.m_t, correctedBounds.m_r, correctedBounds.m_b);
-                                               correctedBounds.m_b = (windowBounds.m_b - windowBounds.m_t) - correctedBounds.m_b;
-                                               correctedBounds.m_t = (windowBounds.m_b - windowBounds.m_t) - correctedBounds.m_t;
+                                               window->screenToClient(bounds.m_l, bounds.m_b, correctedBounds.m_l, correctedBounds.m_b);
+                                               window->screenToClient(bounds.m_r, bounds.m_t, correctedBounds.m_r, correctedBounds.m_t);
                                                
                                                //Update accumulation counts
                                                window->getCursorGrabAccum(x_accum, y_accum);
@@ -1574,19 +1545,24 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
                                                m_cursorDelta_y = y_mouse-mousePos.y;
                                                
                                                //Set new cursor position
-                                               window->clientToScreen(x_mouse, y_mouse, x_cur, y_cur);
+                                               window->clientToScreenIntern(x_mouse, y_mouse, x_cur, y_cur);
                                                setMouseCursorPosition(x_cur, y_cur); /* wrap */
                                                
                                                //Post event
                                                window->getCursorGrabInitPos(x_cur, y_cur);
-                                               pushEventCursor([event timestamp]*1000, GHOST_kEventCursorMove, window, x_cur + x_accum, y_cur + y_accum);
+                                               window->clientToScreenIntern(x_cur + x_accum, y_cur + y_accum, x, y);
+                                               pushEvent(new GHOST_EventCursor([event timestamp]*1000, GHOST_kEventCursorMove, window, x, y));
                                        }
                                                break;
                                        default:
                                        {
                                                //Normal cursor operation: send mouse position in window
                                                NSPoint mousePos = [event locationInWindow];
-                                               pushEventCursor([event timestamp]*1000, GHOST_kEventCursorMove, window, mousePos.x, mousePos.y);
+                                               GHOST_TInt32 x, y;
+
+                                               window->clientToScreenIntern(mousePos.x, mousePos.y, x, y);
+                                               pushEvent(new GHOST_EventCursor([event timestamp]*1000, GHOST_kEventCursorMove, window, x, y));
+
                                                m_cursorDelta_x=0;
                                                m_cursorDelta_y=0; //Mouse motion occurred between two cursor warps, so we can reset the delta counter
                                        }
@@ -1608,6 +1584,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
                                }
                                else {
                                        NSPoint mousePos = [event locationInWindow];
+                                       GHOST_TInt32 x, y;
                                        double dx = [event deltaX];
                                        double dy = -[event deltaY];
                                        
@@ -1624,7 +1601,10 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
                                        if (dy<0.0) dy-=0.5; else dy+=0.5;
                                        if (dy< -deltaMax) dy= -deltaMax; else if (dy>deltaMax) dy=deltaMax;
 
-                                       pushEventTrackpad([event timestamp]*1000, window, GHOST_kTrackpadEventScroll, mousePos.x, mousePos.y, dx, dy);
+                                       window->clientToScreenIntern(mousePos.x, mousePos.y, x, y);
+                                       dy = -dy;
+
+                                       pushEvent(new GHOST_EventTrackpad([event timestamp]*1000, window, GHOST_kTrackpadEventScroll, x, y, dx, dy));
                                }
                        }
                        break;
@@ -1632,16 +1612,20 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
                case NSEventTypeMagnify:
                        {
                                NSPoint mousePos = [event locationInWindow];
-                               pushEventTrackpad([event timestamp]*1000, window, GHOST_kTrackpadEventMagnify, mousePos.x, mousePos.y,
-                                                                                                 [event magnification]*250.0 + 0.1, 0);
+                               GHOST_TInt32 x, y;
+                               window->clientToScreenIntern(mousePos.x, mousePos.y, x, y);
+                               pushEvent(new GHOST_EventTrackpad([event timestamp]*1000, window, GHOST_kTrackpadEventMagnify, x, y,
+                                                                                                 [event magnification]*250.0 + 0.1, 0));
                        }
                        break;
 
                case NSEventTypeRotate:
                        {
                                NSPoint mousePos = [event locationInWindow];
-                               pushEventTrackpad([event timestamp]*1000, window, GHOST_kTrackpadEventRotate, mousePos.x, mousePos.y,
-                                                                                                 -[event rotation] * 5.0, 0);
+                               GHOST_TInt32 x, y;
+                               window->clientToScreenIntern(mousePos.x, mousePos.y, x, y);
+                               pushEvent(new GHOST_EventTrackpad([event timestamp]*1000, window, GHOST_kTrackpadEventRotate, x, y,
+                                                                                                 -[event rotation] * 5.0, 0));
                        }
                case NSEventTypeBeginGesture:
                        m_isGestureInProgress = true;
index b5485c6bcef908318b0f1be719cbc7d1dda5f1ad..e6de2bf07b4ee727b3d94887350152f2985b7293 100644 (file)
@@ -180,6 +180,26 @@ public:
         */
        virtual void clientToScreen(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const;
 
+       /**
+        * Converts a point in screen coordinates to client rectangle coordinates
+        * but without the y coordinate conversion needed for ghost compatibility.
+        * @param inX   The x-coordinate in the client rectangle.
+        * @param inY   The y-coordinate in the client rectangle.
+        * @param outX  The x-coordinate on the screen.
+        * @param outY  The y-coordinate on the screen.
+        */
+       void clientToScreenIntern(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const;
+
+       /**
+        * Converts a point in screen coordinates to client rectangle coordinates,
+        * but without the y coordinate conversion needed for ghost compatibility.
+        * @param inX   The x-coordinate in the client rectangle.
+        * @param inY   The y-coordinate in the client rectangle.
+        * @param outX  The x-coordinate on the screen.
+        * @param outY  The y-coordinate on the screen.
+        */
+       void screenToClientIntern(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const;
+
        /**
         * Gets the screen the window is displayed in
         * @return The NSScreen object
index 224980c6a11612598d8b3e9b2ba8ad5ff1cf8a37..93bc87b2458b48e67ff71bac643aa50cb1bfe5dc 100644 (file)
@@ -691,17 +691,8 @@ GHOST_TWindowState GHOST_WindowCocoa::getState() const
 void GHOST_WindowCocoa::screenToClient(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const
 {
        GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::screenToClient(): window invalid")
-       
-       NSPoint screenCoord;
-       NSPoint baseCoord;
-       
-       screenCoord.x = inX;
-       screenCoord.y = inY;
-       
-       baseCoord = [m_window convertScreenToBase:screenCoord];
-       
-       outX = baseCoord.x;
-       outY = baseCoord.y;
+
+       screenToClientIntern(inX, inY, outX, outY);
 
        /* switch y to match ghost convention */
        GHOST_Rect cBnds;
@@ -718,7 +709,26 @@ void GHOST_WindowCocoa::clientToScreen(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST
        GHOST_Rect cBnds;
        getClientBounds(cBnds);
        inY = (cBnds.getHeight() - 1) - inY;
+
+       clientToScreenIntern(inX, inY, outX, outY);
+}
+
+void GHOST_WindowCocoa::screenToClientIntern(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const
+{
+       NSPoint screenCoord;
+       NSPoint baseCoord;
+       
+       screenCoord.x = inX;
+       screenCoord.y = inY;
        
+       baseCoord = [m_window convertScreenToBase:screenCoord];
+       
+       outX = baseCoord.x;
+       outY = baseCoord.y;
+}
+
+void GHOST_WindowCocoa::clientToScreenIntern(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const
+{
        NSPoint screenCoord;
        NSPoint baseCoord;
        
@@ -1220,7 +1230,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorGrab(GHOST_TGrabCursorMode mode
                        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 
                        m_systemCocoa->getCursorPosition(x_old,y_old);
-                       screenToClient(x_old, y_old, m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]);
+                       screenToClientIntern(x_old, y_old, m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]);
                        //Warp position is stored in client (window base) coordinates
                        setCursorGrabAccum(0, 0);