From c518aa13838d43e7311d65aeb9e3745e5057b806 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 23 Jun 2011 19:55:47 +0000 Subject: [PATCH] GHOST Cocoa: move y origin top/bottom conversions out of windowmanager module and into GHOST. Also fixes a problem where e.g. the user preferences window would not open under the mouse cursor correctly. --- intern/ghost/intern/GHOST_SystemCocoa.h | 11 ++++ intern/ghost/intern/GHOST_SystemCocoa.mm | 51 ++++++++++++++----- intern/ghost/intern/GHOST_Window.cpp | 3 +- intern/ghost/intern/GHOST_Window.h | 6 --- intern/ghost/intern/GHOST_WindowCarbon.cpp | 2 +- intern/ghost/intern/GHOST_WindowCocoa.h | 2 +- intern/ghost/intern/GHOST_WindowCocoa.mm | 17 +++++-- intern/ghost/intern/GHOST_WindowWin32.cpp | 2 +- intern/ghost/intern/GHOST_WindowX11.cpp | 2 +- .../windowmanager/intern/wm_event_system.c | 25 +++------ .../blender/windowmanager/intern/wm_window.c | 21 +------- 11 files changed, 76 insertions(+), 66 deletions(-) diff --git a/intern/ghost/intern/GHOST_SystemCocoa.h b/intern/ghost/intern/GHOST_SystemCocoa.h index e7a8178a382..4779f1f056c 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.h +++ b/intern/ghost/intern/GHOST_SystemCocoa.h @@ -272,6 +272,17 @@ 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; diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm index bf401138cf1..63c8f10971b 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.mm +++ b/intern/ghost/intern/GHOST_SystemCocoa.mm @@ -741,11 +741,13 @@ GHOST_IWindow* GHOST_SystemCocoa::createWindow( NSRect contentRect = [NSWindow contentRectForFrameRect:frame styleMask:(NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask)]; + GHOST_TInt32 bottom = (contentRect.size.height - 1) - height - top; + //Ensures window top left is inside this available rect left = left > contentRect.origin.x ? left : contentRect.origin.x; - top = top > contentRect.origin.y ? top : contentRect.origin.y; - - window = new GHOST_WindowCocoa (this, title, left, top, width, height, state, type, stereoVisual, numOfAASamples); + bottom = bottom > contentRect.origin.y ? bottom : contentRect.origin.y; + + window = new GHOST_WindowCocoa (this, title, left, bottom, width, height, state, type, stereoVisual, numOfAASamples); if (window) { if (window->getValid()) { @@ -804,6 +806,31 @@ 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 */ @@ -821,7 +848,7 @@ GHOST_TSuccess GHOST_SystemCocoa::setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 //Force mouse move event (not pushed by Cocoa) window->screenToClient(x, y, wx, wy); - pushEvent(new GHOST_EventCursor(getMilliSeconds(), GHOST_kEventCursorMove, window, wx,wy)); + pushEventCursor(getMilliSeconds(), GHOST_kEventCursorMove, window, wx,wy); m_outsideLoopEventProcessed = true; return GHOST_kSuccess; @@ -1508,7 +1535,7 @@ 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); - pushEvent(new GHOST_EventCursor([event timestamp]*1000, GHOST_kEventCursorMove, window, x_warp+x_accum, y_warp+y_accum)); + pushEventCursor([event timestamp]*1000, GHOST_kEventCursorMove, window, x_warp+x_accum, y_warp+y_accum); } break; case GHOST_kGrabWrap: //Wrap cursor at area/window boundaries @@ -1552,14 +1579,14 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) //Post event window->getCursorGrabInitPos(x_cur, y_cur); - pushEvent(new GHOST_EventCursor([event timestamp]*1000, GHOST_kEventCursorMove, window, x_cur + x_accum, y_cur + y_accum)); + pushEventCursor([event timestamp]*1000, GHOST_kEventCursorMove, window, x_cur + x_accum, y_cur + y_accum); } break; default: { //Normal cursor operation: send mouse position in window NSPoint mousePos = [event locationInWindow]; - pushEvent(new GHOST_EventCursor([event timestamp]*1000, GHOST_kEventCursorMove, window, mousePos.x, mousePos.y)); + pushEventCursor([event timestamp]*1000, GHOST_kEventCursorMove, window, mousePos.x, mousePos.y); m_cursorDelta_x=0; m_cursorDelta_y=0; //Mouse motion occurred between two cursor warps, so we can reset the delta counter } @@ -1597,7 +1624,7 @@ 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; - pushEvent(new GHOST_EventTrackpad([event timestamp]*1000, window, GHOST_kTrackpadEventScroll, mousePos.x, mousePos.y, dx, dy)); + pushEventTrackpad([event timestamp]*1000, window, GHOST_kTrackpadEventScroll, mousePos.x, mousePos.y, dx, dy); } } break; @@ -1605,16 +1632,16 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) case NSEventTypeMagnify: { NSPoint mousePos = [event locationInWindow]; - pushEvent(new GHOST_EventTrackpad([event timestamp]*1000, window, GHOST_kTrackpadEventMagnify, mousePos.x, mousePos.y, - [event magnification]*250.0 + 0.1, 0)); + pushEventTrackpad([event timestamp]*1000, window, GHOST_kTrackpadEventMagnify, mousePos.x, mousePos.y, + [event magnification]*250.0 + 0.1, 0); } break; case NSEventTypeRotate: { NSPoint mousePos = [event locationInWindow]; - pushEvent(new GHOST_EventTrackpad([event timestamp]*1000, window, GHOST_kTrackpadEventRotate, mousePos.x, mousePos.y, - -[event rotation] * 5.0, 0)); + pushEventTrackpad([event timestamp]*1000, window, GHOST_kTrackpadEventRotate, mousePos.x, mousePos.y, + -[event rotation] * 5.0, 0); } case NSEventTypeBeginGesture: m_isGestureInProgress = true; diff --git a/intern/ghost/intern/GHOST_Window.cpp b/intern/ghost/intern/GHOST_Window.cpp index c518272d614..e34bfe7ff26 100644 --- a/intern/ghost/intern/GHOST_Window.cpp +++ b/intern/ghost/intern/GHOST_Window.cpp @@ -41,8 +41,7 @@ GHOST_Window::GHOST_Window( - const STR_String& /*title*/, - GHOST_TInt32 /*left*/, GHOST_TInt32 /*top*/, GHOST_TUns32 width, GHOST_TUns32 height, + GHOST_TUns32 width, GHOST_TUns32 height, GHOST_TWindowState state, GHOST_TDrawingContextType type, const bool stereoVisual, diff --git a/intern/ghost/intern/GHOST_Window.h b/intern/ghost/intern/GHOST_Window.h index e0c676f53a5..66990abb555 100644 --- a/intern/ghost/intern/GHOST_Window.h +++ b/intern/ghost/intern/GHOST_Window.h @@ -76,9 +76,6 @@ public: * Constructor. * Creates a new window and opens it. * To check if the window was created properly, use the getValid() method. - * @param title The text shown in the title bar of the window. - * @param left The coordinate of the left edge of the window. - * @param top The coordinate of the top edge of the window. * @param width The width the window. * @param heigh The height the window. * @param state The state the window is initially opened with. @@ -87,9 +84,6 @@ public: * @param numOfAASamples Number of samples used for AA (zero if no AA) */ GHOST_Window( - const STR_String& title, - GHOST_TInt32 left, - GHOST_TInt32 top, GHOST_TUns32 width, GHOST_TUns32 height, GHOST_TWindowState state, diff --git a/intern/ghost/intern/GHOST_WindowCarbon.cpp b/intern/ghost/intern/GHOST_WindowCarbon.cpp index 1ffd117d658..c8bd67f9a5c 100644 --- a/intern/ghost/intern/GHOST_WindowCarbon.cpp +++ b/intern/ghost/intern/GHOST_WindowCarbon.cpp @@ -102,7 +102,7 @@ GHOST_WindowCarbon::GHOST_WindowCarbon( const bool stereoVisual, const GHOST_TUns16 numOfAASamples ) : - GHOST_Window(title, left, top, width, height, state, GHOST_kDrawingContextTypeNone), + GHOST_Window(width, height, state, GHOST_kDrawingContextTypeNone), m_windowRef(0), m_grafPtr(0), m_aglCtx(0), diff --git a/intern/ghost/intern/GHOST_WindowCocoa.h b/intern/ghost/intern/GHOST_WindowCocoa.h index 98e0f9cedd1..b5485c6bcef 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.h +++ b/intern/ghost/intern/GHOST_WindowCocoa.h @@ -77,7 +77,7 @@ public: GHOST_SystemCocoa *systemCocoa, const STR_String& title, GHOST_TInt32 left, - GHOST_TInt32 top, + GHOST_TInt32 bottom, GHOST_TUns32 width, GHOST_TUns32 height, GHOST_TWindowState state, diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm index fb7d4a459c7..224980c6a11 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.mm +++ b/intern/ghost/intern/GHOST_WindowCocoa.mm @@ -308,14 +308,14 @@ GHOST_WindowCocoa::GHOST_WindowCocoa( GHOST_SystemCocoa *systemCocoa, const STR_String& title, GHOST_TInt32 left, - GHOST_TInt32 top, + GHOST_TInt32 bottom, GHOST_TUns32 width, GHOST_TUns32 height, GHOST_TWindowState state, GHOST_TDrawingContextType type, const bool stereoVisual, const GHOST_TUns16 numOfAASamples ) : - GHOST_Window(title, left, top, width, height, state, GHOST_kDrawingContextTypeNone, stereoVisual, numOfAASamples), + GHOST_Window(width, height, state, GHOST_kDrawingContextTypeNone, stereoVisual, numOfAASamples), m_customCursor(0) { NSOpenGLPixelFormatAttribute pixelFormatAttrsWindow[40]; @@ -327,13 +327,12 @@ GHOST_WindowCocoa::GHOST_WindowCocoa( NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - //Creates the window NSRect rect; NSSize minSize; rect.origin.x = left; - rect.origin.y = top; + rect.origin.y = bottom; rect.size.width = width; rect.size.height = height; @@ -703,12 +702,22 @@ void GHOST_WindowCocoa::screenToClient(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST outX = baseCoord.x; outY = baseCoord.y; + + /* switch y to match ghost convention */ + GHOST_Rect cBnds; + getClientBounds(cBnds); + outY = (cBnds.getHeight() - 1) - outY; } void GHOST_WindowCocoa::clientToScreen(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const { GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::clientToScreen(): window invalid") + + /* switch y to match ghost convention */ + GHOST_Rect cBnds; + getClientBounds(cBnds); + inY = (cBnds.getHeight() - 1) - inY; NSPoint screenCoord; NSPoint baseCoord; diff --git a/intern/ghost/intern/GHOST_WindowWin32.cpp b/intern/ghost/intern/GHOST_WindowWin32.cpp index aae1509fda1..1ba51376ff9 100644 --- a/intern/ghost/intern/GHOST_WindowWin32.cpp +++ b/intern/ghost/intern/GHOST_WindowWin32.cpp @@ -136,7 +136,7 @@ GHOST_WindowWin32::GHOST_WindowWin32( GHOST_TSuccess msEnabled, int msPixelFormat) : - GHOST_Window(title, left, top, width, height, state, GHOST_kDrawingContextTypeNone, + GHOST_Window(width, height, state, GHOST_kDrawingContextTypeNone, stereoVisual,numOfAASamples), m_system(system), m_hDC(0), diff --git a/intern/ghost/intern/GHOST_WindowX11.cpp b/intern/ghost/intern/GHOST_WindowX11.cpp index fc72ea09f40..de725151607 100644 --- a/intern/ghost/intern/GHOST_WindowX11.cpp +++ b/intern/ghost/intern/GHOST_WindowX11.cpp @@ -164,7 +164,7 @@ GHOST_WindowX11( const bool stereoVisual, const GHOST_TUns16 numOfAASamples ) : - GHOST_Window(title,left,top,width,height,state,type,stereoVisual,numOfAASamples), + GHOST_Window(width,height,state,type,stereoVisual,numOfAASamples), m_context(NULL), m_display(display), m_normal_state(GHOST_kWindowStateNormal), diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 2613cb8f14f..83ef46d109c 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -2365,18 +2365,11 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U if(win->active) { GHOST_TEventCursorData *cd= customdata; wmEvent *lastevent= win->queue.last; - -#if defined(__APPLE__) && defined(GHOST_COCOA) - //Cocoa already uses coordinates with y=0 at bottom, and returns inwindow coordinates on mouse moved event - evt->x= cd->x; - evt->y= cd->y; -#else int cx, cy; GHOST_ScreenToClient(win->ghostwin, cd->x, cd->y, &cx, &cy); evt->x= cx; evt->y= (win->sizey-1) - cy; -#endif event.x= evt->x; event.y= evt->y; @@ -2423,21 +2416,17 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U event.type= MOUSEPAN; break; } -#if defined(__APPLE__) && defined(GHOST_COCOA) - //Cocoa already uses coordinates with y=0 at bottom, and returns inwindow coordinates on mouse moved event - event.x= evt->x = pd->x; - event.y = evt->y = pd->y; -#else + { - int cx, cy; - GHOST_ScreenToClient(win->ghostwin, pd->x, pd->y, &cx, &cy); - event.x= evt->x= cx; - event.y= evt->y= (win->sizey-1) - cy; + int cx, cy; + GHOST_ScreenToClient(win->ghostwin, pd->x, pd->y, &cx, &cy); + event.x= evt->x= cx; + event.y= evt->y= (win->sizey-1) - cy; } -#endif + // Use prevx/prevy so we can calculate the delta later event.prevx= event.x - pd->deltaX; - event.prevy= event.y - pd->deltaY; + event.prevy= event.y - (-pd->deltaY); update_tablet_data(win, &event); wm_event_add(win, &event); diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index 9ee39132521..9b1695be67a 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -673,13 +673,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr private) GHOST_ScreenToClient(win->ghostwin, wx, wy, &cx, &cy); win->eventstate->x= cx; - -#if defined(__APPLE__) && defined(GHOST_COCOA) - //Cocoa already uses coordinates with y=0 at bottom - win->eventstate->y= cy; -#else win->eventstate->y= (win->sizey-1) - cy; -#endif win->addmousemove= 1; /* enables highlighted buttons */ @@ -796,20 +790,13 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr private) wmEvent event; GHOST_TEventDragnDropData *ddd= GHOST_GetEventData(evt); int cx, cy, wx, wy; - /* entering window, update mouse pos */ GHOST_GetCursorPosition(g_system, &wx, &wy); GHOST_ScreenToClient(win->ghostwin, wx, wy, &cx, &cy); win->eventstate->x= cx; - -#if defined(__APPLE__) && defined(GHOST_COCOA) - //Cocoa already uses coordinates with y=0 at bottom - win->eventstate->y= cy; -#else win->eventstate->y= (win->sizey-1) - cy; -#endif event= *(win->eventstate); /* copy last state, like mouse coords */ @@ -1149,12 +1136,7 @@ void wm_get_cursor_position(wmWindow *win, int *x, int *y) { GHOST_GetCursorPosition(g_system, x, y); GHOST_ScreenToClient(win->ghostwin, *x, *y, x, y); -#if defined(__APPLE__) && defined(GHOST_COCOA) - //Cocoa has silly exception that should be fixed at the ghost level - //(ghost is an allegory for an invisible system specific code) -#else *y = (win->sizey-1) - *y; -#endif } /* ******************* exported api ***************** */ @@ -1187,9 +1169,8 @@ void WM_cursor_warp(wmWindow *win, int x, int y) if (win && win->ghostwin) { int oldx=x, oldy=y; -#if !defined(__APPLE__) || !defined(GHOST_COCOA) y= win->sizey -y - 1; -#endif + GHOST_ClientToScreen(win->ghostwin, x, y, &x, &y); GHOST_SetCursorPosition(g_system, x, y);