def startWaitingRoomUI(self, pumpit): self.pumpit = True if 'pumpit' in locals(): self.pumpit = pumpit cfg.wroom = Tk() cfg.wroom.protocol("WM_DELETE_WINDOW", self.quitWaitingRoom) """State variables - By using textvariable=var in definition widget is tied to this variable""" statusmsg_sv = StringVar() #needed entry_sv = StringVar(value = cfg.name) #entry_sv.trace("w", lambda name, index, mode, sv=entry_sv: self.changeName(sv)) chatentry_sv = StringVar(value = "Press enter to chat") """Create and grid the outer content frame""" content = ttk.Frame(cfg.wroom) #, padding=(5, 5, 12, 0)) #Frame in cfg.wroom content.grid(column = 0, row = 0, sticky = (N,W,E,S)) cfg.wroom.grid_columnconfigure(0, weight = 1) cfg.wroom.grid_rowconfigure(0, weight = 1) """Create the different widgets; note the variables that some widgets are bound to""" self.tree = Treeview(content, show="headings", columns=cfg.wroominstance.tree_headers, name = "treeview") self.tree.column("#1", minwidth = 100, width = 120, stretch = NO) self.tree.column("#2", minwidth = 30, width = 60, stretch = NO) self.tree.column("#3", minwidth = 30, width = 50, stretch = YES) self.tree.column("#4", minwidth = 30, width = 50, stretch = YES) self.tree.column("#5", minwidth = 30, width = 50, stretch = YES) namelbl = ttk.Label(content, text="Player name") self.nameentry = ttk.Entry(content, bg = 'white', textvariable = entry_sv, name = "nameentry")#, validatecommand=validateIt) colorlbl = ttk.Label(content, text="Player color") self.colorframe = ttk.Frame(content, name = "colorframe", borderwidth = 1, relief='sunken') lbl = ttk.Label(content, text="Send to player:") #Label on the right self.log = Listbox(content, height = 5, bg = 'white', name = "logbox")#, listvariable=cmessagelog #Listbox with messages self.chatAll = ttk.Button(content, text = 'Chat to All', command = self.chatToAll, default = 'active', width = '6',name = "chat") self.chatentry = ttk.Entry(content, bg = 'white', foreground = 'gray', textvariable = chatentry_sv, name = "chatentry", selectforeground = 'blue') testbtn = ttk.Button(content, text = 'Connections', command = self.test, default = 'active', width = '6', name = "testbtn") ready = ttk.Button(content, text = 'Ready', command = self.toggleReadyForGame, default = 'active', width = '6', name = "readybtn") solitaire = ttk.Button(content, text = 'Solitaire', command = self.solitaire, default = 'active', width = '6', name = "solitairebtn") quit = ttk.Button(content, text = 'Quit', command = self.quitWaitingRoom, default = 'active', width = '6', name = "quitbtn") status = ttk.Label(content, textvariable = statusmsg_sv, anchor = W, name = "statuslbl") #Label on the bottom def get_tree(): """Get from the self.tree an item when clicked""" idxs = self.tree.item(self.tree.focus()) vals = idxs['values'] if len(idxs['values'])==0: return None return vals """def sortby(tree, col, descending): Sort tree contents when a column header is clicked on # grab values to sort data = [(tree.set(child, col), child) \ for child in tree.get_children('')] # now sort the data in place data.sort(reverse=descending) for ix, item in enumerate(data): tree.move(item[1], '', ix) # switch the heading so it will sort in the opposite direction tree.heading(col, command=lambda col=col: sortby(tree, col, int(not descending))) """ def showstatus(*args): """Called when the selection in the listbox changes; Update the status message on the bottom with the new information""" list = get_tree() if list is None: return statusmsg_sv.set("Player %s has this status: %s" % (list[0], list[1])) # Grid all the widgets self.tree.grid(row = 0, column = 0, rowspan = 9, sticky = (N,S,E,W)) namelbl.grid(row = 0, column = 1, columnspan = 2, sticky = (N,W), padx = 5) self.nameentry.grid(row = 1, column = 1, columnspan = 2, sticky = (N,E,W), pady = 5, padx = 5) colorlbl.grid(row = 0, column = 3, columnspan = 1, sticky = (N,W), padx = 5) self.colorframe.grid(row = 1, column = 3, columnspan = 1, sticky = (N,E,W), pady = 5, padx = 5) #testbtn.grid(row = 3, column = 3, columnspan = 1, sticky = E, padx = 5) #Test Button self.log.grid(row = 5, column = 1, columnspan = 3, sticky = (N,S,E,W), padx = 5, pady = 5) #Listbox with all messages self.chatentry.grid(row = 6, column = 1, columnspan = 2, sticky = (N,E), padx = 5, pady = 5) self.chatAll.grid(row = 6, column = 3, columnspan = 1, sticky = (N,E), padx = 5, pady = 5) ready.grid(row = 7, column = 1, sticky = (W,S), padx = 5, pady = 5) # solitaire.grid(row = 7, column = 2, sticky = (W,S), padx = 5, pady = 5) quit.grid(row = 7, column = 3, sticky = (W,S), padx = 5, pady = 5) status.grid(row = 9, column = 0, columnspan = 2, sticky = (W,E)) """Configure content Frame and color Frame""" content.grid_columnconfigure(0, weight = 1) content.grid_rowconfigure(5, weight = 1) h = self.nameentry.winfo_reqheight() self.colorframe.configure(height = h, bg = 'red') """Set event bindings""" self.tree.bind('<<TreeviewSelect>>', showstatus) self.nameentry.bind('<Return>', (lambda _: self.askChangeName(self.nameentry))) self.nameentry.bind('<FocusOut>', (lambda _: self.askChangeName(self.nameentry))) cfg.wroom.bind('<Control-Key-w>', self.quitWaitingRoom) cfg.wroom.bind('<Control-Key-q>', self.quitWaitingRoom) cfg.wroom.bind('<Control-Key-r>', self.toggleReadyForGame) cfg.wroom.bind('<Control-Key-s>', self.solitaire) self.chatentry.bind("<Return>",self.chatToAll) def chatEntryActive(e = None): self.chatentry.config(foreground = 'black') self.chatentry.delete(0, 'end') def chatEntryInactive(e = None): print(self) chatentry_sv.set("Press enter to chat") self.chatentry.config(foreground = 'gray') self.chatentry.bind("<FocusIn>", lambda e: chatEntryActive(e)) self.chatentry.bind("<FocusOut>", lambda e: chatEntryInactive(e)) self.colorframe.bind("<ButtonRelease-1>", self.changeColor) """Set tooltips on widgets""" hover.createToolTip(namelbl, "Type in your name") hover.createToolTip(self.nameentry, "Type in your name") hover.createToolTip(ready, "Toggle ready state to play tantrix with other players") hover.createToolTip(solitaire, "Start a two player game on this computer") hover.createToolTip(quit, "Quit Tantrix") hover.createToolTip(self.chatentry, "Press enter to send to chat") hover.createToolTip(self.chatAll, "Press enter to send to chat") hover.createToolTip(self.colorframe, "Click to select your color") hover.createToolTip(colorlbl, "Your color") """Set the starting state of the interface""" statusmsg_sv.set('') showstatus() """Start main loop for tkinter and Sixpodnet""" self.keepLooping = True if self.pumpit: self.mainLoopWithPump() else: self.mainLoopWithoutPump() return self.quit
def startpreSolitaireUI(self, pumpit): self.pumpit = pumpit cfg.wroom = Tk() cfg.wroom.protocol("WM_DELETE_WINDOW", self.quitpreSolitaire) """State variables - By using textvariable=var in definition widget is tied to this variable""" entry_sv = StringVar(value = cfg.name) entry2_sv = StringVar(value = cfg.opponentname) """Create and grid the outer content frame""" content = ttk.Frame(cfg.wroom) content.grid(column = 0, row = 0, sticky = (N,W,E,S)) cfg.wroom.grid_columnconfigure(0, weight = 1) cfg.wroom.grid_rowconfigure(0, weight = 1) """Create the different widgets; note the variables that some widgets are bound to""" namelbl = ttk.Label(content, text="Player 1's name") self.nameentry = ttk.Entry(content, bg = 'white', textvariable = entry_sv, name = "nameentry") namelbl2 = ttk.Label(content, text="Player 2's name") self.nameentry2 = ttk.Entry(content, bg = 'white', textvariable = entry2_sv, name = "nameentry2") colorlbl = ttk.Label(content, text="Player color") self.colorframe = ttk.Frame(content, name = "colorframe", borderwidth = 1, relief='sunken') colorlbl2 = ttk.Label(content, text="Player2 color") self.colorframe2 = ttk.Frame(content, name = "colorframe2", borderwidth = 1, relief='sunken') startbtn = ttk.Button(content, text = 'Start', command = self.quitToGame, default = 'active', width = '6', name = "solitairebtn") quit = ttk.Button(content, text = 'Quit', command = self.quitpreSolitaire, default = 'active', width = '6', name = "quitbtn") """Grid all the widgets""" namelbl.grid(row = 0, column = 0, columnspan = 2, sticky = (N,W), padx = 5) colorlbl.grid(row = 0, column = 3, columnspan = 1, sticky = (N,W), padx = 5) self.nameentry.grid(row = 1, column = 1, columnspan = 2, sticky = (N,E,W), pady = 5, padx = 5) self.colorframe.grid(row = 1, column = 3, columnspan = 1, sticky = (N,E,W), pady = 5, padx = 5) namelbl2.grid(row = 2, column = 0, columnspan = 2, sticky = (N,W), padx = 5) colorlbl2.grid(row = 2, column = 3, columnspan = 1, sticky = (N,W), padx = 5) self.nameentry2.grid(row = 3, column = 1, columnspan = 2, sticky = (N,E,W), pady = 5, padx = 5) self.colorframe2.grid(row = 3, column = 3, columnspan = 1, sticky = (N,E,W), pady = 5, padx = 5) startbtn.grid(row = 4, column = 3, sticky = (E,S), padx = 5, pady = 5) quit.grid(row = 4, column = 2, sticky = (W,S), padx = 5, pady = 5) """Configure content Frame and color Frame""" content.grid_columnconfigure(0, weight = 1) content.grid_rowconfigure(5, weight = 1) h = self.nameentry.winfo_reqheight() self.colorframe.configure(height = h, bg = cfg.playercolor) self.colorframe2.configure(height = h, bg = cfg.opponentcolor) """Set event bindings""" self.nameentry.bind('<Return>', (lambda _: self.askChangeName(self.nameentry, 1))) self.nameentry2.bind('<Return>', (lambda _: self.askChangeName(self.nameentry2, 2))) self.nameentry.bind('<FocusOut>', (lambda _: self.askChangeName(self.nameentry, 1))) self.nameentry2.bind('<FocusOut>', (lambda _: self.askChangeName(self.nameentry2, 2))) cfg.wroom.bind('<Control-Key-w>', self.quitpreSolitaire) cfg.wroom.bind('<Control-Key-q>', self.quitpreSolitaire) cfg.wroom.bind('<Control-Key-s>', self.quitpreSolitaire) self.colorframe.bind("<ButtonRelease-1>", (lambda _: self.changeColor(1))) self.colorframe2.bind("<ButtonRelease-1>", (lambda _: self.changeColor(2))) """Set tooltips on widgets""" #hover.createToolTip(namelbl, "Type in your name and press Enter") hover.createToolTip(self.nameentry, "Type in the name for player 1") hover.createToolTip(self.nameentry2, "Type in the name for player 2") hover.createToolTip(startbtn, "Start a two player game on this computer") hover.createToolTip(quit, "Quit Tantrix") hover.createToolTip(self.colorframe, "Click to select player 1's color") hover.createToolTip(self.colorframe2, "Click to select player 2's color") #hover.createToolTip(colorlbl, "Your color") """Start main loop for tkinter and Sixpodnet""" self.keepLooping = True if self.pumpit: self.mainLoopWithPump() else: self.mainLoopWithoutPump() return self.quit
def startGameUI(self, wintitle): """Determine attributes from player""" cfg.gameinprogress = True self.win = tk.Tk() self.win.protocol("WM_DELETE_WINDOW", self.deleteWindow) self.win.wm_title(wintitle) self.win.minsize(int(cfg.HEX_COS + (cfg.HEX_SIZE * 2 - cfg.HEX_COS) * 8 + 76), int(math.ceil(cfg.HEX_HEIGHT * 4) + cfg.YTOPPL1 + cfg.HEX_HEIGHT * 1.5 + cfg.HEX_HEIGHT)) self.win.maxsize(int(cfg.HEX_COS + (cfg.HEX_SIZE * 2 - cfg.HEX_COS) * (cfg.ROWS + 30)), int(math.ceil(cfg.HEX_HEIGHT * (cfg.COLS + 18)) + cfg.YTOPPL1 + cfg.HEX_HEIGHT * 1.5 + cfg.HEX_HEIGHT)) #Set the window size and get its geometry to dynamically set the positions of its widgets win_width = cfg.BOARD_WIDTH + 76 #76 is the width of the buttons on the right win_height = cfg.YBOTTOMBOARD + cfg.YTOPBOARD * 2 self.win.geometry('%dx%d+%d+%d' % (win_width, win_height, 0, 0)) """Create self.canvas""" self.canvas = tk.Canvas(self.win, height = 0, width = 0, name = "canvas") """Create main bkgr rectangle in self.canvas""" bg_color = "#F1DCFF" self.backgroundID = self.canvas.create_rectangle(0, 0, 0, 0, width = 2, fill = bg_color) #pink-purple """Create hexagons on self.canvas""" def create_hexagons(): cfg.hexagon_generator = hg.HexagonGenerator(cfg.HEX_SIZE) for row in range(-10, cfg.ROWS + 30): for col in range(-10, cfg.COLS + 18): pts = list(cfg.hexagon_generator(row, col)) self.canvas.create_line(pts, width = 2) create_hexagons() """Append canvas on self.win""" #self.canvas.grid(row = 1, column = 0, rowspan = 5) self.canvas.pack(fill=tk.BOTH, expand=1) """Create rectangles to place over self.canvas""" #Tiles player 1 on top self.textwin1 = self.canvas.create_rectangle(0, 0, 0, 0, width = 2, fill = bg_color, tags = "raised") color = cfg.PLAYERCOLORS.index(cfg.playercolor) if cfg.player_num == 1 else cfg.PLAYERCOLORS.index(cfg.opponentcolor) color = cfg.PLAYERCOLORS[color + 4] self.backgroundTopID = self.canvas.create_rectangle(0, 0, 0, 0, width = 2, fill = color, tags = "raised") #cover the canvas with background for the top tiles self.stipple1 = self.canvas.create_rectangle(0, 0, 0, 0, width = 0, tags = "stipple", fill = "") #"#FEFD6C" top yellow #Tiles player 2 on bottom color = cfg.PLAYERCOLORS.index(cfg.playercolor) if cfg.player_num == 2 else cfg.PLAYERCOLORS.index(cfg.opponentcolor) color = cfg.PLAYERCOLORS[color + 4] self.backgroundBottomID = self.canvas.create_rectangle(0, 0, 0, 0, width = 2, fill = color, tags = "raised") #cover the canvas with background for the bottom tiles self.stipple2 = self.canvas.create_rectangle(0, 0, 0, 0, width = 0, tags = "stipple", fill = "gray", stipple = "gray12") self.textwin2 = self.canvas.create_rectangle(0, 0, 0, 0, width = 2, fill = bg_color, tags = "raised") #cover canvas on the right self.backgroundRightID = self.canvas.create_rectangle(0, 0, 0, 0, width = 2, fill = bg_color, tags = "raised") """Buttons""" btnwidth = 6 """Confirm button""" self.btnConf = tk.Button(self.win, text = "Confirm\nmove", width = btnwidth, name = "btnConf", state = "disabled", relief = "flat", bg = "white", activebackground = "cyan", anchor = tk.W) self.btnConf.bind('<ButtonRelease-1>', self.buttonCallback) self.btnConf_window = self.canvas.create_window(0, 0, anchor = tk.NW, window = self.btnConf) """Reset button""" self.btnReset = tk.Button(self.win, text = "Reset\ndeck", width = btnwidth, name = "btnReset", state = "disabled", relief = "flat", bg = "white", activebackground = "cyan") self.btnReset_window = self.canvas.create_window(0, 0, anchor = tk.SW, window = self.btnReset) self.btnReset.bind('<ButtonRelease-1>', self.buttonCallback) """Quit button""" self.btnQuit = tk.Button(self.win, text = "Quit", width = btnwidth, name = "btnQuit", relief = "flat", bg = "white", activebackground = "red") self.btnQuit_window = self.canvas.create_window(0, 0, anchor = tk.SW, window = self.btnQuit) self.btnQuit.bind('<ButtonRelease-1>', self.buttonCallback) """Score button""" self.btnScore = tk.Button(self.win, text = "Score", width = btnwidth, name = "btnScore", state = "normal", relief = "flat", bg = "white", activebackground = "cyan") self.btnScore_window = self.canvas.create_window(1, 1, anchor = tk.W, window = self.btnScore) self.btnScore.bind('<ButtonRelease-1>', self.buttonCallback) """Text widgets: messages and scores""" self.text1 = self.canvas.create_text(0 + 5, 0, text = "", anchor = tk.NW, font = 15, tags = "raised") self.text2 = self.canvas.create_text(0, 0, text = "", anchor = tk.SW, font = 15, tags = "raised") """Chat""" #cfg.chat = tk.Listbox(self.canvas, height = 5, bg = 'white', name = "logbox")#, listvariable=cmessagelog #Listbox with messages #cfg.chatentry = tk.Entry(self.canvas, bg = 'white', foreground = 'gray', textvariable = chatentry_sv, name = "chatentry", selectforeground = 'blue') #cfg.chat.grid(row = 5, column = 1, columnspan = 3, sticky = (N,S,E,W), padx = 5, pady = 5) #Listbox with all messages """Store widgets and widget items""" cfg.win = self.win cfg.canvas = self.canvas cfg.textwin1 = self.textwin1 cfg.stipple1 = self.stipple1 cfg.stipple2 = self.stipple2 cfg.textwin2 = self.textwin2 cfg.text1 = self.text1 cfg.text2 = self.text2 #cfg.board = self.board cfg.board.message() def configure(event): """Callback to handle resizing of the main window""" win_width, win_height = event.width, event.height """Update coordinates used by UI elements""" cfg.BOARD_WIDTH = win_width - 76 cfg.YTOPBOARD = cfg.YTOPPL1 + cfg.HEX_HEIGHT + cfg.BUFFER cfg.BOARD_HEIGHT = win_height - (cfg.HEX_HEIGHT * 2.5 + cfg.YTOPPL1 - cfg.BUFFER * 2) - 2# - cfg.HEX_HEIGHT / 4#NEW #2 is ~ the Tk window border cfg.YBOTTOMWINDOW = cfg.BOARD_HEIGHT + cfg.HEX_HEIGHT * 2.5 + cfg.YTOPPL1 - cfg.BUFFER * 2# - cfg.HEX_HEIGHT / 2 cfg.YBOTTOMBOARD = cfg.YBOTTOMWINDOW - cfg.HEX_HEIGHT cfg.YBOTTOMPL2 = cfg.YBOTTOMWINDOW - cfg.YTOPPL1 """Positions of canvas and all canvas items""" self.canvas.config(height = win_width, width = win_height) self.canvas.coords(self.backgroundID, 0, cfg.YTOPBOARD, cfg.BOARD_WIDTH, cfg.YBOTTOMBOARD) self.canvas.coords(self.textwin1, 0, 0, cfg.BOARD_WIDTH, cfg.YTOPPL1) self.canvas.coords(self.backgroundTopID, 0, cfg.YTOPPL1, cfg.BOARD_WIDTH, cfg.YTOPBOARD) self.canvas.coords(self.stipple1, 0, cfg.YTOPPL1, cfg.BOARD_WIDTH, cfg.YTOPBOARD) self.canvas.coords(self.backgroundBottomID, 0, cfg.YBOTTOMBOARD - cfg.YTOPPL1, cfg.BOARD_WIDTH, win_height - cfg.YTOPPL1) self.canvas.coords(self.stipple2, 0, cfg.YBOTTOMBOARD - cfg.YTOPPL1, cfg.BOARD_WIDTH, win_height - cfg.YTOPPL1) self.canvas.coords(self.textwin2, 0, cfg.YBOTTOMPL2, cfg.BOARD_WIDTH, cfg.YBOTTOMWINDOW) self.canvas.coords(self.backgroundRightID, cfg.BOARD_WIDTH, 0, win_width, win_height) self.canvas.coords(self.text2, 0 + 5, cfg.YBOTTOMWINDOW) """Positions of the buttons""" self.canvas.coords(self.btnConf_window, cfg.BOARD_WIDTH + cfg.BUFFER * 2, cfg.YTOPBOARD + cfg.HEX_SIZE * 2) self.canvas.coords(self.btnReset_window, cfg.BOARD_WIDTH + cfg.BUFFER * 2, cfg.YTOPBOARD + cfg.HEX_SIZE * 8)#cfg.YBOTTOMBOARD - cfg.HEX_SIZE * 4) self.canvas.coords(self.btnQuit_window, cfg.BOARD_WIDTH + cfg.BUFFER * 2, cfg.YBOTTOMBOARD - cfg.HEX_HEIGHT - cfg.HEX_SIZE * 2) self.canvas.coords(self.btnScore_window, cfg.BOARD_WIDTH + cfg.BUFFER * 2, cfg.YBOTTOMBOARD - cfg.HEX_HEIGHT - cfg.HEX_SIZE * 6) #self.canvas.create_rectangle(0, cfg.YTOPBOARD + cfg.HEX_SIZE, 1000, cfg.YTOPBOARD + cfg.HEX_SIZE * 3, fill="red") #self.canvas.create_rectangle(0, cfg.YBOTTOMBOARD - cfg.HEX_HEIGHT / 2, 1000, cfg.YBOTTOMBOARD - cfg.HEX_SIZE * 8, fill="red") """Positions of the tiles""" cfg.deck.expand() """Update window""" self.win.update() self.canvas.bind("<Configure>", configure) """Set the sizes and positions of canvas, widgets and widget items. Create a bogus event to feed in configure""" class Event(object): pass event = Event() event.width = win_width event.height = win_height configure(event) """Bind arrows that move the table""" self.win.bind('<Left>', lambda event, horiz = 1: cfg.deck.shift(shift_row = horiz)) self.win.bind('<Right>', lambda event, horiz = -1: cfg.deck.shift(shift_row = horiz)) self.win.bind('<Down>', lambda event, vert = -1: cfg.deck.shift(shift_col = vert)) self.win.bind('<Up>', lambda event, vert = 1: cfg.deck.shift(shift_col = vert)) """Set tooltips on widgets""" hover.createToolTip(self.btnQuit, "Quit tantrix") hover.createToolTip(self.btnScore, "Show the score as longest line + closed line") hover.createToolTip(self.btnReset, "Bring back the moved tiles") hover.createToolTip(self.btnConf, "Confirm your move. If the button is disable, something is wrong with your move") """Update window""" self.win.update() self.win.update_idletasks() self.win.update()