2.5
Sanitized the 'tweak' event.
Original idea was to have WM event system generating it
automatically. However, I first tested it via a handler
and operator, to check what kind of configurations would
be useful. It appeared to not work nice, also because
that inserting a tweak operator in a keymap is confusing.
Now 'tweaks' are generated automatically, and can be
catched by keymaps as any event. The current definition
of tweak is:
- if Left/Middle/Rightmouse pressed
if event wasn't handled by window queue (modal handlers)
start checking mousepositions
- while mousepositions are checked
- escape on any event other than mouse
- on mouse events:
- add tweak event if mousemove > 10 pixels
- stop checking for tweak if mousebutton released
- Tweak events have a define indicating mousebutton used
EVT_TWEAK_L, EVT_TWEAK_M, EVT_TWEAK_R
- In keymap definitions you can use _S or _A to map to
action or select mouse userdef.
- Event value in keymap should be KM_ANY for all tweaks,
or use one of the eight directions:
EVT_GESTURE_E, _SE, _S, _SW, _W, _NW, _N, _NE
- And of course you can add modifier checks in keymaps for it.
- Because tweaks are a result of mouse events, the handlers get
both to evaluate. That means that RMB-select + tweak will work
correctly.
In case you don't want both to be handled, for example the
CTRL+LMB 'extrude' and CTRL+LMB-tweak 'lasso select', you will
need to set the first acting on a EVT_RELEASE, this event only
gets passed on when tweak fails.
The current system allows all options, configurable, we had in 2.48,
and many more! A diagram of what's possible is on the todo. :)
Also in this commit: lasso select editmesh failed with 'zbuffer
occluded select'. Also circle-select failed.
This commit is contained in:
@@ -3945,11 +3945,13 @@ static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm)
|
||||
win->ghostwin= NULL;
|
||||
win->eventstate= NULL;
|
||||
win->curswin= NULL;
|
||||
|
||||
win->tweak= NULL;
|
||||
|
||||
win->timers.first= win->timers.last= NULL;
|
||||
win->queue.first= win->queue.last= NULL;
|
||||
win->handlers.first= win->handlers.last= NULL;
|
||||
win->subwindows.first= win->subwindows.last= NULL;
|
||||
win->gesture.first= win->gesture.last= NULL;
|
||||
|
||||
win->drawdata= NULL;
|
||||
win->drawmethod= -1;
|
||||
|
||||
@@ -889,7 +889,4 @@ void ED_marker_keymap(wmWindowManager *wm)
|
||||
|
||||
WM_keymap_add_item(keymap, "MARKER_OT_move", GKEY, KM_PRESS, 0, 0);
|
||||
|
||||
/* generates event, needs to be after select to work */
|
||||
WM_keymap_tweak(keymap, SELECTMOUSE, KM_PRESS, 0, 0);
|
||||
|
||||
}
|
||||
|
||||
@@ -247,10 +247,9 @@ int EM_mask_init_backbuf_border(ViewContext *vc, short mcords[][2], short tot, s
|
||||
}
|
||||
else if(vc->v3d->drawtype<OB_SOLID || (vc->v3d->flag & V3D_ZBUF_SELECT)==0) return 0;
|
||||
|
||||
if(em_vertoffs==0) return 0;
|
||||
|
||||
buf= view3d_read_backbuf(vc, xmin, ymin, xmax, ymax);
|
||||
if(buf==NULL) return 0;
|
||||
if(em_vertoffs==0) return 0;
|
||||
|
||||
dr = buf->rect;
|
||||
|
||||
@@ -260,6 +259,7 @@ int EM_mask_init_backbuf_border(ViewContext *vc, short mcords[][2], short tot, s
|
||||
glColor3ub(0, 0, 0);
|
||||
|
||||
/* yah, opengl doesn't do concave... tsk! */
|
||||
ED_region_pixelspace(vc->ar);
|
||||
draw_triangulated(mcords, tot);
|
||||
|
||||
glBegin(GL_LINE_LOOP); /* for zero sized masks, lines */
|
||||
@@ -301,11 +301,11 @@ int EM_init_backbuf_circle(ViewContext *vc, short xs, short ys, short rads)
|
||||
else return 0;
|
||||
}
|
||||
else if(vc->v3d->drawtype<OB_SOLID || (vc->v3d->flag & V3D_ZBUF_SELECT)==0) return 0;
|
||||
if(em_vertoffs==0) return 0;
|
||||
|
||||
xmin= xs-rads; xmax= xs+rads;
|
||||
ymin= ys-rads; ymax= ys+rads;
|
||||
buf= view3d_read_backbuf(vc, xmin, ymin, xmax, ymax);
|
||||
if(em_vertoffs==0) return 0;
|
||||
if(buf==NULL) return 0;
|
||||
|
||||
dr = buf->rect;
|
||||
|
||||
@@ -206,9 +206,6 @@ void ED_keymap_mesh(wmWindowManager *wm)
|
||||
|
||||
WM_keymap_add_item(keymap, "MESH_OT_selection_type", TABKEY, KM_PRESS, KM_CTRL, 0);
|
||||
|
||||
|
||||
/* transform keymap already defined, so no tweaks for select */
|
||||
|
||||
/* hide */
|
||||
WM_keymap_add_item(keymap, "MESH_OT_hide", HKEY, KM_PRESS, 0, 0);
|
||||
RNA_boolean_set(WM_keymap_add_item(keymap, "MESH_OT_hide", HKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "invert", 1);
|
||||
@@ -236,7 +233,8 @@ void ED_keymap_mesh(wmWindowManager *wm)
|
||||
WM_keymap_add_item(keymap, "MESH_OT_add_duplicate", DKEY, KM_PRESS, KM_SHIFT, 0);
|
||||
WM_keymap_add_item(keymap, "OBJECT_OT_mesh_add", AKEY, KM_PRESS, KM_SHIFT, 0);
|
||||
WM_keymap_add_item(keymap, "MESH_OT_separate", PKEY, KM_PRESS, KM_SHIFT, 0);
|
||||
WM_keymap_add_item(keymap, "MESH_OT_dupli_extrude_cursor", LEFTMOUSE, KM_PRESS, KM_CTRL, 0);
|
||||
/* use KM_RELEASE because same key is used for tweaks */
|
||||
WM_keymap_add_item(keymap, "MESH_OT_dupli_extrude_cursor", LEFTMOUSE, KM_RELEASE, KM_CTRL, 0);
|
||||
|
||||
WM_keymap_add_item(keymap, "MESH_OT_delete", XKEY, KM_PRESS, 0, 0);
|
||||
|
||||
|
||||
@@ -139,9 +139,6 @@ static void action_keymap_keyframes (wmWindowManager *wm, ListBase *keymap)
|
||||
WM_keymap_add_item(keymap, "ACT_OT_set_previewrange", PKEY, KM_PRESS, KM_CTRL|KM_ALT, 0);
|
||||
WM_keymap_add_item(keymap, "ACT_OT_view_all", HOMEKEY, KM_PRESS, 0, 0);
|
||||
|
||||
/* generates event, needs to be after select to work */
|
||||
WM_keymap_tweak(keymap, SELECTMOUSE, KM_PRESS, 0, 0);
|
||||
|
||||
/* transform system */
|
||||
transform_keymap_for_space(wm, keymap, SPACE_ACTION);
|
||||
}
|
||||
|
||||
@@ -186,9 +186,6 @@ static void graphedit_keymap_keyframes (wmWindowManager *wm, ListBase *keymap)
|
||||
//WM_keymap_add_item(keymap, "GRAPHEDIT_OT_set_previewrange", PKEY, KM_PRESS, KM_CTRL|KM_ALT, 0);
|
||||
//WM_keymap_add_item(keymap, "GRAPHEDIT_OT_view_all", HOMEKEY, KM_PRESS, 0, 0);
|
||||
|
||||
/* generates event, needs to be after select to work */
|
||||
WM_keymap_tweak(keymap, SELECTMOUSE, KM_PRESS, 0, 0);
|
||||
|
||||
/* transform system */
|
||||
transform_keymap_for_space(wm, keymap, SPACE_IPO);
|
||||
}
|
||||
|
||||
@@ -73,9 +73,5 @@ void node_keymap(struct wmWindowManager *wm)
|
||||
WM_keymap_add_item(keymap, "NODE_OT_border_select", BKEY, KM_PRESS, 0, 0);
|
||||
WM_keymap_add_item(keymap, "NODE_OT_delete_selection", XKEY, KM_PRESS, 0, 0);
|
||||
|
||||
/* generates event, needs to be after select to work */
|
||||
WM_keymap_tweak(keymap, ACTIONMOUSE, KM_PRESS, 0, 0);
|
||||
WM_keymap_tweak(keymap, SELECTMOUSE, KM_PRESS, 0, 0);
|
||||
|
||||
transform_keymap_for_space(wm, keymap, SPACE_NODE);
|
||||
}
|
||||
|
||||
@@ -155,8 +155,6 @@ void sequencer_keymap(wmWindowManager *wm)
|
||||
|
||||
WM_keymap_verify_item(keymap, "ANIM_OT_change_frame", LEFTMOUSE, KM_PRESS, 0, 0);
|
||||
|
||||
WM_keymap_tweak(keymap, SELECTMOUSE, KM_PRESS, 0, 0);
|
||||
|
||||
transform_keymap_for_space(wm, keymap, SPACE_SEQ);
|
||||
}
|
||||
|
||||
|
||||
@@ -183,10 +183,5 @@ void view3d_keymap(wmWindowManager *wm)
|
||||
|
||||
transform_keymap_for_space(wm, keymap, SPACE_VIEW3D);
|
||||
|
||||
/* generates event, in end to make select work */
|
||||
WM_keymap_tweak(keymap, SELECTMOUSE, KM_PRESS, 0, 0);
|
||||
/* tweak event for border, lasso, etc */
|
||||
WM_keymap_tweak(keymap, ACTIONMOUSE, KM_PRESS, KM_CTRL, 0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -703,6 +703,8 @@ static int view3d_lasso_select_exec(bContext *C, wmOperator *op)
|
||||
RNA_END;
|
||||
|
||||
if(i>1) {
|
||||
view3d_operator_needs_opengl(C);
|
||||
|
||||
/* setup view context for argument to callbacks */
|
||||
view3d_set_viewcontext(C, &vc);
|
||||
|
||||
@@ -1754,6 +1756,8 @@ static int view3d_circle_select_exec(bContext *C, wmOperator *op)
|
||||
ViewContext vc;
|
||||
short mval[2], selecting;
|
||||
|
||||
view3d_operator_needs_opengl(C);
|
||||
|
||||
view3d_set_viewcontext(C, &vc);
|
||||
mval[0]= x;
|
||||
mval[1]= y;
|
||||
|
||||
@@ -2568,9 +2568,6 @@ void ED_keymap_uvedit(wmWindowManager *wm)
|
||||
// XXX not working?
|
||||
RNA_boolean_set(WM_keymap_add_item(keymap, "UV_OT_loop_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, KM_ALT)->ptr, "extend", 1);
|
||||
|
||||
/* generates event, needs to be after select to work */
|
||||
WM_keymap_tweak(keymap, SELECTMOUSE, KM_PRESS, 0, 0);
|
||||
|
||||
WM_keymap_add_item(keymap, "UV_OT_select_linked", LKEY, KM_PRESS, KM_CTRL, 0);
|
||||
WM_keymap_add_item(keymap, "UV_OT_unlink_selection", LKEY, KM_PRESS, KM_ALT, 0);
|
||||
WM_keymap_add_item(keymap, "UV_OT_de_select_all", AKEY, KM_PRESS, 0, 0);
|
||||
|
||||
@@ -38,6 +38,7 @@ struct wmWindowManager;
|
||||
struct wmWindow;
|
||||
|
||||
struct wmEvent;
|
||||
struct wmGesture;
|
||||
struct wmOperatorType;
|
||||
struct wmOperator;
|
||||
|
||||
@@ -102,6 +103,8 @@ typedef struct wmWindow {
|
||||
|
||||
struct wmSubWindow *curswin; /* internal for wm_subwindow.c only */
|
||||
|
||||
struct wmGesture *tweak; /* internal for wm_operators.c */
|
||||
|
||||
int drawmethod, drawfail; /* internal for wm_draw.c only */
|
||||
void *drawdata; /* internal for wm_draw.c only */
|
||||
|
||||
@@ -168,7 +171,7 @@ typedef struct wmKeymapItem {
|
||||
short shift, ctrl, alt, oskey; /* oskey is apple or windowskey, value denotes order of pressed */
|
||||
short keymodifier; /* rawkey modifier */
|
||||
|
||||
short is_tweak; /* internal only, to handle tweak failure events properly */
|
||||
short pad;
|
||||
} wmKeymapItem;
|
||||
|
||||
#define KMAP_MAX_NAME 64
|
||||
|
||||
@@ -68,7 +68,7 @@ typedef struct wmEvent {
|
||||
short prevx, prevy; /* previous mouse pointer position */
|
||||
short unicode; /* future, ghost? */
|
||||
char ascii; /* from ghost */
|
||||
char no_tweak; /* set on tweak failure, to allow other events to try it */
|
||||
char pad;
|
||||
|
||||
/* modifier states */
|
||||
short shift, ctrl, alt, oskey; /* oskey is apple or windowskey, value denotes order of pressed */
|
||||
@@ -224,6 +224,7 @@ typedef struct wmNotifier {
|
||||
#define WM_GESTURE_CIRCLE 5
|
||||
|
||||
/* wmGesture is registered to window listbase, handled by operator callbacks */
|
||||
/* tweak gesture is builtin feature */
|
||||
typedef struct wmGesture {
|
||||
struct wmGesture *next, *prev;
|
||||
int event_type; /* event->type */
|
||||
|
||||
@@ -542,19 +542,6 @@ static int wm_eventmatch(wmEvent *winevent, wmKeymapItem *kmi)
|
||||
if(kmi->keymodifier)
|
||||
if(winevent->keymodifier!=kmi->keymodifier) return 0;
|
||||
|
||||
/* happens on tweak failure */
|
||||
/* weak code, testing only now! (ton) */
|
||||
if(kmi->is_tweak) {
|
||||
/* only after tweak keymap we allow the hack */
|
||||
if(winevent->no_tweak) {
|
||||
winevent->no_tweak= 2;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(winevent->no_tweak==1)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -850,15 +837,23 @@ void wm_event_do_handlers(bContext *C)
|
||||
return;
|
||||
}
|
||||
|
||||
/* builtin tweak, if action is break it removes tweak */
|
||||
if(!wm_event_always_pass(event))
|
||||
wm_tweakevent_test(C, event, action);
|
||||
|
||||
if(wm_event_always_pass(event) || action==WM_HANDLER_CONTINUE) {
|
||||
ScrArea *sa;
|
||||
ARegion *ar;
|
||||
int doit= 0;
|
||||
|
||||
/* XXX to solve, here screen handlers? */
|
||||
if(event->type==MOUSEMOVE) {
|
||||
ED_screen_set_subwinactive(win, event); /* state variables in screen, cursors */
|
||||
wm_paintcursor_test(C, event);
|
||||
if(!wm_event_always_pass(event)) {
|
||||
if(event->type==MOUSEMOVE) {
|
||||
/* state variables in screen, cursors */
|
||||
ED_screen_set_subwinactive(win, event);
|
||||
/* for regions having custom cursors */
|
||||
wm_paintcursor_test(C, event);
|
||||
}
|
||||
}
|
||||
|
||||
for(sa= win->screen->areabase.first; sa; sa= sa->next) {
|
||||
|
||||
@@ -125,15 +125,6 @@ wmKeymapItem *WM_keymap_add_item(ListBase *lb, char *idname, short type, short v
|
||||
return kmi;
|
||||
}
|
||||
|
||||
/* enables tweak for mouse/modifier combo
|
||||
on tweak fail, it passes on event with 'val=1', so other keymap items can test */
|
||||
void WM_keymap_tweak(ListBase *lb, short type, short val, int modifier, short keymodifier)
|
||||
{
|
||||
wmKeymapItem *km= WM_keymap_add_item(lb, "WM_OT_tweak_gesture", type, val, modifier, keymodifier);
|
||||
km->is_tweak= 1;
|
||||
}
|
||||
|
||||
|
||||
/* ****************** storage in WM ************ */
|
||||
|
||||
/* name id's are for storing general or multiple keymaps,
|
||||
|
||||
@@ -729,22 +729,10 @@ void WM_OT_circle_gesture(wmOperatorType *ot)
|
||||
|
||||
/* **************** Tweak gesture *************** */
|
||||
|
||||
static int tweak_gesture_invoke(bContext *C, wmOperator *op, wmEvent *event)
|
||||
{
|
||||
op->customdata= WM_gesture_new(C, event, WM_GESTURE_TWEAK);
|
||||
|
||||
/* add modal handler */
|
||||
WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
|
||||
|
||||
wm_gesture_tag_redraw(C);
|
||||
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
|
||||
static int tweak_gesture_modal(bContext *C, wmOperator *op, wmEvent *event)
|
||||
static void tweak_gesture_modal(bContext *C, wmEvent *event)
|
||||
{
|
||||
wmWindow *window= CTX_wm_window(C);
|
||||
wmGesture *gesture= op->customdata;
|
||||
wmGesture *gesture= window->tweak;
|
||||
rcti *rect= gesture->customdata;
|
||||
int sx, sy, val;
|
||||
|
||||
@@ -758,7 +746,7 @@ static int tweak_gesture_modal(bContext *C, wmOperator *op, wmEvent *event)
|
||||
|
||||
if((val= wm_gesture_evaluate(C, gesture))) {
|
||||
wmEvent event;
|
||||
|
||||
|
||||
event= *(window->eventstate);
|
||||
if(gesture->event_type==LEFTMOUSE)
|
||||
event.type= EVT_TWEAK_L;
|
||||
@@ -770,11 +758,9 @@ static int tweak_gesture_modal(bContext *C, wmOperator *op, wmEvent *event)
|
||||
/* mouse coords! */
|
||||
wm_event_add(window, &event);
|
||||
|
||||
wm_gesture_end(C, op);
|
||||
return OPERATOR_FINISHED;
|
||||
WM_gesture_end(C, gesture); /* frees gesture itself, and unregisters from window */
|
||||
window->tweak= NULL;
|
||||
}
|
||||
else
|
||||
wm_gesture_tag_redraw(C);
|
||||
|
||||
break;
|
||||
|
||||
@@ -782,29 +768,43 @@ static int tweak_gesture_modal(bContext *C, wmOperator *op, wmEvent *event)
|
||||
case RIGHTMOUSE:
|
||||
case MIDDLEMOUSE:
|
||||
if(gesture->event_type==event->type) {
|
||||
wm_gesture_end(C, op);
|
||||
WM_gesture_end(C, gesture);
|
||||
window->tweak= NULL;
|
||||
|
||||
/* when tweak fails we should give the other keymap entries a chance
|
||||
* those then won't react to km_press, but km_release
|
||||
* it sets hidden event value where tweak maps fail on, to prevent loops */
|
||||
event->val= 1;
|
||||
event->no_tweak= 1;
|
||||
return OPERATOR_FINISHED|OPERATOR_PASS_THROUGH;
|
||||
//event->val= 1;
|
||||
//event->no_tweak= 1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
WM_gesture_end(C, gesture);
|
||||
window->tweak= NULL;
|
||||
}
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
|
||||
void WM_OT_tweak_gesture(wmOperatorType *ot)
|
||||
/* standard tweak, called after window handlers passed on event */
|
||||
void wm_tweakevent_test(bContext *C, wmEvent *event, int action)
|
||||
{
|
||||
ot->name= "Tweak Gesture";
|
||||
ot->idname= "WM_OT_tweak_gesture";
|
||||
wmWindow *win= CTX_wm_window(C);
|
||||
|
||||
ot->invoke= tweak_gesture_invoke;
|
||||
ot->modal= tweak_gesture_modal;
|
||||
|
||||
ot->poll= WM_operator_winactive;
|
||||
if(win->tweak==NULL) {
|
||||
if(CTX_wm_region(C)) {
|
||||
if(event->val) { // pressed
|
||||
if( ELEM3(event->type, LEFTMOUSE, MIDDLEMOUSE, RIGHTMOUSE) )
|
||||
win->tweak= WM_gesture_new(C, event, WM_GESTURE_TWEAK);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(action==WM_HANDLER_BREAK) {
|
||||
WM_gesture_end(C, win->tweak);
|
||||
win->tweak= NULL;
|
||||
}
|
||||
else
|
||||
tweak_gesture_modal(C, event);
|
||||
}
|
||||
}
|
||||
|
||||
/* *********************** lasso gesture ****************** */
|
||||
@@ -1171,7 +1171,6 @@ void wm_operatortype_init(void)
|
||||
WM_operatortype_append(WM_OT_save_homefile);
|
||||
WM_operatortype_append(WM_OT_window_fullscreen_toggle);
|
||||
WM_operatortype_append(WM_OT_exit_blender);
|
||||
WM_operatortype_append(WM_OT_tweak_gesture);
|
||||
WM_operatortype_append(WM_OT_open_recentfile);
|
||||
WM_operatortype_append(WM_OT_open_mainfile);
|
||||
WM_operatortype_append(WM_OT_jobs_timer);
|
||||
|
||||
@@ -55,6 +55,8 @@ void wm_operatortype_free(void);
|
||||
void wm_operatortype_init(void);
|
||||
void wm_window_keymap(wmWindowManager *wm);
|
||||
|
||||
void wm_tweakevent_test(bContext *C, wmEvent *event, int action);
|
||||
|
||||
/* wm_gesture.c */
|
||||
#define WM_LASSO_MAX_POINTS 1024
|
||||
void wm_gesture_draw(struct wmWindow *win);
|
||||
|
||||
Reference in New Issue
Block a user