Add markers to animation

This commit is contained in:
chocola-mint
2024-08-31 15:57:34 +09:00
parent 76a135926a
commit ed13a840fa
18 changed files with 2445 additions and 102 deletions

View File

@@ -41,9 +41,11 @@
#include "scene/gui/tree.h"
#include "scene/resources/animation.h"
class AnimationMarkerEdit;
class AnimationTrackEditor;
class AnimationTrackEdit;
class CheckBox;
class ColorPickerButton;
class EditorSpinSlider;
class HSlider;
class OptionButton;
@@ -52,6 +54,7 @@ class SceneTreeDialog;
class SpinBox;
class TextureRect;
class ViewPanner;
class EditorValidationPanel;
class AnimationTrackKeyEdit : public Object {
GDCLASS(AnimationTrackKeyEdit, Object);
@@ -128,6 +131,58 @@ protected:
void _get_property_list(List<PropertyInfo> *p_list) const;
};
class AnimationMarkerKeyEdit : public Object {
GDCLASS(AnimationMarkerKeyEdit, Object);
public:
bool animation_read_only = false;
Ref<Animation> animation;
StringName marker_name;
bool use_fps = false;
AnimationMarkerEdit *marker_edit = nullptr;
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; }
float get_time() const;
protected:
static void _bind_methods();
void _set_marker_name(const StringName &p_name);
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 AnimationMultiMarkerKeyEdit : public Object {
GDCLASS(AnimationMultiMarkerKeyEdit, Object);
public:
bool animation_read_only = false;
Ref<Animation> animation;
Vector<StringName> marker_names;
AnimationMarkerEdit *marker_edit = nullptr;
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; }
protected:
static void _bind_methods();
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 AnimationTimelineEdit : public Range {
GDCLASS(AnimationTimelineEdit, Range);
@@ -218,6 +273,140 @@ public:
AnimationTimelineEdit();
};
class AnimationMarkerEdit : public Control {
GDCLASS(AnimationMarkerEdit, Control);
friend class AnimationTimelineEdit;
enum {
MENU_KEY_INSERT,
MENU_KEY_RENAME,
MENU_KEY_DELETE,
MENU_KEY_TOGGLE_MARKER_NAMES,
};
AnimationTimelineEdit *timeline = nullptr;
Control *play_position = nullptr; // Separate control used to draw so updates for only position changed are much faster.
float play_position_pos = 0.0f;
HashSet<StringName> selection;
Ref<Animation> animation;
bool read_only = false;
Ref<Texture2D> type_icon;
Ref<Texture2D> selected_icon;
PopupMenu *menu = nullptr;
bool hovered = false;
StringName hovering_marker;
void _zoom_changed();
Ref<Texture2D> icon_cache;
void _menu_selected(int p_index);
void _play_position_draw();
bool _try_select_at_ui_pos(const Point2 &p_pos, bool p_aggregate, bool p_deselectable);
bool _is_ui_pos_in_current_section(const Point2 &p_pos);
float insert_at_pos = 0.0f;
bool moving_selection_attempt = false;
bool moving_selection_effective = false;
float moving_selection_offset = 0.0f;
float moving_selection_pivot = 0.0f;
float moving_selection_mouse_begin_x = 0.0f;
float moving_selection_mouse_begin_y = 0.0f;
StringName select_single_attempt;
bool moving_selection = false;
void _move_selection_begin();
void _move_selection(float p_offset);
void _move_selection_commit();
void _move_selection_cancel();
void _clear_selection_for_anim(const Ref<Animation> &p_anim);
void _select_key(const StringName &p_name, bool is_single = false);
void _deselect_key(const StringName &p_name);
void _insert_marker(float p_ofs);
void _rename_marker(const StringName &p_name);
void _delete_selected_markers();
ConfirmationDialog *marker_insert_confirm = nullptr;
LineEdit *marker_insert_new_name = nullptr;
ColorPickerButton *marker_insert_color = nullptr;
AcceptDialog *marker_insert_error_dialog = nullptr;
float marker_insert_ofs = 0;
ConfirmationDialog *marker_rename_confirm = nullptr;
LineEdit *marker_rename_new_name = nullptr;
StringName marker_rename_prev_name;
AcceptDialog *marker_rename_error_dialog = nullptr;
bool should_show_all_marker_names = false;
////////////// edit menu stuff
void _marker_insert_confirmed();
void _marker_insert_new_name_changed(const String &p_text);
void _marker_rename_confirmed();
void _marker_rename_new_name_changed(const String &p_text);
AnimationTrackEditor *editor = nullptr;
HBoxContainer *_create_hbox_labeled_control(const String &p_text, Control *p_control) const;
void _update_key_edit();
void _clear_key_edit();
AnimationMarkerKeyEdit *key_edit = nullptr;
AnimationMultiMarkerKeyEdit *multi_key_edit = nullptr;
protected:
static void _bind_methods();
void _notification(int p_what);
virtual void gui_input(const Ref<InputEvent> &p_event) override;
public:
virtual String get_tooltip(const Point2 &p_pos) const override;
virtual int get_key_height() const;
virtual Rect2 get_key_rect(float p_pixels_sec) const;
virtual bool is_key_selectable_by_distance() const;
virtual 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);
virtual void draw_bg(int p_clip_left, int p_clip_right);
virtual void draw_fg(int p_clip_left, int p_clip_right);
Ref<Animation> get_animation() const;
AnimationTimelineEdit *get_timeline() const { return timeline; }
AnimationTrackEditor *get_editor() const { return editor; }
bool is_selection_active() const { return !selection.is_empty(); }
bool is_moving_selection() const { return moving_selection; }
float get_moving_selection_offset() const { return moving_selection_offset; }
void set_animation(const Ref<Animation> &p_animation, bool p_read_only);
virtual Size2 get_minimum_size() const override;
void set_timeline(AnimationTimelineEdit *p_timeline);
void set_editor(AnimationTrackEditor *p_editor);
void set_play_position(float p_pos);
void update_play_position();
void set_use_fps(bool p_use_fps);
PackedStringArray get_selected_section() const;
bool is_marker_selected(const StringName &p_marker) const;
// For use by AnimationTrackEditor.
void _clear_selection(bool p_update);
AnimationMarkerEdit();
~AnimationMarkerEdit();
};
class AnimationTrackEdit : public Control {
GDCLASS(AnimationTrackEdit, Control);
friend class AnimationTimelineEdit;
@@ -367,6 +556,7 @@ class AnimationTrackEditGroup : public Control {
NodePath node;
Node *root = nullptr;
AnimationTimelineEdit *timeline = nullptr;
AnimationTrackEditor *editor = nullptr;
void _zoom_changed();
@@ -380,6 +570,7 @@ public:
virtual Size2 get_minimum_size() const override;
void set_timeline(AnimationTimelineEdit *p_timeline);
void set_root(Node *p_root);
void set_editor(AnimationTrackEditor *p_editor);
AnimationTrackEditGroup();
};
@@ -388,6 +579,7 @@ class AnimationTrackEditor : public VBoxContainer {
GDCLASS(AnimationTrackEditor, VBoxContainer);
friend class AnimationTimelineEdit;
friend class AnimationBezierTrackEdit;
friend class AnimationMarkerKeyEditEditor;
Ref<Animation> animation;
bool read_only = false;
@@ -405,6 +597,7 @@ class AnimationTrackEditor : public VBoxContainer {
Label *info_message = nullptr;
AnimationTimelineEdit *timeline = nullptr;
AnimationMarkerEdit *marker_edit = nullptr;
HSlider *zoom = nullptr;
EditorSpinSlider *step = nullptr;
TextureRect *zoom_icon = nullptr;
@@ -743,6 +936,10 @@ public:
float get_moving_selection_offset() const;
float snap_time(float p_value, bool p_relative = false);
bool is_grouping_tracks();
PackedStringArray get_selected_section() const;
bool is_marker_selected(const StringName &p_marker) const;
bool is_marker_moving_selection() const;
float get_marker_moving_selection_offset() const;
/** If `p_from_mouse_event` is `true`, handle Shift key presses for precise snapping. */
void goto_prev_step(bool p_from_mouse_event);
@@ -781,4 +978,23 @@ public:
~AnimationTrackKeyEditEditor();
};
// AnimationMarkerKeyEditEditorPlugin
class AnimationMarkerKeyEditEditor : public EditorProperty {
GDCLASS(AnimationMarkerKeyEditEditor, EditorProperty);
Ref<Animation> animation;
StringName marker_name;
bool use_fps = false;
EditorSpinSlider *spinner = nullptr;
void _time_edit_entered();
void _time_edit_exited();
public:
AnimationMarkerKeyEditEditor(Ref<Animation> p_animation, const StringName &p_name, bool p_use_fps);
~AnimationMarkerKeyEditEditor();
};
#endif // ANIMATION_TRACK_EDITOR_H