-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #41 from fabaindaiz/main
Dev: update contributions
- Loading branch information
Showing
12 changed files
with
553 additions
and
336 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
from typing import List, Tuple, Dict | ||
|
||
from src.config import SWAP | ||
from src.interfaces.baseui import BaseUI | ||
from src.interfaces.boardbutton import BoardButton | ||
from src.interfaces.boardlabel import BoardLabel | ||
from src.interfaces.boardtile import BoardTile | ||
from src.modules.resultlist import ResultWord | ||
from src.utils.utils import aux_to_indices | ||
|
||
|
||
class Board: | ||
"""Represents an abstract board | ||
Args: | ||
app (BaseUI): The base user interface for the board. | ||
Attributes: | ||
app (BaseUI): The base user interface for the board. | ||
double_swap (bool): A boolean indicating whether SWAP is greater than or equal to 2. | ||
buttons (List[BoardButton]): A list of board buttons. | ||
labels (List[BoardLabel]): A list of board labels. | ||
tiles (Dict[Tuple[int, int], BoardTile]): A dictionary mapping coordinates to board tiles. | ||
""" | ||
|
||
def __init__(self, app: BaseUI) -> None: | ||
"""Initialize the Board with a BaseUI instance. | ||
Args: | ||
app (BaseUI): The base user interface for the board. | ||
""" | ||
|
||
self.app: BaseUI = app | ||
self.double_swap: bool = SWAP >= 2 | ||
|
||
self.buttons: List[BoardButton] = [] | ||
self.labels: List[BoardLabel] = [] | ||
self.tiles: Dict[Tuple[int, int], BoardTile] = {} | ||
|
||
self.initialize_components() | ||
|
||
def initialize_components(self) -> None: | ||
"""Initialize the components of the board: buttons, tiles, and labels.""" | ||
|
||
self.initialize_buttons() | ||
self.initialize_tiles() | ||
self.initialize_labels() | ||
|
||
def initialize_buttons(self) -> None: | ||
"""Initialize board buttons based on the value of SWAP.""" | ||
|
||
swap_options = [0, 1] | ||
|
||
if self.double_swap: | ||
swap_options.append(2) | ||
|
||
for option in swap_options: | ||
button = self.create_button(option) | ||
|
||
self.buttons.append(button) | ||
|
||
def create_button(self, swap_count: int) -> BoardButton: | ||
"""Create a board button for a specific swap count. | ||
Args: | ||
swap_count (int): The number of swaps represented by the button. | ||
Returns: | ||
BoardButton: The created board button. | ||
""" | ||
|
||
return BoardButton( | ||
parent=self.app, | ||
double_swap=self.double_swap, | ||
swap_count=swap_count, | ||
command=lambda: self.button_command(swap_count), | ||
) | ||
|
||
def initialize_tiles(self) -> None: | ||
"""Initialize board tiles on the board.""" | ||
|
||
for tile_index in range(25): | ||
coord_index = aux_to_indices(tile_index) | ||
|
||
self.tiles[coord_index] = BoardTile(self, tile_index) | ||
|
||
def initialize_labels(self) -> None: | ||
"""Initialize board labels on the board.""" | ||
|
||
for label_index in range(10): | ||
label = BoardLabel(self, label_index) | ||
|
||
self.labels.append(label) | ||
|
||
def set_results(self, word_list: List[ResultWord]) -> None: | ||
"""Set results on the board labels. | ||
Args: | ||
word_list (List[ResultWord]): A list of result words to be displayed on the labels. | ||
""" | ||
|
||
self.reset_labels() | ||
self.update_labels(word_list) | ||
|
||
def reset_labels(self) -> None: | ||
"""Reset the text on all board labels.""" | ||
|
||
for label in self.labels: | ||
label.reset() | ||
|
||
def update_labels(self, word_list: List[ResultWord]) -> None: | ||
"""Update the text and paths on board labels. | ||
Args: | ||
word_list (List[ResultWord]): A list of result words to be displayed on the labels. | ||
""" | ||
|
||
for label, result in zip(self.labels, word_list): | ||
text = result.text() | ||
path = result.path | ||
|
||
label.set_hover(text, path) | ||
|
||
def button_command(self, swap: int) -> None: | ||
"""Handle a button click action, to be implemented in subclasses. | ||
Args: | ||
swap (int): The number of swaps represented by the clicked button. | ||
""" | ||
|
||
raise NotImplementedError() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,163 @@ | ||
from tkinter import ttk | ||
from typing import Callable | ||
|
||
|
||
class BoardButton: | ||
""" | ||
Represents a button on a game board. | ||
Attributes: | ||
INITIAL_HORIZONTAL_POSITION (int): The initial horizontal position for buttons. | ||
INITIAL_VERTICAL_POSITION (int): The initial vertical position for buttons. | ||
DOUBLE_SWAP_HORIZONTAL_POSITION (int): The horizontal position for buttons when double swapping. | ||
BUTTON_HEIGHT (int): The height of the button. | ||
Args: | ||
parent: The parent widget that contains the button. | ||
double_swap (bool): Whether it's a double swap button. | ||
swap_count (int): The number of swaps associated with the button. | ||
command (Callable): The function to execute when the button is clicked. | ||
""" | ||
|
||
INITIAL_HORIZONTAL_POSITION = 100 | ||
INITIAL_VERTICAL_POSITION = 210 | ||
DOUBLE_SWAP_HORIZONTAL_POSITION = 67 | ||
BUTTON_HEIGHT = 30 | ||
|
||
def __init__(self, parent, double_swap: bool, swap_count: int, command: Callable): | ||
""" | ||
Initializes a BoardButton instance. | ||
Args: | ||
parent: The parent widget that contains the button. | ||
double_swap (bool): Whether it's a double swap button. | ||
swap_count (int): The number of swaps associated with the button. | ||
command (Callable): The function to execute when the button is clicked. | ||
""" | ||
|
||
self.parent = parent | ||
self.double_swap = double_swap | ||
self.swap_count = swap_count | ||
self.command = command | ||
self.button = self.initialize() | ||
|
||
def initialize(self): | ||
""" | ||
Initializes the button, sets its style, and positions it on the screen. | ||
Returns: | ||
ttk.Button: The initialized button. | ||
""" | ||
master = self.parent.window | ||
text = self.get_label() | ||
command = self.command | ||
|
||
button = ttk.Button(master=master, text=text, command=command) | ||
|
||
self.configure_style() | ||
self.set_position(button) | ||
|
||
return button | ||
|
||
def get_label(self): | ||
""" | ||
Generates the label text for the button based on the swap count. | ||
Returns: | ||
str: The label text. | ||
""" | ||
return ( | ||
f"{self.swap_count} Swap" | ||
if self.swap_count == 1 | ||
else f"{self.swap_count} Swaps" | ||
) | ||
|
||
def set_position(self, button): | ||
""" | ||
Sets the position of the button on the screen. | ||
Args: | ||
button (ttk.Button): The button to position. | ||
""" | ||
width, height = self.calculate_size() | ||
horizontal_position, vertical_position = self.calculate_position() | ||
|
||
button.place( | ||
x=horizontal_position, y=vertical_position, width=width, height=height | ||
) | ||
|
||
def horizontal_position(self): | ||
""" | ||
Calculates the horizontal position based on double swap and swap count. | ||
Returns: | ||
int: The horizontal position. | ||
""" | ||
return ( | ||
self.DOUBLE_SWAP_HORIZONTAL_POSITION * self.swap_count | ||
if self.double_swap | ||
else self.INITIAL_HORIZONTAL_POSITION * self.swap_count | ||
) | ||
|
||
def calculate_width(self): | ||
""" | ||
Calculates the button width based on double swap. | ||
Returns: | ||
int: The button width. | ||
""" | ||
return ( | ||
self.DOUBLE_SWAP_HORIZONTAL_POSITION | ||
if self.double_swap | ||
else self.INITIAL_HORIZONTAL_POSITION | ||
) | ||
|
||
def calculate_size(self): | ||
""" | ||
Calculates the button size (width and height). | ||
Returns: | ||
Tuple[int, int]: The button width and height. | ||
""" | ||
width = self.calculate_width() | ||
height = self.BUTTON_HEIGHT | ||
|
||
return width, height | ||
|
||
def calculate_padding(self): | ||
""" | ||
Calculates the horizontal and vertical padding for button positioning. | ||
Returns: | ||
Tuple[int, int]: The horizontal and vertical padding. | ||
""" | ||
horizontal_padding = self.parent.HORIZONTAL_PADDING | ||
vertical_padding = self.parent.VERTICAL_PADDING | ||
|
||
return horizontal_padding, vertical_padding | ||
|
||
def calculate_position(self): | ||
""" | ||
Calculates the position of the button on the screen. | ||
Returns: | ||
Tuple[int, int]: The horizontal and vertical position. | ||
""" | ||
horizontal_padding, vertical_padding = self.calculate_padding() | ||
|
||
horizontal_position = horizontal_padding + self.horizontal_position() | ||
vertical_position = vertical_padding + self.INITIAL_VERTICAL_POSITION | ||
|
||
return horizontal_position, vertical_position | ||
|
||
@staticmethod | ||
def configure_style(): | ||
""" | ||
Configures the style of the ttk button. | ||
""" | ||
style = ttk.Style() | ||
style.configure( | ||
style="TButton", | ||
background="#e9e9ed", | ||
font=("Times", 12), | ||
foreground="#000000", | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import tkinter as tk | ||
|
||
from src.utils.utils import aux_to_indices | ||
|
||
|
||
class BoardEntry: | ||
"""Represents a square tile in the board""" | ||
|
||
def __init__(self, board, menu, stringvar: tk.StringVar, aux_cord: int) -> None: | ||
self.board = board | ||
app = board.app | ||
|
||
cord = aux_to_indices(aux_cord) | ||
next = aux_to_indices(aux_cord + 1) | ||
x, y = cord | ||
|
||
def on_validate(input: str) -> bool: | ||
"""Validate the value in the entry""" | ||
if len(input) > 1: | ||
self.board.tiles[cord].entry.focus() | ||
return False | ||
if len(input) == 1: | ||
self.board.tiles[next].entry.focus() | ||
return True | ||
|
||
self.entry: tk.Entry = tk.Entry( | ||
app.window, | ||
textvariable=stringvar, | ||
validate="key", | ||
highlightthickness=2, | ||
) | ||
self.entry["borderwidth"] = "1px" | ||
self.entry["fg"] = "#333333" | ||
self.entry["justify"] = "center" | ||
self.entry["validatecommand"] = (self.entry.register(on_validate), "%P") | ||
self.entry.bind("<Button-3>", lambda event: menu.popup(event)) | ||
self.entry.place( | ||
x=app.HORIZONTAL_PADDING + 40 * x, | ||
y=app.VERTICAL_PADDING + 40 * y, | ||
width=40, | ||
height=40, | ||
) | ||
|
||
def focus(self) -> None: | ||
"""Set the focus on the entry""" | ||
self.entry.focus_set() | ||
self.entry.select_range(0, "end") |
Oops, something went wrong.