summaryrefslogtreecommitdiff
path: root/scene/gui
diff options
context:
space:
mode:
Diffstat (limited to 'scene/gui')
-rw-r--r--scene/gui/base_button.cpp5
-rw-r--r--scene/gui/color_picker.cpp51
-rw-r--r--scene/gui/color_picker.h3
-rw-r--r--scene/gui/gradient_edit.cpp7
-rw-r--r--scene/gui/grid_container.cpp24
-rw-r--r--scene/gui/item_list.cpp38
-rw-r--r--scene/gui/item_list.h2
-rw-r--r--scene/gui/rich_text_label.cpp11
-rw-r--r--scene/gui/tabs.cpp2
-rw-r--r--scene/gui/text_edit.cpp16
-rw-r--r--scene/gui/texture_progress.cpp55
-rw-r--r--scene/gui/tree.cpp2
12 files changed, 149 insertions, 67 deletions
diff --git a/scene/gui/base_button.cpp b/scene/gui/base_button.cpp
index 5f541ea16a..562dd155f9 100644
--- a/scene/gui/base_button.cpp
+++ b/scene/gui/base_button.cpp
@@ -211,6 +211,11 @@ void BaseButton::_gui_input(Ref<InputEvent> p_event) {
if (!toggle_mode) { //mouse press attempt
pressed();
+ if (get_script_instance()) {
+ Variant::CallError ce;
+ get_script_instance()->call(SceneStringNames::get_singleton()->_pressed, NULL, 0, ce);
+ }
+
emit_signal("pressed");
} else {
diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp
index 30bcc48149..31be18612f 100644
--- a/scene/gui/color_picker.cpp
+++ b/scene/gui/color_picker.cpp
@@ -77,8 +77,7 @@ void ColorPicker::_notification(int p_what) {
void ColorPicker::set_focus_on_line_edit() {
- c_text->grab_focus();
- c_text->select();
+ c_text->call_deferred("grab_focus");
}
void ColorPicker::_update_controls() {
@@ -159,14 +158,16 @@ void ColorPicker::_update_color() {
updating = true;
for (int i = 0; i < 4; i++) {
- scroll[i]->set_max(255);
scroll[i]->set_step(0.01);
if (raw_mode_enabled) {
+ scroll[i]->set_max(100);
if (i == 3)
scroll[i]->set_max(1);
scroll[i]->set_value(color.components[i]);
} else {
- scroll[i]->set_value(color.components[i] * 255);
+ const int byte_value = color.components[i] * 255;
+ scroll[i]->set_max(next_power_of_2(MAX(255, byte_value)) - 1);
+ scroll[i]->set_value(byte_value);
}
}
@@ -242,6 +243,7 @@ bool ColorPicker::is_raw_mode() const {
}
void ColorPicker::_update_text_value() {
+ bool visible = true;
if (text_is_constructor) {
String t = "Color(" + String::num(color.r) + "," + String::num(color.g) + "," + String::num(color.b);
if (edit_alpha && color.a < 1)
@@ -250,8 +252,13 @@ void ColorPicker::_update_text_value() {
t += ")";
c_text->set_text(t);
} else {
- c_text->set_text(color.to_html(edit_alpha && color.a < 1));
+ if (color.r > 1 || color.g > 1 || color.b > 1 || color.r < 0 || color.g < 0 || color.b < 0) {
+ visible = false;
+ } else {
+ c_text->set_text(color.to_html(edit_alpha && color.a < 1));
+ }
}
+ c_text->set_visible(visible);
}
void ColorPicker::_sample_draw() {
@@ -462,6 +469,31 @@ void ColorPicker::_screen_pick_pressed() {
screen->show_modal();
}
+void ColorPicker::_focus_enter() {
+ if (c_text->has_focus()) {
+ c_text->select_all();
+ return;
+ }
+ for (int i = 0; i < 4; i++) {
+ if (values[i]->get_line_edit()->has_focus()) {
+ values[i]->get_line_edit()->select_all();
+ break;
+ }
+ }
+}
+
+void ColorPicker::_focus_exit() {
+ for (int i = 0; i < 4; i++) {
+ values[i]->get_line_edit()->select(0, 0);
+ }
+ c_text->select(0, 0);
+}
+
+void ColorPicker::_html_focus_exit() {
+ _html_entered(c_text->get_text());
+ _focus_exit();
+}
+
void ColorPicker::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_pick_color", "color"), &ColorPicker::set_pick_color);
@@ -483,6 +515,9 @@ void ColorPicker::_bind_methods() {
ClassDB::bind_method(D_METHOD("_w_input"), &ColorPicker::_w_input);
ClassDB::bind_method(D_METHOD("_preset_input"), &ColorPicker::_preset_input);
ClassDB::bind_method(D_METHOD("_screen_input"), &ColorPicker::_screen_input);
+ ClassDB::bind_method(D_METHOD("_focus_enter"), &ColorPicker::_focus_enter);
+ ClassDB::bind_method(D_METHOD("_focus_exit"), &ColorPicker::_focus_exit);
+ ClassDB::bind_method(D_METHOD("_html_focus_exit"), &ColorPicker::_html_focus_exit);
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_pick_color", "get_pick_color");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "edit_alpha"), "set_edit_alpha", "is_editing_alpha");
@@ -559,11 +594,14 @@ ColorPicker::ColorPicker() :
scroll[i] = memnew(HSlider);
scroll[i]->set_v_size_flags(SIZE_SHRINK_CENTER);
+ scroll[i]->set_focus_mode(FOCUS_NONE);
hbc->add_child(scroll[i]);
values[i] = memnew(SpinBox);
scroll[i]->share(values[i]);
hbc->add_child(values[i]);
+ values[i]->get_line_edit()->connect("focus_entered", this, "_focus_enter");
+ values[i]->get_line_edit()->connect("focus_exited", this, "_focus_exit");
scroll[i]->set_min(0);
scroll[i]->set_page(0);
@@ -589,6 +627,9 @@ ColorPicker::ColorPicker() :
c_text = memnew(LineEdit);
hhb->add_child(c_text);
c_text->connect("text_entered", this, "_html_entered");
+ c_text->connect("focus_entered", this, "_focus_enter");
+ c_text->connect("focus_exited", this, "_html_focus_exit");
+
text_type->set_text("#");
c_text->set_h_size_flags(SIZE_EXPAND_FILL);
diff --git a/scene/gui/color_picker.h b/scene/gui/color_picker.h
index 01ae1cc464..40ded4fff5 100644
--- a/scene/gui/color_picker.h
+++ b/scene/gui/color_picker.h
@@ -88,6 +88,9 @@ private:
void _screen_input(const Ref<InputEvent> &p_event);
void _add_preset_pressed();
void _screen_pick_pressed();
+ void _focus_enter();
+ void _focus_exit();
+ void _html_focus_exit();
protected:
void _notification(int);
diff --git a/scene/gui/gradient_edit.cpp b/scene/gui/gradient_edit.cpp
index 3985039716..9fc8e98a7f 100644
--- a/scene/gui/gradient_edit.cpp
+++ b/scene/gui/gradient_edit.cpp
@@ -367,6 +367,13 @@ void GradientEdit::_notification(int p_what) {
draw_line(Vector2(-1, -1), Vector2(-1, h + 1), Color(1, 1, 1, 0.6));
}
}
+
+ if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
+
+ if (!is_visible()) {
+ grabbing = false;
+ }
+ }
}
void GradientEdit::_draw_checker(int x, int y, int w, int h) {
diff --git a/scene/gui/grid_container.cpp b/scene/gui/grid_container.cpp
index c2b8a7dfab..9948672097 100644
--- a/scene/gui/grid_container.cpp
+++ b/scene/gui/grid_container.cpp
@@ -36,10 +36,10 @@ void GridContainer::_notification(int p_what) {
case NOTIFICATION_SORT_CHILDREN: {
- Map<int, int> col_minw;
- Map<int, int> row_minh;
- Set<int> col_expanded;
- Set<int> row_expanded;
+ Map<int, int> col_minw; // max of min_width of all controls in each col (indexed by col)
+ Map<int, int> row_minh; // max of min_height of all controls in each row (indexed by row)
+ Set<int> col_expanded; // columns which have the SIZE_EXPAND flag set
+ Set<int> row_expanded; // rows which have the SIZE_EXPAND flag set
int hsep = get_constant("hseparation");
int vsep = get_constant("vseparation");
@@ -88,13 +88,13 @@ void GridContainer::_notification(int p_what) {
remaining_space.width -= hsep * (max_col - 1);
bool can_fit = false;
- while (!can_fit) {
+ while (!can_fit && col_expanded.size() > 0) {
// Check if all minwidth constraints are ok if we use the remaining space
can_fit = true;
- int max_index = 0;
+ int max_index = col_expanded.front()->get();
for (Set<int>::Element *E = col_expanded.front(); E; E = E->next()) {
if (col_minw[E->get()] > col_minw[max_index]) {
- max_index = col_minw[E->get()];
+ max_index = E->get();
}
if (can_fit && (remaining_space.width / col_expanded.size()) < col_minw[E->get()]) {
can_fit = false;
@@ -109,13 +109,13 @@ void GridContainer::_notification(int p_what) {
}
can_fit = false;
- while (!can_fit) {
+ while (!can_fit && row_expanded.size() > 0) {
// Check if all minwidth constraints are ok if we use the remaining space
can_fit = true;
- int max_index = 0;
+ int max_index = row_expanded.front()->get();
for (Set<int>::Element *E = row_expanded.front(); E; E = E->next()) {
if (row_minh[E->get()] > row_minh[max_index]) {
- max_index = row_minh[E->get()];
+ max_index = E->get();
}
if (can_fit && (remaining_space.height / row_expanded.size()) < row_minh[E->get()]) {
can_fit = false;
@@ -130,8 +130,8 @@ void GridContainer::_notification(int p_what) {
}
// Finally, fit the nodes
- int col_expand = remaining_space.width / col_expanded.size();
- int row_expand = remaining_space.height / row_expanded.size();
+ int col_expand = col_expanded.size() > 0 ? remaining_space.width / col_expanded.size() : 0;
+ int row_expand = row_expanded.size() > 0 ? remaining_space.height / row_expanded.size() : 0;
int col_ofs = 0;
int row_ofs = 0;
diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp
index f7574ca2cd..cc17e6bcd8 100644
--- a/scene/gui/item_list.cpp
+++ b/scene/gui/item_list.cpp
@@ -295,35 +295,21 @@ int ItemList::get_current() const {
return current;
}
-void ItemList::move_item(int p_item, int p_to_pos) {
+void ItemList::move_item(int p_from_idx, int p_to_idx) {
- ERR_FAIL_INDEX(p_item, items.size());
- ERR_FAIL_INDEX(p_to_pos, items.size() + 1);
+ ERR_FAIL_INDEX(p_from_idx, items.size());
+ ERR_FAIL_INDEX(p_to_idx, items.size());
- Item it = items[p_item];
- items.remove(p_item);
-
- if (p_to_pos > p_item) {
- p_to_pos--;
+ if (is_anything_selected() && get_selected_items()[0] == p_from_idx) {
+ current = p_to_idx;
}
- if (p_to_pos >= items.size()) {
- items.push_back(it);
- } else {
- items.insert(p_to_pos, it);
- }
-
- if (current < 0) {
- //do none
- } else if (p_item == current) {
- current = p_to_pos;
- } else if (p_to_pos > p_item && current > p_item && current < p_to_pos) {
- current--;
- } else if (p_to_pos < p_item && current < p_item && current > p_to_pos) {
- current++;
- }
+ Item item = items[p_from_idx];
+ items.remove(p_from_idx);
+ items.insert(p_to_idx, item);
update();
+ shape_changed = true;
}
int ItemList::get_item_count() const {
@@ -1423,9 +1409,13 @@ void ItemList::_bind_methods() {
ClassDB::bind_method(D_METHOD("select", "idx", "single"), &ItemList::select, DEFVAL(true));
ClassDB::bind_method(D_METHOD("unselect", "idx"), &ItemList::unselect);
+ ClassDB::bind_method(D_METHOD("unselect_all"), &ItemList::unselect_all);
+
ClassDB::bind_method(D_METHOD("is_selected", "idx"), &ItemList::is_selected);
ClassDB::bind_method(D_METHOD("get_selected_items"), &ItemList::get_selected_items);
+ ClassDB::bind_method(D_METHOD("move_item", "p_from_idx", "p_to_idx"), &ItemList::move_item);
+
ClassDB::bind_method(D_METHOD("get_item_count"), &ItemList::get_item_count);
ClassDB::bind_method(D_METHOD("remove_item", "idx"), &ItemList::remove_item);
@@ -1465,6 +1455,8 @@ void ItemList::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_auto_height", "enable"), &ItemList::set_auto_height);
ClassDB::bind_method(D_METHOD("has_auto_height"), &ItemList::has_auto_height);
+ ClassDB::bind_method(D_METHOD("is_anything_selected"), &ItemList::is_anything_selected);
+
ClassDB::bind_method(D_METHOD("get_item_at_position", "position", "exact"), &ItemList::get_item_at_position, DEFVAL(false));
ClassDB::bind_method(D_METHOD("ensure_current_is_visible"), &ItemList::ensure_current_is_visible);
diff --git a/scene/gui/item_list.h b/scene/gui/item_list.h
index 7f34a250bd..0fa0dd415b 100644
--- a/scene/gui/item_list.h
+++ b/scene/gui/item_list.h
@@ -169,7 +169,7 @@ public:
void set_current(int p_current);
int get_current() const;
- void move_item(int p_item, int p_to_pos);
+ void move_item(int p_from_idx, int p_to_idx);
int get_item_count() const;
void remove_item(int p_idx);
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index 381c6c75a5..5bc5d8e690 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -247,6 +247,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
int rchar = 0;
int lh = 0;
bool line_is_blank = true;
+ int fh = 0;
while (it) {
@@ -262,14 +263,9 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
const CharType *c = text->text.c_str();
const CharType *cf = c;
- int fh = font->get_height();
int ascent = font->get_ascent();
int descent = font->get_descent();
- line_ascent = MAX(line_ascent, ascent);
- line_descent = MAX(line_descent, descent);
- fh = MAX(fh, line_ascent + line_descent); // various fonts!
-
Color color;
bool underline = false;
@@ -317,8 +313,13 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
end++;
}
+ CHECK_HEIGHT(fh);
ENSURE_WIDTH(w);
+ line_ascent = MAX(line_ascent, ascent);
+ line_descent = MAX(line_descent, descent);
+ fh = line_ascent + line_descent;
+
if (end && c[end - 1] == ' ') {
if (p_mode == PROCESS_CACHE) {
spaces_size += font->get_char_size(' ').width;
diff --git a/scene/gui/tabs.cpp b/scene/gui/tabs.cpp
index f0e89877cd..dee32aef7a 100644
--- a/scene/gui/tabs.cpp
+++ b/scene/gui/tabs.cpp
@@ -882,4 +882,6 @@ Tabs::Tabs() {
min_width = 0;
scrolling_enabled = true;
+ buttons_visible = false;
+ hover = -1;
}
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index 95d9173d39..48bd733e80 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -2141,9 +2141,12 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
if (completion_index > 0) {
completion_index--;
- completion_current = completion_options[completion_index];
- update();
+ } else {
+ completion_index = completion_options.size() - 1;
}
+ completion_current = completion_options[completion_index];
+ update();
+
accept_event();
return;
}
@@ -2152,9 +2155,12 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
if (completion_index < completion_options.size() - 1) {
completion_index++;
- completion_current = completion_options[completion_index];
- update();
+ } else {
+ completion_index = 0;
}
+ completion_current = completion_options[completion_index];
+ update();
+
accept_event();
return;
}
@@ -5232,7 +5238,7 @@ void TextEdit::_update_completion_candidates() {
} else {
- while (cofs > 0 && l[cofs - 1] > 32 && _is_completable(l[cofs - 1])) {
+ while (cofs > 0 && l[cofs - 1] > 32 && (l[cofs - 1] == '/' || _is_completable(l[cofs - 1]))) {
s = String::chr(l[cofs - 1]) + s;
if (l[cofs - 1] == '\'' || l[cofs - 1] == '"' || l[cofs - 1] == '$')
break;
diff --git a/scene/gui/texture_progress.cpp b/scene/gui/texture_progress.cpp
index 4a419098a0..4b3ba6df3c 100644
--- a/scene/gui/texture_progress.cpp
+++ b/scene/gui/texture_progress.cpp
@@ -117,22 +117,45 @@ Point2 TextureProgress::unit_val_to_uv(float val) {
Point2 p = get_relative_center();
- if (val < 0.125)
- return Point2(p.x + (1 - p.x) * val * 8, 0);
- if (val < 0.25)
- return Point2(1, p.y * (val - 0.125) * 8);
- if (val < 0.375)
- return Point2(1, p.y + (1 - p.y) * (val - 0.25) * 8);
- if (val < 0.5)
- return Point2(1 - (1 - p.x) * (val - 0.375) * 8, 1);
- if (val < 0.625)
- return Point2(p.x * (1 - (val - 0.5) * 8), 1);
- if (val < 0.75)
- return Point2(0, 1 - ((1 - p.y) * (val - 0.625) * 8));
- if (val < 0.875)
- return Point2(0, p.y - p.y * (val - 0.75) * 8);
- else
- return Point2(p.x * (val - 0.875) * 8, 0);
+ // Minimal version of Liang-Barsky clipping algorithm
+ float angle = (val * Math_TAU) - Math_PI * 0.5;
+ Point2 dir = Vector2(Math::cos(angle), Math::sin(angle));
+ float t1 = 1.0;
+ float cp;
+ float cq;
+ float cr;
+ float edgeLeft = 0.0;
+ float edgeRight = 1.0;
+ float edgeBottom = 0.0;
+ float edgeTop = 1.0;
+
+ for (int edge = 0; edge < 4; edge++) {
+ if (edge == 0) {
+ if (dir.x > 0)
+ continue;
+ cp = -dir.x;
+ cq = -(edgeLeft - p.x);
+ } else if (edge == 1) {
+ if (dir.x < 0)
+ continue;
+ cp = dir.x;
+ cq = (edgeRight - p.x);
+ } else if (edge == 2) {
+ if (dir.y > 0)
+ continue;
+ cp = -dir.y;
+ cq = -(edgeBottom - p.y);
+ } else if (edge == 3) {
+ if (dir.y < 0)
+ continue;
+ cp = dir.y;
+ cq = (edgeTop - p.y);
+ }
+ cr = cq / cp;
+ if (cr >= 0 && cr < t1)
+ t1 = cr;
+ }
+ return (p + t1 * dir);
}
Point2 TextureProgress::get_relative_center() {
diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp
index f08726fab8..e7f63997f2 100644
--- a/scene/gui/tree.cpp
+++ b/scene/gui/tree.cpp
@@ -3907,6 +3907,8 @@ Tree::Tree() {
cache.click_id = -1;
cache.click_item = NULL;
cache.click_column = 0;
+ cache.hover_cell = -1;
+ cache.hover_index = -1;
last_keypress = 0;
focus_in_id = 0;