Cleanup: pep8 & redundant vars
[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 is 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 is None:
53         return
54
55     try:
56         del rna_ui[prop]
57     except:
58         pass
59
60
61 def rna_idprop_context_value(context, context_member, property_type):
62     space = context.space_data
63
64     if space is None or isinstance(space, bpy.types.SpaceProperties):
65         pin_id = space.pin_id
66     else:
67         pin_id = None
68
69     if pin_id and isinstance(pin_id, property_type):
70         rna_item = pin_id
71         context_member = "space_data.pin_id"
72     else:
73         rna_item = eval("context." + context_member)
74
75     return rna_item, context_member
76
77
78 def rna_idprop_has_properties(rna_item):
79     keys = rna_item.keys()
80     nbr_props = len(keys)
81     return (nbr_props > 1) or (nbr_props and '_RNA_UI' not in keys)
82
83
84 def draw(layout, context, context_member, property_type, use_edit=True):
85
86     def assign_props(prop, val, key):
87         prop.data_path = context_member
88         prop.property = key
89
90         try:
91             prop.value = str(val)
92         except:
93             pass
94
95     rna_item, context_member = rna_idprop_context_value(context, context_member, property_type)
96
97     # poll should really get this...
98     if not rna_item:
99         return
100
101     from bpy.utils import escape_identifier
102
103     if rna_item.id_data.library is not None:
104         use_edit = False
105
106     assert(isinstance(rna_item, property_type))
107
108     items = rna_item.items()
109     items.sort()
110
111     if use_edit:
112         row = layout.row()
113         props = row.operator("wm.properties_add", text="Add")
114         props.data_path = context_member
115         del row
116
117     rna_properties = {prop.identifier for prop in rna_item.bl_rna.properties if prop.is_runtime} if items else None
118
119     for key, val in items:
120
121         if key == '_RNA_UI':
122             continue
123
124         row = layout.row()
125         to_dict = getattr(val, "to_dict", None)
126         to_list = getattr(val, "to_list", None)
127
128         # val_orig = val  # UNUSED
129         if to_dict:
130             val = to_dict()
131             val_draw = str(val)
132         elif to_list:
133             val = to_list()
134             val_draw = str(val)
135         else:
136             val_draw = val
137
138         box = row.box()
139
140         if use_edit:
141             split = box.split(percentage=0.75)
142             row = split.row()
143         else:
144             row = box.row()
145
146         row.label(text=key, translate=False)
147
148         # explicit exception for arrays
149         is_rna = (key in rna_properties)
150
151         if to_dict or to_list:
152             row.label(text=val_draw, translate=False)
153         else:
154             if is_rna:
155                 row.prop(rna_item, key, text="")
156             else:
157                 row.prop(rna_item, '["%s"]' % escape_identifier(key), text="")
158
159         if use_edit:
160             row = split.row(align=True)
161             if not is_rna:
162                 props = row.operator("wm.properties_edit", text="Edit")
163                 assign_props(props, val_draw, key)
164             else:
165                 row.label(text="API Defined")
166
167             props = row.operator("wm.properties_remove", text="", icon='ZOOMOUT')
168             assign_props(props, val_draw, key)
169
170
171 class PropertyPanel():
172     """
173     The subclass should have its own poll function
174     and the variable '_context_path' MUST be set.
175     """
176     bl_label = "Custom Properties"
177     bl_options = {'DEFAULT_CLOSED'}
178
179     @classmethod
180     def poll(cls, context):
181         rna_item, context_member = rna_idprop_context_value(context, cls._context_path, cls._property_type)
182         return bool(rna_item)
183
184     """
185     def draw_header(self, context):
186         rna_item, context_member = rna_idprop_context_value(context, self._context_path, self._property_type)
187         tot = len(rna_item.keys())
188         if tot:
189             self.layout().label("%d:" % tot)
190     """
191
192     def draw(self, context):
193         draw(self.layout, context, self._context_path, self._property_type)