1-reproducible-board #2

Merged
panki merged 7 commits from 1-reproducible-board into master 5 months ago

@ -1,17 +1,23 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from textual.app import App, ComposeResult from textual.app import App, ComposeResult
from textual.widgets import Header, Footer, Button, Label, Switch, Static from textual.widgets import Header, Input, Static, Button
from textual.containers import ScrollableContainer from textual.widget import Widget
from textual.message import Message from textual.message import Message
from textual.color import Color from textual.containers import Horizontal
from textual.validation import Number
from textual.reactive import reactive
from asyncio import sleep from asyncio import sleep
from datetime import datetime
import random
class BingoField(Static): class BingoField(Static):
"""A Bingo field widget.""" """A Bingo field widget."""
cursor_x, cursor_y = 2 cursor_x, cursor_y = 2, 2
text = reactive("temp")
class Selected(Message): class Selected(Message):
"""Send message to the board containing clicked field info""" """Send message to the board containing clicked field info"""
@ -21,10 +27,10 @@ class BingoField(Static):
super().__init__() super().__init__()
def __init__(self, num, text: str) -> None: def __init__(self, num, text: str) -> None:
self.text = text
self.num = num self.num = num
self.selected = False self.selected = False
super().__init__() super().__init__()
self.text = text
def on_mount(self) -> None: def on_mount(self) -> None:
self.styles.content_align = ("center", "middle") self.styles.content_align = ("center", "middle")
@ -48,14 +54,58 @@ class BingoField(Static):
return str(self.text) return str(self.text)
class BingoApp(App): class BingoApp(App):
"""A Textual app to manage stopwatches.""" """A Textual app to run a Bingo board."""
CSS_PATH = "bingo.tcss" CSS_PATH = "bingo.tcss"
BINDINGS = [("d", "toggle_dark", "Toggle dark mode")] def compose(self) -> ComposeResult:
"""Create child widgets for the app."""
yield Header()
yield BingoDisplay()
fieldstate = [False for _ in range(25)] def action_toggle_dark(self) -> None:
"""An action to toggle dark mode."""
self.dark = not self.dark
fields = [ class BingoDisplay(Static):
def compose(self) -> ComposeResult:
"""Create child widgets for the app."""
self.board = BingoBoard()
yield self.board
self.input_field = Input(
str(self.board.seed),
type='integer',
placeholder='UNIX timestamp',
max_length=10,
classes='seed_input',
validators=[
Number(minimum=1000000000, maximum = 2000000000)
]
)
self.input_field.border_title = 'Seed'
yield Horizontal(
self.input_field,
Button.error(':game_die: re-roll', classes='roll_btn'),
classes='bottom_line'
)
def on_button_pressed(self, event: Button.Pressed) -> None:
""""""
# reroll
self.board.roll_board(int(datetime.now().timestamp()))
self.input_field.value = str(self.board.seed)
def on_input_submitted(self, event: Input.Submitted) -> None:
if event.validation_result.is_valid:
self.board.roll_board(int(event.value))
class BingoBoard(Widget):
fields = reactive([], recompose = True)
def __init__(self) -> None:
self.fieldstate = [False for _ in range(25)]
super().__init__()
self.fields = [
'Datenelch', 'Datenelch',
'6 Stunden Schlaf', '6 Stunden Schlaf',
'Tschunk getrunken', 'Tschunk getrunken',
@ -82,20 +132,24 @@ class BingoApp(App):
'geduscht', 'geduscht',
'Gulasch gegessen' 'Gulasch gegessen'
] ]
self.default_fields = self.fields
self.roll_board(int(datetime.now().timestamp()))
# todo: prng stuff def roll_board(self, seed):
import random self.seed = seed
random.shuffle(fields) random.seed(seed)
self.fields = random.sample(self.default_fields, len(self.fields))
def watch_fields(self, new_state) -> None:
self.fieldstate = [False for _ in range(25)]
for idx, field in enumerate(self.query(BingoField)):
field.text = new_state[idx]
def compose(self) -> ComposeResult: def compose(self) -> ComposeResult:
"""Create child widgets for the app.""" """Create child widgets for the app."""
yield Header()
for _ in range(25): for _ in range(25):
yield BingoField(_, self.fields[_]) yield BingoField(_, self.fields[_])
yield Footer()
async def on_bingo_field_selected(self, message: BingoField.Selected) -> None: async def on_bingo_field_selected(self, message: BingoField.Selected) -> None:
self.fieldstate[message.num] = message.selected self.fieldstate[message.num] = message.selected
if self.is_bingo(): if self.is_bingo():
@ -139,10 +193,6 @@ class BingoApp(App):
]) ])
return bingo return bingo
def action_toggle_dark(self) -> None:
"""An action to toggle dark mode."""
self.dark = not self.dark
if __name__ == "__main__": if __name__ == "__main__":
app = BingoApp() app = BingoApp()
app.run() app.run()

@ -1,6 +1,25 @@
Screen { BingoBoard {
layout: grid; layout: grid;
grid-size: 5 5; grid-size: 5 5;
height: 100%;
}
BingoDisplay {
layout: vertical;
height: 100%;
}
.bottom_line {
height: auto;
dock: bottom;
}
.seed_input {
width: 70%;
border-title-align: left;
}
.roll_btn {
width: 30%;
} }
.box { .box {
@ -9,3 +28,10 @@ Screen {
text-align: center; text-align: center;
content-align: center middle; content-align: center middle;
} }
Input.-valid {
border: tall $success 60%;
}
Input.-valid:focus {
border: tall $success;
}

Loading…
Cancel
Save