Review record RC-041 (Go, autonomous mode, not independent). Task: MIL-008#1 Task: MIL-008#2 Task: MIL-008#3 Task: MIL-008#4 Task: MIL-008#5 Task: MIL-008#6 Task: MIL-008#7 Task: MIL-008#8
98 lines
2.8 KiB
Python
98 lines
2.8 KiB
Python
"""View of the level screen.
|
|
|
|
@file level_view.py
|
|
@brief Builds the level screen of the wireframe: a title and one button per level.
|
|
"""
|
|
|
|
import tkinter as tk
|
|
from collections.abc import Callable
|
|
|
|
from flash_card.constants import (
|
|
BACKGROUND_COLOR,
|
|
CARD_WIDTH,
|
|
LEVEL_BUTTON_COLOR,
|
|
LEVEL_BUTTON_FONT,
|
|
LEVEL_BUTTON_WIDTH,
|
|
LEVEL_SCREEN_HEIGHT,
|
|
LEVEL_TITLE_FONT,
|
|
)
|
|
from flash_card.domain.value_objects.level import Level
|
|
from flash_card.presentation.features.level.level_view_model import (
|
|
LevelChoice,
|
|
LevelViewModel,
|
|
)
|
|
|
|
|
|
class LevelView:
|
|
"""The level screen: a title and a button for each level."""
|
|
|
|
def __init__(
|
|
self,
|
|
root: tk.Tk,
|
|
view_model: LevelViewModel,
|
|
on_choose: Callable[[Level], None],
|
|
) -> None:
|
|
"""Build the screen on a root.
|
|
|
|
@param root The Tk root window.
|
|
@param view_model The data to show.
|
|
@param on_choose Called with the level the user picked.
|
|
"""
|
|
## @brief Called with the level the user picked.
|
|
self._on_choose = on_choose
|
|
## @brief Frame that holds the whole screen.
|
|
self.frame = tk.Frame(
|
|
root, bg=BACKGROUND_COLOR, width=CARD_WIDTH, height=LEVEL_SCREEN_HEIGHT
|
|
)
|
|
self.frame.grid(row=0, column=0)
|
|
self.frame.grid_propagate(False)
|
|
self.frame.grid_columnconfigure(0, weight=1)
|
|
for row in range(len(view_model.choices) + 1):
|
|
self.frame.grid_rowconfigure(row, weight=1)
|
|
## @brief The title text.
|
|
self.title_label = tk.Label(
|
|
self.frame,
|
|
text=view_model.title,
|
|
font=LEVEL_TITLE_FONT,
|
|
bg=BACKGROUND_COLOR,
|
|
)
|
|
self.title_label.grid(row=0, column=0)
|
|
## @brief One button per choice, in display order.
|
|
self.buttons = tuple(
|
|
self._build_button(row, choice)
|
|
for row, choice in enumerate(view_model.choices, start=1)
|
|
)
|
|
|
|
def choose(self, level: Level) -> None:
|
|
"""Forward the chosen level.
|
|
|
|
@param level The level the user picked.
|
|
@return Nothing.
|
|
"""
|
|
self._on_choose(level)
|
|
|
|
def destroy(self) -> None:
|
|
"""Remove the screen from the window.
|
|
|
|
@return Nothing.
|
|
"""
|
|
self.frame.destroy()
|
|
|
|
def _build_button(self, row: int, choice: LevelChoice) -> tk.Button:
|
|
"""Create the button of one choice.
|
|
|
|
@param row Grid row of the button.
|
|
@param choice The choice the button stands for.
|
|
@return The button, placed in the frame.
|
|
"""
|
|
button = tk.Button(
|
|
self.frame,
|
|
text=choice.label,
|
|
font=LEVEL_BUTTON_FONT,
|
|
width=LEVEL_BUTTON_WIDTH,
|
|
bg=LEVEL_BUTTON_COLOR,
|
|
command=lambda: self.choose(choice.level),
|
|
)
|
|
button.grid(row=row, column=0)
|
|
return button
|