Merge pull request #48008 from LightningAA/scrollcontainer-hide-scrollbars-4.0

Add the ability to hide `ScrollContainer`'s scrollbars
This commit is contained in:
Rémi Verschelde 2021-05-04 12:58:12 +02:00 committed by GitHub
commit 9a8ef54b5a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 84 additions and 59 deletions

View file

@ -39,12 +39,18 @@
<member name="scroll_horizontal_enabled" type="bool" setter="set_enable_h_scroll" getter="is_h_scroll_enabled" default="true">
If [code]true[/code], enables horizontal scrolling.
</member>
<member name="scroll_horizontal_visible" type="bool" setter="set_h_scroll_visible" getter="is_h_scroll_visible" default="true">
If [code]false[/code], hides the horizontal scrollbar.
</member>
<member name="scroll_vertical" type="int" setter="set_v_scroll" getter="get_v_scroll" default="0">
The current vertical scroll value.
</member>
<member name="scroll_vertical_enabled" type="bool" setter="set_enable_v_scroll" getter="is_v_scroll_enabled" default="true">
If [code]true[/code], enables vertical scrolling.
</member>
<member name="scroll_vertical_visible" type="bool" setter="set_v_scroll_visible" getter="is_v_scroll_visible" default="true">
If [code]false[/code], hides the vertical scrollbar.
</member>
</members>
<signals>
<signal name="scroll_ended">

View file

@ -299,7 +299,7 @@ void ScrollContainer::_update_dimensions() {
child_max_size.x = MAX(child_max_size.x, minsize.x);
child_max_size.y = MAX(child_max_size.y, minsize.y);
Rect2 r = Rect2(-scroll, minsize);
Rect2 r = Rect2(-Size2(get_h_scroll(), get_v_scroll()), minsize);
if (!scroll_h || (!h_scroll->is_visible_in_tree() && c->get_h_size_flags() & SIZE_EXPAND)) {
r.position.x = 0;
if (c->get_h_size_flags() & SIZE_EXPAND) {
@ -434,40 +434,16 @@ void ScrollContainer::update_scrollbars() {
Size2 min = child_max_size;
bool hide_scroll_v = !scroll_v || min.height <= size.height;
bool hide_scroll_h = !scroll_h || min.width <= size.width;
v_scroll->set_max(min.height);
if (hide_scroll_v) {
v_scroll->set_page(size.height);
v_scroll->hide();
scroll.y = 0;
} else {
v_scroll->show();
if (hide_scroll_h) {
v_scroll->set_page(size.height);
} else {
v_scroll->set_page(size.height - hmin.height);
}
scroll.y = v_scroll->get_value();
}
bool hide_scroll_h = !scroll_h || min.width <= size.width || !h_scroll_visible;
bool hide_scroll_v = !scroll_v || min.height <= size.height || !v_scroll_visible;
h_scroll->set_max(min.width);
if (hide_scroll_h) {
h_scroll->set_page(size.width);
h_scroll->hide();
scroll.x = 0;
} else {
h_scroll->show();
if (hide_scroll_v) {
h_scroll->set_page(size.width);
} else {
h_scroll->set_page(size.width - vmin.width);
}
h_scroll->set_page(size.width - (hide_scroll_v ? 0 : vmin.width));
h_scroll->set_visible(!hide_scroll_h);
scroll.x = h_scroll->get_value();
}
v_scroll->set_max(min.height);
v_scroll->set_page(size.height - (hide_scroll_h ? 0 : hmin.height));
v_scroll->set_visible(!hide_scroll_v);
// Avoid scrollbar overlapping.
h_scroll->set_anchor_and_offset(SIDE_RIGHT, ANCHOR_END, hide_scroll_v ? 0 : -vmin.width);
@ -475,13 +451,28 @@ void ScrollContainer::update_scrollbars() {
}
void ScrollContainer::_scroll_moved(float) {
scroll.x = h_scroll->get_value();
scroll.y = v_scroll->get_value();
queue_sort();
update();
};
void ScrollContainer::set_h_scroll(int p_pos) {
h_scroll->set_value(p_pos);
_cancel_drag();
}
int ScrollContainer::get_h_scroll() const {
return h_scroll->get_value();
}
void ScrollContainer::set_v_scroll(int p_pos) {
v_scroll->set_value(p_pos);
_cancel_drag();
}
int ScrollContainer::get_v_scroll() const {
return v_scroll->get_value();
}
void ScrollContainer::set_enable_h_scroll(bool p_enable) {
if (scroll_h == p_enable) {
return;
@ -510,22 +501,30 @@ bool ScrollContainer::is_v_scroll_enabled() const {
return scroll_v;
}
int ScrollContainer::get_v_scroll() const {
return v_scroll->get_value();
void ScrollContainer::set_h_scroll_visible(bool p_visible) {
if (h_scroll_visible == p_visible) {
return;
}
h_scroll_visible = p_visible;
update_scrollbars();
}
void ScrollContainer::set_v_scroll(int p_pos) {
v_scroll->set_value(p_pos);
_cancel_drag();
bool ScrollContainer::is_h_scroll_visible() const {
return h_scroll_visible;
}
int ScrollContainer::get_h_scroll() const {
return h_scroll->get_value();
void ScrollContainer::set_v_scroll_visible(bool p_visible) {
if (v_scroll_visible == p_visible) {
return;
}
v_scroll_visible = p_visible;
update_scrollbars();
}
void ScrollContainer::set_h_scroll(int p_pos) {
h_scroll->set_value(p_pos);
_cancel_drag();
bool ScrollContainer::is_v_scroll_visible() const {
return v_scroll_visible;
}
int ScrollContainer::get_deadzone() const {
@ -581,17 +580,29 @@ VScrollBar *ScrollContainer::get_v_scrollbar() {
void ScrollContainer::_bind_methods() {
ClassDB::bind_method(D_METHOD("_gui_input"), &ScrollContainer::_gui_input);
ClassDB::bind_method(D_METHOD("set_enable_h_scroll", "enable"), &ScrollContainer::set_enable_h_scroll);
ClassDB::bind_method(D_METHOD("is_h_scroll_enabled"), &ScrollContainer::is_h_scroll_enabled);
ClassDB::bind_method(D_METHOD("set_enable_v_scroll", "enable"), &ScrollContainer::set_enable_v_scroll);
ClassDB::bind_method(D_METHOD("is_v_scroll_enabled"), &ScrollContainer::is_v_scroll_enabled);
ClassDB::bind_method(D_METHOD("_update_scrollbar_position"), &ScrollContainer::_update_scrollbar_position);
ClassDB::bind_method(D_METHOD("set_h_scroll", "value"), &ScrollContainer::set_h_scroll);
ClassDB::bind_method(D_METHOD("get_h_scroll"), &ScrollContainer::get_h_scroll);
ClassDB::bind_method(D_METHOD("set_v_scroll", "value"), &ScrollContainer::set_v_scroll);
ClassDB::bind_method(D_METHOD("get_v_scroll"), &ScrollContainer::get_v_scroll);
ClassDB::bind_method(D_METHOD("set_enable_h_scroll", "enable"), &ScrollContainer::set_enable_h_scroll);
ClassDB::bind_method(D_METHOD("is_h_scroll_enabled"), &ScrollContainer::is_h_scroll_enabled);
ClassDB::bind_method(D_METHOD("set_enable_v_scroll", "enable"), &ScrollContainer::set_enable_v_scroll);
ClassDB::bind_method(D_METHOD("is_v_scroll_enabled"), &ScrollContainer::is_v_scroll_enabled);
ClassDB::bind_method(D_METHOD("set_h_scroll_visible", "visible"), &ScrollContainer::set_h_scroll_visible);
ClassDB::bind_method(D_METHOD("is_h_scroll_visible"), &ScrollContainer::is_h_scroll_visible);
ClassDB::bind_method(D_METHOD("set_v_scroll_visible", "visible"), &ScrollContainer::set_v_scroll_visible);
ClassDB::bind_method(D_METHOD("is_v_scroll_visible"), &ScrollContainer::is_v_scroll_visible);
ClassDB::bind_method(D_METHOD("set_deadzone", "deadzone"), &ScrollContainer::set_deadzone);
ClassDB::bind_method(D_METHOD("get_deadzone"), &ScrollContainer::get_deadzone);
ClassDB::bind_method(D_METHOD("set_follow_focus", "enabled"), &ScrollContainer::set_follow_focus);
ClassDB::bind_method(D_METHOD("is_following_focus"), &ScrollContainer::is_following_focus);
@ -604,10 +615,12 @@ void ScrollContainer::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "follow_focus"), "set_follow_focus", "is_following_focus");
ADD_GROUP("Scroll", "scroll_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scroll_horizontal_enabled"), "set_enable_h_scroll", "is_h_scroll_enabled");
ADD_PROPERTY(PropertyInfo(Variant::INT, "scroll_horizontal"), "set_h_scroll", "get_h_scroll");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scroll_vertical_enabled"), "set_enable_v_scroll", "is_v_scroll_enabled");
ADD_PROPERTY(PropertyInfo(Variant::INT, "scroll_vertical"), "set_v_scroll", "get_v_scroll");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scroll_horizontal_enabled"), "set_enable_h_scroll", "is_h_scroll_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scroll_vertical_enabled"), "set_enable_v_scroll", "is_v_scroll_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scroll_horizontal_visible"), "set_h_scroll_visible", "is_h_scroll_visible");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scroll_vertical_visible"), "set_v_scroll_visible", "is_v_scroll_visible");
ADD_PROPERTY(PropertyInfo(Variant::INT, "scroll_deadzone"), "set_deadzone", "get_deadzone");
GLOBAL_DEF("gui/common/default_scroll_deadzone", 0);

View file

@ -42,7 +42,6 @@ class ScrollContainer : public Container {
VScrollBar *v_scroll;
Size2 child_max_size;
Size2 scroll;
void update_scrollbars();
@ -50,16 +49,17 @@ class ScrollContainer : public Container {
Vector2 drag_accum;
Vector2 drag_from;
Vector2 last_drag_accum;
float last_drag_time = 0.0;
float time_since_motion = 0.0;
float time_since_motion = 0.0f;
bool drag_touching = false;
bool drag_touching_deaccel = false;
bool click_handled = false;
bool beyond_deadzone = false;
bool scroll_h = true;
bool scroll_v = true;
bool h_scroll_visible = true;
bool v_scroll_visible = true;
int deadzone = 0;
bool follow_focus = false;
@ -80,11 +80,11 @@ protected:
void _ensure_focused_visible(Control *p_node);
public:
int get_v_scroll() const;
void set_v_scroll(int p_pos);
int get_h_scroll() const;
void set_h_scroll(int p_pos);
int get_h_scroll() const;
void set_v_scroll(int p_pos);
int get_v_scroll() const;
void set_enable_h_scroll(bool p_enable);
bool is_h_scroll_enabled() const;
@ -92,6 +92,12 @@ public:
void set_enable_v_scroll(bool p_enable);
bool is_v_scroll_enabled() const;
void set_h_scroll_visible(bool p_visible);
bool is_h_scroll_visible() const;
void set_v_scroll_visible(bool p_visible);
bool is_v_scroll_visible() const;
int get_deadzone() const;
void set_deadzone(int p_deadzone);