2.5
- Edit mesh: Add ctrl+click add vertex or extrude.
I've made it not move the 3d cursor in that case.
Also found out tweak events conflicted with existing
keymap definitions; on tweak failure (= no mousemove)
it now passes on the mouse event as 'mouse down' for
the remaining keymaps to check.
These then actually respond to mouse-up instead of down...
The location in the keymaps where tweaks get generated
remains important. Examples:
1 - 'select' mouse-handler, operator return pass-through
2 - tweak handler checks, and makes tweak event
3 - grabber responds to tweak event
1 - ctrl+mouse tweak handler checks, makes tweak event,
or passes event on
2 - if tweak event, it runs lasso
3 - else when passed on, ctrl+click extrude happens
In the first case, select works on mouse-down, immediate.
In the second case, extrude happens on mouse-release, even
though the keymap defined mouse-press.
This will make designing nice balanced keymaps still not
simple; especially because you can't tell operators to
pass on the key... although we can add the convention that
select-mouse operators always pass on to enable tweaks.
Still a good reason to wait with custom keymaps
when this is fully settled!
This commit is contained in:
@@ -857,10 +857,10 @@ void ED_marker_keymap(wmWindowManager *wm)
|
||||
ListBase *keymap= WM_keymap_listbase(wm, "Markers", 0, 0);
|
||||
|
||||
WM_keymap_verify_item(keymap, "MARKER_OT_add", MKEY, KM_PRESS, 0, 0);
|
||||
WM_keymap_verify_item(keymap, "MARKER_OT_move", EVT_TWEAK_R, KM_ANY, 0, 0);
|
||||
WM_keymap_verify_item(keymap, "MARKER_OT_move", EVT_TWEAK_S, KM_ANY, 0, 0);
|
||||
WM_keymap_verify_item(keymap, "MARKER_OT_duplicate", DKEY, KM_PRESS, KM_SHIFT, 0);
|
||||
WM_keymap_verify_item(keymap, "MARKER_OT_mouseselect", RIGHTMOUSE, KM_PRESS, 0, 0);
|
||||
WM_keymap_verify_item(keymap, "MARKER_OT_mouseselect_extend", RIGHTMOUSE, KM_PRESS, KM_SHIFT, 0);
|
||||
WM_keymap_verify_item(keymap, "MARKER_OT_mouseselect", SELECTMOUSE, KM_PRESS, 0, 0);
|
||||
WM_keymap_verify_item(keymap, "MARKER_OT_mouseselect_extend", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0);
|
||||
WM_keymap_verify_item(keymap, "MARKER_OT_border_select", BKEY, KM_PRESS, 0, 0);
|
||||
WM_keymap_verify_item(keymap, "MARKER_OT_select_all", AKEY, KM_PRESS, 0, 0);
|
||||
WM_keymap_verify_item(keymap, "MARKER_OT_delete", XKEY, KM_PRESS, 0, 0);
|
||||
@@ -868,6 +868,6 @@ 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_verify_item(keymap, "WM_OT_tweak_gesture", RIGHTMOUSE, KM_PRESS, 0, 0);
|
||||
WM_keymap_tweak(keymap, SELECTMOUSE, KM_PRESS, 0, 0);
|
||||
|
||||
}
|
||||
|
||||
@@ -118,6 +118,8 @@ static short icoface[20][3] = {
|
||||
{10,9,11}
|
||||
};
|
||||
|
||||
/* *************** add-click-mesh (extrude) operator ************** */
|
||||
|
||||
static void get_view_aligned_coordinate(ViewContext *vc, float *fp, short mval[2])
|
||||
{
|
||||
float dvec[3];
|
||||
@@ -136,15 +138,19 @@ static void get_view_aligned_coordinate(ViewContext *vc, float *fp, short mval[2
|
||||
}
|
||||
}
|
||||
|
||||
void add_click_mesh(bContext *C)
|
||||
static int dupli_extrude_cursor(bContext *C, wmOperator *op, wmEvent *event)
|
||||
{
|
||||
ViewContext vc;
|
||||
EditVert *eve, *v1;
|
||||
float min[3], max[3];
|
||||
int done= 0;
|
||||
short mval[2];
|
||||
|
||||
em_setup_viewcontext(C, &vc);
|
||||
|
||||
mval[0]= event->x - vc.ar->winrct.xmin;
|
||||
mval[1]= event->y - vc.ar->winrct.ymin;
|
||||
|
||||
INIT_MINMAX(min, max);
|
||||
|
||||
for(v1= vc.em->verts.first;v1; v1=v1->next) {
|
||||
@@ -159,7 +165,6 @@ void add_click_mesh(bContext *C)
|
||||
EditEdge *eed;
|
||||
float vec[3], cent[3], mat[3][3];
|
||||
float nor[3]= {0.0, 0.0, 0.0};
|
||||
short mval[2];
|
||||
|
||||
/* check for edges that are half selected, use for rotation */
|
||||
done= 0;
|
||||
@@ -220,27 +225,45 @@ void add_click_mesh(bContext *C)
|
||||
float mat[3][3],imat[3][3];
|
||||
float *curs= give_cursor(vc.scene, vc.v3d);
|
||||
|
||||
VECCOPY(min, curs);
|
||||
get_view_aligned_coordinate(&vc, min, mval);
|
||||
|
||||
eve= addvertlist(vc.em, 0, NULL);
|
||||
|
||||
Mat3CpyMat4(mat, vc.obedit->obmat);
|
||||
Mat3Inv(imat, mat);
|
||||
|
||||
VECCOPY(eve->co, curs);
|
||||
VecSubf(eve->co, eve->co, vc.obedit->obmat[3]);
|
||||
|
||||
VECCOPY(eve->co, min);
|
||||
Mat3MulVecfl(imat, eve->co);
|
||||
VecSubf(eve->co, eve->co, vc.obedit->obmat[3]);
|
||||
|
||||
eve->f= SELECT;
|
||||
}
|
||||
|
||||
//retopo_do_all();
|
||||
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, vc.obedit);
|
||||
DAG_object_flush_update(vc.scene, vc.obedit, OB_RECALC_DATA);
|
||||
|
||||
BIF_undo_push("Add vertex/edge/face");
|
||||
DAG_object_flush_update(vc.scene, vc.obedit, OB_RECALC_DATA);
|
||||
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void MESH_OT_dupli_extrude_cursor(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name= "Duplicate or Extrude at 3D Cursor";
|
||||
ot->idname= "MESH_OT_dupli_extrude_cursor";
|
||||
|
||||
/* api callbacks */
|
||||
ot->invoke= dupli_extrude_cursor;
|
||||
ot->poll= ED_operator_editmesh;
|
||||
|
||||
/* flags */
|
||||
ot->flag= OPTYPE_REGISTER/*|OPTYPE_UNDO*/;
|
||||
}
|
||||
|
||||
|
||||
/* ********************** */
|
||||
|
||||
/* selected faces get hidden edges */
|
||||
static void make_fgon(EditMesh *em, int make)
|
||||
{
|
||||
|
||||
@@ -106,6 +106,7 @@ void MESH_OT_add_primitive_grid(struct wmOperatorType *ot);
|
||||
void MESH_OT_add_primitive_monkey(struct wmOperatorType *ot);
|
||||
void MESH_OT_add_primitive_uv_sphere(struct wmOperatorType *ot);
|
||||
void MESH_OT_add_primitive_ico_sphere(struct wmOperatorType *ot);
|
||||
void MESH_OT_dupli_extrude_cursor(struct wmOperatorType *ot);
|
||||
|
||||
/* ******************* editmesh_lib.c */
|
||||
void EM_stats_update(EditMesh *em);
|
||||
|
||||
@@ -138,6 +138,7 @@ void ED_operatortypes_mesh(void)
|
||||
WM_operatortype_append(MESH_OT_extrude_mesh);
|
||||
WM_operatortype_append(MESH_OT_edit_faces);
|
||||
WM_operatortype_append(MESH_OT_separate);
|
||||
WM_operatortype_append(MESH_OT_dupli_extrude_cursor);
|
||||
|
||||
}
|
||||
|
||||
@@ -181,6 +182,7 @@ 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);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -140,7 +140,7 @@ static void action_keymap_keyframes (wmWindowManager *wm, ListBase *keymap)
|
||||
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_add_item(keymap, "WM_OT_tweak_gesture", SELECTMOUSE, KM_PRESS, 0, 0);
|
||||
WM_keymap_tweak(keymap, SELECTMOUSE, KM_PRESS, 0, 0);
|
||||
|
||||
/* transform system */
|
||||
transform_keymap_for_space(wm, keymap, SPACE_ACTION);
|
||||
|
||||
@@ -187,7 +187,7 @@ static void graphedit_keymap_keyframes (wmWindowManager *wm, ListBase *keymap)
|
||||
//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_add_item(keymap, "WM_OT_tweak_gesture", SELECTMOUSE, KM_PRESS, 0, 0);
|
||||
WM_keymap_tweak(keymap, SELECTMOUSE, KM_PRESS, 0, 0);
|
||||
|
||||
/* transform system */
|
||||
transform_keymap_for_space(wm, keymap, SPACE_IPO);
|
||||
|
||||
@@ -74,8 +74,8 @@ void node_keymap(struct wmWindowManager *wm)
|
||||
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_add_item(keymap, "WM_OT_tweak_gesture", ACTIONMOUSE, KM_PRESS, 0, 0);
|
||||
WM_keymap_add_item(keymap, "WM_OT_tweak_gesture", SELECTMOUSE, KM_PRESS, 0, 0);
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -151,7 +151,7 @@ void sequencer_keymap(wmWindowManager *wm)
|
||||
|
||||
WM_keymap_verify_item(keymap, "ANIM_OT_change_frame", LEFTMOUSE, KM_PRESS, 0, 0);
|
||||
|
||||
WM_keymap_add_item(keymap, "WM_OT_tweak_gesture", SELECTMOUSE, KM_PRESS, 0, 0);
|
||||
WM_keymap_tweak(keymap, SELECTMOUSE, KM_PRESS, 0, 0);
|
||||
|
||||
transform_keymap_for_space(wm, keymap, SPACE_SEQ);
|
||||
}
|
||||
|
||||
@@ -153,8 +153,8 @@ void view3d_keymap(wmWindowManager *wm)
|
||||
WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, 0, 0);
|
||||
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "type", 1);
|
||||
WM_keymap_add_item(keymap, "VIEW3D_OT_borderselect", BKEY, KM_PRESS, 0, 0);
|
||||
WM_keymap_add_item(keymap, "VIEW3D_OT_lasso_select", LEFTMOUSE, KM_PRESS, KM_CTRL, 0);
|
||||
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_lasso_select", LEFTMOUSE, KM_PRESS, KM_SHIFT|KM_CTRL, 0)->ptr, "type", 1);
|
||||
WM_keymap_add_item(keymap, "VIEW3D_OT_lasso_select", EVT_TWEAK_A, KM_ANY, KM_CTRL, 0);
|
||||
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_lasso_select", EVT_TWEAK_A, KM_ANY, KM_SHIFT|KM_CTRL, 0)->ptr, "type", 1);
|
||||
WM_keymap_add_item(keymap, "VIEW3D_OT_circle_select", CKEY, KM_PRESS, 0, 0);
|
||||
|
||||
WM_keymap_add_item(keymap, "VIEW3D_OT_clipping", BKEY, KM_PRESS, KM_ALT, 0);
|
||||
@@ -182,7 +182,9 @@ void view3d_keymap(wmWindowManager *wm)
|
||||
transform_keymap_for_space(wm, keymap, SPACE_VIEW3D);
|
||||
|
||||
/* generates event, in end to make select work */
|
||||
WM_keymap_verify_item(keymap, "WM_OT_tweak_gesture", SELECTMOUSE, KM_PRESS, 0, 0);
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -702,13 +702,16 @@ static int view3d_lasso_select_exec(bContext *C, wmOperator *op)
|
||||
}
|
||||
RNA_END;
|
||||
|
||||
/* setup view context for argument to callbacks */
|
||||
view3d_set_viewcontext(C, &vc);
|
||||
|
||||
select= RNA_enum_is_equal(op->ptr, "type", "SELECT");
|
||||
view3d_lasso_select(&vc, mcords, i, select);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
if(i>1) {
|
||||
/* setup view context for argument to callbacks */
|
||||
view3d_set_viewcontext(C, &vc);
|
||||
|
||||
select= RNA_enum_is_equal(op->ptr, "type", "SELECT");
|
||||
view3d_lasso_select(&vc, mcords, i, select);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
return OPERATOR_PASS_THROUGH;
|
||||
}
|
||||
|
||||
void VIEW3D_OT_lasso_select(wmOperatorType *ot)
|
||||
|
||||
@@ -2569,7 +2569,7 @@ void ED_keymap_uvedit(wmWindowManager *wm)
|
||||
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_add_item(keymap, "WM_OT_tweak_gesture", SELECTMOUSE, KM_PRESS, 0, 0);
|
||||
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);
|
||||
|
||||
@@ -168,7 +168,7 @@ typedef struct wmKeymapItem {
|
||||
short shift, ctrl, alt, oskey; /* oskey is apple or windowskey, value denotes order of pressed */
|
||||
short keymodifier; /* rawkey modifier */
|
||||
|
||||
short pad;
|
||||
short is_tweak; /* internal only, to handle tweak failure events properly */
|
||||
} wmKeymapItem;
|
||||
|
||||
#define KMAP_MAX_NAME 64
|
||||
|
||||
@@ -71,12 +71,11 @@ void *WM_paint_cursor_activate(struct wmWindowManager *wm, int (*poll)(struct b
|
||||
void WM_paint_cursor_end(struct wmWindowManager *wm, void *handle);
|
||||
|
||||
/* keymap */
|
||||
wmKeymapItem *WM_keymap_set_item (ListBase *lb, char *idname, short type,
|
||||
short val, int modifier, short keymodifier);
|
||||
wmKeymapItem *WM_keymap_verify_item(ListBase *lb, char *idname, short type,
|
||||
short val, int modifier, short keymodifier);
|
||||
wmKeymapItem *WM_keymap_add_item (ListBase *lb, char *idname, short type,
|
||||
wmKeymapItem *WM_keymap_add_item(ListBase *lb, char *idname, short type,
|
||||
short val, int modifier, short keymodifier);
|
||||
wmKeymapItem *WM_keymap_tweak (ListBase *lb, short type, short val, int modifier, short keymodifier);
|
||||
ListBase *WM_keymap_listbase (struct wmWindowManager *wm, const char *nameid,
|
||||
int spaceid, int regionid);
|
||||
|
||||
|
||||
@@ -61,13 +61,13 @@ enum {
|
||||
typedef struct wmEvent {
|
||||
struct wmEvent *next, *prev;
|
||||
|
||||
short type; /* event code itself (short, is also in keymap) */
|
||||
short val; /* press, release, scrollvalue */
|
||||
short x, y; /* mouse pointer position */
|
||||
short prevx, prevy; /* previous mouse pointer position */
|
||||
short unicode; /* future, ghost? */
|
||||
char ascii; /* from ghost */
|
||||
char pad1;
|
||||
short type; /* event code itself (short, is also in keymap) */
|
||||
short val; /* press, release, scrollvalue */
|
||||
short x, y; /* mouse pointer position */
|
||||
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 */
|
||||
|
||||
/* modifier states */
|
||||
short shift, ctrl, alt, oskey; /* oskey is apple or windowskey, value denotes order of pressed */
|
||||
|
||||
@@ -515,6 +515,9 @@ static int wm_eventmatch(wmEvent *winevent, wmKeymapItem *kmi)
|
||||
if(kmi->keymodifier)
|
||||
if(winevent->keymodifier!=kmi->keymodifier) return 0;
|
||||
|
||||
/* happens on tweak failure */
|
||||
if(kmi->is_tweak)
|
||||
if(winevent->no_tweak) return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -545,7 +548,7 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand
|
||||
|
||||
retval= ot->modal(C, op, event);
|
||||
|
||||
/* putting back screen context */
|
||||
/* putting back screen context, reval can pass trough after modal failures! */
|
||||
if((retval & OPERATOR_PASS_THROUGH) || wm_event_always_pass(event)) {
|
||||
CTX_wm_area_set(C, area);
|
||||
CTX_wm_region_set(C, region);
|
||||
@@ -581,7 +584,7 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand
|
||||
MEM_freeN(handler);
|
||||
|
||||
/* prevent silly errors from operator users */
|
||||
retval &= ~OPERATOR_PASS_THROUGH;
|
||||
//retval &= ~OPERATOR_PASS_THROUGH;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -111,25 +111,6 @@ wmKeymapItem *WM_keymap_verify_item(ListBase *lb, char *idname, short type, shor
|
||||
return kmi;
|
||||
}
|
||||
|
||||
/* if item was added, then replace */
|
||||
wmKeymapItem *WM_keymap_set_item(ListBase *lb, char *idname, short type, short val, int modifier, short keymodifier)
|
||||
{
|
||||
wmKeymapItem *kmi;
|
||||
|
||||
for(kmi= lb->first; kmi; kmi= kmi->next)
|
||||
if(strncmp(kmi->idname, idname, OP_MAX_TYPENAME)==0)
|
||||
break;
|
||||
if(kmi==NULL) {
|
||||
kmi= MEM_callocN(sizeof(wmKeymapItem), "keymap entry");
|
||||
|
||||
BLI_addtail(lb, kmi);
|
||||
BLI_strncpy(kmi->idname, idname, OP_MAX_TYPENAME);
|
||||
}
|
||||
keymap_event_set(kmi, type, val, modifier, keymodifier);
|
||||
keymap_properties_set(kmi);
|
||||
return kmi;
|
||||
}
|
||||
|
||||
/* always add item */
|
||||
wmKeymapItem *WM_keymap_add_item(ListBase *lb, char *idname, short type, short val, int modifier, short keymodifier)
|
||||
{
|
||||
@@ -143,6 +124,15 @@ 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 */
|
||||
wmKeymapItem *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,
|
||||
|
||||
@@ -764,9 +764,14 @@ static int tweak_gesture_modal(bContext *C, wmOperator *op, wmEvent *event)
|
||||
case RIGHTMOUSE:
|
||||
case MIDDLEMOUSE:
|
||||
if(gesture->event_type==event->type) {
|
||||
wm_gesture_evaluate(C, gesture);
|
||||
wm_gesture_end(C, op);
|
||||
return OPERATOR_FINISHED;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user