updated config generation to use config frame where possible

This commit is contained in:
bharnden 2019-11-06 20:49:09 -08:00
parent 9987637564
commit 0147bb9988
3 changed files with 65 additions and 140 deletions

View file

@ -1,99 +0,0 @@
import enum
import logging
import tkinter as tk
from tkinter import ttk
class ConfigType(enum.Enum):
STRING = 10
BOOL = 11
EMANECONFIG = 7
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=1)
canvas = tk.Canvas(master, highlightthickness=0)
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(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(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:
value.set(option.value)
entry = tk.Entry(frame, textvariable=value)
entry.grid(row=index, column=1, sticky="ew", pady=pady)
elif config_type == ConfigType.EMANECONFIG:
value.set(option.value)
entry = tk.Entry(frame, textvariable=value, bg="white")
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(
"<Configure>", lambda event: canvas.configure(scrollregion=canvas.bbox("all"))
)
canvas.bind(
"<Configure>", 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: nothing
"""
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":
option.value = "1"
else:
option.value = "0"
else:
option.value = config_value

View file

@ -7,9 +7,9 @@ import tkinter as tk
import webbrowser
from tkinter import ttk
from coretk import configutils
from coretk.dialogs.dialog import Dialog
from coretk.images import ImageEnum, Images
from coretk.widgets import ConfigFrame
PAD_X = 2
PAD_Y = 2
@ -38,10 +38,10 @@ class EmaneConfiguration(Dialog):
self.emane_options()
self.draw_apply_and_cancel()
self.values = None
self.emane_config_frame = None
self.options = app.core.emane_config
self.model_options = None
self.model_values = None
self.model_config_frame = None
def create_text_variable(self, val):
"""
@ -75,7 +75,7 @@ class EmaneConfiguration(Dialog):
f.grid(row=0, column=0, sticky="nsew")
def save_emane_option(self):
configutils.parse_config(self.options, self.values)
self.emane_config_frame.parse_config()
self.emane_dialog.destroy()
def draw_emane_options(self):
@ -83,10 +83,6 @@ class EmaneConfiguration(Dialog):
self.emane_dialog = Dialog(
self, self.app, "emane configuration", modal=False
)
b1 = tk.Button(self.emane_dialog, text="Appy", command=self.save_emane_option)
b2 = tk.Button(
self.emane_dialog, text="Cancel", command=self.emane_dialog.destroy
)
if self.options is None:
session_id = self.app.core.session_id
@ -94,11 +90,20 @@ class EmaneConfiguration(Dialog):
logging.info("emane config: %s", response)
self.options = response.config
self.values = configutils.create_config(
self.emane_dialog, self.options, PAD_X, PAD_Y
)
b1.grid(row=1, column=0)
b2.grid(row=1, column=1)
self.emane_dialog.columnconfigure(0, weight=1)
self.emane_dialog.rowconfigure(0, weight=1)
self.emane_config_frame = ConfigFrame(self.emane_dialog, config=self.options)
self.emane_config_frame.draw_config()
self.emane_config_frame.grid(sticky="nsew")
frame = tk.Frame(self.emane_dialog)
frame.grid(sticky="ew")
for i in range(2):
frame.columnconfigure(i, weight=1)
b1 = tk.Button(frame, text="Appy", command=self.save_emane_option)
b1.grid(row=0, column=0, sticky="ew")
b2 = tk.Button(frame, text="Cancel", command=self.emane_dialog.destroy)
b2.grid(row=0, column=1, sticky="ew")
self.emane_dialog.show()
def save_emane_model_options(self):
@ -111,8 +116,7 @@ class EmaneConfiguration(Dialog):
model_name = self.emane_models[self.emane_model_combobox.current()]
# parse configuration
configutils.parse_config(self.model_options, self.model_values)
config = {x: self.model_options[x].value for x in self.model_options}
config = self.model_config_frame.parse_config()
# add string emane_ infront for grpc call
response = self.app.core.client.set_emane_model_config(
@ -141,17 +145,10 @@ class EmaneConfiguration(Dialog):
# create the dialog and the necessry widget
if not self.emane_model_dialog or not self.emane_model_dialog.winfo_exists():
self.emane_model_dialog = Dialog(
self, self.app, model_name + " configuration", modal=False
self, self.app, f"{model_name} configuration", modal=False
)
b1 = tk.Button(
self.emane_model_dialog, text="Apply", command=self.save_emane_model_options
)
b2 = tk.Button(
self.emane_model_dialog,
text="Cancel",
command=self.emane_model_dialog.destroy,
)
self.emane_model_dialog.columnconfigure(0, weight=1)
self.emane_model_dialog.rowconfigure(0, weight=1)
# query for configurations
session_id = self.app.core.session_id
@ -162,12 +159,20 @@ class EmaneConfiguration(Dialog):
logging.info("emane model config %s", response)
self.model_options = response.config
self.model_values = configutils.create_config(
self.emane_model_dialog, self.model_options, PAD_X, PAD_Y
self.model_config_frame = ConfigFrame(
self.emane_model_dialog, config=self.model_options
)
self.model_config_frame.grid(sticky="nsew")
self.model_config_frame.draw_config()
b1.grid(row=1, column=0, sticky="nsew")
b2.grid(row=1, column=1, sticky="nsew")
frame = tk.Frame(self.emane_model_dialog)
frame.grid(sticky="ew")
for i in range(2):
frame.columnconfigure(i, weight=1)
b1 = tk.Button(frame, text="Apply", command=self.save_emane_model_options)
b1.grid(row=0, column=0, sticky="ew")
b2 = tk.Button(frame, text="Cancel", command=self.emane_model_dialog.destroy)
b2.grid(row=0, column=1, sticky="ew")
self.emane_model_dialog.show()
def draw_option_buttons(self, parent):

View file

@ -3,7 +3,18 @@ import tkinter as tk
from functools import partial
from tkinter import ttk
from coretk.configutils import ConfigType
from core.api.grpc import core_pb2
INT_TYPES = {
core_pb2.ConfigOptionType.UINT8,
core_pb2.ConfigOptionType.UINT16,
core_pb2.ConfigOptionType.UINT32,
core_pb2.ConfigOptionType.UINT64,
core_pb2.ConfigOptionType.INT8,
core_pb2.ConfigOptionType.INT16,
core_pb2.ConfigOptionType.INT32,
core_pb2.ConfigOptionType.INT64,
}
class FrameScroll(tk.LabelFrame):
@ -30,11 +41,8 @@ class FrameScroll(tk.LabelFrame):
def _configure_frame(self, event):
req_width = self.frame.winfo_reqwidth()
req_height = self.frame.winfo_reqheight()
if req_width != self.canvas.winfo_reqwidth():
self.canvas.configure(width=req_width)
if req_height != self.canvas.winfo_reqheight():
self.canvas.configure(height=req_height)
self.canvas.configure(scrollregion=self.canvas.bbox("all"))
def _configure_canvas(self, event):
@ -68,34 +76,45 @@ class ConfigFrame(FrameScroll):
label = tk.Label(self.frame, text=option.label)
label.grid(row=index, pady=pady, padx=padx, sticky="w")
value = tk.StringVar()
config_type = ConfigType(option.type)
if config_type == ConfigType.BOOL:
if option.type == core_pb2.ConfigOptionType.BOOL:
select = tuple(option.select)
combobox = ttk.Combobox(self.frame, textvariable=value, values=select)
combobox = ttk.Combobox(
self.frame, textvariable=value, values=select, state="readonly"
)
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:
elif option.select:
value.set(option.value)
select = tuple(option.select)
combobox = ttk.Combobox(
self.frame, textvariable=value, values=select, state="readonly"
)
combobox.grid(row=index, column=1, sticky="ew", pady=pady)
elif option.type == core_pb2.ConfigOptionType.STRING:
value.set(option.value)
entry = tk.Entry(self.frame, textvariable=value)
entry.grid(row=index, column=1, sticky="ew", pady=pady)
elif config_type == ConfigType.EMANECONFIG:
elif option.type in INT_TYPES:
value.set(option.value)
entry = tk.Entry(self.frame, textvariable=value)
entry.grid(row=index, column=1, sticky="ew", pady=pady)
elif option.type == core_pb2.ConfigOptionType.FLOAT:
value.set(option.value)
entry = tk.Entry(self.frame, textvariable=value)
entry.grid(row=index, column=1, sticky="ew", pady=pady)
else:
logging.error("unhandled config option type: %s", config_type)
logging.error("unhandled config option type: %s", option.type)
self.values[key] = value
def parse_config(self):
for key in self.config:
option = self.config[key]
value = self.values[key]
config_type = ConfigType(option.type)
config_value = value.get()
if config_type == ConfigType.BOOL:
if option.type == core_pb2.ConfigOptionType.BOOL:
if config_value == "On":
option.value = "1"
else: