Merge pull request #1311 from Textualize/fix-1309

Empty containers with auto dimensions will collapse
This commit is contained in:
Will McGugan
2022-12-07 18:32:03 +01:00
committed by GitHub
7 changed files with 46 additions and 8 deletions

View File

@@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
### Changed ### Changed
- Rebuilt `DirectoryTree` with new `Tree` control. - Rebuilt `DirectoryTree` with new `Tree` control.
- Empty containers with a dimension set to `"auto"` will now collapse instead of filling up the available space.
- Container widgets now have default height of `1fr`. - Container widgets now have default height of `1fr`.
- The default `width` of a `Label` is now `auto`. - The default `width` of a `Label` is now `auto`.

View File

@@ -67,7 +67,7 @@ class Layout(ABC):
) )
width = child_width if width is None else max(width, child_width) width = child_width if width is None else max(width, child_width)
if width is None: if width is None:
width = container.width width = 0
return width return width
@@ -86,7 +86,7 @@ class Layout(ABC):
int: Content height (in lines). int: Content height (in lines).
""" """
if not widget.displayed_children: if not widget.displayed_children:
height = container.height height = 0
else: else:
placements, *_ = widget._arrange(Size(width, container.height)) placements, *_ = widget._arrange(Size(width, container.height))
height = max( height = max(

View File

@@ -124,7 +124,7 @@ def get_box_model(
) )
content_height = min(content_height, max_height) content_height = min(content_height, max_height)
content_height = max(Fraction(1), content_height) content_height = max(Fraction(0), content_height)
model = BoxModel( model = BoxModel(
content_width + gutter.width, content_height + gutter.height, margin content_width + gutter.width, content_height + gutter.height, margin
) )

View File

@@ -73,7 +73,7 @@ class HorizontalLayout(Layout):
int: Width of the content. int: Width of the content.
""" """
if not widget.displayed_children: if not widget.displayed_children:
width = container.width width = 0
else: else:
placements, *_ = widget._arrange(container) placements, *_ = widget._arrange(container)
width = max( width = max(

View File

@@ -61,6 +61,7 @@ class Input(Widget, can_focus=True):
border: tall $background; border: tall $background;
width: 100%; width: 100%;
height: 1; height: 1;
min-height: 1;
} }
Input.-disabled { Input.-disabled {
opacity: 0.6; opacity: 0.6;

View File

@@ -0,0 +1,28 @@
import pytest
from textual.layouts.grid import GridLayout
from textual.layouts.horizontal import HorizontalLayout
from textual.layouts.vertical import VerticalLayout
from textual.geometry import Size
from textual.widget import Widget
LAYOUTS = [GridLayout, HorizontalLayout, VerticalLayout]
@pytest.mark.parametrize("layout", LAYOUTS)
def test_empty_widget_height(layout):
"""Test that an empty widget has height equal to 0."""
l = layout()
# Make sure this measurement does not depend on the width.
assert l.get_content_height(Widget(), Size(80, 24), Size(80, 24), 24) == 0
assert l.get_content_height(Widget(), Size(80, 24), Size(80, 24), 20) == 0
assert l.get_content_height(Widget(), Size(80, 24), Size(80, 24), 10) == 0
assert l.get_content_height(Widget(), Size(80, 24), Size(80, 24), 0) == 0
@pytest.mark.parametrize("layout", LAYOUTS)
def test_empty_widget_width(layout):
"""Test that an empty widget has width equal to 0."""
l = layout()
assert l.get_content_width(Widget(), Size(80, 24), Size(80, 24)) == 0

View File

@@ -100,7 +100,7 @@ def test_width():
def test_height(): def test_height():
"""Test width settings.""" """Test height settings."""
styles = Styles() styles = Styles()
one = Fraction(1) one = Fraction(1)
@@ -123,7 +123,7 @@ def test_height():
) )
assert box_model == BoxModel(Fraction(54), Fraction(16), Spacing(1, 2, 3, 4)) assert box_model == BoxModel(Fraction(54), Fraction(16), Spacing(1, 2, 3, 4))
# Set width to 100 vw which should make it the width of the parent # Set height to 100 vw which should make it the height of the parent
styles.height = "100vh" styles.height = "100vh"
box_model = get_box_model( box_model = get_box_model(
@@ -131,7 +131,7 @@ def test_height():
) )
assert box_model == BoxModel(Fraction(54), Fraction(24), Spacing(1, 2, 3, 4)) assert box_model == BoxModel(Fraction(54), Fraction(24), Spacing(1, 2, 3, 4))
# Set the width to 100% should make it fill the container size # Set the height to 100% should make it fill the container size
styles.height = "100%" styles.height = "100%"
box_model = get_box_model( box_model = get_box_model(
@@ -156,6 +156,14 @@ def test_height():
) )
assert box_model == BoxModel(Fraction(54), Fraction(10), Spacing(1, 2, 3, 4)) assert box_model == BoxModel(Fraction(54), Fraction(10), Spacing(1, 2, 3, 4))
# Set height to auto and set content height to 0 to check if box collapses.
styles.height = "auto"
box_model = get_box_model(
styles, Size(60, 20), Size(80, 24), one, one, get_auto_width, lambda *_: 0
)
assert box_model == BoxModel(Fraction(54), Fraction(0), Spacing(1, 2, 3, 4))
def test_max(): def test_max():
"""Check that max_width and max_height are respected.""" """Check that max_width and max_height are respected."""