diff options
author | Campbell Barton <ideasman42@gmail.com> | 2017-12-11 13:35:23 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2017-12-11 13:38:55 +0300 |
commit | 6475f163ecf137b3bfc8a64405e194eef44d8746 (patch) | |
tree | d0992073d4ccd8a8525586edec430d152dc3af59 /source/blender/windowmanager | |
parent | 4737b95b6519bc1b66a812bab73d4664b3098261 (diff) |
Manipulator: make grab-cursor a manipulator flag
As with operators, allow manipulators to grab the cursor.
Previously this was enabled for all 3D manipulators.
Diffstat (limited to 'source/blender/windowmanager')
3 files changed, 31 insertions, 6 deletions
diff --git a/source/blender/windowmanager/manipulators/WM_manipulator_types.h b/source/blender/windowmanager/manipulators/WM_manipulator_types.h index 5fa89b8d35f..e8b81e1a78c 100644 --- a/source/blender/windowmanager/manipulators/WM_manipulator_types.h +++ b/source/blender/windowmanager/manipulators/WM_manipulator_types.h @@ -80,6 +80,10 @@ typedef enum eWM_ManipulatorFlag { * This simply skips scale when calculating the final matrix. * Needed when the manipulator needs to align with the interface underneath it. */ WM_MANIPULATOR_DRAW_NO_SCALE = (1 << 5), + /** + * Hide the cursor and lock it's position while interacting with this manipulator. + */ + WM_MANIPULATOR_GRAB_CURSOR = (1 << 6), } eWM_ManipulatorFlag; /** diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulator_intern.h b/source/blender/windowmanager/manipulators/intern/wm_manipulator_intern.h index bf5c38b9e39..419ac7d5521 100644 --- a/source/blender/windowmanager/manipulators/intern/wm_manipulator_intern.h +++ b/source/blender/windowmanager/manipulators/intern/wm_manipulator_intern.h @@ -112,6 +112,9 @@ struct wmManipulatorMap { struct wmManipulator *modal; /* array for all selected manipulators */ struct wmManipulatorMapSelectState select; + /* cursor location at point of entering modal (see: WM_MANIPULATOR_GRAB_CURSOR) */ + int event_xy[2]; + short event_grabcursor; } mmap_context; }; diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulator_map.c b/source/blender/windowmanager/manipulators/intern/wm_manipulator_map.c index 5d9810272cc..ba3b405e612 100644 --- a/source/blender/windowmanager/manipulators/intern/wm_manipulator_map.c +++ b/source/blender/windowmanager/manipulators/intern/wm_manipulator_map.c @@ -886,9 +886,9 @@ void wm_manipulatormap_modal_set( { if (enable) { BLI_assert(mmap->mmap_context.modal == NULL); + wmWindow *win = CTX_wm_window(C); /* For now only grab cursor for 3D manipulators. */ - bool grab_cursor = (mpr->parent_mgroup->type->flag & WM_MANIPULATORGROUPTYPE_3D) != 0; int retval = OPERATOR_RUNNING_MODAL; if (mpr->type->invoke && @@ -904,6 +904,17 @@ void wm_manipulatormap_modal_set( mpr->state |= WM_MANIPULATOR_STATE_MODAL; mmap->mmap_context.modal = mpr; + if ((mpr->flag & WM_MANIPULATOR_GRAB_CURSOR) && + (WM_event_is_absolute(event) == false)) + { + WM_cursor_grab_enable(win, true, true, NULL); + copy_v2_v2_int(mmap->mmap_context.event_xy, &event->x); + mmap->mmap_context.event_grabcursor = win->grabcursor; + } + else { + mmap->mmap_context.event_xy[0] = INT_MAX; + } + struct wmManipulatorOpElem *mpop = WM_manipulator_operator_get(mpr, mpr->highlight_part); if (mpop && mpop->type) { WM_operator_name_call_ptr(C, mpop->type, WM_OP_INVOKE_DEFAULT, &mpop->ptr); @@ -915,10 +926,6 @@ void wm_manipulatormap_modal_set( } return; } - - if (grab_cursor) { - WM_cursor_grab_enable(CTX_wm_window(C), true, true, NULL); - } } else { BLI_assert(ELEM(mmap->mmap_context.modal, NULL, mpr)); @@ -931,7 +938,18 @@ void wm_manipulatormap_modal_set( mmap->mmap_context.modal = NULL; if (C) { - WM_cursor_grab_disable(CTX_wm_window(C), NULL); + wmWindow *win = CTX_wm_window(C); + if (mmap->mmap_context.event_xy[0] != INT_MAX) { + /* Check if some other part of Blender (typically operators) + * have adjusted the grab mode since it was set. + * If so: warp, so we have a predictable outcome. */ + if (mmap->mmap_context.event_grabcursor == win->grabcursor) { + WM_cursor_grab_disable(win, mmap->mmap_context.event_xy); + } + else { + WM_cursor_warp(win, UNPACK2(mmap->mmap_context.event_xy)); + } + } ED_region_tag_redraw(CTX_wm_region(C)); WM_event_add_mousemove(C); } |