This commit is contained in:
Will McGugan
2022-07-30 13:03:49 +01:00
parent 6be8fb35fe
commit 7ba36c1146
11 changed files with 174 additions and 9 deletions

View File

@@ -2,6 +2,8 @@
The `Mount` event is sent to a widget and Application when it is first mounted.
The mount event is typically used to set the initial state of a widget or to add new children widgets.
- [ ] Bubbles
## Parameters

View File

@@ -17,3 +17,7 @@ The `Resize` event is sent to a widget when its size changes and when it is firs
`event.container_size`
: The size of the widget's container.
## Code
::: textual.events.Mount

View File

@@ -0,0 +1,24 @@
from textual.app import App
from textual.widget import Widget
class WidthApp(App):
CSS = """
Screen > Widget {
height: 5;
background: blue;
color: white;
border: heavy white;
}
Widget.hidden {
display: none;
}
"""
def compose(self):
yield Widget(id="widget1")
yield Widget(id="widget2", classes="hidden")
yield Widget(id="widget3")
app = WidthApp()

View File

@@ -0,0 +1,18 @@
from textual.app import App
from textual.widget import Widget
class WidthApp(App):
CSS = """
Screen > Widget {
background: green;
height: 50%;
color: white;
}
"""
def compose(self):
yield Widget()
app = WidthApp()

View File

@@ -4,9 +4,10 @@ from textual.widget import Widget
class WidthApp(App):
CSS = """
Widget {
background: blue 50%;
Screen > Widget {
background: green;
width: 50%;
color: white;
}
"""

View File

@@ -42,9 +42,9 @@ The first step in all Textual applications is to import the `App` class from `te
--8<-- "docs/examples/introduction/intro01.py"
```
This App class is responsible for loading data, setting up the screen, managing events etc. In a real app most of the core logic of your application will be contained within methods on the this class.
This App class is responsible for loading data, setting up the screen, managing events etc. In a real app most of the core logic of your application will be contained within methods on this class.
The last two lines create an instance of the application and calls `run()`:
The last two lines create an instance of the application and calls the `run()` method:
```python hl_lines="8 9" title="intro01.py"
--8<-- "docs/examples/introduction/intro01.py"
@@ -130,7 +130,7 @@ This script imports App as before, but also the `Widget` class from `textual.wid
Widgets support many of the same events as the Application itself, and can be thought of as mini-applications in their own right. The Clock widget responds to a Mount event which is the first event received when a widget is _mounted_ (added to the App). The code in `Clock.on_mount` sets `styles.content_align` to tuple of `("center", "middle")` which tells Textual to display the Widget's content aligned to the horizontal center, and in the middle vertically. If you resize the terminal, you should find the time remains in the center.
The second line in `on_mount` calls `self.set_interval` which tells Textual to invoke the `self.refresh` function once a second to refresh the Clock widget.
The second line in `on_mount` calls `self.set_interval` which tells Textual to invoke the `self.refresh` method once a second.
When Textual refreshes a widget it calls it's `render` method:

48
docs/styles/display.md Normal file
View File

@@ -0,0 +1,48 @@
# Display
The `display` property defines if a Widget is displayed or not. The default value is `"block"` which will display the widget as normal. Setting the property to `"none"` will effectively make it invisible.
## Example
Note that the second widget is hidden by adding the "hidden" class which sets the display style to None.
=== "display.py"
```python
--8<-- "docs/examples/styles/display.py"
```
=== "Output"
```{.textual path="docs/examples/styles/display.py"}
```
## CSS
```sass
/* Widget is on screen */
display: block;
/* Widget is not on the screen */
display: none;
```
## Python
```python
# Hide the widget
self.styles.display = "none"
# Show the widget again
self.styles.display = "block"
```
There is also a shortcut to show / hide a widget. The `display` property on `Widget` may be set to `True` or `False` to show or hide the widget.
```python
# Hide the widget
widget.display = False
# Show the widget
widget.display = True
```

37
docs/styles/height.md Normal file
View File

@@ -0,0 +1,37 @@
# Height
The `height` property sets a widget's height. By default, it sets the width of the content area, but if `box-sizing` is set to `border-box` it sets the width of the border area.
## Example
=== "width.py"
```python
--8<-- "docs/examples/styles/height.py"
```
=== "Output"
```{.textual path="docs/examples/styles/height.py"}
```
## CSS
```sass
/* Explicit cell height */
height: 10;
/* Percentage height */
height: 50%;
/* Automatic height */
width: auto
```
## Python
```python
self.styles.height = 10
self.styles.height = "50%
self.styles.height = "auto"
```

View File

@@ -11,7 +11,9 @@ nav:
- "events/mount.md"
- "events/resize.md"
- Styles:
- "styles/display.md"
- "styles/width.md"
- "styles/height.md"
- Widgets: "/widgets/"
- Reference:
- "reference/app.md"

View File

@@ -87,8 +87,7 @@ class Action(Event):
class Resize(Event, verbosity=2, bubble=False):
"""Sent when the app or widget has been resized."""
__slots__ = ["size"]
size: Size
__slots__ = ["size", "virtual_size", "container_size"]
def __init__(
self,

View File

@@ -45,10 +45,13 @@ def clamp(value: T, minimum: T, maximum: T) -> T:
class Offset(NamedTuple):
"""A point defined by x and y coordinates."""
"""A cell offset defined by x and y coordinates. Offsets are typically relative to the
top left of the terminal or other container."""
x: int = 0
"""Offset in the x-axis (horizontal)"""
y: int = 0
"""Offset in the y-axis (vertical)"""
@property
def is_origin(self) -> bool:
@@ -118,7 +121,10 @@ class Size(NamedTuple):
"""An area defined by its width and height."""
width: int = 0
"""The width in cells."""
height: int = 0
"""The height in cells."""
def __bool__(self) -> bool:
"""A Size is Falsy if it has area 0."""
@@ -196,12 +202,32 @@ class Size(NamedTuple):
class Region(NamedTuple):
"""Defines a rectangular region."""
"""Defines a rectangular region.
A Region consists a coordinate (x and y) and dimensions (width and height).
```
(x, y)
┌────────────────────┐ ▲
│ │ │
│ │ │
│ │ height
│ │ │
│ │ │
└────────────────────┘ ▼
◀─────── width ──────▶
```
"""
x: int = 0
"""Offset in the x-axis (horizontal)"""
y: int = 0
"""Offset in the y-axis (vertical)"""
width: int = 0
"""The widget of the region"""
height: int = 0
"""The height of the region"""
@classmethod
def from_union(
@@ -754,9 +780,13 @@ class Spacing(NamedTuple):
"""The spacing around a renderable."""
top: int = 0
"""Space from the top of a region."""
right: int = 0
"""Space from the left of a region."""
bottom: int = 0
"""Space from the bottom of a region."""
left: int = 0
"""Space from the left of a region."""
def __bool__(self) -> bool:
return self != (0, 0, 0, 0)