132 lines
4.2 KiB
Python
Executable file
132 lines
4.2 KiB
Python
Executable file
#!/usr/bin/env python3
|
||
from tkinter import *
|
||
from tkinter import ttk
|
||
|
||
from player import Player
|
||
from game import Game
|
||
|
||
PLAYERS: list[Player] = []
|
||
|
||
# init tkinter
|
||
root = Tk()
|
||
root.title("🀄 RonRunner - Mahjong Tournament Scoring 🀄")
|
||
root.geometry("800x500")
|
||
|
||
# configure style
|
||
style = ttk.Style()
|
||
style.theme_use('clam')
|
||
|
||
# configure scrollbar
|
||
canvas = Canvas(root, highlightthickness=0)
|
||
scrollbar = ttk.Scrollbar(root, orient='vertical', command=canvas.yview)
|
||
scrollbarFrame = ttk.Frame(canvas)
|
||
scrollbarFrame.bind(
|
||
"<Configure>",
|
||
lambda e: canvas.configure(scrollregion=canvas.bbox("all"))
|
||
)
|
||
|
||
canvas.create_window((0, 0), window=scrollbarFrame, anchor="nw")
|
||
canvas.configure(yscrollcommand=scrollbar.set)
|
||
|
||
canvas.grid(column=0, row=0, sticky="nsew")
|
||
scrollbar.grid(column=1, row=0, sticky="ns")
|
||
|
||
root.grid_rowconfigure(0, weight=1)
|
||
root.grid_columnconfigure(0, weight=1)
|
||
|
||
frm = scrollbarFrame
|
||
|
||
# activate scrollbar with pad/mouse
|
||
def _on_mousewheel(event):
|
||
canvas.yview_scroll(int(-1*(event.delta/120)), "units")
|
||
|
||
def _on_scroll_up(event):
|
||
canvas.yview_scroll(-1, "units")
|
||
|
||
def _on_scroll_down(event):
|
||
canvas.yview_scroll(1, "units")
|
||
|
||
def _bind_mousewheel(widget):
|
||
widget.bind("<MouseWheel>", _on_mousewheel)
|
||
widget.bind("<Button-4>", _on_scroll_up)
|
||
widget.bind("<Button-5>", _on_scroll_down)
|
||
for child in widget.winfo_children():
|
||
_bind_mousewheel(child)
|
||
|
||
_bind_mousewheel(frm)
|
||
|
||
# init ui
|
||
|
||
# players
|
||
ttk.Label(frm, text="Rank", font=("Helvetica", 11, "bold")).grid(column=0, row=0, padx=10, pady=10)
|
||
ttk.Label(frm, text="Player", font=("Helvetica", 11, "bold")).grid(column=1, row=0, padx=10, pady=10)
|
||
ttk.Label(frm, text="Score", font=("Helvetica", 11, "bold")).grid(column=2, row=0, padx=10, pady=10)
|
||
|
||
entry_player_name = ttk.Entry(frm, width=30, font=("Helvetica", 10))
|
||
entry_player_name.grid(column=1, row=len(PLAYERS) + 1, padx=10, pady=10)
|
||
|
||
# adding player
|
||
def addPlayer(entry: Entry):
|
||
txt = entry.get()
|
||
if txt:
|
||
PLAYERS.append(Player(txt))
|
||
entry.delete(0, END)
|
||
refreshUi()
|
||
|
||
btn_player_name = ttk.Button(frm, text="➕ Add", command=lambda : addPlayer(entry_player_name))
|
||
btn_player_name.grid(column=2, row=1 + len(PLAYERS), padx=10, pady=10)
|
||
|
||
# tables
|
||
# TODO
|
||
|
||
# table history
|
||
# TODO
|
||
|
||
# refresh ui
|
||
def refreshUi():
|
||
# remove old labels
|
||
for widget in frm.winfo_children():
|
||
if widget not in [entry_player_name, btn_player_name]:
|
||
info = widget.grid_info()
|
||
if info.get('row', 0) > 0 and info.get('row', 0) < 100:
|
||
widget.destroy()
|
||
|
||
# show players
|
||
PLAYERS.sort(key=lambda p : p.score, reverse=True)
|
||
for i in range(len(PLAYERS)):
|
||
ttk.Label(frm, text=f"{i+1}", font=("Helvetica", 10, "bold"), foreground="#FF6B6B").grid(column=0, row=i+1, padx=10, pady=8)
|
||
playerLabel = ttk.Label(frm, text=PLAYERS[i].name, font=("Helvetica", 10), foreground="#0066CC")
|
||
playerLabel.grid(column=1, row=i+1, padx=10, pady=8)
|
||
ttk.Label(frm, text=f"{PLAYERS[i].score}", font=("Helvetica", 10, "bold"), foreground="#2ECC71").grid(column=2, row=i+1, padx=10, pady=8)
|
||
|
||
# change player name
|
||
def onClick(event, player=PLAYERS[i]):
|
||
popup = Toplevel(root)
|
||
popup.title(f"Edit - {player.name}")
|
||
popup.geometry("300x150")
|
||
|
||
entry = ttk.Entry(popup, width=30, font=("Helvetica", 10))
|
||
entry.insert(0, player.name)
|
||
entry.grid(column=0, row=0, padx=10, pady=10)
|
||
|
||
def changeName():
|
||
name = entry.get()
|
||
if name and not name in [p.name for p in PLAYERS]:
|
||
player.name = name
|
||
entry.delete(0, END)
|
||
cancelTopLevel(popup)
|
||
|
||
ttk.Button(popup, text="✓ Change", command=changeName).grid(column=1, row=0, padx=5, pady=10)
|
||
ttk.Button(popup, text="✕ Cancel", command=lambda : cancelTopLevel(popup)).grid(column=2, row=0, padx=5, pady=10)
|
||
|
||
playerLabel.bind("<Button-1>", onClick)
|
||
|
||
# adding player
|
||
entry_player_name.grid(column=1, row=len(PLAYERS) + 1)
|
||
btn_player_name.grid(column=2, row=1 + len(PLAYERS))
|
||
|
||
def cancelTopLevel(tl: Toplevel):
|
||
tl.destroy()
|
||
refreshUi()
|
||
|
||
root.mainloop()
|