| 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 | |