summaryrefslogtreecommitdiff
path: root/editor/code_editor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'editor/code_editor.cpp')
-rw-r--r--editor/code_editor.cpp387
1 files changed, 230 insertions, 157 deletions
diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp
index 7bf82fbd1b..bdd30dc653 100644
--- a/editor/code_editor.cpp
+++ b/editor/code_editor.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,14 +31,11 @@
#include "code_editor.h"
#include "core/input/input.h"
-#include "core/object/message_queue.h"
#include "core/os/keyboard.h"
#include "core/string/string_builder.h"
#include "editor/editor_scale.h"
-#include "editor_node.h"
-#include "editor_settings.h"
-#include "scene/gui/margin_container.h"
-#include "scene/gui/separator.h"
+#include "editor/editor_settings.h"
+#include "editor/plugins/script_editor_plugin.h"
#include "scene/resources/font.h"
void GotoLineDialog::popup_find_line(CodeEdit *p_edit) {
@@ -88,29 +85,31 @@ GotoLineDialog::GotoLineDialog() {
}
void FindReplaceBar::_notification(int p_what) {
- if (p_what == NOTIFICATION_READY) {
- find_prev->set_icon(get_theme_icon(SNAME("MoveUp"), SNAME("EditorIcons")));
- find_next->set_icon(get_theme_icon(SNAME("MoveDown"), SNAME("EditorIcons")));
- hide_button->set_normal_texture(get_theme_icon(SNAME("Close"), SNAME("EditorIcons")));
- hide_button->set_hover_texture(get_theme_icon(SNAME("Close"), SNAME("EditorIcons")));
- hide_button->set_pressed_texture(get_theme_icon(SNAME("Close"), SNAME("EditorIcons")));
- hide_button->set_custom_minimum_size(hide_button->get_normal_texture()->get_size());
- } else if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
- set_process_unhandled_input(is_visible_in_tree());
- } else if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) {
- find_prev->set_icon(get_theme_icon(SNAME("MoveUp"), SNAME("EditorIcons")));
- find_next->set_icon(get_theme_icon(SNAME("MoveDown"), SNAME("EditorIcons")));
- hide_button->set_normal_texture(get_theme_icon(SNAME("Close"), SNAME("EditorIcons")));
- hide_button->set_hover_texture(get_theme_icon(SNAME("Close"), SNAME("EditorIcons")));
- hide_button->set_pressed_texture(get_theme_icon(SNAME("Close"), SNAME("EditorIcons")));
- hide_button->set_custom_minimum_size(hide_button->get_normal_texture()->get_size());
- } else if (p_what == NOTIFICATION_THEME_CHANGED) {
- matches_label->add_theme_color_override("font_color", results_count > 0 ? get_theme_color(SNAME("font_color"), SNAME("Label")) : get_theme_color(SNAME("error_color"), SNAME("Editor")));
- } else if (p_what == NOTIFICATION_PREDELETE) {
- if (base_text_editor) {
- base_text_editor->remove_find_replace_bar();
- base_text_editor = nullptr;
- }
+ switch (p_what) {
+ case NOTIFICATION_READY:
+ case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
+ find_prev->set_icon(get_theme_icon(SNAME("MoveUp"), SNAME("EditorIcons")));
+ find_next->set_icon(get_theme_icon(SNAME("MoveDown"), SNAME("EditorIcons")));
+ hide_button->set_normal_texture(get_theme_icon(SNAME("Close"), SNAME("EditorIcons")));
+ hide_button->set_hover_texture(get_theme_icon(SNAME("Close"), SNAME("EditorIcons")));
+ hide_button->set_pressed_texture(get_theme_icon(SNAME("Close"), SNAME("EditorIcons")));
+ hide_button->set_custom_minimum_size(hide_button->get_normal_texture()->get_size());
+ } break;
+
+ case NOTIFICATION_VISIBILITY_CHANGED: {
+ set_process_unhandled_input(is_visible_in_tree());
+ } break;
+
+ case NOTIFICATION_THEME_CHANGED: {
+ matches_label->add_theme_color_override("font_color", results_count > 0 ? get_theme_color(SNAME("font_color"), SNAME("Label")) : get_theme_color(SNAME("error_color"), SNAME("Editor")));
+ } break;
+
+ case NOTIFICATION_PREDELETE: {
+ if (base_text_editor) {
+ base_text_editor->remove_find_replace_bar();
+ base_text_editor = nullptr;
+ }
+ } break;
}
}
@@ -122,12 +121,12 @@ void FindReplaceBar::unhandled_input(const Ref<InputEvent> &p_event) {
return;
}
- Control *focus_owner = get_focus_owner();
+ Control *focus_owner = get_viewport()->gui_get_focus_owner();
if (text_editor->has_focus() || (focus_owner && vbc_lineedit->is_ancestor_of(focus_owner))) {
bool accepted = true;
switch (k->get_keycode()) {
- case KEY_ESCAPE: {
+ case Key::ESCAPE: {
_hide_bar();
} break;
default: {
@@ -152,6 +151,8 @@ bool FindReplaceBar::_search(uint32_t p_flags, int p_from_line, int p_from_col)
text_editor->set_caret_column(pos.x + text.length(), false);
text_editor->center_viewport_to_caret();
text_editor->select(pos.y, pos.x, pos.y, pos.x + text.length());
+
+ line_col_changed_for_result = true;
}
text_editor->set_search_text(text);
@@ -210,6 +211,8 @@ void FindReplaceBar::_replace() {
}
text_editor->end_complex_operation();
results_count = -1;
+ results_count_to_current = -1;
+ needs_to_count_results = true;
if (selection_enabled && is_selection_only()) {
// Reselect in order to keep 'Replace' restricted to selection
@@ -306,6 +309,8 @@ void FindReplaceBar::_replace_all() {
text_editor->call_deferred(SNAME("connect"), "text_changed", callable_mp(this, &FindReplaceBar::_editor_text_changed));
results_count = -1;
+ results_count_to_current = -1;
+ needs_to_count_results = true;
}
void FindReplaceBar::_get_search_from(int &r_line, int &r_col) {
@@ -322,40 +327,57 @@ void FindReplaceBar::_get_search_from(int &r_line, int &r_col) {
}
void FindReplaceBar::_update_results_count() {
- if (results_count != -1) {
+ if (!needs_to_count_results && (result_line != -1)) {
+ results_count_to_current += (flags & TextEdit::SEARCH_BACKWARDS) ? -1 : 1;
+
+ if (results_count_to_current > results_count) {
+ results_count_to_current = results_count_to_current - results_count;
+ } else if (results_count_to_current <= 0) {
+ results_count_to_current = results_count;
+ }
+
return;
}
results_count = 0;
+ results_count_to_current = 0;
String searched = get_search_text();
if (searched.is_empty()) {
return;
}
- String full_text = text_editor->get_text();
+ needs_to_count_results = false;
- int from_pos = 0;
+ for (int i = 0; i < text_editor->get_line_count(); i++) {
+ String line_text = text_editor->get_line(i);
- while (true) {
- int pos = is_case_sensitive() ? full_text.find(searched, from_pos) : full_text.findn(searched, from_pos);
- if (pos == -1) {
- break;
- }
+ int col_pos = 0;
- int pos_subsequent = pos + searched.length();
- if (is_whole_words()) {
- from_pos = pos + 1; // Making sure we won't hit the same match next time, if we get out via a continue.
- if (pos > 0 && !(is_symbol(full_text[pos - 1]) || full_text[pos - 1] == '\n')) {
- continue;
+ while (true) {
+ col_pos = is_case_sensitive() ? line_text.find(searched, col_pos) : line_text.findn(searched, col_pos);
+
+ if (col_pos == -1) {
+ break;
}
- if (pos_subsequent < full_text.length() && !(is_symbol(full_text[pos_subsequent]) || full_text[pos_subsequent] == '\n')) {
- continue;
+
+ if (is_whole_words()) {
+ if (col_pos > 0 && !is_symbol(line_text[col_pos - 1])) {
+ break;
+ }
+ if (col_pos + line_text.length() < line_text.length() && !is_symbol(line_text[col_pos + searched.length()])) {
+ break;
+ }
}
- }
- results_count++;
- from_pos = pos_subsequent;
+ results_count++;
+
+ if (i == result_line && col_pos == result_col) {
+ results_count_to_current = results_count;
+ }
+
+ col_pos += searched.length();
+ }
}
}
@@ -366,12 +388,19 @@ void FindReplaceBar::_update_matches_label() {
matches_label->show();
matches_label->add_theme_color_override("font_color", results_count > 0 ? get_theme_color(SNAME("font_color"), SNAME("Label")) : get_theme_color(SNAME("error_color"), SNAME("Editor")));
- matches_label->set_text(vformat(results_count == 1 ? TTR("%d match.") : TTR("%d matches."), results_count));
+
+ if (results_count == 0) {
+ matches_label->set_text("No match");
+ } else if (results_count == 1) {
+ matches_label->set_text(vformat(TTR("%d match"), results_count));
+ } else {
+ matches_label->set_text(vformat(TTR("%d of %d matches"), results_count_to_current, results_count));
+ }
}
}
bool FindReplaceBar::search_current() {
- uint32_t flags = 0;
+ flags = 0;
if (is_whole_words()) {
flags |= TextEdit::SEARCH_WHOLE_WORDS;
@@ -391,7 +420,7 @@ bool FindReplaceBar::search_prev() {
popup_search(true);
}
- uint32_t flags = 0;
+ flags = 0;
String text = get_search_text();
if (is_whole_words()) {
@@ -426,7 +455,7 @@ bool FindReplaceBar::search_next() {
popup_search(true);
}
- uint32_t flags = 0;
+ flags = 0;
String text;
if (replace_all_mode) {
text = get_replace_text();
@@ -497,6 +526,8 @@ void FindReplaceBar::_show_search(bool p_focus_replace, bool p_show_only) {
}
results_count = -1;
+ results_count_to_current = -1;
+ needs_to_count_results = true;
_update_results_count();
_update_matches_label();
}
@@ -524,11 +555,15 @@ void FindReplaceBar::popup_replace() {
void FindReplaceBar::_search_options_changed(bool p_pressed) {
results_count = -1;
+ results_count_to_current = -1;
+ needs_to_count_results = true;
search_current();
}
void FindReplaceBar::_editor_text_changed() {
results_count = -1;
+ results_count_to_current = -1;
+ needs_to_count_results = true;
if (is_visible_in_tree()) {
preserve_cursor = true;
search_current();
@@ -538,11 +573,13 @@ void FindReplaceBar::_editor_text_changed() {
void FindReplaceBar::_search_text_changed(const String &p_text) {
results_count = -1;
+ results_count_to_current = -1;
+ needs_to_count_results = true;
search_current();
}
void FindReplaceBar::_search_text_submitted(const String &p_text) {
- if (Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
+ if (Input::get_singleton()->is_key_pressed(Key::SHIFT)) {
search_prev();
} else {
search_next();
@@ -553,7 +590,7 @@ void FindReplaceBar::_replace_text_submitted(const String &p_text) {
if (selection_only->is_pressed() && text_editor->has_selection()) {
_replace_all();
_hide_bar();
- } else if (Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
+ } else if (Input::get_singleton()->is_key_pressed(Key::SHIFT)) {
_replace();
search_prev();
} else {
@@ -602,6 +639,8 @@ void FindReplaceBar::set_text_edit(CodeTextEditor *p_text_editor) {
}
results_count = -1;
+ results_count_to_current = -1;
+ needs_to_count_results = true;
base_text_editor = p_text_editor;
text_editor = base_text_editor->get_text_editor();
text_editor->connect("text_changed", callable_mp(this, &FindReplaceBar::_editor_text_changed));
@@ -618,13 +657,9 @@ void FindReplaceBar::_bind_methods() {
}
FindReplaceBar::FindReplaceBar() {
- results_count = -1;
- replace_all_mode = false;
- preserve_cursor = false;
-
vbc_lineedit = memnew(VBoxContainer);
add_child(vbc_lineedit);
- vbc_lineedit->set_alignment(ALIGN_CENTER);
+ vbc_lineedit->set_alignment(BoxContainer::ALIGNMENT_CENTER);
vbc_lineedit->set_h_size_flags(SIZE_EXPAND_FILL);
VBoxContainer *vbc_button = memnew(VBoxContainer);
add_child(vbc_button);
@@ -633,10 +668,10 @@ FindReplaceBar::FindReplaceBar() {
HBoxContainer *hbc_button_search = memnew(HBoxContainer);
vbc_button->add_child(hbc_button_search);
- hbc_button_search->set_alignment(ALIGN_END);
+ hbc_button_search->set_alignment(BoxContainer::ALIGNMENT_END);
hbc_button_replace = memnew(HBoxContainer);
vbc_button->add_child(hbc_button_replace);
- hbc_button_replace->set_alignment(ALIGN_END);
+ hbc_button_replace->set_alignment(BoxContainer::ALIGNMENT_END);
HBoxContainer *hbc_option_search = memnew(HBoxContainer);
vbc_option->add_child(hbc_option_search);
@@ -724,7 +759,7 @@ void CodeTextEditor::input(const Ref<InputEvent> &event) {
}
if (!text_editor->has_focus()) {
- if ((find_replace_bar != nullptr && find_replace_bar->is_visible()) && (find_replace_bar->has_focus() || find_replace_bar->is_ancestor_of(get_focus_owner()))) {
+ if ((find_replace_bar != nullptr && find_replace_bar->is_visible()) && (find_replace_bar->has_focus() || find_replace_bar->is_ancestor_of(get_viewport()->gui_get_focus_owner()))) {
if (ED_IS_SHORTCUT("script_text_editor/find_next", key_event)) {
find_replace_bar->search_next();
accept_event();
@@ -766,9 +801,9 @@ void CodeTextEditor::_text_editor_gui_input(const Ref<InputEvent> &p_event) {
if (mb.is_valid()) {
if (mb->is_pressed() && mb->is_command_pressed()) {
- if (mb->get_button_index() == MOUSE_BUTTON_WHEEL_UP) {
+ if (mb->get_button_index() == MouseButton::WHEEL_UP) {
_zoom_in();
- } else if (mb->get_button_index() == MOUSE_BUTTON_WHEEL_DOWN) {
+ } else if (mb->get_button_index() == MouseButton::WHEEL_DOWN) {
_zoom_out();
}
}
@@ -789,12 +824,15 @@ void CodeTextEditor::_text_editor_gui_input(const Ref<InputEvent> &p_event) {
if (k->is_pressed()) {
if (ED_IS_SHORTCUT("script_editor/zoom_in", p_event)) {
_zoom_in();
+ accept_event();
}
if (ED_IS_SHORTCUT("script_editor/zoom_out", p_event)) {
_zoom_out();
+ accept_event();
}
if (ED_IS_SHORTCUT("script_editor/reset_zoom", p_event)) {
_reset_zoom();
+ accept_event();
}
}
}
@@ -839,6 +877,14 @@ void CodeTextEditor::_line_col_changed() {
sb.append(itos(positional_column + 1).lpad(3));
line_and_col_txt->set_text(sb.as_string());
+
+ if (find_replace_bar) {
+ if (!find_replace_bar->line_col_changed_for_result) {
+ find_replace_bar->needs_to_count_results = true;
+ }
+
+ find_replace_bar->line_col_changed_for_result = false;
+ }
}
void CodeTextEditor::_text_changed() {
@@ -847,6 +893,10 @@ void CodeTextEditor::_text_changed() {
}
idle->start();
+
+ if (find_replace_bar) {
+ find_replace_bar->needs_to_count_results = true;
+ }
}
void CodeTextEditor::_code_complete_timer_timeout() {
@@ -857,7 +907,7 @@ void CodeTextEditor::_code_complete_timer_timeout() {
}
void CodeTextEditor::_complete_request() {
- List<ScriptCodeCompletionOption> entries;
+ List<ScriptLanguage::CodeCompletionOption> entries;
String ctext = text_editor->get_text_for_code_completion();
_code_complete_script(ctext, &entries);
bool forced = false;
@@ -868,7 +918,7 @@ void CodeTextEditor::_complete_request() {
return;
}
- for (const ScriptCodeCompletionOption &e : entries) {
+ for (const ScriptLanguage::CodeCompletionOption &e : entries) {
Color font_color = completion_font_color;
if (e.insert_text.begins_with("\"") || e.insert_text.begins_with("\'")) {
font_color = completion_string_color;
@@ -880,41 +930,41 @@ void CodeTextEditor::_complete_request() {
text_editor->update_code_completion_options(forced);
}
-Ref<Texture2D> CodeTextEditor::_get_completion_icon(const ScriptCodeCompletionOption &p_option) {
+Ref<Texture2D> CodeTextEditor::_get_completion_icon(const ScriptLanguage::CodeCompletionOption &p_option) {
Ref<Texture2D> tex;
switch (p_option.kind) {
- case ScriptCodeCompletionOption::KIND_CLASS: {
- if (has_theme_icon(p_option.display, "EditorIcons")) {
- tex = get_theme_icon(p_option.display, "EditorIcons");
+ case ScriptLanguage::CODE_COMPLETION_KIND_CLASS: {
+ if (has_theme_icon(p_option.display, SNAME("EditorIcons"))) {
+ tex = get_theme_icon(p_option.display, SNAME("EditorIcons"));
} else {
tex = get_theme_icon(SNAME("Object"), SNAME("EditorIcons"));
}
} break;
- case ScriptCodeCompletionOption::KIND_ENUM:
+ case ScriptLanguage::CODE_COMPLETION_KIND_ENUM:
tex = get_theme_icon(SNAME("Enum"), SNAME("EditorIcons"));
break;
- case ScriptCodeCompletionOption::KIND_FILE_PATH:
+ case ScriptLanguage::CODE_COMPLETION_KIND_FILE_PATH:
tex = get_theme_icon(SNAME("File"), SNAME("EditorIcons"));
break;
- case ScriptCodeCompletionOption::KIND_NODE_PATH:
+ case ScriptLanguage::CODE_COMPLETION_KIND_NODE_PATH:
tex = get_theme_icon(SNAME("NodePath"), SNAME("EditorIcons"));
break;
- case ScriptCodeCompletionOption::KIND_VARIABLE:
+ case ScriptLanguage::CODE_COMPLETION_KIND_VARIABLE:
tex = get_theme_icon(SNAME("Variant"), SNAME("EditorIcons"));
break;
- case ScriptCodeCompletionOption::KIND_CONSTANT:
+ case ScriptLanguage::CODE_COMPLETION_KIND_CONSTANT:
tex = get_theme_icon(SNAME("MemberConstant"), SNAME("EditorIcons"));
break;
- case ScriptCodeCompletionOption::KIND_MEMBER:
+ case ScriptLanguage::CODE_COMPLETION_KIND_MEMBER:
tex = get_theme_icon(SNAME("MemberProperty"), SNAME("EditorIcons"));
break;
- case ScriptCodeCompletionOption::KIND_SIGNAL:
+ case ScriptLanguage::CODE_COMPLETION_KIND_SIGNAL:
tex = get_theme_icon(SNAME("MemberSignal"), SNAME("EditorIcons"));
break;
- case ScriptCodeCompletionOption::KIND_FUNCTION:
+ case ScriptLanguage::CODE_COMPLETION_KIND_FUNCTION:
tex = get_theme_icon(SNAME("MemberMethod"), SNAME("EditorIcons"));
break;
- case ScriptCodeCompletionOption::KIND_PLAIN_TEXT:
+ case ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT:
tex = get_theme_icon(SNAME("BoxMesh"), SNAME("EditorIcons"));
break;
default:
@@ -977,6 +1027,7 @@ void CodeTextEditor::update_editor_settings() {
text_editor->set_scroll_past_end_of_file_enabled(EditorSettings::get_singleton()->get("text_editor/behavior/navigation/scroll_past_end_of_file"));
text_editor->set_smooth_scroll_enabled(EditorSettings::get_singleton()->get("text_editor/behavior/navigation/smooth_scrolling"));
text_editor->set_v_scroll_speed(EditorSettings::get_singleton()->get("text_editor/behavior/navigation/v_scroll_speed"));
+ text_editor->set_drag_and_drop_selection_enabled(EditorSettings::get_singleton()->get("text_editor/behavior/navigation/drag_and_drop_selection"));
// Behavior: indent
text_editor->set_indent_using_spaces(EditorSettings::get_singleton()->get("text_editor/behavior/indent/type"));
@@ -994,6 +1045,8 @@ void CodeTextEditor::update_editor_settings() {
guideline_cols.append(EditorSettings::get_singleton()->get("text_editor/appearance/guidelines/line_length_guideline_soft_column"));
}
text_editor->set_line_length_guidelines(guideline_cols);
+ } else {
+ text_editor->set_line_length_guidelines(TypedArray<int>());
}
}
@@ -1314,10 +1367,10 @@ void CodeTextEditor::delete_lines() {
int count = Math::abs(to_line - from_line) + 1;
text_editor->set_caret_line(from_line, false);
+ text_editor->deselect();
for (int i = 0; i < count; i++) {
_delete_line(from_line);
}
- text_editor->deselect();
} else {
_delete_line(text_editor->get_caret_line());
}
@@ -1534,7 +1587,7 @@ void CodeTextEditor::set_edit_state(const Variant &p_state) {
void CodeTextEditor::set_error(const String &p_error) {
error->set_text(p_error);
- if (p_error != "") {
+ if (!p_error.is_empty()) {
error->set_default_cursor_shape(CURSOR_POINTING_HAND);
} else {
error->set_default_cursor_shape(CURSOR_ARROW);
@@ -1546,9 +1599,15 @@ void CodeTextEditor::set_error_pos(int p_line, int p_column) {
error_column = p_column;
}
+Point2i CodeTextEditor::get_error_pos() const {
+ return Point2i(error_line, error_column);
+}
+
void CodeTextEditor::goto_error() {
- if (error->get_text() != "") {
- text_editor->unfold_line(error_line);
+ if (!error->get_text().is_empty()) {
+ if (text_editor->get_line_count() != error_line) {
+ text_editor->unfold_line(error_line);
+ }
text_editor->set_caret_line(error_line);
text_editor->set_caret_column(error_column);
text_editor->center_viewport_to_caret();
@@ -1586,30 +1645,35 @@ void CodeTextEditor::_apply_settings_change() {
_update_text_editor_theme();
font_size = EditorSettings::get_singleton()->get("interface/editor/code_font_size");
-
int ot_mode = EditorSettings::get_singleton()->get("interface/editor/code_font_contextual_ligatures");
- switch (ot_mode) {
- case 1: { // Disable ligatures.
- text_editor->clear_opentype_features();
- text_editor->set_opentype_feature("calt", 0);
- } break;
- case 2: { // Custom.
- text_editor->clear_opentype_features();
- Vector<String> subtag = String(EditorSettings::get_singleton()->get("interface/editor/code_font_custom_opentype_features")).split(",");
- Dictionary ftrs;
- for (int i = 0; i < subtag.size(); i++) {
- Vector<String> subtag_a = subtag[i].split("=");
- if (subtag_a.size() == 2) {
- text_editor->set_opentype_feature(subtag_a[0], subtag_a[1].to_int());
- } else if (subtag_a.size() == 1) {
- text_editor->set_opentype_feature(subtag_a[0], 1);
+
+ Ref<FontVariation> fc = text_editor->get_theme_font(SNAME("font"));
+ if (fc.is_valid()) {
+ switch (ot_mode) {
+ case 1: { // Disable ligatures.
+ Dictionary ftrs;
+ ftrs[TS->name_to_tag("calt")] = 0;
+ fc->set_opentype_features(ftrs);
+ } break;
+ case 2: { // Custom.
+ Vector<String> subtag = String(EditorSettings::get_singleton()->get("interface/editor/code_font_custom_opentype_features")).split(",");
+ Dictionary ftrs;
+ for (int i = 0; i < subtag.size(); i++) {
+ Vector<String> subtag_a = subtag[i].split("=");
+ if (subtag_a.size() == 2) {
+ ftrs[TS->name_to_tag(subtag_a[0])] = subtag_a[1].to_int();
+ } else if (subtag_a.size() == 1) {
+ ftrs[TS->name_to_tag(subtag_a[0])] = 1;
+ }
}
- }
- } break;
- default: { // Default.
- text_editor->clear_opentype_features();
- text_editor->set_opentype_feature("calt", 1);
- } break;
+ fc->set_opentype_features(ftrs);
+ } break;
+ default: { // Default.
+ Dictionary ftrs;
+ ftrs[TS->name_to_tag("calt")] = 1;
+ fc->set_opentype_features(ftrs);
+ } break;
+ }
}
text_editor->set_code_hint_draw_below(EDITOR_GET("text_editor/completion/put_callhint_tooltip_below_current_line"));
@@ -1654,37 +1718,52 @@ void CodeTextEditor::_toggle_scripts_pressed() {
void CodeTextEditor::_error_pressed(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseButton> mb = p_event;
- if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_LEFT) {
+ if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT) {
goto_error();
}
}
+void CodeTextEditor::_update_status_bar_theme() {
+ error_button->set_icon(get_theme_icon(SNAME("StatusError"), SNAME("EditorIcons")));
+ error_button->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), SNAME("Editor")));
+ error_button->add_theme_font_override("font", get_theme_font(SNAME("status_source"), SNAME("EditorFonts")));
+ error_button->add_theme_font_size_override("font_size", get_theme_font_size(SNAME("status_source_size"), SNAME("EditorFonts")));
+
+ warning_button->set_icon(get_theme_icon(SNAME("NodeWarning"), SNAME("EditorIcons")));
+ warning_button->add_theme_color_override("font_color", get_theme_color(SNAME("warning_color"), SNAME("Editor")));
+ warning_button->add_theme_font_override("font", get_theme_font(SNAME("status_source"), SNAME("EditorFonts")));
+ warning_button->add_theme_font_size_override("font_size", get_theme_font_size(SNAME("status_source_size"), SNAME("EditorFonts")));
+
+ line_and_col_txt->add_theme_font_override("font", get_theme_font(SNAME("status_source"), SNAME("EditorFonts")));
+ line_and_col_txt->add_theme_font_size_override("font_size", get_theme_font_size(SNAME("status_source_size"), SNAME("EditorFonts")));
+}
+
void CodeTextEditor::_notification(int p_what) {
switch (p_what) {
+ case NOTIFICATION_ENTER_TREE: {
+ _update_status_bar_theme();
+ } break;
+
case NOTIFICATION_THEME_CHANGED: {
+ _update_status_bar_theme();
if (toggle_scripts_button->is_visible()) {
update_toggle_scripts_button();
}
_update_text_editor_theme();
} break;
- case NOTIFICATION_ENTER_TREE: {
- error_button->set_icon(get_theme_icon(SNAME("StatusError"), SNAME("EditorIcons")));
- warning_button->set_icon(get_theme_icon(SNAME("NodeWarning"), SNAME("EditorIcons")));
- add_theme_constant_override("separation", 4 * EDSCALE);
- } break;
+
case NOTIFICATION_VISIBILITY_CHANGED: {
if (toggle_scripts_button->is_visible()) {
update_toggle_scripts_button();
}
set_process_input(is_visible_in_tree());
} break;
+
case NOTIFICATION_PREDELETE: {
if (find_replace_bar) {
find_replace_bar->set_text_edit(nullptr);
}
} break;
- default:
- break;
}
}
@@ -1710,7 +1789,7 @@ void CodeTextEditor::toggle_bookmark() {
}
void CodeTextEditor::goto_next_bookmark() {
- Array bmarks = text_editor->get_bookmarked_lines();
+ PackedInt32Array bmarks = text_editor->get_bookmarked_lines();
if (bmarks.size() <= 0) {
return;
}
@@ -1734,7 +1813,7 @@ void CodeTextEditor::goto_next_bookmark() {
}
void CodeTextEditor::goto_prev_bookmark() {
- Array bmarks = text_editor->get_bookmarked_lines();
+ PackedInt32Array bmarks = text_editor->get_bookmarked_lines();
if (bmarks.size() <= 0) {
return;
}
@@ -1788,42 +1867,49 @@ void CodeTextEditor::update_toggle_scripts_button() {
CodeTextEditor::CodeTextEditor() {
code_complete_func = nullptr;
- ED_SHORTCUT("script_editor/zoom_in", TTR("Zoom In"), KEY_MASK_CMD | KEY_EQUAL);
- ED_SHORTCUT("script_editor/zoom_out", TTR("Zoom Out"), KEY_MASK_CMD | KEY_MINUS);
- ED_SHORTCUT("script_editor/reset_zoom", TTR("Reset Zoom"), KEY_MASK_CMD | KEY_0);
+ ED_SHORTCUT("script_editor/zoom_in", TTR("Zoom In"), KeyModifierMask::CMD | Key::EQUAL);
+ ED_SHORTCUT("script_editor/zoom_out", TTR("Zoom Out"), KeyModifierMask::CMD | Key::MINUS);
+ ED_SHORTCUT_ARRAY("script_editor/reset_zoom", TTR("Reset Zoom"),
+ { int32_t(KeyModifierMask::CMD | Key::KEY_0), int32_t(KeyModifierMask::CMD | Key::KP_0) });
text_editor = memnew(CodeEdit);
add_child(text_editor);
text_editor->set_v_size_flags(SIZE_EXPAND_FILL);
int ot_mode = EditorSettings::get_singleton()->get("interface/editor/code_font_contextual_ligatures");
- switch (ot_mode) {
- case 1: { // Disable ligatures.
- text_editor->clear_opentype_features();
- text_editor->set_opentype_feature("calt", 0);
- } break;
- case 2: { // Custom.
- text_editor->clear_opentype_features();
- Vector<String> subtag = String(EditorSettings::get_singleton()->get("interface/editor/code_font_custom_opentype_features")).split(",");
- Dictionary ftrs;
- for (int i = 0; i < subtag.size(); i++) {
- Vector<String> subtag_a = subtag[i].split("=");
- if (subtag_a.size() == 2) {
- text_editor->set_opentype_feature(subtag_a[0], subtag_a[1].to_int());
- } else if (subtag_a.size() == 1) {
- text_editor->set_opentype_feature(subtag_a[0], 1);
+ Ref<FontVariation> fc = text_editor->get_theme_font(SNAME("font"));
+ if (fc.is_valid()) {
+ switch (ot_mode) {
+ case 1: { // Disable ligatures.
+ Dictionary ftrs;
+ ftrs[TS->name_to_tag("calt")] = 0;
+ fc->set_opentype_features(ftrs);
+ } break;
+ case 2: { // Custom.
+ Vector<String> subtag = String(EditorSettings::get_singleton()->get("interface/editor/code_font_custom_opentype_features")).split(",");
+ Dictionary ftrs;
+ for (int i = 0; i < subtag.size(); i++) {
+ Vector<String> subtag_a = subtag[i].split("=");
+ if (subtag_a.size() == 2) {
+ ftrs[TS->name_to_tag(subtag_a[0])] = subtag_a[1].to_int();
+ } else if (subtag_a.size() == 1) {
+ ftrs[TS->name_to_tag(subtag_a[0])] = 1;
+ }
}
- }
- } break;
- default: { // Default.
- text_editor->clear_opentype_features();
- text_editor->set_opentype_feature("calt", 1);
- } break;
+ fc->set_opentype_features(ftrs);
+ } break;
+ default: { // Default.
+ Dictionary ftrs;
+ ftrs[TS->name_to_tag("calt")] = 1;
+ fc->set_opentype_features(ftrs);
+ } break;
+ }
}
text_editor->set_draw_line_numbers(true);
text_editor->set_highlight_matching_braces_enabled(true);
text_editor->set_auto_indent_enabled(true);
+ text_editor->set_deselect_on_focus_loss_enabled(false);
status_bar = memnew(HBoxContainer);
add_child(status_bar);
@@ -1853,7 +1939,7 @@ CodeTextEditor::CodeTextEditor() {
ScrollContainer *scroll = memnew(ScrollContainer);
scroll->set_h_size_flags(SIZE_EXPAND_FILL);
scroll->set_v_size_flags(SIZE_EXPAND_FILL);
- scroll->set_enable_v_scroll(false);
+ scroll->set_vertical_scroll_mode(ScrollContainer::SCROLL_MODE_DISABLED);
status_bar->add_child(scroll);
error = memnew(Label);
@@ -1870,12 +1956,6 @@ CodeTextEditor::CodeTextEditor() {
error_button->set_default_cursor_shape(CURSOR_POINTING_HAND);
error_button->connect("pressed", callable_mp(this, &CodeTextEditor::_error_button_pressed));
error_button->set_tooltip(TTR("Errors"));
-
- error_button->add_theme_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("error_color"), SNAME("Editor")));
- error_button->add_theme_font_override("font", EditorNode::get_singleton()->get_gui_base()->get_theme_font(SNAME("status_source"), SNAME("EditorFonts")));
- error_button->add_theme_font_size_override("font_size", EditorNode::get_singleton()->get_gui_base()->get_theme_font_size(SNAME("status_source_size"), SNAME("EditorFonts")));
-
- is_errors_panel_opened = false;
set_error_count(0);
// Warnings
@@ -1886,27 +1966,19 @@ CodeTextEditor::CodeTextEditor() {
warning_button->set_default_cursor_shape(CURSOR_POINTING_HAND);
warning_button->connect("pressed", callable_mp(this, &CodeTextEditor::_warning_button_pressed));
warning_button->set_tooltip(TTR("Warnings"));
-
- warning_button->add_theme_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("warning_color"), SNAME("Editor")));
- warning_button->add_theme_font_override("font", EditorNode::get_singleton()->get_gui_base()->get_theme_font(SNAME("status_source"), SNAME("EditorFonts")));
- warning_button->add_theme_font_size_override("font_size", EditorNode::get_singleton()->get_gui_base()->get_theme_font_size(SNAME("status_source_size"), SNAME("EditorFonts")));
-
- is_warnings_panel_opened = false;
set_warning_count(0);
// Line and column
line_and_col_txt = memnew(Label);
status_bar->add_child(line_and_col_txt);
line_and_col_txt->set_v_size_flags(SIZE_EXPAND | SIZE_SHRINK_CENTER);
- line_and_col_txt->add_theme_font_override("font", EditorNode::get_singleton()->get_gui_base()->get_theme_font(SNAME("status_source"), SNAME("EditorFonts")));
- line_and_col_txt->add_theme_font_size_override("font_size", EditorNode::get_singleton()->get_gui_base()->get_theme_font_size(SNAME("status_source_size"), SNAME("EditorFonts")));
line_and_col_txt->set_tooltip(TTR("Line and column numbers."));
line_and_col_txt->set_mouse_filter(MOUSE_FILTER_STOP);
text_editor->connect("gui_input", callable_mp(this, &CodeTextEditor::_text_editor_gui_input));
text_editor->connect("caret_changed", callable_mp(this, &CodeTextEditor::_line_col_changed));
text_editor->connect("text_changed", callable_mp(this, &CodeTextEditor::_text_changed));
- text_editor->connect("request_code_completion", callable_mp(this, &CodeTextEditor::_complete_request));
+ text_editor->connect("code_completion_requested", callable_mp(this, &CodeTextEditor::_complete_request));
TypedArray<String> cs;
cs.push_back(".");
cs.push_back(",");
@@ -1930,4 +2002,5 @@ CodeTextEditor::CodeTextEditor() {
font_resize_timer->connect("timeout", callable_mp(this, &CodeTextEditor::_font_resize_timeout));
EditorSettings::get_singleton()->connect("settings_changed", callable_mp(this, &CodeTextEditor::_on_settings_change));
+ add_theme_constant_override("separation", 4 * EDSCALE);
}