diff --git a/editor/scene/texture/texture_region_editor_plugin.cpp b/editor/scene/texture/texture_region_editor_plugin.cpp index 5533fc31c85..87fe3174427 100644 --- a/editor/scene/texture/texture_region_editor_plugin.cpp +++ b/editor/scene/texture/texture_region_editor_plugin.cpp @@ -295,6 +295,50 @@ void TextureRegionEditor::_set_grid_parameters_clamping(bool p_enabled) { sb_sep_y->set_allow_greater(!p_enabled); } +void TextureRegionEditor::_commit_drag() { + EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); + if (edited_margin >= 0) { + undo_redo->create_action(TTR("Set Margin")); + static Side side[4] = { SIDE_TOP, SIDE_BOTTOM, SIDE_LEFT, SIDE_RIGHT }; + if (node_ninepatch) { + undo_redo->add_do_method(node_ninepatch, "set_patch_margin", side[edited_margin], node_ninepatch->get_patch_margin(side[edited_margin])); + undo_redo->add_undo_method(node_ninepatch, "set_patch_margin", side[edited_margin], prev_margin); + } else if (res_stylebox.is_valid()) { + undo_redo->add_do_method(res_stylebox.ptr(), "set_texture_margin", side[edited_margin], res_stylebox->get_texture_margin(side[edited_margin])); + undo_redo->add_undo_method(res_stylebox.ptr(), "set_texture_margin", side[edited_margin], prev_margin); + res_stylebox->emit_changed(); + } + edited_margin = -1; + } else { + undo_redo->create_action(TTR("Set Region Rect")); + if (node_sprite_2d) { + undo_redo->add_do_method(node_sprite_2d, "set_region_rect", node_sprite_2d->get_region_rect()); + undo_redo->add_undo_method(node_sprite_2d, "set_region_rect", rect_prev); + } else if (node_sprite_3d) { + undo_redo->add_do_method(node_sprite_3d, "set_region_rect", node_sprite_3d->get_region_rect()); + undo_redo->add_undo_method(node_sprite_3d, "set_region_rect", rect_prev); + } else if (node_ninepatch) { + undo_redo->add_do_method(node_ninepatch, "set_region_rect", node_ninepatch->get_region_rect()); + undo_redo->add_undo_method(node_ninepatch, "set_region_rect", rect_prev); + } else if (res_stylebox.is_valid()) { + undo_redo->add_do_method(res_stylebox.ptr(), "set_region_rect", res_stylebox->get_region_rect()); + undo_redo->add_undo_method(res_stylebox.ptr(), "set_region_rect", rect_prev); + } else if (res_atlas_texture.is_valid()) { + undo_redo->add_do_method(res_atlas_texture.ptr(), "set_region", res_atlas_texture->get_region()); + undo_redo->add_undo_method(res_atlas_texture.ptr(), "set_region", rect_prev); + } + drag_index = -1; + } + + undo_redo->add_do_method(this, "_update_rect"); + undo_redo->add_undo_method(this, "_update_rect"); + undo_redo->add_do_method(texture_overlay, "queue_redraw"); + undo_redo->add_undo_method(texture_overlay, "queue_redraw"); + undo_redo->commit_action(); + drag = false; + creating = false; +} + void TextureRegionEditor::_texture_overlay_input(const Ref &p_input) { if (panner->gui_input(p_input, texture_overlay->get_global_rect())) { return; @@ -304,7 +348,8 @@ void TextureRegionEditor::_texture_overlay_input(const Ref &p_input) mtx.columns[2] = -draw_ofs * draw_zoom; mtx.scale_basis(Vector2(draw_zoom, draw_zoom)); - EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); + bool cancel_drag = false; + Ref mb = p_input; if (mb.is_valid()) { if (mb->get_button_index() == MouseButton::LEFT) { @@ -392,6 +437,7 @@ void TextureRegionEditor::_texture_overlay_input(const Ref &p_input) // We didn't hit anything, but we're in the autoslice mode. Handle it. Vector2 point = mtx.affine_inverse().xform(mb->get_position()); + EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); for (const Rect2 &E : autoslice_cache) { if (E.has_point(point)) { rect = E; @@ -449,74 +495,41 @@ void TextureRegionEditor::_texture_overlay_input(const Ref &p_input) } } else if (!mb->is_pressed() && drag) { - if (edited_margin >= 0) { - undo_redo->create_action(TTR("Set Margin")); - static Side side[4] = { SIDE_TOP, SIDE_BOTTOM, SIDE_LEFT, SIDE_RIGHT }; - if (node_ninepatch) { - undo_redo->add_do_method(node_ninepatch, "set_patch_margin", side[edited_margin], node_ninepatch->get_patch_margin(side[edited_margin])); - undo_redo->add_undo_method(node_ninepatch, "set_patch_margin", side[edited_margin], prev_margin); - } else if (res_stylebox.is_valid()) { - undo_redo->add_do_method(res_stylebox.ptr(), "set_texture_margin", side[edited_margin], res_stylebox->get_texture_margin(side[edited_margin])); - undo_redo->add_undo_method(res_stylebox.ptr(), "set_texture_margin", side[edited_margin], prev_margin); - res_stylebox->emit_changed(); - } - edited_margin = -1; - } else { - undo_redo->create_action(TTR("Set Region Rect")); - if (node_sprite_2d) { - undo_redo->add_do_method(node_sprite_2d, "set_region_rect", node_sprite_2d->get_region_rect()); - undo_redo->add_undo_method(node_sprite_2d, "set_region_rect", rect_prev); - } else if (node_sprite_3d) { - undo_redo->add_do_method(node_sprite_3d, "set_region_rect", node_sprite_3d->get_region_rect()); - undo_redo->add_undo_method(node_sprite_3d, "set_region_rect", rect_prev); - } else if (node_ninepatch) { - undo_redo->add_do_method(node_ninepatch, "set_region_rect", node_ninepatch->get_region_rect()); - undo_redo->add_undo_method(node_ninepatch, "set_region_rect", rect_prev); - } else if (res_stylebox.is_valid()) { - undo_redo->add_do_method(res_stylebox.ptr(), "set_region_rect", res_stylebox->get_region_rect()); - undo_redo->add_undo_method(res_stylebox.ptr(), "set_region_rect", rect_prev); - } else if (res_atlas_texture.is_valid()) { - undo_redo->add_do_method(res_atlas_texture.ptr(), "set_region", res_atlas_texture->get_region()); - undo_redo->add_undo_method(res_atlas_texture.ptr(), "set_region", rect_prev); - } - drag_index = -1; - } - undo_redo->add_do_method(this, "_update_rect"); - undo_redo->add_undo_method(this, "_update_rect"); - undo_redo->add_do_method(texture_overlay, "queue_redraw"); - undo_redo->add_undo_method(texture_overlay, "queue_redraw"); - undo_redo->commit_action(); - drag = false; - creating = false; + _commit_drag(); } + } else if (drag && mb->get_button_index() == MouseButton::RIGHT && mb->is_pressed()) { + cancel_drag = true; + } + } - } else if (mb->get_button_index() == MouseButton::RIGHT && mb->is_pressed()) { - if (drag) { - drag = false; - if (edited_margin >= 0) { - static Side side[4] = { SIDE_TOP, SIDE_BOTTOM, SIDE_LEFT, SIDE_RIGHT }; - if (node_ninepatch) { - node_ninepatch->set_patch_margin(side[edited_margin], prev_margin); - } - if (res_stylebox.is_valid()) { - res_stylebox->set_texture_margin(side[edited_margin], prev_margin); - } - edited_margin = -1; - } else { - _apply_rect(rect_prev); - rect = rect_prev; - texture_preview->queue_redraw(); - texture_overlay->queue_redraw(); - drag_index = -1; - } + if (drag && p_input.is_valid() && p_input->is_action_pressed(SNAME("ui_cancel"), false, true)) { + cancel_drag = true; + } + + if (cancel_drag) { + drag = false; + if (edited_margin >= 0) { + static Side side[4] = { SIDE_TOP, SIDE_BOTTOM, SIDE_LEFT, SIDE_RIGHT }; + if (node_ninepatch) { + node_ninepatch->set_patch_margin(side[edited_margin], prev_margin); } + if (res_stylebox.is_valid()) { + res_stylebox->set_texture_margin(side[edited_margin], prev_margin); + } + edited_margin = -1; + } else { + _apply_rect(rect_prev); + rect = rect_prev; + texture_preview->queue_redraw(); + texture_overlay->queue_redraw(); + drag_index = -1; } } Ref mm = p_input; - if (mm.is_valid()) { - if (drag) { + if (drag && mm.is_valid()) { + if (mm->get_button_mask().has_flag(MouseButtonMask::LEFT)) { if (edited_margin >= 0) { float new_margin = 0; @@ -633,6 +646,8 @@ void TextureRegionEditor::_texture_overlay_input(const Ref &p_input) } texture_preview->queue_redraw(); texture_overlay->queue_redraw(); + } else { + _commit_drag(); } } @@ -658,6 +673,12 @@ void TextureRegionEditor::_zoom_callback(float p_zoom_factor, Vector2 p_origin, _zoom_on_position(draw_zoom * p_zoom_factor, p_origin); } +void TextureRegionEditor::_input_from_window(const Ref &p_event) { + if (!drag && p_event.is_valid() && p_event->is_action_pressed(SNAME("ui_cancel"), false, true)) { + hide(); + } +} + void TextureRegionEditor::_scroll_changed(float) { if (updating_scroll) { return; @@ -862,6 +883,12 @@ void TextureRegionEditor::_notification(int p_what) { } } break; + case NOTIFICATION_WM_WINDOW_FOCUS_OUT: { + if (drag) { + _commit_drag(); + } + } break; + case NOTIFICATION_WM_WINDOW_FOCUS_IN: { // This happens when the user leaves the Editor and returns, // they could have changed the textures, so the cache is cleared. @@ -1135,6 +1162,8 @@ TextureRegionEditor::TextureRegionEditor() { set_title(TTR("Region Editor")); set_process_shortcut_input(true); set_ok_button_text(TTR("Close")); + // Handled manually, to allow canceling dragging. + set_close_on_escape(false); // A power-of-two value works better as a default grid size. snap_offset = EditorSettings::get_singleton()->get_project_metadata("texture_region_editor", "snap_offset", Vector2()); diff --git a/editor/scene/texture/texture_region_editor_plugin.h b/editor/scene/texture/texture_region_editor_plugin.h index 1ca3f3bd62b..cc7e0923b96 100644 --- a/editor/scene/texture/texture_region_editor_plugin.h +++ b/editor/scene/texture/texture_region_editor_plugin.h @@ -138,6 +138,8 @@ class TextureRegionEditor : public AcceptDialog { void _set_grid_parameters_clamping(bool p_enabled); + void _commit_drag(); + protected: void _notification(int p_what); virtual void shortcut_input(const Ref &p_event) override; @@ -147,6 +149,8 @@ protected: void _texture_overlay_draw(); void _texture_overlay_input(const Ref &p_input); + virtual void _input_from_window(const Ref &p_event) override; + Vector2 snap_point(Vector2 p_target) const; public: