updated and used common frame scroll class where needed, created common config widget to use where all configurations get drawn
This commit is contained in:
parent
b71f93e606
commit
9987637564
4 changed files with 109 additions and 55 deletions
|
@ -28,6 +28,7 @@ class ServicesSelectDialog(Dialog):
|
||||||
for group in sorted(self.app.core.services):
|
for group in sorted(self.app.core.services):
|
||||||
self.groups.listbox.insert(tk.END, group)
|
self.groups.listbox.insert(tk.END, group)
|
||||||
self.groups.listbox.bind("<<ListboxSelect>>", self.handle_group_change)
|
self.groups.listbox.bind("<<ListboxSelect>>", self.handle_group_change)
|
||||||
|
self.groups.listbox.selection_set(0)
|
||||||
|
|
||||||
self.services = CheckboxList(
|
self.services = CheckboxList(
|
||||||
frame, text="Services", clicked=self.service_clicked
|
frame, text="Services", clicked=self.service_clicked
|
||||||
|
@ -46,6 +47,9 @@ class ServicesSelectDialog(Dialog):
|
||||||
button = tk.Button(frame, text="Cancel", command=self.destroy)
|
button = tk.Button(frame, text="Cancel", command=self.destroy)
|
||||||
button.grid(row=0, column=1, sticky="ew")
|
button.grid(row=0, column=1, sticky="ew")
|
||||||
|
|
||||||
|
# trigger group change
|
||||||
|
self.groups.listbox.event_generate("<<ListboxSelect>>")
|
||||||
|
|
||||||
def handle_group_change(self, event):
|
def handle_group_change(self, event):
|
||||||
selection = self.groups.listbox.curselection()
|
selection = self.groups.listbox.curselection()
|
||||||
if selection:
|
if selection:
|
||||||
|
@ -53,7 +57,8 @@ class ServicesSelectDialog(Dialog):
|
||||||
group = self.groups.listbox.get(index)
|
group = self.groups.listbox.get(index)
|
||||||
self.services.clear()
|
self.services.clear()
|
||||||
for service in sorted(self.app.core.services[group], key=lambda x: x.name):
|
for service in sorted(self.app.core.services[group], key=lambda x: x.name):
|
||||||
self.services.add(service.name)
|
checked = service.name in self.current_services
|
||||||
|
self.services.add(service.name, checked)
|
||||||
|
|
||||||
def service_clicked(self, name, var):
|
def service_clicked(self, name, var):
|
||||||
if var.get() and name not in self.current_services:
|
if var.get() and name not in self.current_services:
|
||||||
|
|
|
@ -93,6 +93,7 @@ class EmaneConfiguration(Dialog):
|
||||||
response = self.app.core.client.get_emane_config(session_id)
|
response = self.app.core.client.get_emane_config(session_id)
|
||||||
logging.info("emane config: %s", response)
|
logging.info("emane config: %s", response)
|
||||||
self.options = response.config
|
self.options = response.config
|
||||||
|
|
||||||
self.values = configutils.create_config(
|
self.values = configutils.create_config(
|
||||||
self.emane_dialog, self.options, PAD_X, PAD_Y
|
self.emane_dialog, self.options, PAD_X, PAD_Y
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import logging
|
import logging
|
||||||
import tkinter as tk
|
import tkinter as tk
|
||||||
|
|
||||||
from coretk import configutils
|
|
||||||
from coretk.dialogs.dialog import Dialog
|
from coretk.dialogs.dialog import Dialog
|
||||||
|
from coretk.widgets import ConfigFrame
|
||||||
|
|
||||||
PAD_X = 2
|
PAD_X = 2
|
||||||
PAD_Y = 2
|
PAD_Y = 2
|
||||||
|
@ -11,25 +11,33 @@ PAD_Y = 2
|
||||||
class SessionOptionsDialog(Dialog):
|
class SessionOptionsDialog(Dialog):
|
||||||
def __init__(self, master, app):
|
def __init__(self, master, app):
|
||||||
super().__init__(master, app, "Session Options", modal=True)
|
super().__init__(master, app, "Session Options", modal=True)
|
||||||
self.options = None
|
self.config_frame = 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()
|
self.draw()
|
||||||
|
|
||||||
def draw(self):
|
def draw(self):
|
||||||
|
self.columnconfigure(0, weight=1)
|
||||||
|
self.rowconfigure(0, weight=1)
|
||||||
|
|
||||||
session_id = self.app.core.session_id
|
session_id = self.app.core.session_id
|
||||||
response = self.app.core.client.get_session_options(session_id)
|
response = self.app.core.client.get_session_options(session_id)
|
||||||
logging.info("session options: %s", response)
|
logging.info("session options: %s", response)
|
||||||
self.options = response.config
|
|
||||||
self.values = configutils.create_config(self, self.options, PAD_X, PAD_Y)
|
self.config_frame = ConfigFrame(self, config=response.config)
|
||||||
self.save_button.grid(row=1, pady=PAD_Y, padx=PAD_X, sticky="ew")
|
self.config_frame.draw_config()
|
||||||
self.cancel_button.grid(row=1, column=1, pady=PAD_Y, padx=PAD_X, sticky="ew")
|
self.config_frame.grid(sticky="nsew")
|
||||||
|
|
||||||
|
frame = tk.Frame(self)
|
||||||
|
frame.grid(sticky="ew")
|
||||||
|
for i in range(2):
|
||||||
|
frame.columnconfigure(i, weight=1)
|
||||||
|
button = tk.Button(frame, text="Save", command=self.save)
|
||||||
|
button.grid(row=0, column=0, pady=PAD_Y, padx=PAD_X, sticky="ew")
|
||||||
|
button = tk.Button(frame, text="Cancel", command=self.destroy)
|
||||||
|
button.grid(row=0, column=1, pady=PAD_Y, padx=PAD_X, sticky="ew")
|
||||||
|
|
||||||
def save(self):
|
def save(self):
|
||||||
configutils.parse_config(self.options, self.values)
|
config = self.config_frame.parse_config()
|
||||||
session_id = self.app.core.session_id
|
session_id = self.app.core.session_id
|
||||||
config = {x: self.options[x].value for x in self.options}
|
|
||||||
response = self.app.core.client.set_session_options(session_id, config)
|
response = self.app.core.client.set_session_options(session_id, config)
|
||||||
logging.info("saved session config: %s", response)
|
logging.info("saved session config: %s", response)
|
||||||
self.destroy()
|
self.destroy()
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
|
import logging
|
||||||
import tkinter as tk
|
import tkinter as tk
|
||||||
from functools import partial
|
from functools import partial
|
||||||
|
from tkinter import ttk
|
||||||
|
|
||||||
|
from coretk.configutils import ConfigType
|
||||||
|
|
||||||
|
|
||||||
class FrameScroll(tk.LabelFrame):
|
class FrameScroll(tk.LabelFrame):
|
||||||
|
@ -7,29 +11,39 @@ class FrameScroll(tk.LabelFrame):
|
||||||
super().__init__(master, cnf, **kw)
|
super().__init__(master, cnf, **kw)
|
||||||
self.rowconfigure(0, weight=1)
|
self.rowconfigure(0, weight=1)
|
||||||
self.columnconfigure(0, weight=1)
|
self.columnconfigure(0, weight=1)
|
||||||
self.columnconfigure(1, weight=1)
|
|
||||||
self.canvas = tk.Canvas(self, highlightthickness=0)
|
self.canvas = tk.Canvas(self, highlightthickness=0)
|
||||||
self.canvas.grid(row=0, columnspan=2, sticky="nsew", padx=2, pady=2)
|
self.canvas.grid(row=0, sticky="nsew", padx=2, pady=2)
|
||||||
self.canvas.columnconfigure(0, weight=1)
|
self.canvas.columnconfigure(0, weight=1)
|
||||||
self.canvas.rowconfigure(0, weight=1)
|
self.canvas.rowconfigure(0, weight=1)
|
||||||
self.scrollbar = tk.Scrollbar(
|
self.scrollbar = tk.Scrollbar(
|
||||||
self, orient="vertical", command=self.canvas.yview
|
self, orient="vertical", command=self.canvas.yview
|
||||||
)
|
)
|
||||||
self.scrollbar.grid(row=0, column=2, sticky="ns")
|
self.scrollbar.grid(row=0, column=1, sticky="ns")
|
||||||
self.frame = tk.Frame(self.canvas, padx=2, pady=2)
|
self.frame = tk.Frame(self.canvas, padx=2, pady=2)
|
||||||
self.frame.columnconfigure(0, weight=1)
|
|
||||||
self.frame_id = self.canvas.create_window(0, 0, anchor="nw", window=self.frame)
|
self.frame_id = self.canvas.create_window(0, 0, anchor="nw", window=self.frame)
|
||||||
self.canvas.update_idletasks()
|
self.canvas.update_idletasks()
|
||||||
self.canvas.configure(
|
self.canvas.configure(
|
||||||
scrollregion=self.canvas.bbox("all"), yscrollcommand=self.scrollbar.set
|
scrollregion=self.canvas.bbox("all"), yscrollcommand=self.scrollbar.set
|
||||||
)
|
)
|
||||||
self.frame.bind(
|
self.frame.bind("<Configure>", self._configure_frame)
|
||||||
"<Configure>",
|
self.canvas.bind("<Configure>", self._configure_canvas)
|
||||||
lambda event: self.canvas.configure(scrollregion=self.canvas.bbox("all")),
|
|
||||||
)
|
def _configure_frame(self, event):
|
||||||
self.canvas.bind(
|
req_width = self.frame.winfo_reqwidth()
|
||||||
"<Configure>",
|
req_height = self.frame.winfo_reqheight()
|
||||||
lambda event: self.canvas.itemconfig(self.frame_id, width=event.width),
|
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):
|
||||||
|
self.canvas.itemconfig(self.frame_id, width=event.width)
|
||||||
|
|
||||||
|
def update_canvas(self):
|
||||||
|
self.canvas.update_idletasks()
|
||||||
|
self.canvas.configure(
|
||||||
|
scrollregion=self.canvas.bbox("all"), yscrollcommand=self.scrollbar.set
|
||||||
)
|
)
|
||||||
|
|
||||||
def clear(self):
|
def clear(self):
|
||||||
|
@ -37,6 +51,61 @@ class FrameScroll(tk.LabelFrame):
|
||||||
widget.destroy()
|
widget.destroy()
|
||||||
|
|
||||||
|
|
||||||
|
class ConfigFrame(FrameScroll):
|
||||||
|
def __init__(self, master=None, cnf={}, config=None, **kw):
|
||||||
|
super().__init__(master, cnf, **kw)
|
||||||
|
self.frame.columnconfigure(1, weight=1)
|
||||||
|
if not config:
|
||||||
|
config = {}
|
||||||
|
self.config = config
|
||||||
|
self.values = {}
|
||||||
|
|
||||||
|
def draw_config(self):
|
||||||
|
padx = 2
|
||||||
|
pady = 2
|
||||||
|
for index, key in enumerate(sorted(self.config)):
|
||||||
|
option = self.config[key]
|
||||||
|
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:
|
||||||
|
select = tuple(option.select)
|
||||||
|
combobox = ttk.Combobox(self.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(self.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(self.frame, textvariable=value)
|
||||||
|
entry.grid(row=index, column=1, sticky="ew", pady=pady)
|
||||||
|
else:
|
||||||
|
logging.error("unhandled config option type: %s", config_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 config_value == "On":
|
||||||
|
option.value = "1"
|
||||||
|
else:
|
||||||
|
option.value = "0"
|
||||||
|
else:
|
||||||
|
option.value = config_value
|
||||||
|
|
||||||
|
return {x: self.config[x].value for x in self.config}
|
||||||
|
|
||||||
|
|
||||||
class ListboxScroll(tk.LabelFrame):
|
class ListboxScroll(tk.LabelFrame):
|
||||||
def __init__(self, master=None, cnf={}, **kw):
|
def __init__(self, master=None, cnf={}, **kw):
|
||||||
super().__init__(master, cnf, **kw)
|
super().__init__(master, cnf, **kw)
|
||||||
|
@ -51,43 +120,14 @@ class ListboxScroll(tk.LabelFrame):
|
||||||
self.scrollbar.config(command=self.listbox.yview)
|
self.scrollbar.config(command=self.listbox.yview)
|
||||||
|
|
||||||
|
|
||||||
class CheckboxList(tk.LabelFrame):
|
class CheckboxList(FrameScroll):
|
||||||
def __init__(self, master=None, cnf={}, clicked=None, **kw):
|
def __init__(self, master=None, cnf={}, clicked=None, **kw):
|
||||||
super().__init__(master, cnf, **kw)
|
super().__init__(master, cnf, **kw)
|
||||||
self.clicked = clicked
|
self.clicked = clicked
|
||||||
self.rowconfigure(0, weight=1)
|
|
||||||
self.columnconfigure(0, weight=1)
|
|
||||||
self.columnconfigure(1, weight=1)
|
|
||||||
self.canvas = tk.Canvas(self, highlightthickness=0)
|
|
||||||
self.canvas.grid(row=0, columnspan=2, sticky="nsew", padx=2, pady=2)
|
|
||||||
self.canvas.columnconfigure(0, weight=1)
|
|
||||||
self.canvas.rowconfigure(0, weight=1)
|
|
||||||
self.scrollbar = tk.Scrollbar(
|
|
||||||
self, orient="vertical", command=self.canvas.yview
|
|
||||||
)
|
|
||||||
self.scrollbar.grid(row=0, column=2, sticky="ns")
|
|
||||||
self.frame = tk.Frame(self.canvas, padx=2, pady=2)
|
|
||||||
self.frame.columnconfigure(0, weight=1)
|
self.frame.columnconfigure(0, weight=1)
|
||||||
self.frame_id = self.canvas.create_window(0, 0, anchor="nw", window=self.frame)
|
|
||||||
self.canvas.update_idletasks()
|
|
||||||
self.canvas.configure(
|
|
||||||
scrollregion=self.canvas.bbox("all"), yscrollcommand=self.scrollbar.set
|
|
||||||
)
|
|
||||||
self.frame.bind(
|
|
||||||
"<Configure>",
|
|
||||||
lambda event: self.canvas.configure(scrollregion=self.canvas.bbox("all")),
|
|
||||||
)
|
|
||||||
self.canvas.bind(
|
|
||||||
"<Configure>",
|
|
||||||
lambda event: self.canvas.itemconfig(self.frame_id, width=event.width),
|
|
||||||
)
|
|
||||||
|
|
||||||
def clear(self):
|
def add(self, name, checked):
|
||||||
for widget in self.frame.winfo_children():
|
var = tk.BooleanVar(value=checked)
|
||||||
widget.destroy()
|
|
||||||
|
|
||||||
def add(self, name):
|
|
||||||
var = tk.BooleanVar()
|
|
||||||
func = partial(self.clicked, name, var)
|
func = partial(self.clicked, name, var)
|
||||||
checkbox = tk.Checkbutton(self.frame, text=name, variable=var, command=func)
|
checkbox = tk.Checkbutton(self.frame, text=name, variable=var, command=func)
|
||||||
checkbox.grid(sticky="w")
|
checkbox.grid(sticky="w")
|
||||||
|
|
Loading…
Add table
Reference in a new issue