diff --git a/game/addons/mat_maker_gd/editor/MatMakerGDEditor.gd b/game/addons/mat_maker_gd/editor/MatMakerGDEditor.gd index d7fb0435..160e60a2 100644 --- a/game/addons/mat_maker_gd/editor/MatMakerGDEditor.gd +++ b/game/addons/mat_maker_gd/editor/MatMakerGDEditor.gd @@ -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) + diff --git a/game/addons/mat_maker_gd/editor/mm_graph_node.gd b/game/addons/mat_maker_gd/editor/mm_graph_node.gd index b12fc2e7..c7812de7 100644 --- a/game/addons/mat_maker_gd/editor/mm_graph_node.gd +++ b/game/addons/mat_maker_gd/editor/mm_graph_node.gd @@ -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 diff --git a/game/addons/mat_maker_gd/nodes/mm_node_universal_property.gd b/game/addons/mat_maker_gd/nodes/mm_node_universal_property.gd index d79dc27a..68a7a710 100644 --- a/game/addons/mat_maker_gd/nodes/mm_node_universal_property.gd +++ b/game/addons/mat_maker_gd/nodes/mm_node_universal_property.gd @@ -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() diff --git a/game/addons/mat_maker_gd/plugin.gd b/game/addons/mat_maker_gd/plugin.gd index c3b47e16..4cabcdfd 100644 --- a/game/addons/mat_maker_gd/plugin.gd +++ b/game/addons/mat_maker_gd/plugin.gd @@ -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()