121 lines
4.9 KiB
Python
121 lines
4.9 KiB
Python
import json
|
|
from bpy_types import Operator, UIList
|
|
from bpy.props import (StringProperty, EnumProperty, PointerProperty, FloatVectorProperty, IntProperty)
|
|
|
|
from ..propGroups.conversions_from_prop_group import property_group_value_to_custom_property_value
|
|
|
|
class GENERIC_MAP_OT_actions(Operator):
|
|
"""Move items up and down, add and remove"""
|
|
bl_idname = "generic_map.map_action"
|
|
bl_label = "Map Actions"
|
|
bl_description = "Move items up and down, add and remove"
|
|
bl_options = {'REGISTER', 'UNDO'}
|
|
|
|
action: EnumProperty(
|
|
items=(
|
|
('UP', "Up", ""),
|
|
('DOWN', "Down", ""),
|
|
('REMOVE', "Remove", ""),
|
|
('ADD', "Add", ""))) # type: ignore
|
|
|
|
property_group_path: StringProperty(
|
|
name="property group path",
|
|
description="",
|
|
) # type: ignore
|
|
|
|
component_name: StringProperty(
|
|
name="component name",
|
|
description="",
|
|
) # type: ignore
|
|
|
|
target_index: IntProperty(name="target index", description="index of item to manipulate")# type: ignore
|
|
|
|
def invoke(self, context, event):
|
|
object = context.object
|
|
# information is stored in component meta
|
|
components_in_object = object.components_meta.components
|
|
component_meta = next(filter(lambda component: component["long_name"] == self.component_name, components_in_object), None)
|
|
|
|
propertyGroup = component_meta
|
|
for path_item in json.loads(self.property_group_path):
|
|
propertyGroup = getattr(propertyGroup, path_item)
|
|
|
|
keys_list = getattr(propertyGroup, "list")
|
|
index = getattr(propertyGroup, "list_index")
|
|
|
|
values_list = getattr(propertyGroup, "values_list")
|
|
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(keys_list) - 1:
|
|
#item_next = scn.rule_list[index + 1].name
|
|
keys_list.move(index, index + 1)
|
|
propertyGroup.list_index += 1
|
|
|
|
elif self.action == 'UP' and index >= 1:
|
|
#item_prev = scn.rule_list[index - 1].name
|
|
keys_list.move(index, index - 1)
|
|
propertyGroup.list_index -= 1
|
|
|
|
elif self.action == 'REMOVE':
|
|
index = self.target_index
|
|
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':
|
|
print("keys_list", keys_list)
|
|
|
|
# first we gather all key/value pairs
|
|
hashmap = {}
|
|
for index, key in enumerate(keys_list):
|
|
key_entry = {}
|
|
for field_name in key.field_names:
|
|
key_entry[field_name] = getattr(key, field_name, None)
|
|
value_entry = {}
|
|
for field_name in values_list[index].field_names:
|
|
value_entry[field_name] = values_list[index][field_name]
|
|
hashmap[json.dumps(key_entry)] = index
|
|
print("hashmap", hashmap )
|
|
|
|
# then we need to find the index of a specific value if it exists
|
|
key_entry = {}
|
|
for field_name in key_setter.field_names:
|
|
key_entry[field_name] = getattr(key_setter, field_name, None)
|
|
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:
|
|
val = getattr(key_setter, field_name, None)
|
|
if val is not None:
|
|
key[field_name] = val
|
|
# TODO: add error handling
|
|
|
|
value = values_list.add()
|
|
# copy the values over
|
|
for field_name in value_setter.field_names:
|
|
val = getattr(value_setter, field_name, None)
|
|
if val is not None:
|
|
value[field_name] = val
|
|
# TODO: add error handling
|
|
|
|
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)
|
|
#self.report({'INFO'}, info)
|
|
|
|
return {"FINISHED"} |