mirror of
https://github.com/Relintai/material-maker.git
synced 2025-04-01 05:55:37 +02:00
optimized hierarchy pane previews and made them configurable
This commit is contained in:
parent
707c160317
commit
754edea090
@ -10,7 +10,13 @@ var editable : bool = false
|
|||||||
var transmits_seed : bool = true
|
var transmits_seed : bool = true
|
||||||
|
|
||||||
signal connections_changed(removed_connections, added_connections)
|
signal connections_changed(removed_connections, added_connections)
|
||||||
|
signal hierarchy_changed
|
||||||
|
|
||||||
|
func emit_hierarchy_changed():
|
||||||
|
var top = self
|
||||||
|
while top.get_parent() != null and top.get_parent().get_script() == get_script():
|
||||||
|
top = top.get_parent()
|
||||||
|
top.emit_signal("hierarchy_changed")
|
||||||
|
|
||||||
func fix_remotes() -> void:
|
func fix_remotes() -> void:
|
||||||
for c in get_children():
|
for c in get_children():
|
||||||
@ -111,6 +117,8 @@ func add_generator(generator : MMGenBase) -> bool:
|
|||||||
name = generator.name + "_" + str(index)
|
name = generator.name + "_" + str(index)
|
||||||
generator.name = name
|
generator.name = name
|
||||||
add_child(generator)
|
add_child(generator)
|
||||||
|
if generator.get_script() == get_script():
|
||||||
|
emit_hierarchy_changed()
|
||||||
return true
|
return true
|
||||||
|
|
||||||
func remove_generator(generator : MMGenBase) -> bool:
|
func remove_generator(generator : MMGenBase) -> bool:
|
||||||
@ -123,6 +131,8 @@ func remove_generator(generator : MMGenBase) -> bool:
|
|||||||
connections = new_connections
|
connections = new_connections
|
||||||
remove_child(generator)
|
remove_child(generator)
|
||||||
fix_remotes()
|
fix_remotes()
|
||||||
|
if generator.get_script() == get_script():
|
||||||
|
emit_hierarchy_changed()
|
||||||
generator.queue_free()
|
generator.queue_free()
|
||||||
return true
|
return true
|
||||||
|
|
||||||
@ -130,8 +140,10 @@ func replace_generator(old : MMGenBase, new : MMGenBase) -> void:
|
|||||||
new.name = old.name
|
new.name = old.name
|
||||||
new.position = old.position
|
new.position = old.position
|
||||||
remove_child(old)
|
remove_child(old)
|
||||||
old.free()
|
|
||||||
add_child(new)
|
add_child(new)
|
||||||
|
if old.get_script() == get_script() or new.get_script() == get_script():
|
||||||
|
emit_hierarchy_changed()
|
||||||
|
old.free()
|
||||||
|
|
||||||
func get_connected_inputs(generator) -> Array:
|
func get_connected_inputs(generator) -> Array:
|
||||||
var rv : Array = []
|
var rv : Array = []
|
||||||
@ -312,10 +324,11 @@ func create_subgraph(gens : Array) -> MMGenGraph:
|
|||||||
if !found_remote:
|
if !found_remote:
|
||||||
var gen_parameters = remote_script.new()
|
var gen_parameters = remote_script.new()
|
||||||
gen_parameters.name = "gen_parameters"
|
gen_parameters.name = "gen_parameters"
|
||||||
gen_parameters.position = Vector2(center.x - 200, upper_bound-300)
|
gen_parameters.position = Vector2(center.x-200, upper_bound-300)
|
||||||
new_graph.add_child(gen_parameters)
|
new_graph.add_child(gen_parameters)
|
||||||
fix_remotes()
|
fix_remotes()
|
||||||
new_graph.fix_remotes()
|
new_graph.fix_remotes()
|
||||||
|
emit_hierarchy_changed()
|
||||||
return new_graph
|
return new_graph
|
||||||
|
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ onready var button_transmits_seed : Button = $GraphUI/SubGraphUI/ButtonTransmits
|
|||||||
|
|
||||||
signal save_path_changed
|
signal save_path_changed
|
||||||
signal graph_changed
|
signal graph_changed
|
||||||
|
signal view_updated
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
OS.low_processor_usage_mode = true
|
OS.low_processor_usage_mode = true
|
||||||
@ -151,6 +152,7 @@ func update_view(g) -> void:
|
|||||||
button_transmits_seed.pressed = generator.transmits_seed
|
button_transmits_seed.pressed = generator.transmits_seed
|
||||||
else:
|
else:
|
||||||
button_transmits_seed.visible = false
|
button_transmits_seed.visible = false
|
||||||
|
emit_signal("view_updated", generator)
|
||||||
|
|
||||||
|
|
||||||
func clear_material() -> void:
|
func clear_material() -> void:
|
||||||
|
@ -314,9 +314,10 @@ func load_material() -> void:
|
|||||||
|
|
||||||
func do_load_materials(filenames) -> void:
|
func do_load_materials(filenames) -> void:
|
||||||
for f in filenames:
|
for f in filenames:
|
||||||
do_load_material(f)
|
do_load_material(f, false)
|
||||||
|
hierarchy.update_from_graph_edit(get_current_graph_edit())
|
||||||
|
|
||||||
func do_load_material(filename) -> void:
|
func do_load_material(filename : String, update_hierarchy : bool = true) -> void:
|
||||||
var graph_edit : MMGraphEdit = get_current_graph_edit()
|
var graph_edit : MMGraphEdit = get_current_graph_edit()
|
||||||
var node_count = 2 # So test below succeeds if graph_edit is null...
|
var node_count = 2 # So test below succeeds if graph_edit is null...
|
||||||
if graph_edit != null:
|
if graph_edit != null:
|
||||||
@ -330,12 +331,15 @@ func do_load_material(filename) -> void:
|
|||||||
graph_edit = new_pane()
|
graph_edit = new_pane()
|
||||||
graph_edit.load_file(filename)
|
graph_edit.load_file(filename)
|
||||||
add_recent(filename)
|
add_recent(filename)
|
||||||
|
if update_hierarchy:
|
||||||
|
hierarchy.update_from_graph_edit(get_current_graph_edit())
|
||||||
|
|
||||||
func save_material() -> void:
|
func save_material() -> void:
|
||||||
var graph_edit : MMGraphEdit = get_current_graph_edit()
|
var graph_edit : MMGraphEdit = get_current_graph_edit()
|
||||||
if graph_edit != null:
|
if graph_edit != null:
|
||||||
if graph_edit.save_path != null:
|
if graph_edit.save_path != null:
|
||||||
graph_edit.save_file(graph_edit.save_path)
|
graph_edit.save_file(graph_edit.save_path)
|
||||||
|
add_recent(graph_edit.save_path)
|
||||||
else:
|
else:
|
||||||
save_material_as()
|
save_material_as()
|
||||||
|
|
||||||
@ -524,7 +528,6 @@ func _on_PopupMenu_id_pressed(id) -> void:
|
|||||||
# Preview
|
# Preview
|
||||||
|
|
||||||
func update_preview() -> void:
|
func update_preview() -> void:
|
||||||
hierarchy.update_from_graph_edit(get_current_graph_edit())
|
|
||||||
var status
|
var status
|
||||||
need_update = true
|
need_update = true
|
||||||
if updating:
|
if updating:
|
||||||
@ -590,6 +593,7 @@ func _on_Projects_tab_changed(tab) -> void:
|
|||||||
new_tab.connect("node_selected", self, "on_selected_node_change")
|
new_tab.connect("node_selected", self, "on_selected_node_change")
|
||||||
current_tab = new_tab
|
current_tab = new_tab
|
||||||
update_preview()
|
update_preview()
|
||||||
|
hierarchy.update_from_graph_edit(get_current_graph_edit())
|
||||||
|
|
||||||
func on_group_selected(generator) -> void:
|
func on_group_selected(generator) -> void:
|
||||||
var graph_edit : MMGraphEdit = get_current_graph_edit()
|
var graph_edit : MMGraphEdit = get_current_graph_edit()
|
||||||
|
@ -2,67 +2,115 @@ extends Tree
|
|||||||
|
|
||||||
export(int, 0, 3) var preview : int = 0
|
export(int, 0, 3) var preview : int = 0
|
||||||
|
|
||||||
var update_index : int = 0
|
var default_texture : ImageTexture = null
|
||||||
|
var current_graph_edit = null
|
||||||
|
var current_generator = null
|
||||||
|
var item_from_gen : Dictionary = {}
|
||||||
|
|
||||||
|
var pending_updates = {}
|
||||||
|
|
||||||
signal group_selected
|
signal group_selected
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
var default_image = Image.new()
|
||||||
|
default_image.create(24, 24, false, Image.FORMAT_RGBA8)
|
||||||
|
default_image.fill(Color(0.0, 0.0, 0.0, 0.0))
|
||||||
|
default_texture = ImageTexture.new()
|
||||||
|
default_texture.create_from_image(default_image)
|
||||||
|
|
||||||
func update_from_graph_edit(graph_edit) -> void:
|
func update_from_graph_edit(graph_edit) -> void:
|
||||||
update_index += 1
|
for g in item_from_gen.keys():
|
||||||
|
if is_instance_valid(g):
|
||||||
|
g.disconnect("output_changed", self, "on_gen_output_changed")
|
||||||
|
item_from_gen = {}
|
||||||
set_column_expand(0, true)
|
set_column_expand(0, true)
|
||||||
columns = preview+1
|
columns = preview+1
|
||||||
for i in range(1, columns):
|
for i in range(1, columns):
|
||||||
set_column_expand(i, false)
|
set_column_expand(i, false)
|
||||||
set_column_min_width(i, 28)
|
set_column_min_width(i, 28)
|
||||||
if graph_edit == null:
|
clear()
|
||||||
|
pending_updates = {}
|
||||||
|
if current_graph_edit != null and is_instance_valid(current_graph_edit):
|
||||||
|
current_graph_edit.disconnect("view_updated", self, "on_view_updated")
|
||||||
|
if graph_edit == null or graph_edit.top_generator == null or graph_edit.generator == null:
|
||||||
|
current_graph_edit = null
|
||||||
|
current_generator = null
|
||||||
return
|
return
|
||||||
|
current_graph_edit = graph_edit
|
||||||
|
current_graph_edit.connect("view_updated", self, "on_view_updated")
|
||||||
|
current_generator = graph_edit.generator
|
||||||
var file_name = "PTex"
|
var file_name = "PTex"
|
||||||
if graph_edit.save_path != null:
|
if graph_edit.save_path != null:
|
||||||
file_name = graph_edit.save_path.get_file()
|
file_name = graph_edit.save_path.get_file()
|
||||||
fill_tree(graph_edit.top_generator, graph_edit.generator, file_name)
|
fill_item(create_item(null), graph_edit.top_generator, graph_edit.generator, file_name)
|
||||||
|
|
||||||
func fill_tree(top : MMGenGraph, selected : MMGenGraph, top_name : String) -> void:
|
func set_icon(item : TreeItem, generator : MMGenGraph, output : int) -> void:
|
||||||
clear()
|
if output >= preview:
|
||||||
if top == null or selected == null:
|
|
||||||
return
|
return
|
||||||
var root : TreeItem = create_item(null)
|
var result = generator.render(output, 24, true)
|
||||||
root.set_text(0, top_name)
|
while result is GDScriptFunctionState:
|
||||||
if top == selected:
|
result = yield(result, "completed")
|
||||||
root.set_custom_color(0, Color(0.5, 0.5, 1))
|
var tex = ImageTexture.new()
|
||||||
|
result.copy_to_texture(tex)
|
||||||
|
item.set_icon(1-min(generator.get_output_defs().size()-preview, 0)+output, tex)
|
||||||
|
result.release()
|
||||||
|
|
||||||
|
func set_icons(item : TreeItem, generator : MMGenGraph) -> void:
|
||||||
|
var output_count = min(generator.get_output_defs().size(), preview)
|
||||||
|
for output in range(output_count):
|
||||||
|
set_icon(item, generator, output)
|
||||||
|
|
||||||
|
func fill_item(item : TreeItem, generator : MMGenGraph, selected : MMGenGraph, name = null) -> void:
|
||||||
|
item.set_text(0, name if name != null else generator.get_type_name())
|
||||||
|
if generator == selected:
|
||||||
|
item.set_custom_color(0, Color(0.5, 0.5, 1))
|
||||||
else:
|
else:
|
||||||
root.set_custom_color(0, Color(1, 1, 1))
|
item.set_custom_color(0, Color(1, 1, 1))
|
||||||
root.set_metadata(0, top)
|
item.set_metadata(0, generator)
|
||||||
fill_item(root, top, selected)
|
item_from_gen[generator] = item
|
||||||
|
generator.connect("output_changed", self, "on_gen_output_changed", [ generator ])
|
||||||
func set_icon(item, generator) -> void:
|
if preview > 0 and generator.get_output_defs().size() > 0:
|
||||||
var index = update_index
|
for i in range(min(preview, generator.get_output_defs().size())):
|
||||||
var output_count = min(generator.get_output_defs().size(), 3)
|
item.set_icon(i+1, default_texture)
|
||||||
for o in range(output_count):
|
call_deferred("set_icons", item, generator)
|
||||||
var result = generator.render(o, 24, true)
|
|
||||||
while result is GDScriptFunctionState:
|
|
||||||
if index != update_index:
|
|
||||||
return
|
|
||||||
result = yield(result, "completed")
|
|
||||||
if index == update_index:
|
|
||||||
var tex = ImageTexture.new()
|
|
||||||
result.copy_to_texture(tex)
|
|
||||||
item.set_icon(1+preview-output_count+o, tex)
|
|
||||||
result.release()
|
|
||||||
|
|
||||||
func fill_item(parent : TreeItem, generator : MMGenGraph, selected : MMGenGraph) -> void:
|
|
||||||
for c in generator.get_children():
|
for c in generator.get_children():
|
||||||
if c is MMGenGraph:
|
if c is MMGenGraph:
|
||||||
if c.is_template():
|
if c.is_template():
|
||||||
continue
|
continue
|
||||||
var item : TreeItem = create_item(parent)
|
fill_item(create_item(item), c, selected)
|
||||||
item.set_text(0, c.get_type_name())
|
|
||||||
if c == selected:
|
|
||||||
item.set_custom_color(0, Color(0.5, 0.5, 1))
|
|
||||||
elif c.is_editable():
|
|
||||||
item.set_custom_color(0, Color(1, 1, 1))
|
|
||||||
item.set_metadata(0, c)
|
|
||||||
if preview > 0 and c.get_output_defs().size() > 0:
|
|
||||||
call_deferred("set_icon", item, c)
|
|
||||||
fill_item(item, c, selected)
|
|
||||||
|
|
||||||
func _on_Hierarchy_item_double_clicked():
|
func _on_Hierarchy_item_double_clicked() -> void:
|
||||||
emit_signal("group_selected", get_selected().get_metadata(0))
|
emit_signal("group_selected", get_selected().get_metadata(0))
|
||||||
|
|
||||||
|
func on_view_updated(generator) -> void:
|
||||||
|
if item_from_gen.has(current_generator):
|
||||||
|
item_from_gen[current_generator].set_custom_color(0, Color(1, 1, 1))
|
||||||
|
current_generator = generator
|
||||||
|
if item_from_gen.has(current_generator):
|
||||||
|
item_from_gen[current_generator].set_custom_color(0, Color(0.5, 0.5, 1))
|
||||||
|
|
||||||
|
func on_gen_output_changed(index, generator) -> void:
|
||||||
|
if item_from_gen.has(generator) and index < preview:
|
||||||
|
if !pending_updates.has(generator):
|
||||||
|
pending_updates[generator] = [index]
|
||||||
|
elif pending_updates[generator].find(index) == -1:
|
||||||
|
pending_updates[generator].push_back(index)
|
||||||
|
$Delay.stop()
|
||||||
|
$Delay.start()
|
||||||
|
|
||||||
|
func _on_Delay_timeout() -> void:
|
||||||
|
for generator in pending_updates.keys():
|
||||||
|
var item = item_from_gen[generator]
|
||||||
|
for index in pending_updates[generator]:
|
||||||
|
set_icon(item, generator, index)
|
||||||
|
|
||||||
|
func _on_Hierarchy_gui_input(event):
|
||||||
|
if event is InputEventMouseButton and event.button_index == BUTTON_RIGHT and event.pressed:
|
||||||
|
$ContextMenu.rect_position = get_global_mouse_position()
|
||||||
|
$ContextMenu.popup()
|
||||||
|
|
||||||
|
func _on_ContextMenu_id_pressed(id):
|
||||||
|
preview = id
|
||||||
|
update_from_graph_edit(current_graph_edit)
|
||||||
|
|
||||||
|
|
||||||
|
@ -11,5 +11,18 @@ script = ExtResource( 1 )
|
|||||||
__meta__ = {
|
__meta__ = {
|
||||||
"_edit_use_anchors_": false
|
"_edit_use_anchors_": false
|
||||||
}
|
}
|
||||||
|
preview = 2
|
||||||
|
|
||||||
|
[node name="ContextMenu" type="PopupMenu" parent="."]
|
||||||
|
margin_right = 20.0
|
||||||
|
margin_bottom = 20.0
|
||||||
|
items = [ "No preview", null, 0, false, false, 0, 0, null, "", false, "1 preview", null, 0, false, false, 1, 0, null, "", false, "2 previews", null, 0, false, false, 2, 0, null, "", false, "3 previews", null, 0, false, false, 3, 0, null, "", false ]
|
||||||
|
|
||||||
|
[node name="Delay" type="Timer" parent="."]
|
||||||
|
wait_time = 0.5
|
||||||
|
one_shot = true
|
||||||
|
[connection signal="gui_input" from="." to="." method="_on_Hierarchy_gui_input"]
|
||||||
[connection signal="item_activated" from="." to="." method="_on_Hierarchy_item_double_clicked"]
|
[connection signal="item_activated" from="." to="." method="_on_Hierarchy_item_double_clicked"]
|
||||||
[connection signal="item_double_clicked" from="." to="." method="_on_Hierarchy_item_double_clicked"]
|
[connection signal="item_double_clicked" from="." to="." method="_on_Hierarchy_item_double_clicked"]
|
||||||
|
[connection signal="id_pressed" from="ContextMenu" to="." method="_on_ContextMenu_id_pressed"]
|
||||||
|
[connection signal="timeout" from="Delay" to="." method="_on_Delay_timeout"]
|
||||||
|
Loading…
Reference in New Issue
Block a user