extensions_framework: lots of docs and code formatting to be more pep8-like

This commit is contained in:
2010-11-17 21:28:22 +00:00
parent b99a11bc3c
commit 9183f20fb4
7 changed files with 385 additions and 226 deletions

View File

@@ -24,131 +24,170 @@
#
# ***** END GPL LICENCE BLOCK *****
#
import time
import os, time
import bpy
#----------------------------------------------------------------------------------------------------------------------
from extensions_framework.ui import EF_OT_msg
bpy.types.register(EF_OT_msg)
del EF_OT_msg
def log(str, popup=False, module_name='EF'):
print("[%s %s] %s" % (module_name, time.strftime('%Y-%b-%d %H:%M:%S'), str))
"""Print a message to the console, prefixed with the module_name
and the current time. If the popup flag is True, the message will
be raised in the UI as a warning using the operator bpy.ops.ef.msg.
"""
print("[%s %s] %s" %
(module_name, time.strftime('%Y-%b-%d %H:%M:%S'), str))
if popup:
bpy.ops.ef.msg(
msg_type='WARNING',
msg_text=str
)
#----------------------------------------------------------------------------------------------------------------------
from .ui import EF_OT_msg
bpy.types.register(EF_OT_msg)
ef_path = os.path.realpath( os.path.dirname(__file__) )
# log('Extensions_Framework detected and loaded from %s'%ef_path)
del EF_OT_msg, os
#----------------------------------------------------------------------------------------------------------------------
class ef(object):
'''
Extensions Framework base class
'''
added_property_cache = {}
added_property_cache = {}
def init_properties(obj, props, cache=True):
if not obj in ef.added_property_cache.keys():
ef.added_property_cache[obj] = []
"""Initialise custom properties in the given object or type.
The props list is described in the declarative_property_group
class definition. If the cache flag is False, this function
will attempt to redefine properties even if they have already been
added.
"""
if not obj in added_property_cache.keys():
added_property_cache[obj] = []
for prop in props:
if cache and prop['attr'] in ef.added_property_cache[obj]:
continue
try:
if cache and prop['attr'] in added_property_cache[obj]:
continue
if prop['type'] == 'bool':
t = bpy.props.BoolProperty
a = {k: v for k,v in prop.items() if k in ['name','description','default']}
a = {k: v for k,v in prop.items() if k in ['name',
'description','default']}
elif prop['type'] == 'collection':
t = bpy.props.CollectionProperty
a = {k: v for k,v in prop.items() if k in ["ptype", "name", "description"]}
a = {k: v for k,v in prop.items() if k in ["ptype", "name",
"description"]}
a['type'] = a['ptype']
del a['ptype']
elif prop['type'] == 'enum':
t = bpy.props.EnumProperty
a = {k: v for k,v in prop.items() if k in ["items", "name", "description", "default"]}
a = {k: v for k,v in prop.items() if k in ["items", "name",
"description", "default"]}
elif prop['type'] == 'float':
t = bpy.props.FloatProperty
a = {k: v for k,v in prop.items() if k in ["name", "description", "min", "max", "soft_min", "soft_max", "default", "precision"]}
a = {k: v for k,v in prop.items() if k in ["name",
"description", "min", "max", "soft_min", "soft_max",
"default", "precision"]}
elif prop['type'] == 'float_vector':
t = bpy.props.FloatVectorProperty
a = {k: v for k,v in prop.items() if k in ["name", "description", "min", "max", "soft_min", "soft_max", "default", "precision", "size", "subtype"]}
a = {k: v for k,v in prop.items() if k in ["name",
"description", "min", "max", "soft_min", "soft_max",
"default", "precision", "size", "subtype"]}
elif prop['type'] == 'int':
t = bpy.props.IntProperty
a = {k: v for k,v in prop.items() if k in ["name", "description", "min", "max", "soft_min", "soft_max", "default"]}
a = {k: v for k,v in prop.items() if k in ["name",
"description", "min", "max", "soft_min", "soft_max",
"default"]}
elif prop['type'] == 'pointer':
t = bpy.props.PointerProperty
a = {k: v for k,v in prop.items() if k in ["ptype", "name", "description"]}
a = {k: v for k,v in prop.items() if k in ["ptype", "name",
"description"]}
a['type'] = a['ptype']
del a['ptype']
elif prop['type'] == 'string':
t = bpy.props.StringProperty
a = {k: v for k,v in prop.items() if k in ["name", "description", "maxlen", "default", "subtype"]}
a = {k: v for k,v in prop.items() if k in ["name",
"description", "maxlen", "default", "subtype"]}
else:
#ef.log('Property type not recognised: %s' % prop['type'])
continue
setattr(obj, prop['attr'], t(**a))
ef.added_property_cache[obj].append(prop['attr'])
#log('Created property %s.%s' % (obj, prop['attr']))
added_property_cache[obj].append(prop['attr'])
except KeyError:
# Silently skip invalid entries in props
continue
class declarative_property_group(bpy.types.IDPropertyGroup):
"""A declarative_property_group describes a set of logically
related properties, using a declarative style to list each
property type, name, values, and other relevant information.
The information provided for each property depends on the
property's type.
controls = [
# this list controls the order of property
# layout when rendered by a property_group_renderer.
# This can be a nested list, where each list
# becomes a row in the panel layout.
# nesting may be to any depth
]
The properties list attribute in this class describes the
properties present in this group.
# Include some properties in display based on values of others
visibility = {
# See ef.validate for test syntax
Some additional information about the properties in this group
can be specified, so that a UI can be generated to display them.
To that end, the controls list attribute and the visibility dict
attribute are present here, to be read and interpreted by a
property_group_renderer object.
See extensions_framework.ui.property_group_renderer.
"""
"""This list controls the order of property layout when rendered
by a property_group_renderer. This can be a nested list, where each
list becomes a row in the panel layout. Nesting may be to any depth.
"""
controls = []
"""The visibility dict controls the display of properties based on
the value of other properties. See extensions_framework.validate
for test syntax.
"""
visibility = {}
"""The properties list describes each property to be created. Each
item should be a dict of args to pass to a
bpy.props.<?>Property function, with the exception of 'type'
which is used and stripped by extensions_framework in order to
determine which Property creation function to call.
Example item:
{
'type': 'int', # bpy.props.IntProperty
'attr': 'threads', # bpy.types.<type>.threads
'name': 'Render Threads', # Rendered next to the UI
'description': 'Number of threads to use', # Tooltip text in the UI
'default': 1,
'min': 1,
'soft_min': 1,
'max': 64,
'soft_max': 64
}
# engine-specific properties to create in the scene.
# Each item should be a dict of args to pass to a
# bpy.types.Scene.<?>Property function, with the exception
# of 'type' which is used and stripped by ef
properties = [
# example:
#{
# 'type': 'int',
# 'attr': 'threads',
# 'name': 'Render Threads',
# 'description': 'Number of threads to use',
# 'default': 1,
# 'min': 1,
# 'soft_min': 1,
# 'max': 64,
# 'soft_max': 64
#},
]
"""
properties = []
def draw_callback(self, context):
'''
Sub-classes can override this to get a callback
when rendered by a property_group_renderer class
'''
"""Sub-classes can override this to get a callback when
rendering is completed by a property_group_renderer sub-class.
"""
pass
@classmethod
def get_exportable_properties(cls):
"""Return a list of properties which have the 'save_in_preset' key
set to True, and hence should be saved into preset files.
"""
out = []
for prop in cls.properties:
if 'save_in_preset' in prop.keys() and prop['save_in_preset']: