class PonyFrame(ttk.Frame, object): level = TkVarDescriptor(tk.DoubleVar) level_up = TkVarDescriptor(tk.BooleanVar) next_game = TkVarDescriptor(tk.StringVar) reset_next_game = TkVarDescriptor(tk.BooleanVar) def __init__(self, parent, name, level, shards, next_game, offset): ttk.Frame.__init__(self, parent) self.parent = parent self._pony_label = ttk.Label(self.parent, text=name) self.level = level self._level_frame = ttk.Frame(self.parent) self._level_label = ttk.Label(self._level_frame, text=int(self.level)) self._level_scale = ttk.Scale(self._level_frame, from_=0, to=5, orient=HORIZONTAL, variable=PonyFrame.level.raw_klass(self)) PonyFrame.level.raw_klass(self).trace("w", self._level_change) self.level_up = shards == 10 and self.level != 5 self._shards = ttk.Checkbutton( self.parent, state=(DISABLED if self.level == 5 else NORMAL), variable=PonyFrame.level_up.raw_klass(self)) self.next_game = next_game self._option_next = ttk.OptionMenu( self.parent, PonyFrame.next_game.raw_klass(self), self.next_game, Pony.GameTypes.rmap[Pony.GameTypes.Ball], Pony.GameTypes.rmap[Pony.GameTypes.Apple], Pony.GameTypes.rmap[Pony.GameTypes.Book]) self.reset_next_game = False self._reset_checkbox = ttk.Checkbutton( self.parent, variable=PonyFrame.reset_next_game.raw_klass(self)) options = dict(padx=16, pady=2) self._pony_label.grid(row=offset, column=0, sticky=W, **options) self._level_frame.grid(row=offset, column=1, **options) self._level_label.grid(row=0, column=0) self._level_scale.grid(row=1, column=0) self._shards.grid(row=offset, column=2, **options) self._option_next.grid(row=offset, column=3, **options) self._reset_checkbox.grid(row=offset, column=4, **options) def _level_change(self, *args): self.level = int(self.level) self._shards.configure(state=(DISABLED if self.level == 5 else NORMAL)) self.level_up = self.level_up and self.level != 5 self._level_label.config(text=int(self.level))
class PlayerFrame(ttk.Frame, object): complete_quests = TkVarDescriptor(tk.BooleanVar) def __init__(self, parent, xml_handle): ttk.Frame.__init__(self, parent, height=400) self.grid_propagate(0) self._xml_handle = xml_handle self._player_infos = {} for n, (name, typ) in enumerate(xml_handle.player_infos.items()): self._player_infos[name] = CurrencyFrame(self, name, typ.value, typ.limit, n) self.complete_quests = False self._quests_box = ttk.Checkbutton( self, text="Complete current quests", variable=PlayerFrame.complete_quests.raw_klass(self)) self._quests_box.grid(row=(n + 1), column=0, sticky=W, padx=3, pady=2) def commit(self): for name, typ in self._xml_handle.player_infos.items(): typ.value = self._player_infos[name].value if self.complete_quests: for quest in self._xml_handle.quests: quest.complete()
class PreferencesDialog(BaseDiablog): startup_check = TkVarDescriptor(tk.BooleanVar) def __init__(self, master): BaseDiablog.__init__(self, master, "Preferences", exit_on_esc=True) self.startup_check = Config.config["startup_check"] self.general_label = ttk.Label(self.body, text="General") font = Font(self.general_label, self.general_label.cget("font")) font.configure(underline=True) self.general_label.configure(font=font) self.config_frame = ttk.Frame(self) self.startup_check_checkbtn = ttk.Checkbutton( self.config_frame, text="Check for update at launch", variable=PreferencesDialog.startup_check.raw_klass(self), command=self._startup_check_clicked) self.buttons_frame = ttk.Frame(self) self.close_button = ttk.Button(self.buttons_frame, text="Close", command=self.destroy) options = dict(padx=5, pady=5) self.general_label.pack(side=LEFT, **options) self.config_frame.pack(fill=BOTH, expand=True, **options) self.startup_check_checkbtn.pack(side=LEFT, **options) self.buttons_frame.pack(side=BOTTOM, fill=BOTH, expand=True, **options) self.close_button.pack(side=RIGHT, expand=False) def _startup_check_clicked(self): Config.config["startup_check"] = self.startup_check Config.commit()
class MissingPony(ttk.Frame, object): checked = TkVarDescriptor(tk.BooleanVar) def __init__(self, parent, name, offset): ttk.Frame.__init__(self, parent) self.parent = parent self.checked = False self._chkbox = ttk.Checkbutton(self.parent, text="Add {} to inventory".format(name), variable=MissingPony.checked.raw_klass(self)) self._chkbox.grid(row=offset, column=0, sticky=W, padx=3, pady=2) def grid_remove(self): self._chkbox.grid_remove()
class CurrencyFrame(ttk.Frame, object): value = TkVarDescriptor(tk.StringVar) def __init__(self, parent, text, value, limit, offset): ttk.Frame.__init__(self, parent) self.parent = parent self.value = value self._label = ttk.Label(self.parent, text=text) self._entry = ttk.Entry( self.parent, textvariable=CurrencyFrame.value.raw_klass(self)) self._limit = ttk.Label(self.parent, text="(Limit: {})".format(limit)) options = dict(padx=10, pady=4) self._label.grid(row=offset, column=0, sticky=W, **options) self._entry.grid(row=offset, column=1, sticky=NSEW, **options) self._limit.grid(row=offset, column=2, sticky=NSEW, **options)
class ZoneFrame(ttk.Frame, object): clearables_checked = TkVarDescriptor(tk.BooleanVar) foes_checked = TkVarDescriptor(tk.BooleanVar) reset_checked = TkVarDescriptor(tk.BooleanVar) clearables_text = TkVarDescriptor(tk.StringVar) foes_text = TkVarDescriptor(tk.StringVar) reset_text = TkVarDescriptor(tk.StringVar) def __init__(self, parent, zone, offset, reset_offset): ttk.Frame.__init__(self, parent) self.parent = parent self.zone = zone self.clearables_checked = False self.foes_checked = False self.reset_checked = False self.update() self._clearables_box = ttk.Checkbutton( self.parent, textvariable=ZoneFrame.clearables_text.raw_klass(self), variable=ZoneFrame.clearables_checked.raw_klass(self)) self._foes_box = ttk.Checkbutton( self.parent, textvariable=ZoneFrame.foes_text.raw_klass(self), variable=ZoneFrame.foes_checked.raw_klass(self)) self._reset_box = ttk.Checkbutton( self.parent, textvariable=ZoneFrame.reset_text.raw_klass(self), variable=ZoneFrame.reset_checked.raw_klass(self)) options = dict(sticky=W, padx=3, pady=2) self._clearables_box.grid(row=(offset * 2), column=0, **options) self._foes_box.grid(row=(offset * 2) + 1, column=0, **options) self._reset_box.grid(row=reset_offset + offset, column=0, **options) def update(self): self.clearables_text = ( "Remove Clearables Objects from {} ({} remaining)".format( self.zone.name, len(self.zone.clearable_items))) self.foes_text = ("Remove {} from {} ({} remaining)".format( self.zone.foes.name, self.zone.name, len(self.zone.foes))) self.reset_text = ("Reset shops timer for {} ({} shop{})".format( self.zone.name, len(self.zone.shops), "s" if len(self.zone.shops) > 1 else ""))
class DownloadDialog(tk.Toplevel, object): percent = TkVarDescriptor(tk.StringVar) def __init__(self, *args, **kwargs): tk.Toplevel.__init__(self, *args, **kwargs) self.transient() self.title("Downloading...") self.protocol('WM_DELETE_WINDOW', lambda *args: None) self._curbytes = 0 self._maxbytes = 0 self.start = monotonic() self.update_percent() self.mainframe = ttk.Frame(self) self.mainframe.pack(side=TOP, fill=BOTH, expand=True) self.label = ttk.Label(self.mainframe, text="The new version is currently downloading, please wait...", font=20) self.progressframe = ttk.Frame(self.mainframe) self.pb = ttk.Progressbar(self.progressframe, mode="determinate", length=200, orient=HORIZONTAL) self.pblabel = ttk.Label(self.progressframe, textvariable=DownloadDialog.percent.raw_klass(self)) options = dict(padx=3, pady=4) self.label.pack(side=TOP, fill=X, expand=False, **options) self.progressframe.pack(side=BOTTOM, fill=BOTH, expand=True, **options) self.pb.pack(side=LEFT, **options) self.pblabel.pack(side=LEFT, **options) def update_percent(self): try: percent = (self.current / self.total) * 100 except ZeroDivisionError: percent = 0 try: kbps = self.current / (monotonic() - self.start) / 1024 except ZeroDivisionError: kbps = 0 self.percent = "{:.2f}% ({:.2f} KiB/s)".format(percent, kbps) @property def total(self): return self._maxbytes @total.setter def total(self, value): self._maxbytes = int(value) self.pb["maximum"] = self._maxbytes self.update_percent() @property def current(self): return self._curbytes @current.setter def current(self, value): self._curbytes = int(value) self.pb["value"] = self._curbytes self.update_percent()
class BaseGui(tk.Tk, object): savefile = TkVarDescriptor(tk.StringVar) gluid = TkVarDescriptor(tk.StringVar) dbfile = TkVarDescriptor(tk.StringVar) usedb = TkVarDescriptor(tk.BooleanVar) legacy = TkVarDescriptor(tk.BooleanVar) def __init__(self, savedata): tk.Tk.__init__(self) style = ttk.Style() style.theme_use('clam' if 'clam' in style.theme_names() else 'classic') self.savefile = savedata.savefile or "" self.gluid = savedata._gluid or "" self.dbfile = savedata.dbfile or "" self.usedb = savedata.usedb self.legacy = savedata.legacy self.grid() self.wm_title("Celestia Sunrise") self.resizable(False, False) self.bind('<Escape>', lambda _: self.destroy()) self._create_variables() def init(self): self._create_frames() self._create_widgets() self._grid_frames() self._grid_widgets() self._legacy_clicked() self._usedb_clicked() def reinit(self): self._remove_widgets() self._remove_frames() self.init() def _remove_frames(self): self._file_frame.grid_forget() self._key_frame.grid_forget() self._key_entry_frame.grid_forget() self._key_checkbox_frame.grid_forget() def _remove_widgets(self): self._file_label.grid_forget() self._file_entry.grid_forget() self._file_button.grid_forget() self._file_legacy.grid_forget() self._key_label.grid_forget() self._key_entry.grid_forget() self._key_button.grid_forget() self._key_dbfile.grid_forget() self._main_frame.pack_forget() def _create_variables(self): pass def _create_frames(self): self._main_frame = ttk.Frame(self) self._file_frame = ttk.Frame(self._main_frame) self._key_frame = ttk.Frame(self._main_frame) self._key_entry_frame = ttk.Frame(self._key_frame) self._key_checkbox_frame = ttk.Frame(self._key_frame) def _create_widgets(self): self._file_label = ttk.Label(self._file_frame, text="Savegame file: ") self._file_entry = ttk.Entry( self._file_frame, textvariable=BaseGui.savefile.raw_klass(self)) self._file_button = ttk.Button( self._file_frame, text="Browse", command=lambda: BaseGui.savefile.__set__(self, askopenfilename())) self._file_legacy = ttk.Checkbutton( self._file_frame, text="Legacy file", variable=BaseGui.legacy.raw_klass(self), command=self._legacy_clicked) self._key_label = ttk.Label(self._key_entry_frame, text="Key (GLUID): ") self._key_entry = ttk.Entry(self._key_entry_frame, textvariable=BaseGui.gluid.raw_klass(self)) self._key_button = ttk.Button( self._key_entry_frame, text="Browse", command=lambda: BaseGui.dbfile.__set__(self, askopenfilename())) self._key_dbfile = ttk.Checkbutton( self._key_checkbox_frame, text="Use gameloft_sharing database file", variable=BaseGui.usedb.raw_klass(self), command=self._usedb_clicked) def _grid_frames(self): self._main_frame.pack(expand=True, fill=BOTH) options = dict(sticky=NSEW, padx=3, pady=4) self._key_entry_frame.grid(row=0, column=0, **options) self._key_checkbox_frame.grid(row=1, column=0, **options) def _grid_widgets(self): options = dict(padx=3, pady=4) self._file_label.grid(row=0, column=0, sticky=W, **options) self._file_entry.grid(row=0, column=1, sticky=NSEW, **options) self._file_button.grid(row=0, column=2, sticky=E, **options) self._file_legacy.grid(row=1, column=0, sticky=W, **options) self._key_label.grid(row=0, column=0, sticky=W, **options) self._key_entry.grid(row=0, column=1, **options) self._key_button.grid(row=0, column=2, sticky=E, **options) self._key_dbfile.grid(row=0, column=0, sticky=W, **options) def _legacy_clicked(self): if self.legacy: self._key_frame.grid_remove() else: self._key_frame.grid() def _usedb_clicked(self): if not self.usedb: self._key_button.grid_remove() self._key_entry.configure( textvariable=BaseGui.gluid.raw_klass(self)) else: self._key_button.grid() self._key_entry.configure( textvariable=BaseGui.dbfile.raw_klass(self)) @property def savedata(self): return SaveData(self.savefile, self.gluid, self.dbfile, self.usedb, self.legacy)
class BaseGui(tk.Toplevel, object): savefile = TkVarDescriptor(tk.StringVar) gluid = TkVarDescriptor(tk.StringVar) dbfile = TkVarDescriptor(tk.StringVar) usedb = TkVarDescriptor(tk.BooleanVar) legacy = TkVarDescriptor(tk.BooleanVar) def __init__(self, master, savedata): tk.Toplevel.__init__(self, master) style = ttk.Style() style.theme_use('clam' if 'clam' in style.theme_names() else 'classic') self.option_add('*tearOff', False) self.savefile = savedata.savefile or "" self.gluid = savedata._gluid or "" self.dbfile = savedata.dbfile or "" self.usedb = savedata.usedb self.legacy = savedata.legacy self.grid() self.wm_title("Celestia Sunrise") self.resizable(False, False) self.bind('<Escape>', lambda _: self.destroy()) self._create_variables() def init(self): self._create_frames() self._create_widgets() self._grid_frames() self._grid_widgets() self._legacy_clicked() self._usedb_clicked() def reinit(self): self._remove_widgets() self._remove_frames() self.init() def _check_update(self, background=False): if not background: loadingbox = LoadingDialog(self) else: loadingbox = None queue = Queue() thread = ThreadedVersionCheck(queue=queue) thread.start() def success_callback(res): if not res["up_to_date"]: NewVersionDialog(res["download_url"], self) elif not background: showinfo("Up to date", "You're running the latest version") self.after(100, process_queue, self, queue, loadingbox, success_callback, None, None, not background) def _preferences_popup(self): PreferencesDialog(self) def _about_popup(self): from __main__ import INTRO, AUTHOR showinfo( "About", """{intro} {author}""".format(intro=INTRO, author=AUTHOR)) def _remove_frames(self): self._file_frame.grid_forget() self._key_frame.grid_forget() self._key_entry_frame.grid_forget() self._key_checkbox_frame.grid_forget() def _remove_widgets(self): self._file_label.grid_forget() self._file_entry.grid_forget() self._file_button.grid_forget() self._file_legacy.grid_forget() self._key_label.grid_forget() self._key_entry.grid_forget() self._key_button.grid_forget() self._key_dbfile.grid_forget() self._main_frame.pack_forget() def _create_variables(self): pass def _create_frames(self): self._main_frame = ttk.Frame(self) self._file_frame = ttk.Frame(self._main_frame) self._key_frame = ttk.Frame(self._main_frame) self._key_entry_frame = ttk.Frame(self._key_frame) self._key_checkbox_frame = ttk.Frame(self._key_frame) def _create_widgets(self): self._file_label = ttk.Label(self._file_frame, text="Savegame file: ") self._file_entry = ttk.Entry( self._file_frame, textvariable=BaseGui.savefile.raw_klass(self)) self._file_button = ttk.Button( self._file_frame, text="Browse", command=lambda: BaseGui.savefile.__set__(self, askopenfilename())) self._file_legacy = ttk.Checkbutton( self._file_frame, text="Legacy file", variable=BaseGui.legacy.raw_klass(self), command=self._legacy_clicked) self._key_label = ttk.Label(self._key_entry_frame, text="Key (GLUID): ") self._key_entry = ttk.Entry(self._key_entry_frame, textvariable=BaseGui.gluid.raw_klass(self)) self._key_button = ttk.Button( self._key_entry_frame, text="Browse", command=lambda: BaseGui.dbfile.__set__(self, askopenfilename())) self._key_dbfile = ttk.Checkbutton( self._key_checkbox_frame, text="Use gameloft_sharing database file", variable=BaseGui.usedb.raw_klass(self), command=self._usedb_clicked) self._menu = tk.Menu(self) self._filemenu = tk.Menu(self) self._editmenu = tk.Menu(self) self._helpmenu = tk.Menu(self) self._helpmenu.add_command(label="Check for update", command=self._check_update) self._helpmenu.add_separator() self._helpmenu.add_command(label="About", command=self._about_popup) self._menu.add_cascade(label="File", menu=self._filemenu) self._menu.add_cascade(label="Edit", menu=self._editmenu) self._menu.add_cascade(label="Help", menu=self._helpmenu) self.config(menu=self._menu) def _grid_frames(self): self._main_frame.pack(expand=True, fill=BOTH) options = dict(sticky=NSEW, padx=3, pady=4) self._key_entry_frame.grid(row=0, column=0, **options) self._key_checkbox_frame.grid(row=1, column=0, **options) def _grid_widgets(self): options = dict(padx=3, pady=4) self._file_label.grid(row=0, column=0, sticky=W, **options) self._file_entry.grid(row=0, column=1, sticky=NSEW, **options) self._file_button.grid(row=0, column=2, sticky=E, **options) self._file_legacy.grid(row=1, column=0, sticky=W, **options) self._key_label.grid(row=0, column=0, sticky=W, **options) self._key_entry.grid(row=0, column=1, **options) self._key_button.grid(row=0, column=2, sticky=E, **options) self._key_dbfile.grid(row=0, column=0, sticky=W, **options) def _legacy_clicked(self): if self.legacy: self._key_frame.grid_remove() else: self._key_frame.grid() def _usedb_clicked(self): if not self.usedb: self._key_button.grid_remove() self._key_entry.configure( textvariable=BaseGui.gluid.raw_klass(self)) else: self._key_button.grid() self._key_entry.configure( textvariable=BaseGui.dbfile.raw_klass(self)) @property def savedata(self): return SaveData(self.savefile, self.gluid, self.dbfile, self.usedb, self.legacy)