summaryrefslogtreecommitdiff
path: root/scene/gui
diff options
context:
space:
mode:
Diffstat (limited to 'scene/gui')
-rw-r--r--scene/gui/color_picker.cpp2
-rw-r--r--scene/gui/container.cpp4
-rw-r--r--scene/gui/control.cpp5
-rw-r--r--scene/gui/file_dialog.cpp5
-rw-r--r--scene/gui/line_edit.cpp4
-rw-r--r--scene/gui/rich_text_label.cpp321
-rw-r--r--scene/gui/rich_text_label.h5
-rw-r--r--scene/gui/scroll_bar.cpp21
-rw-r--r--scene/gui/scroll_bar.h22
-rw-r--r--scene/gui/tab_container.cpp49
-rw-r--r--scene/gui/tab_container.h1
-rw-r--r--scene/gui/tree.cpp21
12 files changed, 252 insertions, 208 deletions
diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp
index 88710289c7..84170a65d1 100644
--- a/scene/gui/color_picker.cpp
+++ b/scene/gui/color_picker.cpp
@@ -66,7 +66,7 @@ void ColorPicker::_notification(int p_what) {
} break;
case NOTIFICATION_PARENTED: {
for (int i = 0; i < 4; i++) {
- set_margin((Margin)i, get_theme_constant("margin"));
+ set_margin((Margin)i, get_margin((Margin)i) + get_theme_constant("margin"));
}
} break;
case NOTIFICATION_VISIBILITY_CHANGED: {
diff --git a/scene/gui/container.cpp b/scene/gui/container.cpp
index 18a84ce348..a89eef6209 100644
--- a/scene/gui/container.cpp
+++ b/scene/gui/container.cpp
@@ -140,7 +140,7 @@ void Container::queue_sort() {
return;
}
- MessageQueue::get_singleton()->push_call(this, "_sort_children");
+ MessageQueue::get_singleton()->push_callable(callable_mp(this, &Container::_sort_children));
pending_sort = true;
}
@@ -177,8 +177,6 @@ String Container::get_configuration_warning() const {
}
void Container::_bind_methods() {
- ClassDB::bind_method(D_METHOD("_sort_children"), &Container::_sort_children);
-
ClassDB::bind_method(D_METHOD("queue_sort"), &Container::queue_sort);
ClassDB::bind_method(D_METHOD("fit_child_in_rect", "child", "rect"), &Container::fit_child_in_rect);
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index 96aaec6ae9..97daeceda9 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -30,6 +30,7 @@
#include "control.h"
+#include "core/math/geometry_2d.h"
#include "core/message_queue.h"
#include "core/os/keyboard.h"
#include "core/os/os.h"
@@ -2293,8 +2294,8 @@ void Control::_window_find_focus_neighbour(const Vector2 &p_dir, Node *p_at, con
Vector2 fb = points[(j + 1) % 4];
Vector2 pa, pb;
- float d = Geometry::get_closest_points_between_segments(la, lb, fa, fb, pa, pb);
- //float d = Geometry::get_closest_distance_between_segments(Vector3(la.x,la.y,0),Vector3(lb.x,lb.y,0),Vector3(fa.x,fa.y,0),Vector3(fb.x,fb.y,0));
+ float d = Geometry2D::get_closest_points_between_segments(la, lb, fa, fb, pa, pb);
+ //float d = Geometry2D::get_closest_distance_between_segments(Vector3(la.x,la.y,0),Vector3(lb.x,lb.y,0),Vector3(fa.x,fa.y,0),Vector3(fb.x,fb.y,0));
if (d < r_closest_dist) {
r_closest_dist = d;
*r_closest = c;
diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp
index be6b542ae1..630f3c8ff6 100644
--- a/scene/gui/file_dialog.cpp
+++ b/scene/gui/file_dialog.cpp
@@ -402,7 +402,9 @@ void FileDialog::update_file_list() {
TreeItem *root = tree->create_item();
Ref<Texture2D> folder = vbox->get_theme_icon("folder", "FileDialog");
+ Ref<Texture2D> file_icon = vbox->get_theme_icon("file", "FileDialog");
const Color folder_color = vbox->get_theme_color("folder_icon_modulate", "FileDialog");
+ const Color file_color = vbox->get_theme_color("file_icon_modulate", "FileDialog");
List<String> files;
List<String> dirs;
@@ -491,7 +493,10 @@ void FileDialog::update_file_list() {
if (get_icon_func) {
Ref<Texture2D> icon = get_icon_func(base_dir.plus_file(files.front()->get()));
ti->set_icon(0, icon);
+ } else {
+ ti->set_icon(0, file_icon);
}
+ ti->set_icon_modulate(0, file_color);
if (mode == FILE_MODE_OPEN_DIR) {
ti->set_custom_color(0, vbox->get_theme_color("files_disabled", "FileDialog"));
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp
index fbacb3ed9e..ee6783167a 100644
--- a/scene/gui/line_edit.cpp
+++ b/scene/gui/line_edit.cpp
@@ -1211,6 +1211,8 @@ void LineEdit::delete_char() {
}
void LineEdit::delete_text(int p_from_column, int p_to_column) {
+ ERR_FAIL_COND_MSG(p_from_column < 0 || p_from_column > p_to_column || p_to_column > text.length(),
+ vformat("Positional parameters (from: %d, to: %d) are inverted or outside the text length (%d).", p_from_column, p_to_column, text.length()));
if (text.size() > 0) {
Ref<Font> font = get_theme_font("font");
if (font != nullptr) {
@@ -1783,6 +1785,8 @@ void LineEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_max_length", "chars"), &LineEdit::set_max_length);
ClassDB::bind_method(D_METHOD("get_max_length"), &LineEdit::get_max_length);
ClassDB::bind_method(D_METHOD("append_at_cursor", "text"), &LineEdit::append_at_cursor);
+ ClassDB::bind_method(D_METHOD("delete_char_at_cursor"), &LineEdit::delete_char);
+ ClassDB::bind_method(D_METHOD("delete_text", "from_column", "to_column"), &LineEdit::delete_text);
ClassDB::bind_method(D_METHOD("set_editable", "enabled"), &LineEdit::set_editable);
ClassDB::bind_method(D_METHOD("is_editable"), &LineEdit::is_editable);
ClassDB::bind_method(D_METHOD("set_secret", "enabled"), &LineEdit::set_secret);
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index a57408b83b..92508f7fd2 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -256,6 +256,11 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
lh = line < l.height_caches.size() ? l.height_caches[line] : 1; \
line_ascent = line < l.ascent_caches.size() ? l.ascent_caches[line] : 1; \
line_descent = line < l.descent_caches.size() ? l.descent_caches[line] : 1; \
+ if (p_mode == PROCESS_DRAW) { \
+ if (line < l.offset_caches.size()) { \
+ wofs = l.offset_caches[line]; \
+ } \
+ } \
} \
if (p_mode == PROCESS_POINTER && r_click_item && p_click_pos.y >= p_ofs.y + y && p_click_pos.y <= p_ofs.y + y + lh && p_click_pos.x < p_ofs.x + wofs) { \
if (r_outside) \
@@ -646,7 +651,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
}
if (p_mode == PROCESS_DRAW && visible) {
- img->image->draw_rect(ci, Rect2(p_ofs + Point2(align_ofs + wofs, y + lh - font->get_descent() - img->size.height), img->size));
+ img->image->draw_rect(ci, Rect2(p_ofs + Point2(align_ofs + wofs, y + lh - font->get_descent() - img->size.height), img->size), false, img->color);
}
p_char_count++;
@@ -873,7 +878,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
}
void RichTextLabel::_scroll_changed(double) {
- if (updating_scroll || !scroll_active) {
+ if (updating_scroll) {
return;
}
@@ -1443,6 +1448,46 @@ void RichTextLabel::_fetch_item_fx_stack(Item *p_item, Vector<ItemFX *> &r_stack
}
}
+Color RichTextLabel::_get_color_from_string(const String &p_color_str, const Color &p_default_color) {
+ if (p_color_str.begins_with("#")) {
+ return Color::html(p_color_str);
+ } else if (p_color_str == "aqua") {
+ return Color(0, 1, 1);
+ } else if (p_color_str == "black") {
+ return Color(0, 0, 0);
+ } else if (p_color_str == "blue") {
+ return Color(0, 0, 1);
+ } else if (p_color_str == "fuchsia") {
+ return Color(1, 0, 1);
+ } else if (p_color_str == "gray" || p_color_str == "grey") {
+ return Color(0.5, 0.5, 0.5);
+ } else if (p_color_str == "green") {
+ return Color(0, 0.5, 0);
+ } else if (p_color_str == "lime") {
+ return Color(0, 1, 0);
+ } else if (p_color_str == "maroon") {
+ return Color(0.5, 0, 0);
+ } else if (p_color_str == "navy") {
+ return Color(0, 0, 0.5);
+ } else if (p_color_str == "olive") {
+ return Color(0.5, 0.5, 0);
+ } else if (p_color_str == "purple") {
+ return Color(0.5, 0, 0.5);
+ } else if (p_color_str == "red") {
+ return Color(1, 0, 0);
+ } else if (p_color_str == "silver") {
+ return Color(0.75, 0.75, 0.75);
+ } else if (p_color_str == "teal") {
+ return Color(0, 0.5, 0.5);
+ } else if (p_color_str == "white") {
+ return Color(1, 1, 1);
+ } else if (p_color_str == "yellow") {
+ return Color(1, 1, 0);
+ } else {
+ return p_default_color;
+ }
+}
+
bool RichTextLabel::_find_meta(Item *p_item, Variant *r_meta, ItemMeta **r_item) {
Item *item = p_item;
@@ -1636,7 +1681,7 @@ void RichTextLabel::_remove_item(Item *p_item, const int p_line, const int p_sub
}
}
-void RichTextLabel::add_image(const Ref<Texture2D> &p_image, const int p_width, const int p_height) {
+void RichTextLabel::add_image(const Ref<Texture2D> &p_image, const int p_width, const int p_height, const Color &p_color) {
if (current->type == ITEM_TABLE) {
return;
}
@@ -1645,6 +1690,7 @@ void RichTextLabel::add_image(const Ref<Texture2D> &p_image, const int p_width,
ItemImage *item = memnew(ItemImage);
item->image = p_image;
+ item->color = p_color;
if (p_width > 0) {
// custom width
@@ -1924,6 +1970,9 @@ void RichTextLabel::clear() {
selection.click = nullptr;
selection.active = false;
current_idx = 1;
+ if (scroll_follow) {
+ scroll_following = true;
+ }
if (fixed_width != -1) {
minimum_size_changed();
@@ -1967,6 +2016,7 @@ void RichTextLabel::set_scroll_active(bool p_active) {
}
scroll_active = p_active;
+ vscroll->set_drag_node_enabled(p_active);
update();
}
@@ -2034,7 +2084,32 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) {
String tag = p_bbcode.substr(brk_pos + 1, brk_end - brk_pos - 1);
Vector<String> split_tag_block = tag.split(" ", false);
- String bbcode = !split_tag_block.empty() ? split_tag_block[0] : "";
+
+ // Find optional parameters.
+ String bbcode_name;
+ typedef Map<String, String> OptionMap;
+ OptionMap bbcode_options;
+ if (!split_tag_block.empty()) {
+ bbcode_name = split_tag_block[0];
+ for (int i = 1; i < split_tag_block.size(); i++) {
+ const String &expr = split_tag_block[i];
+ int value_pos = expr.find("=");
+ if (value_pos > -1) {
+ bbcode_options[expr.substr(0, value_pos)] = expr.substr(value_pos + 1);
+ }
+ }
+ } else {
+ bbcode_name = tag;
+ }
+
+ // Find main parameter.
+ String bbcode_value;
+ int main_value_pos = bbcode_name.find("=");
+ if (main_value_pos > -1) {
+ bbcode_value = bbcode_name.substr(main_value_pos + 1);
+ bbcode_name = bbcode_name.substr(0, main_value_pos);
+ }
+
if (tag.begins_with("/") && tag_stack.size()) {
bool tag_ok = tag_stack.size() && tag_stack.front()->get() == tag.substr(1, tag.length());
@@ -2160,7 +2235,7 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) {
push_meta(url);
pos = brk_end + 1;
tag_stack.push_front("url");
- } else if (tag == "img") {
+ } else if (bbcode_name == "img") {
int end = p_bbcode.find("[", brk_end);
if (end == -1) {
end = p_bbcode.length();
@@ -2170,80 +2245,42 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) {
Ref<Texture2D> texture = ResourceLoader::load(image, "Texture2D");
if (texture.is_valid()) {
- add_image(texture);
- }
-
- pos = end;
- tag_stack.push_front(tag);
- } else if (tag.begins_with("img=")) {
- int width = 0;
- int height = 0;
-
- String params = tag.substr(4, tag.length());
- int sep = params.find("x");
- if (sep == -1) {
- width = params.to_int();
- } else {
- width = params.substr(0, sep).to_int();
- height = params.substr(sep + 1, params.length()).to_int();
- }
+ Color color = Color(1.0, 1.0, 1.0);
+ OptionMap::Element *color_option = bbcode_options.find("color");
+ if (color_option) {
+ color = _get_color_from_string(color_option->value(), color);
+ }
- int end = p_bbcode.find("[", brk_end);
- if (end == -1) {
- end = p_bbcode.length();
- }
+ int width = 0;
+ int height = 0;
+ if (!bbcode_value.empty()) {
+ int sep = bbcode_value.find("x");
+ if (sep == -1) {
+ width = bbcode_value.to_int();
+ } else {
+ width = bbcode_value.substr(0, sep).to_int();
+ height = bbcode_value.substr(sep + 1).to_int();
+ }
+ } else {
+ OptionMap::Element *width_option = bbcode_options.find("width");
+ if (width_option) {
+ width = width_option->value().to_int();
+ }
- String image = p_bbcode.substr(brk_end + 1, end - brk_end - 1);
+ OptionMap::Element *height_option = bbcode_options.find("height");
+ if (height_option) {
+ height = height_option->value().to_int();
+ }
+ }
- Ref<Texture2D> texture = ResourceLoader::load(image, "Texture");
- if (texture.is_valid()) {
- add_image(texture, width, height);
+ add_image(texture, width, height, color);
}
pos = end;
- tag_stack.push_front("img");
+ tag_stack.push_front(bbcode_name);
} else if (tag.begins_with("color=")) {
- String col = tag.substr(6, tag.length());
- Color color;
-
- if (col.begins_with("#")) {
- color = Color::html(col);
- } else if (col == "aqua") {
- color = Color(0, 1, 1);
- } else if (col == "black") {
- color = Color(0, 0, 0);
- } else if (col == "blue") {
- color = Color(0, 0, 1);
- } else if (col == "fuchsia") {
- color = Color(1, 0, 1);
- } else if (col == "gray" || col == "grey") {
- color = Color(0.5, 0.5, 0.5);
- } else if (col == "green") {
- color = Color(0, 0.5, 0);
- } else if (col == "lime") {
- color = Color(0, 1, 0);
- } else if (col == "maroon") {
- color = Color(0.5, 0, 0);
- } else if (col == "navy") {
- color = Color(0, 0, 0.5);
- } else if (col == "olive") {
- color = Color(0.5, 0.5, 0);
- } else if (col == "purple") {
- color = Color(0.5, 0, 0.5);
- } else if (col == "red") {
- color = Color(1, 0, 0);
- } else if (col == "silver") {
- color = Color(0.75, 0.75, 0.75);
- } else if (col == "teal") {
- color = Color(0, 0.5, 0.5);
- } else if (col == "white") {
- color = Color(1, 1, 1);
- } else if (col == "yellow") {
- color = Color(1, 1, 0);
- } else {
- color = base_color;
- }
-
+ String color_str = tag.substr(6, tag.length());
+ Color color = _get_color_from_string(color_str, base_color);
push_color(color);
pos = brk_end + 1;
tag_stack.push_front("color");
@@ -2261,113 +2298,90 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) {
pos = brk_end + 1;
tag_stack.push_front("font");
- } else if (bbcode == "fade") {
- int startIndex = 0;
- int length = 10;
+ } else if (bbcode_name == "fade") {
+ int start_index = 0;
+ OptionMap::Element *start_option = bbcode_options.find("start");
+ if (start_option) {
+ start_index = start_option->value().to_int();
+ }
- if (split_tag_block.size() > 1) {
- split_tag_block.remove(0);
- for (int i = 0; i < split_tag_block.size(); i++) {
- String expr = split_tag_block[i];
- if (expr.begins_with("start=")) {
- String start_str = expr.substr(6, expr.length());
- startIndex = start_str.to_int();
- } else if (expr.begins_with("length=")) {
- String end_str = expr.substr(7, expr.length());
- length = end_str.to_int();
- }
- }
+ int length = 10;
+ OptionMap::Element *length_option = bbcode_options.find("length");
+ if (length_option) {
+ length = length_option->value().to_int();
}
- push_fade(startIndex, length);
+ push_fade(start_index, length);
pos = brk_end + 1;
tag_stack.push_front("fade");
- } else if (bbcode == "shake") {
+ } else if (bbcode_name == "shake") {
int strength = 5;
- float rate = 20.0f;
+ OptionMap::Element *strength_option = bbcode_options.find("level");
+ if (strength_option) {
+ strength = strength_option->value().to_int();
+ }
- if (split_tag_block.size() > 1) {
- split_tag_block.remove(0);
- for (int i = 0; i < split_tag_block.size(); i++) {
- String expr = split_tag_block[i];
- if (expr.begins_with("level=")) {
- String str_str = expr.substr(6, expr.length());
- strength = str_str.to_int();
- } else if (expr.begins_with("rate=")) {
- String rate_str = expr.substr(5, expr.length());
- rate = rate_str.to_float();
- }
- }
+ float rate = 20.0f;
+ OptionMap::Element *rate_option = bbcode_options.find("rate");
+ if (rate_option) {
+ rate = rate_option->value().to_float();
}
push_shake(strength, rate);
pos = brk_end + 1;
tag_stack.push_front("shake");
set_process_internal(true);
- } else if (bbcode == "wave") {
+ } else if (bbcode_name == "wave") {
float amplitude = 20.0f;
- float period = 5.0f;
+ OptionMap::Element *amplitude_option = bbcode_options.find("amp");
+ if (amplitude_option) {
+ amplitude = amplitude_option->value().to_float();
+ }
- if (split_tag_block.size() > 1) {
- split_tag_block.remove(0);
- for (int i = 0; i < split_tag_block.size(); i++) {
- String expr = split_tag_block[i];
- if (expr.begins_with("amp=")) {
- String amp_str = expr.substr(4, expr.length());
- amplitude = amp_str.to_float();
- } else if (expr.begins_with("freq=")) {
- String period_str = expr.substr(5, expr.length());
- period = period_str.to_float();
- }
- }
+ float period = 5.0f;
+ OptionMap::Element *period_option = bbcode_options.find("freq");
+ if (period_option) {
+ period = period_option->value().to_float();
}
push_wave(period, amplitude);
pos = brk_end + 1;
tag_stack.push_front("wave");
set_process_internal(true);
- } else if (bbcode == "tornado") {
+ } else if (bbcode_name == "tornado") {
float radius = 10.0f;
- float frequency = 1.0f;
+ OptionMap::Element *radius_option = bbcode_options.find("radius");
+ if (radius_option) {
+ radius = radius_option->value().to_float();
+ }
- if (split_tag_block.size() > 1) {
- split_tag_block.remove(0);
- for (int i = 0; i < split_tag_block.size(); i++) {
- String expr = split_tag_block[i];
- if (expr.begins_with("radius=")) {
- String amp_str = expr.substr(7, expr.length());
- radius = amp_str.to_float();
- } else if (expr.begins_with("freq=")) {
- String period_str = expr.substr(5, expr.length());
- frequency = period_str.to_float();
- }
- }
+ float frequency = 1.0f;
+ OptionMap::Element *frequency_option = bbcode_options.find("freq");
+ if (frequency_option) {
+ frequency = frequency_option->value().to_float();
}
push_tornado(frequency, radius);
pos = brk_end + 1;
tag_stack.push_front("tornado");
set_process_internal(true);
- } else if (bbcode == "rainbow") {
+ } else if (bbcode_name == "rainbow") {
float saturation = 0.8f;
+ OptionMap::Element *saturation_option = bbcode_options.find("sat");
+ if (saturation_option) {
+ saturation = saturation_option->value().to_float();
+ }
+
float value = 0.8f;
- float frequency = 1.0f;
+ OptionMap::Element *value_option = bbcode_options.find("val");
+ if (value_option) {
+ value = value_option->value().to_float();
+ }
- if (split_tag_block.size() > 1) {
- split_tag_block.remove(0);
- for (int i = 0; i < split_tag_block.size(); i++) {
- String expr = split_tag_block[i];
- if (expr.begins_with("sat=")) {
- String sat_str = expr.substr(4, expr.length());
- saturation = sat_str.to_float();
- } else if (expr.begins_with("val=")) {
- String val_str = expr.substr(4, expr.length());
- value = val_str.to_float();
- } else if (expr.begins_with("freq=")) {
- String freq_str = expr.substr(5, expr.length());
- frequency = freq_str.to_float();
- }
- }
+ float frequency = 1.0f;
+ OptionMap::Element *frequency_option = bbcode_options.find("freq");
+ if (frequency_option) {
+ frequency = frequency_option->value().to_float();
}
push_rainbow(saturation, value, frequency);
@@ -2398,6 +2412,17 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) {
}
}
+ Vector<ItemFX *> fx_items;
+ for (List<Item *>::Element *E = main->subitems.front(); E; E = E->next()) {
+ Item *subitem = static_cast<Item *>(E->get());
+ _fetch_item_fx_stack(subitem, fx_items);
+
+ if (fx_items.size()) {
+ set_process_internal(true);
+ break;
+ }
+ }
+
return OK;
}
@@ -2634,7 +2659,7 @@ void RichTextLabel::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_text"), &RichTextLabel::get_text);
ClassDB::bind_method(D_METHOD("add_text", "text"), &RichTextLabel::add_text);
ClassDB::bind_method(D_METHOD("set_text", "text"), &RichTextLabel::set_text);
- ClassDB::bind_method(D_METHOD("add_image", "image", "width", "height"), &RichTextLabel::add_image, DEFVAL(0), DEFVAL(0));
+ ClassDB::bind_method(D_METHOD("add_image", "image", "width", "height", "color"), &RichTextLabel::add_image, DEFVAL(0), DEFVAL(0), DEFVAL(Color(1.0, 1.0, 1.0)));
ClassDB::bind_method(D_METHOD("newline"), &RichTextLabel::add_newline);
ClassDB::bind_method(D_METHOD("remove_line", "line"), &RichTextLabel::remove_line);
ClassDB::bind_method(D_METHOD("push_font", "font"), &RichTextLabel::push_font);
diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h
index 019edf5d45..4cec435568 100644
--- a/scene/gui/rich_text_label.h
+++ b/scene/gui/rich_text_label.h
@@ -149,6 +149,7 @@ private:
struct ItemImage : public Item {
Ref<Texture2D> image;
Size2 size;
+ Color color;
ItemImage() { type = ITEM_IMAGE; }
};
@@ -381,6 +382,8 @@ private:
bool _find_by_type(Item *p_item, ItemType p_type);
void _fetch_item_fx_stack(Item *p_item, Vector<ItemFX *> &r_stack);
+ static Color _get_color_from_string(const String &p_color_str, const Color &p_default_color);
+
void _update_scroll();
void _update_fx(ItemFrame *p_frame, float p_delta_time);
void _scroll_changed(double);
@@ -406,7 +409,7 @@ protected:
public:
String get_text();
void add_text(const String &p_text);
- void add_image(const Ref<Texture2D> &p_image, const int p_width = 0, const int p_height = 0);
+ void add_image(const Ref<Texture2D> &p_image, const int p_width = 0, const int p_height = 0, const Color &p_color = Color(1.0, 1.0, 1.0));
void add_newline();
bool remove_line(const int p_line);
void push_font(const Ref<Font> &p_font);
diff --git a/scene/gui/scroll_bar.cpp b/scene/gui/scroll_bar.cpp
index e7950bec98..4db6ca2949 100644
--- a/scene/gui/scroll_bar.cpp
+++ b/scene/gui/scroll_bar.cpp
@@ -506,6 +506,10 @@ void ScrollBar::_drag_node_exit() {
}
void ScrollBar::_drag_node_input(const Ref<InputEvent> &p_input) {
+ if (!drag_node_enabled) {
+ return;
+ }
+
Ref<InputEventMouseButton> mb = p_input;
if (mb.is_valid()) {
@@ -590,6 +594,10 @@ NodePath ScrollBar::get_drag_node() const {
return drag_node_path;
}
+void ScrollBar::set_drag_node_enabled(bool p_enable) {
+ drag_node_enabled = p_enable;
+}
+
void ScrollBar::set_smooth_scroll_enabled(bool p_enable) {
smooth_scroll_enabled = p_enable;
}
@@ -610,19 +618,6 @@ void ScrollBar::_bind_methods() {
ScrollBar::ScrollBar(Orientation p_orientation) {
orientation = p_orientation;
- highlight = HIGHLIGHT_NONE;
- custom_step = -1;
- drag_node = nullptr;
-
- drag.active = false;
-
- drag_node_speed = Vector2();
- drag_node_touching = false;
- drag_node_touching_deaccel = false;
-
- scrolling = false;
- target_scroll = 0;
- smooth_scroll_enabled = false;
if (focus_by_default) {
set_focus_mode(FOCUS_ALL);
diff --git a/scene/gui/scroll_bar.h b/scene/gui/scroll_bar.h
index d2641b14f3..23ee61d9e1 100644
--- a/scene/gui/scroll_bar.h
+++ b/scene/gui/scroll_bar.h
@@ -47,12 +47,12 @@ class ScrollBar : public Range {
Orientation orientation;
Size2 size;
- float custom_step;
+ float custom_step = -1;
- HighlightStatus highlight;
+ HighlightStatus highlight = HIGHLIGHT_NONE;
struct Drag {
- bool active;
+ bool active = false;
float pos_at_click;
float value_at_click;
} drag;
@@ -66,22 +66,23 @@ class ScrollBar : public Range {
static void set_can_focus_by_default(bool p_can_focus);
- Node *drag_node;
+ Node *drag_node = nullptr;
NodePath drag_node_path;
+ bool drag_node_enabled = true;
- Vector2 drag_node_speed;
+ Vector2 drag_node_speed = Vector2();
Vector2 drag_node_accum;
Vector2 drag_node_from;
Vector2 last_drag_node_accum;
float last_drag_node_time;
float time_since_motion;
- bool drag_node_touching;
- bool drag_node_touching_deaccel;
+ bool drag_node_touching = false;
+ bool drag_node_touching_deaccel = false;
bool click_handled;
- bool scrolling;
- double target_scroll;
- bool smooth_scroll_enabled;
+ bool scrolling = false;
+ double target_scroll = 0;
+ bool smooth_scroll_enabled = false;
void _drag_node_exit();
void _drag_node_input(const Ref<InputEvent> &p_input);
@@ -99,6 +100,7 @@ public:
void set_drag_node(const NodePath &p_path);
NodePath get_drag_node() const;
+ void set_drag_node_enabled(bool p_enable);
void set_smooth_scroll_enabled(bool p_enable);
bool is_smooth_scroll_enabled() const;
diff --git a/scene/gui/tab_container.cpp b/scene/gui/tab_container.cpp
index 97b8362214..0d48fde642 100644
--- a/scene/gui/tab_container.cpp
+++ b/scene/gui/tab_container.cpp
@@ -278,7 +278,7 @@ void TabContainer::_notification(int p_what) {
Color font_color_bg = get_theme_color("font_color_bg");
Color font_color_disabled = get_theme_color("font_color_disabled");
int side_margin = get_theme_constant("side_margin");
- int icon_text_distance = get_theme_constant("hseparation");
+ int icon_text_distance = get_theme_constant("icon_separation");
// Find out start and width of the header area.
int header_x = side_margin;
@@ -435,7 +435,30 @@ void TabContainer::_notification(int p_what) {
void TabContainer::_on_theme_changed() {
if (get_tab_count() > 0) {
- set_current_tab(get_current_tab());
+ _repaint();
+ update();
+ }
+}
+
+void TabContainer::_repaint() {
+ Ref<StyleBox> sb = get_theme_stylebox("panel");
+ Vector<Control *> tabs = _get_tabs();
+ for (int i = 0; i < tabs.size(); i++) {
+ Control *c = tabs[i];
+ if (i == current) {
+ c->show();
+ c->set_anchors_and_margins_preset(Control::PRESET_WIDE);
+ if (tabs_visible) {
+ c->set_margin(MARGIN_TOP, _get_top_margin());
+ }
+ c->set_margin(Margin(MARGIN_TOP), c->get_margin(Margin(MARGIN_TOP)) + sb->get_margin(Margin(MARGIN_TOP)));
+ c->set_margin(Margin(MARGIN_LEFT), c->get_margin(Margin(MARGIN_LEFT)) + sb->get_margin(Margin(MARGIN_LEFT)));
+ c->set_margin(Margin(MARGIN_RIGHT), c->get_margin(Margin(MARGIN_RIGHT)) - sb->get_margin(Margin(MARGIN_RIGHT)));
+ c->set_margin(Margin(MARGIN_BOTTOM), c->get_margin(Margin(MARGIN_BOTTOM)) - sb->get_margin(Margin(MARGIN_BOTTOM)));
+
+ } else {
+ c->hide();
+ }
}
}
@@ -465,7 +488,7 @@ int TabContainer::_get_tab_width(int p_index) const {
if (icon.is_valid()) {
width += icon->get_width();
if (text != "") {
- width += get_theme_constant("hseparation");
+ width += get_theme_constant("icon_separation");
}
}
}
@@ -551,25 +574,7 @@ void TabContainer::set_current_tab(int p_current) {
int pending_previous = current;
current = p_current;
- Ref<StyleBox> sb = get_theme_stylebox("panel");
- Vector<Control *> tabs = _get_tabs();
- for (int i = 0; i < tabs.size(); i++) {
- Control *c = tabs[i];
- if (i == current) {
- c->show();
- c->set_anchors_and_margins_preset(Control::PRESET_WIDE);
- if (tabs_visible) {
- c->set_margin(MARGIN_TOP, _get_top_margin());
- }
- c->set_margin(Margin(MARGIN_TOP), c->get_margin(Margin(MARGIN_TOP)) + sb->get_margin(Margin(MARGIN_TOP)));
- c->set_margin(Margin(MARGIN_LEFT), c->get_margin(Margin(MARGIN_LEFT)) + sb->get_margin(Margin(MARGIN_LEFT)));
- c->set_margin(Margin(MARGIN_RIGHT), c->get_margin(Margin(MARGIN_RIGHT)) - sb->get_margin(Margin(MARGIN_RIGHT)));
- c->set_margin(Margin(MARGIN_BOTTOM), c->get_margin(Margin(MARGIN_BOTTOM)) - sb->get_margin(Margin(MARGIN_BOTTOM)));
-
- } else {
- c->hide();
- }
- }
+ _repaint();
_change_notify("current_tab");
diff --git a/scene/gui/tab_container.h b/scene/gui/tab_container.h
index e8cde74c83..55a5d35b30 100644
--- a/scene/gui/tab_container.h
+++ b/scene/gui/tab_container.h
@@ -65,6 +65,7 @@ private:
Vector<Control *> _get_tabs() const;
int _get_tab_width(int p_index) const;
void _on_theme_changed();
+ void _repaint();
void _on_mouse_exited();
void _update_current_tab();
diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp
index 45fcb448f8..7b9db7c081 100644
--- a/scene/gui/tree.cpp
+++ b/scene/gui/tree.cpp
@@ -2364,7 +2364,6 @@ void Tree::_gui_input(Ref<InputEvent> p_event) {
if (pos.x < len) {
cache.hover_type = Cache::CLICK_TITLE;
cache.hover_index = i;
- update();
break;
}
}
@@ -2383,6 +2382,9 @@ void Tree::_gui_input(Ref<InputEvent> p_event) {
mpos.y += v_scroll->get_value();
}
+ TreeItem *old_it = cache.hover_item;
+ int old_col = cache.hover_cell;
+
int col, h, section;
TreeItem *it = _find_item_at_pos(root, mpos, col, h, section);
@@ -2397,18 +2399,21 @@ void Tree::_gui_input(Ref<InputEvent> p_event) {
}
}
- if (it != cache.hover_item) {
- cache.hover_item = it;
- update();
- }
+ cache.hover_item = it;
+ cache.hover_cell = col;
- if (it && col != cache.hover_cell) {
- cache.hover_cell = col;
- update();
+ if (it != old_it || col != old_col) {
+ // Only need to update if mouse enters/exits a button
+ bool was_over_button = old_it && old_it->cells[old_col].custom_button;
+ bool is_over_button = it && it->cells[col].custom_button;
+ if (was_over_button || is_over_button) {
+ update();
+ }
}
}
}
+ // Update if mouse enters/exits columns
if (cache.hover_type != old_hover || cache.hover_index != old_index) {
update();
}