1/**************************************************************************/
2/* animation_state_machine_editor.h */
3/**************************************************************************/
4/* This file is part of: */
5/* GODOT ENGINE */
6/* https://godotengine.org */
7/**************************************************************************/
8/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10/* */
11/* Permission is hereby granted, free of charge, to any person obtaining */
12/* a copy of this software and associated documentation files (the */
13/* "Software"), to deal in the Software without restriction, including */
14/* without limitation the rights to use, copy, modify, merge, publish, */
15/* distribute, sublicense, and/or sell copies of the Software, and to */
16/* permit persons to whom the Software is furnished to do so, subject to */
17/* the following conditions: */
18/* */
19/* The above copyright notice and this permission notice shall be */
20/* included in all copies or substantial portions of the Software. */
21/* */
22/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29/**************************************************************************/
30
31#ifndef ANIMATION_STATE_MACHINE_EDITOR_H
32#define ANIMATION_STATE_MACHINE_EDITOR_H
33
34#include "editor/plugins/animation_tree_editor_plugin.h"
35#include "scene/animation/animation_node_state_machine.h"
36#include "scene/gui/graph_edit.h"
37#include "scene/gui/popup.h"
38#include "scene/gui/tree.h"
39
40class ConfirmationDialog;
41class EditorFileDialog;
42class OptionButton;
43class PanelContainer;
44
45class AnimationNodeStateMachineEditor : public AnimationTreeNodeEditorPlugin {
46 GDCLASS(AnimationNodeStateMachineEditor, AnimationTreeNodeEditorPlugin);
47
48 Ref<AnimationNodeStateMachine> state_machine;
49
50 bool read_only = false;
51
52 Button *tool_select = nullptr;
53 Button *tool_create = nullptr;
54 Button *tool_connect = nullptr;
55 Popup *name_edit_popup = nullptr;
56 LineEdit *name_edit = nullptr;
57
58 HBoxContainer *selection_tools_hb = nullptr;
59 Button *tool_erase = nullptr;
60
61 HBoxContainer *transition_tools_hb = nullptr;
62 OptionButton *switch_mode = nullptr;
63 Button *auto_advance = nullptr;
64
65 OptionButton *play_mode = nullptr;
66
67 PanelContainer *panel = nullptr;
68
69 StringName selected_node;
70 HashSet<StringName> selected_nodes;
71
72 HScrollBar *h_scroll = nullptr;
73 VScrollBar *v_scroll = nullptr;
74
75 Control *state_machine_draw = nullptr;
76 Control *state_machine_play_pos = nullptr;
77
78 PanelContainer *error_panel = nullptr;
79 Label *error_label = nullptr;
80
81 bool updating = false;
82
83 static AnimationNodeStateMachineEditor *singleton;
84
85 void _state_machine_gui_input(const Ref<InputEvent> &p_event);
86 void _connection_draw(const Vector2 &p_from, const Vector2 &p_to, AnimationNodeStateMachineTransition::SwitchMode p_mode, bool p_enabled, bool p_selected, bool p_travel, float p_fade_ratio, bool p_auto_advance, bool p_is_across_group);
87
88 void _state_machine_draw();
89
90 void _state_machine_pos_draw_individual(String p_name, float p_ratio);
91 void _state_machine_pos_draw_all();
92
93 void _update_graph();
94
95 PopupMenu *menu = nullptr;
96 PopupMenu *connect_menu = nullptr;
97 PopupMenu *state_machine_menu = nullptr;
98 PopupMenu *end_menu = nullptr;
99 PopupMenu *animations_menu = nullptr;
100 Vector<String> animations_to_add;
101 Vector<String> nodes_to_connect;
102
103 Vector2 add_node_pos;
104
105 ConfirmationDialog *delete_window = nullptr;
106 Tree *delete_tree = nullptr;
107
108 bool box_selecting = false;
109 Point2 box_selecting_from;
110 Point2 box_selecting_to;
111 Rect2 box_selecting_rect;
112 HashSet<StringName> previous_selected;
113
114 bool dragging_selected_attempt = false;
115 bool dragging_selected = false;
116 Vector2 drag_from;
117 Vector2 drag_ofs;
118 StringName snap_x;
119 StringName snap_y;
120
121 bool connecting = false;
122 bool connection_follows_cursor = false;
123 StringName connecting_from;
124 Vector2 connecting_to;
125 StringName connecting_to_node;
126
127 void _add_menu_type(int p_index);
128 void _add_animation_type(int p_index);
129 void _connect_to(int p_index);
130
131 struct NodeRect {
132 StringName node_name;
133 Rect2 node;
134 Rect2 play;
135 Rect2 name;
136 Rect2 edit;
137 bool can_edit;
138 };
139
140 Vector<NodeRect> node_rects;
141
142 struct TransitionLine {
143 StringName from_node;
144 StringName to_node;
145 Vector2 from;
146 Vector2 to;
147 AnimationNodeStateMachineTransition::SwitchMode mode;
148 StringName advance_condition_name;
149 bool advance_condition_state = false;
150 bool disabled = false;
151 bool auto_advance = false;
152 float width = 0;
153 bool selected;
154 bool travel;
155 float fade_ratio;
156 bool hidden;
157 int transition_index;
158 bool is_across_group = false;
159 };
160
161 Vector<TransitionLine> transition_lines;
162
163 struct NodeUR {
164 StringName name;
165 Ref<AnimationNode> node;
166 Vector2 position;
167 };
168
169 struct TransitionUR {
170 StringName new_from;
171 StringName new_to;
172 StringName old_from;
173 StringName old_to;
174 Ref<AnimationNodeStateMachineTransition> transition;
175 };
176
177 StringName selected_transition_from;
178 StringName selected_transition_to;
179 int selected_transition_index;
180 void _add_transition(const bool p_nested_action = false);
181
182 StringName over_node;
183 int over_node_what = -1;
184
185 String prev_name;
186 void _name_edited(const String &p_text);
187 void _name_edited_focus_out();
188 void _open_editor(const String &p_name);
189 void _scroll_changed(double);
190
191 String _get_root_playback_path(String &r_node_directory);
192
193 void _clip_src_line_to_rect(Vector2 &r_from, const Vector2 &p_to, const Rect2 &p_rect);
194 void _clip_dst_line_to_rect(const Vector2 &p_from, Vector2 &r_to, const Rect2 &p_rect);
195
196 void _erase_selected(const bool p_nested_action = false);
197 void _update_mode();
198 void _open_menu(const Vector2 &p_position);
199 bool _create_submenu(PopupMenu *p_menu, Ref<AnimationNodeStateMachine> p_nodesm, const StringName &p_name, const StringName &p_path);
200 void _stop_connecting();
201
202 void _delete_selected();
203 void _delete_all();
204 void _delete_tree_draw();
205
206 bool last_active = false;
207 StringName last_fading_from_node;
208 StringName last_current_node;
209 Vector<StringName> last_travel_path;
210
211 float fade_from_last_play_pos = 0.0f;
212 float fade_from_current_play_pos = 0.0f;
213 float fade_from_length = 0.0f;
214
215 float last_play_pos = 0.0f;
216 float current_play_pos = 0.0f;
217 float current_length = 0.0f;
218
219 float last_fading_time = 0.0f;
220 float last_fading_pos = 0.0f;
221 float fading_time = 0.0f;
222 float fading_pos = 0.0f;
223
224 float error_time = 0.0f;
225 String error_text;
226
227 EditorFileDialog *open_file = nullptr;
228 Ref<AnimationNode> file_loaded;
229 void _file_opened(const String &p_file);
230
231 enum {
232 MENU_LOAD_FILE = 1000,
233 MENU_PASTE = 1001,
234 MENU_LOAD_FILE_CONFIRM = 1002
235 };
236
237protected:
238 void _notification(int p_what);
239 static void _bind_methods();
240
241public:
242 static AnimationNodeStateMachineEditor *get_singleton() { return singleton; }
243 virtual bool can_edit(const Ref<AnimationNode> &p_node) override;
244 virtual void edit(const Ref<AnimationNode> &p_node) override;
245 virtual CursorShape get_cursor_shape(const Point2 &p_pos) const override;
246 AnimationNodeStateMachineEditor();
247};
248
249class EditorAnimationMultiTransitionEdit : public RefCounted {
250 GDCLASS(EditorAnimationMultiTransitionEdit, RefCounted);
251
252 struct Transition {
253 StringName from;
254 StringName to;
255 Ref<AnimationNodeStateMachineTransition> transition;
256 };
257
258 Vector<Transition> transitions;
259
260protected:
261 bool _set(const StringName &p_name, const Variant &p_property);
262 bool _get(const StringName &p_name, Variant &r_property) const;
263 void _get_property_list(List<PropertyInfo> *p_list) const;
264
265public:
266 void add_transition(const StringName &p_from, const StringName &p_to, Ref<AnimationNodeStateMachineTransition> p_transition);
267
268 EditorAnimationMultiTransitionEdit(){};
269};
270
271#endif // ANIMATION_STATE_MACHINE_EDITOR_H
272