Merge pull request #2030 from Textualize/add-containers

Add containers
This commit is contained in:
Rodrigo Girão Serrão
2023-03-15 10:37:01 +00:00
committed by GitHub
49 changed files with 707 additions and 120 deletions

View File

@@ -1,9 +1,9 @@
from random import randint
import time
from random import randint
from textual.app import App, ComposeResult
from textual.color import Color
from textual.containers import Grid, Vertical
from textual.containers import Grid, VerticalScroll
from textual.widget import Widget
from textual.widgets import Footer, Label
@@ -28,7 +28,7 @@ class MyApp(App[None]):
def compose(self) -> ComposeResult:
yield Grid(
ColourChanger(),
Vertical(id="log"),
VerticalScroll(id="log"),
)
yield Footer()

View File

@@ -1,10 +1,10 @@
import asyncio
from random import randint
import time
from random import randint
from textual.app import App, ComposeResult
from textual.color import Color
from textual.containers import Grid, Vertical
from textual.containers import Grid, VerticalScroll
from textual.widget import Widget
from textual.widgets import Footer, Label
@@ -29,7 +29,7 @@ class MyApp(App[None]):
def compose(self) -> ComposeResult:
yield Grid(
ColourChanger(),
Vertical(id="log"),
VerticalScroll(id="log"),
)
yield Footer()

View File

@@ -1,10 +1,10 @@
import asyncio
from random import randint
import time
from random import randint
from textual.app import App, ComposeResult
from textual.color import Color
from textual.containers import Grid, Vertical
from textual.containers import Grid, VerticalScroll
from textual.widget import Widget
from textual.widgets import Footer, Label
@@ -29,7 +29,7 @@ class MyApp(App[None]):
def compose(self) -> ComposeResult:
yield Grid(
ColourChanger(),
Vertical(id="log"),
VerticalScroll(id="log"),
)
yield Footer()

View File

@@ -6,9 +6,10 @@ except ImportError:
raise ImportError("Please install httpx with 'pip install httpx' ")
from rich.json import JSON
from textual.app import App, ComposeResult
from textual.containers import Vertical
from textual.widgets import Static, Input
from textual.containers import VerticalScroll
from textual.widgets import Input, Static
class DictionaryApp(App):
@@ -18,7 +19,7 @@ class DictionaryApp(App):
def compose(self) -> ComposeResult:
yield Input(placeholder="Search for a word")
yield Vertical(Static(id="results"), id="results-container")
yield VerticalScroll(Static(id="results"), id="results-container")
async def on_input_changed(self, message: Input.Changed) -> None:
"""A coroutine to handle a text changed message."""

View File

@@ -1,5 +1,5 @@
from textual.app import App, ComposeResult
from textual.containers import Container, Horizontal, Vertical
from textual.containers import Container, Horizontal, VerticalScroll
from textual.widgets import Header, Static
@@ -9,7 +9,7 @@ class CombiningLayoutsExample(App):
def compose(self) -> ComposeResult:
yield Header()
with Container(id="app-grid"):
with Vertical(id="left-pane"):
with VerticalScroll(id="left-pane"):
for number in range(15):
yield Static(f"Vertical layout, child {number}")
with Horizontal(id="top-right"):

View File

@@ -1,6 +1,6 @@
from textual.app import App
from textual.containers import Vertical
from textual.widgets import Placeholder, Label, Static
from textual.containers import VerticalScroll
from textual.widgets import Label, Placeholder, Static
class Ruler(Static):
@@ -11,7 +11,7 @@ class Ruler(Static):
class HeightComparisonApp(App):
def compose(self):
yield Vertical(
yield VerticalScroll(
Placeholder(id="cells"), # (1)!
Placeholder(id="percent"),
Placeholder(id="w"),

View File

@@ -1,11 +1,11 @@
from textual.app import App
from textual.containers import Vertical
from textual.containers import VerticalScroll
from textual.widgets import Placeholder
class MaxWidthApp(App):
def compose(self):
yield Vertical(
yield VerticalScroll(
Placeholder("max-width: 50h", id="p1"),
Placeholder("max-width: 999", id="p2"),
Placeholder("max-width: 50%", id="p3"),

View File

@@ -1,4 +1,4 @@
Vertical {
VerticalScroll {
height: 100%;
width: 100%;
overflow-x: auto;
@@ -10,7 +10,8 @@ Placeholder {
}
#p1 {
min-width: 25%; /* (1)! */
min-width: 25%;
/* (1)! */
}
#p2 {

View File

@@ -1,11 +1,11 @@
from textual.app import App
from textual.containers import Vertical
from textual.containers import VerticalScroll
from textual.widgets import Placeholder
class MinWidthApp(App):
def compose(self):
yield Vertical(
yield VerticalScroll(
Placeholder("min-width: 25%", id="p1"),
Placeholder("min-width: 75%", id="p2"),
Placeholder("min-width: 100", id="p3"),

View File

@@ -3,7 +3,7 @@ Screen {
color: black;
}
Vertical {
VerticalScroll {
width: 1fr;
}
@@ -13,7 +13,7 @@ Static {
border: green wide;
color: white 90%;
height: auto;
}
}
#right {
overflow-y: hidden;

View File

@@ -1,6 +1,6 @@
from textual.app import App
from textual.containers import Horizontal, VerticalScroll
from textual.widgets import Static
from textual.containers import Horizontal, Vertical
TEXT = """I must not fear.
Fear is the mind-killer.
@@ -14,8 +14,8 @@ Where the fear has gone there will be nothing. Only I will remain."""
class OverflowApp(App):
def compose(self):
yield Horizontal(
Vertical(Static(TEXT), Static(TEXT), Static(TEXT), id="left"),
Vertical(Static(TEXT), Static(TEXT), Static(TEXT), id="right"),
VerticalScroll(Static(TEXT), Static(TEXT), Static(TEXT), id="left"),
VerticalScroll(Static(TEXT), Static(TEXT), Static(TEXT), id="right"),
)

View File

@@ -1,11 +1,11 @@
from textual.app import App
from textual.containers import Horizontal, Vertical
from textual.containers import Horizontal, VerticalScroll
from textual.widgets import Placeholder
class VisibilityContainersApp(App):
def compose(self):
yield Vertical(
yield VerticalScroll(
Horizontal(
Placeholder(),
Placeholder(),

View File

@@ -2,7 +2,7 @@ Button {
margin: 1 2;
}
Horizontal > Vertical {
Horizontal > VerticalScroll {
width: 24;
}

View File

@@ -1,5 +1,5 @@
from textual.app import App, ComposeResult
from textual.containers import Horizontal, Vertical
from textual.containers import Horizontal, VerticalScroll
from textual.widgets import Button, Static
@@ -8,7 +8,7 @@ class ButtonsApp(App[str]):
def compose(self) -> ComposeResult:
yield Horizontal(
Vertical(
VerticalScroll(
Static("Standard Buttons", classes="header"),
Button("Default"),
Button("Primary!", variant="primary"),
@@ -16,7 +16,7 @@ class ButtonsApp(App[str]):
Button.warning("Warning!"),
Button.error("Error!"),
),
Vertical(
VerticalScroll(
Static("Disabled Buttons", classes="header"),
Button("Default", disabled=True),
Button("Primary!", variant="primary", disabled=True),

View File

@@ -2,7 +2,7 @@ Screen {
align: center middle;
}
Vertical {
VerticalScroll {
width: auto;
height: auto;
border: solid $primary;

View File

@@ -1,5 +1,5 @@
from textual.app import App, ComposeResult
from textual.containers import Vertical
from textual.containers import VerticalScroll
from textual.widgets import Checkbox
@@ -7,7 +7,7 @@ class CheckboxApp(App[None]):
CSS_PATH = "checkbox.css"
def compose(self) -> ComposeResult:
with Vertical():
with VerticalScroll():
yield Checkbox("Arrakis :sweat:")
yield Checkbox("Caladan")
yield Checkbox("Chusuk")

View File

@@ -1,14 +1,13 @@
from textual.app import App, ComposeResult
from textual.containers import Container, Horizontal, Vertical
from textual.containers import Container, Horizontal, VerticalScroll
from textual.widgets import Placeholder
class PlaceholderApp(App):
CSS_PATH = "placeholder.css"
def compose(self) -> ComposeResult:
yield Vertical(
yield VerticalScroll(
Container(
Placeholder("This is a custom label for p1.", id="p1"),
Placeholder("Placeholder p2 here!", id="p2"),

View File

@@ -1,4 +1,4 @@
Vertical {
VerticalScroll {
align: center middle;
}

View File

@@ -1,5 +1,5 @@
from textual.app import App, ComposeResult
from textual.containers import Horizontal, Vertical
from textual.containers import Horizontal, VerticalScroll
from textual.widgets import Label, RadioButton, RadioSet
@@ -7,7 +7,7 @@ class RadioSetChangedApp(App[None]):
CSS_PATH = "radio_set_changed.css"
def compose(self) -> ComposeResult:
with Vertical():
with VerticalScroll():
with Horizontal():
with RadioSet():
yield RadioButton("Battlestar Galactica")

View File

@@ -134,8 +134,8 @@ exceeds the available horizontal space in the parent container.
## Utility containers
Textual comes with several "container" widgets.
These are [Vertical][textual.containers.Vertical], [Horizontal][textual.containers.Horizontal], and [Grid][textual.containers.Grid] which have the corresponding layout.
Textual comes with [several "container" widgets][textual.containers].
Among them, we have [Vertical][textual.containers.Vertical], [Horizontal][textual.containers.Horizontal], and [Grid][textual.containers.Grid] which have the corresponding layout.
The example below shows how we can combine these containers to create a simple 2x2 grid.
Inside a single `Horizontal` container, we place two `Vertical` containers.
@@ -163,8 +163,8 @@ However, Textual comes with a more powerful mechanism for achieving this known a
## Composing with context managers
In the previous section we've show how you add children to a container (such as `Horizontal` and `Vertical`) using positional arguments.
It's fine to do it this way, but Textual offers a simplified syntax using [context managers](https://docs.python.org/3/reference/datamodel.html#context-managers) which is generally easier to write and edit.
In the previous section, we've shown how you add children to a container (such as `Horizontal` and `Vertical`) using positional arguments.
It's fine to do it this way, but Textual offers a simplified syntax using [context managers](https://docs.python.org/3/reference/datamodel.html#context-managers), which is generally easier to write and edit.
When composing a widget, you can introduce a container using Python's `with` statement.
Any widgets yielded within that block are added as a child of the container.
@@ -202,7 +202,7 @@ Let's update the [utility containers](#utility-containers) example to use the co
```{.textual path="docs/examples/guide/layout/utility_containers_using_with.py"}
```
Note how the end result is the same, but the code with context managers is a little easer to read. It is up to you which method you want to use, and you can mix context managers with positional arguments if you like!
Note how the end result is the same, but the code with context managers is a little easier to read. It is up to you which method you want to use, and you can mix context managers with positional arguments if you like!
## Grid

View File

@@ -61,8 +61,8 @@ Open the CSS file tab to see the comments that explain how each height is comput
1. This sets the height to 2 lines.
2. This sets the height to 12.5% of the space made available by the container. The container is 24 lines tall, so 12.5% of 24 is 3.
3. This sets the height to 5% of the width of the direct container, which is the `Vertical` container. Because it expands to fit all of the terminal, the width of the `Vertical` is 80 and 5% of 80 is 4.
4. This sets the height to 12.5% of the height of the direct container, which is the `Vertical` container. Because it expands to fit all of the terminal, the height of the `Vertical` is 24 and 12.5% of 24 is 3.
3. This sets the height to 5% of the width of the direct container, which is the `VerticalScroll` container. Because it expands to fit all of the terminal, the width of the `VerticalScroll` is 80 and 5% of 80 is 4.
4. This sets the height to 12.5% of the height of the direct container, which is the `VerticalScroll` container. Because it expands to fit all of the terminal, the height of the `VerticalScroll` is 24 and 12.5% of 24 is 3.
5. This sets the height to 6.25% of the viewport width, which is 80. 6.25% of 80 is 5.
6. This sets the height to 12.5% of the viewport height, which is 24. 12.5% of 24 is 3.
7. This sets the height of the placeholder to be the optimal size that fits the content without scrolling.

View File

@@ -25,7 +25,7 @@ The default setting for containers is `overflow: auto auto`.
!!! warning
Some built-in containers like `Horizontal` and `Vertical` override these defaults.
Some built-in containers like `Horizontal` and `VerticalScroll` override these defaults.
## Example