[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [23746] trunk/blender/intern/ghost/intern: Cocoa : Bug fix for continuous grab feature implementation

Damien Plisson damien.plisson at yahoo.fr
Fri Oct 9 19:42:31 CEST 2009


Revision: 23746
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=23746
Author:   damien78
Date:     2009-10-09 19:42:31 +0200 (Fri, 09 Oct 2009)

Log Message:
-----------
Cocoa : Bug fix for continuous grab feature implementation

Modified Paths:
--------------
    trunk/blender/intern/ghost/intern/GHOST_SystemCocoa.mm
    trunk/blender/intern/ghost/intern/GHOST_WindowCocoa.h
    trunk/blender/intern/ghost/intern/GHOST_WindowCocoa.mm

Modified: trunk/blender/intern/ghost/intern/GHOST_SystemCocoa.mm
===================================================================
--- trunk/blender/intern/ghost/intern/GHOST_SystemCocoa.mm	2009-10-09 15:47:35 UTC (rev 23745)
+++ trunk/blender/intern/ghost/intern/GHOST_SystemCocoa.mm	2009-10-09 17:42:31 UTC (rev 23746)
@@ -812,9 +812,9 @@
 	//Quartz Display Services uses the old coordinates (top left origin)
 	yf = [[NSScreen mainScreen] frame].size.height -yf;
 	
-	CGAssociateMouseAndMouseCursorPosition(false);
+	//CGAssociateMouseAndMouseCursorPosition(false);
 	CGWarpMouseCursorPosition(CGPointMake(xf, yf));
-	CGAssociateMouseAndMouseCursorPosition(true);
+	//CGAssociateMouseAndMouseCursorPosition(true);
 
     return GHOST_kSuccess;
 }
@@ -1151,7 +1151,7 @@
 					
 					window->getCursorWarpAccum(x_accum, y_accum);
 					x_accum += [event deltaX];
-					y_accum += [event deltaY];
+					y_accum += -[event deltaY]; //Strange Apple implementation (inverted coordinates for the deltaY) ...
 					window->setCursorWarpAccum(x_accum, y_accum);
 					
 					pushEvent(new GHOST_EventCursor([event timestamp], GHOST_kEventCursorMove, window, x_warp+x_accum, y_warp+y_accum));
@@ -1159,6 +1159,7 @@
 				else { //Normal cursor operation: send mouse position in window
 					NSPoint mousePos = [event locationInWindow];
 					pushEvent(new GHOST_EventCursor([event timestamp], GHOST_kEventCursorMove, window, mousePos.x, mousePos.y));
+					window->setCursorWarpAccum(0, 0); //Mouse motion occured between two cursor warps, so we can reset the delta counter
 				}
 				break;
 			}

Modified: trunk/blender/intern/ghost/intern/GHOST_WindowCocoa.h
===================================================================
--- trunk/blender/intern/ghost/intern/GHOST_WindowCocoa.h	2009-10-09 15:47:35 UTC (rev 23745)
+++ trunk/blender/intern/ghost/intern/GHOST_WindowCocoa.h	2009-10-09 17:42:31 UTC (rev 23746)
@@ -237,6 +237,11 @@
 	virtual GHOST_TSuccess setWindowCursorVisibility(bool visible);
 	
 	/**
+	 * Sets the cursor warp accumulator. Overriden for workaround due to Cocoa next event after cursor set giving delta values non zero
+	 */
+	inline virtual bool setCursorWarpAccum(GHOST_TInt32 x, GHOST_TInt32 y);
+	
+	/**
 	 * Sets the cursor grab on the window using
 	 * native window system calls.
 	 * @param warp	Only used when grab is enabled, hides the mouse and allows gragging outside the screen.

Modified: trunk/blender/intern/ghost/intern/GHOST_WindowCocoa.mm
===================================================================
--- trunk/blender/intern/ghost/intern/GHOST_WindowCocoa.mm	2009-10-09 15:47:35 UTC (rev 23745)
+++ trunk/blender/intern/ghost/intern/GHOST_WindowCocoa.mm	2009-10-09 17:42:31 UTC (rev 23746)
@@ -712,18 +712,33 @@
 	return GHOST_kSuccess;
 }
 
+
+//Override this method to provide set feature even if not in warp
+inline bool GHOST_WindowCocoa::setCursorWarpAccum(GHOST_TInt32 x, GHOST_TInt32 y)
+{
+	m_cursorWarpAccumPos[0]= x;
+	m_cursorWarpAccumPos[1]= y;
+	
+	return GHOST_kSuccess;
+}
+
+
 GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorGrab(bool grab, bool warp, bool restore)
 {
+	printf("\ncursor grab %i",grab);
 	if (grab)
 	{
+		//No need to perform grab without warp as it is always on in OS X
 		if(warp) {
-			m_systemCocoa->getCursorPosition(m_cursorWarpInitPos[0], m_cursorWarpInitPos[1]);
-			
-			setCursorWarpAccum(0, 0);
+			GHOST_TInt32 x_old,y_old;
+
+			m_cursorWarp= true;
+			m_systemCocoa->getCursorPosition(x_old,y_old);
+			screenToClient(x_old, y_old, m_cursorWarpInitPos[0], m_cursorWarpInitPos[1]);
+			//Warp position is stored in client (window base) coordinates
 			setWindowCursorVisibility(false);
-			m_cursorWarp= true;
+			return CGAssociateMouseAndMouseCursorPosition(false) == kCGErrorSuccess ? GHOST_kSuccess : GHOST_kFailure;
 		}
-		return CGAssociateMouseAndMouseCursorPosition(false) == kCGErrorSuccess ? GHOST_kSuccess : GHOST_kFailure;
 	}
 	else {
 		if(m_cursorWarp)
@@ -732,34 +747,37 @@
 			/* Almost works without but important otherwise the mouse GHOST location can be incorrect on exit */
 			if(restore) {
 				GHOST_Rect bounds;
-				GHOST_TInt32 x_new, y_new, x_rel, y_rel;
+				GHOST_TInt32 x_new, y_new, x_cur, y_cur;
 				
 				getClientBounds(bounds);
-				printf("\ncursor ungrab with restore");
 				x_new= m_cursorWarpInitPos[0]+m_cursorWarpAccumPos[0];
 				y_new= m_cursorWarpInitPos[1]+m_cursorWarpAccumPos[1];
 				
-				screenToClient(x_new, y_new, x_rel, y_rel);
+				if(x_new < 0)		x_new = 0;
+				if(y_new < 0)		y_new = 0;
+				if(x_new > bounds.getWidth())	x_new = bounds.getWidth();
+				if(y_new > bounds.getHeight())	y_new = bounds.getHeight();
 				
-				if(x_rel < 0)		x_new = (x_new-x_rel) + 2;
-				if(y_rel < 0)		y_new = (y_new-y_rel) + 2;
-				if(x_rel > bounds.getWidth())	x_new -= (x_rel-bounds.getWidth()) + 2;
-				if(y_rel > bounds.getHeight())	y_new -= (y_rel-bounds.getHeight()) + 2;
+				//get/set cursor position works in screen coordinates
+				clientToScreen(x_new, y_new, x_cur, y_cur);
+				m_systemCocoa->setCursorPosition(x_cur, y_cur);
 				
-				clientToScreen(x_new, y_new, x_rel, y_rel);
-				m_systemCocoa->setCursorPosition(x_rel, y_rel);
-				
+				//As Cocoa will give as first deltaX,deltaY this change in cursor position, we need to compensate for it
+				//Issue appearing in case of two transform operations conducted w/o mouse motion in between
+				x_new=m_cursorWarpAccumPos[0];
+				y_new=m_cursorWarpAccumPos[1];
+				setCursorWarpAccum(-x_new, -y_new);
 			}
 			else {
 				m_systemCocoa->setCursorPosition(m_cursorWarpInitPos[0], m_cursorWarpInitPos[1]);
+				setCursorWarpAccum(0, 0);
 			}
 			
-			setCursorWarpAccum(0, 0);
 			m_cursorWarp= false;
+			return CGAssociateMouseAndMouseCursorPosition(true) == kCGErrorSuccess ? GHOST_kSuccess : GHOST_kFailure;
 		}
-		return CGAssociateMouseAndMouseCursorPosition(true) == kCGErrorSuccess ? GHOST_kSuccess : GHOST_kFailure;
 	}
-	
+	return GHOST_kSuccess;
 }
 	
 GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorShape(GHOST_TStandardCursor shape)





More information about the Bf-blender-cvs mailing list