diff --git a/classes/deck/deck.gd b/classes/deck/deck.gd index eba7a8c..468c856 100644 --- a/classes/deck/deck.gd +++ b/classes/deck/deck.gd @@ -175,6 +175,7 @@ func add_lib_group_node(type: String) -> DeckNode: lib.group_output_node = node._id continue group_node.init_io() + group_node.rename(NodeDB.get_library_descriptor(type).name) return group_node @@ -696,7 +697,7 @@ static func from_dict(data: Dictionary, path: String = "") -> Deck: group = DeckHolder.add_group_from_dict(group_data, group_id, group_instance_id, deck.id) else: group = DeckHolder.add_lib_instance( - node.group_id.get_file().trim_suffix(".deck"), + node.group_id.get_file(), deck.id, node.group_instance_id ) diff --git a/classes/deck/deck_holder.gd b/classes/deck/deck_holder.gd index a918eab..c1210cb 100644 --- a/classes/deck/deck_holder.gd +++ b/classes/deck/deck_holder.gd @@ -153,8 +153,8 @@ static func add_lib_instance(type: String, to_deck: String, instance_id: String var nd: NodeDB.NodeDescriptor = NodeDB.libraries[type] var path := nd.script_path var deck_data: Dictionary - if lib_groups.has(path): - deck_data = (lib_groups[path].values()[0] as Deck).to_dict() + if lib_groups.has(type): + deck_data = (lib_groups[type].values()[0] as Deck).to_dict() else: if not NodeDB.libraries.has(type): return null @@ -165,17 +165,17 @@ static func add_lib_instance(type: String, to_deck: String, instance_id: String deck_data = JSON.parse_string(f.get_as_text()) - var instances := lib_groups.get(path, {}) as Dictionary + var instances := lib_groups.get(type, {}) as Dictionary var deck := Deck.from_dict(deck_data) - deck.id = path + deck.id = type deck.instance_id = instance_id deck.is_group = true deck.is_library = true deck._belonging_to = to_deck instances[instance_id] = deck - lib_groups[path] = instances + lib_groups[type] = instances print_verbose("DeckHolder: added lib group %s::%s, id %s" % [deck.id, deck.instance_id, deck.get_instance_id()]) return deck @@ -296,20 +296,20 @@ static func pre_exit_cleanup() -> void: static func send_event(event_name: StringName, event_data: Dictionary = {}) -> void: for deck_id: String in decks: if decks[deck_id] is Deck: - var deck: Deck = (decks[deck_id] as Deck) + var deck: Deck = decks[deck_id] if not is_instance_valid(deck): continue deck.send_event(event_name, event_data) else: for deck_instance_id: String in decks[deck_id]: - var deck: Deck = (decks[deck_id][deck_instance_id] as Deck) + var deck: Deck = decks[deck_id][deck_instance_id] if not is_instance_valid(deck): continue deck.send_event(event_name, event_data) for lib_group_id: String in lib_groups: for lib_instance_id: String in lib_groups[lib_group_id]: - var deck: Deck = (lib_groups[lib_group_id][lib_instance_id] as Deck) + var deck: Deck = lib_groups[lib_group_id][lib_instance_id] if not is_instance_valid(deck): continue deck.send_event(event_name, event_data) diff --git a/classes/deck/node_db.gd b/classes/deck/node_db.gd index 6f0bc50..dda32d0 100644 --- a/classes/deck/node_db.gd +++ b/classes/deck/node_db.gd @@ -89,7 +89,7 @@ static func create_lib_descriptors(path: String) -> void: if not deck.deck.has("library"): current_file = dir.get_next() continue - var type := current_file.trim_suffix(".deck") + var type := current_file if nodes.has(type): DeckHolder.logger.toast_error("Library group '%s' collides with a node with the same type." % type) current_file = dir.get_next() @@ -113,7 +113,8 @@ static func create_lib_descriptors(path: String) -> void: true, true, ) - libraries[descriptor.type] = descriptor + descriptor.added_by_library = path + libraries[type] = descriptor current_file = dir.get_next() @@ -200,6 +201,10 @@ static func is_library(type: String) -> bool: return libraries.has(type) +static func get_library_descriptor(type: String) -> NodeDescriptor: + return libraries.get(type, null) as NodeDescriptor + + ## Returns a capitalized category string. static func get_category_capitalization(category: String) -> String: return CATEGORY_CAPITALIZATION.get(category, category.capitalize()) @@ -220,8 +225,10 @@ class NodeDescriptor: var category: String ## Whether this [DeckNode] reference will appear when searching. See [member DeckNode.appears_in_search]. var appears_in_search: bool - + ## Whether this describes a library group. var is_library: bool + ## If [member is_library] is [code]true[/code], this is the index that adds this library. + var added_by_library: String ## Stores the path to this node's script for later instantiation. var script_path: String @@ -258,6 +265,7 @@ class NodeDescriptor: "category": category, "appears_in_search": appears_in_search, "is_library": is_library, + "added_by_library": added_by_library, } return d @@ -274,5 +282,5 @@ class NodeDescriptor: data.get("appears_in_search", false), data.get("is_library", false) ) - + nd.added_by_library = data.get("added_by_library", "") return nd diff --git a/classes/deck/nodes/group/group_node.gd b/classes/deck/nodes/group/group_node.gd index e9bd452..2c02ad6 100644 --- a/classes/deck/nodes/group/group_node.gd +++ b/classes/deck/nodes/group/group_node.gd @@ -69,37 +69,41 @@ func make_unique() -> Deck: func setup_connections() -> void: - input_node.ports_updated.connect(recalculate_ports) - output_node.ports_updated.connect(recalculate_ports) + if input_node != null: + input_node.ports_updated.connect(recalculate_ports) + if output_node != null: + output_node.ports_updated.connect(recalculate_ports) func recalculate_ports() -> void: var _values := extra_port_values.duplicate() ports.clear() - for output_port: Port in output_node.get_input_ports().slice(0, output_node.get_input_ports().size() - 1): - var port := add_output_port( - output_port.type, - output_port.label, - output_port.descriptor, - output_port.usage_type, - ) - if _values.size() - 1 < port.index: - continue - - port.set_value(_values[port.index]) + if output_node != null: + for output_port: Port in output_node.get_input_ports().slice(0, output_node.get_input_ports().size() - 1): + var port := add_output_port( + output_port.type, + output_port.label, + output_port.descriptor, + output_port.usage_type, + ) + if _values.size() - 1 < port.index: + continue + + port.set_value(_values[port.index]) - for input_port: Port in input_node.get_output_ports().slice(0, input_node.get_output_ports().size() - 1): - var port := add_input_port( - input_port.type, - input_port.label, - input_port.descriptor, - input_port.usage_type, - ) - if _values.size() - 1 < port.index: - continue - - port.set_value(_values[port.index]) + if input_node != null: + for input_port: Port in input_node.get_output_ports().slice(0, input_node.get_output_ports().size() - 1): + var port := add_input_port( + input_port.type, + input_port.label, + input_port.descriptor, + input_port.usage_type, + ) + if _values.size() - 1 < port.index: + continue + + port.set_value(_values[port.index]) extra_ports.clear() extra_port_values.clear() diff --git a/graph_node_renderer/add_node_menu.gd b/graph_node_renderer/add_node_menu.gd index 0ce3fb1..ebd4ed1 100644 --- a/graph_node_renderer/add_node_menu.gd +++ b/graph_node_renderer/add_node_menu.gd @@ -40,17 +40,17 @@ func add_category(category_name: String) -> void: ## Add an item to a category. -func add_category_item(category: String, item: String, tooltip: String = "", favorite: bool = false, library: bool = false) -> void: +func add_category_item(category: String, item: String, type: String, tooltip: String = "", favorite: bool = false, library: bool = false) -> void: var c: Category = categories[category] - c.add_item(item, tooltip, favorite, library) + c.add_item(item, tooltip, type, favorite, library) ## Wrapper around [method add_category_item] and [method add_category]. Adds an item to a [param category], creating the category if it doesn't exist yet. -func add_item(category: String, item: String, tooltip: String = "", favorite: bool = false, library: bool = false) -> void: +func add_item(category: String, item: String, type: String, tooltip: String = "", favorite: bool = false, library: bool = false) -> void: if not categories.has(category): add_category(category) - add_category_item(category, item, tooltip, favorite, library) + add_category_item(category, item, type, tooltip, favorite, library) ## Get a [AddNodeMenu.Category] node by its' identifier. @@ -74,7 +74,7 @@ func search(text: String) -> void: return for nd in search_results: - add_item(nd.category, nd.name, nd.description, NodeDB.is_node_favorite(nd.type), nd.is_library) + add_item(nd.category, nd.name, nd.type, nd.description, NodeDB.is_node_favorite(nd.type), nd.is_library) var c := get_category(nd.category) c.set_item_metadata(c.get_item_count() - 1, "type", nd.type) c.set_item_metadata(c.get_item_count() - 1, "node_descriptor", weakref(nd)) @@ -231,8 +231,8 @@ class Category extends VBoxContainer: ## Add an item to the category. - func add_item(p_name: String, p_tooltip: String, p_favorite: bool = false, p_library: bool = false) -> void: - var item := CategoryItem.new(p_name, p_tooltip, p_favorite, p_library) + func add_item(p_name: String, p_tooltip: String, p_type: String, p_favorite: bool = false, p_library: bool = false) -> void: + var item := CategoryItem.new(p_name, p_tooltip, p_favorite, p_library, p_type) item.favorite_toggled.connect( func(toggled: bool): item_favorite_button_toggled.emit(item.get_index(), toggled) @@ -321,7 +321,7 @@ class CategoryItem extends HBoxContainer: signal favorite_toggled(toggled: bool) - func _init(p_name: String, p_tooltip: String, p_favorite: bool, p_library: bool) -> void: + func _init(p_name: String, p_tooltip: String, p_favorite: bool, p_library: bool, p_type: String) -> void: fav_button = Button.new() fav_button.icon = FAVORITE_ICON if p_favorite else NON_FAVORITE_ICON fav_button.toggle_mode = true @@ -358,11 +358,14 @@ class CategoryItem extends HBoxContainer: inner_hb.add_child(name_button) if p_library: + var nd := NodeDB.get_library_descriptor(p_type) group_texture_rect = TextureRect.new() group_texture_rect.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED group_texture_rect.custom_minimum_size = Vector2(12, 12) group_texture_rect.texture = GROUP_ICON group_texture_rect.tooltip_text = "This is a library group. It will create a group node." + group_texture_rect.tooltip_text += "\nAdded by %s" % nd.added_by_library + inner_hb.add_child(group_texture_rect) var m := MarginContainer.new() m.add_theme_constant_override(&"margin_right", 6) diff --git a/graph_node_renderer/deck_holder_renderer.gd b/graph_node_renderer/deck_holder_renderer.gd index 15fff0a..7ae6d70 100644 --- a/graph_node_renderer/deck_holder_renderer.gd +++ b/graph_node_renderer/deck_holder_renderer.gd @@ -324,7 +324,7 @@ func close_tab(tab: int) -> void: func open_save_dialog(path: String) -> void: file_dialog.file_mode = FileDialog.FILE_MODE_SAVE_FILE file_dialog.title = "Save a Deck" - file_dialog.current_path = path + file_dialog.current_path = path if not path.is_empty() else recent_path _deck_to_save = weakref(get_active_deck()) file_dialog.popup_centered() file_dialog.file_selected.connect(_on_file_dialog_save_file, CONNECT_ONE_SHOT) @@ -451,7 +451,8 @@ func save_tab(tab: int) -> void: var renderer := tab_container.get_content(tab) as DeckRendererGraphEdit var deck := renderer.deck if deck.save_path.is_empty(): - open_save_dialog("res://") + #open_save_dialog("res://") # what the fuck? + open_save_dialog(tab_container.get_tab_metadata(tab, "path", recent_path)) else: var json := JSON.stringify(deck.to_dict(), "\t") var f := FileAccess.open(deck.save_path, FileAccess.WRITE) @@ -485,7 +486,12 @@ func _on_deck_renderer_group_enter_requested(group_id: String) -> void: var deck_renderer: DeckRendererGraphEdit = DECK_SCENE.instantiate() deck_renderer.deck = group_deck deck_renderer.initialize_from_deck() - var tab := tab_container.add_content(deck_renderer, "(g) %s" % group_id.left(8)) + var title := "" + if group_deck.is_library: + title = "(L) %s" % group_deck.id + else: + title = "(G) %s" % group_id.left(8) + var tab := tab_container.add_content(deck_renderer, title) tab_container.set_tab_metadata(tab, "id", group_id) tab_container.set_tab_metadata(tab, "group", true) deck_renderer.group_enter_requested.connect(_on_deck_renderer_group_enter_requested) diff --git a/graph_node_renderer/sidebar/sidebar.gd b/graph_node_renderer/sidebar/sidebar.gd index f067469..6ad7368 100644 --- a/graph_node_renderer/sidebar/sidebar.gd +++ b/graph_node_renderer/sidebar/sidebar.gd @@ -136,6 +136,8 @@ func set_edited_node(id: String = "") -> void: static func create_menu(title: String, id: String, default_collapsed: bool = false) -> AccordionMenu: + if id.is_empty(): + id = title var res := AccordionMenu.new() res.set_title(title) res.collapsed = collapsed_menus.get(id, default_collapsed) @@ -190,14 +192,15 @@ class DeckInspector: ref = weakref(DeckHolder.get_deck(id)) var deck: Deck = ref.get_ref() as Deck - var lib_menu := AccordionMenu.new() - lib_menu.set_title("Library Group") + #var lib_menu := AccordionMenu.new() + #lib_menu.set_title("Library Group") + var lib_menu := Sidebar.create_menu("Library Group", "lib_group", true) var lib_group_text: String if deck.is_library: lib_group_text = "This deck is open as a library group. You may not edit it here.\nTo edit it, you have to open the file it's in." elif not deck.is_group: - lib_group_text = "You may save this deck as a Library Group to reuse it in future decks.\nYou may edit how it will appear." + lib_group_text = "You may save this deck as a Library Group to reuse it in future decks.\nYou may edit how it will appear in search results." else: lib_group_text = "This deck is a group." @@ -247,8 +250,9 @@ class GroupDescriptorsInspector: func _init(p_deck: Deck) -> void: deck = p_deck - menu = AccordionMenu.new() - menu.set_title("Group Inputs/Outputs") + #menu = AccordionMenu.new() + #menu.set_title("Group Inputs/Outputs") + menu = Sidebar.create_menu("Group Inputs/Outputs", "group_io", true) inputs_menu = Sidebar.create_menu("Inputs", "group_inputs", true) outputs_menu = Sidebar.create_menu("Outputs", "group_outputs", true) @@ -471,14 +475,15 @@ class NodeInspector: func add_port_menu(ports: Array[Port], node: DeckNode) -> void: if ports.is_empty(): return - var ports_menu := AccordionMenu.new() - ports_menu.draw_background = true var is_output := ports[0].port_type == DeckNode.PortType.OUTPUT - ports_menu.set_title("Output Ports" if is_output else "Input Ports") + var ports_menu := Sidebar.create_menu("Output Ports" if is_output else "Input Ports", "", false) + ports_menu.draw_background = true for port in ports: - var acc := AccordionMenu.new() + #var acc := AccordionMenu.new() + var id = "output_%s_menu" if is_output else "input_%s_menu" + var acc := Sidebar.create_menu("Port %s" % port.index_of_type, id % port.index_of_type, true) acc.draw_background = true - acc.set_title("Port %s" % port.index_of_type) + #acc.set_title("Port %s" % port.index_of_type) var label_label := DeckInspector.create_label("Name: %s" % port.label) acc.add_child(label_label) @@ -505,5 +510,4 @@ class NodeInspector: acc.add_child(port_hb) ports_menu.add_child(acc) - ports_menu.collapsed = true nodes.append(ports_menu)