Improve SpriteFrameEditor frame addition ordering
This commit is contained in:
parent
c29866dbc0
commit
83d85048ea
2 changed files with 339 additions and 90 deletions
|
@ -42,6 +42,7 @@
|
||||||
#include "editor/scene_tree_dock.h"
|
#include "editor/scene_tree_dock.h"
|
||||||
#include "scene/gui/center_container.h"
|
#include "scene/gui/center_container.h"
|
||||||
#include "scene/gui/margin_container.h"
|
#include "scene/gui/margin_container.h"
|
||||||
|
#include "scene/gui/option_button.h"
|
||||||
#include "scene/gui/panel_container.h"
|
#include "scene/gui/panel_container.h"
|
||||||
#include "scene/gui/separator.h"
|
#include "scene/gui/separator.h"
|
||||||
|
|
||||||
|
@ -131,8 +132,14 @@ void SpriteFramesEditor::_sheet_preview_draw() {
|
||||||
|
|
||||||
Color accent = get_theme_color("accent_color", "Editor");
|
Color accent = get_theme_color("accent_color", "Editor");
|
||||||
|
|
||||||
for (const int &E : frames_selected) {
|
_sheet_sort_frames();
|
||||||
const int idx = E;
|
|
||||||
|
Ref<Font> font = get_theme_font(SNAME("bold"), SNAME("EditorFonts"));
|
||||||
|
int font_size = get_theme_font_size(SNAME("bold_size"), SNAME("EditorFonts"));
|
||||||
|
|
||||||
|
for (int i = 0; i < frames_ordered.size(); ++i) {
|
||||||
|
const int idx = frames_ordered[i].second;
|
||||||
|
|
||||||
const int x = idx % frame_count.x;
|
const int x = idx % frame_count.x;
|
||||||
const int y = idx / frame_count.x;
|
const int y = idx / frame_count.x;
|
||||||
const Point2 pos = draw_offset + Point2(x, y) * (draw_frame_size + draw_sep);
|
const Point2 pos = draw_offset + Point2(x, y) * (draw_frame_size + draw_sep);
|
||||||
|
@ -143,6 +150,15 @@ void SpriteFramesEditor::_sheet_preview_draw() {
|
||||||
split_sheet_preview->draw_rect(Rect2(pos + Size2(3, 3), draw_frame_size - Size2(6, 6)), accent, false);
|
split_sheet_preview->draw_rect(Rect2(pos + Size2(3, 3), draw_frame_size - Size2(6, 6)), accent, false);
|
||||||
split_sheet_preview->draw_rect(Rect2(pos + Size2(4, 4), draw_frame_size - Size2(8, 8)), Color(0, 0, 0, 1), false);
|
split_sheet_preview->draw_rect(Rect2(pos + Size2(4, 4), draw_frame_size - Size2(8, 8)), Color(0, 0, 0, 1), false);
|
||||||
split_sheet_preview->draw_rect(Rect2(pos + Size2(5, 5), draw_frame_size - Size2(10, 10)), Color(0, 0, 0, 1), false);
|
split_sheet_preview->draw_rect(Rect2(pos + Size2(5, 5), draw_frame_size - Size2(10, 10)), Color(0, 0, 0, 1), false);
|
||||||
|
|
||||||
|
const String text = itos(i);
|
||||||
|
const Vector2 string_size = font->get_string_size(text, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size);
|
||||||
|
|
||||||
|
// Stop rendering text if too large.
|
||||||
|
if (string_size.x + 6 < draw_frame_size.x && string_size.y / 2 + 10 < draw_frame_size.y) {
|
||||||
|
split_sheet_preview->draw_string_outline(font, pos + Size2(5, 7) + Size2(0, string_size.y / 2), text, HORIZONTAL_ALIGNMENT_LEFT, string_size.x, font_size, 1, Color(0, 0, 0, 1));
|
||||||
|
split_sheet_preview->draw_string(font, pos + Size2(5, 7) + Size2(0, string_size.y / 2), text, HORIZONTAL_ALIGNMENT_LEFT, string_size.x, font_size, Color(1, 1, 1));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
split_sheet_dialog->get_ok_button()->set_disabled(false);
|
split_sheet_dialog->get_ok_button()->set_disabled(false);
|
||||||
|
@ -156,21 +172,24 @@ void SpriteFramesEditor::_sheet_preview_input(const Ref<InputEvent> &p_event) {
|
||||||
|
|
||||||
if (idx != -1) {
|
if (idx != -1) {
|
||||||
if (mb->is_shift_pressed() && last_frame_selected >= 0) {
|
if (mb->is_shift_pressed() && last_frame_selected >= 0) {
|
||||||
//select multiple
|
// Select multiple frames.
|
||||||
int from = idx;
|
const int from = last_frame_selected;
|
||||||
int to = last_frame_selected;
|
const int to = idx;
|
||||||
if (from > to) {
|
|
||||||
SWAP(from, to);
|
const int diff = ABS(to - from);
|
||||||
}
|
const int dir = SIGN(to - from);
|
||||||
|
|
||||||
|
for (int i = 0; i <= diff; i++) {
|
||||||
|
const int this_idx = from + i * dir;
|
||||||
|
|
||||||
for (int i = from; i <= to; i++) {
|
|
||||||
// Prevent double-toggling the same frame when moving the mouse when the mouse button is still held.
|
// Prevent double-toggling the same frame when moving the mouse when the mouse button is still held.
|
||||||
frames_toggled_by_mouse_hover.insert(idx);
|
frames_toggled_by_mouse_hover.insert(this_idx);
|
||||||
|
|
||||||
if (mb->is_ctrl_pressed()) {
|
if (mb->is_ctrl_pressed()) {
|
||||||
frames_selected.erase(i);
|
frames_selected.erase(this_idx);
|
||||||
} else {
|
} else if (!frames_selected.has(this_idx)) {
|
||||||
frames_selected.insert(i);
|
frames_selected.insert(this_idx, selected_count);
|
||||||
|
selected_count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -180,13 +199,15 @@ void SpriteFramesEditor::_sheet_preview_input(const Ref<InputEvent> &p_event) {
|
||||||
if (frames_selected.has(idx)) {
|
if (frames_selected.has(idx)) {
|
||||||
frames_selected.erase(idx);
|
frames_selected.erase(idx);
|
||||||
} else {
|
} else {
|
||||||
frames_selected.insert(idx);
|
frames_selected.insert(idx, selected_count);
|
||||||
|
selected_count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (last_frame_selected != idx || idx != -1) {
|
if (last_frame_selected != idx || idx != -1) {
|
||||||
last_frame_selected = idx;
|
last_frame_selected = idx;
|
||||||
|
frames_need_sort = true;
|
||||||
split_sheet_preview->queue_redraw();
|
split_sheet_preview->queue_redraw();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -209,13 +230,19 @@ void SpriteFramesEditor::_sheet_preview_input(const Ref<InputEvent> &p_event) {
|
||||||
if (frames_selected.has(idx)) {
|
if (frames_selected.has(idx)) {
|
||||||
frames_selected.erase(idx);
|
frames_selected.erase(idx);
|
||||||
} else {
|
} else {
|
||||||
frames_selected.insert(idx);
|
frames_selected.insert(idx, selected_count);
|
||||||
|
selected_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
last_frame_selected = idx;
|
last_frame_selected = idx;
|
||||||
|
frames_need_sort = true;
|
||||||
split_sheet_preview->queue_redraw();
|
split_sheet_preview->queue_redraw();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (frames_selected.is_empty()) {
|
||||||
|
selected_count = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpriteFramesEditor::_sheet_scroll_input(const Ref<InputEvent> &p_event) {
|
void SpriteFramesEditor::_sheet_scroll_input(const Ref<InputEvent> &p_event) {
|
||||||
|
@ -254,8 +281,11 @@ void SpriteFramesEditor::_sheet_add_frames() {
|
||||||
undo_redo->create_action(TTR("Add Frame"), UndoRedo::MERGE_DISABLE, EditorNode::get_singleton()->get_edited_scene());
|
undo_redo->create_action(TTR("Add Frame"), UndoRedo::MERGE_DISABLE, EditorNode::get_singleton()->get_edited_scene());
|
||||||
int fc = frames->get_frame_count(edited_anim);
|
int fc = frames->get_frame_count(edited_anim);
|
||||||
|
|
||||||
for (const int &E : frames_selected) {
|
_sheet_sort_frames();
|
||||||
int idx = E;
|
|
||||||
|
for (const Pair<int, int> &pair : frames_ordered) {
|
||||||
|
const int idx = pair.second;
|
||||||
|
|
||||||
const Point2 frame_coords(idx % frame_count.x, idx / frame_count.x);
|
const Point2 frame_coords(idx % frame_count.x, idx / frame_count.x);
|
||||||
|
|
||||||
Ref<AtlasTexture> at;
|
Ref<AtlasTexture> at;
|
||||||
|
@ -300,21 +330,103 @@ void SpriteFramesEditor::_sheet_zoom_reset() {
|
||||||
split_sheet_preview->set_custom_minimum_size(texture_size * sheet_zoom);
|
split_sheet_preview->set_custom_minimum_size(texture_size * sheet_zoom);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpriteFramesEditor::_sheet_select_clear_all_frames() {
|
void SpriteFramesEditor::_sheet_order_selected(int p_option) {
|
||||||
bool should_clear = true;
|
frames_need_sort = true;
|
||||||
|
split_sheet_preview->queue_redraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpriteFramesEditor::_sheet_select_all_frames() {
|
||||||
for (int i = 0; i < split_sheet_h->get_value() * split_sheet_v->get_value(); i++) {
|
for (int i = 0; i < split_sheet_h->get_value() * split_sheet_v->get_value(); i++) {
|
||||||
if (!frames_selected.has(i)) {
|
if (!frames_selected.has(i)) {
|
||||||
frames_selected.insert(i);
|
frames_selected.insert(i, selected_count);
|
||||||
should_clear = false;
|
selected_count++;
|
||||||
|
frames_need_sort = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (should_clear) {
|
|
||||||
frames_selected.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
split_sheet_preview->queue_redraw();
|
split_sheet_preview->queue_redraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SpriteFramesEditor::_sheet_clear_all_frames() {
|
||||||
|
frames_selected.clear();
|
||||||
|
selected_count = 0;
|
||||||
|
|
||||||
|
split_sheet_preview->queue_redraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpriteFramesEditor::_sheet_sort_frames() {
|
||||||
|
if (!frames_need_sort) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
frames_need_sort = false;
|
||||||
|
frames_ordered.resize(frames_selected.size());
|
||||||
|
if (frames_selected.is_empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Size2i frame_count = _get_frame_count();
|
||||||
|
const int frame_order = split_sheet_order->get_selected_id();
|
||||||
|
int index = 0;
|
||||||
|
|
||||||
|
// Fill based on order.
|
||||||
|
for (const KeyValue<int, int> &from_pair : frames_selected) {
|
||||||
|
const int idx = from_pair.key;
|
||||||
|
|
||||||
|
const int selection_order = from_pair.value;
|
||||||
|
|
||||||
|
// Default to using selection order.
|
||||||
|
int order_by = selection_order;
|
||||||
|
|
||||||
|
// Extract coordinates for sorting.
|
||||||
|
const int pos_frame_x = idx % frame_count.x;
|
||||||
|
const int pos_frame_y = idx / frame_count.x;
|
||||||
|
|
||||||
|
const int neg_frame_x = frame_count.x - (pos_frame_x + 1);
|
||||||
|
const int neg_frame_y = frame_count.y - (pos_frame_y + 1);
|
||||||
|
|
||||||
|
switch (frame_order) {
|
||||||
|
case FRAME_ORDER_LEFT_RIGHT_TOP_BOTTOM: {
|
||||||
|
order_by = frame_count.x * pos_frame_y + pos_frame_x;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case FRAME_ORDER_LEFT_RIGHT_BOTTOM_TOP: {
|
||||||
|
order_by = frame_count.x * neg_frame_y + pos_frame_x;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case FRAME_ORDER_RIGHT_LEFT_TOP_BOTTOM: {
|
||||||
|
order_by = frame_count.x * pos_frame_y + neg_frame_x;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case FRAME_ORDER_RIGHT_LEFT_BOTTOM_TOP: {
|
||||||
|
order_by = frame_count.x * neg_frame_y + neg_frame_x;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case FRAME_ORDER_TOP_BOTTOM_LEFT_RIGHT: {
|
||||||
|
order_by = pos_frame_y + frame_count.y * pos_frame_x;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case FRAME_ORDER_TOP_BOTTOM_RIGHT_LEFT: {
|
||||||
|
order_by = pos_frame_y + frame_count.y * neg_frame_x;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case FRAME_ORDER_BOTTOM_TOP_LEFT_RIGHT: {
|
||||||
|
order_by = neg_frame_y + frame_count.y * pos_frame_x;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case FRAME_ORDER_BOTTOM_TOP_RIGHT_LEFT: {
|
||||||
|
order_by = neg_frame_y + frame_count.y * neg_frame_x;
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assign in vector.
|
||||||
|
frames_ordered.set(index, Pair<int, int>(order_by, idx));
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort frames.
|
||||||
|
frames_ordered.sort_custom<PairSort<int, int>>();
|
||||||
|
}
|
||||||
|
|
||||||
void SpriteFramesEditor::_sheet_spin_changed(double p_value, int p_dominant_param) {
|
void SpriteFramesEditor::_sheet_spin_changed(double p_value, int p_dominant_param) {
|
||||||
if (updating_split_settings) {
|
if (updating_split_settings) {
|
||||||
return;
|
return;
|
||||||
|
@ -367,10 +479,25 @@ void SpriteFramesEditor::_sheet_spin_changed(double p_value, int p_dominant_para
|
||||||
updating_split_settings = false;
|
updating_split_settings = false;
|
||||||
|
|
||||||
frames_selected.clear();
|
frames_selected.clear();
|
||||||
|
selected_count = 0;
|
||||||
last_frame_selected = -1;
|
last_frame_selected = -1;
|
||||||
split_sheet_preview->queue_redraw();
|
split_sheet_preview->queue_redraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SpriteFramesEditor::_toggle_show_settings() {
|
||||||
|
split_sheet_settings_vb->set_visible(!split_sheet_settings_vb->is_visible());
|
||||||
|
|
||||||
|
_update_show_settings();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpriteFramesEditor::_update_show_settings() {
|
||||||
|
if (is_layout_rtl()) {
|
||||||
|
toggle_settings_button->set_icon(get_theme_icon(split_sheet_settings_vb->is_visible() ? SNAME("Back") : SNAME("Forward"), SNAME("EditorIcons")));
|
||||||
|
} else {
|
||||||
|
toggle_settings_button->set_icon(get_theme_icon(split_sheet_settings_vb->is_visible() ? SNAME("Forward") : SNAME("Back"), SNAME("EditorIcons")));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SpriteFramesEditor::_prepare_sprite_sheet(const String &p_file) {
|
void SpriteFramesEditor::_prepare_sprite_sheet(const String &p_file) {
|
||||||
Ref<Texture2D> texture = ResourceLoader::load(p_file);
|
Ref<Texture2D> texture = ResourceLoader::load(p_file);
|
||||||
if (texture.is_null()) {
|
if (texture.is_null()) {
|
||||||
|
@ -378,6 +505,7 @@ void SpriteFramesEditor::_prepare_sprite_sheet(const String &p_file) {
|
||||||
ERR_FAIL_COND(texture.is_null());
|
ERR_FAIL_COND(texture.is_null());
|
||||||
}
|
}
|
||||||
frames_selected.clear();
|
frames_selected.clear();
|
||||||
|
selected_count = 0;
|
||||||
last_frame_selected = -1;
|
last_frame_selected = -1;
|
||||||
|
|
||||||
bool new_texture = texture != split_sheet_preview->get_texture();
|
bool new_texture = texture != split_sheet_preview->get_texture();
|
||||||
|
@ -408,6 +536,7 @@ void SpriteFramesEditor::_prepare_sprite_sheet(const String &p_file) {
|
||||||
// Reset zoom.
|
// Reset zoom.
|
||||||
_sheet_zoom_reset();
|
_sheet_zoom_reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
split_sheet_dialog->popup_centered_ratio(0.65);
|
split_sheet_dialog->popup_centered_ratio(0.65);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -450,6 +579,8 @@ void SpriteFramesEditor::_notification(int p_what) {
|
||||||
split_sheet_zoom_reset->set_icon(get_theme_icon(SNAME("ZoomReset"), SNAME("EditorIcons")));
|
split_sheet_zoom_reset->set_icon(get_theme_icon(SNAME("ZoomReset"), SNAME("EditorIcons")));
|
||||||
split_sheet_zoom_in->set_icon(get_theme_icon(SNAME("ZoomMore"), SNAME("EditorIcons")));
|
split_sheet_zoom_in->set_icon(get_theme_icon(SNAME("ZoomMore"), SNAME("EditorIcons")));
|
||||||
split_sheet_scroll->add_theme_style_override("panel", get_theme_stylebox(SNAME("panel"), SNAME("Tree")));
|
split_sheet_scroll->add_theme_style_override("panel", get_theme_stylebox(SNAME("panel"), SNAME("Tree")));
|
||||||
|
|
||||||
|
_update_show_settings();
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case NOTIFICATION_READY: {
|
case NOTIFICATION_READY: {
|
||||||
|
@ -1769,82 +1900,58 @@ SpriteFramesEditor::SpriteFramesEditor() {
|
||||||
|
|
||||||
split_sheet_dialog = memnew(ConfirmationDialog);
|
split_sheet_dialog = memnew(ConfirmationDialog);
|
||||||
add_child(split_sheet_dialog);
|
add_child(split_sheet_dialog);
|
||||||
VBoxContainer *split_sheet_vb = memnew(VBoxContainer);
|
|
||||||
split_sheet_dialog->add_child(split_sheet_vb);
|
|
||||||
split_sheet_dialog->set_title(TTR("Select Frames"));
|
split_sheet_dialog->set_title(TTR("Select Frames"));
|
||||||
split_sheet_dialog->connect("confirmed", callable_mp(this, &SpriteFramesEditor::_sheet_add_frames));
|
split_sheet_dialog->connect("confirmed", callable_mp(this, &SpriteFramesEditor::_sheet_add_frames));
|
||||||
|
|
||||||
HBoxContainer *split_sheet_hb = memnew(HBoxContainer);
|
HBoxContainer *split_sheet_hb = memnew(HBoxContainer);
|
||||||
|
split_sheet_dialog->add_child(split_sheet_hb);
|
||||||
|
split_sheet_hb->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||||
|
split_sheet_hb->set_v_size_flags(SIZE_EXPAND_FILL);
|
||||||
|
|
||||||
split_sheet_hb->add_child(memnew(Label(TTR("Horizontal:"))));
|
VBoxContainer *split_sheet_vb = memnew(VBoxContainer);
|
||||||
split_sheet_h = memnew(SpinBox);
|
split_sheet_hb->add_child(split_sheet_vb);
|
||||||
split_sheet_h->set_min(1);
|
split_sheet_vb->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||||
split_sheet_h->set_max(128);
|
split_sheet_vb->set_v_size_flags(SIZE_EXPAND_FILL);
|
||||||
split_sheet_h->set_step(1);
|
|
||||||
split_sheet_hb->add_child(split_sheet_h);
|
|
||||||
split_sheet_h->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_sheet_spin_changed).bind(PARAM_FRAME_COUNT));
|
|
||||||
|
|
||||||
split_sheet_hb->add_child(memnew(Label(TTR("Vertical:"))));
|
HBoxContainer *split_sheet_menu_hb = memnew(HBoxContainer);
|
||||||
split_sheet_v = memnew(SpinBox);
|
|
||||||
split_sheet_v->set_min(1);
|
|
||||||
split_sheet_v->set_max(128);
|
|
||||||
split_sheet_v->set_step(1);
|
|
||||||
split_sheet_hb->add_child(split_sheet_v);
|
|
||||||
split_sheet_v->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_sheet_spin_changed).bind(PARAM_FRAME_COUNT));
|
|
||||||
|
|
||||||
split_sheet_hb->add_child(memnew(VSeparator));
|
split_sheet_menu_hb->add_child(memnew(Label(TTR("Frame Order"))));
|
||||||
split_sheet_hb->add_child(memnew(Label(TTR("Size:"))));
|
|
||||||
split_sheet_size_x = memnew(SpinBox);
|
|
||||||
split_sheet_size_x->set_min(1);
|
|
||||||
split_sheet_size_x->set_step(1);
|
|
||||||
split_sheet_size_x->set_suffix("px");
|
|
||||||
split_sheet_size_x->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_sheet_spin_changed).bind(PARAM_SIZE));
|
|
||||||
split_sheet_hb->add_child(split_sheet_size_x);
|
|
||||||
split_sheet_size_y = memnew(SpinBox);
|
|
||||||
split_sheet_size_y->set_min(1);
|
|
||||||
split_sheet_size_y->set_step(1);
|
|
||||||
split_sheet_size_y->set_suffix("px");
|
|
||||||
split_sheet_size_y->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_sheet_spin_changed).bind(PARAM_SIZE));
|
|
||||||
split_sheet_hb->add_child(split_sheet_size_y);
|
|
||||||
|
|
||||||
split_sheet_hb->add_child(memnew(VSeparator));
|
split_sheet_order = memnew(OptionButton);
|
||||||
split_sheet_hb->add_child(memnew(Label(TTR("Separation:"))));
|
split_sheet_order->add_item(TTR("As Selected"), FRAME_ORDER_SELECTION);
|
||||||
split_sheet_sep_x = memnew(SpinBox);
|
split_sheet_order->add_separator(TTR("By Row"));
|
||||||
split_sheet_sep_x->set_min(0);
|
split_sheet_order->add_item(TTR("Left to Right, Top to Bottom"), FRAME_ORDER_LEFT_RIGHT_TOP_BOTTOM);
|
||||||
split_sheet_sep_x->set_step(1);
|
split_sheet_order->add_item(TTR("Left to Right, Bottom to Top"), FRAME_ORDER_LEFT_RIGHT_BOTTOM_TOP);
|
||||||
split_sheet_sep_x->set_suffix("px");
|
split_sheet_order->add_item(TTR("Right to Left, Top to Bottom"), FRAME_ORDER_RIGHT_LEFT_TOP_BOTTOM);
|
||||||
split_sheet_sep_x->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_sheet_spin_changed).bind(PARAM_USE_CURRENT));
|
split_sheet_order->add_item(TTR("Right to Left, Bottom to Top"), FRAME_ORDER_RIGHT_LEFT_BOTTOM_TOP);
|
||||||
split_sheet_hb->add_child(split_sheet_sep_x);
|
split_sheet_order->add_separator(TTR("By Column"));
|
||||||
split_sheet_sep_y = memnew(SpinBox);
|
split_sheet_order->add_item(TTR("Top to Bottom, Left to Right"), FRAME_ORDER_TOP_BOTTOM_LEFT_RIGHT);
|
||||||
split_sheet_sep_y->set_min(0);
|
split_sheet_order->add_item(TTR("Top to Bottom, Right to Left"), FRAME_ORDER_TOP_BOTTOM_RIGHT_LEFT);
|
||||||
split_sheet_sep_y->set_step(1);
|
split_sheet_order->add_item(TTR("Bottom to Top, Left to Right"), FRAME_ORDER_BOTTOM_TOP_LEFT_RIGHT);
|
||||||
split_sheet_sep_y->set_suffix("px");
|
split_sheet_order->add_item(TTR("Bottom to Top, Right to Left"), FRAME_ORDER_BOTTOM_TOP_RIGHT_LEFT);
|
||||||
split_sheet_sep_y->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_sheet_spin_changed).bind(PARAM_USE_CURRENT));
|
split_sheet_order->connect("item_selected", callable_mp(this, &SpriteFramesEditor::_sheet_order_selected));
|
||||||
split_sheet_hb->add_child(split_sheet_sep_y);
|
split_sheet_menu_hb->add_child(split_sheet_order);
|
||||||
|
|
||||||
split_sheet_hb->add_child(memnew(VSeparator));
|
Button *select_all = memnew(Button);
|
||||||
split_sheet_hb->add_child(memnew(Label(TTR("Offset:"))));
|
select_all->set_text(TTR("Select All"));
|
||||||
split_sheet_offset_x = memnew(SpinBox);
|
select_all->connect("pressed", callable_mp(this, &SpriteFramesEditor::_sheet_select_all_frames));
|
||||||
split_sheet_offset_x->set_min(0);
|
split_sheet_menu_hb->add_child(select_all);
|
||||||
split_sheet_offset_x->set_step(1);
|
|
||||||
split_sheet_offset_x->set_suffix("px");
|
|
||||||
split_sheet_offset_x->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_sheet_spin_changed).bind(PARAM_USE_CURRENT));
|
|
||||||
split_sheet_hb->add_child(split_sheet_offset_x);
|
|
||||||
split_sheet_offset_y = memnew(SpinBox);
|
|
||||||
split_sheet_offset_y->set_min(0);
|
|
||||||
split_sheet_offset_y->set_step(1);
|
|
||||||
split_sheet_offset_y->set_suffix("px");
|
|
||||||
split_sheet_offset_y->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_sheet_spin_changed).bind(PARAM_USE_CURRENT));
|
|
||||||
split_sheet_hb->add_child(split_sheet_offset_y);
|
|
||||||
|
|
||||||
split_sheet_hb->add_spacer();
|
Button *clear_all = memnew(Button);
|
||||||
|
clear_all->set_text(TTR("Select None"));
|
||||||
|
clear_all->connect("pressed", callable_mp(this, &SpriteFramesEditor::_sheet_clear_all_frames));
|
||||||
|
split_sheet_menu_hb->add_child(clear_all);
|
||||||
|
|
||||||
Button *select_clear_all = memnew(Button);
|
split_sheet_menu_hb->add_spacer();
|
||||||
select_clear_all->set_text(TTR("Select/Clear All Frames"));
|
|
||||||
select_clear_all->connect("pressed", callable_mp(this, &SpriteFramesEditor::_sheet_select_clear_all_frames));
|
|
||||||
split_sheet_hb->add_child(select_clear_all);
|
|
||||||
|
|
||||||
split_sheet_vb->add_child(split_sheet_hb);
|
toggle_settings_button = memnew(Button);
|
||||||
|
toggle_settings_button->set_h_size_flags(SIZE_SHRINK_END);
|
||||||
|
toggle_settings_button->set_flat(true);
|
||||||
|
toggle_settings_button->connect("pressed", callable_mp(this, &SpriteFramesEditor::_toggle_show_settings));
|
||||||
|
toggle_settings_button->set_tooltip_text(TTR("Toggle Settings Panel"));
|
||||||
|
split_sheet_menu_hb->add_child(toggle_settings_button);
|
||||||
|
|
||||||
|
split_sheet_vb->add_child(split_sheet_menu_hb);
|
||||||
|
|
||||||
PanelContainer *split_sheet_panel = memnew(PanelContainer);
|
PanelContainer *split_sheet_panel = memnew(PanelContainer);
|
||||||
split_sheet_panel->set_h_size_flags(SIZE_EXPAND_FILL);
|
split_sheet_panel->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||||
|
@ -1896,6 +2003,120 @@ SpriteFramesEditor::SpriteFramesEditor() {
|
||||||
split_sheet_zoom_in->connect("pressed", callable_mp(this, &SpriteFramesEditor::_sheet_zoom_in));
|
split_sheet_zoom_in->connect("pressed", callable_mp(this, &SpriteFramesEditor::_sheet_zoom_in));
|
||||||
split_sheet_zoom_hb->add_child(split_sheet_zoom_in);
|
split_sheet_zoom_hb->add_child(split_sheet_zoom_in);
|
||||||
|
|
||||||
|
split_sheet_settings_vb = memnew(VBoxContainer);
|
||||||
|
split_sheet_settings_vb->set_v_size_flags(SIZE_EXPAND_FILL);
|
||||||
|
|
||||||
|
HBoxContainer *split_sheet_h_hb = memnew(HBoxContainer);
|
||||||
|
split_sheet_h_hb->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||||
|
|
||||||
|
Label *split_sheet_h_label = memnew(Label(TTR("Horizontal")));
|
||||||
|
split_sheet_h_label->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||||
|
split_sheet_h_hb->add_child(split_sheet_h_label);
|
||||||
|
|
||||||
|
split_sheet_h = memnew(SpinBox);
|
||||||
|
split_sheet_h->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||||
|
split_sheet_h->set_min(1);
|
||||||
|
split_sheet_h->set_max(128);
|
||||||
|
split_sheet_h->set_step(1);
|
||||||
|
split_sheet_h_hb->add_child(split_sheet_h);
|
||||||
|
split_sheet_h->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_sheet_spin_changed).bind(PARAM_FRAME_COUNT));
|
||||||
|
split_sheet_settings_vb->add_child(split_sheet_h_hb);
|
||||||
|
|
||||||
|
HBoxContainer *split_sheet_v_hb = memnew(HBoxContainer);
|
||||||
|
split_sheet_v_hb->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||||
|
|
||||||
|
Label *split_sheet_v_label = memnew(Label(TTR("Vertical")));
|
||||||
|
split_sheet_v_label->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||||
|
split_sheet_v_hb->add_child(split_sheet_v_label);
|
||||||
|
|
||||||
|
split_sheet_v = memnew(SpinBox);
|
||||||
|
split_sheet_v->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||||
|
split_sheet_v->set_min(1);
|
||||||
|
split_sheet_v->set_max(128);
|
||||||
|
split_sheet_v->set_step(1);
|
||||||
|
split_sheet_v_hb->add_child(split_sheet_v);
|
||||||
|
split_sheet_v->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_sheet_spin_changed).bind(PARAM_FRAME_COUNT));
|
||||||
|
split_sheet_settings_vb->add_child(split_sheet_v_hb);
|
||||||
|
|
||||||
|
HBoxContainer *split_sheet_size_hb = memnew(HBoxContainer);
|
||||||
|
split_sheet_size_hb->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||||
|
|
||||||
|
Label *split_sheet_size_label = memnew(Label(TTR("Size")));
|
||||||
|
split_sheet_size_label->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||||
|
split_sheet_size_label->set_v_size_flags(SIZE_SHRINK_BEGIN);
|
||||||
|
split_sheet_size_hb->add_child(split_sheet_size_label);
|
||||||
|
|
||||||
|
VBoxContainer *split_sheet_size_vb = memnew(VBoxContainer);
|
||||||
|
split_sheet_size_vb->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||||
|
split_sheet_size_x = memnew(SpinBox);
|
||||||
|
split_sheet_size_x->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||||
|
split_sheet_size_x->set_min(1);
|
||||||
|
split_sheet_size_x->set_step(1);
|
||||||
|
split_sheet_size_x->set_suffix("px");
|
||||||
|
split_sheet_size_x->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_sheet_spin_changed).bind(PARAM_SIZE));
|
||||||
|
split_sheet_size_vb->add_child(split_sheet_size_x);
|
||||||
|
split_sheet_size_y = memnew(SpinBox);
|
||||||
|
split_sheet_size_y->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||||
|
split_sheet_size_y->set_min(1);
|
||||||
|
split_sheet_size_y->set_step(1);
|
||||||
|
split_sheet_size_y->set_suffix("px");
|
||||||
|
split_sheet_size_y->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_sheet_spin_changed).bind(PARAM_SIZE));
|
||||||
|
split_sheet_size_vb->add_child(split_sheet_size_y);
|
||||||
|
split_sheet_size_hb->add_child(split_sheet_size_vb);
|
||||||
|
split_sheet_settings_vb->add_child(split_sheet_size_hb);
|
||||||
|
|
||||||
|
HBoxContainer *split_sheet_sep_hb = memnew(HBoxContainer);
|
||||||
|
split_sheet_sep_hb->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||||
|
|
||||||
|
Label *split_sheet_sep_label = memnew(Label(TTR("Separation")));
|
||||||
|
split_sheet_sep_label->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||||
|
split_sheet_sep_label->set_v_size_flags(SIZE_SHRINK_BEGIN);
|
||||||
|
split_sheet_sep_hb->add_child(split_sheet_sep_label);
|
||||||
|
|
||||||
|
VBoxContainer *split_sheet_sep_vb = memnew(VBoxContainer);
|
||||||
|
split_sheet_sep_vb->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||||
|
split_sheet_sep_x = memnew(SpinBox);
|
||||||
|
split_sheet_sep_x->set_min(0);
|
||||||
|
split_sheet_sep_x->set_step(1);
|
||||||
|
split_sheet_sep_x->set_suffix("px");
|
||||||
|
split_sheet_sep_x->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_sheet_spin_changed).bind(PARAM_USE_CURRENT));
|
||||||
|
split_sheet_sep_vb->add_child(split_sheet_sep_x);
|
||||||
|
split_sheet_sep_y = memnew(SpinBox);
|
||||||
|
split_sheet_sep_y->set_min(0);
|
||||||
|
split_sheet_sep_y->set_step(1);
|
||||||
|
split_sheet_sep_y->set_suffix("px");
|
||||||
|
split_sheet_sep_y->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_sheet_spin_changed).bind(PARAM_USE_CURRENT));
|
||||||
|
split_sheet_sep_vb->add_child(split_sheet_sep_y);
|
||||||
|
split_sheet_sep_hb->add_child(split_sheet_sep_vb);
|
||||||
|
split_sheet_settings_vb->add_child(split_sheet_sep_hb);
|
||||||
|
|
||||||
|
HBoxContainer *split_sheet_offset_hb = memnew(HBoxContainer);
|
||||||
|
split_sheet_offset_hb->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||||
|
|
||||||
|
Label *split_sheet_offset_label = memnew(Label(TTR("Offset")));
|
||||||
|
split_sheet_offset_label->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||||
|
split_sheet_offset_label->set_v_size_flags(SIZE_SHRINK_BEGIN);
|
||||||
|
split_sheet_offset_hb->add_child(split_sheet_offset_label);
|
||||||
|
|
||||||
|
VBoxContainer *split_sheet_offset_vb = memnew(VBoxContainer);
|
||||||
|
split_sheet_offset_vb->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||||
|
split_sheet_offset_x = memnew(SpinBox);
|
||||||
|
split_sheet_offset_x->set_min(0);
|
||||||
|
split_sheet_offset_x->set_step(1);
|
||||||
|
split_sheet_offset_x->set_suffix("px");
|
||||||
|
split_sheet_offset_x->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_sheet_spin_changed).bind(PARAM_USE_CURRENT));
|
||||||
|
split_sheet_offset_vb->add_child(split_sheet_offset_x);
|
||||||
|
split_sheet_offset_y = memnew(SpinBox);
|
||||||
|
split_sheet_offset_y->set_min(0);
|
||||||
|
split_sheet_offset_y->set_step(1);
|
||||||
|
split_sheet_offset_y->set_suffix("px");
|
||||||
|
split_sheet_offset_y->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_sheet_spin_changed).bind(PARAM_USE_CURRENT));
|
||||||
|
split_sheet_offset_vb->add_child(split_sheet_offset_y);
|
||||||
|
split_sheet_offset_hb->add_child(split_sheet_offset_vb);
|
||||||
|
split_sheet_settings_vb->add_child(split_sheet_offset_hb);
|
||||||
|
|
||||||
|
split_sheet_hb->add_child(split_sheet_settings_vb);
|
||||||
|
|
||||||
file_split_sheet = memnew(EditorFileDialog);
|
file_split_sheet = memnew(EditorFileDialog);
|
||||||
file_split_sheet->set_title(TTR("Create Frames from Sprite Sheet"));
|
file_split_sheet->set_title(TTR("Create Frames from Sprite Sheet"));
|
||||||
file_split_sheet->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE);
|
file_split_sheet->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE);
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
#include "scene/gui/texture_rect.h"
|
#include "scene/gui/texture_rect.h"
|
||||||
#include "scene/gui/tree.h"
|
#include "scene/gui/tree.h"
|
||||||
|
|
||||||
|
class OptionButton;
|
||||||
class EditorFileDialog;
|
class EditorFileDialog;
|
||||||
|
|
||||||
class EditorSpriteFramesFrame : public Resource {
|
class EditorSpriteFramesFrame : public Resource {
|
||||||
|
@ -68,6 +69,22 @@ class SpriteFramesEditor : public HSplitContainer {
|
||||||
};
|
};
|
||||||
int dominant_param = PARAM_FRAME_COUNT;
|
int dominant_param = PARAM_FRAME_COUNT;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
FRAME_ORDER_SELECTION, // Order frames were selected in.
|
||||||
|
|
||||||
|
// By Row.
|
||||||
|
FRAME_ORDER_LEFT_RIGHT_TOP_BOTTOM,
|
||||||
|
FRAME_ORDER_LEFT_RIGHT_BOTTOM_TOP,
|
||||||
|
FRAME_ORDER_RIGHT_LEFT_TOP_BOTTOM,
|
||||||
|
FRAME_ORDER_RIGHT_LEFT_BOTTOM_TOP,
|
||||||
|
|
||||||
|
// By Column.
|
||||||
|
FRAME_ORDER_TOP_BOTTOM_LEFT_RIGHT,
|
||||||
|
FRAME_ORDER_TOP_BOTTOM_RIGHT_LEFT,
|
||||||
|
FRAME_ORDER_BOTTOM_TOP_LEFT_RIGHT,
|
||||||
|
FRAME_ORDER_BOTTOM_TOP_RIGHT_LEFT,
|
||||||
|
};
|
||||||
|
|
||||||
bool read_only = false;
|
bool read_only = false;
|
||||||
|
|
||||||
Ref<Texture2D> autoplay_icon;
|
Ref<Texture2D> autoplay_icon;
|
||||||
|
@ -121,6 +138,7 @@ class SpriteFramesEditor : public HSplitContainer {
|
||||||
ConfirmationDialog *split_sheet_dialog = nullptr;
|
ConfirmationDialog *split_sheet_dialog = nullptr;
|
||||||
ScrollContainer *split_sheet_scroll = nullptr;
|
ScrollContainer *split_sheet_scroll = nullptr;
|
||||||
TextureRect *split_sheet_preview = nullptr;
|
TextureRect *split_sheet_preview = nullptr;
|
||||||
|
VBoxContainer *split_sheet_settings_vb = nullptr;
|
||||||
SpinBox *split_sheet_h = nullptr;
|
SpinBox *split_sheet_h = nullptr;
|
||||||
SpinBox *split_sheet_v = nullptr;
|
SpinBox *split_sheet_v = nullptr;
|
||||||
SpinBox *split_sheet_size_x = nullptr;
|
SpinBox *split_sheet_size_x = nullptr;
|
||||||
|
@ -132,9 +150,14 @@ class SpriteFramesEditor : public HSplitContainer {
|
||||||
Button *split_sheet_zoom_out = nullptr;
|
Button *split_sheet_zoom_out = nullptr;
|
||||||
Button *split_sheet_zoom_reset = nullptr;
|
Button *split_sheet_zoom_reset = nullptr;
|
||||||
Button *split_sheet_zoom_in = nullptr;
|
Button *split_sheet_zoom_in = nullptr;
|
||||||
|
Button *toggle_settings_button = nullptr;
|
||||||
|
OptionButton *split_sheet_order = nullptr;
|
||||||
EditorFileDialog *file_split_sheet = nullptr;
|
EditorFileDialog *file_split_sheet = nullptr;
|
||||||
HashSet<int> frames_selected;
|
HashMap<int, int> frames_selected; // Key is frame index. Value is selection order.
|
||||||
HashSet<int> frames_toggled_by_mouse_hover;
|
HashSet<int> frames_toggled_by_mouse_hover;
|
||||||
|
Vector<Pair<int, int>> frames_ordered; // First is the index to be ordered by. Second is the actual frame index.
|
||||||
|
int selected_count = 0;
|
||||||
|
bool frames_need_sort = false;
|
||||||
int last_frame_selected = 0;
|
int last_frame_selected = 0;
|
||||||
|
|
||||||
float scale_ratio;
|
float scale_ratio;
|
||||||
|
@ -206,7 +229,12 @@ class SpriteFramesEditor : public HSplitContainer {
|
||||||
void _sheet_zoom_in();
|
void _sheet_zoom_in();
|
||||||
void _sheet_zoom_out();
|
void _sheet_zoom_out();
|
||||||
void _sheet_zoom_reset();
|
void _sheet_zoom_reset();
|
||||||
void _sheet_select_clear_all_frames();
|
void _sheet_order_selected(int p_option);
|
||||||
|
void _sheet_select_all_frames();
|
||||||
|
void _sheet_clear_all_frames();
|
||||||
|
void _sheet_sort_frames();
|
||||||
|
void _toggle_show_settings();
|
||||||
|
void _update_show_settings();
|
||||||
|
|
||||||
void _edit();
|
void _edit();
|
||||||
void _regist_scene_undo(EditorUndoRedoManager *undo_redo);
|
void _regist_scene_undo(EditorUndoRedoManager *undo_redo);
|
||||||
|
|
Loading…
Reference in a new issue