From f44d483ee284439793cb8485ca27513a18208add Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Thu, 12 Jan 2023 10:32:29 +0000 Subject: [PATCH 1/6] Always refresh a changed scroll value, even if there's no scrollbar See #1201. See https://github.com/Textualize/textual/issues/1201#issuecomment-1380123660 though -- there has been internal discussion about how there may be a need to even inhibit by-code scrolling (as opposed to by-input) scrolling, in some situations. This would likely require that there's something higher-level, perhaps, that doesn't even attempt to animate `scroll_x` or `scroll_y` in the first place. Consider this a placeholder approach for the moment. --- src/textual/widget.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/textual/widget.py b/src/textual/widget.py index 7808f1a087..ea904208c9 100644 --- a/src/textual/widget.py +++ b/src/textual/widget.py @@ -805,14 +805,14 @@ def watch_hover_style( def watch_scroll_x(self, old_value: float, new_value: float) -> None: if self.show_horizontal_scrollbar: self.horizontal_scrollbar.position = round(new_value) - if round(old_value) != round(new_value): - self._refresh_scroll() + if round(old_value) != round(new_value): + self._refresh_scroll() def watch_scroll_y(self, old_value: float, new_value: float) -> None: if self.show_vertical_scrollbar: self.vertical_scrollbar.position = round(new_value) - if round(old_value) != round(new_value): - self._refresh_scroll() + if round(old_value) != round(new_value): + self._refresh_scroll() def validate_scroll_x(self, value: float) -> float: return clamp(value, 0, self.max_scroll_x) From 7cc17d6da13a3ac6472206bf972805735d9ab9d5 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Thu, 12 Jan 2023 11:06:19 +0000 Subject: [PATCH 2/6] Have scroll_x/y watch functions obey relevant allow properties --- src/textual/widget.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/textual/widget.py b/src/textual/widget.py index ea904208c9..d5a3c6efd5 100644 --- a/src/textual/widget.py +++ b/src/textual/widget.py @@ -803,13 +803,13 @@ def watch_hover_style( self.highlight_link_id = hover_style.link_id def watch_scroll_x(self, old_value: float, new_value: float) -> None: - if self.show_horizontal_scrollbar: + if self.allow_horizontal_scroll: self.horizontal_scrollbar.position = round(new_value) if round(old_value) != round(new_value): self._refresh_scroll() def watch_scroll_y(self, old_value: float, new_value: float) -> None: - if self.show_vertical_scrollbar: + if self.allow_vertical_scroll: self.vertical_scrollbar.position = round(new_value) if round(old_value) != round(new_value): self._refresh_scroll() From 9fee634c9d5a18b2a2e86b734171b05f065a769d Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Thu, 12 Jan 2023 13:44:33 +0000 Subject: [PATCH 3/6] Add a new force parameter to all the scroll_ methods See #1201. --- CHANGELOG.md | 1 + src/textual/widget.py | 61 +++++++++++++++++++++++++++++++++++++++---- 2 files changed, 57 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index af9c300121..c0f1d8f05a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Fail-fast and print pretty tracebacks for Widget compose errors https://github.com/Textualize/textual/pull/1505 - Added Widget._refresh_scroll to avoid expensive layout when scrolling https://github.com/Textualize/textual/pull/1524 - `events.Paste` now bubbles https://github.com/Textualize/textual/issues/1434 +- Programmatic calls to scroll now optionally scroll even if overflow styling says otherwise (introduces a new `force` parameter to all the `scroll_*` methods) https://github.com/Textualize/textual/issues/1201 ### Fixed diff --git a/src/textual/widget.py b/src/textual/widget.py index d5a3c6efd5..beec210193 100644 --- a/src/textual/widget.py +++ b/src/textual/widget.py @@ -1337,6 +1337,7 @@ def scroll_to( speed: float | None = None, duration: float | None = None, easing: EasingFunction | str | None = None, + force: bool = False, ) -> bool: """Scroll to a given (absolute) coordinate, optionally animating. @@ -1348,10 +1349,13 @@ def scroll_to( duration (float | None, optional): Duration of animation, if animate is True and speed is None. easing (EasingFunction | str | None, optional): An easing method for the scrolling animation. Defaults to "None", which will result in Textual choosing the default scrolling easing function. + force (bool,optional): Force scrolling even when prohibited by overflow styling. Defaults to `False`. Returns: bool: True if the scroll position changed, otherwise False. """ + maybe_scroll_x = x is not None and (self.allow_horizontal_scroll or force) + maybe_scroll_y = y is not None and (self.allow_vertical_scroll or force) scrolled_x = scrolled_y = False if animate: # TODO: configure animation speed @@ -1361,7 +1365,7 @@ def scroll_to( if easing is None: easing = DEFAULT_SCROLL_EASING - if x is not None: + if maybe_scroll_x: self.scroll_target_x = x if x != self.scroll_x: self.animate( @@ -1372,7 +1376,7 @@ def scroll_to( easing=easing, ) scrolled_x = True - if y is not None: + if maybe_scroll_y: self.scroll_target_y = y if y != self.scroll_y: self.animate( @@ -1385,11 +1389,11 @@ def scroll_to( scrolled_y = True else: - if x is not None: + if maybe_scroll_x: scroll_x = self.scroll_x self.scroll_target_x = self.scroll_x = x scrolled_x = scroll_x != self.scroll_x - if y is not None: + if maybe_scroll_y: scroll_y = self.scroll_y self.scroll_target_y = self.scroll_y = y scrolled_y = scroll_y != self.scroll_y @@ -1405,6 +1409,7 @@ def scroll_relative( speed: float | None = None, duration: float | None = None, easing: EasingFunction | str | None = None, + force: bool = False, ) -> bool: """Scroll relative to current position. @@ -1416,6 +1421,7 @@ def scroll_relative( duration (float | None, optional): Duration of animation, if animate is True and speed is None. easing (EasingFunction | str | None, optional): An easing method for the scrolling animation. Defaults to "None", which will result in Textual choosing the configured default scrolling easing function. + force (bool,optional): Force scrolling even when prohibited by overflow styling. Defaults to `False`. Returns: bool: True if the scroll position changed, otherwise False. @@ -1427,6 +1433,7 @@ def scroll_relative( speed=speed, duration=duration, easing=easing, + force=force, ) def scroll_home( @@ -1436,6 +1443,7 @@ def scroll_home( speed: float | None = None, duration: float | None = None, easing: EasingFunction | str | None = None, + force: bool = False, ) -> bool: """Scroll to home position. @@ -1445,6 +1453,7 @@ def scroll_home( duration (float | None, optional): Duration of animation, if animate is True and speed is None. easing (EasingFunction | str | None, optional): An easing method for the scrolling animation. Defaults to "None", which will result in Textual choosing the configured default scrolling easing function. + force (bool,optional): Force scrolling even when prohibited by overflow styling. Defaults to `False`. Returns: bool: True if any scrolling was done. @@ -1452,7 +1461,13 @@ def scroll_home( if speed is None and duration is None: duration = 1.0 return self.scroll_to( - 0, 0, animate=animate, speed=speed, duration=duration, easing=easing + 0, + 0, + animate=animate, + speed=speed, + duration=duration, + easing=easing, + force=force, ) def scroll_end( @@ -1462,6 +1477,7 @@ def scroll_end( speed: float | None = None, duration: float | None = None, easing: EasingFunction | str | None = None, + force: bool = False, ) -> bool: """Scroll to the end of the container. @@ -1471,6 +1487,7 @@ def scroll_end( duration (float | None, optional): Duration of animation, if animate is True and speed is None. easing (EasingFunction | str | None, optional): An easing method for the scrolling animation. Defaults to "None", which will result in Textual choosing the configured default scrolling easing function. + force (bool,optional): Force scrolling even when prohibited by overflow styling. Defaults to `False`. Returns: bool: True if any scrolling was done. @@ -1485,6 +1502,7 @@ def scroll_end( speed=speed, duration=duration, easing=easing, + force=force, ) def scroll_left( @@ -1494,6 +1512,7 @@ def scroll_left( speed: float | None = None, duration: float | None = None, easing: EasingFunction | str | None = None, + force: bool = False, ) -> bool: """Scroll one cell left. @@ -1503,6 +1522,7 @@ def scroll_left( duration (float | None, optional): Duration of animation, if animate is True and speed is None. easing (EasingFunction | str | None, optional): An easing method for the scrolling animation. Defaults to "None", which will result in Textual choosing the configured default scrolling easing function. + force (bool,optional): Force scrolling even when prohibited by overflow styling. Defaults to `False`. Returns: bool: True if any scrolling was done. @@ -1514,6 +1534,7 @@ def scroll_left( speed=speed, duration=duration, easing=easing, + force=force, ) def scroll_right( @@ -1523,6 +1544,7 @@ def scroll_right( speed: float | None = None, duration: float | None = None, easing: EasingFunction | str | None = None, + force: bool = False, ) -> bool: """Scroll on cell right. @@ -1532,6 +1554,7 @@ def scroll_right( duration (float | None, optional): Duration of animation, if animate is True and speed is None. easing (EasingFunction | str | None, optional): An easing method for the scrolling animation. Defaults to "None", which will result in Textual choosing the configured default scrolling easing function. + force (bool,optional): Force scrolling even when prohibited by overflow styling. Defaults to `False`. Returns: bool: True if any scrolling was done. @@ -1543,6 +1566,7 @@ def scroll_right( speed=speed, duration=duration, easing=easing, + force=force, ) def scroll_down( @@ -1552,6 +1576,7 @@ def scroll_down( speed: float | None = None, duration: float | None = None, easing: EasingFunction | str | None = None, + force: bool = False, ) -> bool: """Scroll one line down. @@ -1561,6 +1586,7 @@ def scroll_down( duration (float | None, optional): Duration of animation, if animate is True and speed is None. easing (EasingFunction | str | None, optional): An easing method for the scrolling animation. Defaults to "None", which will result in Textual choosing the configured default scrolling easing function. + force (bool,optional): Force scrolling even when prohibited by overflow styling. Defaults to `False`. Returns: bool: True if any scrolling was done. @@ -1572,6 +1598,7 @@ def scroll_down( speed=speed, duration=duration, easing=easing, + force=force, ) def scroll_up( @@ -1581,6 +1608,7 @@ def scroll_up( speed: float | None = None, duration: float | None = None, easing: EasingFunction | str | None = None, + force: bool = False, ) -> bool: """Scroll one line up. @@ -1590,6 +1618,7 @@ def scroll_up( duration (float | None, optional): Duration of animation, if animate is True and speed is None. easing (EasingFunction | str | None, optional): An easing method for the scrolling animation. Defaults to "None", which will result in Textual choosing the configured default scrolling easing function. + force (bool,optional): Force scrolling even when prohibited by overflow styling. Defaults to `False`. Returns: bool: True if any scrolling was done. @@ -1601,6 +1630,7 @@ def scroll_up( speed=speed, duration=duration, easing=easing, + force=force, ) def scroll_page_up( @@ -1610,6 +1640,7 @@ def scroll_page_up( speed: float | None = None, duration: float | None = None, easing: EasingFunction | str | None = None, + force: bool = False, ) -> bool: """Scroll one page up. @@ -1619,6 +1650,7 @@ def scroll_page_up( duration (float | None, optional): Duration of animation, if animate is True and speed is None. easing (EasingFunction | str | None, optional): An easing method for the scrolling animation. Defaults to "None", which will result in Textual choosing the configured default scrolling easing function. + force (bool,optional): Force scrolling even when prohibited by overflow styling. Defaults to `False`. Returns: bool: True if any scrolling was done. @@ -1630,6 +1662,7 @@ def scroll_page_up( speed=speed, duration=duration, easing=easing, + force=force, ) def scroll_page_down( @@ -1639,6 +1672,7 @@ def scroll_page_down( speed: float | None = None, duration: float | None = None, easing: EasingFunction | str | None = None, + force: bool = False, ) -> bool: """Scroll one page down. @@ -1648,6 +1682,7 @@ def scroll_page_down( duration (float | None, optional): Duration of animation, if animate is True and speed is None. easing (EasingFunction | str | None, optional): An easing method for the scrolling animation. Defaults to "None", which will result in Textual choosing the configured default scrolling easing function. + force (bool,optional): Force scrolling even when prohibited by overflow styling. Defaults to `False`. Returns: bool: True if any scrolling was done. @@ -1659,6 +1694,7 @@ def scroll_page_down( speed=speed, duration=duration, easing=easing, + force=force, ) def scroll_page_left( @@ -1668,6 +1704,7 @@ def scroll_page_left( speed: float | None = None, duration: float | None = None, easing: EasingFunction | str | None = None, + force: bool = False, ) -> bool: """Scroll one page left. @@ -1677,6 +1714,7 @@ def scroll_page_left( duration (float | None, optional): Duration of animation, if animate is True and speed is None. easing (EasingFunction | str | None, optional): An easing method for the scrolling animation. Defaults to "None", which will result in Textual choosing the configured default scrolling easing function. + force (bool,optional): Force scrolling even when prohibited by overflow styling. Defaults to `False`. Returns: bool: True if any scrolling was done. @@ -1690,6 +1728,7 @@ def scroll_page_left( speed=speed, duration=duration, easing=easing, + force=force, ) def scroll_page_right( @@ -1699,6 +1738,7 @@ def scroll_page_right( speed: float | None = None, duration: float | None = None, easing: EasingFunction | str | None = None, + force: bool = False, ) -> bool: """Scroll one page right. @@ -1708,6 +1748,7 @@ def scroll_page_right( duration (float | None, optional): Duration of animation, if animate is True and speed is None. easing (EasingFunction | str | None, optional): An easing method for the scrolling animation. Defaults to "None", which will result in Textual choosing the configured default scrolling easing function. + force (bool,optional): Force scrolling even when prohibited by overflow styling. Defaults to `False`. Returns: bool: True if any scrolling was done. @@ -1721,6 +1762,7 @@ def scroll_page_right( speed=speed, duration=duration, easing=easing, + force=force, ) def scroll_to_widget( @@ -1732,6 +1774,7 @@ def scroll_to_widget( duration: float | None = None, easing: EasingFunction | str | None = None, top: bool = False, + force: bool = False, ) -> bool: """Scroll scrolling to bring a widget in to view. @@ -1743,6 +1786,7 @@ def scroll_to_widget( easing (EasingFunction | str | None, optional): An easing method for the scrolling animation. Defaults to "None", which will result in Textual choosing the configured default scrolling easing function. top (bool, optional): Scroll widget to top of container. Defaults to False. + force (bool,optional): Force scrolling even when prohibited by overflow styling. Defaults to `False`. Returns: bool: True if any scrolling has occurred in any descendant, otherwise False. @@ -1762,6 +1806,7 @@ def scroll_to_widget( duration=duration, top=top, easing=easing, + force=force, ) if scroll_offset: scrolled = True @@ -1790,6 +1835,7 @@ def scroll_to_region( duration: float | None = None, easing: EasingFunction | str | None = None, top: bool = False, + force: bool = False, ) -> Offset: """Scrolls a given region in to view, if required. @@ -1805,6 +1851,7 @@ def scroll_to_region( easing (EasingFunction | str | None, optional): An easing method for the scrolling animation. Defaults to "None", which will result in Textual choosing the configured default scrolling easing function. top (bool, optional): Scroll region to top of container. Defaults to False. + force (bool,optional): Force scrolling even when prohibited by overflow styling. Defaults to `False`. Returns: Offset: The distance that was scrolled. @@ -1832,6 +1879,7 @@ def scroll_to_region( speed=speed, duration=duration, easing=easing, + force=force, ) return delta @@ -1843,6 +1891,7 @@ def scroll_visible( duration: float | None = None, top: bool = False, easing: EasingFunction | str | None = None, + force: bool = False, ) -> None: """Scroll the container to make this widget visible. @@ -1853,6 +1902,7 @@ def scroll_visible( top (bool, optional): Scroll to top of container. Defaults to False. easing (EasingFunction | str | None, optional): An easing method for the scrolling animation. Defaults to "None", which will result in Textual choosing the configured default scrolling easing function. + force (bool,optional): Force scrolling even when prohibited by overflow styling. Defaults to `False`. """ parent = self.parent if isinstance(parent, Widget): @@ -1864,6 +1914,7 @@ def scroll_visible( duration=duration, top=top, easing=easing, + force=force, ) def __init_subclass__( From 13e68b66c7fd6aaf630b4abfb928fd77aedc6ef7 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Thu, 12 Jan 2023 16:34:36 +0000 Subject: [PATCH 4/6] Tidy up the force parameter in all the docstrings --- src/textual/widget.py | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/textual/widget.py b/src/textual/widget.py index beec210193..90359eaba9 100644 --- a/src/textual/widget.py +++ b/src/textual/widget.py @@ -1349,7 +1349,7 @@ def scroll_to( duration (float | None, optional): Duration of animation, if animate is True and speed is None. easing (EasingFunction | str | None, optional): An easing method for the scrolling animation. Defaults to "None", which will result in Textual choosing the default scrolling easing function. - force (bool,optional): Force scrolling even when prohibited by overflow styling. Defaults to `False`. + force (bool, optional): Force scrolling even when prohibited by overflow styling. Defaults to `False`. Returns: bool: True if the scroll position changed, otherwise False. @@ -1421,7 +1421,7 @@ def scroll_relative( duration (float | None, optional): Duration of animation, if animate is True and speed is None. easing (EasingFunction | str | None, optional): An easing method for the scrolling animation. Defaults to "None", which will result in Textual choosing the configured default scrolling easing function. - force (bool,optional): Force scrolling even when prohibited by overflow styling. Defaults to `False`. + force (bool, optional): Force scrolling even when prohibited by overflow styling. Defaults to `False`. Returns: bool: True if the scroll position changed, otherwise False. @@ -1453,7 +1453,7 @@ def scroll_home( duration (float | None, optional): Duration of animation, if animate is True and speed is None. easing (EasingFunction | str | None, optional): An easing method for the scrolling animation. Defaults to "None", which will result in Textual choosing the configured default scrolling easing function. - force (bool,optional): Force scrolling even when prohibited by overflow styling. Defaults to `False`. + force (bool, optional): Force scrolling even when prohibited by overflow styling. Defaults to `False`. Returns: bool: True if any scrolling was done. @@ -1487,7 +1487,7 @@ def scroll_end( duration (float | None, optional): Duration of animation, if animate is True and speed is None. easing (EasingFunction | str | None, optional): An easing method for the scrolling animation. Defaults to "None", which will result in Textual choosing the configured default scrolling easing function. - force (bool,optional): Force scrolling even when prohibited by overflow styling. Defaults to `False`. + force (bool, optional): Force scrolling even when prohibited by overflow styling. Defaults to `False`. Returns: bool: True if any scrolling was done. @@ -1522,7 +1522,7 @@ def scroll_left( duration (float | None, optional): Duration of animation, if animate is True and speed is None. easing (EasingFunction | str | None, optional): An easing method for the scrolling animation. Defaults to "None", which will result in Textual choosing the configured default scrolling easing function. - force (bool,optional): Force scrolling even when prohibited by overflow styling. Defaults to `False`. + force (bool, optional): Force scrolling even when prohibited by overflow styling. Defaults to `False`. Returns: bool: True if any scrolling was done. @@ -1554,7 +1554,7 @@ def scroll_right( duration (float | None, optional): Duration of animation, if animate is True and speed is None. easing (EasingFunction | str | None, optional): An easing method for the scrolling animation. Defaults to "None", which will result in Textual choosing the configured default scrolling easing function. - force (bool,optional): Force scrolling even when prohibited by overflow styling. Defaults to `False`. + force (bool, optional): Force scrolling even when prohibited by overflow styling. Defaults to `False`. Returns: bool: True if any scrolling was done. @@ -1586,7 +1586,7 @@ def scroll_down( duration (float | None, optional): Duration of animation, if animate is True and speed is None. easing (EasingFunction | str | None, optional): An easing method for the scrolling animation. Defaults to "None", which will result in Textual choosing the configured default scrolling easing function. - force (bool,optional): Force scrolling even when prohibited by overflow styling. Defaults to `False`. + force (bool, optional): Force scrolling even when prohibited by overflow styling. Defaults to `False`. Returns: bool: True if any scrolling was done. @@ -1618,7 +1618,7 @@ def scroll_up( duration (float | None, optional): Duration of animation, if animate is True and speed is None. easing (EasingFunction | str | None, optional): An easing method for the scrolling animation. Defaults to "None", which will result in Textual choosing the configured default scrolling easing function. - force (bool,optional): Force scrolling even when prohibited by overflow styling. Defaults to `False`. + force (bool, optional): Force scrolling even when prohibited by overflow styling. Defaults to `False`. Returns: bool: True if any scrolling was done. @@ -1650,7 +1650,7 @@ def scroll_page_up( duration (float | None, optional): Duration of animation, if animate is True and speed is None. easing (EasingFunction | str | None, optional): An easing method for the scrolling animation. Defaults to "None", which will result in Textual choosing the configured default scrolling easing function. - force (bool,optional): Force scrolling even when prohibited by overflow styling. Defaults to `False`. + force (bool, optional): Force scrolling even when prohibited by overflow styling. Defaults to `False`. Returns: bool: True if any scrolling was done. @@ -1682,7 +1682,7 @@ def scroll_page_down( duration (float | None, optional): Duration of animation, if animate is True and speed is None. easing (EasingFunction | str | None, optional): An easing method for the scrolling animation. Defaults to "None", which will result in Textual choosing the configured default scrolling easing function. - force (bool,optional): Force scrolling even when prohibited by overflow styling. Defaults to `False`. + force (bool, optional): Force scrolling even when prohibited by overflow styling. Defaults to `False`. Returns: bool: True if any scrolling was done. @@ -1714,7 +1714,7 @@ def scroll_page_left( duration (float | None, optional): Duration of animation, if animate is True and speed is None. easing (EasingFunction | str | None, optional): An easing method for the scrolling animation. Defaults to "None", which will result in Textual choosing the configured default scrolling easing function. - force (bool,optional): Force scrolling even when prohibited by overflow styling. Defaults to `False`. + force (bool, optional): Force scrolling even when prohibited by overflow styling. Defaults to `False`. Returns: bool: True if any scrolling was done. @@ -1748,7 +1748,7 @@ def scroll_page_right( duration (float | None, optional): Duration of animation, if animate is True and speed is None. easing (EasingFunction | str | None, optional): An easing method for the scrolling animation. Defaults to "None", which will result in Textual choosing the configured default scrolling easing function. - force (bool,optional): Force scrolling even when prohibited by overflow styling. Defaults to `False`. + force (bool, optional): Force scrolling even when prohibited by overflow styling. Defaults to `False`. Returns: bool: True if any scrolling was done. @@ -1786,7 +1786,7 @@ def scroll_to_widget( easing (EasingFunction | str | None, optional): An easing method for the scrolling animation. Defaults to "None", which will result in Textual choosing the configured default scrolling easing function. top (bool, optional): Scroll widget to top of container. Defaults to False. - force (bool,optional): Force scrolling even when prohibited by overflow styling. Defaults to `False`. + force (bool, optional): Force scrolling even when prohibited by overflow styling. Defaults to `False`. Returns: bool: True if any scrolling has occurred in any descendant, otherwise False. @@ -1851,7 +1851,7 @@ def scroll_to_region( easing (EasingFunction | str | None, optional): An easing method for the scrolling animation. Defaults to "None", which will result in Textual choosing the configured default scrolling easing function. top (bool, optional): Scroll region to top of container. Defaults to False. - force (bool,optional): Force scrolling even when prohibited by overflow styling. Defaults to `False`. + force (bool, optional): Force scrolling even when prohibited by overflow styling. Defaults to `False`. Returns: Offset: The distance that was scrolled. @@ -1902,7 +1902,7 @@ def scroll_visible( top (bool, optional): Scroll to top of container. Defaults to False. easing (EasingFunction | str | None, optional): An easing method for the scrolling animation. Defaults to "None", which will result in Textual choosing the configured default scrolling easing function. - force (bool,optional): Force scrolling even when prohibited by overflow styling. Defaults to `False`. + force (bool, optional): Force scrolling even when prohibited by overflow styling. Defaults to `False`. """ parent = self.parent if isinstance(parent, Widget): From 843810ef177bb436fc8161f3250e4715110c50fa Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Sun, 15 Jan 2023 10:35:20 +0000 Subject: [PATCH 5/6] Remove no-scroll guard from scroll watchers --- src/textual/widget.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/textual/widget.py b/src/textual/widget.py index 90359eaba9..54e543ae54 100644 --- a/src/textual/widget.py +++ b/src/textual/widget.py @@ -803,14 +803,10 @@ def watch_hover_style( self.highlight_link_id = hover_style.link_id def watch_scroll_x(self, old_value: float, new_value: float) -> None: - if self.allow_horizontal_scroll: - self.horizontal_scrollbar.position = round(new_value) if round(old_value) != round(new_value): self._refresh_scroll() def watch_scroll_y(self, old_value: float, new_value: float) -> None: - if self.allow_vertical_scroll: - self.vertical_scrollbar.position = round(new_value) if round(old_value) != round(new_value): self._refresh_scroll() From 2b2d6c730c72483a107a07cf489473907d8c59bd Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Mon, 16 Jan 2023 15:41:20 +0000 Subject: [PATCH 6/6] Correct over-eager remove of if constructs That's how I'm reading https://github.com/Textualize/textual/pull/1550/files/1b9f51a272bc89d1aaf8b15537a19c276c8897fa#r1070555064 --- src/textual/widget.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/textual/widget.py b/src/textual/widget.py index a815cdfd5d..58721fea34 100644 --- a/src/textual/widget.py +++ b/src/textual/widget.py @@ -803,10 +803,12 @@ def watch_hover_style( self.highlight_link_id = hover_style.link_id def watch_scroll_x(self, old_value: float, new_value: float) -> None: + self.horizontal_scrollbar.position = round(new_value) if round(old_value) != round(new_value): self._refresh_scroll() def watch_scroll_y(self, old_value: float, new_value: float) -> None: + self.vertical_scrollbar.position = round(new_value) if round(old_value) != round(new_value): self._refresh_scroll()