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
39class CheckBox;
40class EditorData;
41class EditorSelection;
42class EditorQuickOpen;
43class MenuButton;
44class ReparentDialog;
45class ShaderCreateDialog;
46class TextureRect;
47
48#include "modules/modules_enabled.gen.h" // For regex.
49#ifdef MODULE_REGEX_ENABLED
50class RenameDialog;
51#endif // MODULE_REGEX_ENABLED
52
53class 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 *button_tree_menu = 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 FilterMenuItems {
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 *filter_quick_menu = nullptr;
169 TextureRect *filter_icon = nullptr;
170
171 PopupMenu *menu = nullptr;
172 PopupMenu *menu_subresources = nullptr;
173 PopupMenu *menu_properties = 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 _add_children_to_popup(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 &p_menu_pos);
252 void _update_tree_menu();
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 _append_filter_options_to(PopupMenu *p_menu, 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 _list_all_subresources(PopupMenu *p_menu);
275 void _gather_resources(Node *p_node, List<Pair<Ref<Resource>, Node *>> &r_resources);
276 void _edit_subresource(int p_idx, const PopupMenu *p_from_menu);
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
288private:
289 static SceneTreeDock *singleton;
290
291public:
292 static SceneTreeDock *get_singleton() { return singleton; }
293
294protected:
295 void _notification(int p_what);
296 static void _bind_methods();
297
298public:
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