mirror of
https://github.com/kaosat-dev/Blender_bevy_components_workflow.git
synced 2024-11-26 05:26:42 +00:00
feat(bevy_components): fleshed out & refined hashmap UI & internals
This commit is contained in:
parent
cf87ace91f
commit
c14aeb7af2
@ -5,7 +5,7 @@ from bpy.props import (StringProperty, EnumProperty, PointerProperty, FloatVecto
|
|||||||
class GENERIC_MAP_OT_actions(Operator):
|
class GENERIC_MAP_OT_actions(Operator):
|
||||||
"""Move items up and down, add and remove"""
|
"""Move items up and down, add and remove"""
|
||||||
bl_idname = "generic_map.map_action"
|
bl_idname = "generic_map.map_action"
|
||||||
bl_label = "List Actions"
|
bl_label = "Map Actions"
|
||||||
bl_description = "Move items up and down, add and remove"
|
bl_description = "Move items up and down, add and remove"
|
||||||
bl_options = {'REGISTER', 'UNDO'}
|
bl_options = {'REGISTER', 'UNDO'}
|
||||||
|
|
||||||
@ -26,6 +26,8 @@ class GENERIC_MAP_OT_actions(Operator):
|
|||||||
description="",
|
description="",
|
||||||
) # type: ignore
|
) # type: ignore
|
||||||
|
|
||||||
|
target_index: IntProperty(name="target index", description="index of item to manipulate")# type: ignore
|
||||||
|
|
||||||
def invoke(self, context, event):
|
def invoke(self, context, event):
|
||||||
object = context.object
|
object = context.object
|
||||||
# information is stored in component meta
|
# information is stored in component meta
|
||||||
@ -36,33 +38,74 @@ class GENERIC_MAP_OT_actions(Operator):
|
|||||||
for path_item in json.loads(self.property_group_path):
|
for path_item in json.loads(self.property_group_path):
|
||||||
propertyGroup = getattr(propertyGroup, path_item)
|
propertyGroup = getattr(propertyGroup, path_item)
|
||||||
|
|
||||||
target_list = getattr(propertyGroup, "list")
|
keys_list = getattr(propertyGroup, "list")
|
||||||
index = getattr(propertyGroup, "list_index")
|
index = getattr(propertyGroup, "list_index")
|
||||||
|
|
||||||
values_list = getattr(propertyGroup, "values_list")
|
values_list = getattr(propertyGroup, "values_list")
|
||||||
values_index = getattr(propertyGroup, "values_list_index")
|
values_index = getattr(propertyGroup, "values_list_index")
|
||||||
|
|
||||||
|
key_setter = getattr(propertyGroup, "keys_setter")
|
||||||
|
value_setter = getattr(propertyGroup, "values_setter")
|
||||||
|
|
||||||
if self.action == 'DOWN' and index < len(target_list) - 1:
|
|
||||||
|
if self.action == 'DOWN' and index < len(keys_list) - 1:
|
||||||
#item_next = scn.rule_list[index + 1].name
|
#item_next = scn.rule_list[index + 1].name
|
||||||
target_list.move(index, index + 1)
|
keys_list.move(index, index + 1)
|
||||||
propertyGroup.list_index += 1
|
propertyGroup.list_index += 1
|
||||||
|
|
||||||
elif self.action == 'UP' and index >= 1:
|
elif self.action == 'UP' and index >= 1:
|
||||||
#item_prev = scn.rule_list[index - 1].name
|
#item_prev = scn.rule_list[index - 1].name
|
||||||
target_list.move(index, index - 1)
|
keys_list.move(index, index - 1)
|
||||||
propertyGroup.list_index -= 1
|
propertyGroup.list_index -= 1
|
||||||
|
|
||||||
elif self.action == 'REMOVE':
|
elif self.action == 'REMOVE':
|
||||||
target_list.remove(index)
|
index = self.target_index
|
||||||
propertyGroup.list_index = min(max(0, index - 1), len(target_list) - 1)
|
keys_list.remove(index)
|
||||||
|
values_list.remove(index)
|
||||||
|
propertyGroup.list_index = min(max(0, index - 1), len(keys_list) - 1)
|
||||||
|
propertyGroup.values_index = min(max(0, index - 1), len(keys_list) - 1)
|
||||||
|
|
||||||
if self.action == 'ADD':
|
if self.action == 'ADD':
|
||||||
key = target_list.add()
|
print("keys_list", keys_list)
|
||||||
value = values_list.add()
|
hashmap = {}
|
||||||
|
for index, key in enumerate(keys_list):
|
||||||
|
key_entry = {}
|
||||||
|
for field_name in key.field_names:
|
||||||
|
print("field name", field_name, key)
|
||||||
|
key_entry[field_name] = key[field_name]
|
||||||
|
value_entry = {}
|
||||||
|
for field_name in values_list[index].field_names:
|
||||||
|
value_entry[field_name] = values_list[index][field_name]
|
||||||
|
|
||||||
propertyGroup.list_index = index + 1 # we use this to force the change detection
|
hashmap[json.dumps(key_entry)] = index #{"value": json.dumps(value_entry), "index": index}
|
||||||
propertyGroup.values_index = index + 1 # we use this to force the change detection
|
print("hashmap", hashmap )
|
||||||
|
|
||||||
|
# we need to find the index of a specific value
|
||||||
|
key_entry = {}
|
||||||
|
for field_name in key_setter.field_names:
|
||||||
|
key_entry[field_name] = key_setter[field_name]
|
||||||
|
key_to_add = json.dumps(key_entry)
|
||||||
|
existing_index = hashmap.get(key_to_add, None)
|
||||||
|
print("existing_index", existing_index)
|
||||||
|
|
||||||
|
if existing_index is None:
|
||||||
|
print("adding new value")
|
||||||
|
key = keys_list.add()
|
||||||
|
# copy the values over
|
||||||
|
for field_name in key_setter.field_names:
|
||||||
|
key[field_name] = key_setter[field_name]
|
||||||
|
|
||||||
|
value = values_list.add()
|
||||||
|
# copy the values over
|
||||||
|
for field_name in value_setter.field_names:
|
||||||
|
value[field_name] = value_setter[field_name]
|
||||||
|
|
||||||
|
propertyGroup.list_index = index + 1 # we use this to force the change detection
|
||||||
|
propertyGroup.values_index = index + 1 # we use this to force the change detection
|
||||||
|
else:
|
||||||
|
print("overriding value")
|
||||||
|
for field_name in value_setter.field_names:
|
||||||
|
values_list[existing_index][field_name] = value_setter[field_name]
|
||||||
|
|
||||||
|
|
||||||
#info = '"%s" added to list' % (item.name)
|
#info = '"%s" added to list' % (item.name)
|
||||||
|
@ -85,55 +85,71 @@ def draw_propertyGroup( propertyGroup, layout, nesting =[], rootName=None):
|
|||||||
op.property_group_path = json.dumps(nesting)
|
op.property_group_path = json.dumps(nesting)
|
||||||
|
|
||||||
elif is_map:
|
elif is_map:
|
||||||
|
root = layout.row().column()
|
||||||
|
"""box = root.box()
|
||||||
|
box.label(text="test")
|
||||||
|
root.separator()
|
||||||
|
|
||||||
|
box = root.box()
|
||||||
|
box.label(text="test2")"""
|
||||||
|
|
||||||
keys_list = getattr(propertyGroup, "list")
|
keys_list = getattr(propertyGroup, "list")
|
||||||
values_list = getattr(propertyGroup, "values_list")
|
values_list = getattr(propertyGroup, "values_list")
|
||||||
box = layout.box()
|
box = root.box()
|
||||||
row = box.row()
|
row = box.row()
|
||||||
row.label(text="key")
|
row.label(text="Add entry:")
|
||||||
row.label(text="value")
|
keys_setter = getattr(propertyGroup, "keys_setter")
|
||||||
#values_setter = getattr(propertyGroup, "values_setter")
|
draw_propertyGroup(keys_setter, row, nesting, rootName)
|
||||||
# draw_propertyGroup(values_setter, row, nesting, rootName)
|
|
||||||
|
|
||||||
|
values_setter = getattr(propertyGroup, "values_setter")
|
||||||
|
draw_propertyGroup(values_setter, row, nesting, rootName)
|
||||||
|
|
||||||
|
op = row.operator('generic_map.map_action', icon='ADD', text="")
|
||||||
|
op.action = 'ADD'
|
||||||
|
op.component_name = rootName
|
||||||
|
op.property_group_path = json.dumps(nesting)
|
||||||
|
|
||||||
|
box = root.box()
|
||||||
split = box.split(factor=0.9)
|
split = box.split(factor=0.9)
|
||||||
list_column, buttons_column = (split.column(),split.column())
|
list_column, buttons_column = (split.column(),split.column())
|
||||||
list_column = list_column.box()
|
list_column = list_column.box()
|
||||||
|
|
||||||
for index, item in enumerate(keys_list):
|
for index, item in enumerate(keys_list):
|
||||||
row = list_column.row()
|
row = list_column.row()
|
||||||
#row.label(text=str(index))
|
|
||||||
draw_propertyGroup(item, row, nesting, rootName)
|
draw_propertyGroup(item, row, nesting, rootName)
|
||||||
|
|
||||||
value = values_list[index]
|
value = values_list[index]
|
||||||
draw_propertyGroup(value, row, nesting, rootName)
|
draw_propertyGroup(value, row, nesting, rootName)
|
||||||
|
|
||||||
|
op = row.operator('generic_map.map_action', icon='REMOVE', text="")
|
||||||
|
op.action = 'REMOVE'
|
||||||
|
op.component_name = rootName
|
||||||
|
op.property_group_path = json.dumps(nesting)
|
||||||
|
op.target_index = index
|
||||||
|
|
||||||
|
|
||||||
#various control buttons
|
#various control buttons
|
||||||
buttons_column.separator()
|
buttons_column.separator()
|
||||||
row = buttons_column.row()
|
row = buttons_column.row()
|
||||||
op = row.operator('generic_map.map_action', icon='ADD', text="")
|
|
||||||
op.action = 'ADD'
|
|
||||||
op.component_name = rootName
|
|
||||||
op.property_group_path = json.dumps(nesting)
|
|
||||||
|
|
||||||
row = buttons_column.row()
|
|
||||||
op = row.operator('generic_map.map_action', icon='REMOVE', text="")
|
|
||||||
op.action = 'REMOVE'
|
|
||||||
op.component_name = rootName
|
|
||||||
op.property_group_path = json.dumps(nesting)
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
for fname in field_names:
|
for fname in field_names:
|
||||||
subrow = layout.row()
|
#subrow = layout.row()
|
||||||
nestedPropertyGroup = getattr(propertyGroup, fname)
|
nestedPropertyGroup = getattr(propertyGroup, fname)
|
||||||
nested = getattr(nestedPropertyGroup, "nested", False)
|
nested = getattr(nestedPropertyGroup, "nested", False)
|
||||||
display_name = fname if propertyGroup.tupple_or_struct == "struct" else ""
|
display_name = fname if propertyGroup.tupple_or_struct == "struct" else ""
|
||||||
|
|
||||||
if nested:
|
if nested:
|
||||||
layout.separator()
|
layout.separator()
|
||||||
|
layout.separator()
|
||||||
|
|
||||||
layout.label(text=display_name) # this is the name of the field/sub field
|
layout.label(text=display_name) # this is the name of the field/sub field
|
||||||
layout.separator()
|
layout.separator()
|
||||||
draw_propertyGroup(nestedPropertyGroup, subrow.column(), nesting + [fname], rootName )
|
subrow = layout.row()
|
||||||
|
draw_propertyGroup(nestedPropertyGroup, subrow, nesting + [fname], rootName )
|
||||||
else:
|
else:
|
||||||
|
subrow = layout.row()
|
||||||
subrow.prop(propertyGroup, fname, text=display_name)
|
subrow.prop(propertyGroup, fname, text=display_name)
|
||||||
subrow.separator()
|
subrow.separator()
|
||||||
|
|
||||||
@ -226,8 +242,8 @@ class BEVY_COMPONENTS_PT_ComponentsPanel(bpy.types.Panel):
|
|||||||
# if the component has only 0 or 1 field names, display inline, otherwise change layout
|
# if the component has only 0 or 1 field names, display inline, otherwise change layout
|
||||||
single_field = len(propertyGroup.field_names) < 2
|
single_field = len(propertyGroup.field_names) < 2
|
||||||
prop_group_location = box.row(align=True).column()
|
prop_group_location = box.row(align=True).column()
|
||||||
if single_field:
|
"""if single_field:
|
||||||
prop_group_location = row.column(align=True)#.split(factor=0.9)#layout.row(align=False)
|
prop_group_location = row.column(align=True)#.split(factor=0.9)#layout.row(align=False)"""
|
||||||
|
|
||||||
if component_visible:
|
if component_visible:
|
||||||
if component_invalid:
|
if component_invalid:
|
||||||
|
@ -38,12 +38,10 @@ def property_group_value_to_custom_property_value(property_group, definition, re
|
|||||||
if is_value_type:
|
if is_value_type:
|
||||||
value = conversion_tables[type_name](value)
|
value = conversion_tables[type_name](value)
|
||||||
elif type_info == "Struct":
|
elif type_info == "Struct":
|
||||||
print("generating string for struct")
|
|
||||||
values = {}
|
values = {}
|
||||||
if len(property_group.field_names) ==0:
|
if len(property_group.field_names) ==0:
|
||||||
value = '()'
|
value = '()'
|
||||||
else:
|
else:
|
||||||
print("toto", type_def, definition, property_group)
|
|
||||||
for index, field_name in enumerate(property_group.field_names):
|
for index, field_name in enumerate(property_group.field_names):
|
||||||
item_type_name = definition["properties"][field_name]["type"]["$ref"].replace("#/$defs/", "")
|
item_type_name = definition["properties"][field_name]["type"]["$ref"].replace("#/$defs/", "")
|
||||||
item_definition = registry.type_infos[item_type_name] if item_type_name in registry.type_infos else None
|
item_definition = registry.type_infos[item_type_name] if item_type_name in registry.type_infos else None
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
from bpy.props import (StringProperty, IntProperty, CollectionProperty)
|
from bpy.props import (StringProperty, IntProperty, CollectionProperty)
|
||||||
|
from bpy.props import (PointerProperty)
|
||||||
from .utils import generate_wrapper_propertyGroup
|
from .utils import generate_wrapper_propertyGroup
|
||||||
from . import process_component
|
from . import process_component
|
||||||
|
|
||||||
@ -13,11 +14,9 @@ def process_map(registry, definition, update, nesting=[], nesting_long_names=[])
|
|||||||
nesting = nesting + [short_name]
|
nesting = nesting + [short_name]
|
||||||
nesting_long_names = nesting_long_names + [long_name]
|
nesting_long_names = nesting_long_names + [long_name]
|
||||||
|
|
||||||
#ref_name = definition["items"]["type"]["$ref"].replace("#/$defs/", "")
|
|
||||||
value_ref_name = definition["additionalProperties"]["type"]["$ref"].replace("#/$defs/", "")
|
value_ref_name = definition["additionalProperties"]["type"]["$ref"].replace("#/$defs/", "")
|
||||||
key_ref_name = long_name.split(',')[0].split('<')[1]# FIXME: hack !!!
|
key_ref_name = long_name.split(',')[0].split('<')[1]# FIXME: hack !!!
|
||||||
key_type = ''
|
|
||||||
value_type = ''
|
|
||||||
print("infos", short_name, "long name", long_name)
|
print("infos", short_name, "long name", long_name)
|
||||||
print("value ref", value_ref_name, "key ref", key_ref_name)
|
print("value ref", value_ref_name, "key ref", key_ref_name)
|
||||||
#print("definition", definition)
|
#print("definition", definition)
|
||||||
@ -33,12 +32,14 @@ def process_map(registry, definition, update, nesting=[], nesting_long_names=[])
|
|||||||
|
|
||||||
#if the content of the list is a unit type, we need to generate a fake wrapper, otherwise we cannot use layout.prop(group, "propertyName") as there is no propertyName !
|
#if the content of the list is a unit type, we need to generate a fake wrapper, otherwise we cannot use layout.prop(group, "propertyName") as there is no propertyName !
|
||||||
if is_value_value_type:
|
if is_value_value_type:
|
||||||
values_property_group_class = generate_wrapper_propertyGroup(long_name, original_type_name, definition_link, registry, update)
|
values_property_group_class = generate_wrapper_propertyGroup(f"{long_name}_keys", original_type_name, definition_link, registry, update)
|
||||||
else:
|
else:
|
||||||
(_, list_content_group_class) = process_component.process_component(registry, value_definition, update, {"nested": True, "type_name": original_type_name}, nesting)
|
(_, list_content_group_class) = process_component.process_component(registry, value_definition, update, {"nested": True, "type_name": original_type_name}, nesting, nesting_long_names)
|
||||||
values_property_group_class = list_content_group_class
|
values_property_group_class = list_content_group_class
|
||||||
|
|
||||||
values_collection = CollectionProperty(type=values_property_group_class)
|
values_collection = CollectionProperty(type=values_property_group_class)
|
||||||
|
values_property_group_pointer = PointerProperty(type=values_property_group_class)
|
||||||
|
|
||||||
|
|
||||||
if key_ref_name in type_infos:
|
if key_ref_name in type_infos:
|
||||||
key_definition = type_infos[key_ref_name]
|
key_definition = type_infos[key_ref_name]
|
||||||
@ -49,18 +50,25 @@ def process_map(registry, definition, update, nesting=[], nesting_long_names=[])
|
|||||||
|
|
||||||
#if the content of the list is a unit type, we need to generate a fake wrapper, otherwise we cannot use layout.prop(group, "propertyName") as there is no propertyName !
|
#if the content of the list is a unit type, we need to generate a fake wrapper, otherwise we cannot use layout.prop(group, "propertyName") as there is no propertyName !
|
||||||
if is_key_value_type:
|
if is_key_value_type:
|
||||||
keys_property_group_class = generate_wrapper_propertyGroup(long_name+'_values', original_type_name, definition_link, registry, update)
|
keys_property_group_class = generate_wrapper_propertyGroup(f"{long_name}_values", original_type_name, definition_link, registry, update)
|
||||||
else:
|
else:
|
||||||
(_, list_content_group_class) = process_component.process_component(registry, key_definition, update, {"nested": True, "type_name": original_type_name}, nesting)
|
(_, list_content_group_class) = process_component.process_component(registry, key_definition, update, {"nested": True, "type_name": original_type_name}, nesting, nesting_long_names)
|
||||||
keys_property_group_class = list_content_group_class
|
keys_property_group_class = list_content_group_class
|
||||||
|
|
||||||
keys_collection = CollectionProperty(type=keys_property_group_class)
|
keys_collection = CollectionProperty(type=keys_property_group_class)
|
||||||
|
keys_property_group_pointer = PointerProperty(type=keys_property_group_class)
|
||||||
|
|
||||||
|
|
||||||
__annotations__ = {
|
__annotations__ = {
|
||||||
"list": keys_collection,
|
"list": keys_collection,
|
||||||
"list_index": IntProperty(name = "Index for keys", default = 0, update=update),
|
"list_index": IntProperty(name = "Index for keys", default = 0, update=update),
|
||||||
|
"keys_setter":keys_property_group_pointer,
|
||||||
|
|
||||||
"values_list": values_collection,
|
"values_list": values_collection,
|
||||||
"values_list_index": IntProperty(name = "Index for values", default = 0, update=update),
|
"values_list_index": IntProperty(name = "Index for values", default = 0, update=update),
|
||||||
|
"values_setter":values_property_group_pointer,
|
||||||
|
"toto": {}
|
||||||
|
|
||||||
}
|
}
|
||||||
'''
|
'''
|
||||||
"values_setter": values_setter,
|
"values_setter": values_setter,
|
||||||
|
@ -14,10 +14,7 @@ def generate_wrapper_propertyGroup(wrapped_type_long_name_name, item_long_name,
|
|||||||
is_item_value_type = item_long_name in value_types_defaults
|
is_item_value_type = item_long_name in value_types_defaults
|
||||||
|
|
||||||
wrapper_name = "wrapper_" + wrapped_type_long_name_name
|
wrapper_name = "wrapper_" + wrapped_type_long_name_name
|
||||||
print("WRAPPER NAME", wrapper_name)
|
|
||||||
|
|
||||||
|
|
||||||
# FIXME: this is not a correct generic value for hashmaps !!?
|
|
||||||
wrapper_definition = {
|
wrapper_definition = {
|
||||||
"isComponent": False,
|
"isComponent": False,
|
||||||
"isResource": False,
|
"isResource": False,
|
||||||
|
Loading…
Reference in New Issue
Block a user