Merge pull request #63245 from V-Sekai/animation_editor_read_only
This commit is contained in:
commit
cf95056c91
|
@ -328,6 +328,8 @@ void AnimationBezierTrackEdit::_notification(int p_what) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Color dc = get_theme_color(SNAME("disabled_font_color"), SNAME("Editor"));
|
||||||
|
|
||||||
Ref<Texture2D> remove = get_theme_icon(SNAME("Remove"), SNAME("EditorIcons"));
|
Ref<Texture2D> remove = get_theme_icon(SNAME("Remove"), SNAME("EditorIcons"));
|
||||||
float remove_hpos = limit - hsep - remove->get_width();
|
float remove_hpos = limit - hsep - remove->get_width();
|
||||||
|
|
||||||
|
@ -402,7 +404,11 @@ void AnimationBezierTrackEdit::_notification(int p_what) {
|
||||||
|
|
||||||
float icon_start_height = vofs + rect.size.y / 2;
|
float icon_start_height = vofs + rect.size.y / 2;
|
||||||
Rect2 remove_rect = Rect2(remove_hpos, icon_start_height - remove->get_height() / 2, remove->get_width(), remove->get_height());
|
Rect2 remove_rect = Rect2(remove_hpos, icon_start_height - remove->get_height() / 2, remove->get_width(), remove->get_height());
|
||||||
|
if (read_only) {
|
||||||
|
draw_texture(remove, remove_rect.position, dc);
|
||||||
|
} else {
|
||||||
draw_texture(remove, remove_rect.position);
|
draw_texture(remove, remove_rect.position);
|
||||||
|
}
|
||||||
|
|
||||||
Rect2 lock_rect = Rect2(lock_hpos, icon_start_height - lock->get_height() / 2, lock->get_width(), lock->get_height());
|
Rect2 lock_rect = Rect2(lock_hpos, icon_start_height - lock->get_height() / 2, lock->get_width(), lock->get_height());
|
||||||
if (locked_tracks.has(current_track)) {
|
if (locked_tracks.has(current_track)) {
|
||||||
|
@ -632,8 +638,9 @@ Ref<Animation> AnimationBezierTrackEdit::get_animation() const {
|
||||||
return animation;
|
return animation;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnimationBezierTrackEdit::set_animation_and_track(const Ref<Animation> &p_animation, int p_track) {
|
void AnimationBezierTrackEdit::set_animation_and_track(const Ref<Animation> &p_animation, int p_track, bool p_read_only) {
|
||||||
animation = p_animation;
|
animation = p_animation;
|
||||||
|
read_only = p_read_only;
|
||||||
selected_track = p_track;
|
selected_track = p_track;
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
@ -715,7 +722,7 @@ void AnimationBezierTrackEdit::set_filtered(bool p_filtered) {
|
||||||
continue; // Skip track due to not selected.
|
continue; // Skip track due to not selected.
|
||||||
}
|
}
|
||||||
|
|
||||||
set_animation_and_track(animation, i);
|
set_animation_and_track(animation, i, read_only);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -819,12 +826,16 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
|
||||||
|
|
||||||
if (p_event->is_pressed()) {
|
if (p_event->is_pressed()) {
|
||||||
if (ED_GET_SHORTCUT("animation_editor/duplicate_selection")->matches_event(p_event)) {
|
if (ED_GET_SHORTCUT("animation_editor/duplicate_selection")->matches_event(p_event)) {
|
||||||
|
if (!read_only) {
|
||||||
duplicate_selection();
|
duplicate_selection();
|
||||||
|
}
|
||||||
accept_event();
|
accept_event();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ED_GET_SHORTCUT("animation_editor/delete_selection")->matches_event(p_event)) {
|
if (ED_GET_SHORTCUT("animation_editor/delete_selection")->matches_event(p_event)) {
|
||||||
|
if (!read_only) {
|
||||||
delete_selection();
|
delete_selection();
|
||||||
|
}
|
||||||
accept_event();
|
accept_event();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -917,6 +928,7 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
|
||||||
if (mb.is_valid() && mb->get_button_index() == MouseButton::RIGHT && mb->is_pressed()) {
|
if (mb.is_valid() && mb->get_button_index() == MouseButton::RIGHT && mb->is_pressed()) {
|
||||||
menu_insert_key = mb->get_position();
|
menu_insert_key = mb->get_position();
|
||||||
if (menu_insert_key.x >= limit && menu_insert_key.x <= get_size().width) {
|
if (menu_insert_key.x >= limit && menu_insert_key.x <= get_size().width) {
|
||||||
|
if (!read_only) {
|
||||||
Vector2 popup_pos = get_screen_position() + mb->get_position();
|
Vector2 popup_pos = get_screen_position() + mb->get_position();
|
||||||
|
|
||||||
menu->clear();
|
menu->clear();
|
||||||
|
@ -940,12 +952,13 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT) {
|
if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT) {
|
||||||
for (const KeyValue<int, Rect2> &E : subtracks) {
|
for (const KeyValue<int, Rect2> &E : subtracks) {
|
||||||
if (E.value.has_point(mb->get_position())) {
|
if (E.value.has_point(mb->get_position())) {
|
||||||
if (!locked_tracks.has(E.key) && !hidden_tracks.has(E.key)) {
|
if (!locked_tracks.has(E.key) && !hidden_tracks.has(E.key)) {
|
||||||
set_animation_and_track(animation, E.key);
|
set_animation_and_track(animation, E.key, read_only);
|
||||||
_clear_selection();
|
_clear_selection();
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -958,6 +971,7 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
|
||||||
for (const KeyValue<int, Rect2> &I : track_icons) {
|
for (const KeyValue<int, Rect2> &I : track_icons) {
|
||||||
if (I.value.has_point(mb->get_position())) {
|
if (I.value.has_point(mb->get_position())) {
|
||||||
if (I.key == REMOVE_ICON) {
|
if (I.key == REMOVE_ICON) {
|
||||||
|
if (!read_only) {
|
||||||
undo_redo->create_action("Remove Bezier Track");
|
undo_redo->create_action("Remove Bezier Track");
|
||||||
|
|
||||||
undo_redo->add_do_method(this, "_update_locked_tracks_after", track);
|
undo_redo->add_do_method(this, "_update_locked_tracks_after", track);
|
||||||
|
@ -982,6 +996,7 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
|
||||||
undo_redo->commit_action();
|
undo_redo->commit_action();
|
||||||
|
|
||||||
selected_track = CLAMP(selected_track, 0, animation->get_track_count() - 1);
|
selected_track = CLAMP(selected_track, 0, animation->get_track_count() - 1);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
} else if (I.key == LOCK_ICON) {
|
} else if (I.key == LOCK_ICON) {
|
||||||
if (locked_tracks.has(track)) {
|
if (locked_tracks.has(track)) {
|
||||||
|
@ -991,7 +1006,7 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
|
||||||
if (selected_track == track) {
|
if (selected_track == track) {
|
||||||
for (int i = 0; i < animation->get_track_count(); ++i) {
|
for (int i = 0; i < animation->get_track_count(); ++i) {
|
||||||
if (!locked_tracks.has(i) && animation->track_get_type(i) == Animation::TrackType::TYPE_BEZIER) {
|
if (!locked_tracks.has(i) && animation->track_get_type(i) == Animation::TrackType::TYPE_BEZIER) {
|
||||||
set_animation_and_track(animation, i);
|
set_animation_and_track(animation, i, read_only);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1007,7 +1022,7 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
|
||||||
if (selected_track == track) {
|
if (selected_track == track) {
|
||||||
for (int i = 0; i < animation->get_track_count(); ++i) {
|
for (int i = 0; i < animation->get_track_count(); ++i) {
|
||||||
if (!hidden_tracks.has(i) && animation->track_get_type(i) == Animation::TrackType::TYPE_BEZIER) {
|
if (!hidden_tracks.has(i) && animation->track_get_type(i) == Animation::TrackType::TYPE_BEZIER) {
|
||||||
set_animation_and_track(animation, i);
|
set_animation_and_track(animation, i, read_only);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1046,7 +1061,7 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
set_animation_and_track(animation, track);
|
set_animation_and_track(animation, track, read_only);
|
||||||
solo_track = track;
|
solo_track = track;
|
||||||
}
|
}
|
||||||
update();
|
update();
|
||||||
|
@ -1087,7 +1102,7 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
|
||||||
moving_selection_from_key = pair.second;
|
moving_selection_from_key = pair.second;
|
||||||
moving_selection_from_track = pair.first;
|
moving_selection_from_track = pair.first;
|
||||||
moving_selection_offset = Vector2();
|
moving_selection_offset = Vector2();
|
||||||
set_animation_and_track(animation, pair.first);
|
set_animation_and_track(animation, pair.first, read_only);
|
||||||
selection.clear();
|
selection.clear();
|
||||||
selection.insert(pair);
|
selection.insert(pair);
|
||||||
update();
|
update();
|
||||||
|
@ -1096,6 +1111,7 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!read_only) {
|
||||||
if (edit_points[i].in_rect.has_point(mb->get_position())) {
|
if (edit_points[i].in_rect.has_point(mb->get_position())) {
|
||||||
moving_handle = -1;
|
moving_handle = -1;
|
||||||
moving_handle_key = edit_points[i].key;
|
moving_handle_key = edit_points[i].key;
|
||||||
|
@ -1116,6 +1132,7 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//insert new point
|
//insert new point
|
||||||
if (mb->get_position().x >= limit && mb->get_position().x < get_size().width && mb->is_command_pressed()) {
|
if (mb->get_position().x >= limit && mb->get_position().x < get_size().width && mb->is_command_pressed()) {
|
||||||
|
@ -1191,7 +1208,7 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
|
||||||
selection.insert(IntPair(edit_points[i].track, edit_points[i].key));
|
selection.insert(IntPair(edit_points[i].track, edit_points[i].key));
|
||||||
if (!track_set) {
|
if (!track_set) {
|
||||||
track_set = true;
|
track_set = true;
|
||||||
set_animation_and_track(animation, edit_points[i].track);
|
set_animation_and_track(animation, edit_points[i].track, read_only);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1215,7 +1232,7 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
|
||||||
float track_height = _bezier_h_to_pixel(track_h);
|
float track_height = _bezier_h_to_pixel(track_h);
|
||||||
|
|
||||||
if (abs(mb->get_position().y - track_height) < 10) {
|
if (abs(mb->get_position().y - track_height) < 10) {
|
||||||
set_animation_and_track(animation, i);
|
set_animation_and_track(animation, i, read_only);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1229,6 +1246,7 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (moving_handle != 0 && mb.is_valid() && !mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT) {
|
if (moving_handle != 0 && mb.is_valid() && !mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT) {
|
||||||
|
if (!read_only) {
|
||||||
undo_redo->create_action(TTR("Move Bezier Points"));
|
undo_redo->create_action(TTR("Move Bezier Points"));
|
||||||
undo_redo->add_do_method(animation.ptr(), "bezier_track_set_key_in_handle", selected_track, moving_handle_key, moving_handle_left);
|
undo_redo->add_do_method(animation.ptr(), "bezier_track_set_key_in_handle", selected_track, moving_handle_key, moving_handle_left);
|
||||||
undo_redo->add_do_method(animation.ptr(), "bezier_track_set_key_out_handle", selected_track, moving_handle_key, moving_handle_right);
|
undo_redo->add_do_method(animation.ptr(), "bezier_track_set_key_out_handle", selected_track, moving_handle_key, moving_handle_right);
|
||||||
|
@ -1239,8 +1257,10 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
|
||||||
moving_handle = 0;
|
moving_handle = 0;
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (moving_selection_attempt && mb.is_valid() && !mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT) {
|
if (moving_selection_attempt && mb.is_valid() && !mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT) {
|
||||||
|
if (!read_only) {
|
||||||
if (moving_selection) {
|
if (moving_selection) {
|
||||||
//combit it
|
//combit it
|
||||||
|
|
||||||
|
@ -1320,12 +1340,13 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
|
||||||
} else if (select_single_attempt != IntPair(-1, -1)) {
|
} else if (select_single_attempt != IntPair(-1, -1)) {
|
||||||
selection.clear();
|
selection.clear();
|
||||||
selection.insert(select_single_attempt);
|
selection.insert(select_single_attempt);
|
||||||
set_animation_and_track(animation, select_single_attempt.first);
|
set_animation_and_track(animation, select_single_attempt.first, read_only);
|
||||||
}
|
}
|
||||||
|
|
||||||
moving_selection_attempt = false;
|
moving_selection_attempt = false;
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ref<InputEventMouseMotion> mm = p_event;
|
Ref<InputEventMouseMotion> mm = p_event;
|
||||||
if (moving_selection_attempt && mm.is_valid()) {
|
if (moving_selection_attempt && mm.is_valid()) {
|
||||||
|
@ -1337,7 +1358,9 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
|
||||||
float y = (get_size().height / 2 - mm->get_position().y) * v_zoom + v_scroll;
|
float y = (get_size().height / 2 - mm->get_position().y) * v_zoom + v_scroll;
|
||||||
float x = editor->snap_time(((mm->get_position().x - limit) / timeline->get_zoom_scale()) + timeline->get_value());
|
float x = editor->snap_time(((mm->get_position().x - limit) / timeline->get_zoom_scale()) + timeline->get_value());
|
||||||
|
|
||||||
|
if (!read_only) {
|
||||||
moving_selection_offset = Vector2(x - animation->track_get_key_time(moving_selection_from_track, moving_selection_from_key), y - animation->bezier_track_get_key_value(moving_selection_from_track, moving_selection_from_key));
|
moving_selection_offset = Vector2(x - animation->track_get_key_time(moving_selection_from_track, moving_selection_from_key), y - animation->bezier_track_get_key_value(moving_selection_from_track, moving_selection_from_key));
|
||||||
|
}
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1399,6 +1422,7 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
|
||||||
|
|
||||||
bool is_finishing_key_handle_drag = moving_handle != 0 && mb.is_valid() && !mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT;
|
bool is_finishing_key_handle_drag = moving_handle != 0 && mb.is_valid() && !mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT;
|
||||||
if (is_finishing_key_handle_drag) {
|
if (is_finishing_key_handle_drag) {
|
||||||
|
if (!read_only) {
|
||||||
undo_redo->create_action(TTR("Move Bezier Points"));
|
undo_redo->create_action(TTR("Move Bezier Points"));
|
||||||
if (moving_handle == -1) {
|
if (moving_handle == -1) {
|
||||||
double ratio = timeline->get_zoom_scale() * v_zoom;
|
double ratio = timeline->get_zoom_scale() * v_zoom;
|
||||||
|
@ -1415,6 +1439,7 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void AnimationBezierTrackEdit::_scroll_callback(Vector2 p_scroll_vec, bool p_alt) {
|
void AnimationBezierTrackEdit::_scroll_callback(Vector2 p_scroll_vec, bool p_alt) {
|
||||||
_pan_callback(-p_scroll_vec * 32);
|
_pan_callback(-p_scroll_vec * 32);
|
||||||
|
|
|
@ -54,6 +54,7 @@ class AnimationBezierTrackEdit : public Control {
|
||||||
float play_position_pos = 0;
|
float play_position_pos = 0;
|
||||||
|
|
||||||
Ref<Animation> animation;
|
Ref<Animation> animation;
|
||||||
|
bool read_only = false;
|
||||||
int selected_track = 0;
|
int selected_track = 0;
|
||||||
|
|
||||||
Vector<Rect2> view_rects;
|
Vector<Rect2> view_rects;
|
||||||
|
@ -176,7 +177,7 @@ public:
|
||||||
|
|
||||||
Ref<Animation> get_animation() const;
|
Ref<Animation> get_animation() const;
|
||||||
|
|
||||||
void set_animation_and_track(const Ref<Animation> &p_animation, int p_track);
|
void set_animation_and_track(const Ref<Animation> &p_animation, int p_track, bool p_read_only);
|
||||||
virtual Size2 get_minimum_size() const override;
|
virtual Size2 get_minimum_size() const override;
|
||||||
|
|
||||||
void set_undo_redo(UndoRedo *p_undo_redo);
|
void set_undo_redo(UndoRedo *p_undo_redo);
|
||||||
|
|
|
@ -48,6 +48,7 @@ class AnimationTrackKeyEdit : public Object {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool setting = false;
|
bool setting = false;
|
||||||
|
bool animation_read_only = false;
|
||||||
|
|
||||||
bool _hide_script_from_inspector() {
|
bool _hide_script_from_inspector() {
|
||||||
return true;
|
return true;
|
||||||
|
@ -57,12 +58,17 @@ public:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool _read_only() {
|
||||||
|
return animation_read_only;
|
||||||
|
}
|
||||||
|
|
||||||
static void _bind_methods() {
|
static void _bind_methods() {
|
||||||
ClassDB::bind_method("_update_obj", &AnimationTrackKeyEdit::_update_obj);
|
ClassDB::bind_method("_update_obj", &AnimationTrackKeyEdit::_update_obj);
|
||||||
ClassDB::bind_method("_key_ofs_changed", &AnimationTrackKeyEdit::_key_ofs_changed);
|
ClassDB::bind_method("_key_ofs_changed", &AnimationTrackKeyEdit::_key_ofs_changed);
|
||||||
ClassDB::bind_method("_hide_script_from_inspector", &AnimationTrackKeyEdit::_hide_script_from_inspector);
|
ClassDB::bind_method("_hide_script_from_inspector", &AnimationTrackKeyEdit::_hide_script_from_inspector);
|
||||||
ClassDB::bind_method("get_root_path", &AnimationTrackKeyEdit::get_root_path);
|
ClassDB::bind_method("get_root_path", &AnimationTrackKeyEdit::get_root_path);
|
||||||
ClassDB::bind_method("_dont_undo_redo", &AnimationTrackKeyEdit::_dont_undo_redo);
|
ClassDB::bind_method("_dont_undo_redo", &AnimationTrackKeyEdit::_dont_undo_redo);
|
||||||
|
ClassDB::bind_method("_read_only", &AnimationTrackKeyEdit::_read_only);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _fix_node_path(Variant &value) {
|
void _fix_node_path(Variant &value) {
|
||||||
|
@ -703,6 +709,7 @@ class AnimationMultiTrackKeyEdit : public Object {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool setting = false;
|
bool setting = false;
|
||||||
|
bool animation_read_only = false;
|
||||||
|
|
||||||
bool _hide_script_from_inspector() {
|
bool _hide_script_from_inspector() {
|
||||||
return true;
|
return true;
|
||||||
|
@ -712,12 +719,17 @@ public:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool _read_only() {
|
||||||
|
return animation_read_only;
|
||||||
|
}
|
||||||
|
|
||||||
static void _bind_methods() {
|
static void _bind_methods() {
|
||||||
ClassDB::bind_method("_update_obj", &AnimationMultiTrackKeyEdit::_update_obj);
|
ClassDB::bind_method("_update_obj", &AnimationMultiTrackKeyEdit::_update_obj);
|
||||||
ClassDB::bind_method("_key_ofs_changed", &AnimationMultiTrackKeyEdit::_key_ofs_changed);
|
ClassDB::bind_method("_key_ofs_changed", &AnimationMultiTrackKeyEdit::_key_ofs_changed);
|
||||||
ClassDB::bind_method("_hide_script_from_inspector", &AnimationMultiTrackKeyEdit::_hide_script_from_inspector);
|
ClassDB::bind_method("_hide_script_from_inspector", &AnimationMultiTrackKeyEdit::_hide_script_from_inspector);
|
||||||
ClassDB::bind_method("get_root_path", &AnimationMultiTrackKeyEdit::get_root_path);
|
ClassDB::bind_method("get_root_path", &AnimationMultiTrackKeyEdit::get_root_path);
|
||||||
ClassDB::bind_method("_dont_undo_redo", &AnimationMultiTrackKeyEdit::_dont_undo_redo);
|
ClassDB::bind_method("_dont_undo_redo", &AnimationMultiTrackKeyEdit::_dont_undo_redo);
|
||||||
|
ClassDB::bind_method("_read_only", &AnimationMultiTrackKeyEdit::_read_only);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _fix_node_path(Variant &value, NodePath &base) {
|
void _fix_node_path(Variant &value, NodePath &base) {
|
||||||
|
@ -1416,6 +1428,7 @@ void AnimationTimelineEdit::_anim_length_changed(double p_new_len) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnimationTimelineEdit::_anim_loop_pressed() {
|
void AnimationTimelineEdit::_anim_loop_pressed() {
|
||||||
|
if (!read_only) {
|
||||||
undo_redo->create_action(TTR("Change Animation Loop"));
|
undo_redo->create_action(TTR("Change Animation Loop"));
|
||||||
switch (animation->get_loop_mode()) {
|
switch (animation->get_loop_mode()) {
|
||||||
case Animation::LOOP_NONE: {
|
case Animation::LOOP_NONE: {
|
||||||
|
@ -1432,6 +1445,15 @@ void AnimationTimelineEdit::_anim_loop_pressed() {
|
||||||
}
|
}
|
||||||
undo_redo->add_undo_method(animation.ptr(), "set_loop_mode", animation->get_loop_mode());
|
undo_redo->add_undo_method(animation.ptr(), "set_loop_mode", animation->get_loop_mode());
|
||||||
undo_redo->commit_action();
|
undo_redo->commit_action();
|
||||||
|
} else {
|
||||||
|
String base_path = animation->get_path();
|
||||||
|
if (FileAccess::exists(base_path + ".import")) {
|
||||||
|
EditorNode::get_singleton()->show_warning(TTR("Can't change loop mode on animation instanced from imported scene."));
|
||||||
|
} else {
|
||||||
|
EditorNode::get_singleton()->show_warning(TTR("Can't change loop mode on animation embedded in another scene."));
|
||||||
|
}
|
||||||
|
update_values();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int AnimationTimelineEdit::get_buttons_width() const {
|
int AnimationTimelineEdit::get_buttons_width() const {
|
||||||
|
@ -1656,11 +1678,17 @@ void AnimationTimelineEdit::_notification(int p_what) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnimationTimelineEdit::set_animation(const Ref<Animation> &p_animation) {
|
void AnimationTimelineEdit::set_animation(const Ref<Animation> &p_animation, bool p_read_only) {
|
||||||
animation = p_animation;
|
animation = p_animation;
|
||||||
|
read_only = p_read_only;
|
||||||
|
|
||||||
if (animation.is_valid()) {
|
if (animation.is_valid()) {
|
||||||
len_hb->show();
|
len_hb->show();
|
||||||
|
if (read_only) {
|
||||||
|
add_track->hide();
|
||||||
|
} else {
|
||||||
add_track->show();
|
add_track->show();
|
||||||
|
}
|
||||||
play_position->show();
|
play_position->show();
|
||||||
} else {
|
} else {
|
||||||
len_hb->hide();
|
len_hb->hide();
|
||||||
|
@ -1982,6 +2010,8 @@ void AnimationTrackEdit::_notification(int p_what) {
|
||||||
Color linecolor = color;
|
Color linecolor = color;
|
||||||
linecolor.a = 0.2;
|
linecolor.a = 0.2;
|
||||||
|
|
||||||
|
Color dc = get_theme_color(SNAME("disabled_font_color"), SNAME("Editor"));
|
||||||
|
|
||||||
// NAMES AND ICONS //
|
// NAMES AND ICONS //
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -2131,6 +2161,7 @@ void AnimationTrackEdit::_notification(int p_what) {
|
||||||
ofs += update_icon->get_width() + hsep / 2;
|
ofs += update_icon->get_width() + hsep / 2;
|
||||||
update_mode_rect.size.x += hsep / 2;
|
update_mode_rect.size.x += hsep / 2;
|
||||||
|
|
||||||
|
if (!read_only) {
|
||||||
if (animation->track_get_type(track) == Animation::TYPE_VALUE) {
|
if (animation->track_get_type(track) == Animation::TYPE_VALUE) {
|
||||||
draw_texture(down_icon, Vector2(ofs, int(get_size().height - down_icon->get_height()) / 2));
|
draw_texture(down_icon, Vector2(ofs, int(get_size().height - down_icon->get_height()) / 2));
|
||||||
update_mode_rect.size.x += down_icon->get_width();
|
update_mode_rect.size.x += down_icon->get_width();
|
||||||
|
@ -2142,6 +2173,9 @@ void AnimationTrackEdit::_notification(int p_what) {
|
||||||
} else {
|
} else {
|
||||||
update_mode_rect = Rect2();
|
update_mode_rect = Rect2();
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
update_mode_rect = Rect2();
|
||||||
|
}
|
||||||
|
|
||||||
ofs += down_icon->get_width();
|
ofs += down_icon->get_width();
|
||||||
draw_line(Point2(ofs + hsep * 0.5, 0), Point2(ofs + hsep * 0.5, get_size().height), linecolor, Math::round(EDSCALE));
|
draw_line(Point2(ofs + hsep * 0.5, 0), Point2(ofs + hsep * 0.5, get_size().height), linecolor, Math::round(EDSCALE));
|
||||||
|
@ -2169,7 +2203,7 @@ void AnimationTrackEdit::_notification(int p_what) {
|
||||||
ofs += icon->get_width() + hsep / 2;
|
ofs += icon->get_width() + hsep / 2;
|
||||||
interp_mode_rect.size.x += hsep / 2;
|
interp_mode_rect.size.x += hsep / 2;
|
||||||
|
|
||||||
if (!animation->track_is_compressed(track) && (animation->track_get_type(track) == Animation::TYPE_VALUE || animation->track_get_type(track) == Animation::TYPE_BLEND_SHAPE || animation->track_get_type(track) == Animation::TYPE_POSITION_3D || animation->track_get_type(track) == Animation::TYPE_SCALE_3D || animation->track_get_type(track) == Animation::TYPE_ROTATION_3D)) {
|
if (!read_only && !animation->track_is_compressed(track) && (animation->track_get_type(track) == Animation::TYPE_VALUE || animation->track_get_type(track) == Animation::TYPE_BLEND_SHAPE || animation->track_get_type(track) == Animation::TYPE_POSITION_3D || animation->track_get_type(track) == Animation::TYPE_SCALE_3D || animation->track_get_type(track) == Animation::TYPE_ROTATION_3D)) {
|
||||||
draw_texture(down_icon, Vector2(ofs, int(get_size().height - down_icon->get_height()) / 2));
|
draw_texture(down_icon, Vector2(ofs, int(get_size().height - down_icon->get_height()) / 2));
|
||||||
interp_mode_rect.size.x += down_icon->get_width();
|
interp_mode_rect.size.x += down_icon->get_width();
|
||||||
} else {
|
} else {
|
||||||
|
@ -2202,7 +2236,7 @@ void AnimationTrackEdit::_notification(int p_what) {
|
||||||
ofs += icon->get_width() + hsep / 2;
|
ofs += icon->get_width() + hsep / 2;
|
||||||
loop_wrap_rect.size.x += hsep / 2;
|
loop_wrap_rect.size.x += hsep / 2;
|
||||||
|
|
||||||
if (!animation->track_is_compressed(track) && (animation->track_get_type(track) == Animation::TYPE_VALUE || animation->track_get_type(track) == Animation::TYPE_BLEND_SHAPE || animation->track_get_type(track) == Animation::TYPE_POSITION_3D || animation->track_get_type(track) == Animation::TYPE_SCALE_3D || animation->track_get_type(track) == Animation::TYPE_ROTATION_3D)) {
|
if (!read_only && !animation->track_is_compressed(track) && (animation->track_get_type(track) == Animation::TYPE_VALUE || animation->track_get_type(track) == Animation::TYPE_BLEND_SHAPE || animation->track_get_type(track) == Animation::TYPE_POSITION_3D || animation->track_get_type(track) == Animation::TYPE_SCALE_3D || animation->track_get_type(track) == Animation::TYPE_ROTATION_3D)) {
|
||||||
draw_texture(down_icon, Vector2(ofs, int(get_size().height - down_icon->get_height()) / 2));
|
draw_texture(down_icon, Vector2(ofs, int(get_size().height - down_icon->get_height()) / 2));
|
||||||
loop_wrap_rect.size.x += down_icon->get_width();
|
loop_wrap_rect.size.x += down_icon->get_width();
|
||||||
} else {
|
} else {
|
||||||
|
@ -2223,9 +2257,13 @@ void AnimationTrackEdit::_notification(int p_what) {
|
||||||
remove_rect.position.y = int(get_size().height - icon->get_height()) / 2;
|
remove_rect.position.y = int(get_size().height - icon->get_height()) / 2;
|
||||||
remove_rect.size = icon->get_size();
|
remove_rect.size = icon->get_size();
|
||||||
|
|
||||||
|
if (read_only) {
|
||||||
|
draw_texture(icon, remove_rect.position, dc);
|
||||||
|
} else {
|
||||||
draw_texture(icon, remove_rect.position);
|
draw_texture(icon, remove_rect.position);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (in_group) {
|
if (in_group) {
|
||||||
draw_line(Vector2(timeline->get_name_limit(), get_size().height), get_size(), linecolor, Math::round(EDSCALE));
|
draw_line(Vector2(timeline->get_name_limit(), get_size().height), get_size(), linecolor, Math::round(EDSCALE));
|
||||||
|
@ -2439,8 +2477,10 @@ Ref<Animation> AnimationTrackEdit::get_animation() const {
|
||||||
return animation;
|
return animation;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnimationTrackEdit::set_animation_and_track(const Ref<Animation> &p_animation, int p_track) {
|
void AnimationTrackEdit::set_animation_and_track(const Ref<Animation> &p_animation, int p_track, bool p_read_only) {
|
||||||
animation = p_animation;
|
animation = p_animation;
|
||||||
|
read_only = p_read_only;
|
||||||
|
|
||||||
track = p_track;
|
track = p_track;
|
||||||
update();
|
update();
|
||||||
|
|
||||||
|
@ -2721,17 +2761,23 @@ void AnimationTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
|
||||||
|
|
||||||
if (p_event->is_pressed()) {
|
if (p_event->is_pressed()) {
|
||||||
if (ED_GET_SHORTCUT("animation_editor/duplicate_selection")->matches_event(p_event)) {
|
if (ED_GET_SHORTCUT("animation_editor/duplicate_selection")->matches_event(p_event)) {
|
||||||
|
if (!read_only) {
|
||||||
emit_signal(SNAME("duplicate_request"));
|
emit_signal(SNAME("duplicate_request"));
|
||||||
|
}
|
||||||
accept_event();
|
accept_event();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ED_GET_SHORTCUT("animation_editor/duplicate_selection_transposed")->matches_event(p_event)) {
|
if (ED_GET_SHORTCUT("animation_editor/duplicate_selection_transposed")->matches_event(p_event)) {
|
||||||
|
if (!read_only) {
|
||||||
emit_signal(SNAME("duplicate_transpose_request"));
|
emit_signal(SNAME("duplicate_transpose_request"));
|
||||||
|
}
|
||||||
accept_event();
|
accept_event();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ED_GET_SHORTCUT("animation_editor/delete_selection")->matches_event(p_event)) {
|
if (ED_GET_SHORTCUT("animation_editor/delete_selection")->matches_event(p_event)) {
|
||||||
|
if (!read_only) {
|
||||||
emit_signal(SNAME("delete_request"));
|
emit_signal(SNAME("delete_request"));
|
||||||
|
}
|
||||||
accept_event();
|
accept_event();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2740,6 +2786,7 @@ void AnimationTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
|
||||||
if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT) {
|
if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT) {
|
||||||
Point2 pos = mb->get_position();
|
Point2 pos = mb->get_position();
|
||||||
|
|
||||||
|
if (!read_only) {
|
||||||
if (check_rect.has_point(pos)) {
|
if (check_rect.has_point(pos)) {
|
||||||
undo_redo->create_action(TTR("Toggle Track Enabled"));
|
undo_redo->create_action(TTR("Toggle Track Enabled"));
|
||||||
undo_redo->add_do_method(animation.ptr(), "track_set_enabled", track, !animation->track_is_enabled(track));
|
undo_redo->add_do_method(animation.ptr(), "track_set_enabled", track, !animation->track_is_enabled(track));
|
||||||
|
@ -2814,6 +2861,7 @@ void AnimationTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
|
||||||
accept_event();
|
accept_event();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Check keyframes.
|
// Check keyframes.
|
||||||
|
|
||||||
|
@ -2872,6 +2920,11 @@ void AnimationTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
|
||||||
moving_selection_attempt = true;
|
moving_selection_attempt = true;
|
||||||
moving_selection_from_ofs = (mb->get_position().x - limit) / timeline->get_zoom_scale();
|
moving_selection_from_ofs = (mb->get_position().x - limit) / timeline->get_zoom_scale();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (read_only) {
|
||||||
|
moving_selection_attempt = false;
|
||||||
|
moving_selection_from_ofs = 0.0f;
|
||||||
|
}
|
||||||
accept_event();
|
accept_event();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2883,6 +2936,7 @@ void AnimationTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
|
||||||
if (pos.x >= timeline->get_name_limit() && pos.x <= get_size().width - timeline->get_buttons_width()) {
|
if (pos.x >= timeline->get_name_limit() && pos.x <= get_size().width - timeline->get_buttons_width()) {
|
||||||
// Can do something with menu too! show insert key.
|
// Can do something with menu too! show insert key.
|
||||||
float offset = (pos.x - timeline->get_name_limit()) / timeline->get_zoom_scale();
|
float offset = (pos.x - timeline->get_name_limit()) / timeline->get_zoom_scale();
|
||||||
|
if (!read_only) {
|
||||||
if (!menu) {
|
if (!menu) {
|
||||||
menu = memnew(PopupMenu);
|
menu = memnew(PopupMenu);
|
||||||
add_child(menu);
|
add_child(menu);
|
||||||
|
@ -2912,6 +2966,7 @@ void AnimationTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
|
||||||
accept_event();
|
accept_event();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (mb.is_valid() && !mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT && clicking_on_name) {
|
if (mb.is_valid() && !mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT && clicking_on_name) {
|
||||||
if (!path) {
|
if (!path) {
|
||||||
|
@ -3354,7 +3409,7 @@ void AnimationTrackEditor::remove_track_edit_plugin(const Ref<AnimationTrackEdit
|
||||||
track_edit_plugins.erase(p_plugin);
|
track_edit_plugins.erase(p_plugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnimationTrackEditor::set_animation(const Ref<Animation> &p_anim) {
|
void AnimationTrackEditor::set_animation(const Ref<Animation> &p_anim, bool p_read_only) {
|
||||||
if (animation != p_anim && _get_track_selected() >= 0) {
|
if (animation != p_anim && _get_track_selected() >= 0) {
|
||||||
track_edits[_get_track_selected()]->release_focus();
|
track_edits[_get_track_selected()]->release_focus();
|
||||||
}
|
}
|
||||||
|
@ -3363,7 +3418,8 @@ void AnimationTrackEditor::set_animation(const Ref<Animation> &p_anim) {
|
||||||
_clear_selection();
|
_clear_selection();
|
||||||
}
|
}
|
||||||
animation = p_anim;
|
animation = p_anim;
|
||||||
timeline->set_animation(p_anim);
|
read_only = p_read_only;
|
||||||
|
timeline->set_animation(p_anim, read_only);
|
||||||
|
|
||||||
_cancel_bezier_edit();
|
_cancel_bezier_edit();
|
||||||
_update_tracks();
|
_update_tracks();
|
||||||
|
@ -3372,7 +3428,7 @@ void AnimationTrackEditor::set_animation(const Ref<Animation> &p_anim) {
|
||||||
animation->connect("changed", callable_mp(this, &AnimationTrackEditor::_animation_changed));
|
animation->connect("changed", callable_mp(this, &AnimationTrackEditor::_animation_changed));
|
||||||
|
|
||||||
hscroll->show();
|
hscroll->show();
|
||||||
edit->set_disabled(false);
|
edit->set_disabled(read_only);
|
||||||
step->set_block_signals(true);
|
step->set_block_signals(true);
|
||||||
|
|
||||||
_update_step_spinbox();
|
_update_step_spinbox();
|
||||||
|
@ -3501,7 +3557,7 @@ void AnimationTrackEditor::set_state(const Dictionary &p_state) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnimationTrackEditor::cleanup() {
|
void AnimationTrackEditor::cleanup() {
|
||||||
set_animation(Ref<Animation>());
|
set_animation(Ref<Animation>(), read_only);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnimationTrackEditor::_name_limit_changed() {
|
void AnimationTrackEditor::_name_limit_changed() {
|
||||||
|
@ -4378,6 +4434,27 @@ void AnimationTrackEditor::_update_tracks() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool read_only = false;
|
||||||
|
if (!animation->get_path().is_resource_file()) {
|
||||||
|
int srpos = animation->get_path().find("::");
|
||||||
|
if (srpos != -1) {
|
||||||
|
String base = animation->get_path().substr(0, srpos);
|
||||||
|
if (ResourceLoader::get_resource_type(base) == "PackedScene") {
|
||||||
|
if (!get_tree()->get_edited_scene_root() || get_tree()->get_edited_scene_root()->get_scene_file_path() != base) {
|
||||||
|
read_only = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (FileAccess::exists(base + ".import")) {
|
||||||
|
read_only = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (FileAccess::exists(animation->get_path() + ".import")) {
|
||||||
|
read_only = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
RBMap<String, VBoxContainer *> group_sort;
|
RBMap<String, VBoxContainer *> group_sort;
|
||||||
|
|
||||||
bool use_grouping = !view_group->is_pressed();
|
bool use_grouping = !view_group->is_pressed();
|
||||||
|
@ -4506,7 +4583,7 @@ void AnimationTrackEditor::_update_tracks() {
|
||||||
track_edit->set_undo_redo(undo_redo);
|
track_edit->set_undo_redo(undo_redo);
|
||||||
track_edit->set_timeline(timeline);
|
track_edit->set_timeline(timeline);
|
||||||
track_edit->set_root(root);
|
track_edit->set_root(root);
|
||||||
track_edit->set_animation_and_track(animation, i);
|
track_edit->set_animation_and_track(animation, i, read_only);
|
||||||
track_edit->set_play_position(timeline->get_play_position());
|
track_edit->set_play_position(timeline->get_play_position());
|
||||||
track_edit->set_editor(this);
|
track_edit->set_editor(this);
|
||||||
|
|
||||||
|
@ -5178,6 +5255,7 @@ void AnimationTrackEditor::_update_key_edit() {
|
||||||
if (selection.size() == 1) {
|
if (selection.size() == 1) {
|
||||||
key_edit = memnew(AnimationTrackKeyEdit);
|
key_edit = memnew(AnimationTrackKeyEdit);
|
||||||
key_edit->animation = animation;
|
key_edit->animation = animation;
|
||||||
|
key_edit->animation_read_only = read_only;
|
||||||
key_edit->track = selection.front()->key().track;
|
key_edit->track = selection.front()->key().track;
|
||||||
key_edit->use_fps = timeline->is_using_fps();
|
key_edit->use_fps = timeline->is_using_fps();
|
||||||
|
|
||||||
|
@ -5194,6 +5272,7 @@ void AnimationTrackEditor::_update_key_edit() {
|
||||||
} else if (selection.size() > 1) {
|
} else if (selection.size() > 1) {
|
||||||
multi_key_edit = memnew(AnimationMultiTrackKeyEdit);
|
multi_key_edit = memnew(AnimationMultiTrackKeyEdit);
|
||||||
multi_key_edit->animation = animation;
|
multi_key_edit->animation = animation;
|
||||||
|
multi_key_edit->animation_read_only = read_only;
|
||||||
|
|
||||||
RBMap<int, List<float>> key_ofs_map;
|
RBMap<int, List<float>> key_ofs_map;
|
||||||
RBMap<int, NodePath> base_map;
|
RBMap<int, NodePath> base_map;
|
||||||
|
@ -5473,7 +5552,7 @@ void AnimationTrackEditor::_cancel_bezier_edit() {
|
||||||
void AnimationTrackEditor::_bezier_edit(int p_for_track) {
|
void AnimationTrackEditor::_bezier_edit(int p_for_track) {
|
||||||
_clear_selection(); // Bezier probably wants to use a separate selection mode.
|
_clear_selection(); // Bezier probably wants to use a separate selection mode.
|
||||||
bezier_edit->set_root(root);
|
bezier_edit->set_root(root);
|
||||||
bezier_edit->set_animation_and_track(animation, p_for_track);
|
bezier_edit->set_animation_and_track(animation, p_for_track, read_only);
|
||||||
scroll->hide();
|
scroll->hide();
|
||||||
bezier_edit->show();
|
bezier_edit->show();
|
||||||
// Search everything within the track and curve - edit it.
|
// Search everything within the track and curve - edit it.
|
||||||
|
|
|
@ -56,6 +56,8 @@ class AnimationTimelineEdit : public Range {
|
||||||
GDCLASS(AnimationTimelineEdit, Range);
|
GDCLASS(AnimationTimelineEdit, Range);
|
||||||
|
|
||||||
Ref<Animation> animation;
|
Ref<Animation> animation;
|
||||||
|
bool read_only = false;
|
||||||
|
|
||||||
AnimationTrackEdit *track_edit = nullptr;
|
AnimationTrackEdit *track_edit = nullptr;
|
||||||
int name_limit = 0;
|
int name_limit = 0;
|
||||||
Range *zoom = nullptr;
|
Range *zoom = nullptr;
|
||||||
|
@ -106,7 +108,7 @@ public:
|
||||||
float get_zoom_scale() const;
|
float get_zoom_scale() const;
|
||||||
|
|
||||||
virtual Size2 get_minimum_size() const override;
|
virtual Size2 get_minimum_size() const override;
|
||||||
void set_animation(const Ref<Animation> &p_animation);
|
void set_animation(const Ref<Animation> &p_animation, bool p_read_only);
|
||||||
void set_track_edit(AnimationTrackEdit *p_track_edit);
|
void set_track_edit(AnimationTrackEdit *p_track_edit);
|
||||||
void set_zoom(Range *p_zoom);
|
void set_zoom(Range *p_zoom);
|
||||||
Range *get_zoom() const { return zoom; }
|
Range *get_zoom() const { return zoom; }
|
||||||
|
@ -159,6 +161,7 @@ class AnimationTrackEdit : public Control {
|
||||||
NodePath node_path;
|
NodePath node_path;
|
||||||
|
|
||||||
Ref<Animation> animation;
|
Ref<Animation> animation;
|
||||||
|
bool read_only = false;
|
||||||
int track = 0;
|
int track = 0;
|
||||||
|
|
||||||
Rect2 check_rect;
|
Rect2 check_rect;
|
||||||
|
@ -232,7 +235,7 @@ public:
|
||||||
AnimationTrackEditor *get_editor() const { return editor; }
|
AnimationTrackEditor *get_editor() const { return editor; }
|
||||||
UndoRedo *get_undo_redo() const { return undo_redo; }
|
UndoRedo *get_undo_redo() const { return undo_redo; }
|
||||||
NodePath get_path() const;
|
NodePath get_path() const;
|
||||||
void set_animation_and_track(const Ref<Animation> &p_animation, int p_track);
|
void set_animation_and_track(const Ref<Animation> &p_animation, int p_track, bool p_read_only);
|
||||||
virtual Size2 get_minimum_size() const override;
|
virtual Size2 get_minimum_size() const override;
|
||||||
|
|
||||||
void set_undo_redo(UndoRedo *p_undo_redo);
|
void set_undo_redo(UndoRedo *p_undo_redo);
|
||||||
|
@ -290,6 +293,7 @@ class AnimationTrackEditor : public VBoxContainer {
|
||||||
GDCLASS(AnimationTrackEditor, VBoxContainer);
|
GDCLASS(AnimationTrackEditor, VBoxContainer);
|
||||||
|
|
||||||
Ref<Animation> animation;
|
Ref<Animation> animation;
|
||||||
|
bool read_only = false;
|
||||||
Node *root = nullptr;
|
Node *root = nullptr;
|
||||||
|
|
||||||
MenuButton *edit = nullptr;
|
MenuButton *edit = nullptr;
|
||||||
|
@ -533,7 +537,7 @@ public:
|
||||||
void add_track_edit_plugin(const Ref<AnimationTrackEditPlugin> &p_plugin);
|
void add_track_edit_plugin(const Ref<AnimationTrackEditPlugin> &p_plugin);
|
||||||
void remove_track_edit_plugin(const Ref<AnimationTrackEditPlugin> &p_plugin);
|
void remove_track_edit_plugin(const Ref<AnimationTrackEditPlugin> &p_plugin);
|
||||||
|
|
||||||
void set_animation(const Ref<Animation> &p_anim);
|
void set_animation(const Ref<Animation> &p_anim, bool p_read_only);
|
||||||
Ref<Animation> get_current_animation() const;
|
Ref<Animation> get_current_animation() const;
|
||||||
void set_root(Node *p_root);
|
void set_root(Node *p_root);
|
||||||
Node *get_root() const;
|
Node *get_root() const;
|
||||||
|
|
|
@ -149,13 +149,35 @@ void AnimationLibraryEditor::_file_popup_selected(int p_id) {
|
||||||
}
|
}
|
||||||
switch (p_id) {
|
switch (p_id) {
|
||||||
case FILE_MENU_SAVE_LIBRARY: {
|
case FILE_MENU_SAVE_LIBRARY: {
|
||||||
if (al->get_path().is_resource_file()) {
|
if (al->get_path().is_resource_file() && !FileAccess::exists(al->get_path() + ".import")) {
|
||||||
EditorNode::get_singleton()->save_resource(al);
|
EditorNode::get_singleton()->save_resource(al);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
[[fallthrough]];
|
[[fallthrough]];
|
||||||
}
|
}
|
||||||
case FILE_MENU_SAVE_AS_LIBRARY: {
|
case FILE_MENU_SAVE_AS_LIBRARY: {
|
||||||
|
// Check if we're allowed to save this
|
||||||
|
{
|
||||||
|
String al_path = al->get_path();
|
||||||
|
if (!al_path.is_resource_file()) {
|
||||||
|
int srpos = al_path.find("::");
|
||||||
|
if (srpos != -1) {
|
||||||
|
String base = al_path.substr(0, srpos);
|
||||||
|
if (!get_tree()->get_edited_scene_root() || get_tree()->get_edited_scene_root()->get_scene_file_path() != base) {
|
||||||
|
error_dialog->set_text(TTR("This animation library can't be saved because it does not belong to the edited scene. Make it unique first."));
|
||||||
|
error_dialog->popup_centered();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (FileAccess::exists(al_path + ".import")) {
|
||||||
|
error_dialog->set_text(TTR("This animation library can't be saved because it was imported from another file. Make it unique first."));
|
||||||
|
error_dialog->popup_centered();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
file_dialog->set_file_mode(EditorFileDialog::FILE_MODE_SAVE_FILE);
|
file_dialog->set_file_mode(EditorFileDialog::FILE_MODE_SAVE_FILE);
|
||||||
file_dialog->set_title(TTR("Save Library"));
|
file_dialog->set_title(TTR("Save Library"));
|
||||||
if (al->get_path().is_resource_file()) {
|
if (al->get_path().is_resource_file()) {
|
||||||
|
@ -178,6 +200,9 @@ void AnimationLibraryEditor::_file_popup_selected(int p_id) {
|
||||||
|
|
||||||
Ref<AnimationLibrary> ald = al->duplicate();
|
Ref<AnimationLibrary> ald = al->duplicate();
|
||||||
|
|
||||||
|
// TODO: should probably make all foreign animations assigned to this library
|
||||||
|
// unique too.
|
||||||
|
|
||||||
UndoRedo *undo_redo = EditorNode::get_singleton()->get_undo_redo();
|
UndoRedo *undo_redo = EditorNode::get_singleton()->get_undo_redo();
|
||||||
undo_redo->create_action(vformat(TTR("Make Animation Library Unique: %s"), lib_name));
|
undo_redo->create_action(vformat(TTR("Make Animation Library Unique: %s"), lib_name));
|
||||||
undo_redo->add_do_method(player, "remove_animation_library", lib_name);
|
undo_redo->add_do_method(player, "remove_animation_library", lib_name);
|
||||||
|
@ -188,19 +213,43 @@ void AnimationLibraryEditor::_file_popup_selected(int p_id) {
|
||||||
undo_redo->add_undo_method(this, "_update_editor", player);
|
undo_redo->add_undo_method(this, "_update_editor", player);
|
||||||
undo_redo->commit_action();
|
undo_redo->commit_action();
|
||||||
|
|
||||||
|
update_tree();
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case FILE_MENU_EDIT_LIBRARY: {
|
case FILE_MENU_EDIT_LIBRARY: {
|
||||||
EditorNode::get_singleton()->push_item(al.ptr());
|
EditorNode::get_singleton()->push_item(al.ptr());
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case FILE_MENU_SAVE_ANIMATION: {
|
case FILE_MENU_SAVE_ANIMATION: {
|
||||||
if (anim->get_path().is_resource_file()) {
|
if (anim->get_path().is_resource_file() && !FileAccess::exists(anim->get_path() + ".import")) {
|
||||||
EditorNode::get_singleton()->save_resource(anim);
|
EditorNode::get_singleton()->save_resource(anim);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
[[fallthrough]];
|
[[fallthrough]];
|
||||||
}
|
}
|
||||||
case FILE_MENU_SAVE_AS_ANIMATION: {
|
case FILE_MENU_SAVE_AS_ANIMATION: {
|
||||||
|
// Check if we're allowed to save this
|
||||||
|
{
|
||||||
|
String anim_path = al->get_path();
|
||||||
|
if (!anim_path.is_resource_file()) {
|
||||||
|
int srpos = anim_path.find("::");
|
||||||
|
if (srpos != -1) {
|
||||||
|
String base = anim_path.substr(0, srpos);
|
||||||
|
if (!get_tree()->get_edited_scene_root() || get_tree()->get_edited_scene_root()->get_scene_file_path() != base) {
|
||||||
|
error_dialog->set_text(TTR("This animation can't be saved because it does not belong to the edited scene. Make it unique first."));
|
||||||
|
error_dialog->popup_centered();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (FileAccess::exists(anim_path + ".import")) {
|
||||||
|
error_dialog->set_text(TTR("This animation can't be saved because it was imported from another file. Make it unique first."));
|
||||||
|
error_dialog->popup_centered();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
file_dialog->set_file_mode(EditorFileDialog::FILE_MODE_SAVE_FILE);
|
file_dialog->set_file_mode(EditorFileDialog::FILE_MODE_SAVE_FILE);
|
||||||
file_dialog->set_title(TTR("Save Animation"));
|
file_dialog->set_title(TTR("Save Animation"));
|
||||||
if (anim->get_path().is_resource_file()) {
|
if (anim->get_path().is_resource_file()) {
|
||||||
|
@ -232,6 +281,8 @@ void AnimationLibraryEditor::_file_popup_selected(int p_id) {
|
||||||
undo_redo->add_do_method(this, "_update_editor", player);
|
undo_redo->add_do_method(this, "_update_editor", player);
|
||||||
undo_redo->add_undo_method(this, "_update_editor", player);
|
undo_redo->add_undo_method(this, "_update_editor", player);
|
||||||
undo_redo->commit_action();
|
undo_redo->commit_action();
|
||||||
|
|
||||||
|
update_tree();
|
||||||
} break;
|
} break;
|
||||||
case FILE_MENU_EDIT_ANIMATION: {
|
case FILE_MENU_EDIT_ANIMATION: {
|
||||||
EditorNode::get_singleton()->push_item(anim.ptr());
|
EditorNode::get_singleton()->push_item(anim.ptr());
|
||||||
|
@ -577,19 +628,45 @@ void AnimationLibraryEditor::update_tree() {
|
||||||
} else {
|
} else {
|
||||||
libitem->set_suffix(0, "");
|
libitem->set_suffix(0, "");
|
||||||
}
|
}
|
||||||
libitem->set_editable(0, true);
|
|
||||||
|
Ref<AnimationLibrary> al = player->call("get_animation_library", K);
|
||||||
|
bool animation_library_is_foreign = false;
|
||||||
|
String al_path = al->get_path();
|
||||||
|
if (!al_path.is_resource_file()) {
|
||||||
|
libitem->set_text(1, TTR("[built-in]"));
|
||||||
|
libitem->set_tooltip(1, al_path);
|
||||||
|
int srpos = al_path.find("::");
|
||||||
|
if (srpos != -1) {
|
||||||
|
String base = al_path.substr(0, srpos);
|
||||||
|
if (ResourceLoader::get_resource_type(base) == "PackedScene") {
|
||||||
|
if (!get_tree()->get_edited_scene_root() || get_tree()->get_edited_scene_root()->get_scene_file_path() != base) {
|
||||||
|
animation_library_is_foreign = true;
|
||||||
|
libitem->set_text(1, TTR("[foreign]"));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (FileAccess::exists(base + ".import")) {
|
||||||
|
animation_library_is_foreign = true;
|
||||||
|
libitem->set_text(1, TTR("[imported]"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (FileAccess::exists(al_path + ".import")) {
|
||||||
|
animation_library_is_foreign = true;
|
||||||
|
libitem->set_text(1, TTR("[imported]"));
|
||||||
|
} else {
|
||||||
|
libitem->set_text(1, al_path.get_file());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
libitem->set_editable(0, !animation_library_is_foreign);
|
||||||
libitem->set_metadata(0, K);
|
libitem->set_metadata(0, K);
|
||||||
libitem->set_icon(0, get_theme_icon("AnimationLibrary", "EditorIcons"));
|
libitem->set_icon(0, get_theme_icon("AnimationLibrary", "EditorIcons"));
|
||||||
libitem->add_button(0, get_theme_icon("Add", "EditorIcons"), LIB_BUTTON_ADD, false, TTR("Add Animation to Library"));
|
|
||||||
libitem->add_button(0, get_theme_icon("Load", "EditorIcons"), LIB_BUTTON_LOAD, false, TTR("Load animation from file and add to library"));
|
libitem->add_button(0, get_theme_icon("Add", "EditorIcons"), LIB_BUTTON_ADD, animation_library_is_foreign, TTR("Add Animation to Library"));
|
||||||
libitem->add_button(0, get_theme_icon("ActionPaste", "EditorIcons"), LIB_BUTTON_PASTE, false, TTR("Paste Animation to Library from clipboard"));
|
libitem->add_button(0, get_theme_icon("Load", "EditorIcons"), LIB_BUTTON_LOAD, animation_library_is_foreign, TTR("Load animation from file and add to library"));
|
||||||
Ref<AnimationLibrary> al = player->call("get_animation_library", K);
|
libitem->add_button(0, get_theme_icon("ActionPaste", "EditorIcons"), LIB_BUTTON_PASTE, animation_library_is_foreign, TTR("Paste Animation to Library from clipboard"));
|
||||||
if (al->get_path().is_resource_file()) {
|
|
||||||
libitem->set_text(1, al->get_path().get_file());
|
|
||||||
libitem->set_tooltip(1, al->get_path());
|
|
||||||
} else {
|
|
||||||
libitem->set_text(1, TTR("[built-in]"));
|
|
||||||
}
|
|
||||||
libitem->add_button(1, get_theme_icon("Save", "EditorIcons"), LIB_BUTTON_FILE, false, TTR("Save animation library to resource on disk"));
|
libitem->add_button(1, get_theme_icon("Save", "EditorIcons"), LIB_BUTTON_FILE, false, TTR("Save animation library to resource on disk"));
|
||||||
libitem->add_button(1, get_theme_icon("Remove", "EditorIcons"), LIB_BUTTON_DELETE, false, TTR("Remove animation library"));
|
libitem->add_button(1, get_theme_icon("Remove", "EditorIcons"), LIB_BUTTON_DELETE, false, TTR("Remove animation library"));
|
||||||
|
|
||||||
|
@ -600,20 +677,38 @@ void AnimationLibraryEditor::update_tree() {
|
||||||
for (const StringName &L : animations) {
|
for (const StringName &L : animations) {
|
||||||
TreeItem *anitem = tree->create_item(libitem);
|
TreeItem *anitem = tree->create_item(libitem);
|
||||||
anitem->set_text(0, L);
|
anitem->set_text(0, L);
|
||||||
anitem->set_editable(0, true);
|
anitem->set_editable(0, !animation_library_is_foreign);
|
||||||
anitem->set_metadata(0, L);
|
anitem->set_metadata(0, L);
|
||||||
anitem->set_icon(0, get_theme_icon("Animation", "EditorIcons"));
|
anitem->set_icon(0, get_theme_icon("Animation", "EditorIcons"));
|
||||||
anitem->add_button(0, get_theme_icon("ActionCopy", "EditorIcons"), ANIM_BUTTON_COPY, false, TTR("Copy animation to clipboard"));
|
anitem->add_button(0, get_theme_icon("ActionCopy", "EditorIcons"), ANIM_BUTTON_COPY, animation_library_is_foreign, TTR("Copy animation to clipboard"));
|
||||||
Ref<Animation> anim = al->get_animation(L);
|
|
||||||
|
|
||||||
if (anim->get_path().is_resource_file()) {
|
Ref<Animation> anim = al->get_animation(L);
|
||||||
anitem->set_text(1, anim->get_path().get_file());
|
String anim_path = anim->get_path();
|
||||||
anitem->set_tooltip(1, anim->get_path());
|
if (!anim_path.is_resource_file()) {
|
||||||
} else {
|
|
||||||
anitem->set_text(1, TTR("[built-in]"));
|
anitem->set_text(1, TTR("[built-in]"));
|
||||||
|
anitem->set_tooltip(1, anim_path);
|
||||||
|
int srpos = anim_path.find("::");
|
||||||
|
if (srpos != -1) {
|
||||||
|
String base = anim_path.substr(0, srpos);
|
||||||
|
if (ResourceLoader::get_resource_type(base) == "PackedScene") {
|
||||||
|
if (!get_tree()->get_edited_scene_root() || get_tree()->get_edited_scene_root()->get_scene_file_path() != base) {
|
||||||
|
anitem->set_text(1, TTR("[foreign]"));
|
||||||
}
|
}
|
||||||
anitem->add_button(1, get_theme_icon("Save", "EditorIcons"), ANIM_BUTTON_FILE, false, TTR("Save animation to resource on disk"));
|
} else {
|
||||||
anitem->add_button(1, get_theme_icon("Remove", "EditorIcons"), ANIM_BUTTON_DELETE, false, TTR("Remove animation from Library"));
|
if (FileAccess::exists(base + ".import")) {
|
||||||
|
anitem->set_text(1, TTR("[imported]"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (FileAccess::exists(anim_path + ".import")) {
|
||||||
|
anitem->set_text(1, TTR("[imported]"));
|
||||||
|
} else {
|
||||||
|
anitem->set_text(1, anim_path.get_file());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
anitem->add_button(1, get_theme_icon("Save", "EditorIcons"), ANIM_BUTTON_FILE, animation_library_is_foreign, TTR("Save animation to resource on disk"));
|
||||||
|
anitem->add_button(1, get_theme_icon("Remove", "EditorIcons"), ANIM_BUTTON_DELETE, animation_library_is_foreign, TTR("Remove animation from Library"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,7 @@ void AnimationPlayerEditor::_node_removed(Node *p_node) {
|
||||||
|
|
||||||
set_process(false);
|
set_process(false);
|
||||||
|
|
||||||
track_editor->set_animation(Ref<Animation>());
|
track_editor->set_animation(Ref<Animation>(), true);
|
||||||
track_editor->set_root(nullptr);
|
track_editor->set_root(nullptr);
|
||||||
track_editor->show_select_node_warning(true);
|
track_editor->show_select_node_warning(true);
|
||||||
_update_player();
|
_update_player();
|
||||||
|
@ -283,7 +283,28 @@ void AnimationPlayerEditor::_animation_selected(int p_which) {
|
||||||
|
|
||||||
Ref<Animation> anim = player->get_animation(current);
|
Ref<Animation> anim = player->get_animation(current);
|
||||||
{
|
{
|
||||||
track_editor->set_animation(anim);
|
bool animation_library_is_foreign = false;
|
||||||
|
if (!anim->get_path().is_resource_file()) {
|
||||||
|
int srpos = anim->get_path().find("::");
|
||||||
|
if (srpos != -1) {
|
||||||
|
String base = anim->get_path().substr(0, srpos);
|
||||||
|
if (ResourceLoader::get_resource_type(base) == "PackedScene") {
|
||||||
|
if (!get_tree()->get_edited_scene_root() || get_tree()->get_edited_scene_root()->get_scene_file_path() != base) {
|
||||||
|
animation_library_is_foreign = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (FileAccess::exists(base + ".import")) {
|
||||||
|
animation_library_is_foreign = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (FileAccess::exists(anim->get_path() + ".import")) {
|
||||||
|
animation_library_is_foreign = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
track_editor->set_animation(anim, animation_library_is_foreign);
|
||||||
Node *root = player->get_node(player->get_root());
|
Node *root = player->get_node(player->get_root());
|
||||||
if (root) {
|
if (root) {
|
||||||
track_editor->set_root(root);
|
track_editor->set_root(root);
|
||||||
|
@ -292,7 +313,7 @@ void AnimationPlayerEditor::_animation_selected(int p_which) {
|
||||||
frame->set_max((double)anim->get_length());
|
frame->set_max((double)anim->get_length());
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
track_editor->set_animation(Ref<Animation>());
|
track_editor->set_animation(Ref<Animation>(), true);
|
||||||
track_editor->set_root(nullptr);
|
track_editor->set_root(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -751,14 +772,36 @@ void AnimationPlayerEditor::_animation_edit() {
|
||||||
String current = _get_current();
|
String current = _get_current();
|
||||||
if (current != String()) {
|
if (current != String()) {
|
||||||
Ref<Animation> anim = player->get_animation(current);
|
Ref<Animation> anim = player->get_animation(current);
|
||||||
track_editor->set_animation(anim);
|
|
||||||
|
bool animation_library_is_foreign = false;
|
||||||
|
if (!anim->get_path().is_resource_file()) {
|
||||||
|
int srpos = anim->get_path().find("::");
|
||||||
|
if (srpos != -1) {
|
||||||
|
String base = anim->get_path().substr(0, srpos);
|
||||||
|
if (ResourceLoader::get_resource_type(base) == "PackedScene") {
|
||||||
|
if (!get_tree()->get_edited_scene_root() || get_tree()->get_edited_scene_root()->get_scene_file_path() != base) {
|
||||||
|
animation_library_is_foreign = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (FileAccess::exists(base + ".import")) {
|
||||||
|
animation_library_is_foreign = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (FileAccess::exists(anim->get_path() + ".import")) {
|
||||||
|
animation_library_is_foreign = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
track_editor->set_animation(anim, animation_library_is_foreign);
|
||||||
|
|
||||||
Node *root = player->get_node(player->get_root());
|
Node *root = player->get_node(player->get_root());
|
||||||
if (root) {
|
if (root) {
|
||||||
track_editor->set_root(root);
|
track_editor->set_root(root);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
track_editor->set_animation(Ref<Animation>());
|
track_editor->set_animation(Ref<Animation>(), true);
|
||||||
track_editor->set_root(nullptr);
|
track_editor->set_root(nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -812,13 +855,37 @@ void AnimationPlayerEditor::_update_player() {
|
||||||
|
|
||||||
int active_idx = -1;
|
int active_idx = -1;
|
||||||
bool no_anims_found = true;
|
bool no_anims_found = true;
|
||||||
|
bool foreign_global_anim_lib = false;
|
||||||
|
|
||||||
for (const StringName &K : libraries) {
|
for (const StringName &K : libraries) {
|
||||||
if (K != StringName()) {
|
if (K != StringName()) {
|
||||||
animation->add_separator(K);
|
animation->add_separator(K);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if the global library is foreign since we want to disable options for adding/remove/renaming animations if it is.
|
||||||
Ref<AnimationLibrary> library = player->get_animation_library(K);
|
Ref<AnimationLibrary> library = player->get_animation_library(K);
|
||||||
|
if (K == "") {
|
||||||
|
if (!library->get_path().is_resource_file()) {
|
||||||
|
int srpos = library->get_path().find("::");
|
||||||
|
if (srpos != -1) {
|
||||||
|
String base = library->get_path().substr(0, srpos);
|
||||||
|
if (ResourceLoader::get_resource_type(base) == "PackedScene") {
|
||||||
|
if (!get_tree()->get_edited_scene_root() || get_tree()->get_edited_scene_root()->get_scene_file_path() != base) {
|
||||||
|
foreign_global_anim_lib = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (FileAccess::exists(base + ".import")) {
|
||||||
|
foreign_global_anim_lib = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (FileAccess::exists(library->get_path() + ".import")) {
|
||||||
|
foreign_global_anim_lib = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
List<StringName> animlist;
|
List<StringName> animlist;
|
||||||
library->get_animation_list(&animlist);
|
library->get_animation_list(&animlist);
|
||||||
|
|
||||||
|
@ -835,7 +902,13 @@ void AnimationPlayerEditor::_update_player() {
|
||||||
no_anims_found = false;
|
no_anims_found = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#define ITEM_CHECK_DISABLED(m_item) tool_anim->get_popup()->set_item_disabled(tool_anim->get_popup()->get_item_index(m_item), no_anims_found)
|
#define ITEM_CHECK_DISABLED(m_item) tool_anim->get_popup()->set_item_disabled(tool_anim->get_popup()->get_item_index(m_item), foreign_global_anim_lib)
|
||||||
|
|
||||||
|
ITEM_CHECK_DISABLED(TOOL_NEW_ANIM);
|
||||||
|
|
||||||
|
#undef ITEM_CHECK_DISABLED
|
||||||
|
|
||||||
|
#define ITEM_CHECK_DISABLED(m_item) tool_anim->get_popup()->set_item_disabled(tool_anim->get_popup()->get_item_index(m_item), no_anims_found || foreign_global_anim_lib)
|
||||||
|
|
||||||
ITEM_CHECK_DISABLED(TOOL_DUPLICATE_ANIM);
|
ITEM_CHECK_DISABLED(TOOL_DUPLICATE_ANIM);
|
||||||
ITEM_CHECK_DISABLED(TOOL_RENAME_ANIM);
|
ITEM_CHECK_DISABLED(TOOL_RENAME_ANIM);
|
||||||
|
@ -877,7 +950,29 @@ void AnimationPlayerEditor::_update_player() {
|
||||||
if (!no_anims_found) {
|
if (!no_anims_found) {
|
||||||
String current = animation->get_item_text(animation->get_selected());
|
String current = animation->get_item_text(animation->get_selected());
|
||||||
Ref<Animation> anim = player->get_animation(current);
|
Ref<Animation> anim = player->get_animation(current);
|
||||||
track_editor->set_animation(anim);
|
|
||||||
|
bool animation_library_is_foreign = false;
|
||||||
|
if (!anim->get_path().is_resource_file()) {
|
||||||
|
int srpos = anim->get_path().find("::");
|
||||||
|
if (srpos != -1) {
|
||||||
|
String base = anim->get_path().substr(0, srpos);
|
||||||
|
if (ResourceLoader::get_resource_type(base) == "PackedScene") {
|
||||||
|
if (!get_tree()->get_edited_scene_root() || get_tree()->get_edited_scene_root()->get_scene_file_path() != base) {
|
||||||
|
animation_library_is_foreign = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (FileAccess::exists(base + ".import")) {
|
||||||
|
animation_library_is_foreign = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (FileAccess::exists(anim->get_path() + ".import")) {
|
||||||
|
animation_library_is_foreign = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
track_editor->set_animation(anim, animation_library_is_foreign);
|
||||||
Node *root = player->get_node(player->get_root());
|
Node *root = player->get_node(player->get_root());
|
||||||
if (root) {
|
if (root) {
|
||||||
track_editor->set_root(root);
|
track_editor->set_root(root);
|
||||||
|
|
Loading…
Reference in New Issue