Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'modules/extensions_framework/__init__.py')
-rw-r--r--modules/extensions_framework/__init__.py654
1 files changed, 327 insertions, 327 deletions
diff --git a/modules/extensions_framework/__init__.py b/modules/extensions_framework/__init__.py
index df815eb3..af909b45 100644
--- a/modules/extensions_framework/__init__.py
+++ b/modules/extensions_framework/__init__.py
@@ -33,339 +33,339 @@ bpy.utils.register_class(EF_OT_msg)
del EF_OT_msg
def log(str, popup=False, module_name='EF'):
- """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
- )
+ """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
+ )
added_property_cache = {}
def init_properties(obj, props, cache=True):
- """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:
- 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","options","subtype","update"]}
- elif prop['type'] == 'bool_vector':
- t = bpy.props.BoolVectorProperty
- a = {k: v for k,v in prop.items() if k in ["name",
- "description","default","options","subtype","size",
- "update"]}
- elif prop['type'] == 'collection':
- t = bpy.props.CollectionProperty
- a = {k: v for k,v in prop.items() if k in ["ptype","name",
- "description","default","options"]}
- 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","options","update"]}
- elif prop['type'] == 'float':
- t = bpy.props.FloatProperty
- a = {k: v for k,v in prop.items() if k in ["name",
- "description","default","min","max","soft_min","soft_max",
- "step","precision","options","subtype","unit","update"]}
- elif prop['type'] == 'float_vector':
- t = bpy.props.FloatVectorProperty
- a = {k: v for k,v in prop.items() if k in ["name",
- "description","default","min","max","soft_min","soft_max",
- "step","precision","options","subtype","size","update"]}
- elif prop['type'] == 'int':
- t = bpy.props.IntProperty
- a = {k: v for k,v in prop.items() if k in ["name",
- "description","default","min","max","soft_min","soft_max",
- "step","options","subtype","update"]}
- elif prop['type'] == 'int_vector':
- t = bpy.props.IntVectorProperty
- a = {k: v for k,v in prop.items() if k in ["name",
- "description","default","min","max","soft_min","soft_max",
- "options","subtype","size","update"]}
- elif prop['type'] == 'pointer':
- t = bpy.props.PointerProperty
- a = {k: v for k,v in prop.items() if k in ["ptype", "name",
- "description","options","update"]}
- 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","default","maxlen","options","subtype",
- "update"]}
- else:
- continue
-
- setattr(obj, prop['attr'], t(**a))
-
- added_property_cache[obj].append(prop['attr'])
- except KeyError:
- # Silently skip invalid entries in props
- continue
+ """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:
+ 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","options","subtype","update"]}
+ elif prop['type'] == 'bool_vector':
+ t = bpy.props.BoolVectorProperty
+ a = {k: v for k,v in prop.items() if k in ["name",
+ "description","default","options","subtype","size",
+ "update"]}
+ elif prop['type'] == 'collection':
+ t = bpy.props.CollectionProperty
+ a = {k: v for k,v in prop.items() if k in ["ptype","name",
+ "description","default","options"]}
+ 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","options","update"]}
+ elif prop['type'] == 'float':
+ t = bpy.props.FloatProperty
+ a = {k: v for k,v in prop.items() if k in ["name",
+ "description","default","min","max","soft_min","soft_max",
+ "step","precision","options","subtype","unit","update"]}
+ elif prop['type'] == 'float_vector':
+ t = bpy.props.FloatVectorProperty
+ a = {k: v for k,v in prop.items() if k in ["name",
+ "description","default","min","max","soft_min","soft_max",
+ "step","precision","options","subtype","size","update"]}
+ elif prop['type'] == 'int':
+ t = bpy.props.IntProperty
+ a = {k: v for k,v in prop.items() if k in ["name",
+ "description","default","min","max","soft_min","soft_max",
+ "step","options","subtype","update"]}
+ elif prop['type'] == 'int_vector':
+ t = bpy.props.IntVectorProperty
+ a = {k: v for k,v in prop.items() if k in ["name",
+ "description","default","min","max","soft_min","soft_max",
+ "options","subtype","size","update"]}
+ elif prop['type'] == 'pointer':
+ t = bpy.props.PointerProperty
+ a = {k: v for k,v in prop.items() if k in ["ptype", "name",
+ "description","options","update"]}
+ 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","default","maxlen","options","subtype",
+ "update"]}
+ else:
+ continue
+
+ setattr(obj, prop['attr'], t(**a))
+
+ added_property_cache[obj].append(prop['attr'])
+ except KeyError:
+ # Silently skip invalid entries in props
+ continue
class declarative_property_group(bpy.types.PropertyGroup):
- """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.
-
- The properties list attribute in this class describes the
- properties present in this group.
-
- 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.
-
- """
-
- ef_initialised = False
-
- """This property tells extensions_framework which bpy.type(s)
- to attach this PropertyGroup to. If left as an empty list,
- it will not be attached to any type, but its properties will
- still be initialised. The type(s) given in the list should be
- a string, such as 'Scene'.
-
- """
- ef_attach_to = []
-
- @classmethod
- def initialise_properties(cls):
- """This is a function that should be called on
- sub-classes of declarative_property_group in order
- to ensure that they are initialised when the addon
- is loaded.
- the init_properties is called without caching here,
- as it is assumed that any addon calling this function
- will also call ef_remove_properties when it is
- unregistered.
-
- """
-
- if not cls.ef_initialised:
- for property_group_parent in cls.ef_attach_to:
- if property_group_parent is not None:
- prototype = getattr(bpy.types, property_group_parent)
- if not hasattr(prototype, cls.__name__):
- init_properties(prototype, [{
- 'type': 'pointer',
- 'attr': cls.__name__,
- 'ptype': cls,
- 'name': cls.__name__,
- 'description': cls.__name__
- }], cache=False)
-
- init_properties(cls, cls.properties, cache=False)
- cls.ef_initialised = True
-
- return cls
-
- @classmethod
- def register_initialise_properties(cls):
- """As ef_initialise_properties, but also registers the
- class with RNA. Note that this isn't a great idea
- because it's non-trivial to unregister the class, unless
- you keep track of it yourself.
- """
-
- bpy.utils.register_class(cls)
- cls.initialise_properties()
- return cls
-
- @classmethod
- def remove_properties(cls):
- """This is a function that should be called on
- sub-classes of declarative_property_group in order
- to ensure that they are un-initialised when the addon
- is unloaded.
-
- """
-
- if cls.ef_initialised:
- prototype = getattr(bpy.types, cls.__name__)
- for prop in cls.properties:
- if hasattr(prototype, prop['attr']):
- delattr(prototype, prop['attr'])
-
- for property_group_parent in cls.ef_attach_to:
- if property_group_parent is not None:
- prototype = getattr(bpy.types, property_group_parent)
- if hasattr(prototype, cls.__name__):
- delattr(prototype, cls.__name__)
-
- cls.ef_initialised = False
-
- return cls
-
-
- """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 visibility of properties based on
- the value of other properties. See extensions_framework.validate
- for test syntax.
-
- """
- visibility = {}
-
- """The enabled dict controls the enabled state of properties based on
- the value of other properties. See extensions_framework.validate
- for test syntax.
-
- """
- enabled = {}
-
- """The alert dict controls the alert state of properties based on
- the value of other properties. See extensions_framework.validate
- for test syntax.
-
- """
- alert = {}
-
- """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
- }
-
- """
- properties = []
-
- def draw_callback(self, context):
- """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']:
- out.append(prop)
- return out
-
- def reset(self):
- """Reset all properties in this group to the default value,
- if specified"""
- for prop in self.properties:
- pk = prop.keys()
- if 'attr' in pk and 'default' in pk and hasattr(self, prop['attr']):
- setattr(self, prop['attr'], prop['default'])
+ """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.
+
+ The properties list attribute in this class describes the
+ properties present in this group.
+
+ 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.
+
+ """
+
+ ef_initialised = False
+
+ """This property tells extensions_framework which bpy.type(s)
+ to attach this PropertyGroup to. If left as an empty list,
+ it will not be attached to any type, but its properties will
+ still be initialised. The type(s) given in the list should be
+ a string, such as 'Scene'.
+
+ """
+ ef_attach_to = []
+
+ @classmethod
+ def initialise_properties(cls):
+ """This is a function that should be called on
+ sub-classes of declarative_property_group in order
+ to ensure that they are initialised when the addon
+ is loaded.
+ the init_properties is called without caching here,
+ as it is assumed that any addon calling this function
+ will also call ef_remove_properties when it is
+ unregistered.
+
+ """
+
+ if not cls.ef_initialised:
+ for property_group_parent in cls.ef_attach_to:
+ if property_group_parent is not None:
+ prototype = getattr(bpy.types, property_group_parent)
+ if not hasattr(prototype, cls.__name__):
+ init_properties(prototype, [{
+ 'type': 'pointer',
+ 'attr': cls.__name__,
+ 'ptype': cls,
+ 'name': cls.__name__,
+ 'description': cls.__name__
+ }], cache=False)
+
+ init_properties(cls, cls.properties, cache=False)
+ cls.ef_initialised = True
+
+ return cls
+
+ @classmethod
+ def register_initialise_properties(cls):
+ """As ef_initialise_properties, but also registers the
+ class with RNA. Note that this isn't a great idea
+ because it's non-trivial to unregister the class, unless
+ you keep track of it yourself.
+ """
+
+ bpy.utils.register_class(cls)
+ cls.initialise_properties()
+ return cls
+
+ @classmethod
+ def remove_properties(cls):
+ """This is a function that should be called on
+ sub-classes of declarative_property_group in order
+ to ensure that they are un-initialised when the addon
+ is unloaded.
+
+ """
+
+ if cls.ef_initialised:
+ prototype = getattr(bpy.types, cls.__name__)
+ for prop in cls.properties:
+ if hasattr(prototype, prop['attr']):
+ delattr(prototype, prop['attr'])
+
+ for property_group_parent in cls.ef_attach_to:
+ if property_group_parent is not None:
+ prototype = getattr(bpy.types, property_group_parent)
+ if hasattr(prototype, cls.__name__):
+ delattr(prototype, cls.__name__)
+
+ cls.ef_initialised = False
+
+ return cls
+
+
+ """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 visibility of properties based on
+ the value of other properties. See extensions_framework.validate
+ for test syntax.
+
+ """
+ visibility = {}
+
+ """The enabled dict controls the enabled state of properties based on
+ the value of other properties. See extensions_framework.validate
+ for test syntax.
+
+ """
+ enabled = {}
+
+ """The alert dict controls the alert state of properties based on
+ the value of other properties. See extensions_framework.validate
+ for test syntax.
+
+ """
+ alert = {}
+
+ """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
+ }
+
+ """
+ properties = []
+
+ def draw_callback(self, context):
+ """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']:
+ out.append(prop)
+ return out
+
+ def reset(self):
+ """Reset all properties in this group to the default value,
+ if specified"""
+ for prop in self.properties:
+ pk = prop.keys()
+ if 'attr' in pk and 'default' in pk and hasattr(self, prop['attr']):
+ setattr(self, prop['attr'], prop['default'])
class Addon(object):
- """A list of classes registered by this addon"""
- static_addon_count = 0
-
- addon_serial = 0
- addon_classes = None
- bl_info = None
-
- BL_VERSION = None
- BL_IDNAME = None
-
- def __init__(self, bl_info=None):
- self.addon_classes = []
- self.bl_info = bl_info
-
- # Keep a count in case we have to give this addon an anonymous name
- self.addon_serial = Addon.static_addon_count
- Addon.static_addon_count += 1
-
- if self.bl_info:
- self.BL_VERSION = '.'.join(['%s'%v for v in self.bl_info['version']]).lower()
- self.BL_IDNAME = self.bl_info['name'].lower() + '-' + self.BL_VERSION
- else:
- # construct anonymous name
- self.BL_VERSION = '0'
- self.BL_IDNAME = 'Addon-%03d'%self.addon_serial
-
- def addon_register_class(self, cls):
- """This method is designed to be used as a decorator on RNA-registerable
- classes defined by the addon. By using this decorator, this class will
- keep track of classes registered by this addon so that they can be
- unregistered later in the correct order.
-
- """
- self.addon_classes.append(cls)
- return cls
-
- def register(self):
- """This is the register function that should be exposed in the addon's
- __init__.
-
- """
- for cls in self.addon_classes:
- bpy.utils.register_class(cls)
- if hasattr(cls, 'ef_attach_to'): cls.initialise_properties()
-
- def unregister(self):
- """This is the unregister function that should be exposed in the addon's
- __init__.
-
- """
- for cls in self.addon_classes[::-1]: # unregister in reverse order
- if hasattr(cls, 'ef_attach_to'): cls.remove_properties()
- bpy.utils.unregister_class(cls)
-
- def init_functions(self):
- """Returns references to the three functions that this addon needs
- for successful class registration management. In the addon's __init__
- you would use like this:
-
- addon_register_class, register, unregister = Addon().init_functions()
-
- """
-
- return self.register, self.unregister
+ """A list of classes registered by this addon"""
+ static_addon_count = 0
+
+ addon_serial = 0
+ addon_classes = None
+ bl_info = None
+
+ BL_VERSION = None
+ BL_IDNAME = None
+
+ def __init__(self, bl_info=None):
+ self.addon_classes = []
+ self.bl_info = bl_info
+
+ # Keep a count in case we have to give this addon an anonymous name
+ self.addon_serial = Addon.static_addon_count
+ Addon.static_addon_count += 1
+
+ if self.bl_info:
+ self.BL_VERSION = '.'.join(['%s'%v for v in self.bl_info['version']]).lower()
+ self.BL_IDNAME = self.bl_info['name'].lower() + '-' + self.BL_VERSION
+ else:
+ # construct anonymous name
+ self.BL_VERSION = '0'
+ self.BL_IDNAME = 'Addon-%03d'%self.addon_serial
+
+ def addon_register_class(self, cls):
+ """This method is designed to be used as a decorator on RNA-registerable
+ classes defined by the addon. By using this decorator, this class will
+ keep track of classes registered by this addon so that they can be
+ unregistered later in the correct order.
+
+ """
+ self.addon_classes.append(cls)
+ return cls
+
+ def register(self):
+ """This is the register function that should be exposed in the addon's
+ __init__.
+
+ """
+ for cls in self.addon_classes:
+ bpy.utils.register_class(cls)
+ if hasattr(cls, 'ef_attach_to'): cls.initialise_properties()
+
+ def unregister(self):
+ """This is the unregister function that should be exposed in the addon's
+ __init__.
+
+ """
+ for cls in self.addon_classes[::-1]: # unregister in reverse order
+ if hasattr(cls, 'ef_attach_to'): cls.remove_properties()
+ bpy.utils.unregister_class(cls)
+
+ def init_functions(self):
+ """Returns references to the three functions that this addon needs
+ for successful class registration management. In the addon's __init__
+ you would use like this:
+
+ addon_register_class, register, unregister = Addon().init_functions()
+
+ """
+
+ return self.register, self.unregister