From d8e35a15cb2ef8cf0787837c6207559f2f7c7bc4 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Thu, 1 Sep 2022 21:07:36 +0100 Subject: [PATCH] scrollbar fix --- sandbox/will/spacing.css | 3 ++- src/textual/scroll_view.py | 10 +++++++--- src/textual/scrollbar.py | 40 +++++++++++++++++++++----------------- src/textual/widget.py | 13 +++++++++---- 4 files changed, 40 insertions(+), 26 deletions(-) diff --git a/sandbox/will/spacing.css b/sandbox/will/spacing.css index 4e256a341..5e1aec208 100644 --- a/sandbox/will/spacing.css +++ b/sandbox/will/spacing.css @@ -8,5 +8,6 @@ Static { background: blue 20%; height: 100%; margin: 2 4; - min-width: 30; + min-width: 80; + min-height: 40; } diff --git a/src/textual/scroll_view.py b/src/textual/scroll_view.py index 8312be117..6561905db 100644 --- a/src/textual/scroll_view.py +++ b/src/textual/scroll_view.py @@ -87,15 +87,19 @@ class ScrollView(Widget): width, height = self.container_size if self.show_vertical_scrollbar: self.vertical_scrollbar.window_virtual_size = virtual_size.height - self.vertical_scrollbar.window_size = height + self.vertical_scrollbar.window_size = ( + height - self.scrollbar_size_horizontal + ) if self.show_horizontal_scrollbar: self.horizontal_scrollbar.window_virtual_size = virtual_size.width - self.horizontal_scrollbar.window_size = width + self.horizontal_scrollbar.window_size = ( + width - self.scrollbar_size_vertical + ) self.scroll_x = self.validate_scroll_x(self.scroll_x) self.scroll_y = self.validate_scroll_y(self.scroll_y) self.refresh(layout=False) - self.call_later(self.scroll_to, self.scroll_x, self.scroll_y) + self.scroll_to(self.scroll_x, self.scroll_y) def render(self) -> RenderableType: """Render the scrollable region (if `render_lines` is not implemented). diff --git a/src/textual/scrollbar.py b/src/textual/scrollbar.py index b9dd00774..eb5986873 100644 --- a/src/textual/scrollbar.py +++ b/src/textual/scrollbar.py @@ -93,9 +93,9 @@ class ScrollBarRender: ) -> Segments: if vertical: - bars = [" ", "▁", "▂", "▃", "▄", "▅", "▆", "▇", "█"] + bars = ["▁", "▂", "▃", "▄", "▅", "▆", "▇", " "] else: - bars = ["█", "▉", "▊", "▋", "▌", "▍", "▎", "▏", " "] + bars = ["▉", "▊", "▋", "▌", "▍", "▎", "▏", " "] back = back_color bar = bar_color @@ -110,11 +110,11 @@ class ScrollBarRender: if window_size and size and virtual_size and size != virtual_size: step_size = virtual_size / size - start = int(position / step_size * 9) - end = start + max(9, int(ceil(window_size / step_size * 9))) + start = int(position / step_size * 8) + end = start + max(8, int(ceil(window_size / step_size * 8))) - start_index, start_bar = divmod(start, 9) - end_index, end_bar = divmod(end, 9) + start_index, start_bar = divmod(start, 8) + end_index, end_bar = divmod(end, 8) upper = {"@click": "scroll_up"} lower = {"@click": "scroll_down"} @@ -130,19 +130,23 @@ class ScrollBarRender: ] * (end_index - start_index) if start_index < len(segments): - segments[start_index] = _Segment( - bars[8 - start_bar] * width_thickness, - _Style(bgcolor=back, color=bar, meta=foreground_meta) - if vertical - else _Style(bgcolor=bar, color=back, meta=foreground_meta), - ) + bar_character = bars[7 - start_bar] + if bar_character != " ": + segments[start_index] = _Segment( + bar_character * width_thickness, + _Style(bgcolor=back, color=bar, meta=foreground_meta) + if vertical + else _Style(bgcolor=bar, color=back, meta=foreground_meta), + ) if end_index < len(segments): - segments[end_index] = _Segment( - bars[8 - end_bar] * width_thickness, - _Style(bgcolor=bar, color=back, meta=foreground_meta) - if vertical - else _Style(bgcolor=back, color=bar, meta=foreground_meta), - ) + bar_character = bars[7 - end_bar] + if bar_character != " ": + segments[end_index] = _Segment( + bar_character * width_thickness, + _Style(bgcolor=bar, color=back, meta=foreground_meta) + if vertical + else _Style(bgcolor=back, color=bar, meta=foreground_meta), + ) else: style = _Style(bgcolor=back) segments = [_Segment(blank, style=style)] * int(size) diff --git a/src/textual/widget.py b/src/textual/widget.py index 3f0e2f2bb..e942e93f5 100644 --- a/src/textual/widget.py +++ b/src/textual/widget.py @@ -468,7 +468,7 @@ class Widget(DOMNode): self.app.start_widget(self, scroll_bar) return scroll_bar - def _refresh_scrollbars(self) -> None: + def _refresh_scrollbars(self) -> tuple[bool, bool]: """Refresh scrollbar visibility.""" if not self.is_scrollable: return @@ -499,6 +499,8 @@ class Widget(DOMNode): self.horizontal_scrollbar.display = show_horizontal self.vertical_scrollbar.display = show_vertical + return show_horizontal, show_vertical + @property def scrollbars_enabled(self) -> tuple[bool, bool]: """A tuple of booleans that indicate if scrollbars are enabled. @@ -1248,16 +1250,19 @@ class Widget(DOMNode): width, height = self.container_size if self.show_vertical_scrollbar: self.vertical_scrollbar.window_virtual_size = virtual_size.height - self.vertical_scrollbar.window_size = height + self.vertical_scrollbar.window_size = ( + height - self.scrollbar_size_horizontal + ) if self.show_horizontal_scrollbar: self.horizontal_scrollbar.window_virtual_size = virtual_size.width - self.horizontal_scrollbar.window_size = width + self.horizontal_scrollbar.window_size = ( + width - self.scrollbar_size_vertical + ) self.scroll_x = self.validate_scroll_x(self.scroll_x) self.scroll_y = self.validate_scroll_y(self.scroll_y) self.refresh(layout=True) self.scroll_to(self.scroll_x, self.scroll_y) - # self.call_later(self.scroll_to, self.scroll_x, self.scroll_y) else: self.refresh()