From c65c846638041214cc8cb77652b59f909ee8f83e Mon Sep 17 00:00:00 2001 From: Blake Harnden <32446120+bharnden@users.noreply.github.com> Date: Thu, 31 Oct 2019 15:18:49 -0700 Subject: [PATCH] updated configutils to generate a scrollable view for configurations --- coretk/coretk/configutils.py | 59 +++++++++++++++++++++---- coretk/coretk/dialogs/sessionoptions.py | 5 +-- 2 files changed, 53 insertions(+), 11 deletions(-) diff --git a/coretk/coretk/configutils.py b/coretk/coretk/configutils.py index 97230561..fd5263f3 100644 --- a/coretk/coretk/configutils.py +++ b/coretk/coretk/configutils.py @@ -9,34 +9,77 @@ class ConfigType(enum.Enum): BOOL = 11 -def create_config(master, config, pad_x=2, pad_y=2): +def create_config(master, config, padx=2, pady=2): + """ + Creates a scrollable canvas with an embedded window for displaying configuration + options. Will use grid layout to consume row 0 and columns 0-2. + + :param master: master to add scrollable canvas to + :param dict config: config option mapping keys to config options + :param int padx: x padding for widgets + :param int pady: y padding for widgets + :return: widget value mapping + """ + master.rowconfigure(0, weight=1) master.columnconfigure(0, weight=1) - master.columnconfigure(1, weight=3) + master.columnconfigure(1, weight=1) + + canvas = tk.Canvas(master) + canvas.grid(row=0, columnspan=2, sticky="nsew", padx=padx, pady=pady) + canvas.columnconfigure(0, weight=1) + canvas.rowconfigure(0, weight=1) + + scroll_y = tk.Scrollbar(master, orient="vertical", command=canvas.yview) + scroll_y.grid(row=0, column=2, sticky="ns") + + frame = tk.Frame(canvas, padx=padx, pady=pady) + frame.columnconfigure(0, weight=1) + frame.columnconfigure(1, weight=3) + values = {} for index, key in enumerate(sorted(config)): option = config[key] - label = tk.Label(master, text=option.label) - label.grid(row=index, pady=pad_y, padx=pad_x, sticky="ew") + label = tk.Label(frame, text=option.label) + label.grid(row=index, pady=pady, padx=padx, sticky="ew") value = tk.StringVar() config_type = ConfigType(option.type) if config_type == ConfigType.BOOL: select = tuple(option.select) - combobox = ttk.Combobox(master, textvariable=value, values=select) - combobox.grid(row=index, column=1, sticky="ew", pady=pad_y) + combobox = ttk.Combobox(frame, textvariable=value, values=select) + combobox.grid(row=index, column=1, sticky="ew", pady=pady) if option.value == "1": value.set("On") else: value.set("Off") elif config_type == ConfigType.STRING: - entry = tk.Entry(master, textvariable=value) - entry.grid(row=index, column=1, sticky="ew", pady=pad_y) + entry = tk.Entry(frame, textvariable=value) + entry.grid(row=index, column=1, sticky="ew", pady=pady) else: logging.error("unhandled config option type: %s", config_type) values[key] = value + + frame_id = canvas.create_window(0, 0, anchor="nw", window=frame) + canvas.update_idletasks() + canvas.configure(scrollregion=canvas.bbox("all"), yscrollcommand=scroll_y.set) + + frame.bind( + "", lambda event: canvas.configure(scrollregion=canvas.bbox("all")) + ) + canvas.bind( + "", lambda event: canvas.itemconfig(frame_id, width=event.width) + ) + return values def parse_config(options, values): + """ + Given a set of configurations, parse out values and transform them when needed. + + :param dict options: option key mapping to configuration options + :param dict values: option key mapping to widget values + :return: + """ config = {} for key in options: option = options[key] diff --git a/coretk/coretk/dialogs/sessionoptions.py b/coretk/coretk/dialogs/sessionoptions.py index 3612dab5..65faae81 100644 --- a/coretk/coretk/dialogs/sessionoptions.py +++ b/coretk/coretk/dialogs/sessionoptions.py @@ -23,9 +23,8 @@ class SessionOptionsDialog(Dialog): logging.info("session options: %s", response) self.options = response.config self.values = configutils.create_config(self, self.options, PAD_X, PAD_Y) - row = len(response.config) - self.save_button.grid(row=row, pady=PAD_Y, padx=PAD_X, sticky="ew") - self.cancel_button.grid(row=row, column=1, pady=PAD_Y, padx=PAD_X, sticky="ew") + self.save_button.grid(row=1, pady=PAD_Y, padx=PAD_X, sticky="ew") + self.cancel_button.grid(row=1, column=1, pady=PAD_Y, padx=PAD_X, sticky="ew") def save(self): config = configutils.parse_config(self.options, self.values)