Cleanup: improve docs for grab functions & use rcti for the wrap region

- Use typed enum for the wrap axis.
- Rename `bounds` to `wrap_region`.
- Take a `rcti` argument instead of an `int[4]`.
- Pair wrap & wrap_region arguments together.
This commit is contained in:
Campbell Barton 2022-12-15 13:50:49 +11:00
parent 0240b89599
commit 5da11e22de
10 changed files with 61 additions and 43 deletions

View File

@ -8306,7 +8306,7 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s
/* number editing */
if (state == BUTTON_STATE_NUM_EDITING) {
if (ui_but_is_cursor_warp(but)) {
WM_cursor_grab_enable(CTX_wm_window(C), WM_CURSOR_WRAP_XY, true, nullptr);
WM_cursor_grab_enable(CTX_wm_window(C), WM_CURSOR_WRAP_XY, nullptr, true);
}
ui_numedit_begin(but, data);
}

View File

@ -612,18 +612,18 @@ static bool initWalkInfo(bContext *C, WalkInfo *walk, wmOperator *op, const int
#ifdef USE_CURSOR_WARP_HACK
if (WM_capabilities_flag() & WM_CAPABILITY_CURSOR_WARP) {
int bounds[4];
const rcti *rect = &walk->region->winrct;
const int center[2] = {BLI_rcti_cent_x(rect), BLI_rcti_cent_y(rect)};
const int size[2] = {BLI_rcti_size_x(rect), BLI_rcti_size_y(rect)};
const rcti *winrct = &walk->region->winrct;
const int center[2] = {BLI_rcti_cent_x(winrct), BLI_rcti_cent_y(winrct)};
const int size[2] = {BLI_rcti_size_x(winrct), BLI_rcti_size_y(winrct)};
const int div = 4; /* Where 2 is the region size. */
bounds[0] = center[0] - (size[0] / div); /* X-min. */
bounds[1] = center[1] + (size[1] / div); /* Y-max. */
bounds[2] = center[0] + (size[0] / div); /* X-max. */
bounds[3] = center[1] - (size[1] / div); /* Y-min. */
rcti wrap_region = {};
wrap_region.xmin = center[0] - (size[0] / div);
wrap_region.xmax = center[0] + (size[0] / div);
wrap_region.ymin = center[1] - (size[1] / div);
wrap_region.ymax = center[1] + (size[1] / div);
WM_cursor_grab_enable(win, WM_CURSOR_WRAP_XY, false, bounds);
WM_cursor_grab_enable(win, WM_CURSOR_WRAP_XY, &wrap_region, false);
/* Important to hide afterwards (not part of grabbing),
* since enabling cursor and hiding at the same time ignores bounds. */
@ -633,7 +633,7 @@ static bool initWalkInfo(bContext *C, WalkInfo *walk, wmOperator *op, const int
else
#endif /* USE_CURSOR_WARP_HACK */
{
WM_cursor_grab_enable(win, 0, true, NULL);
WM_cursor_grab_enable(win, WM_CURSOR_WRAP_NONE, NULL, true);
}
return 1;

View File

@ -277,7 +277,7 @@ typedef struct wmWindow {
short lastcursor;
/** The current modal cursor. */
short modalcursor;
/** Cursor grab mode. */
/** Cursor grab mode #GHOST_TGrabCursorMode (run-time only) */
short grabcursor;
/** Internal: tag this for extra mouse-move event,
* makes cursors/buttons active on UI switching. */

View File

@ -321,9 +321,22 @@ void WM_cursor_modal_restore(struct wmWindow *win);
*/
void WM_cursor_wait(bool val);
/**
* \param bounds: can be NULL
* Enable cursor grabbing, optionally hiding the cursor and wrapping cursor-motion
* within a sub-region of the window.
*
* \param wrap: an enum (#WM_CURSOR_WRAP_NONE, #WM_CURSOR_WRAP_XY... etc).
* \param wrap_region: Window-relative region for cursor wrapping (when `wrap` is
* #WM_CURSOR_WRAP_XY). When NULL, the window bounds are used for wrapping.
*
* \note The current grab state can be accessed by #wmWindowManager.grabcursor although.
*/
void WM_cursor_grab_enable(struct wmWindow *win,
eWM_CursorWrapAxis wrap,
const struct rcti *wrap_region,
bool hide);
/**
*
*/
void WM_cursor_grab_enable(struct wmWindow *win, int wrap, bool hide, int bounds[4]);
void WM_cursor_grab_disable(struct wmWindow *win, const int mouse_ungrab_xy[2]);
/**
* After this you can call restore too.
@ -344,7 +357,10 @@ void WM_paint_cursor_remove_by_type(struct wmWindowManager *wm,
void WM_paint_cursor_tag_redraw(struct wmWindow *win, struct ARegion *region);
/**
* This function requires access to the GHOST_SystemHandle (g_system).
* Set the cursor location in window coordinates (compatible with #wmEvent.xy).
*
* \note Some platforms don't support this, check: #WM_CAPABILITY_WINDOW_POSITION
* before relying on this functionality.
*/
void WM_cursor_warp(struct wmWindow *win, int x, int y);

View File

@ -185,12 +185,12 @@ enum {
};
/** For #WM_cursor_grab_enable wrap axis. */
enum {
typedef enum eWM_CursorWrapAxis {
WM_CURSOR_WRAP_NONE = 0,
WM_CURSOR_WRAP_X,
WM_CURSOR_WRAP_Y,
WM_CURSOR_WRAP_XY,
};
} eWM_CursorWrapAxis;
/**
* Context to call operator in for #WM_operator_name_call.

View File

@ -1062,7 +1062,7 @@ void wm_gizmomap_modal_set(
gzmap->gzmap_context.modal = gz;
if ((gz->flag & WM_GIZMO_MOVE_CURSOR) && (event->tablet.is_motion_absolute == false)) {
WM_cursor_grab_enable(win, WM_CURSOR_WRAP_XY, true, NULL);
WM_cursor_grab_enable(win, WM_CURSOR_WRAP_XY, NULL, true);
copy_v2_v2_int(gzmap->gzmap_context.event_xy, event->xy);
gzmap->gzmap_context.event_grabcursor = win->grabcursor;
}

View File

@ -223,22 +223,33 @@ void WM_cursor_wait(bool val)
}
}
void WM_cursor_grab_enable(wmWindow *win, int wrap, bool hide, int bounds[4])
void WM_cursor_grab_enable(wmWindow *win,
const eWM_CursorWrapAxis wrap,
const rcti *wrap_region,
const bool hide)
{
int _wrap_region_buf[4];
int *wrap_region_screen = NULL;
/* Only grab cursor when not running debug.
* It helps not to get a stuck WM when hitting a break-point. */
GHOST_TGrabCursorMode mode = GHOST_kGrabNormal;
GHOST_TAxisFlag mode_axis = GHOST_kAxisX | GHOST_kAxisY;
if (bounds) {
wm_cursor_position_to_ghost_screen_coords(win, &bounds[0], &bounds[1]);
wm_cursor_position_to_ghost_screen_coords(win, &bounds[2], &bounds[3]);
if (wrap_region) {
wrap_region_screen = _wrap_region_buf;
wrap_region_screen[0] = wrap_region->xmin;
wrap_region_screen[1] = wrap_region->ymax;
wrap_region_screen[2] = wrap_region->xmax;
wrap_region_screen[3] = wrap_region->ymin;
wm_cursor_position_to_ghost_screen_coords(win, &wrap_region_screen[0], &wrap_region_screen[1]);
wm_cursor_position_to_ghost_screen_coords(win, &wrap_region_screen[2], &wrap_region_screen[3]);
}
if (hide) {
mode = GHOST_kGrabHide;
}
else if (wrap) {
else if (wrap != WM_CURSOR_WRAP_NONE) {
mode = GHOST_kGrabWrap;
if (wrap == WM_CURSOR_WRAP_X) {
@ -252,7 +263,7 @@ void WM_cursor_grab_enable(wmWindow *win, int wrap, bool hide, int bounds[4])
if ((G.debug & G_DEBUG) == 0) {
if (win->ghostwin) {
if (win->eventstate->tablet.is_motion_absolute == false) {
GHOST_SetCursorGrab(win->ghostwin, mode, mode_axis, bounds, NULL);
GHOST_SetCursorGrab(win->ghostwin, mode, mode_axis, wrap_region_screen, NULL);
}
win->grabcursor = mode;

View File

@ -1517,8 +1517,8 @@ static int wm_operator_invoke(bContext *C,
/* Grab cursor during blocking modal operators (X11)
* Also check for macro. */
if (ot->flag & OPTYPE_BLOCKING || (op->opm && op->opm->type->flag & OPTYPE_BLOCKING)) {
int bounds[4] = {-1, -1, -1, -1};
int wrap = WM_CURSOR_WRAP_NONE;
eWM_CursorWrapAxis wrap = WM_CURSOR_WRAP_NONE;
const rcti *wrap_region = nullptr;
if (event && (U.uiflag & USER_CONTINUOUS_MOUSE)) {
const wmOperator *op_test = op->opm ? op->opm : op;
@ -1536,7 +1536,6 @@ static int wm_operator_invoke(bContext *C,
}
if (wrap) {
const rcti *winrect = nullptr;
ARegion *region = CTX_wm_region(C);
ScrArea *area = CTX_wm_area(C);
@ -1547,21 +1546,14 @@ static int wm_operator_invoke(bContext *C,
if (region && region->regiontype == RGN_TYPE_WINDOW &&
BLI_rcti_isect_pt_v(&region->winrct, event->xy)) {
winrect = &region->winrct;
wrap_region = &region->winrct;
}
else if (area && BLI_rcti_isect_pt_v(&area->totrct, event->xy)) {
winrect = &area->totrct;
}
if (winrect) {
bounds[0] = winrect->xmin;
bounds[1] = winrect->ymax;
bounds[2] = winrect->xmax;
bounds[3] = winrect->ymin;
wrap_region = &area->totrct;
}
}
WM_cursor_grab_enable(CTX_wm_window(C), wrap, false, bounds);
WM_cursor_grab_enable(CTX_wm_window(C), wrap, wrap_region, false);
}
/* Cancel UI handlers, typically tool-tips that can hang around

View File

@ -411,8 +411,8 @@ static int wm_macro_modal(bContext *C, wmOperator *op, const wmEvent *event)
/* If operator is blocking, grab cursor.
* This may end up grabbing twice, but we don't care. */
if (op->opm->type->flag & OPTYPE_BLOCKING) {
int bounds[4] = {-1, -1, -1, -1};
int wrap = WM_CURSOR_WRAP_NONE;
const rcti *wrap_region = NULL;
if ((op->opm->flag & OP_IS_MODAL_GRAB_CURSOR) ||
(op->opm->type->flag & OPTYPE_GRAB_CURSOR_XY)) {
@ -428,14 +428,11 @@ static int wm_macro_modal(bContext *C, wmOperator *op, const wmEvent *event)
if (wrap) {
ARegion *region = CTX_wm_region(C);
if (region) {
bounds[0] = region->winrct.xmin;
bounds[1] = region->winrct.ymax;
bounds[2] = region->winrct.xmax;
bounds[3] = region->winrct.ymin;
wrap_region = &region->winrct;
}
}
WM_cursor_grab_enable(win, wrap, false, bounds);
WM_cursor_grab_enable(win, wrap, wrap_region, false);
}
}
}

View File

@ -2103,6 +2103,8 @@ void WM_init_input_devices(void)
void WM_cursor_warp(wmWindow *win, int x, int y)
{
/* This function requires access to the GHOST_SystemHandle (`g_system`). */
if (!(win && win->ghostwin)) {
return;
}