2009-11-16 22:53:28 +00:00
|
|
|
# ##### 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,
|
2010-02-12 13:34:04 +00:00
|
|
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
2009-11-16 22:53:28 +00:00
|
|
|
#
|
|
|
|
# ##### END GPL LICENSE BLOCK #####
|
|
|
|
|
|
|
|
# <pep8 compliant>
|
|
|
|
|
|
|
|
import bpy
|
|
|
|
|
2009-12-04 17:54:48 +00:00
|
|
|
|
2009-11-19 17:12:08 +00:00
|
|
|
def rna_idprop_ui_get(item, create=True):
|
|
|
|
try:
|
|
|
|
return item['_RNA_UI']
|
|
|
|
except:
|
|
|
|
if create:
|
|
|
|
item['_RNA_UI'] = {}
|
|
|
|
return item['_RNA_UI']
|
|
|
|
else:
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
|
|
def rna_idprop_ui_prop_get(item, prop, create=True):
|
2009-11-21 23:55:14 +00:00
|
|
|
|
2009-11-19 17:12:08 +00:00
|
|
|
rna_ui = rna_idprop_ui_get(item, create)
|
2009-11-21 23:55:14 +00:00
|
|
|
|
2009-11-19 17:12:08 +00:00
|
|
|
if rna_ui == None:
|
|
|
|
return None
|
2009-11-21 23:55:14 +00:00
|
|
|
|
2009-11-19 17:12:08 +00:00
|
|
|
try:
|
|
|
|
return rna_ui[prop]
|
|
|
|
except:
|
|
|
|
rna_ui[prop] = {}
|
|
|
|
return rna_ui[prop]
|
|
|
|
|
|
|
|
|
|
|
|
def rna_idprop_ui_prop_clear(item, prop):
|
|
|
|
rna_ui = rna_idprop_ui_get(item, False)
|
2009-11-21 23:55:14 +00:00
|
|
|
|
2009-11-19 17:12:08 +00:00
|
|
|
if rna_ui == None:
|
|
|
|
return
|
|
|
|
|
|
|
|
try:
|
|
|
|
del rna_ui[prop]
|
|
|
|
except:
|
|
|
|
pass
|
|
|
|
|
2009-11-16 22:53:28 +00:00
|
|
|
|
2009-12-04 17:54:48 +00:00
|
|
|
def draw(layout, context, context_member, use_edit=True):
|
2009-11-21 23:55:14 +00:00
|
|
|
|
2009-11-16 22:53:28 +00:00
|
|
|
def assign_props(prop, val, key):
|
2010-06-14 03:52:10 +00:00
|
|
|
prop.data_path = context_member
|
2009-11-16 22:53:28 +00:00
|
|
|
prop.property = key
|
2009-11-21 23:55:14 +00:00
|
|
|
|
2009-11-16 22:53:28 +00:00
|
|
|
try:
|
|
|
|
prop.value = str(val)
|
|
|
|
except:
|
|
|
|
pass
|
2009-11-21 23:55:14 +00:00
|
|
|
|
2009-11-16 22:53:28 +00:00
|
|
|
rna_item = eval("context." + context_member)
|
2009-12-04 17:54:48 +00:00
|
|
|
|
2009-11-24 00:02:21 +00:00
|
|
|
# poll should really get this...
|
|
|
|
if not rna_item:
|
|
|
|
return
|
2009-11-16 22:53:28 +00:00
|
|
|
|
|
|
|
items = rna_item.items()
|
|
|
|
items.sort()
|
2009-11-21 23:55:14 +00:00
|
|
|
|
2009-11-18 20:01:35 +00:00
|
|
|
if use_edit:
|
|
|
|
row = layout.row()
|
2009-11-23 11:43:38 +00:00
|
|
|
props = row.operator("wm.properties_add", text="Add")
|
2010-06-14 03:52:10 +00:00
|
|
|
props.data_path = context_member
|
2009-11-18 20:01:35 +00:00
|
|
|
del row
|
|
|
|
|
2009-11-16 22:53:28 +00:00
|
|
|
for key, val in items:
|
2009-11-19 18:22:21 +00:00
|
|
|
|
2009-11-18 20:01:35 +00:00
|
|
|
if key == '_RNA_UI':
|
|
|
|
continue
|
2009-11-21 23:55:14 +00:00
|
|
|
|
2009-11-16 22:53:28 +00:00
|
|
|
row = layout.row()
|
2009-11-17 10:30:54 +00:00
|
|
|
convert_to_pyobject = getattr(val, "convert_to_pyobject", None)
|
2009-11-21 23:55:14 +00:00
|
|
|
|
2009-11-17 12:54:29 +00:00
|
|
|
val_orig = val
|
2009-11-17 10:30:54 +00:00
|
|
|
if convert_to_pyobject:
|
2009-11-16 22:53:28 +00:00
|
|
|
val_draw = val = val.convert_to_pyobject()
|
2009-11-17 10:30:54 +00:00
|
|
|
val_draw = str(val_draw)
|
|
|
|
else:
|
2009-11-17 13:18:26 +00:00
|
|
|
val_draw = val
|
2009-11-17 10:30:54 +00:00
|
|
|
|
2009-11-16 22:53:28 +00:00
|
|
|
box = row.box()
|
2009-11-19 18:22:21 +00:00
|
|
|
|
|
|
|
if use_edit:
|
2009-11-17 10:30:54 +00:00
|
|
|
split = box.split(percentage=0.75)
|
|
|
|
row = split.row()
|
2009-11-16 22:53:28 +00:00
|
|
|
else:
|
2009-11-19 18:22:21 +00:00
|
|
|
row = box.row()
|
2009-11-21 23:55:14 +00:00
|
|
|
|
2009-11-23 00:27:30 +00:00
|
|
|
row.label(text=key)
|
2009-11-21 23:55:14 +00:00
|
|
|
|
2009-11-19 18:22:21 +00:00
|
|
|
# explicit exception for arrays
|
|
|
|
if convert_to_pyobject and not hasattr(val_orig, "len"):
|
2009-11-23 00:27:30 +00:00
|
|
|
row.label(text=val_draw)
|
2009-11-19 18:22:21 +00:00
|
|
|
else:
|
2009-11-23 00:27:30 +00:00
|
|
|
row.prop(rna_item, '["%s"]' % key, text="")
|
2009-11-21 23:55:14 +00:00
|
|
|
|
2009-11-19 18:22:21 +00:00
|
|
|
if use_edit:
|
|
|
|
row = split.row(align=True)
|
2009-11-23 11:43:38 +00:00
|
|
|
prop = row.operator("wm.properties_edit", text="edit")
|
2009-11-19 18:22:21 +00:00
|
|
|
assign_props(prop, val_draw, key)
|
2009-11-21 23:55:14 +00:00
|
|
|
|
2009-12-10 11:56:31 +00:00
|
|
|
prop = row.operator("wm.properties_remove", text="", icon='ZOOMOUT')
|
2009-11-19 18:22:21 +00:00
|
|
|
assign_props(prop, val_draw, key)
|
2009-11-21 23:55:14 +00:00
|
|
|
|
2009-11-16 22:53:28 +00:00
|
|
|
|
2010-01-08 08:54:41 +00:00
|
|
|
class PropertyPanel(bpy.types.Panel):
|
|
|
|
"""
|
2010-01-31 14:46:28 +00:00
|
|
|
The subclass should have its own poll function
|
2010-01-08 08:54:41 +00:00
|
|
|
and the variable '_context_path' MUST be set.
|
|
|
|
"""
|
|
|
|
bl_label = "Custom Properties"
|
|
|
|
bl_default_closed = True
|
|
|
|
|
|
|
|
def draw(self, context):
|
|
|
|
draw(self.layout, context, self._context_path)
|
|
|
|
|
|
|
|
|
2009-11-16 22:53:28 +00:00
|
|
|
from bpy.props import *
|
|
|
|
|
|
|
|
|
|
|
|
rna_path = StringProperty(name="Property Edit",
|
2010-06-14 03:52:10 +00:00
|
|
|
description="Property data_path edit", maxlen=1024, default="", options={'HIDDEN'})
|
2009-11-16 22:53:28 +00:00
|
|
|
|
|
|
|
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="")
|
|
|
|
|
2009-11-19 18:22:21 +00:00
|
|
|
rna_min = FloatProperty(name="Min", default=0.0, precision=3)
|
|
|
|
rna_max = FloatProperty(name="Max", default=1.0, precision=3)
|
2009-11-16 22:53:28 +00:00
|
|
|
|
2009-12-04 17:54:48 +00:00
|
|
|
|
2009-11-19 17:12:08 +00:00
|
|
|
class WM_OT_properties_edit(bpy.types.Operator):
|
2010-06-14 03:52:10 +00:00
|
|
|
'''Internal use (edit a property data_path)'''
|
2009-11-19 17:12:08 +00:00
|
|
|
bl_idname = "wm.properties_edit"
|
2009-12-25 20:40:00 +00:00
|
|
|
bl_label = "Edit Property"
|
2009-11-21 23:55:14 +00:00
|
|
|
|
2010-06-14 03:52:10 +00:00
|
|
|
data_path = rna_path
|
2009-11-16 22:53:28 +00:00
|
|
|
property = rna_property
|
2009-11-20 20:58:46 +00:00
|
|
|
value = rna_value
|
2009-11-19 18:22:21 +00:00
|
|
|
min = rna_min
|
|
|
|
max = rna_max
|
2009-11-20 20:58:46 +00:00
|
|
|
description = StringProperty(name="Tip", default="")
|
2009-11-21 23:55:14 +00:00
|
|
|
|
2009-11-16 22:53:28 +00:00
|
|
|
def execute(self, context):
|
2010-06-14 03:52:10 +00:00
|
|
|
data_path = self.properties.data_path
|
2009-11-19 18:22:21 +00:00
|
|
|
value = self.properties.value
|
|
|
|
prop = self.properties.property
|
|
|
|
prop_old = self._last_prop[0]
|
2009-11-19 17:12:08 +00:00
|
|
|
|
2009-11-16 22:53:28 +00:00
|
|
|
try:
|
2009-11-19 18:22:21 +00:00
|
|
|
value_eval = eval(value)
|
2009-11-16 22:53:28 +00:00
|
|
|
except:
|
2009-11-19 18:22:21 +00:00
|
|
|
value_eval = value
|
2009-11-21 23:55:14 +00:00
|
|
|
|
2009-11-16 22:53:28 +00:00
|
|
|
# First remove
|
2010-06-14 03:52:10 +00:00
|
|
|
item = eval("context.%s" % data_path)
|
2009-11-21 23:55:14 +00:00
|
|
|
|
2009-11-19 18:22:21 +00:00
|
|
|
rna_idprop_ui_prop_clear(item, prop_old)
|
|
|
|
exec_str = "del item['%s']" % prop_old
|
2009-11-16 22:53:28 +00:00
|
|
|
# print(exec_str)
|
|
|
|
exec(exec_str)
|
2009-11-21 23:55:14 +00:00
|
|
|
|
|
|
|
|
2009-11-16 22:53:28 +00:00
|
|
|
# Reassign
|
2010-02-24 15:35:15 +00:00
|
|
|
exec_str = "item['%s'] = %s" % (prop, repr(value_eval))
|
2009-11-16 22:53:28 +00:00
|
|
|
# print(exec_str)
|
|
|
|
exec(exec_str)
|
2009-11-23 23:17:23 +00:00
|
|
|
self._last_prop[:] = [prop]
|
2009-11-21 23:55:14 +00:00
|
|
|
|
2009-11-19 18:22:21 +00:00
|
|
|
prop_type = type(item[prop])
|
2009-11-21 23:55:14 +00:00
|
|
|
|
2009-11-19 18:22:21 +00:00
|
|
|
prop_ui = rna_idprop_ui_prop_get(item, prop)
|
2009-11-19 17:12:08 +00:00
|
|
|
|
|
|
|
if prop_type in (float, int):
|
2009-11-21 23:55:14 +00:00
|
|
|
|
2009-11-19 17:12:08 +00:00
|
|
|
prop_ui['soft_min'] = prop_ui['min'] = prop_type(self.properties.min)
|
|
|
|
prop_ui['soft_max'] = prop_ui['max'] = prop_type(self.properties.max)
|
2009-11-21 23:55:14 +00:00
|
|
|
|
2009-11-19 18:22:21 +00:00
|
|
|
prop_ui['description'] = self.properties.description
|
2009-11-21 23:55:14 +00:00
|
|
|
|
2009-12-24 19:50:43 +00:00
|
|
|
return {'FINISHED'}
|
2009-11-16 22:53:28 +00:00
|
|
|
|
2009-11-19 17:12:08 +00:00
|
|
|
def invoke(self, context, event):
|
2009-11-21 23:55:14 +00:00
|
|
|
|
2010-02-27 14:54:45 +00:00
|
|
|
self._last_prop = [self.properties.property]
|
2009-11-21 23:55:14 +00:00
|
|
|
|
2010-06-14 03:52:10 +00:00
|
|
|
item = eval("context.%s" % self.properties.data_path)
|
2009-11-21 23:55:14 +00:00
|
|
|
|
2009-11-19 17:12:08 +00:00
|
|
|
# setup defaults
|
|
|
|
prop_ui = rna_idprop_ui_prop_get(item, self.properties.property, False) # dont create
|
|
|
|
if prop_ui:
|
|
|
|
self.properties.min = prop_ui.get("min", -1000000000)
|
2009-12-04 17:54:48 +00:00
|
|
|
self.properties.max = prop_ui.get("max", 1000000000)
|
|
|
|
self.properties.description = prop_ui.get("description", "")
|
2009-11-21 23:55:14 +00:00
|
|
|
|
2009-11-19 17:12:08 +00:00
|
|
|
wm = context.manager
|
2009-12-07 00:16:57 +00:00
|
|
|
# This crashes, TODO - fix
|
|
|
|
#return wm.invoke_props_popup(self, event)
|
|
|
|
|
2009-11-19 17:12:08 +00:00
|
|
|
wm.invoke_props_popup(self, event)
|
2009-12-24 21:17:14 +00:00
|
|
|
return {'RUNNING_MODAL'}
|
2009-12-08 07:11:43 +00:00
|
|
|
|
2009-11-19 17:12:08 +00:00
|
|
|
|
2009-11-16 22:53:28 +00:00
|
|
|
class WM_OT_properties_add(bpy.types.Operator):
|
2010-06-14 03:52:10 +00:00
|
|
|
'''Internal use (edit a property data_path)'''
|
2009-11-16 22:53:28 +00:00
|
|
|
bl_idname = "wm.properties_add"
|
|
|
|
bl_label = "Add Property"
|
|
|
|
|
2010-06-14 03:52:10 +00:00
|
|
|
data_path = rna_path
|
2009-11-16 22:53:28 +00:00
|
|
|
|
|
|
|
def execute(self, context):
|
2010-06-14 03:52:10 +00:00
|
|
|
item = eval("context.%s" % self.properties.data_path)
|
2009-11-21 23:55:14 +00:00
|
|
|
|
2009-11-16 22:53:28 +00:00
|
|
|
def unique_name(names):
|
|
|
|
prop = 'prop'
|
|
|
|
prop_new = prop
|
|
|
|
i = 1
|
|
|
|
while prop_new in names:
|
|
|
|
prop_new = prop + str(i)
|
2009-12-04 17:54:48 +00:00
|
|
|
i += 1
|
2009-11-21 23:55:14 +00:00
|
|
|
|
2009-11-16 22:53:28 +00:00
|
|
|
return prop_new
|
2009-11-21 23:55:14 +00:00
|
|
|
|
2009-11-16 22:53:28 +00:00
|
|
|
property = unique_name(item.keys())
|
2009-11-21 23:55:14 +00:00
|
|
|
|
2009-11-16 22:53:28 +00:00
|
|
|
item[property] = 1.0
|
2009-12-24 19:50:43 +00:00
|
|
|
return {'FINISHED'}
|
2009-11-21 23:55:14 +00:00
|
|
|
|
2009-12-04 17:54:48 +00:00
|
|
|
|
2009-11-16 22:53:28 +00:00
|
|
|
class WM_OT_properties_remove(bpy.types.Operator):
|
2010-06-14 03:52:10 +00:00
|
|
|
'''Internal use (edit a property data_path)'''
|
2009-11-16 22:53:28 +00:00
|
|
|
bl_idname = "wm.properties_remove"
|
2010-05-10 01:49:35 +00:00
|
|
|
bl_label = "Remove Property"
|
2009-11-16 22:53:28 +00:00
|
|
|
|
2010-06-14 03:52:10 +00:00
|
|
|
data_path = rna_path
|
2009-11-16 22:53:28 +00:00
|
|
|
property = rna_property
|
|
|
|
|
|
|
|
def execute(self, context):
|
2010-06-14 03:52:10 +00:00
|
|
|
item = eval("context.%s" % self.properties.data_path)
|
2009-11-19 17:12:08 +00:00
|
|
|
del item[self.properties.property]
|
2009-12-24 19:50:43 +00:00
|
|
|
return {'FINISHED'}
|