Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add axis constraints to UIScrollingContainer #539

Merged
merged 1 commit into from
Mar 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 24 additions & 4 deletions pygame_gui/elements/ui_scrolling_container.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,10 @@ def __init__(self,
parent_element: Optional[UIElement] = None,
object_id: Optional[Union[ObjectID, str]] = None,
anchors: Optional[Dict[str, Union[str, UIElement]]] = None,
visible: int = 1):
visible: int = 1,
allow_scroll_x: bool = True,
allow_scroll_y: bool = True,
):
# Need to move some declarations early as they are indirectly referenced via the ui element
# constructor
self._root_container = None
Expand All @@ -55,11 +58,14 @@ def __init__(self,
object_id=object_id,
element_id=['scrolling_container'])

# self.parent_element = parent_element
self.scroll_bar_width = 0
self.scroll_bar_height = 0

self.need_to_sort_out_scrollbars = False

self.allow_scroll_x = allow_scroll_x
self.allow_scroll_y = allow_scroll_y

self.vert_scroll_bar: Optional[UIVerticalScrollBar] = None
self.horiz_scroll_bar: Optional[UIHorizontalScrollBar] = None

Expand Down Expand Up @@ -271,7 +277,11 @@ def _sort_out_element_container_scroll_bars(self):
bar has been moved. Instead, it tries to keep the scrollbars in the same approximate position
they were in before resizing
"""

# First call to see if scrolling container size on its own necessitates scroll bars
self._check_scroll_bars_and_adjust()
# second call to see if the view space contraction produced by any scroll bars created
# in the first call, require an additional scroll bar
need_horiz_scroll_bar, need_vert_scroll_bar = self._check_scroll_bars_and_adjust()

if need_vert_scroll_bar:
Expand Down Expand Up @@ -344,18 +354,28 @@ def _check_scroll_bars_and_adjust(self) -> Tuple[bool, bool]:
need_horiz_scroll_bar = False
need_vert_scroll_bar = False
if (self.scrolling_height > self._view_container.rect.height or
self.scrollable_container.relative_rect.top != 0):
self.scrollable_container.relative_rect.top != 0) and self.allow_scroll_y:
need_vert_scroll_bar = True
self.scroll_bar_width = 20
if (self.scrolling_width > self._view_container.rect.width or
self.scrollable_container.relative_rect.left != 0):
self.scrollable_container.relative_rect.left != 0) and self.allow_scroll_x:
need_horiz_scroll_bar = True
self.scroll_bar_height = 20
if need_vert_scroll_bar or need_horiz_scroll_bar:
new_width = (self._root_container.rect.width - self.scroll_bar_width)
new_height = (self._root_container.rect.height - self.scroll_bar_height)
new_dimensions = (new_width, new_height)
self._view_container.set_dimensions(new_dimensions)

if not self.allow_scroll_x:
# horizontal scrolling is banned, lets shrink the scrollable width
# to account for any scroll bar as well
self.scrollable_container.set_dimensions((new_width,
self.scrollable_container.rect.height))
if not self.allow_scroll_y:
self.scrollable_container.set_dimensions((self.scrollable_container.rect.width,
new_height))

self._calculate_scrolling_dimensions()
return need_horiz_scroll_bar, need_vert_scroll_bar

Expand Down
41 changes: 39 additions & 2 deletions tests/test_elements/test_ui_scrolling_container.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,43 @@ def test_set_scrollable_area_dimensions(self, _init_pygame, default_ui_manager,
assert container._view_container.rect.size == (200-container.vert_scroll_bar.rect.width,
200-container.horiz_scroll_bar.rect.height)

def test_set_scrollable_area_dimensions_constrained_x_axis(self, _init_pygame, default_ui_manager,
_display_surface_return_none):
container = UIScrollingContainer(pygame.Rect(100, 100, 200, 200),
manager=default_ui_manager,
allow_scroll_x=False)

assert container.vert_scroll_bar is None
assert container.horiz_scroll_bar is None
assert container.scrollable_container.rect.size == (200, 200)

container.set_scrollable_area_dimensions((200, 600))

assert container.vert_scroll_bar is not None
assert container.horiz_scroll_bar is None
assert container._view_container.rect.size == (200 - container.vert_scroll_bar.rect.width,
200)
assert container.scrollable_container.rect.size == (200 - container.vert_scroll_bar.rect.width, 600)

def test_set_scrollable_area_dimensions_constrained_y_axis(self, _init_pygame, default_ui_manager,
_display_surface_return_none):
container = UIScrollingContainer(pygame.Rect(100, 100, 200, 200),
manager=default_ui_manager,
allow_scroll_y=False)

assert container.vert_scroll_bar is None
assert container.horiz_scroll_bar is None
assert container.scrollable_container.rect.size == (200, 200)

container.set_scrollable_area_dimensions((600, 200))

assert container.vert_scroll_bar is None
assert container.horiz_scroll_bar is not None
assert container._view_container.rect.size == (200,
200 - container.horiz_scroll_bar.rect.height)
assert container.scrollable_container.rect.size == (600,
200 - container.horiz_scroll_bar.rect.height)

def test_update(self, _init_pygame, default_ui_manager,
_display_surface_return_none):
container = UIScrollingContainer(pygame.Rect(100, 100, 200, 200),
Expand All @@ -128,15 +165,15 @@ def test_update(self, _init_pygame, default_ui_manager,

container.update(0.02)

assert container.get_container().relative_rect.x == -37
assert container.get_container().get_relative_rect().x == -37

container.vert_scroll_bar.scroll_wheel_moved = True
container.vert_scroll_bar.scroll_wheel_amount = -1.0
container.vert_scroll_bar.update(0.02)

container.update(0.02)

assert container.get_container().relative_rect.y == -67
assert container.get_container().get_relative_rect().y == -67

container.horiz_scroll_bar.scroll_wheel_right = True
container.horiz_scroll_bar.update(0.02)
Expand Down
Loading