Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[3.x] SpriteFramesEditorPlugin Added zooming #48977

Merged
merged 1 commit into from
May 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
204 changes: 186 additions & 18 deletions editor/plugins/sprite_frames_editor_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
#include "editor/editor_settings.h"
#include "scene/3d/sprite_3d.h"
#include "scene/gui/center_container.h"
#include "scene/gui/margin_container.h"
#include "scene/gui/panel_container.h"

void SpriteFramesEditor::_gui_input(Ref<InputEvent> p_event) {
}
Expand Down Expand Up @@ -141,8 +143,27 @@ void SpriteFramesEditor::_sheet_preview_input(const Ref<InputEvent> &p_event) {
}
}

void SpriteFramesEditor::_sheet_scroll_input(const Ref<InputEvent> &p_event) {
const Ref<InputEventMouseButton> mb = p_event;

if (mb.is_valid()) {
// Zoom in/out using Ctrl + mouse wheel. This is done on the ScrollContainer
// to allow performing this action anywhere, even if the cursor isn't
// hovering the texture in the workspace.
if (mb->get_button_index() == BUTTON_WHEEL_UP && mb->is_pressed() && mb->get_control()) {
_sheet_zoom_in();
// Don't scroll up after zooming in.
accept_event();
} else if (mb->get_button_index() == BUTTON_WHEEL_DOWN && mb->is_pressed() && mb->get_control()) {
_sheet_zoom_out();
// Don't scroll down after zooming out.
accept_event();
}
}
}

void SpriteFramesEditor::_sheet_add_frames() {
Size2i size = split_sheet_preview->get_size();
Size2i size = split_sheet_preview->get_texture()->get_size();
int h = split_sheet_h->get_value();
int v = split_sheet_v->get_value();

Expand Down Expand Up @@ -181,6 +202,28 @@ void SpriteFramesEditor::_sheet_add_frames() {
undo_redo->commit_action();
}

void SpriteFramesEditor::_sheet_zoom_in() {
if (sheet_zoom < max_sheet_zoom) {
sheet_zoom *= scale_ratio;
Size2 texture_size = split_sheet_preview->get_texture()->get_size();
split_sheet_preview->set_custom_minimum_size(texture_size * sheet_zoom);
}
}

void SpriteFramesEditor::_sheet_zoom_out() {
if (sheet_zoom > min_sheet_zoom) {
sheet_zoom /= scale_ratio;
Size2 texture_size = split_sheet_preview->get_texture()->get_size();
split_sheet_preview->set_custom_minimum_size(texture_size * sheet_zoom);
}
}

void SpriteFramesEditor::_sheet_zoom_reset() {
sheet_zoom = 1.f;
Size2 texture_size = split_sheet_preview->get_texture()->get_size();
split_sheet_preview->set_custom_minimum_size(texture_size * sheet_zoom);
}

void SpriteFramesEditor::_sheet_select_clear_all_frames() {
bool should_clear = true;
for (int i = 0; i < split_sheet_h->get_value() * split_sheet_v->get_value(); i++) {
Expand Down Expand Up @@ -208,15 +251,18 @@ void SpriteFramesEditor::_prepare_sprite_sheet(const String &p_file) {
EditorNode::get_singleton()->show_warning(TTR("Unable to load images"));
ERR_FAIL_COND(!texture.is_valid());
}
if (texture != split_sheet_preview->get_texture()) {
//different texture, reset to 4x4
split_sheet_h->set_value(4);
split_sheet_v->set_value(4);
}
frames_selected.clear();
last_frame_selected = -1;

bool new_texture = texture != split_sheet_preview->get_texture();
split_sheet_preview->set_texture(texture);
if (new_texture) {
//different texture, reset to 4x4
split_sheet_h->set_value(4);
split_sheet_v->set_value(4);
//reset zoom
_sheet_zoom_reset();
}
split_sheet_dialog->popup_centered_ratio(0.65);
}

Expand All @@ -232,12 +278,18 @@ void SpriteFramesEditor::_notification(int p_what) {
move_up->set_icon(get_icon("MoveLeft", "EditorIcons"));
move_down->set_icon(get_icon("MoveRight", "EditorIcons"));
_delete->set_icon(get_icon("Remove", "EditorIcons"));
zoom_out->set_icon(get_icon("ZoomLess", "EditorIcons"));
zoom_reset->set_icon(get_icon("ZoomReset", "EditorIcons"));
zoom_in->set_icon(get_icon("ZoomMore", "EditorIcons"));
new_anim->set_icon(get_icon("New", "EditorIcons"));
remove_anim->set_icon(get_icon("Remove", "EditorIcons"));
split_sheet_zoom_out->set_icon(get_icon("ZoomLess", "EditorIcons"));
split_sheet_zoom_reset->set_icon(get_icon("ZoomReset", "EditorIcons"));
split_sheet_zoom_in->set_icon(get_icon("ZoomMore", "EditorIcons"));
FALLTHROUGH;
}
case NOTIFICATION_THEME_CHANGED: {
splite_sheet_scroll->add_style_override("bg", get_stylebox("bg", "Tree"));
split_sheet_scroll->add_style_override("bg", get_stylebox("bg", "Tree"));
} break;
case NOTIFICATION_READY: {
add_constant_override("autohide", 1); // Fixes the dragger always showing up.
Expand Down Expand Up @@ -638,6 +690,54 @@ void SpriteFramesEditor::_animation_fps_changed(double p_value) {
undo_redo->commit_action();
}

void SpriteFramesEditor::_tree_input(const Ref<InputEvent> &p_event) {
const Ref<InputEventMouseButton> mb = p_event;

if (mb.is_valid()) {
if (mb->get_button_index() == BUTTON_WHEEL_UP && mb->is_pressed() && mb->get_control()) {
_zoom_in();
// Don't scroll up after zooming in.
accept_event();
} else if (mb->get_button_index() == BUTTON_WHEEL_DOWN && mb->is_pressed() && mb->get_control()) {
_zoom_out();
// Don't scroll down after zooming out.
accept_event();
}
}
}

void SpriteFramesEditor::_zoom_in() {
// Do not zoom in or out with no visible frames
if (frames->get_frame_count(edited_anim) <= 0) {
return;
}
if (thumbnail_zoom < max_thumbnail_zoom) {
thumbnail_zoom *= scale_ratio;
int thumbnail_size = (int)(thumbnail_default_size * thumbnail_zoom);
tree->set_fixed_column_width(thumbnail_size * 3 / 2);
tree->set_fixed_icon_size(Size2(thumbnail_size, thumbnail_size));
}
}

void SpriteFramesEditor::_zoom_out() {
// Do not zoom in or out with no visible frames
if (frames->get_frame_count(edited_anim) <= 0) {
return;
}
if (thumbnail_zoom > min_thumbnail_zoom) {
thumbnail_zoom /= scale_ratio;
int thumbnail_size = (int)(thumbnail_default_size * thumbnail_zoom);
tree->set_fixed_column_width(thumbnail_size * 3 / 2);
tree->set_fixed_icon_size(Size2(thumbnail_size, thumbnail_size));
}
}

void SpriteFramesEditor::_zoom_reset() {
thumbnail_zoom = 1.0f;
tree->set_fixed_column_width(thumbnail_default_size * 3 / 2);
tree->set_fixed_icon_size(Size2(thumbnail_default_size, thumbnail_default_size));
}

void SpriteFramesEditor::_update_library(bool p_skip_selector) {
updating = true;

Expand Down Expand Up @@ -729,6 +829,9 @@ void SpriteFramesEditor::edit(SpriteFrames *p_frames) {
}

_update_library();
// Clear zoom and split sheet texture
split_sheet_preview->set_texture(Ref<Texture>());
_zoom_reset();
} else {
hide();
}
Expand Down Expand Up @@ -877,15 +980,23 @@ void SpriteFramesEditor::_bind_methods() {
ClassDB::bind_method(D_METHOD("_animation_remove_confirmed"), &SpriteFramesEditor::_animation_remove_confirmed);
ClassDB::bind_method(D_METHOD("_animation_loop_changed"), &SpriteFramesEditor::_animation_loop_changed);
ClassDB::bind_method(D_METHOD("_animation_fps_changed"), &SpriteFramesEditor::_animation_fps_changed);
ClassDB::bind_method(D_METHOD("_tree_input"), &SpriteFramesEditor::_tree_input);
ClassDB::bind_method(D_METHOD("_zoom_in"), &SpriteFramesEditor::_zoom_in);
ClassDB::bind_method(D_METHOD("_zoom_out"), &SpriteFramesEditor::_zoom_out);
ClassDB::bind_method(D_METHOD("_zoom_reset"), &SpriteFramesEditor::_zoom_reset);
ClassDB::bind_method(D_METHOD("get_drag_data_fw"), &SpriteFramesEditor::get_drag_data_fw);
ClassDB::bind_method(D_METHOD("can_drop_data_fw"), &SpriteFramesEditor::can_drop_data_fw);
ClassDB::bind_method(D_METHOD("drop_data_fw"), &SpriteFramesEditor::drop_data_fw);
ClassDB::bind_method(D_METHOD("_prepare_sprite_sheet"), &SpriteFramesEditor::_prepare_sprite_sheet);
ClassDB::bind_method(D_METHOD("_open_sprite_sheet"), &SpriteFramesEditor::_open_sprite_sheet);
ClassDB::bind_method(D_METHOD("_sheet_preview_draw"), &SpriteFramesEditor::_sheet_preview_draw);
ClassDB::bind_method(D_METHOD("_sheet_preview_input"), &SpriteFramesEditor::_sheet_preview_input);
ClassDB::bind_method(D_METHOD("_sheet_scroll_input"), &SpriteFramesEditor::_sheet_scroll_input);
ClassDB::bind_method(D_METHOD("_sheet_spin_changed"), &SpriteFramesEditor::_sheet_spin_changed);
ClassDB::bind_method(D_METHOD("_sheet_add_frames"), &SpriteFramesEditor::_sheet_add_frames);
ClassDB::bind_method(D_METHOD("_sheet_zoom_in"), &SpriteFramesEditor::_sheet_zoom_in);
ClassDB::bind_method(D_METHOD("_sheet_zoom_out"), &SpriteFramesEditor::_sheet_zoom_out);
ClassDB::bind_method(D_METHOD("_sheet_zoom_reset"), &SpriteFramesEditor::_sheet_zoom_reset);
ClassDB::bind_method(D_METHOD("_sheet_select_clear_all_frames"), &SpriteFramesEditor::_sheet_select_clear_all_frames);
}

Expand Down Expand Up @@ -988,19 +1099,30 @@ SpriteFramesEditor::SpriteFramesEditor() {
_delete->set_tooltip(TTR("Delete"));
hbc->add_child(_delete);

hbc->add_spacer();

zoom_out = memnew(ToolButton);
zoom_out->set_tooltip(TTR("Zoom Out"));
hbc->add_child(zoom_out);

zoom_reset = memnew(ToolButton);
zoom_reset->set_tooltip(TTR("Zoom Reset"));
hbc->add_child(zoom_reset);

zoom_in = memnew(ToolButton);
zoom_in->set_tooltip(TTR("Zoom In"));
hbc->add_child(zoom_in);

file = memnew(EditorFileDialog);
add_child(file);

tree = memnew(ItemList);
tree->set_v_size_flags(SIZE_EXPAND_FILL);
tree->set_icon_mode(ItemList::ICON_MODE_TOP);

int thumbnail_size = 96;
tree->set_max_columns(0);
tree->set_icon_mode(ItemList::ICON_MODE_TOP);
tree->set_fixed_column_width(thumbnail_size * 3 / 2);
tree->set_max_text_lines(2);
tree->set_fixed_icon_size(Size2(thumbnail_size, thumbnail_size));
tree->set_drag_forwarding(this);

sub_vb->add_child(tree);
Expand All @@ -1017,7 +1139,11 @@ SpriteFramesEditor::SpriteFramesEditor() {
empty2->connect("pressed", this, "_empty2_pressed");
move_up->connect("pressed", this, "_up_pressed");
move_down->connect("pressed", this, "_down_pressed");
zoom_in->connect("pressed", this, "_zoom_in");
zoom_out->connect("pressed", this, "_zoom_out");
zoom_reset->connect("pressed", this, "_zoom_reset");
file->connect("files_selected", this, "_file_load_request");
tree->connect("gui_input", this, "_tree_input");
loading_scene = false;
sel = -1;

Expand Down Expand Up @@ -1065,29 +1191,71 @@ SpriteFramesEditor::SpriteFramesEditor() {

split_sheet_vb->add_child(split_sheet_hb);

PanelContainer *split_sheet_panel = memnew(PanelContainer);
split_sheet_panel->set_h_size_flags(SIZE_EXPAND_FILL);
split_sheet_panel->set_v_size_flags(SIZE_EXPAND_FILL);
split_sheet_vb->add_child(split_sheet_panel);

split_sheet_preview = memnew(TextureRect);
split_sheet_preview->set_expand(false);
split_sheet_preview->set_expand(true);
split_sheet_preview->set_mouse_filter(MOUSE_FILTER_PASS);
split_sheet_preview->connect("draw", this, "_sheet_preview_draw");
split_sheet_preview->connect("gui_input", this, "_sheet_preview_input");

splite_sheet_scroll = memnew(ScrollContainer);
splite_sheet_scroll->set_enable_h_scroll(true);
splite_sheet_scroll->set_enable_v_scroll(true);
splite_sheet_scroll->set_v_size_flags(SIZE_EXPAND_FILL);
split_sheet_scroll = memnew(ScrollContainer);
split_sheet_scroll->set_enable_h_scroll(true);
split_sheet_scroll->set_enable_v_scroll(true);
split_sheet_scroll->connect("gui_input", this, "_sheet_scroll_input");
split_sheet_panel->add_child(split_sheet_scroll);
CenterContainer *cc = memnew(CenterContainer);
cc->add_child(split_sheet_preview);
cc->set_h_size_flags(SIZE_EXPAND_FILL);
cc->set_v_size_flags(SIZE_EXPAND_FILL);
splite_sheet_scroll->add_child(cc);

split_sheet_vb->add_child(splite_sheet_scroll);
split_sheet_scroll->add_child(cc);

MarginContainer *split_sheet_zoom_margin = memnew(MarginContainer);
split_sheet_panel->add_child(split_sheet_zoom_margin);
split_sheet_zoom_margin->set_h_size_flags(0);
split_sheet_zoom_margin->set_v_size_flags(0);
split_sheet_zoom_margin->add_constant_override("margin_top", 5);
split_sheet_zoom_margin->add_constant_override("margin_left", 5);
HBoxContainer *split_sheet_zoom_hb = memnew(HBoxContainer);
split_sheet_zoom_margin->add_child(split_sheet_zoom_hb);

split_sheet_zoom_out = memnew(ToolButton);
split_sheet_zoom_out->set_focus_mode(FOCUS_NONE);
split_sheet_zoom_out->set_tooltip(TTR("Zoom Out"));
split_sheet_zoom_out->connect("pressed", this, "_sheet_zoom_out");
split_sheet_zoom_hb->add_child(split_sheet_zoom_out);

split_sheet_zoom_reset = memnew(ToolButton);
split_sheet_zoom_reset->set_focus_mode(FOCUS_NONE);
split_sheet_zoom_reset->set_tooltip(TTR("Zoom Reset"));
split_sheet_zoom_reset->connect("pressed", this, "_sheet_zoom_reset");
split_sheet_zoom_hb->add_child(split_sheet_zoom_reset);

split_sheet_zoom_in = memnew(ToolButton);
split_sheet_zoom_in->set_focus_mode(FOCUS_NONE);
split_sheet_zoom_in->set_tooltip(TTR("Zoom In"));
split_sheet_zoom_in->connect("pressed", this, "_sheet_zoom_in");
split_sheet_zoom_hb->add_child(split_sheet_zoom_in);

file_split_sheet = memnew(EditorFileDialog);
file_split_sheet->set_title(TTR("Create Frames from Sprite Sheet"));
file_split_sheet->set_mode(EditorFileDialog::MODE_OPEN_FILE);
add_child(file_split_sheet);
file_split_sheet->connect("file_selected", this, "_prepare_sprite_sheet");

// Config scale.
scale_ratio = 1.2f;
thumbnail_default_size = 96;
thumbnail_zoom = 1.0f;
max_thumbnail_zoom = 8.0f;
min_thumbnail_zoom = 0.1f;
sheet_zoom = 1.0f;
max_sheet_zoom = 16.0f;
min_sheet_zoom = 0.01f;
_zoom_reset();
}

void SpriteFramesEditorPlugin::edit(Object *p_object) {
Expand Down
27 changes: 25 additions & 2 deletions editor/plugins/sprite_frames_editor_plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,13 @@ class SpriteFramesEditor : public HSplitContainer {
ToolButton *empty2;
ToolButton *move_up;
ToolButton *move_down;
ToolButton *zoom_out;
ToolButton *zoom_reset;
ToolButton *zoom_in;
ItemList *tree;
bool loading_scene;
int sel;

HSplitContainer *split;
ToolButton *new_anim;
ToolButton *remove_anim;

Expand All @@ -75,14 +77,26 @@ class SpriteFramesEditor : public HSplitContainer {
ConfirmationDialog *delete_dialog;

ConfirmationDialog *split_sheet_dialog;
ScrollContainer *splite_sheet_scroll;
ScrollContainer *split_sheet_scroll;
YeldhamDev marked this conversation as resolved.
Show resolved Hide resolved
TextureRect *split_sheet_preview;
SpinBox *split_sheet_h;
SpinBox *split_sheet_v;
ToolButton *split_sheet_zoom_out;
ToolButton *split_sheet_zoom_reset;
ToolButton *split_sheet_zoom_in;
EditorFileDialog *file_split_sheet;
Set<int> frames_selected;
int last_frame_selected;

float scale_ratio;
int thumbnail_default_size;
float thumbnail_zoom;
float max_thumbnail_zoom;
float min_thumbnail_zoom;
float sheet_zoom;
float max_sheet_zoom;
float min_sheet_zoom;

void _load_pressed();
void _load_scene_pressed();
void _file_load_request(const PoolVector<String> &p_path, int p_at_pos = -1);
Expand All @@ -103,6 +117,11 @@ class SpriteFramesEditor : public HSplitContainer {
void _animation_loop_changed();
void _animation_fps_changed(double p_value);

void _tree_input(const Ref<InputEvent> &p_event);
void _zoom_in();
void _zoom_out();
void _zoom_reset();

bool updating;

UndoRedo *undo_redo;
Expand All @@ -117,7 +136,11 @@ class SpriteFramesEditor : public HSplitContainer {
void _sheet_preview_draw();
void _sheet_spin_changed(double);
void _sheet_preview_input(const Ref<InputEvent> &p_event);
void _sheet_scroll_input(const Ref<InputEvent> &p_event);
void _sheet_add_frames();
void _sheet_zoom_in();
void _sheet_zoom_out();
void _sheet_zoom_reset();
void _sheet_select_clear_all_frames();

protected:
Expand Down