add offset to WidgetPlacement

This commit is contained in:
Will McGugan
2024-11-18 10:54:16 +00:00
parent 435f73b60d
commit 845840e830
7 changed files with 61 additions and 21 deletions

View File

@@ -6,7 +6,7 @@ from operator import attrgetter
from typing import TYPE_CHECKING, Iterable, Mapping, Sequence
from textual._partition import partition
from textual.geometry import Region, Size, Spacing
from textual.geometry import NULL_OFFSET, NULL_SPACING, Region, Size, Spacing
from textual.layout import DockArrangeResult, WidgetPlacement
if TYPE_CHECKING:
@@ -133,7 +133,8 @@ def _arrange_dock_widgets(
region_offset = region.offset
size = region.size
width, height = size
null_spacing = Spacing()
null_spacing = NULL_SPACING
null_offset = NULL_OFFSET
top = right = bottom = left = 0
@@ -173,6 +174,7 @@ def _arrange_dock_widgets(
append_placement(
_WidgetPlacement(
dock_region.translate(region_offset),
null_offset,
null_spacing,
dock_widget,
top_z,
@@ -202,7 +204,8 @@ def _arrange_split_widgets(
placements: list[WidgetPlacement] = []
append_placement = placements.append
view_region = size.region
null_spacing = Spacing()
null_spacing = NULL_SPACING
null_offset = NULL_OFFSET
for split_widget in split_widgets:
split = split_widget.styles.split
@@ -226,7 +229,9 @@ def _arrange_split_widgets(
raise AssertionError("invalid value for split edge") # pragma: no-cover
append_placement(
_WidgetPlacement(split_region, null_spacing, split_widget, 1, True)
_WidgetPlacement(
split_region, null_offset, null_spacing, split_widget, 1, True
)
)
return placements, view_region

View File

@@ -643,7 +643,7 @@ class Compositor:
)
# Add all the widgets
for sub_region, _, sub_widget, z, fixed, overlay in reversed(
for sub_region, _, _, sub_widget, z, fixed, overlay in reversed(
placements
):
layer_index = get_layer_index(sub_widget.layer, 0)

View File

@@ -84,6 +84,7 @@ class WidgetPlacement(NamedTuple):
"""The position, size, and relative order of a widget within its parent."""
region: Region
offset: Offset
margin: Spacing
widget: Widget
order: int = 0
@@ -92,7 +93,7 @@ class WidgetPlacement(NamedTuple):
@classmethod
def translate(
cls, placements: list[WidgetPlacement], offset: Offset
cls, placements: list[WidgetPlacement], translate_offset: Offset
) -> list[WidgetPlacement]:
"""Move all placements by a given offset.
@@ -103,10 +104,18 @@ class WidgetPlacement(NamedTuple):
Returns:
Placements with adjusted region, or same instance if offset is null.
"""
if offset:
if translate_offset:
return [
cls(region + offset, margin, layout_widget, order, fixed, overlay)
for region, margin, layout_widget, order, fixed, overlay in placements
cls(
region + translate_offset,
offset,
margin,
layout_widget,
order,
fixed,
overlay,
)
for region, offset, margin, layout_widget, order, fixed, overlay in placements
]
return placements

View File

@@ -5,7 +5,7 @@ from typing import TYPE_CHECKING, Iterable
from textual._resolve import resolve
from textual.css.scalar import Scalar
from textual.geometry import Region, Size, Spacing
from textual.geometry import NULL_OFFSET, Region, Size, Spacing
from textual.layout import ArrangeResult, Layout, WidgetPlacement
if TYPE_CHECKING:
@@ -292,6 +292,7 @@ class GridLayout(Layout):
add_placement(
WidgetPlacement(
region + offset,
NULL_OFFSET,
(
margin
if gutter_spacing is None

View File

@@ -4,7 +4,7 @@ from fractions import Fraction
from typing import TYPE_CHECKING
from textual._resolve import resolve_box_models
from textual.geometry import Region, Size
from textual.geometry import NULL_OFFSET, Region, Size
from textual.layout import ArrangeResult, Layout, WidgetPlacement
if TYPE_CHECKING:
@@ -89,6 +89,7 @@ class HorizontalLayout(Layout):
(next_x - x.__floor__()).__floor__(),
content_height.__floor__(),
),
NULL_OFFSET,
box_margin,
widget,
0,

View File

@@ -4,7 +4,7 @@ from fractions import Fraction
from typing import TYPE_CHECKING
from textual._resolve import resolve_box_models
from textual.geometry import Region, Size
from textual.geometry import NULL_OFFSET, Region, Size
from textual.layout import ArrangeResult, Layout, WidgetPlacement
if TYPE_CHECKING:
@@ -93,6 +93,7 @@ class VerticalLayout(Layout):
content_width.__floor__(),
next_y.__floor__() - y.__floor__(),
),
NULL_OFFSET,
box_margin,
widget,
0,

View File

@@ -2,7 +2,7 @@ import pytest
from textual._arrange import TOP_Z, arrange
from textual.app import App
from textual.geometry import Region, Size, Spacing
from textual.geometry import NULL_OFFSET, Region, Size, Spacing
from textual.layout import WidgetPlacement
from textual.widget import Widget
@@ -27,9 +27,11 @@ def test_arrange_dock_top():
assert result.placements == [
WidgetPlacement(
Region(0, 0, 80, 1), Spacing(), header, order=TOP_Z, fixed=True
Region(0, 0, 80, 1), NULL_OFFSET, Spacing(), header, order=TOP_Z, fixed=True
),
WidgetPlacement(
Region(0, 1, 80, 23), NULL_OFFSET, Spacing(), child, order=0, fixed=False
),
WidgetPlacement(Region(0, 1, 80, 23), Spacing(), child, order=0, fixed=False),
]
assert result.widgets == {child, header}
@@ -45,9 +47,16 @@ def test_arrange_dock_left():
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
Region(0, 0, 10, 24),
NULL_OFFSET,
Spacing(),
header,
order=TOP_Z,
fixed=True,
),
WidgetPlacement(
Region(10, 0, 70, 24), NULL_OFFSET, Spacing(), child, order=0, fixed=False
),
WidgetPlacement(Region(10, 0, 70, 24), Spacing(), child, order=0, fixed=False),
]
assert result.widgets == {child, header}
@@ -63,9 +72,16 @@ def test_arrange_dock_right():
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
Region(70, 0, 10, 24),
NULL_OFFSET,
Spacing(),
header,
order=TOP_Z,
fixed=True,
),
WidgetPlacement(
Region(0, 0, 70, 24), NULL_OFFSET, Spacing(), child, order=0, fixed=False
),
WidgetPlacement(Region(0, 0, 70, 24), Spacing(), child, order=0, fixed=False),
]
assert result.widgets == {child, header}
@@ -81,9 +97,16 @@ def test_arrange_dock_bottom():
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
Region(0, 23, 80, 1),
NULL_OFFSET,
Spacing(),
header,
order=TOP_Z,
fixed=True,
),
WidgetPlacement(
Region(0, 0, 80, 23), NULL_OFFSET, Spacing(), child, order=0, fixed=False
),
WidgetPlacement(Region(0, 0, 80, 23), Spacing(), child, order=0, fixed=False),
]
assert result.widgets == {child, header}