|
@@ -265,7 +265,7 @@ void SpriteFramesEditor::_sheet_add_frames() {
|
|
|
at->set_atlas(split_sheet_preview->get_texture());
|
|
|
at->set_region(Rect2(offset + frame_coords * (frame_size + separation), frame_size));
|
|
|
|
|
|
- undo_redo->add_do_method(frames, "add_frame", edited_anim, at, -1);
|
|
|
+ undo_redo->add_do_method(frames, "add_frame", edited_anim, at, 1.0, -1);
|
|
|
undo_redo->add_undo_method(frames, "remove_frame", edited_anim, fc);
|
|
|
}
|
|
|
|
|
@@ -375,9 +375,9 @@ void SpriteFramesEditor::_sheet_spin_changed(double p_value, int p_dominant_para
|
|
|
|
|
|
void SpriteFramesEditor::_prepare_sprite_sheet(const String &p_file) {
|
|
|
Ref<Texture2D> texture = ResourceLoader::load(p_file);
|
|
|
- if (!texture.is_valid()) {
|
|
|
+ if (texture.is_null()) {
|
|
|
EditorNode::get_singleton()->show_warning(TTR("Unable to load images"));
|
|
|
- ERR_FAIL_COND(!texture.is_valid());
|
|
|
+ ERR_FAIL_COND(texture.is_null());
|
|
|
}
|
|
|
frames_selected.clear();
|
|
|
last_frame_selected = -1;
|
|
@@ -477,7 +477,7 @@ void SpriteFramesEditor::_file_load_request(const Vector<String> &p_path, int p_
|
|
|
int count = 0;
|
|
|
|
|
|
for (const Ref<Texture2D> &E : resources) {
|
|
|
- undo_redo->add_do_method(frames, "add_frame", edited_anim, E, p_at_pos == -1 ? -1 : p_at_pos + count);
|
|
|
+ undo_redo->add_do_method(frames, "add_frame", edited_anim, E, 1.0, p_at_pos == -1 ? -1 : p_at_pos + count);
|
|
|
undo_redo->add_undo_method(frames, "remove_frame", edited_anim, p_at_pos == -1 ? fc : p_at_pos);
|
|
|
count++;
|
|
|
}
|
|
@@ -521,8 +521,18 @@ void SpriteFramesEditor::_load_pressed() {
|
|
|
void SpriteFramesEditor::_paste_pressed() {
|
|
|
ERR_FAIL_COND(!frames->has_animation(edited_anim));
|
|
|
|
|
|
- Ref<Texture2D> r = EditorSettings::get_singleton()->get_resource_clipboard();
|
|
|
- if (!r.is_valid()) {
|
|
|
+ Ref<Texture2D> texture;
|
|
|
+ float duration = 1.0;
|
|
|
+
|
|
|
+ Ref<EditorSpriteFramesFrame> frame = EditorSettings::get_singleton()->get_resource_clipboard();
|
|
|
+ if (frame.is_valid()) {
|
|
|
+ texture = frame->texture;
|
|
|
+ duration = frame->duration;
|
|
|
+ } else {
|
|
|
+ texture = EditorSettings::get_singleton()->get_resource_clipboard();
|
|
|
+ }
|
|
|
+
|
|
|
+ if (texture.is_null()) {
|
|
|
dialog->set_text(TTR("Resource clipboard is empty or not a texture!"));
|
|
|
dialog->set_title(TTR("Error!"));
|
|
|
//dialog->get_cancel()->set_text("Close");
|
|
@@ -533,7 +543,7 @@ void SpriteFramesEditor::_paste_pressed() {
|
|
|
|
|
|
Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
|
|
|
undo_redo->create_action(TTR("Paste Frame"));
|
|
|
- undo_redo->add_do_method(frames, "add_frame", edited_anim, r);
|
|
|
+ undo_redo->add_do_method(frames, "add_frame", edited_anim, texture, duration);
|
|
|
undo_redo->add_undo_method(frames, "remove_frame", edited_anim, frames->get_frame_count(edited_anim));
|
|
|
undo_redo->add_do_method(this, "_update_library");
|
|
|
undo_redo->add_undo_method(this, "_update_library");
|
|
@@ -543,15 +553,20 @@ void SpriteFramesEditor::_paste_pressed() {
|
|
|
void SpriteFramesEditor::_copy_pressed() {
|
|
|
ERR_FAIL_COND(!frames->has_animation(edited_anim));
|
|
|
|
|
|
- if (tree->get_current() < 0) {
|
|
|
+ if (frame_list->get_current() < 0) {
|
|
|
return;
|
|
|
}
|
|
|
- Ref<Texture2D> r = frames->get_frame(edited_anim, tree->get_current());
|
|
|
- if (!r.is_valid()) {
|
|
|
+
|
|
|
+ Ref<Texture2D> texture = frames->get_frame_texture(edited_anim, frame_list->get_current());
|
|
|
+ if (texture.is_null()) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- EditorSettings::get_singleton()->set_resource_clipboard(r);
|
|
|
+ Ref<EditorSpriteFramesFrame> frame = memnew(EditorSpriteFramesFrame);
|
|
|
+ frame->texture = texture;
|
|
|
+ frame->duration = frames->get_frame_duration(edited_anim, frame_list->get_current());
|
|
|
+
|
|
|
+ EditorSettings::get_singleton()->set_resource_clipboard(frame);
|
|
|
}
|
|
|
|
|
|
void SpriteFramesEditor::_empty_pressed() {
|
|
@@ -559,19 +574,19 @@ void SpriteFramesEditor::_empty_pressed() {
|
|
|
|
|
|
int from = -1;
|
|
|
|
|
|
- if (tree->get_current() >= 0) {
|
|
|
- from = tree->get_current();
|
|
|
+ if (frame_list->get_current() >= 0) {
|
|
|
+ from = frame_list->get_current();
|
|
|
sel = from;
|
|
|
|
|
|
} else {
|
|
|
from = frames->get_frame_count(edited_anim);
|
|
|
}
|
|
|
|
|
|
- Ref<Texture2D> r;
|
|
|
+ Ref<Texture2D> texture;
|
|
|
|
|
|
Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
|
|
|
undo_redo->create_action(TTR("Add Empty"));
|
|
|
- undo_redo->add_do_method(frames, "add_frame", edited_anim, r, from);
|
|
|
+ undo_redo->add_do_method(frames, "add_frame", edited_anim, texture, 1.0, from);
|
|
|
undo_redo->add_undo_method(frames, "remove_frame", edited_anim, from);
|
|
|
undo_redo->add_do_method(this, "_update_library");
|
|
|
undo_redo->add_undo_method(this, "_update_library");
|
|
@@ -583,19 +598,19 @@ void SpriteFramesEditor::_empty2_pressed() {
|
|
|
|
|
|
int from = -1;
|
|
|
|
|
|
- if (tree->get_current() >= 0) {
|
|
|
- from = tree->get_current();
|
|
|
+ if (frame_list->get_current() >= 0) {
|
|
|
+ from = frame_list->get_current();
|
|
|
sel = from;
|
|
|
|
|
|
} else {
|
|
|
from = frames->get_frame_count(edited_anim);
|
|
|
}
|
|
|
|
|
|
- Ref<Texture2D> r;
|
|
|
+ Ref<Texture2D> texture;
|
|
|
|
|
|
Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
|
|
|
undo_redo->create_action(TTR("Add Empty"));
|
|
|
- undo_redo->add_do_method(frames, "add_frame", edited_anim, r, from + 1);
|
|
|
+ undo_redo->add_do_method(frames, "add_frame", edited_anim, texture, 1.0, from + 1);
|
|
|
undo_redo->add_undo_method(frames, "remove_frame", edited_anim, from + 1);
|
|
|
undo_redo->add_do_method(this, "_update_library");
|
|
|
undo_redo->add_undo_method(this, "_update_library");
|
|
@@ -605,11 +620,11 @@ void SpriteFramesEditor::_empty2_pressed() {
|
|
|
void SpriteFramesEditor::_up_pressed() {
|
|
|
ERR_FAIL_COND(!frames->has_animation(edited_anim));
|
|
|
|
|
|
- if (tree->get_current() < 0) {
|
|
|
+ if (frame_list->get_current() < 0) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- int to_move = tree->get_current();
|
|
|
+ int to_move = frame_list->get_current();
|
|
|
if (to_move < 1) {
|
|
|
return;
|
|
|
}
|
|
@@ -618,11 +633,11 @@ void SpriteFramesEditor::_up_pressed() {
|
|
|
sel -= 1;
|
|
|
|
|
|
Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
|
|
|
- undo_redo->create_action(TTR("Delete Resource"));
|
|
|
- undo_redo->add_do_method(frames, "set_frame", edited_anim, to_move, frames->get_frame(edited_anim, to_move - 1));
|
|
|
- undo_redo->add_do_method(frames, "set_frame", edited_anim, to_move - 1, frames->get_frame(edited_anim, to_move));
|
|
|
- undo_redo->add_undo_method(frames, "set_frame", edited_anim, to_move, frames->get_frame(edited_anim, to_move));
|
|
|
- undo_redo->add_undo_method(frames, "set_frame", edited_anim, to_move - 1, frames->get_frame(edited_anim, to_move - 1));
|
|
|
+ undo_redo->create_action(TTR("Move Frame"));
|
|
|
+ undo_redo->add_do_method(frames, "set_frame", edited_anim, to_move, frames->get_frame_texture(edited_anim, to_move - 1), frames->get_frame_duration(edited_anim, to_move - 1));
|
|
|
+ undo_redo->add_do_method(frames, "set_frame", edited_anim, to_move - 1, frames->get_frame_texture(edited_anim, to_move), frames->get_frame_duration(edited_anim, to_move));
|
|
|
+ undo_redo->add_undo_method(frames, "set_frame", edited_anim, to_move, frames->get_frame_texture(edited_anim, to_move), frames->get_frame_duration(edited_anim, to_move));
|
|
|
+ undo_redo->add_undo_method(frames, "set_frame", edited_anim, to_move - 1, frames->get_frame_texture(edited_anim, to_move - 1), frames->get_frame_duration(edited_anim, to_move - 1));
|
|
|
undo_redo->add_do_method(this, "_update_library");
|
|
|
undo_redo->add_undo_method(this, "_update_library");
|
|
|
undo_redo->commit_action();
|
|
@@ -631,11 +646,11 @@ void SpriteFramesEditor::_up_pressed() {
|
|
|
void SpriteFramesEditor::_down_pressed() {
|
|
|
ERR_FAIL_COND(!frames->has_animation(edited_anim));
|
|
|
|
|
|
- if (tree->get_current() < 0) {
|
|
|
+ if (frame_list->get_current() < 0) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- int to_move = tree->get_current();
|
|
|
+ int to_move = frame_list->get_current();
|
|
|
if (to_move < 0 || to_move >= frames->get_frame_count(edited_anim) - 1) {
|
|
|
return;
|
|
|
}
|
|
@@ -644,11 +659,11 @@ void SpriteFramesEditor::_down_pressed() {
|
|
|
sel += 1;
|
|
|
|
|
|
Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
|
|
|
- undo_redo->create_action(TTR("Delete Resource"));
|
|
|
- undo_redo->add_do_method(frames, "set_frame", edited_anim, to_move, frames->get_frame(edited_anim, to_move + 1));
|
|
|
- undo_redo->add_do_method(frames, "set_frame", edited_anim, to_move + 1, frames->get_frame(edited_anim, to_move));
|
|
|
- undo_redo->add_undo_method(frames, "set_frame", edited_anim, to_move, frames->get_frame(edited_anim, to_move));
|
|
|
- undo_redo->add_undo_method(frames, "set_frame", edited_anim, to_move + 1, frames->get_frame(edited_anim, to_move + 1));
|
|
|
+ undo_redo->create_action(TTR("Move Frame"));
|
|
|
+ undo_redo->add_do_method(frames, "set_frame", edited_anim, to_move, frames->get_frame_texture(edited_anim, to_move + 1), frames->get_frame_duration(edited_anim, to_move + 1));
|
|
|
+ undo_redo->add_do_method(frames, "set_frame", edited_anim, to_move + 1, frames->get_frame_texture(edited_anim, to_move), frames->get_frame_duration(edited_anim, to_move));
|
|
|
+ undo_redo->add_undo_method(frames, "set_frame", edited_anim, to_move, frames->get_frame_texture(edited_anim, to_move), frames->get_frame_duration(edited_anim, to_move));
|
|
|
+ undo_redo->add_undo_method(frames, "set_frame", edited_anim, to_move + 1, frames->get_frame_texture(edited_anim, to_move + 1), frames->get_frame_duration(edited_anim, to_move + 1));
|
|
|
undo_redo->add_do_method(this, "_update_library");
|
|
|
undo_redo->add_undo_method(this, "_update_library");
|
|
|
undo_redo->commit_action();
|
|
@@ -657,11 +672,11 @@ void SpriteFramesEditor::_down_pressed() {
|
|
|
void SpriteFramesEditor::_delete_pressed() {
|
|
|
ERR_FAIL_COND(!frames->has_animation(edited_anim));
|
|
|
|
|
|
- if (tree->get_current() < 0) {
|
|
|
+ if (frame_list->get_current() < 0) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- int to_delete = tree->get_current();
|
|
|
+ int to_delete = frame_list->get_current();
|
|
|
if (to_delete < 0 || to_delete >= frames->get_frame_count(edited_anim)) {
|
|
|
return;
|
|
|
}
|
|
@@ -669,7 +684,7 @@ void SpriteFramesEditor::_delete_pressed() {
|
|
|
Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
|
|
|
undo_redo->create_action(TTR("Delete Resource"));
|
|
|
undo_redo->add_do_method(frames, "remove_frame", edited_anim, to_delete);
|
|
|
- undo_redo->add_undo_method(frames, "add_frame", edited_anim, frames->get_frame(edited_anim, to_delete), to_delete);
|
|
|
+ undo_redo->add_undo_method(frames, "add_frame", edited_anim, frames->get_frame_texture(edited_anim, to_delete), frames->get_frame_duration(edited_anim, to_delete), to_delete);
|
|
|
undo_redo->add_do_method(this, "_update_library");
|
|
|
undo_redo->add_undo_method(this, "_update_library");
|
|
|
undo_redo->commit_action();
|
|
@@ -683,7 +698,7 @@ void SpriteFramesEditor::_animation_select() {
|
|
|
if (frames->has_animation(edited_anim)) {
|
|
|
double value = anim_speed->get_line_edit()->get_text().to_float();
|
|
|
if (!Math::is_equal_approx(value, (double)frames->get_animation_speed(edited_anim))) {
|
|
|
- _animation_fps_changed(value);
|
|
|
+ _animation_speed_changed(value);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -824,8 +839,9 @@ void SpriteFramesEditor::_animation_remove_confirmed() {
|
|
|
undo_redo->add_undo_method(frames, "set_animation_loop", edited_anim, frames->get_animation_loop(edited_anim));
|
|
|
int fc = frames->get_frame_count(edited_anim);
|
|
|
for (int i = 0; i < fc; i++) {
|
|
|
- Ref<Texture2D> frame = frames->get_frame(edited_anim, i);
|
|
|
- undo_redo->add_undo_method(frames, "add_frame", edited_anim, frame);
|
|
|
+ Ref<Texture2D> texture = frames->get_frame_texture(edited_anim, i);
|
|
|
+ float duration = frames->get_frame_duration(edited_anim, i);
|
|
|
+ undo_redo->add_undo_method(frames, "add_frame", edited_anim, texture, duration);
|
|
|
}
|
|
|
undo_redo->add_do_method(this, "_update_library");
|
|
|
undo_redo->add_undo_method(this, "_update_library");
|
|
@@ -853,7 +869,7 @@ void SpriteFramesEditor::_animation_loop_changed() {
|
|
|
undo_redo->commit_action();
|
|
|
}
|
|
|
|
|
|
-void SpriteFramesEditor::_animation_fps_changed(double p_value) {
|
|
|
+void SpriteFramesEditor::_animation_speed_changed(double p_value) {
|
|
|
if (updating) {
|
|
|
return;
|
|
|
}
|
|
@@ -864,11 +880,10 @@ void SpriteFramesEditor::_animation_fps_changed(double p_value) {
|
|
|
undo_redo->add_undo_method(frames, "set_animation_speed", edited_anim, frames->get_animation_speed(edited_anim));
|
|
|
undo_redo->add_do_method(this, "_update_library", true);
|
|
|
undo_redo->add_undo_method(this, "_update_library", true);
|
|
|
-
|
|
|
undo_redo->commit_action();
|
|
|
}
|
|
|
|
|
|
-void SpriteFramesEditor::_tree_input(const Ref<InputEvent> &p_event) {
|
|
|
+void SpriteFramesEditor::_frame_list_gui_input(const Ref<InputEvent> &p_event) {
|
|
|
const Ref<InputEventMouseButton> mb = p_event;
|
|
|
|
|
|
if (mb.is_valid()) {
|
|
@@ -884,6 +899,42 @@ void SpriteFramesEditor::_tree_input(const Ref<InputEvent> &p_event) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+void SpriteFramesEditor::_frame_list_item_selected(int p_index) {
|
|
|
+ if (updating) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ sel = p_index;
|
|
|
+
|
|
|
+ updating = true;
|
|
|
+ frame_duration->set_value(frames->get_frame_duration(edited_anim, p_index));
|
|
|
+ updating = false;
|
|
|
+}
|
|
|
+
|
|
|
+void SpriteFramesEditor::_frame_duration_changed(double p_value) {
|
|
|
+ if (updating) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ int index = frame_list->get_current();
|
|
|
+ if (index < 0) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ sel = index;
|
|
|
+
|
|
|
+ Ref<Texture2D> texture = frames->get_frame_texture(edited_anim, index);
|
|
|
+ float old_duration = frames->get_frame_duration(edited_anim, index);
|
|
|
+
|
|
|
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
|
|
|
+ undo_redo->create_action(TTR("Set Frame Duration"));
|
|
|
+ undo_redo->add_do_method(frames, "set_frame", edited_anim, index, texture, p_value);
|
|
|
+ undo_redo->add_undo_method(frames, "set_frame", edited_anim, index, texture, old_duration);
|
|
|
+ undo_redo->add_do_method(this, "_update_library");
|
|
|
+ undo_redo->add_undo_method(this, "_update_library");
|
|
|
+ undo_redo->commit_action();
|
|
|
+}
|
|
|
+
|
|
|
void SpriteFramesEditor::_zoom_in() {
|
|
|
// Do not zoom in or out with no visible frames
|
|
|
if (frames->get_frame_count(edited_anim) <= 0) {
|
|
@@ -892,8 +943,8 @@ void SpriteFramesEditor::_zoom_in() {
|
|
|
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));
|
|
|
+ frame_list->set_fixed_column_width(thumbnail_size * 3 / 2);
|
|
|
+ frame_list->set_fixed_icon_size(Size2(thumbnail_size, thumbnail_size));
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -905,20 +956,22 @@ void SpriteFramesEditor::_zoom_out() {
|
|
|
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));
|
|
|
+ frame_list->set_fixed_column_width(thumbnail_size * 3 / 2);
|
|
|
+ frame_list->set_fixed_icon_size(Size2(thumbnail_size, thumbnail_size));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void SpriteFramesEditor::_zoom_reset() {
|
|
|
thumbnail_zoom = MAX(1.0f, EDSCALE);
|
|
|
- tree->set_fixed_column_width(thumbnail_default_size * 3 / 2);
|
|
|
- tree->set_fixed_icon_size(Size2(thumbnail_default_size, thumbnail_default_size));
|
|
|
+ frame_list->set_fixed_column_width(thumbnail_default_size * 3 / 2);
|
|
|
+ frame_list->set_fixed_icon_size(Size2(thumbnail_default_size, thumbnail_default_size));
|
|
|
}
|
|
|
|
|
|
void SpriteFramesEditor::_update_library(bool p_skip_selector) {
|
|
|
updating = true;
|
|
|
|
|
|
+ frame_duration->set_value(1.0); // Default.
|
|
|
+
|
|
|
if (!p_skip_selector) {
|
|
|
animations->clear();
|
|
|
|
|
@@ -951,7 +1004,7 @@ void SpriteFramesEditor::_update_library(bool p_skip_selector) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- tree->clear();
|
|
|
+ frame_list->clear();
|
|
|
|
|
|
if (!frames->has_animation(edited_anim)) {
|
|
|
updating = false;
|
|
@@ -966,33 +1019,39 @@ void SpriteFramesEditor::_update_library(bool p_skip_selector) {
|
|
|
|
|
|
for (int i = 0; i < frames->get_frame_count(edited_anim); i++) {
|
|
|
String name;
|
|
|
- Ref<Texture2D> frame = frames->get_frame(edited_anim, i);
|
|
|
+ Ref<Texture2D> texture = frames->get_frame_texture(edited_anim, i);
|
|
|
+ float duration = frames->get_frame_duration(edited_anim, i);
|
|
|
+ String duration_string;
|
|
|
+ if (duration != 1.0f) {
|
|
|
+ duration_string = String::utf8(" [ ×") + String::num_real(frames->get_frame_duration(edited_anim, i)) + " ]";
|
|
|
+ }
|
|
|
|
|
|
- if (frame.is_null()) {
|
|
|
- name = itos(i) + ": " + TTR("(empty)");
|
|
|
+ if (texture.is_null()) {
|
|
|
+ name = itos(i) + ": " + TTR("(empty)") + duration_string;
|
|
|
} else {
|
|
|
- name = itos(i) + ": " + frame->get_name();
|
|
|
+ name = itos(i) + ": " + texture->get_name() + duration_string;
|
|
|
}
|
|
|
|
|
|
- tree->add_item(name, frame);
|
|
|
- if (frame.is_valid()) {
|
|
|
- String tooltip = frame->get_path();
|
|
|
+ frame_list->add_item(name, texture);
|
|
|
+ if (texture.is_valid()) {
|
|
|
+ String tooltip = texture->get_path();
|
|
|
|
|
|
// Frame is often saved as an AtlasTexture subresource within a scene/resource file,
|
|
|
// thus its path might be not what the user is looking for. So we're also showing
|
|
|
// subsequent source texture paths.
|
|
|
String prefix = String::utf8("┖╴");
|
|
|
- Ref<AtlasTexture> at = frame;
|
|
|
+ Ref<AtlasTexture> at = texture;
|
|
|
while (at.is_valid() && at->get_atlas().is_valid()) {
|
|
|
tooltip += "\n" + prefix + at->get_atlas()->get_path();
|
|
|
prefix = " " + prefix;
|
|
|
at = at->get_atlas();
|
|
|
}
|
|
|
|
|
|
- tree->set_item_tooltip(-1, tooltip);
|
|
|
+ frame_list->set_item_tooltip(-1, tooltip);
|
|
|
}
|
|
|
if (sel == i) {
|
|
|
- tree->select(tree->get_item_count() - 1);
|
|
|
+ frame_list->select(frame_list->get_item_count() - 1);
|
|
|
+ frame_duration->set_value(frames->get_frame_duration(edited_anim, i));
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -1059,13 +1118,13 @@ Variant SpriteFramesEditor::get_drag_data_fw(const Point2 &p_point, Control *p_f
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
- int idx = tree->get_item_at_position(p_point, true);
|
|
|
+ int idx = frame_list->get_item_at_position(p_point, true);
|
|
|
|
|
|
if (idx < 0 || idx >= frames->get_frame_count(edited_anim)) {
|
|
|
return Variant();
|
|
|
}
|
|
|
|
|
|
- Ref<Resource> frame = frames->get_frame(edited_anim, idx);
|
|
|
+ Ref<Resource> frame = frames->get_frame_texture(edited_anim, idx);
|
|
|
|
|
|
if (frame.is_null()) {
|
|
|
return Variant();
|
|
@@ -1088,7 +1147,7 @@ bool SpriteFramesEditor::can_drop_data_fw(const Point2 &p_point, const Variant &
|
|
|
}
|
|
|
|
|
|
// reordering frames
|
|
|
- if (d.has("from") && (Object *)(d["from"]) == tree) {
|
|
|
+ if (d.has("from") && (Object *)(d["from"]) == frame_list) {
|
|
|
return true;
|
|
|
}
|
|
|
|
|
@@ -1134,7 +1193,7 @@ void SpriteFramesEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- int at_pos = tree->get_item_at_position(p_point, true);
|
|
|
+ int at_pos = frame_list->get_item_at_position(p_point, true);
|
|
|
|
|
|
if (String(d["type"]) == "resource" && d.has("resource")) {
|
|
|
Ref<Resource> r = d["resource"];
|
|
@@ -1143,28 +1202,30 @@ void SpriteFramesEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
|
|
|
|
|
|
if (texture.is_valid()) {
|
|
|
bool reorder = false;
|
|
|
- if (d.has("from") && (Object *)(d["from"]) == tree) {
|
|
|
+ if (d.has("from") && (Object *)(d["from"]) == frame_list) {
|
|
|
reorder = true;
|
|
|
}
|
|
|
|
|
|
Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
|
|
|
if (reorder) { //drop is from reordering frames
|
|
|
int from_frame = -1;
|
|
|
+ float duration = 1.0;
|
|
|
if (d.has("frame")) {
|
|
|
from_frame = d["frame"];
|
|
|
+ duration = frames->get_frame_duration(edited_anim, from_frame);
|
|
|
}
|
|
|
|
|
|
undo_redo->create_action(TTR("Move Frame"));
|
|
|
undo_redo->add_do_method(frames, "remove_frame", edited_anim, from_frame == -1 ? frames->get_frame_count(edited_anim) : from_frame);
|
|
|
- undo_redo->add_do_method(frames, "add_frame", edited_anim, texture, at_pos == -1 ? -1 : at_pos);
|
|
|
+ undo_redo->add_do_method(frames, "add_frame", edited_anim, texture, duration, at_pos == -1 ? -1 : at_pos);
|
|
|
undo_redo->add_undo_method(frames, "remove_frame", edited_anim, at_pos == -1 ? frames->get_frame_count(edited_anim) - 1 : at_pos);
|
|
|
- undo_redo->add_undo_method(frames, "add_frame", edited_anim, texture, from_frame);
|
|
|
+ undo_redo->add_undo_method(frames, "add_frame", edited_anim, texture, duration, from_frame);
|
|
|
undo_redo->add_do_method(this, "_update_library");
|
|
|
undo_redo->add_undo_method(this, "_update_library");
|
|
|
undo_redo->commit_action();
|
|
|
} else {
|
|
|
undo_redo->create_action(TTR("Add Frame"));
|
|
|
- undo_redo->add_do_method(frames, "add_frame", edited_anim, texture, at_pos == -1 ? -1 : at_pos);
|
|
|
+ undo_redo->add_do_method(frames, "add_frame", edited_anim, texture, 1.0, at_pos == -1 ? -1 : at_pos);
|
|
|
undo_redo->add_undo_method(frames, "remove_frame", edited_anim, at_pos == -1 ? frames->get_frame_count(edited_anim) : at_pos);
|
|
|
undo_redo->add_do_method(this, "_update_library");
|
|
|
undo_redo->add_undo_method(this, "_update_library");
|
|
@@ -1240,11 +1301,11 @@ SpriteFramesEditor::SpriteFramesEditor() {
|
|
|
anim_speed = memnew(SpinBox);
|
|
|
anim_speed->set_suffix(TTR("FPS"));
|
|
|
anim_speed->set_min(0);
|
|
|
- anim_speed->set_max(100);
|
|
|
+ anim_speed->set_max(120);
|
|
|
anim_speed->set_step(0.01);
|
|
|
anim_speed->set_h_size_flags(SIZE_EXPAND_FILL);
|
|
|
hbc_anim_speed->add_child(anim_speed);
|
|
|
- anim_speed->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_animation_fps_changed));
|
|
|
+ anim_speed->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_animation_speed_changed));
|
|
|
|
|
|
anim_loop = memnew(CheckButton);
|
|
|
anim_loop->set_text(TTR("Loop"));
|
|
@@ -1303,6 +1364,20 @@ SpriteFramesEditor::SpriteFramesEditor() {
|
|
|
delete_frame->set_flat(true);
|
|
|
hbc->add_child(delete_frame);
|
|
|
|
|
|
+ hbc->add_child(memnew(VSeparator));
|
|
|
+
|
|
|
+ Label *label = memnew(Label);
|
|
|
+ label->set_text(TTR("Frame Duration:"));
|
|
|
+ hbc->add_child(label);
|
|
|
+
|
|
|
+ frame_duration = memnew(SpinBox);
|
|
|
+ frame_duration->set_prefix(String::utf8("×"));
|
|
|
+ frame_duration->set_min(0);
|
|
|
+ frame_duration->set_max(10);
|
|
|
+ frame_duration->set_step(0.01);
|
|
|
+ frame_duration->set_allow_greater(true);
|
|
|
+ hbc->add_child(frame_duration);
|
|
|
+
|
|
|
hbc->add_spacer();
|
|
|
|
|
|
zoom_out = memnew(Button);
|
|
@@ -1326,17 +1401,18 @@ SpriteFramesEditor::SpriteFramesEditor() {
|
|
|
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);
|
|
|
+ frame_list = memnew(ItemList);
|
|
|
+ frame_list->set_v_size_flags(SIZE_EXPAND_FILL);
|
|
|
+ frame_list->set_icon_mode(ItemList::ICON_MODE_TOP);
|
|
|
|
|
|
- tree->set_max_columns(0);
|
|
|
- tree->set_icon_mode(ItemList::ICON_MODE_TOP);
|
|
|
- tree->set_max_text_lines(2);
|
|
|
- tree->set_drag_forwarding(this);
|
|
|
- tree->connect("gui_input", callable_mp(this, &SpriteFramesEditor::_tree_input));
|
|
|
+ frame_list->set_max_columns(0);
|
|
|
+ frame_list->set_icon_mode(ItemList::ICON_MODE_TOP);
|
|
|
+ frame_list->set_max_text_lines(2);
|
|
|
+ frame_list->set_drag_forwarding(this);
|
|
|
+ frame_list->connect("gui_input", callable_mp(this, &SpriteFramesEditor::_frame_list_gui_input));
|
|
|
+ frame_list->connect("item_selected", callable_mp(this, &SpriteFramesEditor::_frame_list_item_selected));
|
|
|
|
|
|
- sub_vb->add_child(tree);
|
|
|
+ sub_vb->add_child(frame_list);
|
|
|
|
|
|
dialog = memnew(AcceptDialog);
|
|
|
add_child(dialog);
|
|
@@ -1351,33 +1427,34 @@ SpriteFramesEditor::SpriteFramesEditor() {
|
|
|
move_up->connect("pressed", callable_mp(this, &SpriteFramesEditor::_up_pressed));
|
|
|
move_down->connect("pressed", callable_mp(this, &SpriteFramesEditor::_down_pressed));
|
|
|
|
|
|
- load->set_shortcut_context(tree);
|
|
|
+ load->set_shortcut_context(frame_list);
|
|
|
load->set_shortcut(ED_SHORTCUT("sprite_frames/load_from_file", TTR("Add frame from file"), KeyModifierMask::CMD_OR_CTRL | Key::O));
|
|
|
- load_sheet->set_shortcut_context(tree);
|
|
|
+ load_sheet->set_shortcut_context(frame_list);
|
|
|
load_sheet->set_shortcut(ED_SHORTCUT("sprite_frames/load_from_sheet", TTR("Add frames from sprite sheet"), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::SHIFT | Key::O));
|
|
|
- delete_frame->set_shortcut_context(tree);
|
|
|
+ delete_frame->set_shortcut_context(frame_list);
|
|
|
delete_frame->set_shortcut(ED_SHORTCUT("sprite_frames/delete", TTR("Delete Frame"), Key::KEY_DELETE));
|
|
|
- copy->set_shortcut_context(tree);
|
|
|
+ copy->set_shortcut_context(frame_list);
|
|
|
copy->set_shortcut(ED_SHORTCUT("sprite_frames/copy", TTR("Copy Frame"), KeyModifierMask::CMD_OR_CTRL | Key::C));
|
|
|
- paste->set_shortcut_context(tree);
|
|
|
+ paste->set_shortcut_context(frame_list);
|
|
|
paste->set_shortcut(ED_SHORTCUT("sprite_frames/paste", TTR("Paste Frame"), KeyModifierMask::CMD_OR_CTRL | Key::V));
|
|
|
- empty_before->set_shortcut_context(tree);
|
|
|
+ empty_before->set_shortcut_context(frame_list);
|
|
|
empty_before->set_shortcut(ED_SHORTCUT("sprite_frames/empty_before", TTR("Insert Empty (Before Selected)"), KeyModifierMask::ALT | Key::LEFT));
|
|
|
- empty_after->set_shortcut_context(tree);
|
|
|
+ empty_after->set_shortcut_context(frame_list);
|
|
|
empty_after->set_shortcut(ED_SHORTCUT("sprite_frames/empty_after", TTR("Insert Empty (After Selected)"), KeyModifierMask::ALT | Key::RIGHT));
|
|
|
- move_up->set_shortcut_context(tree);
|
|
|
+ move_up->set_shortcut_context(frame_list);
|
|
|
move_up->set_shortcut(ED_SHORTCUT("sprite_frames/move_left", TTR("Move Frame Left"), KeyModifierMask::CMD_OR_CTRL | Key::LEFT));
|
|
|
- move_down->set_shortcut_context(tree);
|
|
|
+ move_down->set_shortcut_context(frame_list);
|
|
|
move_down->set_shortcut(ED_SHORTCUT("sprite_frames/move_right", TTR("Move Frame Right"), KeyModifierMask::CMD_OR_CTRL | Key::RIGHT));
|
|
|
|
|
|
- zoom_out->set_shortcut_context(tree);
|
|
|
+ zoom_out->set_shortcut_context(frame_list);
|
|
|
zoom_out->set_shortcut(ED_SHORTCUT_ARRAY("sprite_frames/zoom_out", TTR("Zoom Out"),
|
|
|
{ int32_t(KeyModifierMask::CMD_OR_CTRL | Key::MINUS), int32_t(KeyModifierMask::CMD_OR_CTRL | Key::KP_SUBTRACT) }));
|
|
|
- zoom_in->set_shortcut_context(tree);
|
|
|
+ zoom_in->set_shortcut_context(frame_list);
|
|
|
zoom_in->set_shortcut(ED_SHORTCUT_ARRAY("sprite_frames/zoom_in", TTR("Zoom In"),
|
|
|
{ int32_t(KeyModifierMask::CMD_OR_CTRL | Key::EQUAL), int32_t(KeyModifierMask::CMD_OR_CTRL | Key::KP_ADD) }));
|
|
|
|
|
|
file->connect("files_selected", callable_mp(this, &SpriteFramesEditor::_file_load_request).bind(-1));
|
|
|
+ frame_duration->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_frame_duration_changed));
|
|
|
loading_scene = false;
|
|
|
sel = -1;
|
|
|
|