async def new(): """Internal coroutine used to create the new file dialogue.""" dialogue = tk.AsyncToplevel(manager) dialogue.title(self.cur_locale.menu.fileselect.new) dialogue.protocol("WM_DELETE_WINDOW", nothing) filename = tk.AsyncEntry(dialogue) filename.pack() async def cb(): if filename.get() != len(filename.get()) * ".": for i in r'\/:*?"<>|': if i in filename.get(): button.config(text=self.cur_locale.menu. fileselect.button.invalid) break else: manager.file = manager.dir / filename.get() await manager.destroy() else: button.config(text=self.cur_locale.menu.fileselect. button.special) # Confirm button button = tk.AsyncButton( dialogue, text=self.cur_locale.menu.fileselect.button.default, callback=cb, ) button.pack(fill=tk.X) # Cancel button tk.AsyncButton( dialogue, text=self.cur_locale.menu.fileselect.button.cancel, callback=dialogue.destroy, ).pack(fill=tk.X) await manager.wait_window(dialogue)
def change_dir(path: typing.Union[str, pathlib.Path]): """Internal function to load a path into the file select menu.""" nonlocal dir, foldermap dir = pathlib.Path(path) manager.dir = dir asyncio.ensure_future(foldermap.destroy()) foldermap = tk.AsyncFrame(manager) foldermap.grid(row=1, column=0) populate_folder(dir) # Cancel button tk.AsyncButton( foldermap, text=self.cur_locale.menu.fileselect.button.cancel, callback=manager.destroy, ).pack(fill=tk.X)
def _setupFields(self): tk.AsyncLabel(self, text=self.master.cur_locale.menu.new.height).pack() self.width = tk.AsyncEntry(self) self.width.pack() self.width.bind("<Return>", lambda i: asyncio.ensure_future(self.checknew())) tk.AsyncLabel(self, text=self.master.cur_locale.menu.new.width).pack() self.height = tk.AsyncEntry(self) self.height.pack() self.height.bind("<Return>", lambda i: asyncio.ensure_future(self.checknew())) tk.AsyncButton(self, callback=self.checknew, text=self.master.cur_locale.menu.new.create).pack()
async def save(self, file: typing.Union[str, pathlib.Path]): """Shortcut to save the PIL file""" # Get the file extension ext = str(file).split(".")[-1] buffer = BytesIO() # Save into buffer self.pil_image.save(buffer, format=ext) # Find out how many bytes the file holds, and reset file pointer max_bytes = buffer.tell() buffer.seek(0) async with aiofiles.open(file, "wb") as fp: # For every byte for i in range(max_bytes): current_byte = buffer.read(1) # Open a window root = tk.AsyncToplevel(self._master) # ... that the user cannot kill root.protocol('WM_DELETE_WINDOW', lambda *i: None) async def cb(i=i): # No late binding # Write the byte await fp.write(current_byte) # ... then kill the root await root.destroy() # ... and place a button if isinstance(self.master, tk.AsyncFrame): master = self.master.master else: master = self.master tk.AsyncButton( root, # ... on the window # ... that says the current byte text=(f"{master.cur_locale.menu.fileselect.write} " f"{current_byte.hex().upper()}"), # ... and writes it on click callback=cb, ).pack() # ... and wait until the button is pressed (so the user cannot mess up) await self._master.wait_window(root)
def _setupFields(self): tk.AsyncLabel(self, text=self.master.cur_locale.menu.entry.x).pack() self.x = tk.AsyncSpinbox(self, from_=1, to=self.canvas.width) self.x.pack() tk.AsyncLabel(self, text=self.master.cur_locale.menu.entry.y).pack() self.y = tk.AsyncSpinbox(self, from_=1, to=self.canvas.height) self.y.pack() tk.AsyncLabel(self, text=self.master.cur_locale.menu.entry.colour).pack() self.colour = tk.AsyncEntry(self) self.colour.pack() tk.AsyncButton( self, callback=self.setupPixel, text=self.master.cur_locale.menu.entry.confirm, ).pack() self.error_label = tk.AsyncLabel(self, text="", fg="red") self.error_label.pack()
def __init__(self, bot: commands.Bot): tk.AsyncTk.__init__(self, loop=bot.loop) self.bot = bot self.current_command = None self.running_commands = {} self.command_frame = tk.AsyncFrame(self) self.command_frame.text = AsyncScrolledText(self.command_frame, state='disabled', width=40, height=10) self.statistics_frame = tk.AsyncFrame(self) self.statistics_frame.guilds = tk.AsyncLabel(self.statistics_frame, text=f'Guilds: {len(bot.guilds)}') self.statistics_frame.channels = tk.AsyncLabel(self.statistics_frame, text=f'Channels: {len([i for i in bot.get_all_channels()])}') self.statistics_frame.users = tk.AsyncLabel(self.statistics_frame, text=f'Users: {len(bot.users)}') self.statistics_frame.emoji = tk.AsyncLabel(self.statistics_frame, text=f'Emoji: {len(bot.emojis)}') self.stdout_frame = tk.AsyncFrame(self) self.stdout_frame.text = AsyncScrolledText(self.stdout_frame, state='disabled', width=40, height=10) self.stdout = MockSTDIO('stdout', self.stdout_frame.text) self.stderr_frame = tk.AsyncFrame(self) self.stderr_frame.text = AsyncScrolledText(self.stderr_frame, state='disabled', width=40, height=10) self.stderr = MockSTDIO('stderr', self.stderr_frame.text) self.command_editing_frame = tk.AsyncFrame(self) self.command_editing_frame.option_button = tk.AsyncMenubutton(self.command_editing_frame, text='Choose a command') menu = tk.AsyncMenu(self.command_editing_frame.option_button) self.command_editing_frame.option_button['menu'] = menu self._menu = menu for name, object in bot.all_commands.items(): menu.add_command(label=name, command=self.make_option(object)) self.command_cache = bot.all_commands.copy() self.command_editing_frame.hidden_var = tk.IntVar(self) self.command_editing_frame.enabled_var = tk.IntVar(self) self.command_editing_frame.help = AsyncScrolledText(self.command_editing_frame, width=40, height=10) self.command_editing_frame.help_submit = tk.AsyncButton(self.command_editing_frame, text='Submit Helpstring', callback=self.submit_helpstring) self.command_editing_frame.hidden = Checkbutton(self.command_editing_frame, text='Hidden:', command=self.set_hidden, variable=self.command_editing_frame.hidden_var) self.command_editing_frame.enabled = Checkbutton(self.command_editing_frame, text='Enabled:', command=self.set_enabled, variable=self.command_editing_frame.enabled_var) tk.AsyncLabel(self.command_frame, text='Command info:').pack() self.command_frame.text.pack() tk.AsyncLabel(self.statistics_frame, text='Statistics:').pack() self.statistics_frame.guilds.pack() self.statistics_frame.channels.pack() self.statistics_frame.users.pack() tk.AsyncLabel(self.stdout_frame, text='STDOut:').pack() self.stdout_frame.text.pack() tk.AsyncLabel(self.stderr_frame, text='STDErr:').pack() self.stderr_frame.text.pack() tk.AsyncLabel(self.command_editing_frame, text='Modify commands:').grid(row=0, column=0, columnspan=2) Separator(self.command_editing_frame).grid(row=1, column=0, columnspan=2) tk.AsyncLabel(self.command_editing_frame, text='Command:', anchor=tk.W).grid(row=2, column=0) self.command_editing_frame.option_button.grid(row=2, column=1) self.command_editing_frame.help.grid(row=3, column=0, columnspan=2) self.command_editing_frame.help_submit.grid(row=4, column=0, columnspan=2) self.command_editing_frame.hidden.grid(row=5, column=0) self.command_editing_frame.enabled.grid(row=5, column=1) self.command_frame.grid(row=0, column=0) self.statistics_frame.grid(row=0, column=1) self.stdout_frame.grid(row=1, column=0) self.stderr_frame.grid(row=2, column=0) self.command_editing_frame.grid(row=1, column=1, rowspan=2) self.wm_protocol('WM_DELETE_WINDOW', self.cog_unload)
def populate_folder(folder: pathlib.Path): """Internally manages the save dialogue.""" nonlocal dir dir = manager.dir for i in [".."] + os.listdir(folder): if (dir / i).is_file(): async def cb(i=i): # i=i prevents late binding # Late binding causes an undetectable error that # causes all buttons to utilise the same callback manager.file = dir / i await manager.destroy() tk.AsyncButton( foldermap, text=f"{i} {self.cur_locale.menu.fileselect.file}", callback=cb, ).pack(fill=tk.X) elif (dir / i).is_dir(): async def cb(i=i): # i=i prevents late binding # Late binding causes an undetectable error that # causes all buttons to utilise the same callback manager.dir = dir / i change_dir(manager.dir) tk.AsyncButton( foldermap, text=f"{i} {self.cur_locale.menu.fileselect.folder}", callback=cb, ).pack(fill=tk.X) async def new(): """Internal coroutine used to create the new file dialogue.""" dialogue = tk.AsyncToplevel(manager) dialogue.title(self.cur_locale.menu.fileselect.new) dialogue.protocol("WM_DELETE_WINDOW", nothing) filename = tk.AsyncEntry(dialogue) filename.pack() async def cb(): if filename.get() != len(filename.get()) * ".": for i in r'\/:*?"<>|': if i in filename.get(): button.config(text=self.cur_locale.menu. fileselect.button.invalid) break else: manager.file = manager.dir / filename.get() await manager.destroy() else: button.config(text=self.cur_locale.menu.fileselect. button.special) # Confirm button button = tk.AsyncButton( dialogue, text=self.cur_locale.menu.fileselect.button.default, callback=cb, ) button.pack(fill=tk.X) # Cancel button tk.AsyncButton( dialogue, text=self.cur_locale.menu.fileselect.button.cancel, callback=dialogue.destroy, ).pack(fill=tk.X) await manager.wait_window(dialogue) if new_file: # New File button tk.AsyncButton(foldermap, text=self.cur_locale.menu.fileselect.new, callback=new).pack(fill=tk.X)
def __init__(this, bot: OmenaBot): atk.AsyncTk.__init__(this, loop=bot.loop) this.bot = bot this.pending_messages = {} this.current_command = None this.running_commands = {} this.command_frame = atk.AsyncFrame(this) this.command_frame.text = AsyncScrolledText(this.command_frame, state='disabled', width=40, height=10) this.statistics_frame = atk.AsyncFrame(this) this.statistics_frame.clock = atk.AsyncLabel(this.statistics_frame, text="") this.statistics_frame.runtime = atk.AsyncLabel(this.statistics_frame, text="") this.statistics_frame.guilds = atk.AsyncLabel( this.statistics_frame, text=f'Guilds: {len(bot.guilds)}') this.statistics_frame.channels = atk.AsyncLabel( this.statistics_frame, text=f'Channels: {len([i for i in bot.get_all_channels()])}') this.statistics_frame.users = atk.AsyncLabel( this.statistics_frame, text=f'Users: {len(bot.users)}') this.statistics_frame.emoji = atk.AsyncLabel( this.statistics_frame, text=f'Emoji: {len(bot.emojis)}') this.stdout_frame = atk.AsyncFrame(this) this.stdout_frame.text = AsyncScrolledText(this.stdout_frame, state='disabled', width=40, height=10) this.stdout = MockSTDIO('stdout', this.stdout_frame.text) this.stderr_frame = atk.AsyncFrame(this) this.stderr_frame.text = AsyncScrolledText(this.stderr_frame, state='disabled', width=40, height=10) this.stderr = MockSTDIO('stderr', this.stderr_frame.text) this.command_editing_frame = atk.AsyncFrame(this) # self.command_editing_frame.menu_button = atk.AsyncMenubutton(self.command_editing_frame, text='Choose a command') this.command_editing_frame.command_var = atk.StringVar( this, name="Choose command") bot_commands = [(i, ) for i in this.bot.commands] this.command_editing_frame.option_menu = atk.AsyncOptionMenu( this.command_editing_frame, this.command_editing_frame.command_var, bot_commands[0], *bot_commands[0:], callback=this.make_option) # , text='Choose a command') this.command_cache = bot.commands.copy() this.command_editing_frame.hidden_var = atk.IntVar(this) this.command_editing_frame.enabled_var = atk.IntVar(this) this.command_editing_frame.help = AsyncScrolledText( this.command_editing_frame, width=40, height=10) this.command_editing_frame.help_submit = atk.AsyncButton( this.command_editing_frame, text='Submit Helpstring', callback=this.submit_helpstring) this.command_editing_frame.hidden = Checkbutton( this.command_editing_frame, text='Hidden:', command=this.set_hidden, variable=this.command_editing_frame.hidden_var) this.command_editing_frame.enabled = Checkbutton( this.command_editing_frame, text='Enabled:', command=this.set_enabled, variable=this.command_editing_frame.enabled_var) def close(self=this): self.bot.loop.create_task(self.bot.close_bot(name="GUI", name_id=-1), name="close task") this.close_button = atk.AsyncButton(this, bg="red", callback=close) atk.AsyncLabel(this.command_frame, text='Command info:').pack() this.command_frame.text.pack() atk.AsyncLabel(this.statistics_frame, text='Statistics:').pack() this.statistics_frame.clock.pack() this.statistics_frame.runtime.pack() this.statistics_frame.guilds.pack() this.statistics_frame.channels.pack() this.statistics_frame.users.pack() atk.AsyncLabel(this.stdout_frame, text='STDOut:').pack() this.stdout_frame.text.pack() atk.AsyncLabel(this.stderr_frame, text='STDErr:').pack() this.stderr_frame.text.pack() atk.AsyncLabel(this.command_editing_frame, text='Modify commands:').grid(row=0, column=0, columnspan=2) Separator(this.command_editing_frame).grid(row=1, column=0, columnspan=2) atk.AsyncLabel(this.command_editing_frame, text='Command:', anchor=atk.W).grid(row=2, column=0) # self.command_editing_frame.menu_button.grid(row=2, column=1) this.command_editing_frame.option_menu.grid(row=2, column=1) this.command_editing_frame.help.grid(row=3, column=0, columnspan=2) this.command_editing_frame.help_submit.grid(row=4, column=0, columnspan=2) this.command_editing_frame.hidden.grid(row=5, column=0) this.command_editing_frame.enabled.grid(row=5, column=1) this.command_frame.grid(row=0, column=0, rows=2) this.stdout_frame.grid(row=2, column=0, rows=2) this.stderr_frame.grid(row=4, column=0, rows=2) this.statistics_frame.grid(row=0, column=1, rows=2) this.command_editing_frame.grid(row=1, column=1, rows=4) this.close_button.grid(row=5, column=1, rows=1) this.wm_protocol('WM_DELETE_WINDOW', this.cog_unload) this.update_clock() this.repack()