Fun stuff with macro
Make macros work with more than one modal operator and mix of modal and invoke/exec As a proof, brought back loopcut + edge slide in a single macro operator called Loopcut and Slide, replacing Loopcut as assigned to Ctrl-R.
This commit is contained in:
@@ -170,13 +170,10 @@ void ED_operatormacros_mesh(void)
|
||||
wmOperatorType *ot;
|
||||
wmOperatorTypeMacro *otmacro;
|
||||
int constraint_axis[3] = {0, 0, 1};
|
||||
|
||||
/*combining operators with invoke and exec portions doesn't work yet.
|
||||
|
||||
ot= WM_operatortype_append_macro("MESH_OT_loopcut", "Loopcut", OPTYPE_UNDO|OPTYPE_REGISTER);
|
||||
WM_operatortype_macro_define(ot, "MESH_OT_edgering_select");
|
||||
WM_operatortype_macro_define(ot, "MESH_OT_subdivide");
|
||||
*/
|
||||
ot= WM_operatortype_append_macro("MESH_OT_loopcut_slide", "Loopcut and Slide", OPTYPE_UNDO|OPTYPE_REGISTER);
|
||||
WM_operatortype_macro_define(ot, "MESH_OT_loopcut");
|
||||
WM_operatortype_macro_define(ot, "TFM_OT_edge_slide");
|
||||
|
||||
ot= WM_operatortype_append_macro("MESH_OT_duplicate_move", "Add Duplicate", OPTYPE_UNDO|OPTYPE_REGISTER);
|
||||
WM_operatortype_macro_define(ot, "MESH_OT_duplicate");
|
||||
@@ -211,7 +208,7 @@ void ED_keymap_mesh(wmKeyConfig *keyconf)
|
||||
keymap= WM_keymap_find(keyconf, "EditMesh", 0, 0);
|
||||
keymap->poll= ED_operator_editmesh;
|
||||
|
||||
WM_keymap_add_item(keymap, "MESH_OT_loopcut", RKEY, KM_PRESS, KM_CTRL, 0);
|
||||
WM_keymap_add_item(keymap, "MESH_OT_loopcut_slide", RKEY, KM_PRESS, KM_CTRL, 0);
|
||||
|
||||
/* selecting */
|
||||
/* standard mouse selection goes via space_view3d */
|
||||
|
||||
@@ -621,7 +621,7 @@ int WM_operator_call_py(bContext *C, wmOperatorType *ot, int context, PointerRNA
|
||||
/* ********************* handlers *************** */
|
||||
|
||||
/* future extra customadata free? */
|
||||
static void wm_event_free_handler(wmEventHandler *handler)
|
||||
void wm_event_free_handler(wmEventHandler *handler)
|
||||
{
|
||||
MEM_freeN(handler);
|
||||
}
|
||||
|
||||
@@ -193,20 +193,20 @@ static int wm_macro_exec(bContext *C, wmOperator *op)
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int wm_macro_invoke(bContext *C, wmOperator *op, wmEvent *event)
|
||||
int wm_macro_invoke_internal(bContext *C, wmOperator *op, wmEvent *event, wmOperator *opm)
|
||||
{
|
||||
wmOperator *opm;
|
||||
int retval= OPERATOR_FINISHED;
|
||||
|
||||
|
||||
// printf("macro invoke %s\n", op->type->idname);
|
||||
|
||||
for(opm= op->macro.first; opm; opm= opm->next) {
|
||||
|
||||
|
||||
/* start from operator received as argument */
|
||||
for( ; opm; opm= opm->next) {
|
||||
|
||||
if(opm->type->invoke)
|
||||
retval= opm->type->invoke(C, opm, event);
|
||||
else if(opm->type->exec)
|
||||
retval= opm->type->exec(C, opm);
|
||||
|
||||
|
||||
/* if modal, pass operator flags to macro, they may be needed later */
|
||||
if(retval & OPERATOR_RUNNING_MODAL)
|
||||
op->flag = opm->flag;
|
||||
@@ -214,28 +214,58 @@ static int wm_macro_invoke(bContext *C, wmOperator *op, wmEvent *event)
|
||||
if(!(retval & OPERATOR_FINISHED))
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
// if(opm)
|
||||
// printf("macro ended not finished\n");
|
||||
// else
|
||||
// printf("macro end\n");
|
||||
|
||||
|
||||
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int wm_macro_invoke(bContext *C, wmOperator *op, wmEvent *event)
|
||||
{
|
||||
return wm_macro_invoke_internal(C, op, event, op->macro.first);
|
||||
}
|
||||
|
||||
static int wm_macro_modal(bContext *C, wmOperator *op, wmEvent *event)
|
||||
{
|
||||
wmOperator *opm = op->opm;
|
||||
int retval= OPERATOR_FINISHED;
|
||||
// printf("macro modal %s\n", op->type->idname);
|
||||
|
||||
if(op->opm==NULL)
|
||||
if(opm==NULL)
|
||||
printf("macro error, calling NULL modal()\n");
|
||||
else {
|
||||
// printf("macro modal %s\n", op->opm->type->idname);
|
||||
return op->opm->type->modal(C, op->opm, event);
|
||||
retval = opm->type->modal(C, opm, event);
|
||||
|
||||
/* if this one is done but it's not the last operator in the macro */
|
||||
if ((retval & OPERATOR_FINISHED) && opm->next) {
|
||||
retval = wm_macro_invoke_internal(C, op, event, opm->next);
|
||||
|
||||
/* if new operator is modal and also added its own handler */
|
||||
if (retval & OPERATOR_RUNNING_MODAL && op->opm != opm) {
|
||||
wmWindow *win = CTX_wm_window(C);
|
||||
wmEventHandler *handler = NULL;
|
||||
|
||||
for (handler = win->modalhandlers.first; handler; handler = handler->next) {
|
||||
/* first handler in list is the new one */
|
||||
if (handler->op == op)
|
||||
break;
|
||||
}
|
||||
|
||||
if (handler) {
|
||||
BLI_remlink(&win->modalhandlers, handler);
|
||||
wm_event_free_handler(handler);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Names have to be static for now */
|
||||
|
||||
@@ -82,7 +82,7 @@ enum {
|
||||
void wm_event_add (wmWindow *win, wmEvent *event_to_add);
|
||||
void wm_event_free_all (wmWindow *win);
|
||||
void wm_event_free (wmEvent *event);
|
||||
|
||||
void wm_event_free_handler (wmEventHandler *handler);
|
||||
|
||||
/* goes over entire hierarchy: events -> window -> screen -> area -> region */
|
||||
void wm_event_do_handlers (bContext *C);
|
||||
|
||||
Reference in New Issue
Block a user