Skip to content

Commit

Permalink
Backported from Godot4: Allow disabling scrolling in Tree.
Browse files Browse the repository at this point in the history
  • Loading branch information
Relintai committed Mar 11, 2024
1 parent 850b5b0 commit b11bd94
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 14 deletions.
6 changes: 6 additions & 0 deletions doc/classes/Tree.xml
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,12 @@
If [code]true[/code], the tree's root is hidden.
</member>
<member name="rect_clip_content" type="bool" setter="set_clip_contents" getter="is_clipping_contents" overrides="Control" default="true" />
<member name="scroll_horizontal_enabled" type="bool" setter="set_h_scroll_enabled" getter="is_h_scroll_enabled" default="true">
If [code]true[/code], enables horizontal scrolling.
</member>
<member name="scroll_vertical_enabled" type="bool" setter="set_v_scroll_enabled" getter="is_v_scroll_enabled" default="true">
If [code]true[/code], enables vertical scrolling.
</member>
<member name="select_mode" type="int" setter="set_select_mode" getter="get_select_mode" enum="Tree.SelectMode" default="0">
Allows single or multiple selection. See the [enum SelectMode] constants.
</member>
Expand Down
84 changes: 70 additions & 14 deletions scene/gui/tree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2764,6 +2764,13 @@ Size2 Tree::get_internal_min_size() const {
void Tree::update_scrollbars() {
Size2 size = get_size();

int tbh;
if (show_column_titles) {
tbh = _get_title_button_height();
} else {
tbh = 0;
}

Size2 hmin = h_scroll->get_combined_minimum_size();
Size2 vmin = v_scroll->get_combined_minimum_size();

Expand All @@ -2773,27 +2780,38 @@ void Tree::update_scrollbars() {
h_scroll->set_begin(Point2(0, size.height - hmin.height));
h_scroll->set_end(Point2(size.width - vmin.width, size.height));

Size2 min = get_internal_min_size();
const real_t tree_content_height = size.height - hmin.height - _get_title_button_height();
Size2 internal_min_size = get_internal_min_size();

if (min.height < tree_content_height) {
v_scroll->hide();
cache.offset.y = 0;
} else {
bool display_vscroll = internal_min_size.height + cache.bg->get_margin(MARGIN_TOP) > size.height;
bool display_hscroll = internal_min_size.width + cache.bg->get_margin(MARGIN_LEFT) > size.width;
for (int i = 0; i < 2; i++) {
// Check twice, as both values are dependent on each other.
if (display_hscroll) {
display_vscroll = internal_min_size.height + cache.bg->get_margin(MARGIN_TOP) + hmin.height > size.height;
}
if (display_vscroll) {
display_hscroll = internal_min_size.width + cache.bg->get_margin(MARGIN_LEFT) + vmin.width > size.width;
}
}

if (display_vscroll) {
v_scroll->show();
v_scroll->set_max(min.height);
v_scroll->set_page(tree_content_height);
v_scroll->set_max(internal_min_size.height);
v_scroll->set_page(size.height - hmin.height - tbh);
cache.offset.y = v_scroll->get_value();
} else {
v_scroll->hide();
cache.offset.y = 0;
}

if (min.width < size.width - vmin.width) {
h_scroll->hide();
cache.offset.x = 0;
} else {
if (display_hscroll) {
h_scroll->show();
h_scroll->set_max(min.width);
h_scroll->set_max(internal_min_size.width);
h_scroll->set_page(size.width - vmin.width);
cache.offset.x = h_scroll->get_value();
} else {
h_scroll->hide();
cache.offset.x = 0;
}
}

Expand Down Expand Up @@ -2962,7 +2980,17 @@ void Tree::_notification(int p_what) {
}

Size2 Tree::get_minimum_size() const {
return Size2(1, 1);
if (h_scroll_enabled && v_scroll_enabled) {
return Size2();
} else {
Vector2 min_size = get_internal_min_size();
Ref<StyleBox> bg = cache.bg;
if (bg.is_valid()) {
min_size.x += bg->get_margin(MARGIN_LEFT) + bg->get_margin(MARGIN_RIGHT);
min_size.y += bg->get_margin(MARGIN_TOP) + bg->get_margin(MARGIN_BOTTOM);
}
return Vector2(h_scroll_enabled ? 0 : min_size.x, v_scroll_enabled ? 0 : min_size.y);
}
}

TreeItem *Tree::create_item(TreeItem *p_parent, int p_idx) {
Expand Down Expand Up @@ -3460,6 +3488,24 @@ void Tree::scroll_to_item(TreeItem *p_item) {
}
}

void Tree::set_h_scroll_enabled(bool p_enable) {
h_scroll_enabled = p_enable;
minimum_size_changed();
}

bool Tree::is_h_scroll_enabled() const {
return h_scroll_enabled;
}

void Tree::set_v_scroll_enabled(bool p_enable) {
v_scroll_enabled = p_enable;
minimum_size_changed();
}

bool Tree::is_v_scroll_enabled() const {
return v_scroll_enabled;
}

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.
Expand Down Expand Up @@ -3880,6 +3926,12 @@ void Tree::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_scroll"), &Tree::get_scroll);
ClassDB::bind_method(D_METHOD("scroll_to_item", "item"), &Tree::_scroll_to_item);

ClassDB::bind_method(D_METHOD("set_h_scroll_enabled", "h_scroll"), &Tree::set_h_scroll_enabled);
ClassDB::bind_method(D_METHOD("is_h_scroll_enabled"), &Tree::is_h_scroll_enabled);

ClassDB::bind_method(D_METHOD("set_v_scroll_enabled", "h_scroll"), &Tree::set_v_scroll_enabled);
ClassDB::bind_method(D_METHOD("is_v_scroll_enabled"), &Tree::is_v_scroll_enabled);

ClassDB::bind_method(D_METHOD("set_hide_folding", "hide"), &Tree::set_hide_folding);
ClassDB::bind_method(D_METHOD("is_folding_hidden"), &Tree::is_folding_hidden);

Expand All @@ -3904,6 +3956,8 @@ void Tree::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hide_root"), "set_hide_root", "is_root_hidden");
ADD_PROPERTY(PropertyInfo(Variant::INT, "drop_mode_flags", PROPERTY_HINT_FLAGS, "On Item,In between"), "set_drop_mode_flags", "get_drop_mode_flags");
ADD_PROPERTY(PropertyInfo(Variant::INT, "select_mode", PROPERTY_HINT_ENUM, "Single,Row,Multi"), "set_select_mode", "get_select_mode");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scroll_horizontal_enabled"), "set_h_scroll_enabled", "is_h_scroll_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scroll_vertical_enabled"), "set_v_scroll_enabled", "is_v_scroll_enabled");

ADD_SIGNAL(MethodInfo("item_selected"));
ADD_SIGNAL(MethodInfo("cell_selected"));
Expand Down Expand Up @@ -3963,6 +4017,8 @@ Tree::Tree() {

h_scroll = memnew(HScrollBar);
v_scroll = memnew(VScrollBar);
h_scroll_enabled = true;
v_scroll_enabled = true;

add_child(h_scroll);
add_child(v_scroll);
Expand Down
7 changes: 7 additions & 0 deletions scene/gui/tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,8 @@ class Tree : public Control {
void _scroll_moved(float p_value);
HScrollBar *h_scroll;
VScrollBar *v_scroll;
bool h_scroll_enabled;
bool v_scroll_enabled;

Size2 get_internal_min_size() const;
void update_cache();
Expand Down Expand Up @@ -593,6 +595,11 @@ class Tree : public Control {
Point2 get_scroll() const;
void scroll_to_item(TreeItem *p_item);

void set_h_scroll_enabled(bool p_enable);
bool is_h_scroll_enabled() const;
void set_v_scroll_enabled(bool p_enable);
bool is_v_scroll_enabled() const;

void set_cursor_can_exit_tree(bool p_enable);
bool can_cursor_exit_tree() const;

Expand Down

0 comments on commit b11bd94

Please sign in to comment.