Skip to content

Commit 6bc9501

Browse files
authored
Merge pull request Textualize#5444 from Textualize/grid-sizing
fix grid sizing
2 parents d34f4a4 + cb48fa9 commit 6bc9501

File tree

4 files changed

+302
-1
lines changed

4 files changed

+302
-1
lines changed

src/textual/layouts/grid.py

+4
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,7 @@ def apply_height_limits(widget: Widget, height: int) -> int:
253253
+ gutter_height,
254254
)
255255
height = max(height, widget_height)
256+
256257
row_scalars[row] = Scalar.from_number(height)
257258

258259
rows = resolve(row_scalars, size.height, gutter_horizontal, size, viewport)
@@ -271,12 +272,15 @@ def apply_height_limits(widget: Widget, height: int) -> int:
271272
x2, cell_width = columns[min(max_column, column + column_span)]
272273
y2, cell_height = rows[min(max_row, row + row_span)]
273274
cell_size = Size(cell_width + x2 - x, cell_height + y2 - y)
275+
274276
box_width, box_height, margin = widget._get_box_model(
275277
cell_size,
276278
viewport,
277279
Fraction(cell_size.width),
278280
Fraction(cell_size.height),
281+
constrain_width=True,
279282
)
283+
280284
if self.stretch_height and len(children) > 1:
281285
if box_height <= cell_size.height:
282286
box_height = Fraction(cell_size.height)

src/textual/widget.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -1455,14 +1455,16 @@ def _get_box_model(
14551455
viewport: Size,
14561456
width_fraction: Fraction,
14571457
height_fraction: Fraction,
1458+
constrain_width: bool = False,
14581459
) -> BoxModel:
14591460
"""Process the box model for this widget.
14601461
14611462
Args:
1462-
container: The size of the container widget (with a layout)
1463+
container: The size of the container widget (with a layout).
14631464
viewport: The viewport size.
14641465
width_fraction: A fraction used for 1 `fr` unit on the width dimension.
14651466
height_fraction: A fraction used for 1 `fr` unit on the height dimension.
1467+
constrain_width: Restrict the width to the container width.
14661468
14671469
Returns:
14681470
The size and margin for this widget.
@@ -1534,6 +1536,9 @@ def _get_box_model(
15341536

15351537
content_width = max(Fraction(0), content_width)
15361538

1539+
if constrain_width:
1540+
content_width = min(Fraction(container.width - gutter.width), content_width)
1541+
15371542
if styles.height is None:
15381543
# No height specified, fill the available space
15391544
content_height = Fraction(content_container.height - margin.height)

tests/snapshot_tests/__snapshots__/test_snapshots/test_widgets_in_grid.svg

+255
Loading

tests/snapshot_tests/test_snapshots.py

+37
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
Grid,
1818
Middle,
1919
Vertical,
20+
VerticalGroup,
2021
VerticalScroll,
2122
HorizontalGroup,
2223
)
@@ -3193,3 +3194,39 @@ def compose(self):
31933194
yield MyListView()
31943195

31953196
snap_compare(TUI(), press=["down", "enter", "down", "down", "enter"])
3197+
3198+
3199+
def test_widgets_in_grid(snap_compare):
3200+
"""You should see a 3x3 grid of labels where the text is wrapped, and there is no superfluous space."""
3201+
TEXT = """I must not fear.
3202+
Fear is the mind-killer.
3203+
Fear is the little-death that brings total obliteration.
3204+
I will face my fear.
3205+
I will permit it to pass over me and through me.
3206+
And when it has gone past, I will turn the inner eye to see its path.
3207+
Where the fear has gone there will be nothing. Only I will remain."""
3208+
3209+
class MyApp(App):
3210+
CSS = """
3211+
VerticalGroup {
3212+
layout: grid;
3213+
grid-size: 3 3;
3214+
grid-columns: 1fr;
3215+
grid-rows: auto;
3216+
height: auto;
3217+
background: blue;
3218+
}
3219+
Label {
3220+
border: heavy red;
3221+
text-align: left;
3222+
}
3223+
"""
3224+
3225+
def compose(self) -> ComposeResult:
3226+
with VerticalGroup():
3227+
for n in range(9):
3228+
label = Label(TEXT, id=f"label{n}")
3229+
label.border_title = str(n)
3230+
yield label
3231+
3232+
snap_compare(MyApp(), terminal_size=(100, 50))

0 commit comments

Comments
 (0)