def __init__( self, master: typing.Union[tk.AsyncTk, tk.AsyncFrame], *, height: int, width: int, ): self.frame = None self.read_nums = 1 if height > 600 or width > 600: true_height = 600 if height > 600 else height true_width = 600 if width > 600 else width self.frame = tk.AsyncFrame(master) self.frame.pack(side=tk.LEFT) super().__init__( self.frame, height=true_height, width=true_width, bg="white", scrollregion=(0, 0, width, height), ) if height > 600: hbar = tk.AsyncScrollbar(self.frame, orient=tk.HORIZONTAL) hbar.pack(side=tk.BOTTOM, fill=tk.X) hbar.config(command=self.yview) self.config(yscrollcommand=hbar.set) # intentional switch if width > 600: vbar = tk.AsyncScrollbar(self.frame, orient=tk.VERTICAL) vbar.pack(side=tk.RIGHT, fill=tk.Y) vbar.config(command=self.xview) self.config(xscrollcommand=vbar.set) # intentional switch self.pack(side=tk.LEFT, expand=True, fill=tk.BOTH) else: super().__init__(master, height=height, width=width, bg="white") self.pack(side=tk.LEFT) self.width, self.height = width, height self.pil_image = Image.new("RGB", (width, height), (255, 255, 255)) self.pil_draw = ImageDraw.Draw(self.pil_image) self.undo_list = [] self.redo_list = [] self._master = master
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 __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)
async def file_select(self, *, new_file: bool = True): """File select dialogue""" manager = tk.AsyncToplevel(self) manager.title(self.cur_locale.menu.fileselect.saveas if new_file else self.cur_locale.menu.fileselect.open) manager.protocol("WM_DELETE_WINDOW", lambda: asyncio.ensure_future(manager.destroy())) dir = pathlib.Path() dirbox = tk.AsyncEntry(manager) dirbox.grid(row=0, column=0) foldermap = tk.AsyncFrame(manager) foldermap.grid(row=1, column=0) 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 boxcallback(*i): """Internal function called to change the directory to what is typed in dirbox.""" change_dir(dirbox.get()) 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) dirbox.bind("<Return>", boxcallback) change_dir(".") await self.wait_window(manager) if hasattr(manager, "file"): return manager.file
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()