From bf22de76f76da6deac72b3dd02679a2d8f360d0e Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Sun, 11 Apr 2021 18:53:23 +0200 Subject: [PATCH] Allow selecting frames by holding down the mouse in SpriteFrames editor This complements the existing (Ctrl +) Shift + Left mouse button multiple frame (de)selection. (cherry picked from commit 5e8eb20ad60e35380eef5e3a7fed1e7955c7d6c4) --- .../plugins/sprite_frames_editor_plugin.cpp | 54 ++++++++++++++++--- editor/plugins/sprite_frames_editor_plugin.h | 1 + 2 files changed, 47 insertions(+), 8 deletions(-) diff --git a/editor/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp index 466a331304d..85c7481a989 100644 --- a/editor/plugins/sprite_frames_editor_plugin.cpp +++ b/editor/plugins/sprite_frames_editor_plugin.cpp @@ -103,17 +103,16 @@ void SpriteFramesEditor::_sheet_preview_draw() { split_sheet_dialog->get_ok()->set_text(vformat(TTR("Add %d Frame(s)"), frames_selected.size())); } void SpriteFramesEditor::_sheet_preview_input(const Ref &p_event) { - Ref mb = p_event; - + const Ref mb = p_event; if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) { - Size2i size = split_sheet_preview->get_size(); - int h = split_sheet_h->get_value(); - int v = split_sheet_v->get_value(); + const Size2i size = split_sheet_preview->get_size(); + const int h = split_sheet_h->get_value(); + const int v = split_sheet_v->get_value(); - int x = CLAMP(int(mb->get_position().x) * h / size.width, 0, h - 1); - int y = CLAMP(int(mb->get_position().y) * v / size.height, 0, v - 1); + const int x = CLAMP(int(mb->get_position().x) * h / size.width, 0, h - 1); + const int y = CLAMP(int(mb->get_position().y) * v / size.height, 0, v - 1); - int idx = h * y + x; + const int idx = h * y + x; if (mb->get_shift() && last_frame_selected >= 0) { //select multiple @@ -124,6 +123,9 @@ void SpriteFramesEditor::_sheet_preview_input(const Ref &p_event) { } for (int i = from; i <= to; i++) { + // Prevent double-toggling the same frame when moving the mouse when the mouse button is still held. + frames_toggled_by_mouse_hover.insert(idx); + if (mb->get_control()) { frames_selected.erase(i); } else { @@ -131,6 +133,9 @@ void SpriteFramesEditor::_sheet_preview_input(const Ref &p_event) { } } } else { + // Prevent double-toggling the same frame when moving the mouse when the mouse button is still held. + frames_toggled_by_mouse_hover.insert(idx); + if (frames_selected.has(idx)) { frames_selected.erase(idx); } else { @@ -141,6 +146,39 @@ void SpriteFramesEditor::_sheet_preview_input(const Ref &p_event) { last_frame_selected = idx; split_sheet_preview->update(); } + + if (mb.is_valid() && !mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) { + frames_toggled_by_mouse_hover.clear(); + } + + const Ref mm = p_event; + if (mm.is_valid() && mm->get_button_mask() & BUTTON_MASK_LEFT) { + // Select by holding down the mouse button on frames. + const Size2i size = split_sheet_preview->get_size(); + const int h = split_sheet_h->get_value(); + const int v = split_sheet_v->get_value(); + + const int x = CLAMP(int(mm->get_position().x) * h / size.width, 0, h - 1); + const int y = CLAMP(int(mm->get_position().y) * v / size.height, 0, v - 1); + + const int idx = h * y + x; + + if (!frames_toggled_by_mouse_hover.has(idx)) { + // Only allow toggling each tile once per mouse hold. + // Otherwise, the selection would constantly "flicker" in and out when moving the mouse cursor. + // The mouse button must be released before it can be toggled again. + frames_toggled_by_mouse_hover.insert(idx); + + if (frames_selected.has(idx)) { + frames_selected.erase(idx); + } else { + frames_selected.insert(idx); + } + + last_frame_selected = idx; + split_sheet_preview->update(); + } + } } void SpriteFramesEditor::_sheet_scroll_input(const Ref &p_event) { diff --git a/editor/plugins/sprite_frames_editor_plugin.h b/editor/plugins/sprite_frames_editor_plugin.h index 77e5226ea69..920fcc526af 100644 --- a/editor/plugins/sprite_frames_editor_plugin.h +++ b/editor/plugins/sprite_frames_editor_plugin.h @@ -86,6 +86,7 @@ class SpriteFramesEditor : public HSplitContainer { ToolButton *split_sheet_zoom_in; EditorFileDialog *file_split_sheet; Set frames_selected; + Set frames_toggled_by_mouse_hover; int last_frame_selected; float scale_ratio;