diff options
-rw-r--r-- | core/input/input.cpp | 5 | ||||
-rw-r--r-- | doc/classes/Control.xml | 12 | ||||
-rwxr-xr-x | doc/tools/makerst.py | 3 | ||||
-rw-r--r-- | editor/code_editor.cpp | 39 | ||||
-rw-r--r-- | editor/code_editor.h | 1 | ||||
-rw-r--r-- | editor/editor_themes.cpp | 31 | ||||
-rw-r--r-- | editor/plugins/script_text_editor.cpp | 15 | ||||
-rw-r--r-- | modules/gdscript/gdscript_editor.cpp | 26 | ||||
-rw-r--r-- | modules/gdscript/language_server/gdscript_text_document.cpp | 4 | ||||
-rw-r--r-- | scene/animation/animation_player.cpp | 6 | ||||
-rw-r--r-- | scene/gui/code_edit.cpp | 31 | ||||
-rw-r--r-- | scene/gui/control.cpp | 50 | ||||
-rw-r--r-- | scene/gui/control.h | 5 | ||||
-rw-r--r-- | scene/gui/text_edit.cpp | 59 | ||||
-rw-r--r-- | scene/gui/text_edit.h | 2 | ||||
-rw-r--r-- | scene/main/node.cpp | 4 | ||||
-rw-r--r-- | scene/resources/material.cpp | 4 |
17 files changed, 195 insertions, 102 deletions
diff --git a/core/input/input.cpp b/core/input/input.cpp index 8ba8b892ac..72563cc40a 100644 --- a/core/input/input.cpp +++ b/core/input/input.cpp @@ -163,8 +163,7 @@ void Input::_bind_methods() { void Input::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const { #ifdef TOOLS_ENABLED - - const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", 0) ? "'" : "\""; + const String quote_style = EDITOR_GET("text_editor/completion/use_single_quotes") ? "'" : "\""; String pf = p_function; if (p_idx == 0 && (pf == "is_action_pressed" || pf == "action_press" || pf == "action_release" || @@ -180,7 +179,7 @@ void Input::get_argument_options(const StringName &p_function, int p_idx, List<S } String name = pi.name.substr(pi.name.find("/") + 1, pi.name.length()); - r_options->push_back(quote_style + name + quote_style); + r_options->push_back(name.quote(quote_style)); } } #endif diff --git a/doc/classes/Control.xml b/doc/classes/Control.xml index 43e3c97bff..0834521c91 100644 --- a/doc/classes/Control.xml +++ b/doc/classes/Control.xml @@ -306,6 +306,18 @@ [/codeblocks] </description> </method> + <method name="begin_bulk_theme_override"> + <return type="void" /> + <description> + Prevents [code]*_theme_*_override[/code] methods from emitting [constant NOTIFICATION_THEME_CHANGED] until [method end_bulk_theme_override] is called. + </description> + </method> + <method name="end_bulk_theme_override"> + <return type="void" /> + <description> + Ends a bulk theme override update. See [method begin_bulk_theme_override]. + </description> + </method> <method name="find_next_valid_focus" qualifiers="const"> <return type="Control" /> <description> diff --git a/doc/tools/makerst.py b/doc/tools/makerst.py index 770419a37c..6f9a07af1f 100755 --- a/doc/tools/makerst.py +++ b/doc/tools/makerst.py @@ -479,7 +479,7 @@ def make_rst_class(class_def, state, dry_run, output_dir): # type: (ClassDef, S format_table(f, ml) # Theme properties - if class_def.theme_items is not None and len(class_def.theme_items) > 0: + if len(class_def.theme_items) > 0: f.write(make_heading("Theme Properties", "-")) pl = [] for theme_item_def in class_def.theme_items.values(): @@ -601,6 +601,7 @@ def make_rst_class(class_def, state, dry_run, output_dir): # type: (ClassDef, S index += 1 + # Theme property descriptions if len(class_def.theme_items) > 0: f.write(make_heading("Theme Property Descriptions", "-")) index = 0 diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp index 4a3be1d29c..a5943c952b 100644 --- a/editor/code_editor.cpp +++ b/editor/code_editor.cpp @@ -1520,40 +1520,12 @@ void CodeTextEditor::goto_error() { } void CodeTextEditor::_update_text_editor_theme() { - text_editor->add_theme_color_override("background_color", EDITOR_GET("text_editor/highlighting/background_color")); - text_editor->add_theme_color_override("completion_background_color", EDITOR_GET("text_editor/highlighting/completion_background_color")); - text_editor->add_theme_color_override("completion_selected_color", EDITOR_GET("text_editor/highlighting/completion_selected_color")); - text_editor->add_theme_color_override("completion_existing_color", EDITOR_GET("text_editor/highlighting/completion_existing_color")); - text_editor->add_theme_color_override("completion_scroll_color", EDITOR_GET("text_editor/highlighting/completion_scroll_color")); - text_editor->add_theme_color_override("completion_font_color", EDITOR_GET("text_editor/highlighting/completion_font_color")); - text_editor->add_theme_color_override("font_color", EDITOR_GET("text_editor/highlighting/text_color")); - text_editor->add_theme_color_override("line_number_color", EDITOR_GET("text_editor/highlighting/line_number_color")); - text_editor->add_theme_color_override("caret_color", EDITOR_GET("text_editor/highlighting/caret_color")); - text_editor->add_theme_color_override("caret_background_color", EDITOR_GET("text_editor/highlighting/caret_background_color")); - text_editor->add_theme_color_override("font_selected_color", EDITOR_GET("text_editor/highlighting/text_selected_color")); - text_editor->add_theme_color_override("selection_color", EDITOR_GET("text_editor/highlighting/selection_color")); - text_editor->add_theme_color_override("brace_mismatch_color", EDITOR_GET("text_editor/highlighting/brace_mismatch_color")); - text_editor->add_theme_color_override("current_line_color", EDITOR_GET("text_editor/highlighting/current_line_color")); - text_editor->add_theme_color_override("line_length_guideline_color", EDITOR_GET("text_editor/highlighting/line_length_guideline_color")); - text_editor->add_theme_color_override("word_highlighted_color", EDITOR_GET("text_editor/highlighting/word_highlighted_color")); - text_editor->add_theme_color_override("bookmark_color", EDITOR_GET("text_editor/highlighting/bookmark_color")); - text_editor->add_theme_color_override("breakpoint_color", EDITOR_GET("text_editor/highlighting/breakpoint_color")); - text_editor->add_theme_color_override("executing_line_color", EDITOR_GET("text_editor/highlighting/executing_line_color")); - text_editor->add_theme_color_override("code_folding_color", EDITOR_GET("text_editor/highlighting/code_folding_color")); - text_editor->add_theme_color_override("search_result_color", EDITOR_GET("text_editor/highlighting/search_result_color")); - text_editor->add_theme_color_override("search_result_border_color", EDITOR_GET("text_editor/highlighting/search_result_border_color")); - text_editor->add_theme_constant_override("line_spacing", EDITOR_DEF("text_editor/theme/line_spacing", 6)); emit_signal(SNAME("load_theme_settings")); - _load_theme_settings(); -} - -void CodeTextEditor::_update_font() { - text_editor->add_theme_font_override("font", get_theme_font(SNAME("source"), SNAME("EditorFonts"))); - text_editor->add_theme_font_size_override("font_size", get_theme_font_size(SNAME("source_size"), SNAME("EditorFonts"))); - error->add_theme_font_override("font", get_theme_font(SNAME("status_source"), SNAME("EditorFonts"))); - error->add_theme_font_size_override("font_size", get_theme_font_size(SNAME("status_source_size"), SNAME("EditorFonts"))); - error->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), SNAME("Editor"))); + error->begin_bulk_theme_override(); + error->add_theme_font_override(SNAME("font"), get_theme_font(SNAME("status_source"), SNAME("EditorFonts"))); + error->add_theme_font_size_override(SNAME("font_size"), get_theme_font_size(SNAME("status_source_size"), SNAME("EditorFonts"))); + error->add_theme_color_override(SNAME("font_color"), get_theme_color(SNAME("error_color"), SNAME("Editor"))); Ref<Font> status_bar_font = get_theme_font(SNAME("status_source"), SNAME("EditorFonts")); int status_bar_font_size = get_theme_font_size(SNAME("status_source_size"), SNAME("EditorFonts")); @@ -1567,6 +1539,7 @@ void CodeTextEditor::_update_font() { n->add_theme_font_size_override("font_size", status_bar_font_size); } } + error->end_bulk_theme_override(); } void CodeTextEditor::_on_settings_change() { @@ -1582,7 +1555,6 @@ void CodeTextEditor::_apply_settings_change() { settings_changed = false; _update_text_editor_theme(); - _update_font(); font_size = EditorSettings::get_singleton()->get("interface/editor/code_font_size"); @@ -1668,7 +1640,6 @@ void CodeTextEditor::_notification(int p_what) { update_toggle_scripts_button(); } _update_text_editor_theme(); - _update_font(); } break; case NOTIFICATION_ENTER_TREE: { error_button->set_icon(get_theme_icon(SNAME("StatusError"), SNAME("EditorIcons"))); diff --git a/editor/code_editor.h b/editor/code_editor.h index 4cd4880df0..ee8f4366dd 100644 --- a/editor/code_editor.h +++ b/editor/code_editor.h @@ -168,7 +168,6 @@ class CodeTextEditor : public VBoxContainer { void _apply_settings_change(); void _update_text_editor_theme(); - void _update_font(); void _complete_request(); Ref<Texture2D> _get_completion_icon(const ScriptCodeCompletionOption &p_option); void _font_resize_timeout(); diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp index fe6c081922..e93c8a1a05 100644 --- a/editor/editor_themes.cpp +++ b/editor/editor_themes.cpp @@ -1051,19 +1051,17 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_constant("line_spacing", "TextEdit", 4 * EDSCALE); // CodeEdit + theme->set_font("font", "CodeEdit", theme->get_font("source", "EditorFonts")); + theme->set_font_size("font_size", "CodeEdit", theme->get_font_size("source_size", "EditorFonts")); theme->set_stylebox("normal", "CodeEdit", style_widget); theme->set_stylebox("focus", "CodeEdit", style_widget_hover); theme->set_stylebox("read_only", "CodeEdit", style_widget_disabled); - theme->set_constant("side_margin", "TabContainer", 0); theme->set_icon("tab", "CodeEdit", theme->get_icon("GuiTab", "EditorIcons")); theme->set_icon("space", "CodeEdit", theme->get_icon("GuiSpace", "EditorIcons")); theme->set_icon("folded", "CodeEdit", theme->get_icon("GuiTreeArrowRight", "EditorIcons")); theme->set_icon("can_fold", "CodeEdit", theme->get_icon("GuiTreeArrowDown", "EditorIcons")); theme->set_icon("executing_line", "CodeEdit", theme->get_icon("MainPlay", "EditorIcons")); - theme->set_color("font_color", "CodeEdit", font_color); - theme->set_color("caret_color", "CodeEdit", font_color); - theme->set_color("selection_color", "CodeEdit", selection_color); - theme->set_constant("line_spacing", "CodeEdit", 4 * EDSCALE); + theme->set_constant("line_spacing", "CodeEdit", EDITOR_DEF("text_editor/theme/line_spacing", 6)); // H/VSplitContainer theme->set_stylebox("bg", "VSplitContainer", make_stylebox(theme->get_icon("GuiVsplitBg", "EditorIcons"), 1, 1, 1, 1)); @@ -1474,6 +1472,29 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { setting->load_text_editor_theme(); } + // Now theme is loaded, apply it to CodeEdit. + theme->set_color("background_color", "CodeEdit", EDITOR_GET("text_editor/highlighting/background_color")); + theme->set_color("completion_background_color", "CodeEdit", EDITOR_GET("text_editor/highlighting/completion_background_color")); + theme->set_color("completion_selected_color", "CodeEdit", EDITOR_GET("text_editor/highlighting/completion_selected_color")); + theme->set_color("completion_existing_color", "CodeEdit", EDITOR_GET("text_editor/highlighting/completion_existing_color")); + theme->set_color("completion_scroll_color", "CodeEdit", EDITOR_GET("text_editor/highlighting/completion_scroll_color")); + theme->set_color("completion_font_color", "CodeEdit", EDITOR_GET("text_editor/highlighting/completion_font_color")); + theme->set_color("font_color", "CodeEdit", EDITOR_GET("text_editor/highlighting/text_color")); + theme->set_color("line_number_color", "CodeEdit", EDITOR_GET("text_editor/highlighting/line_number_color")); + theme->set_color("caret_color", "CodeEdit", EDITOR_GET("text_editor/highlighting/caret_color")); + theme->set_color("font_selected_color", "CodeEdit", EDITOR_GET("text_editor/highlighting/text_selected_color")); + theme->set_color("selection_color", "CodeEdit", EDITOR_GET("text_editor/highlighting/selection_color")); + theme->set_color("brace_mismatch_color", "CodeEdit", EDITOR_GET("text_editor/highlighting/brace_mismatch_color")); + theme->set_color("current_line_color", "CodeEdit", EDITOR_GET("text_editor/highlighting/current_line_color")); + theme->set_color("line_length_guideline_color", "CodeEdit", EDITOR_GET("text_editor/highlighting/line_length_guideline_color")); + theme->set_color("word_highlighted_color", "CodeEdit", EDITOR_GET("text_editor/highlighting/word_highlighted_color")); + theme->set_color("bookmark_color", "CodeEdit", EDITOR_GET("text_editor/highlighting/bookmark_color")); + theme->set_color("breakpoint_color", "CodeEdit", EDITOR_GET("text_editor/highlighting/breakpoint_color")); + theme->set_color("executing_line_color", "CodeEdit", EDITOR_GET("text_editor/highlighting/executing_line_color")); + theme->set_color("code_folding_color", "CodeEdit", EDITOR_GET("text_editor/highlighting/code_folding_color")); + theme->set_color("search_result_color", "CodeEdit", EDITOR_GET("text_editor/highlighting/search_result_color")); + theme->set_color("search_result_border_color", "CodeEdit", EDITOR_GET("text_editor/highlighting/search_result_border_color")); + return theme; } diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp index 8cd746304c..1d7592d2c3 100644 --- a/editor/plugins/script_text_editor.cpp +++ b/editor/plugins/script_text_editor.cpp @@ -1390,6 +1390,7 @@ bool ScriptTextEditor::can_drop_data_fw(const Point2 &p_point, const Variant &p_ if (d.has("type") && (String(d["type"]) == "resource" || String(d["type"]) == "files" || String(d["type"]) == "nodes" || + String(d["type"]) == "obj_property" || String(d["type"]) == "files_and_dirs")) { return true; } @@ -1419,10 +1420,11 @@ static Node *_find_script_node(Node *p_edited_scene, Node *p_current_node, const } void ScriptTextEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) { + const String quote_style = EDITOR_GET("text_editor/completion/use_single_quotes") ? "'" : "\""; + Dictionary d = p_data; CodeEdit *te = code_editor->get_text_editor(); - Point2i pos = te->get_line_column_at_pos(p_point); int row = pos.y; int col = pos.x; @@ -1444,7 +1446,6 @@ void ScriptTextEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data } if (d.has("type") && (String(d["type"]) == "files" || String(d["type"]) == "files_and_dirs")) { - const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", false) ? "'" : "\""; Array files = d["files"]; String text_to_drop; @@ -1488,13 +1489,21 @@ void ScriptTextEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data } String path = sn->get_path_to(node); - text_to_drop += "\"" + path.c_escape() + "\""; + text_to_drop += path.c_escape().quote(quote_style); } te->set_caret_line(row); te->set_caret_column(col); te->insert_text_at_caret(text_to_drop); } + + if (d.has("type") && String(d["type"]) == "obj_property") { + const String text_to_drop = String(d["property"]).c_escape().quote(quote_style); + + te->set_caret_line(row); + te->set_caret_column(col); + te->insert_text_at_caret(text_to_drop); + } } void ScriptTextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) { diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp index 2e570d5a5b..1c6f23f454 100644 --- a/modules/gdscript/gdscript_editor.cpp +++ b/modules/gdscript/gdscript_editor.cpp @@ -623,11 +623,11 @@ static String _make_arguments_hint(const GDScriptParser::FunctionNode *p_functio } static void _get_directory_contents(EditorFileSystemDirectory *p_dir, Map<String, ScriptCodeCompletionOption> &r_list) { - const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", false) ? "'" : "\""; + const String quote_style = EDITOR_GET("text_editor/completion/use_single_quotes") ? "'" : "\""; for (int i = 0; i < p_dir->get_file_count(); i++) { ScriptCodeCompletionOption option(p_dir->get_file_path(i), ScriptCodeCompletionOption::KIND_FILE_PATH); - option.insert_text = quote_style + option.display + quote_style; + option.insert_text = option.display.quote(quote_style); r_list.insert(option.display, option); } @@ -641,20 +641,20 @@ static void _find_annotation_arguments(const GDScriptParser::AnnotationNode *p_a if (p_argument == 3 || p_argument == 4) { // Slider hint. ScriptCodeCompletionOption slider1("or_greater", ScriptCodeCompletionOption::KIND_PLAIN_TEXT); - slider1.insert_text = p_quote_style + slider1.display + p_quote_style; + slider1.insert_text = slider1.display.quote(p_quote_style); r_result.insert(slider1.display, slider1); ScriptCodeCompletionOption slider2("or_lesser", ScriptCodeCompletionOption::KIND_PLAIN_TEXT); - slider2.insert_text = p_quote_style + slider2.display + p_quote_style; + slider2.insert_text = slider2.display.quote(p_quote_style); r_result.insert(slider2.display, slider2); } } else if (p_annotation->name == "@export_exp_easing") { if (p_argument == 0 || p_argument == 1) { // Easing hint. ScriptCodeCompletionOption hint1("attenuation", ScriptCodeCompletionOption::KIND_PLAIN_TEXT); - hint1.insert_text = p_quote_style + hint1.display + p_quote_style; + hint1.insert_text = hint1.display.quote(p_quote_style); r_result.insert(hint1.display, hint1); ScriptCodeCompletionOption hint2("inout", ScriptCodeCompletionOption::KIND_PLAIN_TEXT); - hint2.insert_text = p_quote_style + hint2.display + p_quote_style; + hint2.insert_text = hint2.display.quote(p_quote_style); r_result.insert(hint2.display, hint2); } } else if (p_annotation->name == "@export_node_path") { @@ -2192,7 +2192,7 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c Variant base = p_base.value; GDScriptParser::DataType base_type = p_base.type; - const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", false) ? "'" : "\""; + const String quote_style = EDITOR_GET("text_editor/completion/use_single_quotes") ? "'" : "\""; while (base_type.is_set() && !base_type.is_variant()) { switch (base_type.kind) { @@ -2254,7 +2254,7 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c } String name = s.get_slice("/", 1); ScriptCodeCompletionOption option("/root/" + name, ScriptCodeCompletionOption::KIND_NODE_PATH); - option.insert_text = quote_style + option.display + quote_style; + option.insert_text = option.display.quote(quote_style); r_result.insert(option.display, option); } } @@ -2270,7 +2270,7 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c } String name = s.get_slice("/", 1); ScriptCodeCompletionOption option(name, ScriptCodeCompletionOption::KIND_CONSTANT); - option.insert_text = quote_style + option.display + quote_style; + option.insert_text = option.display.quote(quote_style); r_result.insert(option.display, option); } } @@ -2305,8 +2305,6 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c } static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, const GDScriptParser::Node *p_call, int p_argidx, Map<String, ScriptCodeCompletionOption> &r_result, bool &r_forced, String &r_arghint) { - const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", false) ? "'" : "\""; - if (p_call->type == GDScriptParser::Node::PRELOAD) { if (p_argidx == 0 && bool(EditorSettings::get_singleton()->get("text_editor/completion/complete_file_paths"))) { _get_directory_contents(EditorFileSystem::get_singleton()->get_filesystem(), r_result); @@ -2382,7 +2380,7 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c } ::Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path, Object *p_owner, List<ScriptCodeCompletionOption> *r_options, bool &r_forced, String &r_call_hint) { - const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", false) ? "'" : "\""; + const String quote_style = EDITOR_GET("text_editor/completion/use_single_quotes") ? "'" : "\""; GDScriptParser parser; GDScriptAnalyzer analyzer(&parser); @@ -2671,8 +2669,8 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c Map<StringName, ProjectSettings::AutoloadInfo> autoloads = ProjectSettings::get_singleton()->get_autoload_list(); for (Map<StringName, ProjectSettings::AutoloadInfo>::Element *E = autoloads.front(); E; E = E->next()) { - String name = E->key(); - ScriptCodeCompletionOption option(quote_style + "/root/" + name + quote_style, ScriptCodeCompletionOption::KIND_NODE_PATH); + String path = "/root/" + E->key(); + ScriptCodeCompletionOption option(path.quote(quote_style), ScriptCodeCompletionOption::KIND_NODE_PATH); options.insert(option.display, option); } } diff --git a/modules/gdscript/language_server/gdscript_text_document.cpp b/modules/gdscript/language_server/gdscript_text_document.cpp index 9574c765bc..03b1e3fa44 100644 --- a/modules/gdscript/language_server/gdscript_text_document.cpp +++ b/modules/gdscript/language_server/gdscript_text_document.cpp @@ -291,8 +291,8 @@ Dictionary GDScriptTextDocument::resolve(const Dictionary &p_params) { } } else if (item.kind == lsp::CompletionItemKind::Event) { if (params.context.triggerKind == lsp::CompletionTriggerKind::TriggerCharacter && (params.context.triggerCharacter == "(")) { - const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", false) ? "'" : "\""; - item.insertText = quote_style + item.label + quote_style; + const String quote_style = EDITOR_GET("text_editor/completion/use_single_quotes") ? "'" : "\""; + item.insertText = item.label.quote(quote_style); } } diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp index 5d200ebf86..f6091f224c 100644 --- a/scene/animation/animation_player.cpp +++ b/scene/animation/animation_player.cpp @@ -1493,7 +1493,7 @@ NodePath AnimationPlayer::get_root() const { void AnimationPlayer::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const { #ifdef TOOLS_ENABLED - const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", 0) ? "'" : "\""; + const String quote_style = EDITOR_GET("text_editor/completion/use_single_quotes") ? "'" : "\""; #else const String quote_style = "\""; #endif @@ -1502,8 +1502,8 @@ void AnimationPlayer::get_argument_options(const StringName &p_function, int p_i if (p_idx == 0 && (p_function == "play" || p_function == "play_backwards" || p_function == "remove_animation" || p_function == "has_animation" || p_function == "queue")) { List<StringName> al; get_animation_list(&al); - for (const StringName &E : al) { - r_options->push_back(quote_style + String(E) + quote_style); + for (const StringName &name : al) { + r_options->push_back(String(name).quote(quote_style)); } } Node::get_argument_options(p_function, p_idx, r_options); diff --git a/scene/gui/code_edit.cpp b/scene/gui/code_edit.cpp index 503f9ffd4a..08dd7f28eb 100644 --- a/scene/gui/code_edit.cpp +++ b/scene/gui/code_edit.cpp @@ -72,7 +72,7 @@ void CodeEdit::_notification(int p_what) { can_fold_icon = get_theme_icon(SNAME("can_fold")); folded_icon = get_theme_icon(SNAME("folded")); - code_completion_max_width = get_theme_constant(SNAME("completion_max_width")) * font->get_char_size('x').x; + code_completion_max_width = get_theme_constant(SNAME("completion_max_width")); code_completion_max_lines = get_theme_constant(SNAME("completion_lines")); code_completion_scroll_width = get_theme_constant(SNAME("completion_scroll_width")); code_completion_scroll_color = get_theme_color(SNAME("completion_scroll_color")); @@ -2652,6 +2652,8 @@ TypedArray<String> CodeEdit::_get_delimiters(DelimiterType p_type) const { /* Code Completion */ void CodeEdit::_filter_code_completion_candidates() { ScriptInstance *si = get_script_instance(); + int line_height = get_line_height(); + if (si && si->has_method("_filter_code_completion_candidates")) { code_completion_options.clear(); code_completion_base = ""; @@ -2691,11 +2693,16 @@ void CodeEdit::_filter_code_completion_candidates() { option.icon = completion_options[i].get("icon"); option.default_value = completion_options[i].get("default_value"); - max_width = MAX(max_width, font->get_string_size(option.display).width); + int offset = 0; + if (option.default_value.get_type() == Variant::COLOR) { + offset = line_height; + } + + max_width = MAX(max_width, font->get_string_size(option.display, font_size).width + offset); code_completion_options.push_back(option); } - code_completion_longest_line = MIN(max_width, code_completion_max_width); + code_completion_longest_line = MIN(max_width, code_completion_max_width * font_size); code_completion_current_selected = 0; code_completion_active = true; update(); @@ -2783,6 +2790,11 @@ void CodeEdit::_filter_code_completion_candidates() { option.display = option.display.unquote().quote("'"); } + int offset = 0; + if (option.default_value.get_type() == Variant::COLOR) { + offset = line_height; + } + if (in_string != -1) { String quote = single_quote ? "'" : "\""; option.display = option.display.unquote().quote(quote); @@ -2795,7 +2807,7 @@ void CodeEdit::_filter_code_completion_candidates() { if (string_to_complete.length() == 0) { code_completion_options.push_back(option); - max_width = MAX(max_width, font->get_string_size(option.display).width); + max_width = MAX(max_width, font->get_string_size(option.display, font_size).width + offset); continue; } @@ -2844,7 +2856,7 @@ void CodeEdit::_filter_code_completion_candidates() { } else { completion_options_subseq.push_back(option); } - max_width = MAX(max_width, font->get_string_size(option.display).width); + max_width = MAX(max_width, font->get_string_size(option.display, font_size).width + offset); /* Matched the whole subsequence in s_lower. */ } else if (!*ssq_lower) { /* Finished matching in the first s.length() characters. */ @@ -2853,7 +2865,7 @@ void CodeEdit::_filter_code_completion_candidates() { } else { completion_options_subseq_casei.push_back(option); } - max_width = MAX(max_width, font->get_string_size(option.display).width); + max_width = MAX(max_width, font->get_string_size(option.display, font_size).width + offset); } } @@ -2873,7 +2885,7 @@ void CodeEdit::_filter_code_completion_candidates() { return; } - code_completion_longest_line = MIN(max_width, code_completion_max_width); + code_completion_longest_line = MIN(max_width, code_completion_max_width * font_size); code_completion_current_selected = 0; code_completion_active = true; update(); @@ -2906,7 +2918,10 @@ void CodeEdit::_text_changed() { while (lc /= 10) { line_number_digits++; } - set_gutter_width(line_number_gutter, (line_number_digits + 1) * font->get_char_size('0', 0, font_size).width); + + if (font.is_valid()) { + set_gutter_width(line_number_gutter, (line_number_digits + 1) * font->get_char_size('0', 0, font_size).width); + } lc = get_line_count(); int line_change_size = (lines_edited_to - lines_edited_from); diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index a2e6872da6..f114e06c75 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -1686,6 +1686,17 @@ Rect2 Control::get_anchorable_rect() const { return Rect2(Point2(), get_size()); } +void Control::begin_bulk_theme_override() { + data.bulk_theme_override = true; +} + +void Control::end_bulk_theme_override() { + ERR_FAIL_COND(!data.bulk_theme_override); + + data.bulk_theme_override = false; + _notify_theme_changed(); +} + void Control::add_theme_icon_override(const StringName &p_name, const Ref<Texture2D> &p_icon) { ERR_FAIL_COND(!p_icon.is_valid()); @@ -1695,7 +1706,7 @@ void Control::add_theme_icon_override(const StringName &p_name, const Ref<Textur data.icon_override[p_name] = p_icon; data.icon_override[p_name]->connect("changed", callable_mp(this, &Control::_override_changed), Vector<Variant>(), CONNECT_REFERENCE_COUNTED); - notification(NOTIFICATION_THEME_CHANGED); + _notify_theme_changed(); } void Control::add_theme_style_override(const StringName &p_name, const Ref<StyleBox> &p_style) { @@ -1707,7 +1718,7 @@ void Control::add_theme_style_override(const StringName &p_name, const Ref<Style data.style_override[p_name] = p_style; data.style_override[p_name]->connect("changed", callable_mp(this, &Control::_override_changed), Vector<Variant>(), CONNECT_REFERENCE_COUNTED); - notification(NOTIFICATION_THEME_CHANGED); + _notify_theme_changed(); } void Control::add_theme_font_override(const StringName &p_name, const Ref<Font> &p_font) { @@ -1719,22 +1730,22 @@ void Control::add_theme_font_override(const StringName &p_name, const Ref<Font> data.font_override[p_name] = p_font; data.font_override[p_name]->connect("changed", callable_mp(this, &Control::_override_changed), Vector<Variant>(), CONNECT_REFERENCE_COUNTED); - notification(NOTIFICATION_THEME_CHANGED); + _notify_theme_changed(); } void Control::add_theme_font_size_override(const StringName &p_name, int p_font_size) { data.font_size_override[p_name] = p_font_size; - notification(NOTIFICATION_THEME_CHANGED); + _notify_theme_changed(); } void Control::add_theme_color_override(const StringName &p_name, const Color &p_color) { data.color_override[p_name] = p_color; - notification(NOTIFICATION_THEME_CHANGED); + _notify_theme_changed(); } void Control::add_theme_constant_override(const StringName &p_name, int p_constant) { data.constant_override[p_name] = p_constant; - notification(NOTIFICATION_THEME_CHANGED); + _notify_theme_changed(); } void Control::remove_theme_icon_override(const StringName &p_name) { @@ -1743,7 +1754,7 @@ void Control::remove_theme_icon_override(const StringName &p_name) { } data.icon_override.erase(p_name); - notification(NOTIFICATION_THEME_CHANGED); + _notify_theme_changed(); } void Control::remove_theme_style_override(const StringName &p_name) { @@ -1752,7 +1763,7 @@ void Control::remove_theme_style_override(const StringName &p_name) { } data.style_override.erase(p_name); - notification(NOTIFICATION_THEME_CHANGED); + _notify_theme_changed(); } void Control::remove_theme_font_override(const StringName &p_name) { @@ -1761,22 +1772,22 @@ void Control::remove_theme_font_override(const StringName &p_name) { } data.font_override.erase(p_name); - notification(NOTIFICATION_THEME_CHANGED); + _notify_theme_changed(); } void Control::remove_theme_font_size_override(const StringName &p_name) { data.font_size_override.erase(p_name); - notification(NOTIFICATION_THEME_CHANGED); + _notify_theme_changed(); } void Control::remove_theme_color_override(const StringName &p_name) { data.color_override.erase(p_name); - notification(NOTIFICATION_THEME_CHANGED); + _notify_theme_changed(); } void Control::remove_theme_constant_override(const StringName &p_name) { data.constant_override.erase(p_name); - notification(NOTIFICATION_THEME_CHANGED); + _notify_theme_changed(); } void Control::set_focus_mode(FocusMode p_focus_mode) { @@ -2049,6 +2060,12 @@ void Control::_theme_changed() { _propagate_theme_changed(this, this, nullptr, false); } +void Control::_notify_theme_changed() { + if (!data.bulk_theme_override) { + notification(NOTIFICATION_THEME_CHANGED); + } +} + void Control::set_theme(const Ref<Theme> &p_theme) { if (data.theme == p_theme) { return; @@ -2585,7 +2602,7 @@ bool Control::is_visibility_clip_disabled() const { void Control::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const { #ifdef TOOLS_ENABLED - const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", 0) ? "'" : "\""; + const String quote_style = EDITOR_GET("text_editor/completion/use_single_quotes") ? "'" : "\""; #else const String quote_style = "\""; #endif @@ -2608,8 +2625,8 @@ void Control::get_argument_options(const StringName &p_function, int p_idx, List } sn.sort_custom<StringName::AlphCompare>(); - for (const StringName &E : sn) { - r_options->push_back(quote_style + E + quote_style); + for (const StringName &name : sn) { + r_options->push_back(String(name).quote(quote_style)); } } } @@ -2719,6 +2736,9 @@ void Control::_bind_methods() { ClassDB::bind_method(D_METHOD("set_theme_type_variation", "theme_type"), &Control::set_theme_type_variation); ClassDB::bind_method(D_METHOD("get_theme_type_variation"), &Control::get_theme_type_variation); + ClassDB::bind_method(D_METHOD("begin_bulk_theme_override"), &Control::begin_bulk_theme_override); + ClassDB::bind_method(D_METHOD("end_bulk_theme_override"), &Control::end_bulk_theme_override); + ClassDB::bind_method(D_METHOD("add_theme_icon_override", "name", "texture"), &Control::add_theme_icon_override); ClassDB::bind_method(D_METHOD("add_theme_stylebox_override", "name", "stylebox"), &Control::add_theme_style_override); ClassDB::bind_method(D_METHOD("add_theme_font_override", "name", "font"), &Control::add_theme_font_override); diff --git a/scene/gui/control.h b/scene/gui/control.h index 8d669c7a6d..a871a8e9fb 100644 --- a/scene/gui/control.h +++ b/scene/gui/control.h @@ -220,6 +220,7 @@ private: NodePath focus_next; NodePath focus_prev; + bool bulk_theme_override = false; HashMap<StringName, Ref<Texture2D>> icon_override; HashMap<StringName, Ref<StyleBox>> style_override; HashMap<StringName, Ref<Font>> font_override; @@ -241,6 +242,7 @@ private: void _set_size(const Size2 &p_size); void _theme_changed(); + void _notify_theme_changed(); void _update_minimum_size(); @@ -452,6 +454,9 @@ public: /* SKINNING */ + void begin_bulk_theme_override(); + void end_bulk_theme_override(); + void add_theme_icon_override(const StringName &p_name, const Ref<Texture2D> &p_icon); void add_theme_style_override(const StringName &p_name, const Ref<StyleBox> &p_style); void add_theme_font_override(const StringName &p_name, const Ref<Font> &p_font); diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 443eb68bc5..745920fcdd 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -62,11 +62,19 @@ static bool _is_char(char32_t c) { /////////////////////////////////////////////////////////////////////////////// void TextEdit::Text::set_font(const Ref<Font> &p_font) { + if (font == p_font) { + return; + } font = p_font; + is_dirty = true; } void TextEdit::Text::set_font_size(int p_font_size) { + if (font_size == p_font_size) { + return; + } font_size = p_font_size; + is_dirty = true; } void TextEdit::Text::set_tab_size(int p_tab_size) { @@ -78,16 +86,28 @@ int TextEdit::Text::get_tab_size() const { } void TextEdit::Text::set_font_features(const Dictionary &p_features) { + if (opentype_features.hash() == p_features.hash()) { + return; + } opentype_features = p_features; + is_dirty = true; } void TextEdit::Text::set_direction_and_language(TextServer::Direction p_direction, const String &p_language) { + if (direction == p_direction && language == p_language) { + return; + } direction = p_direction; language = p_language; + is_dirty = true; } void TextEdit::Text::set_draw_control_chars(bool p_draw_control_chars) { + if (draw_control_chars == p_draw_control_chars) { + return; + } draw_control_chars = p_draw_control_chars; + is_dirty = true; } int TextEdit::Text::get_line_width(int p_line, int p_wrap_index) const { @@ -176,9 +196,14 @@ void TextEdit::Text::invalidate_all_lines() { } void TextEdit::Text::invalidate_all() { + if (!is_dirty) { + return; + } + for (int i = 0; i < text.size(); i++) { invalidate_cache(i); } + is_dirty = false; } void TextEdit::Text::clear() { @@ -1110,20 +1135,37 @@ void TextEdit::_notification(int p_what) { t_caret.size.y = h; } t_caret.position += Vector2(char_margin + ofs_x, ofs_y); + draw_rect(t_caret, caret_color, overtype_mode); - draw_rect(t_caret, caret_color, false); + if (l_caret != Rect2() && l_dir != t_dir) { + l_caret.position += Vector2(char_margin + ofs_x, ofs_y); + l_caret.size.x = caret_width; + draw_rect(l_caret, caret_color * Color(1, 1, 1, 0.5)); + } } else { // End of the line. - if (overtype_mode) { - l_caret.position.y = TS->shaped_text_get_descent(rid); + if (gl_size > 0) { + // Adjust for actual line dimensions. + if (overtype_mode) { + l_caret.position.y = TS->shaped_text_get_descent(rid); + l_caret.size.y = caret_width; + } else { + l_caret.position.y = -TS->shaped_text_get_ascent(rid); + l_caret.size.y = h; + } + } else if (overtype_mode) { + l_caret.position.y += l_caret.size.y; l_caret.size.y = caret_width; + } + if (l_caret.position.x >= TS->shaped_text_get_size(rid).x) { + l_caret.size.x = font->get_char_size('m', 0, font_size).x; } else { - l_caret.position.y = -TS->shaped_text_get_ascent(rid); - l_caret.size.y = h; + l_caret.size.x = 3 * caret_width; } l_caret.position += Vector2(char_margin + ofs_x, ofs_y); - l_caret.size.x = font->get_char_size('M', 0, font_size).x; - - draw_rect(l_caret, caret_color, false); + if (l_dir == TextServer::DIRECTION_RTL) { + l_caret.position.x -= l_caret.size.x; + } + draw_rect(l_caret, caret_color, overtype_mode); } } else { // Normal caret. @@ -4748,7 +4790,6 @@ bool TextEdit::_set(const StringName &p_name, const Variant &p_value) { opentype_features[tag] = value; text.set_font_features(opentype_features); text.invalidate_all(); - ; update(); } } diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h index 5d05e07b5d..da322a7bcd 100644 --- a/scene/gui/text_edit.h +++ b/scene/gui/text_edit.h @@ -151,6 +151,8 @@ private: }; private: + bool is_dirty = false; + mutable Vector<Line> text; Ref<Font> font; int font_size = -1; diff --git a/scene/main/node.cpp b/scene/main/node.cpp index cbd5fa7425..155af30a6d 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -2465,7 +2465,7 @@ NodePath Node::get_import_path() const { static void _add_nodes_to_options(const Node *p_base, const Node *p_node, List<String> *r_options) { #ifdef TOOLS_ENABLED - const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", 0) ? "'" : "\""; + const String quote_style = EDITOR_GET("text_editor/completion/use_single_quotes") ? "'" : "\""; #else const String quote_style = "\""; #endif @@ -2474,7 +2474,7 @@ static void _add_nodes_to_options(const Node *p_base, const Node *p_node, List<S return; } String n = p_base->get_path_to(p_node); - r_options->push_back(quote_style + n + quote_style); + r_options->push_back(n.quote(quote_style)); for (int i = 0; i < p_node->get_child_count(); i++) { _add_nodes_to_options(p_base, p_node->get_child(i), r_options); } diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index 08f7274ff6..896a33e02e 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -268,7 +268,7 @@ void ShaderMaterial::_bind_methods() { void ShaderMaterial::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const { #ifdef TOOLS_ENABLED - const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", 0) ? "'" : "\""; + const String quote_style = EDITOR_GET("text_editor/completion/use_single_quotes") ? "'" : "\""; #else const String quote_style = "\""; #endif @@ -279,7 +279,7 @@ void ShaderMaterial::get_argument_options(const StringName &p_function, int p_id List<PropertyInfo> pl; shader->get_param_list(&pl); for (const PropertyInfo &E : pl) { - r_options->push_back(quote_style + E.name.replace_first("shader_param/", "") + quote_style); + r_options->push_back(E.name.replace_first("shader_param/", "").quote(quote_style)); } } } |