|
|
@@ -150,33 +150,38 @@ void GridMapEditor::_menu_option(int p_option) {
|
|
|
options->get_popup()->set_item_checked(idx, !options->get_popup()->is_item_checked(idx));
|
|
|
} break;
|
|
|
|
|
|
- case MENU_OPTION_SELECTION_DUPLICATE:
|
|
|
- case MENU_OPTION_SELECTION_CUT: {
|
|
|
+ case MENU_OPTION_SELECTION_DUPLICATE: {
|
|
|
if (!(selection.active && input_action == INPUT_NONE)) {
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
_set_clipboard_data();
|
|
|
+ clipboard_is_move = false;
|
|
|
|
|
|
- if (p_option == MENU_OPTION_SELECTION_CUT) {
|
|
|
- _delete_selection();
|
|
|
+ if (!clipboard_items.is_empty()) {
|
|
|
+ _setup_paste_mode();
|
|
|
}
|
|
|
+ } break;
|
|
|
|
|
|
- input_action = INPUT_PASTE;
|
|
|
- paste_indicator.click = selection.click;
|
|
|
- paste_indicator.current = cursor_gridpos;
|
|
|
- paste_indicator.begin = selection.begin;
|
|
|
- paste_indicator.end = selection.end;
|
|
|
- paste_indicator.distance_from_cursor = cursor_gridpos - paste_indicator.begin;
|
|
|
- paste_indicator.orientation = 0;
|
|
|
- _update_paste_indicator();
|
|
|
+ case MENU_OPTION_SELECTION_MOVE: {
|
|
|
+ if (!(selection.active && input_action == INPUT_NONE)) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ _set_clipboard_data();
|
|
|
+ clipboard_is_move = true;
|
|
|
+
|
|
|
+ if (!clipboard_items.is_empty()) {
|
|
|
+ _delete_selection();
|
|
|
+ _setup_paste_mode();
|
|
|
+ }
|
|
|
} break;
|
|
|
case MENU_OPTION_SELECTION_CLEAR: {
|
|
|
if (!selection.active) {
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
- _delete_selection();
|
|
|
+ _delete_selection_with_undo();
|
|
|
|
|
|
} break;
|
|
|
case MENU_OPTION_SELECTION_FILL: {
|
|
|
@@ -506,6 +511,21 @@ void GridMapEditor::_delete_selection() {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
+ for (int i = selection.begin.x; i <= selection.end.x; i++) {
|
|
|
+ for (int j = selection.begin.y; j <= selection.end.y; j++) {
|
|
|
+ for (int k = selection.begin.z; k <= selection.end.z; k++) {
|
|
|
+ Vector3i selected = Vector3i(i, j, k);
|
|
|
+ node->set_cell_item(selected, GridMap::INVALID_CELL_ITEM);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void GridMapEditor::_delete_selection_with_undo() {
|
|
|
+ if (!selection.active) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
|
|
|
undo_redo->create_action(TTR("GridMap Delete Selection"));
|
|
|
for (int i = selection.begin.x; i <= selection.end.x; i++) {
|
|
|
@@ -522,6 +542,17 @@ void GridMapEditor::_delete_selection() {
|
|
|
undo_redo->commit_action();
|
|
|
}
|
|
|
|
|
|
+void GridMapEditor::_setup_paste_mode() {
|
|
|
+ input_action = INPUT_PASTE;
|
|
|
+ paste_indicator.click = selection.click;
|
|
|
+ paste_indicator.current = cursor_gridpos;
|
|
|
+ paste_indicator.begin = selection.begin;
|
|
|
+ paste_indicator.end = selection.end;
|
|
|
+ paste_indicator.distance_from_cursor = cursor_gridpos - paste_indicator.begin;
|
|
|
+ paste_indicator.orientation = 0;
|
|
|
+ _update_paste_indicator();
|
|
|
+}
|
|
|
+
|
|
|
void GridMapEditor::_fill_selection() {
|
|
|
if (!selection.active) {
|
|
|
return;
|
|
|
@@ -552,6 +583,7 @@ void GridMapEditor::_clear_clipboard_data() {
|
|
|
}
|
|
|
|
|
|
clipboard_items.clear();
|
|
|
+ clipboard_is_move = false;
|
|
|
}
|
|
|
|
|
|
void GridMapEditor::_set_clipboard_data() {
|
|
|
@@ -624,6 +656,20 @@ void GridMapEditor::_update_paste_indicator() {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+void GridMapEditor::_cancel_pending_move() {
|
|
|
+ if (input_action == INPUT_PASTE) {
|
|
|
+ if (clipboard_is_move) {
|
|
|
+ for (const ClipboardItem &item : clipboard_items) {
|
|
|
+ Vector3 original_position = paste_indicator.begin + item.grid_offset;
|
|
|
+ node->set_cell_item(Vector3i(original_position), item.cell_item, item.orientation);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ _clear_clipboard_data();
|
|
|
+ input_action = INPUT_NONE;
|
|
|
+ _update_paste_indicator();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
void GridMapEditor::_do_paste() {
|
|
|
int idx = options->get_popup()->get_item_index(MENU_OPTION_PASTE_SELECTS);
|
|
|
bool reselect = options->get_popup()->is_item_checked(idx);
|
|
|
@@ -632,7 +678,18 @@ void GridMapEditor::_do_paste() {
|
|
|
rot = node->get_basis_with_orthogonal_index(paste_indicator.orientation);
|
|
|
|
|
|
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
|
|
|
- undo_redo->create_action(TTR("GridMap Paste Selection"));
|
|
|
+
|
|
|
+ if (clipboard_is_move) {
|
|
|
+ undo_redo->create_action(TTR("GridMap Move Selection"));
|
|
|
+
|
|
|
+ for (const ClipboardItem &item : clipboard_items) {
|
|
|
+ Vector3 original_position = paste_indicator.begin + item.grid_offset;
|
|
|
+ undo_redo->add_undo_method(node, "set_cell_item", original_position, item.cell_item, item.orientation);
|
|
|
+ undo_redo->add_do_method(node, "set_cell_item", original_position, GridMap::INVALID_CELL_ITEM);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ undo_redo->create_action(TTR("GridMap Paste Selection"));
|
|
|
+ }
|
|
|
|
|
|
for (const ClipboardItem &item : clipboard_items) {
|
|
|
Vector3 position = rot.xform(item.grid_offset) + paste_indicator.current - paste_indicator.distance_from_cursor;
|
|
|
@@ -715,9 +772,7 @@ EditorPlugin::AfterGUIInput GridMapEditor::forward_spatial_input_event(Camera3D
|
|
|
// Hard key actions:
|
|
|
if (k->get_keycode() == Key::ESCAPE) {
|
|
|
if (input_action == INPUT_PASTE) {
|
|
|
- _clear_clipboard_data();
|
|
|
- input_action = INPUT_NONE;
|
|
|
- _update_paste_indicator();
|
|
|
+ _cancel_pending_move();
|
|
|
return EditorPlugin::AFTER_GUI_INPUT_STOP;
|
|
|
} else if (selection.active) {
|
|
|
_set_selection(false);
|
|
|
@@ -1058,6 +1113,8 @@ void GridMapEditor::edit(GridMap *p_gridmap) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ _cancel_pending_move();
|
|
|
+
|
|
|
node = p_gridmap;
|
|
|
|
|
|
input_action = INPUT_NONE;
|
|
|
@@ -1208,6 +1265,7 @@ void GridMapEditor::_notification(int p_what) {
|
|
|
} break;
|
|
|
|
|
|
case NOTIFICATION_EXIT_TREE: {
|
|
|
+ _cancel_pending_move();
|
|
|
_clear_clipboard_data();
|
|
|
|
|
|
for (int i = 0; i < 3; i++) {
|
|
|
@@ -1467,7 +1525,7 @@ GridMapEditor::GridMapEditor() {
|
|
|
move_action_button->set_shortcut(ED_SHORTCUT("grid_map/move_tool", TTRC("Move"), Key::X, true));
|
|
|
fill_action_button->set_accessibility_name(TTRC("Move"));
|
|
|
move_action_button->connect(SceneStringName(pressed),
|
|
|
- callable_mp(this, &GridMapEditor::_menu_option).bind(MENU_OPTION_SELECTION_CUT));
|
|
|
+ callable_mp(this, &GridMapEditor::_menu_option).bind(MENU_OPTION_SELECTION_MOVE));
|
|
|
action_buttons->add_child(move_action_button);
|
|
|
viewport_shortcut_buttons.push_back(move_action_button);
|
|
|
|
|
|
@@ -1844,6 +1902,7 @@ void GridMapEditorPlugin::make_visible(bool p_visible) {
|
|
|
EditorNode::get_bottom_panel()->make_item_visible(grid_map_editor);
|
|
|
grid_map_editor->set_process(true);
|
|
|
} else {
|
|
|
+ grid_map_editor->_cancel_pending_move();
|
|
|
grid_map_editor->_show_viewports_transform_gizmo(true);
|
|
|
panel_button->hide();
|
|
|
if (grid_map_editor->is_visible_in_tree()) {
|