Macro operator properties using property groups in groups (initial code by brecht).
Works correctly with menu, keymap definitions and keymap export/import. Properties set in the macro definition overwrite those set by the user (there's no way to see that in the UI at this point). MISSING: Python operator calling code to fill in the properties hierarchy. Also contains some keymap export changes by Imran Syed (freakabcd on irc): the exported configuration will use the name of the file and the exported script will select the added configuration when ran.
This commit is contained in:
@@ -18,6 +18,7 @@
|
||||
|
||||
# <pep8 compliant>
|
||||
import bpy
|
||||
import os.path
|
||||
|
||||
# General UI Theme Settings (User Interface)
|
||||
def ui_items_general(col, context):
|
||||
@@ -161,7 +162,8 @@ class USERPREF_HT_header(bpy.types.Header):
|
||||
|
||||
if userpref.active_section == 'INPUT':
|
||||
layout.operator_context = 'INVOKE_DEFAULT'
|
||||
layout.operator("wm.keyconfig_export", "Export Key Configuration...").path = "keymap.py"
|
||||
op = layout.operator("wm.keyconfig_export", "Export Key Configuration...")
|
||||
op.path = "keymap.py"
|
||||
|
||||
|
||||
class USERPREF_PT_tabs(bpy.types.Panel):
|
||||
@@ -1166,15 +1168,24 @@ class USERPREF_PT_input(bpy.types.Panel):
|
||||
subrow.prop(kmi, "alt")
|
||||
subrow.prop(kmi, "oskey", text="Cmd")
|
||||
subrow.prop(kmi, "key_modifier", text="", event=True)
|
||||
|
||||
def display_properties(properties, title = None):
|
||||
box.separator()
|
||||
if title:
|
||||
box.label(text=title)
|
||||
flow = box.column_flow(columns=2)
|
||||
for pname in dir(properties):
|
||||
if not properties.is_property_hidden(pname):
|
||||
value = eval("properties." + pname)
|
||||
if isinstance(value, bpy.types.OperatorProperties):
|
||||
display_properties(value, title = pname)
|
||||
else:
|
||||
flow.prop(properties, pname)
|
||||
|
||||
# Operator properties
|
||||
props = kmi.properties
|
||||
if props is not None:
|
||||
box.separator()
|
||||
flow = box.column_flow(columns=2)
|
||||
for pname in dir(props):
|
||||
if not props.is_property_hidden(pname):
|
||||
flow.prop(props, pname)
|
||||
display_properties(props)
|
||||
|
||||
# Modal key maps attached to this operator
|
||||
if not km.modal:
|
||||
@@ -1344,16 +1355,22 @@ class WM_OT_keyconfig_test(bpy.types.Operator):
|
||||
s.append(", key_modifier=\'%s\'" % kmi.key_modifier)
|
||||
|
||||
s.append(")\n")
|
||||
|
||||
def export_properties(prefix, properties):
|
||||
for pname in dir(properties):
|
||||
if not properties.is_property_hidden(pname):
|
||||
value = eval("properties.%s" % pname)
|
||||
if isinstance(value, bpy.types.OperatorProperties):
|
||||
export_properties(prefix + "." + pname, value)
|
||||
elif properties.is_property_set(pname):
|
||||
value = _string_value(value)
|
||||
if value != "":
|
||||
s.append(prefix + ".%s = %s\n" % (pname, value))
|
||||
|
||||
props = kmi.properties
|
||||
|
||||
if props is not None:
|
||||
for pname in dir(props):
|
||||
if props.is_property_set(pname) and not props.is_property_hidden(pname):
|
||||
value = eval("props.%s" % pname)
|
||||
value = _string_value(value)
|
||||
if value != "":
|
||||
s.append("kmi.properties.%s = %s\n" % (pname, value))
|
||||
export_properties("kmi.properties", props)
|
||||
|
||||
return "".join(s).strip()
|
||||
|
||||
@@ -1451,6 +1468,9 @@ class WM_OT_keyconfig_export(bpy.types.Operator):
|
||||
bl_label = "Export Key Configuration..."
|
||||
|
||||
path = bpy.props.StringProperty(name="File Path", description="File path to write file to.")
|
||||
filter_folder = bpy.props.BoolProperty(name="Filter folders", description="", default=True)
|
||||
filter_text = bpy.props.BoolProperty(name="Filter text", description="", default=True)
|
||||
filter_python = bpy.props.BoolProperty(name="Filter python", description="", default=True)
|
||||
|
||||
def execute(self, context):
|
||||
if not self.properties.path:
|
||||
@@ -1463,10 +1483,15 @@ class WM_OT_keyconfig_export(bpy.types.Operator):
|
||||
wm = context.manager
|
||||
kc = wm.active_keyconfig
|
||||
|
||||
f.write('# Configuration %s\n' % kc.name)
|
||||
if kc.name == 'Blender':
|
||||
name = os.path.splitext(os.path.basename(self.properties.path))[0]
|
||||
else:
|
||||
name = kc.name
|
||||
|
||||
f.write('# Configuration %s\n' % name)
|
||||
|
||||
f.write("wm = bpy.data.window_managers[0]\n")
|
||||
f.write("kc = wm.add_keyconfig(\'%s\')\n\n" % kc.name)
|
||||
f.write("kc = wm.add_keyconfig(\'%s\')\n\n" % name)
|
||||
|
||||
for km in kc.keymaps:
|
||||
km = km.active()
|
||||
@@ -1492,18 +1517,25 @@ class WM_OT_keyconfig_export(bpy.types.Operator):
|
||||
f.write(", key_modifier=\'%s\'" % kmi.key_modifier)
|
||||
f.write(")\n")
|
||||
|
||||
def export_properties(prefix, properties):
|
||||
for pname in dir(properties):
|
||||
if not properties.is_property_hidden(pname):
|
||||
value = eval("properties.%s" % pname)
|
||||
if isinstance(value, bpy.types.OperatorProperties):
|
||||
export_properties(prefix + "." + pname, value)
|
||||
elif properties.is_property_set(pname):
|
||||
value = _string_value(value)
|
||||
if value != "":
|
||||
f.write(prefix + ".%s = %s\n" % (pname, value))
|
||||
|
||||
props = kmi.properties
|
||||
|
||||
|
||||
if props is not None:
|
||||
for pname in dir(props):
|
||||
if props.is_property_set(pname) and not props.is_property_hidden(pname):
|
||||
value = eval("props.%s" % pname)
|
||||
value = _string_value(value)
|
||||
if value != "":
|
||||
f.write("kmi.properties.%s = %s\n" % (pname, value))
|
||||
export_properties("kmi.properties", props)
|
||||
|
||||
f.write("\n")
|
||||
|
||||
f.write("wm.active_keyconfig = wm.keyconfigs[\'%s\']\n" % name)
|
||||
f.close()
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
@@ -159,6 +159,19 @@ static void view3d_panel_operator_redo_header(const bContext *C, Panel *pa)
|
||||
else BLI_strncpy(pa->drawname, "Operator", sizeof(pa->drawname));
|
||||
}
|
||||
|
||||
static void view3d_panel_operator_redo_operator(const bContext *C, Panel *pa, wmOperator *op)
|
||||
{
|
||||
if(op->type->flag & OPTYPE_MACRO) {
|
||||
for(op= op->macro.first; op; op= op->next) {
|
||||
uiItemL(pa->layout, op->idname, 0);
|
||||
view3d_panel_operator_redo_operator(C, pa, op);
|
||||
}
|
||||
}
|
||||
else {
|
||||
view3d_panel_operator_redo_buts(C, pa, op);
|
||||
}
|
||||
}
|
||||
|
||||
static void view3d_panel_operator_redo(const bContext *C, Panel *pa)
|
||||
{
|
||||
wmOperator *op= view3d_last_operator(C);
|
||||
@@ -173,13 +186,7 @@ static void view3d_panel_operator_redo(const bContext *C, Panel *pa)
|
||||
|
||||
uiBlockSetFunc(block, redo_cb, op, NULL);
|
||||
|
||||
if(op->macro.first) {
|
||||
for(op= op->macro.first; op; op= op->next)
|
||||
view3d_panel_operator_redo_buts(C, pa, op);
|
||||
}
|
||||
else {
|
||||
view3d_panel_operator_redo_buts(C, pa, op);
|
||||
}
|
||||
view3d_panel_operator_redo_operator(C, pa, op);
|
||||
}
|
||||
|
||||
/* ******************* */
|
||||
|
||||
@@ -391,15 +391,41 @@ static wmOperator *wm_operator_create(wmWindowManager *wm, wmOperatorType *ot, P
|
||||
motherop = op;
|
||||
root = 1;
|
||||
}
|
||||
|
||||
for(otmacro= ot->macro.first; otmacro; otmacro= otmacro->next) {
|
||||
wmOperatorType *otm= WM_operatortype_find(otmacro->idname, 0);
|
||||
wmOperator *opm= wm_operator_create(wm, otm, otmacro->ptr, NULL);
|
||||
|
||||
IDP_ReplaceGroupInGroup(opm->properties, motherop->properties);
|
||||
|
||||
BLI_addtail(&motherop->macro, opm);
|
||||
opm->opm= motherop; /* pointer to mom, for modal() */
|
||||
|
||||
/* if properties exist, it will contain everything needed */
|
||||
if (properties) {
|
||||
otmacro= ot->macro.first;
|
||||
|
||||
RNA_STRUCT_BEGIN(properties, prop) {
|
||||
|
||||
if (otmacro == NULL)
|
||||
break;
|
||||
|
||||
/* skip invalid properties */
|
||||
if (strcmp(RNA_property_identifier(prop), otmacro->idname) == 0)
|
||||
{
|
||||
wmOperatorType *otm= WM_operatortype_find(otmacro->idname, 0);
|
||||
PointerRNA someptr = RNA_property_pointer_get(properties, prop);
|
||||
wmOperator *opm= wm_operator_create(wm, otm, &someptr, NULL);
|
||||
|
||||
IDP_ReplaceGroupInGroup(opm->properties, otmacro->properties);
|
||||
|
||||
BLI_addtail(&motherop->macro, opm);
|
||||
opm->opm= motherop; /* pointer to mom, for modal() */
|
||||
|
||||
otmacro= otmacro->next;
|
||||
}
|
||||
}
|
||||
RNA_STRUCT_END;
|
||||
} else {
|
||||
for (otmacro = ot->macro.first; otmacro; otmacro = otmacro->next) {
|
||||
wmOperatorType *otm= WM_operatortype_find(otmacro->idname, 0);
|
||||
wmOperator *opm= wm_operator_create(wm, otm, otmacro->ptr, NULL);
|
||||
|
||||
BLI_addtail(&motherop->macro, opm);
|
||||
opm->opm= motherop; /* pointer to mom, for modal() */
|
||||
}
|
||||
}
|
||||
|
||||
if (root)
|
||||
|
||||
@@ -347,8 +347,11 @@ wmOperatorType *WM_operatortype_append_macro(char *idname, char *name, int flag)
|
||||
ot->modal= wm_macro_modal;
|
||||
ot->cancel= wm_macro_cancel;
|
||||
ot->poll= NULL;
|
||||
|
||||
if(!ot->description)
|
||||
ot->description= "(undocumented operator)";
|
||||
|
||||
RNA_def_struct_ui_text(ot->srna, ot->name, ot->description ? ot->description:"(undocumented operator)"); // XXX All ops should have a description but for now allow them not to.
|
||||
RNA_def_struct_ui_text(ot->srna, ot->name, ot->description); // XXX All ops should have a description but for now allow them not to.
|
||||
RNA_def_struct_identifier(ot->srna, ot->idname);
|
||||
|
||||
BLI_addtail(&global_ops, ot);
|
||||
@@ -370,9 +373,12 @@ void WM_operatortype_append_macro_ptr(void (*opfunc)(wmOperatorType*, void*), vo
|
||||
ot->cancel= wm_macro_cancel;
|
||||
ot->poll= NULL;
|
||||
|
||||
if(!ot->description)
|
||||
ot->description= "(undocumented operator)";
|
||||
|
||||
opfunc(ot, userdata);
|
||||
|
||||
RNA_def_struct_ui_text(ot->srna, ot->name, ot->description ? ot->description:"(undocumented operator)");
|
||||
RNA_def_struct_ui_text(ot->srna, ot->name, ot->description);
|
||||
RNA_def_struct_identifier(ot->srna, ot->idname);
|
||||
|
||||
BLI_addtail(&global_ops, ot);
|
||||
@@ -388,6 +394,12 @@ wmOperatorTypeMacro *WM_operatortype_macro_define(wmOperatorType *ot, const char
|
||||
WM_operator_properties_alloc(&(otmacro->ptr), &(otmacro->properties), idname);
|
||||
|
||||
BLI_addtail(&ot->macro, otmacro);
|
||||
|
||||
{
|
||||
wmOperatorType *otsub = WM_operatortype_find(idname, 0);
|
||||
RNA_def_pointer_runtime(ot->srna, otsub->idname, otsub->srna,
|
||||
otsub->name, otsub->description);
|
||||
}
|
||||
|
||||
return otmacro;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user