From ceceee68df545b810ff44a67b0889db0a65d01ee Mon Sep 17 00:00:00 2001 From: "Mike A. Trethewey" Date: Mon, 9 Mar 2020 19:10:40 -0700 Subject: [PATCH] Strip Enemizer Foundation for GUI translation --- resources/app/gui/lang/en.json | 271 +++++++++++++++++++++++++++++++ source/classes/BabelFish.py | 1 + source/classes/Empty.py | 3 + source/gui/loadcliargs.py | 55 ++++++- source/gui/randomize/enemizer.py | 31 ++-- source/gui/widgets.py | 6 +- 6 files changed, 342 insertions(+), 25 deletions(-) create mode 100644 resources/app/gui/lang/en.json create mode 100644 source/classes/Empty.py diff --git a/resources/app/gui/lang/en.json b/resources/app/gui/lang/en.json new file mode 100644 index 00000000..86786378 --- /dev/null +++ b/resources/app/gui/lang/en.json @@ -0,0 +1,271 @@ +{ + "gui": { + "adjust.nobgm": "Disable Music & MSU-1", + "adjust.quickswap": "L/R Quickswapping", + + "adjust.heartcolor": "Heart Color", + "adjust.heartcolor.red": "Red", + "adjust.heartcolor.blue": "Blue", + "adjust.heartcolor.green": "Green", + "adjust.heartcolor.yellow": "Yellow", + "adjust.heartcolor.random": "Random", + + "adjust.heartbeep": "Heart Beep sound rate", + "adjust.heartbeep.double": "Double", + "adjust.heartbeep.normal": "Normal", + "adjust.heartbeep.half": "Half", + "adjust.heartbeep.quarter": "Quarter", + "adjust.heartbeep.off": "Off", + + "adjust.menuspeed": "Menu Speed", + "adjust.menuspeed.instant": "Instant", + "adjust.menuspeed.quadruple": "Quadruple", + "adjust.menuspeed.triple": "Triple", + "adjust.menuspeed.double": "Double", + "adjust.menuspeed.normal": "Normal", + "adjust.menuspeed.half": "Half", + + "adjust.owpalettes": "Overworld Palettes", + "adjust.owpalettes.default": "Default", + "adjust.owpalettes.random": "Random", + "adjust.owpalettes.blackout": "Blackout", + + "adjust.uwpalettes": "Underworld Palettes", + "adjust.uwpalettes.default": "Default", + "adjust.uwpalettes.random": "Random", + "adjust.uwpalettes.blackout": "Blackout", + + "adjust.sprite": "Sprite:", + "adjust.sprite.unchanged": "(unchanged)", + + "adjust.rom": "Rom to adjust: ", + "adjust.rom.filetypes": "Rom Files", + "adjust.rom.opendialog": "Select Rom", + "adjust.rom.go": "Adjust Rom", + "adjust.rom.dialog.error": "Error while patching", + "adjust.rom.dialog.success": "Success", + "adjust.rom.dialog.success.message": "Rom patched successfully.", + + + "randomizer.dungeon.keysanity": "Shuffle: ", + "randomizer.dungeon.mapshuffle": "Maps", + "randomizer.dungeon.compassshuffle": "Compasses", + "randomizer.dungeon.smallkeyshuffle": "Small Keys", + "randomizer.dungeon.bigkeyshuffle": "Big Keys", + + "randomizer.dungeon.dungeondoorshuffle": "Dungeon Door Shuffle", + "randomizer.dungeon.dungeondoorshuffle.vanilla": "Vanilla", + "randomizer.dungeon.dungeondoorshuffle.basic": "Basic", + "randomizer.dungeon.dungeondoorshuffle.crossed": "Crossed", + + "randomizer.dungeon.experimental": "Enable Experimental Features", + + "randomizer.dungeon.dungeon_counters": "Dungeon Chest Counters", + "randomizer.dungeon.dungeon_counters.default": "Auto", + "randomizer.dungeon.dungeon_counters.off": "Off", + "randomizer.dungeon.dungeon_counters.on": "On", + "randomizer.dungeon.dungeon_counters.pickup": "On Compass Pickup", + + + "randomizer.enemizer.potshuffle": "Pot Shuffle", + + "randomizer.enemizer.enemyshuffle": "Enemy Shuffle", + "randomizer.enemizer.enemyshuffle.none": "Vanilla", + "randomizer.enemizer.enemyshuffle.shuffled": "Shuffled", + "randomizer.enemizer.enemyshuffle.chaos": "Chaos", + + "randomizer.enemizer.bossshuffle": "Boss Shuffle", + "randomizer.enemizer.bossshuffle.none": "Vanilla", + "randomizer.enemizer.bossshuffle.basic": "Basic", + "randomizer.enemizer.bossshuffle.shuffled": "Shuffled", + "randomizer.enemizer.bossshuffle.chaos": "Chaos", + + "randomizer.enemizer.enemydamage": "Enemy Damage", + "randomizer.enemizer.enemydamage.default": "Vanilla", + "randomizer.enemizer.enemydamage.shuffled": "Shuffled", + "randomizer.enemizer.enemydamage.choas": "Chaos", + + "randomizer.enemizer.enemyhealth": "Enemy Health", + "randomizer.enemizer.enemyhealth.default": "Vanilla", + "randomizer.enemizer.enemyhealth.easy": "Easy", + "randomizer.enemizer.enemyhealth.normal": "Normal", + "randomizer.enemizer.enemyhealth.hard": "Hard", + "randomizer.enemizer.enemyhealth.expert": "Expert", + + "randomizer.enemizer.enemizercli": "EnemizerCLI path: ", + "randomizer.enemizer.enemizercli.online": "(get online)", + + + "randomizer.entrance.openpyramid": "Pre-open Pyramid Hole", + "randomizer.entrance.shuffleganon": "Include Ganon's Tower and Pyramid Hole in shuffle pool", + + "randomizer.entrance.entranceshuffle": "Entrance Shuffle", + "randomizer.entrance.entranceshuffle.vanilla": "Vanilla", + "randomizer.entrance.entranceshuffle.simple": "Simple", + "randomizer.entrance.entranceshuffle.restricted": "Restricted", + "randomizer.entrance.entranceshuffle.full": "Full", + "randomizer.entrance.entranceshuffle.crossed": "Crossed", + "randomizer.entrance.entranceshuffle.insanity": "Insanity", + "randomizer.entrance.entranceshuffle.restricted_legacy": "Restricted (Legacy)", + "randomizer.entrance.entranceshuffle.full_legacy": "Full (Legacy)", + "randomizer.entrance.entranceshuffle.madness_legacy": "Madness (Legacy)", + "randomizer.entrance.entranceshuffle.insanity_legacy": "Insanity (Legacy)", + "randomizer.entrance.entranceshuffle.dungeonsfull": "Dungeons + Full", + "randomizer.entrance.entranceshuffle.dungeonssimple": "Dungeons + Simple", + + + "randomizer.gameoptions.hints": "Include Helpful Hints", + "randomizer.gameoptions.nobgm": "Disable Music & MSU-1", + "randomizer.gameoptions.quickswap": "L/R Quickswapping", + + "randomizer.gameoptions.heartcolor": "Heart Color", + "randomizer.gameoptions.heartcolor.red": "Red", + "randomizer.gameoptions.heartcolor.blue": "Blue", + "randomizer.gameoptions.heartcolor.green": "Green", + "randomizer.gameoptions.heartcolor.yellow": "Yellow", + "randomizer.gameoptions.heartcolor.random": "Random", + + "randomizer.gameoptions.heartbeep": "Heart Beep sound rate", + "randomizer.gameoptions.heartbeep.double": "Double", + "randomizer.gameoptions.heartbeep.normal": "Normal", + "randomizer.gameoptions.heartbeep.half": "Half", + "randomizer.gameoptions.heartbeep.quarter": "Quarter", + "randomizer.gameoptions.heartbeep.off": "Off", + + "randomizer.gameoptions.menuspeed": "Menu Speed", + "randomizer.gameoptions.menuspeed.instant": "Instant", + "randomizer.gameoptions.menuspeed.quadruple": "Quadruple", + "randomizer.gameoptions.menuspeed.triple": "Triple", + "randomizer.gameoptions.menuspeed.double": "Double", + "randomizer.gameoptions.menuspeed.normal": "Normal", + "randomizer.gameoptions.menuspeed.half": "Half", + + "randomizer.gameoptions.owpalettes": "Overworld Palettes", + "randomizer.gameoptions.owpalettes.default": "Default", + "randomizer.gameoptions.owpalettes.random": "Random", + "randomizer.gameoptions.owpalettes.blackout": "Blackout", + + "randomizer.gameoptions.uwpalettes": "Underworld Palettes", + "randomizer.gameoptions.uwpalettes.default": "Default", + "randomizer.gameoptions.uwpalettes.random": "Random", + "randomizer.gameoptions.uwpalettes.blackout": "Blackout", + + "randomizer.gameoptions.sprite": "Sprite:", + "randomizer.gameoptions.sprite.unchanged": "(unchanged)", + + + "randomizer.generation.spoiler": "Create Spoiler Log", + "randomizer.generation.suppressrom": "Do not create patched ROM", + "randomizer.generation.usestartinventory": "Use starting inventory", + "randomizer.generation.usecustompool": "Use custom item pool", + + "randomizer.generation.saveonexit": "Save Settings on Exit", + "randomizer.generation.saveonexit.ask": "Ask Me", + "randomizer.generation.saveonexit.always": "Always", + "randomizer.generation.saveonexit.never": "Never", + + "randomizer.generation.rom": "Base Rom: ", + "randomizer.generation.rom.filetypes": "Rom Files", + "randomizer.generation.rom.opendialog": "Select Rom", + + + "randomizer.item.retro": "Retro mode (universal keys)", + + "randomizer.item.worldstate": "World State", + "randomizer.item.worldstate.standard": "Standard", + "randomizer.item.worldstate.open": "Open", + "randomizer.item.worldstate.inverted": "Inverted", + "randomizer.item.worldstate.retro": "Retro", + + "randomizer.item.logiclevel": "Logic Level", + "randomizer.item.logiclevel.noglitches": "No Glitches", + "randomizer.item.logiclevel.minorglitches": "Minor Glitches", + "randomizer.item.logiclevel.nologic": "No Logic", + + "randomizer.item.goal": "Goal", + "randomizer.item.goal.ganon": "Defeat Ganon", + "randomizer.item.goal.pedestal": "Master Sword Pedestal", + "randomizer.item.goal.dungeons": "All Dungeons", + "randomizer.item.goal.triforcehunt": "Triforce Hunt", + "randomizer.item.goal.crystals": "Crystals", + + "randomizer.item.crystals_gt": "Crystals to open GT", + "randomizer.item.crystals_gt.0": "0", + "randomizer.item.crystals_gt.1": "1", + "randomizer.item.crystals_gt.2": "2", + "randomizer.item.crystals_gt.3": "3", + "randomizer.item.crystals_gt.4": "4", + "randomizer.item.crystals_gt.5": "5", + "randomizer.item.crystals_gt.6": "6", + "randomizer.item.crystals_gt.7": "7", + "randomizer.item.crystals_gt.random": "Random", + + "randomizer.item.crystals_ganon": "Crystals to harm Ganon", + "randomizer.item.crystals_ganon.0": "0", + "randomizer.item.crystals_ganon.1": "1", + "randomizer.item.crystals_ganon.2": "2", + "randomizer.item.crystals_ganon.3": "3", + "randomizer.item.crystals_ganon.4": "4", + "randomizer.item.crystals_ganon.5": "5", + "randomizer.item.crystals_ganon.6": "6", + "randomizer.item.crystals_ganon.7": "7", + "randomizer.item.crystals_ganon.random": "Random", + + "randomizer.item.weapons": "Weapons", + "randomizer.item.weapons.random": "Randomized", + "randomizer.item.weapons.assured": "Assured", + "randomizer.item.weapons.swordless": "Swordless", + "randomizer.item.weapons.vanilla": "Vanilla", + + "randomizer.item.itempool": "Item Pool", + "randomizer.item.itempool.normal": "Normal", + "randomizer.item.itempool.hard": "Hard", + "randomizer.item.itempool.expert": "Expert", + + "randomizer.item.itemfunction": "Item Functionality", + "randomizer.item.itemfunction.normal": "Normal", + "randomizer.item.itemfunction.hard": "Hard", + "randomizer.item.itemfunction.expert": "Expert", + + "randomizer.item.timer": "Timer Setting", + "randomizer.item.timer.none": "No Timer", + "randomizer.item.timer.display": "Stopwatch", + "randomizer.item.timer.timed": "Timed", + "randomizer.item.timer.timed-ohko": "Timed OHKO", + "randomizer.item.timer.ohko": "OHKO", + "randomizer.item.timer.timed-countdown": "Timed Countdown", + + "randomizer.item.progressives": "Progressive Items", + "randomizer.item.progressives.on": "On", + "randomizer.item.progressives.off": "Off", + "randomizer.item.progressives.random": "Random", + + "randomizer.item.accessibility": "Accessibility", + "randomizer.item.accessibility.items": "100% Inventory", + "randomizer.item.accessibility.locations": "100% Locations", + "randomizer.item.accessibility.none": "Beatable", + + "randomizer.item.sortingalgo": "Item Sorting", + "randomizer.item.sortingalgo.freshness": "Freshness", + "randomizer.item.sortingalgo.flood": "Flood", + "randomizer.item.sortingalgo.vt21": "VT8.21", + "randomizer.item.sortingalgo.vt22": "VT8.22", + "randomizer.item.sortingalgo.vt25": "VT8.25", + "randomizer.item.sortingalgo.vt26": "VT8.26", + "randomizer.item.sortingalgo.balanced": "Balanced", + + + "randomizer.multiworld.worlds": "Worlds", + "randomizer.multiworld.names": "Player names", + + + "bottom.seed": "Seed #", + "bottom.generationcount": "Count", + "bottom.go": "Generate Patched Rom", + "bottom.dialog.error": "Error while creating seed", + "bottom.dialog.success": "Success", + "bottom.dialog.success.message": "Rom created successfully.", + "bottom.outputdir": "Open Output Directory", + "bottom.docs": "Open Documentation" + } +} diff --git a/source/classes/BabelFish.py b/source/classes/BabelFish.py index 4a2897d0..81d24acc 100644 --- a/source/classes/BabelFish.py +++ b/source/classes/BabelFish.py @@ -13,6 +13,7 @@ class BabelFish(): self.lang_defns = {} #collect translations self.add_translation_file() #start with default translation file self.add_translation_file(["resources","app","cli"]) #add help translation file + self.add_translation_file(["resources","app","gui"]) #add gui label translation file self.add_translation_file(["resources","user","meta"]) #add user translation file def add_translation_file(self,subpath=["resources","app","meta"]): diff --git a/source/classes/Empty.py b/source/classes/Empty.py new file mode 100644 index 00000000..a22a92d1 --- /dev/null +++ b/source/classes/Empty.py @@ -0,0 +1,3 @@ +# Need a dummy class +class Empty(): + pass diff --git a/source/gui/loadcliargs.py b/source/gui/loadcliargs.py index b807b599..8e7be63d 100644 --- a/source/gui/loadcliargs.py +++ b/source/gui/loadcliargs.py @@ -2,10 +2,13 @@ from source.classes.SpriteSelector import SpriteSelector as spriteSelector from source.gui.randomize.gameoptions import set_sprite from Rom import Sprite, get_sprite_from_name import source.classes.constants as CONST +from source.classes.BabelFish import BabelFish +from source.classes.Empty import Empty # Load args/settings for most tabs def loadcliargs(gui, args, settings=None): if args is not None: + fish = BabelFish() # for k, v in vars(args).items(): # if type(v) is dict: # setattr(args, k, v[1]) # only get values for player 1 for now @@ -23,6 +26,13 @@ def loadcliargs(gui, args, settings=None): for widget in options[mainpage][subpage]: # Get the value and set it arg = options[mainpage][subpage][widget] + label = fish.translate("gui","gui",mainpage + '.' + subpage + '.' + widget) + if hasattr(gui.pages[mainpage].pages[subpage].widgets[widget],"type"): + type = gui.pages[mainpage].pages[subpage].widgets[widget].type + if type == "checkbox": + gui.pages[mainpage].pages[subpage].widgets[widget].checkbox.configure(text=label) + elif type == "selectbox": + gui.pages[mainpage].pages[subpage].widgets[widget].label.configure(text=label) gui.pages[mainpage].pages[subpage].widgets[widget].storageVar.set(args[arg]) # If we're on the Game Options page and it's not about Hints if subpage == "gameoptions" and not widget == "hints": @@ -30,27 +40,56 @@ def loadcliargs(gui, args, settings=None): # Check if we've got the widget in Adjust settings hasSettings = settings is not None hasWidget = ("adjust." + widget) in settings if hasSettings else None + label = fish.translate("gui","gui","adjust." + widget) + if ("adjust." + widget) in label: + label = fish.translate("gui","gui","randomizer.gameoptions." + widget) + if hasattr(gui.pages["adjust"].content.widgets[widget],"type"): + type = gui.pages["adjust"].content.widgets[widget].type + if type == "checkbox": + gui.pages["adjust"].content.widgets[widget].checkbox.configure(text=label) + elif type == "selectbox": + gui.pages["adjust"].content.widgets[widget].label.configure(text=label) if hasWidget is None: # If we've got a Game Options val and we don't have an Adjust val, use the Game Options val gui.pages["adjust"].content.widgets[widget].storageVar.set(args[arg]) # Get EnemizerCLI setting - gui.pages["randomizer"].pages["enemizer"].enemizerCLIpathVar.set(args["enemizercli"]) + mainpage = "randomizer" + subpage = "enemizer" + widget = "enemizercli" + setting = "enemizercli" + gui.pages[mainpage].pages[subpage].widgets[widget].storageVar.set(args[setting]) + label = fish.translate("gui","gui",mainpage + '.' + subpage + '.' + widget) + gui.pages[mainpage].pages[subpage].widgets[widget].pieces["frame"].label.configure(text=label) + label = fish.translate("gui","gui",mainpage + '.' + subpage + '.' + widget + ".online") + gui.pages[mainpage].pages[subpage].widgets[widget].pieces["online"].label.configure(text=label) # Get baserom path - gui.pages["randomizer"].pages["generation"].romVar.set(args["rom"]) + mainpage = "randomizer" + subpage = "generation" + setting = "rom" + gui.pages[mainpage].pages[subpage].romVar.set(args[setting]) # Get Multiworld Worlds count - if args["multi"]: - gui.pages["randomizer"].pages["multiworld"].widgets["worlds"].storageVar.set(str(args["multi"])) + mainpage = "randomizer" + subpage = "multiworld" + widget = "worlds" + setting = "multi" + if args[setting]: + gui.pages[mainpage].pages[subpage].widgets[widget].storageVar.set(str(args[setting])) # Get Seed ID - if args["seed"]: - gui.frames["bottom"].seedVar.set(str(args["seed"])) + mainpage = "bottom" + setting = "seed" + if args[setting]: + gui.frames[mainpage].seedVar.set(str(args[setting])) # Get number of generations to run - if args["count"]: - gui.frames["bottom"].widgets["generationcount"].storageVar.set(str(args["count"])) + mainpage = "bottom" + widget = "generationcount" + setting = "count" + if args[setting]: + gui.frames[mainpage].widgets[widget].storageVar.set(str(args[setting])) # Get output path gui.outputPath.set(args["outputpath"]) diff --git a/source/gui/randomize/enemizer.py b/source/gui/randomize/enemizer.py index 8c92bd48..dd16bbaa 100644 --- a/source/gui/randomize/enemizer.py +++ b/source/gui/randomize/enemizer.py @@ -3,6 +3,7 @@ import source.gui.widgets as widgets import json import os import webbrowser +from source.classes.Empty import Empty def enemizer_page(parent,settings): def open_enemizer_download(_evt): @@ -46,22 +47,26 @@ def enemizer_page(parent,settings): ## Enemizer CLI Path # This one's more-complicated, build it and stuff it - enemizerPathFrame = Frame(self.frames["bottomEnemizerFrame"]) - enemizerCLIlabel = Label(enemizerPathFrame, text="EnemizerCLI path: ") - enemizerCLIlabel.pack(side=LEFT) - enemizerURL = Label(enemizerPathFrame, text="(get online)", fg="blue", cursor="hand2") - enemizerURL.pack(side=LEFT) - enemizerURL.bind("", open_enemizer_download) - self.enemizerCLIpathVar = StringVar(value=settings["enemizercli"]) - enemizerCLIpathEntry = Entry(enemizerPathFrame, textvariable=self.enemizerCLIpathVar) - enemizerCLIpathEntry.pack(side=LEFT, fill=X, expand=True) + widget = "enemizercli" + self.widgets[widget] = Empty() + self.widgets[widget].pieces = {} + self.widgets[widget].pieces["frame"] = Frame(self.frames["bottomEnemizerFrame"]) + self.widgets[widget].pieces["frame"].label = Label(self.widgets[widget].pieces["frame"], text="EnemizerCLI path: ") + self.widgets[widget].pieces["frame"].label.pack(side=LEFT) + self.widgets[widget].pieces["online"] = Empty() + self.widgets[widget].pieces["online"].label = Label(self.widgets[widget].pieces["frame"], text="(get online)", fg="blue", cursor="hand2") + self.widgets[widget].pieces["online"].label.pack(side=LEFT) + self.widgets[widget].pieces["online"].label.bind("", open_enemizer_download) + self.widgets[widget].storageVar = StringVar(value=settings["enemizercli"]) + self.widgets[widget].pieces["textbox"] = Entry(self.widgets[widget].pieces["frame"], textvariable=self.widgets[widget].storageVar) + self.widgets[widget].pieces["textbox"].pack(side=LEFT, fill=X, expand=True) def EnemizerSelectPath(): path = filedialog.askopenfilename(filetypes=[("EnemizerCLI executable", "*EnemizerCLI*")], initialdir=os.path.join(".")) if path: - self.enemizerCLIpathVar.set(path) + self.widgets[widget].storageVar.set(path) settings["enemizercli"] = path - enemizerCLIbrowseButton = Button(enemizerPathFrame, text='...', command=EnemizerSelectPath) - enemizerCLIbrowseButton.pack(side=LEFT) - enemizerPathFrame.pack(fill=X) + self.widgets[widget].pieces["opendialog"] = Button(self.widgets[widget].pieces["frame"], text='...', command=EnemizerSelectPath) + self.widgets[widget].pieces["opendialog"].pack(side=LEFT) + self.widgets[widget].pieces["frame"].pack(fill=X) return self,settings diff --git a/source/gui/widgets.py b/source/gui/widgets.py index 95e7b1af..eed19272 100644 --- a/source/gui/widgets.py +++ b/source/gui/widgets.py @@ -1,8 +1,5 @@ from tkinter import Checkbutton, Entry, Frame, IntVar, Label, OptionMenu, Spinbox, StringVar, RIGHT, X - -# Need a dummy class -class Empty(): - pass +from source.classes.Empty import Empty # Override Spinbox to include mousewheel support for changing value class mySpinbox(Spinbox): @@ -144,6 +141,7 @@ def make_widget_from_dict(self, defn, parent): managerAttrs = defn["managerAttrs"] if "managerAttrs" in defn else None options = defn["options"] if "options" in defn else None widget = make_widget(self, type, parent, label, None, manager, managerAttrs, options) + widget.type = type return widget # Make a set of generic widgets from a dict