diff options
Diffstat (limited to 'scene/gui/tree.cpp')
-rw-r--r-- | scene/gui/tree.cpp | 112 |
1 files changed, 65 insertions, 47 deletions
diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index db7d390b16..2da76883b4 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -738,9 +738,9 @@ TreeItem *TreeItem::get_first_child() const { TreeItem *TreeItem::_get_prev_visible(bool p_wrap) { TreeItem *current = this; - TreeItem *prev = current->get_prev(); + TreeItem *prev_item = current->get_prev(); - if (!prev) { + if (!prev_item) { current = current->parent; if (current == tree->root && tree->hide_root) { return nullptr; @@ -757,7 +757,7 @@ TreeItem *TreeItem::_get_prev_visible(bool p_wrap) { } } } else { - current = prev; + current = prev_item; while (!current->collapsed && current->first_child) { //go to the very end @@ -773,16 +773,16 @@ TreeItem *TreeItem::_get_prev_visible(bool p_wrap) { TreeItem *TreeItem::get_prev_visible(bool p_wrap) { TreeItem *loop = this; - TreeItem *prev = this->_get_prev_visible(p_wrap); - while (prev && !prev->is_visible()) { - prev = prev->_get_prev_visible(p_wrap); - if (prev == loop) { + TreeItem *prev_item = this->_get_prev_visible(p_wrap); + while (prev_item && !prev_item->is_visible()) { + prev_item = prev_item->_get_prev_visible(p_wrap); + if (prev_item == loop) { // Check that we haven't looped all the way around to the start. - prev = nullptr; + prev_item = nullptr; break; } } - return prev; + return prev_item; } TreeItem *TreeItem::_get_next_visible(bool p_wrap) { @@ -814,16 +814,16 @@ TreeItem *TreeItem::_get_next_visible(bool p_wrap) { TreeItem *TreeItem::get_next_visible(bool p_wrap) { TreeItem *loop = this; - TreeItem *next = this->_get_next_visible(p_wrap); - while (next && !next->is_visible()) { - next = next->_get_next_visible(p_wrap); - if (next == loop) { + TreeItem *next_item = this->_get_next_visible(p_wrap); + while (next_item && !next_item->is_visible()) { + next_item = next_item->_get_next_visible(p_wrap); + if (next_item == loop) { // Check that we haven't looped all the way around to the start. - next = nullptr; + next_item = nullptr; break; } } - return next; + return next_item; } TreeItem *TreeItem::get_child(int p_idx) { @@ -1317,8 +1317,8 @@ bool TreeItem::is_folding_disabled() const { Size2 TreeItem::get_minimum_size(int p_column) { ERR_FAIL_INDEX_V(p_column, cells.size(), Size2()); - Tree *tree = get_tree(); - ERR_FAIL_COND_V(!tree, Size2()); + Tree *parent_tree = get_tree(); + ERR_FAIL_COND_V(!parent_tree, Size2()); const TreeItem::Cell &cell = cells[p_column]; @@ -1328,7 +1328,7 @@ Size2 TreeItem::get_minimum_size(int p_column) { // Text. if (!cell.text.is_empty()) { if (cell.dirty) { - tree->update_item_cell(this, p_column); + parent_tree->update_item_cell(this, p_column); } Size2 text_size = cell.text_buf->get_size(); size.width += text_size.width; @@ -1337,14 +1337,14 @@ Size2 TreeItem::get_minimum_size(int p_column) { // Icon. if (cell.mode == CELL_MODE_CHECK) { - size.width += tree->theme_cache.checked->get_width() + tree->theme_cache.hseparation; + size.width += parent_tree->theme_cache.checked->get_width() + parent_tree->theme_cache.hseparation; } if (cell.icon.is_valid()) { Size2i icon_size = cell.get_icon_size(); if (cell.icon_max_w > 0 && icon_size.width > cell.icon_max_w) { icon_size.width = cell.icon_max_w; } - size.width += icon_size.width + tree->theme_cache.hseparation; + size.width += icon_size.width + parent_tree->theme_cache.hseparation; size.height = MAX(size.height, icon_size.height); } @@ -1352,13 +1352,13 @@ Size2 TreeItem::get_minimum_size(int p_column) { for (int i = 0; i < cell.buttons.size(); i++) { Ref<Texture2D> texture = cell.buttons[i].texture; if (texture.is_valid()) { - Size2 button_size = texture->get_size() + tree->theme_cache.button_pressed->get_minimum_size(); + Size2 button_size = texture->get_size() + parent_tree->theme_cache.button_pressed->get_minimum_size(); size.width += button_size.width; size.height = MAX(size.height, button_size.height); } } if (cell.buttons.size() >= 2) { - size.width += (cell.buttons.size() - 1) * tree->theme_cache.button_margin; + size.width += (cell.buttons.size() - 1) * parent_tree->theme_cache.button_margin; } cells.write[p_column].cached_minimum_size = size; @@ -1504,6 +1504,7 @@ void TreeItem::_bind_methods() { 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("set_button_color", "column", "button_idx", "color"), &TreeItem::set_button_color); ClassDB::bind_method(D_METHOD("is_button_disabled", "column", "button_idx"), &TreeItem::is_button_disabled); ClassDB::bind_method(D_METHOD("set_tooltip_text", "column", "tooltip"), &TreeItem::set_tooltip_text); @@ -3190,7 +3191,7 @@ void Tree::gui_input(const Ref<InputEvent> &p_event) { Ref<InputEventKey> k = p_event; bool is_command = k.is_valid() && k->is_command_or_control_pressed(); - if (p_event->is_action("ui_right") && p_event->is_pressed()) { + if (p_event->is_action("ui_right", true) && p_event->is_pressed()) { if (!cursor_can_exit_tree) { accept_event(); } @@ -3208,7 +3209,7 @@ void Tree::gui_input(const Ref<InputEvent> &p_event) { } else { _go_right(); } - } else if (p_event->is_action("ui_left") && p_event->is_pressed()) { + } else if (p_event->is_action("ui_left", true) && p_event->is_pressed()) { if (!cursor_can_exit_tree) { accept_event(); } @@ -3228,21 +3229,21 @@ void Tree::gui_input(const Ref<InputEvent> &p_event) { _go_left(); } - } else if (p_event->is_action("ui_up") && p_event->is_pressed() && !is_command) { + } else if (p_event->is_action("ui_up", true) && p_event->is_pressed() && !is_command) { if (!cursor_can_exit_tree) { accept_event(); } _go_up(); - } else if (p_event->is_action("ui_down") && p_event->is_pressed() && !is_command) { + } else if (p_event->is_action("ui_down", true) && p_event->is_pressed() && !is_command) { if (!cursor_can_exit_tree) { accept_event(); } _go_down(); - } else if (p_event->is_action("ui_page_down") && p_event->is_pressed()) { + } else if (p_event->is_action("ui_page_down", true) && p_event->is_pressed()) { if (!cursor_can_exit_tree) { accept_event(); } @@ -3280,7 +3281,7 @@ void Tree::gui_input(const Ref<InputEvent> &p_event) { } ensure_cursor_is_visible(); - } else if (p_event->is_action("ui_page_up") && p_event->is_pressed()) { + } else if (p_event->is_action("ui_page_up", true) && p_event->is_pressed()) { if (!cursor_can_exit_tree) { accept_event(); } @@ -3317,7 +3318,7 @@ void Tree::gui_input(const Ref<InputEvent> &p_event) { prev->select(selected_col); } ensure_cursor_is_visible(); - } else if (p_event->is_action("ui_accept") && p_event->is_pressed()) { + } else if (p_event->is_action("ui_accept", true) && p_event->is_pressed()) { if (selected_item) { //bring up editor if possible if (!edit_selected()) { @@ -3326,7 +3327,7 @@ void Tree::gui_input(const Ref<InputEvent> &p_event) { } } accept_event(); - } else if (p_event->is_action("ui_select") && p_event->is_pressed()) { + } else if (p_event->is_action("ui_select", true) && p_event->is_pressed()) { if (select_mode == SELECT_MULTI) { if (!selected_item) { return; @@ -4337,6 +4338,12 @@ TreeItem *Tree::get_selected() const { return selected_item; } +void Tree::set_selected(TreeItem *p_item, int p_column) { + ERR_FAIL_INDEX(p_column, columns.size()); + ERR_FAIL_COND(!p_item); + select_single_item(p_item, get_root(), p_column); +} + int Tree::get_selected_column() const { return selected_col; } @@ -4546,6 +4553,7 @@ void Tree::ensure_cursor_is_visible() { return; // Nothing under cursor. } + // Note: Code below similar to Tree::scroll_to_item(), in case of bug fix both. const Size2 area_size = get_size() - theme_cache.panel_style->get_minimum_size(); int y_offset = get_item_offset(selected_item); @@ -4554,7 +4562,10 @@ void Tree::ensure_cursor_is_visible() { y_offset -= tbh; const int cell_h = compute_item_height(selected_item) + theme_cache.vseparation; - const int screen_h = area_size.height - h_scroll->get_combined_minimum_size().height - tbh; + int screen_h = area_size.height - tbh; + if (h_scroll->is_visible()) { + screen_h -= h_scroll->get_combined_minimum_size().height; + } if (cell_h > screen_h) { // Screen size is too small, maybe it was not resized yet. v_scroll->set_value(y_offset); @@ -4705,26 +4716,32 @@ Point2 Tree::get_scroll() const { void Tree::scroll_to_item(TreeItem *p_item, bool p_center_on_item) { ERR_FAIL_NULL(p_item); - if (!is_visible_in_tree() || !p_item->is_visible()) { - return; // Hack to work around crash in get_item_rect() if Tree is not in tree. - } update_scrollbars(); - const real_t tree_height = get_size().y; - const Rect2 item_rect = get_item_rect(p_item); - const real_t item_y = item_rect.position.y; - const real_t item_height = item_rect.size.y + theme_cache.vseparation; + // Note: Code below similar to Tree::ensure_cursor_is_visible(), in case of bug fix both. + const Size2 area_size = get_size() - theme_cache.panel_style->get_minimum_size(); - if (p_center_on_item) { - v_scroll->set_value(item_y - (tree_height - item_height) / 2.0f); - } else { - if (item_y < v_scroll->get_value()) { - v_scroll->set_value(item_y); + int y_offset = get_item_offset(p_item); + if (y_offset != -1) { + const int tbh = _get_title_button_height(); + y_offset -= tbh; + + const int cell_h = compute_item_height(p_item) + theme_cache.vseparation; + int screen_h = area_size.height - tbh; + if (h_scroll->is_visible()) { + screen_h -= h_scroll->get_combined_minimum_size().height; + } + + if (p_center_on_item) { + v_scroll->set_value(y_offset - (screen_h - cell_h) / 2.0f); } else { - const real_t new_position = item_y + item_height - tree_height; - if (new_position > v_scroll->get_value()) { - v_scroll->set_value(new_position); + if (cell_h > screen_h) { // Screen size is too small, maybe it was not resized yet. + v_scroll->set_value(y_offset); + } else if (y_offset + cell_h > v_scroll->get_value() + screen_h) { + v_scroll->set_value(y_offset - screen_h + cell_h); + } else if (y_offset < v_scroll->get_value()) { + v_scroll->set_value(y_offset); } } } @@ -4817,7 +4834,7 @@ TreeItem *Tree::get_item_with_text(const String &p_find) const { void Tree::_do_incr_search(const String &p_add) { uint64_t time = OS::get_singleton()->get_ticks_usec() / 1000; // convert to msec uint64_t diff = time - last_keypress; - if (diff > uint64_t(GLOBAL_DEF("gui/timers/incremental_search_max_interval_msec", 2000))) { + if (diff > uint64_t(GLOBAL_GET("gui/timers/incremental_search_max_interval_msec"))) { incr_search = p_add; } else if (incr_search != p_add) { incr_search += p_add; @@ -5155,6 +5172,7 @@ void Tree::_bind_methods() { ClassDB::bind_method(D_METHOD("is_root_hidden"), &Tree::is_root_hidden); ClassDB::bind_method(D_METHOD("get_next_selected", "from"), &Tree::get_next_selected); ClassDB::bind_method(D_METHOD("get_selected"), &Tree::get_selected); + ClassDB::bind_method(D_METHOD("set_selected", "item", "column"), &Tree::set_selected); ClassDB::bind_method(D_METHOD("get_selected_column"), &Tree::get_selected_column); ClassDB::bind_method(D_METHOD("get_pressed_button"), &Tree::get_pressed_button); ClassDB::bind_method(D_METHOD("set_select_mode", "mode"), &Tree::set_select_mode); |