Browse Source

Merge pull request #107511 from shadow-foss/insert-at-timeline-cursor-button

Add toggle for inserting keys/markers at current time vs mouse cursor's position
Thaddeus Crews 3 weeks ago
parent
commit
25981beebd

+ 4 - 0
doc/classes/EditorSettings.xml

@@ -547,6 +547,10 @@
 		<member name="editors/animation/default_fps_mode" type="int" setter="" getter="">
 		<member name="editors/animation/default_fps_mode" type="int" setter="" getter="">
 			Default step mode for [AnimationPlayer] (seconds or FPS). The option is remembered locally for a scene and this option only determines the default value when scene doesn't have local state yet.
 			Default step mode for [AnimationPlayer] (seconds or FPS). The option is remembered locally for a scene and this option only determines the default value when scene doesn't have local state yet.
 		</member>
 		</member>
+		<member name="editors/animation/insert_at_current_time" type="bool" setter="" getter="">
+			If [code]true[/code], animation keys and markers are inserted at the current time in the animation.
+			If [code]false[/code], they are inserted at the mouse cursor's position.
+		</member>
 		<member name="editors/animation/onion_layers_future_color" type="Color" setter="" getter="">
 		<member name="editors/animation/onion_layers_future_color" type="Color" setter="" getter="">
 			The modulate color to use for "future" frames displayed in the animation editor's onion skinning feature.
 			The modulate color to use for "future" frames displayed in the animation editor's onion skinning feature.
 		</member>
 		</member>

+ 29 - 2
editor/animation/animation_track_editor.cpp

@@ -3596,7 +3596,7 @@ void AnimationTrackEdit::_menu_selected(int p_index) {
 			emit_signal(SNAME("insert_key"), insert_at_pos);
 			emit_signal(SNAME("insert_key"), insert_at_pos);
 		} break;
 		} break;
 		case MENU_KEY_DUPLICATE: {
 		case MENU_KEY_DUPLICATE: {
-			emit_signal(SNAME("duplicate_request"), insert_at_pos, true);
+			emit_signal(SNAME("duplicate_request"), insert_at_pos, !editor->is_insert_at_current_time_enabled());
 		} break;
 		} break;
 		case MENU_KEY_CUT: {
 		case MENU_KEY_CUT: {
 			emit_signal(SNAME("cut_request"));
 			emit_signal(SNAME("cut_request"));
@@ -3605,7 +3605,7 @@ void AnimationTrackEdit::_menu_selected(int p_index) {
 			emit_signal(SNAME("copy_request"));
 			emit_signal(SNAME("copy_request"));
 		} break;
 		} break;
 		case MENU_KEY_PASTE: {
 		case MENU_KEY_PASTE: {
-			emit_signal(SNAME("paste_request"), insert_at_pos, true);
+			emit_signal(SNAME("paste_request"), insert_at_pos, !editor->is_insert_at_current_time_enabled());
 		} break;
 		} break;
 		case MENU_KEY_ADD_RESET: {
 		case MENU_KEY_ADD_RESET: {
 			emit_signal(SNAME("create_reset_request"));
 			emit_signal(SNAME("create_reset_request"));
@@ -3948,6 +3948,7 @@ void AnimationTrackEditor::set_animation(const Ref<Animation> &p_anim, bool p_re
 		step->set_read_only(false);
 		step->set_read_only(false);
 		snap_keys->set_disabled(false);
 		snap_keys->set_disabled(false);
 		snap_timeline->set_disabled(false);
 		snap_timeline->set_disabled(false);
+		insert_at_current_time->set_disabled(false);
 		fps_compat->set_disabled(false);
 		fps_compat->set_disabled(false);
 		snap_mode->set_disabled(false);
 		snap_mode->set_disabled(false);
 		auto_fit->set_disabled(false);
 		auto_fit->set_disabled(false);
@@ -3971,6 +3972,7 @@ void AnimationTrackEditor::set_animation(const Ref<Animation> &p_anim, bool p_re
 		step->set_read_only(true);
 		step->set_read_only(true);
 		snap_keys->set_disabled(true);
 		snap_keys->set_disabled(true);
 		snap_timeline->set_disabled(true);
 		snap_timeline->set_disabled(true);
+		insert_at_current_time->set_disabled(true);
 		fps_compat->set_disabled(true);
 		fps_compat->set_disabled(true);
 		snap_mode->set_disabled(true);
 		snap_mode->set_disabled(true);
 		bezier_edit_icon->set_disabled(true);
 		bezier_edit_icon->set_disabled(true);
@@ -4930,6 +4932,16 @@ bool AnimationTrackEditor::is_snap_keys_enabled() const {
 	return snap_keys->is_pressed() ^ Input::get_singleton()->is_key_pressed(Key::CMD_OR_CTRL);
 	return snap_keys->is_pressed() ^ Input::get_singleton()->is_key_pressed(Key::CMD_OR_CTRL);
 }
 }
 
 
+bool AnimationTrackEditor::is_insert_at_current_time_enabled() const {
+	return insert_at_current_time->is_pressed();
+}
+
+void AnimationTrackEditor::resolve_insertion_offset(float &r_offset) const {
+	if (is_insert_at_current_time_enabled()) {
+		r_offset = timeline->get_play_position();
+	}
+}
+
 bool AnimationTrackEditor::is_bezier_editor_active() const {
 bool AnimationTrackEditor::is_bezier_editor_active() const {
 	return bezier_edit->is_visible();
 	return bezier_edit->is_visible();
 }
 }
@@ -5342,6 +5354,7 @@ void AnimationTrackEditor::_notification(int p_what) {
 			bezier_edit_icon->set_button_icon(get_editor_theme_icon(SNAME("EditBezier")));
 			bezier_edit_icon->set_button_icon(get_editor_theme_icon(SNAME("EditBezier")));
 			snap_timeline->set_button_icon(get_editor_theme_icon(SNAME("SnapTimeline")));
 			snap_timeline->set_button_icon(get_editor_theme_icon(SNAME("SnapTimeline")));
 			snap_keys->set_button_icon(get_editor_theme_icon(SNAME("SnapKeys")));
 			snap_keys->set_button_icon(get_editor_theme_icon(SNAME("SnapKeys")));
+			insert_at_current_time->set_button_icon(get_editor_theme_icon(SNAME("InsertAtCurrentTime")));
 			fps_compat->set_button_icon(get_editor_theme_icon(SNAME("FPS")));
 			fps_compat->set_button_icon(get_editor_theme_icon(SNAME("FPS")));
 			view_group->set_button_icon(get_editor_theme_icon(view_group->is_pressed() ? SNAME("AnimationTrackList") : SNAME("AnimationTrackGroup")));
 			view_group->set_button_icon(get_editor_theme_icon(view_group->is_pressed() ? SNAME("AnimationTrackList") : SNAME("AnimationTrackGroup")));
 			function_name_toggler->set_button_icon(get_editor_theme_icon(SNAME("MemberMethod")));
 			function_name_toggler->set_button_icon(get_editor_theme_icon(SNAME("MemberMethod")));
@@ -5696,6 +5709,9 @@ void AnimationTrackEditor::_insert_key_from_track(float p_ofs, int p_track) {
 	if (snap_keys->is_pressed() && step->get_value() != 0) {
 	if (snap_keys->is_pressed() && step->get_value() != 0) {
 		p_ofs = snap_time(p_ofs);
 		p_ofs = snap_time(p_ofs);
 	}
 	}
+
+	resolve_insertion_offset(p_ofs);
+
 	while (animation->track_find_key(p_track, p_ofs, Animation::FIND_MODE_APPROX) != -1) { // Make sure insertion point is valid.
 	while (animation->track_find_key(p_track, p_ofs, Animation::FIND_MODE_APPROX) != -1) { // Make sure insertion point is valid.
 		p_ofs += SECOND_DECIMAL;
 		p_ofs += SECOND_DECIMAL;
 	}
 	}
@@ -7909,6 +7925,15 @@ AnimationTrackEditor::AnimationTrackEditor() {
 	view_group->set_tooltip_text(TTR("Group tracks by node or display them as plain list."));
 	view_group->set_tooltip_text(TTR("Group tracks by node or display them as plain list."));
 
 
 	bottom_hf->add_child(view_group);
 	bottom_hf->add_child(view_group);
+
+	insert_at_current_time = memnew(Button);
+	insert_at_current_time->set_flat(true);
+	bottom_hf->add_child(insert_at_current_time);
+	insert_at_current_time->set_disabled(true);
+	insert_at_current_time->set_toggle_mode(true);
+	insert_at_current_time->set_pressed(EDITOR_GET("editors/animation/insert_at_current_time"));
+	insert_at_current_time->set_tooltip_text(TTRC("Insert at current time."));
+
 	bottom_hf->add_child(memnew(VSeparator));
 	bottom_hf->add_child(memnew(VSeparator));
 
 
 	snap_timeline = memnew(Button);
 	snap_timeline = memnew(Button);
@@ -9222,6 +9247,8 @@ void AnimationMarkerEdit::_insert_marker(float p_ofs) {
 		p_ofs = editor->snap_time(p_ofs);
 		p_ofs = editor->snap_time(p_ofs);
 	}
 	}
 
 
+	editor->resolve_insertion_offset(p_ofs);
+
 	marker_insert_confirm->popup_centered(Size2(200, 100) * EDSCALE);
 	marker_insert_confirm->popup_centered(Size2(200, 100) * EDSCALE);
 	marker_insert_color->set_pick_color(Color(1, 1, 1));
 	marker_insert_color->set_pick_color(Color(1, 1, 1));
 
 

+ 3 - 0
editor/animation/animation_track_editor.h

@@ -613,6 +613,7 @@ class AnimationTrackEditor : public VBoxContainer {
 	Label *nearest_fps_label = nullptr;
 	Label *nearest_fps_label = nullptr;
 	TextureRect *zoom_icon = nullptr;
 	TextureRect *zoom_icon = nullptr;
 	Button *snap_keys = nullptr;
 	Button *snap_keys = nullptr;
+	Button *insert_at_current_time = nullptr;
 	Button *snap_timeline = nullptr;
 	Button *snap_timeline = nullptr;
 	Button *bezier_edit_icon = nullptr;
 	Button *bezier_edit_icon = nullptr;
 	OptionButton *snap_mode = nullptr;
 	OptionButton *snap_mode = nullptr;
@@ -954,6 +955,8 @@ public:
 	bool is_moving_selection() const;
 	bool is_moving_selection() const;
 	bool is_snap_timeline_enabled() const;
 	bool is_snap_timeline_enabled() const;
 	bool is_snap_keys_enabled() const;
 	bool is_snap_keys_enabled() const;
+	bool is_insert_at_current_time_enabled() const;
+	void resolve_insertion_offset(float &r_offset) const;
 	bool is_bezier_editor_active() const;
 	bool is_bezier_editor_active() const;
 	bool can_add_reset_key() const;
 	bool can_add_reset_key() const;
 	void _on_filter_updated(const String &p_filter);
 	void _on_filter_updated(const String &p_filter);

+ 1 - 0
editor/icons/InsertAtCurrentTime.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="16" height="16"><path fill="#FFF" d="M5 1 1 5l4 4 4-4zm11 10.46L9.857 8.934l-1.571-.648.648 1.571L11.46 16l.913-2.72 1.815 1.818.91-.91-1.819-1.815z"/></svg>

+ 1 - 0
editor/settings/editor_settings.cpp

@@ -999,6 +999,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
 	_initial_set("editors/animation/confirm_insert_track", true, true);
 	_initial_set("editors/animation/confirm_insert_track", true, true);
 	_initial_set("editors/animation/default_create_bezier_tracks", false, true);
 	_initial_set("editors/animation/default_create_bezier_tracks", false, true);
 	_initial_set("editors/animation/default_create_reset_tracks", true, true);
 	_initial_set("editors/animation/default_create_reset_tracks", true, true);
+	_initial_set("editors/animation/insert_at_current_time", false, true);
 	_initial_set("editors/animation/onion_layers_past_color", Color(1, 0, 0));
 	_initial_set("editors/animation/onion_layers_past_color", Color(1, 0, 0));
 	_initial_set("editors/animation/onion_layers_future_color", Color(0, 1, 0));
 	_initial_set("editors/animation/onion_layers_future_color", Color(0, 1, 0));