Path: blob/master/editor/animation/animation_track_editor.h
21344 views
/**************************************************************************/1/* animation_track_editor.h */2/**************************************************************************/3/* This file is part of: */4/* GODOT ENGINE */5/* https://godotengine.org */6/**************************************************************************/7/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */8/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */9/* */10/* Permission is hereby granted, free of charge, to any person obtaining */11/* a copy of this software and associated documentation files (the */12/* "Software"), to deal in the Software without restriction, including */13/* without limitation the rights to use, copy, modify, merge, publish, */14/* distribute, sublicense, and/or sell copies of the Software, and to */15/* permit persons to whom the Software is furnished to do so, subject to */16/* the following conditions: */17/* */18/* The above copyright notice and this permission notice shall be */19/* included in all copies or substantial portions of the Software. */20/* */21/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */22/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */23/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */24/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */25/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */26/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */27/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */28/**************************************************************************/2930#pragma once3132#include "editor/editor_data.h"33#include "editor/inspector/editor_properties.h"34#include "editor/inspector/property_selector.h"35#include "scene/3d/node_3d.h"36#include "scene/gui/control.h"37#include "scene/gui/menu_button.h"38#include "scene/gui/scroll_bar.h"39#include "scene/gui/tree.h"40#include "scene/resources/animation.h"4142class AnimationMarkerEdit;43class AnimationTrackEditor;44class AnimationTrackEdit;45class CheckBox;46class ColorPickerButton;47class EditorSpinSlider;48class HSlider;49class OptionButton;50class PanelContainer;51class SceneTreeDialog;52class SpinBox;53class TextureRect;54class ViewPanner;55class EditorValidationPanel;5657class AnimationTrackKeyEdit : public Object {58GDCLASS(AnimationTrackKeyEdit, Object);5960public:61bool setting = false;62bool animation_read_only = false;6364Ref<Animation> animation;65int track = -1;66float key_ofs = 0;67Node *root_path = nullptr;6869PropertyInfo hint;70NodePath base;71bool use_fps = false;72AnimationTrackEditor *editor = nullptr;7374bool _hide_script_from_inspector() { return true; }75bool _hide_metadata_from_inspector() { return true; }76bool _dont_undo_redo() { return true; }7778bool _is_read_only() { return animation_read_only; }7980void notify_change();81Node *get_root_path();82void set_use_fps(bool p_enable);8384protected:85static void _bind_methods();86void _fix_node_path(Variant &value);87void _update_obj(const Ref<Animation> &p_anim);88void _key_ofs_changed(const Ref<Animation> &p_anim, float from, float to);89bool _set(const StringName &p_name, const Variant &p_value);90bool _get(const StringName &p_name, Variant &r_ret) const;91void _get_property_list(List<PropertyInfo> *p_list) const;92};9394class AnimationMultiTrackKeyEdit : public Object {95GDCLASS(AnimationMultiTrackKeyEdit, Object);9697public:98bool setting = false;99bool animation_read_only = false;100101Ref<Animation> animation;102103RBMap<int, List<float>> key_ofs_map;104RBMap<int, NodePath> base_map;105PropertyInfo hint;106107Node *root_path = nullptr;108109bool use_fps = false;110AnimationTrackEditor *editor = nullptr;111112bool _hide_script_from_inspector() { return true; }113bool _hide_metadata_from_inspector() { return true; }114bool _dont_undo_redo() { return true; }115116bool _is_read_only() { return animation_read_only; }117118void notify_change();119Node *get_root_path();120void set_use_fps(bool p_enable);121122protected:123static void _bind_methods();124void _fix_node_path(Variant &value, NodePath &base);125void _update_obj(const Ref<Animation> &p_anim);126void _key_ofs_changed(const Ref<Animation> &p_anim, float from, float to);127bool _set(const StringName &p_name, const Variant &p_value);128bool _get(const StringName &p_name, Variant &r_ret) const;129void _get_property_list(List<PropertyInfo> *p_list) const;130};131132class AnimationMarkerKeyEdit : public Object {133GDCLASS(AnimationMarkerKeyEdit, Object);134135public:136bool animation_read_only = false;137138Ref<Animation> animation;139StringName marker_name;140bool use_fps = false;141142AnimationMarkerEdit *marker_edit = nullptr;143144bool _hide_script_from_inspector() { return true; }145bool _hide_metadata_from_inspector() { return true; }146bool _dont_undo_redo() { return true; }147148bool _is_read_only() { return animation_read_only; }149150float get_time() const;151152protected:153static void _bind_methods();154void _set_marker_name(const StringName &p_name);155bool _set(const StringName &p_name, const Variant &p_value);156bool _get(const StringName &p_name, Variant &r_ret) const;157void _get_property_list(List<PropertyInfo> *p_list) const;158};159160class AnimationMultiMarkerKeyEdit : public Object {161GDCLASS(AnimationMultiMarkerKeyEdit, Object);162163public:164bool animation_read_only = false;165166Ref<Animation> animation;167Vector<StringName> marker_names;168169AnimationMarkerEdit *marker_edit = nullptr;170171bool _hide_script_from_inspector() { return true; }172bool _hide_metadata_from_inspector() { return true; }173bool _dont_undo_redo() { return true; }174175bool _is_read_only() { return animation_read_only; }176177protected:178static void _bind_methods();179bool _set(const StringName &p_name, const Variant &p_value);180bool _get(const StringName &p_name, Variant &r_ret) const;181void _get_property_list(List<PropertyInfo> *p_list) const;182};183184class AnimationTimelineEdit : public Range {185GDCLASS(AnimationTimelineEdit, Range);186187friend class AnimationBezierTrackEdit;188friend class AnimationTrackEditor;189friend class AnimationMarkerEdit;190191static constexpr float SCROLL_ZOOM_FACTOR_IN = 1.02f; // Zoom factor per mouse scroll in the animation editor when zooming in. The closer to 1.0, the finer the control.192static constexpr float SCROLL_ZOOM_FACTOR_OUT = 0.98f; // Zoom factor when zooming out. Similar to SCROLL_ZOOM_FACTOR_IN but less than 1.0.193194Ref<Animation> animation;195bool read_only = false;196197AnimationTrackEdit *track_edit = nullptr;198AnimationTrackEditor *editor = nullptr;199int name_limit = 0;200Range *zoom = nullptr;201Range *h_scroll = nullptr;202float play_position_pos = 0.0f;203204HBoxContainer *add_track_hb = nullptr;205HBoxContainer *len_hb = nullptr;206EditorSpinSlider *length = nullptr;207Button *loop = nullptr;208TextureRect *time_icon = nullptr;209210MenuButton *add_track = nullptr;211LineEdit *filter_track = nullptr;212Control *play_position = nullptr; //separate control used to draw so updates for only position changed are much faster213HScrollBar *hscroll = nullptr;214215void _zoom_changed(double);216void _anim_length_changed(double p_new_len);217void _anim_loop_pressed();218219void _play_position_draw();220Rect2 hsize_rect;221222bool editing = false;223bool use_fps = false;224225Ref<ViewPanner> panner;226void _pan_callback(Vector2 p_scroll_vec, Ref<InputEvent> p_event);227void _zoom_callback(float p_zoom_factor, Vector2 p_origin, Ref<InputEvent> p_event);228229Rect2 timeline_resize_rect;230float timeline_resize_from = 0.0f;231float timeline_resize_at = 0.0f;232bool resizing_timeline = false;233234bool dragging_timeline = false;235bool dragging_hsize = false;236float dragging_hsize_from = 0.0f;237float dragging_hsize_at = 0.0f;238double last_zoom_scale = 1.0;239double hscroll_on_zoom_buffer = -1.0;240241Vector2 zoom_scroll_origin;242bool zoom_callback_occurred = false;243244virtual void gui_input(const Ref<InputEvent> &p_event) override;245void _commit_timeline_resize();246void _stop_dragging();247void _track_added(int p_track);248249float _get_zoom_scale(double p_zoom_value) const;250void _scroll_to_start();251252protected:253static void _bind_methods();254void _notification(int p_what);255256public:257int get_name_limit() const;258int get_buttons_width() const;259260float get_zoom_scale() const;261262virtual Size2 get_minimum_size() const override;263void set_animation(const Ref<Animation> &p_animation, bool p_read_only);264void set_track_edit(AnimationTrackEdit *p_track_edit);265void set_editor(AnimationTrackEditor *p_editor);266void set_zoom(Range *p_zoom);267Range *get_zoom() const { return zoom; }268void auto_fit();269270void set_play_position(float p_pos);271float get_play_position() const;272void update_play_position();273274void update_values();275276void set_use_fps(bool p_use_fps);277bool is_using_fps() const;278279void set_hscroll(HScrollBar *p_hscroll);280281virtual CursorShape get_cursor_shape(const Point2 &p_pos) const override;282283AnimationTimelineEdit();284};285286class AnimationMarkerEdit : public Control {287GDCLASS(AnimationMarkerEdit, Control);288friend class AnimationTimelineEdit;289290enum {291MENU_KEY_INSERT,292MENU_KEY_RENAME,293MENU_KEY_DELETE,294MENU_KEY_TOGGLE_MARKER_NAMES,295};296297AnimationTimelineEdit *timeline = nullptr;298Control *play_position = nullptr; // Separate control used to draw so updates for only position changed are much faster.299float play_position_pos = 0.0f;300301HashSet<StringName> selection;302303Ref<Animation> animation;304bool read_only = false;305306Ref<Texture2D> type_icon;307Ref<Texture2D> selected_icon;308309PopupMenu *menu = nullptr;310311bool hovered = false;312StringName hovering_marker;313314void _zoom_changed();315316Ref<Texture2D> icon_cache;317318void _menu_selected(int p_index);319320void _play_position_draw();321bool _try_select_at_ui_pos(const Point2 &p_pos, bool p_aggregate, bool p_deselectable);322bool _is_ui_pos_in_current_section(const Point2 &p_pos);323324float insert_at_pos = 0.0f;325bool moving_selection_attempt = false;326bool moving_selection_effective = false;327float moving_selection_offset = 0.0f;328float moving_selection_pivot = 0.0f;329float moving_selection_mouse_begin_x = 0.0f;330float moving_selection_mouse_begin_y = 0.0f;331StringName select_single_attempt;332bool moving_selection = false;333void _move_selection_begin();334void _move_selection(float p_offset);335void _move_selection_commit();336void _move_selection_cancel();337338void _clear_selection_for_anim(const Ref<Animation> &p_anim);339void _select_key(const StringName &p_name, bool is_single = false);340void _deselect_key(const StringName &p_name);341342void _insert_marker(float p_ofs);343void _rename_marker(const StringName &p_name);344void _delete_selected_markers();345346ConfirmationDialog *marker_insert_confirm = nullptr;347LineEdit *marker_insert_new_name = nullptr;348ColorPickerButton *marker_insert_color = nullptr;349AcceptDialog *marker_insert_error_dialog = nullptr;350float marker_insert_ofs = 0;351352ConfirmationDialog *marker_rename_confirm = nullptr;353LineEdit *marker_rename_new_name = nullptr;354StringName marker_rename_prev_name;355356AcceptDialog *marker_rename_error_dialog = nullptr;357358bool should_show_all_marker_names = false;359360////////////// edit menu stuff361362void _marker_insert_confirmed();363void _marker_insert_new_name_changed(const String &p_text);364void _marker_rename_confirmed();365void _marker_rename_new_name_changed(const String &p_text);366367AnimationTrackEditor *editor = nullptr;368369HBoxContainer *_create_hbox_labeled_control(const String &p_text, Control *p_control) const;370371void _update_key_edit();372void _clear_key_edit();373374AnimationMarkerKeyEdit *key_edit = nullptr;375AnimationMultiMarkerKeyEdit *multi_key_edit = nullptr;376377protected:378static void _bind_methods();379void _notification(int p_what);380381virtual void gui_input(const Ref<InputEvent> &p_event) override;382383public:384virtual String get_tooltip(const Point2 &p_pos) const override;385386virtual int get_key_height() const;387virtual Rect2 get_key_rect(float p_pixels_sec) const;388virtual bool is_key_selectable_by_distance() const;389virtual void draw_key(const StringName &p_name, float p_pixels_sec, int p_x, bool p_selected, int p_clip_left, int p_clip_right);390virtual void draw_bg(int p_clip_left, int p_clip_right);391virtual void draw_fg(int p_clip_left, int p_clip_right);392393Ref<Animation> get_animation() const;394AnimationTimelineEdit *get_timeline() const { return timeline; }395AnimationTrackEditor *get_editor() const { return editor; }396bool is_selection_active() const { return !selection.is_empty(); }397bool is_moving_selection() const { return moving_selection; }398float get_moving_selection_offset() const { return moving_selection_offset; }399void set_animation(const Ref<Animation> &p_animation, bool p_read_only);400virtual Size2 get_minimum_size() const override;401402void set_timeline(AnimationTimelineEdit *p_timeline);403void set_editor(AnimationTrackEditor *p_editor);404405void set_play_position(float p_pos);406void update_play_position();407408void set_use_fps(bool p_use_fps);409410PackedStringArray get_selected_section() const;411bool is_marker_selected(const StringName &p_marker) const;412413// For use by AnimationTrackEditor.414void _clear_selection(bool p_update);415416AnimationMarkerEdit();417};418419class AnimationTrackEdit : public Control {420GDCLASS(AnimationTrackEdit, Control);421friend class AnimationTimelineEdit;422423enum {424MENU_CALL_MODE_CONTINUOUS,425MENU_CALL_MODE_DISCRETE,426MENU_CALL_MODE_CAPTURE,427MENU_INTERPOLATION_NEAREST,428MENU_INTERPOLATION_LINEAR,429MENU_INTERPOLATION_CUBIC,430MENU_INTERPOLATION_LINEAR_ANGLE,431MENU_INTERPOLATION_CUBIC_ANGLE,432MENU_LOOP_WRAP,433MENU_LOOP_CLAMP,434MENU_KEY_INSERT,435MENU_KEY_DUPLICATE,436MENU_KEY_CUT,437MENU_KEY_COPY,438MENU_KEY_PASTE,439MENU_KEY_ADD_RESET,440MENU_KEY_DELETE,441MENU_KEY_LOOKUP,442MENU_USE_BLEND_ENABLED,443MENU_USE_BLEND_DISABLED,444};445446AnimationTimelineEdit *timeline = nullptr;447Popup *path_popup = nullptr;448LineEdit *path = nullptr;449Node *root = nullptr;450Control *play_position = nullptr; //separate control used to draw so updates for only position changed are much faster451float play_position_pos = 0.0f;452NodePath node_path;453454Ref<Animation> animation;455bool read_only = false;456int track = 0;457458Rect2 check_rect;459Rect2 icon_rect;460Rect2 path_rect;461462Rect2 update_mode_rect;463Rect2 interp_mode_rect;464Rect2 loop_wrap_rect;465Rect2 remove_rect;466467Ref<Texture2D> type_icon;468Ref<Texture2D> selected_icon;469470PopupMenu *menu = nullptr;471472bool hovered = false;473bool clicking_on_name = false;474int hovering_key_idx = -1;475476void _zoom_changed();477478Ref<Texture2D> icon_cache;479String path_cache;480481void _menu_selected(int p_index);482483void _path_submitted(const String &p_text);484void _play_position_draw();485bool _is_value_key_valid(const Variant &p_key_value, Variant::Type &r_valid_type) const;486bool _try_select_at_ui_pos(const Point2 &p_pos, bool p_aggregate, bool p_deselectable);487488int lookup_key_idx = -1;489bool _lookup_key(int p_key_idx) const;490491Ref<Texture2D> _get_key_type_icon() const;492493mutable int dropping_at = 0;494float insert_at_pos = 0.0f;495bool moving_selection_attempt = false;496bool moving_selection_effective = false;497float moving_selection_pivot = 0.0f;498float moving_selection_mouse_begin_x = 0.0f;499int select_single_attempt = -1;500bool moving_selection = false;501502bool command_or_control_pressed = false;503504bool in_group = false;505AnimationTrackEditor *editor = nullptr;506507protected:508static void _bind_methods();509void _notification(int p_what);510511virtual void gui_input(const Ref<InputEvent> &p_event) override;512513public:514virtual Variant get_drag_data(const Point2 &p_point) override;515virtual bool can_drop_data(const Point2 &p_point, const Variant &p_data) const override;516virtual void drop_data(const Point2 &p_point, const Variant &p_data) override;517518virtual CursorShape get_cursor_shape(const Point2 &p_pos) const override;519virtual String get_tooltip(const Point2 &p_pos) const override;520521virtual int get_key_height() const;522virtual Rect2 get_key_rect(int p_index, float p_pixels_sec);523virtual bool is_key_selectable_by_distance() const;524virtual void draw_key_link(int p_index_from, int p_index_to, float p_pixels_sec, int p_x, int p_next_x, int p_clip_left, int p_clip_right);525virtual void draw_key(int p_index, float p_pixels_sec, int p_x, bool p_selected, int p_clip_left, int p_clip_right);526virtual void draw_bg(int p_clip_left, int p_clip_right);527virtual void draw_fg(int p_clip_left, int p_clip_right);528529//helper530void draw_texture_region_clipped(const Ref<Texture2D> &p_texture, const Rect2 &p_rect, const Rect2 &p_region);531void draw_rect_clipped(const Rect2 &p_rect, const Color &p_color, bool p_filled = true);532533int get_track() const;534Ref<Animation> get_animation() const;535AnimationTimelineEdit *get_timeline() const { return timeline; }536AnimationTrackEditor *get_editor() const { return editor; }537NodePath get_path() const;538void set_animation_and_track(const Ref<Animation> &p_animation, int p_track, bool p_read_only);539virtual Size2 get_minimum_size() const override;540541void set_timeline(AnimationTimelineEdit *p_timeline);542void set_editor(AnimationTrackEditor *p_editor);543void set_root(Node *p_root);544545void set_play_position(float p_pos);546void update_play_position();547void cancel_drop();548549void set_in_group(bool p_enable);550void append_to_selection(const Rect2 &p_box, bool p_deselection);551552AnimationTrackEdit();553};554555class AnimationTrackEditPlugin : public RefCounted {556GDCLASS(AnimationTrackEditPlugin, RefCounted);557558public:559virtual AnimationTrackEdit *create_value_track_edit(Object *p_object, Variant::Type p_type, const String &p_property, PropertyHint p_hint, const String &p_hint_string, int p_usage);560virtual AnimationTrackEdit *create_audio_track_edit();561virtual AnimationTrackEdit *create_animation_track_edit(Object *p_object);562};563564class AnimationTrackKeyEdit;565class AnimationMultiTrackKeyEdit;566class AnimationBezierTrackEdit;567568class AnimationTrackEditGroup : public Control {569GDCLASS(AnimationTrackEditGroup, Control);570Ref<Texture2D> icon;571Vector2 icon_size;572String node_name;573NodePath node;574Node *root = nullptr;575AnimationTimelineEdit *timeline = nullptr;576AnimationTrackEditor *editor = nullptr;577578bool hovered = false;579580void _zoom_changed();581582protected:583void _notification(int p_what);584585virtual void gui_input(const Ref<InputEvent> &p_event) override;586587public:588void set_type_and_name(const Ref<Texture2D> &p_type, const String &p_name, const NodePath &p_node);589virtual Size2 get_minimum_size() const override;590void set_timeline(AnimationTimelineEdit *p_timeline);591void set_root(Node *p_root);592void set_editor(AnimationTrackEditor *p_editor);593String get_node_name() const;594595AnimationTrackEditGroup();596};597598class AnimationTrackEditor : public VBoxContainer {599GDCLASS(AnimationTrackEditor, VBoxContainer);600friend class AnimationTimelineEdit;601friend class AnimationBezierTrackEdit;602friend class AnimationMarkerKeyEditEditor;603604Ref<Animation> animation;605bool read_only = false;606Node *root = nullptr;607608AcceptDialog *read_only_dialog = nullptr;609610MenuButton *edit = nullptr;611612PanelContainer *main_panel = nullptr;613HScrollBar *hscroll = nullptr;614ScrollContainer *scroll = nullptr;615VBoxContainer *track_vbox = nullptr;616AnimationBezierTrackEdit *bezier_edit = nullptr;617VBoxContainer *timeline_vbox = nullptr;618619MarginContainer *timeline_mc = nullptr;620void _update_timeline_margins();621622VBoxContainer *info_message_vbox = nullptr;623Label *info_message = nullptr;624Button *add_animation_player = nullptr;625void _add_animation_player();626627AnimationTimelineEdit *timeline = nullptr;628AnimationMarkerEdit *marker_edit = nullptr;629HSlider *zoom = nullptr;630EditorSpinSlider *step = nullptr;631Button *fps_compat = nullptr;632Label *nearest_fps_label = nullptr;633TextureRect *zoom_icon = nullptr;634Button *snap_keys = nullptr;635Button *insert_at_current_time = nullptr;636Button *snap_timeline = nullptr;637Button *bezier_edit_icon = nullptr;638OptionButton *snap_mode = nullptr;639Button *auto_fit = nullptr;640Button *auto_fit_bezier = nullptr;641OptionButton *bezier_key_mode = nullptr;642643Button *imported_anim_warning = nullptr;644void _show_imported_anim_warning();645646Button *dummy_player_warning = nullptr;647void _show_dummy_player_warning();648649Button *inactive_player_warning = nullptr;650void _show_inactive_player_warning();651652void _snap_mode_changed(int p_mode);653Vector<AnimationTrackEdit *> track_edits;654Vector<AnimationTrackEditGroup *> groups;655656bool animation_changing_awaiting_update = false;657void _animation_update(); // Updated by AnimationTrackEditor(this)658int _get_track_selected();659void _animation_changed();660void _update_tracks();661void _redraw_tracks();662void _redraw_groups();663void _check_bezier_exist();664665void _name_limit_changed();666void _timeline_changed(float p_new_pos, bool p_timeline_only);667void _track_remove_request(int p_track);668void _animation_track_remove_request(int p_track, Ref<Animation> p_from_animation);669void _track_grab_focus(int p_track);670671void _update_scroll(double);672void _update_nearest_fps_label();673void _update_fps_compat_mode(bool p_enabled);674void _update_step(double p_new_step);675void _update_length(double p_new_len);676void _dropped_track(int p_from_track, int p_to_track);677678void _add_track(int p_type);679void _new_track_node_selected(NodePath p_path);680void _new_track_property_selected(const String &p_name);681682void _update_step_spinbox();683void _store_snap_states();684685PropertySelector *prop_selector = nullptr;686PropertySelector *method_selector = nullptr;687SceneTreeDialog *pick_track = nullptr;688int adding_track_type = 0;689NodePath adding_track_path;690691bool keying = false;692693struct InsertData {694Animation::TrackType type;695NodePath path;696int track_idx = 0;697float time = FLT_MAX; // Defaults to current timeline position.698Variant value;699String query;700bool advance = false;701};702703Label *insert_confirm_text = nullptr;704CheckBox *insert_confirm_bezier = nullptr;705CheckBox *insert_confirm_reset = nullptr;706ConfirmationDialog *insert_confirm = nullptr;707bool insert_queue = false;708List<InsertData> insert_data;709710void _query_insert(const InsertData &p_id);711Ref<Animation> _create_and_get_reset_animation();712void _confirm_insert_list();713struct TrackIndices {714int normal;715int reset;716717TrackIndices(const Animation *p_anim = nullptr, const Animation *p_reset_anim = nullptr) {718normal = p_anim ? p_anim->get_track_count() : 0;719reset = p_reset_anim ? p_reset_anim->get_track_count() : 0;720}721};722TrackIndices _confirm_insert(InsertData p_id, TrackIndices p_next_tracks, bool p_reset_wanted, Ref<Animation> p_reset_anim, bool p_create_beziers);723void _insert_track(bool p_reset_wanted, bool p_create_beziers);724725void _root_removed();726727PropertyInfo _find_hint_for_track(int p_idx, NodePath &r_base_path, Variant *r_current_val = nullptr);728729void _scroll_changed(const Vector2 &p_val);730void _v_scroll_changed(float p_val);731void _h_scroll_changed(float p_val);732733Ref<ViewPanner> panner;734void _pan_callback(Vector2 p_scroll_vec, Ref<InputEvent> p_event);735void _zoom_callback(float p_zoom_factor, Vector2 p_origin, Ref<InputEvent> p_event);736737void _timeline_value_changed(double);738739float insert_key_from_track_call_ofs = 0.0f;740int insert_key_from_track_call_track = 0;741void _insert_key_from_track(float p_ofs, int p_track);742void _add_method_key(const String &p_method);743744void _fetch_value_track_options(const NodePath &p_path, Animation::UpdateMode *r_update_mode, Animation::InterpolationType *r_interpolation_type, bool *r_loop_wrap);745746void _clear_selection_for_anim(const Ref<Animation> &p_anim);747void _select_at_anim(const Ref<Animation> &p_anim, int p_track, float p_pos);748749//selection750751struct SelectedKey {752int track = 0;753int key = 0;754bool operator<(const SelectedKey &p_key) const { return track == p_key.track ? key < p_key.key : track < p_key.track; }755};756757struct KeyInfo {758float pos = 0;759};760761RBMap<SelectedKey, KeyInfo> selection;762763bool moving_selection = false;764float moving_selection_offset = 0.0f;765void _move_selection_begin();766void _move_selection(float p_offset);767void _move_selection_commit();768void _move_selection_cancel();769770AnimationTrackKeyEdit *key_edit = nullptr;771AnimationMultiTrackKeyEdit *multi_key_edit = nullptr;772void _update_key_edit();773void _clear_key_edit();774775Control *box_selection_container = nullptr;776777Control *box_selection = nullptr;778void _box_selection_draw();779bool box_selecting = false;780Vector2 box_selecting_from;781Vector2 box_selecting_to;782Rect2 box_select_rect;783Vector2 prev_scroll_position;784void _scroll_input(const Ref<InputEvent> &p_event);785786Vector<Ref<AnimationTrackEditPlugin>> track_edit_plugins;787788void _toggle_bezier_edit();789void _cancel_bezier_edit();790void _bezier_edit(int p_for_track);791void _bezier_track_set_key_handle_mode(Animation *p_anim, int p_track, int p_index, Animation::HandleMode p_mode, Animation::HandleSetMode p_set_mode = Animation::HANDLE_SET_MODE_NONE);792void _bezier_track_set_key_handle_mode_at_time(Animation *p_anim, int p_track, float p_time, Animation::HandleMode p_mode, Animation::HandleSetMode p_set_mode = Animation::HANDLE_SET_MODE_NONE);793794////////////// edit menu stuff795796ConfirmationDialog *bake_dialog = nullptr;797CheckBox *bake_trs = nullptr;798CheckBox *bake_blendshape = nullptr;799CheckBox *bake_value = nullptr;800SpinBox *bake_fps = nullptr;801802ConfirmationDialog *optimize_dialog = nullptr;803SpinBox *optimize_velocity_error = nullptr;804SpinBox *optimize_angular_error = nullptr;805SpinBox *optimize_precision_error = nullptr;806807ConfirmationDialog *cleanup_dialog = nullptr;808CheckBox *cleanup_keys_with_trimming_head = nullptr;809CheckBox *cleanup_keys_with_trimming_end = nullptr;810CheckBox *cleanup_keys = nullptr;811CheckBox *cleanup_tracks = nullptr;812CheckBox *cleanup_all = nullptr;813814ConfirmationDialog *scale_dialog = nullptr;815SpinBox *scale = nullptr;816817ConfirmationDialog *ease_dialog = nullptr;818OptionButton *transition_selection = nullptr;819OptionButton *ease_selection = nullptr;820SpinBox *ease_fps = nullptr;821822void _select_all_tracks_for_copy();823824void _edit_menu_about_to_popup();825void _edit_menu_pressed(int p_option);826bool scale_from_cursor = false;827828void _cleanup_animation(Ref<Animation> p_animation);829830void _anim_duplicate_keys(float p_ofs, bool p_ofs_valid, int p_track);831832void _anim_copy_keys(bool p_cut);833834bool _is_track_compatible(int p_target_track_idx, Variant::Type p_source_value_type, Animation::TrackType p_source_track_type);835836void _anim_paste_keys(float p_ofs, bool p_ofs_valid, int p_track);837838void _toggle_function_names();839Button *function_name_toggler = nullptr;840841void _view_group_toggle();842843Button *view_group = nullptr;844Button *selected_filter = nullptr;845Button *alphabetic_sorting = nullptr;846847void _auto_fit();848void _auto_fit_bezier();849850void _root_node_changed(Node *p_node, bool p_removed);851void _scene_changed();852void _selection_changed();853854ConfirmationDialog *track_copy_dialog = nullptr;855Tree *track_copy_select = nullptr;856857struct TrackClipboard {858NodePath full_path;859NodePath base_path;860Animation::TrackType track_type = Animation::TYPE_ANIMATION;861Animation::InterpolationType interp_type = Animation::INTERPOLATION_CUBIC_ANGLE;862Animation::UpdateMode update_mode = Animation::UPDATE_CAPTURE;863Animation::LoopMode loop_mode = Animation::LOOP_PINGPONG;864bool loop_wrap = false;865bool enabled = false;866bool use_blend = false;867868struct Key {869float time = 0;870float transition = 0;871Variant value;872};873Vector<Key> keys;874};875876struct KeyClipboard {877int top_track;878879struct Key {880Animation::TrackType track_type;881int track;882float time = 0;883float transition = 0;884Variant value;885};886Vector<Key> keys;887};888889Vector<TrackClipboard> track_clipboard;890KeyClipboard key_clipboard;891892void _set_key_clipboard(int p_top_track, float p_top_time, RBMap<SelectedKey, KeyInfo> &p_keymap);893void _insert_animation_key(NodePath p_path, const Variant &p_value);894895void _pick_track_filter_text_changed(const String &p_newtext);896void _pick_track_select_recursive(TreeItem *p_item, const String &p_filter, Vector<Node *> &p_select_candidates);897898double snap_unit = 0;899bool fps_compatible = true;900int nearest_fps = 0;901void _update_snap_unit();902903protected:904static void _bind_methods();905void _notification(int p_what);906907public:908// Public for use with callable_mp.909void _clear_selection(bool p_update = false);910void _key_selected(int p_key, bool p_single, int p_track);911void _key_deselected(int p_key, int p_track);912913enum {914EDIT_COPY_TRACKS,915EDIT_COPY_TRACKS_CONFIRM,916EDIT_PASTE_TRACKS,917EDIT_CUT_KEYS,918EDIT_COPY_KEYS,919EDIT_PASTE_KEYS,920EDIT_SCALE_SELECTION,921EDIT_SCALE_FROM_CURSOR,922EDIT_SCALE_CONFIRM,923EDIT_SET_START_OFFSET,924EDIT_SET_END_OFFSET,925EDIT_EASE_SELECTION,926EDIT_EASE_CONFIRM,927EDIT_DUPLICATE_SELECTED_KEYS,928EDIT_DUPLICATE_SELECTION,929EDIT_DUPLICATE_TRANSPOSED,930EDIT_MOVE_FIRST_SELECTED_KEY_TO_CURSOR,931EDIT_MOVE_LAST_SELECTED_KEY_TO_CURSOR,932EDIT_ADD_RESET_KEY,933EDIT_DELETE_SELECTION,934EDIT_GOTO_NEXT_STEP,935EDIT_GOTO_NEXT_STEP_TIMELINE_ONLY, // Next step without updating animation.936EDIT_GOTO_PREV_STEP,937EDIT_APPLY_RESET,938EDIT_BAKE_ANIMATION,939EDIT_BAKE_ANIMATION_CONFIRM,940EDIT_OPTIMIZE_ANIMATION,941EDIT_OPTIMIZE_ANIMATION_CONFIRM,942EDIT_CLEAN_UP_ANIMATION,943EDIT_CLEAN_UP_ANIMATION_CONFIRM,944EDIT_GOTO_NEXT_KEYFRAME,945EDIT_GOTO_PREV_KEYFRAME,946};947948void add_track_edit_plugin(const Ref<AnimationTrackEditPlugin> &p_plugin);949void remove_track_edit_plugin(const Ref<AnimationTrackEditPlugin> &p_plugin);950951void set_animation(const Ref<Animation> &p_anim, bool p_read_only);952Ref<Animation> get_current_animation() const;953void set_root(Node *p_root);954Node *get_root() const;955void update_keying();956bool has_keying() const;957958Dictionary get_state() const;959void set_state(const Dictionary &p_state);960void clear();961962void cleanup();963964void set_anim_pos(float p_pos);965void insert_node_value_key(Node *p_node, const String &p_property, bool p_only_if_exists = false, bool p_advance = false);966void insert_value_key(const String &p_property, bool p_advance);967void insert_transform_key(Node3D *p_node, const String &p_sub, const Animation::TrackType p_type, const Variant &p_value);968bool has_track(Node3D *p_node, const String &p_sub, const Animation::TrackType p_type);969void make_insert_queue();970void commit_insert_queue();971972void show_select_node_warning(bool p_show);973void show_dummy_player_warning(bool p_show);974void show_inactive_player_warning(bool p_show);975976bool is_key_selected(int p_track, int p_key) const;977bool is_selection_active() const;978bool is_key_clipboard_active() const;979bool is_moving_selection() const;980bool is_snap_timeline_enabled() const;981bool is_snap_keys_enabled() const;982bool is_insert_at_current_time_enabled() const;983void resolve_insertion_offset(float &r_offset) const;984bool is_bezier_editor_active() const;985bool can_add_reset_key() const;986void _on_filter_updated(const String &p_filter);987float get_moving_selection_offset() const;988float snap_time(float p_value, bool p_relative = false);989float get_snap_unit();990bool is_grouping_tracks();991bool is_sorting_alphabetically();992PackedStringArray get_selected_section() const;993bool is_marker_selected(const StringName &p_marker) const;994bool is_marker_moving_selection() const;995float get_marker_moving_selection_offset() const;996bool is_function_name_pressed();997998/** If `p_from_mouse_event` is `true`, handle Shift key presses for precise snapping. */999void goto_prev_step(bool p_from_mouse_event);10001001/** If `p_from_mouse_event` is `true`, handle Shift key presses for precise snapping. */1002void goto_next_step(bool p_from_mouse_event, bool p_timeline_only = false);10031004bool is_read_only() const;1005bool is_global_library_read_only() const;1006void popup_read_only_dialog();10071008MenuButton *get_edit_menu();1009AnimationTrackEditor();1010~AnimationTrackEditor();1011};10121013// AnimationTrackKeyEditEditorPlugin10141015class AnimationTrackKeyEditEditor : public EditorProperty {1016GDCLASS(AnimationTrackKeyEditEditor, EditorProperty);10171018Ref<Animation> animation;1019int track = -1;1020real_t key_ofs = 0.0;1021bool use_fps = false;10221023EditorSpinSlider *spinner = nullptr;10241025struct KeyDataCache {1026real_t time = 0.0;1027float transition = 0.0;1028Variant value;1029} key_data_cache;10301031void _time_edit_spun();1032void _time_edit_entered();1033void _time_edit_exited();10341035public:1036AnimationTrackKeyEditEditor(Ref<Animation> p_animation, int p_track, real_t p_key_ofs, bool p_use_fps);1037};10381039// AnimationMarkerKeyEditEditorPlugin10401041class AnimationMarkerKeyEditEditor : public EditorProperty {1042GDCLASS(AnimationMarkerKeyEditEditor, EditorProperty);10431044Ref<Animation> animation;1045StringName marker_name;1046bool use_fps = false;10471048EditorSpinSlider *spinner = nullptr;10491050void _time_edit_exited();10511052public:1053AnimationMarkerKeyEditEditor(Ref<Animation> p_animation, const StringName &p_name, bool p_use_fps);1054};105510561057