From 58fb8ec0bf3f2780b94553d51e00f4d62865d83d Mon Sep 17 00:00:00 2001 From: q Date: Fri, 29 Nov 2024 15:53:05 +0200 Subject: [PATCH] tk version of zenitY --- bin/tk-zenity | 1 + shell/tk-zenity | 175 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 176 insertions(+) create mode 120000 bin/tk-zenity create mode 100755 shell/tk-zenity diff --git a/bin/tk-zenity b/bin/tk-zenity new file mode 120000 index 0000000..9467f6e --- /dev/null +++ b/bin/tk-zenity @@ -0,0 +1 @@ +../shell/tk-zenity \ No newline at end of file diff --git a/shell/tk-zenity b/shell/tk-zenity new file mode 100755 index 0000000..f53781e --- /dev/null +++ b/shell/tk-zenity @@ -0,0 +1,175 @@ +#!/usr/bin/env python3 + +import argparse +import sys +import time +import tkinter as tk +import tkinter.messagebox +import tkinter.simpledialog +import tkinter.ttk +from threading import Thread + + +class StdinBox(tk.Toplevel): + def __init__(self, title="", message="", geometry="800x80"): + tk.Toplevel.__init__(self) + self.geometry(geometry) + self.title(title) + self.exit = False + self.my_message = message + self.my_title = title + self.messageLabel = tk.Label(self, text=message, bg="#222", fg="#fff", font="TkFixedFont") + self.messageLabel.pack(expand=True, fill=tk.BOTH) + + daemon = Thread(target=self.stream_stdin) + daemon.start() + self.update_timer() + self.mainloop() + + def update_message(self, message): + self.messageLabel.configure(text=message) + + def update_title(self, title): + self.title(title) + + def update_timer(self): + if self.exit: + self.quit() + return + self.messageLabel.configure(text=self.my_message) + self.update() + self.after(333, self.update_timer) + + def stream_stdin(self): + with open(sys.stdin.fileno(), mode="rt", encoding="utf-8", newline=None, buffering=1, closefd=True) as fp: + for line in fp: + self.my_message = line.rstrip("\r\n") + self.exit = True + +class ListBox(tk.Toplevel): + def __init__(self, title="", message="", geometry="800x800"): + tk.Toplevel.__init__(self) + self.geometry(geometry) # Must change these accordingly + self.configure(background='#222') + self.title(title) + self.messageLabel = tk.Label(self, text=message, bg="#222", fg="#fff", font="TkFixedFont") + self.choose = tk.Listbox(self,bg="#222", fg="#fff", font="TkFixedFont",selectmode='browse') + with open(sys.stdin.fileno(), mode="rt", encoding="utf-8", newline=None, buffering=1, closefd=True) as fp: + for i,line in enumerate(fp): + self.choose.insert(i,line.rstrip("\r\n")) + self.last_element = i + self.choose.select_set(0) + + self.labelframe = tk.Frame(self, bg='#222') + self.cancel_b = tk.Button(self.labelframe, text = "Cancel", command = self.quit) + self.ok_b = tk.Button(self.labelframe, text = "OK", command = self.selected) + + self.messageLabel.pack()#expand=True, fill=tk.BOTH) + self.choose.pack(expand=True,fill=tk.BOTH) + self.cancel_b.pack(side='left') + self.ok_b.pack(side='right') + self.labelframe.pack() + self.choose.focus_set() + self.choose.bind('', self.selected) + self.choose.bind('', self.selected) + self.choose.bind("", self.key_handler) + + self.ok_b.bind('', self.selected) + self.cancel_b.bind('', self.handle_exit) + self.bind_all('', self.handle_exit) + self.bind_all('', self.handle_exit) + + self.mainloop() + + def set_position(self,index): + index = max(0, min( self.last_element, index )) + self.choose.selection_clear(0,tk.END) + self.choose.activate(index) + self.choose.selection_set(index) + + def key_handler(self,event): + if len(event.char) == 1 and event.char.isalnum(): + # ~ print(event.char, event.keysym, event.keycode) + for i in list(range(self.choose.curselection()[0] + 1, self.last_element+1)) + list(range(0,self.choose.curselection()[0]+1)): + if self.choose.get(i).lower().startswith(event.char): + self.set_position(i) + return + if event.keysym == 'Up': + self.set_position(self.choose.curselection()[0] ) + if event.keysym == 'Down': + self.set_position(self.choose.curselection()[0] ) + if event.keysym == 'Next': + self.set_position(self.choose.curselection()[0] +10 ) + if event.keysym == 'Prior': + self.set_position(self.choose.curselection()[0] -10 ) + if event.keysym == 'Home': + self.set_position(0) + if event.keysym == 'End': + self.set_position(self.last_element) + + def selected(self, *args): + for i in self.choose.curselection(): + print(self.choose.get(i), end='') + self.quit() + + def handle_exit(self, *args): + self.quit() + + +def get_opts(): + parser = argparse.ArgumentParser() + parser.add_argument( + "--title", + action="store", + default=None, + help="Window title", + ) + parser.add_argument("--text", action="store", default=None, help="Description text", nargs="?") + parser.add_argument("--geometry", action="store", default=None, help="Geometry (not valid for all commands), ex. 800x200+50+50", nargs="?") + parser.add_argument( + "mode", + action="store", + default="info", + const="info", + nargs="?", + choices=["info", "password", "entry", "stream","list"], + help="operation mode. Note: stream mode expects stdin to update text and line starting with #.", + ) + parsed = parser.parse_args() + + return parsed + + +def set_defaults(opts, title, text, geometry=None): + if opts.text is None: + opts.text = text + if opts.title is None: + opts.title = title + if opts.geometry is None: + opts.geometry = geometry + return opts + + +def main(): + opts = get_opts() + tk.Tk().withdraw() + if opts.mode == "password": + opts = set_defaults(opts, "Password", "Type password:") + pw = tkinter.simpledialog.askstring(opts.title, opts.text, show="*") + print(pw, end="") + if opts.mode == "info": + opts = set_defaults(opts, "Info", "Message") + tkinter.messagebox.showinfo(title=opts.title, message=opts.text) + if opts.mode == "entry": + opts = set_defaults(opts, "Entry", "Type message:") + msg = tkinter.simpledialog.askstring(title=opts.title, prompt=opts.text) + print(msg, end="") + if opts.mode == "stream": + opts = set_defaults(opts, "Info", "", "800x80-50-50") + StdinBox(title=opts.title, message=opts.text, geometry=opts.geometry) + if opts.mode == "list": + opts = set_defaults(opts, "Select", "Select from list:") + ListBox(title=opts.title, message=opts.text) + +if __name__ == "__main__": + main()