From 891e9aef9af1befefc2cdc1f8aaeb72b3b9614a7 Mon Sep 17 00:00:00 2001 From: Blake Harnden <32446120+bharnden@users.noreply.github.com> Date: Thu, 31 Oct 2019 14:06:50 -0700 Subject: [PATCH] initial add with a common dialog class and leveraging it for a session options dialog --- coretk/coretk/configutils.py | 52 +++++++++++++++++++++++++ coretk/coretk/coremenubar.py | 2 +- coretk/coretk/dialogs/__init__.py | 0 coretk/coretk/dialogs/dialog.py | 23 +++++++++++ coretk/coretk/dialogs/sessionoptions.py | 35 +++++++++++++++++ coretk/coretk/menuaction.py | 10 +++-- 6 files changed, 117 insertions(+), 5 deletions(-) create mode 100644 coretk/coretk/configutils.py create mode 100644 coretk/coretk/dialogs/__init__.py create mode 100644 coretk/coretk/dialogs/dialog.py create mode 100644 coretk/coretk/dialogs/sessionoptions.py diff --git a/coretk/coretk/configutils.py b/coretk/coretk/configutils.py new file mode 100644 index 00000000..97230561 --- /dev/null +++ b/coretk/coretk/configutils.py @@ -0,0 +1,52 @@ +import enum +import logging +import tkinter as tk +from tkinter import ttk + + +class ConfigType(enum.Enum): + STRING = 10 + BOOL = 11 + + +def create_config(master, config, pad_x=2, pad_y=2): + master.columnconfigure(0, weight=1) + master.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") + 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) + 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) + else: + logging.error("unhandled config option type: %s", config_type) + values[key] = value + return values + + +def parse_config(options, values): + config = {} + for key in options: + option = options[key] + value = values[key] + config_type = ConfigType(option.type) + config_value = value.get() + if config_type == ConfigType.BOOL: + if config_value == "On": + config_value = "1" + else: + config_value = "0" + config[key] = config_value + return config diff --git a/coretk/coretk/coremenubar.py b/coretk/coretk/coremenubar.py index 1129e8b7..1a558684 100644 --- a/coretk/coretk/coremenubar.py +++ b/coretk/coretk/coremenubar.py @@ -620,7 +620,7 @@ class CoreMenubar(object): underline=0, ) session_menu.add_command( - label="Options...", command=action.session_options, underline=0 + label="Options...", command=self.menu_action.session_options, underline=0 ) self.menubar.add_cascade(label="Session", menu=session_menu, underline=0) diff --git a/coretk/coretk/dialogs/__init__.py b/coretk/coretk/dialogs/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/coretk/coretk/dialogs/dialog.py b/coretk/coretk/dialogs/dialog.py new file mode 100644 index 00000000..9ce421b9 --- /dev/null +++ b/coretk/coretk/dialogs/dialog.py @@ -0,0 +1,23 @@ +import tkinter as tk + +from coretk.images import ImageEnum, Images + + +class Dialog(tk.Toplevel): + def __init__(self, master, title, modal=False): + super().__init__(master, padx=5, pady=5) + image = Images.get(ImageEnum.CORE.value) + self.tk.call("wm", "iconphoto", self._w, image) + self.title(title) + self.protocol("WM_DELETE_WINDOW", self.destroy) + self.withdraw() + self.modal = modal + + def show(self): + self.transient(self.master) + self.focus_force() + if self.modal: + self.grab_set() + self.update() + self.deiconify() + self.wait_window() diff --git a/coretk/coretk/dialogs/sessionoptions.py b/coretk/coretk/dialogs/sessionoptions.py new file mode 100644 index 00000000..3612dab5 --- /dev/null +++ b/coretk/coretk/dialogs/sessionoptions.py @@ -0,0 +1,35 @@ +import logging +import tkinter as tk + +from coretk import configutils +from coretk.dialogs.dialog import Dialog + +PAD_X = 2 +PAD_Y = 2 + + +class SessionOptionsDialog(Dialog): + def __init__(self, master): + super().__init__(master, "Session Options", modal=True) + self.options = None + self.values = None + self.save_button = tk.Button(self, text="Save", command=self.save) + self.cancel_button = tk.Button(self, text="Cancel", command=self.destroy) + self.draw() + + def draw(self): + session_id = self.master.core_grpc.session_id + response = self.master.core_grpc.core.get_session_options(session_id) + 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") + + def save(self): + config = configutils.parse_config(self.options, self.values) + session_id = self.master.core_grpc.session_id + response = self.master.core_grpc.core.set_session_options(session_id, config) + logging.info("saved session config: %s", response) + self.destroy() diff --git a/coretk/coretk/menuaction.py b/coretk/coretk/menuaction.py index 999801c2..22329516 100644 --- a/coretk/coretk/menuaction.py +++ b/coretk/coretk/menuaction.py @@ -7,6 +7,7 @@ import webbrowser from tkinter import filedialog, messagebox from core.api.grpc import core_pb2 +from coretk.dialogs.sessionoptions import SessionOptionsDialog from coretk.setwallpaper import CanvasWallpaper from coretk.sizeandscale import SizeAndScale @@ -314,10 +315,6 @@ def session_emulation_servers(): logging.debug("Click session emulation servers") -def session_options(): - logging.debug("Click session options") - - def help_about(): logging.debug("Click help About") @@ -433,3 +430,8 @@ class MenuAction: def help_core_documentation(self): webbrowser.open_new("http://coreemu.github.io/core/") + + def session_options(self): + logging.debug("Click session options") + dialog = SessionOptionsDialog(self.application) + dialog.show()