Browse Source

Allow disabling scrolling in Tree

Gilles Roudière 4 years ago
parent
commit
b2dddc3c82
3 changed files with 72 additions and 12 deletions
  1. 6 0
      doc/classes/Tree.xml
  2. 60 12
      scene/gui/tree.cpp
  3. 6 0
      scene/gui/tree.h

+ 6 - 0
doc/classes/Tree.xml

@@ -372,6 +372,12 @@
 			If [code]true[/code], the tree's root is hidden.
 			If [code]true[/code], the tree's root is hidden.
 		</member>
 		</member>
 		<member name="rect_clip_content" type="bool" setter="set_clip_contents" getter="is_clipping_contents" override="true" default="true" />
 		<member name="rect_clip_content" type="bool" setter="set_clip_contents" getter="is_clipping_contents" override="true" 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">
 		<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.
 			Allows single or multiple selection. See the [enum SelectMode] constants.
 		</member>
 		</member>

+ 60 - 12
scene/gui/tree.cpp

@@ -3300,26 +3300,38 @@ void Tree::update_scrollbars() {
 	h_scroll->set_begin(Point2(0, size.height - hmin.height));
 	h_scroll->set_begin(Point2(0, size.height - hmin.height));
 	h_scroll->set_end(Point2(size.width - vmin.width, size.height));
 	h_scroll->set_end(Point2(size.width - vmin.width, size.height));
 
 
-	Size2 min = get_internal_min_size();
+	Size2 internal_min_size = get_internal_min_size();
 
 
-	if (min.height < size.height - hmin.height) {
-		v_scroll->hide();
-		cache.offset.y = 0;
-	} else {
+	bool display_vscroll = internal_min_size.height + cache.bg->get_margin(SIDE_TOP) > size.height;
+	bool display_hscroll = internal_min_size.width + cache.bg->get_margin(SIDE_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(SIDE_TOP) + hmin.height > size.height;
+		}
+		if (display_vscroll) {
+			display_hscroll = internal_min_size.width + cache.bg->get_margin(SIDE_LEFT) + vmin.width > size.width;
+		}
+	}
+
+	if (display_vscroll) {
 		v_scroll->show();
 		v_scroll->show();
-		v_scroll->set_max(min.height);
+		v_scroll->set_max(internal_min_size.height);
 		v_scroll->set_page(size.height - hmin.height - tbh);
 		v_scroll->set_page(size.height - hmin.height - tbh);
 		cache.offset.y = v_scroll->get_value();
 		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->show();
-		h_scroll->set_max(min.width);
+		h_scroll->set_max(internal_min_size.width);
 		h_scroll->set_page(size.width - vmin.width);
 		h_scroll->set_page(size.width - vmin.width);
 		cache.offset.x = h_scroll->get_value();
 		cache.offset.x = h_scroll->get_value();
+	} else {
+		h_scroll->hide();
+		cache.offset.x = 0;
 	}
 	}
 }
 }
 
 
@@ -3513,7 +3525,17 @@ void Tree::_update_all() {
 }
 }
 
 
 Size2 Tree::get_minimum_size() const {
 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(SIDE_LEFT) + bg->get_margin(SIDE_RIGHT);
+			min_size.y += bg->get_margin(SIDE_TOP) + bg->get_margin(SIDE_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) {
 TreeItem *Tree::create_item(TreeItem *p_parent, int p_idx) {
@@ -4047,6 +4069,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 *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 *from = p_at;
 	TreeItem *loop = nullptr; // Safe-guard against infinite loop.
 	TreeItem *loop = nullptr; // Safe-guard against infinite loop.
@@ -4468,6 +4508,12 @@ void Tree::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("get_scroll"), &Tree::get_scroll);
 	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("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("set_hide_folding", "hide"), &Tree::set_hide_folding);
 	ClassDB::bind_method(D_METHOD("is_folding_hidden"), &Tree::is_folding_hidden);
 	ClassDB::bind_method(D_METHOD("is_folding_hidden"), &Tree::is_folding_hidden);
 
 
@@ -4487,6 +4533,8 @@ void Tree::_bind_methods() {
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hide_root"), "set_hide_root", "is_root_hidden");
 	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, "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::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("item_selected"));
 	ADD_SIGNAL(MethodInfo("cell_selected"));
 	ADD_SIGNAL(MethodInfo("cell_selected"));

+ 6 - 0
scene/gui/tree.h

@@ -545,6 +545,8 @@ private:
 	void _scroll_moved(float p_value);
 	void _scroll_moved(float p_value);
 	HScrollBar *h_scroll;
 	HScrollBar *h_scroll;
 	VScrollBar *v_scroll;
 	VScrollBar *v_scroll;
+	bool h_scroll_enabled = true;
+	bool v_scroll_enabled = true;
 
 
 	Size2 get_internal_min_size() const;
 	Size2 get_internal_min_size() const;
 	void update_cache();
 	void update_cache();
@@ -679,6 +681,10 @@ public:
 
 
 	Point2 get_scroll() const;
 	Point2 get_scroll() const;
 	void scroll_to_item(TreeItem *p_item);
 	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);
 	void set_cursor_can_exit_tree(bool p_enable);