diff options
author | Chris Bradfield <chris@kidscancode.org> | 2017-09-09 20:10:28 -0700 |
---|---|---|
committer | Chris Bradfield <chris@kidscancode.org> | 2017-09-09 20:10:28 -0700 |
commit | 134e24408a3ae6273da5998ee257495eff79eb1a (patch) | |
tree | 566c3d82ed1925a3d6dcd34c6cb1687328af7f6e /editor | |
parent | f66e9158a8a49d1fb88cd31975a2a492b3aa1d6e (diff) | |
parent | d1cb73b47a17de830d9474026ffa7b3587cfbc68 (diff) |
Merge branch 'master' of git://github.com/godotengine/godot into kcc_lightoccluder2d_doc
Diffstat (limited to 'editor')
37 files changed, 833 insertions, 276 deletions
diff --git a/editor/SCsub b/editor/SCsub index 172447147c..0e690cf465 100644 --- a/editor/SCsub +++ b/editor/SCsub @@ -155,31 +155,71 @@ def make_authors_header(target, source, env): g.write("#define _EDITOR_AUTHORS_H\n") current_section = "" - name_count = -1 + reading = False def close_section(): g.write("\t0\n") g.write("};\n") - g.write("#define " + current_section.upper() + "_COUNT " + str(name_count) + "\n") for line in f: - if name_count >= 0: + if reading: if line.startswith(" "): g.write("\t\"" + line.strip() + "\",\n") - name_count += 1 continue if line.startswith("## "): - if name_count >= 0: + if reading: close_section() - name_count = -1 + reading = False for i in range(len(sections)): if line.strip().endswith(sections[i]): current_section = sections_id[i] - name_count = 0 + reading = True g.write("static const char *" + current_section + "[] = {\n") break - if name_count >= 0: + if reading: + close_section() + + g.write("#endif\n") + +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].srcnode().abspath + dst = target[0].srcnode().abspath + 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\"" + 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 = sections_id[i] + reading = True + g.write("static const char *" + current_section + "[] = {\n") + break + + if reading: close_section() g.write("#endif\n") @@ -393,6 +433,10 @@ if (env["tools"] == "yes"): env.Depends('#editor/authors.gen.h', "../AUTHORS.md") env.Command('#editor/authors.gen.h', "../AUTHORS.md", make_authors_header) + # Donors + env.Depends('#editor/donors.gen.h', "../DONORS.md") + env.Command('#editor/donors.gen.h', "../DONORS.md", make_donors_header) + # License env.Depends('#editor/license.gen.h', ["../COPYRIGHT.txt", "../LICENSE.txt"]) env.Command('#editor/license.gen.h', ["../COPYRIGHT.txt", "../LICENSE.txt"], make_license_header) diff --git a/editor/doc/doc_data.cpp b/editor/doc/doc_data.cpp index 5975e54356..6848c43b68 100644 --- a/editor/doc/doc_data.cpp +++ b/editor/doc/doc_data.cpp @@ -634,6 +634,9 @@ static Error _parse_methods(Ref<XMLParser> &parser, Vector<DocData::MethodDoc> & ERR_FAIL_COND_V(!parser->has_attribute("type"), ERR_FILE_CORRUPT); method.return_type = parser->get_attribute_value("type"); + if (parser->has_attribute("enum")) { + method.return_enum = parser->get_attribute_value("enum"); + } } else if (name == "argument") { DocData::ArgumentDoc argument; @@ -916,7 +919,11 @@ Error DocData::save(const String &p_path) { if (m.return_type != "") { - _write_string(f, 3, "<return type=\"" + m.return_type + "\">"); + String enum_text; + if (m.return_enum != String()) { + enum_text = " enum=\"" + m.return_enum + "\""; + } + _write_string(f, 3, "<return type=\"" + m.return_type + "\"" + enum_text + ">"); _write_string(f, 3, "</return>"); } diff --git a/editor/editor_about.cpp b/editor/editor_about.cpp index 8bd7bfb4bd..a48e6c9057 100644 --- a/editor/editor_about.cpp +++ b/editor/editor_about.cpp @@ -30,6 +30,7 @@ #include "editor_about.h" #include "authors.gen.h" +#include "donors.gen.h" #include "license.gen.h" #include "version.h" #include "version_hash.gen.h" @@ -51,6 +52,47 @@ TextureRect *EditorAbout::get_logo() const { return _logo; } +ScrollContainer *EditorAbout::_populate_list(const String &p_name, const List<String> &p_sections, const char **p_src[]) { + + ScrollContainer *sc = memnew(ScrollContainer); + sc->set_name(p_name); + sc->set_v_size_flags(Control::SIZE_EXPAND); + + VBoxContainer *vbc = memnew(VBoxContainer); + vbc->set_h_size_flags(Control::SIZE_EXPAND_FILL); + sc->add_child(vbc); + + for (int i = 0; i < p_sections.size(); i++) { + + const char **names_ptr = p_src[i]; + if (*names_ptr) { + + Label *lbl = memnew(Label); + lbl->set_text(p_sections[i]); + vbc->add_child(lbl); + + ItemList *il = memnew(ItemList); + il->set_max_columns(16); + il->set_h_size_flags(Control::SIZE_EXPAND_FILL); + il->set_same_column_width(true); + il->set_auto_height(true); + while (*names_ptr) { + il->add_item(String::utf8(*names_ptr++), NULL, false); + } + vbc->add_child(il); + if (il->get_item_count() == 2) { + il->set_fixed_column_width(200 * EDSCALE); + } + + HSeparator *hs = memnew(HSeparator); + hs->set_modulate(Color(0, 0, 0, 0)); + vbc->add_child(hs); + } + } + + return sc; +} + EditorAbout::EditorAbout() { set_title(TTR("Thanks from the Godot community!")); @@ -84,43 +126,29 @@ EditorAbout::EditorAbout() { tc->set_v_size_flags(Control::SIZE_EXPAND_FILL); vbc->add_child(tc); - ScrollContainer *dev_base = memnew(ScrollContainer); - dev_base->set_name(TTR("Authors")); - dev_base->set_v_size_flags(Control::SIZE_EXPAND); - tc->add_child(dev_base); - - VBoxContainer *dev_vbc = memnew(VBoxContainer); - dev_vbc->set_h_size_flags(Control::SIZE_EXPAND_FILL); - dev_base->add_child(dev_vbc); + // Authors List<String> dev_sections; dev_sections.push_back(TTR("Project Founders")); dev_sections.push_back(TTR("Lead Developer")); dev_sections.push_back(TTR("Project Manager")); dev_sections.push_back(TTR("Developers")); - const char **dev_src[] = { dev_founders, dev_lead, dev_manager, dev_names }; + tc->add_child(_populate_list(TTR("Authors"), dev_sections, dev_src)); - for (int i = 0; i < dev_sections.size(); i++) { - - Label *lbl = memnew(Label); - lbl->set_text(dev_sections[i]); - dev_vbc->add_child(lbl); - - ItemList *il = memnew(ItemList); - il->set_max_columns(16); - il->set_h_size_flags(Control::SIZE_EXPAND_FILL); - il->set_fixed_column_width(230 * EDSCALE); - il->set_auto_height(true); - const char **dev_names_ptr = dev_src[i]; - while (*dev_names_ptr) - il->add_item(String::utf8(*dev_names_ptr++), NULL, false); - dev_vbc->add_child(il); - - HSeparator *hs = memnew(HSeparator); - hs->set_modulate(Color(0, 0, 0, 0)); - dev_vbc->add_child(hs); - } + // Donors + + List<String> donor_sections; + donor_sections.push_back(TTR("Platinum Sponsors")); + donor_sections.push_back(TTR("Gold Sponsors")); + donor_sections.push_back(TTR("Mini Sponsors")); + donor_sections.push_back(TTR("Gold Donors")); + donor_sections.push_back(TTR("Silver Donors")); + donor_sections.push_back(TTR("Bronze Donors")); + const char **donor_src[] = { donor_s_plat, donor_s_gold, donor_s_mini, donor_gold, donor_silver, donor_bronze }; + tc->add_child(_populate_list(TTR("Donors"), donor_sections, donor_src)); + + // License TextEdit *license = memnew(TextEdit); license->set_name(TTR("License")); @@ -131,6 +159,8 @@ EditorAbout::EditorAbout() { license->set_text(String::utf8(about_license)); tc->add_child(license); + // Thirdparty License + VBoxContainer *license_thirdparty = memnew(VBoxContainer); license_thirdparty->set_name(TTR("Thirdparty License")); license_thirdparty->set_h_size_flags(Control::SIZE_EXPAND_FILL); diff --git a/editor/editor_about.h b/editor/editor_about.h index d7047c03a3..d455b1f074 100644 --- a/editor/editor_about.h +++ b/editor/editor_about.h @@ -52,6 +52,7 @@ class EditorAbout : public AcceptDialog { private: void _license_tree_selected(); + ScrollContainer *_populate_list(const String &p_name, const List<String> &p_sections, const char **p_src[]); Tree *_tpl_tree; TextEdit *_tpl_text; diff --git a/editor/editor_dir_dialog.cpp b/editor/editor_dir_dialog.cpp index 1b213501aa..cfb3abfd1d 100644 --- a/editor/editor_dir_dialog.cpp +++ b/editor/editor_dir_dialog.cpp @@ -31,50 +31,40 @@ #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) { +void EditorDirDialog::_update_dir(TreeItem *p_item, EditorFileSystemDirectory *p_dir, const String &p_select_path) { updating = true; - p_item->clear_children(); - DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES); - String cdir = p_item->get_metadata(0); - - da->change_dir(cdir); - da->list_dir_begin(); - String p = da->get_next(); - List<String> dirs; - bool ishidden; - bool show_hidden = EditorSettings::get_singleton()->get("filesystem/file_dialog/show_hidden_files"); + String path = p_dir->get_path(); - while (p != "") { + p_item->set_metadata(0, p_dir->get_path()); + p_item->set_icon(0, get_icon("Folder", "EditorIcons")); - ishidden = da->current_is_hidden(); + if (!p_item->get_parent()) { + p_item->set_text(0, "res://"); + } else { - if (show_hidden || !ishidden) { - if (da->current_is_dir() && !p.begins_with(".")) { - dirs.push_back(p); - } + if (!opened_paths.has(path) && (p_select_path == String() || !p_select_path.begins_with(path))) { + p_item->set_collapsed(true); } - p = da->get_next(); + + p_item->set_text(0, p_dir->get_name()); } - dirs.sort(); + //this should be handled by EditorFileSystem already + //bool show_hidden = EditorSettings::get_singleton()->get("filesystem/file_dialog/show_hidden_files"); + updating = false; + for (int i = 0; i < p_dir->get_subdir_count(); i++) { - for (List<String>::Element *E = dirs.front(); E; E = E->next()) { TreeItem *ti = tree->create_item(p_item); - ti->set_text(0, E->get()); - ti->set_icon(0, get_icon("Folder", "EditorIcons")); - ti->set_collapsed(true); + _update_dir(ti, p_dir->get_subdir(i)); } - - memdelete(da); - updating = false; } -void EditorDirDialog::reload() { +void EditorDirDialog::reload(const String &p_with_path) { if (!is_visible_in_tree()) { must_reload = true; @@ -83,10 +73,7 @@ void EditorDirDialog::reload() { tree->clear(); TreeItem *root = tree->create_item(); - root->set_metadata(0, "res://"); - root->set_icon(0, get_icon("Folder", "EditorIcons")); - root->set_text(0, "/"); - _update_dir(root); + _update_dir(root, EditorFileSystem::get_singleton()->get_filesystem(), p_with_path); _item_collapsed(root); must_reload = false; } @@ -94,6 +81,7 @@ void EditorDirDialog::reload() { void EditorDirDialog::_notification(int p_what) { if (p_what == NOTIFICATION_ENTER_TREE) { + EditorFileSystem::get_singleton()->connect("filesystem_changed", this, "reload"); reload(); if (!tree->is_connected("item_collapsed", this, "_item_collapsed")) { @@ -105,6 +93,10 @@ void EditorDirDialog::_notification(int p_what) { } } + if (p_what == NOTIFICATION_EXIT_TREE) { + EditorFileSystem::get_singleton()->disconnect("filesystem_changed", this, "reload"); + } + if (p_what == NOTIFICATION_VISIBILITY_CHANGED) { if (must_reload && is_visible_in_tree()) { reload(); @@ -116,57 +108,13 @@ void EditorDirDialog::_item_collapsed(Object *p_item) { TreeItem *item = Object::cast_to<TreeItem>(p_item); - if (updating || item->is_collapsed()) + if (updating) return; - TreeItem *ci = item->get_children(); - while (ci) { - - String p = ci->get_metadata(0); - if (p == "") { - String pp = item->get_metadata(0); - ci->set_metadata(0, pp.plus_file(ci->get_text(0))); - _update_dir(ci); - } - ci = ci->get_next(); - } -} - -void EditorDirDialog::set_current_path(const String &p_path) { - - reload(); - String p = p_path; - if (p.begins_with("res://")) - p = p.replace_first("res://", ""); - - Vector<String> dirs = p.split("/", false); - - TreeItem *r = tree->get_root(); - for (int i = 0; i < dirs.size(); i++) { - - String d = dirs[i]; - TreeItem *p = r->get_children(); - while (p) { - - if (p->get_text(0) == d) - break; - p = p->get_next(); - } - - ERR_FAIL_COND(!p); - String pp = p->get_metadata(0); - if (pp == "") { - p->set_metadata(0, String(r->get_metadata(0)).plus_file(d)); - _update_dir(p); - } - updating = true; - p->set_collapsed(false); - updating = false; - _item_collapsed(p); - r = p; - } - - r->select(0); + if (item->is_collapsed()) + opened_paths.erase(item->get_metadata(0)); + else + opened_paths.insert(item->get_metadata(0)); } void EditorDirDialog::ok_pressed() { @@ -201,14 +149,16 @@ void EditorDirDialog::_make_dir_confirm() { String dir = ti->get_metadata(0); - DirAccess *d = DirAccess::open(dir); + DirAccessRef d = DirAccess::open(dir); ERR_FAIL_COND(!d); Error err = d->make_dir(makedirname->get_text()); if (err != OK) { - mkdirerr->popup_centered_minsize(Size2(250, 80)); + mkdirerr->popup_centered_minsize(Size2(250, 80) * EDSCALE); } else { - set_current_path(dir.plus_file(makedirname->get_text())); + opened_paths.insert(dir); + //reload(dir.plus_file(makedirname->get_text())); + EditorFileSystem::get_singleton()->scan_changes(); //we created a dir, so rescan changes } makedirname->set_text(""); // reset label } @@ -218,7 +168,7 @@ void EditorDirDialog::_bind_methods() { ClassDB::bind_method(D_METHOD("_item_collapsed"), &EditorDirDialog::_item_collapsed); ClassDB::bind_method(D_METHOD("_make_dir"), &EditorDirDialog::_make_dir); ClassDB::bind_method(D_METHOD("_make_dir_confirm"), &EditorDirDialog::_make_dir_confirm); - ClassDB::bind_method(D_METHOD("reload"), &EditorDirDialog::reload); + ClassDB::bind_method(D_METHOD("reload"), &EditorDirDialog::reload, DEFVAL("")); ADD_SIGNAL(MethodInfo("dir_selected", PropertyInfo(Variant::STRING, "dir"))); } diff --git a/editor/editor_dir_dialog.h b/editor/editor_dir_dialog.h index b8347f75fb..8aa685947b 100644 --- a/editor/editor_dir_dialog.h +++ b/editor/editor_dir_dialog.h @@ -30,6 +30,7 @@ #ifndef EDITOR_DIR_DIALOG_H #define EDITOR_DIR_DIALOG_H +#include "editor/editor_file_system.h" #include "os/dir_access.h" #include "scene/gui/dialogs.h" #include "scene/gui/tree.h" @@ -42,12 +43,13 @@ class EditorDirDialog : public ConfirmationDialog { AcceptDialog *mkdirerr; Button *makedir; + Set<String> opened_paths; Tree *tree; bool updating; void _item_collapsed(Object *p_item); - void _update_dir(TreeItem *p_item); + void _update_dir(TreeItem *p_item, EditorFileSystemDirectory *p_dir, const String &p_select_path = String()); void _make_dir(); void _make_dir_confirm(); @@ -61,8 +63,7 @@ protected: static void _bind_methods(); public: - void set_current_path(const String &p_path); - void reload(); + void reload(const String &p_path = ""); EditorDirDialog(); }; diff --git a/editor/editor_fonts.cpp b/editor/editor_fonts.cpp index 22a9c84d21..3ab3f05906 100644 --- a/editor/editor_fonts.cpp +++ b/editor/editor_fonts.cpp @@ -72,11 +72,14 @@ static Ref<BitmapFont> make_font(int p_height, int p_ascent, int p_valign, int p m_name->add_fallback(FontJapanese); \ m_name->add_fallback(FontFallback); -#define MAKE_DEFAULT_FONT(m_name, m_size) \ - Ref<DynamicFont> m_name; \ - m_name.instance(); \ - m_name->set_size(m_size); \ - m_name->set_font_data(DefaultFont); \ +// the custom spacings might only work with Noto Sans +#define MAKE_DEFAULT_FONT(m_name, m_size) \ + Ref<DynamicFont> m_name; \ + m_name.instance(); \ + m_name->set_size(m_size); \ + m_name->set_font_data(DefaultFont); \ + m_name->set_spacing(DynamicFont::SPACING_TOP, -1); \ + m_name->set_spacing(DynamicFont::SPACING_BOTTOM, -1); \ MAKE_FALLBACKS(m_name); void editor_register_fonts(Ref<Theme> p_theme) { diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp index 0e22f0d386..7fa2c53275 100644 --- a/editor/editor_help.cpp +++ b/editor/editor_help.cpp @@ -1712,9 +1712,8 @@ void EditorHelp::_notification(int p_what) { } break; case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { - Ref<StyleBoxFlat> style(memnew(StyleBoxFlat)); - style->set_bg_color(EditorSettings::get_singleton()->get("text_editor/highlighting/background_color")); - background_panel->add_style_override("panel", style); + + class_desc->add_color_override("selection_color", EDITOR_DEF("text_editor/highlighting/selection_color", Color(0.2, 0.2, 1))); } break; default: break; @@ -1786,14 +1785,12 @@ EditorHelp::EditorHelp() { { background_panel = memnew(Panel); - Ref<StyleBoxFlat> style(memnew(StyleBoxFlat)); - style->set_bg_color(EditorSettings::get_singleton()->get("text_editor/highlighting/background_color")); background_panel->set_v_size_flags(SIZE_EXPAND_FILL); - background_panel->add_style_override("panel", style); //get_stylebox("normal","TextEdit")); vbc->add_child(background_panel); class_desc = memnew(RichTextLabel); background_panel->add_child(class_desc); - class_desc->set_area_as_parent_rect(8); + class_desc->set_area_as_parent_rect(); + class_desc->add_color_override("selection_color", EDITOR_DEF("text_editor/highlighting/selection_color", Color(0.2, 0.2, 1))); class_desc->connect("meta_clicked", this, "_class_desc_select"); class_desc->connect("gui_input", this, "_class_desc_input"); } @@ -1882,8 +1879,13 @@ void EditorHelpBit::_bind_methods() { void EditorHelpBit::_notification(int p_what) { - if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) { - add_style_override("panel", get_stylebox("ScriptPanel", "EditorStyles")); + switch (p_what) { + case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { + + rich_text->add_color_override("selection_color", EDITOR_DEF("text_editor/highlighting/selection_color", Color(0.2, 0.2, 1))); + } break; + + default: break; } } @@ -1897,8 +1899,8 @@ EditorHelpBit::EditorHelpBit() { rich_text = memnew(RichTextLabel); add_child(rich_text); - rich_text->set_area_as_parent_rect(8 * EDSCALE); + rich_text->set_area_as_parent_rect(); rich_text->connect("meta_clicked", this, "_meta_clicked"); + rich_text->add_color_override("selection_color", EDITOR_DEF("text_editor/highlighting/selection_color", Color(0.2, 0.2, 1))); set_custom_minimum_size(Size2(0, 70 * EDSCALE)); - add_style_override("panel", EditorNode::get_singleton()->get_gui_base()->get_stylebox("ScriptPanel", "EditorStyles")); } diff --git a/editor/editor_log.cpp b/editor/editor_log.cpp index a1f416a17c..35291f8f9e 100644 --- a/editor/editor_log.cpp +++ b/editor/editor_log.cpp @@ -59,7 +59,6 @@ void EditorLog::_notification(int p_what) { if (p_what == NOTIFICATION_ENTER_TREE) { - log->add_color_override("default_color", get_color("font_color", "Tree")); //button->set_icon(get_icon("Console","EditorIcons")); } if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) { @@ -91,7 +90,7 @@ void EditorLog::add_message(const String &p_msg, bool p_error) { log->add_newline(); if (p_error) { - log->push_color(get_color("fg_error", "Editor")); + log->push_color(get_color("error_color", "Editor")); Ref<Texture> icon = get_icon("Error", "EditorIcons"); log->add_image(icon); //button->set_icon(icon); diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 6b5db7572a..91d2ddcd19 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -283,13 +283,22 @@ void EditorNode::_notification(int p_what) { scene_tabs->set_tab_close_display_policy((bool(EDITOR_DEF("interface/always_show_close_button_in_scene_tabs", false)) ? Tabs::CLOSE_BUTTON_SHOW_ALWAYS : Tabs::CLOSE_BUTTON_SHOW_ACTIVE_ONLY)); property_editor->set_enable_capitalize_paths(bool(EDITOR_DEF("interface/capitalize_properties", true))); Ref<Theme> theme = create_editor_theme(theme_base->get_theme()); + theme_base->set_theme(theme); + gui_base->add_style_override("panel", gui_base->get_stylebox("Background", "EditorStyles")); play_button_panel->add_style_override("panel", gui_base->get_stylebox("PlayButtonPanel", "EditorStyles")); scene_root_parent->add_style_override("panel", gui_base->get_stylebox("Content", "EditorStyles")); bottom_panel->add_style_override("panel", gui_base->get_stylebox("panel", "TabContainer")); scene_tabs->add_style_override("tab_fg", gui_base->get_stylebox("SceneTabFG", "EditorStyles")); scene_tabs->add_style_override("tab_bg", gui_base->get_stylebox("SceneTabBG", "EditorStyles")); + + file_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles")); + project_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles")); + debug_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles")); + settings_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles")); + help_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles")); + if (bool(EDITOR_DEF("interface/scene_tabs/resize_if_many_tabs", true))) { scene_tabs->set_min_width(int(EDITOR_DEF("interface/scene_tabs/minimum_width", 50)) * EDSCALE); } else { @@ -1368,6 +1377,16 @@ void EditorNode::_set_editing_top_editors(Object *p_current_object) { editor_plugins_over->edit(p_current_object); } +static bool overrides_external_editor(Object *p_object) { + + Script *script = Object::cast_to<Script>(p_object); + + if (!script) + return false; + + return script->get_language()->overrides_external_editor(); +} + void EditorNode::_edit_current() { uint32_t current = editor_history.get_current(); @@ -1434,7 +1453,7 @@ void EditorNode::_edit_current() { if (main_plugin) { // special case if use of external editor is true - if (main_plugin->get_name() == "Script" && bool(EditorSettings::get_singleton()->get("text_editor/external/use_external_editor"))) { + if (main_plugin->get_name() == "Script" && (bool(EditorSettings::get_singleton()->get("text_editor/external/use_external_editor")) || overrides_external_editor(current_obj))) { main_plugin->edit(current_obj); } @@ -1442,6 +1461,7 @@ void EditorNode::_edit_current() { // update screen main_plugin if (!changing_scene) { + if (editor_plugin_screen) editor_plugin_screen->make_visible(false); editor_plugin_screen = main_plugin; @@ -2721,6 +2741,14 @@ Dictionary EditorNode::_get_main_scene_state() { state["property_edit_offset"] = get_property_editor()->get_scene_tree()->get_vscroll_bar()->get_value(); state["saved_version"] = saved_version; state["node_filter"] = scene_tree_dock->get_filter(); + int current = -1; + for (int i = 0; i < editor_table.size(); i++) { + if (editor_plugin_screen == editor_table[i]) { + current = i; + break; + } + } + state["editor_index"] = current; return state; } @@ -2731,8 +2759,9 @@ void EditorNode::_set_main_scene_state(Dictionary p_state, Node *p_for_scene) { changing_scene = false; - if (get_edited_scene()) { + if (p_state.has("editor_index")) { + int index = p_state["editor_index"]; int current = -1; for (int i = 0; i < editor_table.size(); i++) { if (editor_plugin_screen == editor_table[i]) { @@ -2741,15 +2770,18 @@ void EditorNode::_set_main_scene_state(Dictionary p_state, Node *p_for_scene) { } } - if (current < 2) { - //use heuristic instead - - int n2d = 0, n3d = 0; - _find_node_types(get_edited_scene(), n2d, n3d); - if (n2d > n3d) { - _editor_select(EDITOR_2D); - } else if (n3d > n2d) { - _editor_select(EDITOR_3D); + if (current < 2) { //if currently in spatial/2d, only switch to spatial/2d. if curently in script, stay there + if (index < 2 || !get_edited_scene()) { + _editor_select(index); + } else { + //use heuristic instead + int n2d = 0, n3d = 0; + _find_node_types(get_edited_scene(), n2d, n3d); + if (n2d > n3d) { + _editor_select(EDITOR_2D); + } else if (n3d > n2d) { + _editor_select(EDITOR_3D); + } } } } @@ -4818,9 +4850,10 @@ EditorNode::EditorNode() { } file_menu = memnew(MenuButton); + file_menu->set_flat(false); file_menu->set_text(TTR("Scene")); - left_menu_hb->add_child(file_menu); file_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles")); + left_menu_hb->add_child(file_menu); prev_scene = memnew(ToolButton); prev_scene->set_icon(gui_base->get_icon("PrevScene", "EditorIcons")); @@ -4908,6 +4941,7 @@ EditorNode::EditorNode() { p->add_item(TTR("Quit"), FILE_QUIT, KEY_MASK_CMD + KEY_Q); project_menu = memnew(MenuButton); + project_menu->set_flat(false); project_menu->set_tooltip(TTR("Miscellaneous project or scene-wide tools.")); project_menu->set_text(TTR("Project")); project_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles")); @@ -4941,9 +4975,11 @@ EditorNode::EditorNode() { menu_hb->add_child(editor_region); debug_menu = memnew(MenuButton); + debug_menu->set_flat(false); debug_menu->set_text(TTR("Debug")); debug_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles")); left_menu_hb->add_child(debug_menu); + p = debug_menu->get_popup(); p->set_hide_on_item_selection(false); p->add_check_item(TTR("Deploy with Remote Debug"), RUN_DEPLOY_REMOTE_DEBUG); @@ -4965,9 +5001,10 @@ EditorNode::EditorNode() { menu_hb->add_spacer(); settings_menu = memnew(MenuButton); - left_menu_hb->add_child(settings_menu); + settings_menu->set_flat(false); settings_menu->set_text(TTR("Editor")); settings_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles")); + left_menu_hb->add_child(settings_menu); p = settings_menu->get_popup(); p->add_item(TTR("Editor Settings"), SETTINGS_PREFERENCES); @@ -4982,10 +5019,12 @@ EditorNode::EditorNode() { p->add_item(TTR("Manage Export Templates"), SETTINGS_MANAGE_EXPORT_TEMPLATES); // Help Menu - MenuButton *help_menu = memnew(MenuButton); - left_menu_hb->add_child(help_menu); + help_menu = memnew(MenuButton); + help_menu->set_flat(false); help_menu->set_text(TTR("Help")); help_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles")); + left_menu_hb->add_child(help_menu); + p = help_menu->get_popup(); p->connect("id_pressed", this, "_menu_option"); p->add_icon_item(gui_base->get_icon("ClassList", "EditorIcons"), TTR("Classes"), HELP_CLASSES); diff --git a/editor/editor_node.h b/editor/editor_node.h index c3ceee350a..ea74bcbd9d 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -236,11 +236,12 @@ private: MenuButton *file_menu; MenuButton *project_menu; MenuButton *debug_menu; + MenuButton *settings_menu; + MenuButton *help_menu; PopupMenu *tool_menu; ToolButton *export_button; ToolButton *prev_scene; MenuButton *object_menu; - MenuButton *settings_menu; ToolButton *play_button; MenuButton *native_play_button; ToolButton *pause_button; diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index 9c9eef848a..db76a27f5f 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -603,7 +603,6 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { hints["text_editor/theme/color_theme"] = PropertyInfo(Variant::STRING, "text_editor/theme/color_theme", PROPERTY_HINT_ENUM, "Default"); set("text_editor/theme/line_spacing", 4); - set("text_editor/theme/adapted_code_editor_background_color", true); _load_default_text_editor_theme(); diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp index 8943d5f0dc..19356aad3a 100644 --- a/editor/editor_themes.cpp +++ b/editor/editor_themes.cpp @@ -198,6 +198,8 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { bool highlight_tabs = EDITOR_DEF("interface/theme/highlight_tabs", false); int border_size = EDITOR_DEF("interface/theme/border_size", 1); + Color script_bg_color = EDITOR_DEF("text_editor/highlighting/background_color", Color(0, 0, 0, 0)); + switch (preset) { case 0: { // Default highlight_color = Color::html("#699ce8"); @@ -235,8 +237,8 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { Color dark_color_2 = base_color.linear_interpolate(Color(0, 0, 0, 1), contrast * 1.5); Color dark_color_3 = base_color.linear_interpolate(Color(0, 0, 0, 1), contrast * 2); - Color contrast_color_1 = base_color.linear_interpolate((dark_theme ? Color(1, 1, 1, 1) : Color(0, 0, 0, 1)), 0.3); - Color contrast_color_2 = base_color.linear_interpolate((dark_theme ? Color(1, 1, 1, 1) : Color(0, 0, 0, 1)), 0.5); + Color contrast_color_1 = base_color.linear_interpolate((dark_theme ? Color(1, 1, 1, 1) : Color(0, 0, 0, 1)), MAX(contrast, default_contrast)); + Color contrast_color_2 = base_color.linear_interpolate((dark_theme ? Color(1, 1, 1, 1) : Color(0, 0, 0, 1)), MAX(contrast * 1.5, default_contrast * 1.5)); Color font_color = dark_theme ? Color(1, 1, 1) : Color(0, 0, 0); Color font_color_disabled = dark_theme ? Color(0.6, 0.6, 0.6) : Color(0.45, 0.45, 0.45); @@ -279,8 +281,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { editor_register_fonts(theme); // Editor background - Ref<StyleBoxFlat> style_panel = make_flat_stylebox(dark_color_2, 4, 4, 4, 4); - theme->set_stylebox("Background", "EditorStyles", style_panel); + theme->set_stylebox("Background", "EditorStyles", make_flat_stylebox(dark_color_2, 4, 4, 4, 4)); // Focus Ref<StyleBoxFlat> focus_sbt = make_flat_stylebox(contrast_color_1, 4, 4, 4, 4); @@ -302,12 +303,11 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { Ref<StyleBoxFlat> style_menu_hover_bg = make_flat_stylebox(dark_color_2, 4, 4, 4, 4); style_menu_hover_border->set_draw_center(false); - style_menu_hover_border->set_border_width(MARGIN_BOTTOM, border_width); + style_menu_hover_border->set_border_width(MARGIN_BOTTOM, 2 * EDSCALE); style_menu_hover_border->set_border_color_all(highlight_color); - style_menu_hover_border->set_expand_margin_size(MARGIN_BOTTOM, border_width); theme->set_stylebox("normal", "MenuButton", style_menu); - theme->set_stylebox("hover", "MenuButton", style_menu_hover_border); + theme->set_stylebox("hover", "MenuButton", style_menu); theme->set_stylebox("pressed", "MenuButton", style_menu); theme->set_stylebox("focus", "MenuButton", style_menu); theme->set_stylebox("disabled", "MenuButton", style_menu); @@ -333,10 +333,10 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_stylebox("MenuHover", "EditorStyles", style_menu_hover_border); // Content of each tab - Ref<StyleBoxFlat> style_content_panel = make_flat_stylebox(base_color, 4, 5, 4, 4); + Ref<StyleBoxFlat> style_content_panel = make_flat_stylebox(base_color, 4, 4, 4, 4); style_content_panel->set_border_color_all(base_color); style_content_panel->set_border_width_all(border_width); - Ref<StyleBoxFlat> style_content_panel_vp = make_flat_stylebox(base_color, border_width, 5, border_width, border_width); + Ref<StyleBoxFlat> style_content_panel_vp = make_flat_stylebox(base_color, border_width, 4, border_width, border_width); style_content_panel_vp->set_border_color_all(base_color); style_content_panel_vp->set_border_width_all(border_width); theme->set_stylebox("panel", "TabContainer", style_content_panel); @@ -357,6 +357,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_stylebox("pressed", "Button", change_border_color(style_button_type, highlight_color)); theme->set_stylebox("focus", "Button", change_border_color(style_button_type, highlight_color)); theme->set_stylebox("disabled", "Button", style_button_type_disabled); + theme->set_color("font_color", "Button", button_font_color); theme->set_color("font_color_hover", "Button", HIGHLIGHT_COLOR_FONT); theme->set_color("font_color_pressed", "Button", highlight_color); @@ -366,13 +367,12 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_color("icon_color_pressed", "Button", Color(highlight_color.r * 1.15, highlight_color.g * 1.15, highlight_color.b * 1.15, highlight_color.a)); // OptionButton - Ref<StyleBoxFlat> style_option_button = make_flat_stylebox(dark_color_1, 4, 4, 4, 4); - style_option_button->set_border_width_all(border_width); + theme->set_stylebox("normal", "OptionButton", style_button_type); theme->set_stylebox("hover", "OptionButton", change_border_color(style_button_type, contrast_color_1)); theme->set_stylebox("pressed", "OptionButton", change_border_color(style_button_type, HIGHLIGHT_COLOR_FONT)); theme->set_stylebox("focus", "OptionButton", change_border_color(style_button_type, highlight_color)); theme->set_stylebox("disabled", "OptionButton", style_button_type_disabled); - theme->set_stylebox("normal", "OptionButton", style_button_type); + theme->set_color("font_color", "OptionButton", button_font_color); theme->set_color("font_color_hover", "OptionButton", HIGHLIGHT_COLOR_FONT); theme->set_color("font_color_pressed", "OptionButton", highlight_color); @@ -385,6 +385,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { // CheckButton theme->set_icon("on", "CheckButton", theme->get_icon("GuiToggleOn", "EditorIcons")); theme->set_icon("off", "CheckButton", theme->get_icon("GuiToggleOff", "EditorIcons")); + theme->set_color("font_color", "CheckButton", button_font_color); theme->set_color("font_color_hover", "CheckButton", HIGHLIGHT_COLOR_FONT); theme->set_color("font_color_pressed", "CheckButton", highlight_color); @@ -424,12 +425,6 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { style_tree_bg->set_border_color_all(dark_color_3); theme->set_stylebox("bg", "Tree", style_tree_bg); - // Script background - Ref<StyleBoxFlat> style_script_bg = make_flat_stylebox(dark_color_1, 0, 0, 0, 0); - style_script_bg->set_border_width_all(border_width); - style_script_bg->set_border_color_all(dark_color_3); - theme->set_stylebox("ScriptPanel", "EditorStyles", style_script_bg); - // Tree theme->set_icon("checked", "Tree", theme->get_icon("GuiChecked", "EditorIcons")); theme->set_icon("unchecked", "Tree", theme->get_icon("GuiUnchecked", "EditorIcons")); @@ -441,7 +436,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_stylebox("custom_button_pressed", "Tree", make_empty_stylebox()); theme->set_stylebox("custom_button_hover", "Tree", style_button_type); theme->set_color("custom_button_font_highlight", "Tree", HIGHLIGHT_COLOR_FONT); - theme->set_color("font_color", "Tree", font_color_disabled); + theme->set_color("font_color", "Tree", font_color); theme->set_color("font_color_selected", "Tree", font_color); Ref<StyleBox> style_tree_btn = make_flat_stylebox(contrast_color_1, 2, 4, 2, 4); @@ -471,8 +466,6 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_color("prop_category", "Editor", prop_category_color); theme->set_color("prop_section", "Editor", prop_section_color); theme->set_color("prop_subsection", "Editor", prop_subsection_color); - theme->set_color("fg_selected", "Editor", HIGHLIGHT_COLOR_BG); - theme->set_color("fg_error", "Editor", error_color); theme->set_color("drop_position_color", "Tree", highlight_color); // ItemList @@ -531,6 +524,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { // LineEdit Ref<StyleBoxFlat> style_line_edit = make_flat_stylebox(dark_color_1, 6, 4, 6, 4); + style_line_edit->set_border_width_all(border_width); style_line_edit = change_border_color(style_line_edit, contrast_color_1); Ref<StyleBoxFlat> style_line_edit_disabled = change_border_color(style_line_edit, dark_color_1); style_line_edit_disabled->set_bg_color(Color(0, 0, 0, .1)); @@ -614,11 +608,14 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_icon("grabber_highlight", "VSlider", theme->get_icon("GuiSliderGrabberHl", "EditorIcons")); //RichTextLabel - theme->set_color("font_color", "RichTextLabel", font_color); + Color rtl_combined_bg_color = dark_color_1.linear_interpolate(script_bg_color, script_bg_color.a); + Color rtl_font_color = (rtl_combined_bg_color.r + rtl_combined_bg_color.g + rtl_combined_bg_color.b > 0.5 * 3) ? Color(0, 0, 0) : Color(1, 1, 1); + theme->set_color("default_color", "RichTextLabel", rtl_font_color); theme->set_stylebox("focus", "RichTextLabel", make_empty_stylebox()); + theme->set_stylebox("normal", "RichTextLabel", make_flat_stylebox(script_bg_color, 6, 6, 6, 6)); // Panel - theme->set_stylebox("panel", "Panel", style_panel); + theme->set_stylebox("panel", "Panel", make_flat_stylebox(dark_color_1, 6, 4, 6, 4)); // Label theme->set_color("font_color", "Label", font_color); diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index 0ad7b25e4a..a66d1724a1 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -828,7 +828,12 @@ void FileSystemDock::_move_operation(const String &p_to_path) { //make list of remaps Map<String, String> renames; String repfrom = path == "res://" ? path : String(path + "/"); - String repto = p_to_path == "res://" ? p_to_path : String(p_to_path + "/"); + String repto = p_to_path; + if (!repto.ends_with("/")) { + repto += "/"; + } + + print_line("reprfrom: " + repfrom + " repto " + repto); for (int i = 0; i < move_files.size(); i++) { renames[move_files[i]] = move_files[i].replace_first(repfrom, repto); @@ -868,6 +873,13 @@ void FileSystemDock::_move_operation(const String &p_to_path) { if (err != OK) { EditorNode::get_singleton()->add_io_error(TTR("Error moving file:\n") + move_files[i] + "\n"); } + if (FileAccess::exists(move_files[i] + ".import")) { //move imported files too + //@todo should remove the files in .import folder + err = da->rename(move_files[i] + ".import", to + ".import"); + if (err != OK) { + EditorNode::get_singleton()->add_io_error(TTR("Error moving file:\n") + move_files[i] + ".import\n"); + } + } } for (int i = 0; i < move_dirs.size(); i++) { @@ -1827,7 +1839,7 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) { path = "res://"; - add_constant_override("separation", 3); + add_constant_override("separation", 4); } FileSystemDock::~FileSystemDock() { diff --git a/editor/import/resource_importer_texture.cpp b/editor/import/resource_importer_texture.cpp index ade3550daa..f29bdde634 100644 --- a/editor/import/resource_importer_texture.cpp +++ b/editor/import/resource_importer_texture.cpp @@ -33,7 +33,7 @@ #include "io/config_file.h" #include "io/image_loader.h" #include "scene/resources/texture.h" - +#include "editor/editor_node.h" void ResourceImporterTexture::_texture_reimport_srgb(const Ref<StreamTexture> &p_tex) { singleton->mutex->lock(); @@ -411,10 +411,14 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String if (compress_mode == COMPRESS_VIDEO_RAM) { //must import in all formats, in order of priority (so platform choses the best supported one. IE, etc2 over etc). //Android, GLES 2.x + + bool ok_on_pc=false; + if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_s3tc")) { _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); r_platform_variants->push_back("s3tc"); + ok_on_pc=true; } if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_etc2")) { @@ -434,6 +438,9 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String r_platform_variants->push_back("pvrtc"); } + 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."); + } } else { //import normally _save_stex(image, p_save_path + ".stex", compress_mode, lossy, Image::COMPRESS_S3TC /*this is ignored */, mipmaps, tex_flags, stream, detect_3d, detect_srgb, force_rgbe, detect_normal, force_normal); diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 3b74601e78..3d5732c749 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -1019,6 +1019,51 @@ void CanvasItemEditor::_list_select(const Ref<InputEventMouseButton> &b) { } } +void CanvasItemEditor::_update_cursor() { + + CursorShape c = CURSOR_ARROW; + switch (drag) { + case DRAG_NONE: + if (Input::get_singleton()->is_mouse_button_pressed(BUTTON_MIDDLE) || Input::get_singleton()->is_key_pressed(KEY_SPACE)) { + c = CURSOR_DRAG; + } else { + switch (tool) { + case TOOL_MOVE: + c = CURSOR_MOVE; + break; + case TOOL_EDIT_PIVOT: + c = CURSOR_CROSS; + break; + case TOOL_PAN: + c = CURSOR_DRAG; + break; + } + } + break; + case DRAG_LEFT: + case DRAG_RIGHT: + c = CURSOR_HSIZE; + break; + case DRAG_TOP: + case DRAG_BOTTOM: + c = CURSOR_VSIZE; + break; + case DRAG_TOP_LEFT: + case DRAG_BOTTOM_RIGHT: + c = CURSOR_FDIAGSIZE; + break; + case DRAG_TOP_RIGHT: + case DRAG_BOTTOM_LEFT: + c = CURSOR_BDIAGSIZE; + break; + case DRAG_ALL: + case DRAG_NODE_2D: + c = CURSOR_MOVE; + break; + } + viewport->set_default_cursor_shape(c); +} + void CanvasItemEditor::_viewport_gui_input(const Ref<InputEvent> &p_event) { { @@ -1457,6 +1502,7 @@ void CanvasItemEditor::_viewport_gui_input(const Ref<InputEvent> &p_event) { Ref<InputEventMouseMotion> m = p_event; if (m.is_valid()) { // Mouse motion event + _update_cursor(); if (!viewport->has_focus() && (!get_focus_owner() || !get_focus_owner()->is_text_field())) viewport->call_deferred("grab_focus"); @@ -2223,6 +2269,9 @@ void CanvasItemEditor::_notification(int p_what) { if (p_what == NOTIFICATION_FIXED_PROCESS) { + + EditorNode::get_singleton()->get_scene_root()->set_snap_controls_to_pixels(GLOBAL_GET("gui/common/snap_controls_to_pixels")); + List<Node *> &selection = editor_selection->get_selected_node_list(); bool all_control = true; @@ -3562,29 +3611,31 @@ void CanvasItemEditorViewport::_create_preview(const Vector<String> &files) cons Sprite *sprite = memnew(Sprite); sprite->set_texture(texture); sprite->set_modulate(Color(1, 1, 1, 0.7f)); - preview->add_child(sprite); + preview_node->add_child(sprite); label->show(); label_desc->show(); } else { if (scene.is_valid()) { Node *instance = scene->instance(); if (instance) { - preview->add_child(instance); + preview_node->add_child(instance); } } } - editor->get_scene_root()->add_child(preview); + editor->get_scene_root()->add_child(preview_node); } } } void CanvasItemEditorViewport::_remove_preview() { - if (preview->get_parent()) { - editor->get_scene_root()->remove_child(preview); - for (int i = preview->get_child_count() - 1; i >= 0; i--) { - Node *node = preview->get_child(i); - memdelete(node); + if (preview_node->get_parent()) { + for (int i = preview_node->get_child_count() - 1; i >= 0; i--) { + Node *node = preview_node->get_child(i); + node->queue_delete(); + preview_node->remove_child(node); } + editor->get_scene_root()->remove_child(preview_node); + label->hide(); label_desc->hide(); } @@ -3794,11 +3845,11 @@ bool CanvasItemEditorViewport::can_drop_data(const Point2 &p_point, const Varian break; } if (can_instance) { - if (!preview->get_parent()) { // create preview only once + if (!preview_node->get_parent()) { // create preview only once _create_preview(files); } Transform2D trans = canvas->get_canvas_transform(); - preview->set_position((p_point - trans.get_origin()) / trans.get_scale().x); + preview_node->set_position((p_point - trans.get_origin()) / trans.get_scale().x); label->set_text(vformat(TTR("Adding %s..."), default_type)); } return can_instance; @@ -3820,11 +3871,16 @@ void CanvasItemEditorViewport::drop_data(const Point2 &p_point, const Variant &p List<Node *> list = editor->get_editor_selection()->get_selected_node_list(); if (list.size() == 0) { - accept->get_ok()->set_text(TTR("OK :(")); - accept->set_text(TTR("No parent to instance a child at.")); - accept->popup_centered_minsize(); - _remove_preview(); - return; + Node *root_node = editor->get_edited_scene(); + 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(); + return; + } } if (list.size() != 1) { accept->get_ok()->set_text(TTR("I see..")); @@ -3891,7 +3947,7 @@ CanvasItemEditorViewport::CanvasItemEditorViewport(EditorNode *p_node, CanvasIte editor = p_node; editor_data = editor->get_scene_tree_dock()->get_editor_data(); canvas = p_canvas; - preview = memnew(Node2D); + preview_node = memnew(Node2D); accept = memnew(AcceptDialog); editor->get_gui_base()->add_child(accept); @@ -3945,5 +4001,5 @@ CanvasItemEditorViewport::CanvasItemEditorViewport(EditorNode *p_node, CanvasIte } CanvasItemEditorViewport::~CanvasItemEditorViewport() { - memdelete(preview); + memdelete(preview_node); } diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h index da217007ea..2e1a2eac5f 100644 --- a/editor/plugins/canvas_item_editor_plugin.h +++ b/editor/plugins/canvas_item_editor_plugin.h @@ -34,7 +34,6 @@ #include "editor/editor_plugin.h" #include "scene/2d/canvas_item.h" #include "scene/gui/box_container.h" -#include "scene/gui/button_group.h" #include "scene/gui/check_box.h" #include "scene/gui/label.h" #include "scene/gui/panel_container.h" @@ -324,6 +323,7 @@ class CanvasItemEditor : public VBoxContainer { bool updating_scroll; void _update_scroll(float); void _update_scrollbars(); + void _update_cursor(); void incbeg(float &beg, float &end, float inc, float minsize, bool p_symmetric); void incend(float &beg, float &end, float inc, float minsize, bool p_symmetric); @@ -459,7 +459,7 @@ class CanvasItemEditorViewport : public Control { EditorNode *editor; EditorData *editor_data; CanvasItemEditor *canvas; - Node2D *preview; + Node2D *preview_node; AcceptDialog *accept; WindowDialog *selector; Label *selector_label; diff --git a/editor/plugins/collision_polygon_2d_editor_plugin.h b/editor/plugins/collision_polygon_2d_editor_plugin.h index bc3c5a1659..4715abd2e6 100644 --- a/editor/plugins/collision_polygon_2d_editor_plugin.h +++ b/editor/plugins/collision_polygon_2d_editor_plugin.h @@ -33,7 +33,6 @@ #include "editor/editor_node.h" #include "editor/editor_plugin.h" #include "scene/2d/collision_polygon_2d.h" -#include "scene/gui/button_group.h" #include "scene/gui/tool_button.h" /** diff --git a/editor/plugins/collision_polygon_editor_plugin.h b/editor/plugins/collision_polygon_editor_plugin.h index 0150d8a9d7..0f63810443 100644 --- a/editor/plugins/collision_polygon_editor_plugin.h +++ b/editor/plugins/collision_polygon_editor_plugin.h @@ -35,7 +35,6 @@ #include "scene/3d/collision_polygon.h" #include "scene/3d/immediate_geometry.h" #include "scene/3d/mesh_instance.h" -#include "scene/gui/button_group.h" #include "scene/gui/tool_button.h" /** diff --git a/editor/plugins/cube_grid_theme_editor_plugin.cpp b/editor/plugins/cube_grid_theme_editor_plugin.cpp index 08b38c2ca2..1c17daf425 100644 --- a/editor/plugins/cube_grid_theme_editor_plugin.cpp +++ b/editor/plugins/cube_grid_theme_editor_plugin.cpp @@ -88,7 +88,7 @@ void MeshLibraryEditor::_import_scene(Node *p_scene, Ref<MeshLibrary> p_library, if (mesh.is_null()) continue; - int id = p_library->find_item_name(mi->get_name()); + int id = p_library->find_item_by_name(mi->get_name()); if (id < 0) { id = p_library->get_last_unused_item_id(); @@ -111,7 +111,8 @@ void MeshLibraryEditor::_import_scene(Node *p_scene, Ref<MeshLibrary> p_library, sb->get_shape_owners(&shapes); for (List<uint32_t>::Element *E = shapes.front(); E; E = E->next()) { - if (sb->is_shape_owner_disabled(E->get())) continue; + if (sb->is_shape_owner_disabled(E->get())) + continue; //Transform shape_transform = sb->shape_owner_get_transform(E->get()); @@ -120,7 +121,7 @@ void MeshLibraryEditor::_import_scene(Node *p_scene, Ref<MeshLibrary> p_library, for (int k = 0; k < sb->shape_owner_get_shape_count(E->get()); k++) { Ref<Shape> collision = sb->shape_owner_get_shape(E->get(), k); - if (collision.is_valid()) + if (!collision.is_valid()) continue; MeshLibrary::ShapeData shape_data; shape_data.shape = collision; diff --git a/editor/plugins/light_occluder_2d_editor_plugin.h b/editor/plugins/light_occluder_2d_editor_plugin.h index 7a4f18963d..b270dcb6e5 100644 --- a/editor/plugins/light_occluder_2d_editor_plugin.h +++ b/editor/plugins/light_occluder_2d_editor_plugin.h @@ -33,7 +33,6 @@ #include "editor/editor_node.h" #include "editor/editor_plugin.h" #include "scene/2d/light_occluder_2d.h" -#include "scene/gui/button_group.h" #include "scene/gui/tool_button.h" /** diff --git a/editor/plugins/line_2d_editor_plugin.h b/editor/plugins/line_2d_editor_plugin.h index dea77ec248..dea0433084 100644 --- a/editor/plugins/line_2d_editor_plugin.h +++ b/editor/plugins/line_2d_editor_plugin.h @@ -34,7 +34,6 @@ #include "editor/editor_plugin.h" #include "scene/2d/line_2d.h" #include "scene/2d/path_2d.h" -#include "scene/gui/button_group.h" #include "scene/gui/tool_button.h" class CanvasItemEditor; diff --git a/editor/plugins/navigation_polygon_editor_plugin.h b/editor/plugins/navigation_polygon_editor_plugin.h index 33f9d5c785..7dd555e9c9 100644 --- a/editor/plugins/navigation_polygon_editor_plugin.h +++ b/editor/plugins/navigation_polygon_editor_plugin.h @@ -33,7 +33,6 @@ #include "editor/editor_node.h" #include "editor/editor_plugin.h" #include "scene/2d/navigation_polygon.h" -#include "scene/gui/button_group.h" #include "scene/gui/tool_button.h" /** diff --git a/editor/plugins/path_2d_editor_plugin.h b/editor/plugins/path_2d_editor_plugin.h index c195845244..f0f5d4d637 100644 --- a/editor/plugins/path_2d_editor_plugin.h +++ b/editor/plugins/path_2d_editor_plugin.h @@ -33,7 +33,6 @@ #include "editor/editor_node.h" #include "editor/editor_plugin.h" #include "scene/2d/path_2d.h" -#include "scene/gui/button_group.h" #include "scene/gui/tool_button.h" /** diff --git a/editor/plugins/polygon_2d_editor_plugin.h b/editor/plugins/polygon_2d_editor_plugin.h index 38148ca7e3..f9d6a6b4b6 100644 --- a/editor/plugins/polygon_2d_editor_plugin.h +++ b/editor/plugins/polygon_2d_editor_plugin.h @@ -33,7 +33,6 @@ #include "editor/editor_node.h" #include "editor/editor_plugin.h" #include "scene/2d/polygon_2d.h" -#include "scene/gui/button_group.h" #include "scene/gui/tool_button.h" /** diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index a529f152dc..04be1ba4ab 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -972,6 +972,14 @@ void ScriptEditor::_menu_option(int p_option) { EditorNode::get_singleton()->show_warning("Can't obtain the script for running"); break; } + + current->apply_code(); + Error err = scr->reload(false); //hard reload script before running always + + if (err != OK) { + EditorNode::get_singleton()->show_warning("Script failed reloading, check console for errors."); + return; + } if (!scr->is_tool()) { EditorNode::get_singleton()->show_warning("Script is not in tool mode, will not be able to run"); @@ -1149,8 +1157,6 @@ void ScriptEditor::_notification(int p_what) { case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { - tab_container->add_style_override("panel", editor->get_gui_base()->get_stylebox("ScriptPanel", "EditorStyles")); - help_search->set_icon(get_icon("HelpSearch", "EditorIcons")); site_search->set_icon(get_icon("Instance", "EditorIcons")); class_search->set_icon(get_icon("ClassList", "EditorIcons")); @@ -1417,7 +1423,7 @@ void ScriptEditor::_update_script_colors() { int non_zero_hist_size = (hist_size == 0) ? 1 : hist_size; float v = Math::ease((edit_pass - pass) / float(non_zero_hist_size), 0.4); - script_list->set_item_custom_bg_color(i, hot_color.linear_interpolate(cold_color, v)); + script_list->set_item_custom_fg_color(i, hot_color.linear_interpolate(cold_color, v)); } } } @@ -1539,8 +1545,14 @@ bool ScriptEditor::edit(const Ref<Script> &p_script, int p_line, int p_col, bool bool open_dominant = EditorSettings::get_singleton()->get("text_editor/files/open_dominant_script_on_scene_change"); + if (p_script->get_language()->overrides_external_editor()) { + Error err = p_script->get_language()->open_in_external_editor(p_script, p_line >= 0 ? p_line : 0, p_col); + if (err != OK) + ERR_PRINT("Couldn't open script in the overridden external text editor"); + return false; + } + if ((debugger->get_dump_stack_script() != p_script || debugger->get_debug_with_external_editor()) && - p_script->get_language()->open_in_external_editor(p_script, p_line >= 0 ? p_line : 0, p_col) == OK && p_script->get_path().is_resource_file() && bool(EditorSettings::get_singleton()->get("text_editor/external/use_external_editor"))) { @@ -2210,7 +2222,6 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) { members_overview->set_v_size_flags(SIZE_EXPAND_FILL); tab_container = memnew(TabContainer); - tab_container->add_style_override("panel", p_editor->get_gui_base()->get_stylebox("ScriptPanel", "EditorStyles")); tab_container->set_tabs_visible(false); script_split->add_child(tab_container); @@ -2506,9 +2517,9 @@ ScriptEditorPlugin::ScriptEditorPlugin(EditorNode *p_node) { EDITOR_DEF("text_editor/open_scripts/script_temperature_enabled", true); EDITOR_DEF("text_editor/open_scripts/highlight_current_script", true); EDITOR_DEF("text_editor/open_scripts/script_temperature_history_size", 15); - EDITOR_DEF("text_editor/open_scripts/script_temperature_hot_color", Color(1, 0, 0, 0.3)); - EDITOR_DEF("text_editor/open_scripts/script_temperature_cold_color", Color(0, 0, 1, 0.3)); - EDITOR_DEF("text_editor/open_scripts/current_script_background_color", Color(0.81, 0.81, 0.14, 0.63)); + EDITOR_DEF("text_editor/open_scripts/script_temperature_hot_color", Color::html("ed5e5e")); + EDITOR_DEF("text_editor/open_scripts/script_temperature_cold_color", Color(1, 1, 1, 0.3)); + EDITOR_DEF("text_editor/open_scripts/current_script_background_color", Color(1, 1, 1, 0.5)); EDITOR_DEF("text_editor/open_scripts/group_help_pages", true); EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT, "text_editor/open_scripts/sort_scripts_by", PROPERTY_HINT_ENUM, "Name,Path")); EDITOR_DEF("text_editor/open_scripts/sort_scripts_by", 0); diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp index 33890d890d..fae57eb5d2 100644 --- a/editor/plugins/script_text_editor.cpp +++ b/editor/plugins/script_text_editor.cpp @@ -75,14 +75,9 @@ void ScriptTextEditor::_load_theme_settings() { text_edit->clear_colors(); - /* color from color_theme or from editor color */ - - Color background_color = EDITOR_DEF("text_editor/highlighting/background_color", Color(0, 0, 0, 0)); - if (EDITOR_DEF("text_editor/theme/adapted_code_editor_background_color", false)) - background_color = get_color("dark_color_1", "Editor"); - /* keyword color */ - text_edit->add_color_override("background_color", background_color); + + text_edit->add_color_override("background_color", EDITOR_DEF("text_editor/highlighting/background_color", Color(0, 0, 0, 0))); text_edit->add_color_override("completion_background_color", EDITOR_DEF("text_editor/highlighting/completion_background_color", Color(0, 0, 0, 0))); text_edit->add_color_override("completion_selected_color", EDITOR_DEF("text_editor/highlighting/completion_selected_color", Color::html("434244"))); text_edit->add_color_override("completion_existing_color", EDITOR_DEF("text_editor/highlighting/completion_existing_color", Color::html("21dfdfdf"))); diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp index 13b0391a87..b02016c273 100644 --- a/editor/plugins/shader_editor_plugin.cpp +++ b/editor/plugins/shader_editor_plugin.cpp @@ -289,6 +289,8 @@ void ShaderEditor::_editor_settings_changed() { shader_editor->get_text_edit()->cursor_set_blink_speed(EditorSettings::get_singleton()->get("text_editor/cursor/caret_blink_speed")); shader_editor->get_text_edit()->add_constant_override("line_spacing", EditorSettings::get_singleton()->get("text_editor/theme/line_spacing")); shader_editor->get_text_edit()->cursor_set_block_mode(EditorSettings::get_singleton()->get("text_editor/cursor/block_caret")); + shader_editor->get_text_edit()->set_smooth_scroll_enabled(EditorSettings::get_singleton()->get("text_editor/open_scripts/smooth_scrolling")); + shader_editor->get_text_edit()->set_v_scroll_speed(EditorSettings::get_singleton()->get("text_editor/open_scripts/v_scroll_speed")); } void ShaderEditor::_bind_methods() { diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp index d9fc2f32f7..4e722be44b 100644 --- a/editor/plugins/spatial_editor_plugin.cpp +++ b/editor/plugins/spatial_editor_plugin.cpp @@ -35,12 +35,15 @@ #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/visual_instance.h" +#include "scene/resources/packed_scene.h" #include "scene/resources/surface_tool.h" #include "sort.h" @@ -77,7 +80,7 @@ void SpatialEditorViewport::_update_camera(float p_interp_delta) { Transform old_transform = camera->get_global_transform(); Transform transform; - bool disable_interp = (Input::get_singleton()->get_mouse_button_mask() & (2 | 4)) || Input::get_singleton()->is_key_pressed(KEY_SHIFT) || Input::get_singleton()->is_key_pressed(KEY_ALT) || Input::get_singleton()->is_key_pressed(KEY_CONTROL); + bool disable_interp = orthogonal || (Input::get_singleton()->get_mouse_button_mask() & (2 | 4)) || Input::get_singleton()->is_key_pressed(KEY_SHIFT) || Input::get_singleton()->is_key_pressed(KEY_ALT) || Input::get_singleton()->is_key_pressed(KEY_CONTROL); if (p_interp_delta && !disable_interp) { //interpolate @@ -228,7 +231,7 @@ Vector3 SpatialEditorViewport::_get_camera_normal() const { return -_get_camera_transform().basis.get_axis(2); } -Vector3 SpatialEditorViewport::_get_ray(const Vector2 &p_pos) { +Vector3 SpatialEditorViewport::_get_ray(const Vector2 &p_pos) const { return camera->project_ray_normal(p_pos); } @@ -700,6 +703,11 @@ void SpatialEditorViewport::_smouseenter() { surface->grab_focus(); } +void SpatialEditorViewport::_smouseexit() { + + _remove_preview(); +} + void SpatialEditorViewport::_list_select(Ref<InputEventMouseButton> b) { _find_items_at_pos(b->get_position(), clicked_includes_current, selection_results, b->get_shift()); @@ -1895,6 +1903,7 @@ void SpatialEditorViewport::_notification(int p_what) { surface->connect("draw", this, "_draw"); surface->connect("gui_input", this, "_sinput"); surface->connect("mouse_entered", this, "_smouseenter"); + surface->connect("mouse_exited", this, "_smouseexit"); info->add_style_override("panel", get_stylebox("panel", "Panel")); preview_camera->set_icon(get_icon("Camera", "EditorIcons")); _init_gizmo_instance(index); @@ -2425,6 +2434,7 @@ void SpatialEditorViewport::_bind_methods() { ClassDB::bind_method(D_METHOD("_draw"), &SpatialEditorViewport::_draw); ClassDB::bind_method(D_METHOD("_smouseenter"), &SpatialEditorViewport::_smouseenter); + ClassDB::bind_method(D_METHOD("_smouseexit"), &SpatialEditorViewport::_smouseexit); ClassDB::bind_method(D_METHOD("_sinput"), &SpatialEditorViewport::_sinput); ClassDB::bind_method(D_METHOD("_menu_option"), &SpatialEditorViewport::_menu_option); ClassDB::bind_method(D_METHOD("_toggle_camera_preview"), &SpatialEditorViewport::_toggle_camera_preview); @@ -2432,6 +2442,8 @@ void SpatialEditorViewport::_bind_methods() { ClassDB::bind_method(D_METHOD("update_transform_gizmo_view"), &SpatialEditorViewport::update_transform_gizmo_view); ClassDB::bind_method(D_METHOD("_selection_result_pressed"), &SpatialEditorViewport::_selection_result_pressed); ClassDB::bind_method(D_METHOD("_selection_menu_hide"), &SpatialEditorViewport::_selection_menu_hide); + ClassDB::bind_method(D_METHOD("can_drop_data_fw"), &SpatialEditorViewport::can_drop_data_fw); + ClassDB::bind_method(D_METHOD("drop_data_fw"), &SpatialEditorViewport::drop_data_fw); ADD_SIGNAL(MethodInfo("toggle_maximize_view", PropertyInfo(Variant::OBJECT, "viewport"))); } @@ -2481,6 +2493,293 @@ void SpatialEditorViewport::focus_selection() { cursor.pos = center; } +void SpatialEditorViewport::assign_pending_data_pointers(Spatial *p_preview_node, Rect3 *p_preview_bounds, AcceptDialog *p_accept) { + preview_node = p_preview_node; + preview_bounds = p_preview_bounds; + accept = p_accept; +} + +Vector3 SpatialEditorViewport::_get_instance_position(const Point2 &p_pos) const { + const float MAX_DISTANCE = 10; + + Vector3 world_ray = _get_ray(p_pos); + Vector3 world_pos = _get_ray_pos(p_pos); + + Vector<ObjectID> instances = VisualServer::get_singleton()->instances_cull_ray(world_pos, world_ray, get_tree()->get_root()->get_world()->get_scenario()); + Set<Ref<SpatialEditorGizmo> > found_gizmos; + + float closest_dist = MAX_DISTANCE; + + Vector3 point = world_pos + world_ray * MAX_DISTANCE; + Vector3 normal = Vector3(0.0, 0.0, 0.0); + + for (int i = 0; i < instances.size(); i++) { + + MeshInstance *mesh_instance = Object::cast_to<MeshInstance>(ObjectDB::get_instance(instances[i])); + + if (!mesh_instance) + continue; + + Ref<SpatialEditorGizmo> seg = mesh_instance->get_gizmo(); + + if ((!seg.is_valid()) || found_gizmos.has(seg)) { + continue; + } + + found_gizmos.insert(seg); + + int handle = -1; + Vector3 hit_point; + Vector3 hit_normal; + bool inters = seg->intersect_ray(camera, p_pos, hit_point, hit_normal, NULL, false); + + if (!inters) + continue; + + float dist = world_pos.distance_to(hit_point); + + if (dist < 0) + continue; + + if (dist < closest_dist) { + closest_dist = dist; + point = hit_point; + normal = hit_normal; + } + } + Vector3 center = preview_bounds->get_size() * 0.5; + return point + (center * normal); +} + +Rect3 SpatialEditorViewport::_calculate_spatial_bounds(const Spatial *p_parent, const Rect3 p_bounds) { + Rect3 bounds = p_bounds; + for (int i = 0; i < p_parent->get_child_count(); i++) { + Spatial *child = Object::cast_to<Spatial>(p_parent->get_child(i)); + if (child) { + MeshInstance *mesh_instance = Object::cast_to<MeshInstance>(child); + if (mesh_instance) { + Rect3 mesh_instance_bounds = mesh_instance->get_aabb(); + mesh_instance_bounds.position += mesh_instance->get_global_transform().origin - p_parent->get_global_transform().origin; + bounds.merge_with(mesh_instance_bounds); + } + bounds = _calculate_spatial_bounds(child, bounds); + } + } + return bounds; +} + +void SpatialEditorViewport::_create_preview(const Vector<String> &files) const { + for (int i = 0; i < files.size(); i++) { + String path = files[i]; + RES res = ResourceLoader::load(path); + Ref<PackedScene> scene = Ref<PackedScene>(Object::cast_to<PackedScene>(*res)); + if (scene != NULL) { + if (scene.is_valid()) { + Node *instance = scene->instance(); + if (instance) { + preview_node->add_child(instance); + } + } + editor->get_scene_root()->add_child(preview_node); + } + } + *preview_bounds = _calculate_spatial_bounds(preview_node, Rect3()); +} + +void SpatialEditorViewport::_remove_preview() { + if (preview_node->get_parent()) { + for (int i = preview_node->get_child_count() - 1; i >= 0; i--) { + Node *node = preview_node->get_child(i); + node->queue_delete(); + preview_node->remove_child(node); + } + editor->get_scene_root()->remove_child(preview_node); + } +} + +bool SpatialEditorViewport::_cyclical_dependency_exists(const String &p_target_scene_path, Node *p_desired_node) { + if (p_desired_node->get_filename() == p_target_scene_path) { + return true; + } + + int childCount = p_desired_node->get_child_count(); + for (int i = 0; i < childCount; i++) { + Node *child = p_desired_node->get_child(i); + if (_cyclical_dependency_exists(p_target_scene_path, child)) { + return true; + } + } + return false; +} + +bool SpatialEditorViewport::_create_instance(Node *parent, String &path, const Point2 &p_point) { + Ref<PackedScene> sdata = ResourceLoader::load(path); + if (!sdata.is_valid()) { // invalid scene + return false; + } + + Node *instanced_scene = sdata->instance(PackedScene::GEN_EDIT_STATE_INSTANCE); + if (!instanced_scene) { // error on instancing + return false; + } + + if (editor->get_edited_scene()->get_filename() != "") { // cyclical instancing + if (_cyclical_dependency_exists(editor->get_edited_scene()->get_filename(), instanced_scene)) { + memdelete(instanced_scene); + return false; + } + } + + instanced_scene->set_filename(ProjectSettings::get_singleton()->localize_path(path)); + + editor_data->get_undo_redo().add_do_method(parent, "add_child", instanced_scene); + editor_data->get_undo_redo().add_do_method(instanced_scene, "set_owner", editor->get_edited_scene()); + editor_data->get_undo_redo().add_do_reference(instanced_scene); + editor_data->get_undo_redo().add_undo_method(parent, "remove_child", instanced_scene); + + 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", editor->get_edited_scene()->get_path_to(parent), path, new_name); + editor_data->get_undo_redo().add_undo_method(sed, "live_debug_remove_node", NodePath(String(editor->get_edited_scene()->get_path_to(parent)) + "/" + new_name)); + + Transform global_transform; + Spatial *parent_spatial = Object::cast_to<Spatial>(parent); + if (parent_spatial) + global_transform = parent_spatial->get_global_transform(); + + global_transform.origin = _get_instance_position(p_point); + + editor_data->get_undo_redo().add_do_method(instanced_scene, "set_global_transform", global_transform); + + return true; +} + +void SpatialEditorViewport::_perform_drop_data() { + _remove_preview(); + + Vector<String> error_files; + + editor_data->get_undo_redo().create_action(TTR("Create Node")); + + for (int i = 0; i < selected_files.size(); i++) { + String path = selected_files[i]; + RES res = ResourceLoader::load(path); + if (res.is_null()) { + continue; + } + Ref<PackedScene> scene = Ref<PackedScene>(Object::cast_to<PackedScene>(*res)); + if (scene != NULL) { + bool success = _create_instance(target_node, path, drop_pos); + if (!success) { + error_files.push_back(path); + } + } + } + + editor_data->get_undo_redo().commit_action(); + + if (error_files.size() > 0) { + String files_str; + for (int i = 0; i < error_files.size(); i++) { + 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("Ugh")); + accept->set_text(vformat(TTR("Error instancing scene from %s"), files_str.c_str())); + accept->popup_centered_minsize(); + } +} + +bool SpatialEditorViewport::can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const { + + bool can_instance = false; + + if (!preview_node->is_inside_tree()) { + Dictionary d = p_data; + if (d.has("type") && (String(d["type"]) == "files")) { + Vector<String> files = d["files"]; + + List<String> scene_extensions; + ResourceLoader::get_recognized_extensions_for_type("PackedScene", &scene_extensions); + + for (int i = 0; i < files.size(); i++) { + if (scene_extensions.find(files[i].get_extension())) { + RES res = ResourceLoader::load(files[i]); + if (res.is_null()) { + continue; + } + + String type = res->get_class(); + if (type == "PackedScene") { + Ref<PackedScene> sdata = ResourceLoader::load(files[i]); + Node *instanced_scene = sdata->instance(PackedScene::GEN_EDIT_STATE_INSTANCE); + if (!instanced_scene) { + continue; + } + memdelete(instanced_scene); + } + can_instance = true; + break; + } + } + if (can_instance) { + _create_preview(files); + } + } + } else { + can_instance = true; + } + + if (can_instance) { + Transform global_transform = Transform(Basis(), _get_instance_position(p_point)); + preview_node->set_global_transform(global_transform); + } + + return can_instance; +} + +void SpatialEditorViewport::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) { + if (!can_drop_data_fw(p_point, p_data, p_from)) + return; + + bool is_shift = Input::get_singleton()->is_key_pressed(KEY_SHIFT); + + selected_files.clear(); + Dictionary d = p_data; + if (d.has("type") && String(d["type"]) == "files") { + selected_files = d["files"]; + } + + List<Node *> list = editor->get_editor_selection()->get_selected_node_list(); + if (list.size() == 0) { + Node *root_node = editor->get_edited_scene(); + 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(); + return; + } + } + if (list.size() != 1) { + accept->get_ok()->set_text(TTR("I see..")); + accept->set_text(TTR("This operation requires a single selected node.")); + accept->popup_centered_minsize(); + _remove_preview(); + return; + } + + target_node = list[0]; + if (is_shift && target_node != editor->get_edited_scene()) { + target_node = target_node->get_parent(); + } + drop_pos = p_point; + + _perform_drop_data(); +} + SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, EditorNode *p_editor, int p_index) { _edit.mode = TRANSFORM_NONE; @@ -2491,6 +2790,7 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed index = p_index; editor = p_editor; + editor_data = editor->get_scene_tree_dock()->get_editor_data(); editor_selection = editor->get_editor_selection(); undo_redo = editor->get_undo_redo(); clicked = 0; @@ -2509,6 +2809,7 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed c->add_child(viewport); surface = memnew(Control); + surface->set_drag_forwarding(this); add_child(surface); surface->set_area_as_parent_rect(); surface->set_clip_contents(true); @@ -2573,9 +2874,10 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed preview_camera->hide(); preview_camera->connect("toggled", this, "_toggle_camera_preview"); previewing = NULL; - preview = NULL; gizmo_scale = 1.0; + preview_node = NULL; + info = memnew(PanelContainer); info->set_self_modulate(Color(1, 1, 1, 0.4)); surface->add_child(info); @@ -2583,6 +2885,8 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed info->add_child(info_label); info->hide(); + accept = NULL; + freelook_active = false; selection_menu = memnew(PopupMenu); @@ -4000,6 +4304,10 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) { vs = memnew(VSeparator); hbc_menu->add_child(vs); + // Drag and drop support; + preview_node = memnew(Spatial); + preview_bounds = Rect3(); + ED_SHORTCUT("spatial_editor/bottom_view", TTR("Bottom View"), KEY_MASK_ALT + KEY_KP_7); ED_SHORTCUT("spatial_editor/top_view", TTR("Top View"), KEY_KP_7); ED_SHORTCUT("spatial_editor/rear_view", TTR("Rear View"), KEY_MASK_ALT + KEY_KP_1); @@ -4044,6 +4352,9 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) { p = view_menu->get_popup(); + accept = memnew(AcceptDialog); + editor->get_gui_base()->add_child(accept); + p->add_check_shortcut(ED_SHORTCUT("spatial_editor/1_viewport", TTR("1 Viewport"), KEY_MASK_CMD + KEY_1), MENU_VIEW_USE_1_VIEWPORT); p->add_check_shortcut(ED_SHORTCUT("spatial_editor/2_viewports", TTR("2 Viewports"), KEY_MASK_CMD + KEY_2), MENU_VIEW_USE_2_VIEWPORTS); p->add_check_shortcut(ED_SHORTCUT("spatial_editor/2_viewports_alt", TTR("2 Viewports (Alt)"), KEY_MASK_ALT + KEY_MASK_CMD + KEY_2), MENU_VIEW_USE_2_VIEWPORTS_ALT); @@ -4078,6 +4389,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) { viewports[i] = memnew(SpatialEditorViewport(this, editor, i)); viewports[i]->connect("toggle_maximize_view", this, "_toggle_maximize_view"); + viewports[i]->assign_pending_data_pointers(preview_node, &preview_bounds, accept); viewport_base->add_child(viewports[i]); } //vbc->add_child(viewport_base); @@ -4212,6 +4524,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) { } SpatialEditor::~SpatialEditor() { + memdelete(preview_node); } void SpatialEditorPlugin::make_visible(bool p_visible) { diff --git a/editor/plugins/spatial_editor_plugin.h b/editor/plugins/spatial_editor_plugin.h index 374861b5e7..db5abe2b53 100644 --- a/editor/plugins/spatial_editor_plugin.h +++ b/editor/plugins/spatial_editor_plugin.h @@ -106,7 +106,16 @@ private: void _menu_option(int p_option); Size2 prev_size; + Spatial *preview_node; + Rect3 *preview_bounds; + Vector<String> selected_files; + AcceptDialog *accept; + + Node *target_node; + Point2 drop_pos; + EditorNode *editor; + EditorData *editor_data; EditorSelection *editor_selection; UndoRedo *undo_redo; @@ -143,7 +152,7 @@ private: 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; - Vector3 _get_ray(const Vector2 &p_pos); + Vector3 _get_ray(const Vector2 &p_pos) const; Point2 _point_to_screen(const Vector3 &p_point); Transform _get_camera_transform() const; int get_selected_count() const; @@ -250,6 +259,7 @@ private: void _draw(); void _smouseenter(); + void _smouseexit(); void _sinput(const Ref<InputEvent> &p_event); void _update_freelook(real_t delta); SpatialEditor *spatial_editor; @@ -266,6 +276,17 @@ private: void _list_select(Ref<InputEventMouseButton> b); Point2i _get_warped_mouse_motion(const Ref<InputEventMouseMotion> &p_ev_mouse_motion) const; + Vector3 _get_instance_position(const Point2 &p_pos) const; + static Rect3 _calculate_spatial_bounds(const Spatial *p_parent, const Rect3 p_bounds); + void _create_preview(const Vector<String> &files) const; + void _remove_preview(); + bool _cyclical_dependency_exists(const String &p_target_scene_path, Node *p_desired_node); + bool _create_instance(Node *parent, String &path, const Point2 &p_point); + void _perform_drop_data(); + + 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); + protected: void _notification(int p_what); static void _bind_methods(); @@ -281,6 +302,11 @@ public: void focus_selection(); + void assign_pending_data_pointers( + Spatial *p_preview_node, + Rect3 *p_preview_bounds, + AcceptDialog *p_accept); + Viewport *get_viewport_node() { return viewport; } SpatialEditorViewport(SpatialEditor *p_spatial_editor, EditorNode *p_editor, int p_index); @@ -396,6 +422,10 @@ private: Ref<SpatialMaterial> indicator_mat; Ref<SpatialMaterial> cursor_material; + // Scene drag and drop support + Spatial *preview_node; + Rect3 preview_bounds; + /* struct Selected { AABB aabb; @@ -442,6 +472,8 @@ private: MenuButton *transform_menu; MenuButton *view_menu; + AcceptDialog *accept; + ConfirmationDialog *snap_dialog; ConfirmationDialog *xform_dialog; ConfirmationDialog *settings_dialog; @@ -559,6 +591,7 @@ public: Camera *get_camera() { return NULL; } void edit(Spatial *p_spatial); void clear(); + SpatialEditor(EditorNode *p_editor); ~SpatialEditor(); }; diff --git a/editor/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp index c2c26bfe6c..7b40f69082 100644 --- a/editor/plugins/sprite_frames_editor_plugin.cpp +++ b/editor/plugins/sprite_frames_editor_plugin.cpp @@ -244,8 +244,22 @@ void SpriteFramesEditor::_down_pressed() { void SpriteFramesEditor::_delete_pressed() { + ERR_FAIL_COND(!frames->has_animation(edited_anim)); + if (tree->get_current() < 0) return; + + int to_delete = tree->get_current(); + if (to_delete < 0 || to_delete >= frames->get_frame_count(edited_anim)) { + return; + } + + undo_redo->create_action(TTR("Delete Resource")); + undo_redo->add_do_method(frames, "remove_frame", edited_anim, to_delete); + undo_redo->add_undo_method(frames, "add_frame", edited_anim, frames->get_frame(edited_anim, to_delete), to_delete); + undo_redo->add_do_method(this, "_update_library"); + undo_redo->add_undo_method(this, "_update_library"); + undo_redo->commit_action(); } void SpriteFramesEditor::_animation_select() { diff --git a/editor/plugins/theme_editor_plugin.h b/editor/plugins/theme_editor_plugin.h index cb6f086de6..16b2da94d1 100644 --- a/editor/plugins/theme_editor_plugin.h +++ b/editor/plugins/theme_editor_plugin.h @@ -30,7 +30,6 @@ #ifndef THEME_EDITOR_PLUGIN_H #define THEME_EDITOR_PLUGIN_H -#include "scene/gui/button_group.h" #include "scene/gui/check_box.h" #include "scene/gui/file_dialog.h" #include "scene/gui/option_button.h" diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp index 2cd0221ab6..1f65589643 100644 --- a/editor/project_settings_editor.cpp +++ b/editor/project_settings_editor.cpp @@ -182,8 +182,8 @@ void ProjectSettingsEditor::_device_input_add() { Ref<InputEvent> ie; String name = add_at; int idx = edit_idx; - Variant old_val = ProjectSettings::get_singleton()->get(name); - Array arr = old_val; + Array old_val = ProjectSettings::get_singleton()->get(name); + Array arr = old_val.duplicate(); switch (add_type) { @@ -285,8 +285,8 @@ void ProjectSettingsEditor::_press_a_key_confirm() { String name = add_at; int idx = edit_idx; - Variant old_val = ProjectSettings::get_singleton()->get(name); - Array arr = old_val; + Array old_val = ProjectSettings::get_singleton()->get(name); + Array arr = old_val.duplicate(); for (int i = 0; i < arr.size(); i++) { @@ -700,6 +700,8 @@ void ProjectSettingsEditor::_update_actions() { action->set_meta("__input", ie); } } + + _action_check(action_name->get_text()); } void ProjectSettingsEditor::popup_project_settings() { @@ -809,28 +811,41 @@ void ProjectSettingsEditor::_item_del() { undo_redo->commit_action(); } -void ProjectSettingsEditor::_action_adds(String) { +void ProjectSettingsEditor::_action_check(String p_action) { - _action_add(); -} + if (p_action == "") { -void ProjectSettingsEditor::_action_add() { + action_add->set_disabled(true); + } else { - String action = action_name->get_text(); - if (action.find("/") != -1 || action.find(":") != -1 || action == "") { - message->set_text(TTR("Invalid action (anything goes but '/' or ':').")); - message->popup_centered(Size2(300, 100) * EDSCALE); - return; + if (p_action.find("/") != -1 || p_action.find(":") != -1) { + action_add->set_text(TTR("Can't contain '/' or ':'")); + action_add->set_disabled(true); + return; + } + if (ProjectSettings::get_singleton()->has("input/" + p_action)) { + action_add->set_text(TTR("Already existing")); + action_add->set_disabled(true); + return; + } + + action_add->set_disabled(false); } - if (ProjectSettings::get_singleton()->has("input/" + action)) { - message->set_text(vformat(TTR("Action '%s' already exists!"), action)); - message->popup_centered(Size2(300, 100) * EDSCALE); - return; + action_add->set_text(TTR("Add")); +} + +void ProjectSettingsEditor::_action_adds(String) { + + if (!action_add->is_disabled()) { + _action_add(); } +} + +void ProjectSettingsEditor::_action_add() { Array va; - String name = "input/" + action; + String name = "input/" + action_name->get_text(); undo_redo->create_action(TTR("Add Input Action Event")); undo_redo->add_do_method(ProjectSettings::get_singleton(), "set", name, va); undo_redo->add_undo_method(ProjectSettings::get_singleton(), "clear", name); @@ -854,6 +869,7 @@ void ProjectSettingsEditor::_action_add() { return; r->select(0); input_editor->ensure_cursor_is_visible(); + action_add->set_text(TTR("Add")); } void ProjectSettingsEditor::_item_checked(const String &p_item, bool p_check) { @@ -1321,6 +1337,11 @@ void ProjectSettingsEditor::set_plugins_page() { tab_container->set_current_tab(plugin_settings->get_index()); } +TabContainer *ProjectSettingsEditor::get_tabs() { + + return tab_container; +} + void ProjectSettingsEditor::_bind_methods() { ClassDB::bind_method(D_METHOD("_item_selected"), &ProjectSettingsEditor::_item_selected); @@ -1331,6 +1352,7 @@ void ProjectSettingsEditor::_bind_methods() { ClassDB::bind_method(D_METHOD("_save"), &ProjectSettingsEditor::_save); ClassDB::bind_method(D_METHOD("_action_add"), &ProjectSettingsEditor::_action_add); ClassDB::bind_method(D_METHOD("_action_adds"), &ProjectSettingsEditor::_action_adds); + ClassDB::bind_method(D_METHOD("_action_check"), &ProjectSettingsEditor::_action_check); ClassDB::bind_method(D_METHOD("_action_selected"), &ProjectSettingsEditor::_action_selected); ClassDB::bind_method(D_METHOD("_action_edited"), &ProjectSettingsEditor::_action_edited); ClassDB::bind_method(D_METHOD("_action_activated"), &ProjectSettingsEditor::_action_activated); @@ -1361,6 +1383,8 @@ void ProjectSettingsEditor::_bind_methods() { ClassDB::bind_method(D_METHOD("_toggle_search_bar"), &ProjectSettingsEditor::_toggle_search_bar); ClassDB::bind_method(D_METHOD("_copy_to_platform_about_to_show"), &ProjectSettingsEditor::_copy_to_platform_about_to_show); + + ClassDB::bind_method(D_METHOD("get_tabs"), &ProjectSettingsEditor::get_tabs); } ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) { @@ -1475,9 +1499,8 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) { get_ok()->set_text(TTR("Close")); set_hide_on_ok(true); - message = memnew(ConfirmationDialog); + message = memnew(AcceptDialog); add_child(message); - message->set_hide_on_ok(true); Control *input_base = memnew(Control); input_base->set_name(TTR("Input Map")); @@ -1493,7 +1516,6 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) { l = memnew(Label); vbc->add_child(l); - l->set_position(Point2(6, 5) * EDSCALE); l->set_text(TTR("Action:")); hbc = memnew(HBoxContainer); @@ -1503,12 +1525,15 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) { action_name->set_h_size_flags(SIZE_EXPAND_FILL); hbc->add_child(action_name); action_name->connect("text_entered", this, "_action_adds"); + action_name->connect("text_changed", this, "_action_check"); add = memnew(Button); hbc->add_child(add); add->set_custom_minimum_size(Size2(150, 0) * EDSCALE); add->set_text(TTR("Add")); + add->set_disabled(true); add->connect("pressed", this, "_action_add"); + action_add = add; input_editor = memnew(Tree); vbc->add_child(input_editor); diff --git a/editor/project_settings_editor.h b/editor/project_settings_editor.h index ceec089953..7f9b18a968 100644 --- a/editor/project_settings_editor.h +++ b/editor/project_settings_editor.h @@ -66,7 +66,7 @@ class ProjectSettingsEditor : public AcceptDialog { ToolButton *clear_button; HBoxContainer *add_prop_bar; - ConfirmationDialog *message; + AcceptDialog *message; LineEdit *category; LineEdit *property; OptionButton *type; @@ -80,6 +80,7 @@ class ProjectSettingsEditor : public AcceptDialog { MenuButton *popup_copy_to_feature; LineEdit *action_name; + Button *action_add; Tree *input_editor; bool setting; bool updating_translations; @@ -108,6 +109,7 @@ class ProjectSettingsEditor : public AcceptDialog { void _add_item(int p_item, Ref<InputEvent> p_exiting_event = NULL); void _edit_item(Ref<InputEvent> p_exiting_event); + void _action_check(String p_action); void _action_adds(String); void _action_add(); void _device_input_add(); @@ -159,6 +161,8 @@ public: void popup_project_settings(); void set_plugins_page(); + TabContainer *get_tabs(); + void queue_save(); ProjectSettingsEditor(EditorData *p_data); diff --git a/editor/quick_open.cpp b/editor/quick_open.cpp index c71cc5af3f..b92ebed167 100644 --- a/editor/quick_open.cpp +++ b/editor/quick_open.cpp @@ -171,33 +171,50 @@ void EditorQuickOpen::_parse_fs(EditorFileSystemDirectory *efsd, Vector<Pair<Str Pair<String, Ref<Texture> > pair; pair.first = file; pair.second = get_icon((has_icon(efsd->get_file_type(i), ei) ? efsd->get_file_type(i) : ot), ei); + list.push_back(pair); + } + } + + if (add_directories) { + for (int i = 0; i < efsd->get_subdir_count(); i++) { - if (search_text != String() && list.size() > 0) { + _parse_fs(efsd->get_subdir(i), list); + } + } +} - float this_sim = _path_cmp(search_text, file); - float other_sim = _path_cmp(list[0].first, file); - int pos = 1; +Vector<Pair<String, Ref<Texture> > > EditorQuickOpen::_sort_fs(Vector<Pair<String, Ref<Texture> > > &list) { - while (pos < list.size() && this_sim <= other_sim) { - other_sim = _path_cmp(list[pos++].first, file); - } + String search_text = search_box->get_text(); + Vector<Pair<String, Ref<Texture> > > sorted_list; - pos = this_sim >= other_sim ? pos - 1 : pos; - list.insert(pos, pair); + if (search_text == String() || list.size() == 0) + return sorted_list; - } else { + Vector<float> scores; + scores.resize(list.size()); + for (int i = 0; i < list.size(); i++) + scores[i] = _path_cmp(search_text, list[i].first); - list.push_back(pair); - } - } - } + while (list.size() > 0) { - if (add_directories) { - for (int i = 0; i < efsd->get_subdir_count(); i++) { + float best_score = 0.0f; + int best_idx = 0; - _parse_fs(efsd->get_subdir(i), list); + for (int i = 0; i < list.size(); i++) { + float current_score = scores[i]; + if (current_score > best_score) { + best_score = current_score; + best_idx = i; + } } + + sorted_list.push_back(list[best_idx]); + list.remove(best_idx); + scores.remove(best_idx); } + + return sorted_list; } void EditorQuickOpen::_update_search() { @@ -208,6 +225,7 @@ void EditorQuickOpen::_update_search() { Vector<Pair<String, Ref<Texture> > > list; _parse_fs(efsd, list); + list = _sort_fs(list); for (int i = 0; i < list.size(); i++) { TreeItem *ti = search_options->create_item(root); diff --git a/editor/quick_open.h b/editor/quick_open.h index 3f64dd8cf0..5b91965920 100644 --- a/editor/quick_open.h +++ b/editor/quick_open.h @@ -49,6 +49,7 @@ class EditorQuickOpen : public ConfirmationDialog { void _sbox_input(const Ref<InputEvent> &p_ie); void _parse_fs(EditorFileSystemDirectory *efsd, Vector<Pair<String, Ref<Texture> > > &list); + Vector<Pair<String, Ref<Texture> > > _sort_fs(Vector<Pair<String, Ref<Texture> > > &list); float _path_cmp(String search, String path) const; void _confirmed(); diff --git a/editor/settings_config_dialog.cpp b/editor/settings_config_dialog.cpp index 623e458aca..05e3feedb5 100644 --- a/editor/settings_config_dialog.cpp +++ b/editor/settings_config_dialog.cpp @@ -165,7 +165,7 @@ void EditorSettingsDialog::_update_shortcuts() { section->set_custom_bg_color(1, get_color("prop_subsection", "Editor")); } - if (shortcut_filter.is_subsequence_ofi(sc->get_name())) { + if (shortcut_filter.is_subsequence_ofi(sc->get_name()) || shortcut_filter.is_subsequence_ofi(sc->get_as_text())) { TreeItem *item = shortcuts->create_item(section); item->set_text(0, sc->get_name()); |