def guiMain(settings=None): frames = {} mainWindow = Tk() mainWindow.wm_title("OoT Randomizer %s" % ESVersion) set_icon(mainWindow) notebook = ttk.Notebook(mainWindow) frames['rom_tab'] = ttk.Frame(notebook) frames['rules_tab'] = ttk.Frame(notebook) frames['logic_tab'] = ttk.Frame(notebook) frames['other_tab'] = ttk.Frame(notebook) frames['aesthetic_tab'] = ttk.Frame(notebook) adjustWindow = ttk.Frame(notebook) customWindow = ttk.Frame(notebook) notebook.add(frames['rom_tab'], text='ROM Options') notebook.add(frames['rules_tab'], text='Main Rules') notebook.add(frames['logic_tab'], text='Detailed Logic') notebook.add(frames['other_tab'], text='Other') notebook.add(frames['aesthetic_tab'], text='Aesthetics') # Shared Controls # adds a LabelFrame containing a list of radio buttons based on the given data # returns the label_frame, and a variable associated with it def MakeRadioList(parent, data): # create a frame to hold the radio buttons lable_frame = LabelFrame(parent, text=data["name"], labelanchor=NW) # create a variable to hold the result of the user's decision radio_var = StringVar(value=data["default"]); # setup orientation side = TOP anchor = W if "horizontal" in data and data["horizontal"]: side = LEFT anchor = N # add the radio buttons for option in data["options"]: radio_button = Radiobutton(lable_frame, text=option["description"], value=option["value"], variable=radio_var, justify=LEFT, wraplength=data["wraplength"]) radio_button.pack(expand=True, side=side, anchor=anchor) # return the frame so it can be packed, and the var so it can be used return (lable_frame, radio_var) ####################### # randomizer controls # ####################### # hold the results of the user's decisions here guivars = {} # hierarchy ############ #Rules Tab frames['open'] = LabelFrame(frames['rules_tab'], text='Open', labelanchor=NW) frames['logic'] = LabelFrame(frames['rules_tab'], text='Logic', labelanchor=NW) # Logic tab frames['rewards'] = LabelFrame(frames['logic_tab'], text='Remove Specific Locations', labelanchor=NW) frames['tricks'] = LabelFrame(frames['logic_tab'], text='Specific expected tricks', labelanchor=NW) #Other Tab frames['convenience'] = LabelFrame(frames['other_tab'], text='Speed Ups', labelanchor=NW) frames['other'] = LabelFrame(frames['other_tab'], text='Misc', labelanchor=NW) #Aesthetics tab frames['tuniccolor'] = LabelFrame(frames['aesthetic_tab'], text='Tunic Color', labelanchor=NW) frames['navicolor'] = LabelFrame(frames['aesthetic_tab'], text='Navi Color', labelanchor=NW) frames['lowhp'] = LabelFrame(frames['aesthetic_tab'], text='Low HP SFX', labelanchor=NW) # shared settingsFrame = Frame(mainWindow) settings_string_var = StringVar() settingsEntry = Entry(settingsFrame, textvariable=settings_string_var) def show_settings(event=None): settings = guivars_to_settings(guivars) settings_string_var.set( settings.get_settings_string() ) # Update any dependencies for info in setting_infos: if info.gui_params and 'dependency' in info.gui_params: dep_met = True for dep_var, dep_val in info.gui_params['dependency'].items(): if guivars[dep_var].get() != dep_val: dep_met = False if widgets[info.name].winfo_class() == 'Frame': for child in widgets[info.name].winfo_children(): child.configure(state= 'normal' if dep_met else 'disabled') else: widgets[info.name].config(state = 'normal' if dep_met else 'disabled') def import_settings(event=None): try: settings = guivars_to_settings(guivars) text = settings_string_var.get().upper() settings.seed = guivars['seed'].get() settings.update_with_settings_string(text) settings_to_guivars(settings, guivars) except Exception as e: messagebox.showerror(title="Error", message="Invalid settings string") label = Label(settingsFrame, text="Settings String") importSettingsButton = Button(settingsFrame, text='Import Settings String', command=import_settings) label.pack(side=LEFT, anchor=W, padx=5) settingsEntry.pack(side=LEFT, anchor=W) importSettingsButton.pack(side=LEFT, anchor=W, padx=5) fileDialogFrame = Frame(frames['rom_tab']) romDialogFrame = Frame(fileDialogFrame) baseRomLabel = Label(romDialogFrame, text='Base Rom') guivars['rom'] = StringVar(value='ZOOTDEC.z64') romEntry = Entry(romDialogFrame, textvariable=guivars['rom'], width=40) def RomSelect(): rom = filedialog.askopenfilename(filetypes=[("Rom Files", (".z64", ".n64")), ("All Files", "*")]) if rom != '': guivars['rom'].set(rom) romSelectButton = Button(romDialogFrame, text='Select Rom', command=RomSelect, width=10) baseRomLabel.pack(side=LEFT, padx=(40,0)) romEntry.pack(side=LEFT, padx=3) romSelectButton.pack(side=LEFT) romDialogFrame.pack() fileDialogFrame.pack(side=TOP, anchor=W, padx=5, pady=(5,1)) def open_output(): open_file(output_path('')) def output_dir_select(): rom = filedialog.askdirectory(initialdir = default_output_path(guivars['output_dir'].get())) if rom != '': guivars['output_dir'].set(rom) outputDialogFrame = Frame(frames['rom_tab']) outputDirLabel = Label(outputDialogFrame, text='Output Directory') guivars['output_dir'] = StringVar(value='') outputDirEntry = Entry(outputDialogFrame, textvariable=guivars['output_dir'], width=40) outputDirButton = Button(outputDialogFrame, text='Select Dir', command=output_dir_select, width=10) outputDirLabel.pack(side=LEFT, padx=(3,0)) outputDirEntry.pack(side=LEFT, padx=3) outputDirButton.pack(side=LEFT) outputDialogFrame.pack(side=TOP, anchor=W, padx=5, pady=(5,1)) if os.path.exists(local_path('README.html')): def open_readme(): open_file(local_path('README.html')) openReadmeButton = Button(outputDialogFrame, text='Open Documentation', command=open_readme) openReadmeButton.pack(side=LEFT, padx=5) outputDialogFrame.pack(side=TOP, anchor=W, pady=3) countDialogFrame = Frame(frames['rom_tab']) countLabel = Label(countDialogFrame, text='Generation Count') guivars['count'] = StringVar() countSpinbox = Spinbox(countDialogFrame, from_=1, to=100, textvariable=guivars['count'], width=3) countLabel.pack(side=LEFT) countSpinbox.pack(side=LEFT, padx=2) countDialogFrame.pack(side=TOP, anchor=W, padx=5, pady=(1,1)) multiworldFrame = LabelFrame(frames['rom_tab'], text='Multi-World Generation') countLabel = Label(multiworldFrame, wraplength=300, justify=LEFT, text='This is used for co-op generations. Increasing World Count will drastically increase the generation time. For more information see https://github.com/TestRunnerSRL/bizhawk-co-op') countLabel.pack(side=TOP, anchor=W, padx=5, pady=(1,1)) worldCountFrame = Frame(multiworldFrame) countLabel = Label(worldCountFrame, text='World Count') guivars['world_count'] = StringVar() countSpinbox = Spinbox(worldCountFrame, from_=1, to=100, textvariable=guivars['world_count'], width=3) countLabel.pack(side=LEFT) countSpinbox.pack(side=LEFT, padx=2) worldCountFrame.pack(side=LEFT, anchor=N, padx=5, pady=(1,1)) playerNumFrame = Frame(multiworldFrame) countLabel = Label(playerNumFrame, text='Player Number') guivars['player_num'] = StringVar() countSpinbox = Spinbox(playerNumFrame, from_=1, to=100, textvariable=guivars['player_num'], width=3) countLabel.pack(side=LEFT) countSpinbox.pack(side=LEFT, padx=2) playerNumFrame.pack(side=LEFT, anchor=N, padx=5, pady=(1,1)) multiworldFrame.pack(side=TOP, anchor=W, padx=5, pady=(1,1)) # build gui ############ widgets = {} for info in setting_infos: if info.gui_params: if info.gui_params['widget'] == 'Checkbutton': # determine the initial value of the checkbox default_value = 1 if info.gui_params['default'] == "checked" else 0 # create a variable to access the box's state guivars[info.name] = IntVar(value=default_value) # create the checkbox widgets[info.name] = Checkbutton(frames[info.gui_params['group']], text=info.gui_params['text'], variable=guivars[info.name], justify=LEFT, wraplength=200, command=show_settings) widgets[info.name].pack(expand=False, anchor=W) elif info.gui_params['widget'] == 'Combobox': # create the variable to store the user's decision guivars[info.name] = StringVar(value=info.gui_params['default']) # create the option menu widgets[info.name] = Frame(frames[info.gui_params['group']]) # dropdown = OptionMenu(widgets[info.name], guivars[info.name], *(info['options'])) if isinstance(info.gui_params['options'], list): info.gui_params['options'] = dict(zip(info.gui_params['options'], info.gui_params['options'])) dropdown = ttk.Combobox(widgets[info.name], textvariable=guivars[info.name], values=list(info.gui_params['options'].keys()), state='readonly', width=30) dropdown.bind("<<ComboboxSelected>>", show_settings) dropdown.pack(side=BOTTOM, anchor=W) # label the option if 'text' in info.gui_params: label = Label(widgets[info.name], text=info.gui_params['text']) label.pack(side=LEFT, anchor=W, padx=5) # pack the frame widgets[info.name].pack(expand=False, side=TOP, anchor=W, padx=3, pady=3) elif info.gui_params['widget'] == 'Scale': # create the variable to store the user's decision guivars[info.name] = IntVar(value=info.gui_params['default']) # create the option menu widgets[info.name] = Frame(frames[info.gui_params['group']]) # dropdown = OptionMenu(widgets[info.name], guivars[info.name], *(info['options'])) minval = 'min' in info.gui_params and info.gui_params['min'] or 0 maxval = 'max' in info.gui_params and info.gui_params['max'] or 100 stepval = 'step' in info.gui_params and info.gui_params['step'] or 1 scale = Scale(widgets[info.name], variable=guivars[info.name], from_=minval, to=maxval, tickinterval=stepval, resolution=stepval, showvalue=0, orient=HORIZONTAL, sliderlength=15, length=200, command=show_settings) scale.pack(side=BOTTOM, anchor=W) # label the option if 'text' in info.gui_params: label = Label(widgets[info.name], text=info.gui_params['text']) label.pack(side=LEFT, anchor=W, padx=5) # pack the frame widgets[info.name].pack(expand=False, side=TOP, anchor=W, padx=3, pady=3) elif info.gui_params['widget'] == 'Entry': # create the variable to store the user's decision guivars[info.name] = StringVar(value=info.gui_params['default']) # create the option menu widgets[info.name] = Frame(frames[info.gui_params['group']]) entry = Entry(widgets[info.name], textvariable=guivars[info.name], width=30) entry.pack(side=BOTTOM, anchor=W) # label the option if 'text' in info.gui_params: label = Label(widgets[info.name], text=info.gui_params['text']) label.pack(side=LEFT, anchor=W, padx=5) # pack the frame widgets[info.name].pack(expand=False, side=TOP, anchor=W, padx=3, pady=3) # pack the hierarchy frames['open'].pack( fill=BOTH, expand=True, anchor=N, side=LEFT, pady=(5,1) ) frames['logic'].pack( fill=BOTH, expand=True, anchor=N, side=LEFT, pady=(5,1) ) # Logic tab frames['rewards'].pack(fill=BOTH, expand=True, anchor=N, side=LEFT, pady=(5,1) ) frames['tricks'].pack( fill=BOTH, expand=True, anchor=N, side=LEFT, pady=(5,1) ) #Other Tab frames['convenience'].pack(fill=BOTH, expand=True, anchor=N, side=LEFT, pady=(5,1) ) frames['other'].pack( fill=BOTH, expand=True, anchor=N, side=LEFT, pady=(5,1) ) #Aesthetics tab frames['navicolor'].pack( fill=BOTH, expand=True, anchor=N, side=RIGHT, pady=(5,1) ) frames['tuniccolor'].pack(fill=BOTH, expand=True, anchor=W, side=TOP, pady=(5,1) ) frames['lowhp'].pack( fill=BOTH, expand=True, anchor=W, side=BOTTOM, pady=(5,1) ) notebook.pack(fill=BOTH, expand=True, padx=5, pady=5) # didn't refactor the rest, sorry # create the option menu settingsFrame.pack(fill=BOTH, anchor=W, padx=5, pady=(10,0)) def generateRom(): settings = guivars_to_settings(guivars) try: if settings.count is not None: orig_seed = settings.seed for i in range(settings.count): settings.update_seed(orig_seed + '-' + str(i)) main(settings) else: main(settings) except Exception as e: messagebox.showerror(title="Error while creating seed", message=str(e)) else: messagebox.showinfo(title="Success", message="Rom patched successfully") generateSeedFrame = Frame(mainWindow) generateButton = Button(generateSeedFrame, text='Generate Patched Rom', command=generateRom) seedLabel = Label(generateSeedFrame, text='Seed') guivars['seed'] = StringVar() seedEntry = Entry(generateSeedFrame, textvariable=guivars['seed']) seedLabel.pack(side=LEFT) seedEntry.pack(side=LEFT) generateButton.pack(side=LEFT, padx=(5, 0)) generateSeedFrame.pack(side=BOTTOM, anchor=W, padx=5, pady=10) if settings is not None: # load values from commandline args settings_to_guivars(settings, guivars) else: # try to load saved settings try: with open('settings.sav') as f: settings = Settings( json.load(f) ) settings.update_seed("") settings_to_guivars(settings, guivars) except: pass show_settings() mainWindow.mainloop() # save settings on close with open('settings.sav', 'w') as outfile: settings = guivars_to_settings(guivars) json.dump(settings.__dict__, outfile)
def guiMain(args=None): mainWindow = Tk() mainWindow.wm_title("OoT Randomizer %s" % ESVersion) set_icon(mainWindow) notebook = ttk.Notebook(mainWindow) randomizerWindow = ttk.Frame(notebook) adjustWindow = ttk.Frame(notebook) customWindow = ttk.Frame(notebook) notebook.add(randomizerWindow, text='Randomize') notebook.pack() # Shared Controls farBottomFrame = Frame(mainWindow) def open_output(): open_file(output_path('')) openOutputButton = Button(farBottomFrame, text='Open Output Directory', command=open_output) if os.path.exists(local_path('README.html')): def open_readme(): open_file(local_path('README.html')) openReadmeButton = Button(farBottomFrame, text='Open Documentation', command=open_readme) openReadmeButton.pack(side=LEFT) farBottomFrame.pack(side=BOTTOM, fill=X, padx=5, pady=5) # randomizer controls topFrame = Frame(randomizerWindow) rightHalfFrame = Frame(topFrame) checkBoxFrame = Frame(rightHalfFrame) createSpoilerVar = IntVar() createSpoilerCheckbutton = Checkbutton(checkBoxFrame, text="Create Spoiler Log", variable=createSpoilerVar) suppressRomVar = IntVar() suppressRomCheckbutton = Checkbutton(checkBoxFrame, text="Do not create patched Rom", variable=suppressRomVar) compressRomVar = IntVar() compressRomCheckbutton = Checkbutton(checkBoxFrame, text="Compress patched Rom", variable=compressRomVar) openForestVar = IntVar() openForestCheckbutton = Checkbutton(checkBoxFrame, text="Open Forest", variable=openForestVar) openDoorVar = IntVar() openDoorCheckbutton = Checkbutton(checkBoxFrame, text="Open Door of Time", variable=openDoorVar) dungeonItemsVar = IntVar() dungeonItemsCheckbutton = Checkbutton(checkBoxFrame, text="Place Dungeon Items (Compasses/Maps)", onvalue=0, offvalue=1, variable=dungeonItemsVar) beatableOnlyVar = IntVar() beatableOnlyCheckbutton = Checkbutton(checkBoxFrame, text="Only ensure seed is beatable, not all items must be reachable", variable=beatableOnlyVar) hintsVar = IntVar() hintsCheckbutton = Checkbutton(checkBoxFrame, text="Gossip Stone Hints with Stone of Agony", variable=hintsVar) createSpoilerCheckbutton.pack(expand=True, anchor=W) suppressRomCheckbutton.pack(expand=True, anchor=W) compressRomCheckbutton.pack(expand=True, anchor=W) openForestCheckbutton.pack(expand=True, anchor=W) openDoorCheckbutton.pack(expand=True, anchor=W) dungeonItemsCheckbutton.pack(expand=True, anchor=W) beatableOnlyCheckbutton.pack(expand=True, anchor=W) hintsCheckbutton.pack(expand=True, anchor=W) fileDialogFrame = Frame(rightHalfFrame) romDialogFrame = Frame(fileDialogFrame) baseRomLabel = Label(romDialogFrame, text='Base Rom') romVar = StringVar() romEntry = Entry(romDialogFrame, textvariable=romVar) def RomSelect(): rom = filedialog.askopenfilename(filetypes=[("Rom Files", (".z64", ".n64")), ("All Files", "*")]) romVar.set(rom) romSelectButton = Button(romDialogFrame, text='Select Rom', command=RomSelect) baseRomLabel.pack(side=LEFT) romEntry.pack(side=LEFT) romSelectButton.pack(side=LEFT) romDialogFrame.pack() checkBoxFrame.pack() fileDialogFrame.pack() drowDownFrame = Frame(topFrame) bridgeFrame = Frame(drowDownFrame) bridgeVar = StringVar() bridgeVar.set('medallions') bridgeOptionMenu = OptionMenu(bridgeFrame, bridgeVar, 'medallions', 'vanilla', 'dungeons', 'open') bridgeOptionMenu.pack(side=RIGHT) bridgeLabel = Label(bridgeFrame, text='Rainbow Bridge Requirement') bridgeLabel.pack(side=LEFT) bridgeFrame.pack(expand=True, anchor=E) bottomFrame = Frame(randomizerWindow) seedLabel = Label(bottomFrame, text='Seed #') seedVar = StringVar() seedEntry = Entry(bottomFrame, textvariable=seedVar) countLabel = Label(bottomFrame, text='Count') countVar = StringVar() countSpinbox = Spinbox(bottomFrame, from_=1, to=100, textvariable=countVar) def generateRom(): guiargs = Namespace guiargs.seed = int(seedVar.get()) if seedVar.get() else None guiargs.count = int(countVar.get()) if countVar.get() != '1' else None guiargs.bridge = bridgeVar.get() guiargs.create_spoiler = bool(createSpoilerVar.get()) guiargs.suppress_rom = bool(suppressRomVar.get()) guiargs.compress_rom = bool(compressRomVar.get()) guiargs.open_forest = bool(openForestVar.get()) guiargs.open_door_of_time = bool(openDoorVar.get()) guiargs.nodungeonitems = bool(dungeonItemsVar.get()) guiargs.beatableonly = bool(beatableOnlyVar.get()) guiargs.hints = bool(hintsVar.get()) guiargs.rom = romVar.get() try: if guiargs.count is not None: seed = guiargs.seed for _ in range(guiargs.count): main(seed=seed, args=guiargs) seed = random.randint(0, 999999999) else: main(seed=guiargs.seed, args=guiargs) except Exception as e: messagebox.showerror(title="Error while creating seed", message=str(e)) else: messagebox.showinfo(title="Success", message="Rom patched successfully") generateButton = Button(bottomFrame, text='Generate Patched Rom', command=generateRom) seedLabel.pack(side=LEFT) seedEntry.pack(side=LEFT) countLabel.pack(side=LEFT, padx=(5, 0)) countSpinbox.pack(side=LEFT) generateButton.pack(side=LEFT, padx=(5, 0)) openOutputButton.pack(side=RIGHT) drowDownFrame.pack(side=LEFT) rightHalfFrame.pack(side=RIGHT) topFrame.pack(side=TOP) bottomFrame.pack(side=BOTTOM) if args is not None: # load values from commandline args createSpoilerVar.set(int(args.create_spoiler)) suppressRomVar.set(int(args.suppress_rom)) compressRomVar.set(int(args.compress_rom)) if args.nodungeonitems: dungeonItemsVar.set(int(not args.nodungeonitems)) openForestVar.set(int(args.open_forest)) openDoorVar.set(int(args.open_door_of_time)) beatableOnlyVar.set(int(args.beatableonly)) hintsVar.set(int(args.hints)) if args.count: countVar.set(str(args.count)) if args.seed: seedVar.set(str(args.seed)) bridgeVar.set(args.bridge) romVar.set(args.rom) mainWindow.mainloop()
def __init__(self, parent, callback, adjuster=False): if is_bundled(): self.deploy_icons() self.parent = parent self.window = Toplevel(parent) self.window.geometry("800x650") self.sections = [] self.callback = callback self.adjuster = adjuster self.window.wm_title("TAKE ANY ONE YOU WANT") self.window['padx'] = 5 self.window['pady'] = 5 self.all_sprites = [] def open_official_sprite_listing(_evt): webbrowser.open("http://alttpr.com/sprite_preview") def open_unofficial_sprite_dir(_evt): open_file(self.unofficial_sprite_dir) def open_spritesomething_listing(_evt): webbrowser.open( "https://artheau.github.io/SpriteSomething/?mode=zelda3/link") official_frametitle = Frame(self.window) official_title_text = Label(official_frametitle, text="Official Sprites") official_title_link = Label(official_frametitle, text="(open)", fg="blue", cursor="hand2") official_title_text.pack(side=LEFT) official_title_link.pack(side=LEFT) official_title_link.bind("<Button-1>", open_official_sprite_listing) unofficial_frametitle = Frame(self.window) unofficial_title_text = Label(unofficial_frametitle, text="Unofficial Sprites") unofficial_title_link = Label(unofficial_frametitle, text="(open)", fg="blue", cursor="hand2") unofficial_title_text.pack(side=LEFT) unofficial_title_link.pack(side=LEFT) unofficial_title_link.bind("<Button-1>", open_unofficial_sprite_dir) spritesomething_title_link = Label(unofficial_frametitle, text="(SpriteSomething)", fg="blue", cursor="hand2") spritesomething_title_link.pack(side=LEFT) spritesomething_title_link.bind("<Button-1>", open_spritesomething_listing) self.icon_section( official_frametitle, self.official_sprite_dir + '/*', 'Official sprites not found. Click "Update official sprites" to download them.' ) self.icon_section( unofficial_frametitle, self.unofficial_sprite_dir + '/*', 'Put sprites in the unofficial sprites folder (see open link above) to have them appear here.' ) frame = Frame(self.window) frame.pack(side=BOTTOM, fill=X, pady=5) button = Button(frame, text="Browse for file...", command=self.browse_for_sprite) button.pack(side=RIGHT, padx=(5, 0)) button = Button(frame, text="Update official sprites", command=self.update_official_sprites) button.pack(side=RIGHT, padx=(5, 0)) button = Button(frame, text="Default Link sprite", command=self.use_default_link_sprite) button.pack(side=LEFT, padx=(0, 5)) button = Button(frame, text="Random sprite", command=self.use_random_sprite) button.pack(side=LEFT, padx=(0, 5)) if adjuster: button = Button(frame, text="Current sprite from rom", command=self.use_default_sprite) button.pack(side=LEFT, padx=(0, 5)) set_icon(self.window) self.window.focus()
def guiMain(settings=None): frames = {} mainWindow = Tk() mainWindow.wm_title("OoT Randomizer %s" % ESVersion) mainWindow.resizable(False, False) set_icon(mainWindow) notebook = ttk.Notebook(mainWindow) frames['rom_tab'] = ttk.Frame(notebook) frames['rules_tab'] = ttk.Frame(notebook) frames['logic_tab'] = ttk.Frame(notebook) frames['other_tab'] = ttk.Frame(notebook) frames['cosmetic_tab'] = ttk.Frame(notebook) frames['SFX_tab'] = ttk.Frame(notebook) frames['cosmetic_tab_left'] = Frame(frames['cosmetic_tab']) frames['cosmetic_tab_right'] = Frame(frames['cosmetic_tab']) notebook.add(frames['rom_tab'], text='ROM Options') notebook.add(frames['rules_tab'], text='Main Rules') notebook.add(frames['logic_tab'], text='Detailed Logic') notebook.add(frames['other_tab'], text='Other') notebook.add(frames['cosmetic_tab'], text='Cosmetic') notebook.add(frames['SFX_tab'], text='SFX') ####################### # Randomizer controls # ####################### # Hold the results of the user's decisions here guivars = {} widgets = {} presets = {} # Hierarchy ############ #Rules Tab frames['open'] = LabelFrame(frames['rules_tab'], text='Open', labelanchor=NW) frames['world'] = LabelFrame(frames['rules_tab'], text='World', labelanchor=NW) frames['shuffle'] = LabelFrame(frames['rules_tab'], text='Shuffle', labelanchor=NW) # Logic tab frames['checks'] = LabelFrame(frames['logic_tab'], text='Adult Trade Sequence', labelanchor=NW) frames['tricks'] = LabelFrame(frames['logic_tab'], text='Lens of Truth', labelanchor=NW) #Other Tab frames['convenience'] = LabelFrame(frames['other_tab'], text='Timesavers', labelanchor=NW) frames['other'] = LabelFrame(frames['other_tab'], text='Misc', labelanchor=NW) #Cosmetic tab frames['cosmetic'] = LabelFrame(frames['cosmetic_tab_left'], text='General', labelanchor=NW) frames['sword_trails']= LabelFrame(frames['cosmetic_tab_left'], text='Sword Trail Colors',labelanchor=NW) frames['ui_colors']= LabelFrame(frames['cosmetic_tab_left'], text='UI Colors', labelanchor=NW) frames['tunic_colors']= LabelFrame(frames['cosmetic_tab_right'], text='Tunic Colors', labelanchor=NW) frames['navi_colors']= LabelFrame(frames['cosmetic_tab_right'], text='Navi Colors', labelanchor=NW) frames['gauntlet_colors']= LabelFrame(frames['cosmetic_tab_right'], text='Gauntlet Colors', labelanchor=NW) #Cosmetic tab frames['sfx'] = LabelFrame(frames['SFX_tab'], text='General', labelanchor=NW) frames['menu_sfx'] = LabelFrame(frames['SFX_tab'], text='Menu', labelanchor=NW) frames['npc_sfx'] = LabelFrame(frames['SFX_tab'], text='NPC', labelanchor=NW) # Shared def toggle_widget(widget, enabled): widget_type = widget.winfo_class() if widget_type == 'Frame' or widget_type == 'TFrame' or widget_type == 'Labelframe': if widget_type == 'Labelframe': widget.configure(fg='Black'if enabled else 'Grey') for child in widget.winfo_children(): toggle_widget(child, enabled) else: if widget_type == 'TCombobox': widget.configure(state= 'readonly' if enabled else 'disabled') else: widget.configure(state= 'normal' if enabled else 'disabled') if widget_type == 'Scale': widget.configure(fg='Black'if enabled else 'Grey') def show_settings(*event): settings = guivars_to_settings(guivars) settings_string_var.set( settings.get_settings_string() ) # Update any dependencies for info in setting_infos: dep_met = settings.check_dependency(info.name) if info.name in widgets: toggle_widget(widgets[info.name], dep_met) if info.type == list: widgets[info.name].delete(0, END) widgets[info.name].insert(0, *guivars[info.name]) if info.type != list and info.name in guivars and guivars[info.name].get() == 'Custom Color': color = colorchooser.askcolor() if color == (None, None): color = ((0,0,0),'#000000') guivars[info.name].set('Custom (' + color[1] + ')') if info.type != list and info.name in guivars and guivars[info.name].get() == 'Custom Navi Color': innerColor = colorchooser.askcolor(title='Pick an Inner Core color.') if innerColor == (None, None): innerColor = ((0,0,0),'#000000') outerColor = colorchooser.askcolor(title='Pick an Outer Glow color.') if outerColor == (None, None): outerColor = ((0,0,0),'#000000') guivars[info.name].set('Custom (%s %s)' % (innerColor[1], outerColor[1])) update_generation_type() versionCheckFrame = Frame(frames['rom_tab']) versionCheckFrame.pack(side=BOTTOM, anchor=NW, fill=X) fileDialogFrame = Frame(frames['rom_tab']) romDialogFrame = Frame(fileDialogFrame) baseRomLabel = Label(romDialogFrame, text='Base ROM') guivars['rom'] = StringVar(value='') romEntry = Entry(romDialogFrame, textvariable=guivars['rom'], width=50) def RomSelect(): rom = filedialog.askopenfilename(filetypes=[("ROM Files", (".z64", ".n64")), ("All Files", "*")]) if rom != '': guivars['rom'].set(rom) romSelectButton = Button(romDialogFrame, text='Browse', command=RomSelect, width=10) baseRomLabel.pack(side=LEFT, padx=(34,0)) romEntry.pack(side=LEFT, padx=3) romSelectButton.pack(side=LEFT) romDialogFrame.pack() fileDialogFrame.pack(side=TOP, anchor=W, padx=5, pady=(5,1)) def output_dir_select(): rom = filedialog.askdirectory(initialdir = default_output_path(guivars['output_dir'].get())) if rom != '': guivars['output_dir'].set(rom) outputDialogFrame = Frame(frames['rom_tab']) outputDirLabel = Label(outputDialogFrame, text='Output Directory') guivars['output_dir'] = StringVar(value='') outputDirEntry = Entry(outputDialogFrame, textvariable=guivars['output_dir'], width=50) outputDirButton = Button(outputDialogFrame, text='Browse', command=output_dir_select, width=10) outputDirLabel.pack(side=LEFT, padx=(3,0)) outputDirEntry.pack(side=LEFT, padx=3) outputDirButton.pack(side=LEFT) outputDialogFrame.pack(side=TOP, anchor=W, pady=3) distFileDialogFrame = Frame(frames['rom_tab']) distFileLabel = Label(distFileDialogFrame, text='Distribution File') guivars['distribution_file'] = StringVar(value='') distFileEntry = Entry(distFileDialogFrame, textvariable=guivars['distribution_file'], width=50) def DistFileSelect(): distFile = filedialog.askopenfilename(filetypes=[("JSON Files", (".json")), ("All Files", "*")]) if distFile != '': guivars['distribution_file'].set(distFile) distFileSelectButton = Button(distFileDialogFrame, text='Browse', command=DistFileSelect, width=10) distFileLabel.pack(side=LEFT, padx=(9,0)) distFileEntry.pack(side=LEFT, padx=3) distFileSelectButton.pack(side=LEFT) distFileDialogFrame.pack(side=TOP, anchor=W, pady=3) countDialogFrame = Frame(frames['rom_tab']) countLabel = Label(countDialogFrame, text='Generation Count') guivars['count'] = StringVar() widgets['count'] = Spinbox(countDialogFrame, from_=1, to=100, textvariable=guivars['count'], width=3) def open_readme(): open_file('https://wiki.ootrandomizer.com/index.php?title=Main_Page') openReadmeButton = Button(countDialogFrame, text='Open Wiki Page', command=open_readme) openReadmeButton.pack(side=RIGHT, padx=5) def open_output(): open_file(default_output_path(guivars['output_dir'].get())) openOutputButton = Button(countDialogFrame, text='Open Output Directory', command=open_output) openOutputButton.pack(side=RIGHT, padx=5) countLabel.pack(side=LEFT) widgets['count'].pack(side=LEFT, padx=2) countDialogFrame.pack(side=TOP, anchor=W, padx=5, pady=(1,1)) # Build gui ############ for info in setting_infos: if 'group' in info.gui_params: if info.gui_params['widget'] == 'Checkbutton': # Determine the initial value of the checkbox default_value = 1 if info.choices[info.default] == 'checked' else 0 # Create a variable to access the box's state guivars[info.name] = IntVar(value=default_value) # Create the checkbox widgets[info.name] = Checkbutton(frames[info.gui_params['group']], text=info.gui_params['text'], variable=guivars[info.name], justify=LEFT, wraplength=220, command=show_settings) widgets[info.name].pack(expand=False, anchor=W) elif info.gui_params['widget'] == 'Combobox': # Create the variable to store the user's decision guivars[info.name] = StringVar(value=info.choices[info.default]) # Create the option menu widgets[info.name] = Frame(frames[info.gui_params['group']]) dropdown = ttk.Combobox(widgets[info.name], textvariable=guivars[info.name], values=list(map(lambda choice: info.choices[choice], info.choice_list)), state='readonly', width=36) dropdown.bind("<<ComboboxSelected>>", show_settings) dropdown.pack(side=BOTTOM, anchor=W) # Label the option if 'text' in info.gui_params: label = Label(widgets[info.name], text=info.gui_params['text']) label.pack(side=LEFT, anchor=W, padx=5) # Pack the frame widgets[info.name].pack(expand=False, side=TOP, anchor=W, padx=3, pady=3) elif info.gui_params['widget'] == 'Radiobutton': # Create the variable to store the user's decision guivars[info.name] = StringVar(value=info.choices[info.default]) # Create the option menu widgets[info.name] = LabelFrame(frames[info.gui_params['group']], text=info.gui_params.get('text', info.name), labelanchor=NW) # Setup orientation side = TOP anchor = W if "horizontal" in info.gui_params and info.gui_params["horizontal"]: side = LEFT anchor = N # Add the radio buttons for option in map(lambda choice: info.choices[choice], info.choice_list): radio_button = Radiobutton(widgets[info.name], text=option, value=option, variable=guivars[info.name], justify=LEFT, wraplength=220, indicatoron=False, command=show_settings) radio_button.pack(expand=True, side=side, anchor=anchor) # Pack the frame widgets[info.name].pack(expand=False, side=TOP, anchor=W, padx=3, pady=3) elif info.gui_params['widget'] == 'Scale': # Create the variable to store the user's decision guivars[info.name] = IntVar(value=info.choices[info.default]) # Create the option menu widgets[info.name] = Frame(frames[info.gui_params['group']]) minval = info.gui_params.get('min', 0) maxval = info.gui_params.get('max', 100) stepval = info.gui_params.get('step', 1) scale = Scale(widgets[info.name], variable=guivars[info.name], from_=minval, to=maxval, tickinterval=stepval, resolution=stepval, showvalue=0, orient=HORIZONTAL, sliderlength=15, length=235, command=show_settings) scale.pack(side=BOTTOM, anchor=W) # Label the option if 'text' in info.gui_params: label = Label(widgets[info.name], text=info.gui_params['text']) label.pack(side=LEFT, anchor=W, padx=5) # Pack the frame widgets[info.name].pack(expand=False, side=TOP, anchor=W, padx=3, pady=3) elif info.gui_params['widget'] == 'Entry': # Create the variable to store the user's decision guivars[info.name] = StringVar(value=info.default) # Create the option menu widgets[info.name] = Frame(frames[info.gui_params['group']]) if 'validate' in info.gui_params: entry = ValidatingEntry(widgets[info.name], command=show_settings, validate=info.gui_params['validate'], textvariable=guivars[info.name], width=35) else: entry = Entry(widgets[info.name], textvariable=guivars[info.name], width=36) entry.pack(side=BOTTOM, anchor=W) # Label the option if 'text' in info.gui_params: label = Label(widgets[info.name], text=info.gui_params['text']) label.pack(side=LEFT, anchor=W, padx=5) # Pack the frame widgets[info.name].pack(expand=False, side=TOP, anchor=W, padx=3, pady=3) elif info.gui_params['widget'] == 'SearchBox' or info.gui_params['widget'] == 'FilteredSearchBox': filtered = (info.gui_params['widget'] == 'FilteredSearchBox') search_frame = LabelFrame(frames[info.gui_params['group']], text=info.gui_params.get('text', info.name), labelanchor=NW) if filtered: filter_frame = Frame(search_frame) widgets[info.name + '_filterlabel'] = Label(filter_frame, text="Filter: ") widgets[info.name + '_filterlabel'].pack(side=LEFT, anchor=W) widgets[info.name + '_entry'] = SearchBox(search_frame, list(map(lambda choice: info.choices[choice], info.choice_list)), width=78) widgets[info.name + '_filter'] = SearchBoxFilterControl(filter_frame, widgets[info.name + '_entry'], info.gui_params['filterdata'], width=50) widgets[info.name + '_filter'].pack(expand=False, side=LEFT, anchor=W) filter_frame.pack(expand=False, side=TOP, anchor=W, padx=3, pady=3) widgets[info.name + '_entry'].pack(expand=False, side=TOP, anchor=W) else: widgets[info.name + '_entry'] = SearchBox(search_frame, list(map(lambda choice: info.choices[choice], info.choice_list)), width=78) widgets[info.name + '_entry'].pack(expand=False, side=TOP, anchor=W, padx=3, pady=3) list_frame = Frame(search_frame) scrollbar = Scrollbar(list_frame, orient=VERTICAL) widgets[info.name] = Listbox(list_frame, width=78, height=7, yscrollcommand=scrollbar.set) guivars[info.name] = list(info.default) scrollbar.config(command=widgets[info.name].yview) scrollbar.pack(side=RIGHT, fill=Y) widgets[info.name].pack(side=LEFT) list_frame.pack(expand=False, side=TOP, anchor=W, padx=3, pady=3) if 'entry_tooltip' in info.gui_params: ToolTips.register(widgets[info.name + '_entry'], info.gui_params['entry_tooltip']) if filtered: ToolTips.register(widgets[info.name + '_filter'], info.gui_params['entry_tooltip']) if 'list_tooltip' in info.gui_params: ToolTips.register(widgets[info.name], info.gui_params['list_tooltip']) def get_lambda(function, *args): return lambda: function(*args) def add_list_selected(name): new_location = widgets[name +'_entry'].get() if new_location in widgets[name +'_entry'].options and new_location not in widgets[name].get(0, END): widgets[name].insert(END, new_location) guivars[name].append(new_location) show_settings() def remove_list_selected(name): location = widgets[name].get(ACTIVE) widgets[name].delete(ACTIVE) guivars[name].remove(location) show_settings() def add_list_all(name): for new_location in widgets[name + '_entry'].options: if new_location not in widgets[name].get(0, END): widgets[name].insert(END, new_location) guivars[name].append(new_location) show_settings() def remove_list_all(name): items = list(widgets[name].get(0, END)) widgets[name].delete(0, END) guivars[name] = [] for item in (x for x in items if x not in widgets[name + '_entry'].options): widgets[name].insert(END, item) guivars[name].append(item) show_settings() def clear_list_all(name): widgets[name].delete(0, END) guivars[name] = [] show_settings() list_button_frame = Frame(search_frame) list_add = Button(list_button_frame, width=10, text='Add', command=get_lambda(add_list_selected, info.name)) list_add.pack(side=LEFT, anchor=N, padx=3, pady=3) list_remove = Button(list_button_frame, width=10, text='Remove', command=get_lambda(remove_list_selected, info.name)) list_remove.pack(side=LEFT, anchor=N, padx=3, pady=3) list_add = Button(list_button_frame, width=10, text='All', command=get_lambda(add_list_all, info.name)) list_add.pack(side=LEFT, anchor=N, padx=3, pady=3) list_remove = Button(list_button_frame, width=10, text='None', command=get_lambda(remove_list_all, info.name)) list_remove.pack(side=LEFT, anchor=N, padx=3, pady=3) if filtered: list_clear = Button(list_button_frame, width=10, text='Clear', command=get_lambda(clear_list_all, info.name)) list_clear.pack(side=LEFT, anchor=N, padx=3, pady=3) list_button_frame.pack(expand=False, side=TOP, padx=3, pady=3) # pack the frame search_frame.pack(expand=False, side=TOP, anchor=W, padx=3, pady=3) if 'tooltip' in info.gui_params: ToolTips.register(widgets[info.name], info.gui_params['tooltip']) # Pack the hierarchy frames['shuffle'].pack(fill=BOTH, expand=True, anchor=N, side=RIGHT, pady=(5,1)) frames['open'].pack( fill=BOTH, expand=True, anchor=W, side=TOP, pady=(5,1)) frames['world'].pack( fill=BOTH, expand=True, anchor=W, side=BOTTOM, pady=(5,1)) # Logic tab frames['checks'].pack(fill=BOTH, expand=True, anchor=N, side=LEFT, pady=(5,1)) frames['tricks'].pack(fill=BOTH, expand=True, anchor=N, side=LEFT, pady=(5,1)) # Other Tab frames['convenience'].pack(fill=BOTH, expand=True, anchor=N, side=LEFT, pady=(5,1)) frames['other'].pack( fill=BOTH, expand=True, anchor=N, side=LEFT, pady=(5,1)) # Cosmetics tab frames['cosmetic'].pack( fill=BOTH, expand=True, anchor=W, side=TOP) frames['cosmetic_tab_left'].pack( fill=BOTH, expand=True, anchor=W, side=LEFT) frames['cosmetic_tab_right'].pack(fill=BOTH, expand=True, anchor=W, side=RIGHT) # Cosmetics tab - Left Side frames['sword_trails'].pack( fill=BOTH, expand=True, anchor=W, side=TOP) frames['ui_colors'].pack( fill=BOTH, expand=True, anchor=W, side=BOTTOM) # Cosmetics tab - Right Side frames['tunic_colors'].pack(fill=BOTH, expand=True, anchor=N, side=TOP) frames['navi_colors'].pack( fill=BOTH, expand=True, anchor=W, side=TOP) frames['gauntlet_colors'].pack(fill=BOTH, expand=True, anchor=W, side=BOTTOM) #SFX tab frames['sfx'].pack( fill=BOTH, expand=True, anchor=N, side=LEFT, pady=(5,1)) frames['menu_sfx'].pack( fill=BOTH, expand=False, anchor=W, side=TOP, pady=(5,1)) frames['npc_sfx'].pack(fill=BOTH, expand=True, anchor=W, side=BOTTOM, pady=(5,1)) notebook.pack(fill=BOTH, expand=True, padx=5, pady=5) #Multi-World widgets['multiworld'] = LabelFrame(frames['rom_tab'], text='Multi-World Generation') countLabel = Label( widgets['multiworld'], wraplength=250, justify=LEFT, text='''This is used for co-op generations. \ Increasing Player Count will drastically \ increase the generation time. \ \nFor more information, see: \ ''' ) hyperLabel = Label(widgets['multiworld'], wraplength=250, justify=LEFT, text='https://github.com/TestRunnerSRL/\nbizhawk-co-op\n', fg='blue', cursor='hand2') hyperLabel.bind("<Button-1>", lambda event: webbrowser.open_new(r"https://github.com/TestRunnerSRL/bizhawk-co-op")) countLabel.pack(side=TOP, anchor=W, padx=5, pady=0) hyperLabel.pack(side=TOP, anchor=W, padx=5, pady=0) worldCountFrame = Frame(widgets['multiworld']) countLabel = Label(worldCountFrame, text='Player Count') guivars['world_count'] = StringVar() widgets['world_count'] = Spinbox(worldCountFrame, from_=1, to=255, textvariable=guivars['world_count'], width=3) guivars['world_count'].trace('w', show_settings) countLabel.pack(side=LEFT) widgets['world_count'].pack(side=LEFT, padx=2) worldCountFrame.pack(side=LEFT, anchor=N, padx=10, pady=(1,5)) playerNumFrame = Frame(widgets['multiworld']) countLabel = Label(playerNumFrame, text='Player ID') guivars['player_num'] = StringVar() widgets['player_num'] = Spinbox(playerNumFrame, from_=1, to=255, textvariable=guivars['player_num'], width=3) countLabel.pack(side=LEFT) widgets['player_num'].pack(side=LEFT, padx=2) ToolTips.register(widgets['player_num'], 'Generate for specific Player.') playerNumFrame.pack(side=LEFT, anchor=N, padx=10, pady=(1,5)) widgets['multiworld'].pack(side=LEFT, fill=BOTH, anchor=NW, padx=5, pady=5) # Settings Presets Functions def import_setting_preset(): if guivars['settings_preset'].get() == '[New Preset]': messagebox.showerror("Invalid Preset", "You must select an existing preset!") return # Get cosmetic settings old_settings = guivars_to_settings(guivars) new_settings = {setting.name: old_settings.__dict__[setting.name] for setting in filter(lambda s: not (s.shared and s.bitwidth > 0), setting_infos)} preset = presets[guivars['settings_preset'].get()] new_settings.update(preset) settings = Settings(new_settings) settings.seed = guivars['seed'].get() settings_to_guivars(settings, guivars) show_settings() def add_settings_preset(): preset_name = guivars['settings_preset'].get() if preset_name == '[New Preset]': preset_name = simpledialog.askstring("New Preset", "Enter a new preset name:") if not preset_name or preset_name in presets or preset_name == '[New Preset]': messagebox.showerror("Invalid Preset", "You must enter a new preset name!") return elif presets[preset_name].get('locked', False): messagebox.showerror("Invalid Preset", "You cannot modify a locked preset!") return else: if messagebox.askquestion("Overwrite Preset", 'Are you sure you want to overwrite the "%s" preset?' % preset_name) != 'yes': return settings = guivars_to_settings(guivars) preset = {setting.name: settings.__dict__[setting.name] for setting in filter(lambda s: s.shared and s.bitwidth > 0, setting_infos)} presets[preset_name] = preset guivars['settings_preset'].set(preset_name) update_preset_dropdown() save_presets() def remove_setting_preset(): preset_name = guivars['settings_preset'].get() if preset_name == '[New Preset]': messagebox.showerror("Invalid Preset", "You must select an existing preset!") return elif presets[preset_name].get('locked', False): messagebox.showerror("Invalid Preset", "You cannot modify a locked preset!") return confirm = messagebox.askquestion('Remove Setting Preset', 'Are you sure you want to remove the setting preset "%s"?' % preset_name) if confirm != 'yes': return del presets[preset_name] guivars['settings_preset'].set('[New Preset]') update_preset_dropdown() save_presets() def update_preset_dropdown(): widgets['settings_preset']['values'] = ['[New Preset]'] + list(presets.keys()) def save_presets(): presets_file = local_path('presets.sav') with open(presets_file, 'w') as outfile: preset_json = {name: preset for name,preset in presets.items() if not preset.get('locked')} json.dump(preset_json, outfile, indent=4) # Settings Presets widgets['settings_presets'] = LabelFrame(frames['rom_tab'], text='Settings Presets') countLabel = Label( widgets['settings_presets'], wraplength=250, justify=LEFT, text='''Presets are settings that can be saved\ and loaded from. Loading a preset\ will overwrite all settings that affect\ the seed.\ \n\ ''' ) countLabel.pack(side=TOP, anchor=W, padx=5, pady=0) selectPresetFrame = Frame(widgets['settings_presets']) guivars['settings_preset'] = StringVar(value='[New Preset]') widgets['settings_preset'] = ttk.Combobox(selectPresetFrame, textvariable=guivars['settings_preset'], values=['[New Preset]'], state='readonly', width=33) widgets['settings_preset'].pack(side=BOTTOM, anchor=W) ToolTips.register(widgets['settings_preset'], 'Select a setting preset to apply.') widgets['settings_preset'].pack(side=LEFT, padx=(5, 0)) selectPresetFrame.pack(side=TOP, anchor=W, padx=5, pady=(1,5)) buttonPresetFrame = Frame(widgets['settings_presets']) importPresetButton = Button(buttonPresetFrame, text='Load', width=9, command=import_setting_preset) addPresetButton = Button(buttonPresetFrame, text='Save', width=9, command=add_settings_preset) removePresetButton = Button(buttonPresetFrame, text='Remove', width=9, command=remove_setting_preset) importPresetButton.pack(side=LEFT, anchor=W, padx=2) addPresetButton.pack(side=LEFT, anchor=W, padx=2) removePresetButton.pack(side=LEFT, anchor=W, padx=2) buttonPresetFrame.pack(side=TOP, anchor=W, padx=5, pady=(1,5)) widgets['settings_presets'].pack(side=RIGHT, fill=BOTH, anchor=NW, padx=5, pady=5) # Create the generation menu def update_generation_type(event=None): settings = guivars_to_settings(guivars) if generation_notebook.tab(generation_notebook.select())['text'] == 'Generate From Seed': notebook.tab(1, state="normal") if guivars['logic_rules'].get() == 'Glitchless': notebook.tab(2, state="normal") else: notebook.tab(2, state="disabled") notebook.tab(3, state="normal") notebook.tab(4, state="normal") notebook.tab(5, state="normal") toggle_widget(widgets['world_count'], settings.check_dependency('world_count')) toggle_widget(widgets['create_spoiler'], settings.check_dependency('create_spoiler')) toggle_widget(widgets['count'], settings.check_dependency('count')) toggle_widget(widgets['settings_presets'], True) else: notebook.tab(1, state="disabled") notebook.tab(2, state="disabled") notebook.tab(3, state="disabled") if guivars['repatch_cosmetics'].get(): notebook.tab(4, state="normal") notebook.tab(5, state="normal") toggle_widget(widgets['create_cosmetics_log'], settings.check_dependency('create_cosmetics_log')) else: notebook.tab(4, state="disabled") notebook.tab(5, state="disabled") toggle_widget(widgets['create_cosmetics_log'], False) toggle_widget(widgets['world_count'], False) toggle_widget(widgets['create_spoiler'], False) toggle_widget(widgets['count'], False) toggle_widget(widgets['settings_presets'], False) generation_notebook = ttk.Notebook(mainWindow) frames['gen_from_seed'] = ttk.Frame(generation_notebook) frames['gen_from_file'] = ttk.Frame(generation_notebook) generation_notebook.add(frames['gen_from_seed'], text='Generate From Seed') generation_notebook.add(frames['gen_from_file'], text='Generate From File') generation_notebook.bind("<<NotebookTabChanged>>", show_settings) # From seed tab def import_settings(event=None): try: settings = guivars_to_settings(guivars) text = settings_string_var.get().upper() settings.seed = guivars['seed'].get() settings.update_with_settings_string(text) settings_to_guivars(settings, guivars) show_settings() except Exception as e: messagebox.showerror(title="Error", message="Invalid settings string") def copy_settings(event=None): mainWindow.clipboard_clear() new_clip = settings_string_var.get().upper() mainWindow.clipboard_append(new_clip) mainWindow.update() settingsFrame = Frame(frames['gen_from_seed']) settings_string_var = StringVar() widgets['setting_string'] = Entry(settingsFrame, textvariable=settings_string_var, width=44) label = Label(settingsFrame, text="Settings String", width=13, anchor=E) widgets['copy_settings'] = Button(settingsFrame, text='Copy', width=5, command=copy_settings) widgets['import_settings'] = Button(settingsFrame, text='Import', width=7, command=import_settings) label.pack(side=LEFT, anchor=W, padx=5) widgets['setting_string'].pack(side=LEFT, anchor=W) widgets['copy_settings'].pack(side=LEFT, anchor=W, padx=(5, 0)) widgets['import_settings'].pack(side=LEFT, anchor=W) settingsFrame.pack(fill=BOTH, anchor=W, padx=5, pady=(10,0)) def multiple_run(settings, window): orig_seed = settings.seed for i in range(settings.count): settings.update_seed(orig_seed + '-' + str(i)) window.update_title("Generating Seed %s...%d/%d" % (settings.seed, i+1, settings.count)) main(settings, window) def generateRom(): settings = guivars_to_settings(guivars) if settings.count: BackgroundTaskProgress(mainWindow, "Generating Seed %s..." % settings.seed, multiple_run, settings) else: BackgroundTaskProgress(mainWindow, "Generating Seed %s..." % settings.seed, main, settings) generateSeedFrame = Frame(frames['gen_from_seed']) seedLabel = Label(generateSeedFrame, text='Seed', width=13, anchor=E) generateButton = Button(generateSeedFrame, text='Generate!', width=14, command=generateRom) guivars['seed'] = StringVar() widgets['seed'] = Entry(generateSeedFrame, textvariable=guivars['seed'], width=44) seedLabel.pack(side=LEFT, padx=5) widgets['seed'].pack(side=LEFT) generateButton.pack(side=LEFT, padx=(5, 0)) generateSeedFrame.pack(side=BOTTOM, anchor=W, padx=5, pady=10) # From file tab patchDialogFrame = Frame(frames['gen_from_file']) patchFileLabel = Label(patchDialogFrame, text='Patch File') guivars['patch_file'] = StringVar(value='') patchEntry = Entry(patchDialogFrame, textvariable=guivars['patch_file'], width=52) def PatchSelect(): patch_file = filedialog.askopenfilename(filetypes=[("Patch File Archive", "*.zpfz *.zpf"), ("All Files", "*")]) if patch_file != '': guivars['patch_file'].set(patch_file) patchSelectButton = Button(patchDialogFrame, text='Select File', command=PatchSelect, width=14) patchFileLabel.pack(side=LEFT, padx=(5,0)) patchEntry.pack(side=LEFT, padx=3) patchSelectButton.pack(side=LEFT) patchDialogFrame.pack(side=TOP, anchor=W, padx=5, pady=(10,5)) def generateFromFile(): settings = guivars_to_settings(guivars) BackgroundTaskProgress(mainWindow, "Generating From File %s..." % os.path.basename(settings.patch_file), from_patch_file, settings) patchCosmeticsAndGenerateFrame = Frame(frames['gen_from_file']) guivars['repatch_cosmetics'] = IntVar() widgets['repatch_cosmetics'] = Checkbutton(patchCosmeticsAndGenerateFrame, text='Update Cosmetics', variable=guivars['repatch_cosmetics'], justify=LEFT, wraplength=220, command=show_settings) widgets['repatch_cosmetics'].pack(side=LEFT, padx=5, anchor=W) generateFileButton = Button(patchCosmeticsAndGenerateFrame, text='Generate!', width=14, command=generateFromFile) generateFileButton.pack(side=RIGHT, anchor=E) patchCosmeticsAndGenerateFrame.pack(side=BOTTOM, fill=BOTH, expand=True, pady=(0,10), padx=(0, 10)) generation_notebook.pack(fill=BOTH, expand=True, padx=5, pady=5) guivars['checked_version'] = StringVar() guivars['cosmetics_only'] = IntVar() if settings is not None: # Load values from commandline args settings_to_guivars(settings, guivars) else: # Try to load saved settings settingsFile = local_path('settings.sav') try: with open(settingsFile) as f: settings = Settings( json.load(f) ) except: settings = Settings({}) settings_to_guivars(settings, guivars) guivars['seed'].set("") presets = {} for file in [data_path('presets_default.json')] \ + [local_path(f) for f in os.listdir(local_path()) if f.startswith('presets_') and f.endswith('.sav')] \ + [local_path('presets.sav')]: try: with open(file) as f: presets_temp = json.load(f) if file != local_path('presets.sav'): for preset in presets_temp.values(): preset['locked'] = True presets.update(presets_temp) except: pass update_preset_dropdown() show_settings() def gui_check_version(): task = BackgroundTask(mainWindow, check_version, guivars['checked_version'].get()) while task.running: mainWindow.update() if task.status: versionCheckLabel = LabelFrame(versionCheckFrame, text="New Version Available!") versionCheckText = Label(versionCheckLabel, justify=LEFT, text=task.status[(task.status.find(' ')+1):]) versionCheckLink = Label(versionCheckLabel, justify=LEFT, text='Click here and download the current version.', fg='blue', cursor='hand2') versionCheckLink.bind("<Button-1>", lambda event: webbrowser.open_new(r"https://github.com/TestRunnerSRL/OoT-Randomizer/tree/Dev")) versionCheckText.pack(anchor=NW, padx=5, pady=0) versionCheckLink.pack(anchor=NW, padx=5, pady=0) versionCheckLabel.pack(anchor=NW, fill=X, expand="yes", padx=5, pady=5) mainWindow.after(1000, gui_check_version) mainWindow.mainloop() # Save settings on close settings_file = local_path('settings.sav') with open(settings_file, 'w') as outfile: settings = guivars_to_settings(guivars) del settings.__dict__["distribution"] del settings.__dict__["seed"] del settings.__dict__["numeric_seed"] del settings.__dict__["check_version"] if "locked" in settings.__dict__: del settings.__dict__["locked"] json.dump(settings.__dict__, outfile, indent=4) save_presets()
def guiMain(args=None): mainWindow = Tk() mainWindow.wm_title("OoT Randomizer %s" % ESVersion) set_icon(mainWindow) notebook = ttk.Notebook(mainWindow) randomizerWindow = ttk.Frame(notebook) adjustWindow = ttk.Frame(notebook) customWindow = ttk.Frame(notebook) notebook.add(randomizerWindow, text='Randomize') notebook.pack() # Shared Controls farBottomFrame = Frame(mainWindow) def open_output(): open_file(output_path('')) openOutputButton = Button(farBottomFrame, text='Open Output Directory', command=open_output) if os.path.exists(local_path('README.html')): def open_readme(): open_file(local_path('README.html')) openReadmeButton = Button(farBottomFrame, text='Open Documentation', command=open_readme) openReadmeButton.pack(side=LEFT) farBottomFrame.pack(side=BOTTOM, fill=X, padx=5, pady=5) # randomizer controls topFrame = Frame(randomizerWindow) rightHalfFrame = Frame(topFrame) checkBoxFrame = Frame(rightHalfFrame) createSpoilerVar = IntVar() createSpoilerCheckbutton = Checkbutton( checkBoxFrame, text="Create Spoiler Log (affects item layout)", variable=createSpoilerVar) suppressRomVar = IntVar() suppressRomCheckbutton = Checkbutton(checkBoxFrame, text="Do not create patched Rom", variable=suppressRomVar) compressRomVar = IntVar() compressRomCheckbutton = Checkbutton(checkBoxFrame, text="Compress patched Rom", variable=compressRomVar) openForestVar = IntVar() openForestCheckbutton = Checkbutton(checkBoxFrame, text="Open Forest", variable=openForestVar) openDoorVar = IntVar() openDoorCheckbutton = Checkbutton(checkBoxFrame, text="Open Door of Time", variable=openDoorVar) fastGanonVar = IntVar() fastGanonCheckbutton = Checkbutton(checkBoxFrame, text="Skip most of Ganon's Castle", variable=fastGanonVar) dungeonItemsVar = IntVar() dungeonItemsCheckbutton = Checkbutton( checkBoxFrame, text="Place Dungeon Items (Compasses/Maps)", onvalue=0, offvalue=1, variable=dungeonItemsVar) beatableOnlyVar = IntVar() beatableOnlyCheckbutton = Checkbutton( checkBoxFrame, text="Only ensure seed is beatable, not all items must be reachable", variable=beatableOnlyVar) hintsVar = IntVar() hintsCheckbutton = Checkbutton( checkBoxFrame, text="Gossip Stone Hints with Stone of Agony", variable=hintsVar) createSpoilerCheckbutton.pack(expand=True, anchor=W) suppressRomCheckbutton.pack(expand=True, anchor=W) compressRomCheckbutton.pack(expand=True, anchor=W) openForestCheckbutton.pack(expand=True, anchor=W) openDoorCheckbutton.pack(expand=True, anchor=W) fastGanonCheckbutton.pack(expand=True, anchor=W) dungeonItemsCheckbutton.pack(expand=True, anchor=W) beatableOnlyCheckbutton.pack(expand=True, anchor=W) hintsCheckbutton.pack(expand=True, anchor=W) fileDialogFrame = Frame(rightHalfFrame) romDialogFrame = Frame(fileDialogFrame) baseRomLabel = Label(romDialogFrame, text='Base Rom') romVar = StringVar() romEntry = Entry(romDialogFrame, textvariable=romVar) def RomSelect(): rom = filedialog.askopenfilename( filetypes=[("Rom Files", (".z64", ".n64")), ("All Files", "*")]) romVar.set(rom) romSelectButton = Button(romDialogFrame, text='Select Rom', command=RomSelect) baseRomLabel.pack(side=LEFT) romEntry.pack(side=LEFT) romSelectButton.pack(side=LEFT) romDialogFrame.pack() checkBoxFrame.pack() fileDialogFrame.pack() dropDownFrame = Frame(topFrame) bridgeFrame = Frame(dropDownFrame) bridgeVar = StringVar() bridgeVar.set('medallions') bridgeOptionMenu = OptionMenu(bridgeFrame, bridgeVar, 'medallions', 'vanilla', 'dungeons', 'open') bridgeOptionMenu.pack(side=RIGHT) bridgeLabel = Label(bridgeFrame, text='Rainbow Bridge Requirement') bridgeLabel.pack(side=LEFT) colorVars = [] colorVars.append(StringVar()) colorVars.append(StringVar()) colorVars.append(StringVar()) colorVars[0].set('Kokiri Green') colorVars[1].set('Goron Red') colorVars[2].set('Zora Blue') kokiriFrame = Frame(dropDownFrame) kokiriOptionMenu = OptionMenu(kokiriFrame, colorVars[0], 'Kokiri Green', 'Goron Red', 'Zora Blue', 'Black', 'White', 'Purple', 'Yellow', 'Orange', 'Pink', 'Gray', 'Brown', 'Gold', 'Silver', 'Beige', 'Teal', 'Royal Blue', 'Sonic Blue', 'Blood Red', 'Blood Orange', 'NES Green', 'Dark Green', 'Random', 'True Random') kokiriOptionMenu.pack(side=RIGHT) kokiriLabel = Label(kokiriFrame, text='Kokiri Tunic Color') kokiriLabel.pack(side=LEFT) goronFrame = Frame(dropDownFrame) goronOptionMenu = OptionMenu(goronFrame, colorVars[1], 'Kokiri Green', 'Goron Red', 'Zora Blue', 'Black', 'White', 'Purple', 'Yellow', 'Orange', 'Pink', 'Gray', 'Brown', 'Gold', 'Silver', 'Beige', 'Teal', 'Royal Blue', 'Sonic Blue', 'Blood Red', 'Blood Orange', 'NES Green', 'Dark Green', 'Random', 'True Random') goronOptionMenu.pack(side=RIGHT) goronLabel = Label(goronFrame, text='Goron Tunic Color') goronLabel.pack(side=LEFT) zoraFrame = Frame(dropDownFrame) zoraOptionMenu = OptionMenu(zoraFrame, colorVars[2], 'Kokiri Green', 'Goron Red', 'Zora Blue', 'Black', 'White', 'Purple', 'Yellow', 'Orange', 'Pink', 'Gray', 'Brown', 'Gold', 'Silver', 'Beige', 'Teal', 'Royal Blue', 'Sonic Blue', 'Blood Red', 'Blood Orange', 'NES Green', 'Dark Green', 'Random', 'True Random') zoraOptionMenu.pack(side=RIGHT) zoraLabel = Label(zoraFrame, text='Zora Tunic Color') zoraLabel.pack(side=LEFT) lowHealthSFXVar = StringVar() lowHealthSFXVar.set('Default') lowHealthSFXFrame = Frame(dropDownFrame) lowHealthSFXOptionMenu = OptionMenu(lowHealthSFXFrame, lowHealthSFXVar, 'Default', 'Softer Beep', 'Rupee', 'Timer', 'Tamborine', 'Recovery Heart', 'Carrot Refill', 'Navi - Hey!', 'Zelda - Gasp', 'Cluck', 'Mweep!', 'Random', 'None') lowHealthSFXOptionMenu.pack(side=RIGHT) lowHealthSFXLabel = Label(lowHealthSFXFrame, text='Low Health SFX') lowHealthSFXLabel.pack(side=LEFT) bridgeFrame.pack(expand=True, anchor=E) kokiriFrame.pack(expand=True, anchor=E) goronFrame.pack(expand=True, anchor=E) zoraFrame.pack(expand=True, anchor=E) lowHealthSFXFrame.pack(expand=True, anchor=E) bottomFrame = Frame(randomizerWindow) seedLabel = Label(bottomFrame, text='Seed #') seedVar = StringVar() seedEntry = Entry(bottomFrame, textvariable=seedVar) countLabel = Label(bottomFrame, text='Count') countVar = StringVar() countSpinbox = Spinbox(bottomFrame, from_=1, to=100, textvariable=countVar) def generateRom(): guiargs = Namespace guiargs.seed = int(seedVar.get()) if seedVar.get() else None guiargs.count = int(countVar.get()) if countVar.get() != '1' else None guiargs.bridge = bridgeVar.get() guiargs.kokiricolor = colorVars[0].get() guiargs.goroncolor = colorVars[1].get() guiargs.zoracolor = colorVars[2].get() guiargs.healthSFX = lowHealthSFXVar.get() guiargs.create_spoiler = bool(createSpoilerVar.get()) guiargs.suppress_rom = bool(suppressRomVar.get()) guiargs.compress_rom = bool(compressRomVar.get()) guiargs.open_forest = bool(openForestVar.get()) guiargs.open_door_of_time = bool(openDoorVar.get()) guiargs.fast_ganon = bool(fastGanonVar.get()) guiargs.nodungeonitems = bool(dungeonItemsVar.get()) guiargs.beatableonly = bool(beatableOnlyVar.get()) guiargs.hints = bool(hintsVar.get()) guiargs.rom = romVar.get() try: if guiargs.count is not None: seed = guiargs.seed for _ in range(guiargs.count): main(seed=seed, args=guiargs) seed = random.randint(0, 999999999) else: main(seed=guiargs.seed, args=guiargs) except Exception as e: messagebox.showerror(title="Error while creating seed", message=str(e)) else: messagebox.showinfo(title="Success", message="Rom patched successfully") generateButton = Button(bottomFrame, text='Generate Patched Rom', command=generateRom) seedLabel.pack(side=LEFT) seedEntry.pack(side=LEFT) countLabel.pack(side=LEFT, padx=(5, 0)) countSpinbox.pack(side=LEFT) generateButton.pack(side=LEFT, padx=(5, 0)) openOutputButton.pack(side=RIGHT) dropDownFrame.pack(side=LEFT) rightHalfFrame.pack(side=RIGHT) topFrame.pack(side=TOP) bottomFrame.pack(side=BOTTOM) if args is not None: # load values from commandline args createSpoilerVar.set(int(args.create_spoiler)) suppressRomVar.set(int(args.suppress_rom)) compressRomVar.set(int(args.compress_rom)) if args.nodungeonitems: dungeonItemsVar.set(int(not args.nodungeonitems)) openForestVar.set(int(args.open_forest)) openDoorVar.set(int(args.open_door_of_time)) fastGanonVar.set(int(args.fast_ganon)) beatableOnlyVar.set(int(args.beatableonly)) hintsVar.set(int(args.hints)) if args.count: countVar.set(str(args.count)) if args.seed: seedVar.set(str(args.seed)) bridgeVar.set(args.bridge) colorVars[0].set(args.kokiricolor) colorVars[1].set(args.goroncolor) colorVars[2].set(args.zoracolor) lowHealthSFXVar.set(args.healthSFX) romVar.set(args.rom) mainWindow.mainloop()
def guiMain(settings=None): frames = {} mainWindow = Tk() mainWindow.wm_title("OoT Randomizer %s" % ESVersion) mainWindow.resizable(False, False) set_icon(mainWindow) notebook = ttk.Notebook(mainWindow) frames['rom_tab'] = ttk.Frame(notebook) frames['rules_tab'] = ttk.Frame(notebook) frames['logic_tab'] = ttk.Frame(notebook) frames['other_tab'] = ttk.Frame(notebook) frames['aesthetic_tab'] = ttk.Frame(notebook) frames['aesthetic_tab_left'] = Frame(frames['aesthetic_tab']) frames['aesthetic_tab_right'] = Frame(frames['aesthetic_tab']) adjustWindow = ttk.Frame(notebook) customWindow = ttk.Frame(notebook) notebook.add(frames['rom_tab'], text='ROM Options') notebook.add(frames['rules_tab'], text='Main Rules') notebook.add(frames['logic_tab'], text='Detailed Logic') notebook.add(frames['other_tab'], text='Other') notebook.add(frames['aesthetic_tab'], text='Cosmetics') ####################### # randomizer controls # ####################### # hold the results of the user's decisions here guivars = {} # hierarchy ############ #Rules Tab frames['open'] = LabelFrame(frames['rules_tab'], text='Open', labelanchor=NW) frames['world'] = LabelFrame(frames['rules_tab'], text='World', labelanchor=NW) frames['logic'] = LabelFrame(frames['rules_tab'], text='Shuffle', labelanchor=NW) # Logic tab frames['rewards'] = LabelFrame(frames['logic_tab'], text='Remove Specific Locations', labelanchor=NW) frames['tricks'] = LabelFrame(frames['logic_tab'], text='Specific expected tricks', labelanchor=NW) #Other Tab frames['convenience'] = LabelFrame(frames['other_tab'], text='Speed Ups', labelanchor=NW) frames['other'] = LabelFrame(frames['other_tab'], text='Misc', labelanchor=NW) #Aesthetics tab frames['cosmetics'] = LabelFrame(frames['aesthetic_tab'], text='General', labelanchor=NW) frames['tuniccolor'] = LabelFrame(frames['aesthetic_tab_left'], text='Tunic Color', labelanchor=NW) frames['navicolor'] = LabelFrame(frames['aesthetic_tab_right'], text='Navi Color', labelanchor=NW) frames['lowhp'] = LabelFrame(frames['aesthetic_tab_left'], text='Low HP SFX', labelanchor=NW) frames['navihint'] = LabelFrame(frames['aesthetic_tab_right'], text='Navi SFX', labelanchor=NW) # shared settingsFrame = Frame(mainWindow) settings_string_var = StringVar() settingsEntry = Entry(settingsFrame, textvariable=settings_string_var, width=25) def show_settings(event=None): settings = guivars_to_settings(guivars) settings_string_var.set(settings.get_settings_string()) # Update any dependencies for info in setting_infos: if info.gui_params and 'dependency' in info.gui_params: dep_met = info.gui_params['dependency'](guivars) if widgets[info.name].winfo_class() == 'Frame': for child in widgets[info.name].winfo_children(): if child.winfo_class() == 'TCombobox': child.configure( state='readonly' if dep_met else 'disabled') else: child.configure( state='normal' if dep_met else 'disabled') if child.winfo_class() == 'Scale': child.configure(fg='Black' if dep_met else 'Grey') else: if widgets[info.name].winfo_class() == 'TCombobox': widgets[info.name].configure( state='readonly' if dep_met else 'disabled') else: widgets[info.name].configure( state='normal' if dep_met else 'disabled') if widgets[info.name].winfo_class() == 'Scale': widgets[info.name].configure( fg='Black' if dep_met else 'Grey') if info.name in guivars and guivars[ info.name].get() == 'Custom Color': color = askcolor() if color == (None, None): color = ((0, 0, 0), '#000000') guivars[info.name].set('Custom (' + color[1] + ')') def show_settings_special(event=None): if guivars['logic_tricks'].get(): widgets['logic_man_on_roof'].select() widgets['logic_child_deadhand'].select() widgets['logic_dc_jump'].select() widgets['logic_windmill_poh'].select() widgets['logic_crater_bean_poh_with_hovers'].select() widgets['logic_zora_with_cucco'].select() widgets['logic_fewer_tunic_requirements'].select() else: widgets['logic_man_on_roof'].deselect() widgets['logic_child_deadhand'].deselect() widgets['logic_dc_jump'].deselect() widgets['logic_windmill_poh'].deselect() widgets['logic_crater_bean_poh_with_hovers'].deselect() widgets['logic_zora_with_cucco'].deselect() widgets['logic_fewer_tunic_requirements'].deselect() settings = guivars_to_settings(guivars) settings_string_var.set(settings.get_settings_string()) def import_settings(event=None): try: settings = guivars_to_settings(guivars) text = settings_string_var.get().upper() settings.seed = guivars['seed'].get() settings.update_with_settings_string(text) settings_to_guivars(settings, guivars) except Exception as e: messagebox.showerror(title="Error", message="Invalid settings string") label = Label(settingsFrame, text="Settings String") importSettingsButton = Button(settingsFrame, text='Import Settings String', command=import_settings) label.pack(side=LEFT, anchor=W, padx=5) settingsEntry.pack(side=LEFT, anchor=W) importSettingsButton.pack(side=LEFT, anchor=W, padx=5) fileDialogFrame = Frame(frames['rom_tab']) romDialogFrame = Frame(fileDialogFrame) baseRomLabel = Label(romDialogFrame, text='Base ROM') guivars['rom'] = StringVar(value='ZOOTDEC.z64') romEntry = Entry(romDialogFrame, textvariable=guivars['rom'], width=40) def RomSelect(): rom = filedialog.askopenfilename( filetypes=[("ROM Files", (".z64", ".n64")), ("All Files", "*")]) if rom != '': guivars['rom'].set(rom) romSelectButton = Button(romDialogFrame, text='Select ROM', command=RomSelect, width=10) baseRomLabel.pack(side=LEFT, padx=(38, 0)) romEntry.pack(side=LEFT, padx=3) romSelectButton.pack(side=LEFT) romDialogFrame.pack() fileDialogFrame.pack(side=TOP, anchor=W, padx=5, pady=(5, 1)) def open_output(): open_file(output_path('')) def output_dir_select(): rom = filedialog.askdirectory( initialdir=default_output_path(guivars['output_dir'].get())) if rom != '': guivars['output_dir'].set(rom) outputDialogFrame = Frame(frames['rom_tab']) outputDirLabel = Label(outputDialogFrame, text='Output Directory') guivars['output_dir'] = StringVar(value='') outputDirEntry = Entry(outputDialogFrame, textvariable=guivars['output_dir'], width=40) outputDirButton = Button(outputDialogFrame, text='Select Dir', command=output_dir_select, width=10) outputDirLabel.pack(side=LEFT, padx=(3, 0)) outputDirEntry.pack(side=LEFT, padx=3) outputDirButton.pack(side=LEFT) outputDialogFrame.pack(side=TOP, anchor=W, padx=5, pady=(5, 1)) if os.path.exists(local_path('README.html')): def open_readme(): open_file(local_path('README.html')) openReadmeButton = Button(outputDialogFrame, text='Open Documentation', command=open_readme) openReadmeButton.pack(side=LEFT, padx=5) outputDialogFrame.pack(side=TOP, anchor=W, pady=3) countDialogFrame = Frame(frames['rom_tab']) countLabel = Label(countDialogFrame, text='Generation Count') guivars['count'] = StringVar() countSpinbox = Spinbox(countDialogFrame, from_=1, to=100, textvariable=guivars['count'], width=3) countLabel.pack(side=LEFT) countSpinbox.pack(side=LEFT, padx=2) countDialogFrame.pack(side=TOP, anchor=W, padx=5, pady=(1, 1)) # build gui ############ widgets = {} for info in setting_infos: if info.gui_params: if info.gui_params['widget'] == 'Checkbutton': # determine the initial value of the checkbox default_value = 1 if info.gui_params[ 'default'] == "checked" else 0 # create a variable to access the box's state guivars[info.name] = IntVar(value=default_value) # create the checkbox widgets[info.name] = Checkbutton( frames[info.gui_params['group']], text=info.gui_params['text'], variable=guivars[info.name], justify=LEFT, wraplength=190, command=show_settings) widgets[info.name].pack(expand=False, anchor=W) if info.gui_params['widget'] == 'SpecialCheckbutton': # determine the initial value of the checkbox default_value = 1 if info.gui_params[ 'default'] == "checked" else 0 # create a variable to access the box's state guivars[info.name] = IntVar(value=default_value) # create the checkbox widgets[info.name] = Checkbutton( frames[info.gui_params['group']], text=info.gui_params['text'], variable=guivars[info.name], justify=LEFT, wraplength=190, command=show_settings_special) widgets[info.name].pack(expand=False, anchor=W) elif info.gui_params['widget'] == 'Combobox': # create the variable to store the user's decision guivars[info.name] = StringVar( value=info.gui_params['default']) # create the option menu widgets[info.name] = Frame(frames[info.gui_params['group']]) # dropdown = OptionMenu(widgets[info.name], guivars[info.name], *(info['options'])) if isinstance(info.gui_params['options'], list): info.gui_params['options'] = dict( zip(info.gui_params['options'], info.gui_params['options'])) dropdown = ttk.Combobox(widgets[info.name], textvariable=guivars[info.name], values=list( info.gui_params['options'].keys()), state='readonly', width=30) dropdown.bind("<<ComboboxSelected>>", show_settings) dropdown.pack(side=BOTTOM, anchor=W) # label the option if 'text' in info.gui_params: label = Label(widgets[info.name], text=info.gui_params['text']) label.pack(side=LEFT, anchor=W, padx=5) # pack the frame widgets[info.name].pack(expand=False, side=TOP, anchor=W, padx=3, pady=3) elif info.gui_params['widget'] == 'Radiobutton': # create the variable to store the user's decision guivars[info.name] = StringVar( value=info.gui_params['default']) # create the option menu widgets[info.name] = LabelFrame( frames[info.gui_params['group']], text=info.gui_params['text'] if 'text' in info.gui_params else info["name"], labelanchor=NW) if isinstance(info.gui_params['options'], list): info.gui_params['options'] = dict( zip(info.gui_params['options'], info.gui_params['options'])) # setup orientation side = TOP anchor = W if "horizontal" in info.gui_params and info.gui_params[ "horizontal"]: side = LEFT anchor = N # add the radio buttons for option in info.gui_params["options"]: radio_button = Radiobutton(widgets[info.name], text=option, value=option, variable=guivars[info.name], justify=LEFT, wraplength=190, indicatoron=False, command=show_settings) radio_button.pack(expand=True, side=side, anchor=anchor) # pack the frame widgets[info.name].pack(expand=False, side=TOP, anchor=W, padx=3, pady=3) elif info.gui_params['widget'] == 'Scale': # create the variable to store the user's decision guivars[info.name] = IntVar(value=info.gui_params['default']) # create the option menu widgets[info.name] = Frame(frames[info.gui_params['group']]) # dropdown = OptionMenu(widgets[info.name], guivars[info.name], *(info['options'])) minval = 'min' in info.gui_params and info.gui_params[ 'min'] or 0 maxval = 'max' in info.gui_params and info.gui_params[ 'max'] or 100 stepval = 'step' in info.gui_params and info.gui_params[ 'step'] or 1 scale = Scale(widgets[info.name], variable=guivars[info.name], from_=minval, to=maxval, tickinterval=stepval, resolution=stepval, showvalue=0, orient=HORIZONTAL, sliderlength=15, length=200, command=show_settings) scale.pack(side=BOTTOM, anchor=W) # label the option if 'text' in info.gui_params: label = Label(widgets[info.name], text=info.gui_params['text']) label.pack(side=LEFT, anchor=W, padx=5) # pack the frame widgets[info.name].pack(expand=False, side=TOP, anchor=W, padx=3, pady=3) elif info.gui_params['widget'] == 'Entry': # create the variable to store the user's decision guivars[info.name] = StringVar( value=info.gui_params['default']) # create the option menu widgets[info.name] = Frame(frames[info.gui_params['group']]) entry = Entry(widgets[info.name], textvariable=guivars[info.name], width=30) entry.pack(side=BOTTOM, anchor=W) # label the option if 'text' in info.gui_params: label = Label(widgets[info.name], text=info.gui_params['text']) label.pack(side=LEFT, anchor=W, padx=5) # pack the frame widgets[info.name].pack(expand=False, side=TOP, anchor=W, padx=3, pady=3) if 'tooltip' in info.gui_params: ToolTips.register(widgets[info.name], info.gui_params['tooltip']) # pack the hierarchy frames['logic'].pack(fill=BOTH, expand=True, anchor=N, side=RIGHT, pady=(5, 1)) frames['open'].pack(fill=BOTH, expand=True, anchor=W, side=TOP, pady=(5, 1)) frames['world'].pack(fill=BOTH, expand=True, anchor=W, side=BOTTOM, pady=(5, 1)) # Logic tab frames['rewards'].pack(fill=BOTH, expand=True, anchor=N, side=LEFT, pady=(5, 1)) frames['tricks'].pack(fill=BOTH, expand=True, anchor=N, side=LEFT, pady=(5, 1)) #Other Tab frames['convenience'].pack(fill=BOTH, expand=True, anchor=N, side=LEFT, pady=(5, 1)) frames['other'].pack(fill=BOTH, expand=True, anchor=N, side=LEFT, pady=(5, 1)) #Aesthetics tab frames['cosmetics'].pack(fill=BOTH, expand=True, anchor=W, side=TOP) frames['aesthetic_tab_left'].pack(fill=BOTH, expand=True, anchor=W, side=LEFT) frames['aesthetic_tab_right'].pack(fill=BOTH, expand=True, anchor=W, side=RIGHT) #Aesthetics tab - Left Side frames['tuniccolor'].pack(fill=BOTH, expand=True, anchor=W, side=TOP, pady=(5, 1)) frames['lowhp'].pack(fill=BOTH, expand=True, anchor=W, side=TOP, pady=(5, 1)) #Aesthetics tab - Right Side frames['navicolor'].pack(fill=BOTH, expand=True, anchor=W, side=TOP, pady=(5, 1)) frames['navihint'].pack(fill=BOTH, expand=True, anchor=W, side=TOP, pady=(5, 1)) notebook.pack(fill=BOTH, expand=True, padx=5, pady=5) multiworldFrame = LabelFrame(frames['rom_tab'], text='Multi-World Generation') countLabel = Label( multiworldFrame, wraplength=350, justify=LEFT, text= 'This is used for co-op generations. Increasing Player Count will drastically increase the generation time. For more information see:' ) hyperLabel = Label(multiworldFrame, wraplength=350, justify=LEFT, text='https://github.com/TestRunnerSRL/bizhawk-co-op', fg='blue', cursor='hand2') hyperLabel.bind( "<Button-1>", lambda event: webbrowser.open_new( r"https://github.com/TestRunnerSRL/bizhawk-co-op")) countLabel.pack(side=TOP, anchor=W, padx=5, pady=0) hyperLabel.pack(side=TOP, anchor=W, padx=5, pady=0) worldCountFrame = Frame(multiworldFrame) countLabel = Label(worldCountFrame, text='Player Count') guivars['world_count'] = StringVar() countSpinbox = Spinbox(worldCountFrame, from_=1, to=100, textvariable=guivars['world_count'], width=3) countLabel.pack(side=LEFT) countSpinbox.pack(side=LEFT, padx=2) worldCountFrame.pack(side=LEFT, anchor=N, padx=10, pady=(1, 5)) playerNumFrame = Frame(multiworldFrame) countLabel = Label(playerNumFrame, text='Player ID') guivars['player_num'] = StringVar() countSpinbox = Spinbox(playerNumFrame, from_=1, to=100, textvariable=guivars['player_num'], width=3) countLabel.pack(side=LEFT) countSpinbox.pack(side=LEFT, padx=2) playerNumFrame.pack(side=LEFT, anchor=N, padx=10, pady=(1, 5)) multiworldFrame.pack(side=TOP, anchor=W, padx=5, pady=(1, 1)) # didn't refactor the rest, sorry # create the option menu settingsFrame.pack(fill=BOTH, anchor=W, padx=5, pady=(10, 0)) def multiple_run(settings, window): orig_seed = settings.seed for i in range(settings.count): settings.update_seed(orig_seed + '-' + str(i)) window.update_title("Generating Seed...%d/%d" % (i + 1, settings.count)) main(settings, window) def generateRom(): settings = guivars_to_settings(guivars) if settings.count is not None: BackgroundTaskProgress(mainWindow, "Generating Seed...", multiple_run, settings) else: BackgroundTaskProgress(mainWindow, "Generating Seed...", main, settings) generateSeedFrame = Frame(mainWindow) generateButton = Button(generateSeedFrame, text='Generate Patched Rom', command=generateRom) seedLabel = Label(generateSeedFrame, text='Seed') guivars['seed'] = StringVar() seedEntry = Entry(generateSeedFrame, textvariable=guivars['seed'], width=25) seedLabel.pack(side=LEFT, padx=(55, 5)) seedEntry.pack(side=LEFT) generateButton.pack(side=LEFT, padx=(5, 0)) generateSeedFrame.pack(side=BOTTOM, anchor=W, padx=5, pady=10) guivars['checked_version'] = StringVar() if settings is not None: # load values from commandline args settings_to_guivars(settings, guivars) else: # try to load saved settings try: settingsFile = os.path.join( os.path.dirname(os.path.abspath(__file__)), 'settings.sav') with open(settingsFile) as f: settings = Settings(json.load(f)) settings.update_seed("") settings_to_guivars(settings, guivars) except: pass show_settings() def gui_check_version(): task = BackgroundTask(mainWindow, check_version, guivars['checked_version'].get()) while task.running: mainWindow.update() if task.status: dialog = Dialog(mainWindow, title="Version Error", question=task.status, oktext='Don\'t show again', canceltext='OK') if dialog.result: guivars['checked_version'].set(ESVersion) mainWindow.after(1000, gui_check_version) mainWindow.mainloop() # save settings on close with open('settings.sav', 'w') as outfile: settings = guivars_to_settings(guivars) json.dump(settings.__dict__, outfile)
def adjustGUI(): from tkinter import Checkbutton, OptionMenu, Toplevel, LabelFrame, PhotoImage, Tk, LEFT, RIGHT, BOTTOM, TOP, \ StringVar, IntVar, Frame, Label, W, E, X, BOTH, Entry, Spinbox, Button, filedialog, messagebox, ttk from Gui import get_rom_options_frame, get_rom_frame from GuiUtils import set_icon from argparse import Namespace from Main import __version__ as MWVersion adjustWindow = Tk() adjustWindow.wm_title("Berserker's Multiworld %s LttP Adjuster" % MWVersion) set_icon(adjustWindow) rom_options_frame, rom_vars, set_sprite = get_rom_options_frame(adjustWindow) bottomFrame2 = Frame(adjustWindow) romFrame, romVar = get_rom_frame(adjustWindow) romDialogFrame = Frame(adjustWindow) baseRomLabel2 = Label(romDialogFrame, text='Rom to adjust') romVar2 = StringVar() romEntry2 = Entry(romDialogFrame, textvariable=romVar2) def RomSelect2(): rom = filedialog.askopenfilename(filetypes=[("Rom Files", (".sfc", ".smc", ".bmbp")), ("All Files", "*")]) romVar2.set(rom) romSelectButton2 = Button(romDialogFrame, text='Select Rom', command=RomSelect2) romDialogFrame.pack(side=TOP, expand=True, fill=X) baseRomLabel2.pack(side=LEFT) romEntry2.pack(side=LEFT, expand=True, fill=X) romSelectButton2.pack(side=LEFT) def adjustRom(): guiargs = Namespace() guiargs.heartbeep = rom_vars.heartbeepVar.get() guiargs.heartcolor = rom_vars.heartcolorVar.get() guiargs.fastmenu = rom_vars.fastMenuVar.get() guiargs.ow_palettes = rom_vars.owPalettesVar.get() guiargs.uw_palettes = rom_vars.uwPalettesVar.get() guiargs.hud_palettes = rom_vars.hudPalettesVar.get() guiargs.sword_palettes = rom_vars.swordPalettesVar.get() guiargs.shield_palettes = rom_vars.shieldPalettesVar.get() guiargs.quickswap = bool(rom_vars.quickSwapVar.get()) guiargs.disablemusic = bool(rom_vars.disableMusicVar.get()) guiargs.reduceflashing = bool(rom_vars.disableFlashingVar.get()) guiargs.rom = romVar2.get() guiargs.baserom = romVar.get() guiargs.sprite = rom_vars.sprite if rom_vars.sprite_pool: guiargs.world = AdjusterWorld(rom_vars.sprite_pool) try: guiargs, path = adjust(args=guiargs) if rom_vars.sprite_pool: guiargs.sprite_pool = rom_vars.sprite_pool delattr(guiargs, "world") except Exception as e: logging.exception(e) messagebox.showerror(title="Error while adjusting Rom", message=str(e)) else: messagebox.showinfo(title="Success", message=f"Rom patched successfully to {path}") from Utils import persistent_store from Rom import Sprite if isinstance(guiargs.sprite, Sprite): guiargs.sprite = guiargs.sprite.name persistent_store("adjuster", "last_settings_3", guiargs) adjustButton = Button(bottomFrame2, text='Adjust Rom', command=adjustRom) rom_options_frame.pack(side=TOP) adjustButton.pack(side=BOTTOM, padx=(5, 5)) bottomFrame2.pack(side=BOTTOM, pady=(5, 5)) adjustWindow.mainloop()