Path: blob/master/editor/animation/animation_player_editor_plugin.h
21420 views
/**************************************************************************/1/* animation_player_editor_plugin.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/animation/animation_library_editor.h"33#include "editor/animation/animation_track_editor.h"34#include "editor/docks/editor_dock.h"35#include "editor/plugins/editor_plugin.h"36#include "scene/animation/animation_player.h"37#include "scene/gui/dialogs.h"38#include "scene/gui/slider.h"39#include "scene/gui/spin_box.h"40#include "scene/gui/texture_button.h"41#include "scene/gui/tree.h"42#include "scene/resources/material.h"4344class AnimationPlayerEditorPlugin;45class ImageTexture;4647class AnimationPlayerEditor : public EditorDock {48GDCLASS(AnimationPlayerEditor, EditorDock);4950friend AnimationPlayerEditorPlugin;5152AnimationPlayerEditorPlugin *plugin = nullptr;53AnimationMixer *original_node = nullptr; // For pinned mark in SceneTree.54AnimationPlayer *player = nullptr; // For AnimationPlayerEditor, could be dummy.55ObjectID cached_root_node_id;56bool is_dummy = false;5758enum {59TOOL_NEW_ANIM,60TOOL_ANIM_LIBRARY,61TOOL_DUPLICATE_ANIM,62TOOL_RENAME_ANIM,63TOOL_EDIT_TRANSITIONS,64TOOL_REMOVE_ANIM,65TOOL_EDIT_RESOURCE66};6768enum {69ONION_SKINNING_ENABLE,70ONION_SKINNING_PAST,71ONION_SKINNING_FUTURE,72ONION_SKINNING_1_STEP,73ONION_SKINNING_2_STEPS,74ONION_SKINNING_3_STEPS,75ONION_SKINNING_LAST_STEPS_OPTION = ONION_SKINNING_3_STEPS,76ONION_SKINNING_DIFFERENCES_ONLY,77ONION_SKINNING_FORCE_WHITE_MODULATE,78ONION_SKINNING_INCLUDE_GIZMOS,79};8081enum {82ANIM_OPEN,83ANIM_SAVE,84ANIM_SAVE_AS85};8687enum {88RESOURCE_LOAD,89RESOURCE_SAVE90};9192OptionButton *animation = nullptr;93Button *stop = nullptr;94Button *play = nullptr;95Button *play_from = nullptr;96Button *play_bw = nullptr;97Button *play_bw_from = nullptr;98Button *autoplay = nullptr;99100MenuButton *tool_anim = nullptr;101Button *onion_toggle = nullptr;102MenuButton *onion_skinning = nullptr;103Button *pin = nullptr;104SpinBox *frame = nullptr;105LineEdit *scale = nullptr;106LineEdit *name = nullptr;107OptionButton *library = nullptr;108Label *name_title = nullptr;109110Ref<Texture2D> stop_icon;111Ref<Texture2D> pause_icon;112Ref<Texture2D> autoplay_icon;113Ref<Texture2D> reset_icon;114Ref<ImageTexture> autoplay_reset_icon;115116bool finishing = false;117bool last_active = false;118float timeline_position = 0;119120EditorFileDialog *file = nullptr;121ConfirmationDialog *delete_dialog = nullptr;122123AnimationLibraryEditor *library_editor = nullptr;124125struct BlendEditor {126AcceptDialog *dialog = nullptr;127Tree *tree = nullptr;128OptionButton *next = nullptr;129130} blend_editor;131132ConfirmationDialog *name_dialog = nullptr;133AcceptDialog *error_dialog = nullptr;134int name_dialog_op = TOOL_NEW_ANIM;135136bool updating = false;137bool updating_blends = false;138139AnimationTrackEditor *track_editor = nullptr;140static AnimationPlayerEditor *singleton;141142// Onion skinning.143struct {144// Settings.145bool enabled = false;146bool past = true;147bool future = false;148uint32_t steps = 1;149bool differences_only = false;150bool force_white_modulate = false;151bool include_gizmos = false;152153uint32_t get_capture_count() const {154// 'Differences only' needs a capture of the present.155return (past && future ? 2 * steps : steps) + (differences_only ? 1 : 0);156}157158// Rendering.159int64_t last_frame = 0;160int can_overlay = 0;161Size2 capture_size;162LocalVector<RID> captures;163LocalVector<bool> captures_valid;164struct {165RID canvas;166RID canvas_item;167Ref<ShaderMaterial> material;168Ref<Shader> shader;169} capture;170171// Cross-call state.172struct {173double anim_player_position = 0.0;174Ref<AnimatedValuesBackup> anim_values_backup;175Rect2 screen_rect;176Dictionary canvas_edit_state;177Dictionary spatial_edit_state;178} temp;179} onion;180181void _select_anim_by_name(const String &p_anim);182float _get_editor_step() const;183void _play_pressed();184void _play_from_pressed();185void _play_bw_pressed();186void _play_bw_from_pressed();187void _autoplay_pressed();188void _stop_pressed();189void _animation_selected(int p_which);190void _animation_new();191void _animation_rename();192void _animation_name_edited();193194void _animation_remove();195void _animation_remove_confirmed();196void _animation_edit();197void _animation_duplicate();198Ref<Animation> _animation_clone(const Ref<Animation> p_anim);199void _animation_resource_edit();200void _scale_changed(const String &p_scale);201void _seek_value_changed(float p_value, bool p_timeline_only = false);202void _blend_editor_next_changed(const int p_idx);203204void _edit_animation_blend();205void _update_animation_blend();206207void _list_changed();208void _animation_finished(const String &p_name);209void _current_animation_changed(const StringName &p_name);210void _update_animation();211void _update_player();212void _set_controls_disabled(bool p_disabled);213void _update_animation_list_icons();214void _update_name_dialog_library_dropdown();215void _update_playback_tooltips();216void _blend_edited();217218void _animation_player_changed(Object *p_pl);219void _animation_libraries_updated();220221void _animation_key_editor_seek(float p_pos, bool p_timeline_only = false, bool p_update_position_only = false);222void _animation_key_editor_anim_len_changed(float p_len);223void _animation_update_key_frame();224225virtual void shortcut_input(const Ref<InputEvent> &p_ev) override;226void _animation_tool_menu(int p_option);227void _onion_skinning_menu(int p_option);228229void _editor_visibility_changed();230bool _are_onion_layers_valid();231void _allocate_onion_layers();232void _free_onion_layers();233void _prepare_onion_layers_1();234void _prepare_onion_layers_2_prolog();235void _prepare_onion_layers_2_step_prepare(int p_step_offset, uint32_t p_capture_idx);236void _prepare_onion_layers_2_step_capture(int p_step_offset, uint32_t p_capture_idx);237void _prepare_onion_layers_2_epilog();238void _start_onion_skinning();239void _stop_onion_skinning();240241bool _validate_tracks(const Ref<Animation> p_anim);242243void _pin_pressed();244String _get_current() const;245246void _ensure_dummy_player();247248~AnimationPlayerEditor();249250protected:251void _notification(int p_what);252void _node_removed(Node *p_node);253void _find_player();254static void _bind_methods();255256public:257AnimationMixer *get_editing_node() const;258AnimationPlayer *get_player() const;259AnimationMixer *fetch_mixer_for_library() const;260Node *get_cached_root_node() const;261262static AnimationPlayerEditor *get_singleton() { return singleton; }263264bool is_pinned() const { return pin->is_pressed(); }265void unpin() {266pin->set_pressed(false);267_pin_pressed();268}269AnimationTrackEditor *get_track_editor() { return track_editor; }270Dictionary get_state() const;271void set_state(const Dictionary &p_state);272void clear();273274void ensure_visibility();275void go_to_nearest_keyframe(bool p_backward);276277void edit(AnimationMixer *p_node, AnimationPlayer *p_player, bool p_is_dummy);278void forward_force_draw_over_viewport(Control *p_overlay);279280AnimationPlayerEditor(AnimationPlayerEditorPlugin *p_plugin);281};282283class AnimationPlayerEditorPlugin : public EditorPlugin {284GDCLASS(AnimationPlayerEditorPlugin, EditorPlugin);285286friend AnimationPlayerEditor;287288AnimationPlayerEditor *anim_editor = nullptr;289AnimationPlayer *player = nullptr;290AnimationPlayer *dummy_player = nullptr;291ObjectID last_mixer;292293void _update_dummy_player(AnimationMixer *p_mixer);294void _clear_dummy_player();295296protected:297void _notification(int p_what);298299void _property_keyed(const String &p_keyed, const Variant &p_value, bool p_advance);300void _transform_key_request(Object *sp, const String &p_sub, const Transform3D &p_key);301void _update_keying();302303public:304virtual Dictionary get_state() const override { return anim_editor->get_state(); }305virtual void set_state(const Dictionary &p_state) override { anim_editor->set_state(p_state); }306virtual void clear() override { anim_editor->clear(); }307308virtual String get_plugin_name() const override { return "Anim"; }309bool has_main_screen() const override { return false; }310virtual void edit(Object *p_object) override;311virtual bool handles(Object *p_object) const override;312virtual void make_visible(bool p_visible) override;313314virtual void forward_canvas_force_draw_over_viewport(Control *p_overlay) override { anim_editor->forward_force_draw_over_viewport(p_overlay); }315virtual void forward_3d_force_draw_over_viewport(Control *p_overlay) override { anim_editor->forward_force_draw_over_viewport(p_overlay); }316317AnimationPlayerEditorPlugin();318~AnimationPlayerEditorPlugin();319};320321// AnimationTrackKeyEditEditorPlugin322323class EditorInspectorPluginAnimationTrackKeyEdit : public EditorInspectorPlugin {324GDCLASS(EditorInspectorPluginAnimationTrackKeyEdit, EditorInspectorPlugin);325326AnimationTrackKeyEditEditor *atk_editor = nullptr;327328public:329virtual bool can_handle(Object *p_object) override;330virtual void parse_begin(Object *p_object) override;331};332333class AnimationTrackKeyEditEditorPlugin : public EditorPlugin {334GDCLASS(AnimationTrackKeyEditEditorPlugin, EditorPlugin);335336EditorInspectorPluginAnimationTrackKeyEdit *atk_plugin = nullptr;337338public:339bool has_main_screen() const override { return false; }340virtual bool handles(Object *p_object) const override;341342virtual String get_plugin_name() const override { return "AnimationTrackKeyEdit"; }343344AnimationTrackKeyEditEditorPlugin();345};346347// AnimationMarkerKeyEditEditorPlugin348349class EditorInspectorPluginAnimationMarkerKeyEdit : public EditorInspectorPlugin {350GDCLASS(EditorInspectorPluginAnimationMarkerKeyEdit, EditorInspectorPlugin);351352AnimationMarkerKeyEditEditor *amk_editor = nullptr;353354public:355virtual bool can_handle(Object *p_object) override;356virtual void parse_begin(Object *p_object) override;357};358359class AnimationMarkerKeyEditEditorPlugin : public EditorPlugin {360GDCLASS(AnimationMarkerKeyEditEditorPlugin, EditorPlugin);361362EditorInspectorPluginAnimationMarkerKeyEdit *amk_plugin = nullptr;363364public:365bool has_main_screen() const override { return false; }366virtual bool handles(Object *p_object) const override;367368virtual String get_plugin_name() const override { return "AnimationMarkerKeyEdit"; }369370AnimationMarkerKeyEditEditorPlugin();371};372373374