forked from bartvdbraak/blender
allow execution mode to be given as an argument to operators from python (requested by algorith)
example. bpy.ops.tfm.rotate('INVOKE_REGION_WIN', pivot=(0,1,2), ......) bpy_array.c - was too strict with types, 0 should be allowed as well as 0.0 in a float array.
This commit is contained in:
parent
fc975a9148
commit
02f951c3a0
@ -168,7 +168,7 @@ int RE_engine_test_break(struct RenderEngine *engine){return 0;}
|
||||
struct wmOperatorType *WM_operatortype_find(const char *idname, int quiet){return (struct wmOperatorType *) NULL;}
|
||||
struct wmOperatorType *WM_operatortype_first(){return (struct wmOperatorType *) NULL;}
|
||||
struct wmOperatorType *WM_operatortype_exists(const char *idname){return (struct wmOperatorType *) NULL;}
|
||||
int WM_operator_call_py(struct bContext *C, struct wmOperatorType *ot, struct PointerRNA *properties, struct ReportList *reports){return 0;}
|
||||
int WM_operator_call_py(struct bContext *C, struct wmOperatorType *ot, int context, struct PointerRNA *properties, struct ReportList *reports){return 0;}
|
||||
int WM_operatortype_remove(const char *idname){return 0;}
|
||||
void WM_operator_properties_free(struct PointerRNA *ptr){}
|
||||
void WM_operator_properties_create(struct PointerRNA *ptr, const char *opstring){}
|
||||
|
@ -5,6 +5,18 @@ from bpy.__ops__ import dir as op_dir
|
||||
from bpy.__ops__ import call as op_call
|
||||
from bpy.__ops__ import get_rna as op_get_rna
|
||||
|
||||
# Keep in sync with WM_types.h
|
||||
context_dict = {
|
||||
'INVOKE_DEFAULT':0,
|
||||
'INVOKE_REGION_WIN':1,
|
||||
'INVOKE_AREA':2,
|
||||
'INVOKE_SCREEN':3,
|
||||
'EXEC_DEFAULT':4,
|
||||
'EXEC_REGION_WIN':5,
|
||||
'EXEC_AREA':6,
|
||||
'EXEC_SCREEN':7,
|
||||
}
|
||||
|
||||
class bpy_ops(object):
|
||||
'''
|
||||
Fake module like class.
|
||||
@ -94,10 +106,22 @@ class bpy_ops_submodule_op(object):
|
||||
# submod.foo -> SUBMOD_OT_foo
|
||||
return self.module.upper() + '_OT_' + self.func
|
||||
|
||||
def __call__(self, **kw):
|
||||
def __call__(self, *args, **kw):
|
||||
|
||||
# Get the operator from blender
|
||||
return op_call(self.idname(), kw)
|
||||
if len(args) > 1:
|
||||
raise ValueError("only one argument for the execution context is supported ")
|
||||
|
||||
if args:
|
||||
try:
|
||||
context = context_dict[args[0]]
|
||||
except:
|
||||
raise ValueError("Expected a single context argument in: " + str(list(context_dict.keys())))
|
||||
|
||||
return op_call(self.idname(), kw, context)
|
||||
|
||||
else:
|
||||
return op_call(self.idname(), kw)
|
||||
|
||||
def get_rna(self):
|
||||
'''
|
||||
|
@ -285,6 +285,7 @@ typedef struct wmOperator {
|
||||
|
||||
ListBase macro; /* list of operators, can be a tree */
|
||||
struct wmOperator *opm; /* current running macro, not saved */
|
||||
short flag, pad[3];
|
||||
|
||||
} wmOperator;
|
||||
|
||||
@ -295,6 +296,9 @@ typedef struct wmOperator {
|
||||
/* add this flag if the event should pass through */
|
||||
#define OPERATOR_PASS_THROUGH 8
|
||||
|
||||
/* wmOperator flag */
|
||||
#define OPERATOR_REPORT_FREE 1
|
||||
|
||||
|
||||
/* ************** wmEvent ************************ */
|
||||
/* for read-only rna access, dont save this */
|
||||
|
@ -203,17 +203,17 @@ static void pyrna_py_to_boolean(PyObject *py, char *data)
|
||||
|
||||
static int py_float_check(PyObject *py)
|
||||
{
|
||||
return PyFloat_Check(py);
|
||||
return PyFloat_Check(py) || (PyIndex_Check(py));
|
||||
}
|
||||
|
||||
static int py_int_check(PyObject *py)
|
||||
{
|
||||
return PyLong_Check(py);
|
||||
return PyLong_Check(py) || (PyIndex_Check(py));
|
||||
}
|
||||
|
||||
static int py_bool_check(PyObject *py)
|
||||
{
|
||||
return PyBool_Check(py);
|
||||
return PyBool_Check(py) || (PyIndex_Check(py));
|
||||
}
|
||||
|
||||
int pyrna_py_to_float_array(PyObject *py, PointerRNA *ptr, PropertyRNA *prop, char *param_data, char *error_str, int error_str_size)
|
||||
|
@ -40,42 +40,23 @@
|
||||
#include "BKE_utildefines.h"
|
||||
|
||||
|
||||
/* 'self' stores the operator string */
|
||||
static PyObject *pyop_call( PyObject * self, PyObject * args)
|
||||
{
|
||||
wmOperatorType *ot;
|
||||
int error_val = 0;
|
||||
PointerRNA ptr;
|
||||
|
||||
char *opname;
|
||||
PyObject *kw= NULL;
|
||||
char *opname;
|
||||
PyObject *kw= NULL; /* optional args */
|
||||
|
||||
/* note that context is an int, python does the conversion in this case */
|
||||
int context= WM_OP_EXEC_DEFAULT;
|
||||
|
||||
// XXX Todo, work out a better solution for passing on context, could make a tuple from self and pack the name and Context into it...
|
||||
bContext *C = BPy_GetContext();
|
||||
|
||||
|
||||
switch(PyTuple_Size(args)) {
|
||||
case 2:
|
||||
kw = PyTuple_GET_ITEM(args, 1);
|
||||
|
||||
if(!PyDict_Check(kw)) {
|
||||
PyErr_SetString( PyExc_AttributeError, "bpy.__ops__.call: expected second arg to be a dict");
|
||||
return NULL;
|
||||
}
|
||||
/* pass through */
|
||||
case 1:
|
||||
opname = _PyUnicode_AsString(PyTuple_GET_ITEM(args, 0));
|
||||
|
||||
if(opname==NULL) {
|
||||
PyErr_SetString( PyExc_AttributeError, "bpy.__ops__.call: expected the first arg to be a string");
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
PyErr_SetString( PyExc_AttributeError, "bpy.__ops__.call: expected a string and optional dict");
|
||||
if (!PyArg_ParseTuple(args, "s|O!i:bpy.__ops__.call", &opname, &PyDict_Type, &kw, &context))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
ot= WM_operatortype_find(opname, TRUE);
|
||||
|
||||
@ -88,7 +69,7 @@ static PyObject *pyop_call( PyObject * self, PyObject * args)
|
||||
PyErr_SetString( PyExc_SystemError, "bpy.__ops__.call: operator poll() function failed, context is incorrect");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* WM_operator_properties_create(&ptr, opname); */
|
||||
/* Save another lookup */
|
||||
RNA_pointer_create(NULL, ot->srna, NULL, &ptr);
|
||||
@ -102,7 +83,7 @@ static PyObject *pyop_call( PyObject * self, PyObject * args)
|
||||
|
||||
BKE_reports_init(&reports, RPT_STORE);
|
||||
|
||||
WM_operator_call_py(C, ot, &ptr, &reports);
|
||||
WM_operator_call_py(C, ot, context, &ptr, &reports);
|
||||
|
||||
if(BPy_reports_to_error(&reports))
|
||||
error_val = -1;
|
||||
|
@ -165,7 +165,7 @@ wmOperatorTypeMacro *WM_operatortype_macro_define(wmOperatorType *ot, const char
|
||||
int WM_operator_call (struct bContext *C, struct wmOperator *op);
|
||||
int WM_operator_repeat (struct bContext *C, struct wmOperator *op);
|
||||
int WM_operator_name_call (struct bContext *C, const char *opstring, int context, struct PointerRNA *properties);
|
||||
int WM_operator_call_py(struct bContext *C, struct wmOperatorType *ot, struct PointerRNA *properties, struct ReportList *reports);
|
||||
int WM_operator_call_py(struct bContext *C, struct wmOperatorType *ot, int context, struct PointerRNA *properties, struct ReportList *reports);
|
||||
|
||||
void WM_operator_properties_create(struct PointerRNA *ptr, const char *opstring);
|
||||
void WM_operator_properties_free(struct PointerRNA *ptr);
|
||||
@ -245,6 +245,5 @@ void WM_jobs_stop_all(struct wmWindowManager *wm);
|
||||
char *WM_clipboard_text_get(int selection);
|
||||
void WM_clipboard_text_set(char *buf, int selection);
|
||||
|
||||
|
||||
#endif /* WM_API_H */
|
||||
|
||||
|
@ -69,7 +69,7 @@ void WM_operator_free(wmOperator *op)
|
||||
MEM_freeN(op->properties);
|
||||
}
|
||||
|
||||
if(op->reports) {
|
||||
if(op->reports && (op->flag & OPERATOR_REPORT_FREE)) {
|
||||
BKE_reports_clear(op->reports);
|
||||
MEM_freeN(op->reports);
|
||||
}
|
||||
|
@ -345,11 +345,12 @@ static wmOperator *wm_operator_create(wmWindowManager *wm, wmOperatorType *ot, P
|
||||
|
||||
/* initialize error reports */
|
||||
if (reports) {
|
||||
op->reports= reports; /* must be initialized alredy */
|
||||
op->reports= reports; /* must be initialized already */
|
||||
}
|
||||
else {
|
||||
op->reports= MEM_mallocN(sizeof(ReportList), "wmOperatorReportList");
|
||||
BKE_reports_init(op->reports, RPT_STORE);
|
||||
op->flag |= OPERATOR_REPORT_FREE;
|
||||
}
|
||||
|
||||
/* recursive filling of operator macro list */
|
||||
@ -392,13 +393,13 @@ static void wm_region_mouse_co(bContext *C, wmEvent *event)
|
||||
}
|
||||
}
|
||||
|
||||
static int wm_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event, PointerRNA *properties)
|
||||
static int wm_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event, PointerRNA *properties, ReportList *reports)
|
||||
{
|
||||
wmWindowManager *wm= CTX_wm_manager(C);
|
||||
int retval= OPERATOR_PASS_THROUGH;
|
||||
|
||||
if(wm_operator_poll(C, ot)) {
|
||||
wmOperator *op= wm_operator_create(wm, ot, properties, NULL);
|
||||
wmOperator *op= wm_operator_create(wm, ot, properties, reports); /* if reports==NULL, theyll be initialized */
|
||||
|
||||
if((G.f & G_DEBUG) && event && event->type!=MOUSEMOVE)
|
||||
printf("handle evt %d win %d op %s\n", event?event->type:0, CTX_wm_screen(C)->subwinactive, ot->idname);
|
||||
@ -442,10 +443,12 @@ static int wm_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event, P
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* invokes operator in context */
|
||||
int WM_operator_name_call(bContext *C, const char *opstring, int context, PointerRNA *properties)
|
||||
/* WM_operator_name_call is the main accessor function
|
||||
* this is for python to access since its done the operator lookup
|
||||
*
|
||||
* invokes operator in context */
|
||||
static int wm_operator_call_internal(bContext *C, wmOperatorType *ot, int context, PointerRNA *properties, ReportList *reports)
|
||||
{
|
||||
wmOperatorType *ot= WM_operatortype_find(opstring, 0);
|
||||
wmWindow *window= CTX_wm_window(C);
|
||||
wmEvent *event;
|
||||
|
||||
@ -473,7 +476,7 @@ int WM_operator_name_call(bContext *C, const char *opstring, int context, Pointe
|
||||
CTX_wm_region_set(C, ar1);
|
||||
}
|
||||
|
||||
retval= wm_operator_invoke(C, ot, event, properties);
|
||||
retval= wm_operator_invoke(C, ot, event, properties, reports);
|
||||
|
||||
/* set region back */
|
||||
CTX_wm_region_set(C, ar);
|
||||
@ -488,7 +491,7 @@ int WM_operator_name_call(bContext *C, const char *opstring, int context, Pointe
|
||||
ARegion *ar= CTX_wm_region(C);
|
||||
|
||||
CTX_wm_region_set(C, NULL);
|
||||
retval= wm_operator_invoke(C, ot, event, properties);
|
||||
retval= wm_operator_invoke(C, ot, event, properties, reports);
|
||||
CTX_wm_region_set(C, ar);
|
||||
|
||||
return retval;
|
||||
@ -503,7 +506,7 @@ int WM_operator_name_call(bContext *C, const char *opstring, int context, Pointe
|
||||
|
||||
CTX_wm_region_set(C, NULL);
|
||||
CTX_wm_area_set(C, NULL);
|
||||
retval= wm_operator_invoke(C, ot, event, properties);
|
||||
retval= wm_operator_invoke(C, ot, event, properties, reports);
|
||||
CTX_wm_region_set(C, ar);
|
||||
CTX_wm_area_set(C, area);
|
||||
|
||||
@ -512,32 +515,45 @@ int WM_operator_name_call(bContext *C, const char *opstring, int context, Pointe
|
||||
case WM_OP_EXEC_DEFAULT:
|
||||
event= NULL; /* pass on without break */
|
||||
case WM_OP_INVOKE_DEFAULT:
|
||||
return wm_operator_invoke(C, ot, event, properties);
|
||||
return wm_operator_invoke(C, ot, event, properties, reports);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* invokes operator in context */
|
||||
int WM_operator_name_call(bContext *C, const char *opstring, int context, PointerRNA *properties)
|
||||
{
|
||||
wmOperatorType *ot= WM_operatortype_find(opstring, 0);
|
||||
if(ot)
|
||||
return wm_operator_call_internal(C, ot, context, properties, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Similar to WM_operator_name_call called with WM_OP_EXEC_DEFAULT context.
|
||||
- wmOperatorType is used instead of operator name since python alredy has the operator type
|
||||
- poll() must be called by python before this runs.
|
||||
- reports can be passed to this function (so python can report them as exceptions)
|
||||
*/
|
||||
int WM_operator_call_py(bContext *C, wmOperatorType *ot, PointerRNA *properties, ReportList *reports)
|
||||
int WM_operator_call_py(bContext *C, wmOperatorType *ot, int context, PointerRNA *properties, ReportList *reports)
|
||||
{
|
||||
wmWindowManager *wm= CTX_wm_manager(C);
|
||||
wmOperator *op= wm_operator_create(wm, ot, properties, reports);
|
||||
int retval= OPERATOR_CANCELLED;
|
||||
|
||||
|
||||
#if 0
|
||||
wmOperator *op;
|
||||
wmWindowManager *wm= CTX_wm_manager(C);
|
||||
op= wm_operator_create(wm, ot, properties, reports);
|
||||
|
||||
if (op->type->exec)
|
||||
retval= op->type->exec(C, op);
|
||||
else
|
||||
printf("error \"%s\" operator has no exec function, python cannot call it\n", op->type->name);
|
||||
|
||||
if (reports)
|
||||
op->reports= NULL; /* dont let the operator free reports passed to this function */
|
||||
WM_operator_free(op);
|
||||
#endif
|
||||
|
||||
retval= wm_operator_call_internal(C, ot, context, properties, reports);
|
||||
|
||||
return retval;
|
||||
}
|
||||
@ -820,7 +836,7 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand
|
||||
wmOperatorType *ot= WM_operatortype_find(event->keymap_idname, 0);
|
||||
|
||||
if(ot)
|
||||
retval= wm_operator_invoke(C, ot, event, properties);
|
||||
retval= wm_operator_invoke(C, ot, event, properties, NULL);
|
||||
}
|
||||
|
||||
if(retval & OPERATOR_PASS_THROUGH)
|
||||
|
Loading…
Reference in New Issue
Block a user