From 7636d17af627dd10bc7b9c9f66e185af8f8be1ec Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 16 Nov 2009 22:53:28 +0000 Subject: [PATCH] property editor for bone and object ID props, add/remove/edit good example of how editing NON rna data results in very weired scripts :/ --- release/scripts/modules/rna_prop_ui.py | 218 +++++++++++++++++++++ release/scripts/op/wm.py | 8 +- release/scripts/ui/properties_data_bone.py | 13 ++ release/scripts/ui/properties_object.py | 12 ++ 4 files changed, 250 insertions(+), 1 deletion(-) create mode 100644 release/scripts/modules/rna_prop_ui.py diff --git a/release/scripts/modules/rna_prop_ui.py b/release/scripts/modules/rna_prop_ui.py new file mode 100644 index 00000000000..ccb3062bd4b --- /dev/null +++ b/release/scripts/modules/rna_prop_ui.py @@ -0,0 +1,218 @@ +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# ##### END GPL LICENSE BLOCK ##### + +# + +import bpy + +EVIL_PROP = "act_property" +EVIL_PROP_PATH = EVIL_PROP + '_path' +EVIL_PROP_VALUE = EVIL_PROP + '_value' +EVIL_PROP_PROP = EVIL_PROP + '_prop' +EVIL_PROP_PROP_ORIG = EVIL_PROP + '_prop_orig' + +# nasty!, use a scene property to store the active edit item +def evil_prop_init(): + Scene = bpy.types.Scene + if EVIL_PROP_PROP_ORIG not in Scene.bl_rna.properties: + Scene.StringProperty(attr=EVIL_PROP_PATH) + Scene.StringProperty(attr=EVIL_PROP_VALUE) + Scene.StringProperty(attr=EVIL_PROP_PROP) + Scene.StringProperty(attr=EVIL_PROP_PROP_ORIG) + + +def draw(layout, context, context_member): + + def assign_props(prop, val, key): + prop.path = context_member + prop.property = key + + try: + prop.value = str(val) + except: + pass + + rna_item = eval("context." + context_member) + + evil_prop_init() + + scene = context.scene + + global_path = getattr(scene, EVIL_PROP_PATH) + global_value = getattr(scene, EVIL_PROP_VALUE) + global_prop = getattr(scene, EVIL_PROP_PROP) + global_prop_orig = getattr(scene, EVIL_PROP_PROP_ORIG) + + # print((global_path, global_value, global_prop, global_prop_orig)) + + items = rna_item.items() + items.sort() + + row = layout.row() + props = row.itemO("wm.properties_add", properties=True, text="Add") + props.path = context_member + + for key, val in items: + row = layout.row() + + try: + val_draw = val = val.convert_to_pyobject() + except: + if type(val)==str: + val_draw = '"' + val + '"' + else: + val_draw = val + + box = row.box() + + + if key == global_prop_orig and context_member == global_path: + split = box.split(percentage=0.7) + + col = split.row() + col.itemR(scene, EVIL_PROP_PROP) + col.itemR(scene, EVIL_PROP_VALUE) + + col = split.column() + prop = col.itemO("wm.properties_edit_end", properties=True, text="done") + assign_props(prop, val, key) + + else: + split = box.split(percentage=0.5) + col = split.column() + col.itemL(text="%s = %s" % (key, str(val_draw))) + + col = split.column() + prop = col.itemO("wm.properties_edit_begin", properties=True, text="edit") + assign_props(prop, val, key) + + col = split.column() + prop = col.itemO("wm.properties_remove", properties=True, text="del") + assign_props(prop, val, key) + + +from bpy.props import * + + +rna_path = StringProperty(name="Property Edit", + description="Property path edit", maxlen=1024, default="") + +rna_value = StringProperty(name="Property Value", + description="Property value edit", maxlen=1024, default="") + +rna_property = StringProperty(name="Property Name", + description="Property name edit", maxlen=1024, default="") + +class WM_OT_properties_edit_begin(bpy.types.Operator): + '''Internal use (edit a property path)''' + bl_idname = "wm.properties_edit_begin" + bl_label = "Edit Property" + + path = rna_path + value = rna_value + property = rna_property + + def execute(self, context): + scene = context.scene + + setattr(scene, EVIL_PROP_PATH, self.path) + setattr(scene, EVIL_PROP_VALUE, self.value) + setattr(scene, EVIL_PROP_PROP, self.property) + setattr(scene, EVIL_PROP_PROP_ORIG, self.property) + + return ('FINISHED',) + + +class WM_OT_properties_edit_end(bpy.types.Operator): + '''Internal use (edit a property path)''' + bl_idname = "wm.properties_edit_end" + bl_label = "Edit Property" + + path = rna_path + value = rna_value + property = rna_property + + def execute(self, context): + + scene = context.scene + global_path = getattr(scene, EVIL_PROP_PATH) + global_value = getattr(scene, EVIL_PROP_VALUE) + global_prop = getattr(scene, EVIL_PROP_PROP) + + setattr(scene, EVIL_PROP_PATH, "") + setattr(scene, EVIL_PROP_VALUE, "") + setattr(scene, EVIL_PROP_PROP, "") + setattr(scene, EVIL_PROP_PROP_ORIG, "") + + try: + value = eval(global_value) + except: + value = '"' + global_value + '"' # keep as a string + + + # First remove + exec_str = "del context.%s['%s']" % (global_path, self.property) + # print(exec_str) + exec(exec_str) + + + # Reassign + exec_str = "context.%s['%s'] = %s" % (global_path, global_prop, value) + # print(exec_str) + exec(exec_str) + + return ('FINISHED',) + + +class WM_OT_properties_add(bpy.types.Operator): + '''Internal use (edit a property path)''' + bl_idname = "wm.properties_add" + bl_label = "Add Property" + + path = rna_path + + def execute(self, context): + item = eval("context.%s" % self.path) + + def unique_name(names): + prop = 'prop' + prop_new = prop + i = 1 + while prop_new in names: + prop_new = prop + str(i) + i+=1 + + return prop_new + + property = unique_name(item.keys()) + + item[property] = 1.0 + return ('FINISHED',) + +class WM_OT_properties_remove(bpy.types.Operator): + '''Internal use (edit a property path)''' + bl_idname = "wm.properties_remove" + bl_label = "Add Property" + + path = rna_path + property = rna_property + + def execute(self, context): + item = eval("context.%s" % self.path) + del item[self.property] + return ('FINISHED',) diff --git a/release/scripts/op/wm.py b/release/scripts/op/wm.py index 39bd65eec25..1f5a589afc7 100644 --- a/release/scripts/op/wm.py +++ b/release/scripts/op/wm.py @@ -392,7 +392,6 @@ class WM_OT_reload_scripts(bpy.types.Operator): ''' return ('FINISHED',) - bpy.ops.add(MESH_OT_delete_edgeloop) bpy.ops.add(WM_OT_context_set_boolean) @@ -409,3 +408,10 @@ bpy.ops.add(WM_OT_doc_view) bpy.ops.add(WM_OT_doc_edit) bpy.ops.add(WM_OT_reload_scripts) + +# experemental! +import rna_prop_ui +bpy.ops.add(rna_prop_ui.WM_OT_properties_edit_begin) +bpy.ops.add(rna_prop_ui.WM_OT_properties_edit_end) +bpy.ops.add(rna_prop_ui.WM_OT_properties_add) +bpy.ops.add(rna_prop_ui.WM_OT_properties_remove) diff --git a/release/scripts/ui/properties_data_bone.py b/release/scripts/ui/properties_data_bone.py index c670d4677d8..6ea65bf5cd1 100644 --- a/release/scripts/ui/properties_data_bone.py +++ b/release/scripts/ui/properties_data_bone.py @@ -274,9 +274,22 @@ class BONE_PT_deform(BoneButtonsPanel): col.itemL(text="Offset:") col.itemR(bone, "cyclic_offset") +class BONE_PT_properties(BoneButtonsPanel): + bl_label = "Properties" + bl_default_closed = True + + def draw(self, context): + import rna_prop_ui + # reload(rna_prop_ui) + + rna_prop_ui.draw(self.layout, context, "active_bone") + + + bpy.types.register(BONE_PT_context_bone) bpy.types.register(BONE_PT_transform) bpy.types.register(BONE_PT_transform_locks) bpy.types.register(BONE_PT_relations) bpy.types.register(BONE_PT_display) bpy.types.register(BONE_PT_deform) +bpy.types.register(BONE_PT_properties) diff --git a/release/scripts/ui/properties_object.py b/release/scripts/ui/properties_object.py index 45a9318afd3..c7d3f77caed 100644 --- a/release/scripts/ui/properties_object.py +++ b/release/scripts/ui/properties_object.py @@ -292,6 +292,17 @@ class OBJECT_PT_animation(ObjectButtonsPanel): row.itemR(ob, "track_override_parent", text="Override Parent") row.active = ob.parent != None + +class OBJECT_PT_properties(ObjectButtonsPanel): + bl_label = "Properties" + bl_default_closed = True + + def draw(self, context): + import rna_prop_ui + # reload(rna_prop_ui) + + rna_prop_ui.draw(self.layout, context, "object") + bpy.types.register(OBJECT_PT_context_object) bpy.types.register(OBJECT_PT_transform) bpy.types.register(OBJECT_PT_transform_locks) @@ -300,3 +311,4 @@ bpy.types.register(OBJECT_PT_groups) bpy.types.register(OBJECT_PT_display) bpy.types.register(OBJECT_PT_duplication) bpy.types.register(OBJECT_PT_animation) +bpy.types.register(OBJECT_PT_properties)