forked from bartvdbraak/blender
Experimental option to allow moving the mouse outside the view, "Continuous Grab" in the user-prefs.
- Useful for dragging buttons to the far right when theyd otherwise hit the screen edge. - Useful for transform though probably NOT what you want when using the transform manipulator (should make an option). - When enabled, number buttons use this as well as a different conversion of mouse movement float numbuts: mouse 1px == 1-clickstep int numbuts: 2px == 1 (tried 1:1 but its too jitter prone) details... - access as an option to GHOST_SetCursorGrab(grab, warp) - Currently all operators that grab use this, could be made an operator flag - only Ghost/X11 supported currently
This commit is contained in:
parent
828395744a
commit
77476b294f
@ -376,7 +376,7 @@ extern GHOST_TSuccess GHOST_SetCursorPosition(GHOST_SystemHandle systemhandle,
|
|||||||
* @return Indication of success.
|
* @return Indication of success.
|
||||||
*/
|
*/
|
||||||
extern GHOST_TSuccess GHOST_SetCursorGrab(GHOST_WindowHandle windowhandle,
|
extern GHOST_TSuccess GHOST_SetCursorGrab(GHOST_WindowHandle windowhandle,
|
||||||
int grab);
|
int grab, int warp);
|
||||||
|
|
||||||
/***************************************************************************************
|
/***************************************************************************************
|
||||||
** Access to mouse button and keyboard states.
|
** Access to mouse button and keyboard states.
|
||||||
|
@ -271,7 +271,7 @@ public:
|
|||||||
* @param grab The new grab state of the cursor.
|
* @param grab The new grab state of the cursor.
|
||||||
* @return Indication of success.
|
* @return Indication of success.
|
||||||
*/
|
*/
|
||||||
virtual GHOST_TSuccess setCursorGrab(bool grab) { return GHOST_kSuccess; };
|
virtual GHOST_TSuccess setCursorGrab(bool grab, bool warp) { return GHOST_kSuccess; };
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -355,11 +355,11 @@ GHOST_TSuccess GHOST_SetCursorPosition(GHOST_SystemHandle systemhandle,
|
|||||||
|
|
||||||
|
|
||||||
GHOST_TSuccess GHOST_SetCursorGrab(GHOST_WindowHandle windowhandle,
|
GHOST_TSuccess GHOST_SetCursorGrab(GHOST_WindowHandle windowhandle,
|
||||||
int grab)
|
int grab, int warp)
|
||||||
{
|
{
|
||||||
GHOST_IWindow* window = (GHOST_IWindow*) windowhandle;
|
GHOST_IWindow* window = (GHOST_IWindow*) windowhandle;
|
||||||
|
|
||||||
return window->setCursorGrab(grab?true:false);
|
return window->setCursorGrab(grab?true:false, warp?true:false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -388,14 +388,42 @@ GHOST_SystemX11::processEvent(XEvent *xe)
|
|||||||
{
|
{
|
||||||
XMotionEvent &xme = xe->xmotion;
|
XMotionEvent &xme = xe->xmotion;
|
||||||
|
|
||||||
g_event = new
|
if(window->getCursorWarp()) {
|
||||||
GHOST_EventCursor(
|
/* Calculate offscreen location and re-center the mouse */
|
||||||
getMilliSeconds(),
|
GHOST_TInt32 x_warp, y_warp, x_new, y_new, x_accum, y_accum;
|
||||||
GHOST_kEventCursorMove,
|
|
||||||
window,
|
window->getCursorWarpPos(x_warp, y_warp);
|
||||||
xme.x_root,
|
getCursorPosition(x_new, y_new);
|
||||||
xme.y_root
|
|
||||||
);
|
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
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
g_event = new
|
||||||
|
GHOST_EventCursor(
|
||||||
|
getMilliSeconds(),
|
||||||
|
GHOST_kEventCursorMove,
|
||||||
|
window,
|
||||||
|
xme.x_root,
|
||||||
|
xme.y_root
|
||||||
|
);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,12 +48,16 @@ GHOST_Window::GHOST_Window(
|
|||||||
:
|
:
|
||||||
m_drawingContextType(type),
|
m_drawingContextType(type),
|
||||||
m_cursorVisible(true),
|
m_cursorVisible(true),
|
||||||
m_cursorGrabbed(true),
|
m_cursorGrabbed(false),
|
||||||
|
m_cursorWarp(false),
|
||||||
m_cursorShape(GHOST_kStandardCursorDefault),
|
m_cursorShape(GHOST_kStandardCursorDefault),
|
||||||
m_stereoVisual(stereoVisual)
|
m_stereoVisual(stereoVisual)
|
||||||
{
|
{
|
||||||
m_isUnsavedChanges = false;
|
m_isUnsavedChanges = false;
|
||||||
|
|
||||||
|
m_cursorWarpAccumPos[0] = 0;
|
||||||
|
m_cursorWarpAccumPos[1] = 0;
|
||||||
|
|
||||||
m_fullScreen = state == GHOST_kWindowStateFullScreen;
|
m_fullScreen = state == GHOST_kWindowStateFullScreen;
|
||||||
if (m_fullScreen) {
|
if (m_fullScreen) {
|
||||||
m_fullScreenWidth = width;
|
m_fullScreenWidth = width;
|
||||||
@ -94,12 +98,12 @@ GHOST_TSuccess GHOST_Window::setCursorVisibility(bool visible)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GHOST_TSuccess GHOST_Window::setCursorGrab(bool grab)
|
GHOST_TSuccess GHOST_Window::setCursorGrab(bool grab, bool warp)
|
||||||
{
|
{
|
||||||
if(m_cursorGrabbed == grab)
|
if(m_cursorGrabbed == grab)
|
||||||
return GHOST_kSuccess;
|
return GHOST_kSuccess;
|
||||||
|
|
||||||
if (setWindowCursorGrab(grab)) {
|
if (setWindowCursorGrab(grab, warp)) {
|
||||||
m_cursorGrabbed = grab;
|
m_cursorGrabbed = grab;
|
||||||
return GHOST_kSuccess;
|
return GHOST_kSuccess;
|
||||||
}
|
}
|
||||||
|
@ -158,6 +158,10 @@ public:
|
|||||||
* @return The visibility state of the cursor.
|
* @return The visibility state of the cursor.
|
||||||
*/
|
*/
|
||||||
inline virtual bool getCursorVisibility() const;
|
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);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shows or hides the cursor.
|
* Shows or hides the cursor.
|
||||||
@ -171,7 +175,7 @@ public:
|
|||||||
* @param grab The new grab state of the cursor.
|
* @param grab The new grab state of the cursor.
|
||||||
* @return Indication of success.
|
* @return Indication of success.
|
||||||
*/
|
*/
|
||||||
virtual GHOST_TSuccess setCursorGrab(bool grab);
|
virtual GHOST_TSuccess setCursorGrab(bool grab, bool warp);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the window "modified" status, indicating unsaved changes
|
* Sets the window "modified" status, indicating unsaved changes
|
||||||
@ -243,7 +247,7 @@ protected:
|
|||||||
* Sets the cursor grab on the window using
|
* Sets the cursor grab on the window using
|
||||||
* native window system calls.
|
* native window system calls.
|
||||||
*/
|
*/
|
||||||
virtual GHOST_TSuccess setWindowCursorGrab(bool grab) { return GHOST_kSuccess; };
|
virtual GHOST_TSuccess setWindowCursorGrab(bool grab, bool warp) { return GHOST_kSuccess; };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the cursor shape on the window using
|
* Sets the cursor shape on the window using
|
||||||
@ -272,6 +276,15 @@ protected:
|
|||||||
/** The current grabbed state of the cursor */
|
/** The current grabbed state of the cursor */
|
||||||
bool m_cursorGrabbed;
|
bool m_cursorGrabbed;
|
||||||
|
|
||||||
|
/** The current warped state of the cursor */
|
||||||
|
bool m_cursorWarp;
|
||||||
|
|
||||||
|
/** Initial grab location. */
|
||||||
|
GHOST_TInt32 m_cursorWarpInitPos[2];
|
||||||
|
|
||||||
|
/** Accumulated offset from m_cursorWarpInitPos. */
|
||||||
|
GHOST_TInt32 m_cursorWarpAccumPos[2];
|
||||||
|
|
||||||
/** The current shape of the cursor */
|
/** The current shape of the cursor */
|
||||||
GHOST_TStandardCursor m_cursorShape;
|
GHOST_TStandardCursor m_cursorShape;
|
||||||
|
|
||||||
@ -304,6 +317,42 @@ inline bool GHOST_Window::getCursorVisibility() const
|
|||||||
return m_cursorVisible;
|
return m_cursorVisible;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool GHOST_Window::getCursorWarp() const
|
||||||
|
{
|
||||||
|
return m_cursorWarp;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool GHOST_Window::getCursorWarpPos(GHOST_TInt32 &x, GHOST_TInt32 &y) const
|
||||||
|
{
|
||||||
|
if(m_cursorWarp==false)
|
||||||
|
return GHOST_kFailure;
|
||||||
|
|
||||||
|
x= m_cursorWarpInitPos[0];
|
||||||
|
y= m_cursorWarpInitPos[1];
|
||||||
|
return GHOST_kSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool GHOST_Window::getCursorWarpAccum(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;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool GHOST_Window::setCursorWarpAccum(GHOST_TInt32 x, GHOST_TInt32 y)
|
||||||
|
{
|
||||||
|
if(m_cursorWarp==false)
|
||||||
|
return GHOST_kFailure;
|
||||||
|
|
||||||
|
m_cursorWarpAccumPos[0]= x;
|
||||||
|
m_cursorWarpAccumPos[1]= y;
|
||||||
|
|
||||||
|
return GHOST_kSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
inline GHOST_TStandardCursor GHOST_Window::getCursorShape() const
|
inline GHOST_TStandardCursor GHOST_Window::getCursorShape() const
|
||||||
{
|
{
|
||||||
return m_cursorShape;
|
return m_cursorShape;
|
||||||
|
@ -1400,12 +1400,29 @@ setWindowCursorVisibility(
|
|||||||
GHOST_TSuccess
|
GHOST_TSuccess
|
||||||
GHOST_WindowX11::
|
GHOST_WindowX11::
|
||||||
setWindowCursorGrab(
|
setWindowCursorGrab(
|
||||||
bool grab
|
bool grab, bool warp
|
||||||
){
|
){
|
||||||
if(grab)
|
if(grab) {
|
||||||
|
if(warp) {
|
||||||
|
m_system->getCursorPosition(m_cursorWarpInitPos[0], m_cursorWarpInitPos[1]);
|
||||||
|
|
||||||
|
setCursorWarpAccum(0, 0);
|
||||||
|
setWindowCursorVisibility(false);
|
||||||
|
m_cursorWarp= true;
|
||||||
|
}
|
||||||
XGrabPointer(m_display, m_window, True, ButtonPressMask| ButtonReleaseMask|PointerMotionMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
|
XGrabPointer(m_display, m_window, True, ButtonPressMask| ButtonReleaseMask|PointerMotionMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
|
if(m_cursorWarp) { /* are we exiting warp */
|
||||||
|
setWindowCursorVisibility(true);
|
||||||
|
/* Almost works without but important otherwise the mouse GHOST location can be incorrect on exit */
|
||||||
|
m_system->setCursorPosition(m_cursorWarpInitPos[0], m_cursorWarpInitPos[1]);
|
||||||
|
|
||||||
|
setCursorWarpAccum(0, 0);
|
||||||
|
m_cursorWarp= false;
|
||||||
|
}
|
||||||
XUngrabPointer(m_display, CurrentTime);
|
XUngrabPointer(m_display, CurrentTime);
|
||||||
|
}
|
||||||
|
|
||||||
XFlush(m_display);
|
XFlush(m_display);
|
||||||
|
|
||||||
|
@ -252,10 +252,11 @@ protected:
|
|||||||
/**
|
/**
|
||||||
* Sets the cursor grab on the window using
|
* Sets the cursor grab on the window using
|
||||||
* native window system calls.
|
* native window system calls.
|
||||||
|
* @param warp Only used when grab is enabled, hides the mouse and allows gragging outside the screen.
|
||||||
*/
|
*/
|
||||||
GHOST_TSuccess
|
GHOST_TSuccess
|
||||||
setWindowCursorGrab(
|
setWindowCursorGrab(
|
||||||
bool grab
|
bool grab, bool warp
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -109,8 +109,8 @@ class USERPREF_PT_view(bpy.types.Panel):
|
|||||||
sub1.itemL(text="Mouse Wheel:")
|
sub1.itemL(text="Mouse Wheel:")
|
||||||
sub1.itemR(view, "wheel_invert_zoom", text="Invert Zoom")
|
sub1.itemR(view, "wheel_invert_zoom", text="Invert Zoom")
|
||||||
sub1.itemR(view, "wheel_scroll_lines", text="Scroll Lines")
|
sub1.itemR(view, "wheel_scroll_lines", text="Scroll Lines")
|
||||||
sub1.itemS()
|
sub1.itemL(text="Mouse Motion:")
|
||||||
sub1.itemS()
|
sub1.itemR(view, "continuous_mouse", text="Continuous Grab")
|
||||||
sub1.itemS()
|
sub1.itemS()
|
||||||
sub1.itemL(text="Menus:")
|
sub1.itemL(text="Menus:")
|
||||||
sub1.itemR(view, "open_mouse_over")
|
sub1.itemR(view, "open_mouse_over")
|
||||||
|
@ -230,6 +230,15 @@ static uiBut *ui_but_last(uiBlock *block)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ui_is_a_warp_but(uiBut *but)
|
||||||
|
{
|
||||||
|
if(U.uiflag & USER_CONTINUOUS_MOUSE)
|
||||||
|
if(ELEM(but->type, NUM, NUMABS))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/* ********************** button apply/revert ************************/
|
/* ********************** button apply/revert ************************/
|
||||||
|
|
||||||
static ListBase UIAfterFuncs = {NULL, NULL};
|
static ListBase UIAfterFuncs = {NULL, NULL};
|
||||||
@ -1971,6 +1980,51 @@ static int ui_do_but_EXIT(bContext *C, uiBut *but, uiHandleButtonData *data, wmE
|
|||||||
return WM_UI_HANDLER_CONTINUE;
|
return WM_UI_HANDLER_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* var names match ui_numedit_but_NUM */
|
||||||
|
static float ui_numedit_apply_snapf(float tempf, float softmin, float softmax, float softrange, int snap)
|
||||||
|
{
|
||||||
|
if(tempf==softmin || tempf==softmax)
|
||||||
|
return tempf;
|
||||||
|
|
||||||
|
switch(snap) {
|
||||||
|
case 0:
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
if(tempf==softmin || tempf==softmax) { }
|
||||||
|
else if(softrange < 2.10) tempf= 0.1*floor(10*tempf);
|
||||||
|
else if(softrange < 21.0) tempf= floor(tempf);
|
||||||
|
else tempf= 10.0*floor(tempf/10.0);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if(tempf==softmin || tempf==softmax) { }
|
||||||
|
else if(softrange < 2.10) tempf= 0.01*floor(100.0*tempf);
|
||||||
|
else if(softrange < 21.0) tempf= 0.1*floor(10.0*tempf);
|
||||||
|
else tempf= floor(tempf);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return tempf;
|
||||||
|
}
|
||||||
|
|
||||||
|
static float ui_numedit_apply_snap(int temp, float softmin, float softmax, int snap)
|
||||||
|
{
|
||||||
|
if(temp==softmin || temp==softmax)
|
||||||
|
return temp;
|
||||||
|
|
||||||
|
switch(snap) {
|
||||||
|
case 0:
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
temp= 10*(temp/10);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
temp= 100*(temp/100);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
static int ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data, float fac, int snap, int mx)
|
static int ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data, float fac, int snap, int mx)
|
||||||
{
|
{
|
||||||
float deler, tempf, softmin, softmax, softrange;
|
float deler, tempf, softmin, softmax, softrange;
|
||||||
@ -1993,74 +2047,88 @@ static int ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data, float fac, i
|
|||||||
softmax= but->softmax;
|
softmax= but->softmax;
|
||||||
softrange= softmax - softmin;
|
softrange= softmax - softmin;
|
||||||
|
|
||||||
deler= 500;
|
|
||||||
if(!ui_is_but_float(but)) {
|
|
||||||
if((softrange)<100) deler= 200.0;
|
|
||||||
if((softrange)<25) deler= 50.0;
|
|
||||||
}
|
|
||||||
deler /= fac;
|
|
||||||
|
|
||||||
if(ui_is_but_float(but) && softrange > 11) {
|
if(ui_is_a_warp_but(but)) {
|
||||||
/* non linear change in mouse input- good for high precicsion */
|
/* Mouse location isn't screen clamped to the screen so use a linear mapping
|
||||||
data->dragf+= (((float)(mx-data->draglastx))/deler) * (fabs(data->dragstartx-mx)*0.002);
|
* 2px == 1-int, or 1px == 1-ClickStep */
|
||||||
} else if (!ui_is_but_float(but) && softrange > 129) { /* only scale large int buttons */
|
if(ui_is_but_float(but)) {
|
||||||
/* non linear change in mouse input- good for high precicsionm ints need less fine tuning */
|
tempf = data->startvalue + ((mx - data->dragstartx) * fac * 0.01*but->a1);
|
||||||
data->dragf+= (((float)(mx-data->draglastx))/deler) * (fabs(data->dragstartx-mx)*0.004);
|
tempf= ui_numedit_apply_snapf(tempf, softmin, softmax, softrange, snap);
|
||||||
} else {
|
CLAMP(tempf, softmin, softmax);
|
||||||
/*no scaling */
|
|
||||||
data->dragf+= ((float)(mx-data->draglastx))/deler ;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(data->dragf>1.0) data->dragf= 1.0;
|
if(tempf != data->value) {
|
||||||
if(data->dragf<0.0) data->dragf= 0.0;
|
data->dragchange= 1;
|
||||||
data->draglastx= mx;
|
data->value= tempf;
|
||||||
tempf= (softmin + data->dragf*softrange);
|
changed= 1;
|
||||||
|
}
|
||||||
if(!ui_is_but_float(but)) {
|
|
||||||
temp= floor(tempf+.5);
|
|
||||||
|
|
||||||
if(tempf==softmin || tempf==softmax);
|
|
||||||
else if(snap) {
|
|
||||||
if(snap == 2) temp= 100*(temp/100);
|
|
||||||
else temp= 10*(temp/10);
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
temp= data->startvalue + (mx - data->dragstartx)/2; /* simple 2px == 1 */
|
||||||
|
temp= ui_numedit_apply_snap(temp, softmin, softmax, snap);
|
||||||
|
CLAMP(temp, softmin, softmax);
|
||||||
|
|
||||||
CLAMP(temp, softmin, softmax);
|
if(temp != data->value) {
|
||||||
lvalue= (int)data->value;
|
data->dragchange= 1;
|
||||||
|
data->value= temp;
|
||||||
if(temp != lvalue) {
|
changed= 1;
|
||||||
data->dragchange= 1;
|
}
|
||||||
data->value= (double)temp;
|
|
||||||
changed= 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
temp= 0;
|
/* Use a non-linear mapping of the mouse drag especially for large floats (normal behavior) */
|
||||||
|
deler= 500;
|
||||||
|
if(!ui_is_but_float(but)) {
|
||||||
|
if((softrange)<100) deler= 200.0;
|
||||||
|
if((softrange)<25) deler= 50.0;
|
||||||
|
}
|
||||||
|
deler /= fac;
|
||||||
|
|
||||||
if(snap) {
|
if(ui_is_but_float(but) && softrange > 11) {
|
||||||
if(snap == 2) {
|
/* non linear change in mouse input- good for high precicsion */
|
||||||
if(tempf==softmin || tempf==softmax);
|
data->dragf+= (((float)(mx-data->draglastx))/deler) * (fabs(data->dragstartx-mx)*0.002);
|
||||||
else if(softrange < 2.10) tempf= 0.01*floor(100.0*tempf);
|
} else if (!ui_is_but_float(but) && softrange > 129) { /* only scale large int buttons */
|
||||||
else if(softrange < 21.0) tempf= 0.1*floor(10.0*tempf);
|
/* non linear change in mouse input- good for high precicsionm ints need less fine tuning */
|
||||||
else tempf= floor(tempf);
|
data->dragf+= (((float)(mx-data->draglastx))/deler) * (fabs(data->dragstartx-mx)*0.004);
|
||||||
}
|
} else {
|
||||||
else {
|
/*no scaling */
|
||||||
if(tempf==softmin || tempf==softmax);
|
data->dragf+= ((float)(mx-data->draglastx))/deler ;
|
||||||
else if(softrange < 2.10) tempf= 0.1*floor(10*tempf);
|
|
||||||
else if(softrange < 21.0) tempf= floor(tempf);
|
|
||||||
else tempf= 10.0*floor(tempf/10.0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CLAMP(tempf, softmin, softmax);
|
if(data->dragf>1.0) data->dragf= 1.0;
|
||||||
|
if(data->dragf<0.0) data->dragf= 0.0;
|
||||||
|
data->draglastx= mx;
|
||||||
|
tempf= (softmin + data->dragf*softrange);
|
||||||
|
|
||||||
if(tempf != data->value) {
|
|
||||||
data->dragchange= 1;
|
if(!ui_is_but_float(but)) {
|
||||||
data->value= tempf;
|
temp= floor(tempf+.5);
|
||||||
changed= 1;
|
|
||||||
|
temp= ui_numedit_apply_snap(temp, softmin, softmax, snap);
|
||||||
|
|
||||||
|
CLAMP(temp, softmin, softmax);
|
||||||
|
lvalue= (int)data->value;
|
||||||
|
|
||||||
|
if(temp != lvalue) {
|
||||||
|
data->dragchange= 1;
|
||||||
|
data->value= (double)temp;
|
||||||
|
changed= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
temp= 0;
|
||||||
|
tempf= ui_numedit_apply_snapf(tempf, softmin, softmax, softrange, snap);
|
||||||
|
|
||||||
|
CLAMP(tempf, softmin, softmax);
|
||||||
|
|
||||||
|
if(tempf != data->value) {
|
||||||
|
data->dragchange= 1;
|
||||||
|
data->value= tempf;
|
||||||
|
changed= 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2071,7 +2139,10 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
|
|||||||
|
|
||||||
mx= event->x;
|
mx= event->x;
|
||||||
my= event->y;
|
my= event->y;
|
||||||
ui_window_to_block(data->region, block, &mx, &my);
|
|
||||||
|
if(!ui_is_a_warp_but(but)) {
|
||||||
|
ui_window_to_block(data->region, block, &mx, &my);
|
||||||
|
}
|
||||||
|
|
||||||
if(data->state == BUTTON_STATE_HIGHLIGHT) {
|
if(data->state == BUTTON_STATE_HIGHLIGHT) {
|
||||||
/* XXX hardcoded keymap check.... */
|
/* XXX hardcoded keymap check.... */
|
||||||
@ -3636,11 +3707,15 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s
|
|||||||
ui_textedit_end(C, but, data);
|
ui_textedit_end(C, but, data);
|
||||||
|
|
||||||
/* number editing */
|
/* number editing */
|
||||||
if(state == BUTTON_STATE_NUM_EDITING)
|
if(state == BUTTON_STATE_NUM_EDITING) {
|
||||||
|
if(ui_is_a_warp_but(but))
|
||||||
|
WM_cursor_grab(CTX_wm_window(C), 1, 1);
|
||||||
ui_numedit_begin(but, data);
|
ui_numedit_begin(but, data);
|
||||||
else if(data->state == BUTTON_STATE_NUM_EDITING)
|
} else if(data->state == BUTTON_STATE_NUM_EDITING) {
|
||||||
ui_numedit_end(but, data);
|
ui_numedit_end(but, data);
|
||||||
|
if(ui_is_a_warp_but(but))
|
||||||
|
WM_cursor_grab(CTX_wm_window(C), 0, -1);
|
||||||
|
}
|
||||||
/* menu open */
|
/* menu open */
|
||||||
if(state == BUTTON_STATE_MENU_OPEN)
|
if(state == BUTTON_STATE_MENU_OPEN)
|
||||||
ui_blockopen_begin(C, but, data);
|
ui_blockopen_begin(C, but, data);
|
||||||
|
@ -402,6 +402,7 @@ extern UserDef U; /* from blenkernel blender.c */
|
|||||||
#define USER_SHOW_FPS (1 << 21)
|
#define USER_SHOW_FPS (1 << 21)
|
||||||
#define USER_MMB_PASTE (1 << 22)
|
#define USER_MMB_PASTE (1 << 22)
|
||||||
#define USER_MENUFIXEDORDER (1 << 23)
|
#define USER_MENUFIXEDORDER (1 << 23)
|
||||||
|
#define USER_CONTINUOUS_MOUSE (1 << 24)
|
||||||
|
|
||||||
/* Auto-Keying mode */
|
/* Auto-Keying mode */
|
||||||
/* AUTOKEY_ON is a bitflag */
|
/* AUTOKEY_ON is a bitflag */
|
||||||
|
@ -1655,6 +1655,10 @@ static void rna_def_userdef_view(BlenderRNA *brna)
|
|||||||
RNA_def_property_boolean_negative_sdna(prop, NULL, "uiflag", USER_MENUFIXEDORDER);
|
RNA_def_property_boolean_negative_sdna(prop, NULL, "uiflag", USER_MENUFIXEDORDER);
|
||||||
RNA_def_property_ui_text(prop, "Contents Follow Opening Direction", "Otherwise menus, etc will always be top to bottom, left to right, no matter opening direction.");
|
RNA_def_property_ui_text(prop, "Contents Follow Opening Direction", "Otherwise menus, etc will always be top to bottom, left to right, no matter opening direction.");
|
||||||
|
|
||||||
|
prop= RNA_def_property(srna, "continuous_mouse", PROP_BOOLEAN, PROP_NONE);
|
||||||
|
RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_CONTINUOUS_MOUSE);
|
||||||
|
RNA_def_property_ui_text(prop, "Contents Follow Opening Direction", "Otherwise menus, etc will always be top to bottom, left to right, no matter opening direction.");
|
||||||
|
|
||||||
prop= RNA_def_property(srna, "global_pivot", PROP_BOOLEAN, PROP_NONE);
|
prop= RNA_def_property(srna, "global_pivot", PROP_BOOLEAN, PROP_NONE);
|
||||||
RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_LOCKAROUND);
|
RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_LOCKAROUND);
|
||||||
RNA_def_property_ui_text(prop, "Global Pivot", "Lock the same rotation/scaling pivot in all 3D Views.");
|
RNA_def_property_ui_text(prop, "Global Pivot", "Lock the same rotation/scaling pivot in all 3D Views.");
|
||||||
|
@ -75,7 +75,7 @@ void WM_cursor_set (struct wmWindow *win, int curs);
|
|||||||
void WM_cursor_modal (struct wmWindow *win, int curs);
|
void WM_cursor_modal (struct wmWindow *win, int curs);
|
||||||
void WM_cursor_restore (struct wmWindow *win);
|
void WM_cursor_restore (struct wmWindow *win);
|
||||||
void WM_cursor_wait (int val);
|
void WM_cursor_wait (int val);
|
||||||
void WM_cursor_grab (struct wmWindow *win, int val);
|
void WM_cursor_grab (struct wmWindow *win, int val, int warp);
|
||||||
void WM_timecursor (struct wmWindow *win, int nr);
|
void WM_timecursor (struct wmWindow *win, int nr);
|
||||||
|
|
||||||
void *WM_paint_cursor_activate(struct wmWindowManager *wm, int (*poll)(struct bContext *C), void (*draw)(struct bContext *C, int, int, void *customdata), void *customdata);
|
void *WM_paint_cursor_activate(struct wmWindowManager *wm, int (*poll)(struct bContext *C), void (*draw)(struct bContext *C, int, int, void *customdata), void *customdata);
|
||||||
|
@ -163,10 +163,10 @@ void WM_cursor_wait(int val)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WM_cursor_grab(wmWindow *win, int val)
|
void WM_cursor_grab(wmWindow *win, int val, int warp)
|
||||||
{
|
{
|
||||||
if(win)
|
if(win)
|
||||||
GHOST_SetCursorGrab(win->ghostwin, val);
|
GHOST_SetCursorGrab(win->ghostwin, val, warp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* afer this you can call restore too */
|
/* afer this you can call restore too */
|
||||||
|
@ -442,7 +442,7 @@ static int wm_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event, P
|
|||||||
else if(retval & OPERATOR_RUNNING_MODAL) {
|
else if(retval & OPERATOR_RUNNING_MODAL) {
|
||||||
/* grab cursor during blocking modal ops (X11) */
|
/* grab cursor during blocking modal ops (X11) */
|
||||||
if(ot->flag & OPTYPE_BLOCKING)
|
if(ot->flag & OPTYPE_BLOCKING)
|
||||||
WM_cursor_grab(CTX_wm_window(C), 1);
|
WM_cursor_grab(CTX_wm_window(C), 1, (U.uiflag & USER_CONTINUOUS_MOUSE));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
WM_operator_free(op);
|
WM_operator_free(op);
|
||||||
@ -637,8 +637,8 @@ void WM_event_remove_handlers(bContext *C, ListBase *handlers)
|
|||||||
CTX_wm_region_set(C, region);
|
CTX_wm_region_set(C, region);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WM_cursor_grab(CTX_wm_window(C), 0, -1);
|
||||||
WM_operator_free(handler->op);
|
WM_operator_free(handler->op);
|
||||||
WM_cursor_grab(CTX_wm_window(C), 0);
|
|
||||||
}
|
}
|
||||||
else if(handler->ui_remove) {
|
else if(handler->ui_remove) {
|
||||||
ScrArea *area= CTX_wm_area(C);
|
ScrArea *area= CTX_wm_area(C);
|
||||||
@ -835,7 +835,7 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand
|
|||||||
|
|
||||||
/* remove modal handler, operator itself should have been cancelled and freed */
|
/* remove modal handler, operator itself should have been cancelled and freed */
|
||||||
if(retval & (OPERATOR_CANCELLED|OPERATOR_FINISHED)) {
|
if(retval & (OPERATOR_CANCELLED|OPERATOR_FINISHED)) {
|
||||||
WM_cursor_grab(CTX_wm_window(C), 0);
|
WM_cursor_grab(CTX_wm_window(C), 0, -1);
|
||||||
|
|
||||||
BLI_remlink(handlers, handler);
|
BLI_remlink(handlers, handler);
|
||||||
wm_event_free_handler(handler);
|
wm_event_free_handler(handler);
|
||||||
|
Loading…
Reference in New Issue
Block a user