Custom property overrides.
authorLukas Tönne <lukas.toenne@gmail.com>
Tue, 10 Feb 2015 14:44:28 +0000 (15:44 +0100)
committerLukas Tönne <lukas.toenne@gmail.com>
Tue, 10 Feb 2015 14:44:56 +0000 (15:44 +0100)
data_overrides/override.py
data_overrides/ui.py

index d971ea0..fe0518c 100644 (file)
 import bpy, os
 from bpy.types import Operator, PropertyGroup
 from bpy.props import *
+from bpy.utils import escape_identifier
 
 from data_overrides.util import *
 
 # ======================================================================================
 
+class OverrideCustomProperty(PropertyGroup):
+    def _value_get(self):
+        return self['value']
+    def _value_set(self, v):
+        self['value'] = v
+    def _value_del(self):
+        del self['value']
+    value = property(_value_get, _value_set, _value_del)
+
+    def reset(self, target):
+        try:
+            val = eval("target.{}".format(self.name))
+        except:
+            # TODO define exceptions that should be handled gracefully
+            raise
+            return
+        self['value'] = val
+
+    def apply(self, target):
+        val = self['value']
+        try:
+            eval("target.{} = val".format(self.name))
+        except:
+            # TODO define exceptions that should be handled gracefully
+            raise
+            return
+
 class Override(PropertyGroup):
     id_name = StringProperty(name="ID Name", description="Name of the overridden ID datablock")
     id_library = StringProperty(name="ID Library", description="Library file path of the overridden ID datablock")
 
     show_expanded = BoolProperty(name="Show Expanded", description="Expand override details in the interface", default=True)
 
-    def find_id_data(self, blend_data):
+    def add_custom_property(self, name):
+        prop = self.custom_properties.get(name, None)
+        if not prop:
+            target = self.find_target(bpy.data)
+            if target:
+                prop = self.custom_properties.add()
+                prop.name = name
+                prop.reset(target) # initialize with target value
+
+    def find_target(self, blend_data):
         return find_id_data(blend_data, self.id_name, self.id_library)
 
     @property
     def label(self):
         return "{}".format(self.id_name)
 
+    def draw_custom_props(self, context, layout):
+        for prop in self.custom_properties:
+            row = layout.row(align=True)
+            row.label(prop.name, icon='DOT')
+            row.prop(prop, '["{}"]'.format(escape_identifier("value")), text="")
+        
+        row = layout.row()
+        row.operator_context = 'INVOKE_SCREEN'
+        row.context_pointer_set("id_data_override", self)
+        row.operator("scene.override_add_custom_property", text="", icon='ZOOMIN')
+
     def draw(self, context, layout):
-        id_data = self.find_id_data(context.blend_data)
-        if not id_data:
+        target = self.find_target(context.blend_data)
+        if not target:
             return
 
         split = layout.split(0.05)
@@ -50,9 +98,12 @@ class Override(PropertyGroup):
         col.prop(self, "show_expanded", emboss=False, icon_only=True, icon='TRIA_DOWN' if self.show_expanded else 'TRIA_RIGHT')
 
         col = split.column()
-        icon = bpy.types.UILayout.icon(id_data)
+        icon = bpy.types.UILayout.icon(target)
         col.label(text=self.label, icon_value=icon)
 
+        self.draw_custom_props(context, layout)
+
+
 def target_library(target):
     id_data = target.id_data
     return id_data.library.filepath if id_data.library else ""
@@ -90,6 +141,9 @@ def remove_override(scene, target):
 # ======================================================================================
 
 def register_property_groups():
+    bpy.utils.register_class(OverrideCustomProperty)
+
+    Override.custom_properties = CollectionProperty(type=OverrideCustomProperty)
     bpy.utils.register_class(Override)
 
     bpy.types.Scene.overrides = CollectionProperty(type=Override)
index ef97e81..81ca1be 100644 (file)
@@ -79,9 +79,9 @@ class OBJECT_PT_SimulationOverrides(Panel):
 '''
 
 
-class SCENE_OP_AddOverride(Operator):
-    """Add Override"""
-    bl_idname = "scene.add_override"
+class SCENE_OT_Override_Add(Operator):
+    """Add Datablock Override"""
+    bl_idname = "scene.override_add"
     bl_label = "Add Override"
     bl_property = "id_block"
 
@@ -103,6 +103,38 @@ class SCENE_OP_AddOverride(Operator):
         return {'FINISHED'}
 
 
+class SCENE_OT_Override_AddCustomProperty(Operator):
+    """Add Custom Property Override"""
+    bl_idname = "scene.override_add_custom_property"
+    bl_label = "Add Custom Property Override"
+    bl_options = {'REGISTER', 'UNDO'}
+
+    propname = StringProperty(name="Property", description="Path to the custom property to override")
+
+    @classmethod
+    def poll(cls, context):
+        if not context.scene:
+            return False
+        if not hasattr(context, "id_data_override"):
+            return False
+        return True
+
+    def invoke(self, context, event):
+        return context.window_manager.invoke_props_popup(self, event)
+
+    def execute(self, context):
+        print("AAAAAA")
+        scene = context.scene
+        override = context.id_data_override
+
+        if not self.propname:
+            print("no propname?")
+            return {'CANCELLED'}
+
+        print("adding %s" % self.propname)
+        override.add_custom_property(self.propname)
+        return {'FINISHED'}
+
 def template_overrides(layout, context, scene):
     for override in scene.overrides:
         override.draw(context, layout)
@@ -124,7 +156,7 @@ class SCENE_PT_Overrides(Panel):
         layout = self.layout
         scene = context.scene
 
-        layout.operator("scene.add_override")
+        layout.operator("scene.override_add")
 
         box = layout.box()
         template_overrides(box, context, scene)
@@ -135,7 +167,8 @@ class SCENE_PT_Overrides(Panel):
 
 classes = (
 #    OBJECT_PT_SimulationOverrides,
-    SCENE_OP_AddOverride,
+    SCENE_OT_Override_Add,
+    SCENE_OT_Override_AddCustomProperty,
     SCENE_PT_Overrides,
     )