Merge pull request #1823 from Textualize/optimize-scroll

Optimize scroll with a Spatial Map
This commit is contained in:
Will McGugan
2023-02-21 10:41:04 +00:00
committed by GitHub
16 changed files with 538 additions and 177 deletions

View File

@@ -9,10 +9,10 @@ from textual.widget import Widget
def test_arrange_empty():
container = Widget(id="container")
placements, widgets, spacing = arrange(container, [], Size(80, 24), Size(80, 24))
assert placements == []
assert widgets == set()
assert spacing == Spacing(0, 0, 0, 0)
result = arrange(container, [], Size(80, 24), Size(80, 24))
assert result.placements == []
assert result.widgets == set()
assert result.spacing == Spacing(0, 0, 0, 0)
def test_arrange_dock_top():
@@ -22,17 +22,16 @@ def test_arrange_dock_top():
header.styles.dock = "top"
header.styles.height = "1"
placements, widgets, spacing = arrange(
container, [child, header], Size(80, 24), Size(80, 24)
)
assert placements == [
result = arrange(container, [child, header], Size(80, 24), Size(80, 24))
assert result.placements == [
WidgetPlacement(
Region(0, 0, 80, 1), Spacing(), header, order=TOP_Z, fixed=True
),
WidgetPlacement(Region(0, 1, 80, 23), Spacing(), child, order=0, fixed=False),
]
assert widgets == {child, header}
assert spacing == Spacing(1, 0, 0, 0)
assert result.widgets == {child, header}
assert result.spacing == Spacing(1, 0, 0, 0)
def test_arrange_dock_left():
@@ -42,17 +41,15 @@ def test_arrange_dock_left():
header.styles.dock = "left"
header.styles.width = "10"
placements, widgets, spacing = arrange(
container, [child, header], Size(80, 24), Size(80, 24)
)
assert placements == [
result = arrange(container, [child, header], Size(80, 24), Size(80, 24))
assert result.placements == [
WidgetPlacement(
Region(0, 0, 10, 24), Spacing(), header, order=TOP_Z, fixed=True
),
WidgetPlacement(Region(10, 0, 70, 24), Spacing(), child, order=0, fixed=False),
]
assert widgets == {child, header}
assert spacing == Spacing(0, 0, 0, 10)
assert result.widgets == {child, header}
assert result.spacing == Spacing(0, 0, 0, 10)
def test_arrange_dock_right():
@@ -62,17 +59,15 @@ def test_arrange_dock_right():
header.styles.dock = "right"
header.styles.width = "10"
placements, widgets, spacing = arrange(
container, [child, header], Size(80, 24), Size(80, 24)
)
assert placements == [
result = arrange(container, [child, header], Size(80, 24), Size(80, 24))
assert result.placements == [
WidgetPlacement(
Region(70, 0, 10, 24), Spacing(), header, order=TOP_Z, fixed=True
),
WidgetPlacement(Region(0, 0, 70, 24), Spacing(), child, order=0, fixed=False),
]
assert widgets == {child, header}
assert spacing == Spacing(0, 10, 0, 0)
assert result.widgets == {child, header}
assert result.spacing == Spacing(0, 10, 0, 0)
def test_arrange_dock_bottom():
@@ -82,17 +77,15 @@ def test_arrange_dock_bottom():
header.styles.dock = "bottom"
header.styles.height = "1"
placements, widgets, spacing = arrange(
container, [child, header], Size(80, 24), Size(80, 24)
)
assert placements == [
result = arrange(container, [child, header], Size(80, 24), Size(80, 24))
assert result.placements == [
WidgetPlacement(
Region(0, 23, 80, 1), Spacing(), header, order=TOP_Z, fixed=True
),
WidgetPlacement(Region(0, 0, 80, 23), Spacing(), child, order=0, fixed=False),
]
assert widgets == {child, header}
assert spacing == Spacing(0, 0, 1, 0)
assert result.widgets == {child, header}
assert result.spacing == Spacing(0, 0, 1, 0)
def test_arrange_dock_badly():

64
tests/test_spatial_map.py Normal file
View File

@@ -0,0 +1,64 @@
import pytest
from textual._spatial_map import SpatialMap
from textual.geometry import Region
@pytest.mark.parametrize(
"region,grid",
[
(
Region(0, 0, 10, 10),
[
(0, 0),
],
),
(
Region(10, 10, 10, 10),
[
(1, 1),
],
),
(
Region(0, 0, 11, 11),
[(0, 0), (0, 1), (1, 0), (1, 1)],
),
(
Region(5, 5, 15, 3),
[(0, 0), (1, 0)],
),
(
Region(5, 5, 2, 15),
[(0, 0), (0, 1)],
),
],
)
def test_region_to_grid(region, grid):
spatial_map = SpatialMap(10, 10)
assert list(spatial_map._region_to_grid_coordinates(region)) == grid
def test_get_values_in_region() -> None:
spatial_map: SpatialMap[str] = SpatialMap(20, 10)
spatial_map.insert(
[
(Region(10, 5, 5, 5), False, "foo"),
(Region(5, 20, 5, 5), False, "bar"),
(Region(0, 0, 40, 1), True, "title"),
]
)
assert spatial_map.get_values_in_region(Region(0, 0, 10, 5)) == [
"title",
"foo",
]
assert spatial_map.get_values_in_region(Region(0, 1, 10, 5)) == ["title", "foo"]
assert spatial_map.get_values_in_region(Region(0, 10, 10, 5)) == ["title"]
assert spatial_map.get_values_in_region(Region(0, 20, 10, 5)) == ["title", "bar"]
assert spatial_map.get_values_in_region(Region(5, 5, 50, 50)) == [
"title",
"foo",
"bar",
]

View File

@@ -26,21 +26,18 @@ class VisibleTester(App[None]):
async def test_visibility_changes() -> None:
"""Test changing visibility via code and CSS."""
async with VisibleTester().run_test() as pilot:
assert len(pilot.app.screen.visible_widgets) == 5
assert pilot.app.query_one("#keep").visible is True
assert pilot.app.query_one("#hide-via-code").visible is True
assert pilot.app.query_one("#hide-via-css").visible is True
pilot.app.query_one("#hide-via-code").styles.visibility = "hidden"
await pilot.pause(0)
assert len(pilot.app.screen.visible_widgets) == 4
assert pilot.app.query_one("#keep").visible is True
assert pilot.app.query_one("#hide-via-code").visible is False
assert pilot.app.query_one("#hide-via-css").visible is True
pilot.app.query_one("#hide-via-css").set_class(True, "hidden")
await pilot.pause(0)
assert len(pilot.app.screen.visible_widgets) == 3
assert pilot.app.query_one("#keep").visible is True
assert pilot.app.query_one("#hide-via-code").visible is False
assert pilot.app.query_one("#hide-via-css").visible is False