added keys to calculatorm, press methid to Button, primary button style

This commit is contained in:
Will McGugan
2022-08-31 09:30:41 +01:00
parent 78fb85b725
commit 10ede76b9b
3 changed files with 68 additions and 14 deletions

View File

@@ -27,10 +27,6 @@ Button {
color: $text-primary-lighten-2; color: $text-primary-lighten-2;
} }
#ac,#c,#plus-minus,#percent {
tint: $primary 25%;
}
#number-0 { #number-0 {
column-span: 2; column-span: 2;
} }

View File

@@ -1,6 +1,7 @@
from decimal import Decimal from decimal import Decimal
from textual.app import App, ComposeResult from textual.app import App, ComposeResult
from textual import events
from textual.layout import Container from textual.layout import Container
from textual.reactive import Reactive from textual.reactive import Reactive
from textual.widgets import Button, Static from textual.widgets import Button, Static
@@ -16,6 +17,17 @@ class CalculatorApp(App):
value = Reactive.var("") value = Reactive.var("")
operator = Reactive.var("plus") operator = Reactive.var("plus")
KEY_MAP = {
"+": "plus",
"-": "minus",
".": "point",
"*": "multiply",
"/": "divide",
"_": "plus-minus",
"%": "percent",
"=": "equals",
}
def watch_numbers(self, value: str) -> None: def watch_numbers(self, value: str) -> None:
"""Called when numbers is updated.""" """Called when numbers is updated."""
# Update the Numbers widget # Update the Numbers widget
@@ -34,10 +46,10 @@ class CalculatorApp(App):
"""Add our buttons.""" """Add our buttons."""
yield Container( yield Container(
Static(id="numbers"), Static(id="numbers"),
Button("AC", id="ac"), Button("AC", id="ac", variant="primary"),
Button("C", id="c"), Button("C", id="c", variant="primary"),
Button("+/-", id="plus-minus"), Button("+/-", id="plus-minus", variant="primary"),
Button("%", id="percent"), Button("%", id="percent", variant="primary"),
Button("÷", id="divide", variant="warning"), Button("÷", id="divide", variant="warning"),
Button("7", id="number-7"), Button("7", id="number-7"),
Button("8", id="number-8"), Button("8", id="number-8"),
@@ -57,6 +69,22 @@ class CalculatorApp(App):
id="calculator", id="calculator",
) )
def on_key(self, event: events.Key) -> None:
"""Called when the user presses a key."""
def press(button_id: str) -> None:
self.query_one(f"#{button_id}", Button).press()
self.set_focus(None)
key = event.key
if key.isdecimal():
press(f"number-{key}")
elif key == "c":
press("c")
press("ac")
elif key in self.KEY_MAP:
press(self.KEY_MAP[key])
def on_button_pressed(self, event: Button.Pressed) -> None: def on_button_pressed(self, event: Button.Pressed) -> None:
"""Called when a button is pressed.""" """Called when a button is pressed."""

View File

@@ -18,8 +18,8 @@ from ..message import Message
from ..reactive import Reactive from ..reactive import Reactive
from ..widget import Widget from ..widget import Widget
ButtonVariant = Literal["default", "success", "warning", "error"] ButtonVariant = Literal["default", "primary", "success", "warning", "error"]
_VALID_BUTTON_VARIANTS = {"default", "success", "warning", "error"} _VALID_BUTTON_VARIANTS = {"default", "primary", "success", "warning", "error"}
class InvalidButtonVariant(Exception): class InvalidButtonVariant(Exception):
@@ -59,6 +59,32 @@ class Button(Widget, can_focus=True):
border-top: tall $panel-darken-2; border-top: tall $panel-darken-2;
} }
/* Primary variant */
Button.-primary {
background: $primary;
color: $text-primary;
border-top: tall $primary-lighten-2;
border-bottom: tall $primary-darken-3;
}
Button.-primary:hover {
background: $primary-darken-2;
color: $text-primary-darken-2;
}
Button.-active {
tint: $background 30%;
}
Button.-primary.-active {
background: $primary;
border-bottom: tall $primary-lighten-3;
border-top: tall $primary-darken-3;
}
/* Success variant */ /* Success variant */
Button.-success { Button.-success {
@@ -188,14 +214,18 @@ class Button(Widget, can_focus=True):
label.stylize(self.text_style) label.stylize(self.text_style)
return label return label
async def on_click(self, event: events.Click) -> None: async def _on_click(self, event: events.Click) -> None:
event.stop() event.stop()
if self.disabled: self.press()
def press(self) -> None:
"""Respond to a button press."""
if self.disabled or not self.display:
return return
# Manage the "active" effect: # Manage the "active" effect:
self._start_active_affect() self._start_active_affect()
# ...and let other components know that we've just been clicked: # ...and let other components know that we've just been clicked:
await self.emit(Button.Pressed(self)) self.emit_no_wait(Button.Pressed(self))
def _start_active_affect(self) -> None: def _start_active_affect(self) -> None:
"""Start a small animation to show the button was clicked.""" """Start a small animation to show the button was clicked."""
@@ -204,7 +234,7 @@ class Button(Widget, can_focus=True):
self.ACTIVE_EFFECT_DURATION, partial(self.remove_class, "-active") self.ACTIVE_EFFECT_DURATION, partial(self.remove_class, "-active")
) )
async def on_key(self, event: events.Key) -> None: async def _on_key(self, event: events.Key) -> None:
if event.key == "enter" and not self.disabled: if event.key == "enter" and not self.disabled:
self._start_active_affect() self._start_active_affect()
await self.emit(Button.Pressed(self)) await self.emit(Button.Pressed(self))