poll() as a python '@staticmethod' was too limiting and didnt allow useful base class...
[blender.git] / release / scripts / modules / rna_prop_ui.py
1 # ##### BEGIN GPL LICENSE BLOCK #####
2 #
3 #  This program is free software; you can redistribute it and/or
4 #  modify it under the terms of the GNU General Public License
5 #  as published by the Free Software Foundation; either version 2
6 #  of the License, or (at your option) any later version.
7 #
8 #  This program is distributed in the hope that it will be useful,
9 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 #  GNU General Public License for more details.
12 #
13 #  You should have received a copy of the GNU General Public License
14 #  along with this program; if not, write to the Free Software Foundation,
15 #  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 #
17 # ##### END GPL LICENSE BLOCK #####
18
19 # <pep8 compliant>
20
21 import bpy
22
23
24 def rna_idprop_ui_get(item, create=True):
25     try:
26         return item['_RNA_UI']
27     except:
28         if create:
29             item['_RNA_UI'] = {}
30             return item['_RNA_UI']
31         else:
32             return None
33
34
35 def rna_idprop_ui_prop_get(item, prop, create=True):
36
37     rna_ui = rna_idprop_ui_get(item, create)
38
39     if rna_ui == None:
40         return None
41
42     try:
43         return rna_ui[prop]
44     except:
45         rna_ui[prop] = {}
46         return rna_ui[prop]
47
48
49 def rna_idprop_ui_prop_clear(item, prop):
50     rna_ui = rna_idprop_ui_get(item, False)
51
52     if rna_ui == None:
53         return
54
55     try:
56         del rna_ui[prop]
57     except:
58         pass
59
60
61 def draw(layout, context, context_member, use_edit=True):
62
63     def assign_props(prop, val, key):
64         prop.data_path = context_member
65         prop.property = key
66
67         try:
68             prop.value = str(val)
69         except:
70             pass
71
72     rna_item = eval("context." + context_member)
73
74     # poll should really get this...
75     if not rna_item:
76         return
77
78     items = rna_item.items()
79     items.sort()
80
81     if use_edit:
82         row = layout.row()
83         props = row.operator("wm.properties_add", text="Add")
84         props.data_path = context_member
85         del row
86
87     for key, val in items:
88
89         if key == '_RNA_UI':
90             continue
91
92         row = layout.row()
93         convert_to_pyobject = getattr(val, "convert_to_pyobject", None)
94
95         val_orig = val
96         if convert_to_pyobject:
97             val_draw = val = val.convert_to_pyobject()
98             val_draw = str(val_draw)
99         else:
100             val_draw = val
101
102         box = row.box()
103
104         if use_edit:
105             split = box.split(percentage=0.75)
106             row = split.row()
107         else:
108             row = box.row()
109
110         row.label(text=key)
111
112         # explicit exception for arrays
113         if convert_to_pyobject and not hasattr(val_orig, "len"):
114             row.label(text=val_draw)
115         else:
116             row.prop(rna_item, '["%s"]' % key, text="")
117
118         if use_edit:
119             row = split.row(align=True)
120             prop = row.operator("wm.properties_edit", text="edit")
121             assign_props(prop, val_draw, key)
122
123             prop = row.operator("wm.properties_remove", text="", icon='ZOOMOUT')
124             assign_props(prop, val_draw, key)
125
126
127 class PropertyPanel():
128     """
129     The subclass should have its own poll function
130     and the variable '_context_path' MUST be set.
131     """
132     bl_label = "Custom Properties"
133     bl_default_closed = True
134
135     @classmethod
136     def poll(cls, context):
137         bool(eval("context.%s" % cls._context_path))
138
139     def draw(self, context):
140         draw(self.layout, context, self._context_path)
141