diff --git a/coretk/coretk/app.py b/coretk/coretk/app.py index 0a9275f1..7c2562a9 100644 --- a/coretk/coretk/app.py +++ b/coretk/coretk/app.py @@ -14,6 +14,9 @@ from coretk.statusbar import StatusBar from coretk.toolbar import Toolbar from coretk.validation import InputValidation +WIDTH = 1000 +HEIGHT = 800 + class Application(tk.Frame): def __init__(self, master=None): @@ -40,7 +43,7 @@ class Application(tk.Frame): def setup_theme(self): themes.load(self.style) 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", "<>", func) func = partial(themes.theme_change, self.style) self.master.bind("<>", func) @@ -55,13 +58,11 @@ class Application(tk.Frame): self.validation = InputValidation(self) def center(self): - width = 1000 - height = 800 screen_width = self.master.winfo_screenwidth() screen_height = self.master.winfo_screenheight() - x = int((screen_width / 2) - (width / 2)) - y = int((screen_height / 2) - (height / 2)) - self.master.geometry(f"{width}x{height}+{x}+{y}") + x = int((screen_width / 2) - (WIDTH / 2)) + y = int((screen_height / 2) - (HEIGHT / 2)) + self.master.geometry(f"{WIDTH}x{HEIGHT}+{x}+{y}") def draw(self): self.master.option_add("*tearOff", tk.FALSE) diff --git a/coretk/coretk/dialogs/canvassizeandscale.py b/coretk/coretk/dialogs/canvassizeandscale.py index 2798f6f2..1fcfff59 100644 --- a/coretk/coretk/dialogs/canvassizeandscale.py +++ b/coretk/coretk/dialogs/canvassizeandscale.py @@ -46,6 +46,7 @@ class SizeAndScaleDialog(Dialog): self.draw_scale() self.draw_reference_point() self.draw_save_as_default() + self.draw_spacer() self.draw_buttons() def draw_size(self): diff --git a/coretk/coretk/dialogs/canvasbackground.py b/coretk/coretk/dialogs/canvaswallpaper.py similarity index 90% rename from coretk/coretk/dialogs/canvasbackground.py rename to coretk/coretk/dialogs/canvaswallpaper.py index 844b5595..bf6bf922 100644 --- a/coretk/coretk/dialogs/canvasbackground.py +++ b/coretk/coretk/dialogs/canvaswallpaper.py @@ -9,7 +9,7 @@ from coretk.appconfig import BACKGROUNDS_PATH from coretk.dialogs.dialog import Dialog from coretk.images import Images -PADX = 5 +PAD = 5 class CanvasBackgroundDialog(Dialog): @@ -36,17 +36,18 @@ class CanvasBackgroundDialog(Dialog): self.draw_image_selection() self.draw_options() self.draw_additional_options() + self.draw_spacer() self.draw_buttons() def draw_image(self): self.image_label = ttk.Label( 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=PAD) def draw_image_label(self): label = ttk.Label(self.top, text="Image filename: ") - label.grid(row=1, column=0, sticky="ew") + label.grid(sticky="ew") if self.filename.get(): self.draw_preview() @@ -55,14 +56,14 @@ class CanvasBackgroundDialog(Dialog): frame.columnconfigure(0, weight=2) frame.columnconfigure(1, 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.focus() - entry.grid(row=0, column=0, sticky="ew", padx=PADX) + entry.grid(row=0, column=0, sticky="ew", padx=PAD) button = ttk.Button(frame, text="...", command=self.click_open_image) - button.grid(row=0, column=1, sticky="ew", padx=PADX) + button.grid(row=0, column=1, sticky="ew", padx=PAD) button = ttk.Button(frame, text="Clear", command=self.click_clear) button.grid(row=0, column=2, sticky="ew") @@ -73,7 +74,7 @@ class CanvasBackgroundDialog(Dialog): frame.columnconfigure(1, weight=1) frame.columnconfigure(2, weight=1) frame.columnconfigure(3, weight=1) - frame.grid(row=3, column=0, sticky="ew") + frame.grid(sticky="ew") button = ttk.Radiobutton( frame, text="upper-left", value=1, variable=self.scale_option @@ -103,7 +104,7 @@ class CanvasBackgroundDialog(Dialog): checkbutton = ttk.Checkbutton( self.top, text="Show grid", variable=self.show_grid ) - checkbutton.grid(row=4, column=0, sticky="ew", padx=PADX) + checkbutton.grid(sticky="ew", padx=PAD) checkbutton = ttk.Checkbutton( self.top, @@ -111,16 +112,16 @@ class CanvasBackgroundDialog(Dialog): variable=self.adjust_to_dim, command=self.click_adjust_canvas, ) - checkbutton.grid(row=5, column=0, sticky="ew", padx=PADX) + checkbutton.grid(sticky="ew", padx=PAD) def draw_buttons(self): frame = ttk.Frame(self.top) - frame.grid(row=6, column=0, pady=5, sticky="ew") + frame.grid(pady=PAD, sticky="ew") frame.columnconfigure(0, weight=1) frame.columnconfigure(1, weight=1) button = ttk.Button(frame, text="Apply", command=self.click_apply) - button.grid(row=0, column=0, sticky="ew", padx=PADX) + button.grid(row=0, column=0, sticky="ew", padx=PAD) button = ttk.Button(frame, text="Cancel", command=self.destroy) button.grid(row=0, column=1, sticky="ew") diff --git a/coretk/coretk/dialogs/customnodes.py b/coretk/coretk/dialogs/customnodes.py index dbf431d3..75052e6b 100644 --- a/coretk/coretk/dialogs/customnodes.py +++ b/coretk/coretk/dialogs/customnodes.py @@ -8,6 +8,8 @@ from coretk.dialogs.icondialog import IconDialog from coretk.nodeutils import NodeDraw from coretk.widgets import CheckboxList, ListboxScroll +PAD = 5 + class ServicesSelectDialog(Dialog): def __init__(self, master, app, current_services): @@ -23,11 +25,11 @@ class ServicesSelectDialog(Dialog): self.top.rowconfigure(0, weight=1) frame = ttk.Frame(self.top) - frame.grid(stick="nsew") + frame.grid(stick="nsew", pady=PAD) frame.rowconfigure(0, weight=1) for i in range(3): frame.columnconfigure(i, weight=1) - self.groups = ListboxScroll(frame, text="Groups") + self.groups = ListboxScroll(frame, text="Groups", padding=PAD) self.groups.grid(row=0, column=0, sticky="nsew") for group in sorted(self.app.core.services): self.groups.listbox.insert(tk.END, group) @@ -35,11 +37,11 @@ class ServicesSelectDialog(Dialog): self.groups.listbox.selection_set(0) self.services = CheckboxList( - frame, self.app, text="Services", clicked=self.service_clicked + frame, self.app, text="Services", clicked=self.service_clicked, padding=PAD ) self.services.grid(row=0, column=1, sticky="nsew") - self.current = ListboxScroll(frame, text="Selected") + self.current = ListboxScroll(frame, text="Selected", padding=PAD) self.current.grid(row=0, column=2, sticky="nsew") for service in sorted(self.current_services): self.current.listbox.insert(tk.END, service) @@ -49,7 +51,7 @@ class ServicesSelectDialog(Dialog): for i in range(2): frame.columnconfigure(i, weight=1) 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=PAD) button = ttk.Button(frame, text="Cancel", command=self.click_cancel) button.grid(row=0, column=1, sticky="ew") @@ -104,12 +106,12 @@ class CustomNodesDialog(Dialog): def draw_node_config(self): frame = ttk.Frame(self.top) - frame.grid(sticky="nsew") + frame.grid(sticky="nsew", pady=PAD) frame.columnconfigure(0, weight=1) frame.rowconfigure(0, weight=1) - self.nodes_list = ListboxScroll(frame, text="Nodes") - self.nodes_list.grid(row=0, column=0, sticky="nsew") + self.nodes_list = ListboxScroll(frame, text="Nodes", padding=PAD) + self.nodes_list.grid(row=0, column=0, sticky="nsew", padx=PAD) self.nodes_list.listbox.bind("<>", self.handle_node_select) for name in sorted(self.app.core.custom_nodes): self.nodes_list.listbox.insert(tk.END, name) @@ -128,17 +130,17 @@ class CustomNodesDialog(Dialog): def draw_node_buttons(self): frame = ttk.Frame(self.top) - frame.grid(pady=2, sticky="ew") + frame.grid(sticky="ew", pady=PAD) for i in range(3): frame.columnconfigure(i, weight=1) 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=PAD) self.edit_button = ttk.Button( 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=PAD) self.delete_button = ttk.Button( frame, text="Delete", state=tk.DISABLED, command=self.click_delete @@ -152,7 +154,7 @@ class CustomNodesDialog(Dialog): frame.columnconfigure(i, weight=1) 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=PAD) button = ttk.Button(frame, text="Cancel", command=self.destroy) button.grid(row=0, column=1, sticky="ew") diff --git a/coretk/coretk/dialogs/dialog.py b/coretk/coretk/dialogs/dialog.py index 29362960..49662cc4 100644 --- a/coretk/coretk/dialogs/dialog.py +++ b/coretk/coretk/dialogs/dialog.py @@ -30,3 +30,9 @@ class Dialog(tk.Toplevel): self.wait_visibility() self.grab_set() 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) diff --git a/coretk/coretk/dialogs/emaneconfig.py b/coretk/coretk/dialogs/emaneconfig.py index a9042ba3..b16f7cd4 100644 --- a/coretk/coretk/dialogs/emaneconfig.py +++ b/coretk/coretk/dialogs/emaneconfig.py @@ -25,11 +25,10 @@ class GlobalEmaneDialog(Dialog): def draw(self): self.top.columnconfigure(0, weight=1) self.top.rowconfigure(0, weight=1) - self.config_frame = ConfigFrame( - self.top, self.app, self.app.core.emane_config, borderwidth=0 - ) + self.config_frame = ConfigFrame(self.top, self.app, self.app.core.emane_config) self.config_frame.draw_config() self.config_frame.grid(sticky="nsew", pady=PAD) + self.draw_spacer() self.draw_buttons() def draw_buttons(self): @@ -67,9 +66,10 @@ class EmaneModelDialog(Dialog): def draw(self): self.top.columnconfigure(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.grid(sticky="nsew", pady=PAD) + self.draw_spacer() self.draw_buttons() def draw_buttons(self): @@ -111,6 +111,7 @@ class EmaneConfigDialog(Dialog): self.draw_emane_configuration() self.draw_emane_models() self.draw_emane_buttons() + self.draw_spacer() self.draw_apply_and_cancel() def draw_emane_configuration(self): @@ -123,8 +124,9 @@ class EmaneConfigDialog(Dialog): self.top, 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", + justify=tk.CENTER, ) - label.grid(sticky="ew", pady=PAD) + label.grid(pady=PAD) image = Images.get(ImageEnum.EDITNODE, 16) button = ttk.Button( diff --git a/coretk/coretk/dialogs/hooks.py b/coretk/coretk/dialogs/hooks.py index d40f1c36..2850d70e 100644 --- a/coretk/coretk/dialogs/hooks.py +++ b/coretk/coretk/dialogs/hooks.py @@ -5,6 +5,8 @@ from core.api.grpc import core_pb2 from coretk.dialogs.dialog import Dialog from coretk.widgets import CodeText +PAD = 5 + class HookDialog(Dialog): def __init__(self, master, app): @@ -21,14 +23,14 @@ class HookDialog(Dialog): # name and states frame = ttk.Frame(self.top) - frame.grid(row=0, sticky="ew", pady=2) + frame.grid(sticky="ew", pady=PAD) frame.columnconfigure(0, weight=2) frame.columnconfigure(1, weight=7) frame.columnconfigure(2, weight=1) label = ttk.Label(frame, text="Name") - label.grid(row=0, column=0, sticky="ew") + label.grid(row=0, column=0, sticky="ew", padx=PAD) entry = ttk.Entry(frame, textvariable=self.name) - entry.grid(row=0, column=1, sticky="ew") + entry.grid(row=0, column=1, sticky="ew", padx=PAD) 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) self.state.set(initial_state) @@ -40,11 +42,7 @@ class HookDialog(Dialog): combobox.bind("<>", self.state_change) # data - frame = ttk.Frame(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 = CodeText(self.top) self.data.insert( 1.0, ( @@ -53,19 +51,15 @@ class HookDialog(Dialog): "# specified state\n" ), ) - self.data.grid(row=0, column=0, 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) + self.data.grid(sticky="nsew") # button row frame = ttk.Frame(self.top) - frame.grid(row=2, sticky="ew", pady=2) + frame.grid(sticky="ew") for i in range(2): frame.columnconfigure(i, weight=1) 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=PAD) button = ttk.Button(frame, text="Cancel", command=lambda: self.destroy()) button.grid(row=0, column=1, sticky="ew") @@ -104,25 +98,25 @@ class HooksDialog(Dialog): self.top.rowconfigure(0, weight=1) self.listbox = tk.Listbox(self.top) - self.listbox.grid(row=0, sticky="nsew") + self.listbox.grid(sticky="nsew", pady=PAD) self.listbox.bind("<>", self.select) for hook_file in self.app.core.hooks: self.listbox.insert(tk.END, hook_file) frame = ttk.Frame(self.top) - frame.grid(row=1, sticky="ew") + frame.grid(sticky="ew") for i in range(4): frame.columnconfigure(i, weight=1) 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=PAD) self.edit_button = ttk.Button( 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=PAD) self.delete_button = ttk.Button( 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=PAD) button = ttk.Button(frame, text="Cancel", command=lambda: self.destroy()) button.grid(row=0, column=3, sticky="ew") diff --git a/coretk/coretk/dialogs/icondialog.py b/coretk/coretk/dialogs/icondialog.py index 98a4ed55..9273a177 100644 --- a/coretk/coretk/dialogs/icondialog.py +++ b/coretk/coretk/dialogs/icondialog.py @@ -6,6 +6,8 @@ from coretk.appconfig import ICONS_PATH from coretk.dialogs.dialog import Dialog from coretk.images import Images +PAD = 5 + class IconDialog(Dialog): def __init__(self, master, app, name, image): @@ -20,27 +22,30 @@ class IconDialog(Dialog): # row one frame = ttk.Frame(self.top) - frame.grid(row=0, column=0, pady=2, sticky="ew") + frame.grid(pady=PAD, sticky="ew") frame.columnconfigure(0, weight=1) frame.columnconfigure(1, weight=3) label = ttk.Label(frame, text="Image") - label.grid(row=0, column=0, sticky="ew") + label.grid(row=0, column=0, sticky="ew", padx=PAD) 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=PAD) button = ttk.Button(frame, text="...", command=self.click_file) button.grid(row=0, column=2) # row two 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=PAD, sticky="ew") + + # spacer + self.draw_spacer() # row three frame = ttk.Frame(self.top) - frame.grid(row=2, column=0, sticky="ew") + frame.grid(sticky="ew") frame.columnconfigure(0, weight=1) frame.columnconfigure(1, weight=1) 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=PAD) button = ttk.Button(frame, text="Cancel", command=self.click_cancel) button.grid(row=0, column=1, sticky="ew") diff --git a/coretk/coretk/dialogs/mobilityconfig.py b/coretk/coretk/dialogs/mobilityconfig.py index 4e9d9590..007209dd 100644 --- a/coretk/coretk/dialogs/mobilityconfig.py +++ b/coretk/coretk/dialogs/mobilityconfig.py @@ -32,7 +32,8 @@ class MobilityConfigDialog(Dialog): def draw(self): 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.grid(sticky="nsew", pady=PAD) self.draw_apply_buttons() diff --git a/coretk/coretk/dialogs/mobilityplayer.py b/coretk/coretk/dialogs/mobilityplayer.py index 63698644..1e7b4dc1 100644 --- a/coretk/coretk/dialogs/mobilityplayer.py +++ b/coretk/coretk/dialogs/mobilityplayer.py @@ -61,6 +61,7 @@ class MobilityPlayerDialog(Dialog): super().__init__( master, app, f"{canvas_node.core_node.name} Mobility Player", modal=False ) + self.resizable(False, False) self.geometry("") self.canvas_node = canvas_node self.node = canvas_node.core_node diff --git a/coretk/coretk/dialogs/nodeconfig.py b/coretk/coretk/dialogs/nodeconfig.py index 8853e908..619c5ee7 100644 --- a/coretk/coretk/dialogs/nodeconfig.py +++ b/coretk/coretk/dialogs/nodeconfig.py @@ -66,6 +66,19 @@ class NodeConfigDialog(Dialog): frame.grid(sticky="ew") frame.columnconfigure(1, weight=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 + # name field label = ttk.Label(frame, text="Name") label.grid(row=row, column=0, sticky="ew", padx=PAD, pady=PAD) @@ -81,19 +94,6 @@ class NodeConfigDialog(Dialog): entry.grid(row=row, column=1, sticky="ew") 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 if NodeUtils.is_model_node(self.node.type): label = ttk.Label(frame, text="Type") @@ -137,6 +137,7 @@ class NodeConfigDialog(Dialog): if self.canvas_node.interfaces: self.draw_interfaces() + self.draw_spacer() self.draw_buttons() def draw_interfaces(self): diff --git a/coretk/coretk/dialogs/nodeservice.py b/coretk/coretk/dialogs/nodeservice.py index d950371b..dfcef922 100644 --- a/coretk/coretk/dialogs/nodeservice.py +++ b/coretk/coretk/dialogs/nodeservice.py @@ -8,6 +8,8 @@ from coretk.dialogs.dialog import Dialog from coretk.dialogs.serviceconfiguration import ServiceConfiguration from coretk.widgets import CheckboxList, ListboxScroll +PAD = 5 + class NodeService(Dialog): def __init__(self, master, app, canvas_node, services=None): @@ -38,7 +40,7 @@ class NodeService(Dialog): frame.rowconfigure(0, weight=1) for i in range(3): frame.columnconfigure(i, weight=1) - self.groups = ListboxScroll(frame, text="Groups") + self.groups = ListboxScroll(frame, text="Groups", padding=PAD) self.groups.grid(row=0, column=0, sticky="nsew") for group in sorted(self.app.core.services): self.groups.listbox.insert(tk.END, group) @@ -46,11 +48,11 @@ class NodeService(Dialog): self.groups.listbox.selection_set(0) self.services = CheckboxList( - frame, self.app, text="Services", clicked=self.service_clicked + frame, self.app, text="Services", clicked=self.service_clicked, padding=PAD ) self.services.grid(row=0, column=1, sticky="nsew") - self.current = ListboxScroll(frame, text="Selected") + self.current = ListboxScroll(frame, text="Selected", padding=PAD) self.current.grid(row=0, column=2, sticky="nsew") for service in sorted(self.current_services): self.current.listbox.insert(tk.END, service) @@ -60,9 +62,9 @@ class NodeService(Dialog): for i in range(3): frame.columnconfigure(i, weight=1) 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=PAD) 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=PAD) button = ttk.Button(frame, text="Cancel", command=self.click_cancel) button.grid(row=0, column=2, sticky="ew") diff --git a/coretk/coretk/dialogs/observers.py b/coretk/coretk/dialogs/observers.py index 58499bd7..525939e0 100644 --- a/coretk/coretk/dialogs/observers.py +++ b/coretk/coretk/dialogs/observers.py @@ -4,6 +4,8 @@ from tkinter import ttk from coretk.coreclient import Observer from coretk.dialogs.dialog import Dialog +PAD = 5 + class ObserverDialog(Dialog): def __init__(self, master, app): @@ -27,7 +29,7 @@ class ObserverDialog(Dialog): def draw_listbox(self): frame = ttk.Frame(self.top) - frame.grid(sticky="nsew") + frame.grid(sticky="nsew", pady=PAD) frame.columnconfigure(0, weight=1) frame.rowconfigure(0, weight=1) @@ -46,22 +48,22 @@ class ObserverDialog(Dialog): def draw_form_fields(self): frame = ttk.Frame(self.top) - frame.grid(sticky="ew") + frame.grid(sticky="ew", pady=PAD) frame.columnconfigure(1, weight=1) label = ttk.Label(frame, text="Name") - label.grid(row=0, column=0, sticky="w") + label.grid(row=0, column=0, sticky="w", padx=PAD) entry = ttk.Entry(frame, textvariable=self.name) entry.grid(row=0, column=1, sticky="ew") label = ttk.Label(frame, text="Command") - label.grid(row=1, column=0, sticky="w") + label.grid(row=1, column=0, sticky="w", padx=PAD) entry = ttk.Entry(frame, textvariable=self.cmd) entry.grid(row=1, column=1, sticky="ew") def draw_config_buttons(self): frame = ttk.Frame(self.top) - frame.grid(pady=2, sticky="ew") + frame.grid(sticky="ew", pady=PAD) for i in range(3): frame.columnconfigure(i, weight=1) diff --git a/coretk/coretk/dialogs/preferences.py b/coretk/coretk/dialogs/preferences.py index 7298f727..b094eec6 100644 --- a/coretk/coretk/dialogs/preferences.py +++ b/coretk/coretk/dialogs/preferences.py @@ -5,6 +5,8 @@ from tkinter import ttk from coretk import appconfig from coretk.dialogs.dialog import Dialog +PAD = 5 + class PreferencesDialog(Dialog): def __init__(self, master, app): @@ -18,16 +20,17 @@ class PreferencesDialog(Dialog): def draw(self): self.top.columnconfigure(0, weight=1) + self.top.rowconfigure(0, weight=1) self.draw_preferences() self.draw_buttons() def draw_preferences(self): - frame = ttk.LabelFrame(self.top, text="Preferences") - frame.grid(sticky="ew", pady=2) + frame = ttk.LabelFrame(self.top, text="Preferences", padding=PAD) + frame.grid(sticky="nsew", pady=2) frame.columnconfigure(1, weight=1) 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=PAD, padx=PAD, sticky="w") themes = self.app.style.theme_names() combobox = ttk.Combobox( frame, textvariable=self.theme, values=themes, state="readonly" @@ -37,14 +40,14 @@ class PreferencesDialog(Dialog): combobox.bind("<>", self.theme_change) 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=PAD, padx=PAD, sticky="w") combobox = ttk.Combobox( frame, textvariable=self.editor, values=appconfig.EDITORS, state="readonly" ) combobox.grid(row=1, column=1, sticky="ew") 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=PAD, padx=PAD, sticky="w") combobox = ttk.Combobox( frame, textvariable=self.terminal, @@ -54,7 +57,7 @@ class PreferencesDialog(Dialog): combobox.grid(row=2, column=1, sticky="ew") 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=PAD, padx=PAD, sticky="w") entry = ttk.Entry(frame, textvariable=self.gui3d) entry.grid(row=3, column=1, sticky="ew") diff --git a/coretk/coretk/dialogs/servers.py b/coretk/coretk/dialogs/servers.py index 9df7bf55..18c5d6d1 100644 --- a/coretk/coretk/dialogs/servers.py +++ b/coretk/coretk/dialogs/servers.py @@ -4,6 +4,7 @@ from tkinter import ttk from coretk.coreclient import CoreServer from coretk.dialogs.dialog import Dialog +PAD = 5 DEFAULT_NAME = "example" DEFAULT_ADDRESS = "127.0.0.1" DEFAULT_PORT = 50051 @@ -26,13 +27,13 @@ class ServersDialog(Dialog): self.top.columnconfigure(0, weight=1) self.top.rowconfigure(0, weight=1) self.draw_servers() - self.draw_server_configuration() self.draw_servers_buttons() + self.draw_server_configuration() self.draw_apply_buttons() def draw_servers(self): frame = ttk.Frame(self.top) - frame.grid(pady=2, sticky="nsew") + frame.grid(pady=PAD, sticky="nsew") frame.columnconfigure(0, weight=1) frame.rowconfigure(0, weight=1) @@ -51,27 +52,24 @@ class ServersDialog(Dialog): scrollbar.config(command=self.servers.yview) def draw_server_configuration(self): - label = ttk.Label(self.top, text="Server Configuration") - label.grid(pady=2, sticky="ew") - - frame = ttk.Frame(self.top) - frame.grid(pady=2, sticky="ew") + frame = ttk.LabelFrame(self.top, text="Server Configuration", padding=PAD) + frame.grid(pady=PAD, sticky="ew") frame.columnconfigure(1, weight=1) frame.columnconfigure(3, weight=1) frame.columnconfigure(5, weight=1) label = ttk.Label(frame, text="Name") - label.grid(row=0, column=0, sticky="w") + label.grid(row=0, column=0, sticky="w", padx=PAD, pady=PAD) entry = ttk.Entry(frame, textvariable=self.name) entry.grid(row=0, column=1, sticky="ew") label = ttk.Label(frame, text="Address") - label.grid(row=0, column=2, sticky="w") + label.grid(row=0, column=2, sticky="w", padx=PAD, pady=PAD) entry = ttk.Entry(frame, textvariable=self.address) entry.grid(row=0, column=3, sticky="ew") label = ttk.Label(frame, text="Port") - label.grid(row=0, column=4, sticky="w") + label.grid(row=0, column=4, sticky="w", padx=PAD, pady=PAD) entry = ttk.Entry( frame, textvariable=self.port, @@ -85,17 +83,17 @@ class ServersDialog(Dialog): def draw_servers_buttons(self): frame = ttk.Frame(self.top) - frame.grid(pady=2, sticky="ew") + frame.grid(pady=PAD, sticky="ew") for i in range(3): frame.columnconfigure(i, weight=1) 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=PAD) self.save_button = ttk.Button( 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=PAD) self.delete_button = ttk.Button( frame, text="Delete", state=tk.DISABLED, command=self.click_delete @@ -111,7 +109,7 @@ class ServersDialog(Dialog): button = ttk.Button( 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=PAD) button = ttk.Button(frame, text="Cancel", command=self.destroy) button.grid(row=0, column=1, sticky="ew") diff --git a/coretk/coretk/dialogs/sessions.py b/coretk/coretk/dialogs/sessions.py index e3d9e696..f8d26667 100644 --- a/coretk/coretk/dialogs/sessions.py +++ b/coretk/coretk/dialogs/sessions.py @@ -10,6 +10,8 @@ from coretk.dialogs.dialog import Dialog from coretk.errors import show_grpc_error from coretk.images import ImageEnum, Images +PAD = 5 + class SessionsDialog(Dialog): def __init__(self, master, app): @@ -31,6 +33,7 @@ class SessionsDialog(Dialog): def draw(self): self.top.columnconfigure(0, weight=1) + self.top.rowconfigure(1, weight=1) self.draw_description() self.draw_tree() self.draw_buttons() @@ -46,14 +49,19 @@ class SessionsDialog(Dialog): "connect to an existing session. Usually, only sessions in \n" "the RUNTIME state persist in the daemon, except for the \n" "one you might be concurrently editting.", + justify=tk.CENTER, ) - label.grid(row=0, sticky="ew", pady=5) + label.grid(pady=PAD) def draw_tree(self): + frame = ttk.Frame(self.top) + frame.columnconfigure(0, weight=1) + frame.rowconfigure(0, weight=1) + frame.grid(sticky="nsew") 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.heading("id", text="ID") self.tree.column("state", stretch=tk.YES) @@ -72,21 +80,19 @@ class SessionsDialog(Dialog): self.tree.bind("", self.on_selected) self.tree.bind("<>", self.click_select) - yscrollbar = ttk.Scrollbar(self.top, orient="vertical", command=self.tree.yview) - yscrollbar.grid(row=1, column=1, sticky="ns") + yscrollbar = ttk.Scrollbar(frame, orient="vertical", command=self.tree.yview) + yscrollbar.grid(row=0, column=1, sticky="ns") self.tree.configure(yscrollcommand=yscrollbar.set) - xscrollbar = ttk.Scrollbar( - self.top, orient="horizontal", command=self.tree.xview - ) - xscrollbar.grid(row=2, sticky="ew", pady=5) + xscrollbar = ttk.Scrollbar(frame, orient="horizontal", command=self.tree.xview) + xscrollbar.grid(row=1, sticky="ew", pady=5) self.tree.configure(xscrollcommand=xscrollbar.set) def draw_buttons(self): frame = ttk.Frame(self.top) for i in range(4): frame.columnconfigure(i, weight=1) - frame.grid(row=3, sticky="ew") + frame.grid(sticky="ew") image = Images.get(ImageEnum.DOCUMENTNEW, 16) b = ttk.Button( diff --git a/coretk/coretk/dialogs/shapemod.py b/coretk/coretk/dialogs/shapemod.py index e0085a8c..63037c9d 100644 --- a/coretk/coretk/dialogs/shapemod.py +++ b/coretk/coretk/dialogs/shapemod.py @@ -8,6 +8,8 @@ from coretk.dialogs.dialog import Dialog from coretk.graph import tags from coretk.graph.shapeutils import is_draw_shape, is_shape_text +PADX = (0, 5) +PAD = 5 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] @@ -37,20 +39,27 @@ class ShapeDialog(Dialog): self.bold = tk.BooleanVar(value=data.bold) self.italic = tk.BooleanVar(value=data.italic) self.underline = tk.BooleanVar(value=data.underline) - self.top.columnconfigure(0, weight=1) self.draw() def draw(self): - frame = ttk.Frame(self.top) - frame.columnconfigure(0, weight=1) - frame.columnconfigure(1, weight=2) - label = ttk.Label(frame, text="Text for top of shape: ") - label.grid(row=0, column=0, sticky="nsew") - entry = ttk.Entry(frame, textvariable=self.shape_text) - entry.grid(row=0, column=1, sticky="nsew") - frame.grid(row=0, column=0, sticky="nsew", padx=3, pady=3) + self.top.columnconfigure(0, weight=1) + self.draw_label_options() + if is_draw_shape(self.shape.shape_type): + self.draw_shape_options() + self.draw_spacer() + self.draw_buttons() - frame = ttk.Frame(self.top) + def draw_label_options(self): + label_frame = ttk.LabelFrame(self.top, text="Label", padding=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=PAD) + + # font options + frame = ttk.Frame(label_frame) + frame.grid(sticky="nsew", padx=3, pady=3) frame.columnconfigure(0, weight=1) frame.columnconfigure(1, weight=1) frame.columnconfigure(2, weight=1) @@ -65,70 +74,65 @@ class ShapeDialog(Dialog): frame, textvariable=self.font_size, values=FONT_SIZES, state="readonly" ) combobox.grid(row=0, column=1, padx=3, 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") - 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.grid(row=0, column=0) + button.grid(row=0, column=0, sticky="ew") button = ttk.Checkbutton(frame, variable=self.italic, text="Italic") - button.grid(row=0, column=1, padx=3) + button.grid(row=0, column=1, padx=3, sticky="ew") button = ttk.Checkbutton(frame, variable=self.underline, text="Underline") - button.grid(row=0, column=2) - frame.grid(row=2, column=0, sticky="nsew", padx=3, pady=3) + button.grid(row=0, column=2, sticky="ew") - if is_draw_shape(self.shape.shape_type): - frame = ttk.Frame(self.top) - frame.columnconfigure(0, weight=1) - frame.columnconfigure(1, 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) + def draw_shape_options(self): + label_frame = ttk.LabelFrame(self.top, text="Shape", padding=PAD) + label_frame.grid(sticky="ew", pady=PAD) + label_frame.columnconfigure(0, weight=1) - frame = ttk.Frame(self.top) - frame.columnconfigure(0, weight=1) - frame.columnconfigure(1, weight=1) - frame.columnconfigure(2, weight=1) - label = ttk.Label(frame, text="Border color:") - label.grid(row=0, column=0, sticky="nsew") - self.border = ttk.Label( - frame, text=self.border_color, background=self.fill_color - ) - self.border.grid(row=0, column=1, sticky="nsew", padx=3) - 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(label_frame) + frame.grid(sticky="ew") + for i in range(1, 3): + frame.columnconfigure(i, weight=1) + label = ttk.Label(frame, text="Fill Color") + label.grid(row=0, column=0, padx=PADX, sticky="w") + self.fill = ttk.Label(frame, text=self.fill_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) + button.grid(row=0, column=2, sticky="ew") - frame = ttk.Frame(self.top) - frame.columnconfigure(0, weight=1) - frame.columnconfigure(1, weight=2) - label = ttk.Label(frame, text="Border width:") - label.grid(row=0, column=0, sticky="nsew") - combobox = ttk.Combobox( - frame, - textvariable=self.border_width, - 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) + label = ttk.Label(frame, text="Border Color") + label.grid(row=1, column=0, sticky="w", padx=PADX) + self.border = ttk.Label( + frame, text=self.border_color, background=self.border_color + ) + self.border.grid(row=1, column=1, sticky="ew", padx=PADX) + button = ttk.Button(frame, text="Color", command=self.choose_border_color) + button.grid(row=1, column=2, sticky="ew") + frame = ttk.Frame(label_frame) + frame.grid(sticky="ew", pady=PAD) + 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.grid(sticky="nsew") frame.columnconfigure(0, weight=1) frame.columnconfigure(1, weight=1) 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.grid(row=0, column=1, sticky="w", pady=3) - frame.grid(row=6, column=0, sticky="nsew", padx=3, pady=3) + button.grid(row=0, column=1, sticky="ew") def choose_text_color(self): color = colorchooser.askcolor(color="black") @@ -140,7 +144,7 @@ class ShapeDialog(Dialog): self.fill.config(background=color[1], text=color[1]) def choose_border_color(self): - color = colorchooser.askcolor(color="black") + color = colorchooser.askcolor(color=self.border_color) self.border_color = color[1] self.border.config(background=color[1], text=color[1]) diff --git a/coretk/coretk/dialogs/wlanconfig.py b/coretk/coretk/dialogs/wlanconfig.py index 42adc49a..711f94f0 100644 --- a/coretk/coretk/dialogs/wlanconfig.py +++ b/coretk/coretk/dialogs/wlanconfig.py @@ -30,7 +30,8 @@ class WlanConfigDialog(Dialog): def draw(self): 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.grid(sticky="nsew", pady=PAD) self.draw_apply_buttons() diff --git a/coretk/coretk/graph/node.py b/coretk/coretk/graph/node.py index 5757f081..ef4686be 100644 --- a/coretk/coretk/graph/node.py +++ b/coretk/coretk/graph/node.py @@ -4,6 +4,7 @@ from tkinter import font import grpc from core.api.grpc.core_pb2 import NodeType +from coretk import themes from coretk.dialogs.emaneconfig import EmaneConfigDialog from coretk.dialogs.mobilityconfig import MobilityConfigDialog from coretk.dialogs.nodeconfig import NodeConfigDialog @@ -161,6 +162,7 @@ class CanvasNode: is_wlan = self.core_node.type == NodeType.WIRELESS_LAN is_emane = self.core_node.type == NodeType.EMANE context = tk.Menu(self.canvas) + themes.update_menu(self.app.style, context) if self.app.core.is_runtime(): context.add_command(label="Configure", command=self.show_config) if NodeUtils.is_container_node(self.core_node.type): diff --git a/coretk/coretk/menuaction.py b/coretk/coretk/menuaction.py index a9f9ca34..3115cd58 100644 --- a/coretk/coretk/menuaction.py +++ b/coretk/coretk/menuaction.py @@ -12,8 +12,8 @@ import grpc from coretk.appconfig import XML_PATH from coretk.dialogs.about import AboutDialog -from coretk.dialogs.canvasbackground import CanvasBackgroundDialog from coretk.dialogs.canvassizeandscale import SizeAndScaleDialog +from coretk.dialogs.canvaswallpaper import CanvasBackgroundDialog from coretk.dialogs.hooks import HooksDialog from coretk.dialogs.observers import ObserverDialog from coretk.dialogs.preferences import PreferencesDialog diff --git a/coretk/coretk/menubar.py b/coretk/coretk/menubar.py index ed5cb2ca..2521bd97 100644 --- a/coretk/coretk/menubar.py +++ b/coretk/coretk/menubar.py @@ -80,6 +80,7 @@ class Menubar(tk.Menu): :return: nothing """ 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="Redo", accelerator="Ctrl+Y", state=tk.DISABLED) menu.add_separator() @@ -94,9 +95,6 @@ class Menubar(tk.Menu): menu.add_separator() menu.add_command(label="Find...", accelerator="Ctrl+F", 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) def draw_canvas_menu(self): @@ -436,16 +434,14 @@ class Menubar(tk.Menu): """ menu = tk.Menu(self) menu.add_command( - label="Change sessions...", - command=self.menuaction.session_change_sessions, - underline=0, + label="Sessions...", command=self.menuaction.session_change_sessions ) 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="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) def draw_help_menu(self): diff --git a/coretk/coretk/themes.py b/coretk/coretk/themes.py index a1982b3e..a870b278 100644 --- a/coretk/coretk/themes.py +++ b/coretk/coretk/themes.py @@ -140,15 +140,19 @@ def update_bg(style, event): event.widget.config(background=bg) -def update_menu(style, event): +def theme_change_menu(style, event): if not isinstance(event.widget, tk.Menu): return + update_menu(style, event.widget) + + +def update_menu(style, widget): bg = style.lookup(".", "background") fg = style.lookup(".", "foreground") abg = style.lookup(".", "lightcolor") if not abg: abg = bg - event.widget.config( + widget.config( background=bg, foreground=fg, activebackground=abg, activeforeground=fg ) diff --git a/coretk/coretk/widgets.py b/coretk/coretk/widgets.py index fb5582a1..e3fd5c35 100644 --- a/coretk/coretk/widgets.py +++ b/coretk/coretk/widgets.py @@ -65,7 +65,7 @@ class FrameScroll(ttk.LabelFrame): class ConfigFrame(FrameScroll): 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.config = config self.values = {}