def display_load_menu(self): """ Builds a load menu that displays the three save slots. Loads the save information if the save file exists and uses different maze methods/fields to obtain information about the save such as the maze size, player location, trivia category, trivia difficulty, and time spent in game and displays this info. """ saves = Frame(self.root, height=650, width=650, bg='SystemButtonFace') saves.grid(row=0, column=0) save = [] load_instruct = "Loading will take a few seconds, and can be inconsistent.\n" \ "Wait a moment before clicking a save file again or exit the load menu and try again." instruct = Label(saves, text=load_instruct, font='Times 12', pady=10) instruct.grid(row=0, column=0) for i in range(1, 4): savelabel = LabelFrame(saves, height=175, width=550, text=f'Save {i}', cursor='hand1', font='Times 16') savelabel.grid(row=i, column=0, sticky=E) savelabel.grid_propagate(0) try: loadhandle = open(f'save_file_{i}.pkl', 'rb') maze = pickle.load(loadhandle) info = [ f'Rows: {maze.get_size()[0]}', f'Columns: {maze.get_size()[1]}', f'Difficulty: {maze.difficulty}', f'Category: {maze.category}', f'Position: {maze.player_location}', f'Time: {maze.get_time()}' ] for j in range(len(info)): label = Label(savelabel, text=info[j], font='Times 14', anchor=W, padx=5, pady=10) label.grid(row=j % 2, column=j // 2, sticky=W) loadhandle.close() save_file = "save_file_" + str(i) savelabel.bind( '<Button-1>', partial(self.load_game, save_file, load_menu=saves)) except FileNotFoundError: continue save.append(savelabel) back_button = Button( saves, text="Back", font='Times 20', anchor=N, command=lambda: self.screen_switch(saves, self.startmenu)) back_button.grid(row=4, column=0)
class App_Button(object): """docstring for App_Button""" def __init__(self, master, text=None, styles=None, command=None, image=None, title=None, disabled=False): super(App_Button, self).__init__() self.master = master self.text = text self.styles = styles self.command = command self.image = image self.title = title self.disabled = disabled self.putButton() def putButton(self): self.btn_wrapper = LabelFrame(self.master, relief=FLAT, borderwidth=0) self.btn = Button(self.btn_wrapper, text=self.text, relief=FLAT, bg=self.styles['btn_bg'], padx=self.styles['padx'], pady=self.styles['pady'], fg=self.styles['btn_fg'], borderwidth=0, font=self.styles['big_font'], command=self.command, image=self.image, activeforeground=self.styles['a_fg'], activebackground=self.styles['a_bg'], cursor="hand2") self.btn.image = self.image if self.disabled: self.btn.bind("<Button-1>", lambda x: "break") else: self.btn.bind("<Enter>", self.mouseover) self.btn.bind("<Leave>", self.mouseout) self.btn.pack() if self.title is not None: self.tooltip = App_Tooltip(self.btn, text=self.title) def mouseover(self, event): self.btn.config(fg=self.styles['h_fg']) self.btn.config(bg=self.styles['h_bg']) def mouseout(self, event): self.btn.config(fg=self.styles['btn_fg']) self.btn.config(bg=self.styles['btn_bg']) def bind(self, *args, **kwargs): self.btn.bind(*args, **kwargs) def bind_wrapper(self, *args, **kwargs): self.btn_wrapper.bind(*args, **kwargs) def pack(self, *args, **kwargs): self.btn_wrapper.pack(*args, **kwargs) def place(self, *args, **kwargs): self.btn_wrapper.place(*args, **kwargs) def config(self, *args, **kwargs): self.btn.config(*args, **kwargs) def set_tooltip(self, text): self.tooltip.configure(text=text) def pack_forget(self): self.btn_wrapper.pack_forget() def place_forget(self): self.btn_wrapper.place_forget() def winfo_rootx(self): return self.btn_wrapper.winfo_rootx() def winfo_rooty(self): return self.btn_wrapper.winfo_rooty() def winfo_height(self): return self.btn_wrapper.winfo_height() def winfo_width(self): return self.btn_wrapper.winfo_width()
class App_Photo(object): """docstring for App_Photo""" def __init__(self, master, pil_photo, styles, root, fullsize_path, hide_cmd=None, del_cmd=None): super(App_Photo, self).__init__() self.master = master self.pil_photo = pil_photo self.fullsize_path = fullsize_path self.photo = PIL.ImageTk.PhotoImage(pil_photo) self.styles = styles self.tool_styles = styles.copy() self.tool_styles['big_font'] = styles['font'] self.tool_styles['padx'] = 5 self.tool_styles['pady'] = 3 self.root = root self.hide_cmd = hide_cmd self.del_cmd = del_cmd self.putPhoto() def putPhoto(self): self.wrapper = LabelFrame(self.master, bg=self.styles['bg'], borderwidth=0) self.photo_label = Label(self.wrapper, image=self.photo, borderwidth=0, cursor="hand2") self.photo_label.bind("<Button-1>", self.zoom) self.photo_label.bind("<Enter>", self.show_tools) self.photo_label.bind("<Leave>", self.hide_tools) self.photo_label.image = self.photo self.photo_label.pack() self.minimize_tool = App_Button(self.wrapper, text="➖", styles=self.tool_styles, command=self.hide_cmd) self.minimize_tool.bind_wrapper("<Enter>", self.show_tools) self.minimize_tool.place(x=0, y=0) self.minimize_tool.place_forget() self.delete_tool = App_Button(self.wrapper, text="✕", styles=self.tool_styles, command=self.del_cmd) self.delete_tool.bind_wrapper("<Enter>", self.show_tools) self.delete_tool.place(x=0, y=0) self.delete_tool.place_forget() self.overlay = LabelFrame(self.root, bg=self.styles['overlay'], fg=self.styles['overlay'], borderwidth=0) self.overlay_close = App_Button(self.overlay, text="⩁", title="Close the zoomed view", styles=self.styles, command=self.un_zoom) self.overlay_close.place(x=0, y=0) def zoom(self, event): window_width = self.root.winfo_width() window_height = self.root.winfo_height() self.overlay.config(width=window_width) self.overlay.config(height=window_height) self.overlay.place(x=0, y=0) zoomed_width = int(window_width * 0.8) zoomed_height = int(window_height * 0.8) pil_photo = PIL.Image.open(self.fullsize_path) wpercent = (zoomed_width/float(pil_photo.size[0])) hsize = int((float(pil_photo.size[1])*float(wpercent))) zoomed_pil_photo = pil_photo.resize((zoomed_width,hsize), PIL.Image.ANTIALIAS) hpercent = (zoomed_height/float(pil_photo.size[1])) wsize = int((float(pil_photo.size[0])*float(hpercent))) zoomed_pil_photo = pil_photo.resize((wsize,zoomed_height), PIL.Image.ANTIALIAS) zoomed_photo = PIL.ImageTk.PhotoImage(zoomed_pil_photo) self.zoomed_photo_label = Label(self.root, image=zoomed_photo, borderwidth=0) self.zoomed_photo_label.image = zoomed_photo self.zoomed_photo_label.pack() photo_x_pos = (window_width / 2) - (wsize / 2) photo_y_pos = (window_height / 2) - (zoomed_height / 2) overlay_close_width = self.overlay_close.winfo_width() self.overlay_close.place(x=window_width-overlay_close_width-25, y=25) self.zoomed_photo_label.place(x=photo_x_pos, y=photo_y_pos) def un_zoom(self): self.overlay.place_forget() self.zoomed_photo_label.place_forget() def show_tools(self, event): photo_x = self.photo_label.winfo_x() photo_y = self.photo_label.winfo_y() photo_width = self.photo_label.winfo_width() minimize_tool_width = self.minimize_tool.winfo_width() delete_tool_width = self.delete_tool.winfo_width() minimize_tool_x_pos = photo_x + photo_width - minimize_tool_width - delete_tool_width - 5 delete_tool_x_pos = photo_x + photo_width - delete_tool_width tool_y_pos = photo_y + 5 self.minimize_tool.place(x=minimize_tool_x_pos, y=tool_y_pos) self.delete_tool.place(x=delete_tool_x_pos, y=tool_y_pos) def hide_tools(self, event): self.minimize_tool.place_forget() self.delete_tool.place_forget() def bind(self, *args, **kwargs): self.wrapper.bind(*args, **kwargs) def pack(self, *args, **kwargs): self.wrapper.pack(*args, **kwargs) def destroy(self, *args, **kwargs): self.wrapper.destroy(*args, **kwargs)
class App_Checkbox(object): """docstring for App_Checkbox""" def __init__(self, master, text, styles, checked=True, checkbox_id=None,oncheck=None, onuncheck=None): super(App_Checkbox, self).__init__() self.master = master self.text = text self.styles = styles self.checked = checked self.checkbox_id = checkbox_id self.oncheck = oncheck self.onuncheck = onuncheck self.num_toggles = 0 if self.checked else 1 self.putCheckbox() def putCheckbox(self): self.wrapper = LabelFrame(self.master, bg=self.styles['bg'], borderwidth=0, padx=5, pady=6, cursor="hand2") self.box = LabelFrame(self.wrapper, bg=self.styles['bg'], width=30, height=30, borderwidth=1, cursor="hand2") self.box.bind("<Button-1>", self.toggle_check) self.box.pack(side=LEFT) self.label = Label(self.wrapper, fg=self.styles['fg'] if self.checked else self.styles['placeholder_fg'], bg=self.styles['bg'], text=self.text, font=self.styles['font'], cursor="hand2") self.label.bind("<Button-1>", self.toggle_check) self.label.pack(side=LEFT, padx=6) self.check = Label(self.wrapper, fg=self.styles['fg'], bg=self.styles['bg'], text="✔", font=self.styles['checkbox_font'], cursor="hand2") if self.checked: self.check.place(x=4, y=3) self.check.bind("<Button-1>", self.toggle_check) def toggle_check(self, event): self.num_toggles += 1 if self.num_toggles % 2 == 0: self.check.place(x=4, y=3) self.label.config(fg=self.styles['fg']) if self.oncheck != None: self.oncheck(self.checkbox_id) else: self.check.place_forget() self.label.config(fg=self.styles['placeholder_fg']) if self.onuncheck != None: self.onuncheck(self.checkbox_id) def pack(self, *args, **kwargs): self.wrapper.pack(*args, **kwargs) def winfo_width(self, *args, **kwargs): return self.wrapper.winfo_width(*args, **kwargs) def scroll_bind(self, *args, **kwargs): self.wrapper.bind(*args, **kwargs) self.box.bind(*args, **kwargs) self.label.bind(*args, **kwargs) self.check.bind(*args, **kwargs)
class App_Fab(object): """docstring for App_Fab""" def __init__(self, master, structure, styles, root): super(App_Fab, self).__init__() self.master = master self.structure = structure self.styles = styles self.root = root self.styles = styles.copy() self.styles['big_font'] = styles['font'] self.styles['btn_bg'] = styles['menu_bg'] self.styles['padx'] = 15 self.styles['pady'] = 11 self.num_times_toggled = 0 self.menu_item_arr = [] self.putFab() def putFab(self): self.wrapper = LabelFrame(self.master, bg=self.styles['bg'], borderwidth=0, padx=20, pady=20) self.wrapper.bind("<Enter>", lambda e: self.toggle_menu(action="show")) self.wrapper.bind("<Leave>", lambda e: self.toggle_menu(action="hide")) self.fab = App_Button(self.wrapper, text="Menu Ӝ", styles=self.styles, command=self.toggle_menu) self.fab.bind_wrapper("<Enter>", lambda e: self.toggle_menu(action="show")) self.fab.bind_wrapper("<Leave>", lambda e: self.toggle_menu(action="hide")) self.fab.pack(side=BOTTOM, anchor="se") for menu_item in reversed(self.structure): text = menu_item['text'] title = menu_item['title'] command = menu_item['command'] menu_item_btn = App_Button(self.wrapper, text=text, styles=self.styles, command=command, title=title) menu_item_btn.bind_wrapper( "<Enter>", lambda e: self.toggle_menu(action="show")) # menu_item_btn.bind_wrapper("<Leave>", lambda e: self.toggle_menu(action="hide")) self.menu_item_arr.append(menu_item_btn) def show_menu(self, event=None, menu_item_btn=None): menu_item_btn.pack(side=BOTTOM, anchor="se") def hide_menu(self, event=None, menu_item_btn=None): menu_item_btn.pack_forget() def toggle_menu(self, action=None): for menu_item_btn in self.menu_item_arr: if action == None: if self.num_times_toggled % 2 == 0: self.show_menu(menu_item_btn=menu_item_btn) else: self.hide_menu(menu_item_btn=menu_item_btn) else: if action == "show": self.show_menu(menu_item_btn=menu_item_btn) elif action == "hide": self.hide_menu(menu_item_btn=menu_item_btn) self.num_times_toggled += 1 def put(self): window_width = self.root.winfo_width() window_height = self.root.winfo_height() self.wrapper.place(anchor="se", x=window_width - 15, y=window_height - 15)