Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Poirier <theeth@yahoo.com>2009-11-18 01:19:48 +0300
committerMartin Poirier <theeth@yahoo.com>2009-11-18 01:19:48 +0300
commit7b05c9ca30cb61d808a7900886135e99719d9feb (patch)
treef77e53bcc49a14595412a494b5eb362bd3f45439 /source/blender
parent2ae15e39ad01768ce0d54aeb106a9cfa5162efa3 (diff)
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.
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/editors/mesh/mesh_ops.c11
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c2
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c56
-rw-r--r--source/blender/windowmanager/wm_event_system.h2
4 files changed, 49 insertions, 22 deletions
diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c
index ea968bf6fc9..3ce5bbc7e5a 100644
--- a/source/blender/editors/mesh/mesh_ops.c
+++ b/source/blender/editors/mesh/mesh_ops.c
@@ -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 */
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index e5508d58145..42c65a8a8d7 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -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);
}
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index 892deea2081..02b43068321 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -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 */
diff --git a/source/blender/windowmanager/wm_event_system.h b/source/blender/windowmanager/wm_event_system.h
index 4322f70ea61..b7c881629a2 100644
--- a/source/blender/windowmanager/wm_event_system.h
+++ b/source/blender/windowmanager/wm_event_system.h
@@ -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);