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 | |
40 | class ConfirmationDialog; |
41 | class EditorFileDialog; |
42 | class OptionButton; |
43 | class PanelContainer; |
44 | |
45 | class 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 * = 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 * = nullptr; |
96 | PopupMenu * = nullptr; |
97 | PopupMenu * = nullptr; |
98 | PopupMenu * = nullptr; |
99 | PopupMenu * = 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 (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 (const Vector2 &p_position); |
199 | bool (PopupMenu *, 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 | = 1000, |
233 | = 1001, |
234 | = 1002 |
235 | }; |
236 | |
237 | protected: |
238 | void _notification(int p_what); |
239 | static void _bind_methods(); |
240 | |
241 | public: |
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 | |
249 | class 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 | |
260 | protected: |
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 | |
265 | public: |
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 | |