From bce4c77cd444741d4fbfe2300a6d57ca7390e2e7 Mon Sep 17 00:00:00 2001 From: Felix Pankratz Date: Sat, 18 May 2024 14:28:31 +0200 Subject: [PATCH 1/4] Board focusable --- BingoBoard.py | 1 + 1 file changed, 1 insertion(+) diff --git a/BingoBoard.py b/BingoBoard.py index f285c9a..e1a60fe 100644 --- a/BingoBoard.py +++ b/BingoBoard.py @@ -14,6 +14,7 @@ class BingoBoard(Widget): def __init__(self) -> None: self.fieldstate = [False for _ in range(25)] + self.can_focus = True super().__init__() self.fields = [ 'Deko aufgehängt', From 7cf7923b63434c97489b50b0df8e6dab1bc263d2 Mon Sep 17 00:00:00 2001 From: Felix Pankratz Date: Sat, 18 May 2024 15:31:58 +0200 Subject: [PATCH 2/4] add highlighting for selected field and focus-awareness for board --- BingoBoard.py | 15 +++++++++++++++ BingoField.py | 18 ++++++++---------- bingo.tcss | 4 ++++ 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/BingoBoard.py b/BingoBoard.py index e1a60fe..c18f246 100644 --- a/BingoBoard.py +++ b/BingoBoard.py @@ -1,6 +1,7 @@ from textual.reactive import reactive from textual.widget import Widget from textual.app import ComposeResult +from textual.message import Message from datetime import datetime import random @@ -12,6 +13,8 @@ class BingoBoard(Widget): fields = reactive([], recompose = True) + cursor_x, cursor_y = 2, 2 + def __init__(self) -> None: self.fieldstate = [False for _ in range(25)] self.can_focus = True @@ -46,6 +49,9 @@ class BingoBoard(Widget): self.default_fields = self.fields self.roll_board(int(datetime.now().timestamp())) + def fieldnum_from_cursor(self) -> int: + return self.cursor_x + ( self.cursor_y * 5) + def roll_board(self, seed): self.seed = seed random.seed(seed) @@ -61,6 +67,15 @@ class BingoBoard(Widget): for _ in range(25): yield BingoField(_, self.fields[_]) + def on_focus(self, message: Message) -> None: + fields = self.query(BingoField) + fields[self.fieldnum_from_cursor()].set_highlighted(True) + + def on_blur(self, message: Message) -> None: + fields = self.query(BingoField) + fields[self.fieldnum_from_cursor()].set_highlighted(False) + + async def on_bingo_field_selected(self, message: BingoField.Selected) -> None: self.fieldstate[message.num] = message.selected if self.is_bingo(): diff --git a/BingoField.py b/BingoField.py index 28e5ca5..6da0b60 100644 --- a/BingoField.py +++ b/BingoField.py @@ -5,7 +5,6 @@ from textual.reactive import reactive class BingoField(Static): '''A Bingo field widget.''' - cursor_x, cursor_y = 2, 2 text = reactive('') class Selected(Message): @@ -18,27 +17,26 @@ class BingoField(Static): def __init__(self, num, text: str) -> None: self.num = num self.selected = False + self.highlighted = False super().__init__() self.text = text - #def on_mount(self) -> None: - #self.styles.content_align = ('center', 'middle') - #self.styles.text_align = 'center' - #self.styles.border = ('blank', 'green') - #self.styles.height = '100%' - #self.styles.width = '100%' - def on_click(self) -> None: self.selected = not self.selected if self.selected: - # self.styles.animate('background', 'green', duration=0.1) self.add_class('field_selected') else: self.remove_class('field_selected') - #self.styles.animate('background', '#1c1c1c', duration=0.1) # The post_message method sends an event to be handled in the DOM self.post_message(self.Selected(self.num, self.selected)) + def set_highlighted(self, new_highlight: bool) -> None: + self.highlighted = new_highlight + if self.highlighted: + self.add_class('field_highlighted') + else: + self.remove_class('field_highlighted') + def render(self) -> str: return str(self.text) diff --git a/bingo.tcss b/bingo.tcss index ef2eab8..f0aefe4 100644 --- a/bingo.tcss +++ b/bingo.tcss @@ -21,6 +21,10 @@ BingoField.field_selected { background: $success; } +BingoField.field_highlighted { + color: $secondary; +} + BingoDisplay { layout: vertical; height: 100%; From f01fae27d7124c6fa150ab44b22fabafd2190453 Mon Sep 17 00:00:00 2001 From: Felix Pankratz Date: Sat, 18 May 2024 15:43:47 +0200 Subject: [PATCH 3/4] basic cursor --- BingoBoard.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/BingoBoard.py b/BingoBoard.py index c18f246..389488e 100644 --- a/BingoBoard.py +++ b/BingoBoard.py @@ -2,6 +2,7 @@ from textual.reactive import reactive from textual.widget import Widget from textual.app import ComposeResult from textual.message import Message +from textual import events from datetime import datetime import random @@ -75,6 +76,20 @@ class BingoBoard(Widget): fields = self.query(BingoField) fields[self.fieldnum_from_cursor()].set_highlighted(False) + def on_key(self, event: events.Key) -> None: + fields = self.query(BingoField) + fields[self.fieldnum_from_cursor()].set_highlighted(False) + match event.key: + case 'up': + self.cursor_y -= 1 if self.cursor_y > 0 else 0 + case 'down': + self.cursor_y += 1 if self.cursor_y < 4 else 0 + case 'left': + self.cursor_x -= 1 if self.cursor_x > 0 else 0 + case 'right': + self.cursor_x += 1 if self.cursor_x < 4 else 0 + fields[self.fieldnum_from_cursor()].set_highlighted(True) + async def on_bingo_field_selected(self, message: BingoField.Selected) -> None: self.fieldstate[message.num] = message.selected From 23c254a180bbba177974c6fb877c309b2787857c Mon Sep 17 00:00:00 2001 From: Felix Pankratz Date: Sat, 18 May 2024 15:46:30 +0200 Subject: [PATCH 4/4] enter to select --- BingoBoard.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/BingoBoard.py b/BingoBoard.py index 389488e..0acf456 100644 --- a/BingoBoard.py +++ b/BingoBoard.py @@ -88,6 +88,8 @@ class BingoBoard(Widget): self.cursor_x -= 1 if self.cursor_x > 0 else 0 case 'right': self.cursor_x += 1 if self.cursor_x < 4 else 0 + case 'enter': + fields[self.fieldnum_from_cursor()].on_click() fields[self.fieldnum_from_cursor()].set_highlighted(True)