Merge branch 'coretk' into coretk-selectbox

This commit is contained in:
Huy Pham 2019-12-11 14:43:34 -08:00
commit 489d28d2fd
27 changed files with 366 additions and 325 deletions

View file

@ -14,6 +14,9 @@ from coretk.statusbar import StatusBar
from coretk.toolbar import Toolbar from coretk.toolbar import Toolbar
from coretk.validation import InputValidation from coretk.validation import InputValidation
WIDTH = 1000
HEIGHT = 800
class Application(tk.Frame): class Application(tk.Frame):
def __init__(self, master=None): def __init__(self, master=None):
@ -40,8 +43,10 @@ class Application(tk.Frame):
def setup_theme(self): def setup_theme(self):
themes.load(self.style) themes.load(self.style)
self.style.theme_use(self.guiconfig["preferences"]["theme"]) self.style.theme_use(self.guiconfig["preferences"]["theme"])
func = partial(themes.update_menu, self.style) func = partial(themes.theme_change_menu, self.style)
self.master.bind_class("Menu", "<<ThemeChanged>>", func) self.master.bind_class("Menu", "<<ThemeChanged>>", func)
func = partial(themes.theme_change, self.style)
self.master.bind("<<ThemeChanged>>", func)
def setup_app(self): def setup_app(self):
self.master.title("CORE") self.master.title("CORE")
@ -53,13 +58,11 @@ class Application(tk.Frame):
self.validation = InputValidation(self) self.validation = InputValidation(self)
def center(self): def center(self):
width = 1000
height = 800
screen_width = self.master.winfo_screenwidth() screen_width = self.master.winfo_screenwidth()
screen_height = self.master.winfo_screenheight() screen_height = self.master.winfo_screenheight()
x = int((screen_width / 2) - (width / 2)) x = int((screen_width / 2) - (WIDTH / 2))
y = int((screen_height / 2) - (height / 2)) y = int((screen_height / 2) - (HEIGHT / 2))
self.master.geometry(f"{width}x{height}+{x}+{y}") self.master.geometry(f"{WIDTH}x{HEIGHT}+{x}+{y}")
def draw(self): def draw(self):
self.master.option_add("*tearOff", tk.FALSE) self.master.option_add("*tearOff", tk.FALSE)

View file

@ -75,7 +75,7 @@ def check_directory():
editor = EDITORS[1] editor = EDITORS[1]
config = { config = {
"preferences": { "preferences": {
"theme": themes.DARK, "theme": themes.THEME_DARK,
"editor": editor, "editor": editor,
"terminal": terminal, "terminal": terminal,
"gui3d": "/usr/local/bin/std3d.sh", "gui3d": "/usr/local/bin/std3d.sh",

View file

@ -5,8 +5,8 @@ import tkinter as tk
from tkinter import font, ttk from tkinter import font, ttk
from coretk.dialogs.dialog import Dialog from coretk.dialogs.dialog import Dialog
from coretk.themes import FRAME_PAD, PADX, PADY
PAD = 5
PIXEL_SCALE = 100 PIXEL_SCALE = 100
@ -46,20 +46,21 @@ class SizeAndScaleDialog(Dialog):
self.draw_scale() self.draw_scale()
self.draw_reference_point() self.draw_reference_point()
self.draw_save_as_default() self.draw_save_as_default()
self.draw_spacer()
self.draw_buttons() self.draw_buttons()
def draw_size(self): def draw_size(self):
label_frame = ttk.Labelframe(self.top, text="Size", padding=PAD) label_frame = ttk.Labelframe(self.top, text="Size", padding=FRAME_PAD)
label_frame.grid(sticky="ew") label_frame.grid(sticky="ew")
label_frame.columnconfigure(0, weight=1) label_frame.columnconfigure(0, weight=1)
# draw size row 1 # draw size row 1
frame = ttk.Frame(label_frame) frame = ttk.Frame(label_frame)
frame.grid(sticky="ew", pady=3) frame.grid(sticky="ew", pady=PADY)
frame.columnconfigure(1, weight=1) frame.columnconfigure(1, weight=1)
frame.columnconfigure(3, weight=1) frame.columnconfigure(3, weight=1)
label = ttk.Label(frame, text="Width") label = ttk.Label(frame, text="Width")
label.grid(row=0, column=0, sticky="w", padx=PAD) label.grid(row=0, column=0, sticky="w", padx=PADX)
entry = ttk.Entry( entry = ttk.Entry(
frame, frame,
textvariable=self.pixel_width, textvariable=self.pixel_width,
@ -67,9 +68,9 @@ class SizeAndScaleDialog(Dialog):
validatecommand=(self.validation.positive_int, "%P"), validatecommand=(self.validation.positive_int, "%P"),
) )
entry.bind("<FocusOut>", lambda event: self.validation.focus_out(event, "0")) entry.bind("<FocusOut>", lambda event: self.validation.focus_out(event, "0"))
entry.grid(row=0, column=1, sticky="ew", padx=PAD) entry.grid(row=0, column=1, sticky="ew", padx=PADX)
label = ttk.Label(frame, text="x Height") label = ttk.Label(frame, text="x Height")
label.grid(row=0, column=2, sticky="w", padx=PAD) label.grid(row=0, column=2, sticky="w", padx=PADX)
entry = ttk.Entry( entry = ttk.Entry(
frame, frame,
textvariable=self.pixel_height, textvariable=self.pixel_height,
@ -77,17 +78,17 @@ class SizeAndScaleDialog(Dialog):
validatecommand=(self.validation.positive_int, "%P"), validatecommand=(self.validation.positive_int, "%P"),
) )
entry.bind("<FocusOut>", lambda event: self.validation.focus_out(event, "0")) entry.bind("<FocusOut>", lambda event: self.validation.focus_out(event, "0"))
entry.grid(row=0, column=3, sticky="ew", padx=PAD) entry.grid(row=0, column=3, sticky="ew", padx=PADX)
label = ttk.Label(frame, text="Pixels") label = ttk.Label(frame, text="Pixels")
label.grid(row=0, column=4, sticky="w") label.grid(row=0, column=4, sticky="w")
# draw size row 2 # draw size row 2
frame = ttk.Frame(label_frame) frame = ttk.Frame(label_frame)
frame.grid(sticky="ew", pady=3) frame.grid(sticky="ew", pady=PADY)
frame.columnconfigure(1, weight=1) frame.columnconfigure(1, weight=1)
frame.columnconfigure(3, weight=1) frame.columnconfigure(3, weight=1)
label = ttk.Label(frame, text="Width") label = ttk.Label(frame, text="Width")
label.grid(row=0, column=0, sticky="w", padx=PAD) label.grid(row=0, column=0, sticky="w", padx=PADX)
entry = ttk.Entry( entry = ttk.Entry(
frame, frame,
textvariable=self.meters_width, textvariable=self.meters_width,
@ -95,9 +96,9 @@ class SizeAndScaleDialog(Dialog):
validatecommand=(self.validation.positive_float, "%P"), validatecommand=(self.validation.positive_float, "%P"),
) )
entry.bind("<FocusOut>", lambda event: self.validation.focus_out(event, "0")) entry.bind("<FocusOut>", lambda event: self.validation.focus_out(event, "0"))
entry.grid(row=0, column=1, sticky="ew", padx=PAD) entry.grid(row=0, column=1, sticky="ew", padx=PADX)
label = ttk.Label(frame, text="x Height") label = ttk.Label(frame, text="x Height")
label.grid(row=0, column=2, sticky="w", padx=PAD) label.grid(row=0, column=2, sticky="w", padx=PADX)
entry = ttk.Entry( entry = ttk.Entry(
frame, frame,
textvariable=self.meters_height, textvariable=self.meters_height,
@ -105,12 +106,12 @@ class SizeAndScaleDialog(Dialog):
validatecommand=(self.validation.positive_float, "%P"), validatecommand=(self.validation.positive_float, "%P"),
) )
entry.bind("<FocusOut>", lambda event: self.validation.focus_out(event, "0")) entry.bind("<FocusOut>", lambda event: self.validation.focus_out(event, "0"))
entry.grid(row=0, column=3, sticky="ew", padx=PAD) entry.grid(row=0, column=3, sticky="ew", padx=PADX)
label = ttk.Label(frame, text="Meters") label = ttk.Label(frame, text="Meters")
label.grid(row=0, column=4, sticky="w") label.grid(row=0, column=4, sticky="w")
def draw_scale(self): def draw_scale(self):
label_frame = ttk.Labelframe(self.top, text="Scale", padding=PAD) label_frame = ttk.Labelframe(self.top, text="Scale", padding=FRAME_PAD)
label_frame.grid(sticky="ew") label_frame.grid(sticky="ew")
label_frame.columnconfigure(0, weight=1) label_frame.columnconfigure(0, weight=1)
@ -118,7 +119,7 @@ class SizeAndScaleDialog(Dialog):
frame.grid(sticky="ew") frame.grid(sticky="ew")
frame.columnconfigure(1, weight=1) frame.columnconfigure(1, weight=1)
label = ttk.Label(frame, text=f"{PIXEL_SCALE} Pixels =") label = ttk.Label(frame, text=f"{PIXEL_SCALE} Pixels =")
label.grid(row=0, column=0, sticky="w", padx=PAD) label.grid(row=0, column=0, sticky="w", padx=PADX)
entry = ttk.Entry( entry = ttk.Entry(
frame, frame,
textvariable=self.scale, textvariable=self.scale,
@ -126,12 +127,14 @@ class SizeAndScaleDialog(Dialog):
validatecommand=(self.validation.positive_float, "%P"), validatecommand=(self.validation.positive_float, "%P"),
) )
entry.bind("<FocusOut>", lambda event: self.validation.focus_out(event, "0")) entry.bind("<FocusOut>", lambda event: self.validation.focus_out(event, "0"))
entry.grid(row=0, column=1, sticky="ew", padx=PAD) entry.grid(row=0, column=1, sticky="ew", padx=PADX)
label = ttk.Label(frame, text="Meters") label = ttk.Label(frame, text="Meters")
label.grid(row=0, column=2, sticky="w") label.grid(row=0, column=2, sticky="w")
def draw_reference_point(self): def draw_reference_point(self):
label_frame = ttk.Labelframe(self.top, text="Reference Point", padding=PAD) label_frame = ttk.Labelframe(
self.top, text="Reference Point", padding=FRAME_PAD
)
label_frame.grid(sticky="ew") label_frame.grid(sticky="ew")
label_frame.columnconfigure(0, weight=1) label_frame.columnconfigure(0, weight=1)
@ -141,12 +144,12 @@ class SizeAndScaleDialog(Dialog):
label.grid() label.grid()
frame = ttk.Frame(label_frame) frame = ttk.Frame(label_frame)
frame.grid(sticky="ew", pady=3) frame.grid(sticky="ew", pady=PADY)
frame.columnconfigure(1, weight=1) frame.columnconfigure(1, weight=1)
frame.columnconfigure(3, weight=1) frame.columnconfigure(3, weight=1)
label = ttk.Label(frame, text="X") label = ttk.Label(frame, text="X")
label.grid(row=0, column=0, sticky="w", padx=PAD) label.grid(row=0, column=0, sticky="w", padx=PADX)
entry = ttk.Entry( entry = ttk.Entry(
frame, frame,
textvariable=self.x, textvariable=self.x,
@ -154,10 +157,10 @@ class SizeAndScaleDialog(Dialog):
validatecommand=(self.validation.positive_float, "%P"), validatecommand=(self.validation.positive_float, "%P"),
) )
entry.bind("<FocusOut>", lambda event: self.validation.focus_out(event, "0")) entry.bind("<FocusOut>", lambda event: self.validation.focus_out(event, "0"))
entry.grid(row=0, column=1, sticky="ew", padx=PAD) entry.grid(row=0, column=1, sticky="ew", padx=PADX)
label = ttk.Label(frame, text="Y") label = ttk.Label(frame, text="Y")
label.grid(row=0, column=2, sticky="w", padx=PAD) label.grid(row=0, column=2, sticky="w", padx=PADX)
entry = ttk.Entry( entry = ttk.Entry(
frame, frame,
textvariable=self.y, textvariable=self.y,
@ -165,19 +168,19 @@ class SizeAndScaleDialog(Dialog):
validatecommand=(self.validation.positive_float, "%P"), validatecommand=(self.validation.positive_float, "%P"),
) )
entry.bind("<FocusOut>", lambda event: self.validation.focus_out(event, "0")) entry.bind("<FocusOut>", lambda event: self.validation.focus_out(event, "0"))
entry.grid(row=0, column=3, sticky="ew", padx=PAD) entry.grid(row=0, column=3, sticky="ew", padx=PADX)
label = ttk.Label(label_frame, text="Translates To") label = ttk.Label(label_frame, text="Translates To")
label.grid() label.grid()
frame = ttk.Frame(label_frame) frame = ttk.Frame(label_frame)
frame.grid(sticky="ew", pady=3) frame.grid(sticky="ew", pady=PADY)
frame.columnconfigure(1, weight=1) frame.columnconfigure(1, weight=1)
frame.columnconfigure(3, weight=1) frame.columnconfigure(3, weight=1)
frame.columnconfigure(5, weight=1) frame.columnconfigure(5, weight=1)
label = ttk.Label(frame, text="Lat") label = ttk.Label(frame, text="Lat")
label.grid(row=0, column=0, sticky="w", padx=PAD) label.grid(row=0, column=0, sticky="w", padx=PADX)
entry = ttk.Entry( entry = ttk.Entry(
frame, frame,
textvariable=self.lat, textvariable=self.lat,
@ -185,10 +188,10 @@ class SizeAndScaleDialog(Dialog):
validatecommand=(self.validation.positive_float, "%P"), validatecommand=(self.validation.positive_float, "%P"),
) )
entry.bind("<FocusOut>", lambda event: self.validation.focus_out(event, "0")) entry.bind("<FocusOut>", lambda event: self.validation.focus_out(event, "0"))
entry.grid(row=0, column=1, sticky="ew", padx=PAD) entry.grid(row=0, column=1, sticky="ew", padx=PADX)
label = ttk.Label(frame, text="Lon") label = ttk.Label(frame, text="Lon")
label.grid(row=0, column=2, sticky="w", padx=PAD) label.grid(row=0, column=2, sticky="w", padx=PADX)
entry = ttk.Entry( entry = ttk.Entry(
frame, frame,
textvariable=self.lon, textvariable=self.lon,
@ -196,10 +199,10 @@ class SizeAndScaleDialog(Dialog):
validatecommand=(self.validation.positive_float, "%P"), validatecommand=(self.validation.positive_float, "%P"),
) )
entry.bind("<FocusOut>", lambda event: self.validation.focus_out(event, "0")) entry.bind("<FocusOut>", lambda event: self.validation.focus_out(event, "0"))
entry.grid(row=0, column=3, sticky="ew", padx=PAD) entry.grid(row=0, column=3, sticky="ew", padx=PADX)
label = ttk.Label(frame, text="Alt") label = ttk.Label(frame, text="Alt")
label.grid(row=0, column=4, sticky="w", padx=PAD) label.grid(row=0, column=4, sticky="w", padx=PADX)
entry = ttk.Entry( entry = ttk.Entry(
frame, frame,
textvariable=self.alt, textvariable=self.alt,
@ -213,7 +216,7 @@ class SizeAndScaleDialog(Dialog):
button = ttk.Checkbutton( button = ttk.Checkbutton(
self.top, text="Save as default?", variable=self.save_default self.top, text="Save as default?", variable=self.save_default
) )
button.grid(sticky="w", pady=3) button.grid(sticky="w", pady=PADY)
def draw_buttons(self): def draw_buttons(self):
frame = ttk.Frame(self.top) frame = ttk.Frame(self.top)
@ -222,7 +225,7 @@ class SizeAndScaleDialog(Dialog):
frame.grid(sticky="ew") frame.grid(sticky="ew")
button = ttk.Button(frame, text="Apply", command=self.click_apply) button = ttk.Button(frame, text="Apply", command=self.click_apply)
button.grid(row=0, column=0, sticky="ew", padx=PAD) button.grid(row=0, column=0, sticky="ew", padx=PADX)
button = ttk.Button(frame, text="Cancel", command=self.destroy) button = ttk.Button(frame, text="Cancel", command=self.destroy)
button.grid(row=0, column=1, sticky="ew") button.grid(row=0, column=1, sticky="ew")

View file

@ -8,8 +8,7 @@ from tkinter import filedialog, ttk
from coretk.appconfig import BACKGROUNDS_PATH from coretk.appconfig import BACKGROUNDS_PATH
from coretk.dialogs.dialog import Dialog from coretk.dialogs.dialog import Dialog
from coretk.images import Images from coretk.images import Images
from coretk.themes import PADX, PADY
PADX = 5
class CanvasBackgroundDialog(Dialog): class CanvasBackgroundDialog(Dialog):
@ -36,17 +35,18 @@ class CanvasBackgroundDialog(Dialog):
self.draw_image_selection() self.draw_image_selection()
self.draw_options() self.draw_options()
self.draw_additional_options() self.draw_additional_options()
self.draw_spacer()
self.draw_buttons() self.draw_buttons()
def draw_image(self): def draw_image(self):
self.image_label = ttk.Label( self.image_label = ttk.Label(
self.top, text="(image preview)", width=32, anchor=tk.CENTER self.top, text="(image preview)", width=32, anchor=tk.CENTER
) )
self.image_label.grid(row=0, column=0, pady=5) self.image_label.grid(pady=PADY)
def draw_image_label(self): def draw_image_label(self):
label = ttk.Label(self.top, text="Image filename: ") label = ttk.Label(self.top, text="Image filename: ")
label.grid(row=1, column=0, sticky="ew") label.grid(sticky="ew")
if self.filename.get(): if self.filename.get():
self.draw_preview() self.draw_preview()
@ -55,7 +55,7 @@ class CanvasBackgroundDialog(Dialog):
frame.columnconfigure(0, weight=2) frame.columnconfigure(0, weight=2)
frame.columnconfigure(1, weight=1) frame.columnconfigure(1, weight=1)
frame.columnconfigure(2, weight=1) frame.columnconfigure(2, weight=1)
frame.grid(row=2, column=0, sticky="ew") frame.grid(sticky="ew")
entry = ttk.Entry(frame, textvariable=self.filename) entry = ttk.Entry(frame, textvariable=self.filename)
entry.focus() entry.focus()
@ -73,7 +73,7 @@ class CanvasBackgroundDialog(Dialog):
frame.columnconfigure(1, weight=1) frame.columnconfigure(1, weight=1)
frame.columnconfigure(2, weight=1) frame.columnconfigure(2, weight=1)
frame.columnconfigure(3, weight=1) frame.columnconfigure(3, weight=1)
frame.grid(row=3, column=0, sticky="ew") frame.grid(sticky="ew")
button = ttk.Radiobutton( button = ttk.Radiobutton(
frame, text="upper-left", value=1, variable=self.scale_option frame, text="upper-left", value=1, variable=self.scale_option
@ -103,7 +103,7 @@ class CanvasBackgroundDialog(Dialog):
checkbutton = ttk.Checkbutton( checkbutton = ttk.Checkbutton(
self.top, text="Show grid", variable=self.show_grid self.top, text="Show grid", variable=self.show_grid
) )
checkbutton.grid(row=4, column=0, sticky="ew", padx=PADX) checkbutton.grid(sticky="ew", padx=PADX)
checkbutton = ttk.Checkbutton( checkbutton = ttk.Checkbutton(
self.top, self.top,
@ -111,11 +111,11 @@ class CanvasBackgroundDialog(Dialog):
variable=self.adjust_to_dim, variable=self.adjust_to_dim,
command=self.click_adjust_canvas, command=self.click_adjust_canvas,
) )
checkbutton.grid(row=5, column=0, sticky="ew", padx=PADX) checkbutton.grid(sticky="ew", padx=PADX)
def draw_buttons(self): def draw_buttons(self):
frame = ttk.Frame(self.top) frame = ttk.Frame(self.top)
frame.grid(row=6, column=0, pady=5, sticky="ew") frame.grid(pady=PADY, sticky="ew")
frame.columnconfigure(0, weight=1) frame.columnconfigure(0, weight=1)
frame.columnconfigure(1, weight=1) frame.columnconfigure(1, weight=1)

View file

@ -6,6 +6,7 @@ from tkinter import ttk
from coretk.dialogs.dialog import Dialog from coretk.dialogs.dialog import Dialog
from coretk.dialogs.icondialog import IconDialog from coretk.dialogs.icondialog import IconDialog
from coretk.nodeutils import NodeDraw from coretk.nodeutils import NodeDraw
from coretk.themes import FRAME_PAD, PADX, PADY
from coretk.widgets import CheckboxList, ListboxScroll from coretk.widgets import CheckboxList, ListboxScroll
@ -23,11 +24,11 @@ class ServicesSelectDialog(Dialog):
self.top.rowconfigure(0, weight=1) self.top.rowconfigure(0, weight=1)
frame = ttk.Frame(self.top) frame = ttk.Frame(self.top)
frame.grid(stick="nsew") frame.grid(stick="nsew", pady=PADY)
frame.rowconfigure(0, weight=1) frame.rowconfigure(0, weight=1)
for i in range(3): for i in range(3):
frame.columnconfigure(i, weight=1) frame.columnconfigure(i, weight=1)
self.groups = ListboxScroll(frame, text="Groups") self.groups = ListboxScroll(frame, text="Groups", padding=FRAME_PAD)
self.groups.grid(row=0, column=0, sticky="nsew") self.groups.grid(row=0, column=0, sticky="nsew")
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)
@ -35,11 +36,15 @@ class ServicesSelectDialog(Dialog):
self.groups.listbox.selection_set(0) self.groups.listbox.selection_set(0)
self.services = CheckboxList( self.services = CheckboxList(
frame, self.app, text="Services", clicked=self.service_clicked frame,
self.app,
text="Services",
clicked=self.service_clicked,
padding=FRAME_PAD,
) )
self.services.grid(row=0, column=1, sticky="nsew") self.services.grid(row=0, column=1, sticky="nsew")
self.current = ListboxScroll(frame, text="Selected") self.current = ListboxScroll(frame, text="Selected", padding=FRAME_PAD)
self.current.grid(row=0, column=2, sticky="nsew") self.current.grid(row=0, column=2, sticky="nsew")
for service in sorted(self.current_services): for service in sorted(self.current_services):
self.current.listbox.insert(tk.END, service) self.current.listbox.insert(tk.END, service)
@ -49,7 +54,7 @@ class ServicesSelectDialog(Dialog):
for i in range(2): for i in range(2):
frame.columnconfigure(i, weight=1) frame.columnconfigure(i, weight=1)
button = ttk.Button(frame, text="Save", command=self.destroy) button = ttk.Button(frame, text="Save", command=self.destroy)
button.grid(row=0, column=0, sticky="ew") button.grid(row=0, column=0, sticky="ew", padx=PADX)
button = ttk.Button(frame, text="Cancel", command=self.click_cancel) button = ttk.Button(frame, text="Cancel", command=self.click_cancel)
button.grid(row=0, column=1, sticky="ew") button.grid(row=0, column=1, sticky="ew")
@ -104,12 +109,12 @@ class CustomNodesDialog(Dialog):
def draw_node_config(self): def draw_node_config(self):
frame = ttk.Frame(self.top) frame = ttk.Frame(self.top)
frame.grid(sticky="nsew") frame.grid(sticky="nsew", pady=PADY)
frame.columnconfigure(0, weight=1) frame.columnconfigure(0, weight=1)
frame.rowconfigure(0, weight=1) frame.rowconfigure(0, weight=1)
self.nodes_list = ListboxScroll(frame, text="Nodes") self.nodes_list = ListboxScroll(frame, text="Nodes", padding=FRAME_PAD)
self.nodes_list.grid(row=0, column=0, sticky="nsew") self.nodes_list.grid(row=0, column=0, sticky="nsew", padx=PADX)
self.nodes_list.listbox.bind("<<ListboxSelect>>", self.handle_node_select) self.nodes_list.listbox.bind("<<ListboxSelect>>", self.handle_node_select)
for name in sorted(self.app.core.custom_nodes): for name in sorted(self.app.core.custom_nodes):
self.nodes_list.listbox.insert(tk.END, name) self.nodes_list.listbox.insert(tk.END, name)
@ -128,17 +133,17 @@ class CustomNodesDialog(Dialog):
def draw_node_buttons(self): def draw_node_buttons(self):
frame = ttk.Frame(self.top) frame = ttk.Frame(self.top)
frame.grid(pady=2, sticky="ew") frame.grid(sticky="ew", pady=PADY)
for i in range(3): for i in range(3):
frame.columnconfigure(i, weight=1) frame.columnconfigure(i, weight=1)
button = ttk.Button(frame, text="Create", command=self.click_create) button = ttk.Button(frame, text="Create", command=self.click_create)
button.grid(row=0, column=0, sticky="ew") button.grid(row=0, column=0, sticky="ew", padx=PADX)
self.edit_button = ttk.Button( self.edit_button = ttk.Button(
frame, text="Edit", state=tk.DISABLED, command=self.click_edit frame, text="Edit", state=tk.DISABLED, command=self.click_edit
) )
self.edit_button.grid(row=0, column=1, sticky="ew") self.edit_button.grid(row=0, column=1, sticky="ew", padx=PADX)
self.delete_button = ttk.Button( self.delete_button = ttk.Button(
frame, text="Delete", state=tk.DISABLED, command=self.click_delete frame, text="Delete", state=tk.DISABLED, command=self.click_delete
@ -152,7 +157,7 @@ class CustomNodesDialog(Dialog):
frame.columnconfigure(i, weight=1) frame.columnconfigure(i, weight=1)
button = ttk.Button(frame, text="Save", command=self.click_save) button = ttk.Button(frame, text="Save", command=self.click_save)
button.grid(row=0, column=0, sticky="ew") button.grid(row=0, column=0, sticky="ew", padx=PADX)
button = ttk.Button(frame, text="Cancel", command=self.destroy) button = ttk.Button(frame, text="Cancel", command=self.destroy)
button.grid(row=0, column=1, sticky="ew") button.grid(row=0, column=1, sticky="ew")

View file

@ -2,14 +2,12 @@ import tkinter as tk
from tkinter import ttk from tkinter import ttk
from coretk.images import ImageEnum, Images from coretk.images import ImageEnum, Images
from coretk.themes import DIALOG_PAD
DIALOG_PAD = 5
class Dialog(tk.Toplevel): class Dialog(tk.Toplevel):
def __init__(self, master, app, title, modal=False): def __init__(self, master, app, title, modal=False):
super().__init__(master) super().__init__(master)
self.geometry("800x600")
self.withdraw() self.withdraw()
self.app = app self.app = app
self.modal = modal self.modal = modal
@ -31,3 +29,9 @@ class Dialog(tk.Toplevel):
self.wait_visibility() self.wait_visibility()
self.grab_set() self.grab_set()
self.wait_window() self.wait_window()
def draw_spacer(self, row=None):
frame = ttk.Frame(self.top)
frame.grid(row=row, sticky="nsew")
frame.rowconfigure(0, weight=1)
self.top.rowconfigure(frame.grid_info()["row"], weight=1)

View file

@ -11,10 +11,9 @@ import grpc
from coretk.dialogs.dialog import Dialog from coretk.dialogs.dialog import Dialog
from coretk.errors import show_grpc_error from coretk.errors import show_grpc_error
from coretk.images import ImageEnum, Images from coretk.images import ImageEnum, Images
from coretk.themes import PADX, PADY
from coretk.widgets import ConfigFrame from coretk.widgets import ConfigFrame
PAD = 5
class GlobalEmaneDialog(Dialog): class GlobalEmaneDialog(Dialog):
def __init__(self, master, app): def __init__(self, master, app):
@ -25,11 +24,10 @@ class GlobalEmaneDialog(Dialog):
def draw(self): def draw(self):
self.top.columnconfigure(0, weight=1) self.top.columnconfigure(0, weight=1)
self.top.rowconfigure(0, weight=1) self.top.rowconfigure(0, weight=1)
self.config_frame = ConfigFrame( self.config_frame = ConfigFrame(self.top, self.app, self.app.core.emane_config)
self.top, self.app, self.app.core.emane_config, borderwidth=0
)
self.config_frame.draw_config() self.config_frame.draw_config()
self.config_frame.grid(sticky="nsew", pady=PAD) self.config_frame.grid(sticky="nsew", pady=PADY)
self.draw_spacer()
self.draw_buttons() self.draw_buttons()
def draw_buttons(self): def draw_buttons(self):
@ -38,7 +36,7 @@ class GlobalEmaneDialog(Dialog):
for i in range(2): for i in range(2):
frame.columnconfigure(i, weight=1) frame.columnconfigure(i, weight=1)
button = ttk.Button(frame, text="Apply", command=self.click_apply) button = ttk.Button(frame, text="Apply", command=self.click_apply)
button.grid(row=0, column=0, sticky="ew", padx=PAD) button.grid(row=0, column=0, sticky="ew", padx=PADX)
button = ttk.Button(frame, text="Cancel", command=self.destroy) button = ttk.Button(frame, text="Cancel", command=self.destroy)
button.grid(row=0, column=1, sticky="ew") button.grid(row=0, column=1, sticky="ew")
@ -67,9 +65,10 @@ class EmaneModelDialog(Dialog):
def draw(self): def draw(self):
self.top.columnconfigure(0, weight=1) self.top.columnconfigure(0, weight=1)
self.top.rowconfigure(0, weight=1) self.top.rowconfigure(0, weight=1)
self.config_frame = ConfigFrame(self.top, self.app, self.config, borderwidth=0) self.config_frame = ConfigFrame(self.top, self.app, self.config)
self.config_frame.draw_config() self.config_frame.draw_config()
self.config_frame.grid(sticky="nsew", pady=PAD) self.config_frame.grid(sticky="nsew", pady=PADY)
self.draw_spacer()
self.draw_buttons() self.draw_buttons()
def draw_buttons(self): def draw_buttons(self):
@ -78,7 +77,7 @@ class EmaneModelDialog(Dialog):
for i in range(2): for i in range(2):
frame.columnconfigure(i, weight=1) frame.columnconfigure(i, weight=1)
button = ttk.Button(frame, text="Apply", command=self.click_apply) button = ttk.Button(frame, text="Apply", command=self.click_apply)
button.grid(row=0, column=0, sticky="ew", padx=PAD) button.grid(row=0, column=0, sticky="ew", padx=PADX)
button = ttk.Button(frame, text="Cancel", command=self.destroy) button = ttk.Button(frame, text="Cancel", command=self.destroy)
button.grid(row=0, column=1, sticky="ew") button.grid(row=0, column=1, sticky="ew")
@ -111,6 +110,7 @@ class EmaneConfigDialog(Dialog):
self.draw_emane_configuration() self.draw_emane_configuration()
self.draw_emane_models() self.draw_emane_models()
self.draw_emane_buttons() self.draw_emane_buttons()
self.draw_spacer()
self.draw_apply_and_cancel() self.draw_apply_and_cancel()
def draw_emane_configuration(self): def draw_emane_configuration(self):
@ -123,8 +123,9 @@ class EmaneConfigDialog(Dialog):
self.top, self.top,
text="The EMANE emulation system provides more complex wireless radio emulation " text="The EMANE emulation system provides more complex wireless radio emulation "
"\nusing pluggable MAC and PHY modules. Refer to the wiki for configuration option details", "\nusing pluggable MAC and PHY modules. Refer to the wiki for configuration option details",
justify=tk.CENTER,
) )
label.grid(sticky="ew", pady=PAD) label.grid(pady=PADY)
image = Images.get(ImageEnum.EDITNODE, 16) image = Images.get(ImageEnum.EDITNODE, 16)
button = ttk.Button( button = ttk.Button(
@ -137,7 +138,7 @@ class EmaneConfigDialog(Dialog):
), ),
) )
button.image = image button.image = image
button.grid(sticky="ew", pady=PAD) button.grid(sticky="ew", pady=PADY)
def draw_emane_models(self): def draw_emane_models(self):
""" """
@ -146,7 +147,7 @@ class EmaneConfigDialog(Dialog):
:return: nothing :return: nothing
""" """
frame = ttk.Frame(self.top) frame = ttk.Frame(self.top)
frame.grid(sticky="ew", pady=PAD) frame.grid(sticky="ew", pady=PADY)
frame.columnconfigure(1, weight=1) frame.columnconfigure(1, weight=1)
label = ttk.Label(frame, text="Model") label = ttk.Label(frame, text="Model")
@ -164,7 +165,7 @@ class EmaneConfigDialog(Dialog):
def draw_emane_buttons(self): def draw_emane_buttons(self):
frame = ttk.Frame(self.top) frame = ttk.Frame(self.top)
frame.grid(sticky="ew", pady=PAD) frame.grid(sticky="ew", pady=PADY)
for i in range(2): for i in range(2):
frame.columnconfigure(i, weight=1) frame.columnconfigure(i, weight=1)
@ -177,7 +178,7 @@ class EmaneConfigDialog(Dialog):
command=self.click_model_config, command=self.click_model_config,
) )
self.emane_model_button.image = image self.emane_model_button.image = image
self.emane_model_button.grid(row=0, column=0, padx=PAD, sticky="ew") self.emane_model_button.grid(row=0, column=0, padx=PADX, sticky="ew")
image = Images.get(ImageEnum.EDITNODE, 16) image = Images.get(ImageEnum.EDITNODE, 16)
button = ttk.Button( button = ttk.Button(
@ -197,7 +198,7 @@ class EmaneConfigDialog(Dialog):
frame.columnconfigure(i, weight=1) frame.columnconfigure(i, weight=1)
button = ttk.Button(frame, text="Apply", command=self.click_apply) button = ttk.Button(frame, text="Apply", command=self.click_apply)
button.grid(row=0, column=0, padx=PAD, sticky="ew") button.grid(row=0, column=0, padx=PADX, sticky="ew")
button = ttk.Button(frame, text="Cancel", command=self.destroy) button = ttk.Button(frame, text="Cancel", command=self.destroy)
button.grid(row=0, column=1, sticky="ew") button.grid(row=0, column=1, sticky="ew")

View file

@ -3,6 +3,7 @@ from tkinter import ttk
from core.api.grpc import core_pb2 from core.api.grpc import core_pb2
from coretk.dialogs.dialog import Dialog from coretk.dialogs.dialog import Dialog
from coretk.themes import PADX, PADY
from coretk.widgets import CodeText from coretk.widgets import CodeText
@ -21,14 +22,14 @@ class HookDialog(Dialog):
# name and states # name and states
frame = ttk.Frame(self.top) frame = ttk.Frame(self.top)
frame.grid(row=0, sticky="ew", pady=2) frame.grid(sticky="ew", pady=PADY)
frame.columnconfigure(0, weight=2) frame.columnconfigure(0, weight=2)
frame.columnconfigure(1, weight=7) frame.columnconfigure(1, weight=7)
frame.columnconfigure(2, weight=1) frame.columnconfigure(2, weight=1)
label = ttk.Label(frame, text="Name") label = ttk.Label(frame, text="Name")
label.grid(row=0, column=0, sticky="ew") label.grid(row=0, column=0, sticky="ew", padx=PADX)
entry = ttk.Entry(frame, textvariable=self.name) entry = ttk.Entry(frame, textvariable=self.name)
entry.grid(row=0, column=1, sticky="ew") entry.grid(row=0, column=1, sticky="ew", padx=PADX)
values = tuple(x for x in core_pb2.SessionState.Enum.keys() if x != "NONE") values = tuple(x for x in core_pb2.SessionState.Enum.keys() if x != "NONE")
initial_state = core_pb2.SessionState.Enum.Name(core_pb2.SessionState.RUNTIME) initial_state = core_pb2.SessionState.Enum.Name(core_pb2.SessionState.RUNTIME)
self.state.set(initial_state) self.state.set(initial_state)
@ -40,11 +41,7 @@ class HookDialog(Dialog):
combobox.bind("<<ComboboxSelected>>", self.state_change) combobox.bind("<<ComboboxSelected>>", self.state_change)
# data # data
frame = ttk.Frame(self.top) self.data = CodeText(self.top)
frame.columnconfigure(0, weight=1)
frame.rowconfigure(0, weight=1)
frame.grid(row=1, sticky="nsew", pady=2)
self.data = CodeText(frame)
self.data.insert( self.data.insert(
1.0, 1.0,
( (
@ -53,19 +50,15 @@ class HookDialog(Dialog):
"# specified state\n" "# specified state\n"
), ),
) )
self.data.grid(row=0, column=0, sticky="nsew") self.data.grid(sticky="nsew")
scrollbar = ttk.Scrollbar(frame)
scrollbar.grid(row=0, column=1, sticky="ns")
self.data.config(yscrollcommand=scrollbar.set)
scrollbar.config(command=self.data.yview)
# button row # button row
frame = ttk.Frame(self.top) frame = ttk.Frame(self.top)
frame.grid(row=2, sticky="ew", pady=2) frame.grid(sticky="ew")
for i in range(2): for i in range(2):
frame.columnconfigure(i, weight=1) frame.columnconfigure(i, weight=1)
button = ttk.Button(frame, text="Save", command=lambda: self.save()) button = ttk.Button(frame, text="Save", command=lambda: self.save())
button.grid(row=0, column=0, sticky="ew") button.grid(row=0, column=0, sticky="ew", padx=PADX)
button = ttk.Button(frame, text="Cancel", command=lambda: self.destroy()) button = ttk.Button(frame, text="Cancel", command=lambda: self.destroy())
button.grid(row=0, column=1, sticky="ew") button.grid(row=0, column=1, sticky="ew")
@ -104,25 +97,25 @@ class HooksDialog(Dialog):
self.top.rowconfigure(0, weight=1) self.top.rowconfigure(0, weight=1)
self.listbox = tk.Listbox(self.top) self.listbox = tk.Listbox(self.top)
self.listbox.grid(row=0, sticky="nsew") self.listbox.grid(sticky="nsew", pady=PADY)
self.listbox.bind("<<ListboxSelect>>", self.select) self.listbox.bind("<<ListboxSelect>>", self.select)
for hook_file in self.app.core.hooks: for hook_file in self.app.core.hooks:
self.listbox.insert(tk.END, hook_file) self.listbox.insert(tk.END, hook_file)
frame = ttk.Frame(self.top) frame = ttk.Frame(self.top)
frame.grid(row=1, sticky="ew") frame.grid(sticky="ew")
for i in range(4): for i in range(4):
frame.columnconfigure(i, weight=1) frame.columnconfigure(i, weight=1)
button = ttk.Button(frame, text="Create", command=self.click_create) button = ttk.Button(frame, text="Create", command=self.click_create)
button.grid(row=0, column=0, sticky="ew") button.grid(row=0, column=0, sticky="ew", padx=PADX)
self.edit_button = ttk.Button( self.edit_button = ttk.Button(
frame, text="Edit", state=tk.DISABLED, command=self.click_edit frame, text="Edit", state=tk.DISABLED, command=self.click_edit
) )
self.edit_button.grid(row=0, column=1, sticky="ew") self.edit_button.grid(row=0, column=1, sticky="ew", padx=PADX)
self.delete_button = ttk.Button( self.delete_button = ttk.Button(
frame, text="Delete", state=tk.DISABLED, command=self.click_delete frame, text="Delete", state=tk.DISABLED, command=self.click_delete
) )
self.delete_button.grid(row=0, column=2, sticky="ew") self.delete_button.grid(row=0, column=2, sticky="ew", padx=PADX)
button = ttk.Button(frame, text="Cancel", command=lambda: self.destroy()) button = ttk.Button(frame, text="Cancel", command=lambda: self.destroy())
button.grid(row=0, column=3, sticky="ew") button.grid(row=0, column=3, sticky="ew")

View file

@ -5,6 +5,7 @@ from coretk import nodeutils
from coretk.appconfig import ICONS_PATH from coretk.appconfig import ICONS_PATH
from coretk.dialogs.dialog import Dialog from coretk.dialogs.dialog import Dialog
from coretk.images import Images from coretk.images import Images
from coretk.themes import PADX, PADY
class IconDialog(Dialog): class IconDialog(Dialog):
@ -20,27 +21,30 @@ class IconDialog(Dialog):
# row one # row one
frame = ttk.Frame(self.top) frame = ttk.Frame(self.top)
frame.grid(row=0, column=0, pady=2, sticky="ew") frame.grid(pady=PADY, sticky="ew")
frame.columnconfigure(0, weight=1) frame.columnconfigure(0, weight=1)
frame.columnconfigure(1, weight=3) frame.columnconfigure(1, weight=3)
label = ttk.Label(frame, text="Image") label = ttk.Label(frame, text="Image")
label.grid(row=0, column=0, sticky="ew") label.grid(row=0, column=0, sticky="ew", padx=PADX)
entry = ttk.Entry(frame, textvariable=self.file_path) entry = ttk.Entry(frame, textvariable=self.file_path)
entry.grid(row=0, column=1, sticky="ew") entry.grid(row=0, column=1, sticky="ew", padx=PADX)
button = ttk.Button(frame, text="...", command=self.click_file) button = ttk.Button(frame, text="...", command=self.click_file)
button.grid(row=0, column=2) button.grid(row=0, column=2)
# row two # row two
self.image_label = ttk.Label(self.top, image=self.image, anchor=tk.CENTER) self.image_label = ttk.Label(self.top, image=self.image, anchor=tk.CENTER)
self.image_label.grid(row=1, column=0, pady=2, sticky="ew") self.image_label.grid(pady=PADY, sticky="ew")
# spacer
self.draw_spacer()
# row three # row three
frame = ttk.Frame(self.top) frame = ttk.Frame(self.top)
frame.grid(row=2, column=0, sticky="ew") frame.grid(sticky="ew")
frame.columnconfigure(0, weight=1) frame.columnconfigure(0, weight=1)
frame.columnconfigure(1, weight=1) frame.columnconfigure(1, weight=1)
button = ttk.Button(frame, text="Apply", command=self.destroy) button = ttk.Button(frame, text="Apply", command=self.destroy)
button.grid(row=0, column=0, sticky="ew") button.grid(row=0, column=0, sticky="ew", padx=PADX)
button = ttk.Button(frame, text="Cancel", command=self.click_cancel) button = ttk.Button(frame, text="Cancel", command=self.click_cancel)
button.grid(row=0, column=1, sticky="ew") button.grid(row=0, column=1, sticky="ew")

View file

@ -7,10 +7,9 @@ import grpc
from coretk.dialogs.dialog import Dialog from coretk.dialogs.dialog import Dialog
from coretk.errors import show_grpc_error from coretk.errors import show_grpc_error
from coretk.themes import PADX, PADY
from coretk.widgets import ConfigFrame from coretk.widgets import ConfigFrame
PAD = 5
class MobilityConfigDialog(Dialog): class MobilityConfigDialog(Dialog):
def __init__(self, master, app, canvas_node): def __init__(self, master, app, canvas_node):
@ -32,9 +31,10 @@ class MobilityConfigDialog(Dialog):
def draw(self): def draw(self):
self.top.columnconfigure(0, weight=1) self.top.columnconfigure(0, weight=1)
self.config_frame = ConfigFrame(self.top, self.app, self.config, borderwidth=0) self.top.rowconfigure(0, weight=1)
self.config_frame = ConfigFrame(self.top, self.app, self.config)
self.config_frame.draw_config() self.config_frame.draw_config()
self.config_frame.grid(sticky="nsew", pady=PAD) self.config_frame.grid(sticky="nsew", pady=PADY)
self.draw_apply_buttons() self.draw_apply_buttons()
def draw_apply_buttons(self): def draw_apply_buttons(self):
@ -44,7 +44,7 @@ class MobilityConfigDialog(Dialog):
frame.columnconfigure(i, weight=1) frame.columnconfigure(i, weight=1)
button = ttk.Button(frame, text="Apply", command=self.click_apply) button = ttk.Button(frame, text="Apply", command=self.click_apply)
button.grid(row=0, column=0, padx=PAD, sticky="ew") button.grid(row=0, column=0, padx=PADX, sticky="ew")
button = ttk.Button(frame, text="Cancel", command=self.destroy) button = ttk.Button(frame, text="Cancel", command=self.destroy)
button.grid(row=0, column=1, sticky="ew") button.grid(row=0, column=1, sticky="ew")

View file

@ -7,8 +7,8 @@ from core.api.grpc.core_pb2 import MobilityAction
from coretk.dialogs.dialog import Dialog from coretk.dialogs.dialog import Dialog
from coretk.errors import show_grpc_error from coretk.errors import show_grpc_error
from coretk.images import ImageEnum, Images from coretk.images import ImageEnum, Images
from coretk.themes import PADX, PADY
PAD = 5
ICON_SIZE = 16 ICON_SIZE = 16
@ -61,6 +61,7 @@ class MobilityPlayerDialog(Dialog):
super().__init__( super().__init__(
master, app, f"{canvas_node.core_node.name} Mobility Player", modal=False master, app, f"{canvas_node.core_node.name} Mobility Player", modal=False
) )
self.resizable(False, False)
self.geometry("") self.geometry("")
self.canvas_node = canvas_node self.canvas_node = canvas_node
self.node = canvas_node.core_node self.node = canvas_node.core_node
@ -76,36 +77,36 @@ class MobilityPlayerDialog(Dialog):
file_name = self.config["file"].value file_name = self.config["file"].value
label = ttk.Label(self.top, text=file_name) label = ttk.Label(self.top, text=file_name)
label.grid(sticky="ew", pady=PAD) label.grid(sticky="ew", pady=PADY)
self.progressbar = ttk.Progressbar(self.top, mode="indeterminate") self.progressbar = ttk.Progressbar(self.top, mode="indeterminate")
self.progressbar.grid(sticky="ew", pady=PAD) self.progressbar.grid(sticky="ew", pady=PADY)
frame = ttk.Frame(self.top) frame = ttk.Frame(self.top)
frame.grid(sticky="ew", pady=PAD) frame.grid(sticky="ew", pady=PADY)
for i in range(3): for i in range(3):
frame.columnconfigure(i, weight=1) frame.columnconfigure(i, weight=1)
image = Images.get(ImageEnum.START, width=ICON_SIZE) image = Images.get(ImageEnum.START, width=ICON_SIZE)
self.play_button = ttk.Button(frame, image=image, command=self.click_play) self.play_button = ttk.Button(frame, image=image, command=self.click_play)
self.play_button.image = image self.play_button.image = image
self.play_button.grid(row=0, column=0, sticky="ew", padx=PAD) self.play_button.grid(row=0, column=0, sticky="ew", padx=PADX)
image = Images.get(ImageEnum.PAUSE, width=ICON_SIZE) image = Images.get(ImageEnum.PAUSE, width=ICON_SIZE)
self.pause_button = ttk.Button(frame, image=image, command=self.click_pause) self.pause_button = ttk.Button(frame, image=image, command=self.click_pause)
self.pause_button.image = image self.pause_button.image = image
self.pause_button.grid(row=0, column=1, sticky="ew", padx=PAD) self.pause_button.grid(row=0, column=1, sticky="ew", padx=PADX)
image = Images.get(ImageEnum.STOP, width=ICON_SIZE) image = Images.get(ImageEnum.STOP, width=ICON_SIZE)
self.stop_button = ttk.Button(frame, image=image, command=self.click_stop) self.stop_button = ttk.Button(frame, image=image, command=self.click_stop)
self.stop_button.image = image self.stop_button.image = image
self.stop_button.grid(row=0, column=2, sticky="ew", padx=PAD) self.stop_button.grid(row=0, column=2, sticky="ew", padx=PADX)
loop = tk.IntVar(value=int(self.config["loop"].value == "1")) loop = tk.IntVar(value=int(self.config["loop"].value == "1"))
checkbutton = ttk.Checkbutton( checkbutton = ttk.Checkbutton(
frame, text="Loop?", variable=loop, state=tk.DISABLED frame, text="Loop?", variable=loop, state=tk.DISABLED
) )
checkbutton.grid(row=0, column=3, padx=PAD) checkbutton.grid(row=0, column=3, padx=PADX)
rate = self.config["refresh_ms"].value rate = self.config["refresh_ms"].value
label = ttk.Label(frame, text=f"rate {rate} ms") label = ttk.Label(frame, text=f"rate {rate} ms")

View file

@ -7,10 +7,9 @@ from coretk.dialogs.dialog import Dialog
from coretk.dialogs.icondialog import IconDialog from coretk.dialogs.icondialog import IconDialog
from coretk.dialogs.nodeservice import NodeService from coretk.dialogs.nodeservice import NodeService
from coretk.nodeutils import NodeUtils from coretk.nodeutils import NodeUtils
from coretk.themes import FRAME_PAD, PADX, PADY
from coretk.widgets import FrameScroll from coretk.widgets import FrameScroll
PAD = 5
def mac_auto(is_auto, entry): def mac_auto(is_auto, entry):
logging.info("mac auto clicked") logging.info("mac auto clicked")
@ -66,9 +65,22 @@ class NodeConfigDialog(Dialog):
frame.grid(sticky="ew") frame.grid(sticky="ew")
frame.columnconfigure(1, weight=1) frame.columnconfigure(1, weight=1)
# icon field
label = ttk.Label(frame, text="Icon")
label.grid(row=row, column=0, sticky="ew", padx=PADX, pady=PADY)
self.image_button = ttk.Button(
frame,
text="Icon",
image=self.image,
compound=tk.NONE,
command=self.click_icon,
)
self.image_button.grid(row=row, column=1, sticky="ew")
row += 1
# name field # name field
label = ttk.Label(frame, text="Name") label = ttk.Label(frame, text="Name")
label.grid(row=row, column=0, sticky="ew", padx=PAD, pady=PAD) label.grid(row=row, column=0, sticky="ew", padx=PADX, pady=PADY)
entry = ttk.Entry( entry = ttk.Entry(
frame, frame,
textvariable=self.name, textvariable=self.name,
@ -81,23 +93,10 @@ class NodeConfigDialog(Dialog):
entry.grid(row=row, column=1, sticky="ew") entry.grid(row=row, column=1, sticky="ew")
row += 1 row += 1
# icon field
label = ttk.Label(frame, text="Icon")
label.grid(row=row, column=0, sticky="ew", padx=PAD, pady=PAD)
self.image_button = ttk.Button(
frame,
text="Icon",
image=self.image,
compound=tk.NONE,
command=self.click_icon,
)
self.image_button.grid(row=row, column=1, sticky="ew")
row += 1
# node type field # node type field
if NodeUtils.is_model_node(self.node.type): if NodeUtils.is_model_node(self.node.type):
label = ttk.Label(frame, text="Type") label = ttk.Label(frame, text="Type")
label.grid(row=row, column=0, sticky="ew", padx=PAD, pady=PAD) label.grid(row=row, column=0, sticky="ew", padx=PADX, pady=PADY)
combobox = ttk.Combobox( combobox = ttk.Combobox(
frame, frame,
textvariable=self.type, textvariable=self.type,
@ -110,7 +109,7 @@ class NodeConfigDialog(Dialog):
# container image field # container image field
if NodeUtils.is_image_node(self.node.type): if NodeUtils.is_image_node(self.node.type):
label = ttk.Label(frame, text="Image") label = ttk.Label(frame, text="Image")
label.grid(row=row, column=0, sticky="ew", padx=PAD, pady=PAD) label.grid(row=row, column=0, sticky="ew", padx=PADX, pady=PADY)
entry = ttk.Entry(frame, textvariable=self.container_image) entry = ttk.Entry(frame, textvariable=self.container_image)
entry.grid(row=row, column=1, sticky="ew") entry.grid(row=row, column=1, sticky="ew")
row += 1 row += 1
@ -120,7 +119,7 @@ class NodeConfigDialog(Dialog):
frame.grid(sticky="ew") frame.grid(sticky="ew")
frame.columnconfigure(1, weight=1) frame.columnconfigure(1, weight=1)
label = ttk.Label(frame, text="Server") label = ttk.Label(frame, text="Server")
label.grid(row=row, column=0, sticky="ew", padx=PAD, pady=PAD) label.grid(row=row, column=0, sticky="ew", padx=PADX, pady=PADY)
servers = ["localhost"] servers = ["localhost"]
servers.extend(list(sorted(self.app.core.servers.keys()))) servers.extend(list(sorted(self.app.core.servers.keys())))
combobox = ttk.Combobox( combobox = ttk.Combobox(
@ -131,12 +130,13 @@ class NodeConfigDialog(Dialog):
# services # services
button = ttk.Button(self.top, text="Services", command=self.click_services) button = ttk.Button(self.top, text="Services", command=self.click_services)
button.grid(sticky="ew", pady=PAD) button.grid(sticky="ew", pady=PADY)
# interfaces # interfaces
if self.canvas_node.interfaces: if self.canvas_node.interfaces:
self.draw_interfaces() self.draw_interfaces()
self.draw_spacer()
self.draw_buttons() self.draw_buttons()
def draw_interfaces(self): def draw_interfaces(self):
@ -146,17 +146,17 @@ class NodeConfigDialog(Dialog):
scroll.frame.rowconfigure(0, weight=1) scroll.frame.rowconfigure(0, weight=1)
for interface in self.canvas_node.interfaces: for interface in self.canvas_node.interfaces:
logging.info("interface: %s", interface) logging.info("interface: %s", interface)
frame = ttk.LabelFrame(scroll.frame, text=interface.name, padding=PAD) frame = ttk.LabelFrame(scroll.frame, text=interface.name, padding=FRAME_PAD)
frame.grid(sticky="ew", pady=PAD) frame.grid(sticky="ew", pady=PADY)
frame.columnconfigure(1, weight=1) frame.columnconfigure(1, weight=1)
frame.columnconfigure(2, weight=1) frame.columnconfigure(2, weight=1)
label = ttk.Label(frame, text="MAC") label = ttk.Label(frame, text="MAC")
label.grid(row=0, column=0, padx=PAD, pady=PAD) label.grid(row=0, column=0, padx=PADX, pady=PADY)
is_auto = tk.BooleanVar(value=True) is_auto = tk.BooleanVar(value=True)
checkbutton = ttk.Checkbutton(frame, text="Auto?", variable=is_auto) checkbutton = ttk.Checkbutton(frame, text="Auto?", variable=is_auto)
checkbutton.var = is_auto checkbutton.var = is_auto
checkbutton.grid(row=0, column=1, padx=PAD) checkbutton.grid(row=0, column=1, padx=PADX)
mac = tk.StringVar(value=interface.mac) mac = tk.StringVar(value=interface.mac)
entry = ttk.Entry(frame, textvariable=mac, state=tk.DISABLED) entry = ttk.Entry(frame, textvariable=mac, state=tk.DISABLED)
entry.grid(row=0, column=2, sticky="ew") entry.grid(row=0, column=2, sticky="ew")
@ -164,14 +164,14 @@ class NodeConfigDialog(Dialog):
checkbutton.config(command=func) checkbutton.config(command=func)
label = ttk.Label(frame, text="IPv4") label = ttk.Label(frame, text="IPv4")
label.grid(row=1, column=0, padx=PAD, pady=PAD) label.grid(row=1, column=0, padx=PADX, pady=PADY)
ip4 = tk.StringVar(value=f"{interface.ip4}/{interface.ip4mask}") ip4 = tk.StringVar(value=f"{interface.ip4}/{interface.ip4mask}")
entry = ttk.Entry(frame, textvariable=ip4) entry = ttk.Entry(frame, textvariable=ip4)
entry.bind("<FocusOut>", self.app.validation.ip_focus_out) entry.bind("<FocusOut>", self.app.validation.ip_focus_out)
entry.grid(row=1, column=1, columnspan=2, sticky="ew") entry.grid(row=1, column=1, columnspan=2, sticky="ew")
label = ttk.Label(frame, text="IPv6") label = ttk.Label(frame, text="IPv6")
label.grid(row=2, column=0, padx=PAD, pady=PAD) label.grid(row=2, column=0, padx=PADX, pady=PADY)
ip6 = tk.StringVar(value=f"{interface.ip6}/{interface.ip6mask}") ip6 = tk.StringVar(value=f"{interface.ip6}/{interface.ip6mask}")
entry = ttk.Entry(frame, textvariable=ip6) entry = ttk.Entry(frame, textvariable=ip6)
entry.bind("<FocusOut>", self.app.validation.ip_focus_out) entry.bind("<FocusOut>", self.app.validation.ip_focus_out)
@ -186,7 +186,7 @@ class NodeConfigDialog(Dialog):
frame.columnconfigure(1, weight=1) frame.columnconfigure(1, weight=1)
button = ttk.Button(frame, text="Apply", command=self.config_apply) button = ttk.Button(frame, text="Apply", command=self.config_apply)
button.grid(row=0, column=0, padx=2, sticky="ew") button.grid(row=0, column=0, padx=PADX, sticky="ew")
button = ttk.Button(frame, text="Cancel", command=self.destroy) button = ttk.Button(frame, text="Cancel", command=self.destroy)
button.grid(row=0, column=1, sticky="ew") button.grid(row=0, column=1, sticky="ew")

View file

@ -6,6 +6,7 @@ from tkinter import messagebox, ttk
from coretk.dialogs.dialog import Dialog from coretk.dialogs.dialog import Dialog
from coretk.dialogs.serviceconfiguration import ServiceConfiguration from coretk.dialogs.serviceconfiguration import ServiceConfiguration
from coretk.themes import FRAME_PAD, PADX, PADY
from coretk.widgets import CheckboxList, ListboxScroll from coretk.widgets import CheckboxList, ListboxScroll
@ -34,11 +35,11 @@ class NodeService(Dialog):
self.top.rowconfigure(0, weight=1) self.top.rowconfigure(0, weight=1)
frame = ttk.Frame(self.top) frame = ttk.Frame(self.top)
frame.grid(stick="nsew") frame.grid(stick="nsew", pady=PADY)
frame.rowconfigure(0, weight=1) frame.rowconfigure(0, weight=1)
for i in range(3): for i in range(3):
frame.columnconfigure(i, weight=1) frame.columnconfigure(i, weight=1)
self.groups = ListboxScroll(frame, text="Groups") self.groups = ListboxScroll(frame, text="Groups", padding=FRAME_PAD)
self.groups.grid(row=0, column=0, sticky="nsew") self.groups.grid(row=0, column=0, sticky="nsew")
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)
@ -46,11 +47,15 @@ class NodeService(Dialog):
self.groups.listbox.selection_set(0) self.groups.listbox.selection_set(0)
self.services = CheckboxList( self.services = CheckboxList(
frame, self.app, text="Services", clicked=self.service_clicked frame,
self.app,
text="Services",
clicked=self.service_clicked,
padding=FRAME_PAD,
) )
self.services.grid(row=0, column=1, sticky="nsew") self.services.grid(row=0, column=1, sticky="nsew")
self.current = ListboxScroll(frame, text="Selected") self.current = ListboxScroll(frame, text="Selected", padding=FRAME_PAD)
self.current.grid(row=0, column=2, sticky="nsew") self.current.grid(row=0, column=2, sticky="nsew")
for service in sorted(self.current_services): for service in sorted(self.current_services):
self.current.listbox.insert(tk.END, service) self.current.listbox.insert(tk.END, service)
@ -60,9 +65,9 @@ class NodeService(Dialog):
for i in range(3): for i in range(3):
frame.columnconfigure(i, weight=1) frame.columnconfigure(i, weight=1)
button = ttk.Button(frame, text="Configure", command=self.click_configure) button = ttk.Button(frame, text="Configure", command=self.click_configure)
button.grid(row=0, column=0, sticky="ew") button.grid(row=0, column=0, sticky="ew", padx=PADX)
button = ttk.Button(frame, text="Save", command=self.click_save) button = ttk.Button(frame, text="Save", command=self.click_save)
button.grid(row=0, column=1, sticky="ew") button.grid(row=0, column=1, sticky="ew", padx=PADX)
button = ttk.Button(frame, text="Cancel", command=self.click_cancel) button = ttk.Button(frame, text="Cancel", command=self.click_cancel)
button.grid(row=0, column=2, sticky="ew") button.grid(row=0, column=2, sticky="ew")

View file

@ -3,6 +3,7 @@ from tkinter import ttk
from coretk.coreclient import Observer from coretk.coreclient import Observer
from coretk.dialogs.dialog import Dialog from coretk.dialogs.dialog import Dialog
from coretk.themes import PADX, PADY
class ObserverDialog(Dialog): class ObserverDialog(Dialog):
@ -27,7 +28,7 @@ class ObserverDialog(Dialog):
def draw_listbox(self): def draw_listbox(self):
frame = ttk.Frame(self.top) frame = ttk.Frame(self.top)
frame.grid(sticky="nsew") frame.grid(sticky="nsew", pady=PADY)
frame.columnconfigure(0, weight=1) frame.columnconfigure(0, weight=1)
frame.rowconfigure(0, weight=1) frame.rowconfigure(0, weight=1)
@ -46,32 +47,32 @@ class ObserverDialog(Dialog):
def draw_form_fields(self): def draw_form_fields(self):
frame = ttk.Frame(self.top) frame = ttk.Frame(self.top)
frame.grid(sticky="ew") frame.grid(sticky="ew", pady=PADY)
frame.columnconfigure(1, weight=1) frame.columnconfigure(1, weight=1)
label = ttk.Label(frame, text="Name") label = ttk.Label(frame, text="Name")
label.grid(row=0, column=0, sticky="w") label.grid(row=0, column=0, sticky="w", padx=PADX)
entry = ttk.Entry(frame, textvariable=self.name) entry = ttk.Entry(frame, textvariable=self.name)
entry.grid(row=0, column=1, sticky="ew") entry.grid(row=0, column=1, sticky="ew")
label = ttk.Label(frame, text="Command") label = ttk.Label(frame, text="Command")
label.grid(row=1, column=0, sticky="w") label.grid(row=1, column=0, sticky="w", padx=PADX)
entry = ttk.Entry(frame, textvariable=self.cmd) entry = ttk.Entry(frame, textvariable=self.cmd)
entry.grid(row=1, column=1, sticky="ew") entry.grid(row=1, column=1, sticky="ew")
def draw_config_buttons(self): def draw_config_buttons(self):
frame = ttk.Frame(self.top) frame = ttk.Frame(self.top)
frame.grid(pady=2, sticky="ew") frame.grid(sticky="ew", pady=PADY)
for i in range(3): for i in range(3):
frame.columnconfigure(i, weight=1) frame.columnconfigure(i, weight=1)
button = ttk.Button(frame, text="Create", command=self.click_create) button = ttk.Button(frame, text="Create", command=self.click_create)
button.grid(row=0, column=0, sticky="ew") button.grid(row=0, column=0, sticky="ew", padx=PADX)
self.save_button = ttk.Button( self.save_button = ttk.Button(
frame, text="Save", state=tk.DISABLED, command=self.click_save frame, text="Save", state=tk.DISABLED, command=self.click_save
) )
self.save_button.grid(row=0, column=1, sticky="ew") self.save_button.grid(row=0, column=1, sticky="ew", padx=PADX)
self.delete_button = ttk.Button( self.delete_button = ttk.Button(
frame, text="Delete", state=tk.DISABLED, command=self.click_delete frame, text="Delete", state=tk.DISABLED, command=self.click_delete
@ -85,7 +86,7 @@ class ObserverDialog(Dialog):
frame.columnconfigure(i, weight=1) frame.columnconfigure(i, weight=1)
button = ttk.Button(frame, text="Save", command=self.click_save_config) button = ttk.Button(frame, text="Save", command=self.click_save_config)
button.grid(row=0, column=0, sticky="ew") button.grid(row=0, column=0, sticky="ew", padx=PADX)
button = ttk.Button(frame, text="Cancel", command=self.destroy) button = ttk.Button(frame, text="Cancel", command=self.destroy)
button.grid(row=0, column=1, sticky="ew") button.grid(row=0, column=1, sticky="ew")

View file

@ -4,6 +4,7 @@ from tkinter import ttk
from coretk import appconfig from coretk import appconfig
from coretk.dialogs.dialog import Dialog from coretk.dialogs.dialog import Dialog
from coretk.themes import FRAME_PAD, PADX, PADY
class PreferencesDialog(Dialog): class PreferencesDialog(Dialog):
@ -18,16 +19,17 @@ class PreferencesDialog(Dialog):
def draw(self): def draw(self):
self.top.columnconfigure(0, weight=1) self.top.columnconfigure(0, weight=1)
self.top.rowconfigure(0, weight=1)
self.draw_preferences() self.draw_preferences()
self.draw_buttons() self.draw_buttons()
def draw_preferences(self): def draw_preferences(self):
frame = ttk.LabelFrame(self.top, text="Preferences") frame = ttk.LabelFrame(self.top, text="Preferences", padding=FRAME_PAD)
frame.grid(sticky="ew", pady=2) frame.grid(sticky="nsew", pady=PADY)
frame.columnconfigure(1, weight=1) frame.columnconfigure(1, weight=1)
label = ttk.Label(frame, text="Theme") label = ttk.Label(frame, text="Theme")
label.grid(row=0, column=0, pady=2, padx=2, sticky="w") label.grid(row=0, column=0, pady=PADY, padx=PADX, sticky="w")
themes = self.app.style.theme_names() themes = self.app.style.theme_names()
combobox = ttk.Combobox( combobox = ttk.Combobox(
frame, textvariable=self.theme, values=themes, state="readonly" frame, textvariable=self.theme, values=themes, state="readonly"
@ -37,14 +39,14 @@ class PreferencesDialog(Dialog):
combobox.bind("<<ComboboxSelected>>", self.theme_change) combobox.bind("<<ComboboxSelected>>", self.theme_change)
label = ttk.Label(frame, text="Editor") label = ttk.Label(frame, text="Editor")
label.grid(row=1, column=0, pady=2, padx=2, sticky="w") label.grid(row=1, column=0, pady=PADY, padx=PADX, sticky="w")
combobox = ttk.Combobox( combobox = ttk.Combobox(
frame, textvariable=self.editor, values=appconfig.EDITORS, state="readonly" frame, textvariable=self.editor, values=appconfig.EDITORS, state="readonly"
) )
combobox.grid(row=1, column=1, sticky="ew") combobox.grid(row=1, column=1, sticky="ew")
label = ttk.Label(frame, text="Terminal") label = ttk.Label(frame, text="Terminal")
label.grid(row=2, column=0, pady=2, padx=2, sticky="w") label.grid(row=2, column=0, pady=PADY, padx=PADX, sticky="w")
combobox = ttk.Combobox( combobox = ttk.Combobox(
frame, frame,
textvariable=self.terminal, textvariable=self.terminal,
@ -54,7 +56,7 @@ class PreferencesDialog(Dialog):
combobox.grid(row=2, column=1, sticky="ew") combobox.grid(row=2, column=1, sticky="ew")
label = ttk.Label(frame, text="3D GUI") label = ttk.Label(frame, text="3D GUI")
label.grid(row=3, column=0, pady=2, padx=2, sticky="w") label.grid(row=3, column=0, pady=PADY, padx=PADX, sticky="w")
entry = ttk.Entry(frame, textvariable=self.gui3d) entry = ttk.Entry(frame, textvariable=self.gui3d)
entry.grid(row=3, column=1, sticky="ew") entry.grid(row=3, column=1, sticky="ew")
@ -65,7 +67,7 @@ class PreferencesDialog(Dialog):
frame.columnconfigure(i, weight=1) frame.columnconfigure(i, weight=1)
button = ttk.Button(frame, text="Save", command=self.click_save) button = ttk.Button(frame, text="Save", command=self.click_save)
button.grid(row=0, column=0, sticky="ew") button.grid(row=0, column=0, sticky="ew", padx=PADX)
button = ttk.Button(frame, text="Cancel", command=self.destroy) button = ttk.Button(frame, text="Cancel", command=self.destroy)
button.grid(row=0, column=1, sticky="ew") button.grid(row=0, column=1, sticky="ew")

View file

@ -3,6 +3,7 @@ from tkinter import ttk
from coretk.coreclient import CoreServer from coretk.coreclient import CoreServer
from coretk.dialogs.dialog import Dialog from coretk.dialogs.dialog import Dialog
from coretk.themes import FRAME_PAD, PADX, PADY
DEFAULT_NAME = "example" DEFAULT_NAME = "example"
DEFAULT_ADDRESS = "127.0.0.1" DEFAULT_ADDRESS = "127.0.0.1"
@ -26,13 +27,13 @@ class ServersDialog(Dialog):
self.top.columnconfigure(0, weight=1) self.top.columnconfigure(0, weight=1)
self.top.rowconfigure(0, weight=1) self.top.rowconfigure(0, weight=1)
self.draw_servers() self.draw_servers()
self.draw_server_configuration()
self.draw_servers_buttons() self.draw_servers_buttons()
self.draw_server_configuration()
self.draw_apply_buttons() self.draw_apply_buttons()
def draw_servers(self): def draw_servers(self):
frame = ttk.Frame(self.top) frame = ttk.Frame(self.top)
frame.grid(pady=2, sticky="nsew") frame.grid(pady=PADY, sticky="nsew")
frame.columnconfigure(0, weight=1) frame.columnconfigure(0, weight=1)
frame.rowconfigure(0, weight=1) frame.rowconfigure(0, weight=1)
@ -51,27 +52,24 @@ class ServersDialog(Dialog):
scrollbar.config(command=self.servers.yview) scrollbar.config(command=self.servers.yview)
def draw_server_configuration(self): def draw_server_configuration(self):
label = ttk.Label(self.top, text="Server Configuration") frame = ttk.LabelFrame(self.top, text="Server Configuration", padding=FRAME_PAD)
label.grid(pady=2, sticky="ew") frame.grid(pady=PADY, sticky="ew")
frame = ttk.Frame(self.top)
frame.grid(pady=2, sticky="ew")
frame.columnconfigure(1, weight=1) frame.columnconfigure(1, weight=1)
frame.columnconfigure(3, weight=1) frame.columnconfigure(3, weight=1)
frame.columnconfigure(5, weight=1) frame.columnconfigure(5, weight=1)
label = ttk.Label(frame, text="Name") label = ttk.Label(frame, text="Name")
label.grid(row=0, column=0, sticky="w") label.grid(row=0, column=0, sticky="w", padx=PADX, pady=PADY)
entry = ttk.Entry(frame, textvariable=self.name) entry = ttk.Entry(frame, textvariable=self.name)
entry.grid(row=0, column=1, sticky="ew") entry.grid(row=0, column=1, sticky="ew")
label = ttk.Label(frame, text="Address") label = ttk.Label(frame, text="Address")
label.grid(row=0, column=2, sticky="w") label.grid(row=0, column=2, sticky="w", padx=PADX, pady=PADY)
entry = ttk.Entry(frame, textvariable=self.address) entry = ttk.Entry(frame, textvariable=self.address)
entry.grid(row=0, column=3, sticky="ew") entry.grid(row=0, column=3, sticky="ew")
label = ttk.Label(frame, text="Port") label = ttk.Label(frame, text="Port")
label.grid(row=0, column=4, sticky="w") label.grid(row=0, column=4, sticky="w", padx=PADX, pady=PADY)
entry = ttk.Entry( entry = ttk.Entry(
frame, frame,
textvariable=self.port, textvariable=self.port,
@ -85,17 +83,17 @@ class ServersDialog(Dialog):
def draw_servers_buttons(self): def draw_servers_buttons(self):
frame = ttk.Frame(self.top) frame = ttk.Frame(self.top)
frame.grid(pady=2, sticky="ew") frame.grid(pady=PADY, sticky="ew")
for i in range(3): for i in range(3):
frame.columnconfigure(i, weight=1) frame.columnconfigure(i, weight=1)
button = ttk.Button(frame, text="Create", command=self.click_create) button = ttk.Button(frame, text="Create", command=self.click_create)
button.grid(row=0, column=0, sticky="ew") button.grid(row=0, column=0, sticky="ew", padx=PADX)
self.save_button = ttk.Button( self.save_button = ttk.Button(
frame, text="Save", state=tk.DISABLED, command=self.click_save frame, text="Save", state=tk.DISABLED, command=self.click_save
) )
self.save_button.grid(row=0, column=1, sticky="ew") self.save_button.grid(row=0, column=1, sticky="ew", padx=PADX)
self.delete_button = ttk.Button( self.delete_button = ttk.Button(
frame, text="Delete", state=tk.DISABLED, command=self.click_delete frame, text="Delete", state=tk.DISABLED, command=self.click_delete
@ -111,7 +109,7 @@ class ServersDialog(Dialog):
button = ttk.Button( button = ttk.Button(
frame, text="Save Configuration", command=self.click_save_configuration frame, text="Save Configuration", command=self.click_save_configuration
) )
button.grid(row=0, column=0, sticky="ew") button.grid(row=0, column=0, sticky="ew", padx=PADX)
button = ttk.Button(frame, text="Cancel", command=self.destroy) button = ttk.Button(frame, text="Cancel", command=self.destroy)
button.grid(row=0, column=1, sticky="ew") button.grid(row=0, column=1, sticky="ew")

View file

@ -5,11 +5,9 @@ import grpc
from coretk.dialogs.dialog import Dialog from coretk.dialogs.dialog import Dialog
from coretk.errors import show_grpc_error from coretk.errors import show_grpc_error
from coretk.themes import PADX, PADY
from coretk.widgets import ConfigFrame from coretk.widgets import ConfigFrame
PAD_X = 2
PAD_Y = 2
class SessionOptionsDialog(Dialog): class SessionOptionsDialog(Dialog):
def __init__(self, master, app): def __init__(self, master, app):
@ -33,16 +31,16 @@ class SessionOptionsDialog(Dialog):
self.config_frame = ConfigFrame(self.top, self.app, config=self.config) self.config_frame = ConfigFrame(self.top, self.app, config=self.config)
self.config_frame.draw_config() self.config_frame.draw_config()
self.config_frame.grid(sticky="nsew") self.config_frame.grid(sticky="nsew", pady=PADY)
frame = ttk.Frame(self.top) frame = ttk.Frame(self.top)
frame.grid(sticky="ew") frame.grid(sticky="ew")
for i in range(2): for i in range(2):
frame.columnconfigure(i, weight=1) frame.columnconfigure(i, weight=1)
button = ttk.Button(frame, text="Save", command=self.save) button = ttk.Button(frame, text="Save", command=self.save)
button.grid(row=0, column=0, pady=PAD_Y, padx=PAD_X, sticky="ew") button.grid(row=0, column=0, padx=PADX, sticky="ew")
button = ttk.Button(frame, text="Cancel", command=self.destroy) button = ttk.Button(frame, text="Cancel", command=self.destroy)
button.grid(row=0, column=1, pady=PAD_Y, padx=PAD_X, sticky="ew") button.grid(row=0, column=1, padx=PADX, sticky="ew")
def save(self): def save(self):
config = self.config_frame.parse_config() config = self.config_frame.parse_config()

View file

@ -9,6 +9,7 @@ from core.api.grpc import core_pb2
from coretk.dialogs.dialog import Dialog from coretk.dialogs.dialog import Dialog
from coretk.errors import show_grpc_error from coretk.errors import show_grpc_error
from coretk.images import ImageEnum, Images from coretk.images import ImageEnum, Images
from coretk.themes import PADX, PADY
class SessionsDialog(Dialog): class SessionsDialog(Dialog):
@ -31,6 +32,7 @@ class SessionsDialog(Dialog):
def draw(self): def draw(self):
self.top.columnconfigure(0, weight=1) self.top.columnconfigure(0, weight=1)
self.top.rowconfigure(1, weight=1)
self.draw_description() self.draw_description()
self.draw_tree() self.draw_tree()
self.draw_buttons() self.draw_buttons()
@ -46,14 +48,19 @@ class SessionsDialog(Dialog):
"connect to an existing session. Usually, only sessions in \n" "connect to an existing session. Usually, only sessions in \n"
"the RUNTIME state persist in the daemon, except for the \n" "the RUNTIME state persist in the daemon, except for the \n"
"one you might be concurrently editting.", "one you might be concurrently editting.",
justify=tk.CENTER,
) )
label.grid(row=0, sticky="ew", pady=5) label.grid(pady=PADY)
def draw_tree(self): def draw_tree(self):
frame = ttk.Frame(self.top)
frame.columnconfigure(0, weight=1)
frame.rowconfigure(0, weight=1)
frame.grid(sticky="nsew", pady=PADY)
self.tree = ttk.Treeview( self.tree = ttk.Treeview(
self.top, columns=("id", "state", "nodes"), show="headings" frame, columns=("id", "state", "nodes"), show="headings"
) )
self.tree.grid(row=1, sticky="nsew") self.tree.grid(sticky="nsew")
self.tree.column("id", stretch=tk.YES) self.tree.column("id", stretch=tk.YES)
self.tree.heading("id", text="ID") self.tree.heading("id", text="ID")
self.tree.column("state", stretch=tk.YES) self.tree.column("state", stretch=tk.YES)
@ -72,28 +79,26 @@ class SessionsDialog(Dialog):
self.tree.bind("<Double-1>", self.on_selected) self.tree.bind("<Double-1>", self.on_selected)
self.tree.bind("<<TreeviewSelect>>", self.click_select) self.tree.bind("<<TreeviewSelect>>", self.click_select)
yscrollbar = ttk.Scrollbar(self.top, orient="vertical", command=self.tree.yview) yscrollbar = ttk.Scrollbar(frame, orient="vertical", command=self.tree.yview)
yscrollbar.grid(row=1, column=1, sticky="ns") yscrollbar.grid(row=0, column=1, sticky="ns")
self.tree.configure(yscrollcommand=yscrollbar.set) self.tree.configure(yscrollcommand=yscrollbar.set)
xscrollbar = ttk.Scrollbar( xscrollbar = ttk.Scrollbar(frame, orient="horizontal", command=self.tree.xview)
self.top, orient="horizontal", command=self.tree.xview xscrollbar.grid(row=1, sticky="ew")
)
xscrollbar.grid(row=2, sticky="ew", pady=5)
self.tree.configure(xscrollcommand=xscrollbar.set) self.tree.configure(xscrollcommand=xscrollbar.set)
def draw_buttons(self): def draw_buttons(self):
frame = ttk.Frame(self.top) frame = ttk.Frame(self.top)
for i in range(4): for i in range(4):
frame.columnconfigure(i, weight=1) frame.columnconfigure(i, weight=1)
frame.grid(row=3, sticky="ew") frame.grid(sticky="ew")
image = Images.get(ImageEnum.DOCUMENTNEW, 16) image = Images.get(ImageEnum.DOCUMENTNEW, 16)
b = ttk.Button( b = ttk.Button(
frame, image=image, text="New", compound=tk.LEFT, command=self.click_new frame, image=image, text="New", compound=tk.LEFT, command=self.click_new
) )
b.image = image b.image = image
b.grid(row=0, padx=2, sticky="ew") b.grid(row=0, padx=PADX, sticky="ew")
image = Images.get(ImageEnum.FILEOPEN, 16) image = Images.get(ImageEnum.FILEOPEN, 16)
b = ttk.Button( b = ttk.Button(
@ -104,7 +109,7 @@ class SessionsDialog(Dialog):
command=self.click_connect, command=self.click_connect,
) )
b.image = image b.image = image
b.grid(row=0, column=1, padx=2, sticky="ew") b.grid(row=0, column=1, padx=PADX, sticky="ew")
image = Images.get(ImageEnum.EDITDELETE, 16) image = Images.get(ImageEnum.EDITDELETE, 16)
b = ttk.Button( b = ttk.Button(
@ -115,10 +120,10 @@ class SessionsDialog(Dialog):
command=self.click_shutdown, command=self.click_shutdown,
) )
b.image = image b.image = image
b.grid(row=0, column=2, padx=2, sticky="ew") b.grid(row=0, column=2, padx=PADX, sticky="ew")
b = ttk.Button(frame, text="Cancel", command=self.click_new) b = ttk.Button(frame, text="Cancel", command=self.click_new)
b.grid(row=0, column=3, padx=2, sticky="ew") b.grid(row=0, column=3, sticky="ew")
def click_new(self): def click_new(self):
self.app.core.create_new_session() self.app.core.create_new_session()

View file

@ -7,6 +7,7 @@ from tkinter import colorchooser, font, ttk
from coretk.dialogs.dialog import Dialog from coretk.dialogs.dialog import Dialog
from coretk.graph import tags from coretk.graph import tags
from coretk.graph.shapeutils import is_draw_shape, is_shape_text from coretk.graph.shapeutils import is_draw_shape, is_shape_text
from coretk.themes import FRAME_PAD, PADX, PADY
FONT_SIZES = [8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72] FONT_SIZES = [8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72]
BORDER_WIDTH = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] BORDER_WIDTH = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
@ -37,20 +38,27 @@ class ShapeDialog(Dialog):
self.bold = tk.BooleanVar(value=data.bold) self.bold = tk.BooleanVar(value=data.bold)
self.italic = tk.BooleanVar(value=data.italic) self.italic = tk.BooleanVar(value=data.italic)
self.underline = tk.BooleanVar(value=data.underline) self.underline = tk.BooleanVar(value=data.underline)
self.top.columnconfigure(0, weight=1)
self.draw() self.draw()
def draw(self): def draw(self):
frame = ttk.Frame(self.top) self.top.columnconfigure(0, weight=1)
frame.columnconfigure(0, weight=1) self.draw_label_options()
frame.columnconfigure(1, weight=2) if is_draw_shape(self.shape.shape_type):
label = ttk.Label(frame, text="Text for top of shape: ") self.draw_shape_options()
label.grid(row=0, column=0, sticky="nsew") self.draw_spacer()
entry = ttk.Entry(frame, textvariable=self.shape_text) self.draw_buttons()
entry.grid(row=0, column=1, sticky="nsew")
frame.grid(row=0, column=0, sticky="nsew", padx=3, pady=3)
frame = ttk.Frame(self.top) def draw_label_options(self):
label_frame = ttk.LabelFrame(self.top, text="Label", padding=FRAME_PAD)
label_frame.grid(sticky="ew")
label_frame.columnconfigure(0, weight=1)
entry = ttk.Entry(label_frame, textvariable=self.shape_text)
entry.grid(sticky="ew", pady=PADY)
# font options
frame = ttk.Frame(label_frame)
frame.grid(sticky="nsew", pady=PADY)
frame.columnconfigure(0, weight=1) frame.columnconfigure(0, weight=1)
frame.columnconfigure(1, weight=1) frame.columnconfigure(1, weight=1)
frame.columnconfigure(2, weight=1) frame.columnconfigure(2, weight=1)
@ -64,71 +72,66 @@ class ShapeDialog(Dialog):
combobox = ttk.Combobox( combobox = ttk.Combobox(
frame, textvariable=self.font_size, values=FONT_SIZES, state="readonly" frame, textvariable=self.font_size, values=FONT_SIZES, state="readonly"
) )
combobox.grid(row=0, column=1, padx=3, sticky="nsew") combobox.grid(row=0, column=1, padx=PADX, sticky="nsew")
button = ttk.Button(frame, text="Text color", command=self.choose_text_color) button = ttk.Button(frame, text="Color", command=self.choose_text_color)
button.grid(row=0, column=2, sticky="nsew") button.grid(row=0, column=2, sticky="nsew")
frame.grid(row=1, column=0, sticky="nsew", padx=3, pady=3)
frame = ttk.Frame(self.top) # style options
frame = ttk.Frame(label_frame)
frame.grid(sticky="ew")
for i in range(3):
frame.columnconfigure(i, weight=1)
button = ttk.Checkbutton(frame, variable=self.bold, text="Bold") button = ttk.Checkbutton(frame, variable=self.bold, text="Bold")
button.grid(row=0, column=0) button.grid(row=0, column=0, sticky="ew")
button = ttk.Checkbutton(frame, variable=self.italic, text="Italic") button = ttk.Checkbutton(frame, variable=self.italic, text="Italic")
button.grid(row=0, column=1, padx=3) button.grid(row=0, column=1, padx=PADX, sticky="ew")
button = ttk.Checkbutton(frame, variable=self.underline, text="Underline") button = ttk.Checkbutton(frame, variable=self.underline, text="Underline")
button.grid(row=0, column=2) button.grid(row=0, column=2, sticky="ew")
frame.grid(row=2, column=0, sticky="nsew", padx=3, pady=3)
if is_draw_shape(self.shape.shape_type): def draw_shape_options(self):
frame = ttk.Frame(self.top) label_frame = ttk.LabelFrame(self.top, text="Shape", padding=FRAME_PAD)
frame.columnconfigure(0, weight=1) label_frame.grid(sticky="ew", pady=PADY)
frame.columnconfigure(1, weight=1) label_frame.columnconfigure(0, weight=1)
frame.columnconfigure(2, weight=1)
label = ttk.Label(frame, text="Fill color")
label.grid(row=0, column=0, sticky="nsew")
self.fill = ttk.Label(
frame, text=self.fill_color, background=self.fill_color
)
self.fill.grid(row=0, column=1, sticky="nsew", padx=3)
button = ttk.Button(frame, text="Color", command=self.choose_fill_color)
button.grid(row=0, column=2, sticky="nsew")
frame.grid(row=3, column=0, sticky="nsew", padx=3, pady=3)
frame = ttk.Frame(self.top) frame = ttk.Frame(label_frame)
frame.columnconfigure(0, weight=1) frame.grid(sticky="ew")
frame.columnconfigure(1, weight=1) for i in range(1, 3):
frame.columnconfigure(2, weight=1) frame.columnconfigure(i, weight=1)
label = ttk.Label(frame, text="Border color:") label = ttk.Label(frame, text="Fill Color")
label.grid(row=0, column=0, sticky="nsew") label.grid(row=0, column=0, padx=PADX, sticky="w")
self.border = ttk.Label( self.fill = ttk.Label(frame, text=self.fill_color, background=self.fill_color)
frame, text=self.border_color, background=self.fill_color self.fill.grid(row=0, column=1, sticky="ew", padx=PADX)
) button = ttk.Button(frame, text="Color", command=self.choose_fill_color)
self.border.grid(row=0, column=1, sticky="nsew", padx=3) button.grid(row=0, column=2, sticky="ew")
button = ttk.Button(frame, text="Color", command=self.choose_border_color)
button.grid(row=0, column=2, sticky="nsew")
frame.grid(row=4, column=0, sticky="nsew", padx=3, pady=3)
frame = ttk.Frame(self.top) label = ttk.Label(frame, text="Border Color")
frame.columnconfigure(0, weight=1) label.grid(row=1, column=0, sticky="w", padx=PADX)
frame.columnconfigure(1, weight=2) self.border = ttk.Label(
label = ttk.Label(frame, text="Border width:") frame, text=self.border_color, background=self.border_color
label.grid(row=0, column=0, sticky="nsew") )
combobox = ttk.Combobox( self.border.grid(row=1, column=1, sticky="ew", padx=PADX)
frame, button = ttk.Button(frame, text="Color", command=self.choose_border_color)
textvariable=self.border_width, button.grid(row=1, column=2, sticky="ew")
values=BORDER_WIDTH,
state="readonly",
)
combobox.grid(row=0, column=1, sticky="nsew")
frame.grid(row=5, column=0, sticky="nsew", padx=3, pady=3)
frame = ttk.Frame(label_frame)
frame.grid(sticky="ew", pady=PADY)
frame.columnconfigure(1, weight=1)
label = ttk.Label(frame, text="Border Width")
label.grid(row=0, column=0, sticky="w", padx=PADX)
combobox = ttk.Combobox(
frame, textvariable=self.border_width, values=BORDER_WIDTH, state="readonly"
)
combobox.grid(row=0, column=1, sticky="nsew")
def draw_buttons(self):
frame = ttk.Frame(self.top) frame = ttk.Frame(self.top)
frame.grid(sticky="nsew")
frame.columnconfigure(0, weight=1) frame.columnconfigure(0, weight=1)
frame.columnconfigure(1, weight=1) frame.columnconfigure(1, weight=1)
button = ttk.Button(frame, text="Add shape", command=self.click_add) button = ttk.Button(frame, text="Add shape", command=self.click_add)
button.grid(row=0, column=0, sticky="e", padx=3) button.grid(row=0, column=0, sticky="ew", padx=PADX)
button = ttk.Button(frame, text="Cancel", command=self.cancel) button = ttk.Button(frame, text="Cancel", command=self.cancel)
button.grid(row=0, column=1, sticky="w", pady=3) button.grid(row=0, column=1, sticky="ew")
frame.grid(row=6, column=0, sticky="nsew", padx=3, pady=3)
def choose_text_color(self): def choose_text_color(self):
color = colorchooser.askcolor(color="black") color = colorchooser.askcolor(color="black")
@ -140,7 +143,7 @@ class ShapeDialog(Dialog):
self.fill.config(background=color[1], text=color[1]) self.fill.config(background=color[1], text=color[1])
def choose_border_color(self): def choose_border_color(self):
color = colorchooser.askcolor(color="black") color = colorchooser.askcolor(color=self.border_color)
self.border_color = color[1] self.border_color = color[1]
self.border.config(background=color[1], text=color[1]) self.border.config(background=color[1], text=color[1])

View file

@ -8,10 +8,9 @@ import grpc
from coretk.dialogs.dialog import Dialog from coretk.dialogs.dialog import Dialog
from coretk.errors import show_grpc_error from coretk.errors import show_grpc_error
from coretk.themes import PADX, PADY
from coretk.widgets import ConfigFrame from coretk.widgets import ConfigFrame
PAD = 5
class WlanConfigDialog(Dialog): class WlanConfigDialog(Dialog):
def __init__(self, master, app, canvas_node): def __init__(self, master, app, canvas_node):
@ -30,9 +29,10 @@ class WlanConfigDialog(Dialog):
def draw(self): def draw(self):
self.top.columnconfigure(0, weight=1) self.top.columnconfigure(0, weight=1)
self.config_frame = ConfigFrame(self.top, self.app, self.config, borderwidth=0) self.top.rowconfigure(0, weight=1)
self.config_frame = ConfigFrame(self.top, self.app, self.config)
self.config_frame.draw_config() self.config_frame.draw_config()
self.config_frame.grid(sticky="nsew", pady=PAD) self.config_frame.grid(sticky="nsew", pady=PADY)
self.draw_apply_buttons() self.draw_apply_buttons()
def draw_apply_buttons(self): def draw_apply_buttons(self):
@ -47,7 +47,7 @@ class WlanConfigDialog(Dialog):
frame.columnconfigure(i, weight=1) frame.columnconfigure(i, weight=1)
button = ttk.Button(frame, text="Apply", command=self.click_apply) button = ttk.Button(frame, text="Apply", command=self.click_apply)
button.grid(row=0, column=0, padx=PAD, sticky="ew") button.grid(row=0, column=0, padx=PADX, sticky="ew")
button = ttk.Button(frame, text="Cancel", command=self.destroy) button = ttk.Button(frame, text="Cancel", command=self.destroy)
button.grid(row=0, column=1, sticky="ew") button.grid(row=0, column=1, sticky="ew")

View file

@ -5,6 +5,7 @@ import grpc
from core.api.grpc import core_pb2 from core.api.grpc import core_pb2
from core.api.grpc.core_pb2 import NodeType from core.api.grpc.core_pb2 import NodeType
from coretk import themes
from coretk.dialogs.emaneconfig import EmaneConfigDialog from coretk.dialogs.emaneconfig import EmaneConfigDialog
from coretk.dialogs.mobilityconfig import MobilityConfigDialog from coretk.dialogs.mobilityconfig import MobilityConfigDialog
from coretk.dialogs.nodeconfig import NodeConfigDialog from coretk.dialogs.nodeconfig import NodeConfigDialog
@ -162,6 +163,7 @@ class CanvasNode:
is_wlan = self.core_node.type == NodeType.WIRELESS_LAN is_wlan = self.core_node.type == NodeType.WIRELESS_LAN
is_emane = self.core_node.type == NodeType.EMANE is_emane = self.core_node.type == NodeType.EMANE
context = tk.Menu(self.canvas) context = tk.Menu(self.canvas)
themes.update_menu(self.app.style, context)
if self.app.core.is_runtime(): if self.app.core.is_runtime():
context.add_command(label="Configure", command=self.show_config) context.add_command(label="Configure", command=self.show_config)
if NodeUtils.is_container_node(self.core_node.type): if NodeUtils.is_container_node(self.core_node.type):

View file

@ -12,8 +12,8 @@ import grpc
from coretk.appconfig import XML_PATH from coretk.appconfig import XML_PATH
from coretk.dialogs.about import AboutDialog from coretk.dialogs.about import AboutDialog
from coretk.dialogs.canvasbackground import CanvasBackgroundDialog
from coretk.dialogs.canvassizeandscale import SizeAndScaleDialog from coretk.dialogs.canvassizeandscale import SizeAndScaleDialog
from coretk.dialogs.canvaswallpaper import CanvasBackgroundDialog
from coretk.dialogs.hooks import HooksDialog from coretk.dialogs.hooks import HooksDialog
from coretk.dialogs.observers import ObserverDialog from coretk.dialogs.observers import ObserverDialog
from coretk.dialogs.preferences import PreferencesDialog from coretk.dialogs.preferences import PreferencesDialog

View file

@ -80,6 +80,7 @@ class Menubar(tk.Menu):
:return: nothing :return: nothing
""" """
menu = tk.Menu(self) menu = tk.Menu(self)
menu.add_command(label="Preferences", command=self.menuaction.gui_preferences)
menu.add_command(label="Undo", accelerator="Ctrl+Z", state=tk.DISABLED) menu.add_command(label="Undo", accelerator="Ctrl+Z", state=tk.DISABLED)
menu.add_command(label="Redo", accelerator="Ctrl+Y", state=tk.DISABLED) menu.add_command(label="Redo", accelerator="Ctrl+Y", state=tk.DISABLED)
menu.add_separator() menu.add_separator()
@ -94,9 +95,6 @@ class Menubar(tk.Menu):
menu.add_separator() menu.add_separator()
menu.add_command(label="Find...", accelerator="Ctrl+F", state=tk.DISABLED) menu.add_command(label="Find...", accelerator="Ctrl+F", state=tk.DISABLED)
menu.add_command(label="Clear marker", state=tk.DISABLED) menu.add_command(label="Clear marker", state=tk.DISABLED)
menu.add_command(
label="Preferences...", command=self.menuaction.gui_preferences
)
self.add_cascade(label="Edit", menu=menu) self.add_cascade(label="Edit", menu=menu)
def draw_canvas_menu(self): def draw_canvas_menu(self):
@ -436,16 +434,14 @@ class Menubar(tk.Menu):
""" """
menu = tk.Menu(self) menu = tk.Menu(self)
menu.add_command( menu.add_command(
label="Change sessions...", label="Sessions...", command=self.menuaction.session_change_sessions
command=self.menuaction.session_change_sessions,
underline=0,
) )
menu.add_separator() menu.add_separator()
menu.add_command(label="Comments...", state=tk.DISABLED)
menu.add_command(label="Hooks...", command=self.menuaction.session_hooks)
menu.add_command(label="Reset node positions", state=tk.DISABLED)
menu.add_command(label="Servers...", command=self.menuaction.session_servers)
menu.add_command(label="Options...", command=self.menuaction.session_options) menu.add_command(label="Options...", command=self.menuaction.session_options)
menu.add_command(label="Servers...", command=self.menuaction.session_servers)
menu.add_command(label="Hooks...", command=self.menuaction.session_hooks)
menu.add_command(label="Reset Nodes", state=tk.DISABLED)
menu.add_command(label="Comments...", state=tk.DISABLED)
self.add_cascade(label="Session", menu=menu) self.add_cascade(label="Session", menu=menu)
def draw_help_menu(self): def draw_help_menu(self):

View file

@ -13,18 +13,16 @@ class NodeDraw:
self.image_file = None self.image_file = None
self.node_type = None self.node_type = None
self.model = None self.model = None
self.tooltip = None
self.services = set() self.services = set()
@classmethod @classmethod
def from_setup(cls, image_enum, node_type, model=None, tooltip=None): def from_setup(cls, image_enum, node_type, label, model=None, tooltip=None):
node_draw = NodeDraw() node_draw = NodeDraw()
node_draw.image_enum = image_enum node_draw.image_enum = image_enum
node_draw.image = Images.get(image_enum, ICON_SIZE) node_draw.image = Images.get(image_enum, ICON_SIZE)
node_draw.node_type = node_type node_draw.node_type = node_type
node_draw.label = label
node_draw.model = model node_draw.model = model
if tooltip is None:
tooltip = model
node_draw.tooltip = tooltip node_draw.tooltip = tooltip
return node_draw return node_draw
@ -36,6 +34,7 @@ class NodeDraw:
node_draw.image = Images.get_custom(image_file, ICON_SIZE) node_draw.image = Images.get_custom(image_file, ICON_SIZE)
node_draw.node_type = NodeType.DEFAULT node_draw.node_type = NodeType.DEFAULT
node_draw.services = services node_draw.services = services
node_draw.label = name
node_draw.model = name node_draw.model = name
node_draw.tooltip = name node_draw.tooltip = name
return node_draw return node_draw
@ -81,29 +80,29 @@ class NodeUtils:
@classmethod @classmethod
def setup(cls): def setup(cls):
nodes = [ nodes = [
(ImageEnum.ROUTER, NodeType.DEFAULT, "router"), (ImageEnum.ROUTER, NodeType.DEFAULT, "Router", "router"),
(ImageEnum.HOST, NodeType.DEFAULT, "host"), (ImageEnum.HOST, NodeType.DEFAULT, "Host", "host"),
(ImageEnum.PC, NodeType.DEFAULT, "PC"), (ImageEnum.PC, NodeType.DEFAULT, "PC", "PC"),
(ImageEnum.MDR, NodeType.DEFAULT, "mdr"), (ImageEnum.MDR, NodeType.DEFAULT, "MDR", "mdr"),
(ImageEnum.PROUTER, NodeType.DEFAULT, "prouter"), (ImageEnum.PROUTER, NodeType.DEFAULT, "PRouter", "prouter"),
(ImageEnum.DOCKER, NodeType.DOCKER, "Docker"), (ImageEnum.DOCKER, NodeType.DOCKER, "Docker", None),
(ImageEnum.LXC, NodeType.LXC, "LXC"), (ImageEnum.LXC, NodeType.LXC, "LXC", None),
] ]
for image_enum, node_type, model in nodes: for image_enum, node_type, label, model in nodes:
node_draw = NodeDraw.from_setup(image_enum, node_type, model) node_draw = NodeDraw.from_setup(image_enum, node_type, label, model)
cls.NODES.append(node_draw) cls.NODES.append(node_draw)
cls.NODE_ICONS[(node_type, model)] = node_draw.image cls.NODE_ICONS[(node_type, model)] = node_draw.image
network_nodes = [ network_nodes = [
(ImageEnum.HUB, NodeType.HUB, "ethernet hub"), (ImageEnum.HUB, NodeType.HUB, "Hub"),
(ImageEnum.SWITCH, NodeType.SWITCH, "ethernet switch"), (ImageEnum.SWITCH, NodeType.SWITCH, "Switch"),
(ImageEnum.WLAN, NodeType.WIRELESS_LAN, "wireless LAN"), (ImageEnum.WLAN, NodeType.WIRELESS_LAN, "WLAN"),
(ImageEnum.EMANE, NodeType.EMANE, "EMANE"), (ImageEnum.EMANE, NodeType.EMANE, "EMANE"),
(ImageEnum.RJ45, NodeType.RJ45, "rj45 physical interface tool"), (ImageEnum.RJ45, NodeType.RJ45, "RJ45"),
(ImageEnum.TUNNEL, NodeType.TUNNEL, "tunnel tool"), (ImageEnum.TUNNEL, NodeType.TUNNEL, "Tunnel"),
] ]
for image_enum, node_type, tooltip in network_nodes: for image_enum, node_type, label in network_nodes:
node_draw = NodeDraw.from_setup(image_enum, node_type, tooltip=tooltip) node_draw = NodeDraw.from_setup(image_enum, node_type, label)
cls.NETWORK_NODES.append(node_draw) cls.NETWORK_NODES.append(node_draw)
cls.NODE_ICONS[(node_type, None)] = node_draw.image cls.NODE_ICONS[(node_type, None)] = node_draw.image
cls.ANTENNA_ICON = Images.get(ImageEnum.ANTENNA, ANTENNA_SIZE) cls.ANTENNA_ICON = Images.get(ImageEnum.ANTENNA, ANTENNA_SIZE)

View file

@ -1,13 +1,18 @@
import logging import logging
import tkinter as tk import tkinter as tk
DARK = "black" THEME_DARK = "black"
PADX = (0, 5)
PADY = (0, 5)
FRAME_PAD = 5
DIALOG_PAD = 5
class Styles: class Styles:
tooltip = "Tooltip.TLabel" tooltip = "Tooltip.TLabel"
tooltip_frame = "Tooltip.TFrame" tooltip_frame = "Tooltip.TFrame"
service_checkbutton = "Service.TCheckbutton" service_checkbutton = "Service.TCheckbutton"
picker_button = "Picker.TButton"
class Colors: class Colors:
@ -27,7 +32,7 @@ class Colors:
def load(style): def load(style):
style.theme_create( style.theme_create(
DARK, THEME_DARK,
"clam", "clam",
{ {
".": { ".": {
@ -139,14 +144,22 @@ def update_bg(style, event):
event.widget.config(background=bg) event.widget.config(background=bg)
def update_menu(style, event): def theme_change_menu(style, event):
if not isinstance(event.widget, tk.Menu): if not isinstance(event.widget, tk.Menu):
return return
update_menu(style, event.widget)
def update_menu(style, widget):
bg = style.lookup(".", "background") bg = style.lookup(".", "background")
fg = style.lookup(".", "foreground") fg = style.lookup(".", "foreground")
abg = style.lookup(".", "lightcolor") abg = style.lookup(".", "lightcolor")
if not abg: if not abg:
abg = bg abg = bg
event.widget.config( widget.config(
background=bg, foreground=fg, activebackground=abg, activeforeground=fg background=bg, foreground=fg, activebackground=abg, activeforeground=fg
) )
def theme_change(style, event):
style.configure(Styles.picker_button, font=("TkDefaultFont", 8, "normal"))

View file

@ -3,6 +3,7 @@ import threading
import tkinter as tk import tkinter as tk
from functools import partial from functools import partial
from tkinter import ttk from tkinter import ttk
from tkinter.font import Font
from coretk.dialogs.customnodes import CustomNodesDialog from coretk.dialogs.customnodes import CustomNodesDialog
from coretk.graph import tags from coretk.graph import tags
@ -10,13 +11,15 @@ from coretk.graph.enums import GraphMode
from coretk.graph.shapeutils import ShapeType from coretk.graph.shapeutils import ShapeType
from coretk.images import ImageEnum, Images from coretk.images import ImageEnum, Images
from coretk.nodeutils import NodeUtils from coretk.nodeutils import NodeUtils
from coretk.themes import Styles
from coretk.tooltip import Tooltip from coretk.tooltip import Tooltip
WIDTH = 32 WIDTH = 32
PICKER_SIZE = 24
def icon(image_enum): def icon(image_enum, width=WIDTH):
return Images.get(image_enum, WIDTH) return Images.get(image_enum, width)
class Toolbar(ttk.Frame): class Toolbar(ttk.Frame):
@ -34,6 +37,9 @@ class Toolbar(ttk.Frame):
self.app = app self.app = app
self.master = app.master self.master = app.master
# picker data
self.picker_font = Font(size=8)
# design buttons # design buttons
self.select_button = None self.select_button = None
self.link_button = None self.link_button = None
@ -140,9 +146,9 @@ class Toolbar(ttk.Frame):
self.node_picker = ttk.Frame(self.master) self.node_picker = ttk.Frame(self.master)
# draw default nodes # draw default nodes
for node_draw in NodeUtils.NODES: for node_draw in NodeUtils.NODES:
image = icon(node_draw.image_enum) image = icon(node_draw.image_enum, PICKER_SIZE)
func = partial(self.update_button, self.node_button, image, node_draw) func = partial(self.update_button, self.node_button, image, node_draw)
self.create_picker_button(image, func, self.node_picker, node_draw.tooltip) self.create_picker_button(image, func, self.node_picker, node_draw.label)
# draw custom nodes # draw custom nodes
for name in sorted(self.app.core.custom_nodes): for name in sorted(self.app.core.custom_nodes):
node_draw = self.app.core.custom_nodes[name] node_draw = self.app.core.custom_nodes[name]
@ -152,7 +158,7 @@ class Toolbar(ttk.Frame):
# draw edit node # draw edit node
image = icon(ImageEnum.EDITNODE) image = icon(ImageEnum.EDITNODE)
self.create_picker_button( self.create_picker_button(
image, self.click_edit_node, self.node_picker, "custom nodes" image, self.click_edit_node, self.node_picker, "Custom"
) )
self.design_select(self.node_button) self.design_select(self.node_button)
self.node_button.after( self.node_button.after(
@ -169,21 +175,22 @@ class Toolbar(ttk.Frame):
self.wait_window(picker) self.wait_window(picker)
self.app.unbind_all("<ButtonRelease-1>") self.app.unbind_all("<ButtonRelease-1>")
def create_picker_button(self, image, func, frame, tooltip): def create_picker_button(self, image, func, frame, label):
""" """
Create button and put it on the frame Create button and put it on the frame
:param PIL.Image image: button image :param PIL.Image image: button image
:param func: the command that is executed when button is clicked :param func: the command that is executed when button is clicked
:param tkinter.Frame frame: frame that contains the button :param tkinter.Frame frame: frame that contains the button
:param str tooltip: tooltip text :param str label: button label
:return: nothing :return: nothing
""" """
button = ttk.Button(frame, image=image) button = ttk.Button(
frame, image=image, text=label, compound=tk.TOP, style=Styles.picker_button
)
button.image = image button.image = image
button.bind("<ButtonRelease-1>", lambda e: func()) button.bind("<ButtonRelease-1>", lambda e: func())
button.grid(pady=1) button.grid(pady=1)
Tooltip(button, tooltip)
def create_button(self, frame, image, func, tooltip): def create_button(self, frame, image, func, tooltip):
button = ttk.Button(frame, image=image, command=func) button = ttk.Button(frame, image=image, command=func)
@ -269,12 +276,12 @@ class Toolbar(ttk.Frame):
self.hide_pickers() self.hide_pickers()
self.network_picker = ttk.Frame(self.master) self.network_picker = ttk.Frame(self.master)
for node_draw in NodeUtils.NETWORK_NODES: for node_draw in NodeUtils.NETWORK_NODES:
image = icon(node_draw.image_enum) image = icon(node_draw.image_enum, PICKER_SIZE)
self.create_picker_button( self.create_picker_button(
image, image,
partial(self.update_button, self.network_button, image, node_draw), partial(self.update_button, self.network_button, image, node_draw),
self.network_picker, self.network_picker,
node_draw.tooltip, node_draw.label,
) )
self.design_select(self.network_button) self.design_select(self.network_button)
self.network_button.after( self.network_button.after(
@ -311,7 +318,7 @@ class Toolbar(ttk.Frame):
(ImageEnum.TEXT, ShapeType.TEXT), (ImageEnum.TEXT, ShapeType.TEXT),
] ]
for image_enum, shape_type in nodes: for image_enum, shape_type in nodes:
image = icon(image_enum) image = icon(image_enum, PICKER_SIZE)
self.create_picker_button( self.create_picker_button(
image, image,
partial(self.update_annotation, image, shape_type), partial(self.update_annotation, image, shape_type),

View file

@ -5,6 +5,7 @@ from tkinter import filedialog, font, ttk
from tkinter.scrolledtext import ScrolledText from tkinter.scrolledtext import ScrolledText
from core.api.grpc import core_pb2 from core.api.grpc import core_pb2
from coretk.themes import FRAME_PAD, PADX, PADY
INT_TYPES = { INT_TYPES = {
core_pb2.ConfigOptionType.UINT8, core_pb2.ConfigOptionType.UINT8,
@ -16,7 +17,6 @@ INT_TYPES = {
core_pb2.ConfigOptionType.INT32, core_pb2.ConfigOptionType.INT32,
core_pb2.ConfigOptionType.INT64, core_pb2.ConfigOptionType.INT64,
} }
PAD = 5
def file_button_click(value): def file_button_click(value):
@ -65,14 +65,12 @@ class FrameScroll(ttk.LabelFrame):
class ConfigFrame(FrameScroll): class ConfigFrame(FrameScroll):
def __init__(self, master, app, config, **kw): def __init__(self, master, app, config, **kw):
super().__init__(master, app, ttk.Notebook, **kw) super().__init__(master, app, ttk.Notebook, borderwidth=0, **kw)
self.app = app self.app = app
self.config = config self.config = config
self.values = {} self.values = {}
def draw_config(self): def draw_config(self):
padx = 2
pady = 2
group_mapping = {} group_mapping = {}
for key in self.config: for key in self.config:
option = self.config[key] option = self.config[key]
@ -81,19 +79,19 @@ class ConfigFrame(FrameScroll):
for group_name in sorted(group_mapping): for group_name in sorted(group_mapping):
group = group_mapping[group_name] group = group_mapping[group_name]
frame = ttk.Frame(self.frame, padding=PAD) frame = ttk.Frame(self.frame, padding=FRAME_PAD)
frame.columnconfigure(1, weight=1) frame.columnconfigure(1, weight=1)
self.frame.add(frame, text=group_name) self.frame.add(frame, text=group_name)
for index, option in enumerate(sorted(group, key=lambda x: x.name)): for index, option in enumerate(sorted(group, key=lambda x: x.name)):
label = ttk.Label(frame, text=option.label) label = ttk.Label(frame, text=option.label)
label.grid(row=index, pady=pady, padx=padx, sticky="w") label.grid(row=index, pady=PADY, padx=PADX, sticky="w")
value = tk.StringVar() value = tk.StringVar()
if option.type == core_pb2.ConfigOptionType.BOOL: if option.type == core_pb2.ConfigOptionType.BOOL:
select = tuple(option.select) select = tuple(option.select)
combobox = ttk.Combobox( combobox = ttk.Combobox(
frame, textvariable=value, values=select, state="readonly" frame, textvariable=value, values=select, state="readonly"
) )
combobox.grid(row=index, column=1, sticky="ew", pady=pady) combobox.grid(row=index, column=1, sticky="ew")
if option.value == "1": if option.value == "1":
value.set("On") value.set("On")
else: else:
@ -104,15 +102,15 @@ class ConfigFrame(FrameScroll):
combobox = ttk.Combobox( combobox = ttk.Combobox(
frame, textvariable=value, values=select, state="readonly" frame, textvariable=value, values=select, state="readonly"
) )
combobox.grid(row=index, column=1, sticky="ew", pady=pady) combobox.grid(row=index, column=1, sticky="ew")
elif option.type == core_pb2.ConfigOptionType.STRING: elif option.type == core_pb2.ConfigOptionType.STRING:
value.set(option.value) value.set(option.value)
if "file" in option.label: if "file" in option.label:
file_frame = ttk.Frame(frame) file_frame = ttk.Frame(frame)
file_frame.grid(row=index, column=1, sticky="ew", pady=pady) file_frame.grid(row=index, column=1, sticky="ew")
file_frame.columnconfigure(0, weight=1) file_frame.columnconfigure(0, weight=1)
entry = ttk.Entry(file_frame, textvariable=value) entry = ttk.Entry(file_frame, textvariable=value)
entry.grid(row=0, column=0, sticky="ew", padx=padx) entry.grid(row=0, column=0, sticky="ew", padx=PADX)
func = partial(file_button_click, value) func = partial(file_button_click, value)
button = ttk.Button(file_frame, text="...", command=func) button = ttk.Button(file_frame, text="...", command=func)
button.grid(row=0, column=1) button.grid(row=0, column=1)
@ -124,10 +122,10 @@ class ConfigFrame(FrameScroll):
validate="key", validate="key",
validatecommand=(self.app.validation.ip4, "%P"), validatecommand=(self.app.validation.ip4, "%P"),
) )
entry.grid(row=index, column=1, sticky="ew", pady=pady) entry.grid(row=index, column=1, sticky="ew")
else: else:
entry = ttk.Entry(frame, textvariable=value) entry = ttk.Entry(frame, textvariable=value)
entry.grid(row=index, column=1, sticky="ew", pady=pady) entry.grid(row=index, column=1, sticky="ew")
elif option.type in INT_TYPES: elif option.type in INT_TYPES:
value.set(option.value) value.set(option.value)
@ -141,7 +139,7 @@ class ConfigFrame(FrameScroll):
"<FocusOut>", "<FocusOut>",
lambda event: self.app.validation.focus_out(event, "0"), lambda event: self.app.validation.focus_out(event, "0"),
) )
entry.grid(row=index, column=1, sticky="ew", pady=pady) entry.grid(row=index, column=1, sticky="ew")
elif option.type == core_pb2.ConfigOptionType.FLOAT: elif option.type == core_pb2.ConfigOptionType.FLOAT:
value.set(option.value) value.set(option.value)
entry = ttk.Entry( entry = ttk.Entry(
@ -154,7 +152,7 @@ class ConfigFrame(FrameScroll):
"<FocusOut>", "<FocusOut>",
lambda event: self.app.validation.focus_out(event, "0"), lambda event: self.app.validation.focus_out(event, "0"),
) )
entry.grid(row=index, column=1, sticky="ew", pady=pady) entry.grid(row=index, column=1, sticky="ew")
else: else:
logging.error("unhandled config option type: %s", option.type) logging.error("unhandled config option type: %s", option.type)
self.values[option.name] = value self.values[option.name] = value