summaryrefslogtreecommitdiff
path: root/scene/gui
diff options
context:
space:
mode:
Diffstat (limited to 'scene/gui')
-rw-r--r--scene/gui/container.cpp4
-rw-r--r--scene/gui/control.cpp2
-rw-r--r--scene/gui/item_list.cpp2
-rw-r--r--scene/gui/line_edit.cpp2
-rw-r--r--scene/gui/popup.cpp10
-rw-r--r--scene/gui/range.cpp4
-rw-r--r--scene/gui/rich_text_label.cpp32
-rw-r--r--scene/gui/scroll_container.cpp2
-rw-r--r--scene/gui/text_edit.cpp114
-rw-r--r--scene/gui/text_edit.h9
-rw-r--r--scene/gui/tree.cpp25
-rw-r--r--scene/gui/tree.h3
12 files changed, 105 insertions, 104 deletions
diff --git a/scene/gui/container.cpp b/scene/gui/container.cpp
index c9cf5f8308..449076f863 100644
--- a/scene/gui/container.cpp
+++ b/scene/gui/container.cpp
@@ -175,9 +175,9 @@ String Container::get_configuration_warning() const {
if (get_class() == "Container" && get_script().is_null()) {
if (warning != String()) {
- warning += "\n";
+ warning += "\n\n";
}
- warning += TTR("Container by itself serves no purpose unless a script configures its children placement behavior.\nIf you don't intend to add a script, then please use a plain 'Control' node instead.");
+ warning += TTR("Container by itself serves no purpose unless a script configures its children placement behavior.\nIf you don't intend to add a script, use a plain Control node instead.");
}
return warning;
}
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index eccd42cb9f..26be17f6c1 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -2711,7 +2711,7 @@ String Control::get_configuration_warning() const {
if (data.mouse_filter == MOUSE_FILTER_IGNORE && data.tooltip != "") {
if (warning != String()) {
- warning += "\n";
+ warning += "\n\n";
}
warning += TTR("The Hint Tooltip won't be displayed as the control's Mouse Filter is set to \"Ignore\". To solve this, set the Mouse Filter to \"Stop\" or \"Pass\".");
}
diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp
index 91b76839d7..a3bc68ffcd 100644
--- a/scene/gui/item_list.cpp
+++ b/scene/gui/item_list.cpp
@@ -754,7 +754,7 @@ void ItemList::_gui_input(const Ref<InputEvent> &p_event) {
for (int i = current + 1; i <= items.size(); i++) {
if (i == items.size()) {
- if (current == 0)
+ if (current == 0 || current == -1)
break;
else
i = 0;
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp
index 7a015f77db..3dcbf64e7c 100644
--- a/scene/gui/line_edit.cpp
+++ b/scene/gui/line_edit.cpp
@@ -1191,7 +1191,7 @@ void LineEdit::set_cursor_position(int p_pos) {
if (cursor_pos <= window_pos) {
/* Adjust window if cursor goes too much to the left */
set_window_pos(MAX(0, cursor_pos - 1));
- } else if (cursor_pos > window_pos) {
+ } else {
/* Adjust window if cursor goes too much to the right */
int window_width = get_size().width - style->get_minimum_size().width;
bool display_clear_icon = !text.empty() && is_editable() && clear_button_enabled;
diff --git a/scene/gui/popup.cpp b/scene/gui/popup.cpp
index 492e379440..3e003af396 100644
--- a/scene/gui/popup.cpp
+++ b/scene/gui/popup.cpp
@@ -48,6 +48,14 @@ void Popup::_notification(int p_what) {
update_configuration_warning();
}
+ if (p_what == NOTIFICATION_EXIT_TREE) {
+ if (popped_up) {
+ popped_up = false;
+ notification(NOTIFICATION_POPUP_HIDE);
+ emit_signal("popup_hide");
+ }
+ }
+
if (p_what == NOTIFICATION_ENTER_TREE) {
//small helper to make editing of these easier in editor
#ifdef TOOLS_ENABLED
@@ -226,7 +234,7 @@ Popup::Popup() {
String Popup::get_configuration_warning() const {
if (is_visible_in_tree()) {
- return TTR("Popups will hide by default unless you call popup() or any of the popup*() functions. Making them visible for editing is fine though, but they will hide upon running.");
+ return TTR("Popups will hide by default unless you call popup() or any of the popup*() functions. Making them visible for editing is fine, but they will hide upon running.");
}
return String();
diff --git a/scene/gui/range.cpp b/scene/gui/range.cpp
index d00acaf08a..e709bac377 100644
--- a/scene/gui/range.cpp
+++ b/scene/gui/range.cpp
@@ -35,9 +35,9 @@ String Range::get_configuration_warning() const {
if (shared->exp_ratio && shared->min <= 0) {
if (warning != String()) {
- warning += "\n";
+ warning += "\n\n";
}
- warning += TTR("If exp_edit is true min_value must be > 0.");
+ warning += TTR("If \"Exp Edit\" is enabled, \"Min Value\" must be greater than 0.");
}
return warning;
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index 5b91299de6..d6c0981ebc 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -1942,37 +1942,37 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) {
if (col.begins_with("#"))
color = Color::html(col);
else if (col == "aqua")
- color = Color::html("#00FFFF");
+ color = Color(0, 1, 1);
else if (col == "black")
- color = Color::html("#000000");
+ color = Color(0, 0, 0);
else if (col == "blue")
- color = Color::html("#0000FF");
+ color = Color(0, 0, 1);
else if (col == "fuchsia")
- color = Color::html("#FF00FF");
+ color = Color(1, 0, 1);
else if (col == "gray" || col == "grey")
- color = Color::html("#808080");
+ color = Color(0.5, 0.5, 0.5);
else if (col == "green")
- color = Color::html("#008000");
+ color = Color(0, 0.5, 0);
else if (col == "lime")
- color = Color::html("#00FF00");
+ color = Color(0, 1, 0);
else if (col == "maroon")
- color = Color::html("#800000");
+ color = Color(0.5, 0, 0);
else if (col == "navy")
- color = Color::html("#000080");
+ color = Color(0, 0, 0.5);
else if (col == "olive")
- color = Color::html("#808000");
+ color = Color(0.5, 0.5, 0);
else if (col == "purple")
- color = Color::html("#800080");
+ color = Color(0.5, 0, 0.5);
else if (col == "red")
- color = Color::html("#FF0000");
+ color = Color(1, 0, 0);
else if (col == "silver")
- color = Color::html("#C0C0C0");
+ color = Color(0.75, 0.75, 0.75);
else if (col == "teal")
- color = Color::html("#008008");
+ color = Color(0, 0.5, 0.5);
else if (col == "white")
- color = Color::html("#FFFFFF");
+ color = Color(1, 1, 1);
else if (col == "yellow")
- color = Color::html("#FFFF00");
+ color = Color(1, 1, 0);
else
color = base_color;
diff --git a/scene/gui/scroll_container.cpp b/scene/gui/scroll_container.cpp
index d83ae47671..461281a4ed 100644
--- a/scene/gui/scroll_container.cpp
+++ b/scene/gui/scroll_container.cpp
@@ -486,7 +486,7 @@ String ScrollContainer::get_configuration_warning() const {
}
if (found != 1)
- return TTR("ScrollContainer is intended to work with a single child control.\nUse a container as child (VBox,HBox,etc), or a Control and set the custom minimum size manually.");
+ return TTR("ScrollContainer is intended to work with a single child control.\nUse a container as child (VBox, HBox, etc.), or a Control and set the custom minimum size manually.");
else
return "";
}
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index a6e3d644f6..7a937843ab 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -35,6 +35,7 @@
#include "core/os/keyboard.h"
#include "core/os/os.h"
#include "core/project_settings.h"
+#include "core/script_language.h"
#include "scene/main/viewport.h"
#ifdef TOOLS_ENABLED
@@ -1362,7 +1363,7 @@ void TextEdit::_notification(int p_what) {
if (completion_options.size() < 50) {
for (int i = 0; i < completion_options.size(); i++) {
- int w2 = MIN(cache.font->get_string_size(completion_options[i]).x, cmax_width);
+ int w2 = MIN(cache.font->get_string_size(completion_options[i].display).x, cmax_width);
if (w2 > w)
w = w2;
}
@@ -1370,6 +1371,11 @@ void TextEdit::_notification(int p_what) {
w = cmax_width;
}
+ // Add space for completion icons
+ const int icon_hsep = get_constant("hseparation", "ItemList");
+ Size2 icon_area_size(get_row_height(), get_row_height());
+ w += icon_area_size.width + icon_hsep;
+
int th = h + csb->get_minimum_size().y;
if (cursor_pos.y + get_row_height() + th > get_size().height) {
@@ -1397,7 +1403,7 @@ void TextEdit::_notification(int p_what) {
}
int line_from = CLAMP(completion_index - lines / 2, 0, completion_options.size() - lines);
VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(completion_rect.position.x, completion_rect.position.y + (completion_index - line_from) * get_row_height()), Size2(completion_rect.size.width, get_row_height())), cache.completion_selected_color);
- draw_rect(Rect2(completion_rect.position, Size2(nofs, completion_rect.size.height)), cache.completion_existing_color);
+ draw_rect(Rect2(completion_rect.position + Vector2(icon_area_size.x + icon_hsep, 0), Size2(nofs, completion_rect.size.height)), cache.completion_existing_color);
for (int i = 0; i < lines; i++) {
@@ -1405,12 +1411,26 @@ void TextEdit::_notification(int p_what) {
ERR_CONTINUE(l < 0 || l >= completion_options.size());
Color text_color = cache.completion_font_color;
for (int j = 0; j < color_regions.size(); j++) {
- if (completion_options[l].begins_with(color_regions[j].begin_key)) {
+ if (completion_options[l].insert_text.begins_with(color_regions[j].begin_key)) {
text_color = color_regions[j].color;
}
}
int yofs = (get_row_height() - cache.font->get_height()) / 2;
- draw_string(cache.font, Point2(completion_rect.position.x, completion_rect.position.y + i * get_row_height() + cache.font->get_ascent() + yofs), completion_options[l], text_color, completion_rect.size.width);
+ Point2 title_pos(completion_rect.position.x, completion_rect.position.y + i * get_row_height() + cache.font->get_ascent() + yofs);
+
+ //draw completion icon if it is valid
+ Ref<Texture> icon = completion_options[l].icon;
+ Rect2 icon_area(completion_rect.position.x, completion_rect.position.y + i * get_row_height(), icon_area_size.width, icon_area_size.height);
+ if (icon.is_valid()) {
+ const real_t max_scale = 0.7f;
+ const real_t side = max_scale * icon_area.size.width;
+ real_t scale = MIN(side / icon->get_width(), side / icon->get_height());
+ Size2 icon_size = icon->get_size() * scale;
+ draw_texture_rect(icon, Rect2(icon_area.position + (icon_area.size - icon_size) / 2, icon_size));
+ }
+
+ title_pos.x = icon_area.position.x + icon_area.size.width + icon_hsep;
+ draw_string(cache.font, title_pos, completion_options[l].display, text_color, completion_rect.size.width);
}
if (scrollw) {
@@ -3267,28 +3287,6 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
} break;
- case KEY_U: {
- if (!k->get_command() || k->get_shift()) {
- scancode_handled = false;
- break;
- } else {
- if (selection.active) {
- int ini = selection.from_line;
- int end = selection.to_line;
-
- for (int i = ini; i <= end; i++) {
- _uncomment_line(i);
- }
- } else {
- _uncomment_line(cursor.line);
- if (cursor.column >= get_line(cursor.line).length()) {
- cursor.column = MAX(0, get_line(cursor.line).length() - 1);
- }
- }
- update();
- }
- } break;
-
default: {
scancode_handled = false;
@@ -3347,24 +3345,6 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
}
}
-void TextEdit::_uncomment_line(int p_line) {
- String line_text = get_line(p_line);
- for (int i = 0; i < line_text.length(); i++) {
- if (line_text[i] == '#') {
- _remove_text(p_line, i, p_line, i + 1);
- if (p_line == selection.to_line && selection.to_column > line_text.length() - 1) {
- selection.to_column -= 1;
- if (selection.to_column >= selection.from_column) {
- selection.active = false;
- }
- }
- return;
- } else if (line_text[i] != '\t' && line_text[i] != ' ') {
- return;
- }
- }
-}
-
void TextEdit::_scroll_up(real_t p_delta) {
if (scrolling && smooth_scroll_enabled && SGN(target_v_scroll - v_scroll->get_value()) != SGN(-p_delta))
@@ -5925,12 +5905,12 @@ void TextEdit::_confirm_completion() {
_remove_text(cursor.line, cursor.column - completion_base.length(), cursor.line, cursor.column);
cursor_set_column(cursor.column - completion_base.length(), false);
- insert_text_at_cursor(completion_current);
+ insert_text_at_cursor(completion_current.insert_text);
// When inserted into the middle of an existing string/method, don't add an unnecessary quote/bracket.
String line = text[cursor.line];
CharType next_char = line[cursor.column];
- CharType last_completion_char = completion_current[completion_current.length() - 1];
+ CharType last_completion_char = completion_current.insert_text[completion_current.insert_text.length() - 1];
if ((last_completion_char == '"' || last_completion_char == '\'') && last_completion_char == next_char) {
_base_remove_text(cursor.line, cursor.column, cursor.line, cursor.column + 1);
@@ -6066,39 +6046,41 @@ void TextEdit::_update_completion_candidates() {
completion_base = s;
Vector<float> sim_cache;
bool single_quote = s.begins_with("'");
- Vector<String> completion_options_casei;
+ Vector<ScriptCodeCompletionOption> completion_options_casei;
+
+ for (List<ScriptCodeCompletionOption>::Element *E = completion_sources.front(); E; E = E->next()) {
+ ScriptCodeCompletionOption &option = E->get();
- for (int i = 0; i < completion_strings.size(); i++) {
- if (single_quote && completion_strings[i].is_quoted()) {
- completion_strings.write[i] = completion_strings[i].unquote().quote("'");
+ if (single_quote && option.display.is_quoted()) {
+ option.display = option.display.unquote().quote("'");
}
- if (inquote && restore_quotes == 1 && !completion_strings[i].is_quoted()) {
+ if (inquote && restore_quotes == 1 && !option.display.is_quoted()) {
String quote = single_quote ? "'" : "\"";
- completion_strings.write[i] = completion_strings[i].quote(quote);
+ option.display = option.display.quote(quote);
}
- if (completion_strings[i].begins_with(s)) {
- completion_options.push_back(completion_strings[i]);
- } else if (completion_strings[i].to_lower().begins_with(s.to_lower())) {
- completion_options_casei.push_back(completion_strings[i]);
+ if (option.display.begins_with(s)) {
+ completion_options.push_back(option);
+ } else if (option.display.to_lower().begins_with(s.to_lower())) {
+ completion_options_casei.push_back(option);
}
}
completion_options.append_array(completion_options_casei);
if (completion_options.size() == 0) {
- for (int i = 0; i < completion_strings.size(); i++) {
- if (s.is_subsequence_of(completion_strings[i])) {
- completion_options.push_back(completion_strings[i]);
+ for (int i = 0; i < completion_sources.size(); i++) {
+ if (s.is_subsequence_of(completion_sources[i].display)) {
+ completion_options.push_back(completion_sources[i]);
}
}
}
if (completion_options.size() == 0) {
- for (int i = 0; i < completion_strings.size(); i++) {
- if (s.is_subsequence_ofi(completion_strings[i])) {
- completion_options.push_back(completion_strings[i]);
+ for (int i = 0; i < completion_sources.size(); i++) {
+ if (s.is_subsequence_ofi(completion_sources[i].display)) {
+ completion_options.push_back(completion_sources[i]);
}
}
}
@@ -6109,7 +6091,7 @@ void TextEdit::_update_completion_candidates() {
return;
}
- if (completion_options.size() == 1 && s == completion_options[0]) {
+ if (completion_options.size() == 1 && s == completion_options[0].display) {
// A perfect match, stop completion
_cancel_completion();
return;
@@ -6147,12 +6129,12 @@ void TextEdit::set_code_hint(const String &p_hint) {
update();
}
-void TextEdit::code_complete(const Vector<String> &p_strings, bool p_forced) {
+void TextEdit::code_complete(const List<ScriptCodeCompletionOption> &p_strings, bool p_forced) {
- completion_strings = p_strings;
+ completion_sources = p_strings;
completion_active = true;
completion_forced = p_forced;
- completion_current = "";
+ completion_current = ScriptCodeCompletionOption();
completion_index = 0;
_update_completion_candidates();
}
diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h
index 30956ccb23..b47dac0902 100644
--- a/scene/gui/text_edit.h
+++ b/scene/gui/text_edit.h
@@ -255,11 +255,11 @@ private:
Set<String> completion_prefixes;
bool completion_enabled;
- Vector<String> completion_strings;
- Vector<String> completion_options;
+ List<ScriptCodeCompletionOption> completion_sources;
+ Vector<ScriptCodeCompletionOption> completion_options;
bool completion_active;
bool completion_forced;
- String completion_current;
+ ScriptCodeCompletionOption completion_current;
String completion_base;
int completion_index;
Rect2i completion_rect;
@@ -395,7 +395,6 @@ private:
void _update_selection_mode_word();
void _update_selection_mode_line();
- void _uncomment_line(int p_line);
void _scroll_up(real_t p_delta);
void _scroll_down(real_t p_delta);
@@ -704,7 +703,7 @@ public:
void set_tooltip_request_func(Object *p_obj, const StringName &p_function, const Variant &p_udata);
void set_completion(bool p_enabled, const Vector<String> &p_prefixes);
- void code_complete(const Vector<String> &p_strings, bool p_forced = false);
+ void code_complete(const List<ScriptCodeCompletionOption> &p_strings, bool p_forced = false);
void set_code_hint(const String &p_hint);
void query_code_comple();
diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp
index c2493ab321..4005505830 100644
--- a/scene/gui/tree.cpp
+++ b/scene/gui/tree.cpp
@@ -572,13 +572,6 @@ int TreeItem::get_button_by_id(int p_column, int p_id) const {
return -1;
}
-bool TreeItem::is_button_disabled(int p_column, int p_idx) const {
-
- ERR_FAIL_INDEX_V(p_column, cells.size(), false);
- ERR_FAIL_INDEX_V(p_idx, cells[p_column].buttons.size(), false);
-
- return cells[p_column].buttons[p_idx].disabled;
-}
void TreeItem::set_button(int p_column, int p_idx, const Ref<Texture> &p_button) {
ERR_FAIL_COND(p_button.is_null());
@@ -596,6 +589,23 @@ void TreeItem::set_button_color(int p_column, int p_idx, const Color &p_color) {
_changed_notify(p_column);
}
+void TreeItem::set_button_disabled(int p_column, int p_idx, bool p_disabled) {
+
+ ERR_FAIL_INDEX(p_column, cells.size());
+ ERR_FAIL_INDEX(p_idx, cells[p_column].buttons.size());
+
+ cells.write[p_column].buttons.write[p_idx].disabled = p_disabled;
+ _changed_notify(p_column);
+}
+
+bool TreeItem::is_button_disabled(int p_column, int p_idx) const {
+
+ ERR_FAIL_INDEX_V(p_column, cells.size(), false);
+ ERR_FAIL_INDEX_V(p_idx, cells[p_column].buttons.size(), false);
+
+ return cells[p_column].buttons[p_idx].disabled;
+}
+
void TreeItem::set_editable(int p_column, bool p_editable) {
ERR_FAIL_INDEX(p_column, cells.size());
@@ -785,6 +795,7 @@ void TreeItem::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_button", "column", "button_idx"), &TreeItem::get_button);
ClassDB::bind_method(D_METHOD("set_button", "column", "button_idx", "button"), &TreeItem::set_button);
ClassDB::bind_method(D_METHOD("erase_button", "column", "button_idx"), &TreeItem::erase_button);
+ ClassDB::bind_method(D_METHOD("set_button_disabled", "column", "button_idx", "disabled"), &TreeItem::set_button_disabled);
ClassDB::bind_method(D_METHOD("is_button_disabled", "column", "button_idx"), &TreeItem::is_button_disabled);
ClassDB::bind_method(D_METHOD("set_expand_right", "column", "enable"), &TreeItem::set_expand_right);
diff --git a/scene/gui/tree.h b/scene/gui/tree.h
index 45d451eb72..b6cdab766f 100644
--- a/scene/gui/tree.h
+++ b/scene/gui/tree.h
@@ -209,9 +209,10 @@ public:
int get_button_id(int p_column, int p_idx) const;
void erase_button(int p_column, int p_idx);
int get_button_by_id(int p_column, int p_id) const;
- bool is_button_disabled(int p_column, int p_idx) const;
void set_button(int p_column, int p_idx, const Ref<Texture> &p_button);
void set_button_color(int p_column, int p_idx, const Color &p_color);
+ void set_button_disabled(int p_column, int p_idx, bool p_disabled);
+ bool is_button_disabled(int p_column, int p_idx) const;
/* range works for mode number or mode combo */