diff --git a/src/textual/scroll_view.py b/src/textual/scroll_view.py index 5d15b360c..cf61f13e2 100644 --- a/src/textual/scroll_view.py +++ b/src/textual/scroll_view.py @@ -85,24 +85,8 @@ class ScrollView(Widget): virtual_size = self.virtual_size if self._size != size: self._size = size - self._container_size = container_size - - self._refresh_scrollbars() - 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.scrollbar_size_horizontal - ) - if self.show_horizontal_scrollbar: - self.horizontal_scrollbar.window_virtual_size = virtual_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._container_size = size + self._scroll_update(virtual_size) self.scroll_to(self.scroll_x, self.scroll_y) def render(self) -> RenderableType: diff --git a/src/textual/widget.py b/src/textual/widget.py index 994ba4bd8..861dcbe54 100644 --- a/src/textual/widget.py +++ b/src/textual/widget.py @@ -234,9 +234,10 @@ class Widget(DOMNode): Args: value (bool): Show horizontal scrollbar flag. """ - if not value: - # reset the scroll position if the scrollbar is hidden. - self.scroll_to(0, 0, animate=False) + self.refresh(layout=True) + # if not value: + # # reset the scroll position if the scrollbar is hidden. + # self.scroll_to(0, 0, animate=False) def watch_show_vertical_scrollbar(self, value: bool) -> None: """Watch function for show_vertical_scrollbar attribute. @@ -244,9 +245,10 @@ class Widget(DOMNode): Args: value (bool): Show vertical scrollbar flag. """ - if not value: - # reset the scroll position if the scrollbar is hidden. - self.scroll_to(0, 0, animate=False) + self.refresh(layout=True) + # if not value: + # # reset the scroll position if the scrollbar is hidden. + # self.scroll_to(0, 0, animate=False) def mount(self, *anon_widgets: Widget, **widgets: Widget) -> None: """Mount child widgets (making this widget a container). @@ -505,6 +507,11 @@ class Widget(DOMNode): elif overflow_y == "auto": show_vertical = self.virtual_size.height > height + if show_vertical and not show_horizontal: + show_horizontal = ( + self.virtual_size.width + styles.scrollbar_size_vertical > width + ) + self.show_horizontal_scrollbar = show_horizontal self.show_vertical_scrollbar = show_vertical self.horizontal_scrollbar.display = show_horizontal diff --git a/src/textual/widgets/_text_log.py b/src/textual/widgets/_text_log.py index cb3a82f44..e690ab19e 100644 --- a/src/textual/widgets/_text_log.py +++ b/src/textual/widgets/_text_log.py @@ -20,11 +20,13 @@ class TextLog(ScrollView, can_focus=True): """ max_lines: var[int | None] = var(None) + min_width: var[int] = var(78) def __init__( self, *, max_lines: int | None = None, + min_width: int = 78, name: str | None = None, id: str | None = None, classes: str | None = None, @@ -34,6 +36,7 @@ class TextLog(ScrollView, can_focus=True): self._line_cache: LRUCache[tuple[int, int, int, int], list[Segment]] self._line_cache = LRUCache(1024) self.max_width: int = 0 + self.min_width = min_width super().__init__(name=name, id=id, classes=classes) def write(self, content: RenderableType) -> None: @@ -43,10 +46,12 @@ class TextLog(ScrollView, can_focus=True): content (RenderableType): Rich renderable (or text). """ console = self.app.console - width = self.size.width or 80 - lines = self.app.console.render_lines( - content, console.options.update_width(width) + width = max(self.min_width, self.size.width or self.min_width) + segments = self.app.console.render( + content, + console.options.update_width(width).update(overflow="ignore", no_wrap=True), ) + lines = list(Segment.split_lines(segments)) self.max_width = max( self.max_width, max(sum(segment.cell_length for segment in _line) for _line in lines), @@ -56,7 +61,7 @@ class TextLog(ScrollView, can_focus=True): if self.max_lines is not None: self.lines = self.lines[-self.max_lines :] self.virtual_size = Size(self.max_width, len(self.lines)) - self.scroll_end(animate=True, speed=100) + self.scroll_end(animate=False, speed=100) def clear(self) -> None: """Clear the text log."""