diff options
Diffstat (limited to 'editor')
216 files changed, 5171 insertions, 7177 deletions
diff --git a/editor/SCsub b/editor/SCsub index 4fa287c33b..82a4ecb6c0 100644 --- a/editor/SCsub +++ b/editor/SCsub @@ -1,6 +1,7 @@ #!/usr/bin/env python Import('env') + env.editor_sources = [] import os @@ -61,10 +62,6 @@ if env['tools']: env.Depends("#editor/doc_data_compressed.gen.h", docs) env.CommandNoCache("#editor/doc_data_compressed.gen.h", docs, run_in_subprocess(editor_builders.make_doc_header)) - # Certificates - env.Depends("#editor/certs_compressed.gen.h", "#thirdparty/certs/ca-certificates.crt") - env.CommandNoCache("#editor/certs_compressed.gen.h", "#thirdparty/certs/ca-certificates.crt", run_in_subprocess(editor_builders.make_certs_header)) - import glob path = env.Dir('.').abspath @@ -76,24 +73,15 @@ if env['tools']: # Fonts flist = glob.glob(path + "/../thirdparty/fonts/*.ttf") - flist.append(glob.glob(path + "/../thirdparty/fonts/*.otf")) + flist.extend(glob.glob(path + "/../thirdparty/fonts/*.otf")) + flist.sort() env.Depends('#editor/builtin_fonts.gen.h', flist) env.CommandNoCache('#editor/builtin_fonts.gen.h', flist, run_in_subprocess(editor_builders.make_fonts_header)) - # Authors - env.Depends('#editor/authors.gen.h', "../AUTHORS.md") - env.CommandNoCache('#editor/authors.gen.h', "../AUTHORS.md", run_in_subprocess(editor_builders.make_authors_header)) - - # Donors - env.Depends('#editor/donors.gen.h', "../DONORS.md") - env.CommandNoCache('#editor/donors.gen.h', "../DONORS.md", run_in_subprocess(editor_builders.make_donors_header)) - - # License - env.Depends('#editor/license.gen.h', ["../COPYRIGHT.txt", "../LICENSE.txt"]) - env.CommandNoCache('#editor/license.gen.h', ["../COPYRIGHT.txt", "../LICENSE.txt"], run_in_subprocess(editor_builders.make_license_header)) - env.add_source_files(env.editor_sources, "*.cpp") - env.add_source_files(env.editor_sources, ["#thirdparty/misc/clipper.cpp"]) + env_thirdparty = env.Clone() + env_thirdparty.disable_warnings() + env_thirdparty.add_source_files(env.editor_sources, ["#thirdparty/misc/clipper.cpp"]) SConscript('collada/SCsub') SConscript('doc/SCsub') @@ -104,5 +92,3 @@ if env['tools']: lib = env.add_library("editor", env.editor_sources) env.Prepend(LIBS=[lib]) - - Export('env') diff --git a/editor/animation_bezier_editor.cpp b/editor/animation_bezier_editor.cpp index 197599442b..f0dc3ce305 100644 --- a/editor/animation_bezier_editor.cpp +++ b/editor/animation_bezier_editor.cpp @@ -1,5 +1,37 @@ +/*************************************************************************/ +/* animation_bezier_editor.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + #include "animation_bezier_editor.h" +#include "editor/editor_node.h" + float AnimationBezierTrackEdit::_bezier_h_to_pixel(float p_h) { float h = p_h; h = (h - v_scroll) / v_zoom; @@ -258,12 +290,7 @@ void AnimationBezierTrackEdit::_notification(int p_what) { int h = font->get_height(); if (node) { - Ref<Texture> icon; - if (has_icon(node->get_class(), "EditorIcons")) { - icon = get_icon(node->get_class(), "EditorIcons"); - } else { - icon = get_icon("Node", "EditorIcons"); - } + Ref<Texture> icon = EditorNode::get_singleton()->get_object_icon(node, "Node"); h = MAX(h, icon->get_height()); diff --git a/editor/animation_bezier_editor.h b/editor/animation_bezier_editor.h index 544690844a..1c701cc8f4 100644 --- a/editor/animation_bezier_editor.h +++ b/editor/animation_bezier_editor.h @@ -1,3 +1,33 @@ +/*************************************************************************/ +/* animation_bezier_editor.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + #ifndef ANIMATION_BEZIER_EDITOR_H #define ANIMATION_BEZIER_EDITOR_H diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp index 4c4830ad7a..77be561477 100644 --- a/editor/animation_track_editor.cpp +++ b/editor/animation_track_editor.cpp @@ -29,12 +29,13 @@ /*************************************************************************/ #include "animation_track_editor.h" + #include "animation_track_editor_plugins.h" +#include "core/os/keyboard.h" #include "editor/animation_bezier_editor.h" #include "editor/plugins/animation_player_editor_plugin.h" #include "editor_node.h" #include "editor_scale.h" -#include "os/keyboard.h" #include "scene/main/viewport.h" #include "servers/audio/audio_stream.h" @@ -772,9 +773,6 @@ void AnimationTimelineEdit::_notification(int p_what) { hsize_rect = Rect2(get_name_limit() - hsize_icon->get_width() - 2 * EDSCALE, (get_size().height - hsize_icon->get_height()) / 2, hsize_icon->get_width(), hsize_icon->get_height()); draw_texture(hsize_icon, hsize_rect.position); - float keys_from = get_value(); - float keys_to = keys_from + zoomw / scale; - { float time_min = 0; float time_max = animation->get_length(); @@ -4923,8 +4921,8 @@ AnimationTrackEditor::AnimationTrackEditor() { //this shortcut will be checked from the track itself. so no need to enable it here (will conflict with scenetree dock) edit->get_popup()->add_separator(); - edit->get_popup()->add_shortcut(ED_SHORTCUT("animation_editor/goto_next_step", TTR("Goto Next Step"), KEY_MASK_CMD | KEY_RIGHT), EDIT_GOTO_NEXT_STEP); - edit->get_popup()->add_shortcut(ED_SHORTCUT("animation_editor/goto_prev_step", TTR("Goto Prev Step"), KEY_MASK_CMD | KEY_LEFT), EDIT_GOTO_PREV_STEP); + edit->get_popup()->add_shortcut(ED_SHORTCUT("animation_editor/goto_next_step", TTR("Go to Next Step"), KEY_MASK_CMD | KEY_RIGHT), EDIT_GOTO_NEXT_STEP); + edit->get_popup()->add_shortcut(ED_SHORTCUT("animation_editor/goto_prev_step", TTR("Go to Previous Step"), KEY_MASK_CMD | KEY_LEFT), EDIT_GOTO_PREV_STEP); edit->get_popup()->add_separator(); edit->get_popup()->add_item(TTR("Optimize Animation"), EDIT_OPTIMIZE_ANIMATION); edit->get_popup()->add_item(TTR("Clean-Up Animation"), EDIT_CLEAN_UP_ANIMATION); diff --git a/editor/animation_track_editor.h b/editor/animation_track_editor.h index 0692c88bea..deefe6c6fd 100644 --- a/editor/animation_track_editor.h +++ b/editor/animation_track_editor.h @@ -1,3 +1,33 @@ +/*************************************************************************/ +/* animation_track_editor.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + #ifndef ANIMATION_TRACK_EDITOR_H #define ANIMATION_TRACK_EDITOR_H diff --git a/editor/animation_track_editor_plugins.cpp b/editor/animation_track_editor_plugins.cpp index 590621816e..a0ce8dd0a6 100644 --- a/editor/animation_track_editor_plugins.cpp +++ b/editor/animation_track_editor_plugins.cpp @@ -1,3 +1,33 @@ +/*************************************************************************/ +/* animation_track_editor_plugins.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + #include "animation_track_editor_plugins.h" #include "editor/audio_stream_preview.h" #include "editor_resource_preview.h" diff --git a/editor/animation_track_editor_plugins.h b/editor/animation_track_editor_plugins.h index 59604412d9..dd8ff7c8c9 100644 --- a/editor/animation_track_editor_plugins.h +++ b/editor/animation_track_editor_plugins.h @@ -1,3 +1,33 @@ +/*************************************************************************/ +/* animation_track_editor_plugins.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + #ifndef ANIMATION_TRACK_EDITOR_PLUGINS_H #define ANIMATION_TRACK_EDITOR_PLUGINS_H diff --git a/editor/audio_stream_preview.cpp b/editor/audio_stream_preview.cpp index 6e6a7d7935..c5759ac076 100644 --- a/editor/audio_stream_preview.cpp +++ b/editor/audio_stream_preview.cpp @@ -1,3 +1,33 @@ +/*************************************************************************/ +/* audio_stream_preview.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + #include "audio_stream_preview.h" ///////////////////// diff --git a/editor/audio_stream_preview.h b/editor/audio_stream_preview.h index cfe1667e9d..1a8f2eaa15 100644 --- a/editor/audio_stream_preview.h +++ b/editor/audio_stream_preview.h @@ -1,7 +1,37 @@ +/*************************************************************************/ +/* audio_stream_preview.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + #ifndef AUDIO_STREAM_PREVIEW_H #define AUDIO_STREAM_PREVIEW_H -#include "os/thread.h" +#include "core/os/thread.h" #include "scene/main/node.h" #include "servers/audio/audio_stream.h" diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp index 2fecf24d7d..79c22f667a 100644 --- a/editor/code_editor.cpp +++ b/editor/code_editor.cpp @@ -30,10 +30,10 @@ #include "code_editor.h" +#include "core/os/keyboard.h" #include "editor/editor_scale.h" #include "editor_node.h" #include "editor_settings.h" -#include "os/keyboard.h" #include "scene/gui/margin_container.h" #include "scene/gui/separator.h" #include "scene/resources/dynamic_font.h" @@ -44,7 +44,7 @@ void GotoLineDialog::popup_find_line(TextEdit *p_edit) { line->set_text(itos(text_editor->cursor_get_line())); line->select_all(); - popup_centered(Size2(180, 80)); + popup_centered(Size2(180, 80) * EDSCALE); line->grab_focus(); } @@ -65,16 +65,20 @@ void GotoLineDialog::ok_pressed() { GotoLineDialog::GotoLineDialog() { set_title(TTR("Go to Line")); + + VBoxContainer *vbc = memnew(VBoxContainer); + vbc->set_anchor_and_margin(MARGIN_LEFT, ANCHOR_BEGIN, 8 * EDSCALE); + vbc->set_anchor_and_margin(MARGIN_TOP, ANCHOR_BEGIN, 8 * EDSCALE); + vbc->set_anchor_and_margin(MARGIN_RIGHT, ANCHOR_END, -8 * EDSCALE); + vbc->set_anchor_and_margin(MARGIN_BOTTOM, ANCHOR_END, -8 * EDSCALE); + add_child(vbc); + Label *l = memnew(Label); l->set_text(TTR("Line Number:")); - l->set_position(Point2(5, 5)); - add_child(l); + vbc->add_child(l); line = memnew(LineEdit); - line->set_anchor(MARGIN_RIGHT, ANCHOR_END); - line->set_begin(Point2(15, 22)); - line->set_end(Point2(-15, 35)); - add_child(line); + vbc->add_child(line); register_text_enter(line); text_editor = NULL; @@ -374,7 +378,7 @@ void FindReplaceBar::_hide_bar() { void FindReplaceBar::_show_search() { show(); - search_text->grab_focus(); + search_text->call_deferred("grab_focus"); if (text_edit->is_selection_active() && !selection_only->is_pressed()) { search_text->set_text(text_edit->get_selection_text()); diff --git a/editor/collada/SCsub b/editor/collada/SCsub index 04c9a827ef..2b1e889fb0 100644 --- a/editor/collada/SCsub +++ b/editor/collada/SCsub @@ -3,5 +3,3 @@ Import('env') env.add_source_files(env.editor_sources, "*.cpp") - -Export('env') diff --git a/editor/collada/collada.h b/editor/collada/collada.h index 7535162f74..b777fa04c2 100644 --- a/editor/collada/collada.h +++ b/editor/collada/collada.h @@ -33,9 +33,9 @@ #ifndef COLLADA_H #define COLLADA_H -#include "io/xml_parser.h" -#include "map.h" -#include "project_settings.h" +#include "core/io/xml_parser.h" +#include "core/map.h" +#include "core/project_settings.h" #include "scene/resources/material.h" class Collada { diff --git a/editor/connections_dialog.cpp b/editor/connections_dialog.cpp index da73a3930a..a1337268ba 100644 --- a/editor/connections_dialog.cpp +++ b/editor/connections_dialog.cpp @@ -30,10 +30,10 @@ #include "connections_dialog.h" +#include "core/print_string.h" #include "editor_node.h" #include "editor_settings.h" #include "plugins/script_editor_plugin.h" -#include "print_string.h" #include "scene/gui/label.h" #include "scene/gui/popup_menu.h" @@ -341,8 +341,7 @@ ConnectDialog::ConnectDialog() { vbc_right->add_margin_child(TTR("Add Extra Call Argument:"), add_bind_hb); - bind_editor = memnew(PropertyEditor); - bind_editor->hide_top_label(); + bind_editor = memnew(EditorInspector); vbc_right->add_margin_child(TTR("Extra Call Arguments:"), bind_editor, true); @@ -433,6 +432,9 @@ void ConnectionsDock::_make_or_edit_connection() { if (add_script_function) { // pick up args here before "it" is deleted by update_tree script_function_args = it->get_metadata(0).operator Dictionary()["args"]; + for (int i = 0; i < cToMake.binds.size(); i++) { + script_function_args.append("extra_arg_" + itos(i)); + } } if (connect_dialog->is_editing()) { @@ -498,7 +500,7 @@ void ConnectionsDock::_disconnect(TreeItem &item) { } /* -Break all conections of currently selected signal. +Break all connections of currently selected signal. Can undo-redo as a single action. */ void ConnectionsDock::_disconnect_all() { @@ -650,8 +652,8 @@ void ConnectionsDock::_handle_signal_menu_option(int option) { _open_connection_dialog(*item); } break; case DISCONNECT_ALL: { - StringName signalName = item->get_metadata(0).operator Dictionary()["name"]; - disconnect_all_dialog->set_text(TTR("Are you sure you want to remove all connections from the \"") + signalName + "\" signal?"); + StringName signal_name = item->get_metadata(0).operator Dictionary()["name"]; + disconnect_all_dialog->set_text(vformat(TTR("Are you sure you want to remove all connections from the \"%s\" signal?"), signal_name)); disconnect_all_dialog->popup_centered(); } break; } diff --git a/editor/connections_dialog.h b/editor/connections_dialog.h index 932ff693e4..c2fd1f1d09 100644 --- a/editor/connections_dialog.h +++ b/editor/connections_dialog.h @@ -35,7 +35,8 @@ #ifndef CONNECTIONS_DIALOG_H #define CONNECTIONS_DIALOG_H -#include "editor/property_editor.h" +#include "core/undo_redo.h" +#include "editor/editor_inspector.h" #include "editor/scene_tree_editor.h" #include "scene/gui/button.h" #include "scene/gui/check_button.h" @@ -44,7 +45,6 @@ #include "scene/gui/menu_button.h" #include "scene/gui/popup.h" #include "scene/gui/tree.h" -#include "undo_redo.h" class PopupMenu; class ConnectDialogBinds; @@ -62,7 +62,7 @@ class ConnectDialog : public ConfirmationDialog { SceneTreeEditor *tree; ConfirmationDialog *error; - PropertyEditor *bind_editor; + EditorInspector *bind_editor; OptionButton *type_list; CheckButton *deferred; CheckButton *oneshot; diff --git a/editor/create_dialog.cpp b/editor/create_dialog.cpp index 8433f4ff7b..eb11aea9cc 100644 --- a/editor/create_dialog.cpp +++ b/editor/create_dialog.cpp @@ -30,12 +30,12 @@ #include "create_dialog.h" -#include "class_db.h" +#include "core/class_db.h" +#include "core/os/keyboard.h" +#include "core/print_string.h" #include "editor_help.h" #include "editor_node.h" #include "editor_settings.h" -#include "os/keyboard.h" -#include "print_string.h" #include "scene/gui/box_container.h" void CreateDialog::popup_create(bool p_dont_clear, bool p_replace_mode) { @@ -55,12 +55,12 @@ void CreateDialog::popup_create(bool p_dont_clear, bool p_replace_mode) { while (!f->eof_reached()) { String l = f->get_line().strip_edges(); + String name = l.split(" ")[0]; - if (l != String()) { - + if (ClassDB::class_exists(name) || ScriptServer::is_global_class(name)) { TreeItem *ti = recent->create_item(root); ti->set_text(0, l); - ti->set_icon(0, _get_editor_icon(l)); + ti->set_icon(0, EditorNode::get_singleton()->get_class_icon(l, base_type)); } } @@ -151,41 +151,6 @@ void CreateDialog::_sbox_input(const Ref<InputEvent> &p_ie) { } } -Ref<Texture> CreateDialog::_get_editor_icon(const String &p_type) const { - - if (has_icon(p_type, "EditorIcons")) { - return get_icon(p_type, "EditorIcons"); - } - - if (ScriptServer::is_global_class(p_type)) { - String icon_path = EditorNode::get_editor_data().script_class_get_icon_path(p_type); - RES icon; - if (FileAccess::exists(icon_path)) { - icon = ResourceLoader::load(icon_path); - } - if (!icon.is_valid()) { - icon = get_icon(ScriptServer::get_global_class_base(p_type), "EditorIcons"); - } - return icon; - } - - const Map<String, Vector<EditorData::CustomType> > &p_map = EditorNode::get_editor_data().get_custom_types(); - for (const Map<String, Vector<EditorData::CustomType> >::Element *E = p_map.front(); E; E = E->next()) { - const Vector<EditorData::CustomType> &ct = E->value(); - for (int i = 0; i < ct.size(); ++i) { - if (ct[i].name == p_type) { - if (ct[i].icon.is_valid()) { - return ct[i].icon; - } else { - return get_icon("Object", "EditorIcons"); - } - } - } - } - - return get_icon("Object", "EditorIcons"); -} - void CreateDialog::add_type(const String &p_type, HashMap<String, TreeItem *> &p_types, TreeItem *p_root, TreeItem **to_select) { if (p_types.has(p_type)) @@ -244,17 +209,20 @@ void CreateDialog::add_type(const String &p_type, HashMap<String, TreeItem *> &p bool is_search_subsequence = search_box->get_text().is_subsequence_ofi(p_type); String to_select_type = *to_select ? (*to_select)->get_text(0) : ""; to_select_type = to_select_type.split(" ")[0]; - bool current_item_is_preffered; + bool current_item_is_preferred; if (cpp_type) { - current_item_is_preffered = ClassDB::is_parent_class(p_type, preferred_search_result_type) && !ClassDB::is_parent_class(to_select_type, preferred_search_result_type); + String cpp_to_select_type = to_select_type; + if (ScriptServer::is_global_class(to_select_type)) + cpp_to_select_type = ScriptServer::get_global_class_base(to_select_type); + current_item_is_preferred = ClassDB::is_parent_class(p_type, preferred_search_result_type) && !ClassDB::is_parent_class(cpp_to_select_type, preferred_search_result_type); } else { - current_item_is_preffered = ed.script_class_is_parent(p_type, preferred_search_result_type) && !ed.script_class_is_parent(to_select_type, preferred_search_result_type); + current_item_is_preferred = ed.script_class_is_parent(p_type, preferred_search_result_type) && !ed.script_class_is_parent(to_select_type, preferred_search_result_type) && search_box->get_text() != to_select_type; } if (*to_select && p_type.length() < (*to_select)->get_text(0).length()) { - current_item_is_preffered = true; + current_item_is_preferred = true; } - if (((!*to_select || current_item_is_preffered) && is_search_subsequence) || search_box->get_text() == p_type) { + if (((!*to_select || current_item_is_preferred) && is_search_subsequence) || search_box->get_text() == p_type) { *to_select = item; } } @@ -274,7 +242,7 @@ void CreateDialog::add_type(const String &p_type, HashMap<String, TreeItem *> &p const String &description = EditorHelp::get_doc_data()->class_list[p_type].brief_description; item->set_tooltip(0, description); - item->set_icon(0, _get_editor_icon(p_type)); + item->set_icon(0, EditorNode::get_singleton()->get_class_icon(p_type, base_type)); p_types[p_type] = item; } @@ -497,7 +465,11 @@ Object *CreateDialog::instance_selected() { if (custom != String()) { if (ScriptServer::is_global_class(custom)) { - return EditorNode::get_editor_data().script_class_instance(custom); + Object *obj = EditorNode::get_editor_data().script_class_instance(custom); + Node *n = Object::cast_to<Node>(obj); + if (n) + n->set_name(custom); + return obj; } return EditorNode::get_editor_data().instance_custom_type(selected->get_text(0), custom); } else { @@ -574,7 +546,7 @@ void CreateDialog::_update_favorite_list() { continue; TreeItem *ti = favorites->create_item(root); ti->set_text(0, l); - ti->set_icon(0, _get_editor_icon(l)); + ti->set_icon(0, EditorNode::get_singleton()->get_class_icon(l, base_type)); } emit_signal("favorites_updated"); } diff --git a/editor/dependency_editor.cpp b/editor/dependency_editor.cpp index 62ae14c988..d64b02a605 100644 --- a/editor/dependency_editor.cpp +++ b/editor/dependency_editor.cpp @@ -30,9 +30,9 @@ #include "dependency_editor.h" +#include "core/io/resource_loader.h" +#include "core/os/file_access.h" #include "editor_node.h" -#include "io/resource_loader.h" -#include "os/file_access.h" #include "scene/gui/margin_container.h" void DependencyEditor::_notification(int p_what) { @@ -198,12 +198,7 @@ void DependencyEditor::_update_list() { } String name = path.get_file(); - Ref<Texture> icon; - if (has_icon(type, "EditorIcons")) { - icon = get_icon(type, "EditorIcons"); - } else { - icon = get_icon("Object", "EditorIcons"); - } + Ref<Texture> icon = EditorNode::get_singleton()->get_class_icon(type); item->set_text(0, name); item->set_icon(0, icon); item->set_metadata(0, type); @@ -346,13 +341,7 @@ void DependencyEditorOwners::_fill_owners(EditorFileSystemDirectory *efsd) { if (!found) continue; - Ref<Texture> icon; - String type = efsd->get_file_type(i); - if (!has_icon(type, "EditorIcons")) { - icon = get_icon("Object", "EditorIcons"); - } else { - icon = get_icon(type, "EditorIcons"); - } + Ref<Texture> icon = EditorNode::get_singleton()->get_class_icon(efsd->get_file_type(i)); owners->add_item(efsd->get_file_path(i), icon); } @@ -460,7 +449,7 @@ void DependencyRemoveDialog::_build_removed_dependency_tree(const Vector<Removed } //List this file under this dependency - Ref<Texture> icon = has_icon(rd.file_type, "EditorIcons") ? get_icon(rd.file_type, "EditorIcons") : get_icon("Object", "EditorIcons"); + Ref<Texture> icon = EditorNode::get_singleton()->get_class_icon(rd.file_type); TreeItem *file_item = owners->create_item(tree_items[rd.dependency]); file_item->set_text(0, rd.file); file_item->set_icon(0, icon); @@ -515,7 +504,7 @@ void DependencyRemoveDialog::ok_pressed() { } if (dirs_to_delete.size() == 0) { - //If we only deleted files we should only need to tell the file system about the files we touched. + // If we only deleted files we should only need to tell the file system about the files we touched. for (int i = 0; i < files_to_delete.size(); ++i) EditorFileSystem::get_singleton()->update_file(files_to_delete[i]); } else { @@ -529,21 +518,25 @@ void DependencyRemoveDialog::ok_pressed() { } } - // if some dirs would be deleted, favorite dirs need to be updated - Vector<String> previous_favorite_dirs = EditorSettings::get_singleton()->get_favorite_dirs(); - Vector<String> new_favorite_dirs; + EditorFileSystem::get_singleton()->scan_changes(); + } - for (int i = 0; i < previous_favorite_dirs.size(); ++i) { - if (dirs_to_delete.find(previous_favorite_dirs[i] + "/") < 0) { - new_favorite_dirs.push_back(previous_favorite_dirs[i]); - } - } + // If some files/dirs would be deleted, favorite dirs need to be updated + Vector<String> previous_favorites = EditorSettings::get_singleton()->get_favorites(); + Vector<String> new_favorites; - if (new_favorite_dirs.size() < previous_favorite_dirs.size()) { - EditorSettings::get_singleton()->set_favorite_dirs(new_favorite_dirs); + for (int i = 0; i < previous_favorites.size(); ++i) { + if (previous_favorites[i].ends_with("/")) { + if (dirs_to_delete.find(previous_favorites[i]) < 0) + new_favorites.push_back(previous_favorites[i]); + } else { + if (files_to_delete.find(previous_favorites[i]) < 0) + new_favorites.push_back(previous_favorites[i]); } + } - EditorFileSystem::get_singleton()->scan_changes(); + if (new_favorites.size() < previous_favorites.size()) { + EditorSettings::get_singleton()->set_favorites(new_favorites); } } @@ -579,12 +572,7 @@ void DependencyErrorDialog::show(const String &p_for_file, const Vector<String> if (report[i].get_slice_count("::") > 0) type = report[i].get_slice("::", 1); - Ref<Texture> icon; - if (!has_icon(type, "EditorIcons")) { - icon = get_icon("Object", "EditorIcons"); - } else { - icon = get_icon(type, "EditorIcons"); - } + Ref<Texture> icon = EditorNode::get_singleton()->get_class_icon(type); TreeItem *ti = files->create_item(root); ti->set_text(0, dep); @@ -687,12 +675,7 @@ bool OrphanResourcesDialog::_fill_owners(EditorFileSystemDirectory *efsd, HashMa String type = efsd->get_file_type(i); - Ref<Texture> icon; - if (has_icon(type, "EditorIcons")) { - icon = get_icon(type, "EditorIcons"); - } else { - icon = get_icon("Object", "EditorIcons"); - } + Ref<Texture> icon = EditorNode::get_singleton()->get_class_icon(type); ti->set_icon(0, icon); int ds = efsd->get_file_deps(i).size(); ti->set_text(1, itos(ds)); diff --git a/editor/doc/SCsub b/editor/doc/SCsub index 04c9a827ef..2b1e889fb0 100644 --- a/editor/doc/SCsub +++ b/editor/doc/SCsub @@ -3,5 +3,3 @@ Import('env') env.add_source_files(env.editor_sources, "*.cpp") - -Export('env') diff --git a/editor/doc/doc_data.cpp b/editor/doc/doc_data.cpp index fe1cf3484e..599f46d6d9 100644 --- a/editor/doc/doc_data.cpp +++ b/editor/doc/doc_data.cpp @@ -30,15 +30,15 @@ #include "doc_data.h" -#include "engine.h" -#include "global_constants.h" -#include "io/compression.h" -#include "io/marshalls.h" -#include "os/dir_access.h" -#include "project_settings.h" +#include "core/engine.h" +#include "core/global_constants.h" +#include "core/io/compression.h" +#include "core/io/marshalls.h" +#include "core/os/dir_access.h" +#include "core/project_settings.h" +#include "core/script_language.h" +#include "core/version.h" #include "scene/resources/theme.h" -#include "script_language.h" -#include "version.h" void DocData::merge_from(const DocData &p_data) { @@ -382,7 +382,11 @@ void DocData::generate(bool p_basic_types) { PropertyInfo arginfo = EV->get().arguments[i]; ArgumentDoc argument; argument.name = arginfo.name; - argument.type = Variant::get_type_name(arginfo.type); + if (arginfo.type == Variant::OBJECT && arginfo.class_name != StringName()) { + argument.type = arginfo.class_name.operator String(); + } else { + argument.type = Variant::get_type_name(arginfo.type); + } signal.arguments.push_back(argument); } @@ -501,7 +505,7 @@ void DocData::generate(bool p_basic_types) { ad.name = arginfo.name; if (arginfo.type == Variant::NIL) - ad.type = "var"; + ad.type = "Variant"; else ad.type = Variant::get_type_name(arginfo.type); @@ -514,7 +518,7 @@ void DocData::generate(bool p_basic_types) { if (mi.return_val.type == Variant::NIL) { if (mi.return_val.name != "") - method.return_type = "var"; + method.return_type = "Variant"; } else { method.return_type = Variant::get_type_name(mi.return_val.type); } diff --git a/editor/doc/doc_data.h b/editor/doc/doc_data.h index c7b70b5fb9..6633c123e6 100644 --- a/editor/doc/doc_data.h +++ b/editor/doc/doc_data.h @@ -31,9 +31,9 @@ #ifndef DOC_DATA_H #define DOC_DATA_H -#include "io/xml_parser.h" -#include "map.h" -#include "variant.h" +#include "core/io/xml_parser.h" +#include "core/map.h" +#include "core/variant.h" class DocData { public: diff --git a/editor/doc/doc_dump.cpp b/editor/doc/doc_dump.cpp index adbe23dcd5..86fd9b436b 100644 --- a/editor/doc/doc_dump.cpp +++ b/editor/doc/doc_dump.cpp @@ -30,9 +30,9 @@ #include "doc_dump.h" -#include "os/file_access.h" +#include "core/os/file_access.h" +#include "core/version.h" #include "scene/main/node.h" -#include "version.h" static void _write_string(FileAccess *f, int p_tablevel, const String &p_string) { @@ -142,7 +142,7 @@ void DocDump::dump(const String &p_file) { if (arginfo.hint == PROPERTY_HINT_RESOURCE_TYPE) type_name = arginfo.hint_string; else if (arginfo.type == Variant::NIL) - type_name = "var"; + type_name = "Variant"; else type_name = Variant::get_type_name(arginfo.type); diff --git a/editor/doc/doc_dump.h b/editor/doc/doc_dump.h index 48cf1a587b..99398b5d96 100644 --- a/editor/doc/doc_dump.h +++ b/editor/doc/doc_dump.h @@ -31,7 +31,7 @@ #ifndef DOC_DUMP_H #define DOC_DUMP_H -#include "class_db.h" +#include "core/class_db.h" class DocDump { public: diff --git a/editor/editor_about.cpp b/editor/editor_about.cpp index e4602f0f94..cdf0e4b829 100644 --- a/editor/editor_about.cpp +++ b/editor/editor_about.cpp @@ -113,7 +113,6 @@ ScrollContainer *EditorAbout::_populate_list(const String &p_name, const List<St EditorAbout::EditorAbout() { set_title(TTR("Thanks from the Godot community!")); - get_ok()->set_text(TTR("OK")); set_hide_on_ok(true); set_resizable(true); diff --git a/editor/editor_asset_installer.cpp b/editor/editor_asset_installer.cpp index d99908a3c3..6af45f26ae 100644 --- a/editor/editor_asset_installer.cpp +++ b/editor/editor_asset_installer.cpp @@ -30,10 +30,10 @@ #include "editor_asset_installer.h" +#include "core/io/zip_io.h" +#include "core/os/dir_access.h" +#include "core/os/file_access.h" #include "editor_node.h" -#include "io/zip_io.h" -#include "os/dir_access.h" -#include "os/file_access.h" void EditorAssetInstaller::_update_subitems(TreeItem *p_item, bool p_check, bool p_first) { diff --git a/editor/editor_audio_buses.cpp b/editor/editor_audio_buses.cpp index 9c775be87e..6cd81626c7 100644 --- a/editor/editor_audio_buses.cpp +++ b/editor/editor_audio_buses.cpp @@ -30,10 +30,10 @@ #include "editor_audio_buses.h" +#include "core/io/resource_saver.h" +#include "core/os/keyboard.h" #include "editor_node.h" #include "filesystem_dock.h" -#include "io/resource_saver.h" -#include "os/keyboard.h" #include "servers/audio_server.h" void EditorAudioBus::_notification(int p_what) { @@ -765,10 +765,7 @@ EditorAudioBus::EditorAudioBus(EditorAudioBuses *p_buses, bool p_is_master) { if (!ClassDB::can_instance(E->get())) continue; - Ref<Texture> icon; - if (has_icon(E->get(), "EditorIcons")) { - icon = get_icon(E->get(), "EditorIcons"); - } + Ref<Texture> icon = EditorNode::get_singleton()->get_class_icon(E->get()); String name = E->get().operator String().replace("AudioEffect", ""); effect_options->add_item(name); effect_options->set_item_metadata(effect_options->get_item_count() - 1, E->get()); diff --git a/editor/editor_autoload_settings.cpp b/editor/editor_autoload_settings.cpp index d12c85861b..1374c8c9aa 100644 --- a/editor/editor_autoload_settings.cpp +++ b/editor/editor_autoload_settings.cpp @@ -30,9 +30,9 @@ #include "editor_autoload_settings.h" +#include "core/global_constants.h" +#include "core/project_settings.h" #include "editor_node.h" -#include "global_constants.h" -#include "project_settings.h" #include "scene/main/viewport.h" #include "scene/resources/packed_scene.h" diff --git a/editor/editor_builders.py b/editor/editor_builders.py index 6c2f9e298e..9e9fe752b4 100644 --- a/editor/editor_builders.py +++ b/editor/editor_builders.py @@ -9,32 +9,6 @@ from platform_methods import subprocess_main from compat import encode_utf8, byte_to_str, open_utf8, escape_string -def make_certs_header(target, source, env): - - src = source[0] - dst = target[0] - f = open(src, "rb") - g = open_utf8(dst, "w") - buf = f.read() - decomp_size = len(buf) - import zlib - buf = zlib.compress(buf) - - g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n") - g.write("#ifndef _CERTS_RAW_H\n") - g.write("#define _CERTS_RAW_H\n") - g.write("static const int _certs_compressed_size = " + str(len(buf)) + ";\n") - g.write("static const int _certs_uncompressed_size = " + str(decomp_size) + ";\n") - g.write("static const unsigned char _certs_compressed[] = {\n") - for i in range(len(buf)): - g.write("\t" + byte_to_str(buf[i]) + ",\n") - g.write("};\n") - g.write("#endif") - - g.close() - f.close() - - def make_doc_header(target, source, env): dst = target[0] @@ -146,267 +120,5 @@ def make_translations_header(target, source, env): g.close() - -def make_authors_header(target, source, env): - - sections = ["Project Founders", "Lead Developer", "Project Manager", "Developers"] - sections_id = ["dev_founders", "dev_lead", "dev_manager", "dev_names"] - - src = source[0] - dst = target[0] - f = open_utf8(src, "r") - g = open_utf8(dst, "w") - - g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n") - g.write("#ifndef _EDITOR_AUTHORS_H\n") - g.write("#define _EDITOR_AUTHORS_H\n") - - current_section = "" - reading = False - - def close_section(): - g.write("\t0\n") - g.write("};\n") - - for line in f: - if reading: - if line.startswith(" "): - g.write("\t\"" + escape_string(line.strip()) + "\",\n") - continue - if line.startswith("## "): - if reading: - close_section() - reading = False - for i in range(len(sections)): - if line.strip().endswith(sections[i]): - current_section = escape_string(sections_id[i]) - reading = True - g.write("static const char *" + current_section + "[] = {\n") - break - - if reading: - close_section() - - g.write("#endif\n") - - g.close() - f.close() - -def make_donors_header(target, source, env): - - sections = ["Platinum sponsors", "Gold sponsors", "Mini sponsors", "Gold donors", "Silver donors", "Bronze donors"] - sections_id = ["donor_s_plat", "donor_s_gold", "donor_s_mini", "donor_gold", "donor_silver", "donor_bronze"] - - src = source[0] - dst = target[0] - f = open_utf8(src, "r") - g = open_utf8(dst, "w") - - g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n") - g.write("#ifndef _EDITOR_DONORS_H\n") - g.write("#define _EDITOR_DONORS_H\n") - - current_section = "" - reading = False - - def close_section(): - g.write("\t0\n") - g.write("};\n") - - for line in f: - if reading >= 0: - if line.startswith(" "): - g.write("\t\"" + escape_string(line.strip()) + "\",\n") - continue - if line.startswith("## "): - if reading: - close_section() - reading = False - for i in range(len(sections)): - if line.strip().endswith(sections[i]): - current_section = escape_string(sections_id[i]) - reading = True - g.write("static const char *" + current_section + "[] = {\n") - break - - if reading: - close_section() - - g.write("#endif\n") - - g.close() - f.close() - - -def make_license_header(target, source, env): - - src_copyright = source[0] - src_license = source[1] - dst = target[0] - f = open_utf8(src_license, "r") - fc = open_utf8(src_copyright, "r") - g = open_utf8(dst, "w") - - g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n") - g.write("#ifndef _EDITOR_LICENSE_H\n") - g.write("#define _EDITOR_LICENSE_H\n") - g.write("static const char *about_license =") - - for line in f: - escaped_string = escape_string(line.strip()) - g.write("\n\t\"" + escaped_string + "\\n\"") - - g.write(";\n") - - tp_current = 0 - tp_file = "" - tp_comment = "" - tp_copyright = "" - tp_license = "" - - tp_licensename = "" - tp_licensebody = "" - - tp = [] - tp_licensetext = [] - for line in fc: - if line.startswith("#"): - continue - - if line.startswith("Files:"): - tp_file = line[6:].strip() - tp_current = 1 - elif line.startswith("Comment:"): - tp_comment = line[8:].strip() - tp_current = 2 - elif line.startswith("Copyright:"): - tp_copyright = line[10:].strip() - tp_current = 3 - elif line.startswith("License:"): - if tp_current != 0: - tp_license = line[8:].strip() - tp_current = 4 - else: - tp_licensename = line[8:].strip() - tp_current = 5 - elif line.startswith(" "): - if tp_current == 1: - tp_file += "\n" + line.strip() - elif tp_current == 3: - tp_copyright += "\n" + line.strip() - elif tp_current == 5: - if line.strip() == ".": - tp_licensebody += "\n" - else: - tp_licensebody += line[1:] - else: - if tp_current != 0: - if tp_current == 5: - tp_licensetext.append([tp_licensename, tp_licensebody]) - - tp_licensename = "" - tp_licensebody = "" - else: - added = False - for i in tp: - if i[0] == tp_comment: - i[1].append([tp_file, tp_copyright, tp_license]) - added = True - break - if not added: - tp.append([tp_comment,[[tp_file, tp_copyright, tp_license]]]) - - tp_file = [] - tp_comment = "" - tp_copyright = [] - tp_license = "" - tp_current = 0 - - tp_licensetext.append([tp_licensename, tp_licensebody]) - - about_thirdparty = "" - about_tp_copyright_count = "" - about_tp_license = "" - about_tp_copyright = "" - about_tp_file = "" - - for i in tp: - about_thirdparty += "\t\"" + i[0] + "\",\n" - about_tp_copyright_count += str(len(i[1])) + ", " - for j in i[1]: - file_body = "" - copyright_body = "" - for k in j[0].split("\n"): - if file_body != "": - file_body += "\\n\"\n" - escaped_string = escape_string(k.strip()) - file_body += "\t\"" + escaped_string - for k in j[1].split("\n"): - if copyright_body != "": - copyright_body += "\\n\"\n" - escaped_string = escape_string(k.strip()) - copyright_body += "\t\"" + escaped_string - - about_tp_file += "\t" + file_body + "\",\n" - about_tp_copyright += "\t" + copyright_body + "\",\n" - about_tp_license += "\t\"" + j[2] + "\",\n" - - about_license_name = "" - about_license_body = "" - - for i in tp_licensetext: - body = "" - for j in i[1].split("\n"): - if body != "": - body += "\\n\"\n" - escaped_string = escape_string(j.strip()) - body += "\t\"" + escaped_string - - about_license_name += "\t\"" + i[0] + "\",\n" - about_license_body += "\t" + body + "\",\n" - - g.write("static const char *about_thirdparty[] = {\n") - g.write(about_thirdparty) - g.write("\t0\n") - g.write("};\n") - g.write("#define THIRDPARTY_COUNT " + str(len(tp)) + "\n") - - g.write("static const int about_tp_copyright_count[] = {\n\t") - g.write(about_tp_copyright_count) - g.write("0\n};\n") - - g.write("static const char *about_tp_file[] = {\n") - g.write(about_tp_file) - g.write("\t0\n") - g.write("};\n") - - g.write("static const char *about_tp_copyright[] = {\n") - g.write(about_tp_copyright) - g.write("\t0\n") - g.write("};\n") - - g.write("static const char *about_tp_license[] = {\n") - g.write(about_tp_license) - g.write("\t0\n") - g.write("};\n") - - g.write("static const char *about_license_name[] = {\n") - g.write(about_license_name) - g.write("\t0\n") - g.write("};\n") - g.write("#define LICENSE_COUNT " + str(len(tp_licensetext)) + "\n") - - g.write("static const char *about_license_body[] = {\n") - g.write(about_license_body) - g.write("\t0\n") - g.write("};\n") - - g.write("#endif\n") - - g.close() - fc.close() - f.close() - - if __name__ == '__main__': subprocess_main(globals()) diff --git a/editor/editor_data.cpp b/editor/editor_data.cpp index 69c120bb3c..9420452da1 100644 --- a/editor/editor_data.cpp +++ b/editor/editor_data.cpp @@ -30,12 +30,12 @@ #include "editor_data.h" +#include "core/io/resource_loader.h" +#include "core/os/dir_access.h" +#include "core/os/file_access.h" +#include "core/project_settings.h" #include "editor_node.h" #include "editor_settings.h" -#include "io/resource_loader.h" -#include "os/dir_access.h" -#include "os/file_access.h" -#include "project_settings.h" #include "scene/resources/packed_scene.h" void EditorHistory::cleanup_history() { @@ -869,7 +869,7 @@ bool EditorData::script_class_is_parent(const String &p_class, const String &p_i return true; } -StringName EditorData::script_class_get_base(const String &p_class) { +StringName EditorData::script_class_get_base(const String &p_class) const { if (!ScriptServer::is_global_class(p_class)) return StringName(); @@ -895,24 +895,48 @@ Object *EditorData::script_class_instance(const String &p_class) { RES script = ResourceLoader::load(ScriptServer::get_global_class_path(p_class)); if (script.is_valid()) obj->set_script(script.get_ref_ptr()); - - RES icon = ResourceLoader::load(script_class_get_icon_path(p_class)); - if (icon.is_valid()) - obj->set_meta("_editor_icon", icon); - return obj; } } return NULL; } +void EditorData::script_class_set_icon_path(const String &p_class, const String &p_icon_path) { + _script_class_icon_paths[p_class] = p_icon_path; +} + +String EditorData::script_class_get_icon_path(const String &p_class) const { + if (!ScriptServer::is_global_class(p_class)) + return String(); + + String current = p_class; + String ret = _script_class_icon_paths[current]; + while (ret.empty()) { + current = script_class_get_base(current); + if (!ScriptServer::is_global_class(current)) + return String(); + ret = _script_class_icon_paths.has(current) ? _script_class_icon_paths[current] : String(); + } + + return ret; +} + +StringName EditorData::script_class_get_name(const String &p_path) const { + return _script_class_file_to_path.has(p_path) ? _script_class_file_to_path[p_path] : StringName(); +} + +void EditorData::script_class_set_name(const String &p_path, const StringName &p_class) { + _script_class_file_to_path[p_path] = p_class; +} + void EditorData::script_class_save_icon_paths() { List<StringName> keys; _script_class_icon_paths.get_key_list(&keys); Dictionary d; for (List<StringName>::Element *E = keys.front(); E; E = E->next()) { - d[E->get()] = _script_class_icon_paths[E->get()]; + if (ScriptServer::is_global_class(E->get())) + d[E->get()] = _script_class_icon_paths[E->get()]; } ProjectSettings::get_singleton()->set("_global_script_class_icons", d); @@ -927,8 +951,11 @@ void EditorData::script_class_load_icon_paths() { d.get_key_list(&keys); for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { - String key = E->get().operator String(); - _script_class_icon_paths[key] = d[key]; + String name = E->get().operator String(); + _script_class_icon_paths[name] = d[name]; + + String path = ScriptServer::get_global_class_path(name); + script_class_set_name(path, name); } } diff --git a/editor/editor_data.h b/editor/editor_data.h index 285769aa78..87a76ee5ba 100644 --- a/editor/editor_data.h +++ b/editor/editor_data.h @@ -31,12 +31,12 @@ #ifndef EDITOR_DATA_H #define EDITOR_DATA_H +#include "core/list.h" +#include "core/pair.h" +#include "core/undo_redo.h" #include "editor/editor_plugin.h" #include "editor/plugins/script_editor_plugin.h" -#include "list.h" -#include "pair.h" #include "scene/resources/texture.h" -#include "undo_redo.h" class EditorHistory { @@ -147,6 +147,7 @@ private: bool _find_updated_instances(Node *p_root, Node *p_node, Set<String> &checked_paths); HashMap<StringName, String> _script_class_icon_paths; + HashMap<String, StringName> _script_class_file_to_path; public: EditorPlugin *get_editor(Object *p_object); @@ -214,10 +215,14 @@ public: void notify_resource_saved(const Ref<Resource> &p_resource); bool script_class_is_parent(const String &p_class, const String &p_inherits); - StringName script_class_get_base(const String &p_class); + StringName script_class_get_base(const String &p_class) const; Object *script_class_instance(const String &p_class); - String script_class_get_icon_path(const String &p_class) const { return _script_class_icon_paths.has(p_class) ? _script_class_icon_paths[p_class] : String(); } - void script_class_set_icon_path(const String &p_class, const String &p_icon_path) { _script_class_icon_paths[p_class] = p_icon_path; } + + StringName script_class_get_name(const String &p_path) const; + void script_class_set_name(const String &p_path, const StringName &p_class); + + String script_class_get_icon_path(const String &p_class) const; + void script_class_set_icon_path(const String &p_class, const String &p_icon_path); void script_class_clear_icon_paths() { _script_class_icon_paths.clear(); } void script_class_save_icon_paths(); void script_class_load_icon_paths(); diff --git a/editor/editor_dir_dialog.cpp b/editor/editor_dir_dialog.cpp index c094b2b559..6f80b6bea4 100644 --- a/editor/editor_dir_dialog.cpp +++ b/editor/editor_dir_dialog.cpp @@ -30,11 +30,11 @@ #include "editor_dir_dialog.h" +#include "core/os/keyboard.h" +#include "core/os/os.h" #include "editor/editor_file_system.h" #include "editor/editor_settings.h" #include "editor_scale.h" -#include "os/keyboard.h" -#include "os/os.h" void EditorDirDialog::_update_dir(TreeItem *p_item, EditorFileSystemDirectory *p_dir, const String &p_select_path) { updating = true; diff --git a/editor/editor_dir_dialog.h b/editor/editor_dir_dialog.h index 7c19e7de38..a9dc7accfe 100644 --- a/editor/editor_dir_dialog.h +++ b/editor/editor_dir_dialog.h @@ -31,8 +31,8 @@ #ifndef EDITOR_DIR_DIALOG_H #define EDITOR_DIR_DIALOG_H +#include "core/os/dir_access.h" #include "editor/editor_file_system.h" -#include "os/dir_access.h" #include "scene/gui/dialogs.h" #include "scene/gui/tree.h" diff --git a/editor/editor_export.cpp b/editor/editor_export.cpp index e46fe96885..455c889224 100644 --- a/editor/editor_export.cpp +++ b/editor/editor_export.cpp @@ -30,20 +30,20 @@ #include "editor_export.h" +#include "core/io/config_file.h" +#include "core/io/resource_loader.h" +#include "core/io/resource_saver.h" +#include "core/io/zip_io.h" +#include "core/os/file_access.h" +#include "core/project_settings.h" +#include "core/script_language.h" +#include "core/version.h" #include "editor/editor_file_system.h" #include "editor/plugins/script_editor_plugin.h" #include "editor_node.h" #include "editor_settings.h" -#include "io/config_file.h" -#include "io/resource_loader.h" -#include "io/resource_saver.h" -#include "io/zip_io.h" -#include "os/file_access.h" -#include "project_settings.h" #include "scene/resources/scene_format_text.h" -#include "script_language.h" #include "thirdparty/misc/md5.h" -#include "version.h" static int _get_pad(int p_alignment, int p_n) { @@ -667,7 +667,7 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> & String remap = F->get(); String feature = remap.get_slice(".", 1); - if (feature == "fallback" || features.has(feature)) { + if (features.has(feature)) { remap_features.insert(feature); } } @@ -1457,7 +1457,6 @@ void EditorExportPlatformPC::resolve_platform_feature_priorities(const Ref<Edito if (p_features.has("bptc")) { if (p_preset->has("texture_format/no_bptc_fallbacks")) { p_features.erase("s3tc"); - p_features.erase("fallback"); } } } diff --git a/editor/editor_export.h b/editor/editor_export.h index b984d66a1b..b4ee5b89e7 100644 --- a/editor/editor_export.h +++ b/editor/editor_export.h @@ -31,16 +31,16 @@ #ifndef EDITOR_EXPORT_H #define EDITOR_EXPORT_H -#include "os/dir_access.h" -#include "resource.h" +#include "core/os/dir_access.h" +#include "core/resource.h" #include "scene/main/node.h" #include "scene/main/timer.h" #include "scene/resources/texture.h" -class EditorProgress; class FileAccess; class EditorExportPlatform; class EditorFileSystemDirectory; +struct EditorProgress; class EditorExportPreset : public Reference { diff --git a/editor/editor_file_dialog.cpp b/editor/editor_file_dialog.cpp index d240f4ed25..38bdba31ea 100644 --- a/editor/editor_file_dialog.cpp +++ b/editor/editor_file_dialog.cpp @@ -29,14 +29,14 @@ /*************************************************************************/ #include "editor_file_dialog.h" +#include "core/os/file_access.h" +#include "core/os/keyboard.h" +#include "core/os/os.h" +#include "core/print_string.h" #include "dependency_editor.h" #include "editor_resource_preview.h" #include "editor_scale.h" #include "editor_settings.h" -#include "os/file_access.h" -#include "os/keyboard.h" -#include "os/os.h" -#include "print_string.h" #include "scene/gui/center_container.h" #include "scene/gui/label.h" #include "scene/gui/margin_container.h" @@ -198,8 +198,22 @@ void EditorFileDialog::update_dir() { dir->set_text(dir_access->get_current_dir()); - // Disable "Open" button only when we in selecting file(s) mode or open dir mode. + // Disable "Open" button only when selecting file(s) mode. get_ok()->set_disabled(_is_open_should_be_disabled()); + switch (mode) { + + case MODE_OPEN_FILE: + case MODE_OPEN_FILES: + get_ok()->set_text(TTR("Open")); + break; + case MODE_OPEN_DIR: + get_ok()->set_text(TTR("Select Current Folder")); + break; + case MODE_OPEN_ANY: + case MODE_SAVE_FILE: + // FIXME: Implement, or refactor to avoid duplication with set_mode + break; + } } void EditorFileDialog::_dir_entered(String p_dir) { @@ -269,7 +283,7 @@ void EditorFileDialog::_post_popup() { set_process_unhandled_input(true); } -void EditorFileDialog::_thumbnail_result(const String &p_path, const Ref<Texture> &p_preview, const Variant &p_udata) { +void EditorFileDialog::_thumbnail_result(const String &p_path, const Ref<Texture> &p_preview, const Ref<Texture> &p_small_preview, const Variant &p_udata) { if (display_mode == DISPLAY_LIST || p_preview.is_null()) return; @@ -284,7 +298,7 @@ void EditorFileDialog::_thumbnail_result(const String &p_path, const Ref<Texture } } -void EditorFileDialog::_thumbnail_done(const String &p_path, const Ref<Texture> &p_preview, const Variant &p_udata) { +void EditorFileDialog::_thumbnail_done(const String &p_path, const Ref<Texture> &p_preview, const Ref<Texture> &p_small_preview, const Variant &p_udata) { set_process(false); preview_waiting = false; @@ -453,6 +467,8 @@ void EditorFileDialog::_item_selected(int p_item) { file->set_text(d["name"]); _request_single_thumbnail(get_current_dir().plus_file(get_current_file())); + } else if (mode == MODE_OPEN_DIR) { + get_ok()->set_text(TTR("Select This Folder")); } get_ok()->set_disabled(_is_open_should_be_disabled()); @@ -492,6 +508,11 @@ void EditorFileDialog::_items_clear_selection() { get_ok()->set_disabled(false); get_ok()->set_text(TTR("Select Current Folder")); break; + + case MODE_OPEN_ANY: + case MODE_SAVE_FILE: + // FIXME: Implement, or refactor to avoid duplication with set_mode + break; } } @@ -637,7 +658,7 @@ bool EditorFileDialog::_is_open_should_be_disabled() { Vector<int> items = item_list->get_selected_items(); if (items.size() == 0) - return true; + return mode != MODE_OPEN_DIR; // In "Open folder" mode, having nothing selected picks the current folder. for (int i = 0; i < items.size(); i++) { @@ -1115,7 +1136,7 @@ void EditorFileDialog::_update_drives() { void EditorFileDialog::_favorite_selected(int p_idx) { - Vector<String> favorited = EditorSettings::get_singleton()->get_favorite_dirs(); + Vector<String> favorited = EditorSettings::get_singleton()->get_favorites(); ERR_FAIL_INDEX(p_idx, favorited.size()); dir_access->change_dir(favorited[p_idx]); @@ -1130,7 +1151,7 @@ void EditorFileDialog::_favorite_move_up() { int current = favorites->get_current(); if (current > 0 && current < favorites->get_item_count()) { - Vector<String> favorited = EditorSettings::get_singleton()->get_favorite_dirs(); + Vector<String> favorited = EditorSettings::get_singleton()->get_favorites(); int a_idx = favorited.find(String(favorites->get_item_metadata(current - 1))); int b_idx = favorited.find(String(favorites->get_item_metadata(current))); @@ -1139,7 +1160,7 @@ void EditorFileDialog::_favorite_move_up() { return; SWAP(favorited.write[a_idx], favorited.write[b_idx]); - EditorSettings::get_singleton()->set_favorite_dirs(favorited); + EditorSettings::get_singleton()->set_favorites(favorited); _update_favorites(); update_file_list(); @@ -1150,7 +1171,7 @@ void EditorFileDialog::_favorite_move_down() { int current = favorites->get_current(); if (current >= 0 && current < favorites->get_item_count() - 1) { - Vector<String> favorited = EditorSettings::get_singleton()->get_favorite_dirs(); + Vector<String> favorited = EditorSettings::get_singleton()->get_favorites(); int a_idx = favorited.find(String(favorites->get_item_metadata(current + 1))); int b_idx = favorited.find(String(favorites->get_item_metadata(current))); @@ -1159,7 +1180,7 @@ void EditorFileDialog::_favorite_move_down() { return; SWAP(favorited.write[a_idx], favorited.write[b_idx]); - EditorSettings::get_singleton()->set_favorite_dirs(favorited); + EditorSettings::get_singleton()->set_favorites(favorited); _update_favorites(); update_file_list(); @@ -1176,7 +1197,7 @@ void EditorFileDialog::_update_favorites() { favorite->set_pressed(false); - Vector<String> favorited = EditorSettings::get_singleton()->get_favorite_dirs(); + Vector<String> favorited = EditorSettings::get_singleton()->get_favorites(); for (int i = 0; i < favorited.size(); i++) { bool cres = favorited[i].begins_with("res://"); if (cres != res) @@ -1206,7 +1227,7 @@ void EditorFileDialog::_favorite_toggled(bool p_toggle) { String cd = get_current_dir(); - Vector<String> favorited = EditorSettings::get_singleton()->get_favorite_dirs(); + Vector<String> favorited = EditorSettings::get_singleton()->get_favorites(); bool found = false; for (int i = 0; i < favorited.size(); i++) { @@ -1228,7 +1249,7 @@ void EditorFileDialog::_favorite_toggled(bool p_toggle) { favorite->set_pressed(true); } - EditorSettings::get_singleton()->set_favorite_dirs(favorited); + EditorSettings::get_singleton()->set_favorites(favorited); _update_favorites(); } diff --git a/editor/editor_file_dialog.h b/editor/editor_file_dialog.h index b1f8f1108c..56cefb9a47 100644 --- a/editor/editor_file_dialog.h +++ b/editor/editor_file_dialog.h @@ -31,7 +31,7 @@ #ifndef EDITORFILEDIALOG_H #define EDITORFILEDIALOG_H -#include "os/dir_access.h" +#include "core/os/dir_access.h" #include "scene/gui/box_container.h" #include "scene/gui/dialogs.h" #include "scene/gui/item_list.h" @@ -190,8 +190,8 @@ private: void _save_to_recent(); //callback function is callback(String p_path,Ref<Texture> preview,Variant udata) preview null if could not load - void _thumbnail_result(const String &p_path, const Ref<Texture> &p_preview, const Variant &p_udata); - void _thumbnail_done(const String &p_path, const Ref<Texture> &p_preview, const Variant &p_udata); + void _thumbnail_result(const String &p_path, const Ref<Texture> &p_preview, const Ref<Texture> &p_small_preview, const Variant &p_udata); + void _thumbnail_done(const String &p_path, const Ref<Texture> &p_preview, const Ref<Texture> &p_small_preview, const Variant &p_udata); void _request_single_thumbnail(const String &p_path); void _unhandled_input(const Ref<InputEvent> &p_event); diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp index 9562a8c63c..ee20d95f25 100644 --- a/editor/editor_file_system.cpp +++ b/editor/editor_file_system.cpp @@ -30,16 +30,16 @@ #include "editor_file_system.h" +#include "core/io/resource_import.h" +#include "core/io/resource_loader.h" +#include "core/io/resource_saver.h" +#include "core/os/file_access.h" +#include "core/os/os.h" +#include "core/project_settings.h" +#include "core/variant_parser.h" #include "editor_node.h" #include "editor_resource_preview.h" #include "editor_settings.h" -#include "io/resource_import.h" -#include "io/resource_loader.h" -#include "io/resource_saver.h" -#include "os/file_access.h" -#include "os/os.h" -#include "project_settings.h" -#include "variant_parser.h" EditorFileSystem *EditorFileSystem::singleton = NULL; @@ -389,7 +389,7 @@ bool EditorFileSystem::_test_for_reimport(const String &p_path, bool p_only_impo memdelete(f); - // Read the md5's from a separate file (so the import parameters aren't dependant on the file version + // Read the md5's from a separate file (so the import parameters aren't dependent on the file version String base_path = ResourceFormatImporter::get_singleton()->get_import_base_path(p_path); FileAccess *md5s = FileAccess::open(base_path + ".md5", FileAccess::READ, &err); if (!md5s) { // No md5's stored for this resource @@ -1358,6 +1358,7 @@ void EditorFileSystem::_scan_script_classes(EditorFileSystemDirectory *p_dir) { } ScriptServer::add_global_class(files[i]->script_class_name, files[i]->script_class_extends, lang, p_dir->get_file_path(i)); EditorNode::get_editor_data().script_class_set_icon_path(files[i]->script_class_name, files[i]->script_class_icon_path); + EditorNode::get_editor_data().script_class_set_name(files[i]->file, files[i]->script_class_name); } for (int i = 0; i < p_dir->get_subdir_count(); i++) { _scan_script_classes(p_dir->get_subdir(i)); @@ -1377,7 +1378,6 @@ void EditorFileSystem::update_script_classes() { ScriptServer::save_global_classes(); EditorNode::get_editor_data().script_class_save_icon_paths(); - emit_signal("script_classes_updated"); } void EditorFileSystem::_queue_update_script_classes() { @@ -1479,12 +1479,16 @@ void EditorFileSystem::_reimport_file(const String &p_file) { cf.instance(); Error err = cf->load(p_file + ".import"); if (err == OK) { - List<String> sk; - cf->get_section_keys("params", &sk); - for (List<String>::Element *E = sk.front(); E; E = E->next()) { - params[E->get()] = cf->get_value("params", E->get()); + if (cf->has_section("params")) { + List<String> sk; + cf->get_section_keys("params", &sk); + for (List<String>::Element *E = sk.front(); E; E = E->next()) { + params[E->get()] = cf->get_value("params", E->get()); + } + } + if (cf->has_section("remap")) { + importer_name = cf->get_value("remap", "importer"); } - importer_name = cf->get_value("remap", "importer"); } } else { @@ -1716,7 +1720,6 @@ void EditorFileSystem::_bind_methods() { ADD_SIGNAL(MethodInfo("filesystem_changed")); ADD_SIGNAL(MethodInfo("sources_changed", PropertyInfo(Variant::BOOL, "exist"))); ADD_SIGNAL(MethodInfo("resources_reimported", PropertyInfo(Variant::POOL_STRING_ARRAY, "resources"))); - ADD_SIGNAL(MethodInfo("script_classes_updated")); } void EditorFileSystem::_update_extensions() { diff --git a/editor/editor_file_system.h b/editor/editor_file_system.h index 75ca79932f..f2f72eddbd 100644 --- a/editor/editor_file_system.h +++ b/editor/editor_file_system.h @@ -31,11 +31,11 @@ #ifndef EDITOR_FILE_SYSTEM_H #define EDITOR_FILE_SYSTEM_H -#include "os/dir_access.h" -#include "os/thread.h" -#include "os/thread_safe.h" +#include "core/os/dir_access.h" +#include "core/os/thread.h" +#include "core/os/thread_safe.h" +#include "core/set.h" #include "scene/main/node.h" -#include "set.h" class FileAccess; struct EditorProgressBG; diff --git a/editor/editor_fonts.cpp b/editor/editor_fonts.cpp index 8e0d92267c..8b1818b595 100644 --- a/editor/editor_fonts.cpp +++ b/editor/editor_fonts.cpp @@ -37,37 +37,11 @@ #include "scene/resources/default_theme/default_theme.h" #include "scene/resources/dynamic_font.h" -static Ref<BitmapFont> make_font(int p_height, int p_ascent, int p_valign, int p_charcount, const int *p_chars, const Ref<Texture> &p_texture) { - - Ref<BitmapFont> font(memnew(BitmapFont)); - font->add_texture(p_texture); - - for (int i = 0; i < p_charcount; i++) { - - const int *c = &p_chars[i * 8]; - - int chr = c[0]; - Rect2 frect; - frect.position.x = c[1]; - frect.position.y = c[2]; - frect.size.x = c[3]; - frect.size.y = c[4]; - Point2 align(c[5], c[6] + p_valign); - int advance = c[7]; - - font->add_char(chr, 0, frect, align, advance); - } - - font->set_height(p_height); - font->set_ascent(p_ascent); - - return font; -} - #define MAKE_FALLBACKS(m_name) \ m_name->add_fallback(FontArabic); \ m_name->add_fallback(FontHebrew); \ m_name->add_fallback(FontThai); \ + m_name->add_fallback(FontHindi); \ m_name->add_fallback(FontJapanese); \ m_name->add_fallback(FontFallback); @@ -204,6 +178,12 @@ void editor_register_fonts(Ref<Theme> p_theme) { FontThai->set_font_ptr(_font_NotoSansThaiUI_Regular, _font_NotoSansThaiUI_Regular_size); FontThai->set_force_autohinter(true); //just looks better..i think? + Ref<DynamicFontData> FontHindi; + FontHindi.instance(); + FontHindi->set_hinting(font_hinting); + FontHindi->set_font_ptr(_font_NotoSansDevanagariUI_Regular, _font_NotoSansDevanagariUI_Regular_size); + FontHindi->set_force_autohinter(true); //just looks better..i think? + /* Hack */ Ref<DynamicFontData> dfmono; diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp index 5a0a49d577..80dd5aa114 100644 --- a/editor/editor_help.cpp +++ b/editor/editor_help.cpp @@ -30,17 +30,17 @@ #include "editor_help.h" +#include "core/os/keyboard.h" #include "doc_data_compressed.gen.h" #include "editor/plugins/script_editor_plugin.h" #include "editor_node.h" #include "editor_settings.h" -#include "os/keyboard.h" #define CONTRIBUTE_URL "http://docs.godotengine.org/en/latest/community/contributing/updating_the_class_reference.html" #define CONTRIBUTE2_URL "https://github.com/godotengine/godot-docs" #define REQUEST_URL "https://github.com/godotengine/godot-docs/issues/new" -void EditorHelpSearch::popup() { +void EditorHelpSearch::popup_dialog() { popup_centered(Size2(700, 600) * EDSCALE); if (search_box->get_text() != "") { @@ -50,15 +50,16 @@ void EditorHelpSearch::popup() { search_box->grab_focus(); } -void EditorHelpSearch::popup(const String &p_term) { +void EditorHelpSearch::popup_dialog(const String &p_term) { popup_centered(Size2(700, 600) * EDSCALE); if (p_term != "") { search_box->set_text(p_term); search_box->select_all(); _update_search(); - } else + } else { search_box->clear(); + } search_box->grab_focus(); } @@ -88,10 +89,8 @@ void EditorHelpSearch::IncrementalSearch::phase1(Map<String, DocData::ClassDoc>: TreeItem *item = search_options->create_item(root); item->set_metadata(0, "class_name:" + E->key()); item->set_text(0, E->key() + " (Class)"); - if (search->has_icon(E->key(), "EditorIcons")) - item->set_icon(0, search->get_icon(E->key(), "EditorIcons")); - else - item->set_icon(0, def_icon); + Ref<Texture> icon = EditorNode::get_singleton()->get_class_icon(E->key(), "Node"); + item->set_icon(0, icon); } } @@ -99,11 +98,7 @@ void EditorHelpSearch::IncrementalSearch::phase2(Map<String, DocData::ClassDoc>: DocData::ClassDoc &c = E->get(); - Ref<Texture> cicon; - if (search->has_icon(E->key(), "EditorIcons")) - cicon = search->get_icon(E->key(), "EditorIcons"); - else - cicon = def_icon; + Ref<Texture> cicon = EditorNode::get_singleton()->get_class_icon(E->key(), "Node"); for (int i = 0; i < c.methods.size(); i++) { if ((term.begins_with(".") && c.methods[i].name.begins_with(term.right(1))) || (term.ends_with("(") && c.methods[i].name.ends_with(term.left(term.length() - 1).strip_edges())) || (term.begins_with(".") && term.ends_with("(") && c.methods[i].name == term.substr(1, term.length() - 2).strip_edges()) || c.methods[i].name.findn(term) != -1) { @@ -225,7 +220,6 @@ bool EditorHelpSearch::IncrementalSearch::work(uint64_t slot) { void EditorHelpSearch::_update_search() { search_options->clear(); - search_options->set_hide_root(true); String term = search_box->get_text(); if (term.length() < 2) @@ -307,6 +301,7 @@ EditorHelpSearch::EditorHelpSearch() { search_box->connect("text_changed", this, "_text_changed"); search_box->connect("gui_input", this, "_sbox_input"); search_options = memnew(Tree); + search_options->set_hide_root(true); vbc->add_margin_child(TTR("Matches:"), search_options, true); get_ok()->set_text(TTR("Open")); get_ok()->set_disabled(true); @@ -343,10 +338,8 @@ void EditorHelpIndex::add_type(const String &p_type, HashMap<String, TreeItem *> item->set_tooltip(0, EditorHelp::get_doc_data()->class_list[p_type].brief_description); item->set_text(0, p_type); - if (has_icon(p_type, "EditorIcons")) { - - item->set_icon(0, get_icon(p_type, "EditorIcons")); - } + Ref<Texture> icon = EditorNode::get_singleton()->get_class_icon(p_type); + item->set_icon(0, icon); p_types[p_type] = item; } @@ -370,7 +363,7 @@ void EditorHelpIndex::select_class(const String &p_class) { class_list->ensure_cursor_is_visible(); } -void EditorHelpIndex::popup() { +void EditorHelpIndex::popup_dialog() { popup_centered(Size2(500, 600) * EDSCALE); @@ -397,6 +390,16 @@ void EditorHelpIndex::_notification(int p_what) { //_update_icons search_box->set_right_icon(get_icon("Search", "EditorIcons")); search_box->set_clear_button_enabled(true); + + bool enable_rl = EditorSettings::get_singleton()->get("docks/scene_tree/draw_relationship_lines"); + Color rl_color = EditorSettings::get_singleton()->get("docks/scene_tree/relationship_line_color"); + + if (enable_rl) { + class_list->add_constant_override("draw_relationship_lines", 1); + class_list->add_color_override("relationship_line_color", rl_color); + } else { + class_list->add_constant_override("draw_relationship_lines", 0); + } } } @@ -410,7 +413,6 @@ void EditorHelpIndex::_update_class_list() { class_list->clear(); tree_item_map.clear(); TreeItem *root = class_list->create_item(); - class_list->set_hide_root(true); String filter = search_box->get_text().strip_edges(); String to_select = ""; @@ -489,10 +491,21 @@ EditorHelpIndex::EditorHelpIndex() { class_list = memnew(Tree); vbc->add_margin_child(TTR("Class List:") + " ", class_list, true); + class_list->set_hide_root(true); class_list->set_v_size_flags(SIZE_EXPAND_FILL); class_list->connect("item_activated", this, "_tree_item_selected"); + bool enable_rl = EditorSettings::get_singleton()->get("docks/scene_tree/draw_relationship_lines"); + Color rl_color = EditorSettings::get_singleton()->get("docks/scene_tree/relationship_line_color"); + + if (enable_rl) { + class_list->add_constant_override("draw_relationship_lines", 1); + class_list->add_color_override("relationship_line_color", rl_color); + } else { + class_list->add_constant_override("draw_relationship_lines", 0); + } + get_ok()->set_text(TTR("Open")); set_title(TTR("Search Classes")); } @@ -740,6 +753,8 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) { } void EditorHelp::_update_doc() { + if (!doc->class_list.has(edited_class)) + return; scroll_locked = true; @@ -756,6 +771,7 @@ void EditorHelp::_update_doc() { Ref<Font> doc_code_font = get_font("doc_source", "EditorFonts"); String link_color_text = title_color.to_html(false); + // Class name section_line.push_back(Pair<String, int>(TTR("Top"), 0)); class_desc->push_font(doc_title_font); class_desc->push_color(title_color); @@ -767,18 +783,18 @@ void EditorHelp::_update_doc() { class_desc->pop(); class_desc->add_newline(); + // Inheritance tree + + // Ascendents if (cd.inherits != "") { class_desc->push_color(title_color); - class_desc->push_font(doc_title_font); + class_desc->push_font(doc_font); class_desc->add_text(TTR("Inherits:") + " "); class_desc->pop(); - class_desc->pop(); String inherits = cd.inherits; - class_desc->push_font(doc_font); - while (inherits != "") { _add_type(inherits); @@ -793,6 +809,7 @@ void EditorHelp::_update_doc() { class_desc->add_newline(); } + // Descendents if (ClassDB::class_exists(cd.name)) { bool found = false; @@ -804,13 +821,10 @@ void EditorHelp::_update_doc() { if (!found) { class_desc->push_color(title_color); - class_desc->push_font(doc_title_font); + class_desc->push_font(doc_font); class_desc->add_text(TTR("Inherited by:") + " "); class_desc->pop(); - class_desc->pop(); - found = true; - class_desc->push_font(doc_font); } if (prev) { @@ -833,6 +847,7 @@ void EditorHelp::_update_doc() { class_desc->add_newline(); class_desc->add_newline(); + // Brief description if (cd.brief_description != "") { class_desc->push_color(title_color); @@ -854,15 +869,16 @@ void EditorHelp::_update_doc() { class_desc->add_newline(); } + // Properties overview Set<String> skip_methods; bool property_descr = false; if (cd.properties.size()) { - section_line.push_back(Pair<String, int>(TTR("Members"), class_desc->get_line_count() - 2)); + section_line.push_back(Pair<String, int>(TTR("Properties"), class_desc->get_line_count() - 2)); class_desc->push_color(title_color); class_desc->push_font(doc_title_font); - class_desc->add_text(TTR("Members:")); + class_desc->add_text(TTR("Properties:")); class_desc->pop(); class_desc->pop(); @@ -920,6 +936,7 @@ void EditorHelp::_update_doc() { class_desc->add_newline(); } + // Methods overview bool method_descr = false; bool sort_methods = EditorSettings::get_singleton()->get("text_editor/help/sort_functions_alphabetically"); @@ -936,10 +953,10 @@ void EditorHelp::_update_doc() { if (sort_methods) methods.sort(); - section_line.push_back(Pair<String, int>(TTR("Public Methods"), class_desc->get_line_count() - 2)); + section_line.push_back(Pair<String, int>(TTR("Methods"), class_desc->get_line_count() - 2)); class_desc->push_color(title_color); class_desc->push_font(doc_title_font); - class_desc->add_text(TTR("Public Methods:")); + class_desc->add_text(TTR("Methods:")); class_desc->pop(); class_desc->pop(); @@ -1004,22 +1021,20 @@ void EditorHelp::_update_doc() { class_desc->add_newline(); } + // Theme properties if (cd.theme_properties.size()) { - section_line.push_back(Pair<String, int>(TTR("GUI Theme Items"), class_desc->get_line_count() - 2)); + section_line.push_back(Pair<String, int>(TTR("Theme Properties"), class_desc->get_line_count() - 2)); class_desc->push_color(title_color); class_desc->push_font(doc_title_font); - class_desc->add_text(TTR("GUI Theme Items:")); + class_desc->add_text(TTR("Theme Properties:")); class_desc->pop(); class_desc->pop(); - // class_desc->add_newline(); class_desc->push_indent(1); class_desc->push_table(2); class_desc->set_table_column_expand(1, 1); - //class_desc->add_newline(); - for (int i = 0; i < cd.theme_properties.size(); i++) { theme_property_line[cd.theme_properties[i].name] = class_desc->get_line_count() - 2; //gets overridden if description @@ -1056,6 +1071,7 @@ void EditorHelp::_update_doc() { class_desc->add_newline(); } + // Signals if (cd.signals.size()) { if (sort_methods) { @@ -1124,6 +1140,7 @@ void EditorHelp::_update_doc() { class_desc->add_newline(); } + // Constants and enums if (cd.constants.size()) { Map<String, Vector<DocData::ConstantDoc> > enums; @@ -1143,6 +1160,7 @@ void EditorHelp::_update_doc() { } } + // Enums if (enums.size()) { section_line.push_back(Pair<String, int>(TTR("Enumerations"), class_desc->get_line_count() - 2)); @@ -1225,6 +1243,7 @@ void EditorHelp::_update_doc() { class_desc->add_newline(); } + // Constants if (constants.size()) { section_line.push_back(Pair<String, int>(TTR("Constants"), class_desc->get_line_count() - 2)); @@ -1283,13 +1302,14 @@ void EditorHelp::_update_doc() { } } + // Class description if (cd.description != "") { - section_line.push_back(Pair<String, int>(TTR("Description"), class_desc->get_line_count() - 2)); + section_line.push_back(Pair<String, int>(TTR("Class Description"), class_desc->get_line_count() - 2)); description_line = class_desc->get_line_count() - 2; class_desc->push_color(title_color); class_desc->push_font(doc_title_font); - class_desc->add_text(TTR("Description:")); + class_desc->add_text(TTR("Class Description:")); class_desc->pop(); class_desc->pop(); @@ -1306,8 +1326,8 @@ void EditorHelp::_update_doc() { class_desc->add_newline(); } + // Online tutorials { - class_desc->push_color(title_color); class_desc->push_font(doc_title_font); class_desc->add_text(TTR("Online Tutorials:")); @@ -1345,12 +1365,14 @@ void EditorHelp::_update_doc() { class_desc->add_newline(); class_desc->add_newline(); } + + // Property descriptions if (property_descr) { - section_line.push_back(Pair<String, int>(TTR("Properties"), class_desc->get_line_count() - 2)); + section_line.push_back(Pair<String, int>(TTR("Property Descriptions"), class_desc->get_line_count() - 2)); class_desc->push_color(title_color); class_desc->push_font(doc_title_font); - class_desc->add_text(TTR("Property Description:")); + class_desc->add_text(TTR("Property Descriptions:")); class_desc->pop(); class_desc->pop(); @@ -1438,12 +1460,13 @@ void EditorHelp::_update_doc() { } } + // Method descriptions if (method_descr) { - section_line.push_back(Pair<String, int>(TTR("Methods"), class_desc->get_line_count() - 2)); + section_line.push_back(Pair<String, int>(TTR("Method Descriptions"), class_desc->get_line_count() - 2)); class_desc->push_color(title_color); class_desc->push_font(doc_title_font); - class_desc->add_text(TTR("Method Description:")); + class_desc->add_text(TTR("Method Descriptions:")); class_desc->pop(); class_desc->pop(); diff --git a/editor/editor_help.h b/editor/editor_help.h index ad81a39945..25db68b42d 100644 --- a/editor/editor_help.h +++ b/editor/editor_help.h @@ -92,8 +92,8 @@ protected: static void _bind_methods(); public: - void popup(); - void popup(const String &p_term); + void popup_dialog(); + void popup_dialog(const String &p_term); EditorHelpSearch(); }; @@ -120,7 +120,7 @@ protected: public: void select_class(const String &p_class); - void popup(); + void popup_dialog(); EditorHelpIndex(); }; diff --git a/editor/editor_initialize_ssl.cpp b/editor/editor_initialize_ssl.cpp deleted file mode 100644 index aedbfb7bd7..0000000000 --- a/editor/editor_initialize_ssl.cpp +++ /dev/null @@ -1,48 +0,0 @@ -/*************************************************************************/ -/* editor_initialize_ssl.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "editor_initialize_ssl.h" - -#include "certs_compressed.gen.h" -#include "io/compression.h" -#include "io/stream_peer_ssl.h" - -void editor_initialize_certificates() { - - PoolByteArray data; - data.resize(_certs_uncompressed_size + 1); - { - PoolByteArray::Write w = data.write(); - Compression::decompress(w.ptr(), _certs_uncompressed_size, _certs_compressed, _certs_compressed_size, Compression::MODE_DEFLATE); - w[_certs_uncompressed_size] = 0; //make sure it ends at zero - } - - StreamPeerSSL::load_certs_from_memory(data); -} diff --git a/editor/editor_initialize_ssl.h b/editor/editor_initialize_ssl.h deleted file mode 100644 index 71d16b8c53..0000000000 --- a/editor/editor_initialize_ssl.h +++ /dev/null @@ -1,36 +0,0 @@ -/*************************************************************************/ -/* editor_initialize_ssl.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef EDITOR_INITIALIZE_SSL_H -#define EDITOR_INITIALIZE_SSL_H - -void editor_initialize_certificates(); - -#endif // EDITOR_INITIALIZE_SSL_H diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index 852e1930d2..2c4168f1a0 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -36,10 +36,6 @@ #include "multi_node_edit.h" #include "scene/resources/packed_scene.h" -// TODO: -// arrays and dictionary -// replace property editor in sectionedpropertyeditor - Size2 EditorProperty::get_minimum_size() const { Size2 ms; @@ -268,11 +264,6 @@ void EditorProperty::_notification(int p_what) { } else { keying_rect = Rect2(); } - - //int vs = get_constant("vseparation", "Tree"); - Color guide_color = get_color("guide_color", "Tree"); - int vs_height = get_size().height; // vs / 2; - // draw_line(Point2(0, vs_height), Point2(get_size().width, vs_height), guide_color); } } @@ -1138,7 +1129,6 @@ void EditorInspectorSection::_gui_input(const Ref<InputEvent> &p_event) { return; #ifdef TOOLS_ENABLED - Ref<InputEventMouseButton> mb = p_event; if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) { @@ -1167,7 +1157,6 @@ void EditorInspectorSection::unfold() { _test_unfold(); #ifdef TOOLS_ENABLED - object->editor_set_section_unfold(section, true); vbox->show(); update(); @@ -1180,8 +1169,8 @@ void EditorInspectorSection::fold() { if (!vbox_added) return; //kinda pointless -#ifdef TOOLS_ENABLED +#ifdef TOOLS_ENABLED object->editor_set_section_unfold(section, false); vbox->hide(); update(); @@ -1202,7 +1191,6 @@ EditorInspectorSection::EditorInspectorSection() { foldable = false; vbox = memnew(VBoxContainer); vbox_added = false; - //add_child(vbox); } EditorInspectorSection::~EditorInspectorSection() { @@ -1427,10 +1415,7 @@ void EditorInspector::update_tree() { category_vbox = NULL; //reset String type = p.name; - if (has_icon(type, "EditorIcons")) - category->icon = get_icon(type, "EditorIcons"); - else - category->icon = get_icon("Object", "EditorIcons"); + category->icon = EditorNode::get_singleton()->get_class_icon(type, "Object"); category->label = type; category->bg_color = get_color("prop_category", "Editor"); @@ -1461,6 +1446,9 @@ void EditorInspector::update_tree() { } else if (!(p.usage & PROPERTY_USAGE_EDITOR)) continue; + if (p.usage & PROPERTY_USAGE_HIGH_END_GFX && VS::get_singleton()->is_low_end()) + continue; //do not show this property in low end gfx + if (p.name == "script" && (hide_script || bool(object->call("_hide_script_from_inspector")))) { continue; } @@ -1607,12 +1595,6 @@ void EditorInspector::update_tree() { doc_hint = descr; } -#if 0 - if (p.name == selected_property) { - - item->select(1); - } -#endif for (List<Ref<EditorInspectorPlugin> >::Element *E = valid_plugins.front(); E; E = E->next()) { Ref<EditorInspectorPlugin> ped = E->get(); bool exclusive = ped->parse_property(object, p.type, p.name, p.hint, p.hint_string, p.usage); @@ -1752,7 +1734,7 @@ void EditorInspector::edit(Object *p_object) { if (object) { update_scroll_request = 0; //reset if (scroll_cache.has(object->get_instance_id())) { //if exists, set something else - update_scroll_request = scroll_cache[object->get_instance_id()]; //done this way because wait until full size is accomodated + update_scroll_request = scroll_cache[object->get_instance_id()]; //done this way because wait until full size is accommodated } object->add_change_receptor(this); update_tree(); @@ -1812,12 +1794,6 @@ void EditorInspector::_filter_changed(const String &p_text) { update_tree(); } -void EditorInspector::set_subsection_selectable(bool p_selectable) { -} - -void EditorInspector::set_property_selectable(bool p_selectable) { -} - void EditorInspector::set_use_folding(bool p_enable) { use_folding = p_enable; update_tree(); @@ -2005,7 +1981,7 @@ void EditorInspector::_property_keyed(const String &p_path) { if (!object) return; - emit_signal("property_keyed", p_path, object->get(p_path), false); //second param is deprecated + emit_signal("property_keyed", p_path, object->get(p_path), true); //second param is deprecated } void EditorInspector::_property_keyed_with_value(const String &p_path, const Variant &p_value) { diff --git a/editor/editor_inspector.h b/editor/editor_inspector.h index ebe2124a40..dccbdb9a73 100644 --- a/editor/editor_inspector.h +++ b/editor/editor_inspector.h @@ -349,9 +349,6 @@ public: void set_use_filter(bool p_use); void register_text_enter(Node *p_line_edit); - void set_subsection_selectable(bool p_selectable); - void set_property_selectable(bool p_selectable); - void set_use_folding(bool p_enable); bool is_using_folding(); diff --git a/editor/editor_log.cpp b/editor/editor_log.cpp index b3ec717d85..5f5c46f4a7 100644 --- a/editor/editor_log.cpp +++ b/editor/editor_log.cpp @@ -31,10 +31,10 @@ #include "editor_log.h" #include "core/os/keyboard.h" +#include "core/version.h" #include "editor_node.h" #include "scene/gui/center_container.h" #include "scene/resources/dynamic_font.h" -#include "version.h" void EditorLog::_error_handler(void *p_self, const char *p_func, const char *p_file, int p_line, const char *p_error, const char *p_errorexp, ErrorHandlerType p_type) { @@ -49,11 +49,6 @@ void EditorLog::_error_handler(void *p_self, const char *p_func, const char *p_f err_str = String(p_file) + ":" + itos(p_line) + " - " + String(p_error); } - /* - if (!self->is_visible_in_tree()) - self->emit_signal("show_request"); - */ - if (p_type == ERR_HANDLER_WARNING) { self->add_message(err_str, MSG_TYPE_WARNING); } else { @@ -76,17 +71,6 @@ void EditorLog::_notification(int p_what) { } } } - - /*if (p_what==NOTIFICATION_DRAW) { - - RID ci = get_canvas_item(); - get_stylebox("panel","PopupMenu")->draw(ci,Rect2(Point2(),get_size())); - int top_ofs = 20; - int border_ofs=4; - Ref<StyleBox> style = get_stylebox("normal","TextEdit"); - - style->draw(ci,Rect2( Point2(border_ofs,top_ofs),get_size()-Size2(border_ofs*2,top_ofs+border_ofs))); - }*/ } void EditorLog::_clear_request() { @@ -105,6 +89,8 @@ void EditorLog::add_message(const String &p_msg, MessageType p_type) { bool restore = p_type != MSG_TYPE_STD; switch (p_type) { + case MSG_TYPE_STD: { + } break; case MSG_TYPE_ERROR: { log->push_color(get_color("error_color", "Editor")); Ref<Texture> icon = get_icon("Error", "EditorIcons"); @@ -122,7 +108,6 @@ void EditorLog::add_message(const String &p_msg, MessageType p_type) { } log->add_text(p_msg); - //button->set_text(p_msg); if (restore) log->pop(); @@ -132,21 +117,6 @@ void EditorLog::set_tool_button(ToolButton *p_tool_button) { tool_button = p_tool_button; } -/* -void EditorLog::_dragged(const Point2& p_ofs) { - - int ofs = ec->get_minsize().height; - ofs = ofs-p_ofs.y; - if (ofs<50) - ofs=50; - if (ofs>300) - ofs=300; - ec->set_minsize(Size2(ec->get_minsize().width,ofs)); - minimum_size_changed(); - -} -*/ - void EditorLog::_undo_redo_cbk(void *p_self, const String &p_name) { EditorLog *self = (EditorLog *)p_self; @@ -156,7 +126,6 @@ void EditorLog::_undo_redo_cbk(void *p_self, const String &p_name) { void EditorLog::_bind_methods() { ClassDB::bind_method(D_METHOD("_clear_request"), &EditorLog::_clear_request); - //ClassDB::bind_method(D_METHOD("_dragged"),&EditorLog::_dragged ); ADD_SIGNAL(MethodInfo("clear_request")); } @@ -187,7 +156,6 @@ EditorLog::EditorLog() { log->set_h_size_flags(SIZE_EXPAND_FILL); vb->add_child(log); add_message(VERSION_FULL_NAME " (c) 2007-2018 Juan Linietsky, Ariel Manzur & Godot Contributors."); - //log->add_text("Initialization Complete.\n"); //because it looks cool. eh.errfunc = _error_handler; eh.userdata = this; diff --git a/editor/editor_log.h b/editor/editor_log.h index 8d0310d914..78a5671d29 100644 --- a/editor/editor_log.h +++ b/editor/editor_log.h @@ -36,7 +36,7 @@ #include "scene/gui/rich_text_label.h" #include "scene/gui/texture_button.h" //#include "scene/gui/empty_control.h" -#include "os/thread.h" +#include "core/os/thread.h" #include "pane_drag.h" #include "scene/gui/box_container.h" #include "scene/gui/panel_container.h" diff --git a/editor/editor_name_dialog.cpp b/editor/editor_name_dialog.cpp index bacb288273..1ef61802c4 100644 --- a/editor/editor_name_dialog.cpp +++ b/editor/editor_name_dialog.cpp @@ -30,8 +30,8 @@ #include "editor_name_dialog.h" -#include "class_db.h" -#include "os/keyboard.h" +#include "core/class_db.h" +#include "core/os/keyboard.h" void EditorNameDialog::_line_gui_input(const Ref<InputEvent> &p_event) { diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 353dce5b20..790e38afca 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -36,7 +36,6 @@ #include "core/io/resource_loader.h" #include "core/io/resource_saver.h" #include "core/io/stream_peer_ssl.h" -#include "core/io/zip_io.h" #include "core/message_queue.h" #include "core/os/file_access.h" #include "core/os/input.h" @@ -54,7 +53,6 @@ #include "editor/editor_audio_buses.h" #include "editor/editor_file_system.h" #include "editor/editor_help.h" -#include "editor/editor_initialize_ssl.h" #include "editor/editor_properties.h" #include "editor/editor_settings.h" #include "editor/editor_themes.h" @@ -141,12 +139,7 @@ void EditorNode::_update_scene_tabs() { String type = editor_data.get_scene_type(i); Ref<Texture> icon; if (type != String()) { - - if (!gui_base->has_icon(type, "EditorIcons")) { - type = "Node"; - } - - icon = gui_base->get_icon(type, "EditorIcons"); + icon = get_class_icon(type, "Node"); } int current = editor_data.get_edited_scene(); @@ -1174,6 +1167,16 @@ void EditorNode::_dialog_action(String p_file) { int scene_idx = (current_option == FILE_SAVE_SCENE || current_option == FILE_SAVE_AS_SCENE) ? -1 : tab_closing; if (file->get_mode() == EditorFileDialog::MODE_SAVE_FILE) { + bool same_open_scene = false; + for (int i = 0; i < editor_data.get_edited_scene_count(); i++) { + if (editor_data.get_scene_path(i) == p_file && i != scene_idx) + same_open_scene = true; + } + + if (same_open_scene) { + show_warning(TTR("Can't overwrite scene that is still open!")); + return; + } _save_default_environment(); _save_scene_with_preview(p_file, scene_idx); @@ -1735,13 +1738,13 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { } break; case FILE_QUICK_OPEN_SCENE: { - quick_open->popup("PackedScene", true); + quick_open->popup_dialog("PackedScene", true); quick_open->set_title(TTR("Quick Open Scene...")); } break; case FILE_QUICK_OPEN_SCRIPT: { - quick_open->popup("Script", true); + quick_open->popup_dialog("Script", true); quick_open->set_title(TTR("Quick Open Script...")); } break; @@ -1999,7 +2002,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { case RUN_PLAY_CUSTOM_SCENE: { if (run_custom_filename.empty() || editor_run.get_status() == EditorRun::STATUS_STOP) { _menu_option_confirm(RUN_STOP, true); - quick_run->popup("PackedScene", true); + quick_run->popup_dialog("PackedScene", true); quick_run->set_title(TTR("Quick Run Scene...")); play_custom_scene_button->set_pressed(false); } else { @@ -2035,6 +2038,14 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { emit_signal("stop_pressed"); } break; + + case FILE_SHOW_IN_FILESYSTEM: { + String path = editor_data.get_scene_path(editor_data.get_edited_scene()); + if (path != String()) { + filesystem_dock->navigate_to_path(path); + } + } break; + case RUN_PLAY_SCENE: { _save_default_environment(); @@ -2068,7 +2079,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { } break; case RUN_PROJECT_DATA_FOLDER: { - OS::get_singleton()->shell_open(OS::get_singleton()->get_user_data_dir()); + OS::get_singleton()->shell_open(String("file://") + OS::get_singleton()->get_user_data_dir()); } break; case FILE_QUIT: case RUN_PROJECT_MANAGER: { @@ -2204,11 +2215,11 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { } break; case SETTINGS_EDITOR_DATA_FOLDER: { - OS::get_singleton()->shell_open(EditorSettings::get_singleton()->get_data_dir()); + OS::get_singleton()->shell_open(String("file://") + EditorSettings::get_singleton()->get_data_dir()); } break; case SETTINGS_EDITOR_CONFIG_FOLDER: { - OS::get_singleton()->shell_open(EditorSettings::get_singleton()->get_settings_dir()); + OS::get_singleton()->shell_open(String("file://") + EditorSettings::get_singleton()->get_settings_dir()); } break; case SETTINGS_MANAGE_EXPORT_TEMPLATES: { @@ -2747,6 +2758,8 @@ void EditorNode::set_current_scene(int p_idx) { Dictionary state = editor_data.restore_edited_scene_state(editor_selection, &editor_history); _edit_current(); + _update_title(); + call_deferred("_set_main_scene_state", state, get_edited_scene()); //do after everything else is done setting up } @@ -3114,6 +3127,86 @@ void EditorNode::stop_child_process() { _menu_option_confirm(RUN_STOP, false); } +Ref<Texture> EditorNode::get_object_icon(const Object *p_object, const String &p_fallback) const { + ERR_FAIL_COND_V(!p_object || !gui_base, NULL); + + Ref<Script> script = p_object->get_script(); + if (script.is_null() && p_object->is_class("Script")) { + script = p_object; + } + + StringName name; + String icon_path; + if (script.is_valid()) { + name = EditorNode::get_editor_data().script_class_get_name(script->get_path()); + icon_path = EditorNode::get_editor_data().script_class_get_icon_path(name); + name = script->get_instance_base_type(); + } + + if (gui_base->has_icon(p_object->get_class(), "EditorIcons")) + return gui_base->get_icon(p_object->get_class(), "EditorIcons"); + + if (icon_path.length()) + return ResourceLoader::load(icon_path); + + if (p_object->has_meta("_editor_icon")) + return p_object->get_meta("_editor_icon"); + + if (name != StringName()) { + const Map<String, Vector<EditorData::CustomType> > &p_map = EditorNode::get_editor_data().get_custom_types(); + for (const Map<String, Vector<EditorData::CustomType> >::Element *E = p_map.front(); E; E = E->next()) { + const Vector<EditorData::CustomType> &ct = E->value(); + for (int i = 0; i < ct.size(); ++i) { + if (ct[i].name == name && ct[i].icon.is_valid()) { + return ct[i].icon; + } + } + } + } + + if (p_fallback.length()) + return gui_base->get_icon(p_fallback, "EditorIcons"); + + return NULL; +} + +Ref<Texture> EditorNode::get_class_icon(const String &p_class, const String &p_fallback) const { + ERR_FAIL_COND_V(p_class.empty(), NULL); + + if (gui_base->has_icon(p_class, "EditorIcons")) { + return gui_base->get_icon(p_class, "EditorIcons"); + } + + if (ScriptServer::is_global_class(p_class)) { + String icon_path = EditorNode::get_editor_data().script_class_get_icon_path(p_class); + RES icon; + if (FileAccess::exists(icon_path)) { + icon = ResourceLoader::load(icon_path); + } + if (!icon.is_valid()) { + icon = gui_base->get_icon(ScriptServer::get_global_class_base(p_class), "EditorIcons"); + } + return icon; + } + + const Map<String, Vector<EditorData::CustomType> > &p_map = EditorNode::get_editor_data().get_custom_types(); + for (const Map<String, Vector<EditorData::CustomType> >::Element *E = p_map.front(); E; E = E->next()) { + const Vector<EditorData::CustomType> &ct = E->value(); + for (int i = 0; i < ct.size(); ++i) { + if (ct[i].name == p_class) { + if (ct[i].icon.is_valid()) { + return ct[i].icon; + } + } + } + } + + if (p_fallback.length() && gui_base->has_icon(p_fallback, "EditorIcons")) + return gui_base->get_icon(p_fallback, "EditorIcons"); + + return NULL; +} + void EditorNode::progress_add_task(const String &p_task, const String &p_label, int p_steps, bool p_can_cancel) { singleton->progress_dialog->add_task(p_task, p_label, p_steps, p_can_cancel); @@ -3271,19 +3364,12 @@ void EditorNode::_dock_select_input(const Ref<InputEvent> &p_input) { dock_slot[nrect]->show(); dock_select->update(); - VSplitContainer *splits[DOCK_SLOT_MAX / 2] = { - left_l_vsplit, - left_r_vsplit, - right_l_vsplit, - right_r_vsplit, - }; - - for (int i = 0; i < 4; i++) { + for (int i = 0; i < vsplits.size(); i++) { bool in_use = dock_slot[i * 2 + 0]->get_tab_count() || dock_slot[i * 2 + 1]->get_tab_count(); if (in_use) - splits[i]->show(); + vsplits[i]->show(); else - splits[i]->hide(); + vsplits[i]->hide(); } if (right_l_vsplit->is_visible() || right_r_vsplit->is_visible()) @@ -3455,30 +3541,16 @@ void EditorNode::_save_docks_to_config(Ref<ConfigFile> p_layout, const String &p p_layout->set_value(p_section, "dock_filesystem_split", filesystem_dock->get_split_offset()); - VSplitContainer *splits[DOCK_SLOT_MAX / 2] = { - left_l_vsplit, - left_r_vsplit, - right_l_vsplit, - right_r_vsplit, - }; + for (int i = 0; i < vsplits.size(); i++) { - for (int i = 0; i < DOCK_SLOT_MAX / 2; i++) { - - if (splits[i]->is_visible_in_tree()) { - p_layout->set_value(p_section, "dock_split_" + itos(i + 1), splits[i]->get_split_offset()); + if (vsplits[i]->is_visible_in_tree()) { + p_layout->set_value(p_section, "dock_split_" + itos(i + 1), vsplits[i]->get_split_offset()); } } - HSplitContainer *h_splits[4] = { - left_l_hsplit, - left_r_hsplit, - main_hsplit, - right_hsplit, - }; - - for (int i = 0; i < 4; i++) { + for (int i = 0; i < hsplits.size(); i++) { - p_layout->set_value(p_section, "dock_hsplit_" + itos(i + 1), h_splits[i]->get_split_offset()); + p_layout->set_value(p_section, "dock_hsplit_" + itos(i + 1), hsplits[i]->get_split_offset()); } } @@ -3524,21 +3596,14 @@ void EditorNode::_load_docks() { void EditorNode::_update_dock_slots_visibility() { - VSplitContainer *splits[DOCK_SLOT_MAX / 2] = { - left_l_vsplit, - left_r_vsplit, - right_l_vsplit, - right_r_vsplit, - }; - if (!docks_visible) { for (int i = 0; i < DOCK_SLOT_MAX; i++) { dock_slot[i]->hide(); } - for (int i = 0; i < DOCK_SLOT_MAX / 2; i++) { - splits[i]->hide(); + for (int i = 0; i < vsplits.size(); i++) { + vsplits[i]->hide(); } right_hsplit->hide(); @@ -3552,12 +3617,12 @@ void EditorNode::_update_dock_slots_visibility() { dock_slot[i]->hide(); } - for (int i = 0; i < DOCK_SLOT_MAX / 2; i++) { + for (int i = 0; i < vsplits.size(); i++) { bool in_use = dock_slot[i * 2 + 0]->get_tab_count() || dock_slot[i * 2 + 1]->get_tab_count(); if (in_use) - splits[i]->show(); + vsplits[i]->show(); else - splits[i]->hide(); + vsplits[i]->hide(); } for (int i = 0; i < DOCK_SLOT_MAX; i++) { @@ -3577,13 +3642,7 @@ void EditorNode::_update_dock_slots_visibility() { void EditorNode::_dock_tab_changed(int p_tab) { - // update visibility but dont set current tab - VSplitContainer *splits[DOCK_SLOT_MAX / 2] = { - left_l_vsplit, - left_r_vsplit, - right_l_vsplit, - right_r_vsplit, - }; + // update visibility but don't set current tab if (!docks_visible) { @@ -3591,8 +3650,8 @@ void EditorNode::_dock_tab_changed(int p_tab) { dock_slot[i]->hide(); } - for (int i = 0; i < DOCK_SLOT_MAX / 2; i++) { - splits[i]->hide(); + for (int i = 0; i < vsplits.size(); i++) { + vsplits[i]->hide(); } right_hsplit->hide(); @@ -3606,12 +3665,12 @@ void EditorNode::_dock_tab_changed(int p_tab) { dock_slot[i]->hide(); } - for (int i = 0; i < DOCK_SLOT_MAX / 2; i++) { + for (int i = 0; i < vsplits.size(); i++) { bool in_use = dock_slot[i * 2 + 0]->get_tab_count() || dock_slot[i * 2 + 1]->get_tab_count(); if (in_use) - splits[i]->show(); + vsplits[i]->show(); else - splits[i]->hide(); + vsplits[i]->hide(); } bottom_panel->show(); @@ -3670,42 +3729,28 @@ void EditorNode::_load_docks_from_config(Ref<ConfigFile> p_layout, const String } filesystem_dock->set_split_offset(fs_split_ofs); - VSplitContainer *splits[DOCK_SLOT_MAX / 2] = { - left_l_vsplit, - left_r_vsplit, - right_l_vsplit, - right_r_vsplit, - }; - - for (int i = 0; i < DOCK_SLOT_MAX / 2; i++) { + for (int i = 0; i < vsplits.size(); i++) { if (!p_layout->has_section_key(p_section, "dock_split_" + itos(i + 1))) continue; int ofs = p_layout->get_value(p_section, "dock_split_" + itos(i + 1)); - splits[i]->set_split_offset(ofs); + vsplits[i]->set_split_offset(ofs); } - HSplitContainer *h_splits[4] = { - left_l_hsplit, - left_r_hsplit, - main_hsplit, - right_hsplit, - }; - - for (int i = 0; i < 4; i++) { + for (int i = 0; i < hsplits.size(); i++) { if (!p_layout->has_section_key(p_section, "dock_hsplit_" + itos(i + 1))) continue; int ofs = p_layout->get_value(p_section, "dock_hsplit_" + itos(i + 1)); - h_splits[i]->set_split_offset(ofs); + hsplits[i]->set_split_offset(ofs); } - for (int i = 0; i < DOCK_SLOT_MAX / 2; i++) { + for (int i = 0; i < vsplits.size(); i++) { bool in_use = dock_slot[i * 2 + 0]->get_tab_count() || dock_slot[i * 2 + 1]->get_tab_count(); if (in_use) - splits[i]->show(); + vsplits[i]->show(); else - splits[i]->hide(); + vsplits[i]->hide(); } if (right_l_vsplit->is_visible() || right_r_vsplit->is_visible()) @@ -3889,6 +3934,7 @@ void EditorNode::_scene_tab_input(const Ref<InputEvent> &p_input) { scene_tabs_context_menu->add_shortcut(ED_GET_SHORTCUT("editor/save_all_scenes"), FILE_SAVE_ALL_SCENES); if (scene_tabs->get_hovered_tab() >= 0) { scene_tabs_context_menu->add_separator(); + scene_tabs_context_menu->add_item(TTR("Show in filesystem"), FILE_SHOW_IN_FILESYSTEM); scene_tabs_context_menu->add_item(TTR("Play This Scene"), RUN_PLAY_SCENE); scene_tabs_context_menu->add_item(TTR("Close Tab"), FILE_CLOSE); } @@ -3903,7 +3949,7 @@ void EditorNode::_reposition_active_tab(int idx_to) { _update_scene_tabs(); } -void EditorNode::_thumbnail_done(const String &p_path, const Ref<Texture> &p_preview, const Variant &p_udata) { +void EditorNode::_thumbnail_done(const String &p_path, const Ref<Texture> &p_preview, const Ref<Texture> &p_small_preview, const Variant &p_udata) { int p_tab = p_udata.operator signed int(); if (p_preview.is_valid()) { Rect2 rect = scene_tabs->get_tab_rect(p_tab); @@ -4476,6 +4522,16 @@ void EditorNode::_bottom_panel_raise_toggled(bool p_pressed) { } } +void EditorNode::_update_video_driver_color() { + + //todo probably should de-harcode this and add to editor settings + if (video_driver->get_text() == "GLES2") { + video_driver->add_color_override("font_color", Color::hex(0x5586a4ff)); + } else if (video_driver->get_text() == "GLES3") { + video_driver->add_color_override("font_color", Color::hex(0xa5557dff)); + } +} + void EditorNode::_video_driver_selected(int p_which) { String driver = video_driver->get_item_metadata(p_which); @@ -4489,6 +4545,7 @@ void EditorNode::_video_driver_selected(int p_which) { video_driver_request = driver; video_restart_dialog->popup_centered_minsize(); video_driver->select(video_driver_current); + _update_video_driver_color(); } void EditorNode::_bind_methods() { @@ -4595,11 +4652,10 @@ EditorNode::EditorNode() { Physics2DServer::get_singleton()->set_active(false); // no physics by default if editor ScriptServer::set_scripting_enabled(false); // no scripting by default if editor - EditorHelp::generate_doc(); //before any editor classes are crated + EditorHelp::generate_doc(); //before any editor classes are created SceneState::set_disable_placeholders(true); ResourceLoader::clear_translation_remaps(); //no remaps using during editor ResourceLoader::clear_path_remaps(); - editor_initialize_certificates(); //for asset sharing InputDefault *id = Object::cast_to<InputDefault>(Input::get_singleton()); @@ -4793,7 +4849,7 @@ EditorNode::EditorNode() { EDITOR_DEF_RST("interface/inspector/capitalize_properties", true); EDITOR_DEF_RST("interface/inspector/disable_folding", false); EDITOR_DEF("interface/inspector/horizontal_vector2_editing", false); - EDITOR_DEF("interface/inspector/horizontal_vector3_editing", true); + EDITOR_DEF("interface/inspector/horizontal_vector_types_editing", true); EDITOR_DEF("interface/inspector/open_resources_in_current_inspector", true); EDITOR_DEF("interface/inspector/resources_types_to_open_in_new_inspector", "SpatialMaterial,Script"); EDITOR_DEF("run/auto_save/save_before_running", true); @@ -4840,9 +4896,6 @@ EditorNode::EditorNode() { left_l_vsplit->add_child(dock_slot[DOCK_SLOT_LEFT_UL]); dock_slot[DOCK_SLOT_LEFT_BL] = memnew(TabContainer); left_l_vsplit->add_child(dock_slot[DOCK_SLOT_LEFT_BL]); - left_l_vsplit->hide(); - dock_slot[DOCK_SLOT_LEFT_UL]->hide(); - dock_slot[DOCK_SLOT_LEFT_BL]->hide(); left_r_hsplit = memnew(HSplitContainer); left_l_hsplit->add_child(left_r_hsplit); @@ -4880,19 +4933,22 @@ EditorNode::EditorNode() { right_r_vsplit->add_child(dock_slot[DOCK_SLOT_RIGHT_UR]); dock_slot[DOCK_SLOT_RIGHT_BR] = memnew(TabContainer); right_r_vsplit->add_child(dock_slot[DOCK_SLOT_RIGHT_BR]); - right_r_vsplit->hide(); - dock_slot[DOCK_SLOT_RIGHT_UR]->hide(); - dock_slot[DOCK_SLOT_RIGHT_BR]->hide(); - left_l_vsplit->connect("dragged", this, "_dock_split_dragged"); - left_r_vsplit->connect("dragged", this, "_dock_split_dragged"); - right_l_vsplit->connect("dragged", this, "_dock_split_dragged"); - right_r_vsplit->connect("dragged", this, "_dock_split_dragged"); + // Store them for easier access + vsplits.push_back(left_l_vsplit); + vsplits.push_back(left_r_vsplit); + vsplits.push_back(right_l_vsplit); + vsplits.push_back(right_r_vsplit); + + hsplits.push_back(left_l_hsplit); + hsplits.push_back(left_r_hsplit); + hsplits.push_back(main_hsplit); + hsplits.push_back(right_hsplit); - left_l_hsplit->connect("dragged", this, "_dock_split_dragged"); - left_r_hsplit->connect("dragged", this, "_dock_split_dragged"); - main_hsplit->connect("dragged", this, "_dock_split_dragged"); - right_hsplit->connect("dragged", this, "_dock_split_dragged"); + for (int i = 0; i < vsplits.size(); i++) { + vsplits[i]->connect("dragged", this, "_dock_split_dragged"); + hsplits[i]->connect("dragged", this, "_dock_split_dragged"); + } dock_select_popup = memnew(PopupPanel); gui_base->add_child(dock_select_popup); @@ -5346,22 +5402,21 @@ EditorNode::EditorNode() { play_custom_scene_button->set_shortcut(ED_SHORTCUT("editor/play_custom_scene", TTR("Play Custom Scene"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_F5)); #endif + // Toggle for video driver video_driver = memnew(OptionButton); video_driver->set_flat(true); video_driver->set_focus_mode(Control::FOCUS_NONE); video_driver->set_v_size_flags(Control::SIZE_SHRINK_CENTER); + video_driver->connect("item_selected", this, "_video_driver_selected"); + video_driver->add_font_override("font", gui_base->get_font("bold", "EditorFonts")); + menu_hb->add_child(video_driver); + String video_drivers = ProjectSettings::get_singleton()->get_custom_property_info()["rendering/quality/driver/driver_name"].hint_string; String current_video_driver = OS::get_singleton()->get_video_driver_name(OS::get_singleton()->get_current_video_driver()); - menu_hb->add_child(video_driver); video_driver_current = 0; for (int i = 0; i < video_drivers.get_slice_count(","); i++) { String driver = video_drivers.get_slice(",", i); - if (gui_base->has_icon(driver, "EditorIcons")) { - video_driver->add_icon_item(gui_base->get_icon(driver, "EditorIcons"), ""); - } else { - video_driver->add_item(driver); - } - + video_driver->add_item(driver); video_driver->set_item_metadata(i, driver); if (current_video_driver == driver) { @@ -5370,7 +5425,8 @@ EditorNode::EditorNode() { } } - video_driver->connect("item_selected", this, "_video_driver_selected"); + _update_video_driver_color(); + video_restart_dialog = memnew(ConfirmationDialog); video_restart_dialog->set_text(TTR("Changing the video driver requires restarting the editor.")); video_restart_dialog->get_ok()->set_text(TTR("Save & Restart")); @@ -5405,63 +5461,72 @@ EditorNode::EditorNode() { _menu_option(SETTINGS_UPDATE_SPINNER_HIDE); } - scene_tree_dock = memnew(SceneTreeDock(this, scene_root, editor_selection, editor_data)); - dock_slot[DOCK_SLOT_RIGHT_UL]->add_child(scene_tree_dock); - dock_slot[DOCK_SLOT_RIGHT_UL]->set_tab_title(scene_tree_dock->get_index(), TTR("Scene")); - dock_slot[DOCK_SLOT_LEFT_BR]->hide(); + // Instantiate and place editor docks + scene_tree_dock = memnew(SceneTreeDock(this, scene_root, editor_selection, editor_data)); inspector_dock = memnew(InspectorDock(this, editor_data)); - dock_slot[DOCK_SLOT_RIGHT_BL]->add_child(inspector_dock); - dock_slot[DOCK_SLOT_RIGHT_BL]->set_tab_title(inspector_dock->get_index(), TTR("Inspector")); - - Button *property_editable_warning; - import_dock = memnew(ImportDock); - dock_slot[DOCK_SLOT_RIGHT_UL]->add_child(import_dock); - dock_slot[DOCK_SLOT_RIGHT_UL]->set_tab_title(import_dock->get_index(), TTR("Import")); - - bool use_single_dock_column = (OS::get_singleton()->get_screen_size(OS::get_singleton()->get_current_screen()).x < 1200); - node_dock = memnew(NodeDock); - if (use_single_dock_column) { - dock_slot[DOCK_SLOT_RIGHT_UL]->add_child(node_dock); - dock_slot[DOCK_SLOT_RIGHT_UL]->set_tab_title(node_dock->get_index(), TTR("Node")); - } else { - dock_slot[DOCK_SLOT_RIGHT_BL]->add_child(node_dock); - dock_slot[DOCK_SLOT_RIGHT_BL]->set_tab_title(node_dock->get_index(), TTR("Node")); - } filesystem_dock = memnew(FileSystemDock(this)); - filesystem_dock->set_file_list_display_mode(int(EditorSettings::get_singleton()->get("docks/filesystem/display_mode"))); - - if (use_single_dock_column) { - dock_slot[DOCK_SLOT_RIGHT_BL]->add_child(filesystem_dock); - dock_slot[DOCK_SLOT_RIGHT_BL]->set_tab_title(filesystem_dock->get_index(), TTR("FileSystem")); - left_r_vsplit->hide(); - dock_slot[DOCK_SLOT_LEFT_UR]->hide(); - dock_slot[DOCK_SLOT_LEFT_BR]->hide(); - } else { - dock_slot[DOCK_SLOT_LEFT_UR]->add_child(filesystem_dock); - dock_slot[DOCK_SLOT_LEFT_UR]->set_tab_title(filesystem_dock->get_index(), TTR("FileSystem")); - } + filesystem_dock->set_file_list_display_mode(int(EditorSettings::get_singleton()->get("docks/filesystem/files_display_mode"))); filesystem_dock->connect("open", this, "open_request"); filesystem_dock->connect("instance", this, "_instance_request"); - const String docks_section = "docks"; + // Scene: Top left + dock_slot[DOCK_SLOT_LEFT_UR]->add_child(scene_tree_dock); + dock_slot[DOCK_SLOT_LEFT_UR]->set_tab_title(scene_tree_dock->get_index(), TTR("Scene")); + + // Import: Top left, behind Scene + dock_slot[DOCK_SLOT_LEFT_UR]->add_child(import_dock); + dock_slot[DOCK_SLOT_LEFT_UR]->set_tab_title(import_dock->get_index(), TTR("Import")); + + // FileSystem: Bottom left + dock_slot[DOCK_SLOT_LEFT_BR]->add_child(filesystem_dock); + dock_slot[DOCK_SLOT_LEFT_BR]->set_tab_title(filesystem_dock->get_index(), TTR("FileSystem")); + + // Inspector: Full height right + dock_slot[DOCK_SLOT_RIGHT_UL]->add_child(inspector_dock); + dock_slot[DOCK_SLOT_RIGHT_UL]->set_tab_title(inspector_dock->get_index(), TTR("Inspector")); + + // Node: Full height right, behind Inspector + dock_slot[DOCK_SLOT_RIGHT_UL]->add_child(node_dock); + dock_slot[DOCK_SLOT_RIGHT_UL]->set_tab_title(node_dock->get_index(), TTR("Node")); + + // Hide unused dock slots and vsplits + dock_slot[DOCK_SLOT_LEFT_UL]->hide(); + dock_slot[DOCK_SLOT_LEFT_BL]->hide(); + dock_slot[DOCK_SLOT_RIGHT_BL]->hide(); + dock_slot[DOCK_SLOT_RIGHT_UR]->hide(); + dock_slot[DOCK_SLOT_RIGHT_BR]->hide(); + left_l_vsplit->hide(); + right_r_vsplit->hide(); + + // Add some offsets to left_r and main hsplits to make LEFT_R and RIGHT_L docks wider than minsize + left_r_hsplit->set_split_offset(40 * EDSCALE); + main_hsplit->set_split_offset(-40 * EDSCALE); + + // Define corresponding default layout + const String docks_section = "docks"; overridden_default_layout = -1; default_layout.instance(); - default_layout->set_value(docks_section, "dock_3", "FileSystem"); - default_layout->set_value(docks_section, "dock_5", "Scene,Import"); - default_layout->set_value(docks_section, "dock_6", "Inspector,Node"); + // Dock numbers are based on DockSlot enum value + 1 + default_layout->set_value(docks_section, "dock_3", "Scene,Import"); + default_layout->set_value(docks_section, "dock_4", "FileSystem"); + default_layout->set_value(docks_section, "dock_5", "Inspector,Node"); - for (int i = 0; i < DOCK_SLOT_MAX / 2; i++) - default_layout->set_value(docks_section, "dock_hsplit_" + itos(i + 1), 0); - for (int i = 0; i < DOCK_SLOT_MAX / 2; i++) + for (int i = 0; i < vsplits.size(); i++) default_layout->set_value(docks_section, "dock_split_" + itos(i + 1), 0); + default_layout->set_value(docks_section, "dock_hsplit_1", 0); + default_layout->set_value(docks_section, "dock_hsplit_2", 40 * EDSCALE); + default_layout->set_value(docks_section, "dock_hsplit_3", -40 * EDSCALE); + default_layout->set_value(docks_section, "dock_hsplit_4", 0); _update_layouts_menu(); + // Bottom panels + bottom_panel = memnew(PanelContainer); bottom_panel->add_style_override("panel", gui_base->get_stylebox("panel", "TabContainer")); center_split->add_child(bottom_panel); @@ -5634,10 +5699,6 @@ EditorNode::EditorNode() { add_editor_plugin(memnew(SkeletonIKEditorPlugin(this))); add_editor_plugin(memnew(PhysicalBonePlugin(this))); - // FIXME: Disabled as (according to reduz) users were complaining that it gets in the way - // Waiting for PropertyEditor rewrite (planned for 3.1) to be refactored. - //add_editor_plugin(memnew(MaterialEditorPlugin(this))); - for (int i = 0; i < EditorPlugins::get_plugin_count(); i++) add_editor_plugin(EditorPlugins::create(i, this)); @@ -5780,7 +5841,7 @@ EditorNode::EditorNode() { #else ED_SHORTCUT("editor/editor_2d", TTR("Open 2D Editor"), KEY_F1); ED_SHORTCUT("editor/editor_3d", TTR("Open 3D Editor"), KEY_F2); - ED_SHORTCUT("editor/editor_script", TTR("Open Script Editor"), KEY_F3); //hack neded for script editor F3 search to work :) Assign like this or don't use F3 + ED_SHORTCUT("editor/editor_script", TTR("Open Script Editor"), KEY_F3); //hack needed for script editor F3 search to work :) Assign like this or don't use F3 ED_SHORTCUT("editor/editor_help", TTR("Search Help"), KEY_F4); #endif ED_SHORTCUT("editor/editor_assetlib", TTR("Open Asset Library")); @@ -5850,17 +5911,31 @@ bool EditorPluginList::forward_spatial_gui_input(Camera *p_camera, const Ref<Inp return discard; } -void EditorPluginList::forward_draw_over_viewport(Control *p_overlay) { +void EditorPluginList::forward_canvas_draw_over_viewport(Control *p_overlay) { + + for (int i = 0; i < plugins_list.size(); i++) { + plugins_list[i]->forward_canvas_draw_over_viewport(p_overlay); + } +} + +void EditorPluginList::forward_canvas_force_draw_over_viewport(Control *p_overlay) { + + for (int i = 0; i < plugins_list.size(); i++) { + plugins_list[i]->forward_canvas_force_draw_over_viewport(p_overlay); + } +} + +void EditorPluginList::forward_spatial_draw_over_viewport(Control *p_overlay) { for (int i = 0; i < plugins_list.size(); i++) { - plugins_list[i]->forward_draw_over_viewport(p_overlay); + plugins_list[i]->forward_spatial_draw_over_viewport(p_overlay); } } -void EditorPluginList::forward_force_draw_over_viewport(Control *p_overlay) { +void EditorPluginList::forward_spatial_force_draw_over_viewport(Control *p_overlay) { for (int i = 0; i < plugins_list.size(); i++) { - plugins_list[i]->forward_force_draw_over_viewport(p_overlay); + plugins_list[i]->forward_spatial_force_draw_over_viewport(p_overlay); } } diff --git a/editor/editor_node.h b/editor/editor_node.h index 5a17ab6ca0..0096748ed1 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -125,6 +125,7 @@ private: FILE_SAVE_ALL_SCENES, FILE_SAVE_BEFORE_RUN, FILE_SAVE_AND_RUN, + FILE_SHOW_IN_FILESYSTEM, FILE_IMPORT_SUBSCENE, FILE_EXPORT_PROJECT, FILE_EXPORT_MESH_LIBRARY, @@ -207,8 +208,9 @@ private: int video_driver_current; String video_driver_request; void _video_driver_selected(int); + void _update_video_driver_color(); - //split + // Split containers HSplitContainer *left_l_hsplit; VSplitContainer *left_l_vsplit; @@ -221,7 +223,11 @@ private: VSplitContainer *center_split; - //main tabs + // To access those easily by index + Vector<VSplitContainer *> vsplits; + Vector<HSplitContainer *> hsplits; + + // Main tabs Tabs *scene_tabs; PopupMenu *scene_tabs_context_menu; @@ -535,7 +541,7 @@ private: void _scene_tab_exit(); void _scene_tab_input(const Ref<InputEvent> &p_input); void _reposition_active_tab(int idx_to); - void _thumbnail_done(const String &p_path, const Ref<Texture> &p_preview, const Variant &p_udata); + void _thumbnail_done(const String &p_path, const Ref<Texture> &p_preview, const Ref<Texture> &p_small_preview, const Variant &p_udata); void _scene_tab_script_edited(int p_tab); Dictionary _get_main_scene_state(); @@ -706,6 +712,8 @@ public: void stop_child_process(); Ref<Theme> get_editor_theme() const { return theme; } + Ref<Texture> get_object_icon(const Object *p_object, const String &p_fallback = "Object") const; + Ref<Texture> get_class_icon(const String &p_class, const String &p_fallback = "Object") const; void show_accept(const String &p_text, const String &p_title); void show_warning(const String &p_text, const String &p_title = "Warning!"); @@ -810,9 +818,11 @@ public: void make_visible(bool p_visible); void edit(Object *p_object); bool forward_gui_input(const Ref<InputEvent> &p_event); + void forward_canvas_draw_over_viewport(Control *p_overlay); + void forward_canvas_force_draw_over_viewport(Control *p_overlay); bool forward_spatial_gui_input(Camera *p_camera, const Ref<InputEvent> &p_event, bool serve_when_force_input_enabled); - void forward_draw_over_viewport(Control *p_overlay); - void forward_force_draw_over_viewport(Control *p_overlay); + void forward_spatial_draw_over_viewport(Control *p_overlay); + void forward_spatial_force_draw_over_viewport(Control *p_overlay); void add_plugin(EditorPlugin *p_plugin); void clear(); bool empty(); diff --git a/editor/editor_path.cpp b/editor/editor_path.cpp index 9506a0e951..0eff1fd7dd 100644 --- a/editor/editor_path.cpp +++ b/editor/editor_path.cpp @@ -54,12 +54,7 @@ void EditorPath::_add_children_to_popup(Object *p_obj, int p_depth) { if (!obj) continue; - Ref<Texture> icon; - - if (has_icon(obj->get_class(), "EditorIcons")) - icon = get_icon(obj->get_class(), "EditorIcons"); - else - icon = get_icon("Object", "EditorIcons"); + Ref<Texture> icon = EditorNode::get_singleton()->get_object_icon(obj); int index = popup->get_item_count(); popup->add_icon_item(icon, E->get().name.capitalize(), objects.size()); @@ -122,12 +117,7 @@ void EditorPath::_notification(int p_what) { String type = obj->get_class(); - Ref<Texture> icon; - - if (has_icon(obj->get_class(), "EditorIcons")) - icon = get_icon(obj->get_class(), "EditorIcons"); - else - icon = get_icon("Object", "EditorIcons"); + Ref<Texture> icon = EditorNode::get_singleton()->get_object_icon(obj); icon->draw(ci, Point2i(ofs, (size.height - icon->get_height()) / 2)); diff --git a/editor/editor_plugin.cpp b/editor/editor_plugin.cpp index 1f2e73654c..dd3a8aa307 100644 --- a/editor/editor_plugin.cpp +++ b/editor/editor_plugin.cpp @@ -39,6 +39,7 @@ #include "scene/3d/camera.h" #include "scene/gui/popup_menu.h" #include "servers/visual_server.h" + Array EditorInterface::_make_mesh_previews(const Array &p_meshes, int p_preview_size) { Vector<Ref<Mesh> > meshes; @@ -503,17 +504,17 @@ bool EditorPlugin::forward_canvas_gui_input(const Ref<InputEvent> &p_event) { return false; } -void EditorPlugin::forward_draw_over_viewport(Control *p_overlay) { +void EditorPlugin::forward_canvas_draw_over_viewport(Control *p_overlay) { - if (get_script_instance() && get_script_instance()->has_method("forward_draw_over_viewport")) { - get_script_instance()->call("forward_draw_over_viewport", p_overlay); + if (get_script_instance() && get_script_instance()->has_method("forward_canvas_draw_over_viewport")) { + get_script_instance()->call("forward_canvas_draw_over_viewport", p_overlay); } } -void EditorPlugin::forward_force_draw_over_viewport(Control *p_overlay) { +void EditorPlugin::forward_canvas_force_draw_over_viewport(Control *p_overlay) { - if (get_script_instance() && get_script_instance()->has_method("forward_force_draw_over_viewport")) { - get_script_instance()->call("forward_force_draw_over_viewport", p_overlay); + if (get_script_instance() && get_script_instance()->has_method("forward_canvas_force_draw_over_viewport")) { + get_script_instance()->call("forward_canvas_force_draw_over_viewport", p_overlay); } } @@ -522,7 +523,7 @@ int EditorPlugin::update_overlays() const { if (SpatialEditor::get_singleton()->is_visible()) { int count = 0; - for (int i = 0; i < SpatialEditor::VIEWPORTS_COUNT; i++) { + for (uint32_t i = 0; i < SpatialEditor::VIEWPORTS_COUNT; i++) { SpatialEditorViewport *vp = SpatialEditor::get_singleton()->get_editor_viewport(i); if (vp->is_visible()) { vp->update_surface(); @@ -545,6 +546,20 @@ bool EditorPlugin::forward_spatial_gui_input(Camera *p_camera, const Ref<InputEv return false; } + +void EditorPlugin::forward_spatial_draw_over_viewport(Control *p_overlay) { + + if (get_script_instance() && get_script_instance()->has_method("forward_spatial_draw_over_viewport")) { + get_script_instance()->call("forward_spatial_draw_over_viewport", p_overlay); + } +} + +void EditorPlugin::forward_spatial_force_draw_over_viewport(Control *p_overlay) { + + if (get_script_instance() && get_script_instance()->has_method("forward_spatial_force_draw_over_viewport")) { + get_script_instance()->call("forward_spatial_force_draw_over_viewport", p_overlay); + } +} String EditorPlugin::get_name() const { if (get_script_instance() && get_script_instance()->has_method("get_plugin_name")) { @@ -769,8 +784,8 @@ void EditorPlugin::_bind_methods() { ClassDB::bind_method(D_METHOD("get_script_create_dialog"), &EditorPlugin::get_script_create_dialog); ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::BOOL, "forward_canvas_gui_input", PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent"))); - ClassDB::add_virtual_method(get_class_static(), MethodInfo("forward_draw_over_viewport", PropertyInfo(Variant::OBJECT, "overlay", PROPERTY_HINT_RESOURCE_TYPE, "Control"))); - ClassDB::add_virtual_method(get_class_static(), MethodInfo("forward_force_draw_over_viewport", PropertyInfo(Variant::OBJECT, "overlay", PROPERTY_HINT_RESOURCE_TYPE, "Control"))); + ClassDB::add_virtual_method(get_class_static(), MethodInfo("forward_canvas_draw_over_viewport", PropertyInfo(Variant::OBJECT, "overlay", PROPERTY_HINT_RESOURCE_TYPE, "Control"))); + ClassDB::add_virtual_method(get_class_static(), MethodInfo("forward_canvas_force_draw_over_viewport", PropertyInfo(Variant::OBJECT, "overlay", PROPERTY_HINT_RESOURCE_TYPE, "Control"))); ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::BOOL, "forward_spatial_gui_input", PropertyInfo(Variant::OBJECT, "camera", PROPERTY_HINT_RESOURCE_TYPE, "Camera"), PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent"))); ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::STRING, "get_plugin_name")); ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::OBJECT, "get_plugin_icon")); diff --git a/editor/editor_plugin.h b/editor/editor_plugin.h index 1ebddbe2b0..e03aeb5d30 100644 --- a/editor/editor_plugin.h +++ b/editor/editor_plugin.h @@ -31,15 +31,15 @@ #ifndef EDITOR_PLUGIN_H #define EDITOR_PLUGIN_H +#include "core/io/config_file.h" +#include "core/undo_redo.h" #include "editor/editor_inspector.h" #include "editor/import/editor_import_plugin.h" #include "editor/import/resource_importer_scene.h" #include "editor/script_create_dialog.h" -#include "io/config_file.h" #include "scene/gui/tool_button.h" #include "scene/main/node.h" #include "scene/resources/texture.h" -#include "undo_redo.h" /** @author Juan Linietsky <reduzio@gmail.com> @@ -174,9 +174,13 @@ public: void notify_resource_saved(const Ref<Resource> &p_resource); virtual bool forward_canvas_gui_input(const Ref<InputEvent> &p_event); - virtual void forward_draw_over_viewport(Control *p_overlay); - virtual void forward_force_draw_over_viewport(Control *p_overlay); + virtual void forward_canvas_draw_over_viewport(Control *p_overlay); + virtual void forward_canvas_force_draw_over_viewport(Control *p_overlay); + virtual bool forward_spatial_gui_input(Camera *p_camera, const Ref<InputEvent> &p_event); + virtual void forward_spatial_draw_over_viewport(Control *p_overlay); + virtual void forward_spatial_force_draw_over_viewport(Control *p_overlay); + virtual String get_name() const; virtual const Ref<Texture> get_icon() const; virtual bool has_main_screen() const; diff --git a/editor/editor_plugin_settings.cpp b/editor/editor_plugin_settings.cpp index 68f8ed6d94..30027c0c34 100644 --- a/editor/editor_plugin_settings.cpp +++ b/editor/editor_plugin_settings.cpp @@ -30,11 +30,11 @@ #include "editor_plugin_settings.h" +#include "core/io/config_file.h" +#include "core/os/file_access.h" +#include "core/os/main_loop.h" +#include "core/project_settings.h" #include "editor_node.h" -#include "io/config_file.h" -#include "os/file_access.h" -#include "os/main_loop.h" -#include "project_settings.h" #include "scene/gui/margin_container.h" void EditorPluginSettings::_notification(int p_what) { @@ -117,7 +117,7 @@ void EditorPluginSettings::update_plugins() { TreeItem *item = plugin_list->create_item(root); item->set_text(0, name); - item->set_tooltip(0, "Name: " + name + "\nPath: " + path + "\nMain Script: " + script); + item->set_tooltip(0, "Name: " + name + "\nPath: " + path + "\nMain Script: " + script + "\nDescription: " + description); item->set_metadata(0, d); item->set_text(1, version); item->set_metadata(1, script); diff --git a/editor/editor_plugin_settings.h b/editor/editor_plugin_settings.h index 194fac6b92..fe14f87cfc 100644 --- a/editor/editor_plugin_settings.h +++ b/editor/editor_plugin_settings.h @@ -31,11 +31,11 @@ #ifndef EDITORPLUGINSETTINGS_H #define EDITORPLUGINSETTINGS_H +#include "core/undo_redo.h" #include "editor/plugin_config_dialog.h" #include "editor_data.h" #include "property_editor.h" #include "scene/gui/dialogs.h" -#include "undo_redo.h" class EditorPluginSettings : public VBoxContainer { diff --git a/editor/editor_profiler.cpp b/editor/editor_profiler.cpp index f57c863bcf..b57e3826c6 100644 --- a/editor/editor_profiler.cpp +++ b/editor/editor_profiler.cpp @@ -30,9 +30,9 @@ #include "editor_profiler.h" +#include "core/os/os.h" #include "editor_scale.h" #include "editor_settings.h" -#include "os/os.h" void EditorProfiler::_make_metric_ptrs(Metric &m) { @@ -100,8 +100,6 @@ void EditorProfiler::clear() { updating_frame = false; hover_metric = -1; seeking = false; - - _update_plot(); } static String _get_percent_txt(float p_value, float p_total) { @@ -169,7 +167,7 @@ void EditorProfiler::_update_plot() { int w = graph->get_size().width; int h = graph->get_size().height; - bool reset_texture = graph_texture.is_null(); + bool reset_texture = false; int desired_len = w * h * 4; @@ -437,6 +435,7 @@ void EditorProfiler::_activate_pressed() { void EditorProfiler::_clear_pressed() { clear(); + _update_plot(); } void EditorProfiler::_notification(int p_what) { diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp index 3c3df6b8ef..c5c78b2590 100644 --- a/editor/editor_properties.cpp +++ b/editor/editor_properties.cpp @@ -108,6 +108,7 @@ void EditorPropertyMultilineText::_open_big_text() { if (!big_text_dialog) { big_text = memnew(TextEdit); big_text->connect("text_changed", this, "_big_text_changed"); + big_text->set_wrap_enabled(true); big_text_dialog = memnew(AcceptDialog); big_text_dialog->add_child(big_text); big_text_dialog->set_title("Edit Text:"); @@ -152,6 +153,7 @@ EditorPropertyMultilineText::EditorPropertyMultilineText() { set_bottom_editor(hb); text = memnew(TextEdit); text->connect("text_changed", this, "_text_changed"); + text->set_wrap_enabled(true); add_focusable(text); hb->add_child(text); text->set_h_size_flags(SIZE_EXPAND_FILL); @@ -651,6 +653,7 @@ public: int h = bsize * 2 + 1; int vofs = (rect.size.height - h) / 2; + Color color = get_color("highlight_color", "Editor"); for (int i = 0; i < 2; i++) { Point2 ofs(4, vofs); @@ -667,7 +670,8 @@ public: uint32_t idx = i * 10 + j; bool on = value & (1 << idx); Rect2 rect = Rect2(o, Size2(bsize, bsize)); - draw_rect(rect, Color(0, 0, 0, on ? 0.8 : 0.3)); + color.a = on ? 0.6 : 0.2; + draw_rect(rect, color); flag_rects.push_back(rect); } } @@ -815,10 +819,10 @@ void EditorPropertyInteger::_bind_methods() { ClassDB::bind_method(D_METHOD("_value_changed"), &EditorPropertyInteger::_value_changed); } -void EditorPropertyInteger::setup(int p_min, int p_max, bool p_allow_greater, bool p_allow_lesser) { +void EditorPropertyInteger::setup(int p_min, int p_max, int p_step, bool p_allow_greater, bool p_allow_lesser) { spin->set_min(p_min); spin->set_max(p_max); - spin->set_step(1); + spin->set_step(p_step); spin->set_allow_greater(p_allow_greater); spin->set_allow_lesser(p_allow_lesser); } @@ -844,18 +848,11 @@ void EditorPropertyObjectID::update_property() { if (type == "") type = "Object"; - String icon_type = type; - if (has_icon(icon_type, "EditorIcons")) { - type = icon_type; - } else { - type = "Object"; - } - ObjectID id = get_edited_object()->get(get_edited_property()); if (id != 0) { edit->set_text(type + " ID: " + itos(id)); edit->set_disabled(false); - edit->set_icon(get_icon(icon_type, "EditorIcons")); + edit->set_icon(EditorNode::get_singleton()->get_class_icon(type)); } else { edit->set_text(TTR("[Empty]")); edit->set_disabled(true); @@ -1188,21 +1185,39 @@ void EditorPropertyRect2::setup(double p_min, double p_max, double p_step, bool } EditorPropertyRect2::EditorPropertyRect2() { - VBoxContainer *vb = memnew(VBoxContainer); - add_child(vb); + + bool horizontal = EDITOR_GET("interface/inspector/horizontal_vector_types_editing"); + + BoxContainer *bc; + + if (horizontal) { + bc = memnew(HBoxContainer); + add_child(bc); + set_bottom_editor(bc); + } else { + bc = memnew(VBoxContainer); + add_child(bc); + } + static const char *desc[4] = { "x", "y", "w", "h" }; for (int i = 0; i < 4; i++) { spin[i] = memnew(EditorSpinSlider); spin[i]->set_label(desc[i]); spin[i]->set_flat(true); - - vb->add_child(spin[i]); + bc->add_child(spin[i]); add_focusable(spin[i]); spin[i]->connect("value_changed", this, "_value_changed"); + if (horizontal) { + spin[i]->set_h_size_flags(SIZE_EXPAND_FILL); + } + } + + if (!horizontal) { + set_label_reference(spin[0]); //show text and buttons around this } - set_label_reference(spin[0]); //show text and buttons around this setting = false; } + ///////////////////// VECTOR3 ///////////////////////// void EditorPropertyVector3::_value_changed(double val) { @@ -1250,7 +1265,7 @@ void EditorPropertyVector3::setup(double p_min, double p_max, double p_step, boo } EditorPropertyVector3::EditorPropertyVector3() { - bool horizontal = EDITOR_GET("interface/inspector/horizontal_vector3_editing"); + bool horizontal = EDITOR_GET("interface/inspector/horizontal_vector_types_editing"); BoxContainer *bc; @@ -1331,7 +1346,7 @@ void EditorPropertyPlane::setup(double p_min, double p_max, double p_step, bool EditorPropertyPlane::EditorPropertyPlane() { - bool horizontal = EDITOR_GET("interface/inspector/horizontal_vector3_editing"); + bool horizontal = EDITOR_GET("interface/inspector/horizontal_vector_types_editing"); BoxContainer *bc; @@ -1412,7 +1427,7 @@ void EditorPropertyQuat::setup(double p_min, double p_max, double p_step, bool p } EditorPropertyQuat::EditorPropertyQuat() { - bool horizontal = EDITOR_GET("interface/inspector/horizontal_vector3_editing"); + bool horizontal = EDITOR_GET("interface/inspector/horizontal_vector_types_editing"); BoxContainer *bc; @@ -1764,7 +1779,7 @@ void EditorPropertyColor::_color_changed(const Color &p_color) { void EditorPropertyColor::_popup_closed() { - emit_signal("property_changed", get_edited_property(), picker->get_pick_color(), false); + emit_signal("property_changed", get_edited_property(), picker->get_pick_color(), true); } void EditorPropertyColor::_bind_methods() { @@ -1856,14 +1871,7 @@ void EditorPropertyNodePath::update_property() { ERR_FAIL_COND(!target_node); assign->set_text(target_node->get_name()); - - Ref<Texture> icon; - if (has_icon(target_node->get_class(), "EditorIcons")) - icon = get_icon(target_node->get_class(), "EditorIcons"); - else - icon = get_icon("Node", "EditorIcons"); - - assign->set_icon(icon); + assign->set_icon(EditorNode::get_singleton()->get_object_icon(target_node, "Node")); } void EditorPropertyNodePath::setup(const NodePath &p_base_hint, Vector<StringName> p_valid_types) { @@ -1903,7 +1911,7 @@ EditorPropertyNodePath::EditorPropertyNodePath() { clear->connect("pressed", this, "_node_clear"); hbc->add_child(clear); - scene_tree = NULL; //do not allocate unnecesarily + scene_tree = NULL; //do not allocate unnecessarily } ////////////// RESOURCE ////////////////////// @@ -2361,13 +2369,7 @@ void EditorPropertyResource::update_property() { assign->set_text(TTR("[empty]")); } else { - Ref<Texture> icon; - if (has_icon(res->get_class(), "EditorIcons")) - icon = get_icon(res->get_class(), "EditorIcons"); - else - icon = get_icon("Node", "EditorIcons"); - - assign->set_icon(icon); + assign->set_icon(EditorNode::get_singleton()->get_object_icon(res.operator->(), "Node")); if (res->get_name() != String()) { assign->set_text(res->get_name()); @@ -2654,7 +2656,7 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ } else if (p_hint == PROPERTY_HINT_LAYERS_2D_PHYSICS || p_hint == PROPERTY_HINT_LAYERS_2D_RENDER || p_hint == PROPERTY_HINT_LAYERS_3D_PHYSICS || p_hint == PROPERTY_HINT_LAYERS_3D_RENDER) { - EditorPropertyLayers::LayerType lt; + EditorPropertyLayers::LayerType lt = EditorPropertyLayers::LAYER_RENDER_2D; switch (p_hint) { case PROPERTY_HINT_LAYERS_2D_RENDER: lt = EditorPropertyLayers::LAYER_RENDER_2D; @@ -2668,7 +2670,7 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ case PROPERTY_HINT_LAYERS_3D_PHYSICS: lt = EditorPropertyLayers::LAYER_PHYSICS_3D; break; - default: {} //compiler could be smarter here and realize this cant happen + default: {} //compiler could be smarter here and realize this can't happen } EditorPropertyLayers *editor = memnew(EditorPropertyLayers); editor->setup(lt); @@ -2681,14 +2683,19 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ } else { EditorPropertyInteger *editor = memnew(EditorPropertyInteger); - int min = 0, max = 65535; + int min = 0, max = 65535, step = 1; bool greater = true, lesser = true; if (p_hint == PROPERTY_HINT_RANGE && p_hint_text.get_slice_count(",") >= 2) { - greater = false; //if using ranged, asume false by default + greater = false; //if using ranged, assume false by default lesser = false; min = p_hint_text.get_slice(",", 0).to_int(); max = p_hint_text.get_slice(",", 1).to_int(); + + if (p_hint_text.get_slice_count(",") >= 3) { + step = p_hint_text.get_slice(",", 2).to_int(); + } + for (int i = 2; i < p_hint_text.get_slice_count(","); i++) { String slice = p_hint_text.get_slice(",", i).strip_edges(); if (slice == "or_greater") { @@ -2700,7 +2707,7 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ } } - editor->setup(min, max, greater, lesser); + editor->setup(min, max, step, greater, lesser); add_property_editor(p_path, editor); } @@ -2733,7 +2740,7 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ bool greater = true, lesser = true; if ((p_hint == PROPERTY_HINT_RANGE || p_hint == PROPERTY_HINT_EXP_RANGE) && p_hint_text.get_slice_count(",") >= 2) { - greater = false; //if using ranged, asume false by default + greater = false; //if using ranged, assume false by default lesser = false; min = p_hint_text.get_slice(",", 0).to_double(); max = p_hint_text.get_slice(",", 1).to_double(); @@ -3066,7 +3073,7 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ default: {} } - return false; //can be overriden, although it will most likely be last anyway + return false; //can be overridden, although it will most likely be last anyway } void EditorInspectorDefaultPlugin::parse_end() { diff --git a/editor/editor_properties.h b/editor/editor_properties.h index cfc433b880..18e70345aa 100644 --- a/editor/editor_properties.h +++ b/editor/editor_properties.h @@ -265,7 +265,7 @@ protected: public: virtual void update_property(); - void setup(int p_min, int p_max, bool p_allow_greater, bool p_allow_lesser); + void setup(int p_min, int p_max, int p_step, bool p_allow_greater, bool p_allow_lesser); EditorPropertyInteger(); }; diff --git a/editor/editor_properties_array_dict.cpp b/editor/editor_properties_array_dict.cpp index 23dbb026dd..24360813a2 100644 --- a/editor/editor_properties_array_dict.cpp +++ b/editor/editor_properties_array_dict.cpp @@ -1,3 +1,33 @@ +/*************************************************************************/ +/* editor_properties_array_dict.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + #include "editor_properties_array_dict.h" #include "editor/editor_scale.h" #include "editor_properties.h" @@ -306,16 +336,16 @@ void EditorPropertyArray::update_property() { } break; case Variant::INT: { - EditorPropertyInteger *ed = memnew(EditorPropertyInteger); - ed->setup(-100000, 100000, true, true); - prop = ed; + EditorPropertyInteger *editor = memnew(EditorPropertyInteger); + editor->setup(-100000, 100000, 1, true, true); + prop = editor; } break; case Variant::REAL: { - EditorPropertyFloat *ed = memnew(EditorPropertyFloat); - ed->setup(-100000, 100000, 0.001, true, false, true, true); - prop = ed; + EditorPropertyFloat *editor = memnew(EditorPropertyFloat); + editor->setup(-100000, 100000, 0.001, true, false, true, true); + prop = editor; } break; case Variant::STRING: { @@ -327,63 +357,63 @@ void EditorPropertyArray::update_property() { case Variant::VECTOR2: { - EditorPropertyVector2 *ed = memnew(EditorPropertyVector2); - ed->setup(-100000, 100000, 0.001, true); - prop = ed; + EditorPropertyVector2 *editor = memnew(EditorPropertyVector2); + editor->setup(-100000, 100000, 0.001, true); + prop = editor; } break; case Variant::RECT2: { - EditorPropertyRect2 *ed = memnew(EditorPropertyRect2); - ed->setup(-100000, 100000, 0.001, true); - prop = ed; + EditorPropertyRect2 *editor = memnew(EditorPropertyRect2); + editor->setup(-100000, 100000, 0.001, true); + prop = editor; } break; case Variant::VECTOR3: { - EditorPropertyVector3 *ed = memnew(EditorPropertyVector3); - ed->setup(-100000, 100000, 0.001, true); - prop = ed; + EditorPropertyVector3 *editor = memnew(EditorPropertyVector3); + editor->setup(-100000, 100000, 0.001, true); + prop = editor; } break; case Variant::TRANSFORM2D: { - EditorPropertyTransform2D *ed = memnew(EditorPropertyTransform2D); - ed->setup(-100000, 100000, 0.001, true); - prop = ed; + EditorPropertyTransform2D *editor = memnew(EditorPropertyTransform2D); + editor->setup(-100000, 100000, 0.001, true); + prop = editor; } break; case Variant::PLANE: { - EditorPropertyPlane *ed = memnew(EditorPropertyPlane); - ed->setup(-100000, 100000, 0.001, true); - prop = ed; + EditorPropertyPlane *editor = memnew(EditorPropertyPlane); + editor->setup(-100000, 100000, 0.001, true); + prop = editor; } break; case Variant::QUAT: { - EditorPropertyQuat *ed = memnew(EditorPropertyQuat); - ed->setup(-100000, 100000, 0.001, true); - prop = ed; + EditorPropertyQuat *editor = memnew(EditorPropertyQuat); + editor->setup(-100000, 100000, 0.001, true); + prop = editor; } break; case Variant::AABB: { - EditorPropertyAABB *ed = memnew(EditorPropertyAABB); - ed->setup(-100000, 100000, 0.001, true); - prop = ed; + EditorPropertyAABB *editor = memnew(EditorPropertyAABB); + editor->setup(-100000, 100000, 0.001, true); + prop = editor; } break; case Variant::BASIS: { - EditorPropertyBasis *ed = memnew(EditorPropertyBasis); - ed->setup(-100000, 100000, 0.001, true); - prop = ed; + EditorPropertyBasis *editor = memnew(EditorPropertyBasis); + editor->setup(-100000, 100000, 0.001, true); + prop = editor; } break; case Variant::TRANSFORM: { - EditorPropertyTransform *ed = memnew(EditorPropertyTransform); - ed->setup(-100000, 100000, 0.001, true); - prop = ed; + EditorPropertyTransform *editor = memnew(EditorPropertyTransform); + editor->setup(-100000, 100000, 0.001, true); + prop = editor; } break; @@ -401,8 +431,9 @@ void EditorPropertyArray::update_property() { } break; case Variant::OBJECT: { - - prop = memnew(EditorPropertyResource); + EditorPropertyResource *editor = memnew(EditorPropertyResource); + editor->setup("Resource"); + prop = editor; } break; case Variant::DICTIONARY: { @@ -713,7 +744,7 @@ void EditorPropertyDictionary::update_property() { page->connect("value_changed", this, "_page_changed"); } else { // Queue childs for deletion, delete immediately might cause errors. - for (size_t i = 1; i < vbox->get_child_count(); i++) { + for (int i = 1; i < vbox->get_child_count(); i++) { vbox->get_child(i)->queue_delete(); } } @@ -768,16 +799,16 @@ void EditorPropertyDictionary::update_property() { } break; case Variant::INT: { - EditorPropertyInteger *ed = memnew(EditorPropertyInteger); - ed->setup(-100000, 100000, true, true); - prop = ed; + EditorPropertyInteger *editor = memnew(EditorPropertyInteger); + editor->setup(-100000, 100000, 1, true, true); + prop = editor; } break; case Variant::REAL: { - EditorPropertyFloat *ed = memnew(EditorPropertyFloat); - ed->setup(-100000, 100000, 0.001, true, false, true, true); - prop = ed; + EditorPropertyFloat *editor = memnew(EditorPropertyFloat); + editor->setup(-100000, 100000, 0.001, true, false, true, true); + prop = editor; } break; case Variant::STRING: { @@ -785,67 +816,66 @@ void EditorPropertyDictionary::update_property() { } break; - // math types - + // math types case Variant::VECTOR2: { - EditorPropertyVector2 *ed = memnew(EditorPropertyVector2); - ed->setup(-100000, 100000, 0.001, true); - prop = ed; + EditorPropertyVector2 *editor = memnew(EditorPropertyVector2); + editor->setup(-100000, 100000, 0.001, true); + prop = editor; } break; case Variant::RECT2: { - EditorPropertyRect2 *ed = memnew(EditorPropertyRect2); - ed->setup(-100000, 100000, 0.001, true); - prop = ed; + EditorPropertyRect2 *editor = memnew(EditorPropertyRect2); + editor->setup(-100000, 100000, 0.001, true); + prop = editor; } break; case Variant::VECTOR3: { - EditorPropertyVector3 *ed = memnew(EditorPropertyVector3); - ed->setup(-100000, 100000, 0.001, true); - prop = ed; + EditorPropertyVector3 *editor = memnew(EditorPropertyVector3); + editor->setup(-100000, 100000, 0.001, true); + prop = editor; } break; case Variant::TRANSFORM2D: { - EditorPropertyTransform2D *ed = memnew(EditorPropertyTransform2D); - ed->setup(-100000, 100000, 0.001, true); - prop = ed; + EditorPropertyTransform2D *editor = memnew(EditorPropertyTransform2D); + editor->setup(-100000, 100000, 0.001, true); + prop = editor; } break; case Variant::PLANE: { - EditorPropertyPlane *ed = memnew(EditorPropertyPlane); - ed->setup(-100000, 100000, 0.001, true); - prop = ed; + EditorPropertyPlane *editor = memnew(EditorPropertyPlane); + editor->setup(-100000, 100000, 0.001, true); + prop = editor; } break; case Variant::QUAT: { - EditorPropertyQuat *ed = memnew(EditorPropertyQuat); - ed->setup(-100000, 100000, 0.001, true); - prop = ed; + EditorPropertyQuat *editor = memnew(EditorPropertyQuat); + editor->setup(-100000, 100000, 0.001, true); + prop = editor; } break; case Variant::AABB: { - EditorPropertyAABB *ed = memnew(EditorPropertyAABB); - ed->setup(-100000, 100000, 0.001, true); - prop = ed; + EditorPropertyAABB *editor = memnew(EditorPropertyAABB); + editor->setup(-100000, 100000, 0.001, true); + prop = editor; } break; case Variant::BASIS: { - EditorPropertyBasis *ed = memnew(EditorPropertyBasis); - ed->setup(-100000, 100000, 0.001, true); - prop = ed; + EditorPropertyBasis *editor = memnew(EditorPropertyBasis); + editor->setup(-100000, 100000, 0.001, true); + prop = editor; } break; case Variant::TRANSFORM: { - EditorPropertyTransform *ed = memnew(EditorPropertyTransform); - ed->setup(-100000, 100000, 0.001, true); - prop = ed; + EditorPropertyTransform *editor = memnew(EditorPropertyTransform); + editor->setup(-100000, 100000, 0.001, true); + prop = editor; } break; @@ -863,8 +893,9 @@ void EditorPropertyDictionary::update_property() { } break; case Variant::OBJECT: { - - prop = memnew(EditorPropertyResource); + EditorPropertyResource *editor = memnew(EditorPropertyResource); + editor->setup("Resource"); + prop = editor; } break; case Variant::DICTIONARY: { @@ -872,39 +903,53 @@ void EditorPropertyDictionary::update_property() { } break; case Variant::ARRAY: { - - prop = memnew(EditorPropertyArray); - + EditorPropertyArray *editor = memnew(EditorPropertyArray); + editor->setup(Variant::ARRAY); + prop = editor; } break; // arrays case Variant::POOL_BYTE_ARRAY: { - prop = memnew(EditorPropertyArray); + EditorPropertyArray *editor = memnew(EditorPropertyArray); + editor->setup(Variant::POOL_BYTE_ARRAY); + prop = editor; } break; case Variant::POOL_INT_ARRAY: { - prop = memnew(EditorPropertyArray); + EditorPropertyArray *editor = memnew(EditorPropertyArray); + editor->setup(Variant::POOL_INT_ARRAY); + prop = editor; } break; case Variant::POOL_REAL_ARRAY: { - prop = memnew(EditorPropertyArray); + EditorPropertyArray *editor = memnew(EditorPropertyArray); + editor->setup(Variant::POOL_REAL_ARRAY); + prop = editor; } break; case Variant::POOL_STRING_ARRAY: { - prop = memnew(EditorPropertyArray); + EditorPropertyArray *editor = memnew(EditorPropertyArray); + editor->setup(Variant::POOL_STRING_ARRAY); + prop = editor; } break; case Variant::POOL_VECTOR2_ARRAY: { - prop = memnew(EditorPropertyArray); + EditorPropertyArray *editor = memnew(EditorPropertyArray); + editor->setup(Variant::POOL_VECTOR2_ARRAY); + prop = editor; } break; case Variant::POOL_VECTOR3_ARRAY: { - prop = memnew(EditorPropertyArray); + EditorPropertyArray *editor = memnew(EditorPropertyArray); + editor->setup(Variant::POOL_VECTOR3_ARRAY); + prop = editor; } break; case Variant::POOL_COLOR_ARRAY: { - prop = memnew(EditorPropertyArray); + EditorPropertyArray *editor = memnew(EditorPropertyArray); + editor->setup(Variant::POOL_COLOR_ARRAY); + prop = editor; } break; default: {} } @@ -924,7 +969,7 @@ void EditorPropertyDictionary::update_property() { pc->add_child(add_vbox); } prop->set_object_and_property(object.ptr(), prop_name); - int change_index; + int change_index = 0; if (i < amount) { String cs = key.get_construct_string(); diff --git a/editor/editor_properties_array_dict.h b/editor/editor_properties_array_dict.h index a8ddb02e9d..d2bd849f30 100644 --- a/editor/editor_properties_array_dict.h +++ b/editor/editor_properties_array_dict.h @@ -1,3 +1,33 @@ +/*************************************************************************/ +/* editor_properties_array_dict.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + #ifndef EDITOR_PROPERTIES_ARRAY_DICT_H #define EDITOR_PROPERTIES_ARRAY_DICT_H diff --git a/editor/editor_resource_preview.cpp b/editor/editor_resource_preview.cpp index bc56a95b47..310c3b3a52 100644 --- a/editor/editor_resource_preview.cpp +++ b/editor/editor_resource_preview.cpp @@ -30,13 +30,16 @@ #include "editor_resource_preview.h" +#include "core/method_bind_ext.gen.inc" + +#include "core/io/resource_loader.h" +#include "core/io/resource_saver.h" +#include "core/message_queue.h" +#include "core/os/file_access.h" +#include "core/project_settings.h" +#include "editor_node.h" #include "editor_scale.h" #include "editor_settings.h" -#include "io/resource_loader.h" -#include "io/resource_saver.h" -#include "message_queue.h" -#include "os/file_access.h" -#include "project_settings.h" bool EditorResourcePreviewGenerator::handles(const String &p_type) const { @@ -46,32 +49,37 @@ bool EditorResourcePreviewGenerator::handles(const String &p_type) const { ERR_EXPLAIN("EditorResourcePreviewGenerator::handles needs to be overridden"); ERR_FAIL_V(false); } -Ref<Texture> EditorResourcePreviewGenerator::generate(const RES &p_from) const { + +Ref<Texture> EditorResourcePreviewGenerator::generate(const RES &p_from, const Size2 p_size) const { if (get_script_instance() && get_script_instance()->has_method("generate")) { - return get_script_instance()->call("generate", p_from); + return get_script_instance()->call("generate", p_from, p_size); } ERR_EXPLAIN("EditorResourcePreviewGenerator::generate needs to be overridden"); ERR_FAIL_V(Ref<Texture>()); } -Ref<Texture> EditorResourcePreviewGenerator::generate_from_path(const String &p_path) const { +Ref<Texture> EditorResourcePreviewGenerator::generate_from_path(const String &p_path, const Size2 p_size) const { if (get_script_instance() && get_script_instance()->has_method("generate_from_path")) { - return get_script_instance()->call("generate_from_path", p_path); + return get_script_instance()->call("generate_from_path", p_path, p_size); } RES res = ResourceLoader::load(p_path); if (!res.is_valid()) return res; - return generate(res); + return generate(res, p_size); +} + +bool EditorResourcePreviewGenerator::should_generate_small_preview() const { + return false; } void EditorResourcePreviewGenerator::_bind_methods() { ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::BOOL, "handles", PropertyInfo(Variant::STRING, "type"))); - ClassDB::add_virtual_method(get_class_static(), MethodInfo(CLASS_INFO(Texture), "generate", PropertyInfo(Variant::OBJECT, "from", PROPERTY_HINT_RESOURCE_TYPE, "Resource"))); - ClassDB::add_virtual_method(get_class_static(), MethodInfo(CLASS_INFO(Texture), "generate_from_path", PropertyInfo(Variant::STRING, "path", PROPERTY_HINT_FILE))); + ClassDB::add_virtual_method(get_class_static(), MethodInfo(CLASS_INFO(Texture), "generate", PropertyInfo(Variant::OBJECT, "from", PROPERTY_HINT_RESOURCE_TYPE, "Resource"), PropertyInfo(Variant::VECTOR2, "size"))); + ClassDB::add_virtual_method(get_class_static(), MethodInfo(CLASS_INFO(Texture), "generate_from_path", PropertyInfo(Variant::STRING, "path", PROPERTY_HINT_FILE), PropertyInfo(Variant::VECTOR2, "size"))); } EditorResourcePreviewGenerator::EditorResourcePreviewGenerator() { @@ -85,7 +93,7 @@ void EditorResourcePreview::_thread_func(void *ud) { erp->_thread(); } -void EditorResourcePreview::_preview_ready(const String &p_str, const Ref<Texture> &p_texture, ObjectID id, const StringName &p_func, const Variant &p_ud) { +void EditorResourcePreview::_preview_ready(const String &p_str, const Ref<Texture> &p_texture, const Ref<Texture> &p_small_texture, ObjectID id, const StringName &p_func, const Variant &p_ud) { preview_mutex->lock(); @@ -103,6 +111,7 @@ void EditorResourcePreview::_preview_ready(const String &p_str, const Ref<Textur Item item; item.order = order++; item.preview = p_texture; + item.small_preview = p_small_texture; item.last_hash = hash; item.modified_time = modified_time; @@ -110,11 +119,10 @@ void EditorResourcePreview::_preview_ready(const String &p_str, const Ref<Textur preview_mutex->unlock(); - MessageQueue::get_singleton()->push_call(id, p_func, path, p_texture, p_ud); + MessageQueue::get_singleton()->push_call(id, p_func, path, p_texture, p_small_texture, p_ud); } -Ref<Texture> EditorResourcePreview::_generate_preview(const QueueItem &p_item, const String &cache_base) { - +void EditorResourcePreview::_generate_preview(Ref<ImageTexture> &r_texture, Ref<ImageTexture> &r_small_texture, const QueueItem &p_item, const String &cache_base) { String type; if (p_item.resource.is_valid()) @@ -122,40 +130,59 @@ Ref<Texture> EditorResourcePreview::_generate_preview(const QueueItem &p_item, c else type = ResourceLoader::get_resource_type(p_item.path); - if (type == "") - return Ref<Texture>(); //could not guess type + if (type == "") { + r_texture = Ref<ImageTexture>(); + r_small_texture = Ref<ImageTexture>(); + return; //could not guess type + } - Ref<Texture> generated; + int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size"); + thumbnail_size *= EDSCALE; - for (int i = 0; i < preview_generators.size(); i++) { + r_texture = Ref<ImageTexture>(); + r_small_texture = Ref<ImageTexture>(); + for (int i = 0; i < preview_generators.size(); i++) { if (!preview_generators[i]->handles(type)) continue; + + Ref<Texture> generated; if (p_item.resource.is_valid()) { - generated = preview_generators[i]->generate(p_item.resource); + generated = preview_generators[i]->generate(p_item.resource, Vector2(thumbnail_size, thumbnail_size)); } else { - generated = preview_generators[i]->generate_from_path(p_item.path); + generated = preview_generators[i]->generate_from_path(p_item.path, Vector2(thumbnail_size, thumbnail_size)); } + r_texture = generated; + if (r_texture.is_valid() && preview_generators[i]->should_generate_small_preview()) { + int small_thumbnail_size = EditorNode::get_singleton()->get_theme_base()->get_icon("Object", "EditorIcons")->get_width(); // Kind of a workaround to retreive the default icon size + small_thumbnail_size *= EDSCALE; + + Ref<Image> small_image = r_texture->get_data(); + small_image->resize(small_thumbnail_size, small_thumbnail_size, Image::INTERPOLATE_CUBIC); + r_small_texture.instance(); + r_small_texture->create_from_image(small_image); + } break; } if (!p_item.resource.is_valid()) { // cache the preview in case it's a resource on disk - if (generated.is_valid()) { - int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size"); - thumbnail_size *= EDSCALE; + if (r_texture.is_valid()) { //wow it generated a preview... save cache - ResourceSaver::save(cache_base + ".png", generated); + bool has_small_texture = r_small_texture.is_valid(); + ResourceSaver::save(cache_base + ".png", r_texture); + if (has_small_texture) { + ResourceSaver::save(cache_base + "_small.png", r_small_texture); + } FileAccess *f = FileAccess::open(cache_base + ".txt", FileAccess::WRITE); f->store_line(itos(thumbnail_size)); + f->store_line(itos(has_small_texture)); f->store_line(itos(FileAccess::get_modified_time(p_item.path))); f->store_line(FileAccess::get_md5(p_item.path)); memdelete(f); } } - - return generated; } void EditorResourcePreview::_thread() { @@ -177,7 +204,7 @@ void EditorResourcePreview::_thread() { path += ":" + itos(cache[item.path].last_hash); //keep last hash (see description of what this is in condition below) } - _preview_ready(path, cache[item.path].preview, item.id, item.function, item.userdata); + _preview_ready(path, cache[item.path].preview, cache[item.path].small_preview, item.id, item.function, item.userdata); preview_mutex->unlock(); } else { @@ -185,15 +212,17 @@ void EditorResourcePreview::_thread() { preview_mutex->unlock(); Ref<ImageTexture> texture; + Ref<ImageTexture> small_texture; int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size"); thumbnail_size *= EDSCALE; if (item.resource.is_valid()) { - texture = _generate_preview(item, String()); + _generate_preview(texture, small_texture, item, String()); + //adding hash to the end of path (should be ID:<objid>:<hash>) because of 5 argument limit to call_deferred - _preview_ready(item.path + ":" + itos(item.resource->hash_edited_version()), texture, item.id, item.function, item.userdata); + _preview_ready(item.path + ":" + itos(item.resource->hash_edited_version()), texture, small_texture, item.id, item.function, item.userdata); } else { @@ -207,12 +236,13 @@ void EditorResourcePreview::_thread() { FileAccess *f = FileAccess::open(file, FileAccess::READ); if (!f) { - //generate - texture = _generate_preview(item, cache_base); + // No cache found, generate + _generate_preview(texture, small_texture, item, cache_base); } else { uint64_t modtime = FileAccess::get_modified_time(item.path); int tsize = f->get_line().to_int64(); + bool has_small_texture = f->get_line().to_int(); uint64_t last_modtime = f->get_line().to_int64(); bool cache_valid = true; @@ -236,6 +266,7 @@ void EditorResourcePreview::_thread() { f = FileAccess::open(file, FileAccess::WRITE); f->store_line(itos(modtime)); + f->store_line(itos(has_small_texture)); f->store_line(md5); memdelete(f); } @@ -243,12 +274,12 @@ void EditorResourcePreview::_thread() { memdelete(f); } - //cache_valid = false; - if (cache_valid) { Ref<Image> img; img.instance(); + Ref<Image> small_img; + small_img.instance(); if (img->load(cache_base + ".png") != OK) { cache_valid = false; @@ -256,16 +287,24 @@ void EditorResourcePreview::_thread() { texture.instance(); texture->create_from_image(img, Texture::FLAG_FILTER); + + if (has_small_texture) { + if (small_img->load(cache_base + "_small.png") != OK) { + cache_valid = false; + } else { + small_texture.instance(); + small_texture->create_from_image(small_img, Texture::FLAG_FILTER); + } + } } } if (!cache_valid) { - texture = _generate_preview(item, cache_base); + _generate_preview(texture, small_texture, item, cache_base); } } - - _preview_ready(item.path, texture, item.id, item.function, item.userdata); + _preview_ready(item.path, texture, small_texture, item.id, item.function, item.userdata); } } @@ -287,7 +326,7 @@ void EditorResourcePreview::queue_edited_resource_preview(const Ref<Resource> &p if (cache.has(path_id) && cache[path_id].last_hash == p_res->hash_edited_version()) { cache[path_id].order = order++; - p_receiver->call_deferred(p_receiver_func, path_id, cache[path_id].preview, p_userdata); + p_receiver->call_deferred(p_receiver_func, path_id, cache[path_id].preview, cache[path_id].small_preview, p_userdata); preview_mutex->unlock(); return; } @@ -312,7 +351,7 @@ void EditorResourcePreview::queue_resource_preview(const String &p_path, Object preview_mutex->lock(); if (cache.has(p_path)) { cache[p_path].order = order++; - p_receiver->call_deferred(p_receiver_func, p_path, cache[p_path].preview, p_userdata); + p_receiver->call_deferred(p_receiver_func, p_path, cache[p_path].preview, cache[p_path].small_preview, p_userdata); preview_mutex->unlock(); return; } diff --git a/editor/editor_resource_preview.h b/editor/editor_resource_preview.h index 74841b1a1e..a3417cdf60 100644 --- a/editor/editor_resource_preview.h +++ b/editor/editor_resource_preview.h @@ -31,8 +31,8 @@ #ifndef EDITORRESOURCEPREVIEW_H #define EDITORRESOURCEPREVIEW_H -#include "os/semaphore.h" -#include "os/thread.h" +#include "core/os/semaphore.h" +#include "core/os/thread.h" #include "scene/main/node.h" #include "scene/resources/texture.h" @@ -63,8 +63,10 @@ protected: public: virtual bool handles(const String &p_type) const; - virtual Ref<Texture> generate(const RES &p_from) const; - virtual Ref<Texture> generate_from_path(const String &p_path) const; + virtual Ref<Texture> generate(const RES &p_from, const Size2 p_size) const; + virtual Ref<Texture> generate_from_path(const String &p_path, const Size2 p_size) const; + + virtual bool should_generate_small_preview() const; EditorResourcePreviewGenerator(); }; @@ -92,6 +94,7 @@ class EditorResourcePreview : public Node { struct Item { Ref<Texture> preview; + Ref<Texture> small_preview; int order; uint32_t last_hash; uint64_t modified_time; @@ -101,8 +104,8 @@ class EditorResourcePreview : public Node { Map<String, Item> cache; - void _preview_ready(const String &p_str, const Ref<Texture> &p_texture, ObjectID id, const StringName &p_func, const Variant &p_ud); - Ref<Texture> _generate_preview(const QueueItem &p_item, const String &cache_base); + void _preview_ready(const String &p_str, const Ref<Texture> &p_texture, const Ref<Texture> &p_small_texture, ObjectID id, const StringName &p_func, const Variant &p_ud); + void _generate_preview(Ref<ImageTexture> &r_texture, Ref<ImageTexture> &r_small_texture, const QueueItem &p_item, const String &cache_base); static void _thread_func(void *ud); void _thread(); diff --git a/editor/editor_run.cpp b/editor/editor_run.cpp index bbd18306a2..ad5cf49f3f 100644 --- a/editor/editor_run.cpp +++ b/editor/editor_run.cpp @@ -30,8 +30,8 @@ #include "editor_run.h" +#include "core/project_settings.h" #include "editor_settings.h" -#include "project_settings.h" EditorRun::Status EditorRun::get_status() const { @@ -196,8 +196,8 @@ Error EditorRun::run(const String &p_scene, const String p_custom_args, const Li void EditorRun::stop() { if (status != STATUS_STOP && pid != 0) { - const int max_wait_msec = GLOBAL_DEF("editor/stop_max_wait_msec", 10000); - OS::get_singleton()->kill(pid, max_wait_msec); + + OS::get_singleton()->kill(pid); } status = STATUS_STOP; diff --git a/editor/editor_run.h b/editor/editor_run.h index 8da607e6dc..df2324efd7 100644 --- a/editor/editor_run.h +++ b/editor/editor_run.h @@ -31,7 +31,7 @@ #ifndef EDITOR_RUN_H #define EDITOR_RUN_H -#include "os/os.h" +#include "core/os/os.h" #include "scene/main/node.h" class EditorRun { public: diff --git a/editor/editor_run_script.h b/editor/editor_run_script.h index 027fdd428d..892d5151a0 100644 --- a/editor/editor_run_script.h +++ b/editor/editor_run_script.h @@ -31,8 +31,8 @@ #ifndef EDITOR_RUN_SCRIPT_H #define EDITOR_RUN_SCRIPT_H +#include "core/reference.h" #include "editor_plugin.h" -#include "reference.h" class EditorNode; class EditorScript : public Reference { diff --git a/editor/editor_scale.cpp b/editor/editor_scale.cpp index 365ea95e3e..ba1607b408 100644 --- a/editor/editor_scale.cpp +++ b/editor/editor_scale.cpp @@ -30,7 +30,7 @@ #include "editor_scale.h" -#include "os/os.h" +#include "core/os/os.h" static float scale = 1.0; diff --git a/editor/editor_sectioned_inspector.cpp b/editor/editor_sectioned_inspector.cpp index 72050cd79b..9d3ab59116 100644 --- a/editor/editor_sectioned_inspector.cpp +++ b/editor/editor_sectioned_inspector.cpp @@ -1,3 +1,33 @@ +/*************************************************************************/ +/* editor_sectioned_inspector.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + #include "editor_sectioned_inspector.h" #include "editor_scale.h" class SectionedInspectorFilter : public Object { diff --git a/editor/editor_sectioned_inspector.h b/editor/editor_sectioned_inspector.h index 75b51a1581..30d5cd3038 100644 --- a/editor/editor_sectioned_inspector.h +++ b/editor/editor_sectioned_inspector.h @@ -1,3 +1,33 @@ +/*************************************************************************/ +/* editor_sectioned_inspector.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + #ifndef EDITOR_SECTIONED_INSPECTOR_H #define EDITOR_SECTIONED_INSPECTOR_H diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index 5d3c6dd087..2dec21fffb 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -30,6 +30,7 @@ #include "editor_settings.h" +#include "core/io/certs_compressed.gen.h" #include "core/io/compression.h" #include "core/io/config_file.h" #include "core/io/file_access_memory.h" @@ -484,6 +485,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { _initial_set("editors/2d/bone_outline_color", Color(0.35, 0.35, 0.35)); _initial_set("editors/2d/bone_outline_size", 2); _initial_set("editors/2d/keep_margins_when_changing_anchors", false); + _initial_set("editors/2d/viewport_border_color", Color(0.4, 0.4, 1.0, 0.4)); _initial_set("editors/2d/warped_mouse_panning", true); _initial_set("editors/2d/simple_spacebar_panning", false); _initial_set("editors/2d/scroll_to_pan", false); @@ -510,17 +512,16 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { _initial_set("filesystem/file_dialog/show_hidden_files", false); _initial_set("filesystem/file_dialog/display_mode", 0); hints["filesystem/file_dialog/display_mode"] = PropertyInfo(Variant::INT, "filesystem/file_dialog/display_mode", PROPERTY_HINT_ENUM, "Thumbnails,List"); + _initial_set("filesystem/file_dialog/thumbnail_size", 64); hints["filesystem/file_dialog/thumbnail_size"] = PropertyInfo(Variant::INT, "filesystem/file_dialog/thumbnail_size", PROPERTY_HINT_RANGE, "32,128,16"); - _initial_set("docks/filesystem/disable_split", false); - _initial_set("docks/filesystem/split_mode_minimum_height", 600); _initial_set("docks/filesystem/display_mode", 0); - hints["docks/filesystem/display_mode"] = PropertyInfo(Variant::INT, "docks/filesystem/display_mode", PROPERTY_HINT_ENUM, "Thumbnails,List"); + hints["docks/filesystem/display_mode"] = PropertyInfo(Variant::INT, "docks/filesystem/display_mode", PROPERTY_HINT_ENUM, "Tree only, Split"); _initial_set("docks/filesystem/thumbnail_size", 64); hints["docks/filesystem/thumbnail_size"] = PropertyInfo(Variant::INT, "docks/filesystem/thumbnail_size", PROPERTY_HINT_RANGE, "32,128,16"); - _initial_set("docks/filesystem/display_mode", 0); - hints["docks/filesystem/display_mode"] = PropertyInfo(Variant::INT, "docks/filesystem/display_mode", PROPERTY_HINT_ENUM, "Thumbnails,List"); + _initial_set("docks/filesystem/files_display_mode", 0); + hints["docks/filesystem/files_display_mode"] = PropertyInfo(Variant::INT, "docks/filesystem/files_display_mode", PROPERTY_HINT_ENUM, "Thumbnails,List"); _initial_set("docks/filesystem/always_show_folders", true); _initial_set("editors/animation/autorename_animation_tracks", true); @@ -947,6 +948,10 @@ void EditorSettings::setup_network() { _initial_set("network/debug/remote_port", port); add_property_hint(PropertyInfo(Variant::INT, "network/debug/remote_port", PROPERTY_HINT_RANGE, "1,65535,1")); + + // Editor SSL certificates override + _initial_set("network/ssl/editor_ssl_certificates", _SYSTEM_CERTS_PATH); + add_property_hint(PropertyInfo(Variant::STRING, "network/ssl/editor_ssl_certificates", PROPERTY_HINT_GLOBAL_FILE, "*.crt,*.pem")); } void EditorSettings::save() { @@ -1147,20 +1152,20 @@ Variant EditorSettings::get_project_metadata(const String &p_section, const Stri return cf->get_value(p_section, p_key, p_default); } -void EditorSettings::set_favorite_dirs(const Vector<String> &p_favorites_dirs) { +void EditorSettings::set_favorites(const Vector<String> &p_favorites) { - favorite_dirs = p_favorites_dirs; - FileAccess *f = FileAccess::open(get_project_settings_dir().plus_file("favorite_dirs"), FileAccess::WRITE); + favorites = p_favorites; + FileAccess *f = FileAccess::open(get_project_settings_dir().plus_file("favorites"), FileAccess::WRITE); if (f) { - for (int i = 0; i < favorite_dirs.size(); i++) - f->store_line(favorite_dirs[i]); + for (int i = 0; i < favorites.size(); i++) + f->store_line(favorites[i]); memdelete(f); } } -Vector<String> EditorSettings::get_favorite_dirs() const { +Vector<String> EditorSettings::get_favorites() const { - return favorite_dirs; + return favorites; } void EditorSettings::set_recent_dirs(const Vector<String> &p_recent_dirs) { @@ -1181,11 +1186,11 @@ Vector<String> EditorSettings::get_recent_dirs() const { void EditorSettings::load_favorites() { - FileAccess *f = FileAccess::open(get_project_settings_dir().plus_file("favorite_dirs"), FileAccess::READ); + FileAccess *f = FileAccess::open(get_project_settings_dir().plus_file("favorites"), FileAccess::READ); if (f) { String line = f->get_line().strip_edges(); while (line != "") { - favorite_dirs.push_back(line); + favorites.push_back(line); line = f->get_line().strip_edges(); } memdelete(f); @@ -1212,18 +1217,25 @@ bool EditorSettings::is_dark_theme() { void EditorSettings::list_text_editor_themes() { String themes = "Adaptive,Default,Custom"; + DirAccess *d = DirAccess::open(get_text_editor_themes_dir()); if (d) { + List<String> custom_themes; d->list_dir_begin(); String file = d->get_next(); while (file != String()) { if (file.get_extension() == "tet" && file.get_basename().to_lower() != "default" && file.get_basename().to_lower() != "adaptive" && file.get_basename().to_lower() != "custom") { - themes += "," + file.get_basename(); + custom_themes.push_back(file.get_basename()); } file = d->get_next(); } d->list_dir_end(); memdelete(d); + + custom_themes.sort(); + for (List<String>::Element *E = custom_themes.front(); E; E = E->next()) { + themes += "," + E->get(); + } } add_property_hint(PropertyInfo(Variant::STRING, "text_editor/theme/color_theme", PROPERTY_HINT_ENUM, themes)); } @@ -1466,8 +1478,8 @@ void EditorSettings::_bind_methods() { ClassDB::bind_method(D_METHOD("set_project_metadata", "section", "key", "data"), &EditorSettings::set_project_metadata); ClassDB::bind_method(D_METHOD("get_project_metadata", "section", "key", "default"), &EditorSettings::get_project_metadata, DEFVAL(Variant())); - ClassDB::bind_method(D_METHOD("set_favorite_dirs", "dirs"), &EditorSettings::set_favorite_dirs); - ClassDB::bind_method(D_METHOD("get_favorite_dirs"), &EditorSettings::get_favorite_dirs); + ClassDB::bind_method(D_METHOD("set_favorites", "dirs"), &EditorSettings::set_favorites); + ClassDB::bind_method(D_METHOD("get_favorites"), &EditorSettings::get_favorites); ClassDB::bind_method(D_METHOD("set_recent_dirs", "dirs"), &EditorSettings::set_recent_dirs); ClassDB::bind_method(D_METHOD("get_recent_dirs"), &EditorSettings::get_recent_dirs); diff --git a/editor/editor_settings.h b/editor/editor_settings.h index e5b61abf54..7b0de9617c 100644 --- a/editor/editor_settings.h +++ b/editor/editor_settings.h @@ -31,13 +31,13 @@ #ifndef EDITOR_SETTINGS_H #define EDITOR_SETTINGS_H -#include "object.h" +#include "core/object.h" #include "core/io/config_file.h" -#include "os/thread_safe.h" -#include "resource.h" +#include "core/os/thread_safe.h" +#include "core/resource.h" +#include "core/translation.h" #include "scene/gui/shortcut.h" -#include "translation.h" class EditorPlugin; @@ -107,7 +107,7 @@ private: String config_file_path; String project_config_dir; - Vector<String> favorite_dirs; + Vector<String> favorites; Vector<String> recent_dirs; bool save_changed_setting; @@ -173,8 +173,8 @@ public: void set_project_metadata(const String &p_section, const String &p_key, Variant p_data); Variant get_project_metadata(const String &p_section, const String &p_key, Variant p_default) const; - void set_favorite_dirs(const Vector<String> &p_favorites_dirs); - Vector<String> get_favorite_dirs() const; + void set_favorites(const Vector<String> &p_favorites); + Vector<String> get_favorites() const; void set_recent_dirs(const Vector<String> &p_recent_dirs); Vector<String> get_recent_dirs() const; void load_favorites(); diff --git a/editor/editor_spin_slider.cpp b/editor/editor_spin_slider.cpp index b2c9f9865a..b6e4375ce9 100644 --- a/editor/editor_spin_slider.cpp +++ b/editor/editor_spin_slider.cpp @@ -29,9 +29,9 @@ /*************************************************************************/ #include "editor_spin_slider.h" +#include "core/math/expression.h" +#include "core/os/input.h" #include "editor_scale.h" -#include "math/expression.h" -#include "os/input.h" String EditorSpinSlider::get_tooltip(const Point2 &p_pos) const { return rtos(get_value()); @@ -274,7 +274,7 @@ void EditorSpinSlider::_notification(int p_what) { update(); } if (p_what == NOTIFICATION_FOCUS_ENTER) { - /* Sorry, I dont like this, it makes navigating the different fields with arrows more difficult. + /* Sorry, I don't like this, it makes navigating the different fields with arrows more difficult. * Just press enter to edit. * if (Input::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT) && !value_input_just_closed) { _focus_entered(); diff --git a/editor/editor_sub_scene.cpp b/editor/editor_sub_scene.cpp index 056ee59860..7036a0ddaa 100644 --- a/editor/editor_sub_scene.cpp +++ b/editor/editor_sub_scene.cpp @@ -30,6 +30,7 @@ #include "editor_sub_scene.h" +#include "editor/editor_node.h" #include "scene/gui/margin_container.h" #include "scene/resources/packed_scene.h" @@ -84,9 +85,7 @@ void EditorSubScene::_fill_tree(Node *p_node, TreeItem *p_parent) { it->set_text(0, p_node->get_name()); it->set_editable(0, false); it->set_selectable(0, true); - if (has_icon(p_node->get_class(), "EditorIcons")) { - it->set_icon(0, get_icon(p_node->get_class(), "EditorIcons")); - } + it->set_icon(0, EditorNode::get_singleton()->get_object_icon(p_node, "Node")); for (int i = 0; i < p_node->get_child_count(); i++) { diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp index 7ed7b920d9..9e81051dc2 100644 --- a/editor/editor_themes.cpp +++ b/editor/editor_themes.cpp @@ -36,7 +36,6 @@ #include "editor_scale.h" #include "editor_settings.h" #include "modules/svg/image_loader_svg.h" -#include "time.h" static Ref<StyleBoxTexture> make_stylebox(Ref<Texture> p_texture, float p_left, float p_top, float p_right, float p_botton, float p_margin_left = -1, float p_margin_top = -1, float p_margin_right = -1, float p_margin_botton = -1, bool p_draw_center = true) { Ref<StyleBoxTexture> style(memnew(StyleBoxTexture)); @@ -82,12 +81,6 @@ static Ref<StyleBoxLine> make_line_stylebox(Color p_color, int p_thickness = 1, return style; } -static Ref<StyleBoxFlat> change_border_color(Ref<StyleBoxFlat> p_style, Color p_color) { - Ref<StyleBoxFlat> style = p_style->duplicate(); - style->set_border_color_all(p_color); - return style; -} - Ref<ImageTexture> editor_generate_icon(int p_index, bool p_convert_color, float p_scale = EDSCALE, bool p_force_filter = false) { Ref<ImageTexture> icon = memnew(ImageTexture); @@ -199,8 +192,6 @@ void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme = exceptions.push_back("StatusWarning"); exceptions.push_back("NodeWarning"); - clock_t begin_time = clock(); - ImageLoaderSVG::set_convert_colors(&dark_icon_color_dictionary); // generate icons @@ -235,8 +226,6 @@ void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme = } ImageLoaderSVG::set_convert_colors(NULL); - - clock_t end_time = clock(); #else print_line("SVG support disabled, editor icons won't be rendered."); #endif @@ -260,8 +249,6 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { bool use_gn_headers = EDITOR_DEF("interface/theme/use_graph_node_headers", false); - Color script_bg_color = EDITOR_DEF("text_editor/highlighting/background_color", Color(0, 0, 0, 0)); - Color preset_accent_color; Color preset_base_color; float preset_contrast; @@ -491,8 +478,8 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { style_tab_selected->set_bg_color(tab_color); Ref<StyleBoxFlat> style_tab_unselected = style_tab_selected->duplicate(); - style_tab_unselected->set_draw_center(false); - style_tab_unselected->set_border_width_all(0); + style_tab_unselected->set_bg_color(dark_color_1); + style_tab_unselected->set_border_color_all(dark_color_2); // Editor background theme->set_stylebox("Background", "EditorStyles", make_flat_stylebox(background_color, default_margin_size, default_margin_size, default_margin_size, default_margin_size)); @@ -945,6 +932,11 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { // TooltipPanel Ref<StyleBoxFlat> style_tooltip = style_popup->duplicate(); + float v = MAX(border_size * EDSCALE, 1.0); + style_tooltip->set_default_margin(MARGIN_LEFT, v); + style_tooltip->set_default_margin(MARGIN_TOP, v); + style_tooltip->set_default_margin(MARGIN_RIGHT, v); + style_tooltip->set_default_margin(MARGIN_BOTTOM, v); style_tooltip->set_bg_color(Color(mono_color.r, mono_color.g, mono_color.b, 0.9)); style_tooltip->set_border_width_all(border_width); style_tooltip->set_border_color_all(mono_color); @@ -1064,8 +1056,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { const float mono_value = mono_color.r; const Color alpha1 = Color(mono_value, mono_value, mono_value, 0.07); const Color alpha2 = Color(mono_value, mono_value, mono_value, 0.14); - const Color alpha3 = Color(mono_value, mono_value, mono_value, 0.5); - const Color alpha4 = Color(mono_value, mono_value, mono_value, 0.7); + const Color alpha3 = Color(mono_value, mono_value, mono_value, 0.7); // editor main color const Color main_color = Color::html(dark_theme ? "#57b3ff" : "#0480ff"); @@ -1099,9 +1090,9 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { const Color member_variable_color = main_color.linear_interpolate(mono_color, 0.6); const Color mark_color = Color(error_color.r, error_color.g, error_color.b, 0.3); const Color breakpoint_color = error_color; - const Color code_folding_color = alpha4; + const Color code_folding_color = alpha3; const Color search_result_color = alpha1; - const Color search_result_border_color = alpha4; + const Color search_result_border_color = alpha3; EditorSettings *setting = EditorSettings::get_singleton(); String text_editor_color_theme = setting->get("text_editor/theme/color_theme"); diff --git a/editor/export_template_manager.cpp b/editor/export_template_manager.cpp index 6c9d1568fa..52611367f6 100644 --- a/editor/export_template_manager.cpp +++ b/editor/export_template_manager.cpp @@ -30,14 +30,14 @@ #include "export_template_manager.h" +#include "core/io/json.h" +#include "core/io/zip_io.h" +#include "core/os/dir_access.h" #include "core/os/input.h" #include "core/os/keyboard.h" +#include "core/version.h" #include "editor_node.h" #include "editor_scale.h" -#include "io/json.h" -#include "io/zip_io.h" -#include "os/dir_access.h" -#include "version.h" void ExportTemplateManager::_update_template_list() { diff --git a/editor/file_type_cache.cpp b/editor/file_type_cache.cpp index 02e647b733..0e328247ac 100644 --- a/editor/file_type_cache.cpp +++ b/editor/file_type_cache.cpp @@ -30,8 +30,8 @@ #include "file_type_cache.h" -#include "os/file_access.h" -#include "project_settings.h" +#include "core/os/file_access.h" +#include "core/project_settings.h" FileTypeCache *FileTypeCache::singleton = NULL; diff --git a/editor/file_type_cache.h b/editor/file_type_cache.h index 33b50cb1c4..aa2d78f763 100644 --- a/editor/file_type_cache.h +++ b/editor/file_type_cache.h @@ -31,7 +31,7 @@ #ifndef FILE_TYPE_CACHE_H #define FILE_TYPE_CACHE_H -#include "object.h" +#include "core/object.h" class FileTypeCache : Object { diff --git a/editor/fileserver/SCsub b/editor/fileserver/SCsub index f1fa50148f..2b1e889fb0 100644 --- a/editor/fileserver/SCsub +++ b/editor/fileserver/SCsub @@ -1,5 +1,5 @@ #!/usr/bin/env python Import('env') -Export('env') + env.add_source_files(env.editor_sources, "*.cpp") diff --git a/editor/fileserver/editor_file_server.cpp b/editor/fileserver/editor_file_server.cpp index 28b1095256..27fe716855 100644 --- a/editor/fileserver/editor_file_server.cpp +++ b/editor/fileserver/editor_file_server.cpp @@ -31,7 +31,7 @@ #include "editor_file_server.h" #include "../editor_settings.h" -#include "io/marshalls.h" +#include "core/io/marshalls.h" //#define DEBUG_PRINT(m_p) print_line(m_p) //#define DEBUG_TIME(m_what) printf("MS: %s - %lu\n", m_what, OS::get_singleton()->get_ticks_usec()); @@ -330,7 +330,7 @@ void EditorFileServer::stop() { EditorFileServer::EditorFileServer() { - server = TCP_Server::create_ref(); + server.instance(); wait_mutex = Mutex::create(); quit = false; active = false; diff --git a/editor/fileserver/editor_file_server.h b/editor/fileserver/editor_file_server.h index d73c78ee70..8e32c3c82f 100644 --- a/editor/fileserver/editor_file_server.h +++ b/editor/fileserver/editor_file_server.h @@ -31,11 +31,11 @@ #ifndef EDITOR_FILE_SERVER_H #define EDITOR_FILE_SERVER_H -#include "io/file_access_network.h" -#include "io/packet_peer.h" -#include "io/tcp_server.h" -#include "object.h" -#include "os/thread.h" +#include "core/io/file_access_network.h" +#include "core/io/packet_peer.h" +#include "core/io/tcp_server.h" +#include "core/object.h" +#include "core/os/thread.h" class EditorFileServer : public Object { diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index cb38c2f85e..2c69909f23 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -30,62 +30,113 @@ #include "filesystem_dock.h" +#include "core/io/resource_loader.h" +#include "core/os/dir_access.h" +#include "core/os/file_access.h" #include "core/os/keyboard.h" +#include "core/os/os.h" +#include "core/project_settings.h" #include "editor_node.h" #include "editor_settings.h" -#include "io/resource_loader.h" -#include "os/dir_access.h" -#include "os/file_access.h" -#include "os/os.h" -#include "project_settings.h" #include "scene/main/viewport.h" +Ref<Texture> FileSystemDock::_get_tree_item_icon(EditorFileSystemDirectory *p_dir, int p_idx) { + Ref<Texture> file_icon; + if (!p_dir->get_file_import_is_valid(p_idx)) { + file_icon = get_icon("ImportFail", "EditorIcons"); + } else { + String file_type = p_dir->get_file_type(p_idx); + file_icon = (has_icon(file_type, "EditorIcons")) ? get_icon(file_type, "EditorIcons") : get_icon("File", "EditorIcons"); + } + return file_icon; +} + bool FileSystemDock::_create_tree(TreeItem *p_parent, EditorFileSystemDirectory *p_dir, Vector<String> &uncollapsed_paths) { - TreeItem *item = tree->create_item(p_parent); + bool parent_should_expand = false; + + // Create a tree item for the subdirectory + TreeItem *subdirectory_item = tree->create_item(p_parent); String dname = p_dir->get_name(); if (dname == "") dname = "res://"; - item->set_text(0, dname); - item->set_icon(0, get_icon("Folder", "EditorIcons")); - item->set_selectable(0, true); + subdirectory_item->set_text(0, dname); + subdirectory_item->set_icon(0, get_icon("Folder", "EditorIcons")); + subdirectory_item->set_selectable(0, true); String lpath = p_dir->get_path(); - if (lpath != "res://" && lpath.ends_with("/")) { - lpath = lpath.substr(0, lpath.length() - 1); - } - item->set_metadata(0, lpath); - if (lpath == path) { - item->select(0); + subdirectory_item->set_metadata(0, lpath); + if (path == lpath || ((display_mode_setting == DISPLAY_MODE_SETTING_SPLIT) && path.get_base_dir() == lpath)) { + subdirectory_item->select(0); } if ((path.begins_with(lpath) && path != lpath)) { - item->set_collapsed(false); + subdirectory_item->set_collapsed(false); } else { - bool is_collapsed = true; - for (int i = 0; i < uncollapsed_paths.size(); i++) { - if (lpath == uncollapsed_paths[i]) { - is_collapsed = false; - break; + subdirectory_item->set_collapsed(uncollapsed_paths.find(lpath) < 0); + } + if (searched_string.length() > 0 && dname.to_lower().find(searched_string) >= 0) { + parent_should_expand = true; + } + + // Create items for all subdirectories + for (int i = 0; i < p_dir->get_subdir_count(); i++) + parent_should_expand = (_create_tree(subdirectory_item, p_dir->get_subdir(i), uncollapsed_paths) || parent_should_expand); + + // Create all items for the files in the subdirectory + if (display_mode_setting == DISPLAY_MODE_SETTING_TREE_ONLY) { + for (int i = 0; i < p_dir->get_file_count(); i++) { + String file_name = p_dir->get_file(i); + + if (searched_string.length() > 0) { + if (file_name.to_lower().find(searched_string) < 0) { + // The seached string is not in the file name, we skip it + continue; + } else { + // We expand all parents + parent_should_expand = true; + } + } + + TreeItem *file_item = tree->create_item(subdirectory_item); + file_item->set_text(0, file_name); + file_item->set_icon(0, _get_tree_item_icon(p_dir, i)); + String file_metadata = lpath.plus_file(file_name); + file_item->set_metadata(0, file_metadata); + if (path == file_metadata) { + file_item->select(0); + file_item->set_as_cursor(0); } + Array udata; + udata.push_back(tree_update_id); + udata.push_back(file_item); + EditorResourcePreview::get_singleton()->queue_resource_preview(file_metadata, this, "_tree_thumbnail_done", udata); } - item->set_collapsed(is_collapsed); } - for (int i = 0; i < p_dir->get_subdir_count(); i++) - _create_tree(item, p_dir->get_subdir(i), uncollapsed_paths); + if (searched_string.length() > 0) { + if (parent_should_expand) { + subdirectory_item->set_collapsed(false); + } else if (dname != "res://") { + subdirectory_item->get_parent()->remove_child(subdirectory_item); + } + } - return true; + return parent_should_expand; } -void FileSystemDock::_update_tree(bool keep_collapse_state, bool p_uncollapse_root) { - +Vector<String> FileSystemDock::_compute_uncollapsed_paths() { + // Register currently collapsed paths Vector<String> uncollapsed_paths; - if (keep_collapse_state) { - TreeItem *root = tree->get_root(); - if (root) { - TreeItem *resTree = root->get_children()->get_next(); + TreeItem *root = tree->get_root(); + if (root) { + TreeItem *favorites_item = root->get_children(); + if (!favorites_item->is_collapsed()) { + uncollapsed_paths.push_back(favorites_item->get_metadata(0)); + } + TreeItem *resTree = root->get_children()->get_next(); + if (resTree) { Vector<TreeItem *> needs_check; needs_check.push_back(resTree); @@ -102,84 +153,126 @@ void FileSystemDock::_update_tree(bool keep_collapse_state, bool p_uncollapse_ro } } } + return uncollapsed_paths; +} + +void FileSystemDock::_update_tree(const Vector<String> p_uncollapsed_paths, bool p_uncollapse_root) { + // Recreate the tree tree->clear(); + tree_update_id++; updating_tree = true; - TreeItem *root = tree->create_item(); + + // Handles the favorites TreeItem *favorites = tree->create_item(root); favorites->set_icon(0, get_icon("Favorites", "EditorIcons")); favorites->set_text(0, TTR("Favorites:")); - favorites->set_selectable(0, false); + favorites->set_metadata(0, "Favorites"); + favorites->set_collapsed(p_uncollapsed_paths.find("Favorites") < 0); - Vector<String> favorite_paths = EditorSettings::get_singleton()->get_favorite_dirs(); - String res_path = "res://"; - Ref<Texture> folder_icon = get_icon("Folder", "EditorIcons"); + Vector<String> favorite_paths = EditorSettings::get_singleton()->get_favorites(); for (int i = 0; i < favorite_paths.size(); i++) { String fave = favorite_paths[i]; - if (!fave.begins_with(res_path)) + if (!fave.begins_with("res://")) continue; - TreeItem *ti = tree->create_item(favorites); - if (fave == res_path) - ti->set_text(0, "/"); - else - ti->set_text(0, fave.get_file()); - ti->set_icon(0, folder_icon); - ti->set_selectable(0, true); - ti->set_metadata(0, fave); + Ref<Texture> folder_icon = get_icon("Folder", "EditorIcons"); + + String text; + Ref<Texture> icon; + if (fave == "res://") { + text = "/"; + icon = folder_icon; + } else if (fave.ends_with("/")) { + text = fave.substr(0, fave.length() - 1).get_file(); + icon = folder_icon; + } else { + text = fave.get_file(); + int index; + EditorFileSystemDirectory *dir = EditorFileSystem::get_singleton()->find_file(fave, &index); + if (dir) { + icon = _get_tree_item_icon(dir, index); + } else { + icon = get_icon("File", "EditorIcons"); + } + } + + if (searched_string.length() == 0 || text.to_lower().find(searched_string) >= 0) { + TreeItem *ti = tree->create_item(favorites); + ti->set_text(0, text); + ti->set_icon(0, icon); + ti->set_tooltip(0, fave); + ti->set_selectable(0, true); + ti->set_metadata(0, fave); + if (!fave.ends_with("/")) { + Array udata; + udata.push_back(tree_update_id); + udata.push_back(ti); + EditorResourcePreview::get_singleton()->queue_resource_preview(fave, this, "_tree_thumbnail_done", udata); + } + } } + Vector<String> uncollapsed_paths = p_uncollapsed_paths; if (p_uncollapse_root) { uncollapsed_paths.push_back("res://"); } + // Create the remaining of the tree _create_tree(root, EditorFileSystem::get_singleton()->get_filesystem(), uncollapsed_paths); tree->ensure_cursor_is_visible(); updating_tree = false; } void FileSystemDock::_update_display_mode() { - - bool disable_split = bool(EditorSettings::get_singleton()->get("docks/filesystem/disable_split")); - bool compact_mode = get_size().height < int(EditorSettings::get_singleton()->get("docks/filesystem/split_mode_minimum_height")); - DisplayMode new_mode; - if (disable_split || compact_mode) { - new_mode = file_list_view ? DISPLAY_FILE_LIST_ONLY : DISPLAY_TREE_ONLY; + // Compute the new display mode + DisplayMode new_display_mode; + if (display_mode_setting == DISPLAY_MODE_SETTING_TREE_ONLY) { + new_display_mode = file_list_view ? DISPLAY_MODE_FILE_LIST_ONLY : DISPLAY_MODE_TREE_ONLY; } else { - new_mode = DISPLAY_SPLIT; + new_display_mode = DISPLAY_MODE_SPLIT; } - if (new_mode != display_mode) { - switch (new_mode) { - case DISPLAY_TREE_ONLY: + if (new_display_mode != display_mode || old_display_mode_setting != display_mode_setting) { + display_mode = new_display_mode; + old_display_mode_setting = display_mode_setting; + button_toggle_display_mode->set_pressed(display_mode_setting == DISPLAY_MODE_SETTING_SPLIT ? true : false); + switch (display_mode) { + case DISPLAY_MODE_TREE_ONLY: tree->show(); tree->set_v_size_flags(SIZE_EXPAND_FILL); - _update_tree(true); + if (display_mode_setting == DISPLAY_MODE_SETTING_TREE_ONLY) { + tree_search_box->show(); + } else { + tree_search_box->hide(); + } + _update_tree(_compute_uncollapsed_paths()); file_list_vb->hide(); break; - case DISPLAY_FILE_LIST_ONLY: + case DISPLAY_MODE_FILE_LIST_ONLY: tree->hide(); + tree_search_box->hide(); button_tree->show(); file_list_vb->show(); - _update_files(true); + _update_file_list(true); break; - case DISPLAY_SPLIT: + case DISPLAY_MODE_SPLIT: tree->show(); tree->set_v_size_flags(SIZE_EXPAND_FILL); button_tree->hide(); tree->ensure_cursor_is_visible(); - _update_tree(true); + tree_search_box->hide(); + _update_tree(_compute_uncollapsed_paths()); file_list_vb->show(); - _update_files(true); + _update_file_list(true); break; } - display_mode = new_mode; } } @@ -201,34 +294,36 @@ void FileSystemDock::_notification(int p_what) { String ei = "EditorIcons"; button_reload->set_icon(get_icon("Reload", ei)); - button_favorite->set_icon(get_icon("Favorites", ei)); - //button_instance->set_icon(get_icon("Add", ei)); - //button_open->set_icon(get_icon("Folder", ei)); + button_toggle_display_mode->set_icon(get_icon("Panels2", ei)); button_tree->set_icon(get_icon("Filesystem", ei)); _update_file_list_display_mode_button(); button_file_list_display_mode->connect("pressed", this, "_change_file_display"); - //file_options->set_icon( get_icon("Tools","ei")); - files->connect("item_activated", this, "_select_file"); + + files->connect("item_activated", this, "_file_list_activate_file"); button_hist_next->connect("pressed", this, "_fw_history"); button_hist_prev->connect("pressed", this, "_bw_history"); - search_box->set_right_icon(get_icon("Search", ei)); - search_box->set_clear_button_enabled(true); + tree_search_box->set_right_icon(get_icon("Search", ei)); + tree_search_box->set_clear_button_enabled(true); + file_list_search_box->set_right_icon(get_icon("Search", ei)); + file_list_search_box->set_clear_button_enabled(true); button_hist_next->set_icon(get_icon("Forward", ei)); button_hist_prev->set_icon(get_icon("Back", ei)); - button_show->set_icon(get_icon("GuiVisibilityVisible", "EditorIcons")); - file_options->connect("id_pressed", this, "_file_option"); - folder_options->connect("id_pressed", this, "_folder_option"); + file_list_popup->connect("id_pressed", this, "_file_list_rmb_option"); + tree_popup->connect("id_pressed", this, "_tree_rmb_option"); button_tree->connect("pressed", this, "_go_to_tree", varray(), CONNECT_DEFERRED); current_path->connect("text_entered", this, "navigate_to_path"); + display_mode_setting = DisplayModeSetting(int(EditorSettings::get_singleton()->get("docks/filesystem/display_mode"))); + always_show_folders = bool(EditorSettings::get_singleton()->get("docks/filesystem/always_show_folders")); + _update_display_mode(); if (EditorFileSystem::get_singleton()->is_scanning()) { _set_scanning_mode(); } else { - _update_tree(false, true); + _update_tree(Vector<String>(), true); } } break; @@ -245,7 +340,7 @@ void FileSystemDock::_notification(int p_what) { Dictionary dd = get_viewport()->gui_get_drag_data(); if (tree->is_visible_in_tree() && dd.has("type")) { if ((String(dd["type"]) == "files") || (String(dd["type"]) == "files_and_dirs") || (String(dd["type"]) == "resource")) { - tree->set_drop_mode_flags(Tree::DROP_MODE_ON_ITEM); + tree->set_drop_mode_flags(Tree::DROP_MODE_ON_ITEM | Tree::DROP_MODE_INBETWEEN); } else if ((String(dd["type"]) == "favorite")) { tree->set_drop_mode_flags(Tree::DROP_MODE_INBETWEEN); } @@ -261,21 +356,38 @@ void FileSystemDock::_notification(int p_what) { // Update icons String ei = "EditorIcons"; button_reload->set_icon(get_icon("Reload", ei)); - button_favorite->set_icon(get_icon("Favorites", ei)); + button_toggle_display_mode->set_icon(get_icon("Panels2", ei)); button_tree->set_icon(get_icon("Filesystem", ei)); button_hist_next->set_icon(get_icon("Forward", ei)); button_hist_prev->set_icon(get_icon("Back", ei)); - search_box->set_right_icon(get_icon("Search", ei)); - search_box->set_clear_button_enabled(true); + tree_search_box->set_right_icon(get_icon("Search", ei)); + tree_search_box->set_clear_button_enabled(true); + file_list_search_box->set_right_icon(get_icon("Search", ei)); + file_list_search_box->set_clear_button_enabled(true); + + bool should_update_files = false; - // Change size mode - int new_file_list_mode = int(EditorSettings::get_singleton()->get("docks/filesystem/display_mode")); + // Update file list display mode + int new_file_list_mode = int(EditorSettings::get_singleton()->get("docks/filesystem/files_display_mode")); if (new_file_list_mode != file_list_display_mode) { set_file_list_display_mode(new_file_list_mode); - } else { _update_file_list_display_mode_button(); - _update_files(true); + should_update_files = true; + } + + // Update display of files in tree + display_mode_setting = DisplayModeSetting(int(EditorSettings::get_singleton()->get("docks/filesystem/display_mode"))); + + // Update allways showfolders + bool new_always_show_folders = bool(EditorSettings::get_singleton()->get("docks/filesystem/always_show_folders")); + if (new_always_show_folders != always_show_folders) { + always_show_folders = new_always_show_folders; + should_update_files = true; + } + + if (should_update_files) { + _update_file_list(true); } // Change full tree mode @@ -285,74 +397,44 @@ void FileSystemDock::_notification(int p_what) { } } -void FileSystemDock::_dir_selected() { +void FileSystemDock::_tree_multi_selected(Object *p_item, int p_column, bool p_selected) { + // Update the import dock + import_dock_needs_update = true; + call_deferred("_update_import_dock"); - TreeItem *sel = tree->get_selected(); - if (!sel) + // Return if we don't select something new + if (!p_selected) return; - path = sel->get_metadata(0); - - bool found = false; - Vector<String> favorites = EditorSettings::get_singleton()->get_favorite_dirs(); - for (int i = 0; i < favorites.size(); i++) { - - if (favorites[i] == path) { - found = true; - break; - } - } - button_favorite->set_pressed(found); - current_path->set_text(path); - _push_to_history(); - - if (display_mode == DISPLAY_SPLIT) { - _update_files(false); - } -} - -void FileSystemDock::_favorites_pressed() { - - TreeItem *sel = tree->get_selected(); - if (!sel) + // Tree item selected + TreeItem *selected = tree->get_selected(); + if (!selected) return; - path = sel->get_metadata(0); - int idx = -1; - Vector<String> favorites = EditorSettings::get_singleton()->get_favorite_dirs(); - for (int i = 0; i < favorites.size(); i++) { - - if (favorites[i] == path) { - idx = i; - break; - } - } - - if (idx == -1) { - favorites.push_back(path); + TreeItem *favorites_item = tree->get_root()->get_children(); + if (selected->get_parent() == favorites_item) { + // Go to the favorites if we click in the favorites and the path has changed + path = "Favorites"; } else { - favorites.remove(idx); + path = selected->get_metadata(0); + // Note: the "Favorites" item also leads to this path } - EditorSettings::get_singleton()->set_favorite_dirs(favorites); - _update_tree(true); -} -void FileSystemDock::_show_current_scene_file() { + // Set the current path + _set_current_path_text(path); + _push_to_history(); - int index = EditorNode::get_editor_data().get_edited_scene(); - String path = EditorNode::get_editor_data().get_scene_path(index); - if (path != String()) { - navigate_to_path(path); + // Update the file list + if (!updating_tree && display_mode == DISPLAY_MODE_SPLIT) { + _update_file_list(false); } } String FileSystemDock::get_selected_path() const { - - TreeItem *sel = tree->get_selected(); - if (!sel) - return ""; - - return sel->get_metadata(0); + if (path.ends_with("/")) + return path; + else + return path.get_base_dir(); } String FileSystemDock::get_current_path() const { @@ -360,30 +442,55 @@ String FileSystemDock::get_current_path() const { return path; } +void FileSystemDock::_set_current_path_text(const String &p_path) { + if (p_path == "Favorites") { + current_path->set_text(TTR("Favorites")); + } else { + current_path->set_text(path); + } +} + void FileSystemDock::navigate_to_path(const String &p_path) { - // If the path is a file, do not only go to the directory in the tree, also select the file in the file list. - String file_name = ""; - DirAccess *dirAccess = DirAccess::open("res://"); - if (dirAccess->file_exists(p_path)) { - path = p_path.get_base_dir(); - file_name = p_path.get_file(); - } else if (dirAccess->dir_exists(p_path)) { + + if (p_path == "Favorites") { path = p_path; } else { - ERR_EXPLAIN(vformat(TTR("Cannot navigate to '%s' as it has not been found in the file system!"), p_path)); - ERR_FAIL(); + String target_path = p_path; + // If the path is a file, do not only go to the directory in the tree, also select the file in the file list. + if (target_path.ends_with("/")) { + target_path = target_path.substr(0, target_path.length() - 1); + } + DirAccess *dirAccess = DirAccess::open("res://"); + if (dirAccess->file_exists(p_path)) { + path = target_path; + } else if (dirAccess->dir_exists(p_path)) { + path = target_path + "/"; + } else { + ERR_EXPLAIN(vformat(TTR("Cannot navigate to '%s' as it has not been found in the file system!"), p_path)); + ERR_FAIL(); + } } - current_path->set_text(path); + _set_current_path_text(path); _push_to_history(); - if (display_mode == DISPLAY_SPLIT) { - _update_tree(true); - _update_files(false); - } else { - _go_to_file_list(); + if (display_mode == DISPLAY_MODE_SPLIT) { + if (path.ends_with("/") || path == "Favorites") { + _go_to_file_list(); + } + _update_tree(_compute_uncollapsed_paths()); + _update_file_list(false); + } else if (display_mode == DISPLAY_MODE_TREE_ONLY) { + if (path.ends_with("/") || path == "Favorites") { + _go_to_file_list(); + } else { + _update_tree(_compute_uncollapsed_paths()); + } + } else { // DISPLAY_MODE_FILE_LIST_ONLY + _update_file_list(true); } + String file_name = p_path.get_file(); if (!file_name.empty()) { for (int i = 0; i < files->get_item_count(); i++) { if (files->get_item_text(i) == file_name) { @@ -395,15 +502,32 @@ void FileSystemDock::navigate_to_path(const String &p_path) { } } -void FileSystemDock::_thumbnail_done(const String &p_path, const Ref<Texture> &p_preview, const Variant &p_udata) { +void FileSystemDock::_file_list_thumbnail_done(const String &p_path, const Ref<Texture> &p_preview, const Ref<Texture> &p_small_preview, const Variant &p_udata) { if ((file_list_vb->is_visible_in_tree() || path == p_path.get_base_dir()) && p_preview.is_valid()) { - Array uarr = p_udata; int idx = uarr[0]; String file = uarr[1]; - if (idx < files->get_item_count() && files->get_item_text(idx) == file && files->get_item_metadata(idx) == p_path) - files->set_item_icon(idx, p_preview); + if (idx < files->get_item_count() && files->get_item_text(idx) == file && files->get_item_metadata(idx) == p_path) { + if (file_list_display_mode == FILE_LIST_DISPLAY_LIST) { + if (p_small_preview.is_valid()) + files->set_item_icon(idx, p_small_preview); + } else { + files->set_item_icon(idx, p_preview); + } + } + } +} + +void FileSystemDock::_tree_thumbnail_done(const String &p_path, const Ref<Texture> &p_preview, const Ref<Texture> &p_small_preview, const Variant &p_udata) { + if (p_small_preview.is_valid()) { + Array uarr = p_udata; + if (tree_update_id == (int)uarr[0]) { + TreeItem *file_item = Object::cast_to<TreeItem>(uarr[1]); + if (file_item) { + file_item->set_icon(0, p_small_preview); + } + } } } @@ -424,9 +548,9 @@ void FileSystemDock::_change_file_display() { _update_file_list_display_mode_button(); - EditorSettings::get_singleton()->set("docks/filesystem/display_mode", file_list_display_mode); + EditorSettings::get_singleton()->set("docks/filesystem/files_display_mode", file_list_display_mode); - _update_files(true); + _update_file_list(true); } void FileSystemDock::_search(EditorFileSystemDirectory *p_path, List<FileInfo> *matches, int p_max_items) { @@ -438,12 +562,10 @@ void FileSystemDock::_search(EditorFileSystemDirectory *p_path, List<FileInfo> * _search(p_path->get_subdir(i), matches, p_max_items); } - String match = search_box->get_text().to_lower(); - for (int i = 0; i < p_path->get_file_count(); i++) { String file = p_path->get_file(i); - if (file.to_lower().find(match) != -1) { + if (file.to_lower().find(searched_string) != -1) { FileInfo fi; fi.name = file; @@ -459,14 +581,12 @@ void FileSystemDock::_search(EditorFileSystemDirectory *p_path, List<FileInfo> * } } -void FileSystemDock::_update_files(bool p_keep_selection) { +void FileSystemDock::_update_file_list(bool p_keep_selection) { + // Register the previously selected items Set<String> cselection; - if (p_keep_selection) { - for (int i = 0; i < files->get_item_count(); i++) { - if (files->is_selected(i)) cselection.insert(files->get_item_text(i)); } @@ -474,11 +594,10 @@ void FileSystemDock::_update_files(bool p_keep_selection) { files->clear(); - current_path->set_text(path); + _set_current_path_text(path); - EditorFileSystemDirectory *efd = EditorFileSystem::get_singleton()->get_filesystem_path(path); - if (!efd) - return; + String directory = path; + String file = ""; String ei = "EditorIcons"; int thumbnail_size = EditorSettings::get_singleton()->get("docks/filesystem/thumbnail_size"); @@ -487,13 +606,10 @@ void FileSystemDock::_update_files(bool p_keep_selection) { Ref<Texture> file_thumbnail; Ref<Texture> file_thumbnail_broken; - bool always_show_folders = EditorSettings::get_singleton()->get("docks/filesystem/always_show_folders"); - bool use_thumbnails = (file_list_display_mode == FILE_LIST_DISPLAY_THUMBNAILS); - bool use_folders = search_box->get_text().length() == 0 && ((display_mode == DISPLAY_FILE_LIST_ONLY || display_mode == DISPLAY_TREE_ONLY) || always_show_folders); if (use_thumbnails) { - + // Thumbnails mode files->set_max_columns(0); files->set_icon_mode(ItemList::ICON_MODE_TOP); files->set_fixed_column_width(thumbnail_size * 3 / 2); @@ -511,6 +627,7 @@ void FileSystemDock::_update_files(bool p_keep_selection) { } } else { + // No thumbnails files->set_icon_mode(ItemList::ICON_MODE_LEFT); files->set_max_columns(1); files->set_max_text_lines(1); @@ -518,55 +635,117 @@ void FileSystemDock::_update_files(bool p_keep_selection) { files->set_fixed_icon_size(Size2()); } - if (use_folders) { - Ref<Texture> folderIcon = (use_thumbnails) ? folder_thumbnail : get_icon("folder", "FileDialog"); + Ref<Texture> folder_icon = (use_thumbnails) ? folder_thumbnail : get_icon("folder", "FileDialog"); - if (path != "res://") { - files->add_item("..", folderIcon, true); + // Build the FileInfo list + List<FileInfo> filelist; + if (path == "Favorites") { + // Display the favorites + Vector<String> favorites = EditorSettings::get_singleton()->get_favorites(); + for (int i = 0; i < favorites.size(); i++) { + String favorite = favorites[i]; + String text; + Ref<Texture> icon; + if (favorite == "res://") { + text = "/"; + icon = folder_icon; + if (searched_string.length() == 0 || text.to_lower().find(searched_string) >= 0) { + files->add_item(text, icon, true); + files->set_item_metadata(files->get_item_count() - 1, favorite); + } + } else if (favorite.ends_with("/")) { + text = favorite.substr(0, favorite.length() - 1).get_file(); + icon = folder_icon; + if (searched_string.length() == 0 || text.to_lower().find(searched_string) >= 0) { + files->add_item(text, icon, true); + files->set_item_metadata(files->get_item_count() - 1, favorite); + } + } else { + int index; + EditorFileSystemDirectory *efd = EditorFileSystem::get_singleton()->find_file(favorite, &index); + + FileInfo fi; + fi.name = favorite.get_file(); + fi.path = favorite; + if (efd) { + fi.type = efd->get_file_type(index); + fi.import_broken = !efd->get_file_import_is_valid(index); + } else { + fi.type = ""; + fi.import_broken = true; + } + fi.import_status = 0; - String bd = path.get_base_dir(); - if (bd != "res://" && !bd.ends_with("/")) - bd += "/"; + if (searched_string.length() == 0 || fi.name.to_lower().find(searched_string) >= 0) { + filelist.push_back(fi); + } + } + } + } else { - files->set_item_metadata(files->get_item_count() - 1, bd); + // Get infos on the directory + file + if (directory.ends_with("/") && directory != "res://") { + directory = directory.substr(0, directory.length() - 1); + } + EditorFileSystemDirectory *efd = EditorFileSystem::get_singleton()->get_filesystem_path(directory); + if (!efd) { + directory = path.get_base_dir(); + file = path.get_file(); + efd = EditorFileSystem::get_singleton()->get_filesystem_path(directory); } + if (!efd) + return; - for (int i = 0; i < efd->get_subdir_count(); i++) { + if (searched_string.length() > 0) { + // Display the search results + _search(EditorFileSystem::get_singleton()->get_filesystem(), &filelist, 128); + } else { - String dname = efd->get_subdir(i)->get_name(); + if ((display_mode == DISPLAY_MODE_FILE_LIST_ONLY || display_mode == DISPLAY_MODE_TREE_ONLY) || always_show_folders) { + // Display folders in the list - files->add_item(dname, folderIcon, true); - files->set_item_metadata(files->get_item_count() - 1, path.plus_file(dname) + "/"); + if (directory != "res://") { + files->add_item("..", folder_icon, true); - if (cselection.has(dname)) - files->select(files->get_item_count() - 1, false); - } - } + String bd = directory.get_base_dir(); + if (bd != "res://" && !bd.ends_with("/")) + bd += "/"; - List<FileInfo> filelist; + files->set_item_metadata(files->get_item_count() - 1, bd); + files->set_item_selectable(files->get_item_count() - 1, false); + } - if (search_box->get_text().length() > 0) { + for (int i = 0; i < efd->get_subdir_count(); i++) { - _search(EditorFileSystem::get_singleton()->get_filesystem(), &filelist, 128); - filelist.sort(); - } else { + String dname = efd->get_subdir(i)->get_name(); - for (int i = 0; i < efd->get_file_count(); i++) { + files->add_item(dname, folder_icon, true); + files->set_item_metadata(files->get_item_count() - 1, directory.plus_file(dname) + "/"); - FileInfo fi; - fi.name = efd->get_file(i); - fi.path = path.plus_file(fi.name); - fi.type = efd->get_file_type(i); - fi.import_broken = !efd->get_file_import_is_valid(i); - fi.import_status = 0; + if (cselection.has(dname)) { + files->select(files->get_item_count() - 1, false); + } + } + } + + // Display the folder content + for (int i = 0; i < efd->get_file_count(); i++) { - filelist.push_back(fi); + FileInfo fi; + fi.name = efd->get_file(i); + fi.path = directory.plus_file(fi.name); + fi.type = efd->get_file_type(i); + fi.import_broken = !efd->get_file_import_is_valid(i); + fi.import_status = 0; + + filelist.push_back(fi); + } } filelist.sort(); } + // Fills the ItemList control node from the FileInfos String oi = "Object"; - for (List<FileInfo>::Element *E = filelist.front(); E; E = E->next()) { FileInfo *finfo = &(E->get()); String fname = finfo->name; @@ -578,6 +757,7 @@ void FileSystemDock::_update_files(bool p_keep_selection) { String tooltip = fname; + // Select the icons if (!finfo->import_broken) { type_icon = (has_icon(ftype, ei)) ? get_icon(ftype, ei) : get_icon(oi, ei); big_icon = file_thumbnail; @@ -587,28 +767,39 @@ void FileSystemDock::_update_files(bool p_keep_selection) { tooltip += "\n" + TTR("Status: Import of file failed. Please fix file and reimport manually."); } + // Add the item to the ItemList int item_index; if (use_thumbnails) { files->add_item(fname, big_icon, true); item_index = files->get_item_count() - 1; files->set_item_metadata(item_index, fpath); files->set_item_tag_icon(item_index, type_icon); - if (!finfo->import_broken) { - Array udata; - udata.resize(2); - udata[0] = item_index; - udata[1] = fname; - EditorResourcePreview::get_singleton()->queue_resource_preview(fpath, this, "_thumbnail_done", udata); - } + } else { files->add_item(fname, type_icon, true); item_index = files->get_item_count() - 1; files->set_item_metadata(item_index, fpath); } + // Generate the preview + if (!finfo->import_broken) { + Array udata; + udata.resize(2); + udata[0] = item_index; + udata[1] = fname; + EditorResourcePreview::get_singleton()->queue_resource_preview(fpath, this, "_file_list_thumbnail_done", udata); + } + + // Select the items if (cselection.has(fname)) files->select(item_index, false); + if (!p_keep_selection && file != "" && fname == file) { + files->select(item_index, true); + files->ensure_current_is_visible(); + } + + // Tooltip if (finfo->sources.size()) { for (int j = 0; j < finfo->sources.size(); j++) { tooltip += "\nSource: " + finfo->sources[j]; @@ -618,33 +809,49 @@ void FileSystemDock::_update_files(bool p_keep_selection) { } } -void FileSystemDock::_select_file(int p_idx) { - String fpath = files->get_item_metadata(p_idx); +void FileSystemDock::_select_file(const String p_path) { + String fpath = p_path; if (fpath.ends_with("/")) { if (fpath != "res://") { fpath = fpath.substr(0, fpath.length() - 1); } - navigate_to_path(fpath); - } else { + } else if (fpath != "Favorites") { if (ResourceLoader::get_resource_type(fpath) == "PackedScene") { editor->open_request(fpath); } else { editor->load_resource(fpath); } } + navigate_to_path(fpath); +} + +void FileSystemDock::_tree_activate_file() { + TreeItem *selected = tree->get_selected(); + if (selected) { + call_deferred("_select_file", selected->get_metadata(0)); + } +} + +void FileSystemDock::_file_list_activate_file(int p_idx) { + _select_file(files->get_item_metadata(p_idx)); } void FileSystemDock::_go_to_file_list() { - if (display_mode == DISPLAY_TREE_ONLY) { + if (display_mode == DISPLAY_MODE_TREE_ONLY) { + file_list_view = true; _update_display_mode(); } else { - bool collapsed = tree->get_selected()->is_collapsed(); - tree->get_selected()->set_collapsed(!collapsed); - _update_files(false); + TreeItem *selected = tree->get_selected(); + if (selected) { + bool collapsed = selected->is_collapsed(); + selected->set_collapsed(!collapsed); + } + _update_file_list(false); } } + void FileSystemDock::_go_to_tree() { file_list_view = false; @@ -655,7 +862,7 @@ void FileSystemDock::_go_to_tree() { void FileSystemDock::_preview_invalidated(const String &p_path) { - if (file_list_display_mode == FILE_LIST_DISPLAY_THUMBNAILS && p_path.get_base_dir() == path && search_box->get_text() == String() && file_list_vb->is_visible_in_tree()) { + if (file_list_display_mode == FILE_LIST_DISPLAY_THUMBNAILS && p_path.get_base_dir() == path && searched_string.length() == 0 && file_list_vb->is_visible_in_tree()) { for (int i = 0; i < files->get_item_count(); i++) { @@ -665,7 +872,7 @@ void FileSystemDock::_preview_invalidated(const String &p_path) { udata.resize(2); udata[0] = i; udata[1] = files->get_item_text(i); - EditorResourcePreview::get_singleton()->queue_resource_preview(p_path, this, "_thumbnail_done", udata); + EditorResourcePreview::get_singleton()->queue_resource_preview(p_path, this, "_file_list_thumbnail_done", udata); break; } } @@ -680,11 +887,11 @@ void FileSystemDock::_fs_changed() { split_box->show(); if (tree->is_visible()) { - _update_tree(true); + _update_tree(_compute_uncollapsed_paths()); } if (file_list_vb->is_visible()) { - _update_files(true); + _update_file_list(true); } set_process(false); @@ -721,16 +928,16 @@ void FileSystemDock::_bw_history() { void FileSystemDock::_update_history() { path = history[history_pos]; - current_path->set_text(path); + _set_current_path_text(path); if (tree->is_visible()) { - _update_tree(true); + _update_tree(_compute_uncollapsed_paths()); tree->grab_focus(); tree->ensure_cursor_is_visible(); } if (file_list_vb->is_visible()) { - _update_files(false); + _update_file_list(false); } button_hist_prev->set_disabled(history_pos == 0); @@ -968,23 +1175,23 @@ void FileSystemDock::_update_project_settings_after_move(const Map<String, Strin ProjectSettings::get_singleton()->save(); } -void FileSystemDock::_update_favorite_dirs_list_after_move(const Map<String, String> &p_renames) const { - - Vector<String> favorite_dirs = EditorSettings::get_singleton()->get_favorite_dirs(); - Vector<String> new_favorite_dirs; +void FileSystemDock::_update_favorites_list_after_move(const Map<String, String> &p_files_renames, const Map<String, String> &p_folders_renames) const { - for (int i = 0; i < favorite_dirs.size(); i++) { - String old_path = favorite_dirs[i] + "/"; + Vector<String> favorites = EditorSettings::get_singleton()->get_favorites(); + Vector<String> new_favorites; - if (p_renames.has(old_path)) { - String new_path = p_renames[old_path]; - new_favorite_dirs.push_back(new_path.substr(0, new_path.length() - 1)); + for (int i = 0; i < favorites.size(); i++) { + String old_path = favorites[i]; + if (p_folders_renames.has(old_path)) { + new_favorites.push_back(p_folders_renames[old_path]); + } else if (p_files_renames.has(old_path)) { + new_favorites.push_back(p_files_renames[old_path]); } else { - new_favorite_dirs.push_back(favorite_dirs[i]); + new_favorites.push_back(old_path); } } - EditorSettings::get_singleton()->set_favorite_dirs(new_favorite_dirs); + EditorSettings::get_singleton()->set_favorites(new_favorites); } void FileSystemDock::_make_dir_confirm() { @@ -998,9 +1205,13 @@ void FileSystemDock::_make_dir_confirm() { return; } - print_verbose("Making folder " + dir_name + " in " + path); + String directory = path; + if (!directory.ends_with("/")) { + directory = directory.get_base_dir(); + } + print_verbose("Making folder " + dir_name + " in " + directory); DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES); - Error err = da->change_dir(path); + Error err = da->change_dir(directory); if (err == OK) { err = da->make_dir(dir_name); } @@ -1051,7 +1262,7 @@ void FileSystemDock::_rename_operation_confirm() { _update_dependencies_after_move(file_renames); _update_resource_paths_after_move(file_renames); _update_project_settings_after_move(file_renames); - _update_favorite_dirs_list_after_move(folder_renames); + _update_favorites_list_after_move(file_renames, folder_renames); //Rescan everything print_verbose("FileSystem: calling rescan."); @@ -1144,111 +1355,212 @@ void FileSystemDock::_move_operation_confirm(const String &p_to_path, bool overw _update_dependencies_after_move(file_renames); _update_resource_paths_after_move(file_renames); _update_project_settings_after_move(file_renames); - _update_favorite_dirs_list_after_move(folder_renames); + _update_favorites_list_after_move(file_renames, folder_renames); print_verbose("FileSystem: calling rescan."); _rescan(); } } -void FileSystemDock::_file_option(int p_option) { +Vector<String> FileSystemDock::_tree_get_selected(bool remove_self_inclusion) { + // Build a list of selected items with the active one at the first position + Vector<String> selected_strings; + + TreeItem *favorites_item = tree->get_root()->get_children(); + TreeItem *active_selected = tree->get_selected(); + if (active_selected && active_selected != favorites_item) { + selected_strings.push_back(active_selected->get_metadata(0)); + } + + TreeItem *selected = tree->get_root(); + selected = tree->get_next_selected(selected); + while (selected) { + if (selected != active_selected && selected != favorites_item) { + selected_strings.push_back(selected->get_metadata(0)); + } + selected = tree->get_next_selected(selected); + } + + // Remove paths or files that are included into another + if (remove_self_inclusion && selected_strings.size() > 1) { + selected_strings.sort_custom<NaturalNoCaseComparator>(); + String last_path = ""; + for (int i = 0; i < selected_strings.size(); i++) { + if (last_path != "" && selected_strings[i].begins_with(last_path)) { + selected_strings.remove(i); + i--; + } + if (selected_strings[i].ends_with("/")) { + last_path = selected_strings[i]; + } + } + } + return selected_strings; +} + +void FileSystemDock::_tree_rmb_option(int p_option) { + + Vector<String> selected_strings = _tree_get_selected(); + + // Execute the current option switch (p_option) { - case FILE_SHOW_IN_EXPLORER: { + case FOLDER_EXPAND_ALL: + case FOLDER_COLLAPSE_ALL: { + // Expand or collapse the folder + if (selected_strings.size() == 1) { + bool is_collapsed = (p_option == FOLDER_COLLAPSE_ALL); + + Vector<TreeItem *> needs_check; + needs_check.push_back(tree->get_selected()); - String path = this->path; + while (needs_check.size()) { + needs_check[0]->set_collapsed(is_collapsed); - // first try to grab directory from selected file, so that it works for searched files - int idx = files->get_current(); + TreeItem *child = needs_check[0]->get_children(); + while (child) { + needs_check.push_back(child); + child = child->get_next(); + } - if (idx >= 0 && idx < files->get_item_count()) { - path = files->get_item_metadata(idx); - path = path.get_base_dir(); + needs_check.remove(0); + } } + } break; + default: { + _file_option(p_option, selected_strings); + } break; + } +} - path = ProjectSettings::get_singleton()->globalize_path(path); - OS::get_singleton()->shell_open(String("file://") + path); +void FileSystemDock::_file_list_rmb_option(int p_option) { + Vector<int> selected_id = files->get_selected_items(); + Vector<String> selected; + for (int i = 0; i < selected_id.size(); i++) { + selected.push_back(files->get_item_metadata(selected_id[i])); + } + _file_option(p_option, selected); +} + +void FileSystemDock::_file_option(int p_option, const Vector<String> p_selected) { + // The first one should be the active item + + switch (p_option) { + case FILE_SHOW_IN_EXPLORER: { + // Show the file / folder in the OS explorer + String fpath = path; + if (!fpath.ends_with("/")) { + fpath = fpath.get_base_dir(); + } + String dir = ProjectSettings::get_singleton()->globalize_path(fpath); + OS::get_singleton()->shell_open(String("file://") + dir); } break; + case FILE_OPEN: { - for (int i = 0; i < files->get_item_count(); i++) { - if (files->is_selected(i)) { - _select_file(i); - } + // Open the file + for (int i = 0; i < p_selected.size(); i++) { + _select_file(p_selected[i]); } } break; - case FILE_INSTANCE: { + case FILE_INSTANCE: { + // Instance all selected scenes Vector<String> paths; - - for (int i = 0; i < files->get_item_count(); i++) { - if (!files->is_selected(i)) - continue; - String fpath = files->get_item_metadata(i); + for (int i = 0; i < p_selected.size(); i++) { + String fpath = p_selected[i]; if (EditorFileSystem::get_singleton()->get_file_type(fpath) == "PackedScene") { paths.push_back(fpath); } } - if (!paths.empty()) { emit_signal("instance", paths); } } break; - case FILE_DEPENDENCIES: { - int idx = files->get_current(); - if (idx < 0 || idx >= files->get_item_count()) - break; - String fpath = files->get_item_metadata(idx); - deps_editor->edit(fpath); + case FILE_ADD_FAVORITE: { + // Add the files from favorites + Vector<String> favorites = EditorSettings::get_singleton()->get_favorites(); + for (int i = 0; i < p_selected.size(); i++) { + if (favorites.find(p_selected[i]) == -1) { + favorites.push_back(p_selected[i]); + } + } + EditorSettings::get_singleton()->set_favorites(favorites); + _update_tree(_compute_uncollapsed_paths()); } break; - case FILE_OWNERS: { - int idx = files->get_current(); - if (idx < 0 || idx >= files->get_item_count()) - break; - String fpath = files->get_item_metadata(idx); - owners_editor->show(fpath); + case FILE_REMOVE_FAVORITE: { + // Remove the files from favorites + Vector<String> favorites = EditorSettings::get_singleton()->get_favorites(); + for (int i = 0; i < p_selected.size(); i++) { + favorites.erase(p_selected[i]); + } + EditorSettings::get_singleton()->set_favorites(favorites); + _update_tree(_compute_uncollapsed_paths()); + if (path == "Favorites") + _update_file_list(true); } break; + + case FILE_DEPENDENCIES: { + // Checkout the file dependencies + if (!p_selected.empty()) { + String fpath = p_selected[0]; + deps_editor->edit(fpath); + } + } break; + + case FILE_OWNERS: { + // Checkout the file owners + if (!p_selected.empty()) { + String fpath = p_selected[0]; + owners_editor->show(fpath); + } + } break; + case FILE_MOVE: { + // Move the files to a given location to_move.clear(); - for (int i = 0; i < files->get_item_count(); i++) { - if (!files->is_selected(i)) - continue; - - String fpath = files->get_item_metadata(i); - to_move.push_back(FileOrFolder(fpath, !fpath.ends_with("/"))); + for (int i = 0; i < p_selected.size(); i++) { + String fpath = p_selected[i]; + if (fpath != "res://") { + to_move.push_back(FileOrFolder(fpath, !fpath.ends_with("/"))); + } } if (to_move.size() > 0) { move_dialog->popup_centered_ratio(); } } break; - case FILE_RENAME: { - int idx = files->get_current(); - if (idx < 0 || idx >= files->get_item_count()) - break; - to_rename.path = files->get_item_metadata(idx); - to_rename.is_file = !to_rename.path.ends_with("/"); - if (to_rename.is_file) { - String name = to_rename.path.get_file(); - rename_dialog->set_title(TTR("Renaming file:") + " " + name); - rename_dialog_text->set_text(name); - rename_dialog_text->select(0, name.find_last(".")); - } else { - String name = to_rename.path.substr(0, to_rename.path.length() - 1).get_file(); - rename_dialog->set_title(TTR("Renaming folder:") + " " + name); - rename_dialog_text->set_text(name); - rename_dialog_text->select(0, name.length()); + case FILE_RENAME: { + // Rename the active file + if (!p_selected.empty()) { + to_rename.path = p_selected[0]; + if (to_rename.path != "res://") { + to_rename.is_file = !to_rename.path.ends_with("/"); + if (to_rename.is_file) { + String name = to_rename.path.get_file(); + rename_dialog->set_title(TTR("Renaming file:") + " " + name); + rename_dialog_text->set_text(name); + rename_dialog_text->select(0, name.find_last(".")); + } else { + String name = to_rename.path.substr(0, to_rename.path.length() - 1).get_file(); + rename_dialog->set_title(TTR("Renaming folder:") + " " + name); + rename_dialog_text->set_text(name); + rename_dialog_text->select(0, name.length()); + } + rename_dialog->popup_centered_minsize(Size2(250, 80) * EDSCALE); + rename_dialog_text->grab_focus(); + } } - rename_dialog->popup_centered_minsize(Size2(250, 80) * EDSCALE); - rename_dialog_text->grab_focus(); } break; + case FILE_REMOVE: { + // Remove the selected files Vector<String> remove_files; Vector<String> remove_folders; - for (int i = 0; i < files->get_item_count(); i++) { - String fpath = files->get_item_metadata(i); - if (files->is_selected(i) && fpath != "res://") { + for (int i = 0; i < p_selected.size(); i++) { + String fpath = p_selected[i]; + if (fpath != "res://") { if (fpath.ends_with("/")) { remove_folders.push_back(fpath); } else { @@ -1259,166 +1571,77 @@ void FileSystemDock::_file_option(int p_option) { if (remove_files.size() + remove_folders.size() > 0) { remove_dialog->show(remove_folders, remove_files); - //1) find if used - //2) warn } } break; - case FILE_DUPLICATE: { - int idx = files->get_current(); - if (idx < 0 || idx >= files->get_item_count()) - break; - to_duplicate.path = files->get_item_metadata(idx); - to_duplicate.is_file = !to_duplicate.path.ends_with("/"); - if (to_duplicate.is_file) { - String name = to_duplicate.path.get_file(); - duplicate_dialog->set_title(TTR("Duplicating file:") + " " + name); - duplicate_dialog_text->set_text(name); - duplicate_dialog_text->select(0, name.find_last(".")); - } else { - String name = to_duplicate.path.substr(0, to_duplicate.path.length() - 1).get_file(); - duplicate_dialog->set_title(TTR("Duplicating folder:") + " " + name); - duplicate_dialog_text->set_text(name); - duplicate_dialog_text->select(0, name.length()); + case FILE_DUPLICATE: { + // Duplicate the selected files + for (int i = 0; i < p_selected.size(); i++) { + to_duplicate.path = p_selected[i]; + to_duplicate.is_file = !to_duplicate.path.ends_with("/"); + if (to_duplicate.is_file) { + String name = to_duplicate.path.get_file(); + duplicate_dialog->set_title(TTR("Duplicating file:") + " " + name); + duplicate_dialog_text->set_text(name); + duplicate_dialog_text->select(0, name.find_last(".")); + } else { + String name = to_duplicate.path.substr(0, to_duplicate.path.length() - 1).get_file(); + duplicate_dialog->set_title(TTR("Duplicating folder:") + " " + name); + duplicate_dialog_text->set_text(name); + duplicate_dialog_text->select(0, name.length()); + } + duplicate_dialog->popup_centered_minsize(Size2(250, 80) * EDSCALE); + duplicate_dialog_text->grab_focus(); } - duplicate_dialog->popup_centered_minsize(Size2(250, 80) * EDSCALE); - duplicate_dialog_text->grab_focus(); } break; + case FILE_INFO: { } break; - case FILE_REIMPORT: { + case FILE_REIMPORT: { + // Reimport all selected files Vector<String> reimport; - for (int i = 0; i < files->get_item_count(); i++) { - - if (!files->is_selected(i)) - continue; - - String fpath = files->get_item_metadata(i); - reimport.push_back(fpath); + for (int i = 0; i < p_selected.size(); i++) { + reimport.push_back(p_selected[i]); } ERR_FAIL_COND(reimport.size() == 0); - /* - Ref<ResourceImportMetadata> rimd = ResourceLoader::load_import_metadata(reimport[0]); - ERR_FAIL_COND(!rimd.is_valid()); - String editor=rimd->get_editor(); - - if (editor.begins_with("texture_")) { //compatibility fix for old texture format - editor="texture"; - } - - Ref<EditorImportPlugin> rimp = EditorImportExport::get_singleton()->get_import_plugin_by_name(editor); - ERR_FAIL_COND(!rimp.is_valid()); - - if (reimport.size()==1) { - rimp->import_dialog(reimport[0]); - } else { - rimp->reimport_multiple_files(reimport); - - } - */ } break; + case FILE_NEW_FOLDER: { + // Create a new folder make_dir_dialog_text->set_text("new folder"); make_dir_dialog_text->select_all(); make_dir_dialog->popup_centered_minsize(Size2(250, 80) * EDSCALE); make_dir_dialog_text->grab_focus(); } break; + case FILE_NEW_SCRIPT: { - String tarDir = path; - if (tarDir != "res://" && !tarDir.ends_with("/")) { - tarDir += "/"; + // Create a new script + String fpath = path; + if (!fpath.ends_with("/")) { + fpath = fpath.get_base_dir(); } - - make_script_dialog_text->config("Node", tarDir + "new_script.gd"); + make_script_dialog_text->config("Node", fpath + "new_script.gd", false); make_script_dialog_text->popup_centered(Size2(300, 300) * EDSCALE); } break; + case FILE_COPY_PATH: { - int idx = files->get_current(); - if (idx < 0 || idx >= files->get_item_count()) - break; - String fpath = files->get_item_metadata(idx); - OS::get_singleton()->set_clipboard(fpath); + // Copy the file path + if (!p_selected.empty()) { + String fpath = p_selected[0]; + OS::get_singleton()->set_clipboard(fpath); + } } break; + case FILE_NEW_RESOURCE: { + // Create a new resource new_resource_dialog->popup_create(true); } break; } } -void FileSystemDock::_folder_option(int p_option) { - - TreeItem *selected = tree->get_selected(); - - switch (p_option) { - case FOLDER_EXPAND_ALL: - case FOLDER_COLLAPSE_ALL: { - bool is_collapsed = (p_option == FOLDER_COLLAPSE_ALL); - Vector<TreeItem *> needs_check; - needs_check.push_back(selected); - - while (needs_check.size()) { - needs_check[0]->set_collapsed(is_collapsed); - - TreeItem *child = needs_check[0]->get_children(); - while (child) { - needs_check.push_back(child); - child = child->get_next(); - } - - needs_check.remove(0); - } - } break; - case FOLDER_MOVE: { - to_move.clear(); - String fpath = selected->get_metadata(tree->get_selected_column()); - if (fpath != "res://") { - fpath = fpath.ends_with("/") ? fpath.substr(0, fpath.length() - 1) : fpath; - to_move.push_back(FileOrFolder(fpath, false)); - move_dialog->popup_centered_ratio(); - } - } break; - case FOLDER_RENAME: { - to_rename.path = selected->get_metadata(tree->get_selected_column()); - to_rename.is_file = false; - if (to_rename.path != "res://") { - String name = to_rename.path.ends_with("/") ? to_rename.path.substr(0, to_rename.path.length() - 1).get_file() : to_rename.path.get_file(); - rename_dialog->set_title(TTR("Renaming folder:") + " " + name); - rename_dialog_text->set_text(name); - rename_dialog_text->select(0, name.length()); - rename_dialog->popup_centered_minsize(Size2(250, 80) * EDSCALE); - rename_dialog_text->grab_focus(); - } - } break; - case FOLDER_REMOVE: { - Vector<String> remove_folders; - Vector<String> remove_files; - String fpath = selected->get_metadata(tree->get_selected_column()); - if (fpath != "res://") { - remove_folders.push_back(fpath); - remove_dialog->show(remove_folders, remove_files); - } - } break; - case FOLDER_NEW_FOLDER: { - make_dir_dialog_text->set_text("new folder"); - make_dir_dialog_text->select_all(); - make_dir_dialog->popup_centered_minsize(Size2(250, 80) * EDSCALE); - make_dir_dialog_text->grab_focus(); - } break; - case FOLDER_COPY_PATH: { - String fpath = selected->get_metadata(tree->get_selected_column()); - OS::get_singleton()->set_clipboard(fpath); - } break; - case FOLDER_SHOW_IN_EXPLORER: { - String fpath = selected->get_metadata(tree->get_selected_column()); - String dir = ProjectSettings::get_singleton()->globalize_path(fpath); - OS::get_singleton()->shell_open(String("file://") + dir); - } break; - } -} - void FileSystemDock::_resource_created() const { Object *c = new_resource_dialog->instance_selected(); @@ -1431,38 +1654,39 @@ void FileSystemDock::_resource_created() const { RES current_res = RES(r); - editor->save_resource_as(current_res, path); -} - -void FileSystemDock::_dir_rmb_pressed(const Vector2 &p_pos) { - folder_options->clear(); - folder_options->set_size(Size2(1, 1)); + String fpath = path; + if (!fpath.ends_with("/")) { + fpath = fpath.get_base_dir(); + } - folder_options->add_item(TTR("Expand all"), FOLDER_EXPAND_ALL); - folder_options->add_item(TTR("Collapse all"), FOLDER_COLLAPSE_ALL); + editor->save_resource_as(current_res, fpath); +} - TreeItem *item = tree->get_selected(); - if (item) { - String fpath = item->get_metadata(tree->get_selected_column()); - folder_options->add_separator(); - folder_options->add_item(TTR("Copy Path"), FOLDER_COPY_PATH); - if (fpath != "res://") { - folder_options->add_item(TTR("Rename..."), FOLDER_RENAME); - folder_options->add_item(TTR("Move To..."), FOLDER_MOVE); - folder_options->add_item(TTR("Delete"), FOLDER_REMOVE); - } - folder_options->add_separator(); - folder_options->add_item(TTR("New Folder..."), FOLDER_NEW_FOLDER); - folder_options->add_item(TTR("Open In File Manager"), FOLDER_SHOW_IN_EXPLORER); +void FileSystemDock::_search_changed(const String &p_text, const Control *p_from) { + if (searched_string.length() == 0 && p_text.length() > 0) { + // Register the uncollapsed paths before they change + uncollapsed_paths_before_search = _compute_uncollapsed_paths(); } - folder_options->set_position(tree->get_global_position() + p_pos); - folder_options->popup(); -} -void FileSystemDock::_search_changed(const String &p_text) { + searched_string = p_text.to_lower(); + + if (p_from == tree_search_box) + file_list_search_box->set_text(searched_string); + else // file_list_search_box + tree_search_box->set_text(searched_string); - if (file_list_vb->is_visible()) - _update_files(false); + switch (display_mode) { + case DISPLAY_MODE_FILE_LIST_ONLY: { + _update_file_list(false); + } break; + case DISPLAY_MODE_TREE_ONLY: { + _update_tree(searched_string.length() == 0 ? uncollapsed_paths_before_search : Vector<String>()); + } break; + case DISPLAY_MODE_SPLIT: { + _update_file_list(false); + _update_tree(searched_string.length() == 0 ? uncollapsed_paths_before_search : Vector<String>()); + } break; + } } void FileSystemDock::_rescan() { @@ -1471,20 +1695,25 @@ void FileSystemDock::_rescan() { EditorFileSystem::get_singleton()->scan(); } +void FileSystemDock::_toggle_split_mode(bool p_active) { + display_mode_setting = p_active ? DISPLAY_MODE_SETTING_SPLIT : DISPLAY_MODE_SETTING_TREE_ONLY; + EditorSettings::get_singleton()->set("docks/filesystem/display_mode", int(display_mode_setting)); + _update_display_mode(); +} + void FileSystemDock::fix_dependencies(const String &p_for_file) { deps_editor->edit(p_for_file); } void FileSystemDock::focus_on_filter() { - if (display_mode == DISPLAY_FILE_LIST_ONLY && tree->is_visible()) { + if (display_mode == DISPLAY_MODE_FILE_LIST_ONLY && tree->is_visible()) { // Tree mode, switch to files list with search box tree->hide(); file_list_vb->show(); - button_favorite->hide(); } - search_box->grab_focus(); + file_list_search_box->grab_focus(); } void FileSystemDock::set_file_list_display_mode(int p_mode) { @@ -1497,33 +1726,49 @@ void FileSystemDock::set_file_list_display_mode(int p_mode) { } Variant FileSystemDock::get_drag_data_fw(const Point2 &p_point, Control *p_from) { - bool is_favorite = false; + bool all_favorites = true; + bool all_not_favorites = true; + Vector<String> paths; if (p_from == tree) { - TreeItem *selected = tree->get_selected(); - if (!selected) - return Variant(); - - String folder = selected->get_metadata(0); - if (folder == String()) - return Variant(); + // Check if the first selected is in favorite + TreeItem *selected = tree->get_next_selected(tree->get_root()); + while (selected) { + TreeItem *favorites_item = tree->get_root()->get_children(); + if (selected == favorites_item) { + // The "Favorites" item is not draggable + return Variant(); + } - paths.push_back(folder.ends_with("/") ? folder : (folder + "/")); - is_favorite = selected->get_parent() != NULL && tree->get_root()->get_children() == selected->get_parent(); + bool is_favorite = selected->get_parent() != NULL && tree->get_root()->get_children() == selected->get_parent(); + all_favorites &= is_favorite; + all_not_favorites &= !is_favorite; + selected = tree->get_next_selected(selected); + } + if (all_favorites) { + paths = _tree_get_selected(false); + } else { + paths = _tree_get_selected(); + } } else if (p_from == files) { for (int i = 0; i < files->get_item_count(); i++) { if (files->is_selected(i)) { paths.push_back(files->get_item_metadata(i)); } } + all_favorites = false; + all_not_favorites = true; } if (paths.empty()) return Variant(); + if (!all_favorites && !all_not_favorites) + return Variant(); + Dictionary drag_data = EditorNode::get_singleton()->drag_files_and_dirs(paths, p_from); - if (is_favorite) { + if (all_favorites) { drag_data["type"] = "favorite"; } return drag_data; @@ -1535,34 +1780,46 @@ bool FileSystemDock::can_drop_data_fw(const Point2 &p_point, const Variant &p_da if (drag_data.has("type") && String(drag_data["type"]) == "favorite") { - //moving favorite around + // Moving favorite around TreeItem *ti = tree->get_item_at_position(p_point); if (!ti) return false; - int what = tree->get_drop_section_at_position(p_point); + int drop_section = tree->get_drop_section_at_position(p_point); + TreeItem *favorites_item = tree->get_root()->get_children(); + + TreeItem *resources_item = favorites_item->get_next(); - if (ti == tree->get_root()->get_children()) { - return (what == 1); //the parent, first fav + if (ti == favorites_item) { + return (drop_section == 1); // The parent, first fav } - if (ti->get_parent() && tree->get_root()->get_children() == ti->get_parent()) { - return true; // a favorite + if (ti->get_parent() && favorites_item == ti->get_parent()) { + return true; // A favorite } - - if (ti == tree->get_root()->get_children()->get_next()) { - return (what == -1); //the tree, last fav + if (ti == resources_item) { + return (drop_section == -1); // The tree, last fav } return false; } if (drag_data.has("type") && String(drag_data["type"]) == "resource") { - String to_dir = _get_drag_target_folder(p_point, p_from); + // Move resources + String to_dir; + bool favorite; + _get_drag_target_folder(to_dir, favorite, p_point, p_from); return !to_dir.empty(); } if (drag_data.has("type") && (String(drag_data["type"]) == "files" || String(drag_data["type"]) == "files_and_dirs")) { - String to_dir = _get_drag_target_folder(p_point, p_from); + // Move files or dir + String to_dir; + bool favorite; + _get_drag_target_folder(to_dir, favorite, p_point, p_from); + + if (favorite) + return true; + if (to_dir.empty()) return false; @@ -1587,71 +1844,70 @@ void FileSystemDock::drop_data_fw(const Point2 &p_point, const Variant &p_data, return; Dictionary drag_data = p_data; - if (drag_data.has("type") && String(drag_data["type"]) == "favorite") { + Vector<String> dirs = EditorSettings::get_singleton()->get_favorites(); - //moving favorite around + if (drag_data.has("type") && String(drag_data["type"]) == "favorite") { + // Moving favorite around TreeItem *ti = tree->get_item_at_position(p_point); if (!ti) return; + int drop_section = tree->get_drop_section_at_position(p_point); + int drop_position; Vector<String> files = drag_data["files"]; - - ERR_FAIL_COND(files.size() != 1); - - String swap = files[0]; - if (swap != "res://" && swap.ends_with("/")) { - swap = swap.substr(0, swap.length() - 1); - } - - int what = tree->get_drop_section_at_position(p_point); - - TreeItem *swap_item = NULL; - - if (ti == tree->get_root()->get_children()) { - swap_item = tree->get_root()->get_children()->get_children(); - - } else if (ti->get_parent() && tree->get_root()->get_children() == ti->get_parent()) { - if (what == -1) { - swap_item = ti; - } else { - swap_item = ti->get_next(); + TreeItem *favorites_item = tree->get_root()->get_children(); + TreeItem *resources_item = favorites_item->get_next(); + + if (ti == favorites_item) { + // Drop on the favorite folder + drop_position = 0; + } else if (ti == resources_item) { + // Drop on the resouce item + drop_position = dirs.size(); + } else { + // Drop in the list + drop_position = dirs.find(ti->get_metadata(0)); + if (drop_section == 1) { + drop_position++; } } - String swap_with; - - if (swap_item) { - swap_with = swap_item->get_metadata(0); - if (swap_with != "res://" && swap_with.ends_with("/")) { - swap_with = swap_with.substr(0, swap_with.length() - 1); + // Remove dragged favorites + Vector<int> to_remove; + int offset = 0; + for (int i = 0; i < files.size(); i++) { + int to_remove_pos = dirs.find(files[i]); + to_remove.push_back(to_remove_pos); + if (to_remove_pos < drop_position) { + offset++; } } + drop_position -= offset; + to_remove.sort(); + for (int i = 0; i < to_remove.size(); i++) { + dirs.remove(to_remove[i] - i); + } - if (swap == swap_with) - return; - - Vector<String> dirs = EditorSettings::get_singleton()->get_favorite_dirs(); - - ERR_FAIL_COND(dirs.find(swap) == -1); - ERR_FAIL_COND(swap_with != String() && dirs.find(swap_with) == -1); - - dirs.erase(swap); - - if (swap_with == String()) { - dirs.push_back(swap); - } else { - int idx = dirs.find(swap_with); - dirs.insert(idx, swap); + // Re-add them at the right position + for (int i = 0; i < files.size(); i++) { + dirs.insert(drop_position, files[i]); + drop_position++; } - EditorSettings::get_singleton()->set_favorite_dirs(dirs); - _update_tree(true); + EditorSettings::get_singleton()->set_favorites(dirs); + _update_tree(_compute_uncollapsed_paths()); + + if (display_mode == DISPLAY_MODE_SPLIT && path == "Favorites") + _update_file_list(true); return; } if (drag_data.has("type") && String(drag_data["type"]) == "resource") { + // Moving resource Ref<Resource> res = drag_data["resource"]; - String to_dir = _get_drag_target_folder(p_point, p_from); + String to_dir; + bool favorite; + _get_drag_target_folder(to_dir, favorite, p_point, p_from); if (res.is_valid() && !to_dir.empty()) { EditorNode::get_singleton()->push_item(res.ptr()); EditorNode::get_singleton()->save_resource_as(res, to_dir); @@ -1659,7 +1915,10 @@ void FileSystemDock::drop_data_fw(const Point2 &p_point, const Variant &p_data, } if (drag_data.has("type") && (String(drag_data["type"]) == "files" || String(drag_data["type"]) == "files_and_dirs")) { - String to_dir = _get_drag_target_folder(p_point, p_from); + // Move files or add to favorites + String to_dir; + bool favorite; + _get_drag_target_folder(to_dir, favorite, p_point, p_from); if (!to_dir.empty()) { Vector<String> fnames = drag_data["files"]; to_move.clear(); @@ -1667,50 +1926,93 @@ void FileSystemDock::drop_data_fw(const Point2 &p_point, const Variant &p_data, to_move.push_back(FileOrFolder(fnames[i], !fnames[i].ends_with("/"))); } _move_operation_confirm(to_dir); + } else if (favorite) { + // Add the files from favorites + Vector<String> fnames = drag_data["files"]; + Vector<String> favorites = EditorSettings::get_singleton()->get_favorites(); + for (int i = 0; i < fnames.size(); i++) { + if (favorites.find(fnames[i]) == -1) { + favorites.push_back(fnames[i]); + } + } + EditorSettings::get_singleton()->set_favorites(favorites); + _update_tree(_compute_uncollapsed_paths()); } } } -String FileSystemDock::_get_drag_target_folder(const Point2 &p_point, Control *p_from) const { +void FileSystemDock::_get_drag_target_folder(String &target, bool &target_favorites, const Point2 &p_point, Control *p_from) const { + target = String(); + target_favorites = false; + + // In the file list if (p_from == files) { int pos = files->get_item_at_position(p_point, true); - if (pos == -1) - return path; + if (pos == -1) { + return; + } - String target = files->get_item_metadata(pos); - return target.ends_with("/") ? target : path; + String ltarget = files->get_item_metadata(pos); + target = ltarget.ends_with("/") ? ltarget : path; + return; } + // In the tree if (p_from == tree) { TreeItem *ti = tree->get_item_at_position(p_point); - if (ti && ti != tree->get_root()->get_children()) - return ti->get_metadata(0); + int section = tree->get_drop_section_at_position(p_point); + if (ti) { + // Check the favorites first + if (ti == tree->get_root()->get_children() && section >= 0) { + target_favorites = true; + return; + } else if (ti->get_parent() == tree->get_root()->get_children()) { + target_favorites = true; + return; + } else { + String fpath = ti->get_metadata(0); + if (section == 0) { + if (fpath.ends_with("/")) { + // We drop on a folder + target = fpath; + return; + } + } else { + if (ti->get_parent() != tree->get_root()->get_children()) { + // Not in the favorite section + if (fpath != "res://") { + // We drop between two files + if (fpath.ends_with("/")) { + fpath = fpath.substr(0, fpath.length() - 1); + } + target = fpath.get_base_dir(); + return; + } + } + } + } + } } - return String(); + return; } -void FileSystemDock::_files_list_rmb_select(int p_item, const Vector2 &p_pos) { - - //Right clicking ".." should clear current selection - if (files->get_item_text(p_item) == "..") { - for (int i = 0; i < files->get_item_count(); i++) { - files->unselect(i); - } - } +void FileSystemDock::_file_and_folders_fill_popup(PopupMenu *p_popup, Vector<String> p_paths) { + // Add options for files and folders + ERR_FAIL_COND(p_paths.empty()) Vector<String> filenames; Vector<String> foldernames; + Vector<String> favorites = EditorSettings::get_singleton()->get_favorites(); + bool all_files = true; bool all_files_scenes = true; bool all_folders = true; - for (int i = 0; i < files->get_item_count(); i++) { - if (!files->is_selected(i)) { - continue; - } - - String fpath = files->get_item_metadata(i); + bool all_favorites = true; + bool all_not_favorites = true; + for (int i = 0; i < p_paths.size(); i++) { + String fpath = p_paths[i]; if (fpath.ends_with("/")) { foldernames.push_back(fpath); all_files = false; @@ -1719,68 +2021,135 @@ void FileSystemDock::_files_list_rmb_select(int p_item, const Vector2 &p_pos) { all_folders = false; all_files_scenes &= (EditorFileSystem::get_singleton()->get_file_type(fpath) == "PackedScene"); } + + // Check if in favorites + bool found = false; + for (int j = 0; j < favorites.size(); j++) { + if (favorites[j] == fpath) { + found = true; + break; + } + } + if (found) { + all_not_favorites = false; + } else { + all_favorites = false; + } } - file_options->clear(); - file_options->set_size(Size2(1, 1)); if (all_files) { if (all_files_scenes && filenames.size() >= 1) { - file_options->add_item(TTR("Open Scene(s)"), FILE_OPEN); - file_options->add_item(TTR("Instance"), FILE_INSTANCE); - file_options->add_separator(); + p_popup->add_item(TTR("Open Scene(s)"), FILE_OPEN); + p_popup->add_item(TTR("Instance"), FILE_INSTANCE); + p_popup->add_separator(); } if (!all_files_scenes && filenames.size() == 1) { - file_options->add_item(TTR("Open"), FILE_OPEN); - file_options->add_separator(); + p_popup->add_item(TTR("Open"), FILE_OPEN); + p_popup->add_separator(); } + } + if (p_paths.size() >= 1) { + if (!all_favorites) { + p_popup->add_item(TTR("Add to favorites"), FILE_ADD_FAVORITE); + } + if (!all_not_favorites) { + p_popup->add_item(TTR("Remove from favorites"), FILE_REMOVE_FAVORITE); + } + p_popup->add_separator(); + } + + if (all_files) { if (filenames.size() == 1) { - file_options->add_item(TTR("Edit Dependencies..."), FILE_DEPENDENCIES); - file_options->add_item(TTR("View Owners..."), FILE_OWNERS); - file_options->add_separator(); + p_popup->add_item(TTR("Edit Dependencies..."), FILE_DEPENDENCIES); + p_popup->add_item(TTR("View Owners..."), FILE_OWNERS); + p_popup->add_separator(); } } else if (all_folders && foldernames.size() > 0) { - file_options->add_item(TTR("Open"), FILE_OPEN); - file_options->add_separator(); + p_popup->add_item(TTR("Open"), FILE_OPEN); + p_popup->add_separator(); } - int num_items = filenames.size() + foldernames.size(); - if (num_items >= 1) { - if (num_items == 1) { - file_options->add_item(TTR("Copy Path"), FILE_COPY_PATH); - file_options->add_item(TTR("Rename..."), FILE_RENAME); - file_options->add_item(TTR("Duplicate..."), FILE_DUPLICATE); - } - file_options->add_item(TTR("Move To..."), FILE_MOVE); - file_options->add_item(TTR("Delete"), FILE_REMOVE); - file_options->add_separator(); + if (p_paths.size() == 1) { + p_popup->add_item(TTR("Copy Path"), FILE_COPY_PATH); + p_popup->add_item(TTR("Rename..."), FILE_RENAME); + p_popup->add_item(TTR("Duplicate..."), FILE_DUPLICATE); } - file_options->add_item(TTR("New Folder..."), FILE_NEW_FOLDER); - file_options->add_item(TTR("New Script..."), FILE_NEW_SCRIPT); - file_options->add_item(TTR("New Resource..."), FILE_NEW_RESOURCE); + p_popup->add_item(TTR("Move To..."), FILE_MOVE); + p_popup->add_item(TTR("Delete"), FILE_REMOVE); + + if (p_paths.size() == 1) { + p_popup->add_separator(); + p_popup->add_item(TTR("New Folder..."), FILE_NEW_FOLDER); + p_popup->add_item(TTR("New Script..."), FILE_NEW_SCRIPT); + p_popup->add_item(TTR("New Resource..."), FILE_NEW_RESOURCE); - String fpath = files->get_item_metadata(p_item); - String item_text = fpath.ends_with("/") ? TTR("Open In File Manager") : TTR("Show In File Manager"); - file_options->add_item(item_text, FILE_SHOW_IN_EXPLORER); + String fpath = p_paths[0]; + String item_text = fpath.ends_with("/") ? TTR("Open In File Manager") : TTR("Show In File Manager"); + p_popup->add_item(item_text, FILE_SHOW_IN_EXPLORER); + } +} + +void FileSystemDock::_tree_rmb_select(const Vector2 &p_pos) { + // Right click is pressed in the tree + Vector<String> paths = _tree_get_selected(); + + if (paths.size() == 1) { + if (paths[0].ends_with("/")) { + tree_popup->add_item(TTR("Expand all"), FOLDER_EXPAND_ALL); + tree_popup->add_item(TTR("Collapse all"), FOLDER_COLLAPSE_ALL); + tree_popup->add_separator(); + } + } - file_options->set_position(files->get_global_position() + p_pos); - file_options->popup(); + // Popup + if (!paths.empty()) { + tree_popup->clear(); + tree_popup->set_size(Size2(1, 1)); + _file_and_folders_fill_popup(tree_popup, paths); + tree_popup->set_position(tree->get_global_position() + p_pos); + tree_popup->popup(); + } } -void FileSystemDock::_rmb_pressed(const Vector2 &p_pos) { - file_options->clear(); - file_options->set_size(Size2(1, 1)); +void FileSystemDock::_file_list_rmb_select(int p_item, const Vector2 &p_pos) { + // Right click is pressed in the file list + Vector<String> paths; + for (int i = 0; i < files->get_item_count(); i++) { + if (!files->is_selected(i)) + continue; + if (files->get_item_text(p_item) == "..") { + files->unselect(i); + continue; + } + paths.push_back(files->get_item_metadata(i)); + } + + // Popup + if (!paths.empty()) { + file_list_popup->clear(); + file_list_popup->set_size(Size2(1, 1)); + _file_and_folders_fill_popup(file_list_popup, paths); + file_list_popup->set_position(files->get_global_position() + p_pos); + file_list_popup->popup(); + } +} - file_options->add_item(TTR("New Folder..."), FILE_NEW_FOLDER); - file_options->add_item(TTR("New Script..."), FILE_NEW_SCRIPT); - file_options->add_item(TTR("New Resource..."), FILE_NEW_RESOURCE); - file_options->add_item(TTR("Show In File Manager"), FILE_SHOW_IN_EXPLORER); - file_options->set_position(files->get_global_position() + p_pos); - file_options->popup(); +void FileSystemDock::_file_list_rmb_pressed(const Vector2 &p_pos) { + // Right click on empty space for file list + file_list_popup->clear(); + file_list_popup->set_size(Size2(1, 1)); + + file_list_popup->add_item(TTR("New Folder..."), FILE_NEW_FOLDER); + file_list_popup->add_item(TTR("New Script..."), FILE_NEW_SCRIPT); + file_list_popup->add_item(TTR("New Resource..."), FILE_NEW_RESOURCE); + file_list_popup->add_item(TTR("Show In File Manager"), FILE_SHOW_IN_EXPLORER); + file_list_popup->set_position(files->get_global_position() + p_pos); + file_list_popup->popup(); } void FileSystemDock::select_file(const String &p_file) { @@ -1790,11 +2159,24 @@ void FileSystemDock::select_file(const String &p_file) { void FileSystemDock::_file_multi_selected(int p_index, bool p_selected) { + // Set the path to the current focussed item + int current = files->get_current(); + if (current == p_index) { + String fpath = files->get_item_metadata(current); + if (!fpath.ends_with("/")) { + path = fpath; + if (display_mode == DISPLAY_MODE_SPLIT) { + _update_tree(_compute_uncollapsed_paths()); + } + } + } + + // Update the import dock import_dock_needs_update = true; call_deferred("_update_import_dock"); } -void FileSystemDock::_files_gui_input(Ref<InputEvent> p_event) { +void FileSystemDock::_tree_gui_input(Ref<InputEvent> p_event) { if (get_viewport()->get_modal_stack_top()) return; //ignore because of modal window @@ -1802,21 +2184,34 @@ void FileSystemDock::_files_gui_input(Ref<InputEvent> p_event) { Ref<InputEventKey> key = p_event; if (key.is_valid() && key->is_pressed() && !key->is_echo()) { if (ED_IS_SHORTCUT("filesystem_dock/duplicate", p_event)) { - _file_option(FILE_DUPLICATE); + _tree_rmb_option(FILE_DUPLICATE); } else if (ED_IS_SHORTCUT("filesystem_dock/copy_path", p_event)) { - _file_option(FILE_COPY_PATH); + _tree_rmb_option(FILE_COPY_PATH); } else if (ED_IS_SHORTCUT("filesystem_dock/delete", p_event)) { - _file_option(FILE_REMOVE); + _tree_rmb_option(FILE_REMOVE); } else if (ED_IS_SHORTCUT("filesystem_dock/rename", p_event)) { - _file_option(FILE_RENAME); + _tree_rmb_option(FILE_RENAME); } } } -void FileSystemDock::_file_selected() { +void FileSystemDock::_file_list_gui_input(Ref<InputEvent> p_event) { - import_dock_needs_update = true; - _update_import_dock(); + if (get_viewport()->get_modal_stack_top()) + return; //ignore because of modal window + + Ref<InputEventKey> key = p_event; + if (key.is_valid() && key->is_pressed() && !key->is_echo()) { + if (ED_IS_SHORTCUT("filesystem_dock/duplicate", p_event)) { + _file_list_rmb_option(FILE_DUPLICATE); + } else if (ED_IS_SHORTCUT("filesystem_dock/copy_path", p_event)) { + _file_list_rmb_option(FILE_COPY_PATH); + } else if (ED_IS_SHORTCUT("filesystem_dock/delete", p_event)) { + _file_list_rmb_option(FILE_REMOVE); + } else if (ED_IS_SHORTCUT("filesystem_dock/rename", p_event)) { + _file_list_rmb_option(FILE_RENAME); + } + } } void FileSystemDock::_update_import_dock() { @@ -1824,15 +2219,33 @@ void FileSystemDock::_update_import_dock() { if (!import_dock_needs_update) return; - //check import + // List selected + Vector<String> selected; + if (display_mode_setting == DISPLAY_MODE_SETTING_TREE_ONLY) { + // Use the tree + selected = _tree_get_selected(); + + } else { + // Use the file list + for (int i = 0; i < files->get_item_count(); i++) { + if (!files->is_selected(i)) + continue; + + selected.push_back(files->get_item_metadata(i)); + } + } + + // Check import Vector<String> imports; String import_type; + for (int i = 0; i < selected.size(); i++) { + String fpath = selected[i]; - for (int i = 0; i < files->get_item_count(); i++) { - if (!files->is_selected(i)) - continue; + if (fpath.ends_with("/")) { + imports.clear(); + break; + } - String fpath = files->get_item_metadata(i); if (!FileAccess::exists(fpath + ".import")) { imports.clear(); break; @@ -1869,16 +2282,25 @@ void FileSystemDock::_update_import_dock() { void FileSystemDock::_bind_methods() { - ClassDB::bind_method(D_METHOD("_files_gui_input"), &FileSystemDock::_files_gui_input); + ClassDB::bind_method(D_METHOD("_file_list_gui_input"), &FileSystemDock::_file_list_gui_input); + ClassDB::bind_method(D_METHOD("_tree_gui_input"), &FileSystemDock::_tree_gui_input); + ClassDB::bind_method(D_METHOD("_update_tree"), &FileSystemDock::_update_tree); ClassDB::bind_method(D_METHOD("_rescan"), &FileSystemDock::_rescan); - ClassDB::bind_method(D_METHOD("_favorites_pressed"), &FileSystemDock::_favorites_pressed); - ClassDB::bind_method(D_METHOD("_show_current_scene_file"), &FileSystemDock::_show_current_scene_file); - //ClassDB::bind_method(D_METHOD("_instance_pressed"),&ScenesDock::_instance_pressed); - ClassDB::bind_method(D_METHOD("_go_to_file_list"), &FileSystemDock::_go_to_file_list); - ClassDB::bind_method(D_METHOD("_dir_rmb_pressed"), &FileSystemDock::_dir_rmb_pressed); - ClassDB::bind_method(D_METHOD("_thumbnail_done"), &FileSystemDock::_thumbnail_done); + ClassDB::bind_method(D_METHOD("_toggle_split_mode"), &FileSystemDock::_toggle_split_mode); + + ClassDB::bind_method(D_METHOD("_tree_rmb_option", "option"), &FileSystemDock::_tree_rmb_option); + ClassDB::bind_method(D_METHOD("_file_list_rmb_option", "option"), &FileSystemDock::_file_list_rmb_option); + + ClassDB::bind_method(D_METHOD("_tree_rmb_select"), &FileSystemDock::_tree_rmb_select); + ClassDB::bind_method(D_METHOD("_file_list_rmb_select"), &FileSystemDock::_file_list_rmb_select); + ClassDB::bind_method(D_METHOD("_file_list_rmb_pressed"), &FileSystemDock::_file_list_rmb_pressed); + + ClassDB::bind_method(D_METHOD("_file_list_thumbnail_done"), &FileSystemDock::_file_list_thumbnail_done); + ClassDB::bind_method(D_METHOD("_tree_thumbnail_done"), &FileSystemDock::_tree_thumbnail_done); + ClassDB::bind_method(D_METHOD("_file_list_activate_file"), &FileSystemDock::_file_list_activate_file); + ClassDB::bind_method(D_METHOD("_tree_activate_file"), &FileSystemDock::_tree_activate_file); ClassDB::bind_method(D_METHOD("_select_file"), &FileSystemDock::_select_file); ClassDB::bind_method(D_METHOD("_go_to_tree"), &FileSystemDock::_go_to_tree); ClassDB::bind_method(D_METHOD("navigate_to_path"), &FileSystemDock::navigate_to_path); @@ -1886,9 +2308,7 @@ void FileSystemDock::_bind_methods() { ClassDB::bind_method(D_METHOD("_fw_history"), &FileSystemDock::_fw_history); ClassDB::bind_method(D_METHOD("_bw_history"), &FileSystemDock::_bw_history); ClassDB::bind_method(D_METHOD("_fs_changed"), &FileSystemDock::_fs_changed); - ClassDB::bind_method(D_METHOD("_dir_selected"), &FileSystemDock::_dir_selected); - ClassDB::bind_method(D_METHOD("_file_option"), &FileSystemDock::_file_option); - ClassDB::bind_method(D_METHOD("_folder_option"), &FileSystemDock::_folder_option); + ClassDB::bind_method(D_METHOD("_tree_multi_selected"), &FileSystemDock::_tree_multi_selected); ClassDB::bind_method(D_METHOD("_make_dir_confirm"), &FileSystemDock::_make_dir_confirm); ClassDB::bind_method(D_METHOD("_resource_created"), &FileSystemDock::_resource_created); ClassDB::bind_method(D_METHOD("_move_operation_confirm", "to_path", "overwrite"), &FileSystemDock::_move_operation_confirm, DEFVAL(false)); @@ -1901,13 +2321,10 @@ void FileSystemDock::_bind_methods() { ClassDB::bind_method(D_METHOD("get_drag_data_fw"), &FileSystemDock::get_drag_data_fw); ClassDB::bind_method(D_METHOD("can_drop_data_fw"), &FileSystemDock::can_drop_data_fw); ClassDB::bind_method(D_METHOD("drop_data_fw"), &FileSystemDock::drop_data_fw); - ClassDB::bind_method(D_METHOD("_files_list_rmb_select"), &FileSystemDock::_files_list_rmb_select); ClassDB::bind_method(D_METHOD("_preview_invalidated"), &FileSystemDock::_preview_invalidated); - ClassDB::bind_method(D_METHOD("_file_selected"), &FileSystemDock::_file_selected); ClassDB::bind_method(D_METHOD("_file_multi_selected"), &FileSystemDock::_file_multi_selected); ClassDB::bind_method(D_METHOD("_update_import_dock"), &FileSystemDock::_update_import_dock); - ClassDB::bind_method(D_METHOD("_rmb_pressed"), &FileSystemDock::_rmb_pressed); ADD_SIGNAL(MethodInfo("instance", PropertyInfo(Variant::POOL_STRING_ARRAY, "files"))); ADD_SIGNAL(MethodInfo("open")); @@ -1924,9 +2341,12 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) { ED_SHORTCUT("filesystem_dock/delete", TTR("Delete"), KEY_DELETE); ED_SHORTCUT("filesystem_dock/rename", TTR("Rename")); + VBoxContainer *top_vbc = memnew(VBoxContainer); + add_child(top_vbc); + HBoxContainer *toolbar_hbc = memnew(HBoxContainer); toolbar_hbc->add_constant_override("separation", 0); - add_child(toolbar_hbc); + top_vbc->add_child(toolbar_hbc); button_hist_prev = memnew(ToolButton); button_hist_prev->set_disabled(true); @@ -1942,6 +2362,7 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) { current_path = memnew(LineEdit); current_path->set_h_size_flags(SIZE_EXPAND_FILL); + _set_current_path_text(path); toolbar_hbc->add_child(current_path); button_reload = memnew(Button); @@ -1952,22 +2373,25 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) { button_reload->hide(); toolbar_hbc->add_child(button_reload); - //toolbar_hbc->add_spacer(); + button_toggle_display_mode = memnew(Button); + button_toggle_display_mode->set_flat(true); + button_toggle_display_mode->set_toggle_mode(true); + button_toggle_display_mode->connect("toggled", this, "_toggle_split_mode"); + button_toggle_display_mode->set_focus_mode(FOCUS_NONE); + button_toggle_display_mode->set_tooltip(TTR("Toggle split mode")); + toolbar_hbc->add_child(button_toggle_display_mode); + + HBoxContainer *toolbar2_hbc = memnew(HBoxContainer); + toolbar2_hbc->add_constant_override("separation", 0); + top_vbc->add_child(toolbar2_hbc); + + tree_search_box = memnew(LineEdit); + tree_search_box->set_h_size_flags(SIZE_EXPAND_FILL); + tree_search_box->set_placeholder(TTR("Search files")); + tree_search_box->connect("text_changed", this, "_search_changed", varray(tree_search_box)); + toolbar2_hbc->add_child(tree_search_box); - button_favorite = memnew(Button); - button_favorite->set_flat(true); - button_favorite->set_toggle_mode(true); - button_favorite->connect("pressed", this, "_favorites_pressed"); - button_favorite->set_tooltip(TTR("Toggle folder status as Favorite.")); - button_favorite->set_focus_mode(FOCUS_NONE); - toolbar_hbc->add_child(button_favorite); - - button_show = memnew(Button); - button_show->set_flat(true); - button_show->connect("pressed", this, "_show_current_scene_file"); - toolbar_hbc->add_child(button_show); - button_show->set_focus_mode(FOCUS_NONE); - button_show->set_tooltip(TTR("Show current scene file.")); + //toolbar_hbc->add_spacer(); //Control *spacer = memnew( Control); @@ -1990,13 +2414,13 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) { button_instance->set_tooltip(TTR("Instance the selected scene(s) as child of the selected node.")); */ - file_options = memnew(PopupMenu); - file_options->set_hide_on_window_lose_focus(true); - add_child(file_options); + file_list_popup = memnew(PopupMenu); + file_list_popup->set_hide_on_window_lose_focus(true); + add_child(file_list_popup); - folder_options = memnew(PopupMenu); - folder_options->set_hide_on_window_lose_focus(true); - add_child(folder_options); + tree_popup = memnew(PopupMenu); + tree_popup->set_hide_on_window_lose_focus(true); + add_child(tree_popup); split_box = memnew(VSplitContainer); split_box->set_v_size_flags(SIZE_EXPAND_FILL); @@ -2007,13 +2431,15 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) { tree->set_hide_root(true); tree->set_drag_forwarding(this); tree->set_allow_rmb_select(true); - tree->set_custom_minimum_size(Size2(0, 200 * EDSCALE)); + tree->set_select_mode(Tree::SELECT_MULTI); + tree->set_custom_minimum_size(Size2(0, 15 * EDSCALE)); split_box->add_child(tree); tree->connect("item_edited", this, "_favorite_toggled"); - tree->connect("item_activated", this, "_go_to_file_list"); - tree->connect("cell_selected", this, "_dir_selected"); - tree->connect("item_rmb_selected", this, "_dir_rmb_pressed"); + tree->connect("item_activated", this, "_tree_activate_file"); + tree->connect("multi_selected", this, "_tree_multi_selected"); + tree->connect("item_rmb_selected", this, "_tree_rmb_select"); + tree->connect("gui_input", this, "_tree_gui_input"); file_list_vb = memnew(VBoxContainer); file_list_vb->set_v_size_flags(SIZE_EXPAND_FILL); @@ -2027,11 +2453,11 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) { button_tree->hide(); path_hb->add_child(button_tree); - search_box = memnew(LineEdit); - search_box->set_h_size_flags(SIZE_EXPAND_FILL); - search_box->set_placeholder(TTR("Search files")); - search_box->connect("text_changed", this, "_search_changed"); - path_hb->add_child(search_box); + file_list_search_box = memnew(LineEdit); + file_list_search_box->set_h_size_flags(SIZE_EXPAND_FILL); + file_list_search_box->set_placeholder(TTR("Search files")); + file_list_search_box->connect("text_changed", this, "_search_changed", varray(file_list_search_box)); + path_hb->add_child(file_list_search_box); button_file_list_display_mode = memnew(ToolButton); button_file_list_display_mode->set_toggle_mode(true); @@ -2041,11 +2467,11 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) { files->set_v_size_flags(SIZE_EXPAND_FILL); files->set_select_mode(ItemList::SELECT_MULTI); files->set_drag_forwarding(this); - files->connect("item_rmb_selected", this, "_files_list_rmb_select"); - files->connect("gui_input", this, "_files_gui_input"); - files->connect("item_selected", this, "_file_selected"); + files->connect("item_rmb_selected", this, "_file_list_rmb_select"); + files->connect("gui_input", this, "_file_list_gui_input"); files->connect("multi_selected", this, "_file_multi_selected"); - files->connect("rmb_clicked", this, "_rmb_pressed"); + files->connect("rmb_clicked", this, "_file_list_rmb_pressed"); + files->set_custom_minimum_size(Size2(0, 15 * EDSCALE)); files->set_allow_rmb_select(true); file_list_vb->add_child(files); @@ -2123,7 +2549,11 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) { new_resource_dialog->set_base_type("Resource"); new_resource_dialog->connect("create", this, "_resource_created"); + searched_string = String(); + uncollapsed_paths_before_search = Vector<String>(); + updating_tree = false; + tree_update_id = 0; initialized = false; import_dock_needs_update = false; @@ -2131,8 +2561,12 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) { history_max_size = 20; history.push_back("res://"); - display_mode = DISPLAY_SPLIT; + display_mode = DISPLAY_MODE_SPLIT; file_list_display_mode = FILE_LIST_DISPLAY_THUMBNAILS; + + display_mode_setting = DISPLAY_MODE_SETTING_TREE_ONLY; + old_display_mode_setting = DISPLAY_MODE_SETTING_TREE_ONLY; + always_show_folders = false; } FileSystemDock::~FileSystemDock() { diff --git a/editor/filesystem_dock.h b/editor/filesystem_dock.h index fbbe87fc16..d964515572 100644 --- a/editor/filesystem_dock.h +++ b/editor/filesystem_dock.h @@ -44,8 +44,8 @@ #include "scene/gui/tree.h" #include "scene/main/timer.h" -#include "os/dir_access.h" -#include "os/thread.h" +#include "core/os/dir_access.h" +#include "core/os/thread.h" #include "create_dialog.h" @@ -66,15 +66,22 @@ public: }; private: + enum DisplayModeSetting { + DISPLAY_MODE_SETTING_TREE_ONLY, + DISPLAY_MODE_SETTING_SPLIT, + }; + enum DisplayMode { - DISPLAY_TREE_ONLY, - DISPLAY_FILE_LIST_ONLY, - DISPLAY_SPLIT, + DISPLAY_MODE_TREE_ONLY, + DISPLAY_MODE_FILE_LIST_ONLY, + DISPLAY_MODE_SPLIT, }; enum FileMenu { FILE_OPEN, FILE_INSTANCE, + FILE_ADD_FAVORITE, + FILE_REMOVE_FAVORITE, FILE_DEPENDENCIES, FILE_OWNERS, FILE_MOVE, @@ -87,18 +94,9 @@ private: FILE_NEW_SCRIPT, FILE_SHOW_IN_EXPLORER, FILE_COPY_PATH, - FILE_NEW_RESOURCE - }; - - enum FolderMenu { + FILE_NEW_RESOURCE, FOLDER_EXPAND_ALL, FOLDER_COLLAPSE_ALL, - FOLDER_MOVE, - FOLDER_RENAME, - FOLDER_REMOVE, - FOLDER_NEW_FOLDER, - FOLDER_SHOW_IN_EXPLORER, - FOLDER_COPY_PATH }; VBoxContainer *scanning_vb; @@ -109,24 +107,30 @@ private: EditorNode *editor; Set<String> favorites; + Button *button_toggle_display_mode; Button *button_reload; - Button *button_favorite; Button *button_tree; Button *button_file_list_display_mode; Button *button_hist_next; Button *button_hist_prev; - Button *button_show; LineEdit *current_path; - LineEdit *search_box; + LineEdit *tree_search_box; + LineEdit *file_list_search_box; + + String searched_string; + Vector<String> uncollapsed_paths_before_search; + TextureRect *search_icon; HBoxContainer *path_hb; FileListDisplayMode file_list_display_mode; DisplayMode display_mode; + DisplayModeSetting display_mode_setting; + DisplayModeSetting old_display_mode_setting; bool file_list_view; - PopupMenu *file_options; - PopupMenu *folder_options; + PopupMenu *file_list_popup; + PopupMenu *tree_popup; DependencyEditor *deps_editor; DependencyEditorOwners *owners_editor; @@ -143,6 +147,8 @@ private: ScriptCreateDialog *make_script_dialog_text; CreateDialog *new_resource_dialog; + bool always_show_folders; + class FileOrFolder { public: String path; @@ -169,16 +175,20 @@ private: bool initialized; bool updating_tree; + int tree_update_id; Tree *tree; //directories ItemList *files; bool import_dock_needs_update; + Ref<Texture> _get_tree_item_icon(EditorFileSystemDirectory *p_dir, int p_idx); bool _create_tree(TreeItem *p_parent, EditorFileSystemDirectory *p_dir, Vector<String> &uncollapsed_paths); - void _update_tree(bool keep_collapse_state, bool p_uncollapse_root = false); + Vector<String> _compute_uncollapsed_paths(); + void _update_tree(const Vector<String> p_uncollapsed_paths = Vector<String>(), bool p_uncollapse_root = false); - void _files_gui_input(Ref<InputEvent> p_event); + void _file_list_gui_input(Ref<InputEvent> p_event); + void _tree_gui_input(Ref<InputEvent> p_event); - void _update_files(bool p_keep_selection); + void _update_file_list(bool p_keep_selection); void _update_file_list_display_mode_button(); void _change_file_display(); void _fs_changed(); @@ -186,12 +196,13 @@ private: void _go_to_tree(); void _go_to_file_list(); - void _select_file(int p_idx); + void _select_file(const String p_path); + void _tree_activate_file(); + void _file_list_activate_file(int p_idx); void _file_multi_selected(int p_index, bool p_selected); - void _update_import_dock(); + void _tree_multi_selected(Object *p_item, int p_column, bool p_selected); - void _file_selected(); - void _dir_selected(); + void _update_import_dock(); void _get_all_items_in_dir(EditorFileSystemDirectory *efsd, Vector<String> &files, Vector<String> &folders) const; void _find_remaps(EditorFileSystemDirectory *efsd, const Map<String, String> &renames, Vector<String> &to_remaps) const; @@ -199,8 +210,8 @@ private: void _try_duplicate_item(const FileOrFolder &p_item, const String &p_new_path) const; void _update_dependencies_after_move(const Map<String, String> &p_renames) const; void _update_resource_paths_after_move(const Map<String, String> &p_renames) const; - void _update_favorite_dirs_list_after_move(const Map<String, String> &p_renames) const; - void _update_project_settings_after_move(const Map<String, String> &p_renames) const; + void _update_favorites_list_after_move(const Map<String, String> &p_files_renames, const Map<String, String> &p_folders_renames) const; + void _update_project_settings_after_move(const Map<String, String> &p_folders_renames) const; void _resource_created() const; void _make_dir_confirm(); @@ -210,8 +221,9 @@ private: bool _check_existing(); void _move_operation_confirm(const String &p_to_path, bool overwrite = false); - void _file_option(int p_option); - void _folder_option(int p_option); + void _tree_rmb_option(int p_option); + void _file_list_rmb_option(int p_option); + void _file_option(int p_option, const Vector<String> p_selected); void _fw_history(); void _bw_history(); @@ -221,13 +233,14 @@ private: void _set_scanning_mode(); void _rescan(); - void _favorites_pressed(); - void _show_current_scene_file(); - void _search_changed(const String &p_text); + void _toggle_split_mode(bool p_active); - void _dir_rmb_pressed(const Vector2 &p_pos); - void _files_list_rmb_select(int p_item, const Vector2 &p_pos); - void _rmb_pressed(const Vector2 &p_pos); + void _search_changed(const String &p_text, const Control *p_from); + + void _file_and_folders_fill_popup(PopupMenu *p_popup, Vector<String> p_paths); + void _tree_rmb_select(const Vector2 &p_pos); + void _file_list_rmb_select(int p_item, const Vector2 &p_pos); + void _file_list_rmb_pressed(const Vector2 &p_pos); struct FileInfo { String name; @@ -238,22 +251,27 @@ private: bool import_broken; bool operator<(const FileInfo &fi) const { - return name < fi.name; + return NaturalNoCaseComparator()(name, fi.name); } }; void _search(EditorFileSystemDirectory *p_path, List<FileInfo> *matches, int p_max_items); + void _set_current_path_text(const String &p_path); + Variant get_drag_data_fw(const Point2 &p_point, Control *p_from); bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const; void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from); - String _get_drag_target_folder(const Point2 &p_point, Control *p_from) const; + void _get_drag_target_folder(String &target, bool &target_favorites, const Point2 &p_point, Control *p_from) const; void _preview_invalidated(const String &p_path); - void _thumbnail_done(const String &p_path, const Ref<Texture> &p_preview, const Variant &p_udata); + void _file_list_thumbnail_done(const String &p_path, const Ref<Texture> &p_preview, const Ref<Texture> &p_small_preview, const Variant &p_udata); + void _tree_thumbnail_done(const String &p_path, const Ref<Texture> &p_preview, const Ref<Texture> &p_small_preview, const Variant &p_udata); void _update_display_mode(); + Vector<String> _tree_get_selected(bool remove_self_inclusion = true); + protected: void _notification(int p_what); static void _bind_methods(); diff --git a/editor/find_in_files.cpp b/editor/find_in_files.cpp index 9ede8a05bc..2af81b8ac7 100644 --- a/editor/find_in_files.cpp +++ b/editor/find_in_files.cpp @@ -302,7 +302,7 @@ FindInFilesDialog::FindInFilesDialog() { set_custom_minimum_size(Size2(400, 190)); set_resizable(true); - set_title(TTR("Find in files")); + set_title(TTR("Find in Files")); VBoxContainer *vbc = memnew(VBoxContainer); vbc->set_anchor_and_margin(MARGIN_LEFT, ANCHOR_BEGIN, 8 * EDSCALE); @@ -406,11 +406,8 @@ FindInFilesDialog::FindInFilesDialog() { HBoxContainer *hbc = memnew(HBoxContainer); hbc->set_alignment(HBoxContainer::ALIGN_CENTER); - _find_button = memnew(Button); - _find_button->set_text(TTR("Find...")); - _find_button->connect("pressed", this, "_on_find_button_pressed"); + _find_button = add_button(TTR("Find..."), false, "find"); _find_button->set_disabled(true); - hbc->add_child(_find_button); { Control *placeholder = memnew(Control); @@ -418,11 +415,8 @@ FindInFilesDialog::FindInFilesDialog() { hbc->add_child(placeholder); } - _replace_button = memnew(Button); - _replace_button->set_text(TTR("Replace...")); - _replace_button->connect("pressed", this, "_on_replace_button_pressed"); + _replace_button = add_button(TTR("Replace..."), false, "replace"); _replace_button->set_disabled(true); - hbc->add_child(_replace_button); { Control *placeholder = memnew(Control); @@ -430,10 +424,8 @@ FindInFilesDialog::FindInFilesDialog() { hbc->add_child(placeholder); } - Button *cancel_button = memnew(Button); + Button *cancel_button = get_ok(); cancel_button->set_text(TTR("Cancel")); - cancel_button->connect("pressed", this, "hide"); - hbc->add_child(cancel_button); vbc->add_child(hbc); } @@ -487,14 +479,14 @@ void FindInFilesDialog::_on_folder_button_pressed() { _folder_dialog->popup_centered_ratio(); } -void FindInFilesDialog::_on_find_button_pressed() { - emit_signal(SIGNAL_FIND_REQUESTED); - hide(); -} - -void FindInFilesDialog::_on_replace_button_pressed() { - emit_signal(SIGNAL_REPLACE_REQUESTED); - hide(); +void FindInFilesDialog::custom_action(const String &p_action) { + if (p_action == "find") { + emit_signal(SIGNAL_FIND_REQUESTED); + hide(); + } else if (p_action == "replace") { + emit_signal(SIGNAL_REPLACE_REQUESTED); + hide(); + } } void FindInFilesDialog::_on_search_text_modified(String text) { @@ -509,7 +501,7 @@ void FindInFilesDialog::_on_search_text_modified(String text) { void FindInFilesDialog::_on_search_text_entered(String text) { // This allows to trigger a global search without leaving the keyboard if (!_find_button->is_disabled()) - _on_find_button_pressed(); + custom_action("find"); } void FindInFilesDialog::_on_folder_selected(String path) { @@ -522,8 +514,6 @@ void FindInFilesDialog::_on_folder_selected(String path) { void FindInFilesDialog::_bind_methods() { ClassDB::bind_method("_on_folder_button_pressed", &FindInFilesDialog::_on_folder_button_pressed); - ClassDB::bind_method("_on_find_button_pressed", &FindInFilesDialog::_on_find_button_pressed); - ClassDB::bind_method("_on_replace_button_pressed", &FindInFilesDialog::_on_replace_button_pressed); ClassDB::bind_method("_on_folder_selected", &FindInFilesDialog::_on_folder_selected); ClassDB::bind_method("_on_search_text_modified", &FindInFilesDialog::_on_search_text_modified); ClassDB::bind_method("_on_search_text_entered", &FindInFilesDialog::_on_search_text_entered); @@ -864,7 +854,7 @@ void FindInFilesPanel::apply_replaces_in_file(String fpath, const Vector<Result> // If the file is already open, I assume the editor will reload it. // If there are unsaved changes, the user will be asked on focus, - // however that means either loosing changes or loosing replaces. + // however that means either losing changes or losing replaces. FileAccess *f = FileAccess::open(fpath, FileAccess::READ); ERR_FAIL_COND(f == NULL); diff --git a/editor/find_in_files.h b/editor/find_in_files.h index 75ea1c3161..7f37123430 100644 --- a/editor/find_in_files.h +++ b/editor/find_in_files.h @@ -91,8 +91,8 @@ class CheckBox; class FileDialog; // Prompts search parameters -class FindInFilesDialog : public WindowDialog { - GDCLASS(FindInFilesDialog, WindowDialog) +class FindInFilesDialog : public AcceptDialog { + GDCLASS(FindInFilesDialog, AcceptDialog) public: static const char *SIGNAL_FIND_REQUESTED; static const char *SIGNAL_REPLACE_REQUESTED; @@ -111,11 +111,10 @@ protected: static void _bind_methods(); void _notification(int p_what); + void custom_action(const String &p_action); private: void _on_folder_button_pressed(); - void _on_find_button_pressed(); - void _on_replace_button_pressed(); void _on_folder_selected(String path); void _on_search_text_modified(String text); void _on_search_text_entered(String text); diff --git a/editor/groups_editor.cpp b/editor/groups_editor.cpp index 0efd14e932..cb9703342f 100644 --- a/editor/groups_editor.cpp +++ b/editor/groups_editor.cpp @@ -90,12 +90,7 @@ void GroupDialog::_load_nodes(Node *p_current) { node->set_metadata(0, path); node->set_tooltip(0, path); - Ref<Texture> icon; - if (p_current->has_meta("_editor_icon")) { - icon = p_current->get_meta("_editor_icon"); - } else { - icon = get_icon((has_icon(p_current->get_class(), "EditorIcons") ? p_current->get_class() : String("Object")), "EditorIcons"); - } + Ref<Texture> icon = EditorNode::get_singleton()->get_object_icon(p_current, "Node"); node->set_icon(0, icon); if (!_can_edit(p_current, selected_group)) { diff --git a/editor/groups_editor.h b/editor/groups_editor.h index 461cf0f8c2..7705b3b6fb 100644 --- a/editor/groups_editor.h +++ b/editor/groups_editor.h @@ -31,6 +31,7 @@ #ifndef GROUPS_EDITOR_H #define GROUPS_EDITOR_H +#include "core/undo_redo.h" #include "editor/scene_tree_editor.h" #include "scene/gui/button.h" #include "scene/gui/dialogs.h" @@ -39,7 +40,6 @@ #include "scene/gui/popup.h" #include "scene/gui/tool_button.h" #include "scene/gui/tree.h" -#include "undo_redo.h" /** @author Juan Linietsky <reduzio@gmail.com> diff --git a/editor/icons/README.md b/editor/icons/README.md index 3a2aba5b07..5f652e47ab 100644 --- a/editor/icons/README.md +++ b/editor/icons/README.md @@ -9,4 +9,4 @@ There you can find the optimizer script. If you add a new icon, please make a pull request to this repo: https://github.com/godotengine/godot-design/ -and store the the optimized SVG version here. +and store the optimized SVG version here. diff --git a/editor/icons/SCsub b/editor/icons/SCsub index 31bf8f116a..109e1aa83b 100644 --- a/editor/icons/SCsub +++ b/editor/icons/SCsub @@ -1,15 +1,13 @@ #!/usr/bin/env python Import('env') + from platform_methods import run_in_subprocess import editor_icons_builders - make_editor_icons_builder = Builder(action=run_in_subprocess(editor_icons_builders.make_editor_icons_action), suffix='.h', src_suffix='.svg') env['BUILDERS']['MakeEditorIconsBuilder'] = make_editor_icons_builder env.Alias('editor_icons', [env.MakeEditorIconsBuilder('#editor/editor_icons.gen.h', Glob("*.svg"))]) - -Export('env') diff --git a/editor/icons/icon_GUI_checked.svg b/editor/icons/icon_GUI_checked.svg index e5fa67ebf5..8d00eca8d3 100644 --- a/editor/icons/icon_GUI_checked.svg +++ b/editor/icons/icon_GUI_checked.svg @@ -1,3 +1 @@ -<svg width="16" height="16" version="1.1" viewBox="0 0 16 15.999999" xmlns="http://www.w3.org/2000/svg"> -<path d="m4 2c-1.1046 0-2 0.89543-2 2v8c0 1.1046 0.89543 2 2 2h8c1.1046 0 2-0.89543 2-2v-8c0-1.1046-0.89543-2-2-2h-8zm7.293 2.293l1.4141 1.4141-6.707 6.707-2.707-2.707 1.4141-1.4141 1.293 1.293 5.293-5.293z" fill="#e0e0e0" fill-opacity=".78431"/> -</svg> +<svg height="16" viewBox="0 0 16 15.999999" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0"><path d="m3.3333333 1c-1.2887 0-2.3333333 1.0446683-2.3333333 2.3333333v9.3333337c0 1.2887 1.0446683 2.333333 2.3333333 2.333333h9.3333337c1.2887 0 2.333333-1.044668 2.333333-2.333333v-9.3333337c0-1.2887-1.044668-2.3333333-2.333333-2.3333333z" fill-opacity=".188235" stroke-width="1.166667"/><path d="m11.500773 3.7343508-5.6117507 5.6117502-1.7045017-1.6814543-1.4992276 1.4992276 3.2037293 3.1806817 7.1109777-7.1109775z" stroke-width="1.060227"/></g></svg>
\ No newline at end of file diff --git a/editor/icons/icon_GUI_radio_checked.svg b/editor/icons/icon_GUI_radio_checked.svg index 6a65d49eeb..447b57f8ae 100644 --- a/editor/icons/icon_GUI_radio_checked.svg +++ b/editor/icons/icon_GUI_radio_checked.svg @@ -1,6 +1 @@ -<svg width="16" height="16" version="1.1" viewBox="0 0 16 15.999999" xmlns="http://www.w3.org/2000/svg"> -<g transform="translate(0 -1036.4)"> -<circle cx="8" cy="1044.4" r="5" fill="none" stroke="#e0e0e0" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".78431" stroke-width="2"/> -<circle cx="8" cy="1044.4" r="3" fill="#e0e0e0" fill-opacity=".78431"/> -</g> -</svg> +<svg height="16" viewBox="0 0 16 15.999999" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0"><path d="m15 8a7 7 0 0 1 -7 7 7 7 0 0 1 -7-7 7 7 0 0 1 7-7 7 7 0 0 1 7 7" fill-opacity=".188235" stroke-width="2.333333"/><path d="m12 8a4 4 0 0 1 -4 4 4 4 0 0 1 -4-4 4 4 0 0 1 4-4 4 4 0 0 1 4 4" stroke-width="1.333333"/></g></svg>
\ No newline at end of file diff --git a/editor/icons/icon_GUI_radio_unchecked.svg b/editor/icons/icon_GUI_radio_unchecked.svg index 6e52a8af77..1e8117bd10 100644 --- a/editor/icons/icon_GUI_radio_unchecked.svg +++ b/editor/icons/icon_GUI_radio_unchecked.svg @@ -1,5 +1 @@ -<svg width="16" height="16" version="1.1" viewBox="0 0 16 15.999999" xmlns="http://www.w3.org/2000/svg"> -<g transform="translate(0 -1036.4)"> -<circle cx="8" cy="1044.4" r="5" fill="none" stroke="#e0e0e0" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".78431" stroke-width="2"/> -</g> -</svg> +<svg height="16" viewBox="0 0 16 15.999999" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m15 8a7 7 0 0 1 -7 7 7 7 0 0 1 -7-7 7 7 0 0 1 7-7 7 7 0 0 1 7 7" fill="#e0e0e0" fill-opacity=".188235" stroke-width="2.333333"/></svg>
\ No newline at end of file diff --git a/editor/icons/icon_GUI_unchecked.svg b/editor/icons/icon_GUI_unchecked.svg index 59df40954f..9575422df3 100644 --- a/editor/icons/icon_GUI_unchecked.svg +++ b/editor/icons/icon_GUI_unchecked.svg @@ -1,3 +1 @@ -<svg width="16" height="16" version="1.1" viewBox="0 0 16 15.999999" xmlns="http://www.w3.org/2000/svg"> -<path d="m4 2a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h8a2 2 0 0 0 2 -2v-8a2 2 0 0 0 -2 -2h-8zm0.80078 2h6.3984a0.8 0.8 0 0 1 0.80078 0.80078v6.3984a0.8 0.8 0 0 1 -0.80078 0.80078h-6.3984a0.8 0.8 0 0 1 -0.80078 -0.80078v-6.3984a0.8 0.8 0 0 1 0.80078 -0.80078z" fill="#e0e0e0" fill-opacity=".78431"/> -</svg> +<svg height="16" viewBox="0 0 16 15.999999" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3.3333333 1c-1.2887 0-2.3333333 1.0446683-2.3333333 2.3333333v9.3333337c0 1.2887 1.0446683 2.333333 2.3333333 2.333333h9.3333337c1.2887 0 2.333333-1.044668 2.333333-2.333333v-9.3333337c0-1.2887-1.044668-2.3333333-2.333333-2.3333333z" fill="#e0e0e0" fill-opacity=".188235" stroke-width="1.166667"/></svg>
\ No newline at end of file diff --git a/editor/icons/icon_GUI_viewport_hdiagsplitter.svg b/editor/icons/icon_GUI_viewport_hdiagsplitter.svg new file mode 100644 index 0000000000..36769768fd --- /dev/null +++ b/editor/icons/icon_GUI_viewport_hdiagsplitter.svg @@ -0,0 +1,64 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="64" + height="34" + version="1.1" + viewBox="0 0 64 34" + id="svg6" + sodipodi:docname="icon_GUI_vsplitter1.svg" + inkscape:version="0.92.2 2405546, 2018-03-11"> + <metadata + id="metadata12"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs10" /> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1366" + inkscape:window-height="714" + id="namedview8" + showgrid="false" + inkscape:zoom="5.6568543" + inkscape:cx="37.006499" + inkscape:cy="15.680715" + inkscape:window-x="0" + inkscape:window-y="0" + inkscape:window-maximized="1" + inkscape:current-layer="svg6" /> + <g + transform="translate(0,-1018.4)" + id="g4" /> + <g + transform="rotate(90,541.2,539.2)" + id="g4-3"> + <path + id="path2-6" + style="fill:none;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-opacity:0.39216003" + d="M 4.0306826,1048.4 H 34 m -30,30 v -60" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cccc" /> + </g> +</svg> diff --git a/editor/icons/icon_GUI_viewport_vdiagsplitter.svg b/editor/icons/icon_GUI_viewport_vdiagsplitter.svg new file mode 100644 index 0000000000..f23b4a0a74 --- /dev/null +++ b/editor/icons/icon_GUI_viewport_vdiagsplitter.svg @@ -0,0 +1,68 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="34" + height="64" + version="1.1" + viewBox="0 0 34 64" + id="svg6" + sodipodi:docname="icon_GUI_vsplitter2.svg" + inkscape:version="0.92.2 2405546, 2018-03-11"> + <metadata + id="metadata12"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs10" /> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1366" + inkscape:window-height="714" + id="namedview8" + showgrid="false" + inkscape:zoom="4" + inkscape:cx="32.245723" + inkscape:cy="44.255214" + inkscape:window-x="0" + inkscape:window-y="0" + inkscape:window-maximized="1" + inkscape:current-layer="svg6" /> + <g + transform="translate(0,-988.4)" + id="g4" /> + <g + id="g839" + transform="rotate(90,32.003536,32.003535)"> + <g + id="g4-3" + transform="rotate(90,526.2,554.2)"> + <path + sodipodi:nodetypes="cccc" + inkscape:connector-curvature="0" + d="M 4.0306826,1048.4 H 34 m -30,30 v -60" + style="fill:none;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-opacity:0.39216003" + id="path2-6" /> + </g> + </g> +</svg> diff --git a/editor/icons/icon_GUI_viewport_vhsplitter.svg b/editor/icons/icon_GUI_viewport_vhsplitter.svg new file mode 100644 index 0000000000..429cf909ae --- /dev/null +++ b/editor/icons/icon_GUI_viewport_vhsplitter.svg @@ -0,0 +1,63 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="64" + height="64" + version="1.1" + viewBox="0 0 64 64" + id="svg6" + sodipodi:docname="icon_GUI_vsplitter.svg" + inkscape:version="0.92.2 2405546, 2018-03-11"> + <metadata + id="metadata12"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs10" /> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1366" + inkscape:window-height="714" + id="namedview8" + showgrid="false" + inkscape:zoom="4.65625" + inkscape:cx="9.8488117" + inkscape:cy="20.04653" + inkscape:window-x="0" + inkscape:window-y="0" + inkscape:window-maximized="1" + inkscape:current-layer="svg6" /> + <g + transform="translate(0,-988.4)" + id="g4" /> + <g + transform="rotate(90,526.2,554.2)" + id="g4-3"> + <path + id="path2-6" + style="fill:none;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-opacity:0.39216003" + d="m -26,1048.4 h 60 m -30,30 v -60" + inkscape:connector-curvature="0" /> + </g> +</svg> diff --git a/editor/icons/icon_c_p_u_particles_2_d.svg b/editor/icons/icon_c_p_u_particles_2_d.svg new file mode 100644 index 0000000000..926e675fee --- /dev/null +++ b/editor/icons/icon_c_p_u_particles_2_d.svg @@ -0,0 +1,60 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="16" + height="16" + version="1.1" + viewBox="0 0 16 16" + id="svg6" + sodipodi:docname="icon_c_p_u_particles_2_d.svg" + inkscape:version="0.92.3 (2405546, 2018-03-11)"> + <metadata + id="metadata12"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs10" /> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1741" + inkscape:window-height="753" + id="namedview8" + showgrid="false" + inkscape:zoom="14.75" + inkscape:cx="-5.6949153" + inkscape:cy="7.7288136" + inkscape:window-x="67" + inkscape:window-y="27" + inkscape:window-maximized="0" + inkscape:current-layer="svg6" /> + <path + style="fill:#a3b6f3;fill-opacity:0.99215686" + d="m 4.5587261,0.60940813 c -0.4226244,0 -0.7617187,0.3410473 -0.7617187,0.76367177 v 0.5078126 c 0,0.1028478 0.020058,0.199689 0.056641,0.2890624 H 2.6602887 c -0.4226245,0 -0.7617188,0.3390944 -0.7617188,0.7617188 v 0.921875 C 1.8581419,3.8469787 1.821771,3.8301112 1.7794293,3.8301112 H 1.2716168 c -0.42262448,0 -0.76367188,0.3410475 -0.76367188,0.7636719 v 0.3730468 c 0,0.4226245 0.3410474,0.7617188 0.76367188,0.7617188 h 0.5078125 c 0.042396,0 0.078663,-0.016851 0.1191406,-0.023437 v 4.4531248 c -0.040428,-0.0066 -0.076799,-0.02344 -0.1191406,-0.02344 H 1.2716168 c -0.42262448,0 -0.76367188,0.341047 -0.76367188,0.763672 v 0.373047 c 0,0.422625 0.3410474,0.761718 0.76367188,0.761718 h 0.5078125 c 0.042396,0 0.078663,-0.01685 0.1191406,-0.02344 v 1.125 c 0,0.422624 0.3390944,0.763672 0.7617188,0.763672 h 1.1367187 v 0.457031 c 0,0.422624 0.3390943,0.763672 0.7617187,0.763672 H 4.931773 c 0.4226244,0 0.7636719,-0.341048 0.7636719,-0.763672 v -0.457031 h 4.4062501 v 0.457031 c 0,0.422624 0.339094,0.763672 0.761719,0.763672 h 0.373047 c 0.422624,0 0.763671,-0.341048 0.763671,-0.763672 v -0.457031 h 1.269532 c 0.422625,0 0.763672,-0.341048 0.763672,-0.763672 v -1.111328 c 0.01774,0.0012 0.03272,0.0098 0.05078,0.0098 h 0.507812 c 0.422624,0 0.763672,-0.339093 0.763672,-0.761718 v -0.373047 c 0,-0.422624 -0.341048,-0.763672 -0.763672,-0.763672 h -0.507812 c -0.01803,0 -0.03307,0.0085 -0.05078,0.0098 V 5.7187831 c 0.01774,0.00122 0.03272,0.00977 0.05078,0.00977 h 0.507812 c 0.422624,0 0.763672,-0.3390943 0.763672,-0.7617188 V 4.5937831 c 0,-0.4226244 -0.341048,-0.7636719 -0.763672,-0.7636719 h -0.507812 c -0.01803,0 -0.03307,0.00855 -0.05078,0.00977 V 2.9316737 c 0,-0.4226244 -0.341047,-0.7617187 -0.763672,-0.7617188 h -1.328125 c 0.03658,-0.089375 0.05859,-0.1862118 0.05859,-0.2890624 V 1.3730799 c 0,-0.42262437 -0.341047,-0.76367177 -0.763671,-0.76367177 h -0.373047 c -0.422625,0 -0.761719,0.3410474 -0.761719,0.76367177 v 0.5078126 c 0,0.1028478 0.02006,0.1996891 0.05664,0.2890624 H 5.6368511 C 5.6734361,2.08058 5.6954449,1.9837431 5.6954449,1.8808925 V 1.3730799 c 0,-0.42262437 -0.3410475,-0.76367177 -0.7636719,-0.76367177 z M 7.7970074,2.9668299 A 3.279661,3.6440678 0 0 1 11.009898,5.9062831 2.1864407,2.1864407 0 0 1 12.89857,8.0683925 2.1864407,2.1864407 0 0 1 10.71107,10.25394 H 4.8809918 A 2.1864407,2.1864407 0 0 1 2.6954449,8.0683925 2.1864407,2.1864407 0 0 1 4.5802105,5.9043299 3.279661,3.6440678 0 0 1 7.7970074,2.9668299 Z M 4.8809918,10.982455 A 0.72881355,0.72881355 0 0 1 5.6095074,11.710971 0.72881355,0.72881355 0 0 1 4.8809918,12.44144 0.72881355,0.72881355 0 0 1 4.1524761,11.710971 0.72881355,0.72881355 0 0 1 4.8809918,10.982455 Z m 5.8300782,0 A 0.72881355,0.72881355 0 0 1 11.441539,11.710971 0.72881355,0.72881355 0 0 1 10.71107,12.44144 0.72881355,0.72881355 0 0 1 9.9825543,11.710971 0.72881355,0.72881355 0 0 1 10.71107,10.982455 Z M 7.7970074,11.710971 A 0.72881355,0.72881355 0 0 1 8.525523,12.44144 0.72881355,0.72881355 0 0 1 7.7970074,13.169955 0.72881355,0.72881355 0 0 1 7.0684918,12.44144 0.72881355,0.72881355 0 0 1 7.7970074,11.710971 Z" + id="rect822" + inkscape:connector-curvature="0" /> + <g + inkscape:groupmode="layer" + id="layer1" + inkscape:label="Layer 1" /> +</svg> diff --git a/editor/icons/icon_g_l_e_s_2.svg b/editor/icons/icon_g_l_e_s_2.svg deleted file mode 100644 index efc4f01e4f..0000000000 --- a/editor/icons/icon_g_l_e_s_2.svg +++ /dev/null @@ -1,69 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<!-- Created with Inkscape (http://www.inkscape.org/) --> - -<svg - xmlns:dc="http://purl.org/dc/elements/1.1/" - xmlns:cc="http://creativecommons.org/ns#" - xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" - xmlns:svg="http://www.w3.org/2000/svg" - xmlns="http://www.w3.org/2000/svg" - xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - version="1.1" - id="svg2" - width="48" - height="16" - viewBox="0 0 47.999999 16" - sodipodi:docname="icon_g_l_e_s_2.svg" - inkscape:version="0.92.3 (2405546, 2018-03-11)"> - <metadata - id="metadata8"> - <rdf:RDF> - <cc:Work - rdf:about=""> - <dc:format>image/svg+xml</dc:format> - <dc:type - rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> - <dc:title /> - </cc:Work> - </rdf:RDF> - </metadata> - <defs - id="defs6" /> - <sodipodi:namedview - pagecolor="#ffffff" - bordercolor="#666666" - borderopacity="1" - objecttolerance="10" - gridtolerance="10" - guidetolerance="10" - inkscape:pageopacity="0" - inkscape:pageshadow="2" - inkscape:window-width="1484" - inkscape:window-height="697" - id="namedview4" - showgrid="false" - inkscape:zoom="13.520979" - inkscape:cx="20.549976" - inkscape:cy="7.9399684" - inkscape:window-x="67" - inkscape:window-y="27" - inkscape:window-maximized="0" - inkscape:current-layer="svg2" /> - <path - inkscape:connector-curvature="0" - id="path835" - d="m 19.839879,15.499154 c -0.0652,-0.0268 -0.141743,-0.1098 -0.170113,-0.184417 -0.03304,-0.08688 -0.05158,-0.95731 -0.05158,-5.912028 V 3.1830459 l 0.108486,-0.1379162 c 0.150269,-0.1910365 0.41814,-0.1907342 0.568677,6.436e-4 l 0.10899,0.1385579 -0.01358,6.2990785 c -0.01194,6.8660953 -0.0921,5.3381383 -0.0921,5.9327083 -0.106573,0.104434 -0.315006,0.142158 -0.458762,0.08303 z M 5.3808767,14.575188 C 4.5309456,14.518738 3.6260357,14.196602 2.9750499,13.718734 2.5767564,13.42636 2.0035795,12.787236 1.747789,12.350269 1.2385669,11.480363 1.0170768,10.580508 1.0213778,9.399057 1.0293972,7.2009406 1.9726797,5.5285643 3.6891526,4.6693537 4.7813316,4.1226444 6.2246017,4.0371807 7.4330177,4.4476602 8.1309525,4.6847376 8.4685433,4.8972607 9.0207129,5.4471587 9.4063328,5.8311907 9.5338898,6.0004852 9.7108978,6.3631718 9.8335428,6.6144683 9.9681328,6.9987435 10.020175,7.2461971 10.145759,7.8433551 10.170431,7.8289765 9.0218356,7.828057 8.5307356,7.8276009 8.0769363,7.8134035 8.0133918,7.7963663 7.9392662,7.7764919 7.8757344,7.6970176 7.8361313,7.5746239 7.5012661,6.5397183 6.6297764,6.0267536 5.4889128,6.193037 4.244092,6.3744711 3.4980921,7.3344965 3.343357,8.9541432 3.2260083,10.182472 3.5434132,11.329338 4.1781352,11.97041 c 0.46237,0.466997 0.9869175,0.673904 1.7084683,0.673904 1.2025378,0 1.9439704,-0.533034 2.1862936,-1.57178 0.055989,-0.240028 0.059178,-0.324448 0.012859,-0.341503 -0.033838,-0.01246 -0.5090516,-0.02871 -1.0560342,-0.03612 L 6.0352096,10.681458 V 9.8178001 8.9541431 l 1.9890278,-0.014575 c 1.0939663,-0.00802 2.0422396,-0.00163 2.1072756,0.014201 l 0.118246,0.028779 -0.01356,2.6814549 -0.01356,2.681455 -0.7170922,0.01455 c -0.8295927,0.01682 -0.7753286,0.05076 -0.8815155,-0.55106 -0.036825,-0.208719 -0.077853,-0.379487 -0.091164,-0.379487 -0.013311,0 -0.16916,0.135437 -0.3463303,0.300972 -0.3894417,0.363866 -0.8188673,0.600316 -1.3418506,0.738852 -0.4725114,0.125166 -0.8081647,0.149449 -1.4638111,0.10591 z M 32.49721,14.469781 c -0.928547,-0.194854 -1.630354,-0.56605 -2.174913,-1.150343 -0.515384,-0.552992 -0.832054,-1.344249 -0.800629,-2.000518 l 0.01549,-0.323408 1.060826,-0.01418 1.060825,-0.01418 0.05146,0.135352 c 0.0283,0.07444 0.0517,0.198593 0.05197,0.275887 8.54e-4,0.230559 0.229434,0.649361 0.479979,0.879354 0.347226,0.318744 0.735307,0.44853 1.431019,0.478576 1.267096,0.05472 2.007349,-0.393206 1.947849,-1.178652 -0.0456,-0.601928 -0.471503,-0.860841 -2.12876,-1.294103 C 32.881626,10.103917 32.242852,9.9264243 32.07283,9.8691486 30.95902,9.4939337 30.283515,8.9537559 29.97948,8.195172 29.836139,7.8375288 29.784025,7.0484225 29.874852,6.6109088 30.100606,5.5234588 31.071976,4.6456053 32.416011,4.314394 33.01697,4.1662997 34.128873,4.156633 34.77144,4.293917 c 1.67335,0.3575071 2.584333,1.270761 2.774448,2.7813655 0.0543,0.4314615 0.0347,0.4394334 -1.080484,0.4394334 -0.521251,0 -0.9851,-0.023133 -1.038665,-0.051802 C 35.367672,7.4313026 35.307808,7.3078793 35.273143,7.1462409 35.195527,6.7843357 35.099156,6.6147944 34.849667,6.4012402 34.543832,6.1394568 34.14764,6.029069 33.515213,6.0294329 c -0.428465,2.111e-4 -0.570793,0.021517 -0.784491,0.1172346 -0.47592,0.2131691 -0.654939,0.4628549 -0.654939,0.9134748 0,0.5904894 0.225799,0.7059322 2.58195,1.3200619 1.350552,0.3520209 1.903346,0.598685 2.415601,1.0778741 0.591219,0.5530567 0.852295,1.2543747 0.796412,2.1393787 -0.07929,1.255762 -0.891416,2.255747 -2.192274,2.699402 -0.885807,0.302103 -2.21918,0.374602 -3.180262,0.172924 z M 11.476954,14.306572 c -0.0138,-0.03619 -0.019,-2.268126 -0.01158,-4.9598581 l 0.0135,-4.8940567 1.066335,-0.01419 c 0.742348,-0.00988 1.088249,0.00399 1.138458,0.045665 0.06009,0.049873 0.07211,0.7135739 0.07211,3.9791612 v 3.9193056 h 2.293081 c 1.756352,0 2.314103,0.01538 2.382892,0.06567 0.07993,0.05845 0.08822,0.166396 0.07543,0.981428 l -0.01437,0.915757 -3.495384,0.01345 c -2.768549,0.0107 -3.500605,-1.69e-4 -3.520473,-0.05234 z m 10.193414,0.0026 c -0.04842,-0.04842 -0.06297,-1.193838 -0.06236,-4.9074882 4.61e-4,-2.6643823 0.01959,-4.8739347 0.04256,-4.9101166 0.03301,-0.05201 0.813774,-0.062971 3.728627,-0.052342 l 3.686862,0.013441 V 5.3948518 6.337024 l -2.5648,0.026171 -2.5648,0.026172 v 0.9421438 0.9421716 l 2.313597,0.026171 c 1.548367,0.017515 2.332217,0.044804 2.36989,0.082507 0.03673,0.036745 0.05127,0.3461819 0.04183,0.889829 l -0.01446,0.8334926 -2.355428,0.02617 -2.355429,0.02617 v 1.0992 1.099199 l 2.617143,0.0274 c 1.439428,0.01507 2.623562,0.03274 2.63141,0.03926 0.0078,0.0065 0.0078,0.441727 0,0.967118 l -0.01427,0.955257 -3.718613,0.01343 c -2.848812,0.01027 -3.733388,-0.0013 -3.781773,-0.04973 z m 17.753791,-0.378679 c -0.04061,-0.105824 0.0759,-0.828141 0.198829,-1.232689 0.288088,-0.948035 0.88431,-1.590368 2.319422,-2.498804 1.100465,-0.6965999 1.86374,-1.2293374 2.17747,-1.5198007 0.515251,-0.477031 0.731074,-1.0868265 0.620161,-1.7522036 -0.126353,-0.7579473 -0.607483,-1.1395723 -1.436711,-1.1395723 -0.930964,0 -1.401324,0.4507271 -1.481617,1.4197789 l -0.03634,0.4383927 h -1.099202 -1.099196 l -0.01524,-0.3725124 c -0.03408,-0.8332648 0.288934,-1.6827799 0.855164,-2.2490093 0.399774,-0.3997734 1.09283,-0.7574546 1.70958,-0.8822975 0.580047,-0.1174131 1.71432,-0.1077309 2.332892,0.019914 1.258364,0.2596698 2.203978,1.0560413 2.520675,2.1228587 0.104477,0.3519131 0.117355,0.4871812 0.09657,1.0144101 -0.01959,0.4962935 -0.04847,0.667451 -0.157022,0.9292002 -0.313508,0.7560998 -0.900391,1.3802206 -1.888823,2.0086882 -1.507571,0.958543 -1.915442,1.243322 -2.230808,1.557578 -0.26352,0.262604 -0.32016,0.345357 -0.261709,0.382352 0.04123,0.0261 1.061246,0.04757 2.280484,0.04802 1.96272,7.11e-4 2.209393,0.0099 2.237659,0.0836 0.01749,0.04554 0.03178,0.408703 0.03178,0.807033 0,0.398331 -0.0143,0.761495 -0.03178,0.807033 -0.0286,0.07445 -0.414152,0.0828 -3.822672,0.0828 -3.236429,0 -3.795092,-0.01093 -3.819578,-0.07475 z" - style="fill:#5586a4;fill-opacity:1;stroke-width:0.05234285" - sodipodi:nodetypes="ccscccccccccsscsscccccscccsccsccccccccccssscccccccccccccccscsccsccccsssscscccccccscscscccccccscccccccscccccccscccccccccccscccccsssccccccccscscc" /> - <path - style="fill:#000000;stroke-width:1.06666672" - d="" - id="path819" - inkscape:connector-curvature="0" /> - <path - style="fill:#000000;stroke-width:1.06666672" - d="" - id="path817" - inkscape:connector-curvature="0" /> -</svg> diff --git a/editor/icons/icon_g_l_e_s_3.svg b/editor/icons/icon_g_l_e_s_3.svg deleted file mode 100644 index dfa3c26b38..0000000000 --- a/editor/icons/icon_g_l_e_s_3.svg +++ /dev/null @@ -1,67 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<!-- Created with Inkscape (http://www.inkscape.org/) --> - -<svg - xmlns:dc="http://purl.org/dc/elements/1.1/" - xmlns:cc="http://creativecommons.org/ns#" - xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" - xmlns:svg="http://www.w3.org/2000/svg" - xmlns="http://www.w3.org/2000/svg" - xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - version="1.1" - id="svg2" - width="48" - height="16" - viewBox="0 0 47.999999 16" - sodipodi:docname="icon_g_l_e_s_3.svg" - inkscape:version="0.92.3 (2405546, 2018-03-11)"> - <metadata - id="metadata8"> - <rdf:RDF> - <cc:Work - rdf:about=""> - <dc:format>image/svg+xml</dc:format> - <dc:type - rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> - <dc:title></dc:title> - </cc:Work> - </rdf:RDF> - </metadata> - <defs - id="defs6" /> - <sodipodi:namedview - pagecolor="#ffffff" - bordercolor="#666666" - borderopacity="1" - objecttolerance="10" - gridtolerance="10" - guidetolerance="10" - inkscape:pageopacity="0" - inkscape:pageshadow="2" - inkscape:window-width="1484" - inkscape:window-height="697" - id="namedview4" - showgrid="false" - inkscape:zoom="13.520979" - inkscape:cx="20.549976" - inkscape:cy="7.9399684" - inkscape:window-x="67" - inkscape:window-y="27" - inkscape:window-maximized="0" - inkscape:current-layer="svg2" /> - <path - style="fill:#6aa455;fill-opacity:1;stroke-width:0.05234285" - d="M 20.011719 2.9023438 C 19.90715 2.9022255 19.801697 2.9494036 19.726562 3.0449219 L 19.619141 3.1835938 L 19.619141 9.4023438 C 19.619141 14.357062 19.636882 15.227573 19.669922 15.314453 C 19.698292 15.38907 19.774644 15.4732 19.839844 15.5 C 19.9836 15.559128 20.192255 15.52045 20.298828 15.416016 C 20.298828 14.821446 20.378685 16.35047 20.390625 9.484375 L 20.404297 3.1835938 L 20.294922 3.0449219 C 20.219653 2.949233 20.116287 2.902462 20.011719 2.9023438 z M 33.578125 4.1972656 C 33.144709 4.2010336 32.716495 4.240406 32.416016 4.3144531 C 31.071981 4.6456644 30.100754 5.5238781 29.875 6.6113281 C 29.784173 7.0488418 29.835175 7.8376693 29.978516 8.1953125 C 30.282551 8.9538964 30.958456 9.4939257 32.072266 9.8691406 C 32.242288 9.9264163 32.881487 10.104023 33.492188 10.263672 C 35.149445 10.696934 35.575494 10.956666 35.621094 11.558594 C 35.680594 12.34404 34.940924 12.791048 33.673828 12.736328 C 32.978116 12.706282 32.589413 12.576557 32.242188 12.257812 C 31.991643 12.02782 31.762573 11.609465 31.761719 11.378906 C 31.761449 11.301612 31.739238 11.176002 31.710938 11.101562 L 31.658203 10.966797 L 30.597656 10.980469 L 29.537109 10.996094 L 29.521484 11.318359 C 29.490059 11.974628 29.806882 12.767321 30.322266 13.320312 C 30.866825 13.904606 31.5695 14.275849 32.498047 14.470703 C 33.459129 14.672381 34.791927 14.598978 35.677734 14.296875 C 36.978592 13.85322 37.789851 12.853418 37.869141 11.597656 C 37.925024 10.712652 37.665438 10.012041 37.074219 9.4589844 C 36.561964 8.9797953 36.008755 8.7328803 34.658203 8.3808594 C 32.302052 7.7667297 32.076172 7.6510363 32.076172 7.0605469 C 32.076172 6.609927 32.254549 6.3596535 32.730469 6.1464844 C 32.944167 6.0507668 33.08716 6.029508 33.515625 6.0292969 C 34.148052 6.028933 34.543774 6.1386072 34.849609 6.4003906 C 35.099098 6.6139448 35.195822 6.7845792 35.273438 7.1464844 C 35.308103 7.3081228 35.366714 7.4312793 35.425781 7.4628906 C 35.479346 7.4915596 35.943593 7.515625 36.464844 7.515625 C 37.580028 7.515625 37.599222 7.5076334 37.544922 7.0761719 C 37.354807 5.5655674 36.444834 4.6504759 34.771484 4.2929688 C 34.450201 4.2243268 34.011541 4.1934977 33.578125 4.1972656 z M 5.5175781 4.1992188 C 4.8691862 4.2376134 4.2355426 4.3965672 3.6894531 4.6699219 C 1.9729802 5.5291325 1.0295038 7.2003211 1.0214844 9.3984375 C 1.0171834 10.579889 1.2388248 11.479703 1.7480469 12.349609 C 2.0038374 12.786576 2.5763159 13.426376 2.9746094 13.71875 C 3.6255952 14.196618 4.5309283 14.517769 5.3808594 14.574219 C 6.0365058 14.617758 6.3712386 14.593916 6.84375 14.46875 C 7.3667333 14.330214 7.7980583 14.094335 8.1875 13.730469 C 8.3646703 13.564934 8.5198921 13.429688 8.5332031 13.429688 C 8.5465141 13.429688 8.588175 13.599875 8.625 13.808594 C 8.7311869 14.410414 8.6762667 14.376195 9.5058594 14.359375 L 10.222656 14.345703 L 10.236328 11.664062 L 10.25 8.9824219 L 10.130859 8.953125 C 10.065823 8.937294 9.1174038 8.9314331 8.0234375 8.9394531 L 6.0351562 8.9550781 L 6.0351562 9.8183594 L 6.0351562 10.681641 L 7.0292969 10.695312 C 7.5762795 10.702722 8.0520995 10.718009 8.0859375 10.730469 C 8.1322565 10.747524 8.1282546 10.832238 8.0722656 11.072266 C 7.8299424 12.111012 7.0892565 12.644531 5.8867188 12.644531 C 5.1651679 12.644531 4.6401044 12.4377 4.1777344 11.970703 C 3.5430124 11.329631 3.2264013 10.183407 3.34375 8.9550781 C 3.4984851 7.3354314 4.2434605 6.3747935 5.4882812 6.1933594 C 6.6291449 6.027076 7.5010723 6.5393131 7.8359375 7.5742188 C 7.8755406 7.6966124 7.9395463 7.7770006 8.0136719 7.796875 C 8.0772164 7.8139122 8.5303844 7.8276689 9.0214844 7.828125 C 10.17008 7.8290445 10.145115 7.8432518 10.019531 7.2460938 C 9.967489 6.9986401 9.8335825 6.6145778 9.7109375 6.3632812 C 9.5339295 6.0005947 9.4071043 5.8312976 9.0214844 5.4472656 C 8.4693148 4.8973676 8.1315285 4.684343 7.4335938 4.4472656 C 6.8293858 4.2420259 6.16597 4.1608241 5.5175781 4.1992188 z M 42.03125 4.2617188 L 41.537109 4.4335938 C 40.933232 4.6433398 40.657695 4.8014669 40.300781 5.1386719 C 39.969225 5.4519119 39.761404 5.8046136 39.621094 6.2910156 C 39.502474 6.7023596 39.433137 7.3494687 39.498047 7.4492188 C 39.531044 7.4999487 39.783863 7.5127831 40.576172 7.5019531 L 41.611328 7.4863281 L 41.691406 7.0703125 C 41.808812 6.4678105 41.927622 6.2685471 42.265625 6.0957031 C 42.510424 5.9705181 42.604184 5.953125 43.019531 5.953125 C 43.426321 5.953125 43.533311 5.9721266 43.765625 6.0878906 C 44.253715 6.3311276 44.455638 6.904517 44.273438 7.53125 C 44.105442 8.109131 43.697334 8.363965 42.791016 8.453125 C 42.521874 8.479605 42.288464 8.51424 42.271484 8.53125 C 42.225224 8.577174 42.232777 9.7874244 42.279297 9.8339844 C 42.301291 9.8559744 42.598053 9.8907794 42.939453 9.9121094 C 43.836652 9.9681724 44.239534 10.166191 44.525391 10.691406 C 44.916028 11.409137 44.561069 12.318315 43.787109 12.582031 C 43.476088 12.688024 42.767292 12.688624 42.470703 12.583984 C 42.00204 12.418633 41.795632 12.174325 41.642578 11.597656 L 41.560547 11.285156 L 40.46875 11.285156 L 39.376953 11.285156 L 39.361328 11.527344 C 39.352678 11.660649 39.384791 11.918152 39.431641 12.099609 C 39.739925 13.294376 40.783209 14.156157 42.212891 14.396484 C 42.284425 14.408514 42.682741 14.422181 43.097656 14.425781 C 44.074936 14.434074 44.653306 14.320796 45.308594 13.996094 C 46.07786 13.61492 46.610204 13.058412 46.847656 12.382812 C 47.087412 11.700564 47.08166 10.999125 46.833984 10.333984 C 46.695621 9.962377 46.130198 9.3782416 45.6875 9.1503906 C 45.523031 9.0657476 45.386773 8.9810006 45.386719 8.9628906 C 45.386654 8.9447846 45.539488 8.8195027 45.724609 8.6835938 C 46.129744 8.3861558 46.390215 8.064434 46.53125 7.6875 C 46.963216 6.532963 46.370297 5.2063894 45.166016 4.6308594 C 44.482944 4.3044164 44.23589 4.2611938 43.072266 4.2617188 L 42.03125 4.2617188 z M 12.544922 4.4375 L 11.478516 4.453125 L 11.464844 9.3476562 C 11.457424 12.039388 11.462763 14.270451 11.476562 14.306641 C 11.49643 14.358812 12.229498 14.370075 14.998047 14.359375 L 18.492188 14.345703 L 18.507812 13.429688 C 18.520602 12.614656 18.511571 12.507669 18.431641 12.449219 C 18.362852 12.398929 17.80518 12.382812 16.048828 12.382812 L 13.755859 12.382812 L 13.755859 8.4628906 C 13.755859 5.1973033 13.743684 4.534248 13.683594 4.484375 C 13.633385 4.4427 13.28727 4.42762 12.544922 4.4375 z M 25.378906 4.4394531 C 22.464053 4.4288241 21.683401 4.4401775 21.650391 4.4921875 C 21.627421 4.5283694 21.607883 6.7379615 21.607422 9.4023438 C 21.606812 13.115994 21.621502 14.260174 21.669922 14.308594 C 21.718307 14.357024 22.60236 14.369645 25.451172 14.359375 L 29.169922 14.345703 L 29.185547 13.390625 C 29.193347 12.865234 29.193347 12.430328 29.185547 12.423828 C 29.177699 12.417308 27.992162 12.399836 26.552734 12.384766 L 23.935547 12.355469 L 23.935547 11.257812 L 23.935547 10.158203 L 26.291016 10.132812 L 28.646484 10.105469 L 28.662109 9.2714844 C 28.671549 8.7278373 28.655871 8.4195575 28.619141 8.3828125 C 28.581468 8.3451095 27.798367 8.3182962 26.25 8.3007812 L 23.935547 8.2734375 L 23.935547 7.3320312 L 23.935547 6.3886719 L 26.501953 6.3632812 L 29.066406 6.3378906 L 29.066406 5.3945312 L 29.066406 4.453125 L 25.378906 4.4394531 z " - id="path3424" /> - <path - style="fill:#000000;stroke-width:1.06666672" - d="" - id="path819" - inkscape:connector-curvature="0" /> - <path - style="fill:#000000;stroke-width:1.06666672" - d="" - id="path817" - inkscape:connector-curvature="0" /> -</svg> diff --git a/editor/icons/icon_text_file.svg b/editor/icons/icon_text_file.svg new file mode 100644 index 0000000000..342a407b79 --- /dev/null +++ b/editor/icons/icon_text_file.svg @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="16" + height="16" + version="1.1" + viewBox="0 0 16 16" + id="svg8" + sodipodi:docname="icon_text_file.svg" + inkscape:version="0.92.2 2405546, 2018-03-11" + enable-background="new"> + <metadata + id="metadata14"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs12" /> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="2560" + inkscape:window-height="1440" + id="namedview10" + showgrid="false" + inkscape:zoom="64" + inkscape:cx="-0.11275433" + inkscape:cy="5.0633688" + inkscape:window-x="1920" + inkscape:window-y="0" + inkscape:window-maximized="0" + inkscape:current-layer="svg8" + inkscape:snap-grids="true" /> + <path + style="display:inline;fill:#e0e0e0" + d="m 13.370548,12.198712 c 0.359546,-0.0075 0.719092,-0.015 1.078638,-0.0225 -0.004,-0.738576 -0.008,-1.477152 -0.01198,-2.215728 -1.429703,0.011985 -2.859406,0.02397 -4.289109,0.035955 0.004,0.759672 0.008,1.519344 0.01198,2.279016 0.40349,-0.01135 0.806981,-0.02271 1.210471,-0.03406 0,1.251681 0,2.503363 0,3.755044 0.666667,0 1.333333,0 2,0 M 6.1005477,12.247152 c 0.332722,0.21587 0.665444,0.431741 0.998166,0.647611 -0.3328629,0.218648 -0.6657258,0.437297 -0.9985887,0.655945 -1e-7,0.818044 -2e-7,1.636088 -3e-7,2.454132 0.5662705,-0.533749 1.1325409,-1.067498 1.6988114,-1.601247 0.6353035,0.532396 1.2706071,1.064791 1.9059106,1.597187 -9.5e-4,-0.757409 -0.0019,-1.514817 -0.00285,-2.272226 -0.2987204,-0.278501 -0.5974407,-0.557002 -0.8961611,-0.835503 0.2983766,-0.205775 0.5967531,-0.41155 0.8951297,-0.617325 0.00283,-0.73844 0.00565,-1.476881 0.00848,-2.215321 -0.63732,0.474447 -1.27464,0.948893 -1.91196,1.42334 C 7.2318406,10.979446 6.6661958,10.475146 6.1005511,9.9708468 M 4.6399123,12.202271 c 0.3595459,-0.0075 0.7190917,-0.015 1.0786376,-0.0225 -0.00399,-0.738576 -0.00799,-1.477152 -0.011985,-2.2157276 -1.4297028,0.011985 -2.8594057,0.02397 -4.2891085,0.035955 0.00399,0.7596716 0.00799,1.5193436 0.011985,2.2790156 0.4034903,-0.01135 0.8069806,-0.02271 1.2104709,-0.03406 0,1.251681 0,2.503363 0,3.755044 0.6666667,0 1.3333333,0 2,0 M 7,1 C 6.81185,1.7526 6.6237,2.5052 6.43555,3.2578 6.0521572,3.3957205 5.6943609,3.6619566 5.3589944,3.3047548 4.8252629,2.9844032 4.2915315,2.6640516 3.7578,2.3437 3.2864333,2.8150667 2.8150667,3.2864333 2.3437,3.7578 2.7421333,4.4225 3.1405667,5.0872 3.539,5.7519 3.3683054,6.121632 3.3058712,6.5625877 2.8157946,6.5467719 2.2105097,6.6978312 1.6052249,6.8488906 0.99994,6.99995 c 0,0.6666667 0,1.3333333 0,2 1.7571667,0 3.5143333,0 5.2715,0 C 5.5845118,7.9199003 6.2580962,6.3373839 7.5001288,6.0629153 8.7083679,5.7047153 10.045643,6.7406952 9.99996,7.99995 c 0.104409,0.4657408 -0.6052318,1.1778026 0.181951,1 1.606006,0 3.212013,0 4.818019,0 0,-0.6666667 0,-1.3333333 0,-2 C 14.24733,6.8118 13.49473,6.62365 12.74213,6.4355 12.603459,6.0528244 12.33852,5.6958457 12.695012,5.3607965 13.015418,4.8264643 13.335824,4.2921322 13.65623,3.7578 13.184863,3.2864333 12.713497,2.8150667 12.24213,2.3437 11.57743,2.7421333 10.91273,3.1405667 10.24803,3.539 9.8782981,3.3683053 9.4373423,3.3058712 9.4531581,2.8157946 9.3020988,2.2105097 9.1510394,1.6052249 8.99998,0.99994 8.3333478,0.99998002 7.6664935,0.99985998 7,1 Z" + id="path4781-7" + inkscape:connector-curvature="0" /> +</svg> diff --git a/editor/import/SCsub b/editor/import/SCsub index f1fa50148f..2b1e889fb0 100644 --- a/editor/import/SCsub +++ b/editor/import/SCsub @@ -1,5 +1,5 @@ #!/usr/bin/env python Import('env') -Export('env') + env.add_source_files(env.editor_sources, "*.cpp") diff --git a/editor/import/editor_import_collada.cpp b/editor/import/editor_import_collada.cpp index d4bd4f85e6..60ca66e464 100644 --- a/editor/import/editor_import_collada.cpp +++ b/editor/import/editor_import_collada.cpp @@ -30,9 +30,9 @@ #include "editor_import_collada.h" +#include "core/os/os.h" #include "editor/collada/collada.h" #include "editor/editor_node.h" -#include "os/os.h" #include "scene/3d/camera.h" #include "scene/3d/light.h" #include "scene/3d/mesh_instance.h" @@ -490,120 +490,6 @@ Error ColladaImport::_create_material(const String &p_target) { return OK; } -static void _generate_normals(const PoolVector<int> &p_indices, const PoolVector<Vector3> &p_vertices, PoolVector<Vector3> &r_normals) { - - r_normals.resize(p_vertices.size()); - PoolVector<Vector3>::Write narrayw = r_normals.write(); - - int iacount = p_indices.size() / 3; - PoolVector<int>::Read index_arrayr = p_indices.read(); - PoolVector<Vector3>::Read vertex_arrayr = p_vertices.read(); - - for (int idx = 0; idx < iacount; idx++) { - - Vector3 v[3] = { - vertex_arrayr[index_arrayr[idx * 3 + 0]], - vertex_arrayr[index_arrayr[idx * 3 + 1]], - vertex_arrayr[index_arrayr[idx * 3 + 2]] - }; - - Vector3 normal = Plane(v[0], v[1], v[2]).normal; - - narrayw[index_arrayr[idx * 3 + 0]] += normal; - narrayw[index_arrayr[idx * 3 + 1]] += normal; - narrayw[index_arrayr[idx * 3 + 2]] += normal; - } - - int vlen = p_vertices.size(); - - for (int idx = 0; idx < vlen; idx++) { - narrayw[idx].normalize(); - } -} - -static void _generate_tangents_and_binormals(const PoolVector<int> &p_indices, const PoolVector<Vector3> &p_vertices, const PoolVector<Vector3> &p_uvs, const PoolVector<Vector3> &p_normals, PoolVector<real_t> &r_tangents) { - - int vlen = p_vertices.size(); - - Vector<Vector3> tangents; - tangents.resize(vlen); - Vector<Vector3> binormals; - binormals.resize(vlen); - - int iacount = p_indices.size() / 3; - - PoolVector<int>::Read index_arrayr = p_indices.read(); - PoolVector<Vector3>::Read vertex_arrayr = p_vertices.read(); - PoolVector<Vector3>::Read narrayr = p_normals.read(); - PoolVector<Vector3>::Read uvarrayr = p_uvs.read(); - - for (int idx = 0; idx < iacount; idx++) { - - Vector3 v1 = vertex_arrayr[index_arrayr[idx * 3 + 0]]; - Vector3 v2 = vertex_arrayr[index_arrayr[idx * 3 + 1]]; - Vector3 v3 = vertex_arrayr[index_arrayr[idx * 3 + 2]]; - - Vector3 w1 = uvarrayr[index_arrayr[idx * 3 + 0]]; - Vector3 w2 = uvarrayr[index_arrayr[idx * 3 + 1]]; - Vector3 w3 = uvarrayr[index_arrayr[idx * 3 + 2]]; - - real_t x1 = v2.x - v1.x; - real_t x2 = v3.x - v1.x; - real_t y1 = v2.y - v1.y; - real_t y2 = v3.y - v1.y; - real_t z1 = v2.z - v1.z; - real_t z2 = v3.z - v1.z; - - real_t s1 = w2.x - w1.x; - real_t s2 = w3.x - w1.x; - real_t t1 = w2.y - w1.y; - real_t t2 = w3.y - w1.y; - - real_t r = (s1 * t2 - s2 * t1); - - Vector3 tangent; - Vector3 binormal; - - if (r == 0) { - - binormal = Vector3(); - tangent = Vector3(); - } else { - tangent = Vector3((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, - (t2 * z1 - t1 * z2) * r) - .normalized(); - binormal = Vector3((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, - (s1 * z2 - s2 * z1) * r) - .normalized(); - } - - tangents.write[index_arrayr[idx * 3 + 0]] += tangent; - binormals.write[index_arrayr[idx * 3 + 0]] += binormal; - tangents.write[index_arrayr[idx * 3 + 1]] += tangent; - binormals.write[index_arrayr[idx * 3 + 1]] += binormal; - tangents.write[index_arrayr[idx * 3 + 2]] += tangent; - binormals.write[index_arrayr[idx * 3 + 2]] += binormal; - } - - r_tangents.resize(vlen * 4); - PoolVector<real_t>::Write tarrayw = r_tangents.write(); - - for (int idx = 0; idx < vlen; idx++) { - Vector3 tangent = tangents[idx]; - Vector3 bingen = narrayr[idx].cross(tangent); - float dir; - if (bingen.dot(binormals[idx]) < 0) - dir = -1.0; - else - dir = +1.0; - - tarrayw[idx * 4 + 0] = tangent.x; - tarrayw[idx * 4 + 1] = tangent.y; - tarrayw[idx * 4 + 2] = tangent.z; - tarrayw[idx * 4 + 3] = dir; - } -} - Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_mesh, const Map<String, Collada::NodeGeometry::Material> &p_material_map, const Collada::MeshData &meshdata, const Transform &p_local_xform, const Vector<int> &bone_remap, const Collada::SkinControllerData *p_skin_controller, const Collada::MorphControllerData *p_morph_data, Vector<Ref<ArrayMesh> > p_morph_meshes, bool p_use_compression, bool p_use_mesh_material) { bool local_xform_mirror = p_local_xform.basis.determinant() < 0; diff --git a/editor/import/editor_import_plugin.h b/editor/import/editor_import_plugin.h index 92d83158ef..b850c0605b 100644 --- a/editor/import/editor_import_plugin.h +++ b/editor/import/editor_import_plugin.h @@ -31,7 +31,7 @@ #ifndef EDITOR_IMPORT_PLUGIN_H #define EDITOR_IMPORT_PLUGIN_H -#include "io/resource_import.h" +#include "core/io/resource_import.h" class EditorImportPlugin : public ResourceImporter { GDCLASS(EditorImportPlugin, Reference) diff --git a/editor/import/editor_scene_importer_gltf.cpp b/editor/import/editor_scene_importer_gltf.cpp index 4d5c292847..a6b754de3b 100644 --- a/editor/import/editor_scene_importer_gltf.cpp +++ b/editor/import/editor_scene_importer_gltf.cpp @@ -29,10 +29,10 @@ /*************************************************************************/ #include "editor_scene_importer_gltf.h" -#include "io/json.h" -#include "math_defs.h" -#include "os/file_access.h" -#include "os/os.h" +#include "core/io/json.h" +#include "core/math/math_defs.h" +#include "core/os/file_access.h" +#include "core/os/os.h" #include "scene/3d/camera.h" #include "scene/3d/mesh_instance.h" #include "scene/animation/animation_player.h" @@ -793,7 +793,7 @@ Vector<Quat> EditorSceneImporterGLTF::_decode_accessor_as_quat(GLTFState &state, ret.resize(ret_size); { for (int i = 0; i < ret_size; i++) { - ret.write[i] = Quat(attribs_ptr[i * 4 + 0], attribs_ptr[i * 4 + 1], attribs_ptr[i * 4 + 2], attribs_ptr[i * 4 + 3]); + ret.write[i] = Quat(attribs_ptr[i * 4 + 0], attribs_ptr[i * 4 + 1], attribs_ptr[i * 4 + 2], attribs_ptr[i * 4 + 3]).normalized(); } } return ret; @@ -1793,17 +1793,24 @@ template <> struct EditorSceneImporterGLTFInterpolate<Quat> { Quat lerp(const Quat &a, const Quat &b, float c) const { + ERR_FAIL_COND_V(a.is_normalized() == false, Quat()); + ERR_FAIL_COND_V(b.is_normalized() == false, Quat()); - return a.slerp(b, c); + return a.slerp(b, c).normalized(); } Quat catmull_rom(const Quat &p0, const Quat &p1, const Quat &p2, const Quat &p3, float c) { + ERR_FAIL_COND_V(p1.is_normalized() == false, Quat()); + ERR_FAIL_COND_V(p2.is_normalized() == false, Quat()); - return p1.slerp(p2, c); + return p1.slerp(p2, c).normalized(); } Quat bezier(Quat start, Quat control_1, Quat control_2, Quat end, float t) { - return start.slerp(end, t); + ERR_FAIL_COND_V(start.is_normalized() == false, Quat()); + ERR_FAIL_COND_V(end.is_normalized() == false, Quat()); + + return start.slerp(end, t).normalized(); } }; @@ -1869,9 +1876,9 @@ T EditorSceneImporterGLTF::_interpolate_track(const Vector<float> &p_times, cons float c = (p_time - p_times[idx]) / (p_times[idx + 1] - p_times[idx]); T from = p_values[idx * 3 + 1]; - T c1 = from + p_values[idx * 3 + 0]; - T to = p_values[idx * 3 + 3]; - T c2 = to + p_values[idx * 3 + 2]; + T c1 = from + p_values[idx * 3 + 2]; + T to = p_values[idx * 3 + 4]; + T c2 = to + p_values[idx * 3 + 3]; return interp.bezier(from, c1, c2, to, c); @@ -1903,15 +1910,15 @@ void EditorSceneImporterGLTF::_import_animation(GLTFState &state, AnimationPlaye NodePath node_path; GLTFNode *node = state.nodes[E->key()]; - for (int i = 0; i < node->godot_nodes.size(); i++) { + for (int n = 0; n < node->godot_nodes.size(); n++) { if (node->joints.size()) { - Skeleton *sk = (Skeleton *)node->godot_nodes[i]; + Skeleton *sk = (Skeleton *)node->godot_nodes[n]; String path = ap->get_parent()->get_path_to(sk); - String bone = sk->get_bone_name(node->joints[i].godot_bone_index); + String bone = sk->get_bone_name(node->joints[n].godot_bone_index); node_path = path + ":" + bone; } else { - node_path = ap->get_parent()->get_path_to(node->godot_nodes[i]); + node_path = ap->get_parent()->get_path_to(node->godot_nodes[n]); } for (int i = 0; i < track.rotation_track.times.size(); i++) { @@ -1945,7 +1952,7 @@ void EditorSceneImporterGLTF::_import_animation(GLTFState &state, AnimationPlaye Vector3 base_scale = Vector3(1, 1, 1); if (!track.rotation_track.values.size()) { - base_rot = state.nodes[E->key()]->rotation; + base_rot = state.nodes[E->key()]->rotation.normalized(); } if (!track.translation_track.values.size()) { @@ -1986,11 +1993,12 @@ void EditorSceneImporterGLTF::_import_animation(GLTFState &state, AnimationPlaye xform.basis.set_quat_scale(rot, scale); xform.origin = pos; - Skeleton *skeleton = skeletons[node->joints[i].skin]; - int bone = node->joints[i].godot_bone_index; + Skeleton *skeleton = skeletons[node->joints[n].skin]; + int bone = node->joints[n].godot_bone_index; xform = skeleton->get_bone_rest(bone).affine_inverse() * xform; rot = xform.basis.get_rotation_quat(); + rot.normalize(); scale = xform.basis.get_scale(); pos = xform.origin; } diff --git a/editor/import/resource_importer_bitmask.cpp b/editor/import/resource_importer_bitmask.cpp index 7b330936f6..917d6d1bcc 100644 --- a/editor/import/resource_importer_bitmask.cpp +++ b/editor/import/resource_importer_bitmask.cpp @@ -30,10 +30,10 @@ #include "resource_importer_bitmask.h" #include "core/image.h" +#include "core/io/config_file.h" +#include "core/io/image_loader.h" #include "editor/editor_file_system.h" #include "editor/editor_node.h" -#include "io/config_file.h" -#include "io/image_loader.h" #include "scene/resources/bit_mask.h" #include "scene/resources/texture.h" diff --git a/editor/import/resource_importer_bitmask.h b/editor/import/resource_importer_bitmask.h index f3537df819..1b97152099 100644 --- a/editor/import/resource_importer_bitmask.h +++ b/editor/import/resource_importer_bitmask.h @@ -31,8 +31,8 @@ #ifndef RESOURCE_IMPORTER_BITMASK_H #define RESOURCE_IMPORTER_BITMASK_H -#include "image.h" -#include "io/resource_import.h" +#include "core/image.h" +#include "core/io/resource_import.h" class StreamBitMap; diff --git a/editor/import/resource_importer_csv_translation.cpp b/editor/import/resource_importer_csv_translation.cpp index cf850eef03..e7f9e1afe6 100644 --- a/editor/import/resource_importer_csv_translation.cpp +++ b/editor/import/resource_importer_csv_translation.cpp @@ -30,10 +30,10 @@ #include "resource_importer_csv_translation.h" -#include "compressed_translation.h" -#include "io/resource_saver.h" -#include "os/file_access.h" -#include "translation.h" +#include "core/compressed_translation.h" +#include "core/io/resource_saver.h" +#include "core/os/file_access.h" +#include "core/translation.h" String ResourceImporterCSVTranslation::get_importer_name() const { diff --git a/editor/import/resource_importer_csv_translation.h b/editor/import/resource_importer_csv_translation.h index f5f230c6bd..370c182f65 100644 --- a/editor/import/resource_importer_csv_translation.h +++ b/editor/import/resource_importer_csv_translation.h @@ -31,7 +31,7 @@ #ifndef RESOURCEIMPORTERCSVTRANSLATION_H #define RESOURCEIMPORTERCSVTRANSLATION_H -#include "io/resource_import.h" +#include "core/io/resource_import.h" class ResourceImporterCSVTranslation : public ResourceImporter { GDCLASS(ResourceImporterCSVTranslation, ResourceImporter) diff --git a/editor/import/resource_importer_image.cpp b/editor/import/resource_importer_image.cpp index b6a67c0cd3..923a9a20ec 100644 --- a/editor/import/resource_importer_image.cpp +++ b/editor/import/resource_importer_image.cpp @@ -1,8 +1,38 @@ +/*************************************************************************/ +/* resource_importer_image.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + #include "resource_importer_image.h" -#include "io/image_loader.h" -#include "io/resource_saver.h" -#include "os/file_access.h" +#include "core/io/image_loader.h" +#include "core/io/resource_saver.h" +#include "core/os/file_access.h" #include "scene/resources/texture.h" String ResourceImporterImage::get_importer_name() const { diff --git a/editor/import/resource_importer_image.h b/editor/import/resource_importer_image.h index 5aadd00a35..d282ac482d 100644 --- a/editor/import/resource_importer_image.h +++ b/editor/import/resource_importer_image.h @@ -1,8 +1,38 @@ +/*************************************************************************/ +/* resource_importer_image.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + #ifndef RESOURCE_IMPORTER_IMAGE_H #define RESOURCE_IMPORTER_IMAGE_H -#include "image.h" -#include "io/resource_import.h" +#include "core/image.h" +#include "core/io/resource_import.h" class ResourceImporterImage : public ResourceImporter { GDCLASS(ResourceImporterImage, ResourceImporter) diff --git a/editor/import/resource_importer_layered_texture.cpp b/editor/import/resource_importer_layered_texture.cpp index 211bb7bcc9..afda07c1c2 100644 --- a/editor/import/resource_importer_layered_texture.cpp +++ b/editor/import/resource_importer_layered_texture.cpp @@ -1,11 +1,41 @@ +/*************************************************************************/ +/* resource_importer_layered_texture.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + #include "resource_importer_layered_texture.h" #include "resource_importer_texture.h" +#include "core/io/config_file.h" +#include "core/io/image_loader.h" #include "editor/editor_file_system.h" #include "editor/editor_node.h" -#include "io/config_file.h" -#include "io/image_loader.h" #include "scene/resources/texture.h" String ResourceImporterLayeredTexture::get_importer_name() const { @@ -52,6 +82,7 @@ String ResourceImporterLayeredTexture::get_preset_name(int p_idx) const { void ResourceImporterLayeredTexture::get_import_options(List<ImportOption> *r_options, int p_preset) const { r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/mode", PROPERTY_HINT_ENUM, "Lossless,Video RAM,Uncompressed", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), p_preset == PRESET_3D ? 1 : 0)); + r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "compress/no_bptc_if_rgb"), false)); r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "flags/repeat", PROPERTY_HINT_ENUM, "Disabled,Enabled,Mirrored"), 0)); r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "flags/filter"), true)); r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "flags/mipmaps"), p_preset == PRESET_COLOR_CORRECT ? 0 : 1)); @@ -273,7 +304,7 @@ Error ResourceImporterLayeredTexture::import(const String &p_source_file, const } if (!ok_on_pc) { - EditorNode::add_io_error("Warning, no suitable PC VRAM compression enabled in Project Settings. This texture will not display correcly on PC."); + EditorNode::add_io_error("Warning, no suitable PC VRAM compression enabled in Project Settings. This texture will not display correctly on PC."); } } else { //import normally diff --git a/editor/import/resource_importer_layered_texture.h b/editor/import/resource_importer_layered_texture.h index ec73b2624d..a4b83bf56c 100644 --- a/editor/import/resource_importer_layered_texture.h +++ b/editor/import/resource_importer_layered_texture.h @@ -1,8 +1,38 @@ +/*************************************************************************/ +/* resource_importer_layered_texture.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + #ifndef RESOURCE_IMPORTER_LAYERED_TEXTURE_H #define RESOURCE_IMPORTER_LAYERED_TEXTURE_H -#include "image.h" -#include "io/resource_import.h" +#include "core/image.h" +#include "core/io/resource_import.h" class StreamTexture; diff --git a/editor/import/resource_importer_obj.cpp b/editor/import/resource_importer_obj.cpp index 3f101cd04d..c237d2e854 100644 --- a/editor/import/resource_importer_obj.cpp +++ b/editor/import/resource_importer_obj.cpp @@ -30,8 +30,8 @@ #include "resource_importer_obj.h" -#include "io/resource_saver.h" -#include "os/file_access.h" +#include "core/io/resource_saver.h" +#include "core/os/file_access.h" #include "scene/3d/mesh_instance.h" #include "scene/3d/spatial.h" #include "scene/resources/mesh.h" @@ -126,7 +126,12 @@ static Error _parse_material_library(const String &p_path, Map<String, Ref<Spati ERR_FAIL_COND_V(current.is_null(), ERR_FILE_CORRUPT); String p = l.replace("map_Kd", "").replace("\\", "/").strip_edges(); - String path = base_path.plus_file(p); + String path; + if (p.is_abs_path()) { + path = p; + } else { + path = base_path.plus_file(p); + } Ref<Texture> texture = ResourceLoader::load(path); @@ -141,7 +146,12 @@ static Error _parse_material_library(const String &p_path, Map<String, Ref<Spati ERR_FAIL_COND_V(current.is_null(), ERR_FILE_CORRUPT); String p = l.replace("map_Ks", "").replace("\\", "/").strip_edges(); - String path = base_path.plus_file(p); + String path; + if (p.is_abs_path()) { + path = p; + } else { + path = base_path.plus_file(p); + } Ref<Texture> texture = ResourceLoader::load(path); @@ -156,7 +166,12 @@ static Error _parse_material_library(const String &p_path, Map<String, Ref<Spati ERR_FAIL_COND_V(current.is_null(), ERR_FILE_CORRUPT); String p = l.replace("map_Ns", "").replace("\\", "/").strip_edges(); - String path = base_path.plus_file(p); + String path; + if (p.is_abs_path()) { + path = p; + } else { + path = base_path.plus_file(p); + } Ref<Texture> texture = ResourceLoader::load(path); diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp index f544811eb0..6d72cb4909 100644 --- a/editor/import/resource_importer_scene.cpp +++ b/editor/import/resource_importer_scene.cpp @@ -30,8 +30,8 @@ #include "resource_importer_scene.h" +#include "core/io/resource_saver.h" #include "editor/editor_node.h" -#include "io/resource_saver.h" #include "scene/resources/packed_scene.h" #include "scene/3d/collision_shape.h" diff --git a/editor/import/resource_importer_scene.h b/editor/import/resource_importer_scene.h index 2bde9432fc..b046e2e975 100644 --- a/editor/import/resource_importer_scene.h +++ b/editor/import/resource_importer_scene.h @@ -31,7 +31,7 @@ #ifndef RESOURCEIMPORTERSCENE_H #define RESOURCEIMPORTERSCENE_H -#include "io/resource_import.h" +#include "core/io/resource_import.h" #include "scene/resources/animation.h" #include "scene/resources/mesh.h" #include "scene/resources/shape.h" diff --git a/editor/import/resource_importer_texture.cpp b/editor/import/resource_importer_texture.cpp index d03395c070..5eb1a42f9f 100644 --- a/editor/import/resource_importer_texture.cpp +++ b/editor/import/resource_importer_texture.cpp @@ -30,10 +30,10 @@ #include "resource_importer_texture.h" +#include "core/io/config_file.h" +#include "core/io/image_loader.h" #include "editor/editor_file_system.h" #include "editor/editor_node.h" -#include "io/config_file.h" -#include "io/image_loader.h" #include "scene/resources/texture.h" void ResourceImporterTexture::_texture_reimport_srgb(const Ref<StreamTexture> &p_tex) { @@ -164,11 +164,19 @@ bool ResourceImporterTexture::get_option_visibility(const String &p_option, cons if (compress_mode != COMPRESS_LOSSY && compress_mode != COMPRESS_VIDEO_RAM) { return false; } - } else if (p_option == "compress/no_bptc_if_rgb" || p_option == "compress/hdr_mode") { + } else if (p_option == "compress/hdr_mode") { int compress_mode = int(p_options["compress/mode"]); if (compress_mode != COMPRESS_VIDEO_RAM) { return false; } + } else if (p_option == "compress/bptc_ldr") { + int compress_mode = int(p_options["compress/mode"]); + if (compress_mode != COMPRESS_VIDEO_RAM) { + return false; + } + if (!ProjectSettings::get_singleton()->get("rendering/vram_compression/import_bptc")) { + return false; + } } return true; @@ -193,8 +201,8 @@ void ResourceImporterTexture::get_import_options(List<ImportOption> *r_options, r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/mode", PROPERTY_HINT_ENUM, "Lossless,Lossy,Video RAM,Uncompressed", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), p_preset == PRESET_3D ? 2 : 0)); r_options->push_back(ImportOption(PropertyInfo(Variant::REAL, "compress/lossy_quality", PROPERTY_HINT_RANGE, "0,1,0.01"), 0.7)); - r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "compress/no_bptc_if_rgb"), false)); - r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/hdr_mode", PROPERTY_HINT_ENUM, "LDR Fallback,Force RGBE,RGBE Fallback"), 0)); + r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/hdr_mode", PROPERTY_HINT_ENUM, "Enabled,Force RGBE"), 0)); + r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/bptc_ldr", PROPERTY_HINT_ENUM, "Enabled,RGBA Only"), 0)); r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/normal_map", PROPERTY_HINT_ENUM, "Detect,Enable,Disabled"), 0)); r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "flags/repeat", PROPERTY_HINT_ENUM, "Disabled,Enabled,Mirrored"), p_preset == PRESET_3D ? 1 : 0)); r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "flags/filter"), p_preset == PRESET_2D_PIXEL ? false : true)); @@ -353,7 +361,6 @@ void ResourceImporterTexture::_save_stex(const Ref<Image> &p_image, const String Error ResourceImporterTexture::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files) { int compress_mode = p_options["compress/mode"]; - int no_bptc_if_rgb = p_options["compress/no_bptc_if_rgb"]; float lossy = p_options["compress/lossy_quality"]; int repeat = p_options["flags/repeat"]; bool filter = p_options["flags/filter"]; @@ -365,11 +372,11 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String bool invert_color = p_options["process/invert_color"]; bool stream = p_options["stream"]; int size_limit = p_options["size_limit"]; - bool force_rgbe = int(p_options["compress/hdr_mode"]) == 1; - bool rgbe_fallback = int(p_options["compress/hdr_mode"]) == 2; bool hdr_as_srgb = p_options["process/HDR_as_SRGB"]; int normal = p_options["compress/normal_map"]; float scale = p_options["svg/scale"]; + bool force_rgbe = p_options["compress/hdr_mode"]; + int bptc_ldr = p_options["compress/bptc_ldr"]; Ref<Image> image; image.instance(); @@ -424,8 +431,8 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String int width = image->get_width(); image->lock(); - for (int i = 0; i < height; i++) { - for (int j = 0; j < width; j++) { + for (int i = 0; i < width; i++) { + for (int j = 0; j < height; j++) { image->set_pixel(i, j, image->get_pixel(i, j).inverted()); } } @@ -442,61 +449,57 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String //Android, GLES 2.x bool ok_on_pc = false; - bool encode_bptc = false; bool is_hdr = (image->get_format() >= Image::FORMAT_RF && image->get_format() <= Image::FORMAT_RGBE9995); - bool no_ldr_compression = (is_hdr && rgbe_fallback); + bool is_ldr = (image->get_format() >= Image::FORMAT_L8 && image->get_format() <= Image::FORMAT_RGBA5551); + bool can_bptc = ProjectSettings::get_singleton()->get("rendering/vram_compression/import_bptc"); + bool can_s3tc = ProjectSettings::get_singleton()->get("rendering/vram_compression/import_s3tc"); - if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_bptc")) { + if (can_bptc) { + Image::DetectChannels channels = image->get_detected_channels(); + if (is_hdr) { - encode_bptc = true; + if (channels == Image::DETECTED_LA || channels == Image::DETECTED_RGBA) { + can_bptc = false; + } + } else if (is_ldr) { - if (no_bptc_if_rgb && !is_hdr) { - Image::DetectChannels channels = image->get_detected_channels(); - if (channels != Image::DETECTED_LA && channels != Image::DETECTED_RGBA) { - encode_bptc = false; + //handle "RGBA Only" setting + if (bptc_ldr == 1 && channels != Image::DETECTED_LA && channels != Image::DETECTED_RGBA) { + can_bptc = false; } } } - if (encode_bptc) { - - _save_stex(image, p_save_path + ".bptc.stex", compress_mode, lossy, Image::COMPRESS_BPTC, mipmaps, tex_flags, stream, detect_3d, detect_srgb, force_rgbe, detect_normal, force_normal); - r_platform_variants->push_back("bptc"); - ok_on_pc = true; + if (!can_bptc && is_hdr && !force_rgbe) { + //convert to ldr if this can't be stored hdr + image->convert(Image::FORMAT_RGBA8); } - if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_s3tc") && !no_ldr_compression) { - - _save_stex(image, p_save_path + ".s3tc.stex", compress_mode, lossy, Image::COMPRESS_S3TC, mipmaps, tex_flags, stream, detect_3d, detect_srgb, force_rgbe, detect_normal, force_normal); + if (can_bptc || can_s3tc) { + _save_stex(image, p_save_path + ".s3tc.stex", compress_mode, lossy, can_bptc ? Image::COMPRESS_BPTC : Image::COMPRESS_S3TC, mipmaps, tex_flags, stream, detect_3d, detect_srgb, force_rgbe, detect_normal, force_normal); r_platform_variants->push_back("s3tc"); ok_on_pc = true; } - if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_etc2") && !no_ldr_compression) { + if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_etc2")) { _save_stex(image, p_save_path + ".etc2.stex", compress_mode, lossy, Image::COMPRESS_ETC2, mipmaps, tex_flags, stream, detect_3d, detect_srgb, force_rgbe, detect_normal, force_normal); r_platform_variants->push_back("etc2"); } - if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_etc") && !no_ldr_compression) { + if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_etc")) { _save_stex(image, p_save_path + ".etc.stex", compress_mode, lossy, Image::COMPRESS_ETC, mipmaps, tex_flags, stream, detect_3d, detect_srgb, force_rgbe, detect_normal, force_normal); r_platform_variants->push_back("etc"); } - if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_pvrtc") && !no_ldr_compression) { + if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_pvrtc")) { _save_stex(image, p_save_path + ".pvrtc.stex", compress_mode, lossy, Image::COMPRESS_PVRTC4, mipmaps, tex_flags, stream, detect_3d, detect_srgb, force_rgbe, detect_normal, force_normal); r_platform_variants->push_back("pvrtc"); } - if (is_hdr && rgbe_fallback) { - _save_stex(image, p_save_path + ".fallback.stex", compress_mode, lossy, Image::COMPRESS_S3TC /*this is ignored */, mipmaps, tex_flags, stream, detect_3d, detect_srgb, true, detect_normal, force_normal); - r_platform_variants->push_back("fallback"); - ok_on_pc = true; - } - if (!ok_on_pc) { - EditorNode::add_io_error("Warning, no suitable PC VRAM compression enabled in Project Settings. This texture will not display correcly on PC."); + EditorNode::add_io_error("Warning, no suitable PC VRAM compression enabled in Project Settings. This texture will not display correctly on PC."); } } else { //import normally diff --git a/editor/import/resource_importer_texture.h b/editor/import/resource_importer_texture.h index fd6f75c3f4..b49b29874d 100644 --- a/editor/import/resource_importer_texture.h +++ b/editor/import/resource_importer_texture.h @@ -31,8 +31,8 @@ #ifndef RESOURCEIMPORTTEXTURE_H #define RESOURCEIMPORTTEXTURE_H -#include "image.h" -#include "io/resource_import.h" +#include "core/image.h" +#include "core/io/resource_import.h" class StreamTexture; diff --git a/editor/import/resource_importer_wav.cpp b/editor/import/resource_importer_wav.cpp index d04f29ea5e..55f4cc7439 100644 --- a/editor/import/resource_importer_wav.cpp +++ b/editor/import/resource_importer_wav.cpp @@ -30,9 +30,9 @@ #include "resource_importer_wav.h" -#include "io/marshalls.h" -#include "io/resource_saver.h" -#include "os/file_access.h" +#include "core/io/marshalls.h" +#include "core/io/resource_saver.h" +#include "core/os/file_access.h" #include "scene/resources/audio_stream_sample.h" String ResourceImporterWAV::get_importer_name() const { diff --git a/editor/import/resource_importer_wav.h b/editor/import/resource_importer_wav.h index f78ab09e9b..a630ff732e 100644 --- a/editor/import/resource_importer_wav.h +++ b/editor/import/resource_importer_wav.h @@ -31,7 +31,7 @@ #ifndef RESOURCEIMPORTWAV_H #define RESOURCEIMPORTWAV_H -#include "io/resource_import.h" +#include "core/io/resource_import.h" class ResourceImporterWAV : public ResourceImporter { GDCLASS(ResourceImporterWAV, ResourceImporter) diff --git a/editor/inspector_dock.cpp b/editor/inspector_dock.cpp index 0335053162..4f4980d83c 100644 --- a/editor/inspector_dock.cpp +++ b/editor/inspector_dock.cpp @@ -36,6 +36,12 @@ void InspectorDock::_menu_option(int p_option) { switch (p_option) { + case EXPAND_ALL: { + _menu_expandall(); + } break; + case COLLAPSE_ALL: { + _menu_collapseall(); + } break; case RESOURCE_MAKE_BUILT_IN: { _unref_resource(); } break; @@ -98,6 +104,7 @@ void InspectorDock::_menu_option(int p_option) { res = duplicates[res]; current->set(E->get().name, res); + editor->get_inspector()->update_property(E->get().name); } } } @@ -152,7 +159,6 @@ void InspectorDock::_resource_file_selected(String p_file) { RES res = ResourceLoader::load(p_file); if (res.is_null()) { - warning_dialog->get_ok()->set_text(TTR("OK")); warning_dialog->set_text(TTR("Failed to load resource.")); return; }; @@ -225,11 +231,10 @@ void InspectorDock::_prepare_history() { already.insert(id); - Ref<Texture> icon = get_icon("Object", "EditorIcons"); - if (has_icon(obj->get_class(), "EditorIcons")) - icon = get_icon(obj->get_class(), "EditorIcons"); - else + Ref<Texture> icon = EditorNode::get_singleton()->get_object_icon(obj, ""); + if (icon.is_null()) { icon = base_icon; + } String text; if (Object::cast_to<Resource>(obj)) { @@ -254,6 +259,8 @@ void InspectorDock::_prepare_history() { } history_menu->get_popup()->add_icon_item(icon, text, i); } + + editor_path->update_path(); } void InspectorDock::_select_history(int p_idx) const { @@ -314,7 +321,6 @@ void InspectorDock::_transform_keyed(Object *sp, const String &p_sub, const Tran } void InspectorDock::_warning_pressed() { - warning_dialog->get_ok()->set_text(TTR("Ok")); warning_dialog->popup_centered_minsize(); } @@ -399,8 +405,8 @@ void InspectorDock::update(Object *p_object) { PopupMenu *p = object_menu->get_popup(); p->clear(); - p->add_shortcut(ED_SHORTCUT("property_editor/expand_all", TTR("Expand all properties")), EXPAND_ALL); - p->add_shortcut(ED_SHORTCUT("property_editor/collapse_all", TTR("Collapse all properties")), COLLAPSE_ALL); + p->add_shortcut(ED_SHORTCUT("property_editor/expand_all", TTR("Expand All Properties")), EXPAND_ALL); + p->add_shortcut(ED_SHORTCUT("property_editor/collapse_all", TTR("Collapse All Properties")), COLLAPSE_ALL); p->add_separator(); if (is_resource) { p->add_item(TTR("Save"), RESOURCE_SAVE); diff --git a/editor/multi_node_edit.cpp b/editor/multi_node_edit.cpp index 173be01586..be4e752d55 100644 --- a/editor/multi_node_edit.cpp +++ b/editor/multi_node_edit.cpp @@ -30,7 +30,7 @@ #include "multi_node_edit.h" -#include "core/helper/math_fieldwise.h" +#include "core/math/math_fieldwise.h" #include "editor_node.h" bool MultiNodeEdit::_set(const StringName &p_name, const Variant &p_value) { diff --git a/editor/output_strings.h b/editor/output_strings.h index 0729971704..4833f2067e 100644 --- a/editor/output_strings.h +++ b/editor/output_strings.h @@ -31,7 +31,7 @@ #ifndef OUTPUT_STRINGS_H #define OUTPUT_STRINGS_H -#include "map.h" +#include "core/map.h" #include "scene/gui/control.h" #include "scene/gui/scroll_bar.h" diff --git a/editor/plugins/SCsub b/editor/plugins/SCsub index f1fa50148f..2b1e889fb0 100644 --- a/editor/plugins/SCsub +++ b/editor/plugins/SCsub @@ -1,5 +1,5 @@ #!/usr/bin/env python Import('env') -Export('env') + env.add_source_files(env.editor_sources, "*.cpp") diff --git a/editor/plugins/abstract_polygon_2d_editor.cpp b/editor/plugins/abstract_polygon_2d_editor.cpp index 2d341cdd93..f7e59e2beb 100644 --- a/editor/plugins/abstract_polygon_2d_editor.cpp +++ b/editor/plugins/abstract_polygon_2d_editor.cpp @@ -275,6 +275,10 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) return (mb.is_valid() && mb->get_button_index() == 1); } + CanvasItemEditor::Tool tool = CanvasItemEditor::get_singleton()->get_current_tool(); + if (tool != CanvasItemEditor::TOOL_SELECT) + return false; + if (mb.is_valid()) { Transform2D xform = canvas_item_editor->get_canvas_transform() * _get_node()->get_global_transform(); @@ -283,10 +287,10 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) Vector2 cpoint = _get_node()->get_global_transform().affine_inverse().xform(canvas_item_editor->snap_point(canvas_item_editor->get_canvas_transform().affine_inverse().xform(mb->get_position()))); if (mode == MODE_EDIT || (_is_line() && mode == MODE_CREATE)) { - if (mb->get_button_index() == BUTTON_LEFT) { - if (mb->is_pressed()) { + if (mb->get_control() || mb->get_shift() || mb->get_alt()) + return false; const PosVertex insert = closest_edge_point(gpoint); @@ -512,12 +516,10 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) return false; } -void AbstractPolygon2DEditor::forward_draw_over_viewport(Control *p_overlay) { +void AbstractPolygon2DEditor::forward_canvas_draw_over_viewport(Control *p_overlay) { if (!_get_node()) return; - Control *vpc = canvas_item_editor->get_viewport_control(); - Transform2D xform = canvas_item_editor->get_canvas_transform() * _get_node()->get_global_transform(); const Ref<Texture> handle = get_icon("EditorHandle", "EditorIcons"); @@ -558,7 +560,7 @@ void AbstractPolygon2DEditor::forward_draw_over_viewport(Control *p_overlay) { Vector2 point = xform.xform(p); Vector2 next_point = xform.xform(p2); - vpc->draw_line(point, next_point, col, 2 * EDSCALE); + p_overlay->draw_line(point, next_point, col, 2 * EDSCALE); } } @@ -582,7 +584,7 @@ void AbstractPolygon2DEditor::forward_draw_over_viewport(Control *p_overlay) { p2 = points[(i + 1) % n_points] + offset; const Vector2 next_point = xform.xform(p2); - vpc->draw_line(point, next_point, col, 2 * EDSCALE); + p_overlay->draw_line(point, next_point, col, 2 * EDSCALE); } } @@ -594,14 +596,14 @@ void AbstractPolygon2DEditor::forward_draw_over_viewport(Control *p_overlay) { const Vector2 point = xform.xform(p); const Color modulate = vertex == active_point ? Color(0.5, 1, 2) : Color(1, 1, 1); - vpc->draw_texture(handle, point - handle->get_size() * 0.5, modulate); + p_overlay->draw_texture(handle, point - handle->get_size() * 0.5, modulate); } } if (edge_point.valid()) { Ref<Texture> add_handle = get_icon("EditorHandleAdd", "EditorIcons"); - vpc->draw_texture(add_handle, edge_point.pos - add_handle->get_size() * 0.5); + p_overlay->draw_texture(add_handle, edge_point.pos - add_handle->get_size() * 0.5); } } diff --git a/editor/plugins/abstract_polygon_2d_editor.h b/editor/plugins/abstract_polygon_2d_editor.h index 9ba03bcdf6..00634ba5b8 100644 --- a/editor/plugins/abstract_polygon_2d_editor.h +++ b/editor/plugins/abstract_polygon_2d_editor.h @@ -137,7 +137,7 @@ protected: public: bool forward_gui_input(const Ref<InputEvent> &p_event); - void forward_draw_over_viewport(Control *p_overlay); + void forward_canvas_draw_over_viewport(Control *p_overlay); void edit(Node *p_polygon); AbstractPolygon2DEditor(EditorNode *p_editor, bool p_wip_destructive = true); @@ -153,7 +153,7 @@ class AbstractPolygon2DEditorPlugin : public EditorPlugin { public: virtual bool forward_canvas_gui_input(const Ref<InputEvent> &p_event) { return polygon_editor->forward_gui_input(p_event); } - virtual void forward_draw_over_viewport(Control *p_overlay) { polygon_editor->forward_draw_over_viewport(p_overlay); } + virtual void forward_canvas_draw_over_viewport(Control *p_overlay) { polygon_editor->forward_canvas_draw_over_viewport(p_overlay); } bool has_main_screen() const { return false; } virtual String get_name() const { return klass; } diff --git a/editor/plugins/animation_blend_space_1d_editor.cpp b/editor/plugins/animation_blend_space_1d_editor.cpp index 5373015654..4b1e710705 100644 --- a/editor/plugins/animation_blend_space_1d_editor.cpp +++ b/editor/plugins/animation_blend_space_1d_editor.cpp @@ -1,6 +1,36 @@ +/*************************************************************************/ +/* animation_blend_space_1d_editor.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + #include "animation_blend_space_1d_editor.h" -#include "os/keyboard.h" +#include "core/os/keyboard.h" #include "scene/animation/animation_blend_tree.h" StringName AnimationNodeBlendSpace1DEditor::get_blend_position_path() const { diff --git a/editor/plugins/animation_blend_space_1d_editor.h b/editor/plugins/animation_blend_space_1d_editor.h index 278357b9c7..ca6135406c 100644 --- a/editor/plugins/animation_blend_space_1d_editor.h +++ b/editor/plugins/animation_blend_space_1d_editor.h @@ -1,3 +1,33 @@ +/*************************************************************************/ +/* animation_blend_space_1d_editor.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + #ifndef ANIMATION_BLEND_SPACE_1D_EDITOR_H #define ANIMATION_BLEND_SPACE_1D_EDITOR_H diff --git a/editor/plugins/animation_blend_space_2d_editor.cpp b/editor/plugins/animation_blend_space_2d_editor.cpp index 2d240b5a5c..c4f8cdc3d7 100644 --- a/editor/plugins/animation_blend_space_2d_editor.cpp +++ b/editor/plugins/animation_blend_space_2d_editor.cpp @@ -1,10 +1,40 @@ +/*************************************************************************/ +/* animation_blend_space_2d_editor.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + #include "animation_blend_space_2d_editor.h" #include "core/io/resource_loader.h" +#include "core/math/delaunay.h" +#include "core/os/input.h" +#include "core/os/keyboard.h" #include "core/project_settings.h" -#include "math/delaunay.h" -#include "os/input.h" -#include "os/keyboard.h" #include "scene/animation/animation_blend_tree.h" #include "scene/animation/animation_player.h" #include "scene/gui/menu_button.h" diff --git a/editor/plugins/animation_blend_space_2d_editor.h b/editor/plugins/animation_blend_space_2d_editor.h index 0bf1e25d7a..613289e4d8 100644 --- a/editor/plugins/animation_blend_space_2d_editor.h +++ b/editor/plugins/animation_blend_space_2d_editor.h @@ -1,3 +1,33 @@ +/*************************************************************************/ +/* animation_blend_space_2d_editor.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + #ifndef ANIMATION_BLEND_SPACE_2D_EDITOR_H #define ANIMATION_BLEND_SPACE_2D_EDITOR_H diff --git a/editor/plugins/animation_blend_tree_editor_plugin.cpp b/editor/plugins/animation_blend_tree_editor_plugin.cpp index dbb5fa578b..205458fb1d 100644 --- a/editor/plugins/animation_blend_tree_editor_plugin.cpp +++ b/editor/plugins/animation_blend_tree_editor_plugin.cpp @@ -1,10 +1,40 @@ +/*************************************************************************/ +/* animation_blend_tree_editor_plugin.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + #include "animation_blend_tree_editor_plugin.h" #include "core/io/resource_loader.h" +#include "core/os/input.h" +#include "core/os/keyboard.h" #include "core/project_settings.h" #include "editor/editor_inspector.h" -#include "os/input.h" -#include "os/keyboard.h" #include "scene/animation/animation_player.h" #include "scene/gui/menu_button.h" #include "scene/gui/panel.h" @@ -101,10 +131,6 @@ void AnimationNodeBlendTreeEditor::_update_graph() { Ref<AnimationNode> agnode = blend_tree->get_node(E->get()); - if (!agnode->is_connected("changed", this, "_node_changed")) { - agnode->connect("changed", this, "_node_changed", varray(agnode->get_instance_id()), CONNECT_DEFERRED); - } - node->set_offset(blend_tree->get_node_position(E->get()) * EDSCALE); node->set_title(agnode->get_caption()); @@ -211,7 +237,7 @@ void AnimationNodeBlendTreeEditor::_update_graph() { mb->get_popup()->connect("index_pressed", this, "_anim_selected", varray(options, E->get()), CONNECT_DEFERRED); } - /* should be no longer necesary, as the boolean works + /* should be no longer necessary, as the boolean works Ref<AnimationNodeOneShot> oneshot = agnode; if (oneshot.is_valid()) { @@ -512,11 +538,7 @@ bool AnimationNodeBlendTreeEditor::_update_filters(const Ref<AnimationNode> &ano if (base->has_node(accum)) { Node *node = base->get_node(accum); - if (has_icon(node->get_class(), "EditorIcons")) { - ti->set_icon(0, get_icon(node->get_class(), "EditorIcons")); - } else { - ti->set_icon(0, get_icon("Node", "EditorIcons")); - } + ti->set_icon(0, EditorNode::get_singleton()->get_object_icon(node, "Node")); } } else { @@ -529,7 +551,7 @@ bool AnimationNodeBlendTreeEditor::_update_filters(const Ref<AnimationNode> &ano node = base->get_node(accum); } if (!node) - continue; //no node, cant edit + continue; //no node, can't edit if (path.get_subname_count()) { @@ -695,14 +717,6 @@ void AnimationNodeBlendTreeEditor::_scroll_changed(const Vector2 &p_scroll) { updating = false; } -void AnimationNodeBlendTreeEditor::_node_changed(ObjectID p_node) { - - AnimationNode *an = Object::cast_to<AnimationNode>(ObjectDB::get_instance(p_node)); - //if (an && an->get_parent() == blend_tree) { - _update_graph(); - //} -} - void AnimationNodeBlendTreeEditor::_bind_methods() { ClassDB::bind_method("_update_graph", &AnimationNodeBlendTreeEditor::_update_graph); @@ -720,7 +734,6 @@ void AnimationNodeBlendTreeEditor::_bind_methods() { ClassDB::bind_method("_update_filters", &AnimationNodeBlendTreeEditor::_update_filters); ClassDB::bind_method("_filter_edited", &AnimationNodeBlendTreeEditor::_filter_edited); ClassDB::bind_method("_filter_toggled", &AnimationNodeBlendTreeEditor::_filter_toggled); - ClassDB::bind_method("_node_changed", &AnimationNodeBlendTreeEditor::_node_changed); ClassDB::bind_method("_removed_from_graph", &AnimationNodeBlendTreeEditor::_removed_from_graph); ClassDB::bind_method("_property_changed", &AnimationNodeBlendTreeEditor::_property_changed); ClassDB::bind_method("_file_opened", &AnimationNodeBlendTreeEditor::_file_opened); diff --git a/editor/plugins/animation_blend_tree_editor_plugin.h b/editor/plugins/animation_blend_tree_editor_plugin.h index 35ecc32979..e2daefdec6 100644 --- a/editor/plugins/animation_blend_tree_editor_plugin.h +++ b/editor/plugins/animation_blend_tree_editor_plugin.h @@ -1,3 +1,33 @@ +/*************************************************************************/ +/* animation_blend_tree_editor_plugin.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + #ifndef ANIMATION_BLEND_TREE_EDITOR_PLUGIN_H #define ANIMATION_BLEND_TREE_EDITOR_PLUGIN_H @@ -74,8 +104,6 @@ class AnimationNodeBlendTreeEditor : public AnimationTreeNodeEditorPlugin { void _filter_toggled(); Ref<AnimationNode> _filter_edit; - void _node_changed(ObjectID p_node); - void _property_changed(const StringName &p_property, const Variant &p_value); void _removed_from_graph(); diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp index 9ab5436de8..445664f8dd 100644 --- a/editor/plugins/animation_player_editor_plugin.cpp +++ b/editor/plugins/animation_player_editor_plugin.cpp @@ -30,12 +30,12 @@ #include "animation_player_editor_plugin.h" +#include "core/io/resource_loader.h" +#include "core/io/resource_saver.h" +#include "core/os/keyboard.h" +#include "core/project_settings.h" #include "editor/animation_track_editor.h" #include "editor/editor_settings.h" -#include "io/resource_loader.h" -#include "io/resource_saver.h" -#include "os/keyboard.h" -#include "project_settings.h" // For onion skinning #include "editor/plugins/canvas_item_editor_plugin.h" @@ -908,7 +908,7 @@ void AnimationPlayerEditor::edit(AnimationPlayer *p_player) { } } -void AnimationPlayerEditor::forward_force_draw_over_viewport(Control *p_overlay) { +void AnimationPlayerEditor::forward_canvas_force_draw_over_viewport(Control *p_overlay) { if (!onion.can_overlay) return; @@ -1515,7 +1515,7 @@ void AnimationPlayerEditor::_prepare_onion_layers_2() { void AnimationPlayerEditor::_start_onion_skinning() { - // FIXME: Using "idle_frame" makes onion layers update one frame behing the current + // FIXME: Using "idle_frame" makes onion layers update one frame behind the current if (!get_tree()->is_connected("idle_frame", this, "call_deferred")) { get_tree()->connect("idle_frame", this, "call_deferred", varray("_prepare_onion_layers_1")); } diff --git a/editor/plugins/animation_player_editor_plugin.h b/editor/plugins/animation_player_editor_plugin.h index 5ac7b99903..55f082aadb 100644 --- a/editor/plugins/animation_player_editor_plugin.h +++ b/editor/plugins/animation_player_editor_plugin.h @@ -246,7 +246,7 @@ public: void set_undo_redo(UndoRedo *p_undo_redo) { undo_redo = p_undo_redo; } void edit(AnimationPlayer *p_player); - void forward_force_draw_over_viewport(Control *p_overlay); + void forward_canvas_force_draw_over_viewport(Control *p_overlay); AnimationPlayerEditor(EditorNode *p_editor, AnimationPlayerEditorPlugin *p_plugin); }; @@ -271,7 +271,7 @@ public: virtual bool handles(Object *p_object) const; virtual void make_visible(bool p_visible); - virtual void forward_force_draw_over_viewport(Control *p_overlay) { anim_editor->forward_force_draw_over_viewport(p_overlay); } + virtual void forward_canvas_force_draw_over_viewport(Control *p_overlay) { anim_editor->forward_canvas_force_draw_over_viewport(p_overlay); } AnimationPlayerEditorPlugin(EditorNode *p_node); ~AnimationPlayerEditorPlugin(); diff --git a/editor/plugins/animation_state_machine_editor.cpp b/editor/plugins/animation_state_machine_editor.cpp index 3a65cb9b38..e83773257b 100644 --- a/editor/plugins/animation_state_machine_editor.cpp +++ b/editor/plugins/animation_state_machine_editor.cpp @@ -1,10 +1,40 @@ +/*************************************************************************/ +/* animation_state_machine_editor.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + #include "animation_state_machine_editor.h" #include "core/io/resource_loader.h" +#include "core/math/delaunay.h" +#include "core/os/input.h" +#include "core/os/keyboard.h" #include "core/project_settings.h" -#include "math/delaunay.h" -#include "os/input.h" -#include "os/keyboard.h" #include "scene/animation/animation_blend_tree.h" #include "scene/animation/animation_player.h" #include "scene/gui/menu_button.h" @@ -633,7 +663,7 @@ void AnimationNodeStateMachineEditor::_state_machine_draw() { transition_lines.clear(); - //draw conecting line for potential new transition + //draw connecting line for potential new transition if (connecting) { Vector2 from = (state_machine->get_node_position(connecting_from) * EDSCALE) - state_machine->get_graph_offset() * EDSCALE; Vector2 to; diff --git a/editor/plugins/animation_state_machine_editor.h b/editor/plugins/animation_state_machine_editor.h index 49d08607cf..7b8a4a0e94 100644 --- a/editor/plugins/animation_state_machine_editor.h +++ b/editor/plugins/animation_state_machine_editor.h @@ -1,3 +1,33 @@ +/*************************************************************************/ +/* animation_state_machine_editor.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + #ifndef ANIMATION_STATE_MACHINE_EDITOR_H #define ANIMATION_STATE_MACHINE_EDITOR_H diff --git a/editor/plugins/animation_tree_editor_plugin.cpp b/editor/plugins/animation_tree_editor_plugin.cpp index 19921ef54f..24787a78e9 100644 --- a/editor/plugins/animation_tree_editor_plugin.cpp +++ b/editor/plugins/animation_tree_editor_plugin.cpp @@ -1,3 +1,33 @@ +/*************************************************************************/ +/* animation_tree_editor_plugin.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + #include "animation_tree_editor_plugin.h" #include "animation_blend_space_1d_editor.h" @@ -5,10 +35,10 @@ #include "animation_blend_tree_editor_plugin.h" #include "animation_state_machine_editor.h" #include "core/io/resource_loader.h" +#include "core/math/delaunay.h" +#include "core/os/input.h" +#include "core/os/keyboard.h" #include "core/project_settings.h" -#include "math/delaunay.h" -#include "os/input.h" -#include "os/keyboard.h" #include "scene/animation/animation_blend_tree.h" #include "scene/animation/animation_player.h" #include "scene/gui/menu_button.h" diff --git a/editor/plugins/animation_tree_editor_plugin.h b/editor/plugins/animation_tree_editor_plugin.h index b12054bb62..be8848d600 100644 --- a/editor/plugins/animation_tree_editor_plugin.h +++ b/editor/plugins/animation_tree_editor_plugin.h @@ -1,3 +1,33 @@ +/*************************************************************************/ +/* animation_tree_editor_plugin.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + #ifndef ANIMATION_TREE_EDITOR_PLUGIN_H #define ANIMATION_TREE_EDITOR_PLUGIN_H diff --git a/editor/plugins/animation_tree_player_editor_plugin.cpp b/editor/plugins/animation_tree_player_editor_plugin.cpp index 36d10ab99e..c79e3a436d 100644 --- a/editor/plugins/animation_tree_player_editor_plugin.cpp +++ b/editor/plugins/animation_tree_player_editor_plugin.cpp @@ -31,9 +31,9 @@ #include "animation_tree_player_editor_plugin.h" #include "core/io/resource_loader.h" +#include "core/os/input.h" +#include "core/os/keyboard.h" #include "core/project_settings.h" -#include "os/input.h" -#include "os/keyboard.h" #include "scene/gui/menu_button.h" #include "scene/gui/panel.h" #include "scene/main/viewport.h" diff --git a/editor/plugins/audio_stream_editor_plugin.cpp b/editor/plugins/audio_stream_editor_plugin.cpp index 454a5d72f2..06ca5833e2 100644 --- a/editor/plugins/audio_stream_editor_plugin.cpp +++ b/editor/plugins/audio_stream_editor_plugin.cpp @@ -30,9 +30,9 @@ #include "audio_stream_editor_plugin.h" +#include "core/io/resource_loader.h" +#include "core/project_settings.h" #include "editor/editor_settings.h" -#include "io/resource_loader.h" -#include "project_settings.h" void AudioStreamEditor::_notification(int p_what) { diff --git a/editor/plugins/baked_lightmap_editor_plugin.cpp b/editor/plugins/baked_lightmap_editor_plugin.cpp index 59b79bd070..e65a697857 100644 --- a/editor/plugins/baked_lightmap_editor_plugin.cpp +++ b/editor/plugins/baked_lightmap_editor_plugin.cpp @@ -50,6 +50,7 @@ void BakedLightmapEditorPlugin::_bake() { case BakedLightmap::BAKE_ERROR_CANT_CREATE_IMAGE: EditorNode::get_singleton()->show_warning(TTR("Failed creating lightmap images, make sure path is writable.")); break; + default: {} } } } diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 72248b62a3..f65c8cbd0d 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -30,15 +30,15 @@ #include "canvas_item_editor_plugin.h" +#include "core/os/input.h" +#include "core/os/keyboard.h" +#include "core/print_string.h" +#include "core/project_settings.h" #include "editor/editor_node.h" #include "editor/editor_settings.h" #include "editor/plugins/animation_player_editor_plugin.h" #include "editor/plugins/script_editor_plugin.h" #include "editor/script_editor_debugger.h" -#include "os/input.h" -#include "os/keyboard.h" -#include "print_string.h" -#include "project_settings.h" #include "scene/2d/light_2d.h" #include "scene/2d/particles_2d.h" #include "scene/2d/polygon_2d.h" @@ -55,6 +55,7 @@ #define MAX_ZOOM 100 #define RULER_WIDTH 15 * EDSCALE +#define SCALE_HANDLE_DISTANCE 25 class SnapDialog : public ConfirmationDialog { @@ -335,10 +336,11 @@ void CanvasItemEditor::_unhandled_key_input(const Ref<InputEvent> &p_ev) { if (!is_visible_in_tree() || get_viewport()->gui_has_modal_stack()) return; - if (k->get_control()) - return; + if (k->get_scancode() == KEY_CONTROL || k->get_scancode() == KEY_ALT || k->get_scancode() == KEY_SHIFT) { + viewport->update(); + } - if (k->is_pressed() && !k->is_echo()) { + if (k->is_pressed() && !k->get_control() && !k->is_echo()) { if ((snap_grid || show_grid) && multiply_grid_step_shortcut.is_valid() && multiply_grid_step_shortcut->is_shortcut(p_ev)) { // Multiply the grid size grid_step_multiplier = MIN(grid_step_multiplier + 1, 12); @@ -441,8 +443,12 @@ void CanvasItemEditor::_find_canvas_items_at_pos(const Point2 &p_pos, Node *p_no CanvasItem *canvas_item = Object::cast_to<CanvasItem>(p_node); for (int i = p_node->get_child_count() - 1; i >= 0; i--) { - if (canvas_item && !canvas_item->is_set_as_toplevel()) { - _find_canvas_items_at_pos(p_pos, p_node->get_child(i), r_items, p_limit, p_parent_xform * canvas_item->get_transform(), p_canvas_xform); + if (canvas_item) { + if (!canvas_item->is_set_as_toplevel()) { + _find_canvas_items_at_pos(p_pos, p_node->get_child(i), r_items, p_limit, p_parent_xform * canvas_item->get_transform(), p_canvas_xform); + } else { + _find_canvas_items_at_pos(p_pos, p_node->get_child(i), r_items, p_limit, canvas_item->get_transform(), p_canvas_xform); + } } else { CanvasLayer *cl = Object::cast_to<CanvasLayer>(p_node); _find_canvas_items_at_pos(p_pos, p_node->get_child(i), r_items, p_limit, Transform2D(), cl ? cl->get_transform() : p_canvas_xform); @@ -608,8 +614,12 @@ void CanvasItemEditor::_find_canvas_items_in_rect(const Rect2 &p_rect, Node *p_n if (!lock_children || !editable) { for (int i = p_node->get_child_count() - 1; i >= 0; i--) { - if (canvas_item && !canvas_item->is_set_as_toplevel()) { - _find_canvas_items_in_rect(p_rect, p_node->get_child(i), r_items, p_parent_xform * canvas_item->get_transform(), p_canvas_xform); + if (canvas_item) { + if (!canvas_item->is_set_as_toplevel()) { + _find_canvas_items_in_rect(p_rect, p_node->get_child(i), r_items, p_parent_xform * canvas_item->get_transform(), p_canvas_xform); + } else { + _find_canvas_items_in_rect(p_rect, p_node->get_child(i), r_items, canvas_item->get_transform(), p_canvas_xform); + } } else { CanvasLayer *canvas_layer = Object::cast_to<CanvasLayer>(p_node); _find_canvas_items_in_rect(p_rect, p_node->get_child(i), r_items, Transform2D(), canvas_layer ? canvas_layer->get_transform() : p_canvas_xform); @@ -667,7 +677,7 @@ List<CanvasItem *> CanvasItemEditor::_get_edited_canvas_items(bool retreive_lock List<CanvasItem *> selection; for (Map<Node *, Object *>::Element *E = editor_selection->get_selection().front(); E; E = E->next()) { CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E->key()); - if (canvas_item && canvas_item->is_visible_in_tree() && canvas_item->get_viewport() == EditorNode::get_singleton()->get_scene_root() && (!retreive_locked || !canvas_item->has_meta("_edit_lock_"))) { + if (canvas_item && canvas_item->is_visible_in_tree() && canvas_item->get_viewport() == EditorNode::get_singleton()->get_scene_root() && (retreive_locked || !canvas_item->has_meta("_edit_lock_"))) { CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item); if (se) { selection.push_back(canvas_item); @@ -705,6 +715,46 @@ Vector2 CanvasItemEditor::_position_to_anchor(const Control *p_control, Vector2 return (p_control->get_transform().xform(position) - parent_rect.position) / parent_rect.size; } +void CanvasItemEditor::_save_canvas_item_ik_chain(const CanvasItem *p_canvas_item, List<float> *p_bones_length, List<Dictionary> *p_bones_state) { + if (p_bones_length) + *p_bones_length = List<float>(); + if (p_bones_state) + *p_bones_state = List<Dictionary>(); + + const Node2D *bone = Object::cast_to<Node2D>(p_canvas_item); + if (bone && bone->has_meta("_edit_bone_")) { + // Check if we have an IK chain + List<const Node2D *> bone_ik_list; + bool ik_found = false; + bone = Object::cast_to<Node2D>(bone->get_parent()); + while (bone) { + bone_ik_list.push_back(bone); + if (bone->has_meta("_edit_ik_")) { + ik_found = true; + break; + } else if (!bone->has_meta("_edit_bone_")) { + break; + } + bone = Object::cast_to<Node2D>(bone->get_parent()); + } + + //Save the bone state and length if we have an IK chain + if (ik_found) { + bone = Object::cast_to<Node2D>(p_canvas_item); + Transform2D bone_xform = bone->get_global_transform(); + for (List<const Node2D *>::Element *bone_E = bone_ik_list.front(); bone_E; bone_E = bone_E->next()) { + bone_xform = bone_xform * bone->get_transform().affine_inverse(); + const Node2D *parent_bone = bone_E->get(); + if (p_bones_length) + p_bones_length->push_back(parent_bone->get_global_transform().get_origin().distance_to(bone->get_global_position())); + if (p_bones_state) + p_bones_state->push_back(parent_bone->_edit_get_state()); + bone = parent_bone; + } + } + } +} + void CanvasItemEditor::_save_canvas_item_state(List<CanvasItem *> p_canvas_items, bool save_bones) { for (List<CanvasItem *>::Element *E = p_canvas_items.front(); E; E = E->next()) { CanvasItem *canvas_item = E->get(); @@ -717,54 +767,28 @@ void CanvasItemEditor::_save_canvas_item_state(List<CanvasItem *> p_canvas_items } else { se->pre_drag_rect = Rect2(); } - se->pre_drag_bones_length = List<float>(); - se->pre_drag_bones_undo_state = List<Dictionary>(); // If we have a bone, save the state of all nodes in the IK chain - Node2D *bone = Object::cast_to<Node2D>(canvas_item); - if (bone && bone->has_meta("_edit_bone_")) { - // Check if we have an IK chain - List<Node2D *> bone_ik_list; - bool ik_found = false; - bone = Object::cast_to<Node2D>(bone->get_parent()); - while (bone) { - bone_ik_list.push_back(bone); - if (bone->has_meta("_edit_ik_")) { - ik_found = true; - break; - } else if (!bone->has_meta("_edit_bone_")) { - break; - } - bone = Object::cast_to<Node2D>(bone->get_parent()); - } - - //Save the bone state and length if we have an IK chain - if (ik_found) { - bone = Object::cast_to<Node2D>(canvas_item); - Transform2D bone_xform = bone->get_global_transform(); - for (List<Node2D *>::Element *bone_E = bone_ik_list.front(); bone_E; bone_E = bone_E->next()) { - bone_xform = bone_xform * bone->get_transform().affine_inverse(); - Node2D *parent_bone = bone_E->get(); - se->pre_drag_bones_length.push_back(parent_bone->get_global_transform().get_origin().distance_to(bone->get_global_position())); - se->pre_drag_bones_undo_state.push_back(parent_bone->_edit_get_state()); - bone = parent_bone; - } - } - } + _save_canvas_item_ik_chain(canvas_item, &(se->pre_drag_bones_length), &(se->pre_drag_bones_undo_state)); } } } +void CanvasItemEditor::_restore_canvas_item_ik_chain(CanvasItem *p_canvas_item, const List<Dictionary> *p_bones_state) { + CanvasItem *canvas_item = p_canvas_item; + for (const List<Dictionary>::Element *E = p_bones_state->front(); E; E = E->next()) { + canvas_item = Object::cast_to<CanvasItem>(canvas_item->get_parent()); + canvas_item->_edit_set_state(E->get()); + } +} + void CanvasItemEditor::_restore_canvas_item_state(List<CanvasItem *> p_canvas_items, bool restore_bones) { for (List<CanvasItem *>::Element *E = drag_selection.front(); E; E = E->next()) { CanvasItem *canvas_item = E->get(); CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item); canvas_item->_edit_set_state(se->undo_state); if (restore_bones) { - for (List<Dictionary>::Element *E = se->pre_drag_bones_undo_state.front(); E; E = E->next()) { - canvas_item = Object::cast_to<CanvasItem>(canvas_item->get_parent()); - canvas_item->_edit_set_state(E->get()); - } + _restore_canvas_item_ik_chain(canvas_item, &(se->pre_drag_bones_undo_state)); } } } @@ -1189,73 +1213,72 @@ bool CanvasItemEditor::_gui_input_pivot(const Ref<InputEvent> &p_event) { void CanvasItemEditor::_solve_IK(Node2D *leaf_node, Point2 target_position) { CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(leaf_node); - if (se && !se->pre_drag_bones_undo_state.empty()) { - - // Build the node list - Point2 leaf_pos = target_position; - - List<Node2D *> joints_list; - List<Point2> joints_pos; - Node2D *joint = leaf_node; - Transform2D joint_transform = leaf_node->get_global_transform_with_canvas(); - for (int i = 0; i < se->pre_drag_bones_undo_state.size() + 1; i++) { - joints_list.push_back(joint); - joints_pos.push_back(joint_transform.get_origin()); - joint_transform = joint_transform * joint->get_transform().affine_inverse(); - joint = Object::cast_to<Node2D>(joint->get_parent()); - } - Point2 root_pos = joints_list.back()->get()->get_global_transform_with_canvas().get_origin(); - - // Restraints the node to a maximum distance is necessary - float total_len = 0; - for (List<float>::Element *E = se->pre_drag_bones_length.front(); E; E = E->next()) { - total_len += E->get(); - } - if ((root_pos.distance_to(leaf_pos)) > total_len) { - Vector2 rel = leaf_pos - root_pos; - rel = rel.normalized() * total_len; - leaf_pos = root_pos + rel; - } - joints_pos[0] = leaf_pos; - - // Run the solver - int solver_iterations = 64; - float solver_k = 0.3; - - // Build the position list - for (int i = 0; i < solver_iterations; i++) { - // Handle the leaf joint - int node_id = 0; + if (se) { + int nb_bones = se->pre_drag_bones_undo_state.size(); + if (nb_bones > 0) { + + // Build the node list + Point2 leaf_pos = target_position; + + List<Node2D *> joints_list; + List<Point2> joints_pos; + Node2D *joint = leaf_node; + Transform2D joint_transform = leaf_node->get_global_transform_with_canvas(); + for (int i = 0; i < nb_bones + 1; i++) { + joints_list.push_back(joint); + joints_pos.push_back(joint_transform.get_origin()); + joint_transform = joint_transform * joint->get_transform().affine_inverse(); + joint = Object::cast_to<Node2D>(joint->get_parent()); + } + Point2 root_pos = joints_list.back()->get()->get_global_transform_with_canvas().get_origin(); + + // Restraints the node to a maximum distance is necessary + float total_len = 0; for (List<float>::Element *E = se->pre_drag_bones_length.front(); E; E = E->next()) { - Vector2 direction = (joints_pos[node_id + 1] - joints_pos[node_id]).normalized(); - int len = E->get(); - if (E == se->pre_drag_bones_length.front()) { - joints_pos[1] = joints_pos[1].linear_interpolate(joints_pos[0] + len * direction, solver_k); - } else if (E == se->pre_drag_bones_length.back()) { - joints_pos[node_id] = joints_pos[node_id].linear_interpolate(joints_pos[node_id + 1] - len * direction, solver_k); - } else { - Vector2 center = (joints_pos[node_id + 1] + joints_pos[node_id]) / 2.0; - joints_pos[node_id] = joints_pos[node_id].linear_interpolate(center - (direction * len) / 2.0, solver_k); - joints_pos[node_id + 1] = joints_pos[node_id + 1].linear_interpolate(center + (direction * len) / 2.0, solver_k); + total_len += E->get(); + } + if ((root_pos.distance_to(leaf_pos)) > total_len) { + Vector2 rel = leaf_pos - root_pos; + rel = rel.normalized() * total_len; + leaf_pos = root_pos + rel; + } + joints_pos[0] = leaf_pos; + + // Run the solver + int solver_iterations = 64; + float solver_k = 0.3; + + // Build the position list + for (int i = 0; i < solver_iterations; i++) { + // Handle the leaf joint + int node_id = 0; + for (List<float>::Element *E = se->pre_drag_bones_length.front(); E; E = E->next()) { + Vector2 direction = (joints_pos[node_id + 1] - joints_pos[node_id]).normalized(); + int len = E->get(); + if (E == se->pre_drag_bones_length.front()) { + joints_pos[1] = joints_pos[1].linear_interpolate(joints_pos[0] + len * direction, solver_k); + } else if (E == se->pre_drag_bones_length.back()) { + joints_pos[node_id] = joints_pos[node_id].linear_interpolate(joints_pos[node_id + 1] - len * direction, solver_k); + } else { + Vector2 center = (joints_pos[node_id + 1] + joints_pos[node_id]) / 2.0; + joints_pos[node_id] = joints_pos[node_id].linear_interpolate(center - (direction * len) / 2.0, solver_k); + joints_pos[node_id + 1] = joints_pos[node_id + 1].linear_interpolate(center + (direction * len) / 2.0, solver_k); + } + node_id++; } - node_id++; } - } - // Set the position - float total_rot = 0.0f; - for (int node_id = joints_list.size() - 1; node_id > 0; node_id--) { - Point2 current = (joints_list[node_id - 1]->get_global_position() - joints_list[node_id]->get_global_position()).normalized(); - Point2 target = (joints_pos[node_id - 1] - joints_list[node_id]->get_global_position()).normalized(); - float rot = current.angle_to(target); - if (joints_list[node_id]->get_global_transform().basis_determinant() < 0) { - rot = -rot; + // Set the position + for (int node_id = joints_list.size() - 1; node_id > 0; node_id--) { + Point2 current = (joints_list[node_id - 1]->get_global_position() - joints_list[node_id]->get_global_position()).normalized(); + Point2 target = (joints_pos[node_id - 1] - joints_list[node_id]->get_global_position()).normalized(); + float rot = current.angle_to(target); + if (joints_list[node_id]->get_global_transform().basis_determinant() < 0) { + rot = -rot; + } + joints_list[node_id]->rotate(rot); } - joints_list[node_id]->rotate(rot); - total_rot += rot; } - - joints_list[0]->rotate(-total_rot); } } @@ -1267,7 +1290,7 @@ bool CanvasItemEditor::_gui_input_rotate(const Ref<InputEvent> &p_event) { if (drag_type == DRAG_NONE) { if (b.is_valid() && b->get_button_index() == BUTTON_LEFT && b->is_pressed()) { drag_selection = _get_edited_canvas_items(); - if (drag_selection.size() > 0 && ((b->get_control() && tool == TOOL_SELECT) || tool == TOOL_ROTATE)) { + if (drag_selection.size() > 0 && ((b->get_control() && !b->get_alt() && tool == TOOL_SELECT) || tool == TOOL_ROTATE)) { drag_type = DRAG_ROTATE; drag_from = transform.affine_inverse().xform(b->get_position()); CanvasItem *canvas_item = drag_selection[0]; @@ -1615,6 +1638,115 @@ bool CanvasItemEditor::_gui_input_resize(const Ref<InputEvent> &p_event) { return false; } +bool CanvasItemEditor::_gui_input_scale(const Ref<InputEvent> &p_event) { + + Ref<InputEventMouseButton> b = p_event; + Ref<InputEventMouseMotion> m = p_event; + + // Drag resize handles + if (drag_type == DRAG_NONE) { + if (b.is_valid() && b->get_button_index() == BUTTON_LEFT && b->is_pressed() && ((b->get_alt() && b->get_control()) || tool == TOOL_SCALE)) { + List<CanvasItem *> selection = _get_edited_canvas_items(); + if (selection.size() == 1) { + CanvasItem *canvas_item = selection[0]; + + Transform2D xform = transform * canvas_item->get_global_transform_with_canvas(); + Transform2D unscaled_transform = (xform * canvas_item->get_transform().affine_inverse() * Transform2D(canvas_item->_edit_get_rotation(), canvas_item->_edit_get_position())).orthonormalized(); + Transform2D simple_xform = viewport->get_transform() * unscaled_transform; + + drag_type = DRAG_SCALE_BOTH; + + Size2 scale_factor = Size2(SCALE_HANDLE_DISTANCE, SCALE_HANDLE_DISTANCE); + Rect2 x_handle_rect = Rect2(scale_factor.x * EDSCALE, -5 * EDSCALE, 10 * EDSCALE, 10 * EDSCALE); + if (x_handle_rect.has_point(simple_xform.affine_inverse().xform(b->get_position()))) { + drag_type = DRAG_SCALE_X; + } + Rect2 y_handle_rect = Rect2(-5 * EDSCALE, -(scale_factor.y + 10) * EDSCALE, 10 * EDSCALE, 10 * EDSCALE); + if (y_handle_rect.has_point(simple_xform.affine_inverse().xform(b->get_position()))) { + drag_type = DRAG_SCALE_Y; + } + + drag_from = transform.affine_inverse().xform(b->get_position()); + drag_selection = List<CanvasItem *>(); + drag_selection.push_back(canvas_item); + _save_canvas_item_state(drag_selection); + return true; + } + } + } + + if (drag_type == DRAG_SCALE_BOTH || drag_type == DRAG_SCALE_X || drag_type == DRAG_SCALE_Y) { + // Resize the node + if (m.is_valid()) { + _restore_canvas_item_state(drag_selection); + CanvasItem *canvas_item = drag_selection[0]; + + drag_to = transform.affine_inverse().xform(m->get_position()); + + Transform2D parent_xform = canvas_item->get_global_transform_with_canvas() * canvas_item->get_transform().affine_inverse(); + Transform2D unscaled_transform = (transform * parent_xform * Transform2D(canvas_item->_edit_get_rotation(), canvas_item->_edit_get_position())).orthonormalized(); + Transform2D simple_xform = (viewport->get_transform() * unscaled_transform).affine_inverse() * transform; + + bool uniform = m->get_shift(); + + Point2 drag_from_local = simple_xform.xform(drag_from); + Point2 drag_to_local = simple_xform.xform(drag_to); + Point2 offset = drag_to_local - drag_from_local; + + Size2 scale = canvas_item->call("get_scale"); + float ratio = scale.y / scale.x; + if (drag_type == DRAG_SCALE_BOTH) { + Size2 scale_factor = drag_to_local / drag_from_local; + if (uniform) { + if (ABS(offset.x) > ABS(offset.y)) { + scale.x *= scale_factor.x; + scale.y = scale.x * ratio; + } else { + scale.y *= scale_factor.y; + scale.x = scale.y / ratio; + } + } else { + scale *= scale_factor; + } + } else { + Size2 scale_factor = Vector2(offset.x, -offset.y) / SCALE_HANDLE_DISTANCE; + Size2 parent_scale = parent_xform.get_scale(); + scale_factor *= Vector2(1.0 / parent_scale.x, 1.0 / parent_scale.y); + if (drag_type == DRAG_SCALE_X) { + scale.x += scale_factor.x; + if (uniform) { + scale.y = scale.x * ratio; + } + } else if (drag_type == DRAG_SCALE_Y) { + scale.y += scale_factor.y; + if (uniform) { + scale.x = scale.y / ratio; + } + } + } + canvas_item->call("set_scale", scale); + return true; + } + + // Confirm resize + if (b.is_valid() && b->get_button_index() == BUTTON_LEFT && !b->is_pressed()) { + _commit_canvas_item_state(drag_selection, TTR("Scale CanvasItem")); + drag_type = DRAG_NONE; + viewport->update(); + return true; + } + + // Cancel a drag + if (b.is_valid() && b->get_button_index() == BUTTON_RIGHT && b->is_pressed()) { + _restore_canvas_item_state(drag_selection); + drag_type = DRAG_NONE; + viewport->update(); + return true; + } + } + return false; +} + bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) { Ref<InputEventMouseButton> b = p_event; Ref<InputEventMouseMotion> m = p_event; @@ -1624,8 +1756,8 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) { //Start moving the nodes if (b.is_valid() && b->get_button_index() == BUTTON_LEFT && b->is_pressed()) { List<CanvasItem *> selection = _get_edited_canvas_items(); - if ((b->get_alt() || tool == TOOL_MOVE) && selection.size() > 0) { - drag_type = DRAG_ALL; + if (((b->get_alt() && !b->get_control()) || tool == TOOL_MOVE) && selection.size() > 0) { + drag_type = DRAG_MOVE; drag_from = transform.affine_inverse().xform(b->get_position()); drag_selection = selection; _save_canvas_item_state(drag_selection); @@ -1634,9 +1766,18 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) { } } - if (drag_type == DRAG_ALL) { + if (drag_type == DRAG_MOVE) { // Move the nodes if (m.is_valid()) { + + // Save the ik chain for reapplying before IK solve + Vector<List<Dictionary> > all_bones_ik_states; + for (List<CanvasItem *>::Element *E = drag_selection.front(); E; E = E->next()) { + List<Dictionary> bones_ik_states; + _save_canvas_item_ik_chain(E->get(), NULL, &bones_ik_states); + all_bones_ik_states.push_back(bones_ik_states); + } + _restore_canvas_item_state(drag_selection, true); drag_to = transform.affine_inverse().xform(m->get_position()); @@ -1658,6 +1799,7 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) { } bool force_no_IK = m->get_alt(); + int index = 0; for (List<CanvasItem *>::Element *E = drag_selection.front(); E; E = E->next()) { CanvasItem *canvas_item = E->get(); CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item); @@ -1665,16 +1807,21 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) { Node2D *node2d = Object::cast_to<Node2D>(canvas_item); if (node2d && se->pre_drag_bones_undo_state.size() > 0 && !force_no_IK) { + real_t initial_leaf_node_rotation = node2d->get_global_transform_with_canvas().get_rotation(); + _restore_canvas_item_ik_chain(node2d, &(all_bones_ik_states[index])); + real_t final_leaf_node_rotation = node2d->get_global_transform_with_canvas().get_rotation(); + node2d->rotate(initial_leaf_node_rotation - final_leaf_node_rotation); _solve_IK(node2d, new_pos); } else { canvas_item->_edit_set_position(canvas_item->_edit_get_position() + xform.xform(new_pos) - xform.xform(previous_pos)); } + index++; } return true; } // Confirm the move (only if it was moved) - if (b.is_valid() && !b->is_pressed() && b->get_button_index() == BUTTON_LEFT && (drag_type == DRAG_ALL)) { + if (b.is_valid() && !b->is_pressed() && b->get_button_index() == BUTTON_LEFT && (drag_type == DRAG_MOVE)) { if (transform.affine_inverse().xform(b->get_position()) != drag_from) { _commit_canvas_item_state(drag_selection, TTR("Move CanvasItem"), true); } @@ -1707,6 +1854,14 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) { if (drag_selection.size() > 0) { + // Save the ik chain for reapplying before IK solve + Vector<List<Dictionary> > all_bones_ik_states; + for (List<CanvasItem *>::Element *E = drag_selection.front(); E; E = E->next()) { + List<Dictionary> bones_ik_states; + _save_canvas_item_ik_chain(E->get(), NULL, &bones_ik_states); + all_bones_ik_states.push_back(bones_ik_states); + } + _restore_canvas_item_state(drag_selection, true); bool move_local_base = k->get_alt(); @@ -1752,6 +1907,7 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) { new_pos = previous_pos + (drag_to - drag_from); } + int index = 0; for (List<CanvasItem *>::Element *E = drag_selection.front(); E; E = E->next()) { CanvasItem *canvas_item = E->get(); CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item); @@ -1759,10 +1915,15 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) { Node2D *node2d = Object::cast_to<Node2D>(canvas_item); if (node2d && se->pre_drag_bones_undo_state.size() > 0) { + real_t initial_leaf_node_rotation = node2d->get_global_transform_with_canvas().get_rotation(); + _restore_canvas_item_ik_chain(node2d, &(all_bones_ik_states[index])); + real_t final_leaf_node_rotation = node2d->get_global_transform_with_canvas().get_rotation(); + node2d->rotate(initial_leaf_node_rotation - final_leaf_node_rotation); _solve_IK(node2d, new_pos); } else { canvas_item->_edit_set_position(canvas_item->_edit_get_position() + xform.xform(new_pos) - xform.xform(previous_pos)); } + index++; } } return true; @@ -1820,11 +1981,7 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) { for (int i = 0; i < selection_results.size(); i++) { CanvasItem *item = selection_results[i].item; - Ref<Texture> icon; - if (item->has_meta("_editor_icon")) - icon = item->get_meta("_editor_icon"); - else - icon = get_icon(has_icon(item->get_class(), "EditorIcons") ? item->get_class() : String("Object"), "EditorIcons"); + Ref<Texture> icon = EditorNode::get_singleton()->get_object_icon(item, "Node"); String node_path = "/" + root_name + "/" + root_path.rel_path_to(item->get_path()); selection_menu->add_item(item->get_name()); @@ -1858,22 +2015,9 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) { // Retrieve the bones _get_bones_at_pos(click, selection); - for (int i = 0; i < selection.size(); i++) { - if (editor_selection->is_selected(selection[i].item)) { - // Drag the node(s) if requested - List<CanvasItem *> selection = _get_edited_canvas_items(); - - drag_type = DRAG_ALL; - drag_selection = selection; - drag_from = click; - _save_canvas_item_state(drag_selection); - - return true; - } - } - - if (!selection.empty()) + if (!selection.empty()) { canvas_item = selection[0].item; + } if (!canvas_item) { // Start a box selection @@ -1894,7 +2038,7 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) { // Drag the node(s) if requested List<CanvasItem *> selection = _get_edited_canvas_items(); - drag_type = DRAG_ALL; + drag_type = DRAG_MOVE; drag_selection = selection; drag_from = click; _save_canvas_item_state(drag_selection); @@ -1974,10 +2118,7 @@ bool CanvasItemEditor::_gui_input_hover(const Ref<InputEvent> &p_event) { _HoverResult hover_result; hover_result.position = canvas_item->get_global_transform_with_canvas().get_origin(); - if (has_icon(canvas_item->get_class(), "EditorIcons")) - hover_result.icon = get_icon(canvas_item->get_class(), "EditorIcons"); - else - hover_result.icon = get_icon("Object", "EditorIcons"); + hover_result.icon = EditorNode::get_singleton()->get_object_icon(canvas_item); hover_result.name = canvas_item->get_name(); hovering_results_tmp.push_back(hover_result); @@ -2019,6 +2160,8 @@ void CanvasItemEditor::_gui_input_viewport(const Ref<InputEvent> &p_event) { //printf("Open scene on double click\n"); } else if ((accepted = _gui_input_anchors(p_event))) { //printf("Anchors\n"); + } else if ((accepted = _gui_input_scale(p_event))) { + //printf("Set scale\n"); } else if ((accepted = _gui_input_pivot(p_event))) { //printf("Set pivot\n"); } else if ((accepted = _gui_input_resize(p_event))) { @@ -2073,7 +2216,7 @@ void CanvasItemEditor::_gui_input_viewport(const Ref<InputEvent> &p_event) { case DRAG_BOTTOM_LEFT: c = CURSOR_BDIAGSIZE; break; - case DRAG_ALL: + case DRAG_MOVE: c = CURSOR_MOVE; break; case DRAG_PAN: @@ -2235,7 +2378,7 @@ void CanvasItemEditor::_draw_rulers() { if (i % minor_subdivision == 0) { viewport->draw_line(Point2(position.x, RULER_WIDTH * 0.33), Point2(position.x, RULER_WIDTH), graduation_color); } else { - viewport->draw_line(Point2(position.x, RULER_WIDTH * 0.66), Point2(position.x, RULER_WIDTH), graduation_color); + viewport->draw_line(Point2(position.x, RULER_WIDTH * 0.75), Point2(position.x, RULER_WIDTH), graduation_color); } } } @@ -2247,12 +2390,17 @@ void CanvasItemEditor::_draw_rulers() { if (i % (major_subdivision * minor_subdivision) == 0) { viewport->draw_line(Point2(0, position.y), Point2(RULER_WIDTH, position.y), graduation_color); float val = (ruler_transform * major_subdivide * minor_subdivide).xform(Point2(0, i)).y; - viewport->draw_string(font, Point2(2, position.y + 2 + font->get_height()), vformat(((int)val == val) ? "%d" : "%.1f", val), font_color); + + Transform2D text_xform = Transform2D(-Math_PI / 2.0, Point2(font->get_height(), position.y - 2)); + viewport->draw_set_transform_matrix(viewport->get_transform() * text_xform); + viewport->draw_string(font, Point2(), vformat(((int)val == val) ? "%d" : "%.1f", val), font_color); + viewport->draw_set_transform_matrix(viewport->get_transform()); + } else { if (i % minor_subdivision == 0) { viewport->draw_line(Point2(RULER_WIDTH * 0.33, position.y), Point2(RULER_WIDTH, position.y), graduation_color); } else { - viewport->draw_line(Point2(RULER_WIDTH * 0.66, position.y), Point2(RULER_WIDTH, position.y), graduation_color); + viewport->draw_line(Point2(RULER_WIDTH * 0.75, position.y), Point2(RULER_WIDTH, position.y), graduation_color); } } } @@ -2301,6 +2449,188 @@ void CanvasItemEditor::_draw_grid() { } } +void CanvasItemEditor::_draw_control_helpers(Control *control) { + Transform2D xform = transform * control->get_global_transform_with_canvas(); + RID ci = viewport->get_canvas_item(); + if (tool == TOOL_SELECT && show_helpers && !Object::cast_to<Container>(control->get_parent())) { + // Draw the helpers + Color color_base = Color(0.8, 0.8, 0.8, 0.5); + + float anchors_values[4]; + anchors_values[0] = control->get_anchor(MARGIN_LEFT); + anchors_values[1] = control->get_anchor(MARGIN_TOP); + anchors_values[2] = control->get_anchor(MARGIN_RIGHT); + anchors_values[3] = control->get_anchor(MARGIN_BOTTOM); + + // Draw the anchors + Vector2 anchors[4]; + Vector2 anchors_pos[4]; + for (int i = 0; i < 4; i++) { + anchors[i] = Vector2((i % 2 == 0) ? anchors_values[i] : anchors_values[(i + 1) % 4], (i % 2 == 1) ? anchors_values[i] : anchors_values[(i + 1) % 4]); + anchors_pos[i] = xform.xform(_anchor_to_position(control, anchors[i])); + } + + // Get which anchor is dragged + int dragged_anchor = -1; + switch (drag_type) { + case DRAG_ANCHOR_ALL: + case DRAG_ANCHOR_TOP_LEFT: + dragged_anchor = 0; + break; + case DRAG_ANCHOR_TOP_RIGHT: + dragged_anchor = 1; + break; + case DRAG_ANCHOR_BOTTOM_RIGHT: + dragged_anchor = 2; + break; + case DRAG_ANCHOR_BOTTOM_LEFT: + dragged_anchor = 3; + break; + default: + break; + } + + if (dragged_anchor >= 0) { + // Draw the 4 lines when dragged + bool snapped; + Color color_snapped = Color(0.64, 0.93, 0.67, 0.5); + + Vector2 corners_pos[4]; + for (int i = 0; i < 4; i++) { + corners_pos[i] = xform.xform(_anchor_to_position(control, Vector2((i == 0 || i == 3) ? ANCHOR_BEGIN : ANCHOR_END, (i <= 1) ? ANCHOR_BEGIN : ANCHOR_END))); + } + + Vector2 line_starts[4]; + Vector2 line_ends[4]; + for (int i = 0; i < 4; i++) { + float anchor_val = (i >= 2) ? ANCHOR_END - anchors_values[i] : anchors_values[i]; + line_starts[i] = Vector2::linear_interpolate(corners_pos[i], corners_pos[(i + 1) % 4], anchor_val); + line_ends[i] = Vector2::linear_interpolate(corners_pos[(i + 3) % 4], corners_pos[(i + 2) % 4], anchor_val); + snapped = anchors_values[i] == 0.0 || anchors_values[i] == 0.5 || anchors_values[i] == 1.0; + viewport->draw_line(line_starts[i], line_ends[i], snapped ? color_snapped : color_base, (i == dragged_anchor || (i + 3) % 4 == dragged_anchor) ? 2 : 1); + } + + // Display the percentages next to the lines + float percent_val; + percent_val = anchors_values[(dragged_anchor + 2) % 4] - anchors_values[dragged_anchor]; + percent_val = (dragged_anchor >= 2) ? -percent_val : percent_val; + _draw_percentage_at_position(percent_val, (anchors_pos[dragged_anchor] + anchors_pos[(dragged_anchor + 1) % 4]) / 2, (Margin)((dragged_anchor + 1) % 4)); + + percent_val = anchors_values[(dragged_anchor + 3) % 4] - anchors_values[(dragged_anchor + 1) % 4]; + percent_val = ((dragged_anchor + 1) % 4 >= 2) ? -percent_val : percent_val; + _draw_percentage_at_position(percent_val, (anchors_pos[dragged_anchor] + anchors_pos[(dragged_anchor + 3) % 4]) / 2, (Margin)(dragged_anchor)); + + percent_val = anchors_values[(dragged_anchor + 1) % 4]; + percent_val = ((dragged_anchor + 1) % 4 >= 2) ? ANCHOR_END - percent_val : percent_val; + _draw_percentage_at_position(percent_val, (line_starts[dragged_anchor] + anchors_pos[dragged_anchor]) / 2, (Margin)(dragged_anchor)); + + percent_val = anchors_values[dragged_anchor]; + percent_val = (dragged_anchor >= 2) ? ANCHOR_END - percent_val : percent_val; + _draw_percentage_at_position(percent_val, (line_ends[(dragged_anchor + 1) % 4] + anchors_pos[dragged_anchor]) / 2, (Margin)((dragged_anchor + 1) % 4)); + } + + Rect2 anchor_rects[4]; + anchor_rects[0] = Rect2(anchors_pos[0] - anchor_handle->get_size(), anchor_handle->get_size()); + anchor_rects[1] = Rect2(anchors_pos[1] - Vector2(0.0, anchor_handle->get_size().y), Point2(-anchor_handle->get_size().x, anchor_handle->get_size().y)); + anchor_rects[2] = Rect2(anchors_pos[2], -anchor_handle->get_size()); + anchor_rects[3] = Rect2(anchors_pos[3] - Vector2(anchor_handle->get_size().x, 0.0), Point2(anchor_handle->get_size().x, -anchor_handle->get_size().y)); + + for (int i = 0; i < 4; i++) { + anchor_handle->draw_rect(ci, anchor_rects[i]); + } + + // Draw the margin values and the node width/height when dragging control side + float ratio = 0.33; + Transform2D parent_transform = xform * control->get_transform().affine_inverse(); + float node_pos_in_parent[4]; + + Rect2 parent_rect = control->get_parent_anchorable_rect(); + + node_pos_in_parent[0] = control->get_anchor(MARGIN_LEFT) * parent_rect.size.width + control->get_margin(MARGIN_LEFT) + parent_rect.position.x; + node_pos_in_parent[1] = control->get_anchor(MARGIN_TOP) * parent_rect.size.height + control->get_margin(MARGIN_TOP) + parent_rect.position.y; + node_pos_in_parent[2] = control->get_anchor(MARGIN_RIGHT) * parent_rect.size.width + control->get_margin(MARGIN_RIGHT) + parent_rect.position.x; + node_pos_in_parent[3] = control->get_anchor(MARGIN_BOTTOM) * parent_rect.size.height + control->get_margin(MARGIN_BOTTOM) + parent_rect.position.y; + + Point2 start, end; + switch (drag_type) { + case DRAG_LEFT: + case DRAG_TOP_LEFT: + case DRAG_BOTTOM_LEFT: + _draw_margin_at_position(control->get_size().width, parent_transform.xform(Vector2((node_pos_in_parent[0] + node_pos_in_parent[2]) / 2, node_pos_in_parent[3])) + Vector2(0, 5), MARGIN_BOTTOM); + case DRAG_MOVE: + start = Vector2(node_pos_in_parent[0], Math::lerp(node_pos_in_parent[1], node_pos_in_parent[3], ratio)); + end = start - Vector2(control->get_margin(MARGIN_LEFT), 0); + _draw_margin_at_position(control->get_margin(MARGIN_LEFT), parent_transform.xform((start + end) / 2), MARGIN_TOP); + viewport->draw_line(parent_transform.xform(start), parent_transform.xform(end), color_base, 1); + break; + default: + break; + } + switch (drag_type) { + case DRAG_RIGHT: + case DRAG_TOP_RIGHT: + case DRAG_BOTTOM_RIGHT: + _draw_margin_at_position(control->get_size().width, parent_transform.xform(Vector2((node_pos_in_parent[0] + node_pos_in_parent[2]) / 2, node_pos_in_parent[3])) + Vector2(0, 5), MARGIN_BOTTOM); + case DRAG_MOVE: + start = Vector2(node_pos_in_parent[2], Math::lerp(node_pos_in_parent[3], node_pos_in_parent[1], ratio)); + end = start - Vector2(control->get_margin(MARGIN_RIGHT), 0); + _draw_margin_at_position(control->get_margin(MARGIN_RIGHT), parent_transform.xform((start + end) / 2), MARGIN_BOTTOM); + viewport->draw_line(parent_transform.xform(start), parent_transform.xform(end), color_base, 1); + break; + default: + break; + } + switch (drag_type) { + case DRAG_TOP: + case DRAG_TOP_LEFT: + case DRAG_TOP_RIGHT: + _draw_margin_at_position(control->get_size().height, parent_transform.xform(Vector2(node_pos_in_parent[2], (node_pos_in_parent[1] + node_pos_in_parent[3]) / 2)) + Vector2(5, 0), MARGIN_RIGHT); + case DRAG_MOVE: + start = Vector2(Math::lerp(node_pos_in_parent[0], node_pos_in_parent[2], ratio), node_pos_in_parent[1]); + end = start - Vector2(0, control->get_margin(MARGIN_TOP)); + _draw_margin_at_position(control->get_margin(MARGIN_TOP), parent_transform.xform((start + end) / 2), MARGIN_LEFT); + viewport->draw_line(parent_transform.xform(start), parent_transform.xform(end), color_base, 1); + break; + default: + break; + } + switch (drag_type) { + case DRAG_BOTTOM: + case DRAG_BOTTOM_LEFT: + case DRAG_BOTTOM_RIGHT: + _draw_margin_at_position(control->get_size().height, parent_transform.xform(Vector2(node_pos_in_parent[2], (node_pos_in_parent[1] + node_pos_in_parent[3]) / 2) + Vector2(5, 0)), MARGIN_RIGHT); + case DRAG_MOVE: + start = Vector2(Math::lerp(node_pos_in_parent[2], node_pos_in_parent[0], ratio), node_pos_in_parent[3]); + end = start - Vector2(0, control->get_margin(MARGIN_BOTTOM)); + _draw_margin_at_position(control->get_margin(MARGIN_BOTTOM), parent_transform.xform((start + end) / 2), MARGIN_RIGHT); + viewport->draw_line(parent_transform.xform(start), parent_transform.xform(end), color_base, 1); + break; + default: + break; + } + + switch (drag_type) { + //Draw the ghost rect if the node if rotated/scaled + case DRAG_LEFT: + case DRAG_TOP_LEFT: + case DRAG_TOP: + case DRAG_TOP_RIGHT: + case DRAG_RIGHT: + case DRAG_BOTTOM_RIGHT: + case DRAG_BOTTOM: + case DRAG_BOTTOM_LEFT: + case DRAG_MOVE: + if (control->get_rotation() != 0.0 || control->get_scale() != Vector2(1, 1)) { + Rect2 rect = Rect2(Vector2(node_pos_in_parent[0], node_pos_in_parent[1]), control->get_size()); + viewport->draw_rect(parent_transform.xform(rect), color_base, false); + } + break; + default: + break; + } + } +} + void CanvasItemEditor::_draw_selection() { Ref<Texture> pivot_icon = get_icon("EditorPivot", "EditorIcons"); Ref<Texture> position_icon = get_icon("EditorPosition", "EditorIcons"); @@ -2317,7 +2647,7 @@ void CanvasItemEditor::_draw_selection() { // Draw the previous position if we are dragging the node if (show_helpers && - (drag_type == DRAG_ALL || drag_type == DRAG_ROTATE || + (drag_type == DRAG_MOVE || drag_type == DRAG_ROTATE || drag_type == DRAG_LEFT || drag_type == DRAG_RIGHT || drag_type == DRAG_TOP || drag_type == DRAG_BOTTOM || drag_type == DRAG_TOP_LEFT || drag_type == DRAG_TOP_RIGHT || drag_type == DRAG_BOTTOM_LEFT || drag_type == DRAG_BOTTOM_RIGHT)) { const Transform2D pre_drag_xform = transform * se->pre_drag_xform; @@ -2359,199 +2689,26 @@ void CanvasItemEditor::_draw_selection() { } } else { - Transform2D transform = Transform2D(xform.get_rotation(), xform.get_origin()); - viewport->draw_set_transform_matrix(transform); + Transform2D unscaled_transform = (xform * canvas_item->get_transform().affine_inverse() * Transform2D(canvas_item->_edit_get_rotation(), canvas_item->_edit_get_position())).orthonormalized(); + Transform2D simple_xform = viewport->get_transform() * unscaled_transform; + viewport->draw_set_transform_matrix(simple_xform); viewport->draw_texture(position_icon, -(position_icon->get_size() / 2)); - viewport->draw_set_transform_matrix(Transform2D()); + viewport->draw_set_transform_matrix(viewport->get_transform()); } - if (single && (tool == TOOL_SELECT || tool == TOOL_MOVE || tool == TOOL_ROTATE || tool == TOOL_EDIT_PIVOT)) { //kind of sucks + if (single && (tool == TOOL_SELECT || tool == TOOL_MOVE || tool == TOOL_SCALE || tool == TOOL_ROTATE || tool == TOOL_EDIT_PIVOT)) { //kind of sucks // Draw the pivot if (canvas_item->_edit_get_pivot() != Vector2() || drag_type == DRAG_PIVOT || tool == TOOL_EDIT_PIVOT) { // This is not really clean :/ viewport->draw_texture(pivot_icon, (xform.xform(canvas_item->_edit_get_pivot()) - (pivot_icon->get_size() / 2)).floor()); } + // Draw control-related helpers Control *control = Object::cast_to<Control>(canvas_item); if (control) { - if (tool == TOOL_SELECT && show_helpers && !Object::cast_to<Container>(control->get_parent())) { - // Draw the helpers - Color color_base = Color(0.8, 0.8, 0.8, 0.5); - - float anchors_values[4]; - anchors_values[0] = control->get_anchor(MARGIN_LEFT); - anchors_values[1] = control->get_anchor(MARGIN_TOP); - anchors_values[2] = control->get_anchor(MARGIN_RIGHT); - anchors_values[3] = control->get_anchor(MARGIN_BOTTOM); - - // Draw the anchors - Vector2 anchors[4]; - Vector2 anchors_pos[4]; - for (int i = 0; i < 4; i++) { - anchors[i] = Vector2((i % 2 == 0) ? anchors_values[i] : anchors_values[(i + 1) % 4], (i % 2 == 1) ? anchors_values[i] : anchors_values[(i + 1) % 4]); - anchors_pos[i] = xform.xform(_anchor_to_position(control, anchors[i])); - } - - // Get which anchor is dragged - int dragged_anchor = -1; - switch (drag_type) { - case DRAG_ANCHOR_ALL: - case DRAG_ANCHOR_TOP_LEFT: - dragged_anchor = 0; - break; - case DRAG_ANCHOR_TOP_RIGHT: - dragged_anchor = 1; - break; - case DRAG_ANCHOR_BOTTOM_RIGHT: - dragged_anchor = 2; - break; - case DRAG_ANCHOR_BOTTOM_LEFT: - dragged_anchor = 3; - break; - default: - break; - } - - if (dragged_anchor >= 0) { - // Draw the 4 lines when dragged - bool snapped; - Color color_snapped = Color(0.64, 0.93, 0.67, 0.5); - - Vector2 corners_pos[4]; - for (int i = 0; i < 4; i++) { - corners_pos[i] = xform.xform(_anchor_to_position(control, Vector2((i == 0 || i == 3) ? ANCHOR_BEGIN : ANCHOR_END, (i <= 1) ? ANCHOR_BEGIN : ANCHOR_END))); - } - - Vector2 line_starts[4]; - Vector2 line_ends[4]; - for (int i = 0; i < 4; i++) { - float anchor_val = (i >= 2) ? ANCHOR_END - anchors_values[i] : anchors_values[i]; - line_starts[i] = Vector2::linear_interpolate(corners_pos[i], corners_pos[(i + 1) % 4], anchor_val); - line_ends[i] = Vector2::linear_interpolate(corners_pos[(i + 3) % 4], corners_pos[(i + 2) % 4], anchor_val); - snapped = anchors_values[i] == 0.0 || anchors_values[i] == 0.5 || anchors_values[i] == 1.0; - viewport->draw_line(line_starts[i], line_ends[i], snapped ? color_snapped : color_base, (i == dragged_anchor || (i + 3) % 4 == dragged_anchor) ? 2 : 1); - } - - // Display the percentages next to the lines - float percent_val; - percent_val = anchors_values[(dragged_anchor + 2) % 4] - anchors_values[dragged_anchor]; - percent_val = (dragged_anchor >= 2) ? -percent_val : percent_val; - _draw_percentage_at_position(percent_val, (anchors_pos[dragged_anchor] + anchors_pos[(dragged_anchor + 1) % 4]) / 2, (Margin)((dragged_anchor + 1) % 4)); - - percent_val = anchors_values[(dragged_anchor + 3) % 4] - anchors_values[(dragged_anchor + 1) % 4]; - percent_val = ((dragged_anchor + 1) % 4 >= 2) ? -percent_val : percent_val; - _draw_percentage_at_position(percent_val, (anchors_pos[dragged_anchor] + anchors_pos[(dragged_anchor + 3) % 4]) / 2, (Margin)(dragged_anchor)); - - percent_val = anchors_values[(dragged_anchor + 1) % 4]; - percent_val = ((dragged_anchor + 1) % 4 >= 2) ? ANCHOR_END - percent_val : percent_val; - _draw_percentage_at_position(percent_val, (line_starts[dragged_anchor] + anchors_pos[dragged_anchor]) / 2, (Margin)(dragged_anchor)); - - percent_val = anchors_values[dragged_anchor]; - percent_val = (dragged_anchor >= 2) ? ANCHOR_END - percent_val : percent_val; - _draw_percentage_at_position(percent_val, (line_ends[(dragged_anchor + 1) % 4] + anchors_pos[dragged_anchor]) / 2, (Margin)((dragged_anchor + 1) % 4)); - } - - Rect2 anchor_rects[4]; - anchor_rects[0] = Rect2(anchors_pos[0] - anchor_handle->get_size(), anchor_handle->get_size()); - anchor_rects[1] = Rect2(anchors_pos[1] - Vector2(0.0, anchor_handle->get_size().y), Point2(-anchor_handle->get_size().x, anchor_handle->get_size().y)); - anchor_rects[2] = Rect2(anchors_pos[2], -anchor_handle->get_size()); - anchor_rects[3] = Rect2(anchors_pos[3] - Vector2(anchor_handle->get_size().x, 0.0), Point2(anchor_handle->get_size().x, -anchor_handle->get_size().y)); - - for (int i = 0; i < 4; i++) { - anchor_handle->draw_rect(ci, anchor_rects[i]); - } - - // Draw the margin values and the node width/height when dragging control side - float ratio = 0.33; - Transform2D parent_transform = xform * control->get_transform().affine_inverse(); - float node_pos_in_parent[4]; - - Rect2 parent_rect = control->get_parent_anchorable_rect(); - - node_pos_in_parent[0] = control->get_anchor(MARGIN_LEFT) * parent_rect.size.width + control->get_margin(MARGIN_LEFT) + parent_rect.position.x; - node_pos_in_parent[1] = control->get_anchor(MARGIN_TOP) * parent_rect.size.height + control->get_margin(MARGIN_TOP) + parent_rect.position.y; - node_pos_in_parent[2] = control->get_anchor(MARGIN_RIGHT) * parent_rect.size.width + control->get_margin(MARGIN_RIGHT) + parent_rect.position.x; - node_pos_in_parent[3] = control->get_anchor(MARGIN_BOTTOM) * parent_rect.size.height + control->get_margin(MARGIN_BOTTOM) + parent_rect.position.y; - - Point2 start, end; - switch (drag_type) { - case DRAG_LEFT: - case DRAG_TOP_LEFT: - case DRAG_BOTTOM_LEFT: - _draw_margin_at_position(control->get_size().width, parent_transform.xform(Vector2((node_pos_in_parent[0] + node_pos_in_parent[2]) / 2, node_pos_in_parent[3])) + Vector2(0, 5), MARGIN_BOTTOM); - case DRAG_ALL: - start = Vector2(node_pos_in_parent[0], Math::lerp(node_pos_in_parent[1], node_pos_in_parent[3], ratio)); - end = start - Vector2(control->get_margin(MARGIN_LEFT), 0); - _draw_margin_at_position(control->get_margin(MARGIN_LEFT), parent_transform.xform((start + end) / 2), MARGIN_TOP); - viewport->draw_line(parent_transform.xform(start), parent_transform.xform(end), color_base, 1); - break; - default: - break; - } - switch (drag_type) { - case DRAG_RIGHT: - case DRAG_TOP_RIGHT: - case DRAG_BOTTOM_RIGHT: - _draw_margin_at_position(control->get_size().width, parent_transform.xform(Vector2((node_pos_in_parent[0] + node_pos_in_parent[2]) / 2, node_pos_in_parent[3])) + Vector2(0, 5), MARGIN_BOTTOM); - case DRAG_ALL: - start = Vector2(node_pos_in_parent[2], Math::lerp(node_pos_in_parent[3], node_pos_in_parent[1], ratio)); - end = start - Vector2(control->get_margin(MARGIN_RIGHT), 0); - _draw_margin_at_position(control->get_margin(MARGIN_RIGHT), parent_transform.xform((start + end) / 2), MARGIN_BOTTOM); - viewport->draw_line(parent_transform.xform(start), parent_transform.xform(end), color_base, 1); - break; - default: - break; - } - switch (drag_type) { - case DRAG_TOP: - case DRAG_TOP_LEFT: - case DRAG_TOP_RIGHT: - _draw_margin_at_position(control->get_size().height, parent_transform.xform(Vector2(node_pos_in_parent[2], (node_pos_in_parent[1] + node_pos_in_parent[3]) / 2)) + Vector2(5, 0), MARGIN_RIGHT); - case DRAG_ALL: - start = Vector2(Math::lerp(node_pos_in_parent[0], node_pos_in_parent[2], ratio), node_pos_in_parent[1]); - end = start - Vector2(0, control->get_margin(MARGIN_TOP)); - _draw_margin_at_position(control->get_margin(MARGIN_TOP), parent_transform.xform((start + end) / 2), MARGIN_LEFT); - viewport->draw_line(parent_transform.xform(start), parent_transform.xform(end), color_base, 1); - break; - default: - break; - } - switch (drag_type) { - case DRAG_BOTTOM: - case DRAG_BOTTOM_LEFT: - case DRAG_BOTTOM_RIGHT: - _draw_margin_at_position(control->get_size().height, parent_transform.xform(Vector2(node_pos_in_parent[2], (node_pos_in_parent[1] + node_pos_in_parent[3]) / 2) + Vector2(5, 0)), MARGIN_RIGHT); - case DRAG_ALL: - start = Vector2(Math::lerp(node_pos_in_parent[2], node_pos_in_parent[0], ratio), node_pos_in_parent[3]); - end = start - Vector2(0, control->get_margin(MARGIN_BOTTOM)); - _draw_margin_at_position(control->get_margin(MARGIN_BOTTOM), parent_transform.xform((start + end) / 2), MARGIN_RIGHT); - viewport->draw_line(parent_transform.xform(start), parent_transform.xform(end), color_base, 1); - break; - default: - break; - } - - switch (drag_type) { - //Draw the ghost rect if the node if rotated/scaled - case DRAG_LEFT: - case DRAG_TOP_LEFT: - case DRAG_TOP: - case DRAG_TOP_RIGHT: - case DRAG_RIGHT: - case DRAG_BOTTOM_RIGHT: - case DRAG_BOTTOM: - case DRAG_BOTTOM_LEFT: - case DRAG_ALL: - if (control->get_rotation() != 0.0 || control->get_scale() != Vector2(1, 1)) { - Rect2 rect = Rect2(Vector2(node_pos_in_parent[0], node_pos_in_parent[1]), control->get_size()); - viewport->draw_rect(parent_transform.xform(rect), color_base, false); - } - break; - default: - break; - } - } + _draw_control_helpers(control); } + // Draw the resize handles if (tool == TOOL_SELECT && canvas_item->_edit_use_rect()) { Rect2 rect = canvas_item->_edit_get_rect(); Vector2 endpoints[4] = { @@ -2561,7 +2718,6 @@ void CanvasItemEditor::_draw_selection() { xform.xform(rect.position + Vector2(0, rect.size.y)) }; for (int i = 0; i < 4; i++) { - // Draw the resize handles int prev = (i + 3) % 4; int next = (i + 1) % 4; @@ -2576,6 +2732,46 @@ void CanvasItemEditor::_draw_selection() { select_handle->draw(ci, (ofs - (select_handle->get_size() / 2)).floor()); } } + + // Draw the rescale handles + bool is_ctrl = Input::get_singleton()->is_key_pressed(KEY_CONTROL); + bool is_alt = Input::get_singleton()->is_key_pressed(KEY_ALT); + if ((is_alt && is_ctrl) || tool == TOOL_SCALE || drag_type == DRAG_SCALE_X || drag_type == DRAG_SCALE_Y) { + + Transform2D unscaled_transform = (xform * canvas_item->get_transform().affine_inverse() * Transform2D(canvas_item->_edit_get_rotation(), canvas_item->_edit_get_position())).orthonormalized(); + Transform2D simple_xform = viewport->get_transform() * unscaled_transform; + + Size2 scale_factor = Size2(SCALE_HANDLE_DISTANCE, SCALE_HANDLE_DISTANCE); + bool uniform = Input::get_singleton()->is_key_pressed(KEY_SHIFT); + Point2 offset = (simple_xform.affine_inverse().xform(drag_to) - simple_xform.affine_inverse().xform(drag_from)) * zoom; + + if (drag_type == DRAG_SCALE_X) { + scale_factor.x += offset.x; + if (uniform) { + scale_factor.y += offset.x; + } + } else if (drag_type == DRAG_SCALE_Y) { + scale_factor.y -= offset.y; + if (uniform) { + scale_factor.x -= offset.y; + } + } + + //scale_factor *= zoom; + + viewport->draw_set_transform_matrix(simple_xform); + Rect2 x_handle_rect = Rect2(scale_factor.x * EDSCALE, -5 * EDSCALE, 10 * EDSCALE, 10 * EDSCALE); + Color x_axis_color(1.0, 0.4, 0.4, 0.6); + viewport->draw_rect(x_handle_rect, x_axis_color); + viewport->draw_line(Point2(), Point2(scale_factor.x * EDSCALE, 0), x_axis_color); + + Rect2 y_handle_rect = Rect2(-5 * EDSCALE, -(scale_factor.y + 10) * EDSCALE, 10 * EDSCALE, 10 * EDSCALE); + Color y_axis_color(0.4, 1.0, 0.4, 0.6); + viewport->draw_rect(y_handle_rect, y_axis_color); + viewport->draw_line(Point2(), Point2(0, -scale_factor.y * EDSCALE), y_axis_color); + + viewport->draw_set_transform_matrix(viewport->get_transform()); + } } } @@ -2650,7 +2846,7 @@ void CanvasItemEditor::_draw_axis() { RID ci = viewport->get_canvas_item(); - Color area_axis_color(0.4, 0.4, 1.0, 0.4); + Color area_axis_color = EditorSettings::get_singleton()->get("editors/2d/viewport_border_color"); Size2 screen_size = Size2(ProjectSettings::get_singleton()->get("display/window/size/width"), ProjectSettings::get_singleton()->get("display/window/size/height")); @@ -2750,15 +2946,16 @@ void CanvasItemEditor::_draw_invisible_nodes_positions(Node *p_node, const Trans _draw_invisible_nodes_positions(p_node->get_child(i), parent_xform, canvas_xform); } - if (canvas_item && !canvas_item->_edit_use_rect() && !editor_selection->is_selected(canvas_item)) { + if (canvas_item && !canvas_item->_edit_use_rect() && (!editor_selection->is_selected(canvas_item) || (canvas_item->has_meta("_edit_lock_") && canvas_item->get_meta("_edit_lock_")))) { Transform2D xform = transform * canvas_xform * parent_xform; // Draw the node's position Ref<Texture> position_icon = get_icon("EditorPositionUnselected", "EditorIcons"); - Transform2D transform = Transform2D(xform.get_rotation(), xform.get_origin()); - viewport->draw_set_transform_matrix(transform); + Transform2D unscaled_transform = (xform * canvas_item->get_transform().affine_inverse() * Transform2D(canvas_item->_edit_get_rotation(), canvas_item->_edit_get_position())).orthonormalized(); + Transform2D simple_xform = viewport->get_transform() * unscaled_transform; + viewport->draw_set_transform_matrix(simple_xform); viewport->draw_texture(position_icon, -position_icon->get_size() / 2, Color(1.0, 1.0, 1.0, 0.5)); - viewport->draw_set_transform_matrix(Transform2D()); + viewport->draw_set_transform_matrix(viewport->get_transform()); } } @@ -2775,7 +2972,7 @@ void CanvasItemEditor::_draw_hover() { Size2 item_size = Size2(node_icon->get_size().x + 4 + node_name_size.x, MAX(node_icon->get_size().y, node_name_size.y - 3)); Point2 pos = transform.xform(hovering_results[i].position) - Point2(0, item_size.y) + (Point2(node_icon->get_size().x, -node_icon->get_size().y) / 4); - // Rectify the position to avoid overlaping items + // Rectify the position to avoid overlapping items for (List<Rect2>::Element *E = previous_rects.front(); E; E = E->next()) { if (E->get().intersects(Rect2(pos, item_size))) { pos.y = E->get().get_position().y - item_size.y; @@ -2822,13 +3019,13 @@ void CanvasItemEditor::_draw_locks_and_groups(Node *p_node, const Transform2D &p float offset = 0; Ref<Texture> lock = get_icon("LockViewport", "EditorIcons"); - if (p_node->has_meta("_edit_lock_")) { + if (p_node->has_meta("_edit_lock_") && show_edit_locks) { lock->draw(viewport_canvas_item, (transform * canvas_xform * parent_xform).xform(Point2(0, 0)) + Point2(offset, 0)); offset += lock->get_size().x; } Ref<Texture> group = get_icon("GroupViewport", "EditorIcons"); - if (canvas_item->has_meta("_edit_group_")) { + if (canvas_item->has_meta("_edit_group_") && show_edit_locks) { group->draw(viewport_canvas_item, (transform * canvas_xform * parent_xform).xform(Point2(0, 0)) + Point2(offset, 0)); //offset += group->get_size().x; } @@ -2902,6 +3099,7 @@ bool CanvasItemEditor::_build_bones_list(Node *p_node) { } void CanvasItemEditor::_draw_viewport() { + // Update the transform transform = Transform2D(); transform.scale_basis(Size2(zoom, zoom)); @@ -2950,11 +3148,11 @@ void CanvasItemEditor::_draw_viewport() { EditorPluginList *over_plugin_list = editor->get_editor_plugins_over(); if (!over_plugin_list->empty()) { - over_plugin_list->forward_draw_over_viewport(viewport); + over_plugin_list->forward_canvas_draw_over_viewport(viewport); } EditorPluginList *force_over_plugin_list = editor->get_editor_plugins_force_over(); if (!force_over_plugin_list->empty()) { - force_over_plugin_list->forward_force_draw_over_viewport(viewport); + force_over_plugin_list->forward_canvas_force_draw_over_viewport(viewport); } _draw_bones(); @@ -3086,6 +3284,7 @@ void CanvasItemEditor::_notification(int p_what) { select_button->set_icon(get_icon("ToolSelect", "EditorIcons")); list_select_button->set_icon(get_icon("ListSelect", "EditorIcons")); move_button->set_icon(get_icon("ToolMove", "EditorIcons")); + scale_button->set_icon(get_icon("ToolScale", "EditorIcons")); rotate_button->set_icon(get_icon("ToolRotate", "EditorIcons")); snap_button->set_icon(get_icon("Snap", "EditorIcons")); snap_config_menu->set_icon(get_icon("GuiMiniTabMenu", "EditorIcons")); @@ -3394,7 +3593,7 @@ void CanvasItemEditor::_button_toggle_snap(bool p_status) { void CanvasItemEditor::_button_tool_select(int p_index) { - ToolButton *tb[TOOL_MAX] = { select_button, list_select_button, move_button, rotate_button, pivot_button, pan_button }; + ToolButton *tb[TOOL_MAX] = { select_button, list_select_button, move_button, scale_button, rotate_button, pivot_button, pan_button }; for (int i = 0; i < TOOL_MAX; i++) { tb[i]->set_pressed(i == p_index); } @@ -3426,6 +3625,12 @@ void CanvasItemEditor::_popup_callback(int p_op) { view_menu->get_popup()->set_item_checked(idx, show_viewport); viewport->update(); } break; + case SHOW_EDIT_LOCKS: { + show_edit_locks = !show_edit_locks; + int idx = view_menu->get_popup()->get_item_index(SHOW_EDIT_LOCKS); + view_menu->get_popup()->set_item_checked(idx, show_edit_locks); + viewport->update(); + } break; case SNAP_USE_NODE_PARENT: { snap_node_parent = !snap_node_parent; int idx = smartsnap_config_popup->get_item_index(SNAP_USE_NODE_PARENT); @@ -4029,6 +4234,7 @@ Dictionary CanvasItemEditor::get_state() const { state["show_rulers"] = show_rulers; state["show_guides"] = show_guides; state["show_helpers"] = show_helpers; + state["show_edit_locks"] = show_edit_locks; state["snap_rotation"] = snap_rotation; state["snap_relative"] = snap_relative; state["snap_pixel"] = snap_pixel; @@ -4148,6 +4354,12 @@ void CanvasItemEditor::set_state(const Dictionary &p_state) { view_menu->get_popup()->set_item_checked(idx, show_helpers); } + if (state.has("show_edit_locks")) { + show_edit_locks = state["show_edit_locks"]; + int idx = view_menu->get_popup()->get_item_index(SHOW_EDIT_LOCKS); + view_menu->get_popup()->set_item_checked(idx, show_edit_locks); + } + if (state.has("snap_rotation")) { snap_rotation = state["snap_rotation"]; int idx = snap_config_menu->get_popup()->get_item_index(SNAP_USE_ROTATION); @@ -4273,7 +4485,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { zoom_plus = memnew(ToolButton); zoom_hb->add_child(zoom_plus); zoom_plus->connect("pressed", this, "_button_zoom_plus"); - zoom_plus->set_shortcut(ED_SHORTCUT("canvas_item_editor/zoom_plus", TTR("Zoom in"), KEY_MASK_CMD | KEY_PLUS)); + zoom_plus->set_shortcut(ED_SHORTCUT("canvas_item_editor/zoom_plus", TTR("Zoom in"), KEY_MASK_CMD | KEY_EQUAL)); // Usually direct access key for PLUS zoom_plus->set_focus_mode(FOCUS_NONE); updating_scroll = false; @@ -4286,6 +4498,8 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { select_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/select_mode", TTR("Select Mode"), KEY_Q)); select_button->set_tooltip(keycode_get_string(KEY_MASK_CMD) + TTR("Drag: Rotate") + "\n" + TTR("Alt+Drag: Move") + "\n" + TTR("Press 'v' to Change Pivot, 'Shift+v' to Drag Pivot (while moving).") + "\n" + TTR("Alt+RMB: Depth list selection")); + hb->add_child(memnew(VSeparator)); + move_button = memnew(ToolButton); hb->add_child(move_button); move_button->set_toggle_mode(true); @@ -4300,6 +4514,13 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { rotate_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/rotate_mode", TTR("Rotate Mode"), KEY_E)); rotate_button->set_tooltip(TTR("Rotate Mode")); + scale_button = memnew(ToolButton); + hb->add_child(scale_button); + scale_button->set_toggle_mode(true); + scale_button->connect("pressed", this, "_button_tool_select", make_binds(TOOL_SCALE)); + scale_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/scale_mode", TTR("Scale Mode"), KEY_S)); + scale_button->set_tooltip(TTR("Scale Mode")); + hb->add_child(memnew(VSeparator)); list_select_button = memnew(ToolButton); @@ -4409,6 +4630,8 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/show_guides", TTR("Show Guides"), KEY_Y), SHOW_GUIDES); p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/show_origin", TTR("Show Origin")), SHOW_ORIGIN); p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/show_viewport", TTR("Show Viewport")), SHOW_VIEWPORT); + p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/show_edit_locks", TTR("Show Group And Lock Icons")), SHOW_EDIT_LOCKS); + p->add_separator(); p->add_shortcut(ED_SHORTCUT("canvas_item_editor/center_selection", TTR("Center Selection"), KEY_F), VIEW_CENTER_TO_SELECTION); p->add_shortcut(ED_SHORTCUT("canvas_item_editor/frame_selection", TTR("Frame Selection"), KEY_MASK_SHIFT | KEY_F), VIEW_FRAME_TO_SELECTION); @@ -4499,6 +4722,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { show_helpers = false; show_rulers = true; show_guides = true; + show_edit_locks = true; zoom = 1; view_offset = Point2(-150 - RULER_WIDTH, -95 - RULER_WIDTH); previous_update_view_offset = view_offset; // Moves the view a little bit to the left so that (0,0) is visible. The values a relative to a 16/10 screen @@ -4791,7 +5015,6 @@ void CanvasItemEditorViewport::_perform_drop_data() { // Without root dropping multiple files is not allowed if (!target_node && selected_files.size() > 1) { - accept->get_ok()->set_text(TTR("Ok")); accept->set_text(TTR("Cannot instantiate multiple nodes without root.")); accept->popup_centered_minsize(); return; @@ -4853,7 +5076,6 @@ void CanvasItemEditorViewport::_perform_drop_data() { files_str += error_files[i].get_file().get_basename() + ","; } files_str = files_str.substr(0, files_str.length() - 1); - accept->get_ok()->set_text(TTR("OK")); accept->set_text(vformat(TTR("Error instancing scene from %s"), files_str.c_str())); accept->popup_centered_minsize(); } diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h index 2c943385ad..c788a63d56 100644 --- a/editor/plugins/canvas_item_editor_plugin.h +++ b/editor/plugins/canvas_item_editor_plugin.h @@ -71,18 +71,21 @@ class CanvasItemEditor : public VBoxContainer { GDCLASS(CanvasItemEditor, VBoxContainer); - EditorNode *editor; - +public: enum Tool { TOOL_SELECT, TOOL_LIST_SELECT, TOOL_MOVE, + TOOL_SCALE, TOOL_ROTATE, TOOL_EDIT_PIVOT, TOOL_PAN, TOOL_MAX }; +private: + EditorNode *editor; + enum MenuOption { SNAP_USE, SNAP_USE_NODE_PARENT, @@ -102,6 +105,7 @@ class CanvasItemEditor : public VBoxContainer { SHOW_GUIDES, SHOW_ORIGIN, SHOW_VIEWPORT, + SHOW_EDIT_LOCKS, LOCK_SELECTED, UNLOCK_SELECTED, GROUP_SELECTED, @@ -188,7 +192,10 @@ class CanvasItemEditor : public VBoxContainer { DRAG_ANCHOR_BOTTOM_RIGHT, DRAG_ANCHOR_BOTTOM_LEFT, DRAG_ANCHOR_ALL, - DRAG_ALL, + DRAG_MOVE, + DRAG_SCALE_X, + DRAG_SCALE_Y, + DRAG_SCALE_BOTH, DRAG_ROTATE, DRAG_PIVOT, DRAG_V_GUIDE, @@ -220,6 +227,7 @@ class CanvasItemEditor : public VBoxContainer { bool show_origin; bool show_viewport; bool show_helpers; + bool show_edit_locks; float zoom; Point2 view_offset; Point2 previous_update_view_offset; @@ -298,17 +306,19 @@ class CanvasItemEditor : public VBoxContainer { List<PoseClipboard> pose_clipboard; ToolButton *select_button; - ToolButton *list_select_button; + ToolButton *move_button; + ToolButton *scale_button; ToolButton *rotate_button; + ToolButton *list_select_button; + ToolButton *pivot_button; + ToolButton *pan_button; + ToolButton *snap_button; MenuButton *snap_config_menu; PopupMenu *smartsnap_config_popup; - ToolButton *pivot_button; - ToolButton *pan_button; - ToolButton *lock_button; ToolButton *unlock_button; @@ -368,7 +378,9 @@ class CanvasItemEditor : public VBoxContainer { void _add_canvas_item(CanvasItem *p_canvas_item); + void _save_canvas_item_ik_chain(const CanvasItem *p_canvas_item, List<float> *p_bones_length, List<Dictionary> *p_bones_state); void _save_canvas_item_state(List<CanvasItem *> p_canvas_items, bool save_bones = false); + void _restore_canvas_item_ik_chain(CanvasItem *p_canvas_item, const List<Dictionary> *p_bones_state); void _restore_canvas_item_state(List<CanvasItem *> p_canvas_items, bool restore_bones = false); void _commit_canvas_item_state(List<CanvasItem *> p_canvas_items, String action_name, bool commit_bones = false); @@ -408,6 +420,7 @@ class CanvasItemEditor : public VBoxContainer { void _draw_guides(); void _draw_focus(); void _draw_grid(); + void _draw_control_helpers(Control *control); void _draw_selection(); void _draw_axis(); void _draw_bones(); @@ -420,6 +433,7 @@ class CanvasItemEditor : public VBoxContainer { bool _gui_input_anchors(const Ref<InputEvent> &p_event); bool _gui_input_move(const Ref<InputEvent> &p_event); bool _gui_input_open_scene_on_double_click(const Ref<InputEvent> &p_event); + bool _gui_input_scale(const Ref<InputEvent> &p_event); bool _gui_input_pivot(const Ref<InputEvent> &p_event); bool _gui_input_resize(const Ref<InputEvent> &p_event); bool _gui_input_rotate(const Ref<InputEvent> &p_event); @@ -528,6 +542,8 @@ public: Control *get_viewport_control() { return viewport; } + Tool get_current_tool() { return tool; } + void set_undo_redo(UndoRedo *p_undo_redo) { undo_redo = p_undo_redo; } void edit(CanvasItem *p_canvas_item); diff --git a/editor/plugins/collision_polygon_editor_plugin.cpp b/editor/plugins/collision_polygon_editor_plugin.cpp index 5109379add..805a7d3835 100644 --- a/editor/plugins/collision_polygon_editor_plugin.cpp +++ b/editor/plugins/collision_polygon_editor_plugin.cpp @@ -31,10 +31,10 @@ #include "collision_polygon_editor_plugin.h" #include "canvas_item_editor_plugin.h" +#include "core/os/file_access.h" +#include "core/os/input.h" +#include "core/os/keyboard.h" #include "editor/editor_settings.h" -#include "os/file_access.h" -#include "os/input.h" -#include "os/keyboard.h" #include "scene/3d/camera.h" #include "spatial_editor_plugin.h" diff --git a/editor/plugins/collision_shape_2d_editor_plugin.cpp b/editor/plugins/collision_shape_2d_editor_plugin.cpp index 9e052bb027..d1a94f5b49 100644 --- a/editor/plugins/collision_shape_2d_editor_plugin.cpp +++ b/editor/plugins/collision_shape_2d_editor_plugin.cpp @@ -323,7 +323,6 @@ bool CollisionShape2DEditor::forward_canvas_gui_input(const Ref<InputEvent> &p_e if (mb.is_valid()) { Vector2 gpoint = mb->get_position(); - Vector2 cpoint = node->get_global_transform().affine_inverse().xform(canvas_item_editor->snap_point(canvas_item_editor->get_canvas_transform().affine_inverse().xform(mb->get_position()))); if (mb->get_button_index() == BUTTON_LEFT) { if (mb->is_pressed()) { @@ -415,7 +414,7 @@ void CollisionShape2DEditor::_get_current_shape_type() { canvas_item_editor->get_viewport_control()->update(); } -void CollisionShape2DEditor::forward_draw_over_viewport(Control *p_overlay) { +void CollisionShape2DEditor::forward_canvas_draw_over_viewport(Control *p_overlay) { if (!node) { return; diff --git a/editor/plugins/collision_shape_2d_editor_plugin.h b/editor/plugins/collision_shape_2d_editor_plugin.h index 10784f1129..fb7b2acb0f 100644 --- a/editor/plugins/collision_shape_2d_editor_plugin.h +++ b/editor/plugins/collision_shape_2d_editor_plugin.h @@ -75,7 +75,7 @@ protected: public: bool forward_canvas_gui_input(const Ref<InputEvent> &p_event); - void forward_draw_over_viewport(Control *p_overlay); + void forward_canvas_draw_over_viewport(Control *p_overlay); void edit(Node *p_node); CollisionShape2DEditor(EditorNode *p_editor); @@ -89,7 +89,7 @@ class CollisionShape2DEditorPlugin : public EditorPlugin { public: virtual bool forward_canvas_gui_input(const Ref<InputEvent> &p_event) { return collision_shape_2d_editor->forward_canvas_gui_input(p_event); } - virtual void forward_draw_over_viewport(Control *p_overlay) { return collision_shape_2d_editor->forward_draw_over_viewport(p_overlay); } + virtual void forward_canvas_draw_over_viewport(Control *p_overlay) { return collision_shape_2d_editor->forward_canvas_draw_over_viewport(p_overlay); } virtual String get_name() const { return "CollisionShape2D"; } bool has_main_screen() const { return false; } diff --git a/editor/plugins/cpu_particles_editor_plugin.cpp b/editor/plugins/cpu_particles_editor_plugin.cpp index b32f927249..8d3ebc5052 100644 --- a/editor/plugins/cpu_particles_editor_plugin.cpp +++ b/editor/plugins/cpu_particles_editor_plugin.cpp @@ -1,4 +1,35 @@ +/*************************************************************************/ +/* cpu_particles_editor_plugin.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + #include "cpu_particles_editor_plugin.h" + #include "editor/plugins/spatial_editor_plugin.h" void CPUParticlesEditor::_node_removed(Node *p_node) { diff --git a/editor/plugins/cpu_particles_editor_plugin.h b/editor/plugins/cpu_particles_editor_plugin.h index f47d17104d..16fb0bab0c 100644 --- a/editor/plugins/cpu_particles_editor_plugin.h +++ b/editor/plugins/cpu_particles_editor_plugin.h @@ -1,3 +1,33 @@ +/*************************************************************************/ +/* cpu_particles_editor_plugin.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + #ifndef CPU_PARTICLES_EDITOR_PLUGIN_H #define CPU_PARTICLES_EDITOR_PLUGIN_H diff --git a/editor/plugins/curve_editor_plugin.cpp b/editor/plugins/curve_editor_plugin.cpp index f5bdf77973..ace3012c10 100644 --- a/editor/plugins/curve_editor_plugin.cpp +++ b/editor/plugins/curve_editor_plugin.cpp @@ -31,9 +31,9 @@ #include "curve_editor_plugin.h" #include "canvas_item_editor_plugin.h" -#include "core_string_names.h" -#include "os/input.h" -#include "os/keyboard.h" +#include "core/core_string_names.h" +#include "core/os/input.h" +#include "core/os/keyboard.h" CurveEditor::CurveEditor() { _selected_point = -1; @@ -205,13 +205,13 @@ void CurveEditor::on_gui_input(const Ref<InputEvent> &p_event) { curve.set_point_left_tangent(_selected_point, tangent); // Note: if a tangent is set to linear, it shouldn't be linked to the other - if (link && _selected_point != curve.get_point_count() - 1 && !curve.get_point_right_mode(_selected_point) != Curve::TANGENT_FREE) + if (link && _selected_point != (curve.get_point_count() - 1) && curve.get_point_right_mode(_selected_point) != Curve::TANGENT_LINEAR) curve.set_point_right_tangent(_selected_point, tangent); } else { curve.set_point_right_tangent(_selected_point, tangent); - if (link && _selected_point != 0 && !curve.get_point_left_mode(_selected_point) != Curve::TANGENT_FREE) + if (link && _selected_point != 0 && curve.get_point_left_mode(_selected_point) != Curve::TANGENT_LINEAR) curve.set_point_left_tangent(_selected_point, tangent); } } @@ -782,12 +782,13 @@ bool CurvePreviewGenerator::handles(const String &p_type) const { return p_type == "Curve"; } -Ref<Texture> CurvePreviewGenerator::generate(const Ref<Resource> &p_from) { +Ref<Texture> CurvePreviewGenerator::generate(const Ref<Resource> &p_from, const Size2 p_size) const { Ref<Curve> curve_ref = p_from; ERR_FAIL_COND_V(curve_ref.is_null(), Ref<Texture>()); Curve &curve = **curve_ref; + // FIXME: Should be ported to use p_size as done in b2633a97 int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size"); thumbnail_size *= EDSCALE; Ref<Image> img_ref; diff --git a/editor/plugins/curve_editor_plugin.h b/editor/plugins/curve_editor_plugin.h index 255f359ed2..fa0b92e353 100644 --- a/editor/plugins/curve_editor_plugin.h +++ b/editor/plugins/curve_editor_plugin.h @@ -131,14 +131,14 @@ class CurveEditorPlugin : public EditorPlugin { public: CurveEditorPlugin(EditorNode *p_node); - String get_name() const { return "Curve"; } + virtual String get_name() const { return "Curve"; } }; class CurvePreviewGenerator : public EditorResourcePreviewGenerator { GDCLASS(CurvePreviewGenerator, EditorResourcePreviewGenerator) public: - bool handles(const String &p_type) const; - Ref<Texture> generate(const Ref<Resource> &p_from); + virtual bool handles(const String &p_type) const; + virtual Ref<Texture> generate(const Ref<Resource> &p_from, const Size2 p_size) const; }; #endif // CURVE_EDITOR_PLUGIN_H diff --git a/editor/plugins/editor_preview_plugins.cpp b/editor/plugins/editor_preview_plugins.cpp index 9acbceec92..7f83865777 100644 --- a/editor/plugins/editor_preview_plugins.cpp +++ b/editor/plugins/editor_preview_plugins.cpp @@ -30,12 +30,12 @@ #include "editor_preview_plugins.h" +#include "core/io/file_access_memory.h" +#include "core/io/resource_loader.h" +#include "core/os/os.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" -#include "io/file_access_memory.h" -#include "io/resource_loader.h" -#include "os/os.h" #include "scene/resources/bit_mask.h" #include "scene/resources/dynamic_font.h" #include "scene/resources/material.h" @@ -78,7 +78,11 @@ bool EditorTexturePreviewPlugin::handles(const String &p_type) const { return ClassDB::is_parent_class(p_type, "Texture"); } -Ref<Texture> EditorTexturePreviewPlugin::generate(const RES &p_from) const { +bool EditorTexturePreviewPlugin::should_generate_small_preview() const { + return true; +} + +Ref<Texture> EditorTexturePreviewPlugin::generate(const RES &p_from, const Size2 p_size) const { Ref<Image> img; Ref<AtlasTexture> atex = p_from; @@ -100,8 +104,6 @@ Ref<Texture> EditorTexturePreviewPlugin::generate(const RES &p_from) const { img = img->duplicate(); img->clear_mipmaps(); - int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size"); - thumbnail_size *= EDSCALE; if (img->is_compressed()) { if (img->decompress() != OK) return Ref<Texture>(); @@ -109,22 +111,15 @@ Ref<Texture> EditorTexturePreviewPlugin::generate(const RES &p_from) const { img->convert(Image::FORMAT_RGBA8); } - int width, height; - if (img->get_width() > thumbnail_size && img->get_width() >= img->get_height()) { - - width = thumbnail_size; - height = img->get_height() * thumbnail_size / img->get_width(); - } else if (img->get_height() > thumbnail_size && img->get_height() >= img->get_width()) { - - height = thumbnail_size; - width = img->get_width() * thumbnail_size / img->get_height(); - } else { - - width = img->get_width(); - height = img->get_height(); + Vector2 new_size = img->get_size(); + if (new_size.x > p_size.x) { + new_size = Vector2(p_size.x, new_size.y * p_size.x / new_size.x); } + if (new_size.y > p_size.y) { + new_size = Vector2(new_size.x * p_size.y / new_size.y, p_size.y); + } + img->resize(new_size.x, new_size.y, Image::INTERPOLATE_CUBIC); - img->resize(width, height); post_process_preview(img); Ref<ImageTexture> ptex = Ref<ImageTexture>(memnew(ImageTexture)); @@ -143,7 +138,7 @@ bool EditorImagePreviewPlugin::handles(const String &p_type) const { return p_type == "Image"; } -Ref<Texture> EditorImagePreviewPlugin::generate(const RES &p_from) const { +Ref<Texture> EditorImagePreviewPlugin::generate(const RES &p_from, const Size2 p_size) const { Ref<Image> img = p_from; @@ -153,8 +148,6 @@ Ref<Texture> EditorImagePreviewPlugin::generate(const RES &p_from) const { img = img->duplicate(); img->clear_mipmaps(); - int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size"); - thumbnail_size *= EDSCALE; if (img->is_compressed()) { if (img->decompress() != OK) return Ref<Image>(); @@ -162,22 +155,15 @@ Ref<Texture> EditorImagePreviewPlugin::generate(const RES &p_from) const { img->convert(Image::FORMAT_RGBA8); } - int width, height; - if (img->get_width() > thumbnail_size && img->get_width() >= img->get_height()) { - - width = thumbnail_size; - height = img->get_height() * thumbnail_size / img->get_width(); - } else if (img->get_height() > thumbnail_size && img->get_height() >= img->get_width()) { - - height = thumbnail_size; - width = img->get_width() * thumbnail_size / img->get_height(); - } else { - - width = img->get_width(); - height = img->get_height(); + Vector2 new_size = img->get_size(); + if (new_size.x > p_size.x) { + new_size = Vector2(p_size.x, new_size.y * p_size.x / new_size.x); + } + if (new_size.y > p_size.y) { + new_size = Vector2(new_size.x * p_size.y / new_size.y, p_size.y); } + img->resize(new_size.x, new_size.y, Image::INTERPOLATE_CUBIC); - img->resize(width, height); post_process_preview(img); Ref<ImageTexture> ptex; @@ -190,6 +176,9 @@ Ref<Texture> EditorImagePreviewPlugin::generate(const RES &p_from) const { EditorImagePreviewPlugin::EditorImagePreviewPlugin() { } +bool EditorImagePreviewPlugin::should_generate_small_preview() const { + return true; +} //////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////// bool EditorBitmapPreviewPlugin::handles(const String &p_type) const { @@ -197,7 +186,7 @@ bool EditorBitmapPreviewPlugin::handles(const String &p_type) const { return ClassDB::is_parent_class(p_type, "BitMap"); } -Ref<Texture> EditorBitmapPreviewPlugin::generate(const RES &p_from) const { +Ref<Texture> EditorBitmapPreviewPlugin::generate(const RES &p_from, const Size2 p_size) const { Ref<BitMap> bm = p_from; @@ -227,8 +216,6 @@ Ref<Texture> EditorBitmapPreviewPlugin::generate(const RES &p_from) const { img.instance(); img->create(bm->get_size().width, bm->get_size().height, 0, Image::FORMAT_L8, data); - int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size"); - thumbnail_size *= EDSCALE; if (img->is_compressed()) { if (img->decompress() != OK) return Ref<Texture>(); @@ -236,22 +223,15 @@ Ref<Texture> EditorBitmapPreviewPlugin::generate(const RES &p_from) const { img->convert(Image::FORMAT_RGBA8); } - int width, height; - if (img->get_width() > thumbnail_size && img->get_width() >= img->get_height()) { - - width = thumbnail_size; - height = img->get_height() * thumbnail_size / img->get_width(); - } else if (img->get_height() > thumbnail_size && img->get_height() >= img->get_width()) { - - height = thumbnail_size; - width = img->get_width() * thumbnail_size / img->get_height(); - } else { - - width = img->get_width(); - height = img->get_height(); + Vector2 new_size = img->get_size(); + if (new_size.x > p_size.x) { + new_size = Vector2(p_size.x, new_size.y * p_size.x / new_size.x); + } + if (new_size.y > p_size.y) { + new_size = Vector2(new_size.x * p_size.y / new_size.y, p_size.y); } + img->resize(new_size.x, new_size.y, Image::INTERPOLATE_CUBIC); - img->resize(width, height); post_process_preview(img); Ref<ImageTexture> ptex = Ref<ImageTexture>(memnew(ImageTexture)); @@ -260,6 +240,10 @@ Ref<Texture> EditorBitmapPreviewPlugin::generate(const RES &p_from) const { return ptex; } +bool EditorBitmapPreviewPlugin::should_generate_small_preview() const { + return true; +} + EditorBitmapPreviewPlugin::EditorBitmapPreviewPlugin() { } @@ -269,12 +253,12 @@ bool EditorPackedScenePreviewPlugin::handles(const String &p_type) const { return ClassDB::is_parent_class(p_type, "PackedScene"); } -Ref<Texture> EditorPackedScenePreviewPlugin::generate(const RES &p_from) const { +Ref<Texture> EditorPackedScenePreviewPlugin::generate(const RES &p_from, const Size2 p_size) const { - return generate_from_path(p_from->get_path()); + return generate_from_path(p_from->get_path(), p_size); } -Ref<Texture> EditorPackedScenePreviewPlugin::generate_from_path(const String &p_path) const { +Ref<Texture> EditorPackedScenePreviewPlugin::generate_from_path(const String &p_path, const Size2 p_size) const { String temp_path = EditorSettings::get_singleton()->get_cache_dir(); String cache_base = ProjectSettings::get_singleton()->globalize_path(p_path).md5_text(); @@ -323,7 +307,11 @@ bool EditorMaterialPreviewPlugin::handles(const String &p_type) const { return ClassDB::is_parent_class(p_type, "Material"); //any material } -Ref<Texture> EditorMaterialPreviewPlugin::generate(const RES &p_from) const { +bool EditorMaterialPreviewPlugin::should_generate_small_preview() const { + return true; +} + +Ref<Texture> EditorMaterialPreviewPlugin::generate(const RES &p_from, const Size2 p_size) const { Ref<Material> material = p_from; ERR_FAIL_COND_V(material.is_null(), Ref<Texture>()); @@ -346,10 +334,9 @@ Ref<Texture> EditorMaterialPreviewPlugin::generate(const RES &p_from) const { ERR_FAIL_COND_V(!img.is_valid(), Ref<ImageTexture>()); - int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size"); - thumbnail_size *= EDSCALE; img->convert(Image::FORMAT_RGBA8); - img->resize(thumbnail_size, thumbnail_size); + int thumbnail_size = MAX(p_size.x, p_size.y); + img->resize(thumbnail_size, thumbnail_size, Image::INTERPOLATE_CUBIC); post_process_preview(img); Ref<ImageTexture> ptex = Ref<ImageTexture>(memnew(ImageTexture)); ptex->create_from_image(img, 0); @@ -490,7 +477,7 @@ bool EditorScriptPreviewPlugin::handles(const String &p_type) const { return ClassDB::is_parent_class(p_type, "Script"); } -Ref<Texture> EditorScriptPreviewPlugin::generate(const RES &p_from) const { +Ref<Texture> EditorScriptPreviewPlugin::generate(const RES &p_from, const Size2 p_size) const { Ref<Script> scr = p_from; if (scr.is_null()) @@ -512,10 +499,9 @@ Ref<Texture> EditorScriptPreviewPlugin::generate(const RES &p_from) const { int line = 0; int col = 0; - int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size"); - thumbnail_size *= EDSCALE; Ref<Image> img; img.instance(); + int thumbnail_size = MAX(p_size.x, p_size.y); img->create(thumbnail_size, thumbnail_size, 0, Image::FORMAT_RGBA8); Color bg_color = EditorSettings::get_singleton()->get("text_editor/highlighting/background_color"); @@ -613,16 +599,15 @@ bool EditorAudioStreamPreviewPlugin::handles(const String &p_type) const { return ClassDB::is_parent_class(p_type, "AudioStream"); } -Ref<Texture> EditorAudioStreamPreviewPlugin::generate(const RES &p_from) const { +Ref<Texture> EditorAudioStreamPreviewPlugin::generate(const RES &p_from, const Size2 p_size) const { Ref<AudioStream> stream = p_from; ERR_FAIL_COND_V(stream.is_null(), Ref<Texture>()); - int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size"); - thumbnail_size *= EDSCALE; PoolVector<uint8_t> img; - int w = thumbnail_size; - int h = thumbnail_size; + + int w = p_size.x; + int h = p_size.y; img.resize(w * h * 3); PoolVector<uint8_t>::Write imgdata = img.write(); @@ -711,7 +696,7 @@ bool EditorMeshPreviewPlugin::handles(const String &p_type) const { return ClassDB::is_parent_class(p_type, "Mesh"); //any Mesh } -Ref<Texture> EditorMeshPreviewPlugin::generate(const RES &p_from) const { +Ref<Texture> EditorMeshPreviewPlugin::generate(const RES &p_from, const Size2 p_size) const { Ref<Mesh> mesh = p_from; ERR_FAIL_COND_V(mesh.is_null(), Ref<Texture>()); @@ -749,10 +734,17 @@ Ref<Texture> EditorMeshPreviewPlugin::generate(const RES &p_from) const { VS::get_singleton()->instance_set_base(mesh_instance, RID()); - int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size"); - thumbnail_size *= EDSCALE; img->convert(Image::FORMAT_RGBA8); - img->resize(thumbnail_size, thumbnail_size); + + Vector2 new_size = img->get_size(); + if (new_size.x > p_size.x) { + new_size = Vector2(p_size.x, new_size.y * p_size.x / new_size.x); + } + if (new_size.y > p_size.y) { + new_size = Vector2(new_size.x * p_size.y / new_size.y, p_size.y); + } + img->resize(new_size.x, new_size.y, Image::INTERPOLATE_CUBIC); + post_process_preview(img); Ref<ImageTexture> ptex = Ref<ImageTexture>(memnew(ImageTexture)); @@ -825,15 +817,12 @@ bool EditorFontPreviewPlugin::handles(const String &p_type) const { return ClassDB::is_parent_class(p_type, "DynamicFontData"); } -Ref<Texture> EditorFontPreviewPlugin::generate_from_path(const String &p_path) const { +Ref<Texture> EditorFontPreviewPlugin::generate_from_path(const String &p_path, const Size2 p_size) const { Ref<DynamicFontData> SampledFont; SampledFont.instance(); SampledFont->set_font_path(p_path); - int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size"); - thumbnail_size *= EDSCALE; - Ref<DynamicFont> sampled_font; sampled_font.instance(); sampled_font->set_size(50); @@ -864,7 +853,15 @@ Ref<Texture> EditorFontPreviewPlugin::generate_from_path(const String &p_path) c ERR_FAIL_COND_V(img.is_null(), Ref<ImageTexture>()); img->convert(Image::FORMAT_RGBA8); - img->resize(thumbnail_size, thumbnail_size); + + Vector2 new_size = img->get_size(); + if (new_size.x > p_size.x) { + new_size = Vector2(p_size.x, new_size.y * p_size.x / new_size.x); + } + if (new_size.y > p_size.y) { + new_size = Vector2(new_size.x * p_size.y / new_size.y, p_size.y); + } + img->resize(new_size.x, new_size.y, Image::INTERPOLATE_CUBIC); post_process_preview(img); @@ -874,9 +871,9 @@ Ref<Texture> EditorFontPreviewPlugin::generate_from_path(const String &p_path) c return ptex; } -Ref<Texture> EditorFontPreviewPlugin::generate(const RES &p_from) const { +Ref<Texture> EditorFontPreviewPlugin::generate(const RES &p_from, const Size2 p_size) const { - return generate_from_path(p_from->get_path()); + return generate_from_path(p_from->get_path(), p_size); } EditorFontPreviewPlugin::EditorFontPreviewPlugin() { diff --git a/editor/plugins/editor_preview_plugins.h b/editor/plugins/editor_preview_plugins.h index 8bd7943383..ed5d2a3ecd 100644 --- a/editor/plugins/editor_preview_plugins.h +++ b/editor/plugins/editor_preview_plugins.h @@ -39,7 +39,8 @@ class EditorTexturePreviewPlugin : public EditorResourcePreviewGenerator { GDCLASS(EditorTexturePreviewPlugin, EditorResourcePreviewGenerator) public: virtual bool handles(const String &p_type) const; - virtual Ref<Texture> generate(const RES &p_from) const; + virtual bool should_generate_small_preview() const; + virtual Ref<Texture> generate(const RES &p_from, const Size2 p_size) const; EditorTexturePreviewPlugin(); }; @@ -48,7 +49,8 @@ class EditorImagePreviewPlugin : public EditorResourcePreviewGenerator { GDCLASS(EditorImagePreviewPlugin, EditorResourcePreviewGenerator) public: virtual bool handles(const String &p_type) const; - virtual Ref<Texture> generate(const RES &p_from) const; + virtual bool should_generate_small_preview() const; + virtual Ref<Texture> generate(const RES &p_from, const Size2 p_size) const; EditorImagePreviewPlugin(); }; @@ -57,7 +59,8 @@ class EditorBitmapPreviewPlugin : public EditorResourcePreviewGenerator { GDCLASS(EditorBitmapPreviewPlugin, EditorResourcePreviewGenerator) public: virtual bool handles(const String &p_type) const; - virtual Ref<Texture> generate(const RES &p_from) const; + virtual bool should_generate_small_preview() const; + virtual Ref<Texture> generate(const RES &p_from, const Size2 p_size) const; EditorBitmapPreviewPlugin(); }; @@ -66,8 +69,8 @@ class EditorPackedScenePreviewPlugin : public EditorResourcePreviewGenerator { public: virtual bool handles(const String &p_type) const; - virtual Ref<Texture> generate(const RES &p_from) const; - virtual Ref<Texture> generate_from_path(const String &p_path) const; + virtual Ref<Texture> generate(const RES &p_from, const Size2 p_size) const; + virtual Ref<Texture> generate_from_path(const String &p_path, const Size2 p_size) const; EditorPackedScenePreviewPlugin(); }; @@ -95,7 +98,8 @@ protected: public: virtual bool handles(const String &p_type) const; - virtual Ref<Texture> generate(const RES &p_from) const; + virtual bool should_generate_small_preview() const; + virtual Ref<Texture> generate(const RES &p_from, const Size2 p_size) const; EditorMaterialPreviewPlugin(); ~EditorMaterialPreviewPlugin(); @@ -104,7 +108,7 @@ public: class EditorScriptPreviewPlugin : public EditorResourcePreviewGenerator { public: virtual bool handles(const String &p_type) const; - virtual Ref<Texture> generate(const RES &p_from) const; + virtual Ref<Texture> generate(const RES &p_from, const Size2 p_size) const; EditorScriptPreviewPlugin(); }; @@ -112,7 +116,7 @@ public: class EditorAudioStreamPreviewPlugin : public EditorResourcePreviewGenerator { public: virtual bool handles(const String &p_type) const; - virtual Ref<Texture> generate(const RES &p_from) const; + virtual Ref<Texture> generate(const RES &p_from, const Size2 p_size) const; EditorAudioStreamPreviewPlugin(); }; @@ -139,7 +143,7 @@ protected: public: virtual bool handles(const String &p_type) const; - virtual Ref<Texture> generate(const RES &p_from) const; + virtual Ref<Texture> generate(const RES &p_from, const Size2 p_size) const; EditorMeshPreviewPlugin(); ~EditorMeshPreviewPlugin(); @@ -162,8 +166,8 @@ protected: public: virtual bool handles(const String &p_type) const; - virtual Ref<Texture> generate(const RES &p_from) const; - virtual Ref<Texture> generate_from_path(const String &p_path) const; + virtual Ref<Texture> generate(const RES &p_from, const Size2 p_size) const; + virtual Ref<Texture> generate_from_path(const String &p_path, const Size2 p_size) const; EditorFontPreviewPlugin(); ~EditorFontPreviewPlugin(); diff --git a/editor/plugins/item_list_editor_plugin.cpp b/editor/plugins/item_list_editor_plugin.cpp index f75fb0d109..186e66f980 100644 --- a/editor/plugins/item_list_editor_plugin.cpp +++ b/editor/plugins/item_list_editor_plugin.cpp @@ -30,7 +30,7 @@ #include "item_list_editor_plugin.h" -#include "io/resource_loader.h" +#include "core/io/resource_loader.h" bool ItemListPlugin::_set(const StringName &p_name, const Variant &p_value) { @@ -278,25 +278,27 @@ void ItemListEditor::_add_pressed() { void ItemListEditor::_delete_pressed() { - TreeItem *ti = tree->get_selected(); - - if (!ti) + if (selected_idx == -1) return; - if (ti->get_parent() != tree->get_root()) + String current_selected = (String)property_editor->get_selected_path(); + + if (current_selected == "") return; - int idx = ti->get_text(0).to_int(); + // FIXME: Currently relying on selecting a *property* to derive what item to delete + // e.g. you select "1/enabled" to delete item 1. + // This should be fixed so that you can delete by selecting the item section header, + // or a delete button on that header. - if (selected_idx == -1) - return; + int idx = current_selected.get_slice("/", 0).to_int(); item_plugins[selected_idx]->erase(idx); } void ItemListEditor::_edit_items() { - dialog->popup_centered(Vector2(300, 400)); + dialog->popup_centered(Vector2(300, 400) * EDSCALE); } void ItemListEditor::edit(Node *p_item_list) { @@ -315,10 +317,7 @@ void ItemListEditor::edit(Node *p_item_list) { item_plugins[i]->set_object(p_item_list); property_editor->edit(item_plugins[i]); - if (has_icon(item_list->get_class(), "EditorIcons")) - toolbar_button->set_icon(get_icon(item_list->get_class(), "EditorIcons")); - else - toolbar_button->set_icon(Ref<Texture>()); + toolbar_button->set_icon(EditorNode::get_singleton()->get_object_icon(item_list, "")); selected_idx = i; return; @@ -382,13 +381,9 @@ ItemListEditor::ItemListEditor() { hbc->add_child(del_button); del_button->connect("pressed", this, "_delete_button"); - property_editor = memnew(PropertyEditor); - property_editor->hide_top_label(); - property_editor->set_subsection_selectable(true); + property_editor = memnew(EditorInspector); vbc->add_child(property_editor); property_editor->set_v_size_flags(SIZE_EXPAND_FILL); - - tree = property_editor->get_property_tree(); } ItemListEditor::~ItemListEditor() { diff --git a/editor/plugins/item_list_editor_plugin.h b/editor/plugins/item_list_editor_plugin.h index d6a071b9b9..3dc3775f83 100644 --- a/editor/plugins/item_list_editor_plugin.h +++ b/editor/plugins/item_list_editor_plugin.h @@ -32,9 +32,9 @@ #define ITEM_LIST_EDITOR_PLUGIN_H #include "canvas_item_editor_plugin.h" +#include "editor/editor_inspector.h" #include "editor/editor_node.h" #include "editor/editor_plugin.h" - #include "scene/gui/menu_button.h" #include "scene/gui/option_button.h" #include "scene/gui/popup_menu.h" @@ -210,7 +210,7 @@ class ItemListEditor : public HBoxContainer { ToolButton *toolbar_button; AcceptDialog *dialog; - PropertyEditor *property_editor; + EditorInspector *property_editor; Tree *tree; Button *add_button; Button *del_button; diff --git a/editor/plugins/light_occluder_2d_editor_plugin.cpp b/editor/plugins/light_occluder_2d_editor_plugin.cpp index 3351e5918f..2f2e1dae81 100644 --- a/editor/plugins/light_occluder_2d_editor_plugin.cpp +++ b/editor/plugins/light_occluder_2d_editor_plugin.cpp @@ -31,8 +31,8 @@ #include "light_occluder_2d_editor_plugin.h" #include "canvas_item_editor_plugin.h" +#include "core/os/file_access.h" #include "editor/editor_settings.h" -#include "os/file_access.h" void LightOccluder2DEditor::_notification(int p_what) { @@ -319,13 +319,11 @@ bool LightOccluder2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) { return false; } -void LightOccluder2DEditor::forward_draw_over_viewport(Control *p_overlay) { +void LightOccluder2DEditor::forward_canvas_draw_over_viewport(Control *p_overlay) { if (!node || !node->get_occluder_polygon().is_valid()) return; - Control *vpc = canvas_item_editor->get_viewport_control(); - Vector<Vector2> poly; if (wip_active) @@ -353,9 +351,9 @@ void LightOccluder2DEditor::forward_draw_over_viewport(Control *p_overlay) { if (i == poly.size() - 1 && (!node->get_occluder_polygon()->is_closed() || wip_active)) { } else { - vpc->draw_line(point, next_point, col, 2); + p_overlay->draw_line(point, next_point, col, 2); } - vpc->draw_texture(handle, point - handle->get_size() * 0.5); + p_overlay->draw_texture(handle, point - handle->get_size() * 0.5); } } diff --git a/editor/plugins/light_occluder_2d_editor_plugin.h b/editor/plugins/light_occluder_2d_editor_plugin.h index 39de8b1020..a1962892ee 100644 --- a/editor/plugins/light_occluder_2d_editor_plugin.h +++ b/editor/plugins/light_occluder_2d_editor_plugin.h @@ -83,7 +83,7 @@ protected: public: Vector2 snap_point(const Vector2 &p_point) const; - void forward_draw_over_viewport(Control *p_overlay); + void forward_canvas_draw_over_viewport(Control *p_overlay); bool forward_gui_input(const Ref<InputEvent> &p_event); void edit(Node *p_collision_polygon); LightOccluder2DEditor(EditorNode *p_editor); @@ -98,7 +98,7 @@ class LightOccluder2DEditorPlugin : public EditorPlugin { public: virtual bool forward_canvas_gui_input(const Ref<InputEvent> &p_event) { return light_occluder_editor->forward_gui_input(p_event); } - virtual void forward_draw_over_viewport(Control *p_overlay) { return light_occluder_editor->forward_draw_over_viewport(p_overlay); } + virtual void forward_canvas_draw_over_viewport(Control *p_overlay) { return light_occluder_editor->forward_canvas_draw_over_viewport(p_overlay); } virtual String get_name() const { return "LightOccluder2D"; } bool has_main_screen() const { return false; } diff --git a/editor/plugins/material_editor_plugin.cpp b/editor/plugins/material_editor_plugin.cpp index 27a16fd3dd..5e59a73061 100644 --- a/editor/plugins/material_editor_plugin.cpp +++ b/editor/plugins/material_editor_plugin.cpp @@ -28,397 +28,9 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -// FIXME: Disabled as (according to reduz) users were complaining that it gets in the way -// Waiting for PropertyEditor rewrite (planned for 3.1) to be refactored. - #include "material_editor_plugin.h" -#include "scene/3d/particles.h" - -#if 0 - -#include "scene/main/viewport.h" - -void MaterialEditor::_gui_input(InputEvent p_event) { - - -} - -void MaterialEditor::_notification(int p_what) { - - if (p_what==NOTIFICATION_PHYSICS_PROCESS) { - - } - - - if (p_what==NOTIFICATION_READY) { - - //get_scene()->connect("node_removed",this,"_node_removed"); - - if (first_enter) { - //it's in propertyeditor so.. could be moved around - - light_1_switch->set_normal_texture(get_icon("MaterialPreviewLight1","EditorIcons")); - light_1_switch->set_pressed_texture(get_icon("MaterialPreviewLight1Off","EditorIcons")); - light_2_switch->set_normal_texture(get_icon("MaterialPreviewLight2","EditorIcons")); - light_2_switch->set_pressed_texture(get_icon("MaterialPreviewLight2Off","EditorIcons")); - - sphere_switch->set_normal_texture(get_icon("MaterialPreviewSphereOff","EditorIcons")); - sphere_switch->set_pressed_texture(get_icon("MaterialPreviewSphere","EditorIcons")); - box_switch->set_normal_texture(get_icon("MaterialPreviewCubeOff","EditorIcons")); - box_switch->set_pressed_texture(get_icon("MaterialPreviewCube","EditorIcons")); - - first_enter=false; - } - - } - - if (p_what==NOTIFICATION_DRAW) { - - - Ref<Texture> checkerboard = get_icon("Checkerboard","EditorIcons"); - Size2 size = get_size(); - - draw_texture_rect(checkerboard,Rect2(Point2(),size),true); - - } -} - - - -void MaterialEditor::edit(Ref<Material> p_material) { - - material=p_material; - - if (!material.is_null()) { - sphere_mesh->surface_set_material(0,material); - box_mesh->surface_set_material(0,material); - } else { - - hide(); - } - -} - - -void MaterialEditor::_button_pressed(Node* p_button) { - - if (p_button==light_1_switch) { - light1->set_enabled(!light_1_switch->is_pressed()); - } - - if (p_button==light_2_switch) { - light2->set_enabled(!light_2_switch->is_pressed()); - } - - if (p_button==box_switch) { - box_instance->show(); - sphere_instance->hide(); - box_switch->set_pressed(true); - sphere_switch->set_pressed(false); - } - - if (p_button==sphere_switch) { - box_instance->hide(); - sphere_instance->show(); - box_switch->set_pressed(false); - sphere_switch->set_pressed(true); - } - -} - -void MaterialEditor::_bind_methods() { - - ClassDB::bind_method(D_METHOD("_gui_input"),&MaterialEditor::_gui_input); - ClassDB::bind_method(D_METHOD("_button_pressed"),&MaterialEditor::_button_pressed); - -} - -MaterialEditor::MaterialEditor() { - - viewport = memnew( Viewport ); - Ref<World> world; - world.instance(); - viewport->set_world(world); //use own world - add_child(viewport); - viewport->set_disable_input(true); - - camera = memnew( Camera ); - camera->set_transform(Transform(Matrix3(),Vector3(0,0,3))); - camera->set_perspective(45,0.1,10); - viewport->add_child(camera); - - light1 = memnew( DirectionalLight ); - light1->set_transform(Transform().looking_at(Vector3(-1,-1,-1),Vector3(0,1,0))); - viewport->add_child(light1); - - light2 = memnew( DirectionalLight ); - light2->set_transform(Transform().looking_at(Vector3(0,1,0),Vector3(0,0,1))); - light2->set_color(Light::COLOR_DIFFUSE,Color(0.7,0.7,0.7)); - light2->set_color(Light::COLOR_SPECULAR,Color(0.7,0.7,0.7)); - viewport->add_child(light2); - - sphere_instance = memnew( MeshInstance ); - viewport->add_child(sphere_instance); - - box_instance = memnew( MeshInstance ); - viewport->add_child(box_instance); - - Transform box_xform; - box_xform.basis.rotate(Vector3(1,0,0),Math::deg2rad(25)); - box_xform.basis = box_xform.basis * Matrix3().rotated(Vector3(0,1,0),Math::deg2rad(25)); - box_xform.basis.scale(Vector3(0.8,0.8,0.8)); - box_instance->set_transform(box_xform); - - { - - sphere_mesh.instance(); - - - int lats=32; - int lons=32; - float radius=1.0; - - PoolVector<Vector3> vertices; - PoolVector<Vector3> normals; - PoolVector<Vector2> uvs; - PoolVector<float> tangents; - Matrix3 tt = Matrix3(Vector3(0,1,0),Math_PI*0.5); - - for(int i = 1; i <= lats; i++) { - double lat0 = Math_PI * (-0.5 + (double) (i - 1) / lats); - double z0 = Math::sin(lat0); - double zr0 = Math::cos(lat0); - - double lat1 = Math_PI * (-0.5 + (double) i / lats); - double z1 = Math::sin(lat1); - double zr1 = Math::cos(lat1); - - for(int j = lons; j >= 1; j--) { - - double lng0 = 2 * Math_PI * (double) (j - 1) / lons; - double x0 = Math::cos(lng0); - double y0 = Math::sin(lng0); - - double lng1 = 2 * Math_PI * (double) (j) / lons; - double x1 = Math::cos(lng1); - double y1 = Math::sin(lng1); - - - Vector3 v[4]={ - Vector3(x1 * zr0, z0, y1 *zr0), - Vector3(x1 * zr1, z1, y1 *zr1), - Vector3(x0 * zr1, z1, y0 *zr1), - Vector3(x0 * zr0, z0, y0 *zr0) - }; - -#define ADD_POINT(m_idx) \ - normals.push_back(v[m_idx]); \ - vertices.push_back(v[m_idx] * radius); \ - { \ - Vector2 uv(Math::atan2(v[m_idx].x, v[m_idx].z), Math::atan2(-v[m_idx].y, v[m_idx].z)); \ - uv /= Math_PI; \ - uv *= 4.0; \ - uv = uv * 0.5 + Vector2(0.5, 0.5); \ - uvs.push_back(uv); \ - } \ - { \ - Vector3 t = tt.xform(v[m_idx]); \ - tangents.push_back(t.x); \ - tangents.push_back(t.y); \ - tangents.push_back(t.z); \ - tangents.push_back(1.0); \ - } - - - - ADD_POINT(0); - ADD_POINT(1); - ADD_POINT(2); - - ADD_POINT(2); - ADD_POINT(3); - ADD_POINT(0); - } - } - - Array arr; - arr.resize(VS::ARRAY_MAX); - arr[VS::ARRAY_VERTEX]=vertices; - arr[VS::ARRAY_NORMAL]=normals; - arr[VS::ARRAY_TANGENT]=tangents; - arr[VS::ARRAY_TEX_UV]=uvs; - - sphere_mesh->add_surface(Mesh::PRIMITIVE_TRIANGLES,arr); - - sphere_instance->set_mesh(sphere_mesh); - - } - { - - - box_mesh.instance(); - - PoolVector<Vector3> vertices; - PoolVector<Vector3> normals; - PoolVector<float> tangents; - PoolVector<Vector3> uvs; - - int vtx_idx=0; -#define ADD_VTX(m_idx) \ - ; \ - vertices.push_back(face_points[m_idx]); \ - normals.push_back(normal_points[m_idx]); \ - tangents.push_back(normal_points[m_idx][1]); \ - tangents.push_back(normal_points[m_idx][2]); \ - tangents.push_back(normal_points[m_idx][0]); \ - tangents.push_back(1.0); \ - uvs.push_back(Vector3(uv_points[m_idx * 2 + 0], uv_points[m_idx * 2 + 1], 0)); \ - vtx_idx++;\ - - for (int i=0;i<6;i++) { - - - Vector3 face_points[4]; - Vector3 normal_points[4]; - float uv_points[8]={0,0,0,1,1,1,1,0}; - - for (int j=0;j<4;j++) { - - float v[3]; - v[0]=1.0; - v[1]=1-2*((j>>1)&1); - v[2]=v[1]*(1-2*(j&1)); - - for (int k=0;k<3;k++) { - - if (i<3) - face_points[j][(i+k)%3]=v[k]*(i>=3?-1:1); - else - face_points[3-j][(i+k)%3]=v[k]*(i>=3?-1:1); - } - normal_points[j]=Vector3(); - normal_points[j][i%3]=(i>=3?-1:1); - } - - //tri 1 - ADD_VTX(0); - ADD_VTX(1); - ADD_VTX(2); - //tri 2 - ADD_VTX(2); - ADD_VTX(3); - ADD_VTX(0); - - } - - - - Array d; - d.resize(VS::ARRAY_MAX); - d[VisualServer::ARRAY_NORMAL]= normals ; - d[VisualServer::ARRAY_TANGENT]= tangents ; - d[VisualServer::ARRAY_TEX_UV]= uvs ; - d[VisualServer::ARRAY_VERTEX]= vertices ; - - PoolVector<int> indices; - indices.resize(vertices.size()); - for(int i=0;i<vertices.size();i++) - indices.set(i,i); - d[VisualServer::ARRAY_INDEX]=indices; - - box_mesh->add_surface(Mesh::PRIMITIVE_TRIANGLES,d); - box_instance->set_mesh(box_mesh); - box_instance->hide(); - - - - } - - set_custom_minimum_size(Size2(1,150)*EDSCALE); - - HBoxContainer *hb = memnew( HBoxContainer ); - add_child(hb); - hb->set_anchors_and_margins_preset(Control::PRESET_WIDE, Control::PRESET_MODE_MINSIZE, 2); - - VBoxContainer *vb_shape = memnew( VBoxContainer ); - hb->add_child(vb_shape); - - sphere_switch = memnew( TextureButton ); - sphere_switch->set_toggle_mode(true); - sphere_switch->set_pressed(true); - vb_shape->add_child(sphere_switch); - sphere_switch->connect("pressed",this,"_button_pressed",varray(sphere_switch)); - - box_switch = memnew( TextureButton ); - box_switch->set_toggle_mode(true); - box_switch->set_pressed(false); - vb_shape->add_child(box_switch); - box_switch->connect("pressed",this,"_button_pressed",varray(box_switch)); - - hb->add_spacer(); - - VBoxContainer *vb_light = memnew( VBoxContainer ); - hb->add_child(vb_light); - - light_1_switch = memnew( TextureButton ); - light_1_switch->set_toggle_mode(true); - vb_light->add_child(light_1_switch); - light_1_switch->connect("pressed",this,"_button_pressed",varray(light_1_switch)); - - light_2_switch = memnew( TextureButton ); - light_2_switch->set_toggle_mode(true); - vb_light->add_child(light_2_switch); - light_2_switch->connect("pressed",this,"_button_pressed",varray(light_2_switch)); - - first_enter=true; - -} - - -void MaterialEditorPlugin::edit(Object *p_object) { - - Material * s = Object::cast_to<Material>(p_object); - if (!s) - return; - - material_editor->edit(Ref<Material>(s)); -} - -bool MaterialEditorPlugin::handles(Object *p_object) const { - - return p_object->is_type("Material"); -} - -void MaterialEditorPlugin::make_visible(bool p_visible) { - - if (p_visible) { - material_editor->show(); - //material_editor->set_process(true); - } else { - - material_editor->hide(); - //material_editor->set_process(false); - } - -} - -MaterialEditorPlugin::MaterialEditorPlugin(EditorNode *p_node) { - - editor=p_node; - material_editor = memnew( MaterialEditor ); - add_control_to_container(CONTAINER_PROPERTY_EDITOR_BOTTOM,material_editor); - material_editor->hide(); - - - -} - - -MaterialEditorPlugin::~MaterialEditorPlugin() -{ -} -#endif +#include "scene/resources/particles_material.h" String SpatialMaterialConversionPlugin::converts_to() const { @@ -429,7 +41,7 @@ bool SpatialMaterialConversionPlugin::handles(const Ref<Resource> &p_resource) c Ref<SpatialMaterial> mat = p_resource; return mat.is_valid(); } -Ref<Resource> SpatialMaterialConversionPlugin::convert(const Ref<Resource> &p_resource) { +Ref<Resource> SpatialMaterialConversionPlugin::convert(const Ref<Resource> &p_resource) const { Ref<SpatialMaterial> mat = p_resource; ERR_FAIL_COND_V(!mat.is_valid(), Ref<Resource>()); @@ -475,7 +87,7 @@ bool ParticlesMaterialConversionPlugin::handles(const Ref<Resource> &p_resource) Ref<ParticlesMaterial> mat = p_resource; return mat.is_valid(); } -Ref<Resource> ParticlesMaterialConversionPlugin::convert(const Ref<Resource> &p_resource) { +Ref<Resource> ParticlesMaterialConversionPlugin::convert(const Ref<Resource> &p_resource) const { Ref<ParticlesMaterial> mat = p_resource; ERR_FAIL_COND_V(!mat.is_valid(), Ref<Resource>()); @@ -513,7 +125,7 @@ bool CanvasItemMaterialConversionPlugin::handles(const Ref<Resource> &p_resource Ref<CanvasItemMaterial> mat = p_resource; return mat.is_valid(); } -Ref<Resource> CanvasItemMaterialConversionPlugin::convert(const Ref<Resource> &p_resource) { +Ref<Resource> CanvasItemMaterialConversionPlugin::convert(const Ref<Resource> &p_resource) const { Ref<CanvasItemMaterial> mat = p_resource; ERR_FAIL_COND_V(!mat.is_valid(), Ref<Resource>()); diff --git a/editor/plugins/material_editor_plugin.h b/editor/plugins/material_editor_plugin.h index 80a5c535b8..c06d95e700 100644 --- a/editor/plugins/material_editor_plugin.h +++ b/editor/plugins/material_editor_plugin.h @@ -32,84 +32,13 @@ #define MATERIAL_EDITOR_PLUGIN_H #include "editor/property_editor.h" -// FIXME: Disabled as (according to reduz) users were complaining that it gets in the way -// Waiting for PropertyEditor rewrite (planned for 3.1) to be refactored. -#if 0 - -#include "editor/editor_node.h" -#include "editor/editor_plugin.h" -#include "scene/3d/camera.h" -#include "scene/3d/light.h" -#include "scene/3d/mesh_instance.h" -#include "scene/resources/material.h" - -class MaterialEditor : public Control { - - GDCLASS(MaterialEditor, Control); - - - Viewport *viewport; - MeshInstance *sphere_instance; - MeshInstance *box_instance; - DirectionalLight *light1; - DirectionalLight *light2; - Camera *camera; - - Ref<Mesh> sphere_mesh; - Ref<Mesh> box_mesh; - - TextureButton *sphere_switch; - TextureButton *box_switch; - - TextureButton *light_1_switch; - TextureButton *light_2_switch; - - - Ref<Material> material; - - - void _button_pressed(Node* p_button); - bool first_enter; - -protected: - void _notification(int p_what); - void _gui_input(InputEvent p_event); - static void _bind_methods(); -public: - - void edit(Ref<Material> p_material); - MaterialEditor(); -}; - - -class MaterialEditorPlugin : public EditorPlugin { - - GDCLASS( MaterialEditorPlugin, EditorPlugin ); - - MaterialEditor *material_editor; - EditorNode *editor; - -public: - - virtual String get_name() const { return "Material"; } - bool has_main_screen() const { return false; } - virtual void edit(Object *p_node); - virtual bool handles(Object *p_node) const; - virtual void make_visible(bool p_visible); - - MaterialEditorPlugin(EditorNode *p_node); - ~MaterialEditorPlugin(); - -}; - -#endif class SpatialMaterialConversionPlugin : public EditorResourceConversionPlugin { GDCLASS(SpatialMaterialConversionPlugin, EditorResourceConversionPlugin) public: virtual String converts_to() const; virtual bool handles(const Ref<Resource> &p_resource) const; - virtual Ref<Resource> convert(const Ref<Resource> &p_resource); + virtual Ref<Resource> convert(const Ref<Resource> &p_resource) const; }; class ParticlesMaterialConversionPlugin : public EditorResourceConversionPlugin { @@ -117,7 +46,7 @@ class ParticlesMaterialConversionPlugin : public EditorResourceConversionPlugin public: virtual String converts_to() const; virtual bool handles(const Ref<Resource> &p_resource) const; - virtual Ref<Resource> convert(const Ref<Resource> &p_resource); + virtual Ref<Resource> convert(const Ref<Resource> &p_resource) const; }; class CanvasItemMaterialConversionPlugin : public EditorResourceConversionPlugin { @@ -125,7 +54,7 @@ class CanvasItemMaterialConversionPlugin : public EditorResourceConversionPlugin public: virtual String converts_to() const; virtual bool handles(const Ref<Resource> &p_resource) const; - virtual Ref<Resource> convert(const Ref<Resource> &p_resource); + virtual Ref<Resource> convert(const Ref<Resource> &p_resource) const; }; #endif // MATERIAL_EDITOR_PLUGIN_H diff --git a/editor/plugins/mesh_editor_plugin.cpp b/editor/plugins/mesh_editor_plugin.cpp index 7b7e23531a..73a216e96f 100644 --- a/editor/plugins/mesh_editor_plugin.cpp +++ b/editor/plugins/mesh_editor_plugin.cpp @@ -65,14 +65,6 @@ void MeshEditor::_notification(int p_what) { first_enter = false; } } - - if (p_what == NOTIFICATION_DRAW) { - - Ref<Texture> checkerboard = get_icon("Checkerboard", "EditorIcons"); - Size2 size = get_size(); - - //draw_texture_rect(checkerboard, Rect2(Point2(), size), true); - } } void MeshEditor::_update_rotation() { diff --git a/editor/plugins/particles_2d_editor_plugin.cpp b/editor/plugins/particles_2d_editor_plugin.cpp index ae5d510502..5dcbca2ed6 100644 --- a/editor/plugins/particles_2d_editor_plugin.cpp +++ b/editor/plugins/particles_2d_editor_plugin.cpp @@ -31,9 +31,9 @@ #include "particles_2d_editor_plugin.h" #include "canvas_item_editor_plugin.h" -#include "io/image_loader.h" -#include "scene/3d/particles.h" +#include "core/io/image_loader.h" #include "scene/gui/separator.h" +#include "scene/resources/particles_material.h" void Particles2DEditorPlugin::edit(Object *p_object) { diff --git a/editor/plugins/particles_2d_editor_plugin.h b/editor/plugins/particles_2d_editor_plugin.h index 2b6123141b..71ca8ef499 100644 --- a/editor/plugins/particles_2d_editor_plugin.h +++ b/editor/plugins/particles_2d_editor_plugin.h @@ -34,7 +34,6 @@ #include "editor/editor_node.h" #include "editor/editor_plugin.h" #include "scene/2d/collision_polygon_2d.h" - #include "scene/2d/particles_2d.h" #include "scene/gui/box_container.h" #include "scene/gui/file_dialog.h" diff --git a/editor/plugins/particles_editor_plugin.cpp b/editor/plugins/particles_editor_plugin.cpp index 3c381158a4..6b41946918 100644 --- a/editor/plugins/particles_editor_plugin.cpp +++ b/editor/plugins/particles_editor_plugin.cpp @@ -29,9 +29,12 @@ /*************************************************************************/ #include "particles_editor_plugin.h" + +#include "core/io/resource_loader.h" #include "editor/plugins/spatial_editor_plugin.h" -#include "io/resource_loader.h" #include "scene/3d/cpu_particles.h" +#include "scene/resources/particles_material.h" + bool ParticlesEditorBase::_generate(PoolVector<Vector3> &points, PoolVector<Vector3> &normals) { bool use_normals = emission_fill->get_selected() == 1; diff --git a/editor/plugins/particles_editor_plugin.h b/editor/plugins/particles_editor_plugin.h index 622ce6e8a9..830d30d98f 100644 --- a/editor/plugins/particles_editor_plugin.h +++ b/editor/plugins/particles_editor_plugin.h @@ -43,6 +43,7 @@ class ParticlesEditorBase : public Control { GDCLASS(ParticlesEditorBase, Control) + protected: Spatial *base_node; Panel *panel; diff --git a/editor/plugins/path_2d_editor_plugin.cpp b/editor/plugins/path_2d_editor_plugin.cpp index 33e182faef..88b3194490 100644 --- a/editor/plugins/path_2d_editor_plugin.cpp +++ b/editor/plugins/path_2d_editor_plugin.cpp @@ -31,9 +31,9 @@ #include "path_2d_editor_plugin.h" #include "canvas_item_editor_plugin.h" +#include "core/os/file_access.h" +#include "core/os/keyboard.h" #include "editor/editor_settings.h" -#include "os/file_access.h" -#include "os/keyboard.h" void Path2DEditor::_notification(int p_what) { @@ -288,7 +288,7 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) { return false; } -void Path2DEditor::forward_draw_over_viewport(Control *p_overlay) { +void Path2DEditor::forward_canvas_draw_over_viewport(Control *p_overlay) { if (!node) return; diff --git a/editor/plugins/path_2d_editor_plugin.h b/editor/plugins/path_2d_editor_plugin.h index 1e3955f84f..3a78657746 100644 --- a/editor/plugins/path_2d_editor_plugin.h +++ b/editor/plugins/path_2d_editor_plugin.h @@ -107,7 +107,7 @@ protected: public: bool forward_gui_input(const Ref<InputEvent> &p_event); - void forward_draw_over_viewport(Control *p_overlay); + void forward_canvas_draw_over_viewport(Control *p_overlay); void edit(Node *p_path2d); Path2DEditor(EditorNode *p_editor); }; @@ -121,7 +121,7 @@ class Path2DEditorPlugin : public EditorPlugin { public: virtual bool forward_canvas_gui_input(const Ref<InputEvent> &p_event) { return path2d_editor->forward_gui_input(p_event); } - virtual void forward_draw_over_viewport(Control *p_overlay) { return path2d_editor->forward_draw_over_viewport(p_overlay); } + virtual void forward_canvas_draw_over_viewport(Control *p_overlay) { return path2d_editor->forward_canvas_draw_over_viewport(p_overlay); } virtual String get_name() const { return "Path2D"; } bool has_main_screen() const { return false; } diff --git a/editor/plugins/path_editor_plugin.cpp b/editor/plugins/path_editor_plugin.cpp index 618c70d1a1..df6c40ed02 100644 --- a/editor/plugins/path_editor_plugin.cpp +++ b/editor/plugins/path_editor_plugin.cpp @@ -30,7 +30,7 @@ #include "path_editor_plugin.h" -#include "os/keyboard.h" +#include "core/os/keyboard.h" #include "scene/resources/curve.h" #include "spatial_editor_plugin.h" @@ -57,7 +57,7 @@ String PathSpatialGizmo::get_handle_name(int p_idx) const { return n; } -Variant PathSpatialGizmo::get_handle_value(int p_idx) const { +Variant PathSpatialGizmo::get_handle_value(int p_idx) { Ref<Curve3D> c = path->get_curve(); if (c.is_null()) @@ -215,8 +215,8 @@ void PathSpatialGizmo::redraw() { clear(); - Ref<SpatialMaterial> path_material = gizmo_plugin->get_material("path_material"); - Ref<SpatialMaterial> path_thin_material = gizmo_plugin->get_material("path_thin_material"); + Ref<SpatialMaterial> path_material = gizmo_plugin->get_material("path_material", this); + Ref<SpatialMaterial> path_thin_material = gizmo_plugin->get_material("path_thin_material", this); Ref<SpatialMaterial> handles_material = gizmo_plugin->get_material("handles"); Ref<Curve3D> c = path->get_curve(); @@ -641,24 +641,8 @@ String PathSpatialGizmoPlugin::get_name() const { PathSpatialGizmoPlugin::PathSpatialGizmoPlugin() { Color path_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/path", Color(0.5, 0.5, 1.0, 0.8)); - - Ref<SpatialMaterial> path_material = Ref<SpatialMaterial>(memnew(SpatialMaterial)); - path_color.a = 0.8; - path_material->set_albedo(path_color); - path_material->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true); - path_material->set_line_width(3); - path_material->set_cull_mode(SpatialMaterial::CULL_DISABLED); - path_material->set_flag(SpatialMaterial::FLAG_UNSHADED, true); - - Ref<SpatialMaterial> path_thin_material = Ref<SpatialMaterial>(memnew(SpatialMaterial)); + create_material("path_material", path_color); path_color.a = 0.4; - path_thin_material->set_albedo(path_color); - path_thin_material->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true); - path_thin_material->set_line_width(1); - path_thin_material->set_cull_mode(SpatialMaterial::CULL_DISABLED); - path_thin_material->set_flag(SpatialMaterial::FLAG_UNSHADED, true); - - add_material("path_material", path_material); - add_material("path_thin_material", path_thin_material); + create_material("path_thin_material", path_color); create_handle_material("handles"); } diff --git a/editor/plugins/path_editor_plugin.h b/editor/plugins/path_editor_plugin.h index 61f309e794..c77b2a41cc 100644 --- a/editor/plugins/path_editor_plugin.h +++ b/editor/plugins/path_editor_plugin.h @@ -45,7 +45,7 @@ class PathSpatialGizmo : public EditorSpatialGizmo { public: virtual String get_handle_name(int p_idx) const; - virtual Variant get_handle_value(int p_idx) const; + virtual Variant get_handle_value(int p_idx); virtual void set_handle(int p_idx, Camera *p_camera, const Point2 &p_point); virtual void commit_handle(int p_idx, const Variant &p_restore, bool p_cancel = false); diff --git a/editor/plugins/physical_bone_plugin.cpp b/editor/plugins/physical_bone_plugin.cpp index 42f1adcadf..6341d7f2ef 100644 --- a/editor/plugins/physical_bone_plugin.cpp +++ b/editor/plugins/physical_bone_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -69,15 +69,7 @@ PhysicalBoneEditor::PhysicalBoneEditor(EditorNode *p_editor) : hide(); } -PhysicalBoneEditor::~PhysicalBoneEditor() { - // TODO the spatial_editor_hb should be removed from SpatialEditor, but in this moment it's not possible - for (int i = spatial_editor_hb->get_child_count() - 1; 0 <= i; --i) { - Node *n = spatial_editor_hb->get_child(i); - spatial_editor_hb->remove_child(n); - memdelete(n); - } - memdelete(spatial_editor_hb); -} +PhysicalBoneEditor::~PhysicalBoneEditor() {} void PhysicalBoneEditor::set_selected(PhysicalBone *p_pb) { @@ -98,19 +90,17 @@ void PhysicalBoneEditor::show() { PhysicalBonePlugin::PhysicalBonePlugin(EditorNode *p_editor) : editor(p_editor), - selected(NULL) { - - physical_bone_editor = memnew(PhysicalBoneEditor(editor)); -} + selected(NULL), + physical_bone_editor(editor) {} void PhysicalBonePlugin::make_visible(bool p_visible) { if (p_visible) { - physical_bone_editor->show(); + physical_bone_editor.show(); } else { - physical_bone_editor->hide(); - physical_bone_editor->set_selected(NULL); + physical_bone_editor.hide(); + physical_bone_editor.set_selected(NULL); selected = NULL; } } @@ -119,5 +109,5 @@ void PhysicalBonePlugin::edit(Object *p_node) { selected = static_cast<PhysicalBone *>(p_node); // Trust it ERR_FAIL_COND(!selected); - physical_bone_editor->set_selected(selected); + physical_bone_editor.set_selected(selected); } diff --git a/editor/plugins/physical_bone_plugin.h b/editor/plugins/physical_bone_plugin.h index 9e7a50307a..e1f8c9ec47 100644 --- a/editor/plugins/physical_bone_plugin.h +++ b/editor/plugins/physical_bone_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -64,7 +64,7 @@ class PhysicalBonePlugin : public EditorPlugin { EditorNode *editor; PhysicalBone *selected; - PhysicalBoneEditor *physical_bone_editor; + PhysicalBoneEditor physical_bone_editor; public: virtual String get_name() const { return "PhysicalBone"; } diff --git a/editor/plugins/polygon_2d_editor_plugin.cpp b/editor/plugins/polygon_2d_editor_plugin.cpp index a437cd5362..f937744d45 100644 --- a/editor/plugins/polygon_2d_editor_plugin.cpp +++ b/editor/plugins/polygon_2d_editor_plugin.cpp @@ -31,10 +31,10 @@ #include "polygon_2d_editor_plugin.h" #include "canvas_item_editor_plugin.h" +#include "core/os/file_access.h" +#include "core/os/input.h" +#include "core/os/keyboard.h" #include "editor/editor_settings.h" -#include "os/file_access.h" -#include "os/input.h" -#include "os/keyboard.h" #include "scene/2d/skeleton_2d.h" Node2D *Polygon2DEditor::_get_node() const { @@ -767,6 +767,7 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) { node->set_polygon(uv_new); } } break; + default: {} } if (bone_painting) { diff --git a/editor/plugins/resource_preloader_editor_plugin.cpp b/editor/plugins/resource_preloader_editor_plugin.cpp index c6e8ec1a2b..dd327d0a2c 100644 --- a/editor/plugins/resource_preloader_editor_plugin.cpp +++ b/editor/plugins/resource_preloader_editor_plugin.cpp @@ -30,9 +30,9 @@ #include "resource_preloader_editor_plugin.h" +#include "core/io/resource_loader.h" +#include "core/project_settings.h" #include "editor/editor_settings.h" -#include "io/resource_loader.h" -#include "project_settings.h" void ResourcePreloaderEditor::_gui_input(Ref<InputEvent> p_event) { } @@ -238,8 +238,7 @@ void ResourcePreloaderEditor::_update_library() { ti->set_text(2, type); ti->set_selectable(2, false); - if (has_icon(type, "EditorIcons")) - ti->set_icon(2, get_icon(type, "EditorIcons")); + ti->set_icon(2, EditorNode::get_singleton()->get_class_icon(type, "")); } //player->add_resource("default",resource); diff --git a/editor/plugins/root_motion_editor_plugin.cpp b/editor/plugins/root_motion_editor_plugin.cpp index af3c09afc5..b3adf19a64 100644 --- a/editor/plugins/root_motion_editor_plugin.cpp +++ b/editor/plugins/root_motion_editor_plugin.cpp @@ -1,3 +1,33 @@ +/*************************************************************************/ +/* root_motion_editor_plugin.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + #include "root_motion_editor_plugin.h" #include "editor/editor_node.h" #include "scene/main/viewport.h" @@ -79,11 +109,7 @@ void EditorPropertyRootMotion::_node_assign() { if (base->has_node(accum)) { Node *node = base->get_node(accum); - if (has_icon(node->get_class(), "EditorIcons")) { - ti->set_icon(0, get_icon(node->get_class(), "EditorIcons")); - } else { - ti->set_icon(0, get_icon("Node", "EditorIcons")); - } + ti->set_icon(0, EditorNode::get_singleton()->get_object_icon(node, "Node")); } } else { @@ -96,7 +122,7 @@ void EditorPropertyRootMotion::_node_assign() { node = base->get_node(accum); } if (!node) - continue; //no node, cant edit + continue; //no node, can't edit if (path.get_subname_count()) { @@ -205,14 +231,7 @@ void EditorPropertyRootMotion::update_property() { ERR_FAIL_COND(!target_node); assign->set_text(target_node->get_name()); - - Ref<Texture> icon; - if (has_icon(target_node->get_class(), "EditorIcons")) - icon = get_icon(target_node->get_class(), "EditorIcons"); - else - icon = get_icon("Node", "EditorIcons"); - - assign->set_icon(icon); + assign->set_icon(EditorNode::get_singleton()->get_object_icon(target_node, "Node")); } void EditorPropertyRootMotion::setup(const NodePath &p_base_hint) { @@ -284,7 +303,7 @@ bool EditorInspectorRootMotionPlugin::parse_property(Object *p_object, Variant:: return true; } - return false; //can be overriden, although it will most likely be last anyway + return false; //can be overridden, although it will most likely be last anyway } void EditorInspectorRootMotionPlugin::parse_end() { diff --git a/editor/plugins/root_motion_editor_plugin.h b/editor/plugins/root_motion_editor_plugin.h index 84af47872f..2b5492350b 100644 --- a/editor/plugins/root_motion_editor_plugin.h +++ b/editor/plugins/root_motion_editor_plugin.h @@ -1,3 +1,33 @@ +/*************************************************************************/ +/* root_motion_editor_plugin.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + #ifndef ROOT_MOTION_EDITOR_PLUGIN_H #define ROOT_MOTION_EDITOR_PLUGIN_H diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index 1bb7c98114..7cda15bdc6 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -59,25 +59,10 @@ void ScriptEditorBase::_bind_methods() { ADD_SIGNAL(MethodInfo("search_in_files_requested", PropertyInfo(Variant::STRING, "text"))); } -static bool _can_open_in_editor(Script *p_script) { - +static bool _is_built_in_script(Script *p_script) { String path = p_script->get_path(); - if (path.find("::") != -1) { - //refuse handling this if it can't be edited - - bool valid = false; - for (int i = 0; i < EditorNode::get_singleton()->get_editor_data().get_edited_scene_count(); i++) { - if (path.begins_with(EditorNode::get_singleton()->get_editor_data().get_scene_path(i))) { - valid = true; - break; - } - } - - return valid; - } - - return true; + return path.find("::") != -1; } class EditorScriptCodeCompletionCache : public ScriptCodeCompletionCache { @@ -111,7 +96,7 @@ public: } } - RES get_cached_resource(const String &p_path) { + virtual RES get_cached_resource(const String &p_path) { Map<String, Cache>::Element *E = cached.find(p_path); if (!E) { @@ -149,9 +134,11 @@ public: max_cache_size = 128; max_time_cache = 5 * 60 * 1000; //minutes, five } + + virtual ~EditorScriptCodeCompletionCache() {} }; -void ScriptEditorQuickOpen::popup(const Vector<String> &p_functions, bool p_dontclear) { +void ScriptEditorQuickOpen::popup_dialog(const Vector<String> &p_functions, bool p_dontclear) { popup_centered_ratio(0.6); if (p_dontclear) @@ -504,6 +491,13 @@ void ScriptEditor::_open_recent_script(int p_idx) { return; } // if it's a path then its most likely a deleted file not help + } else if (path.find("::") != -1) { + // built-in script + Ref<Script> script = ResourceLoader::load(path); + if (script.is_valid()) { + edit(script, true); + return; + } } else if (!path.is_resource_file()) { _help_class_open(path); return; @@ -805,7 +799,7 @@ bool ScriptEditor::_test_script_times_on_disk(RES p_for_script) { if (se) { RES edited_res = se->get_edited_resource(); - if (edited_res.is_valid() && p_for_script != edited_res) + if (p_for_script.is_valid() && edited_res.is_valid() && p_for_script != edited_res) continue; if (edited_res->get_path() == "" || edited_res->get_path().find("local://") != -1 || edited_res->get_path().find("::") != -1) @@ -862,7 +856,7 @@ void ScriptEditor::_file_dialog_action(String p_file) { if (extensions.find(p_file.get_extension())) { Ref<Script> scr = ResourceLoader::load(p_file); if (!scr.is_valid()) { - editor->show_warning(TTR("Error could not load file."), TTR("Error!")); + editor->show_warning(TTR("Error: could not load file."), TTR("Error!")); file_dialog_option = -1; return; } @@ -939,7 +933,7 @@ void ScriptEditor::_menu_option(int p_option) { switch (p_option) { case FILE_NEW: { - script_create_dialog->config("Node", ".gd"); + script_create_dialog->config("Node", "new_script"); script_create_dialog->popup_centered(Size2(300, 300) * EDSCALE); } break; case FILE_NEW_TEXTFILE: { @@ -976,11 +970,11 @@ void ScriptEditor::_menu_option(int p_option) { } break; case SEARCH_HELP: { - help_search_dialog->popup(); + help_search_dialog->popup_dialog(); } break; case SEARCH_CLASSES: { - help_index->popup(); + help_index->popup_dialog(); } break; case SEARCH_WEBSITE: { @@ -1212,7 +1206,7 @@ void ScriptEditor::_menu_option(int p_option) { case SEARCH_CLASSES: { - help_index->popup(); + help_index->popup_dialog(); help_index->call_deferred("select_class", help->get_class()); } break; case HELP_SEARCH_FIND: { @@ -1422,21 +1416,6 @@ void ScriptEditor::notify_script_changed(const Ref<Script> &p_script) { emit_signal("editor_script_changed", p_script); } -static const Node *_find_node_with_script(const Node *p_node, const RefPtr &p_script) { - - if (p_node->get_script() == p_script) - return p_node; - - for (int i = 0; i < p_node->get_child_count(); i++) { - - const Node *result = _find_node_with_script(p_node->get_child(i), p_script); - if (result) - return result; - } - - return NULL; -} - void ScriptEditor::get_breakpoints(List<String> *p_breakpoints) { for (int i = 0; i < tab_container->get_child_count(); i++) { @@ -1692,7 +1671,6 @@ void ScriptEditor::_update_script_names() { if (restoring_layout) return; - waiting_update_names = false; Set<Ref<Script> > used; Node *edited = EditorNode::get_singleton()->get_edited_scene(); if (edited) { @@ -1743,7 +1721,7 @@ void ScriptEditor::_update_script_names() { } break; case DISPLAY_DIR_AND_NAME: { if (!path.get_base_dir().get_file().empty()) { - sd.name = path.get_base_dir().get_file() + "/" + name; + sd.name = path.get_base_dir().get_file().plus_file(name); } else { sd.name = name; } @@ -1794,8 +1772,8 @@ void ScriptEditor::_update_script_names() { new_cur_tab = i; } } - tab_container->call_deferred("set_current_tab", new_prev_tab); - tab_container->call_deferred("set_current_tab", new_cur_tab); + tab_container->set_current_tab(new_prev_tab); + tab_container->set_current_tab(new_cur_tab); _sort_list_on_update = false; } @@ -1816,8 +1794,12 @@ void ScriptEditor::_update_script_names() { } } - _update_members_overview(); - _update_help_overview(); + if (!waiting_update_names) { + _update_members_overview(); + _update_help_overview(); + } else { + waiting_update_names = false; + } _update_members_overview_visibility(); _update_help_overview_visibility(); _update_script_colors(); @@ -2014,6 +1996,7 @@ bool ScriptEditor::edit(const RES &p_resource, int p_line, int p_col, bool p_gra _go_to_tab(tab_container->get_tab_count() - 1); } + _sort_list_on_update = true; _update_script_names(); _save_layout(); se->connect("name_changed", this, "_update_script_names"); @@ -2103,8 +2086,6 @@ void ScriptEditor::_editor_play() { debug_menu->get_popup()->set_item_disabled(debug_menu->get_popup()->get_item_index(DEBUG_STEP), true); debug_menu->get_popup()->set_item_disabled(debug_menu->get_popup()->get_item_index(DEBUG_BREAK), false); debug_menu->get_popup()->set_item_disabled(debug_menu->get_popup()->get_item_index(DEBUG_CONTINUE), true); - - //debugger_gui->start_listening(Globals::get_singleton()->get("debug/debug_port")); } void ScriptEditor::_editor_pause() { @@ -2588,6 +2569,7 @@ void ScriptEditor::_help_class_open(const String &p_class) { eh->go_to_class(p_class, 0); eh->connect("go_to_help", this, "_help_class_goto"); _add_recent_script(p_class); + _sort_list_on_update = true; _update_script_names(); _save_layout(); } @@ -2617,6 +2599,7 @@ void ScriptEditor::_help_class_goto(const String &p_desc) { eh->go_to_help(p_desc); eh->connect("go_to_help", this, "_help_class_goto"); _add_recent_script(eh->get_class()); + _sort_list_on_update = true; _update_script_names(); _save_layout(); } @@ -2725,7 +2708,7 @@ void ScriptEditor::set_scene_root_script(Ref<Script> p_script) { if (bool(EditorSettings::get_singleton()->get("text_editor/external/use_external_editor"))) return; - if (open_dominant && p_script.is_valid() && _can_open_in_editor(p_script.ptr())) { + if (open_dominant && p_script.is_valid()) { edit(p_script); } } @@ -2746,11 +2729,11 @@ void ScriptEditor::set_live_auto_reload_running_scripts(bool p_enabled) { } void ScriptEditor::_help_index(String p_text) { - help_index->popup(); + help_index->popup_dialog(); } void ScriptEditor::_help_search(String p_text) { - help_search_dialog->popup(p_text); + help_search_dialog->popup_dialog(p_text); } void ScriptEditor::_open_script_request(const String &p_path) { @@ -3017,7 +3000,7 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) { file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/show_in_file_system", TTR("Show In File System")), SHOW_IN_FILE_SYSTEM); file_menu->get_popup()->add_separator(); - file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/history_previous", TTR("History Prev"), KEY_MASK_ALT | KEY_LEFT), WINDOW_PREV); + file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/history_previous", TTR("History Previous"), KEY_MASK_ALT | KEY_LEFT), WINDOW_PREV); file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/history_next", TTR("History Next"), KEY_MASK_ALT | KEY_RIGHT), WINDOW_NEXT); file_menu->get_popup()->add_separator(); @@ -3064,7 +3047,7 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) { debug_menu->get_popup()->add_separator(); //debug_menu->get_popup()->add_check_item("Show Debugger",DEBUG_SHOW); debug_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("debugger/keep_debugger_open", TTR("Keep Debugger Open")), DEBUG_SHOW_KEEP_OPEN); - debug_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("debugger/debug_with_exteral_editor", TTR("Debug with external editor")), DEBUG_WITH_EXTERNAL_EDITOR); + debug_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("debugger/debug_with_external_editor", TTR("Debug with External Editor")), DEBUG_WITH_EXTERNAL_EDITOR); debug_menu->get_popup()->connect("id_pressed", this, "_menu_option"); debug_menu->get_popup()->set_item_disabled(debug_menu->get_popup()->get_item_index(DEBUG_NEXT), true); @@ -3137,7 +3120,6 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) { error_dialog = memnew(AcceptDialog); add_child(error_dialog); - error_dialog->get_ok()->set_text(TTR("OK")); debugger = memnew(ScriptEditorDebugger(editor)); debugger->connect("goto_script_line", this, "_goto_script_line"); @@ -3221,7 +3203,17 @@ ScriptEditor::~ScriptEditor() { void ScriptEditorPlugin::edit(Object *p_object) { if (Object::cast_to<Script>(p_object)) { - script_editor->edit(Object::cast_to<Script>(p_object)); + + Script *p_script = Object::cast_to<Script>(p_object); + String scene_path = p_script->get_path().get_slice("::", 0); + + if (_is_built_in_script(p_script) && !EditorNode::get_singleton()->is_scene_open(scene_path)) { + EditorNode::get_singleton()->load_scene(scene_path); + + script_editor->call_deferred("edit", p_script); + } else { + script_editor->edit(p_script); + } } if (Object::cast_to<TextFile>(p_object)) { @@ -3236,13 +3228,7 @@ bool ScriptEditorPlugin::handles(Object *p_object) const { } if (Object::cast_to<Script>(p_object)) { - - bool valid = _can_open_in_editor(Object::cast_to<Script>(p_object)); - - if (!valid) { //user tried to open it by clicking - EditorNode::get_singleton()->show_warning(TTR("Built-in scripts can only be edited when the scene they belong to is loaded")); - } - return valid; + return true; } return p_object->is_class("Script"); diff --git a/editor/plugins/script_editor_plugin.h b/editor/plugins/script_editor_plugin.h index 737f17358b..28c07393f7 100644 --- a/editor/plugins/script_editor_plugin.h +++ b/editor/plugins/script_editor_plugin.h @@ -31,6 +31,7 @@ #ifndef SCRIPT_EDITOR_PLUGIN_H #define SCRIPT_EDITOR_PLUGIN_H +#include "core/script_language.h" #include "editor/code_editor.h" #include "editor/editor_help.h" #include "editor/editor_plugin.h" @@ -44,7 +45,6 @@ #include "scene/gui/tree.h" #include "scene/main/timer.h" #include "scene/resources/text_file.h" -#include "script_language.h" class ScriptEditorQuickOpen : public ConfirmationDialog { @@ -67,7 +67,7 @@ protected: static void _bind_methods(); public: - void popup(const Vector<String> &p_functions, bool p_dontclear = false); + void popup_dialog(const Vector<String> &p_functions, bool p_dontclear = false); ScriptEditorQuickOpen(); }; diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp index 4e7047ee38..9b968c3523 100644 --- a/editor/plugins/script_text_editor.cpp +++ b/editor/plugins/script_text_editor.cpp @@ -30,10 +30,10 @@ #include "script_text_editor.h" +#include "core/os/keyboard.h" #include "editor/editor_node.h" #include "editor/editor_settings.h" #include "editor/script_editor_debugger.h" -#include "os/keyboard.h" Vector<String> ScriptTextEditor::get_functions() { @@ -317,6 +317,7 @@ void ScriptTextEditor::_notification(int p_what) { switch (p_what) { case NOTIFICATION_READY: _load_theme_settings(); + _change_syntax_highlighter(EditorSettings::get_singleton()->get_project_metadata("script_text_editor", "syntax_highlighter", 0)); break; } } @@ -939,7 +940,8 @@ void ScriptTextEditor::_edit_option(int p_op) { } break; case SEARCH_LOCATE_FUNCTION: { - quick_open->popup(get_functions()); + quick_open->popup_dialog(get_functions()); + quick_open->set_title(TTR("Go to Function")); } break; case SEARCH_GOTO_LINE: { @@ -1058,6 +1060,7 @@ void ScriptTextEditor::_change_syntax_highlighter(int p_idx) { } // highlighter_menu->set_item_checked(p_idx, true); set_syntax_highlighter(highlighters[highlighter_menu->get_item_text(p_idx)]); + EditorSettings::get_singleton()->set_project_metadata("script_text_editor", "syntax_highlighter", p_idx); } void ScriptTextEditor::_bind_methods() { @@ -1256,7 +1259,7 @@ void ScriptTextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) { int to_column = tx->get_selection_to_column(); if (row < from_line || row > to_line || (row == from_line && col < from_column) || (row == to_line && col > to_column)) { - // Right click is outside the seleted text + // Right click is outside the selected text tx->deselect(); } } @@ -1273,7 +1276,6 @@ void ScriptTextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) { word_at_mouse = tx->get_selection_text(); bool has_color = (word_at_mouse == "Color"); - int fold_state = 0; bool foldable = tx->can_fold(row) || tx->is_folded(row); bool open_docs = false; bool goto_definition = false; @@ -1475,9 +1477,9 @@ ScriptTextEditor::ScriptTextEditor() { convert_case->set_name("convert_case"); edit_menu->get_popup()->add_child(convert_case); edit_menu->get_popup()->add_submenu_item(TTR("Convert Case"), "convert_case"); - convert_case->add_shortcut(ED_SHORTCUT("script_text_editor/convert_to_uppercase", TTR("Uppercase")), EDIT_TO_UPPERCASE); - convert_case->add_shortcut(ED_SHORTCUT("script_text_editor/convert_to_lowercase", TTR("Lowercase")), EDIT_TO_LOWERCASE); - convert_case->add_shortcut(ED_SHORTCUT("script_text_editor/capitalize", TTR("Capitalize")), EDIT_CAPITALIZE); + convert_case->add_shortcut(ED_SHORTCUT("script_text_editor/convert_to_uppercase", TTR("Uppercase"), KEY_MASK_SHIFT | KEY_F4), EDIT_TO_UPPERCASE); + convert_case->add_shortcut(ED_SHORTCUT("script_text_editor/convert_to_lowercase", TTR("Lowercase"), KEY_MASK_SHIFT | KEY_F5), EDIT_TO_LOWERCASE); + convert_case->add_shortcut(ED_SHORTCUT("script_text_editor/capitalize", TTR("Capitalize"), KEY_MASK_SHIFT | KEY_F6), EDIT_CAPITALIZE); convert_case->connect("id_pressed", this, "_edit_option"); highlighters["Standard"] = NULL; @@ -1549,13 +1551,14 @@ void ScriptTextEditor::register_editor() { ED_SHORTCUT("script_text_editor/unfold_all_lines", TTR("Unfold All Lines"), 0); #ifdef OSX_ENABLED ED_SHORTCUT("script_text_editor/clone_down", TTR("Clone Down"), KEY_MASK_SHIFT | KEY_MASK_CMD | KEY_C); + ED_SHORTCUT("script_text_editor/complete_symbol", TTR("Complete Symbol"), KEY_MASK_CTRL | KEY_SPACE); #else ED_SHORTCUT("script_text_editor/clone_down", TTR("Clone Down"), KEY_MASK_CMD | KEY_B); -#endif ED_SHORTCUT("script_text_editor/complete_symbol", TTR("Complete Symbol"), KEY_MASK_CMD | KEY_SPACE); +#endif ED_SHORTCUT("script_text_editor/trim_trailing_whitespace", TTR("Trim Trailing Whitespace"), KEY_MASK_CMD | KEY_MASK_ALT | KEY_T); ED_SHORTCUT("script_text_editor/convert_indent_to_spaces", TTR("Convert Indent To Spaces"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_Y); - ED_SHORTCUT("script_text_editor/convert_indent_to_tabs", TTR("Convert Indent To Tabs"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_X); + ED_SHORTCUT("script_text_editor/convert_indent_to_tabs", TTR("Convert Indent To Tabs"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_I); ED_SHORTCUT("script_text_editor/auto_indent", TTR("Auto Indent"), KEY_MASK_CMD | KEY_I); #ifdef OSX_ENABLED @@ -1564,27 +1567,28 @@ void ScriptTextEditor::register_editor() { ED_SHORTCUT("script_text_editor/toggle_breakpoint", TTR("Toggle Breakpoint"), KEY_F9); #endif ED_SHORTCUT("script_text_editor/remove_all_breakpoints", TTR("Remove All Breakpoints"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_F9); - ED_SHORTCUT("script_text_editor/goto_next_breakpoint", TTR("Goto Next Breakpoint"), KEY_MASK_CMD | KEY_PERIOD); - ED_SHORTCUT("script_text_editor/goto_previous_breakpoint", TTR("Goto Previous Breakpoint"), KEY_MASK_CMD | KEY_COMMA); - - ED_SHORTCUT("script_text_editor/convert_to_uppercase", TTR("Convert To Uppercase"), KEY_MASK_SHIFT | KEY_F4); - ED_SHORTCUT("script_text_editor/convert_to_lowercase", TTR("Convert To Lowercase"), KEY_MASK_SHIFT | KEY_F3); - ED_SHORTCUT("script_text_editor/capitalize", TTR("Capitalize"), KEY_MASK_SHIFT | KEY_F2); + ED_SHORTCUT("script_text_editor/goto_next_breakpoint", TTR("Go to Next Breakpoint"), KEY_MASK_CMD | KEY_PERIOD); + ED_SHORTCUT("script_text_editor/goto_previous_breakpoint", TTR("Go to Previous Breakpoint"), KEY_MASK_CMD | KEY_COMMA); ED_SHORTCUT("script_text_editor/find", TTR("Find..."), KEY_MASK_CMD | KEY_F); #ifdef OSX_ENABLED ED_SHORTCUT("script_text_editor/find_next", TTR("Find Next"), KEY_MASK_CMD | KEY_G); ED_SHORTCUT("script_text_editor/find_previous", TTR("Find Previous"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_G); + ED_SHORTCUT("script_text_editor/replace", TTR("Replace..."), KEY_MASK_ALT | KEY_MASK_CMD | KEY_F); #else ED_SHORTCUT("script_text_editor/find_next", TTR("Find Next"), KEY_F3); ED_SHORTCUT("script_text_editor/find_previous", TTR("Find Previous"), KEY_MASK_SHIFT | KEY_F3); -#endif ED_SHORTCUT("script_text_editor/replace", TTR("Replace..."), KEY_MASK_CMD | KEY_R); +#endif - ED_SHORTCUT("script_text_editor/find_in_files", TTR("Find in files..."), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_F); + ED_SHORTCUT("script_text_editor/find_in_files", TTR("Find in Files..."), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_F); - ED_SHORTCUT("script_text_editor/goto_function", TTR("Goto Function..."), KEY_MASK_ALT | KEY_MASK_CMD | KEY_F); - ED_SHORTCUT("script_text_editor/goto_line", TTR("Goto Line..."), KEY_MASK_CMD | KEY_L); +#ifdef OSX_ENABLED + ED_SHORTCUT("script_text_editor/goto_function", TTR("Go to Function..."), KEY_MASK_CTRL | KEY_MASK_CMD | KEY_J); +#else + ED_SHORTCUT("script_text_editor/goto_function", TTR("Go to Function..."), KEY_MASK_ALT | KEY_MASK_CMD | KEY_F); +#endif + ED_SHORTCUT("script_text_editor/goto_line", TTR("Go to Line..."), KEY_MASK_CMD | KEY_L); #ifdef OSX_ENABLED ED_SHORTCUT("script_text_editor/contextual_help", TTR("Contextual Help"), KEY_MASK_ALT | KEY_MASK_SHIFT | KEY_SPACE); diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp index 5ee40dc90a..17f93b55a1 100644 --- a/editor/plugins/shader_editor_plugin.cpp +++ b/editor/plugins/shader_editor_plugin.cpp @@ -86,10 +86,7 @@ void ShaderTextEditor::_load_theme_settings() { Color search_result_border_color = EDITOR_GET("text_editor/highlighting/search_result_border_color"); Color symbol_color = EDITOR_GET("text_editor/highlighting/symbol_color"); Color keyword_color = EDITOR_GET("text_editor/highlighting/keyword_color"); - Color basetype_color = EDITOR_GET("text_editor/highlighting/base_type_color"); - Color type_color = EDITOR_GET("text_editor/highlighting/engine_type_color"); Color comment_color = EDITOR_GET("text_editor/highlighting/comment_color"); - Color string_color = EDITOR_GET("text_editor/highlighting/string_color"); get_text_edit()->add_color_override("background_color", background_color); get_text_edit()->add_color_override("completion_background_color", completion_background_color); @@ -140,26 +137,9 @@ void ShaderTextEditor::_load_theme_settings() { get_text_edit()->add_keyword_color(E->get(), keyword_color); } - //colorize core types - //Color basetype_color= EDITOR_DEF("text_editor/base_type_color",Color(0.3,0.3,0.0)); - //colorize comments get_text_edit()->add_color_region("/*", "*/", comment_color, false); get_text_edit()->add_color_region("//", "", comment_color, false); - - /*//colorize strings - Color string_color = EDITOR_DEF("text_editor/string_color",Color::hex(0x6b6f00ff)); - - List<String> strings; - shader->get_shader_mode()->get_string_delimiters(&strings); - - for (List<String>::Element *E=strings.front();E;E=E->next()) { - - String string = E->get(); - String beg = string.get_slice(" ",0); - String end = string.get_slice_count(" ")>1?string.get_slice(" ",1):String(); - get_text_edit()->add_color_region(beg,end,string_color,end==""); - }*/ } void ShaderTextEditor::_check_shader_mode() { @@ -426,7 +406,7 @@ void ShaderEditor::ensure_select_current() { void ShaderEditor::edit(const Ref<Shader> &p_shader) { - if (p_shader.is_null()) + if (p_shader.is_null() || !p_shader->is_text_shader()) return; shader = p_shader; @@ -468,7 +448,6 @@ void ShaderEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) { int col, row; TextEdit *tx = shader_editor->get_text_edit(); tx->_get_mouse_pos(mb->get_global_position() - tx->get_global_position(), row, col); - Vector2 mpos = mb->get_global_position() - tx->get_global_position(); tx->set_right_click_moves_caret(EditorSettings::get_singleton()->get("text_editor/cursor/right_click_moves_caret")); if (tx->is_right_click_moving_caret()) { @@ -480,7 +459,7 @@ void ShaderEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) { int to_column = tx->get_selection_to_column(); if (row < from_line || row > to_line || (row == from_line && col < from_column) || (row == to_line && col > to_column)) { - // Right click is outside the seleted text + // Right click is outside the selected text tx->deselect(); } } @@ -606,7 +585,7 @@ void ShaderEditorPlugin::edit(Object *p_object) { bool ShaderEditorPlugin::handles(Object *p_object) const { Shader *shader = Object::cast_to<Shader>(p_object); - return shader != NULL; + return shader != NULL && shader->is_text_shader(); } void ShaderEditorPlugin::make_visible(bool p_visible) { diff --git a/editor/plugins/skeleton_editor_plugin.cpp b/editor/plugins/skeleton_editor_plugin.cpp index 314db4198d..e7d9f1b702 100644 --- a/editor/plugins/skeleton_editor_plugin.cpp +++ b/editor/plugins/skeleton_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -29,9 +29,10 @@ /*************************************************************************/ #include "skeleton_editor_plugin.h" + #include "scene/3d/collision_shape.h" #include "scene/3d/physics_body.h" -#include "scene/3d/physics_joint.h"; +#include "scene/3d/physics_joint.h" #include "scene/resources/capsule_shape.h" #include "scene/resources/sphere_shape.h" #include "spatial_editor_plugin.h" diff --git a/editor/plugins/skeleton_editor_plugin.h b/editor/plugins/skeleton_editor_plugin.h index 0ab94c15b5..aac3e06063 100644 --- a/editor/plugins/skeleton_editor_plugin.h +++ b/editor/plugins/skeleton_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/skeleton_ik_editor_plugin.cpp b/editor/plugins/skeleton_ik_editor_plugin.cpp index 2d343d3edd..c605548a6b 100644 --- a/editor/plugins/skeleton_ik_editor_plugin.cpp +++ b/editor/plugins/skeleton_ik_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/skeleton_ik_editor_plugin.h b/editor/plugins/skeleton_ik_editor_plugin.h index e645bea39a..3e412305c9 100644 --- a/editor/plugins/skeleton_ik_editor_plugin.h +++ b/editor/plugins/skeleton_ik_editor_plugin.h @@ -1,12 +1,12 @@ /*************************************************************************/ -/* skeleton_ik_editor_plugin.h */ +/* skeleton_ik_editor_plugin.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp index 906c51b9f6..114610c562 100644 --- a/editor/plugins/spatial_editor_plugin.cpp +++ b/editor/plugins/spatial_editor_plugin.cpp @@ -30,23 +30,25 @@ #include "spatial_editor_plugin.h" -#include "camera_matrix.h" +#include "core/math/camera_matrix.h" #include "core/os/input.h" - +#include "core/os/keyboard.h" +#include "core/print_string.h" +#include "core/project_settings.h" +#include "core/sort.h" #include "editor/editor_node.h" #include "editor/editor_settings.h" #include "editor/plugins/animation_player_editor_plugin.h" #include "editor/plugins/script_editor_plugin.h" #include "editor/script_editor_debugger.h" #include "editor/spatial_editor_gizmos.h" -#include "os/keyboard.h" -#include "print_string.h" -#include "project_settings.h" #include "scene/3d/camera.h" +#include "scene/3d/collision_shape.h" +#include "scene/3d/mesh_instance.h" +#include "scene/3d/physics_body.h" #include "scene/3d/visual_instance.h" #include "scene/resources/packed_scene.h" #include "scene/resources/surface_tool.h" -#include "sort.h" #define DISTANCE_DEFAULT 4 @@ -274,7 +276,7 @@ void SpatialEditorViewport::_select_clicked(bool p_append, bool p_single) { _select(sp, clicked_wants_append, true); } -void SpatialEditorViewport::_select(Spatial *p_node, bool p_append, bool p_single) { +void SpatialEditorViewport::_select(Node *p_node, bool p_append, bool p_single) { if (!p_append) { editor_selection->clear(); @@ -307,7 +309,7 @@ ObjectID SpatialEditorViewport::_select_ray(const Point2 &p_pos, bool p_append, Node *edited_scene = get_tree()->get_edited_scene_root(); ObjectID closest = 0; - Spatial *item = NULL; + Node *item = NULL; float closest_dist = 1e20; int selected_handle = -1; @@ -340,20 +342,15 @@ ObjectID SpatialEditorViewport::_select_ray(const Point2 &p_pos, bool p_append, continue; if (dist < closest_dist) { - //make sure that whathever is selected is editable - while (spat && spat != edited_scene && spat->get_owner() != edited_scene && !edited_scene->is_editable_instance(spat->get_owner())) { - spat = Object::cast_to<Spatial>(spat->get_owner()); + item = Object::cast_to<Node>(spat); + while (item->get_owner() && item->get_owner() != edited_scene && !edited_scene->is_editable_instance(item->get_owner())) { + item = item->get_owner(); } - if (spat) { - item = spat; - closest = spat->get_instance_id(); - closest_dist = dist; - selected_handle = handle; - } else { - ERR_PRINT("Bug?"); - } + closest = item->get_instance_id(); + closest_dist = dist; + selected_handle = handle; } } @@ -499,7 +496,7 @@ void SpatialEditorViewport::_select_region() { } Vector<ObjectID> instances = VisualServer::get_singleton()->instances_cull_convex(frustum, get_tree()->get_root()->get_world()->get_scenario()); - Vector<Spatial *> selected; + Vector<Node *> selected; Node *edited_scene = get_tree()->get_edited_scene_root(); @@ -509,12 +506,12 @@ void SpatialEditorViewport::_select_region() { if (!sp) continue; - Spatial *root_sp = sp; - while (root_sp && root_sp != edited_scene && root_sp->get_owner() != edited_scene && !edited_scene->is_editable_instance(root_sp->get_owner())) { - root_sp = Object::cast_to<Spatial>(root_sp->get_owner()); + Node *item = Object::cast_to<Node>(sp); + while (item->get_owner() && item->get_owner() != edited_scene && !edited_scene->is_editable_instance(item->get_owner())) { + item = item->get_owner(); } - if (selected.find(root_sp) != -1) continue; + if (selected.find(item) != -1) continue; Ref<EditorSpatialGizmo> seg = sp->get_gizmo(); @@ -522,7 +519,7 @@ void SpatialEditorViewport::_select_region() { continue; if (seg->intersect_frustum(camera, frustum)) { - selected.push_back(root_sp); + selected.push_back(item); } } @@ -534,12 +531,12 @@ void SpatialEditorViewport::_select_region() { void SpatialEditorViewport::_update_name() { - String ortho = orthogonal ? TTR("Orthogonal") : TTR("Perspective"); + String view_mode = orthogonal ? TTR("Orthogonal") : TTR("Perspective"); if (name != "") - view_menu->set_text("[ " + name + " " + ortho + " ]"); + view_menu->set_text("[ " + name + " " + view_mode + " ]"); else - view_menu->set_text("[ " + ortho + " ]"); + view_menu->set_text("[ " + view_mode + " ]"); view_menu->set_size(Vector2(0, 0)); // resets the button size } @@ -850,11 +847,7 @@ void SpatialEditorViewport::_list_select(Ref<InputEventMouseButton> b) { Spatial *spat = selection_results[i].item; - Ref<Texture> icon; - if (spat->has_meta("_editor_icon")) - icon = spat->get_meta("_editor_icon"); - else - icon = get_icon(has_icon(spat->get_class(), "EditorIcons") ? spat->get_class() : String("Object"), "EditorIcons"); + Ref<Texture> icon = EditorNode::get_singleton()->get_object_icon(spat, "Node"); String node_path = "/" + root_name + "/" + root_path.rel_path_to(spat->get_path()); @@ -1004,6 +997,10 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) { set_message(TTR("View Plane Transform."), 2); } break; + case TRANSFORM_YZ: + case TRANSFORM_XZ: + case TRANSFORM_XY: { + } break; } } } break; @@ -1552,6 +1549,10 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) { plane = Plane(_edit.center, spatial_editor->get_gizmo_transform().basis.get_axis(2)); axis = Vector3(0, 0, 1); break; + case TRANSFORM_YZ: + case TRANSFORM_XZ: + case TRANSFORM_XY: + break; } Vector3 intersection; @@ -1911,7 +1912,7 @@ void SpatialEditorViewport::_nav_orbit(Ref<InputEventWithModifiers> p_event, con void SpatialEditorViewport::_nav_look(Ref<InputEventWithModifiers> p_event, const Vector2 &p_relative) { // Freelook only works properly in perspective. - // It technically works too in ortho, but it's awful for a user due to fov being near zero + // It could technically work in ortho, but it's terrible for a user due to FOV being a fixed width. if (!orthogonal) { real_t degrees_per_pixel = EditorSettings::get_singleton()->get("editors/3d/navigation_feel/orbit_sensitivity"); real_t radians_per_pixel = Math::deg2rad(degrees_per_pixel); @@ -2082,7 +2083,7 @@ void SpatialEditorViewport::set_message(String p_message, float p_time) { } void SpatialEditorPlugin::edited_scene_changed() { - for (int i = 0; i < SpatialEditor::VIEWPORTS_COUNT; i++) { + for (uint32_t i = 0; i < SpatialEditor::VIEWPORTS_COUNT; i++) { SpatialEditorViewport *viewport = SpatialEditor::get_singleton()->get_editor_viewport(i); if (viewport->is_visible()) { viewport->notification(Control::NOTIFICATION_VISIBILITY_CHANGED); @@ -2206,7 +2207,7 @@ void SpatialEditorViewport::_notification(int p_what) { bool shrink = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_HALF_RESOLUTION)); - if (shrink != viewport_container->get_stretch_shrink() > 1) { + if (shrink != (viewport_container->get_stretch_shrink() > 1)) { viewport_container->set_stretch_shrink(shrink ? 2 : 1); } @@ -2319,12 +2320,12 @@ void SpatialEditorViewport::_draw() { EditorPluginList *over_plugin_list = EditorNode::get_singleton()->get_editor_plugins_over(); if (!over_plugin_list->empty()) { - over_plugin_list->forward_draw_over_viewport(surface); + over_plugin_list->forward_spatial_draw_over_viewport(surface); } EditorPluginList *force_over_plugin_list = editor->get_editor_plugins_force_over(); if (!force_over_plugin_list->empty()) { - force_over_plugin_list->forward_force_draw_over_viewport(surface); + force_over_plugin_list->forward_spatial_force_draw_over_viewport(surface); } if (surface->has_focus()) { @@ -2353,7 +2354,6 @@ void SpatialEditorViewport::_draw() { Point2 center = _point_to_screen(_edit.center); VisualServer::get_singleton()->canvas_item_add_line(ci, _edit.mouse_pos, center, Color(0.4, 0.7, 1.0, 0.8)); } - if (previewing) { Size2 ss = Size2(ProjectSettings::get_singleton()->get("display/window/size/width"), ProjectSettings::get_singleton()->get("display/window/size/height")); @@ -3274,7 +3274,6 @@ void SpatialEditorViewport::_perform_drop_data() { files_str += error_files[i].get_file().get_basename() + ","; } files_str = files_str.substr(0, files_str.length() - 1); - accept->get_ok()->set_text(TTR("OK")); accept->set_text(vformat(TTR("Error instancing scene from %s"), files_str.c_str())); accept->popup_centered_minsize(); } @@ -3355,7 +3354,6 @@ void SpatialEditorViewport::drop_data_fw(const Point2 &p_point, const Variant &p if (root_node) { list.push_back(root_node); } else { - accept->get_ok()->set_text(TTR("OK")); accept->set_text(TTR("No parent to instance a child at.")); accept->popup_centered_minsize(); _remove_preview(); @@ -3363,7 +3361,6 @@ void SpatialEditorViewport::drop_data_fw(const Point2 &p_point, const Variant &p } } if (list.size() != 1) { - accept->get_ok()->set_text(TTR("OK")); accept->set_text(TTR("This operation requires a single selected node.")); accept->popup_centered_minsize(); _remove_preview(); @@ -3546,69 +3543,77 @@ void SpatialEditorViewportContainer::_gui_input(const Ref<InputEvent> &p_event) Ref<InputEventMouseButton> mb = p_event; - if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) { + if (mb.is_valid() && mb->get_button_index() == BUTTON_LEFT) { - Vector2 size = get_size(); + if (mb->is_pressed()) { + Vector2 size = get_size(); - int h_sep = get_constant("separation", "HSplitContainer"); - int v_sep = get_constant("separation", "VSplitContainer"); + int h_sep = get_constant("separation", "HSplitContainer"); + int v_sep = get_constant("separation", "VSplitContainer"); - int mid_w = size.width * ratio_h; - int mid_h = size.height * ratio_v; - - dragging_h = mb->get_position().x > (mid_w - h_sep / 2) && mb->get_position().x < (mid_w + h_sep / 2); - dragging_v = mb->get_position().y > (mid_h - v_sep / 2) && mb->get_position().y < (mid_h + v_sep / 2); + int mid_w = size.width * ratio_h; + int mid_h = size.height * ratio_v; - drag_begin_pos = mb->get_position(); - drag_begin_ratio.x = ratio_h; - drag_begin_ratio.y = ratio_v; + dragging_h = mb->get_position().x > (mid_w - h_sep / 2) && mb->get_position().x < (mid_w + h_sep / 2); + dragging_v = mb->get_position().y > (mid_h - v_sep / 2) && mb->get_position().y < (mid_h + v_sep / 2); - switch (view) { - case VIEW_USE_1_VIEWPORT: { + drag_begin_pos = mb->get_position(); + drag_begin_ratio.x = ratio_h; + drag_begin_ratio.y = ratio_v; - dragging_h = false; - dragging_v = false; + switch (view) { + case VIEW_USE_1_VIEWPORT: { - } break; - case VIEW_USE_2_VIEWPORTS: { + dragging_h = false; + dragging_v = false; - dragging_h = false; + } break; + case VIEW_USE_2_VIEWPORTS: { - } break; - case VIEW_USE_2_VIEWPORTS_ALT: { - - dragging_v = false; + dragging_h = false; - } break; - case VIEW_USE_3_VIEWPORTS: { + } break; + case VIEW_USE_2_VIEWPORTS_ALT: { - if (dragging_v) - dragging_h = false; - else dragging_v = false; - } break; - case VIEW_USE_3_VIEWPORTS_ALT: { + } break; + case VIEW_USE_3_VIEWPORTS: + case VIEW_USE_3_VIEWPORTS_ALT: + case VIEW_USE_4_VIEWPORTS: { - if (dragging_h) - dragging_v = false; - else - dragging_h = false; - } break; - case VIEW_USE_4_VIEWPORTS: { + // Do nothing. - } break; + } break; + } + } else { + dragging_h = false; + dragging_v = false; } } - if (mb.is_valid() && !mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) { - dragging_h = false; - dragging_v = false; - } - Ref<InputEventMouseMotion> mm = p_event; - if (mm.is_valid() && (dragging_h || dragging_v)) { + if (mm.is_valid()) { + + if (view == VIEW_USE_3_VIEWPORTS || view == VIEW_USE_3_VIEWPORTS_ALT || view == VIEW_USE_4_VIEWPORTS) { + Vector2 size = get_size(); + + int h_sep = get_constant("separation", "HSplitContainer"); + int v_sep = get_constant("separation", "VSplitContainer"); + + int mid_w = size.width * ratio_h; + int mid_h = size.height * ratio_v; + + bool was_hovering_h = hovering_h; + bool was_hovering_v = hovering_v; + hovering_h = mm->get_position().x > (mid_w - h_sep / 2) && mm->get_position().x < (mid_w + h_sep / 2); + hovering_v = mm->get_position().y > (mid_h - v_sep / 2) && mm->get_position().y < (mid_h + v_sep / 2); + + if (was_hovering_h != hovering_h || was_hovering_v != hovering_v) { + update(); + } + } if (dragging_h) { float new_ratio = drag_begin_ratio.x + (mm->get_position().x - drag_begin_pos.x) / get_size().width; @@ -3638,9 +3643,12 @@ void SpatialEditorViewportContainer::_notification(int p_what) { if (p_what == NOTIFICATION_DRAW && mouseover) { Ref<Texture> h_grabber = get_icon("grabber", "HSplitContainer"); - Ref<Texture> v_grabber = get_icon("grabber", "VSplitContainer"); + Ref<Texture> hdiag_grabber = get_icon("GuiViewportHdiagsplitter", "EditorIcons"); + Ref<Texture> vdiag_grabber = get_icon("GuiViewportVdiagsplitter", "EditorIcons"); + Ref<Texture> vh_grabber = get_icon("GuiViewportVhsplitter", "EditorIcons"); + Vector2 size = get_size(); int h_sep = get_constant("separation", "HSplitContainer"); @@ -3657,35 +3665,62 @@ void SpatialEditorViewportContainer::_notification(int p_what) { case VIEW_USE_1_VIEWPORT: { - //nothing to show + // Nothing to show. } break; case VIEW_USE_2_VIEWPORTS: { draw_texture(v_grabber, Vector2((size.width - v_grabber->get_width()) / 2, mid_h - v_grabber->get_height() / 2)); + set_default_cursor_shape(CURSOR_VSPLIT); } break; case VIEW_USE_2_VIEWPORTS_ALT: { draw_texture(h_grabber, Vector2(mid_w - h_grabber->get_width() / 2, (size.height - h_grabber->get_height()) / 2)); + set_default_cursor_shape(CURSOR_HSPLIT); } break; case VIEW_USE_3_VIEWPORTS: { - draw_texture(v_grabber, Vector2((size.width - v_grabber->get_width()) / 2, mid_h - v_grabber->get_height() / 2)); - draw_texture(h_grabber, Vector2(mid_w - h_grabber->get_width() / 2, mid_h + v_grabber->get_height() / 2 + (size_bottom - h_grabber->get_height()) / 2)); + if ((hovering_v && hovering_h && !dragging_v && !dragging_h) || (dragging_v && dragging_h)) { + draw_texture(hdiag_grabber, Vector2(mid_w - hdiag_grabber->get_width() / 2, mid_h - v_grabber->get_height() / 4)); + set_default_cursor_shape(CURSOR_DRAG); + } else if ((hovering_v && !dragging_h) || dragging_v) { + draw_texture(v_grabber, Vector2((size.width - v_grabber->get_width()) / 2, mid_h - v_grabber->get_height() / 2)); + set_default_cursor_shape(CURSOR_VSPLIT); + } else if (hovering_h || dragging_h) { + draw_texture(h_grabber, Vector2(mid_w - h_grabber->get_width() / 2, mid_h + v_grabber->get_height() / 2 + (size_bottom - h_grabber->get_height()) / 2)); + set_default_cursor_shape(CURSOR_HSPLIT); + } } break; case VIEW_USE_3_VIEWPORTS_ALT: { - draw_texture(v_grabber, Vector2((size_left - v_grabber->get_width()) / 2, mid_h - v_grabber->get_height() / 2)); - draw_texture(h_grabber, Vector2(mid_w - h_grabber->get_width() / 2, (size.height - h_grabber->get_height()) / 2)); + if ((hovering_v && hovering_h && !dragging_v && !dragging_h) || (dragging_v && dragging_h)) { + draw_texture(vdiag_grabber, Vector2(mid_w - vdiag_grabber->get_width() + v_grabber->get_height() / 4, mid_h - vdiag_grabber->get_height() / 2)); + set_default_cursor_shape(CURSOR_DRAG); + } else if ((hovering_v && !dragging_h) || dragging_v) { + draw_texture(v_grabber, Vector2((size_left - v_grabber->get_width()) / 2, mid_h - v_grabber->get_height() / 2)); + set_default_cursor_shape(CURSOR_VSPLIT); + } else if (hovering_h || dragging_h) { + draw_texture(h_grabber, Vector2(mid_w - h_grabber->get_width() / 2, (size.height - h_grabber->get_height()) / 2)); + set_default_cursor_shape(CURSOR_HSPLIT); + } + } break; case VIEW_USE_4_VIEWPORTS: { Vector2 half(mid_w, mid_h); - draw_texture(v_grabber, half - v_grabber->get_size() / 2.0); - draw_texture(h_grabber, half - h_grabber->get_size() / 2.0); + if ((hovering_v && hovering_h && !dragging_v && !dragging_h) || (dragging_v && dragging_h)) { + draw_texture(vh_grabber, half - vh_grabber->get_size() / 2.0); + set_default_cursor_shape(CURSOR_DRAG); + } else if ((hovering_v && !dragging_h) || dragging_v) { + draw_texture(v_grabber, half - v_grabber->get_size() / 2.0); + set_default_cursor_shape(CURSOR_VSPLIT); + } else if (hovering_h || dragging_h) { + draw_texture(h_grabber, half - h_grabber->get_size() / 2.0); + set_default_cursor_shape(CURSOR_HSPLIT); + } } break; } @@ -3729,6 +3764,7 @@ void SpatialEditorViewportContainer::_notification(int p_what) { case VIEW_USE_1_VIEWPORT: { + viewports[0]->show(); for (int i = 1; i < 4; i++) { viewports[i]->hide(); @@ -3739,7 +3775,7 @@ void SpatialEditorViewportContainer::_notification(int p_what) { } break; case VIEW_USE_2_VIEWPORTS: { - for (int i = 1; i < 4; i++) { + for (int i = 0; i < 4; i++) { if (i == 1 || i == 3) viewports[i]->hide(); @@ -3753,7 +3789,7 @@ void SpatialEditorViewportContainer::_notification(int p_what) { } break; case VIEW_USE_2_VIEWPORTS_ALT: { - for (int i = 1; i < 4; i++) { + for (int i = 0; i < 4; i++) { if (i == 1 || i == 3) viewports[i]->hide(); @@ -3766,7 +3802,7 @@ void SpatialEditorViewportContainer::_notification(int p_what) { } break; case VIEW_USE_3_VIEWPORTS: { - for (int i = 1; i < 4; i++) { + for (int i = 0; i < 4; i++) { if (i == 1) viewports[i]->hide(); @@ -3781,7 +3817,7 @@ void SpatialEditorViewportContainer::_notification(int p_what) { } break; case VIEW_USE_3_VIEWPORTS_ALT: { - for (int i = 1; i < 4; i++) { + for (int i = 0; i < 4; i++) { if (i == 1) viewports[i]->hide(); @@ -3796,7 +3832,7 @@ void SpatialEditorViewportContainer::_notification(int p_what) { } break; case VIEW_USE_4_VIEWPORTS: { - for (int i = 1; i < 4; i++) { + for (int i = 0; i < 4; i++) { viewports[i]->show(); } @@ -3829,10 +3865,13 @@ void SpatialEditorViewportContainer::_bind_methods() { SpatialEditorViewportContainer::SpatialEditorViewportContainer() { + set_clip_contents(true); view = VIEW_USE_1_VIEWPORT; mouseover = false; ratio_h = 0.5; ratio_v = 0.5; + hovering_v = false; + hovering_h = false; dragging_v = false; dragging_h = false; } @@ -3914,8 +3953,9 @@ void _update_all_gizmos(Node *p_node) { } } -void SpatialEditor::update_all_gizmos() { - _update_all_gizmos(SceneTree::get_singleton()->get_root()); +void SpatialEditor::update_all_gizmos(Node *p_node) { + if (!p_node) p_node = SceneTree::get_singleton()->get_root(); + _update_all_gizmos(p_node); } Object *SpatialEditor::_get_editor_data(Object *p_what) { @@ -4103,7 +4143,7 @@ void SpatialEditor::set_state(const Dictionary &p_state) { for (int j = 0; j < gizmo_plugins.size(); ++j) { if (!gizmo_plugins[j]->can_be_hidden()) continue; int state = EditorSpatialGizmoPlugin::ON_TOP; - for (uint32_t i = 0; i < keys.size(); i++) { + for (int i = 0; i < keys.size(); i++) { if (gizmo_plugins.write[j]->get_name() == keys[i]) { state = gizmos_status[keys[i]]; } @@ -4427,6 +4467,8 @@ void SpatialEditor::_menu_item_pressed(int p_option) { void SpatialEditor::_init_indicators() { { + origin_enabled = true; + grid_enabled = true; indicator_mat.instance(); indicator_mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true); @@ -4467,9 +4509,6 @@ void SpatialEditor::_init_indicators() { VS::get_singleton()->instance_set_layer_mask(origin_instance, 1 << SpatialEditorViewport::GIZMO_GRID_LAYER); VisualServer::get_singleton()->instance_geometry_set_cast_shadows_setting(origin_instance, VS::SHADOW_CASTING_SETTING_OFF); - - grid_enabled = true; - last_grid_snap = 1; } { @@ -4990,32 +5029,29 @@ void SpatialEditor::_unhandled_key_input(Ref<InputEvent> p_event) { if (!k->is_pressed()) return; - if (ED_IS_SHORTCUT("spatial_editor/tool_select", p_event)) + if (ED_IS_SHORTCUT("spatial_editor/tool_select", p_event)) { _menu_item_pressed(MENU_TOOL_SELECT); - - else if (ED_IS_SHORTCUT("spatial_editor/tool_move", p_event)) + } else if (ED_IS_SHORTCUT("spatial_editor/tool_move", p_event)) { _menu_item_pressed(MENU_TOOL_MOVE); - - else if (ED_IS_SHORTCUT("spatial_editor/tool_rotate", p_event)) + } else if (ED_IS_SHORTCUT("spatial_editor/tool_rotate", p_event)) { _menu_item_pressed(MENU_TOOL_ROTATE); - - else if (ED_IS_SHORTCUT("spatial_editor/tool_scale", p_event)) + } else if (ED_IS_SHORTCUT("spatial_editor/tool_scale", p_event)) { _menu_item_pressed(MENU_TOOL_SCALE); - else if (ED_IS_SHORTCUT("spatial_editor/snap_to_floor", p_event)) + } else if (ED_IS_SHORTCUT("spatial_editor/snap_to_floor", p_event)) { snap_selected_nodes_to_floor(); - - else if (ED_IS_SHORTCUT("spatial_editor/local_coords", p_event)) + } else if (ED_IS_SHORTCUT("spatial_editor/local_coords", p_event)) { if (are_local_coords_enabled()) { _menu_item_toggled(false, MENU_TOOL_LOCAL_COORDS); } else { _menu_item_toggled(true, MENU_TOOL_LOCAL_COORDS); } - else if (ED_IS_SHORTCUT("spatial_editor/snap", p_event)) + } else if (ED_IS_SHORTCUT("spatial_editor/snap", p_event)) { if (is_snap_enabled()) { _menu_item_toggled(false, MENU_TOOL_USE_SNAP); } else { _menu_item_toggled(true, MENU_TOOL_USE_SNAP); } + } } } } @@ -5291,6 +5327,8 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) { tool_button[TOOL_MODE_SELECT]->connect("pressed", this, "_menu_item_pressed", button_binds); tool_button[TOOL_MODE_SELECT]->set_tooltip(TTR("Select Mode (Q)") + "\n" + keycode_get_string(KEY_MASK_CMD) + TTR("Drag: Rotate\nAlt+Drag: Move\nAlt+RMB: Depth list selection")); + hbc_menu->add_child(memnew(VSeparator)); + tool_button[TOOL_MODE_MOVE] = memnew(ToolButton); hbc_menu->add_child(tool_button[TOOL_MODE_MOVE]); tool_button[TOOL_MODE_MOVE]->set_toggle_mode(true); @@ -5315,6 +5353,8 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) { tool_button[TOOL_MODE_SCALE]->connect("pressed", this, "_menu_item_pressed", button_binds); tool_button[TOOL_MODE_SCALE]->set_tooltip(TTR("Scale Mode (R)")); + hbc_menu->add_child(memnew(VSeparator)); + tool_button[TOOL_MODE_LIST_SELECT] = memnew(ToolButton); hbc_menu->add_child(tool_button[TOOL_MODE_LIST_SELECT]); tool_button[TOOL_MODE_LIST_SELECT]->set_toggle_mode(true); @@ -5335,8 +5375,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) { tool_button[TOOL_UNLOCK_SELECTED]->connect("pressed", this, "_menu_item_pressed", button_binds); tool_button[TOOL_UNLOCK_SELECTED]->set_tooltip(TTR("Unlock the selected object (can be moved).")); - VSeparator *vs = memnew(VSeparator); - hbc_menu->add_child(vs); + hbc_menu->add_child(memnew(VSeparator)); tool_option_button[TOOL_OPT_LOCAL_COORDS] = memnew(ToolButton); hbc_menu->add_child(tool_option_button[TOOL_OPT_LOCAL_COORDS]); @@ -5358,8 +5397,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) { sct = ED_GET_SHORTCUT("spatial_editor/snap").ptr()->get_as_text(); tool_option_button[TOOL_OPT_USE_SNAP]->set_tooltip(vformat(TTR("Snap Mode (%s)"), sct)); - vs = memnew(VSeparator); - hbc_menu->add_child(vs); + hbc_menu->add_child(memnew(VSeparator)); // Drag and drop support; preview_node = memnew(Spatial); @@ -5381,7 +5419,6 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) { ED_SHORTCUT("spatial_editor/tool_move", TTR("Tool Move"), KEY_W); ED_SHORTCUT("spatial_editor/tool_rotate", TTR("Tool Rotate"), KEY_E); ED_SHORTCUT("spatial_editor/tool_scale", TTR("Tool Scale"), KEY_R); - ED_SHORTCUT("spatial_editor/snap_to_floor", TTR("Snap To Floor"), KEY_PAGEDOWN); ED_SHORTCUT("spatial_editor/freelook_toggle", TTR("Toggle Freelook"), KEY_MASK_SHIFT + KEY_F); @@ -5392,7 +5429,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) { hbc_menu->add_child(transform_menu); p = transform_menu->get_popup(); - p->add_shortcut(ED_SHORTCUT("spatial_editor/snap_to_floor", TTR("Snap object to floor")), MENU_SNAP_TO_FLOOR); + p->add_shortcut(ED_SHORTCUT("spatial_editor/snap_to_floor", TTR("Snap object to floor"), KEY_PAGEDOWN), MENU_SNAP_TO_FLOOR); p->add_shortcut(ED_SHORTCUT("spatial_editor/configure_snap", TTR("Configure Snap...")), MENU_TRANSFORM_CONFIGURE_SNAP); p->add_separator(); p->add_shortcut(ED_SHORTCUT("spatial_editor/transform_dialog", TTR("Transform Dialog...")), MENU_TRANSFORM_DIALOG); @@ -5593,7 +5630,6 @@ void SpatialEditorPlugin::make_visible(bool p_visible) { spatial_editor->show(); spatial_editor->set_process(true); - spatial_editor->grab_focus(); } else { @@ -5664,7 +5700,7 @@ SpatialEditorPlugin::~SpatialEditorPlugin() { void EditorSpatialGizmoPlugin::create_material(const String &p_name, const Color &p_color, bool p_billboard, bool p_on_top, bool p_use_vertex_color) { - Color instanced_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/instanced", Color(0.7, 0.7, 0.7, 0.5)); + Color instanced_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/instanced", Color(0.7, 0.7, 0.7, 0.6)); Vector<Ref<SpatialMaterial> > mats; @@ -5706,7 +5742,7 @@ void EditorSpatialGizmoPlugin::create_material(const String &p_name, const Color void EditorSpatialGizmoPlugin::create_icon_material(const String &p_name, const Ref<Texture> &p_texture, bool p_on_top, const Color &p_albedo) { - Color instanced_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/instanced", Color(0.7, 0.7, 0.7, 0.5)); + Color instanced_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/instanced", Color(0.7, 0.7, 0.7, 0.6)); Vector<Ref<SpatialMaterial> > icons; @@ -5719,7 +5755,7 @@ void EditorSpatialGizmoPlugin::create_icon_material(const String &p_name, const Color color = instanced ? instanced_color : p_albedo; if (!selected) { - color.a *= 0.3; + color.a *= 0.85; } icon->set_albedo(color); diff --git a/editor/plugins/spatial_editor_plugin.h b/editor/plugins/spatial_editor_plugin.h index 5850c0dbf1..c552f21e39 100644 --- a/editor/plugins/spatial_editor_plugin.h +++ b/editor/plugins/spatial_editor_plugin.h @@ -86,7 +86,7 @@ public: Vector<Vector3> handles; Vector<Vector3> secondary_handles; - float selectable_icon_size = -1.0f; + float selectable_icon_size; bool billboard_handle; bool valid; @@ -127,9 +127,7 @@ public: virtual void redraw(); virtual void free(); - //TODO remove (?) virtual bool is_editable() const; - virtual bool can_draw() const; void set_hidden(bool p_hidden); void set_plugin(EditorSpatialGizmoPlugin *p_gizmo); @@ -226,7 +224,7 @@ private: void _compute_edit(const Point2 &p_point); void _clear_selected(); void _select_clicked(bool p_append, bool p_single); - void _select(Spatial *p_node, bool p_append, bool p_single); + void _select(Node *p_node, bool p_append, bool p_single); ObjectID _select_ray(const Point2 &p_pos, bool p_append, bool &r_includes_current, int *r_gizmo_handle = NULL, bool p_alt_select = false); void _find_items_at_pos(const Point2 &p_pos, bool &r_includes_current, Vector<_RayResult> &results, bool p_alt_select = false); Vector3 _get_ray_pos(const Vector2 &p_pos) const; @@ -406,6 +404,7 @@ public: AcceptDialog *p_accept); Viewport *get_viewport_node() { return viewport; } + Camera *get_camera() { return camera; } // return the default camera object. SpatialEditorViewport(SpatialEditor *p_spatial_editor, EditorNode *p_editor, int p_index); }; @@ -445,6 +444,9 @@ private: float ratio_h; float ratio_v; + bool hovering_v; + bool hovering_h; + bool dragging_v; bool dragging_h; Vector2 drag_begin_pos; @@ -512,7 +514,6 @@ private: RID grid[3]; RID grid_instance[3]; bool grid_visible[3]; //currently visible - float last_grid_snap; bool grid_enable[3]; //should be always visible if true bool grid_enabled; @@ -677,7 +678,7 @@ public: Ref<ArrayMesh> get_scale_plane_gizmo(int idx) const { return scale_plane_gizmo[idx]; } void update_transform_gizmo(); - void update_all_gizmos(); + void update_all_gizmos(Node *p_node = NULL); void snap_selected_nodes_to_floor(); void select_gizmo_highlight_axis(int p_axis); void set_custom_camera(Node *p_camera) { custom_camera = p_camera; } @@ -710,7 +711,6 @@ public: void register_gizmo_plugin(Ref<EditorSpatialGizmoPlugin> ref); - Camera *get_camera() { return NULL; } void edit(Spatial *p_spatial); void clear(); diff --git a/editor/plugins/sprite_editor_plugin.cpp b/editor/plugins/sprite_editor_plugin.cpp index 58a1835e68..c574b5e8ba 100644 --- a/editor/plugins/sprite_editor_plugin.cpp +++ b/editor/plugins/sprite_editor_plugin.cpp @@ -97,7 +97,7 @@ Vector<Vector2> expand(const Vector<Vector2> &points, const Rect2i &rect, float int lasti = p2->Contour.size() - 1; Vector2 prev = Vector2(p2->Contour[lasti].X / PRECISION, p2->Contour[lasti].Y / PRECISION); - for (int i = 0; i < p2->Contour.size(); i++) { + for (unsigned int i = 0; i < p2->Contour.size(); i++) { Vector2 cur = Vector2(p2->Contour[i].X / PRECISION, p2->Contour[i].Y / PRECISION); if (cur.distance_to(prev) > 0.5) { diff --git a/editor/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp index fcbbee2b9c..30246147c2 100644 --- a/editor/plugins/sprite_frames_editor_plugin.cpp +++ b/editor/plugins/sprite_frames_editor_plugin.cpp @@ -30,9 +30,9 @@ #include "sprite_frames_editor_plugin.h" +#include "core/io/resource_loader.h" +#include "core/project_settings.h" #include "editor/editor_settings.h" -#include "io/resource_loader.h" -#include "project_settings.h" #include "scene/3d/sprite_3d.h" void SpriteFramesEditor::_gui_input(Ref<InputEvent> p_event) { diff --git a/editor/plugins/text_editor.cpp b/editor/plugins/text_editor.cpp index 16c25f3074..4ff7046a35 100644 --- a/editor/plugins/text_editor.cpp +++ b/editor/plugins/text_editor.cpp @@ -30,6 +30,8 @@ #include "text_editor.h" +#include "editor_node.h" + void TextEditor::add_syntax_highlighter(SyntaxHighlighter *p_highlighter) { highlighters[p_highlighter->get_name()] = p_highlighter; highlighter_menu->add_radio_check_item(p_highlighter->get_name()); @@ -64,6 +66,7 @@ void TextEditor::_change_syntax_highlighter(int p_idx) { el = el->next(); } set_syntax_highlighter(highlighters[highlighter_menu->get_item_text(p_idx)]); + EditorSettings::get_singleton()->set_project_metadata("text_editor", "syntax_highlighter", p_idx); } void TextEditor::_load_theme_settings() { @@ -158,10 +161,7 @@ String TextEditor::get_name() { Ref<Texture> TextEditor::get_icon() { - if (get_parent_control() && get_parent_control()->has_icon(text_file->get_class(), "EditorIcons")) { - return get_parent_control()->get_icon(text_file->get_class(), "EditorIcons"); - } - return Ref<Texture>(); + return EditorNode::get_singleton()->get_object_icon(text_file.operator->(), ""); } RES TextEditor::get_edited_resource() const { @@ -299,7 +299,7 @@ void TextEditor::_notification(int p_what) { switch (p_what) { case NOTIFICATION_READY: _load_theme_settings(); - set_syntax_highlighter(NULL); + _change_syntax_highlighter(EditorSettings::get_singleton()->get_project_metadata("text_editor", "syntax_highlighter", 0)); break; } } @@ -475,7 +475,7 @@ void TextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) { int to_column = tx->get_selection_to_column(); if (row < from_line || row > to_line || (row == from_line && col < from_column) || (row == to_line && col > to_column)) { - // Right click is outside the seleted text + // Right click is outside the selected text tx->deselect(); } } diff --git a/editor/plugins/texture_editor_plugin.cpp b/editor/plugins/texture_editor_plugin.cpp index e891850870..140d37fdb5 100644 --- a/editor/plugins/texture_editor_plugin.cpp +++ b/editor/plugins/texture_editor_plugin.cpp @@ -30,9 +30,9 @@ #include "texture_editor_plugin.h" +#include "core/io/resource_loader.h" +#include "core/project_settings.h" #include "editor/editor_settings.h" -#include "io/resource_loader.h" -#include "project_settings.h" void TextureEditor::_gui_input(Ref<InputEvent> p_event) { } diff --git a/editor/plugins/texture_region_editor_plugin.cpp b/editor/plugins/texture_region_editor_plugin.cpp index 4390b94ece..33e1f7c6a3 100644 --- a/editor/plugins/texture_region_editor_plugin.cpp +++ b/editor/plugins/texture_region_editor_plugin.cpp @@ -31,8 +31,8 @@ #include "texture_region_editor_plugin.h" #include "core/core_string_names.h" -#include "os/input.h" -#include "os/keyboard.h" +#include "core/os/input.h" +#include "core/os/keyboard.h" #include "scene/gui/check_box.h" /** diff --git a/editor/plugins/theme_editor_plugin.cpp b/editor/plugins/theme_editor_plugin.cpp index 92b95963f9..acee1a6942 100644 --- a/editor/plugins/theme_editor_plugin.cpp +++ b/editor/plugins/theme_editor_plugin.cpp @@ -30,8 +30,8 @@ #include "theme_editor_plugin.h" -#include "os/file_access.h" -#include "version.h" +#include "core/os/file_access.h" +#include "core/version.h" void ThemeEditor::edit(const Ref<Theme> &p_theme) { diff --git a/editor/plugins/tile_map_editor_plugin.cpp b/editor/plugins/tile_map_editor_plugin.cpp index 34dd36692c..aa4338d775 100644 --- a/editor/plugins/tile_map_editor_plugin.cpp +++ b/editor/plugins/tile_map_editor_plugin.cpp @@ -31,10 +31,10 @@ #include "tile_map_editor_plugin.h" #include "canvas_item_editor_plugin.h" +#include "core/os/input.h" +#include "core/os/keyboard.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" -#include "os/input.h" -#include "os/keyboard.h" #include "scene/gui/split_container.h" void TileMapEditor::_notification(int p_what) { @@ -238,8 +238,8 @@ void TileMapEditor::_create_set_cell_undo(const Vector2 &p_vec, const CellOp &p_ cell_new["transpose"] = p_cell_new.tr; cell_new["auto_coord"] = p_cell_new.ac; - undo_redo->add_undo_method(node, "set_celld", p_vec, cell_old); - undo_redo->add_do_method(node, "set_celld", p_vec, cell_new); + undo_redo->add_undo_method(node, "_set_celld", p_vec, cell_old); + undo_redo->add_do_method(node, "_set_celld", p_vec, cell_new); } void TileMapEditor::_start_undo(const String &p_action) { @@ -457,36 +457,38 @@ void TileMapEditor::_update_palette() { palette->select(0); } - if ((manual_autotile && tileset->tile_get_tile_mode(sel_tile) == TileSet::AUTO_TILE) || tileset->tile_get_tile_mode(sel_tile) == TileSet::ATLAS_TILE) { + if (sel_tile != TileMap::INVALID_CELL) { + if ((manual_autotile && tileset->tile_get_tile_mode(sel_tile) == TileSet::AUTO_TILE) || tileset->tile_get_tile_mode(sel_tile) == TileSet::ATLAS_TILE) { - const Map<Vector2, uint16_t> &tiles = tileset->autotile_get_bitmask_map(sel_tile); + const Map<Vector2, uint16_t> &tiles = tileset->autotile_get_bitmask_map(sel_tile); - Vector<Vector2> entries; - for (const Map<Vector2, uint16_t>::Element *E = tiles.front(); E; E = E->next()) { - entries.push_back(E->key()); - } - entries.sort(); + Vector<Vector2> entries; + for (const Map<Vector2, uint16_t>::Element *E = tiles.front(); E; E = E->next()) { + entries.push_back(E->key()); + } + entries.sort(); - Ref<Texture> tex = tileset->tile_get_texture(sel_tile); + Ref<Texture> tex = tileset->tile_get_texture(sel_tile); - for (int i = 0; i < entries.size(); i++) { + for (int i = 0; i < entries.size(); i++) { - manual_palette->add_item(String()); + manual_palette->add_item(String()); - if (tex.is_valid()) { + if (tex.is_valid()) { - Rect2 region = tileset->tile_get_region(sel_tile); - int spacing = tileset->autotile_get_spacing(sel_tile); - region.size = tileset->autotile_get_size(sel_tile); // !! - region.position += (region.size + Vector2(spacing, spacing)) * entries[i]; + Rect2 region = tileset->tile_get_region(sel_tile); + int spacing = tileset->autotile_get_spacing(sel_tile); + region.size = tileset->autotile_get_size(sel_tile); // !! + region.position += (region.size + Vector2(spacing, spacing)) * entries[i]; - if (!region.has_no_area()) - manual_palette->set_item_icon_region(manual_palette->get_item_count() - 1, region); + if (!region.has_no_area()) + manual_palette->set_item_icon_region(manual_palette->get_item_count() - 1, region); - manual_palette->set_item_icon(manual_palette->get_item_count() - 1, tex); - } + manual_palette->set_item_icon(manual_palette->get_item_count() - 1, tex); + } - manual_palette->set_item_metadata(manual_palette->get_item_count() - 1, entries[i]); + manual_palette->set_item_metadata(manual_palette->get_item_count() - 1, entries[i]); + } } } @@ -684,7 +686,7 @@ void TileMapEditor::_erase_selection() { } } -void TileMapEditor::_draw_cell(int p_cell, const Point2i &p_point, bool p_flip_h, bool p_flip_v, bool p_transpose, const Transform2D &p_xform) { +void TileMapEditor::_draw_cell(Control *p_viewport, int p_cell, const Point2i &p_point, bool p_flip_h, bool p_flip_v, bool p_transpose, const Transform2D &p_xform) { Ref<Texture> t = node->get_tileset()->tile_get_texture(p_cell); @@ -781,19 +783,19 @@ void TileMapEditor::_draw_cell(int p_cell, const Point2i &p_point, bool p_flip_h modulate.a = 0.5; if (r.has_no_area()) - canvas_item_editor->draw_texture_rect(t, rect, false, modulate, p_transpose); + p_viewport->draw_texture_rect(t, rect, false, modulate, p_transpose); else - canvas_item_editor->draw_texture_rect_region(t, rect, r, modulate, p_transpose); + p_viewport->draw_texture_rect_region(t, rect, r, modulate, p_transpose); } -void TileMapEditor::_draw_fill_preview(int p_cell, const Point2i &p_point, bool p_flip_h, bool p_flip_v, bool p_transpose, const Transform2D &p_xform) { +void TileMapEditor::_draw_fill_preview(Control *p_viewport, int p_cell, const Point2i &p_point, bool p_flip_h, bool p_flip_v, bool p_transpose, const Transform2D &p_xform) { PoolVector<Vector2> points = _bucket_fill(p_point, false, true); PoolVector<Vector2>::Read pr = points.read(); int len = points.size(); for (int i = 0; i < len; ++i) { - _draw_cell(p_cell, pr[i], p_flip_h, p_flip_v, p_transpose, p_xform); + _draw_cell(p_viewport, p_cell, pr[i], p_flip_h, p_flip_v, p_transpose, p_xform); } } @@ -1388,17 +1390,17 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) { return false; } -void TileMapEditor::forward_draw_over_viewport(Control *p_overlay) { +void TileMapEditor::forward_canvas_draw_over_viewport(Control *p_overlay) { if (!node) return; Transform2D cell_xf = node->get_cell_transform(); - Transform2D xform = CanvasItemEditor::get_singleton()->get_canvas_transform() * node->get_global_transform(); + Transform2D xform = p_overlay->get_canvas_transform() * node->get_global_transform(); Transform2D xform_inv = xform.affine_inverse(); - Size2 screen_size = canvas_item_editor->get_size(); + Size2 screen_size = p_overlay->get_size(); { Rect2 aabb; aabb.position = node->world_to_map(xform_inv.xform(Vector2())); @@ -1417,7 +1419,7 @@ void TileMapEditor::forward_draw_over_viewport(Control *p_overlay) { Vector2 to = xform.xform(node->map_to_world(Vector2(i, si.position.y + si.size.y + 1))); Color col = i == 0 ? Color(1, 0.8, 0.2, 0.5) : Color(1, 0.3, 0.1, 0.2); - canvas_item_editor->draw_line(from, to, col, 1); + p_overlay->draw_line(from, to, col, 1); if (max_lines-- == 0) break; } @@ -1437,7 +1439,7 @@ void TileMapEditor::forward_draw_over_viewport(Control *p_overlay) { Vector2 from = xform.xform(node->map_to_world(Vector2(i, j), true) + ofs); Vector2 to = xform.xform(node->map_to_world(Vector2(i, j + 1), true) + ofs); Color col = i == 0 ? Color(1, 0.8, 0.2, 0.5) : Color(1, 0.3, 0.1, 0.2); - canvas_item_editor->draw_line(from, to, col, 1); + p_overlay->draw_line(from, to, col, 1); if (max_lines-- == 0) break; @@ -1455,7 +1457,7 @@ void TileMapEditor::forward_draw_over_viewport(Control *p_overlay) { Vector2 to = xform.xform(node->map_to_world(Vector2(si.position.x + si.size.x + 1, i))); Color col = i == 0 ? Color(1, 0.8, 0.2, 0.5) : Color(1, 0.3, 0.1, 0.2); - canvas_item_editor->draw_line(from, to, col, 1); + p_overlay->draw_line(from, to, col, 1); if (max_lines-- == 0) break; @@ -1474,7 +1476,7 @@ void TileMapEditor::forward_draw_over_viewport(Control *p_overlay) { Vector2 from = xform.xform(node->map_to_world(Vector2(j, i), true) + ofs); Vector2 to = xform.xform(node->map_to_world(Vector2(j + 1, i), true) + ofs); Color col = i == 0 ? Color(1, 0.8, 0.2, 0.5) : Color(1, 0.3, 0.1, 0.2); - canvas_item_editor->draw_line(from, to, col, 1); + p_overlay->draw_line(from, to, col, 1); if (max_lines-- == 0) break; @@ -1491,7 +1493,7 @@ void TileMapEditor::forward_draw_over_viewport(Control *p_overlay) { points.push_back(xform.xform(node->map_to_world((rectangle.position + Point2(rectangle.size.x + 1, rectangle.size.y + 1))))); points.push_back(xform.xform(node->map_to_world((rectangle.position + Point2(0, rectangle.size.y + 1))))); - canvas_item_editor->draw_colored_polygon(points, Color(0.2, 0.8, 1, 0.4)); + p_overlay->draw_colored_polygon(points, Color(0.2, 0.8, 1, 0.4)); } if (mouse_over) { @@ -1517,7 +1519,7 @@ void TileMapEditor::forward_draw_over_viewport(Control *p_overlay) { col = Color(1.0, 0.4, 0.2, 0.8); for (int i = 0; i < 4; i++) - canvas_item_editor->draw_line(endpoints[i], endpoints[(i + 1) % 4], col, 2); + p_overlay->draw_line(endpoints[i], endpoints[(i + 1) % 4], col, 2); bool bucket_preview = EditorSettings::get_singleton()->get("editors/tile_map/bucket_fill_preview"); if (tool == TOOL_SELECTING || tool == TOOL_PICKING || !bucket_preview) { @@ -1536,7 +1538,7 @@ void TileMapEditor::forward_draw_over_viewport(Control *p_overlay) { for (Map<Point2i, CellOp>::Element *E = paint_undo.front(); E; E = E->next()) { - _draw_cell(ids[0], E->key(), flip_h, flip_v, transpose, xform); + _draw_cell(p_overlay, ids[0], E->key(), flip_h, flip_v, transpose, xform); } } else if (tool == TOOL_RECTANGLE_PAINT) { @@ -1549,7 +1551,7 @@ void TileMapEditor::forward_draw_over_viewport(Control *p_overlay) { for (int i = rectangle.position.y; i <= rectangle.position.y + rectangle.size.y; i++) { for (int j = rectangle.position.x; j <= rectangle.position.x + rectangle.size.x; j++) { - _draw_cell(ids[0], Point2i(j, i), flip_h, flip_v, transpose, xform); + _draw_cell(p_overlay, ids[0], Point2i(j, i), flip_h, flip_v, transpose, xform); } } } else if (tool == TOOL_PASTING) { @@ -1571,7 +1573,7 @@ void TileMapEditor::forward_draw_over_viewport(Control *p_overlay) { TileData tcd = E->get(); - _draw_cell(tcd.cell, tcd.pos + ofs, tcd.flip_h, tcd.flip_v, tcd.transpose, xform); + _draw_cell(p_overlay, tcd.cell, tcd.pos + ofs, tcd.flip_h, tcd.flip_v, tcd.transpose, xform); } Rect2i duplicate = rectangle; @@ -1583,12 +1585,12 @@ void TileMapEditor::forward_draw_over_viewport(Control *p_overlay) { points.push_back(xform.xform(node->map_to_world((duplicate.position + Point2(duplicate.size.x + 1, duplicate.size.y + 1))))); points.push_back(xform.xform(node->map_to_world((duplicate.position + Point2(0, duplicate.size.y + 1))))); - canvas_item_editor->draw_colored_polygon(points, Color(0.2, 1.0, 0.8, 0.2)); + p_overlay->draw_colored_polygon(points, Color(0.2, 1.0, 0.8, 0.2)); } else if (tool == TOOL_BUCKET) { Vector<int> tiles = get_selected_tiles(); - _draw_fill_preview(tiles[0], over_tile, flip_h, flip_v, transpose, xform); + _draw_fill_preview(p_overlay, tiles[0], over_tile, flip_h, flip_v, transpose, xform); } else { @@ -1597,7 +1599,7 @@ void TileMapEditor::forward_draw_over_viewport(Control *p_overlay) { if (st.size() == 1 && st[0] == TileMap::INVALID_CELL) return; - _draw_cell(st[0], over_tile, flip_h, flip_v, transpose, xform); + _draw_cell(p_overlay, st[0], over_tile, flip_h, flip_v, transpose, xform); } } } diff --git a/editor/plugins/tile_map_editor_plugin.h b/editor/plugins/tile_map_editor_plugin.h index c824824d56..74aece6f47 100644 --- a/editor/plugins/tile_map_editor_plugin.h +++ b/editor/plugins/tile_map_editor_plugin.h @@ -168,8 +168,8 @@ class TileMapEditor : public VBoxContainer { void _select(const Point2i &p_from, const Point2i &p_to); void _erase_selection(); - void _draw_cell(int p_cell, const Point2i &p_point, bool p_flip_h, bool p_flip_v, bool p_transpose, const Transform2D &p_xform); - void _draw_fill_preview(int p_cell, const Point2i &p_point, bool p_flip_h, bool p_flip_v, bool p_transpose, const Transform2D &p_xform); + void _draw_cell(Control *p_viewport, int p_cell, const Point2i &p_point, bool p_flip_h, bool p_flip_v, bool p_transpose, const Transform2D &p_xform); + void _draw_fill_preview(Control *p_viewport, int p_cell, const Point2i &p_point, bool p_flip_h, bool p_flip_v, bool p_transpose, const Transform2D &p_xform); void _clear_bucket_cache(); void _update_copydata(); @@ -206,7 +206,7 @@ public: HBoxContainer *get_toolbar() const { return toolbar; } bool forward_gui_input(const Ref<InputEvent> &p_event); - void forward_draw_over_viewport(Control *p_overlay); + void forward_canvas_draw_over_viewport(Control *p_overlay); void edit(Node *p_tile_map); @@ -225,7 +225,7 @@ protected: public: virtual bool forward_canvas_gui_input(const Ref<InputEvent> &p_event) { return tile_map_editor->forward_gui_input(p_event); } - virtual void forward_draw_over_viewport(Control *p_overlay) { tile_map_editor->forward_draw_over_viewport(p_overlay); } + virtual void forward_canvas_draw_over_viewport(Control *p_overlay) { tile_map_editor->forward_canvas_draw_over_viewport(p_overlay); } virtual String get_name() const { return "TileMap"; } bool has_main_screen() const { return false; } diff --git a/editor/plugins/tile_set_editor_plugin.cpp b/editor/plugins/tile_set_editor_plugin.cpp index 55a04a51b3..3de2284cea 100644 --- a/editor/plugins/tile_set_editor_plugin.cpp +++ b/editor/plugins/tile_set_editor_plugin.cpp @@ -498,7 +498,7 @@ void TileSetEditor::_on_tileset_toolbar_button_pressed(int p_index) { } break; case TOOL_TILESET_REMOVE_TEXTURE: { if (get_current_texture().is_valid()) { - cd->set_text(TTR("Remove Selected Textue and ALL TILES wich uses it?")); + cd->set_text(TTR("Remove selected texture and ALL TILES which use it?")); cd->popup_centered(Size2(300, 60)); } else { err_dialog->set_text(TTR("You haven't selected a texture to remove.")); @@ -581,7 +581,7 @@ void TileSetEditor::_on_textures_added(const PoolStringArray &p_paths) { texture_list->select(texture_list->get_item_count() - 1); _on_texture_list_selected(texture_list->get_item_count() - 1); if (invalid_count > 0) { - err_dialog->set_text(String::num(invalid_count, 0) + TTR(" file(s) was not added because was already on the list.")); + err_dialog->set_text(vformat(TTR("%s file(s) were not added because was already on the list."), String::num(invalid_count, 0))); err_dialog->popup_centered(Size2(300, 60)); } } @@ -795,6 +795,7 @@ void TileSetEditor::_on_workspace_draw() { spin_priority->set_suffix(" / " + String::num(total, 0)); draw_highlight_subtile(edited_shape_coord, queue_others); } break; + default: {} } draw_tile_subdivision(get_current_tile(), Color(0.347214, 0.722656, 0.617063)); @@ -1365,6 +1366,7 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) { } } } break; + default: {} } } } @@ -1434,6 +1436,7 @@ void TileSetEditor::_on_tool_clicked(int p_tool) { workspace->update(); } } break; + default: {} } } } else if (p_tool == ZOOM_OUT) { @@ -1715,16 +1718,18 @@ void TileSetEditor::draw_polygon_shapes() { Vector<Vector2> polygon; Vector<Color> colors; + Vector2 anchor = WORKSPACE_MARGIN; + anchor += tileset->tile_get_region(get_current_tile()).position; for (int j = 0; j < shape->get_polygon().size(); j++) { - polygon.push_back(shape->get_polygon()[j]); + polygon.push_back(shape->get_polygon()[j] + anchor); colors.push_back(c_bg); } workspace->draw_polygon(polygon, colors); for (int j = 0; j < shape->get_polygon().size() - 1; j++) { - workspace->draw_line(shape->get_polygon()[j], shape->get_polygon()[j + 1], c_border, 1, true); + workspace->draw_line(shape->get_polygon()[j] + anchor, shape->get_polygon()[j + 1] + anchor, c_border, 1, true); } - workspace->draw_line(shape->get_polygon()[shape->get_polygon().size() - 1], shape->get_polygon()[0], c_border, 1, true); + workspace->draw_line(shape->get_polygon()[shape->get_polygon().size() - 1] + anchor, shape->get_polygon()[0] + anchor, c_border, 1, true); if (shape == edited_occlusion_shape) { draw_handles = true; } @@ -1788,10 +1793,11 @@ void TileSetEditor::draw_polygon_shapes() { Vector<Vector2> polygon; Vector<Color> colors; - + Vector2 anchor = WORKSPACE_MARGIN; + anchor += tileset->tile_get_region(get_current_tile()).position; PoolVector<Vector2> vertices = shape->get_vertices(); for (int j = 0; j < shape->get_polygon(0).size(); j++) { - polygon.push_back(vertices[shape->get_polygon(0)[j]]); + polygon.push_back(vertices[shape->get_polygon(0)[j]] + anchor); colors.push_back(c_bg); } workspace->draw_polygon(polygon, colors); @@ -1799,7 +1805,7 @@ void TileSetEditor::draw_polygon_shapes() { if (shape->get_polygon_count() > 0) { PoolVector<Vector2> vertices = shape->get_vertices(); for (int j = 0; j < shape->get_polygon(0).size() - 1; j++) { - workspace->draw_line(vertices[shape->get_polygon(0)[j]], vertices[shape->get_polygon(0)[j + 1]], c_border, 1, true); + workspace->draw_line(vertices[shape->get_polygon(0)[j]] + anchor, vertices[shape->get_polygon(0)[j + 1]] + anchor, c_border, 1, true); } if (shape == edited_navigation_shape) { draw_handles = true; @@ -1859,6 +1865,7 @@ void TileSetEditor::draw_polygon_shapes() { } } } break; + default: {} } if (creating_shape) { for (int j = 0; j < current_shape.size() - 1; j++) { @@ -1954,6 +1961,8 @@ void TileSetEditor::close_shape(const Vector2 &shape_anchor) { void TileSetEditor::select_coord(const Vector2 &coord) { current_shape = PoolVector2Array(); + if (get_current_tile() == -1) + return; Rect2 current_tile_region = tileset->tile_get_region(get_current_tile()); current_tile_region.position += WORKSPACE_MARGIN; if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::SINGLE_TILE) { @@ -2038,8 +2047,10 @@ Vector2 TileSetEditor::snap_point(const Vector2 &point) { anchor += tileset->tile_get_region(get_current_tile()).position; anchor += WORKSPACE_MARGIN; Rect2 region(anchor, tile_size); - if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::SINGLE_TILE) + if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::SINGLE_TILE) { region.position = tileset->tile_get_region(get_current_tile()).position + WORKSPACE_MARGIN; + region.size = tileset->tile_get_region(get_current_tile()).size; + } if (tools[TOOL_GRID_SNAP]->is_pressed()) { p.x = Math::snap_scalar_seperation(snap_offset.x, snap_step.x, p.x, snap_separation.x); @@ -2254,6 +2265,9 @@ bool TilesetEditorContext::_set(const StringName &p_name, const Variant &p_value tileset_editor->workspace_overlay->update(); } return v; + } else if (name == "tileset_script") { + tileset->set_script(p_value); + return true; } tileset_editor->err_dialog->set_text(TTR("This property can't be changed.")); @@ -2302,6 +2316,9 @@ bool TilesetEditorContext::_get(const StringName &p_name, Variant &r_ret) const } else if (name == "selected_occlusion") { r_ret = tileset_editor->edited_occlusion_shape; v = true; + } else if (name == "tileset_script") { + r_ret = tileset->get_script(); + v = true; } return v; } @@ -2346,6 +2363,9 @@ void TilesetEditorContext::_get_property_list(List<PropertyInfo> *p_list) const if (tileset_editor->edit_mode == TileSetEditor::EDITMODE_OCCLUSION && tileset_editor->edited_occlusion_shape.is_valid()) { p_list->push_back(PropertyInfo(Variant::OBJECT, "selected_occlusion", PROPERTY_HINT_RESOURCE_TYPE, tileset_editor->edited_occlusion_shape->get_class())); } + if (!tileset.is_null()) { + p_list->push_back(PropertyInfo(Variant::OBJECT, "tileset_script", PROPERTY_HINT_RESOURCE_TYPE, "Script")); + } } TilesetEditorContext::TilesetEditorContext(TileSetEditor *p_tileset_editor) { diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index 63e89b78ea..39e50ec7f8 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -1,10 +1,40 @@ +/*************************************************************************/ +/* visual_shader_editor_plugin.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + #include "visual_shader_editor_plugin.h" #include "core/io/resource_loader.h" +#include "core/os/input.h" +#include "core/os/keyboard.h" #include "core/project_settings.h" #include "editor/editor_properties.h" -#include "os/input.h" -#include "os/keyboard.h" #include "scene/animation/animation_player.h" #include "scene/gui/menu_button.h" #include "scene/gui/panel.h" @@ -480,6 +510,17 @@ void VisualShaderEditor::_connection_request(const String &p_from, int p_from_in } undo_redo->create_action("Nodes Connected"); + + List<VisualShader::Connection> conns; + visual_shader->get_node_connections(type, &conns); + + for (List<VisualShader::Connection>::Element *E = conns.front(); E; E = E->next()) { + if (E->get().to_node == to && E->get().to_port == p_to_index) { + undo_redo->add_do_method(visual_shader.ptr(), "disconnect_nodes", type, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port); + undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes", type, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port); + } + } + undo_redo->add_do_method(visual_shader.ptr(), "connect_nodes", type, from, p_from_index, to, p_to_index); undo_redo->add_undo_method(visual_shader.ptr(), "disconnect_nodes", type, from, p_from_index, to, p_to_index); undo_redo->add_do_method(this, "_update_graph"); @@ -599,7 +640,7 @@ void VisualShaderEditor::_duplicate_nodes() { int id = String(graph->get_child(i)->get_name()).to_int(); Ref<VisualShaderNode> node = visual_shader->get_node(type, id); Ref<VisualShaderNodeOutput> output = node; - if (output.is_valid()) //cant duplicate output + if (output.is_valid()) //can't duplicate output continue; if (node.is_valid()) { nodes.push_back(id); @@ -902,7 +943,10 @@ public: class VisualShaderNodePluginDefaultEditor : public VBoxContainer { GDCLASS(VisualShaderNodePluginDefaultEditor, VBoxContainer) public: - void _property_changed(const String &prop, const Variant &p_value) { + void _property_changed(const String &prop, const Variant &p_value, bool p_changing = false) { + + if (p_changing) + return; UndoRedo *undo_redo = EditorNode::get_singleton()->get_undo_redo(); @@ -949,7 +993,7 @@ public: } static void _bind_methods() { - ClassDB::bind_method("_property_changed", &VisualShaderNodePluginDefaultEditor::_property_changed); + ClassDB::bind_method("_property_changed", &VisualShaderNodePluginDefaultEditor::_property_changed, DEFVAL(false)); ClassDB::bind_method("_node_changed", &VisualShaderNodePluginDefaultEditor::_node_changed); ClassDB::bind_method("_refresh_request", &VisualShaderNodePluginDefaultEditor::_refresh_request); } @@ -1128,7 +1172,7 @@ bool EditorInspectorShaderModePlugin::parse_property(Object *p_object, Variant:: return true; } - return false; //can be overriden, although it will most likely be last anyway + return false; //can be overridden, although it will most likely be last anyway } void EditorInspectorShaderModePlugin::parse_end() { diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h index f86374ff6b..49a51ede8f 100644 --- a/editor/plugins/visual_shader_editor_plugin.h +++ b/editor/plugins/visual_shader_editor_plugin.h @@ -1,3 +1,33 @@ +/*************************************************************************/ +/* visual_shader_editor_plugin.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + #ifndef VISUAL_SHADER_EDITOR_PLUGIN_H #define VISUAL_SHADER_EDITOR_PLUGIN_H diff --git a/editor/progress_dialog.cpp b/editor/progress_dialog.cpp index f735ef97db..29a780961e 100644 --- a/editor/progress_dialog.cpp +++ b/editor/progress_dialog.cpp @@ -30,10 +30,10 @@ #include "progress_dialog.h" +#include "core/message_queue.h" +#include "core/os/os.h" #include "editor_scale.h" #include "main/main.h" -#include "message_queue.h" -#include "os/os.h" void BackgroundProgress::_add_task(const String &p_task, const String &p_label, int p_steps) { diff --git a/editor/project_export.cpp b/editor/project_export.cpp index 019d5d382c..fa6dce1771 100644 --- a/editor/project_export.cpp +++ b/editor/project_export.cpp @@ -30,17 +30,17 @@ #include "project_export.h" -#include "compressed_translation.h" +#include "core/compressed_translation.h" +#include "core/io/image_loader.h" +#include "core/io/resource_loader.h" +#include "core/io/resource_saver.h" +#include "core/os/dir_access.h" +#include "core/os/file_access.h" +#include "core/os/os.h" +#include "core/project_settings.h" #include "editor_data.h" #include "editor_node.h" #include "editor_settings.h" -#include "io/image_loader.h" -#include "io/resource_loader.h" -#include "io/resource_saver.h" -#include "os/dir_access.h" -#include "os/file_access.h" -#include "os/os.h" -#include "project_settings.h" #include "scene/gui/box_container.h" #include "scene/gui/margin_container.h" #include "scene/gui/scroll_container.h" @@ -655,16 +655,9 @@ bool ProjectExportDialog::_fill_tree(EditorFileSystemDirectory *p_dir, TreeItem file->set_cell_mode(0, TreeItem::CELL_MODE_CHECK); file->set_text(0, p_dir->get_file(i)); - Ref<Texture> tex; - if (has_icon(type, editor_icons)) { - tex = get_icon(type, editor_icons); - } else { - tex = get_icon("Object", editor_icons); - } - String path = p_dir->get_file_path(i); - file->set_icon(0, tex); + file->set_icon(0, EditorNode::get_singleton()->get_class_icon(type)); file->set_editable(0, true); file->set_checked(0, current->has_export_file(path)); file->set_metadata(0, path); @@ -723,6 +716,25 @@ void ProjectExportDialog::_open_export_template_manager() { hide(); } +void ProjectExportDialog::_validate_export_path(const String &p_path) { + // Disable export via OK button or Enter key if LineEdit has an empty filename + bool invalid_path = (p_path.get_file().get_basename() == ""); + + // Check if state change before needlessly messing with signals + if (invalid_path && export_project->get_ok()->is_disabled()) + return; + if (!invalid_path && !export_project->get_ok()->is_disabled()) + return; + + if (invalid_path) { + export_project->get_ok()->set_disabled(true); + export_project->get_line_edit()->disconnect("text_entered", export_project, "_file_entered"); + } else { + export_project->get_ok()->set_disabled(false); + export_project->get_line_edit()->connect("text_entered", export_project, "_file_entered"); + } +} + void ProjectExportDialog::_export_project() { Ref<EditorExportPreset> current = EditorExport::get_singleton()->get_export_preset(presets->get_current()); @@ -732,12 +744,19 @@ void ProjectExportDialog::_export_project() { export_project->set_access(FileDialog::ACCESS_FILESYSTEM); export_project->clear_filters(); - export_project->set_current_file(default_filename); String extension = platform->get_binary_extension(current); - if (extension != String()) { export_project->add_filter("*." + extension + " ; " + platform->get_name() + " Export"); + export_project->set_current_file(default_filename + "." + extension); + } else { + export_project->set_current_file(default_filename); + } + + // Ensure that signal is connected if previous attempt left it disconnected with _validate_export_path + if (!export_project->get_line_edit()->is_connected("text_entered", export_project, "_file_entered")) { + export_project->get_ok()->set_disabled(false); + export_project->get_line_edit()->connect("text_entered", export_project, "_file_entered"); } export_project->set_mode(FileDialog::MODE_SAVE_FILE); @@ -746,7 +765,7 @@ void ProjectExportDialog::_export_project() { void ProjectExportDialog::_export_project_to_path(const String &p_path) { // Save this name for use in future exports (but drop the file extension) - default_filename = p_path.get_basename().get_file(); + default_filename = p_path.get_file().get_basename(); EditorSettings::get_singleton()->set_project_metadata("export_options", "default_filename", default_filename); Ref<EditorExportPreset> current = EditorExport::get_singleton()->get_export_preset(presets->get_current()); @@ -785,11 +804,13 @@ void ProjectExportDialog::_bind_methods() { ClassDB::bind_method("_export_pck_zip", &ProjectExportDialog::_export_pck_zip); ClassDB::bind_method("_export_pck_zip_selected", &ProjectExportDialog::_export_pck_zip_selected); ClassDB::bind_method("_open_export_template_manager", &ProjectExportDialog::_open_export_template_manager); + ClassDB::bind_method("_validate_export_path", &ProjectExportDialog::_validate_export_path); ClassDB::bind_method("_export_project", &ProjectExportDialog::_export_project); ClassDB::bind_method("_export_project_to_path", &ProjectExportDialog::_export_project_to_path); ClassDB::bind_method("_custom_features_changed", &ProjectExportDialog::_custom_features_changed); ClassDB::bind_method("_tab_changed", &ProjectExportDialog::_tab_changed); } + ProjectExportDialog::ProjectExportDialog() { set_title(TTR("Export")); @@ -942,6 +963,9 @@ ProjectExportDialog::ProjectExportDialog() { get_cancel()->set_text(TTR("Close")); get_ok()->set_text(TTR("Export PCK/Zip")); export_button = add_button(TTR("Export Project"), !OS::get_singleton()->get_swap_ok_cancel(), "export"); + export_button->connect("pressed", this, "_export_project"); + // Disable initially before we select a valid preset + export_button->set_disabled(true); export_pck_zip = memnew(FileDialog); export_pck_zip->add_filter("*.zip ; ZIP File"); @@ -981,7 +1005,7 @@ ProjectExportDialog::ProjectExportDialog() { export_project->set_access(FileDialog::ACCESS_FILESYSTEM); add_child(export_project); export_project->connect("file_selected", this, "_export_project_to_path"); - export_button->connect("pressed", this, "_export_project"); + export_project->get_line_edit()->connect("text_changed", this, "_validate_export_path"); export_debug = memnew(CheckButton); export_debug->set_text(TTR("Export With Debug")); @@ -997,10 +1021,14 @@ ProjectExportDialog::ProjectExportDialog() { editor_icons = "EditorIcons"; - default_filename = EditorSettings::get_singleton()->get_project_metadata("export_options", "default_filename", String()); - + default_filename = EditorSettings::get_singleton()->get_project_metadata("export_options", "default_filename", ""); + // If no default set, use project name if (default_filename == "") { + // If no project name defined, use a sane default default_filename = ProjectSettings::get_singleton()->get("application/config/name"); + if (default_filename == "") { + default_filename = "UnnamedProject"; + } } } diff --git a/editor/project_export.h b/editor/project_export.h index 1f8723febd..552c6d7faf 100644 --- a/editor/project_export.h +++ b/editor/project_export.h @@ -136,6 +136,7 @@ private: void _export_pck_zip(); void _export_pck_zip_selected(const String &p_path); + void _validate_export_path(const String &p_path); void _export_project(); void _export_project_to_path(const String &p_path); diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp index 3a6a73d3cc..83de5a646a 100644 --- a/editor/project_manager.cpp +++ b/editor/project_manager.cpp @@ -30,18 +30,20 @@ #include "project_manager.h" -#include "editor_initialize_ssl.h" +#include "core/io/config_file.h" +#include "core/io/resource_saver.h" +#include "core/io/stream_peer_ssl.h" +#include "core/io/zip_io.h" +#include "core/os/dir_access.h" +#include "core/os/file_access.h" +#include "core/os/keyboard.h" +#include "core/os/os.h" +#include "core/translation.h" +#include "core/version.h" +#include "core/version_hash.gen.h" #include "editor_scale.h" #include "editor_settings.h" #include "editor_themes.h" -#include "io/config_file.h" -#include "io/resource_saver.h" -#include "io/stream_peer_ssl.h" -#include "io/zip_io.h" -#include "os/dir_access.h" -#include "os/file_access.h" -#include "os/keyboard.h" -#include "os/os.h" #include "scene/gui/center_container.h" #include "scene/gui/line_edit.h" #include "scene/gui/margin_container.h" @@ -49,9 +51,6 @@ #include "scene/gui/separator.h" #include "scene/gui/texture_rect.h" #include "scene/gui/tool_button.h" -#include "translation.h" -#include "version.h" -#include "version_hash.gen.h" class ProjectDialog : public ConfirmationDialog { @@ -1000,6 +999,10 @@ void ProjectManager::_unhandled_input(const Ref<InputEvent> &p_ev) { _open_project(); } break; + case KEY_DELETE: { + + _erase_project(); + } break; case KEY_HOME: { for (int i = 0; i < scroll_children->get_child_count(); i++) { @@ -1751,7 +1754,11 @@ ProjectManager::ProjectManager() { } break; } +#ifndef OSX_ENABLED + // The macOS platform implementation uses its own hiDPI window resizing code + // TODO: Resize windows on hiDPI displays on Windows and Linux and remove the line below OS::get_singleton()->set_window_size(OS::get_singleton()->get_window_size() * MAX(1, EDSCALE)); +#endif } FileDialog::set_default_show_hidden_files(EditorSettings::get_singleton()->get("filesystem/file_dialog/show_hidden_files")); @@ -2055,8 +2062,6 @@ void ProjectListFilter::_bind_methods() { ProjectListFilter::ProjectListFilter() { - editor_initialize_certificates(); //for asset sharing - _current_filter = FILTER_NAME; filter_option = memnew(OptionButton); diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp index a7c336eb16..7a68646f40 100644 --- a/editor/project_settings_editor.cpp +++ b/editor/project_settings_editor.cpp @@ -1750,12 +1750,9 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) { globals_editor = memnew(SectionedInspector); props_base->add_child(globals_editor); globals_editor->get_inspector()->set_undo_redo(EditorNode::get_singleton()->get_undo_redo()); - globals_editor->get_inspector()->set_property_selectable(true); - //globals_editor->hide_top_label(); globals_editor->set_v_size_flags(Control::SIZE_EXPAND_FILL); globals_editor->register_search_box(search_box); globals_editor->get_inspector()->connect("property_selected", this, "_item_selected"); - //globals_editor->get_inspector()->connect("property_toggled", this, "_item_checked", varray(), CONNECT_DEFERRED); globals_editor->get_inspector()->connect("property_edited", this, "_settings_prop_edited"); globals_editor->get_inspector()->connect("restart_requested", this, "_editor_restart_request"); @@ -1843,9 +1840,9 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) { input_editor->set_column_title(0, TTR("Action")); input_editor->set_column_title(1, TTR("Deadzone")); input_editor->set_column_expand(1, false); - input_editor->set_column_min_width(1, 80); + input_editor->set_column_min_width(1, 80 * EDSCALE); input_editor->set_column_expand(2, false); - input_editor->set_column_min_width(2, 50); + input_editor->set_column_min_width(2, 50 * EDSCALE); input_editor->connect("item_edited", this, "_action_edited"); input_editor->connect("item_activated", this, "_action_activated"); input_editor->connect("cell_selected", this, "_action_selected"); diff --git a/editor/property_editor.cpp b/editor/property_editor.cpp index d9812f7425..c611327a31 100644 --- a/editor/property_editor.cpp +++ b/editor/property_editor.cpp @@ -34,6 +34,7 @@ #include "core/io/image_loader.h" #include "core/io/marshalls.h" #include "core/io/resource_loader.h" +#include "core/math/expression.h" #include "core/os/input.h" #include "core/os/keyboard.h" #include "core/pair.h" @@ -1531,21 +1532,24 @@ void CustomPropertyEditor::_modified(String p_string) { updating = true; switch (type) { case Variant::INT: { - - if (evaluator) - v = evaluator->eval(value_editor[0]->get_text()); - else + String text = value_editor[0]->get_text(); + Ref<Expression> expr; + expr.instance(); + Error err = expr->parse(text); + if (err != OK) { v = value_editor[0]->get_text().to_int(); + return; + } else { + v = expr->execute(Array(), NULL, false); + } emit_signal("variant_changed"); } break; case Variant::REAL: { if (hint != PROPERTY_HINT_EXP_EASING) { - if (evaluator) - v = evaluator->eval(value_editor[0]->get_text()); - else - v = value_editor[0]->get_text().to_double(); + String text = value_editor[0]->get_text(); + v = _parse_real_expression(text); emit_signal("variant_changed"); } @@ -1558,13 +1562,8 @@ void CustomPropertyEditor::_modified(String p_string) { case Variant::VECTOR2: { Vector2 vec; - if (evaluator) { - vec.x = evaluator->eval(value_editor[0]->get_text()); - vec.y = evaluator->eval(value_editor[1]->get_text()); - } else { - vec.x = value_editor[0]->get_text().to_double(); - vec.y = value_editor[1]->get_text().to_double(); - } + vec.x = _parse_real_expression(value_editor[0]->get_text()); + vec.y = _parse_real_expression(value_editor[1]->get_text()); v = vec; _emit_changed_whole_or_field(); @@ -1572,17 +1571,11 @@ void CustomPropertyEditor::_modified(String p_string) { case Variant::RECT2: { Rect2 r2; - if (evaluator) { - r2.position.x = evaluator->eval(value_editor[0]->get_text()); - r2.position.y = evaluator->eval(value_editor[1]->get_text()); - r2.size.x = evaluator->eval(value_editor[2]->get_text()); - r2.size.y = evaluator->eval(value_editor[3]->get_text()); - } else { - r2.position.x = value_editor[0]->get_text().to_double(); - r2.position.y = value_editor[1]->get_text().to_double(); - r2.size.x = value_editor[2]->get_text().to_double(); - r2.size.y = value_editor[3]->get_text().to_double(); - } + + r2.position.x = _parse_real_expression(value_editor[0]->get_text()); + r2.position.y = _parse_real_expression(value_editor[1]->get_text()); + r2.size.x = _parse_real_expression(value_editor[2]->get_text()); + r2.size.y = _parse_real_expression(value_editor[3]->get_text()); v = r2; _emit_changed_whole_or_field(); @@ -1591,15 +1584,9 @@ void CustomPropertyEditor::_modified(String p_string) { case Variant::VECTOR3: { Vector3 vec; - if (evaluator) { - vec.x = evaluator->eval(value_editor[0]->get_text()); - vec.y = evaluator->eval(value_editor[1]->get_text()); - vec.z = evaluator->eval(value_editor[2]->get_text()); - } else { - vec.x = value_editor[0]->get_text().to_double(); - vec.y = value_editor[1]->get_text().to_double(); - vec.z = value_editor[2]->get_text().to_double(); - } + vec.x = _parse_real_expression(value_editor[0]->get_text()); + vec.y = _parse_real_expression(value_editor[1]->get_text()); + vec.z = _parse_real_expression(value_editor[2]->get_text()); v = vec; _emit_changed_whole_or_field(); @@ -1607,17 +1594,10 @@ void CustomPropertyEditor::_modified(String p_string) { case Variant::PLANE: { Plane pl; - if (evaluator) { - pl.normal.x = evaluator->eval(value_editor[0]->get_text()); - pl.normal.y = evaluator->eval(value_editor[1]->get_text()); - pl.normal.z = evaluator->eval(value_editor[2]->get_text()); - pl.d = evaluator->eval(value_editor[3]->get_text()); - } else { - pl.normal.x = value_editor[0]->get_text().to_double(); - pl.normal.y = value_editor[1]->get_text().to_double(); - pl.normal.z = value_editor[2]->get_text().to_double(); - pl.d = value_editor[3]->get_text().to_double(); - } + pl.normal.x = _parse_real_expression(value_editor[0]->get_text()); + pl.normal.y = _parse_real_expression(value_editor[1]->get_text()); + pl.normal.z = _parse_real_expression(value_editor[2]->get_text()); + pl.d = _parse_real_expression(value_editor[3]->get_text()); v = pl; _emit_changed_whole_or_field(); @@ -1625,17 +1605,10 @@ void CustomPropertyEditor::_modified(String p_string) { case Variant::QUAT: { Quat q; - if (evaluator) { - q.x = evaluator->eval(value_editor[0]->get_text()); - q.y = evaluator->eval(value_editor[1]->get_text()); - q.z = evaluator->eval(value_editor[2]->get_text()); - q.w = evaluator->eval(value_editor[3]->get_text()); - } else { - q.x = value_editor[0]->get_text().to_double(); - q.y = value_editor[1]->get_text().to_double(); - q.z = value_editor[2]->get_text().to_double(); - q.w = value_editor[3]->get_text().to_double(); - } + q.x = _parse_real_expression(value_editor[0]->get_text()); + q.y = _parse_real_expression(value_editor[1]->get_text()); + q.z = _parse_real_expression(value_editor[2]->get_text()); + q.w = _parse_real_expression(value_editor[3]->get_text()); v = q; _emit_changed_whole_or_field(); @@ -1645,21 +1618,12 @@ void CustomPropertyEditor::_modified(String p_string) { Vector3 pos; Vector3 size; - if (evaluator) { - pos.x = evaluator->eval(value_editor[0]->get_text()); - pos.y = evaluator->eval(value_editor[1]->get_text()); - pos.z = evaluator->eval(value_editor[2]->get_text()); - size.x = evaluator->eval(value_editor[3]->get_text()); - size.y = evaluator->eval(value_editor[4]->get_text()); - size.z = evaluator->eval(value_editor[5]->get_text()); - } else { - pos.x = value_editor[0]->get_text().to_double(); - pos.y = value_editor[1]->get_text().to_double(); - pos.z = value_editor[2]->get_text().to_double(); - size.x = value_editor[3]->get_text().to_double(); - size.y = value_editor[4]->get_text().to_double(); - size.z = value_editor[5]->get_text().to_double(); - } + pos.x = _parse_real_expression(value_editor[0]->get_text()); + pos.y = _parse_real_expression(value_editor[1]->get_text()); + pos.z = _parse_real_expression(value_editor[2]->get_text()); + size.x = _parse_real_expression(value_editor[3]->get_text()); + size.y = _parse_real_expression(value_editor[4]->get_text()); + size.z = _parse_real_expression(value_editor[5]->get_text()); v = AABB(pos, size); _emit_changed_whole_or_field(); @@ -1668,11 +1632,7 @@ void CustomPropertyEditor::_modified(String p_string) { Transform2D m; for (int i = 0; i < 6; i++) { - if (evaluator) { - m.elements[i / 2][i % 2] = evaluator->eval(value_editor[i]->get_text()); - } else { - m.elements[i / 2][i % 2] = value_editor[i]->get_text().to_double(); - } + m.elements[i / 2][i % 2] = _parse_real_expression(value_editor[i]->get_text()); } v = m; @@ -1683,12 +1643,7 @@ void CustomPropertyEditor::_modified(String p_string) { Basis m; for (int i = 0; i < 9; i++) { - - if (evaluator) { - m.elements[i / 3][i % 3] = evaluator->eval(value_editor[i]->get_text()); - } else { - m.elements[i / 3][i % 3] = value_editor[i]->get_text().to_double(); - } + m.elements[i / 3][i % 3] = _parse_real_expression(value_editor[i]->get_text()); } v = m; @@ -1699,25 +1654,14 @@ void CustomPropertyEditor::_modified(String p_string) { Basis basis; for (int i = 0; i < 9; i++) { - - if (evaluator) { - basis.elements[i / 3][i % 3] = evaluator->eval(value_editor[(i / 3) * 4 + i % 3]->get_text()); - } else { - basis.elements[i / 3][i % 3] = value_editor[(i / 3) * 4 + i % 3]->get_text().to_double(); - } + basis.elements[i / 3][i % 3] = _parse_real_expression(value_editor[(i / 3) * 4 + i % 3]->get_text()); } Vector3 origin; - if (evaluator) { - origin.x = evaluator->eval(value_editor[3]->get_text()); - origin.y = evaluator->eval(value_editor[7]->get_text()); - origin.z = evaluator->eval(value_editor[11]->get_text()); - } else { - origin.x = value_editor[3]->get_text().to_double(); - origin.y = value_editor[7]->get_text().to_double(); - origin.z = value_editor[11]->get_text().to_double(); - } + origin.x = _parse_real_expression(value_editor[3]->get_text()); + origin.y = _parse_real_expression(value_editor[7]->get_text()); + origin.z = _parse_real_expression(value_editor[11]->get_text()); v = Transform(basis, origin); _emit_changed_whole_or_field(); @@ -1759,6 +1703,19 @@ void CustomPropertyEditor::_modified(String p_string) { updating = false; } +real_t CustomPropertyEditor::_parse_real_expression(String text) { + Ref<Expression> expr; + expr.instance(); + Error err = expr->parse(text); + real_t out; + if (err != OK) { + out = value_editor[0]->get_text().to_double(); + } else { + out = expr->execute(Array(), NULL, false); + } + return out; +} + void CustomPropertyEditor::_emit_changed_whole_or_field() { if (!Input::get_singleton()->is_key_pressed(KEY_SHIFT)) { @@ -1910,6 +1867,7 @@ void CustomPropertyEditor::_bind_methods() { ADD_SIGNAL(MethodInfo("variant_field_changed", PropertyInfo(Variant::STRING, "field"))); ADD_SIGNAL(MethodInfo("resource_edit_request")); } + CustomPropertyEditor::CustomPropertyEditor() { read_only = false; @@ -2033,2743 +1991,3 @@ CustomPropertyEditor::CustomPropertyEditor() { create_dialog = NULL; property_select = NULL; } - -bool PropertyEditor::_might_be_in_instance() { - - if (!obj) - return false; - - Node *node = Object::cast_to<Node>(obj); - - Node *edited_scene = EditorNode::get_singleton()->get_edited_scene(); - - bool might_be = false; - - while (node) { - - if (node->get_scene_instance_state().is_valid()) { - might_be = true; - break; - } - if (node == edited_scene) { - if (node->get_scene_inherited_state().is_valid()) { - might_be = true; - break; - } - might_be = false; - break; - } - node = node->get_owner(); - } - - return might_be; -} - -bool PropertyEditor::_get_instanced_node_original_property(const StringName &p_prop, Variant &value) { - - Node *node = Object::cast_to<Node>(obj); - - if (!node) - return false; - - Node *orig = node; - - Node *edited_scene = EditorNode::get_singleton()->get_edited_scene(); - - bool found = false; - - while (node) { - - Ref<SceneState> ss; - - if (node == edited_scene) { - ss = node->get_scene_inherited_state(); - - } else { - ss = node->get_scene_instance_state(); - } - - if (ss.is_valid()) { - - NodePath np = node->get_path_to(orig); - int node_idx = ss->find_node_by_path(np); - if (node_idx >= 0) { - bool lfound = false; - Variant lvar; - lvar = ss->get_property_value(node_idx, p_prop, lfound); - if (lfound) { - - found = true; - value = lvar; - } - } - } - if (node == edited_scene) { - //just in case - break; - } - node = node->get_owner(); - } - - return found; -} - -bool PropertyEditor::_is_property_different(const Variant &p_current, const Variant &p_orig, int p_usage) { - - { - Node *node = Object::cast_to<Node>(obj); - if (!node) - return false; - - Node *edited_scene = EditorNode::get_singleton()->get_edited_scene(); - bool found_state = false; - - while (node) { - - Ref<SceneState> ss; - - if (node == edited_scene) { - ss = node->get_scene_inherited_state(); - - } else { - ss = node->get_scene_instance_state(); - } - - if (ss.is_valid()) { - found_state = true; - } - if (node == edited_scene) { - //just in case - break; - } - node = node->get_owner(); - } - - if (!found_state) - return false; //pointless to check if we are not comparing against anything. - } - - if (p_orig.get_type() == Variant::NIL) { - - //special cases - if (p_current.is_zero() && p_usage & PROPERTY_USAGE_STORE_IF_NONZERO) - return false; - if (p_current.is_one() && p_usage & PROPERTY_USAGE_STORE_IF_NONONE) - return false; - } - - if (p_current.get_type() == Variant::REAL && p_orig.get_type() == Variant::REAL) { - float a = p_current; - float b = p_orig; - - return Math::abs(a - b) > CMP_EPSILON; //this must be done because, as some scenes save as text, there might be a tiny difference in floats due to numerical error - } - - return bool(Variant::evaluate(Variant::OP_NOT_EQUAL, p_current, p_orig)); -} - -bool PropertyEditor::_is_instanced_node_with_original_property_different(const String &p_name, TreeItem *item) { - bool mbi = _might_be_in_instance(); - if (mbi) { - Variant vorig; - Dictionary d = item->get_metadata(0); - int usage = d.has("usage") ? int(int(d["usage"]) & (PROPERTY_USAGE_STORE_IF_NONONE | PROPERTY_USAGE_STORE_IF_NONZERO)) : 0; - if (_get_instanced_node_original_property(p_name, vorig) || usage) { - Variant v = obj->get(p_name); - - if (_is_property_different(v, vorig, usage)) { - return true; - } - } - } - return false; -} - -TreeItem *PropertyEditor::find_item(TreeItem *p_item, const String &p_name) { - - if (!p_item) - return NULL; - - String name = p_item->get_metadata(1); - - if (name == p_name) { - - return p_item; - } - - TreeItem *c = p_item->get_children(); - - while (c) { - - TreeItem *found = find_item(c, p_name); - if (found) - return found; - c = c->get_next(); - } - - return NULL; -} - -void PropertyEditor::_changed_callback(Object *p_changed, const char *p_prop) { - - _changed_callbacks(p_changed, p_prop); -} - -void PropertyEditor::_changed_callbacks(Object *p_changed, const String &p_prop) { - - if (p_changed != obj) - return; - - if (changing) - return; - - if (p_prop == String()) - update_tree_pending = true; - else { - - pending[p_prop] = p_prop; - } -} - -void PropertyEditor::update_property(const String &p_prop) { - - if (obj) - _changed_callbacks(obj, p_prop); -} - -void PropertyEditor::set_item_text(TreeItem *p_item, int p_type, const String &p_name, int p_hint, const String &p_hint_text) { - - switch (p_type) { - - case Variant::BOOL: { - - p_item->set_checked(1, obj->get(p_name)); - } break; - case Variant::REAL: - case Variant::INT: { - - if (p_hint == PROPERTY_HINT_LAYERS_2D_PHYSICS || p_hint == PROPERTY_HINT_LAYERS_2D_RENDER || p_hint == PROPERTY_HINT_LAYERS_3D_PHYSICS || p_hint == PROPERTY_HINT_LAYERS_3D_RENDER) { - tree->update(); - break; - } - - if (p_hint == PROPERTY_HINT_FLAGS) { - Vector<String> values = p_hint_text.split(","); - String flags; - int val = obj->get(p_name); - for (int i = 0; i < values.size(); i++) { - - String v = values[i]; - if (v == "") - continue; - if (!(val & (1 << i))) - continue; - - if (flags != "") - flags += ", "; - flags += v; - } - p_item->set_text(1, flags); - break; - } - - if (p_hint == PROPERTY_HINT_EXP_EASING) { - - p_item->set_text(1, String::num(obj->get(p_name), 2)); - break; - } - - if (p_type == Variant::REAL) { - p_item->set_range(1, obj->get(p_name)); - - } else { - /* FIXME: Why are both statements equal? */ - p_item->set_range(1, obj->get(p_name)); - } - - p_item->set_editable(1, !read_only); - - } break; - case Variant::STRING: - - if (p_hint == PROPERTY_HINT_TYPE_STRING) { - - p_item->set_text(1, obj->get(p_name)); - } - - if (p_hint == PROPERTY_HINT_METHOD_OF_VARIANT_TYPE || - p_hint == PROPERTY_HINT_METHOD_OF_BASE_TYPE || - p_hint == PROPERTY_HINT_METHOD_OF_INSTANCE || - p_hint == PROPERTY_HINT_METHOD_OF_SCRIPT || - p_hint == PROPERTY_HINT_PROPERTY_OF_VARIANT_TYPE || - p_hint == PROPERTY_HINT_PROPERTY_OF_BASE_TYPE || - p_hint == PROPERTY_HINT_PROPERTY_OF_INSTANCE || - p_hint == PROPERTY_HINT_PROPERTY_OF_SCRIPT) { - - p_item->set_text(1, obj->get(p_name)); - } - - if (p_hint == PROPERTY_HINT_ENUM) { - - Vector<String> strings = p_hint_text.split(","); - String current = obj->get(p_name); - int idx = 0; - for (int x = 0; x < strings.size(); x++) { - if (strings[x] == current) { - idx = x; - break; - } - } - p_item->set_text(1, p_hint_text); - p_item->set_range(1, idx); - break; - } - - case Variant::VECTOR3: - case Variant::QUAT: - case Variant::VECTOR2: - case Variant::AABB: - case Variant::RECT2: - case Variant::TRANSFORM2D: - case Variant::BASIS: - case Variant::TRANSFORM: { - - p_item->set_text(1, obj->get(p_name)); - - } break; - case Variant::COLOR: { - - tree->update(); - - } break; - case Variant::NODE_PATH: { - - p_item->set_text(1, obj->get(p_name)); - } break; - case Variant::OBJECT: { - - Ref<EncodedObjectAsID> encoded = obj->get(p_name); //for debugger and remote tools - - if (encoded.is_valid()) { - - p_item->set_text(1, "Object: " + itos(encoded->get_object_id())); - p_item->set_icon(1, Ref<Texture>()); - p_item->set_custom_as_button(1, true); - - } else if (obj->get(p_name).get_type() == Variant::NIL || obj->get(p_name).operator RefPtr().is_null()) { - p_item->set_text(1, "<null>"); - p_item->set_icon(1, Ref<Texture>()); - p_item->set_custom_as_button(1, false); - - Dictionary d = p_item->get_metadata(0); - int hint = d.has("hint") ? d["hint"].operator int() : -1; - String hint_text = d.has("hint_text") ? d["hint_text"] : ""; - if (hint == PROPERTY_HINT_RESOURCE_TYPE && hint_text == "Texture") { - p_item->set_icon(1, NULL); - } - - } else { - p_item->set_custom_as_button(1, true); - RES res = obj->get(p_name).operator RefPtr(); - if (res->is_class("Texture")) { - int tw = EditorSettings::get_singleton()->get("docks/property_editor/texture_preview_width"); - Vector2 size(res->call("get_width"), res->call("get_height")); - if (size.width < size.height) { - tw = MAX((size.width / size.height) * tw, 1); - } - p_item->set_icon_max_width(1, tw); - p_item->set_icon(1, res); - p_item->set_text(1, ""); - - } else if (res->get_name() != "") { - - p_item->set_text(1, res->get_name()); - } else if (res->get_path() != "" && !res->get_path().begins_with("local://")) { - p_item->set_text(1, res->get_path().get_file()); - } else { - p_item->set_text(1, "<" + res->get_class() + ">"); - }; - - if (res.is_valid() && res->get_path().is_resource_file()) { - p_item->set_tooltip(1, res->get_path()); - } else if (res.is_valid()) { - p_item->set_tooltip(1, res->get_name() + " (" + res->get_class() + ")"); - } - - if (has_icon(res->get_class(), "EditorIcons")) { - - p_item->set_icon(0, get_icon(res->get_class(), "EditorIcons")); - } else { - - Dictionary d = p_item->get_metadata(0); - int hint = d.has("hint") ? d["hint"].operator int() : -1; - String hint_text = d.has("hint_text") ? d["hint_text"] : ""; - if (hint == PROPERTY_HINT_RESOURCE_TYPE) { - - if (has_icon(hint_text, "EditorIcons")) { - - p_item->set_icon(0, get_icon(hint_text, "EditorIcons")); - - } else { - p_item->set_icon(0, get_icon("Object", "EditorIcons")); - } - } - } - - if (res->is_class("Script")) { - p_item->set_text(1, res->get_path().get_file()); - } else if (!res->is_class("Texture")) { - //texture already previews via itself - EditorResourcePreview::get_singleton()->queue_edited_resource_preview(res, this, "_resource_preview_done", p_item->get_instance_id()); - } - } - - } break; - default: {}; - } -} - -void PropertyEditor::_check_reload_status(const String &p_name, TreeItem *item) { - - bool has_reload = false; - int found = -1; - bool is_disabled = false; - - for (int i = 0; i < item->get_button_count(1); i++) { - - if (item->get_button_id(1, i) == 3) { - found = i; - is_disabled = item->is_button_disabled(1, i); - break; - } - } - - if (_is_instanced_node_with_original_property_different(p_name, item)) { - has_reload = true; - } - - if (obj->call("property_can_revert", p_name).operator bool()) { - - has_reload = true; - } - - if (!has_reload && !obj->get_script().is_null()) { - Ref<Script> scr = obj->get_script(); - Variant orig_value; - if (scr->get_property_default_value(p_name, orig_value)) { - if (orig_value != obj->get(p_name)) { - has_reload = true; - } - } - } - - if (found != -1 && !has_reload) { - - if (!is_disabled) { - item->erase_button(1, found); - if (item->get_cell_mode(1) == TreeItem::CELL_MODE_RANGE && item->get_text(1) == String()) { - item->add_button(1, get_icon("ReloadEmpty", "EditorIcons"), 3, true); - } - } - } else if (found == -1 && has_reload) { - item->add_button(1, get_icon("ReloadSmall", "EditorIcons"), 3); - } else if (found != -1 && has_reload && is_disabled) { - item->erase_button(1, found); - item->add_button(1, get_icon("ReloadSmall", "EditorIcons"), 3); - } -} - -bool PropertyEditor::_is_drop_valid(const Dictionary &p_drag_data, const Dictionary &p_item_data) const { - - Dictionary d = p_item_data; - - if (d.has("type")) { - - int type = d["type"]; - if (type == Variant::OBJECT && d.has("hint") && d.has("hint_text") && int(d["hint"]) == PROPERTY_HINT_RESOURCE_TYPE) { - - String allowed_type = d["hint_text"]; - - Dictionary drag_data = p_drag_data; - if (drag_data.has("type") && String(drag_data["type"]) == "resource") { - Ref<Resource> res = drag_data["resource"]; - for (int i = 0; i < allowed_type.get_slice_count(","); i++) { - String at = allowed_type.get_slice(",", i).strip_edges(); - if (res.is_valid() && ClassDB::is_parent_class(res->get_class(), at)) { - return true; - } - } - } - - if (drag_data.has("type") && String(drag_data["type"]) == "files") { - - Vector<String> files = drag_data["files"]; - - if (files.size() == 1) { - String file = files[0]; - String ftype = EditorFileSystem::get_singleton()->get_file_type(file); - - if (ftype != "") { - - for (int i = 0; i < allowed_type.get_slice_count(","); i++) { - String at = allowed_type.get_slice(",", i).strip_edges(); - if (ClassDB::is_parent_class(ftype, at)) { - return true; - } - } - } - } - } - } - } - - return false; -} -void PropertyEditor::_mark_drop_fields(TreeItem *p_at) { - - if (_is_drop_valid(get_viewport()->gui_get_drag_data(), p_at->get_metadata(0))) - p_at->set_custom_bg_color(1, get_color("accent_color", "Editor"), true); - - if (p_at->get_children()) { - _mark_drop_fields(p_at->get_children()); - } - - if (p_at->get_next()) { - _mark_drop_fields(p_at->get_next()); - } -} - -Variant PropertyEditor::get_drag_data_fw(const Point2 &p_point, Control *p_from) { - - TreeItem *item = tree->get_item_at_position(p_point); - if (!item) - return Variant(); - - Dictionary d = item->get_metadata(0); - if (!d.has("name")) - return Variant(); - - int col = tree->get_column_at_position(p_point); - if (col == 0) { - - Dictionary dp; - dp["type"] = "obj_property"; - dp["object"] = obj; - dp["property"] = d["name"]; - dp["value"] = obj->get(d["name"]); - - Label *label = memnew(Label); - label->set_text(d["name"]); - set_drag_preview(label); - return dp; - } - - Variant val = obj->get(d["name"]); - - if (val.get_type() == Variant::OBJECT) { - RES res = val; - if (res.is_valid()) { - - custom_editor->hide_menu(); - return EditorNode::get_singleton()->drag_resource(res, p_from); - } - } - - return Variant(); -} - -bool PropertyEditor::can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const { - - TreeItem *item = tree->get_item_at_position(p_point); - if (!item) - return false; - - int col = tree->get_column_at_position(p_point); - if (col != 1) - return false; - - return _is_drop_valid(p_data, item->get_metadata(0)); -} -void PropertyEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) { - - TreeItem *item = tree->get_item_at_position(p_point); - if (!item) - return; - - int col = tree->get_column_at_position(p_point); - if (col != 1) - return; - - if (!_is_drop_valid(p_data, item->get_metadata(0))) - return; - - Dictionary d = item->get_metadata(0); - - if (!d.has("name")) - return; - - String name = d["name"]; - - Dictionary drag_data = p_data; - if (drag_data.has("type") && String(drag_data["type"]) == "resource") { - Ref<Resource> res = drag_data["resource"]; - if (res.is_valid()) { - _edit_set(name, res); - return; - } - } - - if (drag_data.has("type") && String(drag_data["type"]) == "files") { - - Vector<String> files = drag_data["files"]; - - if (files.size() == 1) { - String file = files[0]; - RES res = ResourceLoader::load(file); - if (res.is_valid()) { - _edit_set(name, res); - return; - } - } - } -} - -void PropertyEditor::_clear_drop_fields(TreeItem *p_at) { - - Dictionary d = p_at->get_metadata(0); - - if (d.has("type")) { - - int type = d["type"]; - if (type == Variant::OBJECT) { - p_at->clear_custom_bg_color(1); - } - } - - if (p_at->get_children()) { - _clear_drop_fields(p_at->get_children()); - } - - if (p_at->get_next()) { - _clear_drop_fields(p_at->get_next()); - } -} - -void PropertyEditor::_notification(int p_what) { - - if (p_what == NOTIFICATION_ENTER_TREE) { - - get_tree()->connect("node_removed", this, "_node_removed"); - } - if (p_what == NOTIFICATION_EXIT_TREE) { - - get_tree()->disconnect("node_removed", this, "_node_removed"); - edit(NULL); - } - - if (p_what == NOTIFICATION_DRAG_BEGIN) { - - if (is_visible_in_tree() && tree->get_root()) { - _mark_drop_fields(tree->get_root()); - } - } - - if (p_what == NOTIFICATION_DRAG_END) { - if (is_visible_in_tree() && tree->get_root()) { - _clear_drop_fields(tree->get_root()); - } - } - - if (p_what == NOTIFICATION_PHYSICS_PROCESS) { - - if (refresh_countdown > 0) { - refresh_countdown -= get_physics_process_delta_time(); - if (refresh_countdown <= 0) { - TreeItem *root = tree->get_root(); - _refresh_item(root); - } - } - - changing = true; - - if (update_tree_pending) { - - update_tree(); - update_tree_pending = false; - - } else { - - const String *k = NULL; - while ((k = pending.next(k))) { - - TreeItem *item = find_item(tree->get_root(), *k); - if (!item) - continue; - - _check_reload_status(*k, item); - - Dictionary d = item->get_metadata(0); - set_item_text(item, d["type"], d["name"], d["hint"], d["hint_text"]); - } - } - - pending.clear(); - - changing = false; - } - - if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) { - update_tree(); - } -} - -TreeItem *PropertyEditor::get_parent_node(String p_path, HashMap<String, TreeItem *> &item_paths, TreeItem *root, TreeItem *category) { - - TreeItem *item = NULL; - - if (p_path == "") { - - item = category ? category : root; - } else if (item_paths.has(p_path)) { - - item = item_paths.get(p_path); - } else { - - TreeItem *parent = get_parent_node(p_path.left(p_path.find_last("/")), item_paths, root, NULL); - item = tree->create_item(parent); - - String name = (p_path.find("/") != -1) ? p_path.right(p_path.find_last("/") + 1) : p_path; - item->set_text(0, capitalize_paths ? name.capitalize() : name); - item->set_tooltip(0, p_path); - if (item->get_parent() != root) { - item->set_icon(0, get_icon("Folder", "EditorIcons")); - } - - item->set_editable(0, false); - if (!subsection_selectable) { - item->set_expand_right(0, true); - } - item->set_selectable(0, subsection_selectable); - item->set_editable(1, false); - item->set_selectable(1, subsection_selectable); - - if (use_folding) { - if (!obj->editor_is_section_unfolded(p_path)) { - updating_folding = true; - item->set_collapsed(true); - updating_folding = false; - } - item->set_metadata(0, p_path); - foldable_property_cache.push_back(p_path); - } - - if (item->get_parent() == root) { - - item->set_custom_bg_color(0, get_color("prop_subsection", "Editor")); - item->set_custom_bg_color(1, get_color("prop_subsection", "Editor")); - } - - item_paths[p_path] = item; - } - - return item; -} - -void PropertyEditor::_refresh_item(TreeItem *p_item) { - - if (!p_item) - return; - - String name = p_item->get_metadata(1); - - if (name != String()) { - - _check_reload_status(name, p_item); - Dictionary d = p_item->get_metadata(0); - set_item_text(p_item, d["type"], d["name"], d["hint"], d["hint_text"]); - } - - TreeItem *c = p_item->get_children(); - - while (c) { - - _refresh_item(c); - - c = c->get_next(); - } -} - -void PropertyEditor::refresh() { - - if (refresh_countdown > 0) - return; - refresh_countdown = EditorSettings::get_singleton()->get("docks/property_editor/auto_refresh_interval"); -} - -void PropertyEditor::update_tree() { - - tree->clear(); - foldable_property_cache.clear(); - - if (!obj) - return; - - HashMap<String, TreeItem *> item_path; - - TreeItem *root = tree->create_item(NULL); - tree->set_hide_root(true); - - List<PropertyInfo> plist; - obj->get_property_list(&plist, true); - - bool draw_red = false; - - { - Node *nod = Object::cast_to<Node>(obj); - Node *es = EditorNode::get_singleton()->get_edited_scene(); - if (nod && es != nod && nod->get_owner() != es) { - draw_red = true; - } - } - - Color sscolor = get_color("prop_subsection", "Editor"); - - TreeItem *current_category = NULL; - - String filter = search_box ? search_box->get_text() : ""; - String group; - String group_base; - - for (List<PropertyInfo>::Element *I = plist.front(); I; I = I->next()) { - - PropertyInfo &p = I->get(); - - //make sure the property can be edited - - if (p.usage & PROPERTY_USAGE_GROUP) { - - group = p.name; - group_base = p.hint_string; - - continue; - - } else if (p.usage & PROPERTY_USAGE_CATEGORY) { - - group = ""; - group_base = ""; - - if (!show_categories) - continue; - - List<PropertyInfo>::Element *N = I->next(); - bool valid = true; - //if no properties in category, skip - while (N) { - if (N->get().usage & PROPERTY_USAGE_EDITOR) - break; - if (N->get().usage & PROPERTY_USAGE_CATEGORY) { - valid = false; - break; - } - N = N->next(); - } - if (!valid) - continue; //empty, ignore - TreeItem *sep = tree->create_item(root); - current_category = sep; - String type = p.name; - - if (has_icon(type, "EditorIcons")) - sep->set_icon(0, get_icon(type, "EditorIcons")); - else - sep->set_icon(0, get_icon("Object", "EditorIcons")); - - sep->set_text(0, type); - sep->set_expand_right(0, true); - sep->set_selectable(0, false); - sep->set_selectable(1, false); - sep->set_custom_bg_color(0, get_color("prop_category", "Editor")); - sep->set_custom_bg_color(1, get_color("prop_category", "Editor")); - sep->set_text_align(0, TreeItem::ALIGN_CENTER); - sep->set_disable_folding(true); - - if (use_doc_hints) { - StringName type = p.name; - if (!class_descr_cache.has(type)) { - - String descr; - DocData *dd = EditorHelp::get_doc_data(); - Map<String, DocData::ClassDoc>::Element *E = dd->class_list.find(type); - if (E) { - descr = E->get().brief_description; - } - class_descr_cache[type] = descr.word_wrap(80); - } - - sep->set_tooltip(0, TTR("Class:") + " " + p.name + (class_descr_cache[type] == "" ? "" : "\n\n" + class_descr_cache[type])); - } - continue; - - } else if (!(p.usage & PROPERTY_USAGE_EDITOR)) - continue; - - if (hide_script && p.name == "script") - continue; - - String basename = p.name; - if (group != "") { - if (group_base != "") { - if (basename.begins_with(group_base)) { - basename = basename.replace_first(group_base, ""); - } else if (group_base.begins_with(basename)) { - //keep it, this is used pretty often - } else { - group = ""; //no longer using group base, clear - } - } - } - - if (group != "") { - basename = group + "/" + basename; - } - - String name = (basename.find("/") != -1) ? basename.right(basename.find_last("/") + 1) : basename; - - if (capitalize_paths) { - int dot = name.find("."); - if (dot != -1) { - String ov = name.right(dot); - name = name.substr(0, dot); - name = name.camelcase_to_underscore().capitalize(); - name += ov; - - } else { - name = name.camelcase_to_underscore().capitalize(); - } - } - - String path = basename.left(basename.find_last("/")); - - if (use_filter && filter != "") { - - String cat = path; - - if (capitalize_paths) - cat = cat.capitalize(); - - if (!filter.is_subsequence_ofi(cat) && !filter.is_subsequence_ofi(name)) - continue; - } - - TreeItem *parent = get_parent_node(path, item_path, root, current_category); - int level = 0; - if (parent != root) { - level++; - TreeItem *parent_lev = parent; - while (parent_lev->get_parent() != root) { - parent_lev = parent_lev->get_parent(); - level++; - } - } - if (level > 4) - level = 4; - - Color col = sscolor; - col.a = (level / 4.0) * 0.7; - - TreeItem *item = tree->create_item(parent); - - if (level > 0) { - item->set_custom_bg_color(0, col); - } - item->set_editable(0, false); - item->set_selectable(0, property_selectable); - - if (p.usage & PROPERTY_USAGE_CHECKABLE) { - - item->set_cell_mode(0, TreeItem::CELL_MODE_CHECK); - item->set_selectable(0, true); - item->set_editable(0, true); - item->set_checked(0, p.usage & PROPERTY_USAGE_CHECKED); - } - - item->set_text(0, name); - item->set_tooltip(0, p.name); - - if (name.find(".") != -1) { - Color textcol = get_color("font_color", "Tree"); - textcol.a *= 0.5; - //override :D - item->set_custom_color(0, textcol); - item->set_custom_color(1, textcol); - - Color iconcol(1, 1, 1, 0.6); - item->set_icon_color(0, iconcol); - item->set_icon_color(1, iconcol); - } - - if (use_doc_hints) { - - StringName classname = obj->get_class_name(); - StringName propname = p.name; - String descr; - bool found = false; - - Map<StringName, Map<StringName, String> >::Element *E = descr_cache.find(classname); - if (E) { - Map<StringName, String>::Element *F = E->get().find(propname); - if (F) { - found = true; - descr = F->get(); - } - } - - if (!found) { - DocData *dd = EditorHelp::get_doc_data(); - Map<String, DocData::ClassDoc>::Element *E = dd->class_list.find(classname); - while (E && descr == String()) { - for (int i = 0; i < E->get().properties.size(); i++) { - if (E->get().properties[i].name == propname.operator String()) { - descr = E->get().properties[i].description.strip_edges().word_wrap(80); - break; - } - } - if (!E->get().inherits.empty()) { - E = dd->class_list.find(E->get().inherits); - } else { - break; - } - } - descr_cache[classname][propname] = descr; - } - - item->set_tooltip(0, TTR("Property:") + " " + p.name + (descr == "" ? "" : "\n\n" + descr)); - } - - Dictionary d; - d["name"] = p.name; - d["type"] = (int)p.type; - d["hint"] = (int)p.hint; - d["hint_text"] = p.hint_string; - d["usage"] = (int)p.usage; - - item->set_metadata(0, d); - item->set_metadata(1, p.name); - - if (draw_red) - item->set_custom_color(0, get_color("error_color", "Editor")); - - if (p.name == selected_property) { - - item->select(1); - } - - switch (p.type) { - - case Variant::BOOL: { - - item->set_cell_mode(1, TreeItem::CELL_MODE_CHECK); - item->set_text(1, TTR("On")); - item->set_tooltip(1, obj->get(p.name) ? "True" : "False"); - item->set_checked(1, obj->get(p.name)); - if (show_type_icons) - item->set_icon(0, get_icon("bool", "EditorIcons")); - item->set_editable(1, !read_only); - - } break; - case Variant::REAL: - case Variant::INT: { - - if (p.hint == PROPERTY_HINT_EXP_EASING) { - - item->set_cell_mode(1, TreeItem::CELL_MODE_CUSTOM); - item->set_text(1, String::num(obj->get(p.name), 2)); - item->set_editable(1, !read_only); - if (show_type_icons) - item->set_icon(0, get_icon("Curve", "EditorIcons")); - - break; - } - - if (p.hint == PROPERTY_HINT_LAYERS_2D_PHYSICS || p.hint == PROPERTY_HINT_LAYERS_2D_RENDER || p.hint == PROPERTY_HINT_LAYERS_3D_PHYSICS || p.hint == PROPERTY_HINT_LAYERS_3D_RENDER) { - - item->set_cell_mode(1, TreeItem::CELL_MODE_CUSTOM); - item->set_editable(1, !read_only); - item->set_custom_draw(1, this, "_draw_flags"); - break; - } - - if (p.hint == PROPERTY_HINT_FLAGS) { - - item->set_cell_mode(1, TreeItem::CELL_MODE_CUSTOM); - item->set_editable(1, !read_only); - - Vector<String> values = p.hint_string.split(","); - String flags; - int val = obj->get(p.name); - for (int i = 0; i < values.size(); i++) { - - String v = values[i]; - if (v == "") - continue; - if (!(val & (1 << i))) - continue; - - if (flags != "") - flags += ", "; - flags += v; - } - item->set_text(1, flags); - break; - } - - if (p.hint == PROPERTY_HINT_ENUM) - item->set_cell_mode(1, TreeItem::CELL_MODE_RANGE); - else - item->set_cell_mode(1, TreeItem::CELL_MODE_RANGE_EXPRESSION); - - if (p.hint == PROPERTY_HINT_SPRITE_FRAME || p.hint == PROPERTY_HINT_RANGE || p.hint == PROPERTY_HINT_EXP_RANGE) { - - int c = p.hint_string.get_slice_count(","); - float min = 0, max = 100, step = p.type == Variant::REAL ? .01 : 1; - if (c >= 1) { - - min = p.hint_string.get_slice(",", 0).to_double(); - } - if (c >= 2) { - - max = p.hint_string.get_slice(",", 1).to_double(); - } - - if (p.hint != PROPERTY_HINT_SPRITE_FRAME && c >= 3) { - - step = p.hint_string.get_slice(",", 2).to_double(); - } - - item->set_range_config(1, min, max, step, p.hint == PROPERTY_HINT_EXP_RANGE); - } else if (p.hint == PROPERTY_HINT_ENUM) { - - item->set_text(1, p.hint_string); - if (show_type_icons) - item->set_icon(0, get_icon("Enum", "EditorIcons")); - item->set_range(1, obj->get(p.name)); - item->set_editable(1, !read_only); - break; - } else if (p.hint == PROPERTY_HINT_OBJECT_ID) { - - item->set_cell_mode(1, TreeItem::CELL_MODE_CUSTOM); - - String type = p.hint_string; - if (type == "") - type = "Object"; - - ObjectID id = obj->get(p.name); - if (id != 0) { - item->set_text(1, type + " ID: " + itos(id)); - item->add_button(1, get_icon("EditResource", "EditorIcons")); - } else { - item->set_text(1, TTR("[Empty]")); - } - - if (has_icon(p.hint_string, "EditorIcons")) { - type = p.hint_string; - } else { - type = "Object"; - } - - item->set_icon(0, get_icon(type, "EditorIcons")); - - break; - - } else { - if (p.type == Variant::REAL) { - - item->set_range_config(1, -16777216, 16777216, 0.001); - } else { - - item->set_range_config(1, -2147483647, 2147483647, 1); - } - }; - - if (p.type == Variant::REAL) { - if (show_type_icons) - item->set_icon(0, get_icon("float", "EditorIcons")); - item->set_range(1, obj->get(p.name)); - - } else { - if (show_type_icons) - item->set_icon(0, get_icon("int", "EditorIcons")); - item->set_range(1, obj->get(p.name)); - } - - item->set_editable(1, !read_only); - - } break; - case Variant::STRING: { - - switch (p.hint) { - - case PROPERTY_HINT_DIR: - case PROPERTY_HINT_FILE: - case PROPERTY_HINT_GLOBAL_DIR: - case PROPERTY_HINT_GLOBAL_FILE: { - - item->set_cell_mode(1, TreeItem::CELL_MODE_STRING); - item->set_editable(1, !read_only); - if (show_type_icons) - item->set_icon(0, get_icon("File", "EditorIcons")); - item->set_text(1, obj->get(p.name)); - item->add_button(1, get_icon("Folder", "EditorIcons")); - - } break; - case PROPERTY_HINT_ENUM: { - - item->set_cell_mode(1, TreeItem::CELL_MODE_RANGE); - Vector<String> strings = p.hint_string.split(","); - String current = obj->get(p.name); - int idx = 0; - for (int x = 0; x < strings.size(); x++) { - if (strings[x] == current) { - idx = x; - break; - } - } - item->set_text(1, p.hint_string); - item->set_range(1, idx); - item->set_editable(1, !read_only); - if (show_type_icons) - item->set_icon(0, get_icon("Enum", "EditorIcons")); - - } break; - case PROPERTY_HINT_METHOD_OF_VARIANT_TYPE: ///< a property of a type - case PROPERTY_HINT_METHOD_OF_BASE_TYPE: ///< a method of a base type - case PROPERTY_HINT_METHOD_OF_INSTANCE: ///< a method of an instance - case PROPERTY_HINT_METHOD_OF_SCRIPT: ///< a method of a script & base - case PROPERTY_HINT_PROPERTY_OF_VARIANT_TYPE: ///< a property of a type - case PROPERTY_HINT_PROPERTY_OF_BASE_TYPE: ///< a property of a base type - case PROPERTY_HINT_PROPERTY_OF_INSTANCE: ///< a property of an instance - case PROPERTY_HINT_PROPERTY_OF_SCRIPT: ///< a property of a script & base - case PROPERTY_HINT_TYPE_STRING: { - - item->set_cell_mode(1, TreeItem::CELL_MODE_CUSTOM); - item->set_editable(1, !read_only); - if (show_type_icons) - item->set_icon(0, get_icon("String", "EditorIcons")); - item->set_text(1, obj->get(p.name)); - - } break; - - default: { - - item->set_cell_mode(1, TreeItem::CELL_MODE_STRING); - item->set_editable(1, !read_only); - if (show_type_icons) - item->set_icon(0, get_icon("String", "EditorIcons")); - item->set_text(1, obj->get(p.name)); - if (p.hint == PROPERTY_HINT_MULTILINE_TEXT) - item->add_button(1, get_icon("MultiLine", "EditorIcons")); - - } break; - } - - } break; - case Variant::ARRAY: { - - item->set_cell_mode(1, TreeItem::CELL_MODE_CUSTOM); - item->add_button(1, get_icon("EditResource", "EditorIcons")); - - Variant v = obj->get(p.name); - String type_name = "Array"; - String type_name_suffix = ""; - - String hint = p.hint_string; - while (hint.begins_with(itos(Variant::ARRAY) + ":")) { - type_name += "<Array"; - type_name_suffix += ">"; - hint = hint.right(2); - } - if (hint.find(":") >= 0) { - int colon_pos = hint.find(":"); - String hint_string = hint.right(colon_pos + 1); - hint = hint.left(colon_pos); - - PropertyHint property_hint = PROPERTY_HINT_NONE; - - if (hint.find("/") >= 0) { - int slash_pos = hint.find("/"); - property_hint = PropertyHint(hint.right(slash_pos + 1).to_int()); - hint = hint.left(slash_pos); - } - - if (property_hint == PROPERTY_HINT_RESOURCE_TYPE) { - type_name += "<" + hint_string; - } else { - type_name += "<" + Variant::get_type_name(Variant::Type(hint.to_int())); - } - type_name_suffix += ">"; - } - type_name += type_name_suffix; - - if (v.is_array()) - item->set_text(1, type_name + "(" + itos(v.call("size")) + ")"); - else - item->set_text(1, type_name + "()"); - - if (show_type_icons) - item->set_icon(0, get_icon("PoolByteArray", "EditorIcons")); - - } break; - case Variant::DICTIONARY: { - - Variant v = obj->get(p.name); - - item->set_cell_mode(1, TreeItem::CELL_MODE_STRING); - item->set_text(1, String("Dictionary{") + itos(v.call("size")) + "}"); - item->add_button(1, get_icon("EditResource", "EditorIcons")); - - if (show_type_icons) - item->set_icon(0, get_icon("Dictionary", "EditorIcons")); - - } break; - - case Variant::POOL_INT_ARRAY: { - - item->set_cell_mode(1, TreeItem::CELL_MODE_CUSTOM); - item->add_button(1, get_icon("EditResource", "EditorIcons")); - - Variant v = obj->get(p.name); - if (v.is_array()) - item->set_text(1, "IntArray[" + itos(v.call("size")) + "]"); - else - item->set_text(1, "IntArray[]"); - if (show_type_icons) - item->set_icon(0, get_icon("PoolIntArray", "EditorIcons")); - - } break; - case Variant::POOL_REAL_ARRAY: { - - item->set_cell_mode(1, TreeItem::CELL_MODE_CUSTOM); - item->add_button(1, get_icon("EditResource", "EditorIcons")); - - Variant v = obj->get(p.name); - if (v.is_array()) - item->set_text(1, "FloatArray[" + itos(v.call("size")) + "]"); - else - item->set_text(1, "FloatArray[]"); - if (show_type_icons) - item->set_icon(0, get_icon("PoolRealArray", "EditorIcons")); - - } break; - case Variant::POOL_STRING_ARRAY: { - - item->set_cell_mode(1, TreeItem::CELL_MODE_CUSTOM); - item->add_button(1, get_icon("EditResource", "EditorIcons")); - - Variant v = obj->get(p.name); - if (v.is_array()) - item->set_text(1, "String[" + itos(v.call("size")) + "]"); - else - item->set_text(1, "String[]"); - if (show_type_icons) - item->set_icon(0, get_icon("PoolStringArray", "EditorIcons")); - - } break; - case Variant::POOL_BYTE_ARRAY: { - - item->set_cell_mode(1, TreeItem::CELL_MODE_CUSTOM); - item->add_button(1, get_icon("EditResource", "EditorIcons")); - - Variant v = obj->get(p.name); - if (v.is_array()) - item->set_text(1, "Byte[" + itos(v.call("size")) + "]"); - else - item->set_text(1, "Byte[]"); - if (show_type_icons) - item->set_icon(0, get_icon("PoolByteArray", "EditorIcons")); - - } break; - case Variant::POOL_VECTOR2_ARRAY: { - - item->set_cell_mode(1, TreeItem::CELL_MODE_CUSTOM); - item->add_button(1, get_icon("EditResource", "EditorIcons")); - - Variant v = obj->get(p.name); - if (v.is_array()) - item->set_text(1, "Vector2[" + itos(v.call("size")) + "]"); - else - item->set_text(1, "Vector2[]"); - if (show_type_icons) - item->set_icon(0, get_icon("Vector2", "EditorIcons")); - - } break; - case Variant::POOL_VECTOR3_ARRAY: { - - item->set_cell_mode(1, TreeItem::CELL_MODE_CUSTOM); - item->add_button(1, get_icon("EditResource", "EditorIcons")); - - Variant v = obj->get(p.name); - if (v.is_array()) - item->set_text(1, "Vector3[" + itos(v.call("size")) + "]"); - else - item->set_text(1, "Vector3[]"); - if (show_type_icons) - item->set_icon(0, get_icon("Vector3", "EditorIcons")); - - } break; - case Variant::POOL_COLOR_ARRAY: { - - item->set_cell_mode(1, TreeItem::CELL_MODE_CUSTOM); - item->add_button(1, get_icon("EditResource", "EditorIcons")); - - Variant v = obj->get(p.name); - if (v.is_array()) - item->set_text(1, "Color[" + itos(v.call("size")) + "]"); - else - item->set_text(1, "Color[]"); - if (show_type_icons) - item->set_icon(0, get_icon("Color", "EditorIcons")); - - } break; - case Variant::VECTOR2: { - - item->set_cell_mode(1, TreeItem::CELL_MODE_CUSTOM); - item->set_editable(1, true); - item->set_text(1, obj->get(p.name)); - if (show_type_icons) - item->set_icon(0, get_icon("Vector2", "EditorIcons")); - - } break; - case Variant::RECT2: { - - item->set_cell_mode(1, TreeItem::CELL_MODE_CUSTOM); - item->set_editable(1, true); - item->set_text(1, obj->get(p.name)); - if (show_type_icons) - item->set_icon(0, get_icon("Rect2", "EditorIcons")); - - } break; - case Variant::VECTOR3: { - - item->set_cell_mode(1, TreeItem::CELL_MODE_CUSTOM); - item->set_editable(1, true); - item->set_text(1, obj->get(p.name)); - if (show_type_icons) - item->set_icon(0, get_icon("Vector3", "EditorIcons")); - - } break; - case Variant::TRANSFORM2D: - case Variant::BASIS: { - - item->set_cell_mode(1, TreeItem::CELL_MODE_CUSTOM); - item->set_editable(1, true); - item->set_text(1, obj->get(p.name)); - - } break; - case Variant::TRANSFORM: { - - item->set_cell_mode(1, TreeItem::CELL_MODE_CUSTOM); - item->set_editable(1, true); - item->set_text(1, obj->get(p.name)); - if (show_type_icons) - item->set_icon(0, get_icon("Transform", "EditorIcons")); - - } break; - case Variant::PLANE: { - - item->set_cell_mode(1, TreeItem::CELL_MODE_CUSTOM); - item->set_editable(1, true); - item->set_text(1, obj->get(p.name)); - if (show_type_icons) - item->set_icon(0, get_icon("Plane", "EditorIcons")); - - } break; - case Variant::AABB: { - - item->set_cell_mode(1, TreeItem::CELL_MODE_CUSTOM); - item->set_editable(1, true); - item->set_text(1, "AABB"); - if (show_type_icons) - item->set_icon(0, get_icon("AABB", "EditorIcons")); - - } break; - - case Variant::QUAT: { - - item->set_cell_mode(1, TreeItem::CELL_MODE_CUSTOM); - item->set_editable(1, true); - item->set_text(1, obj->get(p.name)); - if (show_type_icons) - item->set_icon(0, get_icon("Quat", "EditorIcons")); - - } break; - case Variant::COLOR: { - - item->set_cell_mode(1, TreeItem::CELL_MODE_CUSTOM); - item->set_editable(1, !read_only); - item->set_custom_draw(1, this, "_draw_transparency"); - if (show_type_icons) - item->set_icon(0, get_icon("Color", "EditorIcons")); - - } break; - - case Variant::NODE_PATH: { - - item->set_cell_mode(1, TreeItem::CELL_MODE_STRING); - item->set_editable(1, !read_only); - item->set_text(1, obj->get(p.name)); - item->add_button(1, get_icon("CopyNodePath", "EditorIcons")); - if (show_type_icons) - item->set_icon(0, get_icon("NodePath", "EditorIcons")); - - } break; - case Variant::OBJECT: { - - item->set_cell_mode(1, TreeItem::CELL_MODE_CUSTOM); - item->set_editable(1, !read_only); - String type; - if (p.hint == PROPERTY_HINT_RESOURCE_TYPE) - type = p.hint_string; - - RES res = obj->get(p.name).operator RefPtr(); - if (type.begins_with("RES:") && type != "RES:") { // Remote resources - res = ResourceLoader::load(type.substr(4, type.length())); - } - Ref<EncodedObjectAsID> encoded = obj->get(p.name); //for debugger and remote tools - - if (encoded.is_valid()) { - - item->set_text(1, "Object: " + itos(encoded->get_object_id())); - item->set_icon(1, Ref<Texture>()); - item->set_custom_as_button(1, true); - item->set_editable(1, true); - - } else if (obj->get(p.name).get_type() == Variant::NIL || res.is_null()) { - - item->set_text(1, "<null>"); - item->set_icon(1, Ref<Texture>()); - item->set_custom_as_button(1, false); - - } else if (res.is_valid()) { - - item->set_custom_as_button(1, true); - - if (res->is_class("Texture")) { - int tw = EditorSettings::get_singleton()->get("docks/property_editor/texture_preview_width"); - Vector2 size(res->call("get_width"), res->call("get_height")); - if (size.width < size.height) { - tw = MAX((size.width / size.height) * tw, 1); - } - item->set_icon_max_width(1, tw); - item->set_icon(1, res); - item->set_text(1, ""); - - } else if (res->get_name() != "") { - - item->set_text(1, res->get_name()); - } else if (res->get_path() != "" && !res->get_path().begins_with("local://")) { - item->set_text(1, res->get_path().get_file()); - - } else { - item->set_text(1, "<" + res->get_class() + ">"); - } - - if (has_icon(res->get_class(), "EditorIcons")) { - type = res->get_class(); - } - - if (res.is_valid() && res->get_path().is_resource_file()) { - item->set_tooltip(1, res->get_path()); - } else if (res.is_valid()) { - item->set_tooltip(1, res->get_name() + " (" + res->get_class() + ")"); - } - if (res->is_class("Script")) { - item->set_text(1, res->get_path().get_file()); - } else if (!res->is_class("Texture")) { - //texture already previews via itself - EditorResourcePreview::get_singleton()->queue_edited_resource_preview(res, this, "_resource_preview_done", item->get_instance_id()); - } - } - - if (type != String()) { - if (type.find(",") != -1) - type = type.get_slice(",", 0); - if (has_icon(type, "EditorIcons")) - item->set_icon(0, get_icon(type, "EditorIcons")); - else - item->set_icon(0, get_icon("Object", "EditorIcons")); - } - - } break; - default: {}; - } - - if (keying) { - - if (p.hint == PROPERTY_HINT_SPRITE_FRAME) { - - item->add_button(1, get_icon("KeyNext", "EditorIcons"), 5); - } else { - item->add_button(1, get_icon("Key", "EditorIcons"), 2); - } - } - - bool has_reload = false; - - if (_is_instanced_node_with_original_property_different(p.name, item)) { - item->add_button(1, get_icon("ReloadSmall", "EditorIcons"), 3); - has_reload = true; - } - - if (obj->call("property_can_revert", p.name).operator bool()) { - - item->add_button(1, get_icon("ReloadSmall", "EditorIcons"), 3); - has_reload = true; - } - - if (!has_reload && !obj->get_script().is_null()) { - Ref<Script> scr = obj->get_script(); - Variant orig_value; - if (scr->get_property_default_value(p.name, orig_value)) { - if (orig_value != obj->get(p.name)) { - item->add_button(1, get_icon("ReloadSmall", "EditorIcons"), 3); - has_reload = true; - } - } - } - - if (_might_be_in_instance() && !has_reload && item->get_cell_mode(1) == TreeItem::CELL_MODE_RANGE && item->get_text(1) == String()) { - item->add_button(1, get_icon("ReloadEmpty", "EditorIcons"), 3, true); - } - } -} - -void PropertyEditor::_draw_transparency(Object *t, const Rect2 &p_rect) { - - TreeItem *ti = Object::cast_to<TreeItem>(t); - if (!ti) - return; - - Color color = obj->get(ti->get_metadata(1)); - Ref<Texture> arrow = tree->get_icon("select_option"); - - // make a little space between consecutive color fields - Rect2 area = p_rect; - area.position.y += 1; - area.size.height -= 2; - area.size.width -= arrow->get_size().width + 5; - tree->draw_texture_rect(get_icon("GuiMiniCheckerboard", "EditorIcons"), area, true); - tree->draw_rect(area, color); -} - -void PropertyEditor::_item_folded(Object *item_obj) { - - if (updating_folding) - return; - - TreeItem *item = Object::cast_to<TreeItem>(item_obj); - - obj->editor_set_section_unfold(item->get_metadata(0), !item->is_collapsed()); -} - -void PropertyEditor::_item_selected() { - - TreeItem *item = tree->get_selected(); - ERR_FAIL_COND(!item); - selected_property = item->get_metadata(1); -} - -void PropertyEditor::_item_rmb_edited() { - _custom_editor_request(true); -} - -void PropertyEditor::_edit_set(const String &p_name, const Variant &p_value, bool p_refresh_all, const String &p_changed_field) { - - if (autoclear) { - TreeItem *item = tree->get_selected(); - if (item && item->get_cell_mode(0) == TreeItem::CELL_MODE_CHECK) { - - item->set_checked(0, true); - } - } - - if (!undo_redo || Object::cast_to<ArrayPropertyEdit>(obj) || Object::cast_to<DictionaryPropertyEdit>(obj)) { //kind of hacky - - obj->set(p_name, p_value); - if (p_refresh_all) - _changed_callbacks(obj, ""); - else - _changed_callbacks(obj, p_name); - - emit_signal(_prop_edited, p_name); - - } else if (Object::cast_to<MultiNodeEdit>(obj)) { - - Object::cast_to<MultiNodeEdit>(obj)->set_property_field(p_name, p_value, p_changed_field); - _changed_callbacks(obj, p_name); - emit_signal(_prop_edited, p_name); - } else { - - undo_redo->create_action(TTR("Set") + " " + p_name, UndoRedo::MERGE_ENDS); - undo_redo->add_do_property(obj, p_name, p_value); - undo_redo->add_undo_property(obj, p_name, obj->get(p_name)); - - if (p_refresh_all) { - undo_redo->add_do_method(this, "_changed_callback", obj, ""); - undo_redo->add_undo_method(this, "_changed_callback", obj, ""); - } else { - - undo_redo->add_do_method(this, "_changed_callback", obj, p_name); - undo_redo->add_undo_method(this, "_changed_callback", obj, p_name); - } - - Resource *r = Object::cast_to<Resource>(obj); - if (r) { - if (!r->is_edited() && String(p_name) != "resource/edited") { - undo_redo->add_do_method(r, "set_edited", true); - undo_redo->add_undo_method(r, "set_edited", false); - } - - if (String(p_name) == "resource_local_to_scene") { - bool prev = obj->get(p_name); - bool next = p_value; - if (next) { - undo_redo->add_do_method(this, "setup_local_to_scene"); - } - if (prev) { - undo_redo->add_undo_method(this, "setup_local_to_scene"); - } - } - } - undo_redo->add_do_method(this, "emit_signal", _prop_edited, p_name); - undo_redo->add_undo_method(this, "emit_signal", _prop_edited, p_name); - undo_redo->commit_action(); - } -} - -void PropertyEditor::_item_edited() { - - TreeItem *item = tree->get_edited(); - if (!item) - return; //it all happened too fast.. - - Dictionary d = item->get_metadata(0); - - String name = d["name"]; - - if (tree->get_edited_column() == 0) { - //property checked - if (autoclear) { - if (!item->is_checked(0)) { - obj->set(name, Variant()); - update_property(name); - } else { - Variant::CallError ce; - obj->set(name, Variant::construct(Variant::Type(int(d["type"])), NULL, 0, ce)); - } - } else { - emit_signal("property_toggled", name, item->is_checked(0)); - } - return; - } - - if (autoclear && item->get_cell_mode(0) == TreeItem::CELL_MODE_CHECK && item->get_cell_mode(1) != TreeItem::CELL_MODE_CUSTOM) { - item->set_checked(0, true); - } - - int type = d["type"]; - int hint = d["hint"]; - int usage = d["usage"]; - bool refresh_all = usage & PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED; - - String hint_text = d["hint_text"]; - switch (type) { - - case Variant::NIL: { - - } break; - case Variant::BOOL: { - - item->set_tooltip(1, item->is_checked(1) ? "True" : "False"); - _edit_set(name, item->is_checked(1), refresh_all); - } break; - case Variant::INT: - case Variant::REAL: { - - if (hint == PROPERTY_HINT_LAYERS_2D_PHYSICS || hint == PROPERTY_HINT_LAYERS_2D_RENDER || hint == PROPERTY_HINT_LAYERS_3D_PHYSICS || hint == PROPERTY_HINT_LAYERS_3D_RENDER) - break; - if (hint == PROPERTY_HINT_EXP_EASING) - break; - if (hint == PROPERTY_HINT_FLAGS) - break; - - if (type == Variant::INT) - _edit_set(name, int64_t(round(item->get_range(1))), refresh_all); - else - _edit_set(name, item->get_range(1), refresh_all); - } break; - case Variant::STRING: { - - if (hint == PROPERTY_HINT_ENUM) { - - int idx = item->get_range(1); - - Vector<String> strings = hint_text.split(","); - String txt; - if (idx >= 0 && idx < strings.size()) { - - txt = strings[idx]; - } - - _edit_set(name, txt, refresh_all); - } else { - _edit_set(name, item->get_text(1), refresh_all); - } - } break; - - // math types - case Variant::VECTOR3: { - - } break; - case Variant::PLANE: { - - } break; - case Variant::QUAT: { - - } break; - case Variant::AABB: { - - } break; - case Variant::BASIS: { - - } break; - case Variant::TRANSFORM: { - - } break; - case Variant::COLOR: { - - } break; - - case Variant::NODE_PATH: { - _edit_set(name, NodePath(item->get_text(1)), refresh_all); - - } break; - case Variant::OBJECT: { - if (!item->is_custom_set_as_button(1)) - break; - - Ref<EncodedObjectAsID> encoded = obj->get(name); //for debugger and remote tools - - if (encoded.is_valid()) { - - emit_signal("object_id_selected", encoded->get_object_id()); - } - - RES res = obj->get(name); - if (res.is_valid()) { - emit_signal("resource_selected", res.get_ref_ptr(), name); - } - - } break; - - case Variant::DICTIONARY: { - - } break; - - // arrays - case Variant::POOL_BYTE_ARRAY: { - - } break; - case Variant::POOL_INT_ARRAY: { - - } break; - case Variant::POOL_REAL_ARRAY: { - - } break; - case Variant::POOL_STRING_ARRAY: { - - } break; - case Variant::POOL_VECTOR3_ARRAY: { - - } break; - case Variant::POOL_COLOR_ARRAY: { - - } break; - }; -} - -void PropertyEditor::_resource_edit_request() { - - RES res = custom_editor->get_variant(); - if (res.is_null()) - return; - - String name = custom_editor->get_name(); - - emit_signal("resource_selected", res.get_ref_ptr(), name); -} - -void PropertyEditor::_custom_editor_edited() { - - if (!obj) - return; - - _edit_set(custom_editor->get_name(), custom_editor->get_variant()); -} - -void PropertyEditor::_custom_editor_edited_field(const String &p_field_name) { - - ERR_FAIL_COND(p_field_name == ""); - - if (!obj) - return; - - _edit_set(custom_editor->get_name(), custom_editor->get_variant(), false, p_field_name); -} - -void PropertyEditor::_custom_editor_request(bool p_arrow) { - - TreeItem *item = tree->get_edited(); - ERR_FAIL_COND(!item); - Dictionary d = item->get_metadata(0); - - String name = d["name"]; - Variant::Type type = Variant::NIL; - if (d.has("type")) - type = (Variant::Type)((int)(d["type"])); - - Variant v = obj->get(name); - int hint = d.has("hint") ? d["hint"].operator int() : -1; - String hint_text = d.has("hint_text") ? d["hint_text"] : ""; - Rect2 where = tree->get_custom_popup_rect(); - custom_editor->set_position(where.position); - - if (custom_editor->edit(obj, name, type, v, hint, hint_text)) { - custom_editor->popup(); - } -} - -void PropertyEditor::edit(Object *p_object) { - - if (obj == p_object) - return; - if (obj) { - - obj->remove_change_receptor(this); - } - - obj = p_object; - - evaluator->edit(p_object); - - update_tree(); - - if (obj) { - - obj->add_change_receptor(this); - } -} - -void PropertyEditor::_set_range_def(Object *p_item, String prop, float p_frame) { - - TreeItem *ti = Object::cast_to<TreeItem>(p_item); - ERR_FAIL_COND(!ti); - - ti->call_deferred("set_range", 1, p_frame); - obj->call_deferred("set", prop, p_frame); -} - -void PropertyEditor::_edit_button(Object *p_item, int p_column, int p_button) { - - TreeItem *ti = Object::cast_to<TreeItem>(p_item); - ERR_FAIL_COND(!ti); - - Dictionary d = ti->get_metadata(0); - - if (p_button == 2) { - - if (!d.has("name")) - return; - String prop = d["name"]; - emit_signal("property_keyed", prop, obj->get(prop), false); - } else if (p_button == 5) { - if (!d.has("name")) - return; - String prop = d["name"]; - emit_signal("property_keyed", prop, obj->get(prop), true); - call_deferred("_set_range_def", ti, prop, ti->get_range(p_column) + 1.0); - } else if (p_button == 3) { - - if (!d.has("name")) - return; - - String prop = d["name"]; - - Variant vorig; - - if (_might_be_in_instance() && _get_instanced_node_original_property(prop, vorig)) { - - _edit_set(prop, vorig.duplicate(true)); // Set, making sure to duplicate arrays properly - return; - } - - if (obj->call("property_can_revert", prop).operator bool()) { - Variant rev = obj->call("property_get_revert", prop); - _edit_set(prop, rev); - } - - if (!obj->get_script().is_null()) { - Ref<Script> scr = obj->get_script(); - Variant orig_value; - if (scr->get_property_default_value(prop, orig_value)) { - _edit_set(prop, orig_value); - } - } - - } else { - - Dictionary d = ti->get_metadata(0); - if (!d.has("type")) - return; - if (!d.has("hint")) - return; - if (!d.has("name")) - return; - if (!d.has("hint_text")) - return; - - int t = d["type"]; - int h = d["hint"]; - String n = d["name"]; - String ht = d["hint_text"]; - - if (t == Variant::NODE_PATH) { - - Variant v = obj->get(n); - Rect2 where = tree->get_item_rect(ti, 1); - where.position -= tree->get_scroll(); - where.position += tree->get_global_position() + Point2(where.size.width, 0); - for (int i = ti->get_button_count(p_column) - 1; i >= p_button; i--) - where.position.x -= ti->get_button(p_column, i)->get_width(); - custom_editor->set_position(where.position); - custom_editor->edit(obj, n, (Variant::Type)t, v, h, ht); - custom_editor->popup(); - - } else if (t == Variant::STRING) { - - Variant v = obj->get(n); - custom_editor->edit(obj, n, (Variant::Type)t, v, h, ht); - if (h == PROPERTY_HINT_FILE || h == PROPERTY_HINT_DIR || h == PROPERTY_HINT_GLOBAL_DIR || h == PROPERTY_HINT_GLOBAL_FILE) { - - Rect2 where = tree->get_item_rect(ti, 1); - where.position -= tree->get_scroll(); - where.position += tree->get_global_position() + Point2(where.size.width, 0); - for (int i = ti->get_button_count(p_column) - 1; i >= p_button; i--) - where.position.x -= ti->get_button(p_column, i)->get_width(); - custom_editor->set_position(where.position); - custom_editor->popup(); - } else { - custom_editor->popup_centered_ratio(); - } - - } else if (t == Variant::OBJECT) { - - RES r = obj->get(n); - if (r.is_valid()) { - - emit_signal("resource_selected", r, n); - } - } else if (t == Variant::INT && h == PROPERTY_HINT_OBJECT_ID) { - - emit_signal("object_id_selected", obj->get(n)); - - } else if (t == Variant::ARRAY || t == Variant::POOL_INT_ARRAY || t == Variant::POOL_REAL_ARRAY || t == Variant::POOL_STRING_ARRAY || t == Variant::POOL_VECTOR2_ARRAY || t == Variant::POOL_VECTOR3_ARRAY || t == Variant::POOL_COLOR_ARRAY || t == Variant::POOL_BYTE_ARRAY) { - - Variant v = obj->get(n); - - if (v.get_type() != t) { - Variant::CallError ce; - v = Variant::construct(Variant::Type(t), NULL, 0, ce); - } - - Ref<ArrayPropertyEdit> ape = memnew(ArrayPropertyEdit); - ape->edit(obj, n, ht, Variant::Type(t)); - EditorNode::get_singleton()->push_item(ape.ptr()); - - } else if (t == Variant::DICTIONARY) { - - Variant v = obj->get(n); - - if (v.get_type() != t) { - Variant::CallError ce; - v = Variant::construct(Variant::Type(t), NULL, 0, ce); - } - - Ref<DictionaryPropertyEdit> dpe = memnew(DictionaryPropertyEdit); - dpe->edit(obj, n); - EditorNode::get_singleton()->push_item(dpe.ptr()); - } - } -} - -void PropertyEditor::_node_removed(Node *p_node) { - - if (p_node == obj) { - edit(NULL); - } -} - -void PropertyEditor::set_keying(bool p_active) { - - if (keying == p_active) - return; - - keying = p_active; - update_tree(); -} - -void PropertyEditor::_draw_flags(Object *p_object, const Rect2 &p_rect) { - - TreeItem *ti = Object::cast_to<TreeItem>(p_object); - if (!ti) - return; - - Dictionary d = ti->get_metadata(0); - - if (!d.has("name")) - return; - - uint32_t f = obj->get(d["name"]); - - int bsize = (p_rect.size.height * 80 / 100) / 2; - - int h = bsize * 2 + 1; - int vofs = (p_rect.size.height - h) / 2; - - for (int i = 0; i < 2; i++) { - - Point2 ofs(4, vofs); - if (i == 1) - ofs.y += bsize + 1; - - ofs += p_rect.position; - for (int j = 0; j < 10; j++) { - - Point2 o = ofs + Point2(j * (bsize + 1), 0); - if (j >= 5) - o.x += 1; - - uint32_t idx = i * 10 + j; - bool on = f & (1 << idx); - tree->draw_rect(Rect2(o, Size2(bsize, bsize)), Color(0, 0, 0, on ? 0.8 : 0.3)); - } - } -} - -void PropertyEditor::_filter_changed(const String &p_text) { - - update_tree(); -} - -void PropertyEditor::_resource_preview_done(const String &p_path, const Ref<Texture> &p_preview, Variant p_ud) { - - if (p_preview.is_null()) - return; //don't bother with empty preview - - ObjectID id = p_ud; - Object *obj = ObjectDB::get_instance(id); - - if (!obj) - return; - - TreeItem *ti = Object::cast_to<TreeItem>(obj); - - ERR_FAIL_COND(!ti); - - int tw = EditorSettings::get_singleton()->get("docks/property_editor/texture_preview_width"); - - ti->set_icon(1, p_preview); //should be scaled I think? - ti->set_icon_max_width(1, tw); - ti->set_text(1, ""); -} -void PropertyEditor::_bind_methods() { - - ClassDB::bind_method("_item_edited", &PropertyEditor::_item_edited); - ClassDB::bind_method("_item_selected", &PropertyEditor::_item_selected); - ClassDB::bind_method("_item_rmb_edited", &PropertyEditor::_item_rmb_edited); - ClassDB::bind_method("_item_folded", &PropertyEditor::_item_folded); - ClassDB::bind_method("_custom_editor_request", &PropertyEditor::_custom_editor_request); - ClassDB::bind_method("_custom_editor_edited", &PropertyEditor::_custom_editor_edited); - ClassDB::bind_method("_custom_editor_edited_field", &PropertyEditor::_custom_editor_edited_field, DEFVAL("")); - ClassDB::bind_method("_resource_edit_request", &PropertyEditor::_resource_edit_request); - ClassDB::bind_method("_node_removed", &PropertyEditor::_node_removed); - ClassDB::bind_method("_edit_button", &PropertyEditor::_edit_button); - ClassDB::bind_method("_changed_callback", &PropertyEditor::_changed_callbacks); - ClassDB::bind_method("_draw_flags", &PropertyEditor::_draw_flags); - ClassDB::bind_method("_set_range_def", &PropertyEditor::_set_range_def); - ClassDB::bind_method("_filter_changed", &PropertyEditor::_filter_changed); - ClassDB::bind_method("update_tree", &PropertyEditor::update_tree); - ClassDB::bind_method("_resource_preview_done", &PropertyEditor::_resource_preview_done); - ClassDB::bind_method("refresh", &PropertyEditor::refresh); - ClassDB::bind_method("_draw_transparency", &PropertyEditor::_draw_transparency); - ClassDB::bind_method("edit", &PropertyEditor::edit); - - ClassDB::bind_method(D_METHOD("get_drag_data_fw"), &PropertyEditor::get_drag_data_fw); - ClassDB::bind_method(D_METHOD("can_drop_data_fw"), &PropertyEditor::can_drop_data_fw); - ClassDB::bind_method(D_METHOD("drop_data_fw"), &PropertyEditor::drop_data_fw); - - ADD_SIGNAL(MethodInfo("property_toggled", PropertyInfo(Variant::STRING, "property"), PropertyInfo(Variant::BOOL, "value"))); - ADD_SIGNAL(MethodInfo("resource_selected", PropertyInfo(Variant::OBJECT, "res"), PropertyInfo(Variant::STRING, "prop"))); - ADD_SIGNAL(MethodInfo("object_id_selected", PropertyInfo(Variant::INT, "id"))); - ADD_SIGNAL(MethodInfo("property_keyed", PropertyInfo(Variant::STRING, "property"))); - ADD_SIGNAL(MethodInfo("property_edited", PropertyInfo(Variant::STRING, "property"))); -} - -Tree *PropertyEditor::get_property_tree() { - - return tree; -} - -Label *PropertyEditor::get_top_label() { - - return top_label; -} - -void PropertyEditor::hide_top_label() { - - top_label->hide(); - tree->set_begin(Point2(0, 0)); -} - -String PropertyEditor::get_selected_path() const { - - TreeItem *ti = tree->get_selected(); - if (!ti) - return ""; - - Dictionary d = ti->get_metadata(0); - - if (d.has("name")) - return d["name"]; - else - return ""; -} - -bool PropertyEditor::is_capitalize_paths_enabled() const { - - return capitalize_paths; -} - -void PropertyEditor::set_enable_capitalize_paths(bool p_capitalize) { - - capitalize_paths = p_capitalize; - update_tree_pending = true; -} - -void PropertyEditor::set_autoclear(bool p_enable) { - - autoclear = p_enable; -} - -void PropertyEditor::set_show_categories(bool p_show) { - - show_categories = p_show; - update_tree(); -} - -void PropertyEditor::set_use_filter(bool p_use) { - - if (p_use == use_filter) - return; - - use_filter = p_use; - update_tree(); -} - -void PropertyEditor::register_text_enter(Node *p_line_edit) { - - ERR_FAIL_NULL(p_line_edit); - search_box = Object::cast_to<LineEdit>(p_line_edit); - - if (search_box) - search_box->connect("text_changed", this, "_filter_changed"); -} - -void PropertyEditor::set_property_selectable(bool p_selectable) { - property_selectable = p_selectable; - update_tree(); -} - -void PropertyEditor::set_subsection_selectable(bool p_selectable) { - - if (p_selectable == subsection_selectable) - return; - - subsection_selectable = p_selectable; - update_tree(); -} - -void PropertyEditor::set_use_folding(bool p_enable) { - - use_folding = p_enable; - tree->set_hide_folding(false); -} - -void PropertyEditor::collapse_all_folding() { - if (!obj) - return; - for (List<String>::Element *E = foldable_property_cache.front(); E; E = E->next()) { - obj->editor_set_section_unfold(E->get(), false); - } - update_tree(); -} - -void PropertyEditor::expand_all_folding() { - - if (!obj) - return; - for (List<String>::Element *E = foldable_property_cache.front(); E; E = E->next()) { - obj->editor_set_section_unfold(E->get(), true); - } - update_tree(); -} - -PropertyEditor::PropertyEditor() { - - _prop_edited = "property_edited"; - - hide_script = true; - use_folding = false; - - undo_redo = NULL; - obj = NULL; - search_box = NULL; - changing = false; - update_tree_pending = false; - - top_label = memnew(Label); - top_label->set_text(TTR("Properties:")); - top_label->set_anchor(MARGIN_RIGHT, ANCHOR_END); - top_label->set_begin(Point2(10, 0)); - top_label->set_end(Point2(0, 12)); - - add_child(top_label); - - tree = memnew(Tree); - tree->set_anchor(MARGIN_RIGHT, ANCHOR_END); - tree->set_anchor(MARGIN_BOTTOM, ANCHOR_END); - tree->set_begin(Point2(0, 19)); - tree->set_end(Point2(0, 0)); - - tree->set_columns(2); - tree->set_column_expand(0, true); - tree->set_column_min_width(0, 30); - tree->set_column_expand(1, true); - tree->set_column_min_width(1, 18); - add_child(tree); - - tree->connect("item_edited", this, "_item_edited", varray(), CONNECT_DEFERRED); - tree->connect("item_rmb_edited", this, "_item_rmb_edited"); - tree->connect("cell_selected", this, "_item_selected"); - tree->connect("item_collapsed", this, "_item_folded"); - - tree->set_drag_forwarding(this); - - set_physics_process(true); - - custom_editor = memnew(CustomPropertyEditor); - custom_editor->set_pass_on_modal_close_click(false); - add_child(custom_editor); - - tree->connect("custom_popup_edited", this, "_custom_editor_request"); - tree->connect("button_pressed", this, "_edit_button"); - custom_editor->connect("variant_changed", this, "_custom_editor_edited"); - custom_editor->connect("variant_field_changed", this, "_custom_editor_edited_field"); - custom_editor->connect("resource_edit_request", this, "_resource_edit_request", make_binds(), CONNECT_DEFERRED); - tree->set_hide_folding(true); - - evaluator = memnew(PropertyValueEvaluator); - tree->set_value_evaluator(evaluator); - custom_editor->set_value_evaluator(evaluator); - - capitalize_paths = true; - autoclear = false; - tree->set_column_titles_visible(false); - tree->add_constant_override("button_margin", 0); - - keying = false; - read_only = false; - show_categories = false; - refresh_countdown = 0; - use_doc_hints = false; - updating_folding = true; - use_filter = false; - subsection_selectable = false; - property_selectable = false; - show_type_icons = false; // TODO: need to reimplement it to work with the new inspector -} - -PropertyEditor::~PropertyEditor() { - memdelete(evaluator); -} - -///////////////////////////// - -class SectionedPropertyEditorFilter : public Object { - - GDCLASS(SectionedPropertyEditorFilter, Object); - - Object *edited; - String section; - bool allow_sub; - - bool _set(const StringName &p_name, const Variant &p_value) { - - if (!edited) - return false; - - String name = p_name; - if (section != "") { - name = section + "/" + name; - } - - bool valid; - edited->set(name, p_value, &valid); - return valid; - } - - bool _get(const StringName &p_name, Variant &r_ret) const { - - if (!edited) - return false; - - String name = p_name; - if (section != "") { - name = section + "/" + name; - } - - bool valid = false; - - r_ret = edited->get(name, &valid); - return valid; - } - void _get_property_list(List<PropertyInfo> *p_list) const { - - if (!edited) - return; - - List<PropertyInfo> pinfo; - edited->get_property_list(&pinfo); - for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) { - - PropertyInfo pi = E->get(); - int sp = pi.name.find("/"); - - if (pi.name == "resource_path" || pi.name == "resource_name" || pi.name == "resource_local_to_scene" || pi.name.begins_with("script/")) //skip resource stuff - continue; - - if (sp == -1) { - pi.name = "global/" + pi.name; - } - - if (pi.name.begins_with(section + "/")) { - pi.name = pi.name.replace_first(section + "/", ""); - if (!allow_sub && pi.name.find("/") != -1) - continue; - p_list->push_back(pi); - } - } - } - - bool property_can_revert(const String &p_name) { - - return edited->call("property_can_revert", section + "/" + p_name); - } - - Variant property_get_revert(const String &p_name) { - - return edited->call("property_get_revert", section + "/" + p_name); - } - -protected: - static void _bind_methods() { - - ClassDB::bind_method("property_can_revert", &SectionedPropertyEditorFilter::property_can_revert); - ClassDB::bind_method("property_get_revert", &SectionedPropertyEditorFilter::property_get_revert); - } - -public: - void set_section(const String &p_section, bool p_allow_sub) { - - section = p_section; - allow_sub = p_allow_sub; - _change_notify(); - } - - void set_edited(Object *p_edited) { - edited = p_edited; - _change_notify(); - } - - SectionedPropertyEditorFilter() { - edited = NULL; - } -}; - -void SectionedPropertyEditor::_bind_methods() { - - ClassDB::bind_method("_section_selected", &SectionedPropertyEditor::_section_selected); - ClassDB::bind_method("_search_changed", &SectionedPropertyEditor::_search_changed); - - ClassDB::bind_method("update_category_list", &SectionedPropertyEditor::update_category_list); -} - -void SectionedPropertyEditor::_section_selected() { - - if (!sections->get_selected()) - return; - - filter->set_section(sections->get_selected()->get_metadata(0), sections->get_selected()->get_children() == NULL); -} - -void SectionedPropertyEditor::set_current_section(const String &p_section) { - - if (section_map.has(p_section)) { - section_map[p_section]->select(0); - } -} - -String SectionedPropertyEditor::get_current_section() const { - - if (sections->get_selected()) - return sections->get_selected()->get_metadata(0); - else - return ""; -} - -String SectionedPropertyEditor::get_full_item_path(const String &p_item) { - - String base = get_current_section(); - - if (base != "") - return base + "/" + p_item; - else - return p_item; -} - -void SectionedPropertyEditor::edit(Object *p_object) { - - if (!p_object) { - obj = -1; - sections->clear(); - - filter->set_edited(NULL); - editor->edit(NULL); - - return; - } - - ObjectID id = p_object->get_instance_id(); - - if (obj != id) { - - obj = id; - update_category_list(); - - filter->set_edited(p_object); - editor->edit(filter); - - if (sections->get_root()->get_children()) { - sections->get_root()->get_children()->select(0); - } - } else { - - update_category_list(); - } -} - -void SectionedPropertyEditor::update_category_list() { - - String selected_category = get_current_section(); - sections->clear(); - - Object *o = ObjectDB::get_instance(obj); - - if (!o) - return; - - List<PropertyInfo> pinfo; - o->get_property_list(&pinfo); - - section_map.clear(); - - TreeItem *root = sections->create_item(); - section_map[""] = root; - - for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) { - - PropertyInfo pi = E->get(); - - if (pi.usage & PROPERTY_USAGE_CATEGORY) - continue; - else if (!(pi.usage & PROPERTY_USAGE_EDITOR)) - continue; - - if (pi.name.find(":") != -1 || pi.name == "script" || pi.name == "resource_name" || pi.name == "resource_path" || pi.name == "resource_local_to_scene") - continue; - - if (search_box && search_box->get_text() != String() && pi.name.findn(search_box->get_text()) == -1) - continue; - - int sp = pi.name.find("/"); - if (sp == -1) - pi.name = "Global/" + pi.name; - - Vector<String> sectionarr = pi.name.split("/"); - String metasection; - - int sc = MIN(2, sectionarr.size() - 1); - - for (int i = 0; i < sc; i++) { - - TreeItem *parent = section_map[metasection]; - parent->set_custom_bg_color(0, get_color("prop_subsection", "Editor")); - - if (i > 0) { - metasection += "/" + sectionarr[i]; - } else { - metasection = sectionarr[i]; - } - - if (!section_map.has(metasection)) { - TreeItem *ms = sections->create_item(parent); - section_map[metasection] = ms; - ms->set_text(0, sectionarr[i].capitalize()); - ms->set_metadata(0, metasection); - ms->set_selectable(0, false); - } - - if (i == sc - 1) { - //if it has children, make selectable - section_map[metasection]->set_selectable(0, true); - } - } - } - - if (section_map.has(selected_category)) { - section_map[selected_category]->select(0); - } - - editor->update_tree(); -} - -void SectionedPropertyEditor::register_search_box(LineEdit *p_box) { - - search_box = p_box; - editor->register_text_enter(p_box); - search_box->connect("text_changed", this, "_search_changed"); -} - -void SectionedPropertyEditor::_search_changed(const String &p_what) { - - update_category_list(); -} - -PropertyEditor *SectionedPropertyEditor::get_property_editor() { - - return editor; -} - -SectionedPropertyEditor::SectionedPropertyEditor() { - - obj = -1; - - search_box = NULL; - - add_constant_override("autohide", 1); // Fixes the dragger always showing up - - VBoxContainer *left_vb = memnew(VBoxContainer); - left_vb->set_custom_minimum_size(Size2(170, 0) * EDSCALE); - add_child(left_vb); - - sections = memnew(Tree); - sections->set_v_size_flags(SIZE_EXPAND_FILL); - sections->set_hide_root(true); - - left_vb->add_child(sections, true); - - VBoxContainer *right_vb = memnew(VBoxContainer); - right_vb->set_custom_minimum_size(Size2(300, 0) * EDSCALE); - right_vb->set_h_size_flags(SIZE_EXPAND_FILL); - add_child(right_vb); - - filter = memnew(SectionedPropertyEditorFilter); - editor = memnew(PropertyEditor); - editor->set_v_size_flags(SIZE_EXPAND_FILL); - right_vb->add_child(editor, true); - - editor->get_property_tree()->set_column_titles_visible(false); - - editor->hide_top_label(); - - sections->connect("cell_selected", this, "_section_selected"); -} - -SectionedPropertyEditor::~SectionedPropertyEditor() { - - memdelete(filter); -} - -double PropertyValueEvaluator::eval(const String &p_text) { - - // If range value contains a comma replace it with dot (issue #6028) - const String &p_new_text = p_text.replace(",", "."); - - if (!obj || !script_language) - return _default_eval(p_new_text); - - Ref<Script> script = Ref<Script>(script_language->create_script()); - script->set_source_code(_build_script(p_new_text)); - Error err = script->reload(); - if (err) { - ERR_PRINTS("PropertyValueEvaluator: Error loading script for expression: " + p_new_text); - return _default_eval(p_new_text); - } - - Object dummy; - ScriptInstance *script_instance = script->instance_create(&dummy); - if (!script_instance) - return _default_eval(p_new_text); - - Variant::CallError call_err; - Variant arg = obj; - const Variant *args[] = { &arg }; - double result = script_instance->call("eval", args, 1, call_err); - if (call_err.error == Variant::CallError::CALL_OK) { - return result; - } - ERR_PRINTS("PropertyValueEvaluator: Eval failed, error code: " + itos(call_err.error)); - - return _default_eval(p_new_text); -} - -void PropertyValueEvaluator::edit(Object *p_obj) { - obj = p_obj; -} - -String PropertyValueEvaluator::_build_script(const String &p_text) { - String script_text = "tool\nextends Object\nfunc eval(s):\n\tself = s\n\treturn " + p_text.strip_edges() + "\n"; - return script_text; -} - -PropertyValueEvaluator::PropertyValueEvaluator() { - script_language = NULL; - - for (int i = 0; i < ScriptServer::get_language_count(); i++) { - if (ScriptServer::get_language(i)->get_name() == "GDScript") { - script_language = ScriptServer::get_language(i); - } - } -} - -PropertyValueEvaluator::~PropertyValueEvaluator() { -} diff --git a/editor/property_editor.h b/editor/property_editor.h index 7d8fa22f3f..c74103df3d 100644 --- a/editor/property_editor.h +++ b/editor/property_editor.h @@ -135,6 +135,9 @@ class CustomPropertyEditor : public Popup { void _text_edit_changed(); void _file_selected(String p_file); void _modified(String p_string); + + real_t _parse_real_expression(String text); + void _range_modified(double p_value); void _focus_enter(); void _focus_exit(); @@ -168,204 +171,9 @@ public: void set_read_only(bool p_read_only) { read_only = p_read_only; } - void set_value_evaluator(PropertyValueEvaluator *p_evaluator) { evaluator = p_evaluator; } - bool edit(Object *p_owner, const String &p_name, Variant::Type p_type, const Variant &p_variant, int p_hint, String p_hint_text); CustomPropertyEditor(); }; -class PropertyEditor : public Control { - - GDCLASS(PropertyEditor, Control); - - Tree *tree; - Label *top_label; - LineEdit *search_box; - - PropertyValueEvaluator *evaluator; - - Object *obj; - - StringName _prop_edited; - - bool capitalize_paths; - bool changing; - bool update_tree_pending; - bool autoclear; - bool keying; - bool read_only; - bool show_categories; - bool show_type_icons; - float refresh_countdown; - bool use_doc_hints; - bool use_filter; - bool subsection_selectable; - bool hide_script; - bool use_folding; - bool property_selectable; - bool updating_folding; - - List<String> foldable_property_cache; - HashMap<String, String> pending; - String selected_property; - - Map<StringName, Map<StringName, String> > descr_cache; - Map<StringName, String> class_descr_cache; - - CustomPropertyEditor *custom_editor; - - void _resource_edit_request(); - void _custom_editor_edited(); - void _custom_editor_edited_field(const String &p_field_name); - void _custom_editor_request(bool p_arrow); - - void _item_selected(); - void _item_rmb_edited(); - void _item_edited(); - TreeItem *get_parent_node(String p_path, HashMap<String, TreeItem *> &item_paths, TreeItem *root, TreeItem *category); - - void set_item_text(TreeItem *p_item, int p_type, const String &p_name, int p_hint = PROPERTY_HINT_NONE, const String &p_hint_text = ""); - - TreeItem *find_item(TreeItem *p_item, const String &p_name); - - virtual void _changed_callback(Object *p_changed, const char *p_prop); - virtual void _changed_callbacks(Object *p_changed, const String &p_prop); - - void _check_reload_status(const String &p_name, TreeItem *item); - - void _edit_button(Object *p_item, int p_column, int p_button); - - void _node_removed(Node *p_node); - - friend class ProjectExportDialog; - void _edit_set(const String &p_name, const Variant &p_value, bool p_refresh_all = false, const String &p_changed_field = ""); - void _draw_flags(Object *p_object, const Rect2 &p_rect); - - bool _might_be_in_instance(); - bool _get_instanced_node_original_property(const StringName &p_prop, Variant &value); - bool _is_property_different(const Variant &p_current, const Variant &p_orig, int p_usage = 0); - bool _is_instanced_node_with_original_property_different(const String &p_name, TreeItem *item); - - void _refresh_item(TreeItem *p_item); - void _set_range_def(Object *p_item, String prop, float p_frame); - - void _filter_changed(const String &p_text); - - void _mark_drop_fields(TreeItem *p_at); - void _clear_drop_fields(TreeItem *p_at); - - bool _is_drop_valid(const Dictionary &p_drag_data, const Dictionary &p_item_data) const; - Variant get_drag_data_fw(const Point2 &p_point, Control *p_from); - bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const; - void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from); - - void _resource_preview_done(const String &p_path, const Ref<Texture> &p_preview, Variant p_ud); - void _draw_transparency(Object *t, const Rect2 &p_rect); - void _item_folded(Object *item_obj); - - UndoRedo *undo_redo; - -protected: - void _notification(int p_what); - static void _bind_methods(); - -public: - void set_undo_redo(UndoRedo *p_undo_redo) { undo_redo = p_undo_redo; } - - String get_selected_path() const; - - Tree *get_property_tree(); - Label *get_top_label(); - void hide_top_label(); - void update_tree(); - void update_property(const String &p_prop); - - void refresh(); - - void edit(Object *p_object); - - void set_keying(bool p_active); - void set_read_only(bool p_read_only) { - read_only = p_read_only; - custom_editor->set_read_only(p_read_only); - } - - bool is_capitalize_paths_enabled() const; - void set_enable_capitalize_paths(bool p_capitalize); - void set_autoclear(bool p_enable); - - void set_show_categories(bool p_show); - void set_use_doc_hints(bool p_enable) { use_doc_hints = p_enable; } - void set_hide_script(bool p_hide) { hide_script = p_hide; } - - void set_use_filter(bool p_use); - void register_text_enter(Node *p_line_edit); - - void set_subsection_selectable(bool p_selectable); - void set_property_selectable(bool p_selectable); - - void set_use_folding(bool p_enable); - - void collapse_all_folding(); - void expand_all_folding(); - - PropertyEditor(); - ~PropertyEditor(); -}; - -class SectionedPropertyEditorFilter; - -class SectionedPropertyEditor : public HSplitContainer { - - GDCLASS(SectionedPropertyEditor, HSplitContainer); - - ObjectID obj; - - Tree *sections; - SectionedPropertyEditorFilter *filter; - - Map<String, TreeItem *> section_map; - PropertyEditor *editor; - LineEdit *search_box; - - static void _bind_methods(); - void _section_selected(); - - void _search_changed(const String &p_what); - -public: - void register_search_box(LineEdit *p_box); - PropertyEditor *get_property_editor(); - void edit(Object *p_object); - String get_full_item_path(const String &p_item); - - void set_current_section(const String &p_section); - String get_current_section() const; - - void update_category_list(); - - SectionedPropertyEditor(); - ~SectionedPropertyEditor(); -}; - -class PropertyValueEvaluator : public ValueEvaluator { - GDCLASS(PropertyValueEvaluator, ValueEvaluator); - - Object *obj; - ScriptLanguage *script_language; - String _build_script(const String &p_text); - - _FORCE_INLINE_ double _default_eval(const String &p_text) { - return p_text.to_double(); - } - -public: - void edit(Object *p_obj); - double eval(const String &p_text); - - PropertyValueEvaluator(); - ~PropertyValueEvaluator(); -}; - #endif diff --git a/editor/property_selector.cpp b/editor/property_selector.cpp index dae1bdeeb0..9042bdc7c1 100644 --- a/editor/property_selector.cpp +++ b/editor/property_selector.cpp @@ -30,8 +30,9 @@ #include "property_selector.h" +#include "core/os/keyboard.h" +#include "editor/editor_node.h" #include "editor_scale.h" -#include "os/keyboard.h" void PropertySelector::_text_changed(const String &p_newtext) { @@ -161,10 +162,8 @@ void PropertySelector::_update_search() { Ref<Texture> icon; if (E->get().name == "Script Variables") { icon = get_icon("Script", "EditorIcons"); - } else if (has_icon(E->get().name, "EditorIcons")) { - icon = get_icon(E->get().name, "EditorIcons"); } else { - icon = get_icon("Object", "EditorIcons"); + icon = EditorNode::get_singleton()->get_class_icon(E->get().name); } category->set_icon(0, icon); continue; @@ -241,10 +240,8 @@ void PropertySelector::_update_search() { if (E->get().name == "*Script Methods") { icon = get_icon("Script", "EditorIcons"); script_methods = true; - } else if (has_icon(rep, "EditorIcons")) { - icon = get_icon(rep, "EditorIcons"); } else { - icon = get_icon("Object", "EditorIcons"); + icon = EditorNode::get_singleton()->get_class_icon(rep); } category->set_icon(0, icon); diff --git a/editor/pvrtc_compress.cpp b/editor/pvrtc_compress.cpp index 57a2b0d97f..30e78aa32b 100644 --- a/editor/pvrtc_compress.cpp +++ b/editor/pvrtc_compress.cpp @@ -30,11 +30,11 @@ #include "pvrtc_compress.h" +#include "core/io/resource_loader.h" +#include "core/io/resource_saver.h" +#include "core/os/file_access.h" +#include "core/os/os.h" #include "editor_settings.h" -#include "io/resource_loader.h" -#include "io/resource_saver.h" -#include "os/file_access.h" -#include "os/os.h" #include "scene/resources/texture.h" static void (*_base_image_compress_pvrtc2_func)(Image *) = NULL; @@ -115,11 +115,6 @@ static void _compress_pvrtc4(Image *p_image) { _compress_image(Image::COMPRESS_PVRTC4, p_image); } -static void _compress_etc(Image *p_image) { - - _compress_image(Image::COMPRESS_ETC, p_image); -} - void _pvrtc_register_compressors() { _base_image_compress_pvrtc2_func = Image::_image_compress_pvrtc2_func; @@ -127,5 +122,4 @@ void _pvrtc_register_compressors() { Image::_image_compress_pvrtc2_func = _compress_pvrtc2; Image::_image_compress_pvrtc4_func = _compress_pvrtc4; - //Image::_image_compress_etc_func=_compress_etc; //use the built in one for ETC } diff --git a/editor/pvrtc_compress.h b/editor/pvrtc_compress.h index cdd2f0d242..0396837623 100644 --- a/editor/pvrtc_compress.h +++ b/editor/pvrtc_compress.h @@ -31,7 +31,7 @@ #ifndef PVRTC_COMPRESS_H #define PVRTC_COMPRESS_H -#include "image.h" +#include "core/image.h" void _pvrtc_register_compressors(); diff --git a/editor/quick_open.cpp b/editor/quick_open.cpp index d2101f1e00..e48a0022e8 100644 --- a/editor/quick_open.cpp +++ b/editor/quick_open.cpp @@ -30,9 +30,9 @@ #include "quick_open.h" -#include "os/keyboard.h" +#include "core/os/keyboard.h" -void EditorQuickOpen::popup(const StringName &p_base, bool p_enable_multi, bool p_add_dirs, bool p_dontclear) { +void EditorQuickOpen::popup_dialog(const StringName &p_base, bool p_enable_multi, bool p_add_dirs, bool p_dontclear) { add_directories = p_add_dirs; popup_centered_ratio(0.6); diff --git a/editor/quick_open.h b/editor/quick_open.h index ecc6af0c53..5451d5a08c 100644 --- a/editor/quick_open.h +++ b/editor/quick_open.h @@ -31,8 +31,8 @@ #ifndef EDITOR_QUICK_OPEN_H #define EDITOR_QUICK_OPEN_H +#include "core/pair.h" #include "editor_file_system.h" -#include "pair.h" #include "scene/gui/dialogs.h" #include "scene/gui/tree.h" class EditorQuickOpen : public ConfirmationDialog { @@ -66,7 +66,7 @@ public: String get_selected() const; Vector<String> get_selected_files() const; - void popup(const StringName &p_base, bool p_enable_multi = false, bool p_add_dirs = false, bool p_dontclear = false); + void popup_dialog(const StringName &p_base, bool p_enable_multi = false, bool p_add_dirs = false, bool p_dontclear = false); EditorQuickOpen(); }; diff --git a/editor/rename_dialog.cpp b/editor/rename_dialog.cpp index d617089142..47e1ae0dab 100644 --- a/editor/rename_dialog.cpp +++ b/editor/rename_dialog.cpp @@ -30,12 +30,12 @@ #include "rename_dialog.h" +#include "core/print_string.h" #include "editor_node.h" #include "editor_settings.h" #include "editor_themes.h" #include "modules/regex/regex.h" #include "plugins/script_editor_plugin.h" -#include "print_string.h" #include "scene/gui/control.h" #include "scene/gui/label.h" #include "scene/gui/tab_container.h" @@ -220,21 +220,21 @@ RenameDialog::RenameDialog(SceneTreeEditor *p_scene_tree_editor, UndoRedo *p_und Label *lbl_count_step = memnew(Label); lbl_count_step->set_text(TTR("Step")); - lbl_count_step->set_tooltip(TTR("Ammount by which counter is incremented for each node")); + lbl_count_step->set_tooltip(TTR("Amount by which counter is incremented for each node")); hbc_count_options->add_child(lbl_count_step); spn_count_step = memnew(SpinBox); - spn_count_step->set_tooltip(TTR("Ammount by which counter is incremented for each node")); + spn_count_step->set_tooltip(TTR("Amount by which counter is incremented for each node")); spn_count_step->set_step(1); hbc_count_options->add_child(spn_count_step); Label *lbl_count_padding = memnew(Label); lbl_count_padding->set_text(TTR("Padding")); - lbl_count_padding->set_tooltip(TTR("Minium number of digits for the counter.\nMissing digits are padded with leading zeros.")); + lbl_count_padding->set_tooltip(TTR("Minimum number of digits for the counter.\nMissing digits are padded with leading zeros.")); hbc_count_options->add_child(lbl_count_padding); spn_count_padding = memnew(SpinBox); - spn_count_padding->set_tooltip(TTR("Minium number of digits for the counter.\nMissing digits are padded with leading zeros.")); + spn_count_padding->set_tooltip(TTR("Minimum number of digits for the counter.\nMissing digits are padded with leading zeros.")); spn_count_padding->set_step(1); hbc_count_options->add_child(spn_count_padding); diff --git a/editor/rename_dialog.h b/editor/rename_dialog.h index c5ebc30c0c..fa558660a4 100644 --- a/editor/rename_dialog.h +++ b/editor/rename_dialog.h @@ -37,8 +37,8 @@ #include "scene/gui/option_button.h" #include "scene/gui/spin_box.h" +#include "core/undo_redo.h" #include "editor/scene_tree_editor.h" -#include "undo_redo.h" /** @author Blazej Floch diff --git a/editor/reparent_dialog.cpp b/editor/reparent_dialog.cpp index da8bfdbbd2..3a6864b052 100644 --- a/editor/reparent_dialog.cpp +++ b/editor/reparent_dialog.cpp @@ -30,7 +30,7 @@ #include "reparent_dialog.h" -#include "print_string.h" +#include "core/print_string.h" #include "scene/gui/box_container.h" #include "scene/gui/label.h" diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index 39250ab391..11a0a42b9e 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -119,7 +119,6 @@ void SceneTreeDock::instance(const String &p_file) { if (!edited_scene) { current_option = -1; - accept->get_ok()->set_text(TTR("OK")); accept->set_text(TTR("No parent to instance a child at.")); accept->popup_centered_minsize(); return; @@ -142,7 +141,6 @@ void SceneTreeDock::instance_scenes(const Vector<String> &p_files, Node *p_paren if (!parent || !edited_scene) { - accept->get_ok()->set_text(TTR("OK")); accept->set_text(TTR("No parent to instance the scenes at.")); accept->popup_centered_minsize(); return; @@ -164,7 +162,6 @@ void SceneTreeDock::_perform_instance_scenes(const Vector<String> &p_files, Node Ref<PackedScene> sdata = ResourceLoader::load(p_files[i]); if (!sdata.is_valid()) { current_option = -1; - accept->get_ok()->set_text(TTR("OK")); accept->set_text(vformat(TTR("Error loading scene from %s"), p_files[i])); accept->popup_centered_minsize(); error = true; @@ -174,7 +171,6 @@ void SceneTreeDock::_perform_instance_scenes(const Vector<String> &p_files, Node Node *instanced_scene = sdata->instance(PackedScene::GEN_EDIT_STATE_INSTANCE); if (!instanced_scene) { current_option = -1; - accept->get_ok()->set_text(TTR("OK")); accept->set_text(vformat(TTR("Error instancing scene from %s"), p_files[i])); accept->popup_centered_minsize(); error = true; @@ -185,7 +181,6 @@ void SceneTreeDock::_perform_instance_scenes(const Vector<String> &p_files, Node if (_cyclical_dependency_exists(edited_scene->get_filename(), instanced_scene)) { - accept->get_ok()->set_text(TTR("Ok")); accept->set_text(vformat(TTR("Cannot instance the scene '%s' because the current scene exists within one of its nodes."), p_files[i])); accept->popup_centered_minsize(); error = true; @@ -224,7 +219,7 @@ void SceneTreeDock::_perform_instance_scenes(const Vector<String> &p_files, Node String new_name = parent->validate_child_name(instanced_scene); ScriptEditorDebugger *sed = ScriptEditor::get_singleton()->get_debugger(); editor_data->get_undo_redo().add_do_method(sed, "live_debug_instance_node", edited_scene->get_path_to(parent), p_files[i], new_name); - editor_data->get_undo_redo().add_undo_method(sed, "live_debug_remove_node", NodePath(String(edited_scene->get_path_to(parent)) + "/" + new_name)); + editor_data->get_undo_redo().add_undo_method(sed, "live_debug_remove_node", NodePath(String(edited_scene->get_path_to(parent)).plus_file(new_name))); } editor_data->get_undo_redo().commit_action(); @@ -233,7 +228,6 @@ void SceneTreeDock::_perform_instance_scenes(const Vector<String> &p_files, Node void SceneTreeDock::_replace_with_branch_scene(const String &p_file, Node *base) { Ref<PackedScene> sdata = ResourceLoader::load(p_file); if (!sdata.is_valid()) { - accept->get_ok()->set_text(TTR("OK")); accept->set_text(vformat(TTR("Error loading scene from %s"), p_file)); accept->popup_centered_minsize(); return; @@ -241,7 +235,6 @@ void SceneTreeDock::_replace_with_branch_scene(const String &p_file, Node *base) Node *instanced_scene = sdata->instance(PackedScene::GEN_EDIT_STATE_INSTANCE); if (!instanced_scene) { - accept->get_ok()->set_text(TTR("OK")); accept->set_text(vformat(TTR("Error instancing scene from %s"), p_file)); accept->popup_centered_minsize(); return; @@ -354,9 +347,9 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { if (path == "") { String root_path = editor_data->get_edited_scene_root()->get_filename(); if (root_path == "") { - path = "res://" + selected->get_name(); + path = String("res://").plus_file(selected->get_name()); } else { - path = root_path.get_base_dir() + "/" + selected->get_name(); + path = root_path.get_base_dir().plus_file(selected->get_name()); } } @@ -399,9 +392,6 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { const RefPtr empty; editor_data->get_undo_redo().add_do_method(E->get(), "set_script", empty); editor_data->get_undo_redo().add_undo_method(E->get(), "set_script", existing); - - editor_data->get_undo_redo().add_do_method(E->get(), "set_meta", "_editor_icon", get_icon(E->get()->get_class(), "EditorIcons")); - editor_data->get_undo_redo().add_undo_method(E->get(), "set_meta", "_editor_icon", E->get()->get_meta("_editor_icon")); } } @@ -419,7 +409,6 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { if (scene_tree->get_selected() == edited_scene) { current_option = -1; - accept->get_ok()->set_text(TTR("OK")); accept->set_text(TTR("This operation can't be done on the tree root.")); accept->popup_centered_minsize(); break; @@ -480,7 +469,6 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { if (editor_selection->is_selected(edited_scene)) { current_option = -1; - accept->get_ok()->set_text(TTR("OK")); accept->set_text(TTR("This operation can't be done on the tree root.")); accept->popup_centered_minsize(); break; @@ -533,7 +521,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { ScriptEditorDebugger *sed = ScriptEditor::get_singleton()->get_debugger(); editor_data->get_undo_redo().add_do_method(sed, "live_debug_duplicate_node", edited_scene->get_path_to(node), dup->get_name()); - editor_data->get_undo_redo().add_undo_method(sed, "live_debug_remove_node", NodePath(String(edited_scene->get_path_to(parent)) + "/" + dup->get_name())); + editor_data->get_undo_redo().add_undo_method(sed, "live_debug_remove_node", NodePath(String(edited_scene->get_path_to(parent)).plus_file(dup->get_name()))); } editor_data->get_undo_redo().commit_action(); @@ -550,7 +538,6 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { if (editor_selection->is_selected(edited_scene)) { current_option = -1; - accept->get_ok()->set_text(TTR("OK")); accept->set_text(TTR("This operation can't be done on the tree root.")); accept->popup_centered_minsize(); break; @@ -581,15 +568,21 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { return; editor_data->get_undo_redo().create_action("Make node as Root"); - _node_replace_owner(root, node, node, MODE_DO); editor_data->get_undo_redo().add_do_method(node->get_parent(), "remove_child", node); + editor_data->get_undo_redo().add_do_method(root->get_parent(), "remove_child", root); + editor_data->get_undo_redo().add_do_method(node, "add_child", root); editor_data->get_undo_redo().add_do_method(editor, "set_edited_scene", node); editor_data->get_undo_redo().add_do_method(node, "set_filename", root->get_filename()); + editor_data->get_undo_redo().add_do_method(root, "set_filename", String()); + _node_replace_owner(root, root, node, MODE_DO); + editor_data->get_undo_redo().add_undo_method(root, "set_filename", root->get_filename()); editor_data->get_undo_redo().add_undo_method(node, "set_filename", String()); + editor_data->get_undo_redo().add_undo_method(node, "remove_child", root); editor_data->get_undo_redo().add_undo_method(editor, "set_edited_scene", root); editor_data->get_undo_redo().add_undo_method(node->get_parent(), "add_child", node); - _node_replace_owner(root, node, root, MODE_UNDO); + _node_replace_owner(root, root, root, MODE_UNDO); + editor_data->get_undo_redo().add_do_method(scene_tree, "update_tree"); editor_data->get_undo_redo().add_undo_method(scene_tree, "update_tree"); editor_data->get_undo_redo().add_undo_reference(root); @@ -637,7 +630,6 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { Node *scene = editor_data->get_edited_scene_root(); if (!scene) { - accept->get_ok()->set_text(TTR("OK")); accept->set_text(TTR("This operation can't be done without a scene.")); accept->popup_centered_minsize(); break; @@ -646,7 +638,6 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { List<Node *> selection = editor_selection->get_selected_node_list(); if (selection.size() != 1) { - accept->get_ok()->set_text(TTR("OK")); accept->set_text(TTR("This operation requires a single selected node.")); accept->popup_centered_minsize(); break; @@ -655,14 +646,12 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { Node *tocopy = selection.front()->get(); if (tocopy == scene) { - accept->get_ok()->set_text(TTR("OK")); accept->set_text(TTR("Can not perform with the root node.")); accept->popup_centered_minsize(); break; } if (tocopy != editor_data->get_edited_scene_root() && tocopy->get_filename() != "") { - accept->get_ok()->set_text(TTR("OK")); accept->set_text(TTR("This operation can't be done on instanced scenes.")); accept->popup_centered_minsize(); break; @@ -707,18 +696,13 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { Node *node = e->get(); if (node) { bool editable = EditorNode::get_singleton()->get_edited_scene()->is_editable_instance(node); - int editable_item_idx = menu->get_item_idx_from_text(TTR("Editable Children")); - int placeholder_item_idx = menu->get_item_idx_from_text(TTR("Load As Placeholder")); - editable = !editable; - - EditorNode::get_singleton()->get_edited_scene()->set_editable_instance(node, editable); - menu->set_item_checked(editable_item_idx, editable); if (editable) { - node->set_scene_instance_load_placeholder(false); - menu->set_item_checked(placeholder_item_idx, false); + editable_instance_remove_dialog->set_text(TTR("Disabling \"editable_instance\" will cause all properties of the node to be reverted to their default.")); + editable_instance_remove_dialog->popup_centered_minsize(); + break; } - scene_tree->update_tree(); + _toggle_editable_children(); } } } break; @@ -844,6 +828,8 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { editor_data->get_undo_redo().add_undo_method(editor, "set_edited_scene", (Object *)NULL); editor_data->get_undo_redo().commit_action(); + editor->edit_node(new_node); + } break; default: { @@ -987,24 +973,22 @@ void SceneTreeDock::_notification(int p_what) { void SceneTreeDock::_node_replace_owner(Node *p_base, Node *p_node, Node *p_root, ReplaceOwnerMode p_mode) { - if (p_base != p_node) { - if (p_node->get_owner() == p_base) { - UndoRedo *undo_redo = &editor_data->get_undo_redo(); - switch (p_mode) { - case MODE_BIDI: { - undo_redo->add_do_method(p_node, "set_owner", p_root); - undo_redo->add_undo_method(p_node, "set_owner", p_base); + if (p_node->get_owner() == p_base || !p_node->get_owner()) { + UndoRedo *undo_redo = &editor_data->get_undo_redo(); + switch (p_mode) { + case MODE_BIDI: { + undo_redo->add_do_method(p_node, "set_owner", p_root); + undo_redo->add_undo_method(p_node, "set_owner", p_base); - } break; - case MODE_DO: { - undo_redo->add_do_method(p_node, "set_owner", p_root); + } break; + case MODE_DO: { + undo_redo->add_do_method(p_node, "set_owner", p_root); - } break; - case MODE_UNDO: { - undo_redo->add_undo_method(p_node, "set_owner", p_root); + } break; + case MODE_UNDO: { + undo_redo->add_undo_method(p_node, "set_owner", p_root); - } break; - } + } break; } } @@ -1304,7 +1288,6 @@ bool SceneTreeDock::_validate_no_foreign() { if (E->get() != edited_scene && E->get()->get_owner() != edited_scene) { - accept->get_ok()->set_text(TTR("OK")); accept->set_text(TTR("Can't operate on nodes from a foreign scene!")); accept->popup_centered_minsize(); return false; @@ -1312,7 +1295,6 @@ bool SceneTreeDock::_validate_no_foreign() { if (edited_scene->get_scene_inherited_state().is_valid() && edited_scene->get_scene_inherited_state()->find_node_by_path(edited_scene->get_path_to(E->get())) >= 0) { - accept->get_ok()->set_text(TTR("OK")); accept->set_text(TTR("Can't operate on nodes the current scene inherits from!")); accept->popup_centered_minsize(); return false; @@ -1424,7 +1406,7 @@ void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, V } editor_data->get_undo_redo().add_do_method(sed, "live_debug_reparent_node", edited_scene->get_path_to(node), edited_scene->get_path_to(new_parent), new_name, p_position_in_parent + inc); - editor_data->get_undo_redo().add_undo_method(sed, "live_debug_reparent_node", NodePath(String(edited_scene->get_path_to(new_parent)) + "/" + new_name), edited_scene->get_path_to(node->get_parent()), node->get_name(), node->get_index()); + editor_data->get_undo_redo().add_undo_method(sed, "live_debug_reparent_node", NodePath(String(edited_scene->get_path_to(new_parent)).plus_file(new_name)), edited_scene->get_path_to(node->get_parent()), node->get_name(), node->get_index()); if (p_keep_global_xform) { if (Object::cast_to<Node2D>(node)) @@ -1496,19 +1478,6 @@ void SceneTreeDock::_script_created(Ref<Script> p_script) { Ref<Script> existing = E->get()->get_script(); editor_data->get_undo_redo().add_do_method(E->get(), "set_script", p_script.get_ref_ptr()); editor_data->get_undo_redo().add_undo_method(E->get(), "set_script", existing); - - String icon_path; - String name = p_script->get_language()->get_global_class_name(p_script->get_path(), NULL, &icon_path); - if (ScriptServer::is_global_class(name)) { - RES icon = ResourceLoader::load(icon_path); - editor_data->get_undo_redo().add_do_method(E->get(), "set_meta", "_editor_icon", icon); - String existing_name = existing.is_valid() ? existing->get_language()->get_global_class_name(existing->get_path()) : String(); - if (existing.is_null() || !ScriptServer::is_global_class(existing_name)) { - editor_data->get_undo_redo().add_undo_method(E->get(), "set_meta", "_editor_icon", get_icon(E->get()->get_class(), "EditorIcons")); - } else { - editor_data->get_undo_redo().add_undo_method(E->get(), "set_meta", "_editor_icon", editor_data->script_class_get_icon_path(existing_name)); - } - } } editor_data->get_undo_redo().commit_action(); @@ -1516,6 +1485,33 @@ void SceneTreeDock::_script_created(Ref<Script> p_script) { editor->push_item(p_script.operator->()); } +void SceneTreeDock::_toggle_editable_children() { + List<Node *> selection = editor_selection->get_selected_node_list(); + List<Node *>::Element *e = selection.front(); + if (e) { + Node *node = e->get(); + if (node) { + bool editable = EditorNode::get_singleton()->get_edited_scene()->is_editable_instance(node); + + int editable_item_idx = menu->get_item_idx_from_text(TTR("Editable Children")); + int placeholder_item_idx = menu->get_item_idx_from_text(TTR("Load As Placeholder")); + editable = !editable; + + EditorNode::get_singleton()->get_edited_scene()->set_editable_instance(node, editable); + + menu->set_item_checked(editable_item_idx, editable); + if (editable) { + node->set_scene_instance_load_placeholder(false); + menu->set_item_checked(placeholder_item_idx, false); + } + + SpatialEditor::get_singleton()->update_all_gizmos(node); + + scene_tree->update_tree(); + } + } +} + void SceneTreeDock::_delete_confirm() { List<Node *> remove_list = editor_selection->get_selected_node_list(); @@ -1597,7 +1593,7 @@ void SceneTreeDock::_delete_confirm() { // Fixes the EditorHistory from still offering deleted notes EditorHistory *editor_history = EditorNode::get_singleton()->get_editor_history(); editor_history->cleanup_history(); - EditorNode::get_singleton()->call("_prepare_history"); + EditorNode::get_singleton()->get_inspector_dock()->call("_prepare_history"); } void SceneTreeDock::_update_script_button() { @@ -1614,6 +1610,10 @@ void SceneTreeDock::_selection_changed() { if (selection_size > 1) { //automatically turn on multi-edit _tool_selected(TOOL_MULTI_EDIT); + } else if (selection_size == 1) { + editor->push_item(EditorNode::get_singleton()->get_editor_selection()->get_selected_node_list()[0]); + } else { + editor->push_item(NULL); } _update_script_button(); } @@ -1656,7 +1656,7 @@ void SceneTreeDock::_create() { String new_name = parent->validate_child_name(child); ScriptEditorDebugger *sed = ScriptEditor::get_singleton()->get_debugger(); editor_data->get_undo_redo().add_do_method(sed, "live_debug_create_node", edited_scene->get_path_to(parent), child->get_class(), new_name); - editor_data->get_undo_redo().add_undo_method(sed, "live_debug_remove_node", NodePath(String(edited_scene->get_path_to(parent)) + "/" + new_name)); + editor_data->get_undo_redo().add_undo_method(sed, "live_debug_remove_node", NodePath(String(edited_scene->get_path_to(parent)).plus_file(new_name))); } else { @@ -1805,12 +1805,17 @@ void SceneTreeDock::_new_scene_from(String p_file) { List<Node *> selection = editor_selection->get_selected_node_list(); if (selection.size() != 1) { - accept->get_ok()->set_text(TTR("OK")); accept->set_text(TTR("This operation requires a single selected node.")); accept->popup_centered_minsize(); return; } + if (EditorNode::get_singleton()->is_scene_open(p_file)) { + accept->set_text(TTR("Can't overwrite scene that is still open!")); + accept->popup_centered_minsize(); + return; + } + Node *base = selection.front()->get(); Map<Node *, Node *> reown; @@ -1823,7 +1828,6 @@ void SceneTreeDock::_new_scene_from(String p_file) { memdelete(copy); if (err != OK) { - accept->get_ok()->set_text(TTR("OK")); accept->set_text(TTR("Couldn't save new scene. Likely dependencies (instances) couldn't be satisfied.")); accept->popup_centered_minsize(); return; @@ -1835,14 +1839,12 @@ void SceneTreeDock::_new_scene_from(String p_file) { err = ResourceSaver::save(p_file, sdata, flg); if (err != OK) { - accept->get_ok()->set_text(TTR("OK")); accept->set_text(TTR("Error saving scene.")); accept->popup_centered_minsize(); return; } _replace_with_branch_scene(p_file, base); } else { - accept->get_ok()->set_text(TTR("OK")); accept->set_text(TTR("Error duplicating scene to save it.")); accept->popup_centered_minsize(); return; @@ -1877,32 +1879,6 @@ static bool _has_visible_children(Node *p_node) { return false; } -static Node *_find_last_visible(Node *p_node) { - - Node *last = NULL; - - bool collapsed = p_node->is_displayed_folded(); - - if (!collapsed) { - for (int i = 0; i < p_node->get_child_count(); i++) { - if (_is_node_visible(p_node->get_child(i))) { - last = p_node->get_child(i); - } - } - } - - if (last) { - Node *lastc = _find_last_visible(last); - if (lastc) - last = lastc; - - } else { - last = p_node; - } - - return last; -} - void SceneTreeDock::_normalize_drop(Node *&to_node, int &to_pos, int p_type) { to_pos = -1; @@ -2017,12 +1993,7 @@ void SceneTreeDock::_add_children_to_popup(Object *p_obj, int p_depth) { if (!obj) continue; - Ref<Texture> icon; - - if (has_icon(obj->get_class(), "EditorIcons")) - icon = get_icon(obj->get_class(), "EditorIcons"); - else - icon = get_icon("Object", "EditorIcons"); + Ref<Texture> icon = EditorNode::get_singleton()->get_object_icon(obj); if (menu->get_item_count() == 0) { menu->add_submenu_item(TTR("Sub-Resources"), "Sub-Resources"); @@ -2252,7 +2223,7 @@ void SceneTreeDock::_update_create_root_dialog() { String name = l.get_slicec(' ', 0); if (ScriptServer::is_global_class(name)) name = ScriptServer::get_global_class_base(name); - button->set_icon(get_icon(name, "EditorIcons")); + button->set_icon(EditorNode::get_singleton()->get_class_icon(name)); button->connect("pressed", this, "_favorite_root_selected", make_binds(l)); } } @@ -2292,6 +2263,7 @@ void SceneTreeDock::_bind_methods() { ClassDB::bind_method(D_METHOD("_input"), &SceneTreeDock::_input); ClassDB::bind_method(D_METHOD("_nodes_drag_begin"), &SceneTreeDock::_nodes_drag_begin); ClassDB::bind_method(D_METHOD("_delete_confirm"), &SceneTreeDock::_delete_confirm); + ClassDB::bind_method(D_METHOD("_toggle_editable_children"), &SceneTreeDock::_toggle_editable_children); ClassDB::bind_method(D_METHOD("_node_prerenamed"), &SceneTreeDock::_node_prerenamed); ClassDB::bind_method(D_METHOD("_import_subscene"), &SceneTreeDock::_import_subscene); ClassDB::bind_method(D_METHOD("_selection_changed"), &SceneTreeDock::_selection_changed); @@ -2433,7 +2405,6 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSel add_child(create_dialog); create_dialog->connect("create", this, "_create"); create_dialog->connect("favorites_updated", this, "_update_create_root_dialog"); - EditorFileSystem::get_singleton()->connect("script_classes_updated", create_dialog, "_save_and_update_favorite_list"); rename_dialog = memnew(RenameDialog(scene_tree, &editor_data->get_undo_redo())); add_child(rename_dialog); @@ -2458,6 +2429,10 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSel add_child(delete_dialog); delete_dialog->connect("confirmed", this, "_delete_confirm"); + editable_instance_remove_dialog = memnew(ConfirmationDialog); + add_child(editable_instance_remove_dialog); + editable_instance_remove_dialog->connect("confirmed", this, "_toggle_editable_children"); + import_subscene_dialog = memnew(EditorSubScene); add_child(import_subscene_dialog); import_subscene_dialog->connect("subscene_selected", this, "_import_subscene"); diff --git a/editor/scene_tree_dock.h b/editor/scene_tree_dock.h index 34a7c98d11..269b0b69db 100644 --- a/editor/scene_tree_dock.h +++ b/editor/scene_tree_dock.h @@ -121,6 +121,7 @@ class SceneTreeDock : public VBoxContainer { ScriptCreateDialog *script_create_dialog; AcceptDialog *accept; ConfirmationDialog *delete_dialog; + ConfirmationDialog *editable_instance_remove_dialog; ReparentDialog *reparent_dialog; EditorFileDialog *file; @@ -169,6 +170,8 @@ class SceneTreeDock : public VBoxContainer { void _delete_confirm(); + void _toggle_editable_children(); + void _node_prerenamed(Node *p_node, const String &p_new_name); void _nodes_drag_begin(); diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp index a916ae23f6..07670bb420 100644 --- a/editor/scene_tree_editor.cpp +++ b/editor/scene_tree_editor.cpp @@ -30,11 +30,11 @@ #include "scene_tree_editor.h" +#include "core/message_queue.h" +#include "core/print_string.h" #include "editor/plugins/animation_player_editor_plugin.h" #include "editor/plugins/canvas_item_editor_plugin.h" #include "editor_node.h" -#include "message_queue.h" -#include "print_string.h" #include "scene/gui/label.h" #include "scene/main/viewport.h" #include "scene/resources/packed_scene.h" @@ -186,11 +186,7 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) { item->set_collapsed(true); } - Ref<Texture> icon; - if (p_node->has_meta("_editor_icon")) - icon = p_node->get_meta("_editor_icon"); - else - icon = get_icon((has_icon(p_node->get_class(), "EditorIcons") ? p_node->get_class() : String("Object")), "EditorIcons"); + Ref<Texture> icon = EditorNode::get_singleton()->get_object_icon(p_node, "Node"); item->set_icon(0, icon); item->set_metadata(0, p_node->get_path()); diff --git a/editor/scene_tree_editor.h b/editor/scene_tree_editor.h index c4f63f5736..e575fb986a 100644 --- a/editor/scene_tree_editor.h +++ b/editor/scene_tree_editor.h @@ -31,12 +31,12 @@ #ifndef SCENE_TREE_EDITOR_H #define SCENE_TREE_EDITOR_H +#include "core/undo_redo.h" #include "editor_data.h" #include "editor_settings.h" #include "scene/gui/button.h" #include "scene/gui/dialogs.h" #include "scene/gui/tree.h" -#include "undo_redo.h" /** @author Juan Linietsky <reduzio@gmail.com> */ diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp index 24c4ba4cb7..df704706af 100644 --- a/editor/script_create_dialog.cpp +++ b/editor/script_create_dialog.cpp @@ -30,13 +30,13 @@ #include "script_create_dialog.h" +#include "core/io/resource_saver.h" +#include "core/os/file_access.h" +#include "core/project_settings.h" +#include "core/script_language.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" #include "editor_file_system.h" -#include "io/resource_saver.h" -#include "os/file_access.h" -#include "project_settings.h" -#include "script_language.h" void ScriptCreateDialog::_notification(int p_what) { @@ -50,12 +50,17 @@ void ScriptCreateDialog::_notification(int p_what) { } } -void ScriptCreateDialog::config(const String &p_base_name, const String &p_base_path) { +bool ScriptCreateDialog::_can_be_built_in() { + return (supports_built_in && built_in_enabled); +} + +void ScriptCreateDialog::config(const String &p_base_name, const String &p_base_path, bool p_built_in_enabled) { class_name->set_text(""); class_name->deselect(); parent_name->set_text(p_base_name); parent_name->deselect(); + if (p_base_path != "") { initial_bp = p_base_path.get_basename(); file_path->set_text(initial_bp + "." + ScriptServer::get_language(language_menu->get_selected())->get_extension()); @@ -65,6 +70,8 @@ void ScriptCreateDialog::config(const String &p_base_name, const String &p_base_ } file_path->deselect(); + built_in_enabled = p_built_in_enabled; + _lang_changed(current_language); _class_name_changed(""); _path_changed(file_path->get_text()); @@ -163,7 +170,6 @@ void ScriptCreateDialog::_create_new() { if (script_template != "") { scr = ResourceLoader::load(script_template); if (scr.is_null()) { - alert->get_ok()->set_text(TTR("OK")); alert->set_text(vformat(TTR("Error loading template '%s'"), script_template)); alert->popup_centered(); return; @@ -200,7 +206,6 @@ void ScriptCreateDialog::_load_exist() { String path = file_path->get_text(); RES p_script = ResourceLoader::load(path, "Script"); if (p_script.is_null()) { - alert->get_ok()->set_text(TTR("OK")); alert->set_text(vformat(TTR("Error loading script from %s"), path)); alert->popup_centered(); return; @@ -359,7 +364,7 @@ void ScriptCreateDialog::_path_changed(const String &p_path) { is_path_valid = false; is_new_script_created = true; - String p = p_path; + String p = p_path.strip_edges(); if (p == "") { _msg_path_valid(false, TTR("Path is empty")); @@ -367,6 +372,12 @@ void ScriptCreateDialog::_path_changed(const String &p_path) { return; } + if (p.get_file().get_basename() == "") { + _msg_path_valid(false, TTR("Filename is empty")); + _update_dialog(); + return; + } + p = ProjectSettings::get_singleton()->localize_path(p); if (!p.begins_with("res://")) { _msg_path_valid(false, TTR("Path is not local")); @@ -539,7 +550,7 @@ void ScriptCreateDialog::_update_dialog() { } } - if (!supports_built_in) + if (!_can_be_built_in()) internal->set_pressed(false); /* Is Script created or loaded from existing file */ @@ -548,14 +559,14 @@ void ScriptCreateDialog::_update_dialog() { get_ok()->set_text(TTR("Create")); parent_name->set_editable(true); parent_browse_button->set_disabled(false); - internal->set_disabled(!supports_built_in); + internal->set_disabled(!_can_be_built_in()); _msg_path_valid(true, TTR("Built-in script (into scene file)")); } else if (is_new_script_created) { // New Script Created get_ok()->set_text(TTR("Create")); parent_name->set_editable(true); parent_browse_button->set_disabled(false); - internal->set_disabled(!supports_built_in); + internal->set_disabled(!_can_be_built_in()); if (is_path_valid) { _msg_path_valid(true, TTR("Create new script file")); } @@ -564,7 +575,7 @@ void ScriptCreateDialog::_update_dialog() { get_ok()->set_text(TTR("Load")); parent_name->set_editable(false); parent_browse_button->set_disabled(true); - internal->set_disabled(!supports_built_in); + internal->set_disabled(!_can_be_built_in()); if (is_path_valid) { _msg_path_valid(true, TTR("Load existing script file")); } @@ -583,7 +594,7 @@ void ScriptCreateDialog::_bind_methods() { ClassDB::bind_method("_path_entered", &ScriptCreateDialog::_path_entered); ClassDB::bind_method("_template_changed", &ScriptCreateDialog::_template_changed); - ClassDB::bind_method(D_METHOD("config", "inherits", "path"), &ScriptCreateDialog::config); + ClassDB::bind_method(D_METHOD("config", "inherits", "path", "built_in_enabled"), &ScriptCreateDialog::config, DEFVAL(true)); ADD_SIGNAL(MethodInfo("script_created", PropertyInfo(Variant::OBJECT, "script", PROPERTY_HINT_RESOURCE_TYPE, "Script"))); } @@ -788,6 +799,7 @@ ScriptCreateDialog::ScriptCreateDialog() { has_named_classes = false; supports_built_in = false; can_inherit_from_file = false; + built_in_enabled = true; is_built_in = false; is_new_script_created = true; diff --git a/editor/script_create_dialog.h b/editor/script_create_dialog.h index 1ad4a1b7a1..e0bf336b56 100644 --- a/editor/script_create_dialog.h +++ b/editor/script_create_dialog.h @@ -69,11 +69,13 @@ class ScriptCreateDialog : public ConfirmationDialog { bool is_parent_name_valid; bool is_class_name_valid; bool is_built_in; + bool built_in_enabled; int current_language; bool re_check_path; String script_template; Vector<String> template_list; + bool _can_be_built_in(); void _path_changed(const String &p_path = String()); void _path_entered(const String &p_path = String()); void _lang_changed(int l = 0); @@ -96,8 +98,7 @@ protected: static void _bind_methods(); public: - void config(const String &p_base_name, const String &p_base_path); - + void config(const String &p_base_name, const String &p_base_path, bool p_built_in_enabled = true); ScriptCreateDialog(); }; diff --git a/editor/script_editor_debugger.cpp b/editor/script_editor_debugger.cpp index 9db53fe5f5..eb72d0aa6e 100644 --- a/editor/script_editor_debugger.cpp +++ b/editor/script_editor_debugger.cpp @@ -30,11 +30,13 @@ #include "script_editor_debugger.h" +#include "core/io/marshalls.h" +#include "core/project_settings.h" +#include "core/ustring.h" #include "editor_node.h" #include "editor_profiler.h" #include "editor_settings.h" #include "main/performance.h" -#include "project_settings.h" #include "property_editor.h" #include "scene/gui/dialogs.h" #include "scene/gui/label.h" @@ -47,7 +49,6 @@ #include "scene/gui/texture_button.h" #include "scene/gui/tree.h" #include "scene/resources/packed_scene.h" -#include "ustring.h" class ScriptEditorDebuggerVariables : public Object { @@ -396,7 +397,6 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da dobreak->set_disabled(false); docontinue->set_disabled(true); emit_signal("breaked", false, false, Variant()); - //tabs->set_current_tab(0); profiler->set_enabled(true); profiler->disable_seeking(); inspector->edit(NULL); @@ -429,8 +429,9 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da ObjectID id = ObjectID(p_data[i + 3]); it->set_text(0, p_data[i + 1]); - if (has_icon(p_data[i + 2], "EditorIcons")) - it->set_icon(0, get_icon(p_data[i + 2], "EditorIcons")); + Ref<Texture> icon = EditorNode::get_singleton()->get_class_icon(p_data[i + 2], ""); + if (icon.is_valid()) + it->set_icon(0, icon); it->set_metadata(0, id); if (id == inspected_object_id) { @@ -492,17 +493,23 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da pinfo.usage = PropertyUsageFlags(int(prop[4])); Variant var = prop[5]; - String hint_string = pinfo.hint_string; - if (hint_string.begins_with("RES:") && hint_string != "RES:") { - String path = hint_string.substr(4, hint_string.length()); - var = ResourceLoader::load(path); - } - if (is_new_object) { //don't update.. it's the same, instead refresh debugObj->prop_list.push_back(pinfo); } + if (var.get_type() == Variant::STRING) { + String str = var; + var = str.substr(4, str.length()); + + if (str.begins_with("PATH")) { + if (String(var).empty()) + var = RES(); + else + var = ResourceLoader::load(var); + } + } + debugObj->prop_values[pinfo.name] = var; } @@ -573,14 +580,10 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da PropertyHint h = PROPERTY_HINT_NONE; String hs = String(); - if (n.begins_with("*")) { - - n = n.substr(1, n.length()); + if (v.get_type() == Variant::OBJECT) { + v = Object::cast_to<EncodedObjectAsID>(v)->get_object_id(); h = PROPERTY_HINT_OBJECT_ID; - String s = v; - s = s.replace("[", ""); - hs = s.get_slice(":", 0); - v = s.get_slice(":", 1).to_int(); + hs = "Object"; } variables->add_property("Locals/" + n, v, h, hs); @@ -596,14 +599,10 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da PropertyHint h = PROPERTY_HINT_NONE; String hs = String(); - if (n.begins_with("*")) { - - n = n.substr(1, n.length()); + if (v.get_type() == Variant::OBJECT) { + v = Object::cast_to<EncodedObjectAsID>(v)->get_object_id(); h = PROPERTY_HINT_OBJECT_ID; - String s = v; - s = s.replace("[", ""); - hs = s.get_slice(":", 0); - v = s.get_slice(":", 1).to_int(); + hs = "Object"; } variables->add_property("Members/" + n, v, h, hs); @@ -619,14 +618,10 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da PropertyHint h = PROPERTY_HINT_NONE; String hs = String(); - if (n.begins_with("*")) { - - n = n.substr(1, n.length()); + if (v.get_type() == Variant::OBJECT) { + v = Object::cast_to<EncodedObjectAsID>(v)->get_object_id(); h = PROPERTY_HINT_OBJECT_ID; - String s = v; - s = s.replace("[", ""); - hs = s.get_slice(":", 0); - v = s.get_slice(":", 1).to_int(); + hs = "Object"; } variables->add_property("Globals/" + n, v, h, hs); @@ -712,27 +707,66 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da bool warning = err[9]; bool e; String time = String("%d:%02d:%02d:%04d").sprintf(vals, &e); - String txt = time + " - " + (err[8].is_zero() ? String(err[7]) : String(err[8])); + String txt = err[8].is_zero() ? String(err[7]) : String(err[8]); + + TreeItem *r = error_tree->get_root(); + if (!r) { + r = error_tree->create_item(); + } - String tooltip = TTR("Type:") + String(warning ? TTR("Warning") : TTR("Error")); - tooltip += "\n" + TTR("Description:") + " " + String(err[8]); - tooltip += "\n" + TTR("Time:") + " " + time; - tooltip += "\nC " + TTR("Error:") + " " + String(err[7]); - tooltip += "\nC " + TTR("Source:") + " " + String(err[5]) + ":" + String(err[6]); - tooltip += "\nC " + TTR("Function:") + " " + String(err[4]); + TreeItem *error = error_tree->create_item(r); + error->set_collapsed(true); - error_list->add_item(txt, EditorNode::get_singleton()->get_gui_base()->get_icon(warning ? "Warning" : "Error", "EditorIcons")); - error_list->set_item_tooltip(error_list->get_item_count() - 1, tooltip); + error->set_icon(0, get_icon(warning ? "Warning" : "Error", "EditorIcons")); + error->set_text(0, time); + error->set_text_align(0, TreeItem::ALIGN_LEFT); - int scc = p_data[1]; + error->set_text(1, txt); - Array stack; - stack.resize(scc); - for (int i = 0; i < scc; i++) { - stack[i] = p_data[2 + i]; + String source(err[5]); + bool source_is_project_file = source.begins_with("res://"); + if (source_is_project_file) + txt = source.get_file() + ":" + String(err[6]); + else + txt = source + ":" + String(err[6]); + + String method = err[4]; + if (method.length() > 0) + txt += " @ " + method + "()"; + + TreeItem *c_info = error_tree->create_item(error); + c_info->set_text(0, "<" + TTR(source_is_project_file ? "Source" : "C Source") + ">"); + c_info->set_text(1, txt); + c_info->set_text_align(0, TreeItem::ALIGN_LEFT); + + if (source_is_project_file) { + Array meta; + meta.push_back(source); + meta.push_back(err[6]); + error->set_metadata(0, meta); + c_info->set_metadata(0, meta); } - error_list->set_item_metadata(error_list->get_item_count() - 1, stack); + int scc = p_data[1]; + + for (int i = 0; i < scc; i += 3) { + String script = p_data[2 + i]; + String method = p_data[3 + i]; + int line = p_data[4 + i]; + TreeItem *stack_trace = error_tree->create_item(error); + + Array meta; + meta.push_back(script); + meta.push_back(line); + stack_trace->set_metadata(0, meta); + + if (i == 0) { + stack_trace->set_text(0, "<" + TTR("Stack Trace") + ">"); + stack_trace->set_text_align(0, TreeItem::ALIGN_LEFT); + error->set_metadata(0, meta); + } + stack_trace->set_text(1, script.get_file() + ":" + itos(line) + " @ " + method + "()"); + } if (warning) warning_count++; @@ -970,8 +1004,8 @@ void ScriptEditorDebugger::_notification(int p_what) { //scene_tree_refresh->set_icon( get_icon("Reload","EditorIcons")); le_set->connect("pressed", this, "_live_edit_set"); le_clear->connect("pressed", this, "_live_edit_clear"); - error_list->connect("item_selected", this, "_error_selected"); - error_stack->connect("item_selected", this, "_error_stack_selected"); + error_tree->connect("item_selected", this, "_error_selected"); + error_tree->connect("item_activated", this, "_error_activated"); vmem_refresh->set_icon(get_icon("Reload", "EditorIcons")); reason->add_color_override("font_color", get_color("error_color", "Editor")); @@ -1017,19 +1051,19 @@ void ScriptEditorDebugger::_notification(int p_what) { if (error_count != last_error_count || warning_count != last_warning_count) { if (error_count == 0 && warning_count == 0) { - error_split->set_name(TTR("Errors")); + error_tree->set_name(TTR("Errors")); debugger_button->set_text(TTR("Debugger")); debugger_button->set_icon(Ref<Texture>()); - tabs->set_tab_icon(error_split->get_index(), Ref<Texture>()); + tabs->set_tab_icon(error_tree->get_index(), Ref<Texture>()); } else { - error_split->set_name(TTR("Errors") + " (" + itos(error_count + warning_count) + ")"); + error_tree->set_name(TTR("Errors") + " (" + itos(error_count + warning_count) + ")"); debugger_button->set_text(TTR("Debugger") + " (" + itos(error_count + warning_count) + ")"); if (error_count == 0) { debugger_button->set_icon(get_icon("Warning", "EditorIcons")); - tabs->set_tab_icon(error_split->get_index(), get_icon("Warning", "EditorIcons")); + tabs->set_tab_icon(error_tree->get_index(), get_icon("Warning", "EditorIcons")); } else { debugger_button->set_icon(get_icon("Error", "EditorIcons")); - tabs->set_tab_icon(error_split->get_index(), get_icon("Error", "EditorIcons")); + tabs->set_tab_icon(error_tree->get_index(), get_icon("Error", "EditorIcons")); } } last_error_count = error_count; @@ -1060,8 +1094,7 @@ void ScriptEditorDebugger::_notification(int p_what) { inspect_scene_tree->clear(); le_set->set_disabled(true); le_clear->set_disabled(false); - error_list->clear(); - error_stack->clear(); + error_tree->clear(); error_count = 0; warning_count = 0; profiler_signature.clear(); @@ -1261,9 +1294,6 @@ void ScriptEditorDebugger::stop() { EditorNode::get_singleton()->get_scene_tree_dock()->hide_remote_tree(); EditorNode::get_singleton()->get_scene_tree_dock()->hide_tab_buttons(); - Node *node = editor->get_scene_tree_dock()->get_tree_editor()->get_selected(); - editor->push_item(node); - if (hide_on_stop) { if (is_visible_in_tree()) EditorNode::get_singleton()->hide_bottom_panel(); @@ -1659,45 +1689,52 @@ void ScriptEditorDebugger::reload_scripts() { } } -void ScriptEditorDebugger::_error_selected(int p_idx) { +void ScriptEditorDebugger::_error_activated() { + TreeItem *selected = error_tree->get_selected(); + + TreeItem *ci = selected->get_children(); + if (ci) { + selected->set_collapsed(!selected->is_collapsed()); + } +} - error_stack->clear(); - Array st = error_list->get_item_metadata(p_idx); - for (int i = 0; i < st.size(); i += 3) { +void ScriptEditorDebugger::_error_selected() { + TreeItem *selected = error_tree->get_selected(); - String script = st[i]; - String func = st[i + 1]; - int line = st[i + 2]; - Array md; - md.push_back(st[i]); - md.push_back(st[i + 1]); - md.push_back(st[i + 2]); + Array meta = selected->get_metadata(0); - String str = func; - String tooltip_str = TTR("Function:") + " " + func; - if (script.length() > 0) { - str += " in " + script.get_file(); - tooltip_str = TTR("File:") + " " + script + "\n" + tooltip_str; - if (line > 0) { - str += ":line " + itos(line); - tooltip_str += "\n" + TTR("Line:") + " " + itos(line); - } - } + if (meta.size() == 0) { + return; + } - error_stack->add_item(str); - error_stack->set_item_metadata(error_stack->get_item_count() - 1, md); - error_stack->set_item_tooltip(error_stack->get_item_count() - 1, tooltip_str); + Ref<Script> s = ResourceLoader::load(meta[0]); + emit_signal("goto_script_line", s, int(meta[1]) - 1); +} + +void ScriptEditorDebugger::_expand_errors_list() { + + TreeItem *root = error_tree->get_root(); + if (!root) + return; + + TreeItem *item = root->get_children(); + while (item) { + item->set_collapsed(false); + item = item->get_next(); } } -void ScriptEditorDebugger::_error_stack_selected(int p_idx) { +void ScriptEditorDebugger::_collapse_errors_list() { - Array arr = error_stack->get_item_metadata(p_idx); - if (arr.size() != 3) + TreeItem *root = error_tree->get_root(); + if (!root) return; - Ref<Script> s = ResourceLoader::load(arr[0]); - emit_signal("goto_script_line", s, int(arr[2]) - 1); + TreeItem *item = root->get_children(); + while (item) { + item->set_collapsed(true); + item = item->get_next(); + } } void ScriptEditorDebugger::set_hide_on_stop(bool p_hide) { @@ -1754,27 +1791,24 @@ void ScriptEditorDebugger::_clear_remote_objects() { void ScriptEditorDebugger::_clear_errors_list() { - error_list->clear(); + error_tree->clear(); error_count = 0; warning_count = 0; _notification(NOTIFICATION_PROCESS); } // Right click on specific file(s) or folder(s). -void ScriptEditorDebugger::_error_list_item_rmb_selected(int p_item, const Vector2 &p_pos) { +void ScriptEditorDebugger::_error_tree_item_rmb_selected(const Vector2 &p_pos) { item_menu->clear(); item_menu->set_size(Size2(1, 1)); - // Allow specific actions only on one item. - bool single_item_selected = error_list->get_selected_items().size() == 1; - - if (single_item_selected) { + if (error_tree->is_anything_selected()) { item_menu->add_icon_item(get_icon("ActionCopy", "EditorIcons"), TTR("Copy Error"), ITEM_MENU_COPY_ERROR); } if (item_menu->get_item_count() > 0) { - item_menu->set_position(error_list->get_global_position() + p_pos); + item_menu->set_position(error_tree->get_global_position() + p_pos); item_menu->popup(); } } @@ -1784,10 +1818,30 @@ void ScriptEditorDebugger::_item_menu_id_pressed(int p_option) { switch (p_option) { case ITEM_MENU_COPY_ERROR: { - String title = error_list->get_item_text(error_list->get_current()); - String desc = error_list->get_item_tooltip(error_list->get_current()); + TreeItem *ti = error_tree->get_selected(); + while (ti->get_parent() != error_tree->get_root()) + ti = ti->get_parent(); + + String type; + + if (ti->get_icon(0) == get_icon("Warning", "EditorIcons")) { + type = "W "; + } else if (ti->get_icon(0) == get_icon("Error", "EditorIcons")) { + type = "E "; + } + + String text = ti->get_text(0) + " "; + int rpad_len = text.length(); + + text = type + text + ti->get_text(1) + "\n"; + TreeItem *ci = ti->get_children(); + while (ci) { + text += " " + ci->get_text(0).rpad(rpad_len) + ci->get_text(1) + "\n"; + ci = ci->get_next(); + } + + OS::get_singleton()->set_clipboard(text); - OS::get_singleton()->set_clipboard(title + "\n----------\n" + desc); } break; case ITEM_MENU_SAVE_REMOTE_NODE: { @@ -1826,12 +1880,14 @@ void ScriptEditorDebugger::_bind_methods() { ClassDB::bind_method(D_METHOD("_live_edit_clear"), &ScriptEditorDebugger::_live_edit_clear); ClassDB::bind_method(D_METHOD("_error_selected"), &ScriptEditorDebugger::_error_selected); - ClassDB::bind_method(D_METHOD("_error_stack_selected"), &ScriptEditorDebugger::_error_stack_selected); + ClassDB::bind_method(D_METHOD("_error_activated"), &ScriptEditorDebugger::_error_activated); + ClassDB::bind_method(D_METHOD("_expand_errors_list"), &ScriptEditorDebugger::_expand_errors_list); + ClassDB::bind_method(D_METHOD("_collapse_errors_list"), &ScriptEditorDebugger::_collapse_errors_list); ClassDB::bind_method(D_METHOD("_profiler_activate"), &ScriptEditorDebugger::_profiler_activate); ClassDB::bind_method(D_METHOD("_profiler_seeked"), &ScriptEditorDebugger::_profiler_seeked); ClassDB::bind_method(D_METHOD("_clear_errors_list"), &ScriptEditorDebugger::_clear_errors_list); - ClassDB::bind_method(D_METHOD("_error_list_item_rmb_selected"), &ScriptEditorDebugger::_error_list_item_rmb_selected); + ClassDB::bind_method(D_METHOD("_error_tree_item_rmb_selected"), &ScriptEditorDebugger::_error_tree_item_rmb_selected); ClassDB::bind_method(D_METHOD("_item_menu_id_pressed"), &ScriptEditorDebugger::_item_menu_id_pressed); ClassDB::bind_method(D_METHOD("_paused"), &ScriptEditorDebugger::_paused); @@ -1946,16 +2002,14 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) { stack_dump->connect("cell_selected", this, "_stack_dump_frame_selected"); sc->add_child(stack_dump); - inspector = memnew(PropertyEditor); + inspector = memnew(EditorInspector); inspector->set_h_size_flags(SIZE_EXPAND_FILL); - inspector->hide_top_label(); - inspector->get_property_tree()->set_column_title(0, TTR("Variable")); inspector->set_enable_capitalize_paths(false); inspector->set_read_only(true); inspector->connect("object_id_selected", this, "_scene_tree_property_select_object"); sc->add_child(inspector); - server = TCP_Server::create_ref(); + server.instance(); pending_in_queue = 0; @@ -1967,44 +2021,52 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) { } { //errors - - error_split = memnew(HSplitContainer); VBoxContainer *errvb = memnew(VBoxContainer); + errvb->set_name(TTR("Errors")); + HBoxContainer *errhb = memnew(HBoxContainer); - errvb->set_h_size_flags(SIZE_EXPAND_FILL); - Label *velb = memnew(Label(TTR("Errors:"))); - velb->set_h_size_flags(SIZE_EXPAND_FILL); - errhb->add_child(velb); + errvb->add_child(errhb); + + Button *expand_all = memnew(Button); + expand_all->set_text(TTR("Expand All")); + expand_all->connect("pressed", this, "_expand_errors_list"); + errhb->add_child(expand_all); + + Button *collapse_all = memnew(Button); + collapse_all->set_text(TTR("Collapse All")); + collapse_all->connect("pressed", this, "_collapse_errors_list"); + errhb->add_child(collapse_all); + + Control *space = memnew(Control); + space->set_h_size_flags(SIZE_EXPAND_FILL); + errhb->add_child(space); clearbutton = memnew(Button); clearbutton->set_text(TTR("Clear")); + clearbutton->set_h_size_flags(0); clearbutton->connect("pressed", this, "_clear_errors_list"); errhb->add_child(clearbutton); - errvb->add_child(errhb); - error_list = memnew(ItemList); - error_list->set_v_size_flags(SIZE_EXPAND_FILL); - error_list->set_h_size_flags(SIZE_EXPAND_FILL); - error_list->connect("item_rmb_selected", this, "_error_list_item_rmb_selected"); - error_list->set_allow_rmb_select(true); - error_list->set_autoscroll_to_bottom(true); + error_tree = memnew(Tree); + error_tree->set_columns(2); - item_menu = memnew(PopupMenu); - item_menu->connect("id_pressed", this, "_item_menu_id_pressed"); - error_list->add_child(item_menu); + error_tree->set_column_expand(0, false); + error_tree->set_column_min_width(0, 140); - errvb->add_child(error_list); + error_tree->set_column_expand(1, true); - error_split->add_child(errvb); + error_tree->set_select_mode(Tree::SELECT_ROW); + error_tree->set_hide_root(true); + error_tree->set_v_size_flags(SIZE_EXPAND_FILL); + error_tree->set_allow_rmb_select(true); + error_tree->connect("item_rmb_selected", this, "_error_tree_item_rmb_selected"); + errvb->add_child(error_tree); - errvb = memnew(VBoxContainer); - errvb->set_h_size_flags(SIZE_EXPAND_FILL); - error_stack = memnew(ItemList); - errvb->add_margin_child(TTR("Stack Trace (if applicable):"), error_stack, true); - error_split->add_child(errvb); + item_menu = memnew(PopupMenu); + item_menu->connect("id_pressed", this, "_item_menu_id_pressed"); + error_tree->add_child(item_menu); - error_split->set_name(TTR("Errors")); - tabs->add_child(error_split); + tabs->add_child(errvb); } { // remote scene tree @@ -2180,7 +2242,6 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) { ScriptEditorDebugger::~ScriptEditorDebugger() { - //inspector->edit(NULL); memdelete(variables); ppeer->set_stream_peer(Ref<StreamPeer>()); diff --git a/editor/script_editor_debugger.h b/editor/script_editor_debugger.h index ce705aa35b..cebf6d785e 100644 --- a/editor/script_editor_debugger.h +++ b/editor/script_editor_debugger.h @@ -33,12 +33,12 @@ #include "core/io/packet_peer.h" #include "core/io/tcp_server.h" -#include "property_editor.h" +#include "editor/editor_inspector.h" +#include "editor/property_editor.h" #include "scene/gui/box_container.h" #include "scene/gui/button.h" class Tree; -class PropertyEditor; class EditorNode; class ScriptEditorDebuggerVariables; class LineEdit; @@ -88,8 +88,7 @@ class ScriptEditorDebugger : public Control { Set<ObjectID> unfold_cache; HSplitContainer *error_split; - ItemList *error_list; - ItemList *error_stack; + Tree *error_tree; Tree *inspect_scene_tree; Button *clearbutton; PopupMenu *item_menu; @@ -130,7 +129,7 @@ class ScriptEditorDebugger : public Control { LineEdit *vmem_total; Tree *stack_dump; - PropertyEditor *inspector; + EditorInspector *inspector; Ref<TCP_Server> server; Ref<StreamPeerTCP> connection; @@ -179,8 +178,11 @@ class ScriptEditorDebugger : public Control { void _method_changed(Object *p_base, const StringName &p_name, VARIANT_ARG_DECLARE); void _property_changed(Object *p_base, const StringName &p_property, const Variant &p_value); - void _error_selected(int p_idx); - void _error_stack_selected(int p_idx); + void _error_activated(); + void _error_selected(); + + void _expand_errors_list(); + void _collapse_errors_list(); void _profiler_activate(bool p_enable); void _profiler_seeked(); @@ -191,7 +193,7 @@ class ScriptEditorDebugger : public Control { void _clear_remote_objects(); void _clear_errors_list(); - void _error_list_item_rmb_selected(int p_item, const Vector2 &p_pos); + void _error_tree_item_rmb_selected(const Vector2 &p_pos); void _item_menu_id_pressed(int p_option); protected: diff --git a/editor/settings_config_dialog.cpp b/editor/settings_config_dialog.cpp index 4ebba73cb3..537c9ac6b8 100644 --- a/editor/settings_config_dialog.cpp +++ b/editor/settings_config_dialog.cpp @@ -30,11 +30,11 @@ #include "settings_config_dialog.h" +#include "core/os/keyboard.h" +#include "core/project_settings.h" #include "editor_file_system.h" #include "editor_node.h" #include "editor_settings.h" -#include "os/keyboard.h" -#include "project_settings.h" #include "scene/gui/margin_container.h" #include "script_editor_debugger.h" @@ -56,11 +56,7 @@ void EditorSettingsDialog::_settings_property_edited(const String &p_name) { String full_name = inspector->get_full_item_path(p_name); - // Small usability workaround to update the text color settings when the - // color theme is changed - if (full_name == "text_editor/theme/color_theme") { - inspector->get_inspector()->update_tree(); - } else if (full_name == "interface/theme/accent_color" || full_name == "interface/theme/base_color" || full_name == "interface/theme/contrast") { + if (full_name == "interface/theme/accent_color" || full_name == "interface/theme/base_color" || full_name == "interface/theme/contrast") { EditorSettings::get_singleton()->set_manually("interface/theme/preset", "Custom"); // set preset to Custom } else if (full_name.begins_with("text_editor/highlighting")) { EditorSettings::get_singleton()->set_manually("text_editor/theme/color_theme", "Custom"); @@ -365,7 +361,7 @@ void EditorSettingsDialog::_tabs_tab_changed(int p_tab) { void EditorSettingsDialog::_focus_current_search_box() { Control *tab = tabs->get_current_tab_control(); - LineEdit *current_search_box; + LineEdit *current_search_box = NULL; if (tab == tab_general) current_search_box = search_box; else if (tab == tab_shortcuts) diff --git a/editor/spatial_editor_gizmos.cpp b/editor/spatial_editor_gizmos.cpp index 64638cdb1e..96bca86f83 100644 --- a/editor/spatial_editor_gizmos.cpp +++ b/editor/spatial_editor_gizmos.cpp @@ -30,12 +30,32 @@ #include "spatial_editor_gizmos.h" -#include "geometry.h" -#include "quick_hull.h" -#include "scene/3d/camera.h" +#include "core/math/geometry.h" +#include "core/math/quick_hull.h" +#include "scene/3d/audio_stream_player_3d.h" +#include "scene/3d/baked_lightmap.h" +#include "scene/3d/collision_polygon.h" +#include "scene/3d/collision_shape.h" +#include "scene/3d/gi_probe.h" +#include "scene/3d/light.h" +#include "scene/3d/listener.h" +#include "scene/3d/mesh_instance.h" +#include "scene/3d/navigation_mesh.h" +#include "scene/3d/particles.h" +#include "scene/3d/physics_joint.h" +#include "scene/3d/portal.h" +#include "scene/3d/position_3d.h" +#include "scene/3d/ray_cast.h" +#include "scene/3d/reflection_probe.h" +#include "scene/3d/room_instance.h" #include "scene/3d/soft_body.h" +#include "scene/3d/spring_arm.h" +#include "scene/3d/sprite_3d.h" +#include "scene/3d/vehicle_body.h" +#include "scene/3d/visibility_notifier.h" #include "scene/resources/box_shape.h" #include "scene/resources/capsule_shape.h" +#include "scene/resources/concave_polygon_shape.h" #include "scene/resources/convex_polygon_shape.h" #include "scene/resources/cylinder_shape.h" #include "scene/resources/plane_shape.h" @@ -44,17 +64,8 @@ #include "scene/resources/sphere_shape.h" #include "scene/resources/surface_tool.h" -// Keep small children away from this file. -// It's so ugly it will eat them alive - -// The previous comment is kept only for historical reasons. -// No children will be harmed by the viewing of this file... hopefully. - #define HANDLE_HALF_SIZE 9.5 -bool EditorSpatialGizmo::can_draw() const { - return is_editable(); -} bool EditorSpatialGizmo::is_editable() const { ERR_FAIL_COND_V(!spatial_node, false); @@ -704,6 +715,7 @@ EditorSpatialGizmo::EditorSpatialGizmo() { instanced = false; spatial_node = NULL; gizmo_plugin = NULL; + selectable_icon_size = -1.0f; } EditorSpatialGizmo::~EditorSpatialGizmo() { @@ -898,7 +910,6 @@ void LightSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) { } p_gizmo->add_lines(lines, material); - p_gizmo->add_collision_segments(lines); p_gizmo->add_unscaled_billboard(icon, 0.05); } @@ -929,8 +940,6 @@ void LightSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) { } p_gizmo->add_lines(points, material, true); - p_gizmo->add_collision_segments(points); - p_gizmo->add_unscaled_billboard(icon, 0.05); Vector<Vector3> handles; @@ -972,38 +981,14 @@ void LightSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) { p_gizmo->add_lines(points, material); + float ra = 16 * Math_PI * 2.0 / 64.0; + Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * w; + Vector<Vector3> handles; handles.push_back(Vector3(0, 0, -r)); - - Vector<Vector3> collision_segments; - - for (int i = 0; i < 64; i++) { - - float ra = i * Math_PI * 2.0 / 64.0; - float rb = (i + 1) * Math_PI * 2.0 / 64.0; - Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * w; - Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * w; - - collision_segments.push_back(Vector3(a.x, a.y, -d)); - collision_segments.push_back(Vector3(b.x, b.y, -d)); - - if (i % 16 == 0) { - - collision_segments.push_back(Vector3(a.x, a.y, -d)); - collision_segments.push_back(Vector3()); - } - - if (i == 16) { - - handles.push_back(Vector3(a.x, a.y, -d)); - } - } - - collision_segments.push_back(Vector3(0, 0, -r)); - collision_segments.push_back(Vector3()); + handles.push_back(Vector3(a.x, a.y, -d)); p_gizmo->add_handles(handles, get_material("handles")); - p_gizmo->add_collision_segments(collision_segments); p_gizmo->add_unscaled_billboard(icon, 0.05); } } @@ -1139,7 +1124,6 @@ void AudioStreamPlayer3DSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) } p_gizmo->add_lines(points, material); - p_gizmo->add_collision_segments(points); Vector<Vector3> handles; float ha = Math::deg2rad(player->get_emission_angle()); @@ -1334,7 +1318,6 @@ void CameraSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) { } p_gizmo->add_lines(lines, material); - p_gizmo->add_collision_segments(lines); p_gizmo->add_unscaled_billboard(icon, 0.05); p_gizmo->add_handles(handles, get_material("handles")); @@ -1377,7 +1360,6 @@ void CameraSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) { } p_gizmo->add_lines(lines, material); - p_gizmo->add_collision_segments(lines); } } @@ -1722,8 +1704,16 @@ void PhysicalBoneSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) { return; Skeleton *sk(physical_bone->find_skeleton_parent()); + if (!sk) + return; + PhysicalBone *pb(sk->get_physical_bone(physical_bone->get_bone_id())); + if (!pb) + return; + PhysicalBone *pbp(sk->get_physical_bone_parent(physical_bone->get_bone_id())); + if (!pbp) + return; Vector<Vector3> points; @@ -2105,12 +2095,10 @@ void SoftBodySpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) { Vector<Vector3> points; soft_body->get_mesh()->generate_debug_mesh_indices(points); - soft_body->get_mesh()->clear_cache(); Ref<Material> material = get_material("shape_material", p_gizmo); p_gizmo->add_lines(lines, material); - p_gizmo->add_collision_segments(lines); p_gizmo->add_handles(points, get_material("handles")); p_gizmo->add_collision_triangles(tm); } @@ -2427,7 +2415,6 @@ void ParticlesGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) { Ref<Material> icon = get_material("particles_icon", p_gizmo); p_gizmo->add_lines(lines, material); - p_gizmo->add_collision_segments(lines); if (p_gizmo->is_selected()) { Ref<Material> solid_material = get_material("particles_solid_material", p_gizmo); @@ -2612,7 +2599,6 @@ void ReflectionProbeGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) { } p_gizmo->add_unscaled_billboard(icon, 0.05); - p_gizmo->add_collision_segments(lines); p_gizmo->add_handles(handles, get_material("handles")); } @@ -2727,7 +2713,6 @@ void GIProbeGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) { } p_gizmo->add_lines(lines, material); - p_gizmo->add_collision_segments(lines); lines.clear(); @@ -2897,7 +2882,6 @@ void BakedIndirectLightGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) { } p_gizmo->add_lines(lines, material); - p_gizmo->add_collision_segments(lines); Vector<Vector3> handles; @@ -3488,6 +3472,14 @@ void CollisionShapeSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) { } } + if (Object::cast_to<ConcavePolygonShape>(*s)) { + + Ref<ConcavePolygonShape> cs = s; + Ref<ArrayMesh> mesh = cs->get_debug_mesh()->duplicate(); + mesh->surface_set_material(0, material); + p_gizmo->add_mesh(mesh); + } + if (Object::cast_to<RayShape>(*s)) { Ref<RayShape> rs = s; diff --git a/editor/spatial_editor_gizmos.h b/editor/spatial_editor_gizmos.h index 6f29e9d999..371e3bc689 100644 --- a/editor/spatial_editor_gizmos.h +++ b/editor/spatial_editor_gizmos.h @@ -32,27 +32,7 @@ #define SPATIAL_EDITOR_GIZMOS_H #include "editor/plugins/spatial_editor_plugin.h" -#include "scene/3d/audio_stream_player_3d.h" -#include "scene/3d/baked_lightmap.h" #include "scene/3d/camera.h" -#include "scene/3d/collision_polygon.h" -#include "scene/3d/collision_shape.h" -#include "scene/3d/gi_probe.h" -#include "scene/3d/light.h" -#include "scene/3d/listener.h" -#include "scene/3d/mesh_instance.h" -#include "scene/3d/navigation_mesh.h" -#include "scene/3d/particles.h" -#include "scene/3d/physics_joint.h" -#include "scene/3d/portal.h" -#include "scene/3d/position_3d.h" -#include "scene/3d/ray_cast.h" -#include "scene/3d/reflection_probe.h" -#include "scene/3d/room_instance.h" -#include "scene/3d/spring_arm.h" -#include "scene/3d/sprite_3d.h" -#include "scene/3d/vehicle_body.h" -#include "scene/3d/visibility_notifier.h" class Camera; diff --git a/editor/translations/extract.py b/editor/translations/extract.py index 0dee1819dd..ebb032fd6f 100755 --- a/editor/translations/extract.py +++ b/editor/translations/extract.py @@ -88,7 +88,7 @@ def process_file(f, fname): unique_str.append(msg) unique_loc[msg] = [location] elif (not location in unique_loc[msg]): - # Add additional location to previous occurence too + # Add additional location to previous occurrence too msg_pos = main_po.find('\nmsgid "' + msg + '"') if (msg_pos == -1): print("Someone apparently thought writing Python was as easy as GDScript. Ping Akien.") |