summaryrefslogtreecommitdiff
path: root/scene/gui/tree.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene/gui/tree.cpp')
-rw-r--r--scene/gui/tree.cpp92
1 files changed, 76 insertions, 16 deletions
diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp
index 45fcb448f8..070948237a 100644
--- a/scene/gui/tree.cpp
+++ b/scene/gui/tree.cpp
@@ -1208,8 +1208,9 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
if (drop_mode_flags && drop_mode_over == p_item) {
Rect2 r = cell_rect;
+ bool has_parent = p_item->get_children() != nullptr;
- if (drop_mode_section == -1 || drop_mode_section == 0) {
+ if (drop_mode_section == -1 || has_parent || drop_mode_section == 0) {
RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(r.position.x, r.position.y, r.size.x, 1), cache.drop_position_color);
}
@@ -1218,7 +1219,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(r.position.x + r.size.x - 1, r.position.y, 1, r.size.y), cache.drop_position_color);
}
- if (drop_mode_section == 1 || drop_mode_section == 0) {
+ if ((drop_mode_section == 1 && !has_parent) || drop_mode_section == 0) {
RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(r.position.x, r.position.y + r.size.y, r.size.x, 1), cache.drop_position_color);
}
}
@@ -1786,7 +1787,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool
case TreeItem::CELL_MODE_STRING: {
//nothing in particular
- if (select_mode == SELECT_MULTI && (get_tree()->get_event_count() == focus_in_id || !already_cursor)) {
+ if (select_mode == SELECT_MULTI && (get_viewport()->get_processed_events_count() == focus_in_id || !already_cursor)) {
bring_up_editor = false;
}
@@ -1861,7 +1862,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool
} else {
editor_text = String::num(p_item->cells[col].val, Math::range_step_decimals(p_item->cells[col].step));
- if (select_mode == SELECT_MULTI && get_tree()->get_event_count() == focus_in_id) {
+ if (select_mode == SELECT_MULTI && get_viewport()->get_processed_events_count() == focus_in_id) {
bring_up_editor = false;
}
}
@@ -1971,7 +1972,7 @@ void Tree::_text_editor_enter(String p_text) {
//popup_edited_item->edited_signal.call( popup_edited_item_col );
} break;
case TreeItem::CELL_MODE_RANGE: {
- c.val = p_text.to_double();
+ c.val = p_text.to_float();
if (c.step > 0) {
c.val = Math::stepify(c.val, c.step);
}
@@ -2364,7 +2365,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 +2383,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 +2400,26 @@ 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) {
+ if (old_it && old_col >= old_it->cells.size()) {
+ // Columns may have changed since last update().
+ update();
+ } else {
+ // 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();
}
@@ -2782,7 +2793,7 @@ int Tree::_get_title_button_height() const {
void Tree::_notification(int p_what) {
if (p_what == NOTIFICATION_FOCUS_ENTER) {
- focus_in_id = get_tree()->get_event_count();
+ focus_in_id = get_viewport()->get_processed_events_count();
}
if (p_what == NOTIFICATION_MOUSE_EXIT) {
if (cache.hover_type != Cache::CLICK_NONE) {
@@ -3405,7 +3416,7 @@ void Tree::scroll_to_item(TreeItem *p_item) {
const Rect2 r = get_item_rect(p_item);
- if (r.position.y < v_scroll->get_value()) {
+ if (r.position.y <= v_scroll->get_value()) {
v_scroll->set_value(r.position.y);
} else if (r.position.y + r.size.y + 2 * cache.vseparation > v_scroll->get_value() + get_size().y) {
v_scroll->set_value(r.position.y + r.size.y + 2 * cache.vseparation - get_size().y);
@@ -3414,6 +3425,8 @@ void Tree::scroll_to_item(TreeItem *p_item) {
TreeItem *Tree::_search_item_text(TreeItem *p_at, const String &p_find, int *r_col, bool p_selectable, bool p_backwards) {
TreeItem *from = p_at;
+ TreeItem *loop = nullptr; // Safe-guard against infinite loop.
+
while (p_at) {
for (int i = 0; i < columns.size(); i++) {
if (p_at->get_text(i).findn(p_find) == 0 && (!p_selectable || p_at->is_selectable(i))) {
@@ -3433,6 +3446,12 @@ TreeItem *Tree::_search_item_text(TreeItem *p_at, const String &p_find, int *r_c
if ((p_at) == from) {
break;
}
+
+ if (!loop) {
+ loop = p_at;
+ } else if (loop == p_at) {
+ break;
+ }
}
return nullptr;
@@ -3618,6 +3637,47 @@ TreeItem *Tree::get_item_at_position(const Point2 &p_pos) const {
return nullptr;
}
+int Tree::get_button_id_at_position(const Point2 &p_pos) const {
+ if (root) {
+ Point2 pos = p_pos;
+ pos -= cache.bg->get_offset();
+ pos.y -= _get_title_button_height();
+ if (pos.y < 0) {
+ return -1;
+ }
+
+ if (h_scroll->is_visible_in_tree()) {
+ pos.x += h_scroll->get_value();
+ }
+ if (v_scroll->is_visible_in_tree()) {
+ pos.y += v_scroll->get_value();
+ }
+
+ int col, h, section;
+ TreeItem *it = _find_item_at_pos(root, pos, col, h, section);
+
+ if (it) {
+ const TreeItem::Cell &c = it->cells[col];
+ int col_width = get_column_width(col);
+
+ for (int i = 0; i < col; i++) {
+ pos.x -= get_column_width(i);
+ }
+
+ for (int j = c.buttons.size() - 1; j >= 0; j--) {
+ Ref<Texture2D> b = c.buttons[j].texture;
+ Size2 size = b->get_size() + cache.button_pressed->get_minimum_size();
+ if (pos.x > col_width - size.width) {
+ return c.buttons[j].id;
+ }
+ col_width -= size.width;
+ }
+ }
+ }
+
+ return -1;
+}
+
String Tree::get_tooltip(const Point2 &p_pos) const {
if (root) {
Point2 pos = p_pos;
@@ -3834,7 +3894,7 @@ Tree::Tree() {
add_child(popup_menu);
// popup_menu->set_as_toplevel(true);
- popup_editor = memnew(PopupPanel);
+ popup_editor = memnew(Popup);
popup_editor->set_wrap_controls(true);
add_child(popup_editor);
popup_editor_vb = memnew(VBoxContainer);