mirror of
https://github.com/Textualize/textual.git
synced 2025-10-17 02:38:12 +03:00
better thumb math
This commit is contained in:
@@ -112,8 +112,14 @@ class ScrollBarRender:
|
|||||||
if window_size and size and virtual_size and size != virtual_size:
|
if window_size and size and virtual_size and size != virtual_size:
|
||||||
step_size = virtual_size / size
|
step_size = virtual_size / size
|
||||||
|
|
||||||
|
thumb_size = window_size / step_size * len_bars
|
||||||
|
|
||||||
|
if thumb_size < len_bars:
|
||||||
|
virtual_size += step_size
|
||||||
|
step_size = virtual_size / size
|
||||||
|
|
||||||
start = int(position / step_size * len_bars)
|
start = int(position / step_size * len_bars)
|
||||||
end = start + max(len_bars, int(ceil(window_size / step_size * len_bars)))
|
end = start + max(len_bars, ceil(thumb_size))
|
||||||
|
|
||||||
start_index, start_bar = divmod(max(0, start), len_bars)
|
start_index, start_bar = divmod(max(0, start), len_bars)
|
||||||
end_index, end_bar = divmod(max(0, end), len_bars)
|
end_index, end_bar = divmod(max(0, end), len_bars)
|
||||||
@@ -246,6 +252,7 @@ class ScrollBar(Widget):
|
|||||||
yield "thickness", self.thickness
|
yield "thickness", self.thickness
|
||||||
|
|
||||||
def render(self) -> RenderableType:
|
def render(self) -> RenderableType:
|
||||||
|
assert self.parent is not None
|
||||||
styles = self.parent.styles
|
styles = self.parent.styles
|
||||||
if self.grabbed:
|
if self.grabbed:
|
||||||
background = styles.scrollbar_background_active
|
background = styles.scrollbar_background_active
|
||||||
@@ -258,11 +265,25 @@ class ScrollBar(Widget):
|
|||||||
color = styles.scrollbar_color
|
color = styles.scrollbar_color
|
||||||
color = background + color
|
color = background + color
|
||||||
scrollbar_style = Style.from_color(color.rich_color, background.rich_color)
|
scrollbar_style = Style.from_color(color.rich_color, background.rich_color)
|
||||||
|
return self._render_bar(scrollbar_style)
|
||||||
|
|
||||||
|
def _render_bar(self, scrollbar_style: Style) -> RenderableType:
|
||||||
|
"""Get a renderable for the scrollbar with given style.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
scrollbar_style: Scrollbar style.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Scrollbar renderable.
|
||||||
|
"""
|
||||||
|
window_size = (
|
||||||
|
self.window_size if self.window_size < self.window_virtual_size else 0
|
||||||
|
)
|
||||||
|
virtual_size = self.window_virtual_size
|
||||||
|
|
||||||
return self.renderer(
|
return self.renderer(
|
||||||
virtual_size=self.window_virtual_size,
|
virtual_size=ceil(virtual_size),
|
||||||
window_size=(
|
window_size=ceil(window_size),
|
||||||
self.window_size if self.window_size < self.window_virtual_size else 0
|
|
||||||
),
|
|
||||||
position=self.position,
|
position=self.position,
|
||||||
thickness=self.thickness,
|
thickness=self.thickness,
|
||||||
vertical=self.vertical,
|
vertical=self.vertical,
|
||||||
@@ -311,14 +332,26 @@ class ScrollBar(Widget):
|
|||||||
x: float | None = None
|
x: float | None = None
|
||||||
y: float | None = None
|
y: float | None = None
|
||||||
if self.vertical:
|
if self.vertical:
|
||||||
|
size = self.size.height
|
||||||
|
virtual_size = self.window_virtual_size
|
||||||
|
step_size = virtual_size / size
|
||||||
|
thumb_size = self.window_size / step_size
|
||||||
|
if thumb_size < 1:
|
||||||
|
virtual_size = ceil(virtual_size + step_size)
|
||||||
y = round(
|
y = round(
|
||||||
self.grabbed_position
|
self.grabbed_position
|
||||||
+ (
|
+ (
|
||||||
(event.screen_y - self.grabbed.y)
|
(event.screen_y - self.grabbed.y)
|
||||||
* (self.window_virtual_size / self.window_size)
|
* (virtual_size / self.window_size)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
|
size = self.size.width
|
||||||
|
virtual_size = self.window_virtual_size
|
||||||
|
step_size = virtual_size / size
|
||||||
|
thumb_size = self.window_size / step_size
|
||||||
|
if thumb_size < 1:
|
||||||
|
virtual_size = ceil(virtual_size + step_size)
|
||||||
x = round(
|
x = round(
|
||||||
self.grabbed_position
|
self.grabbed_position
|
||||||
+ (
|
+ (
|
||||||
@@ -345,3 +378,17 @@ class ScrollBarCorner(Widget):
|
|||||||
styles = self.parent.styles
|
styles = self.parent.styles
|
||||||
color = styles.scrollbar_corner_color
|
color = styles.scrollbar_corner_color
|
||||||
return Blank(color)
|
return Blank(color)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
from rich import print
|
||||||
|
from rich.console import Console
|
||||||
|
|
||||||
|
console = Console()
|
||||||
|
scrollbar = ScrollBar()
|
||||||
|
scrollbar.window_virtual_size = 100
|
||||||
|
scrollbar.window_size = 10
|
||||||
|
scrollbar.position = 95
|
||||||
|
|
||||||
|
style = Style.parse("magenta on #333333")
|
||||||
|
console.print(scrollbar._render_bar(style), height=10)
|
||||||
|
|||||||
Reference in New Issue
Block a user