You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-09 12:50:35 +00:00
Defer updating the animations Tree in SpriteFramesEditor to avoid crashes
Previously, clicking the LMB while renaming an animation could cause `SpriteFramesEditor::_update_library(false)` to be called during `Tree::propagate_mouse_event()`. This may cause a crash. We can defer updates to the editor interface to avoid calling `Tree::create_item()` at the wrong time. Enables `SpriteFramesEditor::_select_animation()` to be able to undo/redo
This commit is contained in:
@@ -870,13 +870,10 @@ void SpriteFramesEditor::_sync_animation() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SpriteFramesEditor::_select_animation(const String &p_name, bool p_update_node) {
|
void SpriteFramesEditor::_select_animation(const String &p_name, bool p_update_node) {
|
||||||
TreeItem *selected = nullptr;
|
if (!frames->has_animation(p_name)) {
|
||||||
selected = animations->get_item_with_text(p_name);
|
|
||||||
if (!selected) {
|
|
||||||
return;
|
return;
|
||||||
};
|
}
|
||||||
|
edited_anim = p_name;
|
||||||
edited_anim = selected->get_text(0);
|
|
||||||
|
|
||||||
if (animated_sprite) {
|
if (animated_sprite) {
|
||||||
if (p_update_node) {
|
if (p_update_node) {
|
||||||
@@ -951,6 +948,7 @@ void SpriteFramesEditor::_animation_name_edited() {
|
|||||||
counter++;
|
counter++;
|
||||||
name = new_name + "_" + itos(counter);
|
name = new_name + "_" + itos(counter);
|
||||||
}
|
}
|
||||||
|
edited->set_text(0, name);
|
||||||
|
|
||||||
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
|
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
|
||||||
undo_redo->create_action(TTR("Rename Animation"), UndoRedo::MERGE_DISABLE, EditorNode::get_singleton()->get_edited_scene());
|
undo_redo->create_action(TTR("Rename Animation"), UndoRedo::MERGE_DISABLE, EditorNode::get_singleton()->get_edited_scene());
|
||||||
@@ -958,11 +956,12 @@ void SpriteFramesEditor::_animation_name_edited() {
|
|||||||
undo_redo->add_undo_method(frames.ptr(), "rename_animation", name, edited_anim);
|
undo_redo->add_undo_method(frames.ptr(), "rename_animation", name, edited_anim);
|
||||||
_rename_node_animation(undo_redo, false, edited_anim, name, name);
|
_rename_node_animation(undo_redo, false, edited_anim, name, name);
|
||||||
_rename_node_animation(undo_redo, true, edited_anim, edited_anim, edited_anim);
|
_rename_node_animation(undo_redo, true, edited_anim, edited_anim, edited_anim);
|
||||||
|
undo_redo->add_do_method(this, "_select_animation", name);
|
||||||
|
undo_redo->add_undo_method(this, "_select_animation", edited_anim);
|
||||||
undo_redo->add_do_method(this, "_update_library");
|
undo_redo->add_do_method(this, "_update_library");
|
||||||
undo_redo->add_undo_method(this, "_update_library");
|
undo_redo->add_undo_method(this, "_update_library");
|
||||||
undo_redo->commit_action();
|
undo_redo->commit_action();
|
||||||
|
|
||||||
_select_animation(name);
|
|
||||||
animations->grab_focus();
|
animations->grab_focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1007,11 +1006,12 @@ void SpriteFramesEditor::_animation_add() {
|
|||||||
undo_redo->create_action(TTR("Add Animation"), UndoRedo::MERGE_DISABLE, EditorNode::get_singleton()->get_edited_scene());
|
undo_redo->create_action(TTR("Add Animation"), UndoRedo::MERGE_DISABLE, EditorNode::get_singleton()->get_edited_scene());
|
||||||
undo_redo->add_do_method(frames.ptr(), "add_animation", name);
|
undo_redo->add_do_method(frames.ptr(), "add_animation", name);
|
||||||
undo_redo->add_undo_method(frames.ptr(), "remove_animation", name);
|
undo_redo->add_undo_method(frames.ptr(), "remove_animation", name);
|
||||||
|
undo_redo->add_do_method(this, "_select_animation", name);
|
||||||
|
undo_redo->add_undo_method(this, "_select_animation", edited_anim);
|
||||||
undo_redo->add_do_method(this, "_update_library");
|
undo_redo->add_do_method(this, "_update_library");
|
||||||
undo_redo->add_undo_method(this, "_update_library");
|
undo_redo->add_undo_method(this, "_update_library");
|
||||||
undo_redo->commit_action();
|
undo_redo->commit_action();
|
||||||
|
|
||||||
_select_animation(name);
|
|
||||||
animations->grab_focus();
|
animations->grab_focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1057,11 +1057,11 @@ void SpriteFramesEditor::_animation_remove_confirmed() {
|
|||||||
float duration = frames->get_frame_duration(edited_anim, i);
|
float duration = frames->get_frame_duration(edited_anim, i);
|
||||||
undo_redo->add_undo_method(frames.ptr(), "add_frame", edited_anim, texture, duration);
|
undo_redo->add_undo_method(frames.ptr(), "add_frame", edited_anim, texture, duration);
|
||||||
}
|
}
|
||||||
|
undo_redo->add_do_method(this, "_select_animation", new_edited);
|
||||||
|
undo_redo->add_undo_method(this, "_select_animation", edited_anim);
|
||||||
undo_redo->add_do_method(this, "_update_library");
|
undo_redo->add_do_method(this, "_update_library");
|
||||||
undo_redo->add_undo_method(this, "_update_library");
|
undo_redo->add_undo_method(this, "_update_library");
|
||||||
undo_redo->commit_action();
|
undo_redo->commit_action();
|
||||||
|
|
||||||
_select_animation(new_edited);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpriteFramesEditor::_animation_search_text_changed(const String &p_text) {
|
void SpriteFramesEditor::_animation_search_text_changed(const String &p_text) {
|
||||||
@@ -1179,6 +1179,20 @@ void SpriteFramesEditor::_zoom_reset() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SpriteFramesEditor::_update_library(bool p_skip_selector) {
|
void SpriteFramesEditor::_update_library(bool p_skip_selector) {
|
||||||
|
if (!p_skip_selector) {
|
||||||
|
animations_dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pending_update) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pending_update = true;
|
||||||
|
callable_mp(this, &SpriteFramesEditor::_update_library_impl).call_deferred();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpriteFramesEditor::_update_library_impl() {
|
||||||
|
pending_update = false;
|
||||||
|
|
||||||
if (frames.is_null()) {
|
if (frames.is_null()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1187,7 +1201,8 @@ void SpriteFramesEditor::_update_library(bool p_skip_selector) {
|
|||||||
|
|
||||||
frame_duration->set_value_no_signal(1.0); // Default.
|
frame_duration->set_value_no_signal(1.0); // Default.
|
||||||
|
|
||||||
if (!p_skip_selector) {
|
if (animations_dirty) {
|
||||||
|
animations_dirty = false;
|
||||||
animations->clear();
|
animations->clear();
|
||||||
|
|
||||||
TreeItem *anim_root = animations->create_item();
|
TreeItem *anim_root = animations->create_item();
|
||||||
@@ -1624,6 +1639,7 @@ void SpriteFramesEditor::_autoplay_pressed() {
|
|||||||
|
|
||||||
void SpriteFramesEditor::_bind_methods() {
|
void SpriteFramesEditor::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("_update_library", "skipsel"), &SpriteFramesEditor::_update_library, DEFVAL(false));
|
ClassDB::bind_method(D_METHOD("_update_library", "skipsel"), &SpriteFramesEditor::_update_library, DEFVAL(false));
|
||||||
|
ClassDB::bind_method(D_METHOD("_select_animation", "name", "update_node"), &SpriteFramesEditor::_select_animation, DEFVAL(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpriteFramesEditor::_node_removed(Node *p_node) {
|
void SpriteFramesEditor::_node_removed(Node *p_node) {
|
||||||
|
|||||||
@@ -189,6 +189,7 @@ class SpriteFramesEditor : public HSplitContainer {
|
|||||||
void _down_pressed();
|
void _down_pressed();
|
||||||
void _frame_duration_changed(double p_value);
|
void _frame_duration_changed(double p_value);
|
||||||
void _update_library(bool p_skip_selector = false);
|
void _update_library(bool p_skip_selector = false);
|
||||||
|
void _update_library_impl();
|
||||||
|
|
||||||
void _update_stop_icon();
|
void _update_stop_icon();
|
||||||
void _play_pressed();
|
void _play_pressed();
|
||||||
@@ -214,6 +215,9 @@ class SpriteFramesEditor : public HSplitContainer {
|
|||||||
void _zoom_out();
|
void _zoom_out();
|
||||||
void _zoom_reset();
|
void _zoom_reset();
|
||||||
|
|
||||||
|
bool animations_dirty = false;
|
||||||
|
bool pending_update = false;
|
||||||
|
|
||||||
bool updating;
|
bool updating;
|
||||||
bool updating_split_settings = false; // Skip SpinBox/Range callback when setting value by code.
|
bool updating_split_settings = false; // Skip SpinBox/Range callback when setting value by code.
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user