Skip to content

Commit a8401e3

Browse files
committed
UIAutoScrollingContainers
These containers automatically resize their scrollable containers when new elements are added
1 parent 54dc83a commit a8401e3

File tree

3 files changed

+115
-2
lines changed

3 files changed

+115
-2
lines changed

pygame_gui/elements/__init__.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
from pygame_gui.elements.ui_scrolling_container import UIScrollingContainer
1919
from pygame_gui.elements.ui_text_entry_box import UITextEntryBox
2020
from pygame_gui.elements.ui_auto_resizing_container import UIAutoResizingContainer
21+
from pygame_gui.elements.ui_auto_scrolling_container import UIAutoScrollingContainer
2122

2223

2324
__all__ = ['UIImage',
@@ -40,4 +41,5 @@
4041
'UIWindow',
4142
'UIScrollingContainer',
4243
'UITextEntryBox',
43-
'UIAutoResizingContainer']
44+
'UIAutoResizingContainer',
45+
'UIAutoScrollingContainer']
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
import pygame
2+
from pygame_gui.core import UIElement, ObjectID
3+
from pygame_gui.core.interfaces import IUIManagerInterface, IContainerLikeInterface
4+
from pygame_gui.elements import UIScrollingContainer, UIAutoResizingContainer
5+
6+
from typing import *
7+
8+
9+
class UIAutoScrollingContainer(UIScrollingContainer):
10+
"""
11+
A container like UI element that lets users scroll around a larger container of content with
12+
scroll bars. Also allows to prevent adding scroll bars to the horizontal or vertical axis.
13+
14+
:param relative_rect: The size and relative position of the container. This will also be the
15+
starting size of the scrolling area.
16+
:param manager: The UI manager for this element. If not provided or set to None,
17+
it will try to use the first UIManager that was created by your application.
18+
:param starting_height: The starting layer height of this container above its container.
19+
Defaults to 1.
20+
:param container: The container this container is within. Defaults to None (which is the root
21+
container for the UI)
22+
:param parent_element: A parent element for this container. Defaults to None, or the
23+
container if you've set that.
24+
:param object_id: An object ID for this element.
25+
:param anchors: Layout anchors in a dictionary.
26+
:param visible: Whether the element is visible by default. Warning - container visibility
27+
may override this.
28+
"""
29+
30+
def __init__(self,
31+
relative_rect: pygame.Rect,
32+
manager: Optional[IUIManagerInterface] = None,
33+
allow_scroll_x: bool = True,
34+
allow_scroll_y: bool = True,
35+
*,
36+
starting_height: int = 1,
37+
container: Optional[IContainerLikeInterface] = None,
38+
parent_element: Optional[UIElement] = None,
39+
object_id: Optional[Union[ObjectID, str]] = None,
40+
anchors: Optional[Dict[str, Union[str, UIElement]]] = None,
41+
visible: int = 1):
42+
super().__init__(relative_rect, manager,
43+
starting_height=starting_height,
44+
container=container,
45+
parent_element=parent_element,
46+
object_id=object_id,
47+
anchors=anchors,
48+
visible=visible)
49+
50+
self._create_valid_ids(container=container,
51+
parent_element=parent_element,
52+
object_id=object_id,
53+
element_id="auto_scrolling_container")
54+
55+
self.allow_scroll_x = allow_scroll_x
56+
self.allow_scroll_y = allow_scroll_y
57+
58+
anchors = {"left": "left",
59+
"right": "left",
60+
"top": "top",
61+
"bottom": "top"}
62+
63+
resize_left: bool = True
64+
resize_right: bool = True
65+
resize_top: bool = True
66+
resize_bottom: bool = True
67+
68+
if not self.allow_scroll_x:
69+
anchors["right"] = "right"
70+
resize_left = False
71+
resize_right = False
72+
73+
if not self.allow_scroll_y:
74+
anchors["bottom"] = "bottom"
75+
resize_top = False
76+
resize_bottom = False
77+
78+
self.scrollable_container.kill()
79+
scrollable_rect = pygame.Rect(0, 0, relative_rect.width, relative_rect.height)
80+
self.scrollable_container = UIAutoResizingContainer(relative_rect=scrollable_rect,
81+
manager=manager,
82+
resize_left=resize_left,
83+
resize_right=resize_right,
84+
resize_top=resize_top,
85+
resize_bottom=resize_bottom,
86+
starting_height=0,
87+
container=self._view_container,
88+
parent_element=parent_element,
89+
object_id=ObjectID(
90+
object_id="#scrollable_container",
91+
class_id=None),
92+
anchors=anchors)
93+
94+
self.scrollable_container_dimensions = scrollable_rect.size
95+
96+
def update(self, time_delta: float):
97+
"""
98+
Updates the scrolling container's position based upon the scroll bars and updates the
99+
scrollbar's visible percentage as well if that has changed.
100+
101+
:param time_delta: The time passed between frames, measured in seconds.
102+
103+
"""
104+
super().update(time_delta)
105+
106+
new_dimensions = self.scrollable_container.rect.size
107+
108+
if self.scrollable_container_dimensions != new_dimensions:
109+
self.scrollable_container_dimensions = new_dimensions
110+
self._calculate_scrolling_dimensions()
111+
self._sort_out_element_container_scroll_bars()

pygame_gui/elements/ui_scrolling_container.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ def _calculate_scrolling_dimensions(self):
286286
def _sort_out_element_container_scroll_bars(self):
287287
"""
288288
This creates, re-sizes or removes the scrollbars after resizing, but not after the scroll
289-
bar has been moved. Instead it tries to keep the scrollbars in the same approximate position
289+
bar has been moved. Instead, it tries to keep the scrollbars in the same approximate position
290290
they were in before resizing
291291
"""
292292
self._check_scroll_bars_and_adjust()

0 commit comments

Comments
 (0)