Skip to content

Commit

Permalink
Bindings and focus example Counter
Browse files Browse the repository at this point in the history
  • Loading branch information
darrenburns committed Sep 25, 2024
1 parent 86a6fcc commit 3c8f567
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 8 deletions.
2 changes: 1 addition & 1 deletion docs/examples/guide/widgets/counter.tcss
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Counter {
padding: 1 2;
color: $text-muted;

&:focus {
&:focus { /* (1)! */
background: $primary;
color: $text;
text-style: bold;
Expand Down
2 changes: 1 addition & 1 deletion docs/examples/guide/widgets/counter01.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from textual.widgets import Footer, Static


class Counter(Static, can_focus=True):
class Counter(Static, can_focus=True): # (1)!
"""A counter that can be incremented and decremented by pressing keys."""

count = reactive(0)
Expand Down
20 changes: 14 additions & 6 deletions docs/guide/widgets.md
Original file line number Diff line number Diff line change
Expand Up @@ -200,30 +200,41 @@ A widget is only be able to handle key presses if it or one of its descendants h
To demonstrate, let's design a simple interactive counter widget which can be incremented and decremented using the keyboard.

In the following example, we define a simple `Counter` widget with `can_focus=True`, and some CSS to make it stand out when focused.
Our app contains three `Counter` widgets, which we can move focus between using ++tab++ and ++shift+tab++.

=== "counter01.py"

```python title="counter01.py" hl_lines="6"
--8<-- "docs/examples/guide/widgets/counter01.py"
```

1. Allow the widget to receive input focus.

=== "counter.tcss"

```css title="counter.tcss" hl_lines="6-11"
--8<-- "docs/examples/guide/widgets/counter.tcss"
```

1. These styles are applied only when the widget has focus.

=== "Output"

```{.textual path="docs/examples/guide/widgets/counter01.py"}
```

Notice that Textual automatically focused the first widget, and that pressing ++tab++ and ++shift+tab++ will move focus between widgets.

Now that our counter is focusable, let's add some keybindings for incrementing and decrementing the counter.
To do this, we add a `BINDINGS` class variable to `Counter`, with bindings for incrementing and decrementing the counter using ++up++ and ++down++ respectively.
!!! note

You can also move focus to a widget by clicking on it.

Now that our counter is focusable, let's make it interactive by adding some key bindings and actions to it.
To do this, we add a `BINDINGS` class variable to `Counter`, with bindings for ++up++ and ++down++.
These new bindings are linked to the `change_count` action, which updates the `count` reactive attribute.

With our bindings in place, we can now change the count of the _currently focused counter_ using ++up++ and ++down++.

=== "counter02.py"

```python title="counter02.py" hl_lines="9-12 19-20"
Expand All @@ -238,12 +249,9 @@ These new bindings are linked to the `change_count` action, which updates the `c

=== "Output"

```{.textual path="docs/examples/guide/widgets/counter02.py"}
```{.textual path="docs/examples/guide/widgets/counter02.py" press="up,tab,down,down"}
```

With our bindings in place, we can now change the count of the _currently focused counter_ using ++up++ and ++down++.


## Rich renderables

In previous examples we've set strings as content for Widgets. You can also use special objects called [renderables](https://rich.readthedocs.io/en/latest/protocol.html) for advanced visuals. You can use any renderable defined in [Rich](https://github.com/Textualize/rich) or third party libraries.
Expand Down

0 comments on commit 3c8f567

Please sign in to comment.