Skip to content

Commit

Permalink
Add node delete action (#13)
Browse files Browse the repository at this point in the history
* add command to delete selected nodes with X

* add confirmation dialog for deleting nodes except when pressing shift
  • Loading branch information
NathanLovato authored Jun 1, 2023
1 parent 178e994 commit bf0ee46
Showing 1 changed file with 58 additions and 0 deletions.
58 changes: 58 additions & 0 deletions addons/gd-blender-3d-shortcuts/plugin.gd
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,11 @@ func _forward_3d_gui_input(camera, event):
forward = true
KEY_H:
commit_hide_nodes()
KEY_X:
if event.shift_pressed:
delete_selected_nodes()
else:
confirm_delete_selected_nodes()
else:
if event is InputEventKey:
# Not sure why event.pressed always return false for numpad keys
Expand Down Expand Up @@ -508,6 +513,59 @@ func commit_hide_nodes():
undo_redo.add_undo_method(Utils, "hide_nodes", nodes, false)
undo_redo.commit_action()

## Opens a popup dialog to confirm deletion of selected nodes.
func confirm_delete_selected_nodes():
var selected_nodes = get_editor_interface().get_selection().get_selected_nodes()
if selected_nodes.is_empty():
return

var editor_theme = get_editor_interface().get_base_control().theme
var popup = ConfirmationDialog.new()
popup.theme = editor_theme

# Setting dialog text dynamically depending on the selection to mimick Godot's normal behavior.
popup.dialog_text = "Delete "
var selection_size = selected_nodes.size()
if selection_size == 1:
popup.dialog_text += selected_nodes[0].get_name()
elif selection_size > 1:
popup.dialog_text += str(selection_size) + " nodes"
for node in selected_nodes:
if node.get_child_count() > 0:
popup.dialog_text += " and children"
break
popup.dialog_text += "?"

add_child(popup)
popup.popup_centered()
popup.canceled.connect(popup.queue_free)
popup.confirmed.connect(delete_selected_nodes)
popup.confirmed.connect(popup.queue_free)

## Instantly deletes selected nodes and creates an undo history entry.
func delete_selected_nodes():
var undo_redo = get_undo_redo()

var selected_nodes = get_editor_interface().get_selection().get_selected_nodes()
# Avoid creating an unnecessary history entry if no nodes are selected.
if selected_nodes.is_empty():
return

undo_redo.create_action("Delete Nodes", UndoRedo.MERGE_DISABLE)
for node in selected_nodes:
# We can't free nodes, they must be kept in memory for undo to work.
# That's why we use remove_child instead and call UndoRedo.add_undo_reference() below.
undo_redo.add_do_method(node.get_parent(), "remove_child", node)
undo_redo.add_undo_method(node.get_parent(), "add_child", node, true)
undo_redo.add_undo_method(node.get_parent(), "move_child", node, node.get_index())
# Every node's owner must be set upon undoing, otherwise, it won't appear in the scene dock
# and it'll be lost upon saving.
undo_redo.add_undo_method(node, "set_owner", node.owner)
for child in Utils.recursive_get_children(node):
undo_redo.add_undo_method(child, "set_owner", node.owner)
undo_redo.add_undo_reference(node)
undo_redo.commit_action()

func revert():
var nodes = get_editor_interface().get_selection().get_transformable_selected_nodes()
Utils.revert_transform(nodes, _cache_global_transforms)
Expand Down

0 comments on commit bf0ee46

Please sign in to comment.