Skip to content

Commit

Permalink
DigitDisplay: followup on PR review
Browse files Browse the repository at this point in the history
  • Loading branch information
eliasdorneles committed Jul 26, 2023
1 parent 7497c86 commit 2933f69
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 86 deletions.
10 changes: 5 additions & 5 deletions docs/examples/widgets/digit_display.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
from textual.app import App, ComposeResult
from textual.widgets import Static
from textual.widgets import Label
from textual.widgets import DigitDisplay


class MyApp(App):
BINDINGS = []

def compose(self) -> ComposeResult:
yield Static("Digits: 0123456789")
yield Label("Digits: 0123456789")
yield DigitDisplay("0123456789")

punctuation=" .+,XYZ^*/-="
yield Static("Punctuation: " + punctuation)
punctuation = " .+,XYZ^*/-="
yield Label("Punctuation: " + punctuation)
yield DigitDisplay(punctuation)

equation = "x = y^2 + 3.14159*y + 10"
yield Static("Equation: " + equation)
yield Label("Equation: " + equation)
yield DigitDisplay(equation)


Expand Down
24 changes: 15 additions & 9 deletions docs/widgets/digit_display.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ A widget to display digits and basic arithmetic operators using Unicode blocks.

## Examples

=== "Static example"

### Static display example

=== "Screenshot"

```{.textual path="docs/examples/widgets/digit_display.py"}
```
Expand All @@ -18,9 +21,12 @@ A widget to display digits and basic arithmetic operators using Unicode blocks.
--8<-- "docs/examples/widgets/digit_display.py"
```

=== "Reacting to an input"

```{.textual path="docs/examples/widgets/digit_display_reacting.py"}
### Reacting to an input

=== "Screenshot"

```{.textual path="docs/examples/widgets/digit_display_reacting.py" press="1,2,3"}
```

=== "digit_display_reacting.py"
Expand All @@ -31,16 +37,16 @@ A widget to display digits and basic arithmetic operators using Unicode blocks.

## Reactive attributes

| Name | Type | Default | Description |
| ------ | ------ | ------- | ---------------------------------------------- |
| `digits` | `str` | `""` | Use this to update the digits to be displayed. |
| Name | Type | Default | Description |
| ------ | ------ | ------- | ---------------------------------------------- |
| `digits` | `str` | `""` | Use this to update the digits to be displayed. |


## Read-only attributes

| Name | Type | Description |
| ------ | ------ | ----------------------------------------- |
| `supported_digits` | `frozenset[str]` | Contains the list of supported digits/characters.
| Name | Type | Description |
| ------ | ------ | ----------------------------------------- |
| `supported_digits` | `frozenset[str]` | Contains the list of supported digits/characters. |

## Messages

Expand Down
36 changes: 18 additions & 18 deletions src/textual/widgets/_digit_display.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@

class _SingleDigitDisplay(Static):
digit = reactive(" ", layout=True)
"""The digit to display."""

DEFAULT_CSS = """
_SingleDigitDisplay {
Expand All @@ -212,19 +213,28 @@ def __init__(self, initial_value=" ", **kwargs):
super().__init__(**kwargs)
self.digit = initial_value

def watch_digit(self, digit: str) -> None:
"""Called when the digit attribute changes."""
def validate_digit(self, digit: str) -> str:
"""Sanitize and validate the digit input."""
if len(digit) > 1:
raise ValueError(f"Expected a single character, got {len(digit)}")
digit = digit.upper()
if digit not in _character_map:
raise ValueError(f"Unsupported character: {digit}")
return digit

def _watch_digit(self, digit: str) -> None:
"""Called when the digit attribute changes and passes validation."""
self.update(_character_map[digit.upper()])


class DigitDisplay(Widget):
"""A widget to display digits and basic arithmetic operators using Unicode blocks."""

digits = reactive("", layout=True)
"""The digits to display."""

supported_digits = frozenset(_character_map.keys())
"""The digits and characters supported by this widget."""

DEFAULT_CSS = """
DigitDisplay {
Expand All @@ -242,27 +252,17 @@ def compose(self) -> ComposeResult:
for widget in self._displays:
yield widget

def _add_digit_widget(self, digit: str) -> None:
new_widget = _SingleDigitDisplay(digit)
self._displays.append(new_widget)
self.mount(new_widget)

def watch_digits(self, digits: str) -> None:
def _watch_digits(self, digits: str) -> None:
"""
Called when the digits attribute changes.
Here we update the display widgets to match the input digits.
"""
diff_digits_len = len(digits) - len(self._displays)

# Here we add or remove widgets to match the number of digits
if diff_digits_len > 0:
start = len(self._displays)
for i in range(diff_digits_len):
self._add_digit_widget(digits[start + i])
elif diff_digits_len < 0:
for display in self._displays[diff_digits_len:]:
self._displays.remove(display)
display.remove()
while len(self._displays) < len(digits):
self._displays.append(_SingleDigitDisplay(digits[len(self._displays)]))
self.mount(self._displays[-1])
while len(self._displays) > len(digits):
self._displays.pop().remove()

# At this point, the number of widgets matches the number of digits, and we can
# update the contents of the widgets that might need it
Expand Down
Loading

0 comments on commit 2933f69

Please sign in to comment.