From 361de218cab3aa55bb81ee4d42446d8099ab6651 Mon Sep 17 00:00:00 2001 From: filmfreedom-org Date: Sat, 29 May 2021 01:44:21 -0500 Subject: [PATCH] prop_factory enum property tested/working. --- abx/prop_factory.py | 31 ++++++++++++------ tests/test_prop_factory.py | 65 +++++++++++++++++++++----------------- 2 files changed, 57 insertions(+), 39 deletions(-) diff --git a/abx/prop_factory.py b/abx/prop_factory.py index 01a8eec..0a6711e 100644 --- a/abx/prop_factory.py +++ b/abx/prop_factory.py @@ -21,6 +21,16 @@ import yaml def EnumFromList(schema, listname): return [(e, e.capitalize(), e.capitalize()) for e in schema[listname]] +def ExpandEnumList(schema, options): + blender_options = [] + for option in options: + if type(option) is str: + blender_options.append((option, option, option)) + elif isinstance(option, tuple) or isinstance(option, list): + option = tuple(option[0:3] + ([option[-1]]*(3-len(option)))) + blender_options.append(option) + return blender_options + class PropertyGroupFactory(bpy.types.PropertyGroup): """ Metadata property group factory for attachment to Blender object types. @@ -33,31 +43,32 @@ class PropertyGroupFactory(bpy.types.PropertyGroup): 'keywords': { 'name', 'description', 'default', 'maxlen', 'options', 'subtype'}, 'translate': { - 'desc': ('description', None)}}, + 'desc': (None, 'description', None)}}, 'enum': { 'property': bpy.props.EnumProperty, 'keywords': { 'items', 'name', 'description', 'default', 'options'}, 'translate': { - 'desc': ('description', None), - 'items_from': ('items', EnumFromList)}}, + 'desc': (None, 'description', None), + 'items_from': (EnumFromList, 'items'), + 'items': (ExpandEnumList, 'items')}}, 'int': { 'property': bpy.props.IntProperty, 'keywords': { 'name', 'description', 'default', 'min', 'max', 'soft_min', 'soft_max', 'step', 'options', 'subtype'}, 'translate': { - 'desc': ('description', None)}}, + 'desc': (None, 'description')}}, 'float': { 'property': bpy.props.FloatProperty, 'keywords': { 'name', 'description', 'default', 'min', 'max', 'soft_min', 'soft_max', 'step', 'options', 'subtype', 'precision', 'unit'}, 'translate': { - 'desc': ('description', None)}}, + 'desc': (None, 'description')}}, 'bool': { 'property': bpy.props.BoolProperty, 'keywords': { 'name', 'description', 'default', 'options', 'subtype'}, 'translate': { - 'desc': ('description', None)}} + 'desc': (None, 'description')}} } def __new__(cls, name, schema): @@ -74,13 +85,13 @@ class PropertyGroupFactory(bpy.types.PropertyGroup): filtered = {} for param in definition: if 'translate' in propmap and param in propmap['translate']: - translator = propmap['translate'][param][1] + translator = propmap['translate'][param][0] if callable(translator): - # Filtered translation - filtered[propmap['translate'][param][0]] = translator(schema, definition[param]) + # Filtered translation + filtered[propmap['translate'][param][1]] = translator(schema, definition[param]) else: # Simple translation - filtered[propmap['translate'][param][0]] = definition[param] + filtered[propmap['translate'][param][1]] = definition[param] else: filtered[param] = definition[param] diff --git a/tests/test_prop_factory.py b/tests/test_prop_factory.py index 7ef2230..6d142a4 100644 --- a/tests/test_prop_factory.py +++ b/tests/test_prop_factory.py @@ -75,6 +75,25 @@ class TestPropertyGroupFactory(unittest.TestCase): default: 'unknown' desc: An enumerated property using a list reference. + - code: enum_prop2 + name: MyEnum2 + type: enum + items: + - op1 + - op2 + - op3 + default: op1 + desc: An enumerated property using a direct list of strings. + + - code: enum_prop3 + name: MyEnum3 + items: + - op1 + - ('op2', 'Option2') + - ('op3', 'Option3', 'Option Three') + default: op1 + desc: An enumerated property using direct list with mixed types. + enum1_list: - unknown - option1 @@ -103,47 +122,35 @@ class TestPropertyGroupFactory(unittest.TestCase): bpy.context.scene.my_custom_property_group.prop1, 'default') - def test_creating_complex_sampler(self): + def test_creating_and_attaching_complex_sampler(self): schema = yaml.safe_load(io.StringIO(self.SAMPLER)) sampler = prop_factory.PropertyGroupFactory( 'sampler', schema) bpy.types.Scene.sampler = bpy.props.PointerProperty(type=sampler) - self.assertEqual( - bpy.context.scene.sampler.str_prop, 'str_prop') - - self.assertEqual( - bpy.context.scene.sampler.int_prop, 1) - - self.assertEqual( - bpy.context.scene.sampler.float_prop, 1.0) - - self.assertEqual( - bpy.context.scene.sampler.bool_prop, False) - - self.assertEqual( - bpy.context.scene.sampler.enum_prop1, 'unknown') + self.assertEqual(bpy.context.scene.sampler.str_prop, 'str_prop') + self.assertEqual(bpy.context.scene.sampler.int_prop, 1) + self.assertEqual(bpy.context.scene.sampler.float_prop, 1.0) + self.assertEqual(bpy.context.scene.sampler.bool_prop, False) + self.assertEqual(bpy.context.scene.sampler.enum_prop1, 'unknown') + self.assertEqual(bpy.context.scene.sampler.enum_prop2, 'op1') + self.assertEqual(bpy.context.scene.sampler.enum_prop3, 'op1') bpy.context.scene.sampler.str_prop = 'my string' bpy.context.scene.sampler.int_prop = 2 bpy.context.scene.sampler.float_prop = 0.7 bpy.context.scene.sampler.bool_prop = True bpy.context.scene.sampler.enum_prop1 = 'option1' + bpy.context.scene.sampler.enum_prop2 = 'op2' + bpy.context.scene.sampler.enum_prop3 = 'op3' - self.assertEqual( - bpy.context.scene.sampler.str_prop, 'my string') - - self.assertEqual( - bpy.context.scene.sampler.int_prop, 2) - - self.assertAlmostEqual( - bpy.context.scene.sampler.float_prop, 0.7) - - self.assertEqual( - bpy.context.scene.sampler.bool_prop, True) - - self.assertEqual( - bpy.context.scene.sampler.enum_prop1, 'option1') + self.assertEqual(bpy.context.scene.sampler.str_prop, 'my string') + self.assertEqual(bpy.context.scene.sampler.int_prop, 2) + self.assertAlmostEqual(bpy.context.scene.sampler.float_prop, 0.7) + self.assertEqual(bpy.context.scene.sampler.bool_prop, True) + self.assertEqual(bpy.context.scene.sampler.enum_prop1, 'option1') + self.assertEqual(bpy.context.scene.sampler.enum_prop2, 'op2') + self.assertEqual(bpy.context.scene.sampler.enum_prop3, 'op3')