Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/intern
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2009-10-17 18:08:01 +0400
committerCampbell Barton <ideasman42@gmail.com>2009-10-17 18:08:01 +0400
commit91d89c1ff7c215744e46957a1e7cc40adb7ac066 (patch)
treea811c95542f7fd40ff13cf592dfff1077a34f7d4 /intern
parent53624a53d9054a91688a1a988c6f3515ab601923 (diff)
Adjustments to continuous grab
- Use an enum for grab modes rather then boolean options. -- GHOST_kGrabNormal: continuous grab userpref disabled -- GHOST_kGrabWrap: wrap the mouse at the screen bounds * -- GHOST_kGrabHide: hide the mouse while grabbing and restore the mouse where it was initially pressed * GrabWrap is nice for transform and tools where you want some idea where the cursor is, previously I found both restoring the mouse at its original location and restoring at a clamped location was confusing with operators like transform, wrapping is not ideal but IMHO the best of a bad bunch of options. GrabHide is for numbuts, where restoring the mouse at the initial location isnt so confusing.
Diffstat (limited to 'intern')
-rw-r--r--intern/ghost/GHOST_C-api.h2
-rw-r--r--intern/ghost/GHOST_IWindow.h2
-rw-r--r--intern/ghost/GHOST_Rect.h22
-rw-r--r--intern/ghost/GHOST_Types.h6
-rw-r--r--intern/ghost/intern/GHOST_C-api.cpp4
-rw-r--r--intern/ghost/intern/GHOST_SystemX11.cpp51
-rw-r--r--intern/ghost/intern/GHOST_Window.cpp15
-rw-r--r--intern/ghost/intern/GHOST_Window.h57
-rw-r--r--intern/ghost/intern/GHOST_WindowCocoa.h2
-rw-r--r--intern/ghost/intern/GHOST_WindowX11.cpp46
-rw-r--r--intern/ghost/intern/GHOST_WindowX11.h5
11 files changed, 102 insertions, 110 deletions
diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h
index 00d2cdb1e3b..93bd12437ab 100644
--- a/intern/ghost/GHOST_C-api.h
+++ b/intern/ghost/GHOST_C-api.h
@@ -376,7 +376,7 @@ extern GHOST_TSuccess GHOST_SetCursorPosition(GHOST_SystemHandle systemhandle,
* @return Indication of success.
*/
extern GHOST_TSuccess GHOST_SetCursorGrab(GHOST_WindowHandle windowhandle,
- int grab, int warp, int restore);
+ GHOST_TGrabCursorMode mode);
/***************************************************************************************
** Access to mouse button and keyboard states.
diff --git a/intern/ghost/GHOST_IWindow.h b/intern/ghost/GHOST_IWindow.h
index 993b41a4d4f..3ab9bef2bfa 100644
--- a/intern/ghost/GHOST_IWindow.h
+++ b/intern/ghost/GHOST_IWindow.h
@@ -271,7 +271,7 @@ public:
* @param grab The new grab state of the cursor.
* @return Indication of success.
*/
- virtual GHOST_TSuccess setCursorGrab(bool grab, bool warp, bool restore) { return GHOST_kSuccess; };
+ virtual GHOST_TSuccess setCursorGrab(GHOST_TGrabCursorMode mode) { return GHOST_kSuccess; };
};
diff --git a/intern/ghost/GHOST_Rect.h b/intern/ghost/GHOST_Rect.h
index 6271ecad408..98169ad2aa4 100644
--- a/intern/ghost/GHOST_Rect.h
+++ b/intern/ghost/GHOST_Rect.h
@@ -127,6 +127,13 @@ public:
virtual inline void unionPoint(GHOST_TInt32 x, GHOST_TInt32 y);
/**
+ * Grows the rectangle to included a point.
+ * @param x The x-coordinate of the point.
+ * @param y The y-coordinate of the point.
+ */
+ virtual inline void wrapPoint(GHOST_TInt32 &x, GHOST_TInt32 &y, GHOST_TInt32 ofs);
+
+ /**
* Returns whether the point is inside this rectangle.
* Point on the boundary is considered inside.
* @param x x-coordinate of point to test.
@@ -222,6 +229,21 @@ inline void GHOST_Rect::unionPoint(GHOST_TInt32 x, GHOST_TInt32 y)
if (y > m_b) m_b = y;
}
+inline void GHOST_Rect::wrapPoint(GHOST_TInt32 &x, GHOST_TInt32 &y, GHOST_TInt32 ofs)
+{
+ GHOST_TInt32 w= getWidth();
+ GHOST_TInt32 h= getHeight();
+
+ /* highly unlikely but avoid eternal loop */
+ if(w-ofs <= 0 || h-ofs <= 0)
+ return;
+
+ while(x-ofs < m_l) x+= w;
+ while(y-ofs < m_t) y+= h;
+ while(x+ofs > m_r) x-= w;
+ while(y+ofs > m_b) y-= h;
+}
+
inline bool GHOST_Rect::isInside(GHOST_TInt32 x, GHOST_TInt32 y) const
{
return (x >= m_l) && (x <= m_r) && (y >= m_t) && (y <= m_b);
diff --git a/intern/ghost/GHOST_Types.h b/intern/ghost/GHOST_Types.h
index 14e3c4bb5f7..e98e58740ad 100644
--- a/intern/ghost/GHOST_Types.h
+++ b/intern/ghost/GHOST_Types.h
@@ -341,6 +341,12 @@ typedef enum {
GHOST_kKeyF24
} GHOST_TKey;
+typedef enum {
+ GHOST_kGrabDisable = 0, /* grab not set */
+ GHOST_kGrabNormal, /* no cursor adjustments */
+ GHOST_kGrabWrap, /* wrap the mouse location to prevent limiting screen bounds */
+ GHOST_kGrabHide, /* hide the mouse while grabbing and restore the original location on release (numbuts) */
+} GHOST_TGrabCursorMode;
typedef void* GHOST_TEventDataPtr;
diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp
index e225ad4fd90..5563e0d1aa8 100644
--- a/intern/ghost/intern/GHOST_C-api.cpp
+++ b/intern/ghost/intern/GHOST_C-api.cpp
@@ -355,11 +355,11 @@ GHOST_TSuccess GHOST_SetCursorPosition(GHOST_SystemHandle systemhandle,
GHOST_TSuccess GHOST_SetCursorGrab(GHOST_WindowHandle windowhandle,
- int grab, int warp, int restore)
+ GHOST_TGrabCursorMode mode)
{
GHOST_IWindow* window = (GHOST_IWindow*) windowhandle;
- return window->setCursorGrab(grab?true:false, warp?true:false, restore?true:false);
+ return window->setCursorGrab(mode);
}
diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp
index 8c87abf16bc..abf0b612f9a 100644
--- a/intern/ghost/intern/GHOST_SystemX11.cpp
+++ b/intern/ghost/intern/GHOST_SystemX11.cpp
@@ -388,31 +388,36 @@ GHOST_SystemX11::processEvent(XEvent *xe)
{
XMotionEvent &xme = xe->xmotion;
- if(window->getCursorWarp()) {
- /* Calculate offscreen location and re-center the mouse */
- GHOST_TInt32 x_warp, y_warp, x_new, y_new, x_accum, y_accum;
-
- window->getCursorWarpPos(x_warp, y_warp);
- getCursorPosition(x_new, y_new);
-
- if(x_warp != x_new || y_warp != y_new) {
- window->getCursorWarpAccum(x_accum, y_accum);
- x_accum += x_new - x_warp;
- y_accum += y_new - y_warp;
-
- window->setCursorWarpAccum(x_accum, y_accum);
- setCursorPosition(x_warp, y_warp); /* reset */
-
- g_event = new
- GHOST_EventCursor(
- getMilliSeconds(),
- GHOST_kEventCursorMove,
- window,
- x_warp + x_accum,
- y_warp + y_accum
- );
+ if(window->getCursorGrabMode() != GHOST_kGrabDisable && window->getCursorGrabMode() != GHOST_kGrabNormal)
+ {
+ GHOST_TInt32 x_new= xme.x_root;
+ GHOST_TInt32 y_new= xme.y_root;
+ GHOST_TInt32 x_accum, y_accum;
+ GHOST_Rect bounds;
+
+ window->getClientBounds(bounds);
+
+ /* could also clamp to screen bounds
+ * wrap with a window outside the view will fail atm */
+
+ bounds.wrapPoint(x_new, y_new, 1); /* offset of one incase blender is at screen bounds */
+ window->getCursorGrabAccum(x_accum, y_accum);
+
+ if(x_new != xme.x_root || y_new != xme.y_root) {
+ setCursorPosition(x_new, y_new); /* wrap */
+ window->setCursorGrabAccum(x_accum + (xme.x_root - x_new), y_accum + (xme.y_root - y_new));
}
+
+ g_event = new
+ GHOST_EventCursor(
+ getMilliSeconds(),
+ GHOST_kEventCursorMove,
+ window,
+ xme.x_root + x_accum,
+ xme.y_root + y_accum
+ );
+
}
else {
g_event = new
diff --git a/intern/ghost/intern/GHOST_Window.cpp b/intern/ghost/intern/GHOST_Window.cpp
index 94feb83e003..cda6bfa06ee 100644
--- a/intern/ghost/intern/GHOST_Window.cpp
+++ b/intern/ghost/intern/GHOST_Window.cpp
@@ -48,15 +48,14 @@ GHOST_Window::GHOST_Window(
:
m_drawingContextType(type),
m_cursorVisible(true),
- m_cursorGrabbed(false),
- m_cursorWarp(false),
+ m_cursorGrab(GHOST_kGrabDisable),
m_cursorShape(GHOST_kStandardCursorDefault),
m_stereoVisual(stereoVisual)
{
m_isUnsavedChanges = false;
- m_cursorWarpAccumPos[0] = 0;
- m_cursorWarpAccumPos[1] = 0;
+ m_cursorGrabAccumPos[0] = 0;
+ m_cursorGrabAccumPos[1] = 0;
m_fullScreen = state == GHOST_kWindowStateFullScreen;
if (m_fullScreen) {
@@ -98,13 +97,13 @@ GHOST_TSuccess GHOST_Window::setCursorVisibility(bool visible)
}
}
-GHOST_TSuccess GHOST_Window::setCursorGrab(bool grab, bool warp, bool restore)
+GHOST_TSuccess GHOST_Window::setCursorGrab(GHOST_TGrabCursorMode mode)
{
- if(m_cursorGrabbed == grab)
+ if(m_cursorGrab == mode)
return GHOST_kSuccess;
- if (setWindowCursorGrab(grab, warp, restore)) {
- m_cursorGrabbed = grab;
+ if (setWindowCursorGrab(mode)) {
+ m_cursorGrab = mode;
return GHOST_kSuccess;
}
else {
diff --git a/intern/ghost/intern/GHOST_Window.h b/intern/ghost/intern/GHOST_Window.h
index 786918716c5..e66a3c2fd36 100644
--- a/intern/ghost/intern/GHOST_Window.h
+++ b/intern/ghost/intern/GHOST_Window.h
@@ -158,10 +158,9 @@ public:
* @return The visibility state of the cursor.
*/
inline virtual bool getCursorVisibility() const;
- inline virtual bool getCursorWarp() const;
- inline virtual bool getCursorWarpPos(GHOST_TInt32 &x, GHOST_TInt32 &y) const;
- inline virtual bool getCursorWarpAccum(GHOST_TInt32 &x, GHOST_TInt32 &y) const;
- inline virtual bool setCursorWarpAccum(GHOST_TInt32 x, GHOST_TInt32 y);
+ inline virtual GHOST_TGrabCursorMode getCursorGrabMode() const;
+ inline virtual void getCursorGrabAccum(GHOST_TInt32 &x, GHOST_TInt32 &y) const;
+ inline virtual void setCursorGrabAccum(GHOST_TInt32 x, GHOST_TInt32 y);
/**
* Shows or hides the cursor.
@@ -175,7 +174,7 @@ public:
* @param grab The new grab state of the cursor.
* @return Indication of success.
*/
- virtual GHOST_TSuccess setCursorGrab(bool grab, bool warp, bool restore);
+ virtual GHOST_TSuccess setCursorGrab(GHOST_TGrabCursorMode mode);
/**
* Sets the window "modified" status, indicating unsaved changes
@@ -247,7 +246,7 @@ protected:
* Sets the cursor grab on the window using
* native window system calls.
*/
- virtual GHOST_TSuccess setWindowCursorGrab(bool grab, bool warp, bool restore) { return GHOST_kSuccess; };
+ virtual GHOST_TSuccess setWindowCursorGrab(GHOST_TGrabCursorMode mode) { return GHOST_kSuccess; };
/**
* Sets the cursor shape on the window using
@@ -274,16 +273,13 @@ protected:
bool m_cursorVisible;
/** The current grabbed state of the cursor */
- bool m_cursorGrabbed;
-
- /** The current warped state of the cursor */
- bool m_cursorWarp;
+ GHOST_TGrabCursorMode m_cursorGrab;
/** Initial grab location. */
- GHOST_TInt32 m_cursorWarpInitPos[2];
+ GHOST_TInt32 m_cursorGrabInitPos[2];
- /** Accumulated offset from m_cursorWarpInitPos. */
- GHOST_TInt32 m_cursorWarpAccumPos[2];
+ /** Accumulated offset from m_cursorGrabInitPos. */
+ GHOST_TInt32 m_cursorGrabAccumPos[2];
/** The current shape of the cursor */
GHOST_TStandardCursor m_cursorShape;
@@ -317,40 +313,21 @@ inline bool GHOST_Window::getCursorVisibility() const
return m_cursorVisible;
}
-inline bool GHOST_Window::getCursorWarp() const
-{
- return m_cursorWarp;
-}
-
-inline bool GHOST_Window::getCursorWarpPos(GHOST_TInt32 &x, GHOST_TInt32 &y) const
+inline GHOST_TGrabCursorMode GHOST_Window::getCursorGrabMode() const
{
- if(m_cursorWarp==false)
- return GHOST_kFailure;
-
- x= m_cursorWarpInitPos[0];
- y= m_cursorWarpInitPos[1];
- return GHOST_kSuccess;
+ return m_cursorGrab;
}
-inline bool GHOST_Window::getCursorWarpAccum(GHOST_TInt32 &x, GHOST_TInt32 &y) const
+inline void GHOST_Window::getCursorGrabAccum(GHOST_TInt32 &x, GHOST_TInt32 &y) const
{
- if(m_cursorWarp==false)
- return GHOST_kFailure;
-
- x= m_cursorWarpAccumPos[0];
- y= m_cursorWarpAccumPos[1];
- return GHOST_kSuccess;
+ x= m_cursorGrabAccumPos[0];
+ y= m_cursorGrabAccumPos[1];
}
-inline bool GHOST_Window::setCursorWarpAccum(GHOST_TInt32 x, GHOST_TInt32 y)
+inline void GHOST_Window::setCursorGrabAccum(GHOST_TInt32 x, GHOST_TInt32 y)
{
- if(m_cursorWarp==false)
- return GHOST_kFailure;
-
- m_cursorWarpAccumPos[0]= x;
- m_cursorWarpAccumPos[1]= y;
-
- return GHOST_kSuccess;
+ m_cursorGrabAccumPos[0]= x;
+ m_cursorGrabAccumPos[1]= y;
}
inline GHOST_TStandardCursor GHOST_Window::getCursorShape() const
diff --git a/intern/ghost/intern/GHOST_WindowCocoa.h b/intern/ghost/intern/GHOST_WindowCocoa.h
index d6c154535a9..e5fff75c66e 100644
--- a/intern/ghost/intern/GHOST_WindowCocoa.h
+++ b/intern/ghost/intern/GHOST_WindowCocoa.h
@@ -239,7 +239,7 @@ protected:
/**
* 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);
+ inline virtual bool setCursorGrabAccum(GHOST_TInt32 x, GHOST_TInt32 y);
/**
* Sets the cursor grab on the window using
diff --git a/intern/ghost/intern/GHOST_WindowX11.cpp b/intern/ghost/intern/GHOST_WindowX11.cpp
index d197b534352..9914bad23c8 100644
--- a/intern/ghost/intern/GHOST_WindowX11.cpp
+++ b/intern/ghost/intern/GHOST_WindowX11.cpp
@@ -1400,47 +1400,27 @@ setWindowCursorVisibility(
GHOST_TSuccess
GHOST_WindowX11::
setWindowCursorGrab(
- bool grab, bool warp, bool restore
+ GHOST_TGrabCursorMode mode
){
- if(grab) {
- if(warp) {
- m_system->getCursorPosition(m_cursorWarpInitPos[0], m_cursorWarpInitPos[1]);
+ if(mode != GHOST_kGrabDisable) {
+ if(mode != GHOST_kGrabNormal) {
+ m_system->getCursorPosition(m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]);
+ setCursorGrabAccum(0, 0);
+
+ if(mode == GHOST_kGrabHide)
+ setWindowCursorVisibility(false);
- setCursorWarpAccum(0, 0);
- setWindowCursorVisibility(false);
- m_cursorWarp= true;
}
XGrabPointer(m_display, m_window, True, ButtonPressMask| ButtonReleaseMask|PointerMotionMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
}
else {
- if(m_cursorWarp) { /* are we exiting warp */
+ if (m_cursorGrab==GHOST_kGrabHide) {
+ m_system->setCursorPosition(m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]);
setWindowCursorVisibility(true);
- /* 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;
-
- getClientBounds(bounds);
-
- 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_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;
- m_system->setCursorPosition(x_new, y_new);
-
- }
- else {
- m_system->setCursorPosition(m_cursorWarpInitPos[0], m_cursorWarpInitPos[1]);
- }
-
- setCursorWarpAccum(0, 0);
- m_cursorWarp= false;
}
+
+ /* Almost works without but important otherwise the mouse GHOST location can be incorrect on exit */
+ setCursorGrabAccum(0, 0);
XUngrabPointer(m_display, CurrentTime);
}
diff --git a/intern/ghost/intern/GHOST_WindowX11.h b/intern/ghost/intern/GHOST_WindowX11.h
index eb0689ab410..0dba1776553 100644
--- a/intern/ghost/intern/GHOST_WindowX11.h
+++ b/intern/ghost/intern/GHOST_WindowX11.h
@@ -256,9 +256,12 @@ protected:
*/
GHOST_TSuccess
setWindowCursorGrab(
- bool grab, bool warp, bool restore
+ GHOST_TGrabCursorMode mode
);
+ GHOST_TGrabCursorMode
+ getWindowCursorGrab() const;
+
/**
* Sets the cursor shape on the window using
* native window system calls.