forked from bartvdbraak/blender
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.
This commit is contained in:
parent
a014886c57
commit
c518aa1383
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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),
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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),
|
||||
|
@ -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),
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user