# (c) 2023-present Eroax # (c) 2023-present Yagich # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) extends GraphNode class_name DeckNodeRendererGraphNode ## [GraphNode] based renderer of [DeckNode] ## Stores the data container [DeckNode] that the visuals of this [DeckNodeRendererGraphNode] ## are based off. var node: DeckNode const TYPE_COLORS := { DeckType.Types.BOOL: Color("#7048e0"), DeckType.Types.STRING: Color("#dbe048"), DeckType.Types.NUMERIC: Color("#68e36c"), DeckType.Types.ARRAY: Color("#e36868"), DeckType.Types.DICTIONARY: Color("#79ede3"), DeckType.Types.ANY: Color.WHITE, } const PORT_USAGE_ICONS := { Port.UsageType.TRIGGER: preload("res://graph_node_renderer/textures/port_trigger_12.svg"), Port.UsageType.VALUE_REQUEST: preload("res://graph_node_renderer/textures/port_data_request_12.svg"), Port.UsageType.BOTH: preload("res://graph_node_renderer/textures/port_any_12.svg"), } const DESCRIPTOR_SCENES := { "button": preload("res://graph_node_renderer/descriptors/button_descriptor.tscn"), "field": preload("res://graph_node_renderer/descriptors/field_descriptor.tscn"), "singlechoice": preload("res://graph_node_renderer/descriptors/single_choice_descriptor.tscn"), "codeblock": preload("res://graph_node_renderer/descriptors/codeblock_descriptor.tscn"), "checkbox": preload("res://graph_node_renderer/descriptors/check_box_descriptor.tscn"), "spinbox": preload("res://graph_node_renderer/descriptors/spin_box_descriptor.tscn"), "label": preload("res://graph_node_renderer/descriptors/label_descriptor.tscn"), } ## Setups up all the properties based off [member node]. Including looping through ## [method DeckNode.get_all_ports()] and setting up all the descriptors. func _ready() -> void: title = node.name node.position_updated.connect(_on_node_position_updated) resize_request.connect(_on_resize_request) #node.port_added.connect(_on_node_port_added) #node.port_removed.connect(_on_node_port_removed) node.ports_updated.connect(_on_node_ports_updated) for port in node.get_all_ports(): update_port(port) position_offset_changed.connect(_on_position_offset_changed) node.renamed.connect(_on_node_renamed) if node.node_type == "group_node": get_titlebar_hbox().tooltip_text = "Group %s" % node.group_id.left(8) if get_child_count() == 0: create_group_help_text() size = node.get_meta("size", Vector2()) ## Connected to [signal GraphElement.position_offset_updated] and updates the ## [member node]s properties func _on_position_offset_changed() -> void: node.position.x = position_offset.x node.position.y = position_offset.y node.position_updated.emit(node.position) (get_parent() as DeckRendererGraphEdit).dirty = true ## Connected to [member node]s [signal position_updated] to keep parity with the ## data position. func _on_node_position_updated(new_position: Dictionary) -> void: position_offset_changed.disconnect(_on_position_offset_changed) position_offset.x = new_position.x position_offset.y = new_position.y position_offset_changed.connect(_on_position_offset_changed) (get_parent() as DeckRendererGraphEdit).dirty = true func _on_resize_request(new_minsize: Vector2) -> void: node.set_meta(&"size", new_minsize) (get_parent() as DeckRendererGraphEdit).dirty = true ## Connected to [member node]s [signal port_added] handles setting up the specified ## [member Port.descriptor] with it's required nodes/signals etc. + adding the port ## using [method GraphNode.set_slot] func _on_node_port_added(port_idx: int) -> void: var port := node.get_all_ports()[port_idx] update_port(port) ## Connected to [member node]s [signal port_removed], queue_frees the [Node] ## used for the descriptor, as well as using [method GraphNode.set_slot] to remove the slot. func _on_node_port_removed(port_idx: int) -> void: set_slot( port_idx, false, 0, Color.WHITE, false, 0, Color.WHITE, ) get_child(port_idx).queue_free() ## Connected to [member node]s [signal ports_updated]. Remakes all of the ports ## + their descriptors whenever this is received to allow keeping the Renderers ports up to date. func _on_node_ports_updated() -> void: clear_all_slots() for c in get_children(): c.queue_free() for port in node.get_all_ports(): update_port(port) if get_child_count() == 0: create_group_help_text() await get_tree().process_frame size = Vector2() func _on_node_renamed(new_name: String) -> void: title = new_name func create_group_help_text() -> void: var l := Label.new() l.text = RendererShortcuts.interpolate_string("This group node has no used ports.\nPress {enter_group} to enter and edit it to see changes reflected.") add_child(l) func update_port(port: Port) -> void: var descriptor_split := port.descriptor.split(":") var d: DescriptorContainer if DESCRIPTOR_SCENES.has(descriptor_split[0]): d = DESCRIPTOR_SCENES[descriptor_split[0]].instantiate() else: d = DESCRIPTOR_SCENES.label.instantiate() add_child(d) d.set_up_from_port(port, node) set_slot( port.index, port.port_type == DeckNode.PortType.INPUT, port.type, TYPE_COLORS[port.type], port.port_type == DeckNode.PortType.OUTPUT, port.type, TYPE_COLORS[port.type], PORT_USAGE_ICONS[port.usage_type], PORT_USAGE_ICONS[port.usage_type], )