|
| 1 | +import json |
| 2 | +import os |
| 3 | + |
| 4 | +import Tkinter as tk |
| 5 | + |
| 6 | + |
| 7 | +TITLE_FONT = ("Helvetica", 60) |
| 8 | +SUBTITLE_FONT = ("Helvetica", 30) |
| 9 | +TEXT_FONT = ("Helvetica", 20) |
| 10 | +INPUT_FONT = ("Helvetica", 12) |
| 11 | + |
| 12 | +class NewGame(tk.Frame): |
| 13 | + |
| 14 | + def __init__(self, parent, controller): |
| 15 | + tk.Frame.__init__(self, parent) |
| 16 | + self.controller = controller |
| 17 | + |
| 18 | + self.newDice = tk.BooleanVar(value=False) |
| 19 | + self.playerToEmailMap = {} |
| 20 | + |
| 21 | + self.createTitleFrame() |
| 22 | + |
| 23 | + leftFrame = tk.Frame(self) |
| 24 | + leftFrame.pack(side="left", expand=True, fill="both") |
| 25 | + self.createDiceFrame(leftFrame) |
| 26 | + |
| 27 | + rightFrame = tk.Frame(self) |
| 28 | + rightFrame.pack(side="left", expand=True, fill="both") |
| 29 | + self.createPlayerFrame(rightFrame) |
| 30 | + |
| 31 | + |
| 32 | + def createTitleFrame(self): |
| 33 | + titleFrame = tk.Frame(self) |
| 34 | + titleFrame.pack(side="top", expand=False, fill="x", anchor="n", pady=(0, self.controller.HEIGHT/32)) |
| 35 | + |
| 36 | + tk.Label(titleFrame, text="NEW GAME", font=SUBTITLE_FONT, height=2 |
| 37 | + ).pack(side="top") |
| 38 | + |
| 39 | + self.errorMessage = tk.Label(titleFrame, text="", font=TEXT_FONT, fg="red") |
| 40 | + self.errorMessage.pack(side="top") |
| 41 | + |
| 42 | + |
| 43 | + def createDiceFrame(self, frame): |
| 44 | + diceFrame = tk.LabelFrame(frame, text="Select Dice", font=INPUT_FONT, relief="ridge", padx=20, pady=20) |
| 45 | + diceFrame.pack(side="top") |
| 46 | + |
| 47 | + tk.Radiobutton(diceFrame, text="Use existing dice:", variable=self.newDice, value=False, font=TEXT_FONT |
| 48 | + ).pack(side="top", pady=(0, 20)) |
| 49 | + self.createDiceList(diceFrame) |
| 50 | + |
| 51 | + tk.Radiobutton(diceFrame, text="Create new dice:", variable=self.newDice, value=True, font=TEXT_FONT |
| 52 | + ).pack(side="top", pady=(0, 20)) |
| 53 | + self.diceName = tk.Text(diceFrame, height=1, width=40, font=INPUT_FONT) |
| 54 | + self.diceName.pack(side="top") |
| 55 | + |
| 56 | + def createDiceList(self, diceFrame): |
| 57 | + self.diceList = tk.Listbox(diceFrame, height=10, width=40, font=INPUT_FONT, exportselection=False) |
| 58 | + self.diceList.pack(side="top", pady=(0, self.controller.HEIGHT/8)) |
| 59 | + |
| 60 | + options = os.listdir("data") |
| 61 | + for option in options: |
| 62 | + self.diceList.insert(tk.END, option) |
| 63 | + |
| 64 | + |
| 65 | + def createPlayerFrame(self, frame): |
| 66 | + playerFrame = tk.LabelFrame(frame, text="Select Players", font=INPUT_FONT, relief="ridge", padx=20, pady=20) |
| 67 | + playerFrame.pack(side="top") |
| 68 | + |
| 69 | + addPlayerFrame = tk.Frame(playerFrame) |
| 70 | + addPlayerFrame.grid(row=0, column=0, padx=(0, self.controller.WIDTH/16)) |
| 71 | + self.createAddPlayerFrame(addPlayerFrame) |
| 72 | + |
| 73 | + showPlayersFrame = tk.Frame(playerFrame) |
| 74 | + showPlayersFrame.grid(row=0, column=1) |
| 75 | + self.createShowPlayersFrame(showPlayersFrame) |
| 76 | + |
| 77 | + buttonFrame = tk.Frame(frame) |
| 78 | + buttonFrame.pack(side="top", anchor="e", padx=(0, self.controller.WIDTH/32), pady=(self.controller.HEIGHT/8, 0)) |
| 79 | + self.createButtonFrame(buttonFrame) |
| 80 | + |
| 81 | + def createAddPlayerFrame(self, addPlayerFrame): |
| 82 | + tk.Label(addPlayerFrame, text="Add Player:", font=TEXT_FONT |
| 83 | + ).grid(row=0, column=0, columnspan=2, pady=(0, 20)) |
| 84 | + self.createPlayerList(addPlayerFrame) |
| 85 | + |
| 86 | + tk.Label(addPlayerFrame, text="Name:", font=TEXT_FONT |
| 87 | + ).grid(row=2, column=0, pady=(0, 20)) |
| 88 | + self.playerName = tk.Text(addPlayerFrame, height=1, width=40, font=INPUT_FONT) |
| 89 | + self.playerName.grid(row=2, column=1, pady=(0, 20)) |
| 90 | + |
| 91 | + tk.Label(addPlayerFrame, text="Email:", font=TEXT_FONT |
| 92 | + ).grid(row=3, column=0, pady=(0, 20)) |
| 93 | + self.playerEmail = tk.Text(addPlayerFrame, height=1, width=40, font=INPUT_FONT) |
| 94 | + self.playerEmail.grid(row=3, column=1, pady=(0, 20)) |
| 95 | + |
| 96 | + tk.Button(addPlayerFrame, text="Add", font=TEXT_FONT, width=10, relief="groove", bd=2, command=self.addPlayer |
| 97 | + ).grid(row=4, column=1, sticky="e") |
| 98 | + |
| 99 | + def createPlayerList(self, addPlayerFrame): |
| 100 | + playerList = tk.Listbox(addPlayerFrame, height=10, width=40, font=INPUT_FONT, exportselection=False) |
| 101 | + playerList.bind('<<ListboxSelect>>', self.selectPlayer) |
| 102 | + playerList.bind('<Double-Button-1>', self.addPlayer) |
| 103 | + playerList.grid(row=1, column=0, columnspan=2, pady=(0,40)) |
| 104 | + |
| 105 | + players = json.load(file("players.txt")) |
| 106 | + for player in players.keys(): |
| 107 | + playerList.insert(tk.END, player) |
| 108 | + |
| 109 | + self.playerToEmailMap = players |
| 110 | + |
| 111 | + def createShowPlayersFrame(self, showPlayersFrame): |
| 112 | + self.playerLabel = tk.Label(showPlayersFrame, text="Players (0):", font=TEXT_FONT) |
| 113 | + self.playerLabel.grid(row=0, column=0, columnspan=2, pady=(0, 20)) |
| 114 | + |
| 115 | + self.chosenPlayersList = tk.Listbox(showPlayersFrame, height=7, width=40, font=INPUT_FONT) |
| 116 | + self.chosenPlayersList.grid(row=1, column=0, columnspan=2, pady=(0, 40)) |
| 117 | + |
| 118 | + tk.Button(showPlayersFrame, text="Remove", font=TEXT_FONT, width=10, relief="groove", bd=2, command=self.removePlayer |
| 119 | + ).grid(row=2, column=0) |
| 120 | + |
| 121 | + tk.Button(showPlayersFrame, text="Clear", font=TEXT_FONT, width=10, relief="groove", bd=2, command=self.clearPlayerList |
| 122 | + ).grid(row=2, column=1) |
| 123 | + |
| 124 | + def createButtonFrame(self, buttonFrame): |
| 125 | + tk.Button(buttonFrame, text="Start", font=TEXT_FONT, width=10, relief="groove", bd=2, command=self.validateInput |
| 126 | + ).pack(side="right") |
| 127 | + |
| 128 | + tk.Button(buttonFrame, text="Cancel", font=TEXT_FONT, width=10, relief="groove", bd=2, command=lambda: self.controller.showFrame('MainMenu') |
| 129 | + ).pack(side="right") |
| 130 | + |
| 131 | + |
| 132 | + def addPlayer(self, evt=None): |
| 133 | + name = getText(self.playerName) |
| 134 | + if(name and not name in self.chosenPlayersList.get(0, tk.END)): |
| 135 | + self.chosenPlayersList.insert(tk.END, name) |
| 136 | + self.updateNumPlayers() |
| 137 | + |
| 138 | + def removePlayer(self): |
| 139 | + selected = getSelected(self.chosenPlayersList) |
| 140 | + if selected: |
| 141 | + self.chosenPlayersList.delete(selected["index"]) |
| 142 | + self.updateNumPlayers() |
| 143 | + |
| 144 | + def clearPlayerList(self): |
| 145 | + self.chosenPlayersList.delete(0, tk.END) |
| 146 | + self.updateNumPlayers() |
| 147 | + |
| 148 | + def selectPlayer(self, evt): |
| 149 | + selected = getSelected(evt.widget) |
| 150 | + if selected: |
| 151 | + self.playerName.delete("1.0", tk.END) |
| 152 | + self.playerName.insert("1.0", selected["value"]) |
| 153 | + |
| 154 | + self.playerEmail.delete("1.0", tk.END) |
| 155 | + self.playerEmail.insert("1.0", self.playerToEmailMap[selected["value"]]) |
| 156 | + |
| 157 | + def updateNumPlayers(self): |
| 158 | + self.playerLabel.config(text="Players (" + str(self.chosenPlayersList.size()) + "):") |
| 159 | + |
| 160 | + def validateInput(self): |
| 161 | + diceName = self.validateDiceName() |
| 162 | + if not diceName: |
| 163 | + return |
| 164 | + |
| 165 | + if not self.chosenPlayersList.size(): |
| 166 | + self.errorMessage.config(text="Must have at least one player.") |
| 167 | + return |
| 168 | + |
| 169 | + self.start(diceName) |
| 170 | + |
| 171 | + def validateDiceName(self): |
| 172 | + if self.newDice.get(): |
| 173 | + diceName = getText(self.diceName) |
| 174 | + if not diceName: |
| 175 | + self.errorMessage.config(text="Please enter a dice name.") |
| 176 | + if os.path.exists("data/" + diceName): |
| 177 | + self.errorMessage.config(text="Dice name already exists.") |
| 178 | + return None |
| 179 | + os.mkdir('data/' + diceName) |
| 180 | + else: |
| 181 | + selected = getSelected(self.diceList) |
| 182 | + if selected: |
| 183 | + diceName = selected["value"] |
| 184 | + else: |
| 185 | + self.errorMessage.config(text="No dice selected.") |
| 186 | + return None |
| 187 | + |
| 188 | + return diceName |
| 189 | + |
| 190 | + def start(self, diceName): |
| 191 | + self.controller.diceName = diceName |
| 192 | + for i in xrange(0, self.chosenPlayersList.size()): |
| 193 | + name = self.chosenPlayersList.get(i) |
| 194 | + email = self.playerToEmailMap.get(name) |
| 195 | + self.controller.addPlayer(name, email) |
| 196 | + |
| 197 | + self.controller.start() |
| 198 | + self.controller.showFrame('Main') |
| 199 | + |
| 200 | + |
| 201 | +def getText(textWidget): |
| 202 | + return textWidget.get("1.0",'end-1c') |
| 203 | + |
| 204 | +def getSelected(listbox): |
| 205 | + if listbox.curselection(): |
| 206 | + index = int(listbox.curselection()[0]) |
| 207 | + value = listbox.get(index) |
| 208 | + return {"index": index, "value": value} |
| 209 | + return None |
| 210 | + |
0 commit comments