Last active
October 14, 2023 22:03
-
-
Save Specnr/cef8e4e9aa475629f0c88961e453f017 to your computer and use it in GitHub Desktop.
A Tkinter GUI which writes commands for the tourney controller to read
This file contains hidden or 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
| import tkinter as tk | |
| from tkinter import ttk | |
| import os | |
| import time | |
| import scripts.PlayerFetcher as pf | |
| class Player: | |
| def __init__(self, twitch_username, display_name): | |
| self.twitch_username = twitch_username | |
| self.display_name = display_name | |
| path = os.path.dirname(os.path.realpath(__file__)) | |
| obstxtPath = os.path.abspath(os.path.realpath( | |
| os.path.join(path, 'data', 'obs.txt'))) | |
| defaultPlayerPath = os.path.abspath(os.path.realpath( | |
| os.path.join(path, 'data', 'default_players.txt'))) | |
| def write_to_file(cmd): | |
| with open(obstxtPath, 'w') as f: | |
| f.write(cmd) | |
| def swap_players(idx1, idx2): | |
| write_to_file(f"sw{idx1}{idx2}") | |
| def set_player(idx, player): | |
| write_to_file(f"s{idx}{player}") | |
| def focus_player(idx): | |
| write_to_file(f"f{idx}") | |
| def get_defaults(): | |
| names = [] | |
| with open(defaultPlayerPath, "r") as f: | |
| for line in f: | |
| names.append(line.strip()) | |
| return names | |
| class Rectangle: | |
| def __init__(self, master, grid, row, col, idx, val): | |
| self.master = master | |
| self.grid = grid | |
| self.row = row | |
| self.col = col | |
| self.idx = idx | |
| if val: | |
| self.value = tk.StringVar(value=val) | |
| set_player(self.idx + 1, val) | |
| elif self.idx < len(self.grid.players): | |
| self.value = tk.StringVar(value=self.grid.players[self.idx].twitch_username) | |
| else: | |
| self.value = tk.StringVar(value="NULL") | |
| self.isSelected = tk.BooleanVar(value=False) | |
| self.rectangle_frame = tk.Frame( | |
| self.master, bg="white", borderwidth=2, relief="groove", width=100, height=100) | |
| self.rectangle_frame.grid( | |
| row=self.row, column=self.col, padx=20, pady=20) | |
| self.checkbox = tk.Checkbutton( | |
| self.rectangle_frame, variable=self.isSelected, command=self.on_checkbox_click) | |
| self.checkbox.pack(side="left", padx=(10, 0), pady=10) | |
| # Add a label next to the checkbox | |
| self.label = tk.Label(self.rectangle_frame, textvariable=self.value) | |
| self.label.pack(side="left", padx=(0, 10), pady=10) | |
| def on_checkbox_click(self): | |
| if self.isSelected.get(): | |
| self.grid.on_rectangle_select(self) | |
| else: | |
| self.grid.on_rectangle_deselect(self) | |
| def swap_with(self, other): | |
| temp_value = self.value.get() | |
| self.value.set(other.value.get()) | |
| other.value.set(temp_value) | |
| temp_is_selected = self.isSelected.get() | |
| self.isSelected.set(other.isSelected.get()) | |
| other.isSelected.set(temp_is_selected) | |
| class RectangleGrid: | |
| def __init__(self, master): | |
| self.master = master | |
| self.master.resizable(False, False) | |
| self.rectangles = [] | |
| self.players = pf.get_players_directly() | |
| self.filtered_players = [] | |
| defaults = get_defaults() | |
| for i in range(2): | |
| for j in range(3): | |
| self.rectangles.append( | |
| Rectangle(self.master, self, i, j, len(self.rectangles), defaults[i * 3 + j])) | |
| time.sleep(0.5) | |
| self.selected_rectangles = [] | |
| self.entry = ttk.Entry(self.master) | |
| self.entry.grid(row=0, column=3, padx=(10)) | |
| self.entry.bind("<KeyRelease>", self.update_players) | |
| self.listbox = tk.Listbox(self.master) | |
| self.listbox.grid(row=1, column=3, rowspan=2, padx=(10)) | |
| self.listbox.bind("<<ListboxSelect>>", self.on_listbox_select) | |
| self.button_frame = tk.Frame(self.master) | |
| self.button_frame.grid(row=4, column=0, columnspan=2, pady=10) | |
| self.focus_button = tk.Button( | |
| self.button_frame, text="Focus", command=self.on_focus, state="disabled", width=10, pady=5) | |
| self.focus_button.pack(side="left", padx=(0, 5)) | |
| self.update_players(None) | |
| def get_current_names(self): | |
| return [rect.value.get().lower() for rect in self.rectangles] | |
| def update_players(self, _): | |
| self.players = pf.get_players_directly() | |
| self.filtered_players = [p for p in self.players if self.entry.get().lower() in p.twitch_username.lower() and not p.twitch_username.lower() in self.get_current_names()] | |
| self.filtered_players.sort(key=lambda x: x.twitch_username) | |
| self.listbox.delete(0, tk.END) | |
| for s in self.filtered_players: | |
| self.listbox.insert(tk.END, s.twitch_username) | |
| def swap_logic(self): | |
| if len(self.selected_rectangles) == 2: | |
| self.selected_rectangles[0].swap_with(self.selected_rectangles[1]) | |
| for rect in self.selected_rectangles: | |
| rect.isSelected.set(False) | |
| self.selected_rectangles = [] | |
| def on_focus(self): | |
| if len(self.selected_rectangles) == 1: | |
| focus_player( | |
| self.selected_rectangles[0].idx + 1) | |
| if self.selected_rectangles[0].idx > 0: | |
| self.selected_rectangles.append(self.rectangles[0]) | |
| self.swap_logic() | |
| self.focus_button.config(state="disabled") | |
| def on_swap(self): | |
| if len(self.selected_rectangles) == 2: | |
| swap_players( | |
| self.selected_rectangles[0].idx + 1, self.selected_rectangles[1].idx + 1) | |
| self.swap_logic() | |
| self.focus_button.config(state="disabled") | |
| def on_rectangle_select(self, rectangle): | |
| self.selected_rectangles.append(rectangle) | |
| if len(self.selected_rectangles) == 1: | |
| self.focus_button.config(state="normal") | |
| self.on_swap() | |
| def on_rectangle_deselect(self, rectangle): | |
| self.selected_rectangles.remove(rectangle) | |
| self.focus_button.config(state="disabled") | |
| def on_listbox_select(self, event): | |
| selected_index = self.listbox.curselection() | |
| if selected_index and len(self.selected_rectangles) > 0: | |
| index = int(selected_index[0]) | |
| selected_player = self.filtered_players[index] | |
| set_player(self.selected_rectangles[0].idx + 1, selected_player.twitch_username) | |
| self.selected_rectangles[0].value.set(selected_player.twitch_username) | |
| self.selected_rectangles[0].isSelected.set(False) | |
| self.selected_rectangles[0].on_checkbox_click() | |
| self.update_players(None) | |
| self.entry.delete(0, tk.END) | |
| print("BOOTING...") | |
| root = tk.Tk() | |
| root.title("Tournament Controller v3") | |
| grid = RectangleGrid(root) | |
| def update_players(): | |
| global grid | |
| grid.players = pf.get_players_directly() | |
| print("Updated players") | |
| root.after(10000, update_players) | |
| update_players() | |
| print("READY!") | |
| root.mainloop() |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Removed dropdowns as they made it less intuitive