1 | /**************************************************************************/ |
2 | /* scene_tree_dock.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 SCENE_TREE_DOCK_H |
32 | #define SCENE_TREE_DOCK_H |
33 | |
34 | #include "editor/gui/scene_tree_editor.h" |
35 | #include "editor/script_create_dialog.h" |
36 | #include "scene/gui/box_container.h" |
37 | #include "scene/resources/animation.h" |
38 | |
39 | class CheckBox; |
40 | class EditorData; |
41 | class EditorSelection; |
42 | class EditorQuickOpen; |
43 | class ; |
44 | class ReparentDialog; |
45 | class ShaderCreateDialog; |
46 | class TextureRect; |
47 | |
48 | #include "modules/modules_enabled.gen.h" // For regex. |
49 | #ifdef MODULE_REGEX_ENABLED |
50 | class RenameDialog; |
51 | #endif // MODULE_REGEX_ENABLED |
52 | |
53 | class SceneTreeDock : public VBoxContainer { |
54 | GDCLASS(SceneTreeDock, VBoxContainer); |
55 | |
56 | enum Tool { |
57 | TOOL_NEW, |
58 | TOOL_INSTANTIATE, |
59 | TOOL_EXPAND_COLLAPSE, |
60 | TOOL_CUT, |
61 | TOOL_COPY, |
62 | TOOL_PASTE, |
63 | TOOL_PASTE_AS_SIBLING, |
64 | TOOL_RENAME, |
65 | #ifdef MODULE_REGEX_ENABLED |
66 | TOOL_BATCH_RENAME, |
67 | #endif // MODULE_REGEX_ENABLED |
68 | TOOL_REPLACE, |
69 | TOOL_EXTEND_SCRIPT, |
70 | TOOL_ATTACH_SCRIPT, |
71 | TOOL_DETACH_SCRIPT, |
72 | TOOL_MOVE_UP, |
73 | TOOL_MOVE_DOWN, |
74 | TOOL_DUPLICATE, |
75 | TOOL_REPARENT, |
76 | TOOL_REPARENT_TO_NEW_NODE, |
77 | TOOL_MAKE_ROOT, |
78 | TOOL_NEW_SCENE_FROM, |
79 | TOOL_MULTI_EDIT, |
80 | TOOL_ERASE, |
81 | TOOL_COPY_NODE_PATH, |
82 | TOOL_OPEN_DOCUMENTATION, |
83 | TOOL_AUTO_EXPAND, |
84 | TOOL_SCENE_EDITABLE_CHILDREN, |
85 | TOOL_SCENE_USE_PLACEHOLDER, |
86 | TOOL_SCENE_MAKE_LOCAL, |
87 | TOOL_SCENE_OPEN, |
88 | TOOL_SCENE_CLEAR_INHERITANCE, |
89 | TOOL_SCENE_CLEAR_INHERITANCE_CONFIRM, |
90 | TOOL_SCENE_OPEN_INHERITED, |
91 | TOOL_TOGGLE_SCENE_UNIQUE_NAME, |
92 | TOOL_CREATE_2D_SCENE, |
93 | TOOL_CREATE_3D_SCENE, |
94 | TOOL_CREATE_USER_INTERFACE, |
95 | TOOL_CREATE_FAVORITE, |
96 | |
97 | }; |
98 | |
99 | enum { |
100 | EDIT_SUBRESOURCE_BASE = 100 |
101 | }; |
102 | |
103 | Vector<ObjectID> subresources; |
104 | |
105 | bool reset_create_dialog = false; |
106 | |
107 | int current_option = 0; |
108 | CreateDialog *create_dialog = nullptr; |
109 | #ifdef MODULE_REGEX_ENABLED |
110 | RenameDialog *rename_dialog = nullptr; |
111 | #endif // MODULE_REGEX_ENABLED |
112 | |
113 | Button *button_add = nullptr; |
114 | Button *button_instance = nullptr; |
115 | Button *button_create_script = nullptr; |
116 | Button *button_detach_script = nullptr; |
117 | MenuButton * = nullptr; |
118 | |
119 | Button *node_shortcuts_toggle = nullptr; |
120 | VBoxContainer *beginner_node_shortcuts = nullptr; |
121 | VBoxContainer *favorite_node_shortcuts = nullptr; |
122 | |
123 | Button *button_2d = nullptr; |
124 | Button *button_3d = nullptr; |
125 | Button *button_ui = nullptr; |
126 | Button *button_custom = nullptr; |
127 | Button *button_clipboard = nullptr; |
128 | |
129 | HBoxContainer *button_hb = nullptr; |
130 | Button *edit_local, *edit_remote; |
131 | SceneTreeEditor *scene_tree = nullptr; |
132 | Control *remote_tree = nullptr; |
133 | |
134 | HBoxContainer *tool_hbc = nullptr; |
135 | void _tool_selected(int p_tool, bool p_confirm_override = false); |
136 | void _property_selected(int p_idx); |
137 | |
138 | Node *property_drop_node = nullptr; |
139 | String resource_drop_path; |
140 | void _perform_property_drop(Node *p_node, String p_property, Ref<Resource> p_res); |
141 | |
142 | EditorData *editor_data = nullptr; |
143 | EditorSelection *editor_selection = nullptr; |
144 | |
145 | List<Node *> node_clipboard; |
146 | String clipboard_source_scene; |
147 | HashMap<String, HashMap<Ref<Resource>, Ref<Resource>>> clipboard_resource_remap; |
148 | |
149 | ScriptCreateDialog *script_create_dialog = nullptr; |
150 | ShaderCreateDialog *shader_create_dialog = nullptr; |
151 | AcceptDialog *accept = nullptr; |
152 | ConfirmationDialog *delete_dialog = nullptr; |
153 | Label *delete_dialog_label = nullptr; |
154 | CheckBox *delete_tracks_checkbox = nullptr; |
155 | ConfirmationDialog *editable_instance_remove_dialog = nullptr; |
156 | ConfirmationDialog *placeholder_editable_instance_remove_dialog = nullptr; |
157 | |
158 | ReparentDialog *reparent_dialog = nullptr; |
159 | EditorQuickOpen *quick_open = nullptr; |
160 | EditorFileDialog *new_scene_from_dialog = nullptr; |
161 | |
162 | enum { |
163 | FILTER_BY_TYPE = 64, // Used in the same menus as the Tool enum. |
164 | FILTER_BY_GROUP, |
165 | }; |
166 | |
167 | LineEdit *filter = nullptr; |
168 | PopupMenu * = nullptr; |
169 | TextureRect *filter_icon = nullptr; |
170 | |
171 | PopupMenu * = nullptr; |
172 | PopupMenu * = nullptr; |
173 | PopupMenu * = nullptr; |
174 | ConfirmationDialog *clear_inherit_confirm = nullptr; |
175 | |
176 | bool first_enter = true; |
177 | |
178 | void _create(); |
179 | void _do_create(Node *p_parent); |
180 | Node *scene_root = nullptr; |
181 | Node *edited_scene = nullptr; |
182 | Node *pending_click_select = nullptr; |
183 | bool tree_clicked = false; |
184 | |
185 | VBoxContainer *create_root_dialog = nullptr; |
186 | String selected_favorite_root; |
187 | |
188 | Ref<ShaderMaterial> selected_shader_material; |
189 | |
190 | void (Object *p_obj, int p_depth); |
191 | |
192 | void _node_reparent(NodePath p_path, bool p_keep_global_xform); |
193 | void _do_reparent(Node *p_new_parent, int p_position_in_parent, Vector<Node *> p_nodes, bool p_keep_global_xform); |
194 | |
195 | void _set_owners(Node *p_owner, const Array &p_nodes); |
196 | |
197 | enum ReplaceOwnerMode { |
198 | MODE_BIDI, |
199 | MODE_DO, |
200 | MODE_UNDO |
201 | }; |
202 | |
203 | void _node_replace_owner(Node *p_base, Node *p_node, Node *p_root, ReplaceOwnerMode p_mode = MODE_BIDI); |
204 | void _load_request(const String &p_path); |
205 | void _script_open_request(const Ref<Script> &p_script); |
206 | void _push_item(Object *p_object); |
207 | void _handle_select(Node *p_node); |
208 | |
209 | bool _cyclical_dependency_exists(const String &p_target_scene_path, Node *p_desired_node); |
210 | bool _track_inherit(const String &p_target_scene_path, Node *p_desired_node); |
211 | |
212 | void _node_selected(); |
213 | void _node_renamed(); |
214 | void _script_created(Ref<Script> p_script); |
215 | void _shader_created(Ref<Shader> p_shader); |
216 | void _script_creation_closed(); |
217 | void _shader_creation_closed(); |
218 | |
219 | void _delete_confirm(bool p_cut = false); |
220 | void _delete_dialog_closed(); |
221 | |
222 | void _toggle_editable_children_from_selection(); |
223 | void _toggle_editable_children(Node *p_node); |
224 | |
225 | void _toggle_placeholder_from_selection(); |
226 | |
227 | void _node_prerenamed(Node *p_node, const String &p_new_name); |
228 | |
229 | void _nodes_drag_begin(); |
230 | virtual void input(const Ref<InputEvent> &p_event) override; |
231 | virtual void shortcut_input(const Ref<InputEvent> &p_event) override; |
232 | |
233 | void _new_scene_from(String p_file); |
234 | void _set_node_owner_recursive(Node *p_node, Node *p_owner); |
235 | |
236 | bool _validate_no_foreign(); |
237 | bool _validate_no_instance(); |
238 | void _selection_changed(); |
239 | void _update_script_button(); |
240 | |
241 | void _fill_path_renames(Vector<StringName> base_path, Vector<StringName> new_base_path, Node *p_node, HashMap<Node *, NodePath> *p_renames); |
242 | bool _has_tracks_to_delete(Node *p_node, List<Node *> &p_to_delete) const; |
243 | |
244 | void _normalize_drop(Node *&to_node, int &to_pos, int p_type); |
245 | |
246 | void _nodes_dragged(Array p_nodes, NodePath p_to, int p_type); |
247 | void _files_dropped(Vector<String> p_files, NodePath p_to, int p_type); |
248 | void _script_dropped(String p_file, NodePath p_to); |
249 | void _quick_open(); |
250 | |
251 | void _tree_rmb(const Vector2 &); |
252 | void (); |
253 | |
254 | void _filter_changed(const String &p_filter); |
255 | void _filter_gui_input(const Ref<InputEvent> &p_event); |
256 | void _filter_option_selected(int option); |
257 | void (PopupMenu *, bool p_include_separator = true); |
258 | |
259 | void _perform_instantiate_scenes(const Vector<String> &p_files, Node *parent, int p_pos); |
260 | void _replace_with_branch_scene(const String &p_file, Node *base); |
261 | |
262 | void _remote_tree_selected(); |
263 | void _local_tree_selected(); |
264 | |
265 | void _update_create_root_dialog(); |
266 | void _favorite_root_selected(const String &p_class); |
267 | |
268 | void _feature_profile_changed(); |
269 | |
270 | void _clear_clipboard(); |
271 | void _create_remap_for_node(Node *p_node, HashMap<Ref<Resource>, Ref<Resource>> &r_remap); |
272 | void _create_remap_for_resource(Ref<Resource> p_resource, HashMap<Ref<Resource>, Ref<Resource>> &r_remap); |
273 | |
274 | void (PopupMenu *); |
275 | void _gather_resources(Node *p_node, List<Pair<Ref<Resource>, Node *>> &r_resources); |
276 | void (int p_idx, const PopupMenu *); |
277 | |
278 | bool profile_allow_editing = true; |
279 | bool profile_allow_script_editing = true; |
280 | |
281 | static void _update_configuration_warning(); |
282 | |
283 | bool _update_node_path(Node *p_root_node, NodePath &r_node_path, HashMap<Node *, NodePath> *p_renames) const; |
284 | bool _check_node_path_recursive(Node *p_root_node, Variant &r_variant, HashMap<Node *, NodePath> *p_renames) const; |
285 | bool _check_node_recursive(Variant &r_variant, Node *p_node, Node *p_by_node, const String type_hint, String &r_warn_message); |
286 | void _replace_node(Node *p_node, Node *p_by_node, bool p_keep_properties = true, bool p_remove_old = true); |
287 | |
288 | private: |
289 | static SceneTreeDock *singleton; |
290 | |
291 | public: |
292 | static SceneTreeDock *get_singleton() { return singleton; } |
293 | |
294 | protected: |
295 | void _notification(int p_what); |
296 | static void _bind_methods(); |
297 | |
298 | public: |
299 | String get_filter(); |
300 | void set_filter(const String &p_filter); |
301 | void save_branch_to_file(String p_directory); |
302 | |
303 | void _focus_node(); |
304 | |
305 | void add_root_node(Node *p_node); |
306 | void set_edited_scene(Node *p_scene); |
307 | void instantiate(const String &p_file); |
308 | void instantiate_scenes(const Vector<String> &p_files, Node *p_parent = nullptr); |
309 | void set_selected(Node *p_node, bool p_emit_selected = false); |
310 | void fill_path_renames(Node *p_node, Node *p_new_parent, HashMap<Node *, NodePath> *p_renames); |
311 | void perform_node_renames(Node *p_base, HashMap<Node *, NodePath> *p_renames, HashMap<Ref<Animation>, HashSet<int>> *r_rem_anims = nullptr); |
312 | void perform_node_replace(Node *p_base, Node *p_node, Node *p_by_node); |
313 | SceneTreeEditor *get_tree_editor() { return scene_tree; } |
314 | EditorData *get_editor_data() { return editor_data; } |
315 | |
316 | void add_remote_tree_editor(Control *p_remote); |
317 | void show_remote_tree(); |
318 | void hide_remote_tree(); |
319 | void show_tab_buttons(); |
320 | void hide_tab_buttons(); |
321 | |
322 | void replace_node(Node *p_node, Node *p_by_node); |
323 | |
324 | void attach_script_to_selected(bool p_extend); |
325 | void open_script_dialog(Node *p_for_node, bool p_extend); |
326 | |
327 | void attach_shader_to_selected(int p_preferred_mode = -1); |
328 | void open_shader_dialog(const Ref<ShaderMaterial> &p_for_material, int p_preferred_mode = -1); |
329 | |
330 | void open_add_child_dialog(); |
331 | void open_instance_child_dialog(); |
332 | |
333 | List<Node *> paste_nodes(bool p_paste_as_sibling = false); |
334 | List<Node *> get_node_clipboard() const; |
335 | |
336 | ScriptCreateDialog *get_script_create_dialog() { |
337 | return script_create_dialog; |
338 | } |
339 | |
340 | SceneTreeDock(Node *p_scene_root, EditorSelection *p_editor_selection, EditorData &p_editor_data); |
341 | ~SceneTreeDock(); |
342 | }; |
343 | |
344 | #endif // SCENE_TREE_DOCK_H |
345 | |