Merge branch 'main' into fix-1372

This commit is contained in:
Will McGugan
2023-01-25 12:06:18 +01:00
committed by GitHub
13 changed files with 83 additions and 15 deletions

View File

@@ -12,12 +12,17 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- Added the coroutines `Animator.wait_for_fully_idle` and `pilot.wait_for_scheduled_animations` that allow waiting for all current and scheduled animations https://github.com/Textualize/textual/issues/1658
- Added the method `Animator.is_being_animated` that checks if an attribute of an object is being animated or is scheduled for animation
### Changed
- Breaking change: `TreeNode` can no longer be imported from `textual.widgets`; it is now available via `from textual.widgets.tree import TreeNode`. https://github.com/Textualize/textual/pull/1637
### Fixed
- Fixed stuck screen https://github.com/Textualize/textual/issues/1632
- Fixed relative units in `grid-rows` and `grid-columns` being computed with respect to the wrong dimension https://github.com/Textualize/textual/issues/1406
- Fixed bug with animations that were triggered back to back, where the second one wouldn't start https://github.com/Textualize/textual/issues/1372
- Fixed bug with animations that were scheduled where all but the first would be skipped https://github.com/Textualize/textual/issues/1372
- Programmatically setting `overflow_x`/`overflow_y` refreshes the layout correctly https://github.com/Textualize/textual/issues/1616
- Fixed double-paste into `Input` https://github.com/Textualize/textual/issues/1657
## [0.10.1] - 2023-01-20

View File

@@ -4,7 +4,8 @@ from pathlib import Path
from rich.text import Text
from textual.app import App, ComposeResult
from textual.widgets import Header, Footer, Tree, TreeNode
from textual.widgets import Header, Footer, Tree
from textual.widgets.tree import TreeNode
class TreeApp(App):

View File

@@ -704,6 +704,9 @@ class StringEnumProperty:
"""
return obj.get_rule(self.name, self._default)
def _before_refresh(self, obj: StylesBase, value: str | None) -> None:
"""Do any housekeeping before asking for a layout refresh after a value change."""
def __set__(self, obj: StylesBase, value: str | None = None):
"""Set the string property and ensure it is in the set of allowed values.
@@ -717,6 +720,7 @@ class StringEnumProperty:
_rich_traceback_omit = True
if value is None:
if obj.clear_rule(self.name):
self._before_refresh(obj, value)
obj.refresh(layout=self._layout)
else:
if value not in self._valid_values:
@@ -729,9 +733,20 @@ class StringEnumProperty:
),
)
if obj.set_rule(self.name, value):
self._before_refresh(obj, value)
obj.refresh(layout=self._layout)
class OverflowProperty(StringEnumProperty):
"""Descriptor for overflow styles that forces widgets to refresh scrollbars."""
def _before_refresh(self, obj: StylesBase, value: str | None) -> None:
from ..widget import Widget # Avoid circular import
if isinstance(obj.node, Widget):
obj.node._refresh_scrollbars()
class NameProperty:
"""Descriptor for getting and setting name properties."""

View File

@@ -26,6 +26,7 @@ from ._style_properties import (
NameListProperty,
NameProperty,
OffsetProperty,
OverflowProperty,
ScalarListProperty,
ScalarProperty,
SpacingProperty,
@@ -246,8 +247,8 @@ class StylesBase(ABC):
dock = DockProperty()
overflow_x = StringEnumProperty(VALID_OVERFLOW, "hidden")
overflow_y = StringEnumProperty(VALID_OVERFLOW, "hidden")
overflow_x = OverflowProperty(VALID_OVERFLOW, "hidden")
overflow_y = OverflowProperty(VALID_OVERFLOW, "hidden")
layer = NameProperty()
layers = NameListProperty()

View File

@@ -1,7 +1,6 @@
from __future__ import annotations
from asyncio import Lock, wait
from asyncio import Lock, create_task, wait
from collections import Counter
from fractions import Fraction
from itertools import islice
@@ -922,7 +921,7 @@ class Widget(DOMNode):
show_horizontal = self.show_horizontal_scrollbar
if overflow_x == "hidden":
show_horizontal = False
if overflow_x == "scroll":
elif overflow_x == "scroll":
show_horizontal = True
elif overflow_x == "auto":
show_horizontal = self.virtual_size.width > width
@@ -1974,13 +1973,14 @@ class Widget(DOMNode):
"""
show_vertical_scrollbar, show_horizontal_scrollbar = self.scrollbars_enabled
scrollbar_size_horizontal = self.styles.scrollbar_size_horizontal
scrollbar_size_vertical = self.styles.scrollbar_size_vertical
styles = self.styles
scrollbar_size_horizontal = styles.scrollbar_size_horizontal
scrollbar_size_vertical = styles.scrollbar_size_vertical
if self.styles.scrollbar_gutter == "stable":
if styles.scrollbar_gutter == "stable":
# Let's _always_ reserve some space, whether the scrollbar is actually displayed or not:
show_vertical_scrollbar = True
scrollbar_size_vertical = self.styles.scrollbar_size_vertical
scrollbar_size_vertical = styles.scrollbar_size_vertical
if show_horizontal_scrollbar and show_vertical_scrollbar:
(region, _, _, _) = region.split(

View File

@@ -23,7 +23,6 @@ if typing.TYPE_CHECKING:
from ._static import Static
from ._text_log import TextLog
from ._tree import Tree
from ._tree_node import TreeNode
from ._welcome import Welcome
from ..widget import Widget
@@ -44,7 +43,6 @@ __all__ = [
"Static",
"TextLog",
"Tree",
"TreeNode",
"Welcome",
]

View File

@@ -1 +0,0 @@
from ._tree import TreeNode as TreeNode

View File

@@ -0,0 +1,5 @@
"""Make non-widget DataTable support classes available."""
from ._data_table import Column, Row
__all__ = ["Column", "Row"]

View File

@@ -0,0 +1,5 @@
"""Make non-widget Tree support classes available."""
from ._tree import TreeNode
__all__ = ["TreeNode"]

View File

@@ -0,0 +1,37 @@
"""Regression test for #1616 https://github.com/Textualize/textual/issues/1616"""
import pytest
from textual.app import App
from textual.containers import Vertical
async def test_overflow_change_updates_virtual_size_appropriately():
class MyApp(App):
def compose(self):
yield Vertical()
app = MyApp()
async with app.run_test() as pilot:
vertical = app.query_one(Vertical)
height = vertical.virtual_size.height
vertical.styles.overflow_x = "scroll"
await pilot.pause() # Let changes propagate.
assert vertical.virtual_size.height < height
vertical.styles.overflow_x = "hidden"
await pilot.pause()
assert vertical.virtual_size.height == height
width = vertical.virtual_size.width
vertical.styles.overflow_y = "scroll"
await pilot.pause()
assert vertical.virtual_size.width < width
vertical.styles.overflow_y = "hidden"
await pilot.pause()
assert vertical.virtual_size.width == width

View File

@@ -1,5 +1,6 @@
import pytest
from textual.widgets import Tree, TreeNode
from textual.widgets import Tree
from textual.widgets.tree import TreeNode
def label_of(node: TreeNode[None]):

View File

@@ -1,4 +1,5 @@
from textual.widgets import Tree, TreeNode
from textual.widgets import Tree
from textual.widgets.tree import TreeNode
from rich.text import Text

View File

@@ -1,4 +1,4 @@
from textual.widgets import TreeNode, Tree
from textual.widgets import Tree
def test_tree_node_parent() -> None: