1 # ##### BEGIN GPL LICENSE BLOCK #####
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.
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.
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 # ##### END GPL LICENSE BLOCK #####
24 def rna_idprop_ui_get(item, create=True):
26 return item['_RNA_UI']
30 return item['_RNA_UI']
35 def rna_idprop_ui_prop_get(item, prop, create=True):
37 rna_ui = rna_idprop_ui_get(item, create)
49 def rna_idprop_ui_prop_clear(item, prop):
50 rna_ui = rna_idprop_ui_get(item, False)
61 def draw(layout, context, context_member, use_edit=True):
63 def assign_props(prop, val, key):
64 prop.path = context_member
72 rna_item = eval("context." + context_member)
74 # poll should really get this...
78 items = rna_item.items()
83 props = row.operator("wm.properties_add", text="Add")
84 props.path = context_member
87 for key, val in items:
93 convert_to_pyobject = getattr(val, "convert_to_pyobject", None)
96 if convert_to_pyobject:
97 val_draw = val = val.convert_to_pyobject()
98 val_draw = str(val_draw)
105 split = box.split(percentage=0.75)
112 # explicit exception for arrays
113 if convert_to_pyobject and not hasattr(val_orig, "len"):
114 row.label(text=val_draw)
116 row.prop(rna_item, '["%s"]' % key, text="")
119 row = split.row(align=True)
120 prop = row.operator("wm.properties_edit", text="edit")
121 assign_props(prop, val_draw, key)
123 prop = row.operator("wm.properties_remove", text="", icon='ICON_ZOOMOUT')
124 assign_props(prop, val_draw, key)
127 from bpy.props import *
130 rna_path = StringProperty(name="Property Edit",
131 description="Property path edit", maxlen=1024, default="", hidden=True)
133 rna_value = StringProperty(name="Property Value",
134 description="Property value edit", maxlen=1024, default="")
136 rna_property = StringProperty(name="Property Name",
137 description="Property name edit", maxlen=1024, default="")
139 rna_min = FloatProperty(name="Min", default=0.0, precision=3)
140 rna_max = FloatProperty(name="Max", default=1.0, precision=3)
143 class WM_OT_properties_edit(bpy.types.Operator):
144 '''Internal use (edit a property path)'''
145 bl_idname = "wm.properties_edit"
146 bl_label = "Edit Property!"
149 property = rna_property
153 description = StringProperty(name="Tip", default="")
155 # the class instance is not persistant, need to store in the class
156 # not ideal but changes as the op runs.
159 def execute(self, context):
160 path = self.properties.path
161 value = self.properties.value
162 prop = self.properties.property
163 prop_old = self._last_prop[0]
166 value_eval = eval(value)
170 if type(value_eval) == str:
171 value_eval = '"' + value_eval + '"'
174 item = eval("context.%s" % path)
176 rna_idprop_ui_prop_clear(item, prop_old)
177 exec_str = "del item['%s']" % prop_old
183 exec_str = "item['%s'] = %s" % (prop, value_eval)
186 self._last_prop[:] = [prop]
188 prop_type = type(item[prop])
190 prop_ui = rna_idprop_ui_prop_get(item, prop)
192 if prop_type in (float, int):
194 prop_ui['soft_min'] = prop_ui['min'] = prop_type(self.properties.min)
195 prop_ui['soft_max'] = prop_ui['max'] = prop_type(self.properties.max)
197 prop_ui['description'] = self.properties.description
201 def invoke(self, context, event):
203 self._last_prop[:] = [self.properties.property]
205 item = eval("context.%s" % self.properties.path)
208 prop_ui = rna_idprop_ui_prop_get(item, self.properties.property, False) # dont create
210 self.properties.min = prop_ui.get("min", -1000000000)
211 self.properties.max = prop_ui.get("max", 1000000000)
212 self.properties.description = prop_ui.get("description", "")
215 _message = "PyConsole, press Ctrl+D to unlock the BGE"
218 # evaluate commands in current namespace
219 frame = sys._getframe()
220 namespace = frame.f_globals.copy()
221 namespace.update(frame.f_locals)
225 # Autocomp in python, not as comprehensive as IPython
228 try: # ick, some pythons dont have this
230 readline.parse_and_bind("tab: complete")
234 code.interact(banner=_message, local=namespace)
237 wm.invoke_props_popup(self, event)
238 return ('RUNNING_MODAL',)
241 class WM_OT_properties_add(bpy.types.Operator):
242 '''Internal use (edit a property path)'''
243 bl_idname = "wm.properties_add"
244 bl_label = "Add Property"
248 def execute(self, context):
249 item = eval("context.%s" % self.properties.path)
251 def unique_name(names):
255 while prop_new in names:
256 prop_new = prop + str(i)
261 property = unique_name(item.keys())
267 class WM_OT_properties_remove(bpy.types.Operator):
268 '''Internal use (edit a property path)'''
269 bl_idname = "wm.properties_remove"
270 bl_label = "Add Property"
273 property = rna_property
275 def execute(self, context):
276 item = eval("context.%s" % self.properties.path)
277 del item[self.properties.property]