feat(ui): wip session_view.py
This commit is contained in:
@@ -0,0 +1,220 @@
|
||||
import sys
|
||||
from dataclasses import dataclass
|
||||
from enum import Enum, auto
|
||||
from typing import Optional
|
||||
|
||||
import wx
|
||||
|
||||
from mind_reader.core import SessionState
|
||||
|
||||
|
||||
def enable_high_dpi_support():
|
||||
if sys.platform == "win32":
|
||||
try:
|
||||
import ctypes
|
||||
|
||||
ctypes.windll.shcore.SetProcessDpiAwareness(2)
|
||||
except Exception:
|
||||
try:
|
||||
import ctypes
|
||||
|
||||
ctypes.windll.user32.SetProcessDPIAware()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
class CardState(Enum):
|
||||
SETTER_NOT_SET = auto()
|
||||
SETTER_HIDDEN = auto()
|
||||
SETTER_REVEALED = auto()
|
||||
|
||||
GUESSER_DISABLED = auto()
|
||||
GUESSER_WAITING = auto()
|
||||
GUESSER_CORRECT = auto()
|
||||
GUESSER_WRONG = auto()
|
||||
|
||||
|
||||
class ArrowDirection(Enum):
|
||||
LEFT = auto()
|
||||
RIGHT = auto()
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class SetterCardColour:
|
||||
NOT_SET = wx.Colour(82, 97, 107)
|
||||
HIDDEN = wx.Colour(201, 214, 223)
|
||||
REVEALED = wx.Colour(240, 245, 249)
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class GuesserCardColour:
|
||||
DISABLED = wx.Colour(82, 97, 107)
|
||||
WAITING = wx.Colour(201, 214, 223)
|
||||
CORRECT = wx.Colour(76, 175, 80)
|
||||
WRONG = wx.Colour(229, 115, 115)
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class ArrowSymbol:
|
||||
LEFT: str = "◀"
|
||||
RIGHT: str = "▶"
|
||||
|
||||
|
||||
class Card(wx.Panel):
|
||||
def __init__(self, parent, state: CardState):
|
||||
super().__init__(parent, style=wx.BORDER_SIMPLE)
|
||||
self._direction: Optional[ArrowDirection] = None
|
||||
self._state = state
|
||||
self._setup()
|
||||
self._update()
|
||||
|
||||
def _setup(self):
|
||||
self.SetMinSize(wx.Size(35, 35))
|
||||
|
||||
self.label = wx.StaticText(self, style=wx.ALIGN_CENTER)
|
||||
|
||||
# font = self.label.GetFont()
|
||||
# font.SetPointSize(6)
|
||||
# self.label.SetFont(font)
|
||||
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
sizer.AddStretchSpacer()
|
||||
sizer.Add(self.label, 0, wx.ALIGN_CENTER)
|
||||
sizer.AddStretchSpacer()
|
||||
|
||||
self.SetSizer(sizer)
|
||||
|
||||
def _update(self):
|
||||
match self._state:
|
||||
case CardState.SETTER_NOT_SET:
|
||||
colour = SetterCardColour.NOT_SET
|
||||
show_arrow = False
|
||||
|
||||
case CardState.SETTER_HIDDEN:
|
||||
colour = SetterCardColour.HIDDEN
|
||||
show_arrow = False
|
||||
|
||||
case CardState.SETTER_REVEALED:
|
||||
colour = SetterCardColour.REVEALED
|
||||
show_arrow = True
|
||||
|
||||
case CardState.GUESSER_DISABLED:
|
||||
colour = GuesserCardColour.DISABLED
|
||||
show_arrow = False
|
||||
|
||||
case CardState.GUESSER_WAITING:
|
||||
colour = GuesserCardColour.WAITING
|
||||
show_arrow = False
|
||||
|
||||
case CardState.GUESSER_CORRECT:
|
||||
colour = GuesserCardColour.CORRECT
|
||||
show_arrow = True
|
||||
|
||||
case CardState.GUESSER_WRONG:
|
||||
colour = GuesserCardColour.WRONG
|
||||
show_arrow = True
|
||||
|
||||
match self._direction:
|
||||
case ArrowDirection.LEFT:
|
||||
symbol = ArrowSymbol.LEFT
|
||||
|
||||
case ArrowDirection.RIGHT:
|
||||
symbol = ArrowSymbol.RIGHT
|
||||
|
||||
if show_arrow and self._direction:
|
||||
match self._direction:
|
||||
case ArrowDirection.LEFT:
|
||||
symbol = ArrowSymbol.LEFT
|
||||
|
||||
case ArrowDirection.RIGHT:
|
||||
symbol = ArrowSymbol.RIGHT
|
||||
|
||||
self.label.SetLabel(symbol)
|
||||
|
||||
else:
|
||||
self.label.SetLabel("")
|
||||
|
||||
self.SetBackgroundColour(colour)
|
||||
|
||||
self.Layout()
|
||||
self.Refresh()
|
||||
|
||||
def set(
|
||||
self,
|
||||
state: CardState,
|
||||
direction: Optional[ArrowDirection] = None,
|
||||
) -> None:
|
||||
self._state = state
|
||||
self._direction = direction
|
||||
self._update()
|
||||
|
||||
|
||||
class SessionPanel(wx.Panel):
|
||||
def __init__(self, parent, sequence_length: int = 20):
|
||||
super().__init__(parent)
|
||||
self._sequence_length = sequence_length
|
||||
self._setter_sequence: list[Card] = []
|
||||
self._guesser_sequence: list[Card] = []
|
||||
|
||||
self._setup()
|
||||
|
||||
def _setup(self) -> None:
|
||||
main_sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
|
||||
setter_sizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
for _ in range(self._sequence_length):
|
||||
card = Card(self, CardState.SETTER_NOT_SET)
|
||||
setter_sizer.Add(card, 0, wx.ALL, 3)
|
||||
self._setter_sequence.append(card)
|
||||
|
||||
guesser_sizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
for _ in range(self._sequence_length):
|
||||
card = Card(self, CardState.GUESSER_DISABLED)
|
||||
guesser_sizer.Add(card, 0, wx.ALL, 3)
|
||||
self._guesser_sequence.append(card)
|
||||
|
||||
main_sizer.Add(setter_sizer, 0, wx.ALL, 5)
|
||||
main_sizer.Add(guesser_sizer, 0, wx.ALL, 5)
|
||||
self.SetSizer(main_sizer)
|
||||
|
||||
def update_setter_card(
|
||||
self,
|
||||
index: int,
|
||||
state: CardState,
|
||||
direction: Optional[ArrowDirection] = None,
|
||||
) -> None:
|
||||
self._setter_sequence[index].set(state, direction)
|
||||
|
||||
def update_guesser_card(
|
||||
self,
|
||||
index: int,
|
||||
state: CardState,
|
||||
direction: Optional[ArrowDirection] = None,
|
||||
) -> None:
|
||||
self._guesser_sequence[index].set(state, direction)
|
||||
|
||||
|
||||
class TestFrame(wx.Frame):
|
||||
def __init__(self):
|
||||
super().__init__(None, title="TestFrame", size=wx.Size(900, 500))
|
||||
main_panel = SessionPanel(self)
|
||||
main_sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
main_sizer.Add(main_panel, 1, wx.EXPAND)
|
||||
self.SetSizer(main_sizer)
|
||||
self.Layout()
|
||||
|
||||
main_panel.update_setter_card(
|
||||
0, CardState.SETTER_REVEALED, ArrowDirection.LEFT
|
||||
)
|
||||
|
||||
main_panel.update_guesser_card(
|
||||
0, CardState.GUESSER_WRONG, ArrowDirection.RIGHT
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
enable_high_dpi_support()
|
||||
app = wx.App()
|
||||
frame = TestFrame()
|
||||
frame.Show()
|
||||
app.MainLoop()
|
||||
Reference in New Issue
Block a user