Skip to content

Commit 784909a

Browse files
committed
gui: improve scroll bar thumb size and appearance
1 parent fe5d2d1 commit 784909a

File tree

1 file changed

+39
-14
lines changed

1 file changed

+39
-14
lines changed

arcade/gui/experimental/scroll_area.py

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
UIMouseReleaseEvent,
1919
UIMouseScrollEvent,
2020
UIWidget,
21-
bind,
21+
bind, UIKeyPressEvent,
2222
)
2323
from arcade.types import LBWH
2424

@@ -42,7 +42,7 @@ def __init__(self, scroll_area: UIScrollArea, vertical: bool = True):
4242
self.with_border(color=arcade.uicolor.GRAY_CONCRETE)
4343
self.vertical = vertical
4444

45-
self._scroll_bar_size = 20
45+
# self._scroll_bar_size = 20
4646

4747
bind(self, "_thumb_hover", self.trigger_render)
4848
bind(self, "_dragging", self.trigger_render)
@@ -52,6 +52,10 @@ def __init__(self, scroll_area: UIScrollArea, vertical: bool = True):
5252
bind(scroll_area, "content_width", self.trigger_full_render)
5353

5454
def on_event(self, event: UIEvent) -> Optional[bool]:
55+
# check if we are scrollable
56+
if not self._scrollable():
57+
return EVENT_UNHANDLED
58+
5559
# detect if event is mouse down and inside the scroll thumb
5660
# if so, start dragging the thumb
5761
thumb_rect_relative = self._thumb_rect()
@@ -68,20 +72,20 @@ def on_event(self, event: UIEvent) -> Optional[bool]:
6872
# if so, update the scroll position
6973
if isinstance(event, UIMouseDragEvent) and self._dragging:
7074
sx, sy = event.pos - self.rect.bottom_left
71-
sx -= self._scroll_bar_size / 2
72-
sy -= self._scroll_bar_size / 2
75+
sx -= self._scroll_bar_size() / 2
76+
sy -= self._scroll_bar_size() / 2
7377

7478
scroll_area = self.scroll_area
7579

7680
if self.vertical:
77-
available_track_size = self.content_height - self._scroll_bar_size
81+
available_track_size = self.content_height - self._scroll_bar_size()
7882
target_progress = 1 - sy / available_track_size
7983
target_progress = max(0, min(1, target_progress))
8084

8185
scroll_range = scroll_area.surface.height - scroll_area.content_height
8286
scroll_area.scroll_y = -target_progress * scroll_range
8387
else:
84-
available_track_size = self.content_width - self._scroll_bar_size
88+
available_track_size = self.content_width - self._scroll_bar_size()
8589
target_progress = sx / available_track_size
8690
target_progress = max(0, min(1, target_progress))
8791
scroll_range = scroll_area.surface.width - scroll_area.content_width
@@ -95,7 +99,28 @@ def on_event(self, event: UIEvent) -> Optional[bool]:
9599
self._dragging = False
96100
return True
97101

102+
if isinstance(event, UIKeyPressEvent):
103+
print(self._scroll_bar_size())
104+
98105
return EVENT_UNHANDLED
106+
107+
def _scroll_bar_size(self):
108+
# based on: https://stackoverflow.com/a/16367035
109+
110+
content_size = self.scroll_area.surface.height if self.vertical else self.scroll_area.surface.width
111+
view_size = self.scroll_area.content_height if self.vertical else self.scroll_area.content_width
112+
ratio = view_size / content_size
113+
114+
scoll_range = self.content_height if self.vertical else self.content_width
115+
116+
return scoll_range * ratio
117+
118+
def _scrollable(self):
119+
return (
120+
self.scroll_area.surface.height - self.scroll_area.content_height
121+
if self.vertical
122+
else self.scroll_area.surface.width - self.scroll_area.content_width
123+
) > 0
99124

100125
def _thumb_rect(self):
101126
"""Calculate the rect of the thumb."""
@@ -108,24 +133,24 @@ def _thumb_rect(self):
108133
else scroll_area.surface.width - scroll_area.content_width
109134
)
110135

111-
if scroll_range <= 0:
112-
# content is smaller than the scroll area, no need for a thumb
113-
return XYWH(0, 0, 0, 0)
136+
if not self._scrollable():
137+
# content is smaller than the scroll area, full size thumb
138+
return LBWH(0,0, self.content_width, self.content_height)
114139

115140
scroll_progress = -scroll_value / scroll_range
116141

117142
content_size = self.content_height if self.vertical else self.content_width
118-
available_track_size = content_size - self._scroll_bar_size
143+
available_track_size = content_size - self._scroll_bar_size()
119144

120145
if self.vertical:
121-
scroll_bar_y = self._scroll_bar_size / 2 + available_track_size * (1 - scroll_progress)
146+
scroll_bar_y = self._scroll_bar_size() / 2 + available_track_size * (1 - scroll_progress)
122147
scroll_bar_x = self.content_width / 2
123-
return XYWH(scroll_bar_x, scroll_bar_y, self.content_width, self._scroll_bar_size)
148+
return XYWH(scroll_bar_x, scroll_bar_y, self.content_width, self._scroll_bar_size())
124149

125150
else:
126-
scroll_bar_x = self._scroll_bar_size / 2 + available_track_size * scroll_progress
151+
scroll_bar_x = self._scroll_bar_size() / 2 + available_track_size * scroll_progress
127152
scroll_bar_y = self.content_height / 2
128-
return XYWH(scroll_bar_x, scroll_bar_y, self._scroll_bar_size, self.content_height)
153+
return XYWH(scroll_bar_x, scroll_bar_y, self._scroll_bar_size(), self.content_height)
129154

130155
def do_render(self, surface: Surface):
131156
"""Render the scroll bar."""

0 commit comments

Comments
 (0)