Implemented undo redo support for mat_maker_gd. It does have some issues with undoing some of the changes, those will be fixed later. However all actions seems to properly mark the resource as dirty.

This commit is contained in:
Relintai 2022-01-21 13:22:39 +01:00
parent 87336f55e8
commit 2ce6e4d466
4 changed files with 174 additions and 15 deletions

View File

@ -11,10 +11,22 @@ export(NodePath) var add_popup_path : NodePath = "Popups/AddPopup"
var _graph_edit : GraphEdit = null
var _material : MMMateial
var _ignore_material_change_event : bool = false
var _event_recreate_queued : bool = false
var _plugin : EditorPlugin = null
var _undo_redo : UndoRedo = null
func _enter_tree():
ensure_objs()
func set_plugin(plugin : EditorPlugin) -> void:
_plugin = plugin
_undo_redo = plugin.get_undo_redo()
func get_undo_redo() -> UndoRedo:
return _undo_redo
func ensure_objs() -> void:
if !_graph_edit:
_graph_edit = get_node(graph_edit_path)
@ -63,6 +75,7 @@ func recreate() -> void:
for n in _material.nodes:
var gn : GraphNode = MMGraphNode.new()
gn.slot_colors = slot_colors
gn.set_editor(self)
gn.set_node(_material, n)
_graph_edit.add_child(gn)
@ -80,6 +93,8 @@ func recreate() -> void:
_graph_edit.connect_node(output_node.name, from_slot, input_node.name, to_slot)
_material.render()
_event_recreate_queued = false
func find_graph_node_for(nnode) -> Node:
for c in _graph_edit.get_children():
@ -93,33 +108,63 @@ func find_graph_node_for(nnode) -> Node:
return null
func set_mmmaterial(object : MMMateial):
if _material:
_material.disconnect("changed", self, "on_material_changed")
_material = object
recreate()
if _material:
_material.connect("changed", self, "on_material_changed")
recreate()
func on_material_changed() -> void:
if _ignore_material_change_event:
return
if _event_recreate_queued:
return
call_deferred("recreate")
func ignore_changes(val : bool) -> void:
_ignore_material_change_event = val
func on_graph_edit_connection_request(from: String, from_slot: int, to: String, to_slot: int):
var from_node : GraphNode = _graph_edit.get_node(from)
var to_node : GraphNode = _graph_edit.get_node(to)
ignore_changes(true)
_material.cancel_render_and_wait()
if from_node.connect_slot(from_slot, to_node, to_slot):
_graph_edit.connect_node(from, from_slot, to, to_slot)
ignore_changes(false)
func on_graph_edit_disconnection_request(from: String, from_slot: int, to: String, to_slot: int):
var from_node : GraphNode = _graph_edit.get_node(from)
var to_node : GraphNode = _graph_edit.get_node(to)
ignore_changes(true)
_material.cancel_render_and_wait()
if from_node.disconnect_slot(from_slot, to_node, to_slot):
_graph_edit.disconnect_node(from, from_slot, to, to_slot)
ignore_changes(false)
func on_graph_node_close_request(node : GraphNode) -> void:
if _material:
ignore_changes(true)
_material.cancel_render_and_wait()
_material.remove_node(node._node)
recreate()
ignore_changes(false)
func _on_AddButton_pressed():
get_node(add_popup_path).popup_centered()
@ -139,10 +184,15 @@ func _on_AddPopup_ok_pressed(script_path : String):
print("_on_AddPopup_ok_pressed: Error !nnode! script: " + script_path)
return
ignore_changes(true)
_material.add_node(nnode)
var gn : GraphNode = MMGraphNode.new()
gn.slot_colors = slot_colors
gn.set_editor(self)
gn.set_node(_material, nnode)
_graph_edit.add_child(gn)
ignore_changes(false)

View File

@ -11,11 +11,24 @@ var _material : MMMateial = null
var _node : MMNode = null
var properties : Array = Array()
var _editor_node
var _undo_redo : UndoRedo = null
var _ignore_change_event : bool = false
func _init():
show_close = true
connect("offset_changed", self, "on_offset_changed")
connect("close_request", self, "on_close_request")
func set_editor(editor_node) -> void:
_editor_node = editor_node
_undo_redo = _editor_node.get_undo_redo()
func ignore_changes(val : bool) -> void:
_ignore_change_event = val
_editor_node.ignore_changes(val)
func add_slot_texture(getter : String, setter : String) -> int:
var t : TextureRect = TextureRect.new()
t.rect_min_size = Vector2(128, 128)
@ -448,7 +461,12 @@ func connect_slot(slot_idx : int, to_node : Node, to_slot_idx : int) -> bool:
to_property_index = i
break
to_node.properties[to_property_index][6].set_input_property(properties[from_property_index][6])
#to_node.properties[to_property_index][6].set_input_property(properties[from_property_index][6])
_undo_redo.create_action("MMGD: connect_slot")
_undo_redo.add_do_method(to_node.properties[to_property_index][6], "set_input_property", properties[from_property_index][6])
_undo_redo.add_undo_method(to_node.properties[to_property_index][6], "set_input_property", to_node.properties[to_property_index][6].input_property)
_undo_redo.commit_action()
return true
@ -472,7 +490,12 @@ func disconnect_slot(slot_idx : int, to_node : Node, to_slot_idx : int) -> bool:
to_property_index = i
break
to_node.properties[to_property_index][6].set_input_property(null)
#to_node.properties[to_property_index][6].set_input_property(null)
_undo_redo.create_action("MMGD: disconnect_slot")
_undo_redo.add_do_method(to_node.properties[to_property_index][6], "unset_input_property")
_undo_redo.add_undo_method(to_node.properties[to_property_index][6], "set_input_property", to_node.properties[to_property_index][6].input_property)
_undo_redo.commit_action()
return true
@ -532,37 +555,96 @@ func on_node_changed():
#get all properties again
#_node.recalculate_image(_material)
if _ignore_change_event:
return
propagate_node_change()
func on_int_spinbox_value_changed(val : float, slot_idx) -> void:
_node.call(properties[slot_idx][4], int(val))
#_node.call(properties[slot_idx][4], int(val))
ignore_changes(true)
_undo_redo.create_action("MMGD: value changed")
_undo_redo.add_do_method(_node, properties[slot_idx][4], int(val))
_undo_redo.add_undo_method(_node, properties[slot_idx][4], _node.call(properties[slot_idx][3]))
_undo_redo.commit_action()
ignore_changes(false)
func on_float_spinbox_value_changed(val : float, slot_idx) -> void:
_node.call(properties[slot_idx][4], val)
#_node.call(properties[slot_idx][4], val)
ignore_changes(true)
_undo_redo.create_action("MMGD: value changed")
_undo_redo.add_do_method(_node, properties[slot_idx][4], val)
_undo_redo.add_undo_method(_node, properties[slot_idx][4], _node.call(properties[slot_idx][3]))
_undo_redo.commit_action()
ignore_changes(false)
func on_vector2_spinbox_value_changed(val : float, slot_idx, spinbox_x, spinbox_y) -> void:
var vv : Vector2 = Vector2(spinbox_x.value, spinbox_y.value)
_node.call(properties[slot_idx][4], vv)
#_node.call(properties[slot_idx][4], vv)
ignore_changes(true)
_undo_redo.create_action("MMGD: value changed")
_undo_redo.add_do_method(_node, properties[slot_idx][4], vv)
_undo_redo.add_undo_method(_node, properties[slot_idx][4], _node.call(properties[slot_idx][3]))
_undo_redo.commit_action()
ignore_changes(false)
func on_vector3_spinbox_value_changed(val : float, slot_idx, spinbox_x, spinbox_y, spinbox_z) -> void:
var vv : Vector3 = Vector3(spinbox_x.value, spinbox_y.value, spinbox_z.value)
_node.call(properties[slot_idx][4], vv)
#_node.call(properties[slot_idx][4], vv)
ignore_changes(true)
_undo_redo.create_action("MMGD: value changed")
_undo_redo.add_do_method(_node, properties[slot_idx][4], vv)
_undo_redo.add_undo_method(_node, properties[slot_idx][4], _node.call(properties[slot_idx][3]))
_undo_redo.commit_action()
ignore_changes(false)
func on_int_universal_spinbox_value_changed(val : float, slot_idx) -> void:
properties[slot_idx][6].set_default_value(int(val))
#properties[slot_idx][6].set_default_value(int(val))
ignore_changes(true)
_undo_redo.create_action("MMGD: value changed")
_undo_redo.add_do_method(properties[slot_idx][6], "set_default_value", int(val))
_undo_redo.add_undo_method(properties[slot_idx][6], "set_default_value", properties[slot_idx][6].get_default_value())
_undo_redo.commit_action()
ignore_changes(false)
func on_float_universal_spinbox_value_changed(val : float, slot_idx) -> void:
properties[slot_idx][6].set_default_value(val)
#properties[slot_idx][6].set_default_value(val)
ignore_changes(true)
_undo_redo.create_action("MMGD: value changed")
_undo_redo.add_do_method(properties[slot_idx][6], "set_default_value", val)
_undo_redo.add_undo_method(properties[slot_idx][6], "set_default_value", properties[slot_idx][6].get_default_value())
_undo_redo.commit_action()
ignore_changes(false)
func on_vector2_universal_spinbox_value_changed(val : float, slot_idx, spinbox_x, spinbox_y) -> void:
var vv : Vector2 = Vector2(spinbox_x.value, spinbox_y.value)
properties[slot_idx][6].set_default_value(vv)
#properties[slot_idx][6].set_default_value(vv)
ignore_changes(true)
_undo_redo.create_action("MMGD: value changed")
_undo_redo.add_do_method(properties[slot_idx][6], "set_default_value", vv)
_undo_redo.add_undo_method(properties[slot_idx][6], "set_default_value", properties[slot_idx][6].get_default_value())
_undo_redo.commit_action()
ignore_changes(false)
func on_slot_enum_item_selected(val : int, slot_idx : int) -> void:
_node.call(properties[slot_idx][4], val)
#_node.call(properties[slot_idx][4], val)
ignore_changes(true)
_undo_redo.create_action("MMGD: value changed")
_undo_redo.add_do_method(_node, properties[slot_idx][4], val)
_undo_redo.add_undo_method(_node, properties[slot_idx][4], _node.call(properties[slot_idx][3]))
_undo_redo.commit_action()
ignore_changes(false)
func on_universal_texture_changed(slot_idx : int) -> void:
var img : Image = properties[slot_idx][6].get_active_image()
@ -585,13 +667,34 @@ func on_universal_texture_changed_image_picker(slot_idx : int) -> void:
properties[slot_idx][5].texture_normal = ImageTexture.new()
func on_slot_line_edit_text_entered(text : String, slot_idx : int) -> void:
_node.call(properties[slot_idx][4], text)
#_node.call(properties[slot_idx][4], text)
ignore_changes(true)
_undo_redo.create_action("MMGD: value changed")
_undo_redo.add_do_method(_node, properties[slot_idx][4], text)
_undo_redo.add_undo_method(_node, properties[slot_idx][4], _node.call(properties[slot_idx][3]))
_undo_redo.commit_action()
ignore_changes(false)
func on_universal_color_changed(c : Color, slot_idx : int) -> void:
properties[slot_idx][6].set_default_value(c)
#properties[slot_idx][6].set_default_value(c)
ignore_changes(true)
_undo_redo.create_action("MMGD: value changed")
_undo_redo.add_do_method(properties[slot_idx][6], "set_default_value", c)
_undo_redo.add_undo_method(properties[slot_idx][6], "set_default_value", properties[slot_idx][6].get_default_value())
_undo_redo.commit_action()
ignore_changes(false)
func on_universal_image_path_changed(f : String, slot_idx : int) -> void:
_node.call(properties[slot_idx][8], f)
ignore_changes(true)
_undo_redo.create_action("MMGD: value changed")
_undo_redo.add_do_method(properties[slot_idx][6], "set_default_value", f)
_undo_redo.add_undo_method(properties[slot_idx][6], "set_default_value", properties[slot_idx][6].get_default_value())
_undo_redo.commit_action()
ignore_changes(false)
func get_material_node() -> MMNode:
return _node

View File

@ -311,6 +311,11 @@ func set_input_property(val : MMNodeUniversalProperty) -> void:
input_property.connect("changed", self, "on_input_property_changed")
emit_changed()
# Because in UndiRedo if you pass null as the only argument it will look
# for a method with no arguments
func unset_input_property() -> void:
set_input_property(null)
func on_input_property_changed() -> void:
emit_changed()

View File

@ -16,6 +16,7 @@ func _enter_tree():
add_custom_type("MMNodeUniversalProperty", "Resource", MMNodeUniversalProperty, null)
editor_scene = editor_packed_scene.instance()
editor_scene.set_plugin(self)
tool_button = add_control_to_bottom_panel(editor_scene, "MMGD")
tool_button.hide()