2018-08-29 22:38:13 +02:00
/**************************************************************************/
/* animation_track_editor.h */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
2018-06-07 17:46:14 +02:00
# ifndef ANIMATION_TRACK_EDITOR_H
# define ANIMATION_TRACK_EDITOR_H
2019-06-23 19:52:49 +02:00
# include "editor/editor_data.h"
2022-08-21 02:30:18 +02:00
# include "editor/editor_properties.h"
2019-06-23 19:52:49 +02:00
# include "editor/property_selector.h"
2022-08-01 16:04:35 +02:00
# include "scene/3d/node_3d.h"
2018-06-07 17:46:14 +02:00
# include "scene/gui/control.h"
# include "scene/gui/menu_button.h"
# include "scene/gui/scroll_bar.h"
2023-04-07 18:59:49 +02:00
# include "scene/gui/tree.h"
2018-06-07 17:46:14 +02:00
# include "scene/resources/animation.h"
2022-12-08 13:38:01 +01:00
class AnimationTrackEditor ;
2021-05-10 01:15:09 +02:00
class AnimationTrackEdit ;
2023-04-07 18:59:49 +02:00
class CheckBox ;
class EditorSpinSlider ;
class HSlider ;
class OptionButton ;
class PanelContainer ;
class SceneTreeDialog ;
class SpinBox ;
class TextureRect ;
2022-01-13 17:19:15 +01:00
class ViewPanner ;
2021-05-10 01:15:09 +02:00
2022-12-08 13:38:01 +01:00
class AnimationTrackKeyEdit : public Object {
GDCLASS ( AnimationTrackKeyEdit , Object ) ;
public :
bool setting = false ;
bool animation_read_only = false ;
Ref < Animation > animation ;
int track = - 1 ;
float key_ofs = 0 ;
Node * root_path = nullptr ;
PropertyInfo hint ;
NodePath base ;
bool use_fps = false ;
2023-10-18 03:29:02 +02:00
AnimationTrackEditor * editor = nullptr ;
2022-12-08 13:38:01 +01:00
bool _hide_script_from_inspector ( ) { return true ; }
bool _hide_metadata_from_inspector ( ) { return true ; }
bool _dont_undo_redo ( ) { return true ; }
bool _is_read_only ( ) { return animation_read_only ; }
void notify_change ( ) ;
Node * get_root_path ( ) ;
void set_use_fps ( bool p_enable ) ;
protected :
static void _bind_methods ( ) ;
void _fix_node_path ( Variant & value ) ;
void _update_obj ( const Ref < Animation > & p_anim ) ;
void _key_ofs_changed ( const Ref < Animation > & p_anim , float from , float to ) ;
bool _set ( const StringName & p_name , const Variant & p_value ) ;
bool _get ( const StringName & p_name , Variant & r_ret ) const ;
void _get_property_list ( List < PropertyInfo > * p_list ) const ;
} ;
class AnimationMultiTrackKeyEdit : public Object {
GDCLASS ( AnimationMultiTrackKeyEdit , Object ) ;
public :
bool setting = false ;
bool animation_read_only = false ;
Ref < Animation > animation ;
RBMap < int , List < float > > key_ofs_map ;
RBMap < int , NodePath > base_map ;
PropertyInfo hint ;
Node * root_path = nullptr ;
bool use_fps = false ;
2023-10-18 03:29:02 +02:00
AnimationTrackEditor * editor = nullptr ;
2022-12-08 13:38:01 +01:00
bool _hide_script_from_inspector ( ) { return true ; }
bool _hide_metadata_from_inspector ( ) { return true ; }
bool _dont_undo_redo ( ) { return true ; }
bool _is_read_only ( ) { return animation_read_only ; }
void notify_change ( ) ;
Node * get_root_path ( ) ;
void set_use_fps ( bool p_enable ) ;
protected :
static void _bind_methods ( ) ;
void _fix_node_path ( Variant & value , NodePath & base ) ;
void _update_obj ( const Ref < Animation > & p_anim ) ;
void _key_ofs_changed ( const Ref < Animation > & p_anim , float from , float to ) ;
bool _set ( const StringName & p_name , const Variant & p_value ) ;
bool _get ( const StringName & p_name , Variant & r_ret ) const ;
void _get_property_list ( List < PropertyInfo > * p_list ) const ;
} ;
2018-06-07 17:46:14 +02:00
class AnimationTimelineEdit : public Range {
2019-03-19 19:35:57 +01:00
GDCLASS ( AnimationTimelineEdit , Range ) ;
2018-06-07 17:46:14 +02:00
2023-11-15 17:33:58 +01:00
friend class AnimationBezierTrackEdit ;
friend class AnimationTrackEditor ;
2024-02-12 14:28:13 +01:00
static 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.
static constexpr float SCROLL_ZOOM_FACTOR_OUT = 0.98f ; // Zoom factor when zooming out. Similar to SCROLL_ZOOM_FACTOR_IN but less than 1.0.
2023-11-15 17:33:58 +01:00
2018-06-07 17:46:14 +02:00
Ref < Animation > animation ;
2022-05-04 02:17:08 +02:00
bool read_only = false ;
2022-04-04 15:06:57 +02:00
AnimationTrackEdit * track_edit = nullptr ;
2022-05-02 16:28:25 +02:00
int name_limit = 0 ;
2022-04-04 15:06:57 +02:00
Range * zoom = nullptr ;
Range * h_scroll = nullptr ;
2022-05-02 16:28:25 +02:00
float play_position_pos = 0.0f ;
2018-06-07 17:46:14 +02:00
2022-04-04 15:06:57 +02:00
HBoxContainer * len_hb = nullptr ;
EditorSpinSlider * length = nullptr ;
Button * loop = nullptr ;
TextureRect * time_icon = nullptr ;
2018-06-07 17:46:14 +02:00
2022-04-04 15:06:57 +02:00
MenuButton * add_track = nullptr ;
Control * play_position = nullptr ; //separate control used to draw so updates for only position changed are much faster
HScrollBar * hscroll = nullptr ;
2018-06-07 17:46:14 +02:00
void _zoom_changed ( double ) ;
void _anim_length_changed ( double p_new_len ) ;
void _anim_loop_pressed ( ) ;
void _play_position_draw ( ) ;
Rect2 hsize_rect ;
2022-02-15 15:56:58 +01:00
bool editing = false ;
bool use_fps = false ;
2018-06-07 17:46:14 +02:00
2022-01-13 17:19:15 +01:00
Ref < ViewPanner > panner ;
2023-01-19 17:50:51 +01:00
void _pan_callback ( Vector2 p_scroll_vec , Ref < InputEvent > p_event ) ;
void _zoom_callback ( float p_zoom_factor , Vector2 p_origin , Ref < InputEvent > p_event ) ;
2022-01-13 17:19:15 +01:00
2022-02-15 15:56:58 +01:00
bool dragging_timeline = false ;
bool dragging_hsize = false ;
2022-05-02 16:28:25 +02:00
float dragging_hsize_from = 0.0f ;
float dragging_hsize_at = 0.0f ;
2023-11-15 17:33:58 +01:00
double last_zoom_scale = 1.0 ;
double hscroll_on_zoom_buffer = - 1.0 ;
Vector2 zoom_scroll_origin ;
bool zoom_callback_occured = false ;
2018-06-07 17:46:14 +02:00
2021-08-22 17:37:22 +02:00
virtual void gui_input ( const Ref < InputEvent > & p_event ) override ;
2018-06-07 17:46:14 +02:00
void _track_added ( int p_track ) ;
protected :
static void _bind_methods ( ) ;
void _notification ( int p_what ) ;
public :
int get_name_limit ( ) const ;
int get_buttons_width ( ) const ;
float get_zoom_scale ( ) const ;
2020-07-10 12:34:39 +02:00
virtual Size2 get_minimum_size ( ) const override ;
2022-05-04 02:17:08 +02:00
void set_animation ( const Ref < Animation > & p_animation , bool p_read_only ) ;
2021-05-10 01:15:09 +02:00
void set_track_edit ( AnimationTrackEdit * p_track_edit ) ;
2018-06-07 17:46:14 +02:00
void set_zoom ( Range * p_zoom ) ;
Range * get_zoom ( ) const { return zoom ; }
void set_play_position ( float p_pos ) ;
float get_play_position ( ) const ;
void update_play_position ( ) ;
void update_values ( ) ;
2019-04-14 21:43:38 +02:00
void set_use_fps ( bool p_use_fps ) ;
bool is_using_fps ( ) const ;
2018-06-07 17:46:14 +02:00
void set_hscroll ( HScrollBar * p_hscroll ) ;
2022-03-11 10:18:27 +01:00
virtual CursorShape get_cursor_shape ( const Point2 & p_pos ) const override ;
2018-06-07 17:46:14 +02:00
AnimationTimelineEdit ( ) ;
} ;
class AnimationTrackEdit : public Control {
2019-03-19 19:35:57 +01:00
GDCLASS ( AnimationTrackEdit , Control ) ;
2022-11-17 04:24:48 +01:00
friend class AnimationTimelineEdit ;
2018-06-07 17:46:14 +02:00
enum {
MENU_CALL_MODE_CONTINUOUS ,
MENU_CALL_MODE_DISCRETE ,
MENU_CALL_MODE_CAPTURE ,
MENU_INTERPOLATION_NEAREST ,
MENU_INTERPOLATION_LINEAR ,
MENU_INTERPOLATION_CUBIC ,
2022-08-26 04:42:00 +02:00
MENU_INTERPOLATION_LINEAR_ANGLE ,
MENU_INTERPOLATION_CUBIC_ANGLE ,
2018-06-07 17:46:14 +02:00
MENU_LOOP_WRAP ,
MENU_LOOP_CLAMP ,
MENU_KEY_INSERT ,
MENU_KEY_DUPLICATE ,
2024-02-15 00:44:40 +01:00
MENU_KEY_CUT ,
2024-02-06 18:57:10 +01:00
MENU_KEY_COPY ,
MENU_KEY_PASTE ,
2021-12-06 00:45:45 +01:00
MENU_KEY_ADD_RESET ,
2023-01-27 19:25:49 +01:00
MENU_KEY_DELETE ,
MENU_USE_BLEND_ENABLED ,
MENU_USE_BLEND_DISABLED ,
2018-06-07 17:46:14 +02:00
} ;
2022-05-02 16:28:25 +02:00
2022-04-04 15:06:57 +02:00
AnimationTimelineEdit * timeline = nullptr ;
Popup * path_popup = nullptr ;
LineEdit * path = nullptr ;
Node * root = nullptr ;
Control * play_position = nullptr ; //separate control used to draw so updates for only position changed are much faster
2022-05-02 16:28:25 +02:00
float play_position_pos = 0.0f ;
2019-03-06 14:22:38 +01:00
NodePath node_path ;
2018-06-07 17:46:14 +02:00
Ref < Animation > animation ;
2022-05-04 02:17:08 +02:00
bool read_only = false ;
2022-05-02 16:28:25 +02:00
int track = 0 ;
2018-06-07 17:46:14 +02:00
Rect2 check_rect ;
Rect2 path_rect ;
Rect2 update_mode_rect ;
Rect2 interp_mode_rect ;
2021-10-15 15:25:00 +02:00
Rect2 loop_wrap_rect ;
2018-06-07 17:46:14 +02:00
Rect2 remove_rect ;
2019-06-11 20:43:37 +02:00
Ref < Texture2D > type_icon ;
Ref < Texture2D > selected_icon ;
2018-06-07 17:46:14 +02:00
2022-04-04 15:06:57 +02:00
PopupMenu * menu = nullptr ;
2018-06-07 17:46:14 +02:00
2022-03-21 21:55:33 +01:00
bool hovered = false ;
2022-02-15 15:56:58 +01:00
bool clicking_on_name = false ;
2022-03-21 22:59:34 +01:00
int hovering_key_idx = - 1 ;
2018-06-07 17:46:14 +02:00
void _zoom_changed ( ) ;
2019-06-11 20:43:37 +02:00
Ref < Texture2D > icon_cache ;
2018-06-07 17:46:14 +02:00
String path_cache ;
void _menu_selected ( int p_index ) ;
2021-06-16 18:43:34 +02:00
void _path_submitted ( const String & p_text ) ;
2018-06-07 17:46:14 +02:00
void _play_position_draw ( ) ;
2019-06-23 19:52:49 +02:00
bool _is_value_key_valid ( const Variant & p_key_value , Variant : : Type & r_valid_type ) const ;
2024-02-06 18:57:10 +01:00
bool _try_select_at_ui_pos ( const Point2 & p_pos , bool p_aggregate , bool p_deselectable ) ;
2018-06-07 17:46:14 +02:00
2022-03-10 06:46:05 +01:00
Ref < Texture2D > _get_key_type_icon ( ) const ;
2022-05-02 16:28:25 +02:00
mutable int dropping_at = 0 ;
float insert_at_pos = 0.0f ;
2022-02-15 15:56:58 +01:00
bool moving_selection_attempt = false ;
2022-05-02 16:28:25 +02:00
int select_single_attempt = - 1 ;
2022-02-15 15:56:58 +01:00
bool moving_selection = false ;
2022-05-02 16:28:25 +02:00
float moving_selection_from_ofs = 0.0f ;
2018-06-07 17:46:14 +02:00
2022-02-15 15:56:58 +01:00
bool in_group = false ;
2022-04-04 15:06:57 +02:00
AnimationTrackEditor * editor = nullptr ;
2018-06-07 17:46:14 +02:00
protected :
static void _bind_methods ( ) ;
void _notification ( int p_what ) ;
2021-08-22 17:37:22 +02:00
virtual void gui_input ( const Ref < InputEvent > & p_event ) override ;
2018-06-07 17:46:14 +02:00
public :
2020-07-10 12:34:39 +02:00
virtual Variant get_drag_data ( const Point2 & p_point ) override ;
virtual bool can_drop_data ( const Point2 & p_point , const Variant & p_data ) const override ;
virtual void drop_data ( const Point2 & p_point , const Variant & p_data ) override ;
2018-06-07 17:46:14 +02:00
2020-07-10 12:34:39 +02:00
virtual String get_tooltip ( const Point2 & p_pos ) const override ;
2018-06-07 17:46:14 +02:00
virtual int get_key_height ( ) const ;
virtual Rect2 get_key_rect ( int p_index , float p_pixels_sec ) ;
virtual bool is_key_selectable_by_distance ( ) const ;
virtual void draw_key_link ( int p_index , float p_pixels_sec , int p_x , int p_next_x , int p_clip_left , int p_clip_right ) ;
virtual void draw_key ( int p_index , float p_pixels_sec , int p_x , bool p_selected , int p_clip_left , int p_clip_right ) ;
virtual void draw_bg ( int p_clip_left , int p_clip_right ) ;
virtual void draw_fg ( int p_clip_left , int p_clip_right ) ;
//helper
2019-06-11 20:43:37 +02:00
void draw_texture_region_clipped ( const Ref < Texture2D > & p_texture , const Rect2 & p_rect , const Rect2 & p_region ) ;
2018-06-07 17:46:14 +02:00
void draw_rect_clipped ( const Rect2 & p_rect , const Color & p_color , bool p_filled = true ) ;
int get_track ( ) const ;
Ref < Animation > get_animation ( ) const ;
AnimationTimelineEdit * get_timeline ( ) const { return timeline ; }
AnimationTrackEditor * get_editor ( ) const { return editor ; }
2019-03-06 14:22:38 +01:00
NodePath get_path ( ) const ;
2022-05-04 02:17:08 +02:00
void set_animation_and_track ( const Ref < Animation > & p_animation , int p_track , bool p_read_only ) ;
2020-07-10 12:34:39 +02:00
virtual Size2 get_minimum_size ( ) const override ;
2018-06-07 17:46:14 +02:00
void set_timeline ( AnimationTimelineEdit * p_timeline ) ;
void set_editor ( AnimationTrackEditor * p_editor ) ;
void set_root ( Node * p_root ) ;
void set_play_position ( float p_pos ) ;
void update_play_position ( ) ;
void cancel_drop ( ) ;
void set_in_group ( bool p_enable ) ;
2019-06-19 12:34:22 +02:00
void append_to_selection ( const Rect2 & p_box , bool p_deselection ) ;
2018-06-07 17:46:14 +02:00
AnimationTrackEdit ( ) ;
} ;
2021-06-04 18:03:15 +02:00
class AnimationTrackEditPlugin : public RefCounted {
GDCLASS ( AnimationTrackEditPlugin , RefCounted ) ;
2019-03-19 19:35:57 +01:00
2018-06-07 17:46:14 +02:00
public :
virtual 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 ) ;
virtual AnimationTrackEdit * create_audio_track_edit ( ) ;
virtual AnimationTrackEdit * create_animation_track_edit ( Object * p_object ) ;
} ;
class AnimationTrackKeyEdit ;
2019-07-22 08:43:40 +02:00
class AnimationMultiTrackKeyEdit ;
2018-06-07 17:46:14 +02:00
class AnimationBezierTrackEdit ;
class AnimationTrackEditGroup : public Control {
2019-03-19 19:35:57 +01:00
GDCLASS ( AnimationTrackEditGroup , Control ) ;
2019-06-11 20:43:37 +02:00
Ref < Texture2D > icon ;
2023-11-25 23:41:25 +01:00
Vector2 icon_size ;
2018-06-07 17:46:14 +02:00
String node_name ;
NodePath node ;
2020-11-24 10:12:55 +01:00
Node * root = nullptr ;
AnimationTimelineEdit * timeline = nullptr ;
2018-06-07 17:46:14 +02:00
void _zoom_changed ( ) ;
protected :
void _notification ( int p_what ) ;
2023-08-31 07:10:12 +02:00
virtual void gui_input ( const Ref < InputEvent > & p_event ) override ;
2018-06-07 17:46:14 +02:00
public :
2019-06-11 20:43:37 +02:00
void set_type_and_name ( const Ref < Texture2D > & p_type , const String & p_name , const NodePath & p_node ) ;
2020-07-10 12:34:39 +02:00
virtual Size2 get_minimum_size ( ) const override ;
2018-06-07 17:46:14 +02:00
void set_timeline ( AnimationTimelineEdit * p_timeline ) ;
void set_root ( Node * p_root ) ;
AnimationTrackEditGroup ( ) ;
} ;
class AnimationTrackEditor : public VBoxContainer {
2019-03-19 19:35:57 +01:00
GDCLASS ( AnimationTrackEditor , VBoxContainer ) ;
2022-11-17 04:24:48 +01:00
friend class AnimationTimelineEdit ;
2024-02-06 18:57:10 +01:00
friend class AnimationBezierTrackEdit ;
2018-06-07 17:46:14 +02:00
Ref < Animation > animation ;
2022-05-04 02:17:08 +02:00
bool read_only = false ;
2022-04-04 15:06:57 +02:00
Node * root = nullptr ;
2018-06-07 17:46:14 +02:00
2022-04-04 15:06:57 +02:00
MenuButton * edit = nullptr ;
2018-06-07 17:46:14 +02:00
2022-04-04 15:06:57 +02:00
PanelContainer * main_panel = nullptr ;
HScrollBar * hscroll = nullptr ;
ScrollContainer * scroll = nullptr ;
VBoxContainer * track_vbox = nullptr ;
AnimationBezierTrackEdit * bezier_edit = nullptr ;
2019-09-04 07:20:57 +02:00
2022-04-04 15:06:57 +02:00
Label * info_message = nullptr ;
2018-06-07 17:46:14 +02:00
2022-04-04 15:06:57 +02:00
AnimationTimelineEdit * timeline = nullptr ;
HSlider * zoom = nullptr ;
EditorSpinSlider * step = nullptr ;
TextureRect * zoom_icon = nullptr ;
Button * snap = nullptr ;
Button * bezier_edit_icon = nullptr ;
OptionButton * snap_mode = nullptr ;
Button * imported_anim_warning = nullptr ;
2020-02-21 17:44:59 +01:00
void _show_imported_anim_warning ( ) ;
2019-04-23 07:02:34 +02:00
2023-07-20 17:34:06 +02:00
Button * dummy_player_warning = nullptr ;
void _show_dummy_player_warning ( ) ;
Button * inactive_player_warning = nullptr ;
void _show_inactive_player_warning ( ) ;
2019-04-14 21:43:38 +02:00
void _snap_mode_changed ( int p_mode ) ;
2018-06-07 17:46:14 +02:00
Vector < AnimationTrackEdit * > track_edits ;
Vector < AnimationTrackEditGroup * > groups ;
2022-02-15 15:56:58 +01:00
bool animation_changing_awaiting_update = false ;
2022-08-22 12:45:30 +02:00
void _animation_update ( ) ; // Updated by AnimationTrackEditor(this)
2018-06-07 17:46:14 +02:00
int _get_track_selected ( ) ;
void _animation_changed ( ) ;
void _update_tracks ( ) ;
2022-08-29 03:44:00 +02:00
void _redraw_tracks ( ) ;
void _redraw_groups ( ) ;
2023-02-11 12:39:02 +01:00
void _check_bezier_exist ( ) ;
2018-06-07 17:46:14 +02:00
void _name_limit_changed ( ) ;
2023-11-21 22:14:32 +01:00
void _timeline_changed ( float p_new_pos , bool p_timeline_only ) ;
2018-06-07 17:46:14 +02:00
void _track_remove_request ( int p_track ) ;
2022-04-23 00:40:28 +02:00
void _animation_track_remove_request ( int p_track , Ref < Animation > p_from_animation ) ;
2019-05-25 18:01:44 +02:00
void _track_grab_focus ( int p_track ) ;
2018-06-07 17:46:14 +02:00
void _update_scroll ( double ) ;
void _update_step ( double p_new_step ) ;
2019-06-26 15:08:25 +02:00
void _update_length ( double p_new_len ) ;
2018-06-07 17:46:14 +02:00
void _dropped_track ( int p_from_track , int p_to_track ) ;
void _add_track ( int p_type ) ;
void _new_track_node_selected ( NodePath p_path ) ;
void _new_track_property_selected ( String p_name ) ;
2019-04-14 21:43:38 +02:00
void _update_step_spinbox ( ) ;
2022-04-04 15:06:57 +02:00
PropertySelector * prop_selector = nullptr ;
PropertySelector * method_selector = nullptr ;
SceneTreeDialog * pick_track = nullptr ;
2022-05-02 16:28:25 +02:00
int adding_track_type = 0 ;
2018-06-07 17:46:14 +02:00
NodePath adding_track_path ;
2022-02-15 15:56:58 +01:00
bool keying = false ;
2018-06-07 17:46:14 +02:00
struct InsertData {
Animation : : TrackType type ;
NodePath path ;
2020-11-24 10:12:55 +01:00
int track_idx = 0 ;
2018-06-07 17:46:14 +02:00
Variant value ;
String query ;
2020-11-24 10:12:55 +01:00
bool advance = false ;
2022-05-02 16:28:25 +02:00
} ;
2018-06-07 17:46:14 +02:00
2022-04-04 15:06:57 +02:00
Label * insert_confirm_text = nullptr ;
CheckBox * insert_confirm_bezier = nullptr ;
CheckBox * insert_confirm_reset = nullptr ;
ConfirmationDialog * insert_confirm = nullptr ;
2022-02-15 15:56:58 +01:00
bool insert_queue = false ;
2018-06-07 17:46:14 +02:00
List < InsertData > insert_data ;
void _query_insert ( const InsertData & p_id ) ;
2020-12-20 11:46:44 +01:00
Ref < Animation > _create_and_get_reset_animation ( ) ;
2018-06-07 17:46:14 +02:00
void _confirm_insert_list ( ) ;
2020-12-20 11:46:44 +01:00
struct TrackIndices {
int normal ;
int reset ;
TrackIndices ( const Animation * p_anim = nullptr , const Animation * p_reset_anim = nullptr ) {
normal = p_anim ? p_anim - > get_track_count ( ) : 0 ;
reset = p_reset_anim ? p_reset_anim - > get_track_count ( ) : 0 ;
}
} ;
2022-07-17 19:42:53 +02:00
TrackIndices _confirm_insert ( InsertData p_id , TrackIndices p_next_tracks , bool p_reset_wanted , Ref < Animation > p_reset_anim , bool p_create_beziers ) ;
void _insert_track ( bool p_reset_wanted , bool p_create_beziers ) ;
2018-06-07 17:46:14 +02:00
2021-10-03 14:49:18 +02:00
void _root_removed ( ) ;
2018-06-07 17:46:14 +02:00
2020-04-02 01:20:12 +02:00
PropertyInfo _find_hint_for_track ( int p_idx , NodePath & r_base_path , Variant * r_current_val = nullptr ) ;
2018-06-07 17:46:14 +02:00
2022-01-13 17:19:15 +01:00
Ref < ViewPanner > panner ;
2023-01-19 17:50:51 +01:00
void _pan_callback ( Vector2 p_scroll_vec , Ref < InputEvent > p_event ) ;
void _zoom_callback ( float p_zoom_factor , Vector2 p_origin , Ref < InputEvent > p_event ) ;
2022-01-13 17:19:15 +01:00
2018-06-07 17:46:14 +02:00
void _timeline_value_changed ( double ) ;
2022-05-02 16:28:25 +02:00
float insert_key_from_track_call_ofs = 0.0f ;
int insert_key_from_track_call_track = 0 ;
2018-06-07 17:46:14 +02:00
void _insert_key_from_track ( float p_ofs , int p_track ) ;
void _add_method_key ( const String & p_method ) ;
2023-12-30 10:24:09 +01:00
void _fetch_value_track_options ( const NodePath & p_path , Animation : : UpdateMode * r_update_mode , Animation : : InterpolationType * r_interpolation_type , bool * r_loop_wrap ) ;
2018-06-07 17:46:14 +02:00
void _clear_selection_for_anim ( const Ref < Animation > & p_anim ) ;
void _select_at_anim ( const Ref < Animation > & p_anim , int p_track , float p_pos ) ;
//selection
struct SelectedKey {
2020-11-24 10:12:55 +01:00
int track = 0 ;
int key = 0 ;
2018-06-07 17:46:14 +02:00
bool operator < ( const SelectedKey & p_key ) const { return track = = p_key . track ? key < p_key . key : track < p_key . track ; } ;
} ;
struct KeyInfo {
2020-11-24 10:12:55 +01:00
float pos = 0 ;
2018-06-07 17:46:14 +02:00
} ;
2022-05-13 15:04:37 +02:00
RBMap < SelectedKey , KeyInfo > selection ;
2018-06-07 17:46:14 +02:00
2022-02-15 15:56:58 +01:00
bool moving_selection = false ;
2022-05-02 16:28:25 +02:00
float moving_selection_offset = 0.0f ;
2018-06-07 17:46:14 +02:00
void _move_selection_begin ( ) ;
void _move_selection ( float p_offset ) ;
void _move_selection_commit ( ) ;
void _move_selection_cancel ( ) ;
2022-04-04 15:06:57 +02:00
AnimationTrackKeyEdit * key_edit = nullptr ;
AnimationMultiTrackKeyEdit * multi_key_edit = nullptr ;
2018-06-07 17:46:14 +02:00
void _update_key_edit ( ) ;
void _clear_key_edit ( ) ;
2022-04-04 15:06:57 +02:00
Control * box_selection = nullptr ;
2018-06-07 17:46:14 +02:00
void _box_selection_draw ( ) ;
2022-02-15 15:56:58 +01:00
bool box_selecting = false ;
2018-06-07 17:46:14 +02:00
Vector2 box_selecting_from ;
Rect2 box_select_rect ;
void _scroll_input ( const Ref < InputEvent > & p_event ) ;
2020-03-17 07:33:00 +01:00
Vector < Ref < AnimationTrackEditPlugin > > track_edit_plugins ;
2018-06-07 17:46:14 +02:00
2021-11-09 16:05:28 +01:00
void _toggle_bezier_edit ( ) ;
2018-06-07 17:46:14 +02:00
void _cancel_bezier_edit ( ) ;
void _bezier_edit ( int p_for_track ) ;
2022-08-22 12:45:30 +02:00
void _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 ) ;
2018-06-07 17:46:14 +02:00
////////////// edit menu stuff
2022-08-21 02:30:18 +02:00
ConfirmationDialog * bake_dialog = nullptr ;
CheckBox * bake_trs = nullptr ;
CheckBox * bake_blendshape = nullptr ;
CheckBox * bake_value = nullptr ;
SpinBox * bake_fps = nullptr ;
2022-04-04 15:06:57 +02:00
ConfirmationDialog * optimize_dialog = nullptr ;
2022-08-07 03:55:37 +02:00
SpinBox * optimize_velocity_error = nullptr ;
2022-04-04 15:06:57 +02:00
SpinBox * optimize_angular_error = nullptr ;
2022-08-07 03:55:37 +02:00
SpinBox * optimize_precision_error = nullptr ;
2018-06-07 17:46:14 +02:00
2022-04-04 15:06:57 +02:00
ConfirmationDialog * cleanup_dialog = nullptr ;
2023-12-31 08:05:34 +01:00
CheckBox * cleanup_keys_with_trimming_head = nullptr ;
CheckBox * cleanup_keys_with_trimming_end = nullptr ;
2022-04-04 15:06:57 +02:00
CheckBox * cleanup_keys = nullptr ;
CheckBox * cleanup_tracks = nullptr ;
CheckBox * cleanup_all = nullptr ;
2018-06-07 17:46:14 +02:00
2022-04-04 15:06:57 +02:00
ConfirmationDialog * scale_dialog = nullptr ;
SpinBox * scale = nullptr ;
2018-06-07 17:46:14 +02:00
2022-08-21 02:30:18 +02:00
ConfirmationDialog * ease_dialog = nullptr ;
OptionButton * transition_selection = nullptr ;
OptionButton * ease_selection = nullptr ;
SpinBox * ease_fps = nullptr ;
2019-06-19 13:00:15 +02:00
void _select_all_tracks_for_copy ( ) ;
2020-12-20 11:46:44 +01:00
void _edit_menu_about_to_popup ( ) ;
2018-06-07 17:46:14 +02:00
void _edit_menu_pressed ( int p_option ) ;
2022-05-02 16:28:25 +02:00
int last_menu_track_opt = 0 ;
2018-06-07 17:46:14 +02:00
void _cleanup_animation ( Ref < Animation > p_animation ) ;
2024-02-06 18:57:10 +01:00
void _anim_duplicate_keys ( float p_ofs , int p_track ) ;
2024-02-15 00:44:40 +01:00
void _anim_copy_keys ( bool p_cut ) ;
2024-02-06 18:57:10 +01:00
bool _is_track_compatible ( int p_target_track_idx , Variant : : Type p_source_value_type , Animation : : TrackType p_source_track_type ) ;
void _anim_paste_keys ( float p_ofs , int p_track ) ;
2018-06-07 17:46:14 +02:00
void _view_group_toggle ( ) ;
2022-04-04 15:06:57 +02:00
Button * view_group = nullptr ;
Button * selected_filter = nullptr ;
2018-06-07 17:46:14 +02:00
void _selection_changed ( ) ;
2022-04-04 15:06:57 +02:00
ConfirmationDialog * track_copy_dialog = nullptr ;
Tree * track_copy_select = nullptr ;
2019-06-19 13:00:15 +02:00
2018-06-07 17:46:14 +02:00
struct TrackClipboard {
NodePath full_path ;
NodePath base_path ;
2022-05-04 20:53:48 +02:00
Animation : : TrackType track_type = Animation : : TYPE_ANIMATION ;
2022-08-26 04:42:00 +02:00
Animation : : InterpolationType interp_type = Animation : : INTERPOLATION_CUBIC_ANGLE ;
2022-05-04 20:53:48 +02:00
Animation : : UpdateMode update_mode = Animation : : UPDATE_CAPTURE ;
2022-07-28 21:55:10 +02:00
Animation : : LoopMode loop_mode = Animation : : LOOP_PINGPONG ;
2020-11-24 10:12:55 +01:00
bool loop_wrap = false ;
bool enabled = false ;
2023-01-27 19:25:49 +01:00
bool use_blend = false ;
2018-06-07 17:46:14 +02:00
struct Key {
2020-11-24 10:12:55 +01:00
float time = 0 ;
float transition = 0 ;
2018-06-07 17:46:14 +02:00
Variant value ;
} ;
Vector < Key > keys ;
} ;
2024-02-06 18:57:10 +01:00
struct KeyClipboard {
int top_track ;
struct Key {
Animation : : TrackType track_type ;
int track ;
float time = 0 ;
float transition = 0 ;
Variant value ;
} ;
Vector < Key > keys ;
} ;
2018-06-07 17:46:14 +02:00
Vector < TrackClipboard > track_clipboard ;
2024-02-06 18:57:10 +01:00
KeyClipboard key_clipboard ;
2018-06-07 17:46:14 +02:00
2024-02-06 18:57:10 +01:00
void _set_key_clipboard ( int p_top_track , float p_top_time , RBMap < SelectedKey , KeyInfo > & p_keymap ) ;
2018-06-07 17:46:14 +02:00
void _insert_animation_key ( NodePath p_path , const Variant & p_value ) ;
2021-03-12 16:40:17 +01:00
void _pick_track_filter_text_changed ( const String & p_newtext ) ;
void _pick_track_select_recursive ( TreeItem * p_item , const String & p_filter , Vector < Node * > & p_select_candidates ) ;
void _pick_track_filter_input ( const Ref < InputEvent > & p_ie ) ;
2018-06-07 17:46:14 +02:00
protected :
static void _bind_methods ( ) ;
void _notification ( int p_what ) ;
public :
2020-12-06 16:09:18 +01:00
// Public for use with callable_mp.
void _clear_selection ( bool p_update = false ) ;
void _key_selected ( int p_key , bool p_single , int p_track ) ;
void _key_deselected ( int p_key , int p_track ) ;
2021-05-10 01:15:09 +02:00
enum {
EDIT_COPY_TRACKS ,
EDIT_COPY_TRACKS_CONFIRM ,
EDIT_PASTE_TRACKS ,
2024-02-15 00:44:40 +01:00
EDIT_CUT_KEYS ,
2024-02-06 18:57:10 +01:00
EDIT_COPY_KEYS ,
EDIT_PASTE_KEYS ,
2021-05-10 01:15:09 +02:00
EDIT_SCALE_SELECTION ,
EDIT_SCALE_FROM_CURSOR ,
EDIT_SCALE_CONFIRM ,
2023-12-31 08:05:34 +01:00
EDIT_SET_START_OFFSET ,
EDIT_SET_END_OFFSET ,
2022-08-21 02:30:18 +02:00
EDIT_EASE_SELECTION ,
EDIT_EASE_CONFIRM ,
2024-02-06 18:57:10 +01:00
EDIT_DUPLICATE_SELECTED_KEYS ,
2023-12-31 08:05:34 +01:00
EDIT_DUPLICATE_SELECTION ,
EDIT_DUPLICATE_TRANSPOSED ,
EDIT_MOVE_FIRST_SELECTED_KEY_TO_CURSOR ,
EDIT_MOVE_LAST_SELECTED_KEY_TO_CURSOR ,
2021-12-06 00:45:45 +01:00
EDIT_ADD_RESET_KEY ,
2021-05-10 01:15:09 +02:00
EDIT_DELETE_SELECTION ,
EDIT_GOTO_NEXT_STEP ,
2021-05-23 15:32:03 +02:00
EDIT_GOTO_NEXT_STEP_TIMELINE_ONLY , // Next step without updating animation.
2021-05-10 01:15:09 +02:00
EDIT_GOTO_PREV_STEP ,
EDIT_APPLY_RESET ,
2022-08-29 03:44:00 +02:00
EDIT_BAKE_ANIMATION ,
EDIT_BAKE_ANIMATION_CONFIRM ,
2021-05-10 01:15:09 +02:00
EDIT_OPTIMIZE_ANIMATION ,
EDIT_OPTIMIZE_ANIMATION_CONFIRM ,
EDIT_CLEAN_UP_ANIMATION ,
EDIT_CLEAN_UP_ANIMATION_CONFIRM
} ;
2018-06-07 17:46:14 +02:00
void add_track_edit_plugin ( const Ref < AnimationTrackEditPlugin > & p_plugin ) ;
void remove_track_edit_plugin ( const Ref < AnimationTrackEditPlugin > & p_plugin ) ;
2022-05-04 02:17:08 +02:00
void set_animation ( const Ref < Animation > & p_anim , bool p_read_only ) ;
2018-06-07 17:46:14 +02:00
Ref < Animation > get_current_animation ( ) const ;
void set_root ( Node * p_root ) ;
Node * get_root ( ) const ;
void update_keying ( ) ;
bool has_keying ( ) const ;
2019-04-14 21:43:38 +02:00
Dictionary get_state ( ) const ;
void set_state ( const Dictionary & p_state ) ;
2018-06-07 17:46:14 +02:00
void cleanup ( ) ;
void set_anim_pos ( float p_pos ) ;
void insert_node_value_key ( Node * p_node , const String & p_property , const Variant & p_value , bool p_only_if_exists = false ) ;
void insert_value_key ( const String & p_property , const Variant & p_value , bool p_advance ) ;
2021-10-16 03:04:09 +02:00
void insert_transform_key ( Node3D * p_node , const String & p_sub , const Animation : : TrackType p_type , const Variant p_value ) ;
bool has_track ( Node3D * p_node , const String & p_sub , const Animation : : TrackType p_type ) ;
2021-08-10 05:11:27 +02:00
void make_insert_queue ( ) ;
void commit_insert_queue ( ) ;
2018-06-07 17:46:14 +02:00
void show_select_node_warning ( bool p_show ) ;
2023-07-20 17:34:06 +02:00
void show_dummy_player_warning ( bool p_show ) ;
void show_inactive_player_warning ( bool p_show ) ;
2018-06-07 17:46:14 +02:00
bool is_key_selected ( int p_track , int p_key ) const ;
bool is_selection_active ( ) const ;
2024-02-06 18:57:10 +01:00
bool is_key_clipboard_active ( ) const ;
2018-06-07 17:46:14 +02:00
bool is_moving_selection ( ) const ;
2019-08-06 01:15:20 +02:00
bool is_snap_enabled ( ) const ;
2018-06-07 17:46:14 +02:00
float get_moving_selection_offset ( ) const ;
2019-11-17 23:34:36 +01:00
float snap_time ( float p_value , bool p_relative = false ) ;
2019-05-25 18:01:44 +02:00
bool is_grouping_tracks ( ) ;
2018-06-07 17:46:14 +02:00
2021-05-10 01:15:09 +02:00
/** If `p_from_mouse_event` is `true`, handle Shift key presses for precise snapping. */
void goto_prev_step ( bool p_from_mouse_event ) ;
/** If `p_from_mouse_event` is `true`, handle Shift key presses for precise snapping. */
2021-05-23 15:32:03 +02:00
void goto_next_step ( bool p_from_mouse_event , bool p_timeline_only = false ) ;
2021-05-10 01:15:09 +02:00
2018-06-07 17:46:14 +02:00
MenuButton * get_edit_menu ( ) ;
AnimationTrackEditor ( ) ;
~ AnimationTrackEditor ( ) ;
} ;
2022-12-08 13:38:01 +01:00
// AnimationTrackKeyEditEditorPlugin
class AnimationTrackKeyEditEditor : public EditorProperty {
GDCLASS ( AnimationTrackKeyEditEditor , EditorProperty ) ;
Ref < Animation > animation ;
int track = - 1 ;
real_t key_ofs = 0.0 ;
bool use_fps = false ;
EditorSpinSlider * spinner = nullptr ;
struct KeyDataCache {
real_t time = 0.0 ;
float transition = 0.0 ;
Variant value ;
} key_data_cache ;
void _time_edit_entered ( ) ;
void _time_edit_exited ( ) ;
public :
AnimationTrackKeyEditEditor ( Ref < Animation > p_animation , int p_track , real_t p_key_ofs , bool p_use_fps ) ;
~ AnimationTrackKeyEditEditor ( ) ;
} ;
2018-06-07 17:46:14 +02:00
# endif // ANIMATION_TRACK_EDITOR_H