2018-07-22 17:20:27 +02:00
|
|
|
extends GraphEdit
|
2019-10-07 20:41:57 +02:00
|
|
|
class_name MMGraphEdit
|
2018-07-22 17:20:27 +02:00
|
|
|
|
2018-09-04 21:45:14 +02:00
|
|
|
var editor_interface = null
|
2018-10-13 17:31:37 +02:00
|
|
|
var node_factory = null
|
2018-09-04 21:45:14 +02:00
|
|
|
|
2019-08-12 15:58:42 +02:00
|
|
|
var save_path = null setget set_save_path
|
2018-08-09 22:19:27 +02:00
|
|
|
var need_save = false
|
2018-08-05 18:46:23 +02:00
|
|
|
|
2019-09-19 07:56:32 +02:00
|
|
|
var top_generator = null
|
2019-08-12 15:58:42 +02:00
|
|
|
var generator = null
|
|
|
|
|
2019-12-27 22:30:49 +01:00
|
|
|
var last_selected = null
|
|
|
|
|
2020-02-01 08:35:00 +01:00
|
|
|
onready var node_popup = $"../AddNodePopup"
|
|
|
|
|
2019-10-20 11:33:33 +02:00
|
|
|
onready var timer : Timer = $Timer
|
|
|
|
|
|
|
|
onready var subgraph_ui : HBoxContainer = $GraphUI/SubGraphUI
|
2019-11-04 07:58:17 +01:00
|
|
|
onready var button_transmits_seed : Button = $GraphUI/SubGraphUI/ButtonTransmitsSeed
|
2019-10-20 11:33:33 +02:00
|
|
|
|
2018-08-05 18:46:23 +02:00
|
|
|
signal save_path_changed
|
2018-07-28 09:37:51 +02:00
|
|
|
signal graph_changed
|
|
|
|
|
2019-10-20 16:22:06 +02:00
|
|
|
func _ready() -> void:
|
2018-08-12 19:25:18 +02:00
|
|
|
OS.low_processor_usage_mode = true
|
2018-08-22 07:33:50 +02:00
|
|
|
center_view()
|
2020-01-28 22:40:03 +01:00
|
|
|
for t in range(41):
|
2019-12-25 10:36:45 +01:00
|
|
|
add_valid_connection_type(t, 42)
|
|
|
|
add_valid_connection_type(42, t)
|
2018-08-22 07:33:50 +02:00
|
|
|
|
2019-10-20 16:22:06 +02:00
|
|
|
func _gui_input(event) -> void:
|
2018-08-22 07:33:50 +02:00
|
|
|
if event is InputEventKey and event.pressed:
|
2018-08-28 08:33:41 +02:00
|
|
|
var scancode_with_modifiers = event.get_scancode_with_modifiers()
|
2020-02-15 11:17:41 +01:00
|
|
|
if scancode_with_modifiers == KEY_DELETE or scancode_with_modifiers == KEY_BACKSPACE:
|
2018-08-22 07:33:50 +02:00
|
|
|
remove_selection()
|
2020-02-15 11:17:41 +01:00
|
|
|
return
|
|
|
|
if event is InputEventMouseMotion and event.button_mask == 0:
|
|
|
|
for c in get_children():
|
|
|
|
if c is GraphNode and Rect2(c.rect_global_position, c.rect_size*c.get_global_transform().get_scale()).has_point(event.global_position):
|
|
|
|
hint_tooltip = c.get_slot_tooltip(c.get_global_transform().xform_inv(event.global_position))
|
2018-08-22 07:33:50 +02:00
|
|
|
|
|
|
|
# Misc. useful functions
|
2019-11-06 23:49:26 +01:00
|
|
|
func get_source(node, port) -> Dictionary:
|
2018-07-22 17:20:27 +02:00
|
|
|
for c in get_connection_list():
|
2019-08-13 13:38:11 +02:00
|
|
|
if c.to == node and c.to_port == port:
|
2018-07-22 17:20:27 +02:00
|
|
|
return { node=c.from, slot=c.from_port }
|
2019-11-06 23:49:26 +01:00
|
|
|
return {}
|
2018-07-22 17:20:27 +02:00
|
|
|
|
2019-10-20 16:22:06 +02:00
|
|
|
func offset_from_global_position(global_position) -> Vector2:
|
2018-08-22 07:33:50 +02:00
|
|
|
return (scroll_offset + global_position - rect_global_position) / zoom
|
|
|
|
|
2019-10-20 16:22:06 +02:00
|
|
|
func add_node(node) -> void:
|
2018-07-30 08:45:19 +02:00
|
|
|
add_child(node)
|
2019-12-11 08:02:22 +01:00
|
|
|
move_child(node, 0)
|
2018-07-30 08:45:19 +02:00
|
|
|
node.connect("close_request", self, "remove_node", [ node ])
|
|
|
|
|
2018-08-12 19:25:18 +02:00
|
|
|
func connect_node(from, from_slot, to, to_slot):
|
2020-02-08 09:37:46 +01:00
|
|
|
var from_node : MMGraphNodeBase = get_node(from)
|
|
|
|
var to_node : MMGraphNodeBase = get_node(to)
|
|
|
|
if generator.connect_children(from_node.generator, from_slot, to_node.generator, to_slot):
|
2019-08-13 13:38:11 +02:00
|
|
|
var disconnect = get_source(to, to_slot)
|
2019-11-10 15:02:00 +01:00
|
|
|
if !disconnect.empty():
|
2019-08-13 13:38:11 +02:00
|
|
|
.disconnect_node(disconnect.node, disconnect.slot, to, to_slot)
|
|
|
|
.connect_node(from, from_slot, to, to_slot)
|
|
|
|
send_changed_signal()
|
2018-08-12 19:25:18 +02:00
|
|
|
|
2019-10-20 16:22:06 +02:00
|
|
|
func disconnect_node(from, from_slot, to, to_slot) -> void:
|
2019-08-14 09:02:38 +02:00
|
|
|
if generator.disconnect_children(get_node(from).generator, from_slot, get_node(to).generator, to_slot):
|
|
|
|
.disconnect_node(from, from_slot, to, to_slot)
|
2019-10-27 10:12:03 +01:00
|
|
|
send_changed_signal()
|
|
|
|
|
|
|
|
func on_connections_changed(removed_connections : Array, added_connections : Array) -> void:
|
|
|
|
for c in removed_connections:
|
|
|
|
.disconnect_node("node_"+c.from, c.from_port, "node_"+c.to, c.to_port)
|
|
|
|
for c in added_connections:
|
|
|
|
.connect_node("node_"+c.from, c.from_port, "node_"+c.to, c.to_port)
|
2018-08-12 19:25:18 +02:00
|
|
|
|
2019-10-20 16:22:06 +02:00
|
|
|
func remove_node(node) -> void:
|
2019-10-27 10:12:03 +01:00
|
|
|
if generator.remove_generator(node.generator):
|
|
|
|
var node_name = node.name
|
|
|
|
for c in get_connection_list():
|
|
|
|
if c.from == node_name or c.to == node_name:
|
|
|
|
disconnect_node(c.from, c.from_port, c.to, c.to_port)
|
2020-01-03 16:03:53 +01:00
|
|
|
if node == last_selected:
|
|
|
|
set_last_selected(null)
|
|
|
|
remove_child(node)
|
2020-01-05 12:36:46 +01:00
|
|
|
node.queue_free()
|
2019-10-27 10:12:03 +01:00
|
|
|
send_changed_signal()
|
2018-08-03 08:16:38 +02:00
|
|
|
|
2018-08-05 18:46:23 +02:00
|
|
|
# Global operations on graph
|
|
|
|
|
2019-10-20 16:22:06 +02:00
|
|
|
func update_tab_title() -> void:
|
2018-08-27 17:22:57 +02:00
|
|
|
if !get_parent().has_method("set_tab_title"):
|
2019-09-11 07:53:06 +02:00
|
|
|
print("no set_tab_title method")
|
2018-08-27 17:22:57 +02:00
|
|
|
return
|
2018-08-05 18:46:23 +02:00
|
|
|
var title = "[unnamed]"
|
|
|
|
if save_path != null:
|
|
|
|
title = save_path.right(save_path.rfind("/")+1)
|
2018-08-09 22:19:27 +02:00
|
|
|
if need_save:
|
|
|
|
title += " *"
|
2018-09-01 11:09:45 +02:00
|
|
|
if get_parent().has_method("set_tab_title"):
|
|
|
|
get_parent().set_tab_title(get_index(), title)
|
2018-08-09 22:19:27 +02:00
|
|
|
|
2019-10-20 16:22:06 +02:00
|
|
|
func set_need_save(ns) -> void:
|
2018-08-09 22:19:27 +02:00
|
|
|
if ns != need_save:
|
|
|
|
need_save = ns
|
2018-08-27 17:22:57 +02:00
|
|
|
update_tab_title()
|
2018-08-05 18:46:23 +02:00
|
|
|
|
2019-10-20 16:22:06 +02:00
|
|
|
func set_save_path(path) -> void:
|
2018-08-05 18:46:23 +02:00
|
|
|
if path != save_path:
|
|
|
|
save_path = path
|
2018-09-01 11:09:45 +02:00
|
|
|
update_tab_title()
|
|
|
|
emit_signal("save_path_changed", self, path)
|
2018-08-05 18:46:23 +02:00
|
|
|
|
2019-10-20 16:22:06 +02:00
|
|
|
func clear_view() -> void:
|
2018-08-03 08:16:38 +02:00
|
|
|
clear_connections()
|
|
|
|
for c in get_children():
|
|
|
|
if c is GraphNode:
|
2020-01-03 16:03:53 +01:00
|
|
|
if c == last_selected:
|
2020-01-06 08:13:42 +01:00
|
|
|
set_last_selected(null)
|
2018-08-03 08:16:38 +02:00
|
|
|
remove_child(c)
|
|
|
|
c.free()
|
2019-09-19 07:56:32 +02:00
|
|
|
|
2019-09-29 10:07:32 +02:00
|
|
|
# Center view
|
|
|
|
|
2019-10-20 16:22:06 +02:00
|
|
|
func center_view() -> void:
|
2019-09-29 10:07:32 +02:00
|
|
|
var center = Vector2(0, 0)
|
|
|
|
var node_count = 0
|
|
|
|
for c in get_children():
|
|
|
|
if c is GraphNode:
|
|
|
|
center += c.offset + 0.5*c.rect_size
|
|
|
|
node_count += 1
|
|
|
|
if node_count > 0:
|
|
|
|
center /= node_count
|
|
|
|
scroll_offset = center - 0.5*rect_size
|
|
|
|
|
2019-10-20 16:22:06 +02:00
|
|
|
func update_view(g) -> void:
|
2019-10-27 10:12:03 +01:00
|
|
|
if generator != null:
|
|
|
|
generator.disconnect("connections_changed", self, "on_connections_changed")
|
2019-09-19 07:56:32 +02:00
|
|
|
clear_view()
|
|
|
|
generator = g
|
2019-10-27 10:12:03 +01:00
|
|
|
if generator != null:
|
|
|
|
generator.connect("connections_changed", self, "on_connections_changed")
|
2019-09-19 07:56:32 +02:00
|
|
|
update_graph(generator.get_children(), generator.connections)
|
2019-10-20 11:33:33 +02:00
|
|
|
subgraph_ui.visible = generator != top_generator
|
|
|
|
subgraph_ui.get_node("Label").text = generator.label
|
2019-09-29 10:07:32 +02:00
|
|
|
center_view()
|
2019-11-04 07:58:17 +01:00
|
|
|
if generator.get_parent() is MMGenGraph:
|
|
|
|
button_transmits_seed.visible = true
|
|
|
|
button_transmits_seed.pressed = generator.transmits_seed
|
|
|
|
else:
|
|
|
|
button_transmits_seed.visible = false
|
|
|
|
|
2019-09-19 07:56:32 +02:00
|
|
|
|
2019-10-20 16:22:06 +02:00
|
|
|
func clear_material() -> void:
|
2019-09-19 07:56:32 +02:00
|
|
|
if top_generator != null:
|
|
|
|
remove_child(top_generator)
|
|
|
|
top_generator.free()
|
|
|
|
top_generator = null
|
2019-08-14 15:55:39 +02:00
|
|
|
generator = null
|
2018-08-05 18:46:23 +02:00
|
|
|
send_changed_signal()
|
2018-08-03 08:16:38 +02:00
|
|
|
|
2019-10-20 16:22:06 +02:00
|
|
|
func update_graph(generators, connections) -> Array:
|
2019-09-17 08:12:53 +02:00
|
|
|
var rv = []
|
2019-08-15 11:53:21 +02:00
|
|
|
for g in generators:
|
|
|
|
var node = node_factory.create_node(g.get_type())
|
|
|
|
if node != null:
|
|
|
|
node.name = "node_"+g.name
|
|
|
|
add_node(node)
|
|
|
|
node.generator = g
|
|
|
|
node.offset = g.position
|
2019-09-17 08:12:53 +02:00
|
|
|
rv.push_back(node)
|
2019-08-15 11:53:21 +02:00
|
|
|
for c in connections:
|
|
|
|
.connect_node("node_"+c.from, c.from_port, "node_"+c.to, c.to_port)
|
2020-01-31 01:17:05 +01:00
|
|
|
|
2019-09-17 08:12:53 +02:00
|
|
|
return rv
|
2019-08-15 11:53:21 +02:00
|
|
|
|
2019-10-20 16:22:06 +02:00
|
|
|
func new_material() -> void:
|
2018-08-03 08:16:38 +02:00
|
|
|
clear_material()
|
2020-01-28 11:47:29 +01:00
|
|
|
top_generator = mm_loader.create_gen({nodes=[{name="Material", type="material","parameters":{"size":11}}], connections=[]})
|
2019-09-19 07:56:32 +02:00
|
|
|
if top_generator != null:
|
|
|
|
add_child(top_generator)
|
2019-12-11 08:02:22 +01:00
|
|
|
move_child(top_generator, 0)
|
2019-09-19 07:56:32 +02:00
|
|
|
update_view(top_generator)
|
2019-12-11 08:02:22 +01:00
|
|
|
center_view()
|
2019-09-11 07:53:06 +02:00
|
|
|
set_save_path(null)
|
2019-08-14 15:55:39 +02:00
|
|
|
set_need_save(false)
|
2018-08-05 18:46:23 +02:00
|
|
|
|
2019-11-06 23:49:26 +01:00
|
|
|
func get_free_name(type) -> String:
|
2018-08-19 02:11:52 +02:00
|
|
|
var i = 0
|
|
|
|
while true:
|
|
|
|
var node_name = type+"_"+str(i)
|
|
|
|
if !has_node(node_name):
|
|
|
|
return node_name
|
|
|
|
i += 1
|
2019-11-06 23:49:26 +01:00
|
|
|
return ""
|
2018-08-19 02:11:52 +02:00
|
|
|
|
2019-11-06 23:49:26 +01:00
|
|
|
func create_nodes(data, position : Vector2 = Vector2(0, 0)) -> Array:
|
2020-02-08 08:19:36 +01:00
|
|
|
if !data is Dictionary:
|
2019-11-06 23:49:26 +01:00
|
|
|
return []
|
2018-08-22 07:33:50 +02:00
|
|
|
if data.has("type"):
|
2019-08-15 11:53:21 +02:00
|
|
|
data = { nodes=[data], connections=[] }
|
2020-02-08 08:19:36 +01:00
|
|
|
if data.has("nodes") and typeof(data.nodes) == TYPE_ARRAY and data.has("connections") and typeof(data.connections) == TYPE_ARRAY:
|
2020-01-28 11:47:29 +01:00
|
|
|
var new_stuff = mm_loader.add_to_gen_graph(generator, data.nodes, data.connections)
|
2019-08-17 17:35:48 +02:00
|
|
|
for g in new_stuff.generators:
|
|
|
|
g.position += position
|
2019-09-17 08:12:53 +02:00
|
|
|
return update_graph(new_stuff.generators, new_stuff.connections)
|
|
|
|
return []
|
2018-08-03 08:16:38 +02:00
|
|
|
|
2019-10-20 16:22:06 +02:00
|
|
|
func create_gen_from_type(gen_name) -> void:
|
2019-10-13 10:14:43 +02:00
|
|
|
create_nodes({ type=gen_name, parameters={} }, scroll_offset+0.5*rect_size)
|
2019-10-07 20:41:57 +02:00
|
|
|
|
2019-10-20 16:22:06 +02:00
|
|
|
func load_file(filename) -> void:
|
2018-08-03 08:16:38 +02:00
|
|
|
clear_material()
|
2020-01-28 11:47:29 +01:00
|
|
|
top_generator = mm_loader.load_gen(filename)
|
2019-09-19 07:56:32 +02:00
|
|
|
if top_generator != null:
|
|
|
|
add_child(top_generator)
|
2019-12-11 08:02:22 +01:00
|
|
|
move_child(top_generator, 0)
|
2019-09-19 07:56:32 +02:00
|
|
|
update_view(top_generator)
|
2019-12-11 08:02:22 +01:00
|
|
|
center_view()
|
2019-08-12 15:58:42 +02:00
|
|
|
set_save_path(filename)
|
|
|
|
set_need_save(false)
|
|
|
|
|
2019-10-20 16:22:06 +02:00
|
|
|
func save_file(filename) -> void:
|
2019-09-19 07:56:32 +02:00
|
|
|
var data = top_generator.serialize()
|
2018-07-30 08:45:19 +02:00
|
|
|
var file = File.new()
|
|
|
|
if file.open(filename, File.WRITE) == OK:
|
2019-10-27 14:36:16 +01:00
|
|
|
file.store_string(JSON.print(data, "\t", true))
|
2018-07-30 08:45:19 +02:00
|
|
|
file.close()
|
2018-08-05 18:46:23 +02:00
|
|
|
set_save_path(filename)
|
2018-08-09 22:19:27 +02:00
|
|
|
set_need_save(false)
|
2018-08-05 18:46:23 +02:00
|
|
|
|
2020-02-17 08:54:46 +01:00
|
|
|
func get_material_node() -> MMGenMaterial:
|
|
|
|
for g in top_generator.get_children():
|
|
|
|
if g.has_method("get_export_profiles"):
|
|
|
|
return g
|
|
|
|
return null
|
|
|
|
|
2020-02-24 23:29:33 +01:00
|
|
|
func export_material(export_prefix, profile) -> void:
|
|
|
|
for g in top_generator.get_children():
|
|
|
|
if g.has_method("export_material"):
|
|
|
|
g.export_material(export_prefix, profile)
|
2018-07-24 08:04:25 +02:00
|
|
|
|
2019-11-17 07:40:50 +01:00
|
|
|
# Cut / copy / paste / duplicate
|
2018-07-28 09:37:51 +02:00
|
|
|
|
2019-10-20 16:22:06 +02:00
|
|
|
func get_selected_nodes() -> Array:
|
2019-09-29 10:07:32 +02:00
|
|
|
var selected_nodes = []
|
|
|
|
for n in get_children():
|
|
|
|
if n is GraphNode and n.selected:
|
|
|
|
selected_nodes.append(n)
|
|
|
|
return selected_nodes
|
|
|
|
|
2019-10-20 16:22:06 +02:00
|
|
|
func remove_selection() -> void:
|
2018-08-19 02:11:52 +02:00
|
|
|
for c in get_children():
|
2019-08-13 13:38:11 +02:00
|
|
|
if c is GraphNode and c.selected and c.name != "Material":
|
2018-08-19 02:11:52 +02:00
|
|
|
remove_node(c)
|
|
|
|
|
2019-09-17 08:12:53 +02:00
|
|
|
# Maybe move this to gen_graph...
|
2019-10-20 16:22:06 +02:00
|
|
|
func serialize_selection() -> Dictionary:
|
2018-08-19 02:11:52 +02:00
|
|
|
var data = { nodes = [], connections = [] }
|
2018-08-22 07:33:50 +02:00
|
|
|
var nodes = []
|
2018-08-19 02:11:52 +02:00
|
|
|
for c in get_children():
|
2019-08-13 13:38:11 +02:00
|
|
|
if c is GraphNode and c.selected and c.name != "Material":
|
2018-08-22 07:33:50 +02:00
|
|
|
nodes.append(c)
|
|
|
|
if nodes.empty():
|
2019-10-20 16:22:06 +02:00
|
|
|
return {}
|
2018-08-22 07:33:50 +02:00
|
|
|
var center = Vector2(0, 0)
|
|
|
|
for n in nodes:
|
|
|
|
center += n.offset+0.5*n.rect_size
|
|
|
|
center /= nodes.size()
|
|
|
|
for n in nodes:
|
2019-09-09 22:00:18 +02:00
|
|
|
var s = n.generator.serialize()
|
2018-08-22 07:33:50 +02:00
|
|
|
var p = n.offset-center
|
|
|
|
s.node_position = { x=p.x, y=p.y }
|
|
|
|
data.nodes.append(s)
|
2018-08-19 02:11:52 +02:00
|
|
|
for c in get_connection_list():
|
|
|
|
var from = get_node(c.from)
|
|
|
|
var to = get_node(c.to)
|
|
|
|
if from != null and from.selected and to != null and to.selected:
|
2019-09-17 08:12:53 +02:00
|
|
|
var connection = c.duplicate(true)
|
|
|
|
connection.from = from.generator.name
|
|
|
|
connection.to = to.generator.name
|
|
|
|
data.connections.append(connection)
|
2018-08-22 07:33:50 +02:00
|
|
|
return data
|
2018-08-19 02:11:52 +02:00
|
|
|
|
2019-10-20 16:22:06 +02:00
|
|
|
func can_copy() -> bool:
|
2018-08-27 12:15:57 +02:00
|
|
|
for c in get_children():
|
2019-08-13 13:38:11 +02:00
|
|
|
if c is GraphNode and c.selected and c.name != "Material":
|
2018-08-27 12:15:57 +02:00
|
|
|
return true
|
|
|
|
return false
|
|
|
|
|
2019-10-20 16:22:06 +02:00
|
|
|
func cut() -> void:
|
2018-08-22 07:33:50 +02:00
|
|
|
copy()
|
|
|
|
remove_selection()
|
|
|
|
|
2019-10-20 16:22:06 +02:00
|
|
|
func copy() -> void:
|
2018-08-22 07:33:50 +02:00
|
|
|
OS.clipboard = to_json(serialize_selection())
|
|
|
|
|
2020-02-13 08:39:17 +01:00
|
|
|
func do_paste(data) -> void:
|
|
|
|
var position = scroll_offset+0.5*rect_size
|
|
|
|
if Rect2(Vector2(0, 0), rect_size).has_point(get_local_mouse_position()):
|
|
|
|
position = offset_from_global_position(get_global_transform().xform(get_local_mouse_position()))
|
2018-08-19 02:11:52 +02:00
|
|
|
for c in get_children():
|
|
|
|
if c is GraphNode:
|
|
|
|
c.selected = false
|
2020-02-13 08:39:17 +01:00
|
|
|
var new_nodes = create_nodes(data, position)
|
2019-11-02 08:43:54 +01:00
|
|
|
if new_nodes != null:
|
|
|
|
for c in new_nodes:
|
|
|
|
c.selected = true
|
2018-08-22 07:33:50 +02:00
|
|
|
|
2020-02-13 08:39:17 +01:00
|
|
|
func paste() -> void:
|
|
|
|
do_paste(parse_json(OS.clipboard))
|
|
|
|
|
2019-11-17 07:40:50 +01:00
|
|
|
func duplicate_selected() -> void:
|
2020-02-13 08:39:17 +01:00
|
|
|
do_paste(serialize_selection())
|
2019-11-17 07:40:50 +01:00
|
|
|
|
2018-08-22 07:33:50 +02:00
|
|
|
# Delay after graph update
|
|
|
|
|
2019-10-20 16:22:06 +02:00
|
|
|
func send_changed_signal() -> void:
|
2018-08-22 07:33:50 +02:00
|
|
|
set_need_save(true)
|
2019-11-05 22:28:01 +01:00
|
|
|
timer.stop()
|
|
|
|
timer.start(0.2)
|
2018-08-22 07:33:50 +02:00
|
|
|
|
2019-10-20 16:22:06 +02:00
|
|
|
func do_send_changed_signal() -> void:
|
2018-08-22 07:33:50 +02:00
|
|
|
emit_signal("graph_changed")
|
2018-08-19 02:11:52 +02:00
|
|
|
|
2018-08-12 19:25:18 +02:00
|
|
|
# Drag and drop
|
|
|
|
|
2019-10-20 16:22:06 +02:00
|
|
|
func can_drop_data(position, data) -> bool:
|
2018-08-22 07:33:50 +02:00
|
|
|
return typeof(data) == TYPE_DICTIONARY and (data.has('type') or (data.has('nodes') and data.has('connections')))
|
2018-08-05 18:46:23 +02:00
|
|
|
|
2019-10-20 16:22:06 +02:00
|
|
|
func drop_data(position, data) -> void:
|
2018-08-25 19:18:40 +02:00
|
|
|
# The following mitigates the SpinBox problem (captures mouse while dragging)
|
|
|
|
if Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
|
|
|
|
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
|
2018-08-22 07:33:50 +02:00
|
|
|
create_nodes(data, offset_from_global_position(get_global_transform().xform(position)))
|
2019-09-19 07:56:32 +02:00
|
|
|
|
2019-10-20 16:22:06 +02:00
|
|
|
func on_ButtonUp_pressed() -> void:
|
2019-09-19 07:56:32 +02:00
|
|
|
if generator != top_generator && generator.get_parent() is MMGenGraph:
|
|
|
|
call_deferred("update_view", generator.get_parent())
|
2019-09-29 10:07:32 +02:00
|
|
|
|
2019-10-20 16:22:06 +02:00
|
|
|
func _on_Label_text_changed(new_text) -> void:
|
2019-10-10 22:43:34 +02:00
|
|
|
generator.label = new_text
|
|
|
|
|
2019-09-29 10:07:32 +02:00
|
|
|
# Create subgraph
|
|
|
|
|
2019-10-20 16:22:06 +02:00
|
|
|
func create_subgraph() -> void:
|
2019-09-29 10:07:32 +02:00
|
|
|
var generators = []
|
|
|
|
for n in get_selected_nodes():
|
|
|
|
generators.push_back(n.generator)
|
2019-11-17 07:40:50 +01:00
|
|
|
var subgraph = generator.create_subgraph(generators)
|
|
|
|
if subgraph != null:
|
|
|
|
update_view(subgraph)
|
2019-10-10 22:43:34 +02:00
|
|
|
|
2019-10-20 16:22:06 +02:00
|
|
|
func _on_ButtonShowTree_pressed() -> void:
|
2020-01-25 15:20:08 +01:00
|
|
|
var graph_tree : Popup = preload("res://material_maker/widgets/graph_tree/graph_tree.tscn").instance()
|
2019-10-20 11:33:33 +02:00
|
|
|
add_child(graph_tree)
|
2020-02-08 14:48:15 +01:00
|
|
|
graph_tree.init("Top", top_generator)
|
2019-10-22 08:28:24 +02:00
|
|
|
graph_tree.connect("item_double_clicked", self, "edit_subgraph")
|
2019-10-20 11:33:33 +02:00
|
|
|
graph_tree.popup_centered()
|
2019-10-22 08:28:24 +02:00
|
|
|
|
|
|
|
func edit_subgraph(g : MMGenGraph) -> void:
|
|
|
|
if !g.is_editable():
|
|
|
|
g.toggle_editable()
|
|
|
|
update_view(g)
|
2019-11-04 07:58:17 +01:00
|
|
|
|
|
|
|
|
2019-11-06 23:49:26 +01:00
|
|
|
func _on_ButtonTransmitsSeed_toggled(button_pressed) -> void:
|
2019-11-04 07:58:17 +01:00
|
|
|
if button_pressed != generator.transmits_seed:
|
|
|
|
generator.transmits_seed = button_pressed
|
2019-12-27 22:30:49 +01:00
|
|
|
|
|
|
|
func _on_GraphEdit_node_selected(node) -> void:
|
2020-01-03 16:03:53 +01:00
|
|
|
set_last_selected(node)
|
|
|
|
|
|
|
|
func set_last_selected(node) -> void:
|
|
|
|
if node is GraphNode:
|
|
|
|
last_selected = node
|
|
|
|
else:
|
|
|
|
last_selected = null
|
2019-12-27 22:30:49 +01:00
|
|
|
|
|
|
|
func _on_GraphEdit_gui_input(event) -> void:
|
2020-01-29 13:01:42 +01:00
|
|
|
if event.is_action_pressed("ui_library_popup") && get_rect().has_point(get_local_mouse_position()):
|
2020-02-01 08:35:00 +01:00
|
|
|
node_popup.rect_global_position = get_global_mouse_position()
|
|
|
|
node_popup.show()
|
2019-12-27 22:30:49 +01:00
|
|
|
if event is InputEventMouseButton:
|
|
|
|
call_deferred("check_last_selected")
|
|
|
|
|
2020-02-01 08:35:00 +01:00
|
|
|
func request_popup(from, from_slot, release_position) -> void:
|
|
|
|
node_popup.rect_global_position = get_global_mouse_position()
|
|
|
|
node_popup.show()
|
|
|
|
node_popup.set_quick_connect(from, from_slot)
|
2020-01-31 01:17:05 +01:00
|
|
|
|
2019-12-27 22:30:49 +01:00
|
|
|
func check_last_selected() -> void:
|
2020-01-06 08:13:42 +01:00
|
|
|
if last_selected != null and !(is_instance_valid(last_selected) and last_selected.selected):
|
2019-12-27 22:30:49 +01:00
|
|
|
last_selected = null
|
2020-01-03 16:03:53 +01:00
|
|
|
emit_signal("node_selected", null)
|
2020-01-29 13:01:42 +01:00
|
|
|
|
|
|
|
|