pygui updated main app frame to use grid layout like everything else
This commit is contained in:
parent
be70c5383e
commit
b858e66c49
8 changed files with 60 additions and 38 deletions
|
@ -16,7 +16,7 @@ WIDTH = 1000
|
||||||
HEIGHT = 800
|
HEIGHT = 800
|
||||||
|
|
||||||
|
|
||||||
class Application(tk.Frame):
|
class Application(ttk.Frame):
|
||||||
def __init__(self, proxy: bool):
|
def __init__(self, proxy: bool):
|
||||||
super().__init__(master=None)
|
super().__init__(master=None)
|
||||||
# load node icons
|
# load node icons
|
||||||
|
@ -25,6 +25,7 @@ class Application(tk.Frame):
|
||||||
# widgets
|
# widgets
|
||||||
self.menubar = None
|
self.menubar = None
|
||||||
self.toolbar = None
|
self.toolbar = None
|
||||||
|
self.right_frame = None
|
||||||
self.canvas = None
|
self.canvas = None
|
||||||
self.statusbar = None
|
self.statusbar = None
|
||||||
self.validation = None
|
self.validation = None
|
||||||
|
@ -66,8 +67,8 @@ class Application(tk.Frame):
|
||||||
self.master.protocol("WM_DELETE_WINDOW", self.on_closing)
|
self.master.protocol("WM_DELETE_WINDOW", self.on_closing)
|
||||||
image = Images.get(ImageEnum.CORE, 16)
|
image = Images.get(ImageEnum.CORE, 16)
|
||||||
self.master.tk.call("wm", "iconphoto", self.master._w, image)
|
self.master.tk.call("wm", "iconphoto", self.master._w, image)
|
||||||
self.pack(fill=tk.BOTH, expand=True)
|
|
||||||
self.validation = InputValidation(self)
|
self.validation = InputValidation(self)
|
||||||
|
self.master.option_add("*tearOff", tk.FALSE)
|
||||||
|
|
||||||
def center(self):
|
def center(self):
|
||||||
screen_width = self.master.winfo_screenwidth()
|
screen_width = self.master.winfo_screenwidth()
|
||||||
|
@ -79,9 +80,17 @@ class Application(tk.Frame):
|
||||||
)
|
)
|
||||||
|
|
||||||
def draw(self):
|
def draw(self):
|
||||||
self.master.option_add("*tearOff", tk.FALSE)
|
self.master.rowconfigure(0, weight=1)
|
||||||
|
self.master.columnconfigure(0, weight=1)
|
||||||
|
self.rowconfigure(0, weight=1)
|
||||||
|
self.columnconfigure(1, weight=1)
|
||||||
|
self.grid(sticky="nsew")
|
||||||
self.toolbar = Toolbar(self, self)
|
self.toolbar = Toolbar(self, self)
|
||||||
self.toolbar.pack(side=tk.LEFT, fill=tk.Y, ipadx=2, ipady=2)
|
self.toolbar.grid(sticky="ns")
|
||||||
|
self.right_frame = ttk.Frame(self)
|
||||||
|
self.right_frame.columnconfigure(0, weight=1)
|
||||||
|
self.right_frame.rowconfigure(0, weight=1)
|
||||||
|
self.right_frame.grid(row=0, column=1, sticky="nsew")
|
||||||
self.draw_canvas()
|
self.draw_canvas()
|
||||||
self.draw_status()
|
self.draw_status()
|
||||||
self.menubar = Menubar(self.master, self)
|
self.menubar = Menubar(self.master, self)
|
||||||
|
@ -89,20 +98,24 @@ class Application(tk.Frame):
|
||||||
def draw_canvas(self):
|
def draw_canvas(self):
|
||||||
width = self.guiconfig["preferences"]["width"]
|
width = self.guiconfig["preferences"]["width"]
|
||||||
height = self.guiconfig["preferences"]["height"]
|
height = self.guiconfig["preferences"]["height"]
|
||||||
self.canvas = CanvasGraph(self, self.core, width, height)
|
canvas_frame = ttk.Frame(self.right_frame)
|
||||||
self.canvas.pack(fill=tk.BOTH, expand=True)
|
canvas_frame.rowconfigure(0, weight=1)
|
||||||
|
canvas_frame.columnconfigure(0, weight=1)
|
||||||
|
canvas_frame.grid(sticky="nsew", pady=1)
|
||||||
|
self.canvas = CanvasGraph(canvas_frame, self, self.core, width, height)
|
||||||
|
self.canvas.grid(sticky="nsew")
|
||||||
|
scroll_y = ttk.Scrollbar(canvas_frame, command=self.canvas.yview)
|
||||||
|
scroll_y.grid(row=0, column=1, sticky="ns")
|
||||||
scroll_x = ttk.Scrollbar(
|
scroll_x = ttk.Scrollbar(
|
||||||
self.canvas, orient=tk.HORIZONTAL, command=self.canvas.xview
|
canvas_frame, orient=tk.HORIZONTAL, command=self.canvas.xview
|
||||||
)
|
)
|
||||||
scroll_x.pack(side=tk.BOTTOM, fill=tk.X)
|
scroll_x.grid(row=1, column=0, sticky="ew")
|
||||||
scroll_y = ttk.Scrollbar(self.canvas, command=self.canvas.yview)
|
|
||||||
scroll_y.pack(side=tk.RIGHT, fill=tk.Y)
|
|
||||||
self.canvas.configure(xscrollcommand=scroll_x.set)
|
self.canvas.configure(xscrollcommand=scroll_x.set)
|
||||||
self.canvas.configure(yscrollcommand=scroll_y.set)
|
self.canvas.configure(yscrollcommand=scroll_y.set)
|
||||||
|
|
||||||
def draw_status(self):
|
def draw_status(self):
|
||||||
self.statusbar = StatusBar(master=self, app=self)
|
self.statusbar = StatusBar(self.right_frame, self)
|
||||||
self.statusbar.pack(side=tk.BOTTOM, fill=tk.X)
|
self.statusbar.grid(sticky="ew")
|
||||||
|
|
||||||
def on_closing(self):
|
def on_closing(self):
|
||||||
self.menubar.prompt_save_running_session(True)
|
self.menubar.prompt_save_running_session(True)
|
||||||
|
|
|
@ -4,7 +4,7 @@ core node services
|
||||||
import logging
|
import logging
|
||||||
import tkinter as tk
|
import tkinter as tk
|
||||||
from tkinter import messagebox, ttk
|
from tkinter import messagebox, ttk
|
||||||
from typing import TYPE_CHECKING, Any, Set
|
from typing import TYPE_CHECKING, Set
|
||||||
|
|
||||||
from core.gui.dialogs.configserviceconfig import ConfigServiceConfigDialog
|
from core.gui.dialogs.configserviceconfig import ConfigServiceConfigDialog
|
||||||
from core.gui.dialogs.dialog import Dialog
|
from core.gui.dialogs.dialog import Dialog
|
||||||
|
@ -19,7 +19,7 @@ if TYPE_CHECKING:
|
||||||
class NodeConfigServiceDialog(Dialog):
|
class NodeConfigServiceDialog(Dialog):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
master: Any,
|
master: tk.Widget,
|
||||||
app: "Application",
|
app: "Application",
|
||||||
canvas_node: "CanvasNode",
|
canvas_node: "CanvasNode",
|
||||||
services: Set[str] = None,
|
services: Set[str] = None,
|
||||||
|
|
|
@ -3,7 +3,7 @@ core node services
|
||||||
"""
|
"""
|
||||||
import tkinter as tk
|
import tkinter as tk
|
||||||
from tkinter import messagebox, ttk
|
from tkinter import messagebox, ttk
|
||||||
from typing import TYPE_CHECKING, Any
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
from core.gui.dialogs.dialog import Dialog
|
from core.gui.dialogs.dialog import Dialog
|
||||||
from core.gui.dialogs.serviceconfig import ServiceConfigDialog
|
from core.gui.dialogs.serviceconfig import ServiceConfigDialog
|
||||||
|
@ -16,7 +16,9 @@ if TYPE_CHECKING:
|
||||||
|
|
||||||
|
|
||||||
class NodeServiceDialog(Dialog):
|
class NodeServiceDialog(Dialog):
|
||||||
def __init__(self, master: Any, app: "Application", canvas_node: "CanvasNode"):
|
def __init__(
|
||||||
|
self, master: tk.Widget, app: "Application", canvas_node: "CanvasNode"
|
||||||
|
):
|
||||||
title = f"{canvas_node.core_node.name} Services"
|
title = f"{canvas_node.core_node.name} Services"
|
||||||
super().__init__(master, app, title)
|
super().__init__(master, app, title)
|
||||||
self.app = app
|
self.app = app
|
||||||
|
|
|
@ -47,10 +47,15 @@ class ShowVar(BooleanVar):
|
||||||
|
|
||||||
class CanvasGraph(tk.Canvas):
|
class CanvasGraph(tk.Canvas):
|
||||||
def __init__(
|
def __init__(
|
||||||
self, master: "Application", core: "CoreClient", width: int, height: int
|
self,
|
||||||
|
master: tk.Widget,
|
||||||
|
app: "Application",
|
||||||
|
core: "CoreClient",
|
||||||
|
width: int,
|
||||||
|
height: int,
|
||||||
):
|
):
|
||||||
super().__init__(master, highlightthickness=0, background="#cccccc")
|
super().__init__(master, highlightthickness=0, background="#cccccc")
|
||||||
self.app = master
|
self.app = app
|
||||||
self.core = core
|
self.core = core
|
||||||
self.mode = GraphMode.SELECT
|
self.mode = GraphMode.SELECT
|
||||||
self.annotation_type = None
|
self.annotation_type = None
|
||||||
|
@ -67,7 +72,7 @@ class CanvasGraph(tk.Canvas):
|
||||||
self.wireless_network = {}
|
self.wireless_network = {}
|
||||||
|
|
||||||
self.drawing_edge = None
|
self.drawing_edge = None
|
||||||
self.grid = None
|
self.rect = None
|
||||||
self.shape_drawing = False
|
self.shape_drawing = False
|
||||||
self.default_dimensions = (width, height)
|
self.default_dimensions = (width, height)
|
||||||
self.current_dimensions = self.default_dimensions
|
self.current_dimensions = self.default_dimensions
|
||||||
|
@ -107,12 +112,12 @@ class CanvasGraph(tk.Canvas):
|
||||||
self.draw_grid()
|
self.draw_grid()
|
||||||
|
|
||||||
def draw_canvas(self, dimensions: Tuple[int, int] = None):
|
def draw_canvas(self, dimensions: Tuple[int, int] = None):
|
||||||
if self.grid is not None:
|
if self.rect is not None:
|
||||||
self.delete(self.grid)
|
self.delete(self.rect)
|
||||||
if not dimensions:
|
if not dimensions:
|
||||||
dimensions = self.default_dimensions
|
dimensions = self.default_dimensions
|
||||||
self.current_dimensions = dimensions
|
self.current_dimensions = dimensions
|
||||||
self.grid = self.create_rectangle(
|
self.rect = self.create_rectangle(
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
*dimensions,
|
*dimensions,
|
||||||
|
@ -182,7 +187,7 @@ class CanvasGraph(tk.Canvas):
|
||||||
return scaled_x, scaled_y
|
return scaled_x, scaled_y
|
||||||
|
|
||||||
def inside_canvas(self, x: float, y: float) -> [bool, bool]:
|
def inside_canvas(self, x: float, y: float) -> [bool, bool]:
|
||||||
x1, y1, x2, y2 = self.bbox(self.grid)
|
x1, y1, x2, y2 = self.bbox(self.rect)
|
||||||
valid_x = x1 <= x <= x2
|
valid_x = x1 <= x <= x2
|
||||||
valid_y = y1 <= y <= y2
|
valid_y = y1 <= y <= y2
|
||||||
return valid_x and valid_y
|
return valid_x and valid_y
|
||||||
|
@ -219,7 +224,7 @@ class CanvasGraph(tk.Canvas):
|
||||||
for i in range(0, height, 27):
|
for i in range(0, height, 27):
|
||||||
self.create_line(0, i, width, i, dash=(2, 4), tags=tags.GRIDLINE)
|
self.create_line(0, i, width, i, dash=(2, 4), tags=tags.GRIDLINE)
|
||||||
self.tag_lower(tags.GRIDLINE)
|
self.tag_lower(tags.GRIDLINE)
|
||||||
self.tag_lower(self.grid)
|
self.tag_lower(self.rect)
|
||||||
|
|
||||||
def add_wireless_edge(
|
def add_wireless_edge(
|
||||||
self, src: CanvasNode, dst: CanvasNode, link: core_pb2.Link
|
self, src: CanvasNode, dst: CanvasNode, link: core_pb2.Link
|
||||||
|
@ -293,7 +298,7 @@ class CanvasGraph(tk.Canvas):
|
||||||
)
|
)
|
||||||
x = core_node.position.x
|
x = core_node.position.x
|
||||||
y = core_node.position.y
|
y = core_node.position.y
|
||||||
node = CanvasNode(self.master, x, y, core_node, image)
|
node = CanvasNode(self.app, x, y, core_node, image)
|
||||||
self.nodes[node.id] = node
|
self.nodes[node.id] = node
|
||||||
self.core.canvas_nodes[core_node.id] = node
|
self.core.canvas_nodes[core_node.id] = node
|
||||||
|
|
||||||
|
@ -732,7 +737,7 @@ class CanvasGraph(tk.Canvas):
|
||||||
self.node_draw.image = Images.get_custom(
|
self.node_draw.image = Images.get_custom(
|
||||||
self.node_draw.image_file, int(ICON_SIZE * self.app.app_scale)
|
self.node_draw.image_file, int(ICON_SIZE * self.app.app_scale)
|
||||||
)
|
)
|
||||||
node = CanvasNode(self.master, x, y, core_node, self.node_draw.image)
|
node = CanvasNode(self.app, x, y, core_node, self.node_draw.image)
|
||||||
self.core.canvas_nodes[core_node.id] = node
|
self.core.canvas_nodes[core_node.id] = node
|
||||||
self.nodes[node.id] = node
|
self.nodes[node.id] = node
|
||||||
return node
|
return node
|
||||||
|
@ -741,7 +746,7 @@ class CanvasGraph(tk.Canvas):
|
||||||
"""
|
"""
|
||||||
retrieve canvas width and height in pixels
|
retrieve canvas width and height in pixels
|
||||||
"""
|
"""
|
||||||
x0, y0, x1, y1 = self.coords(self.grid)
|
x0, y0, x1, y1 = self.coords(self.rect)
|
||||||
canvas_w = abs(x0 - x1)
|
canvas_w = abs(x0 - x1)
|
||||||
canvas_h = abs(y0 - y1)
|
canvas_h = abs(y0 - y1)
|
||||||
return canvas_w, canvas_h
|
return canvas_w, canvas_h
|
||||||
|
@ -756,7 +761,7 @@ class CanvasGraph(tk.Canvas):
|
||||||
self, image: ImageTk.PhotoImage, x: float = None, y: float = None
|
self, image: ImageTk.PhotoImage, x: float = None, y: float = None
|
||||||
):
|
):
|
||||||
if x is None and y is None:
|
if x is None and y is None:
|
||||||
x1, y1, x2, y2 = self.bbox(self.grid)
|
x1, y1, x2, y2 = self.bbox(self.rect)
|
||||||
x = (x1 + x2) / 2
|
x = (x1 + x2) / 2
|
||||||
y = (y1 + y2) / 2
|
y = (y1 + y2) / 2
|
||||||
self.wallpaper_id = self.create_image((x, y), image=image, tags=tags.WALLPAPER)
|
self.wallpaper_id = self.create_image((x, y), image=image, tags=tags.WALLPAPER)
|
||||||
|
@ -778,7 +783,7 @@ class CanvasGraph(tk.Canvas):
|
||||||
image = ImageTk.PhotoImage(cropped)
|
image = ImageTk.PhotoImage(cropped)
|
||||||
|
|
||||||
# draw on canvas
|
# draw on canvas
|
||||||
x1, y1, _, _ = self.bbox(self.grid)
|
x1, y1, _, _ = self.bbox(self.rect)
|
||||||
x = (cropx / 2) + x1
|
x = (cropx / 2) + x1
|
||||||
y = (cropy / 2) + y1
|
y = (cropy / 2) + y1
|
||||||
self.draw_wallpaper(image, x, y)
|
self.draw_wallpaper(image, x, y)
|
||||||
|
@ -920,7 +925,7 @@ class CanvasGraph(tk.Canvas):
|
||||||
copy = self.core.create_node(
|
copy = self.core.create_node(
|
||||||
actual_x, actual_y, core_node.type, core_node.model
|
actual_x, actual_y, core_node.type, core_node.model
|
||||||
)
|
)
|
||||||
node = CanvasNode(self.master, scaled_x, scaled_y, copy, canvas_node.image)
|
node = CanvasNode(self.app, scaled_x, scaled_y, copy, canvas_node.image)
|
||||||
|
|
||||||
# copy configurations and services
|
# copy configurations and services
|
||||||
node.core_node.services[:] = canvas_node.core_node.services
|
node.core_node.services[:] = canvas_node.core_node.services
|
||||||
|
|
|
@ -298,11 +298,11 @@ class CanvasNode:
|
||||||
dialog.show()
|
dialog.show()
|
||||||
|
|
||||||
def show_services(self):
|
def show_services(self):
|
||||||
dialog = NodeServiceDialog(self.app.master, self.app, self)
|
dialog = NodeServiceDialog(self.app, self.app, self)
|
||||||
dialog.show()
|
dialog.show()
|
||||||
|
|
||||||
def show_config_services(self):
|
def show_config_services(self):
|
||||||
dialog = NodeConfigServiceDialog(self.app.master, self.app, self)
|
dialog = NodeConfigServiceDialog(self.app, self.app, self)
|
||||||
dialog.show()
|
dialog.show()
|
||||||
|
|
||||||
def has_emane_link(self, interface_id: int) -> core_pb2.Node:
|
def has_emane_link(self, interface_id: int) -> core_pb2.Node:
|
||||||
|
|
|
@ -13,7 +13,7 @@ if TYPE_CHECKING:
|
||||||
|
|
||||||
|
|
||||||
class StatusBar(ttk.Frame):
|
class StatusBar(ttk.Frame):
|
||||||
def __init__(self, master: "Application", app: "Application", **kwargs):
|
def __init__(self, master: tk.Widget, app: "Application", **kwargs):
|
||||||
super().__init__(master, **kwargs)
|
super().__init__(master, **kwargs)
|
||||||
self.app = app
|
self.app = app
|
||||||
self.status = None
|
self.status = None
|
||||||
|
|
|
@ -181,21 +181,24 @@ def theme_change(event: tk.Event):
|
||||||
Styles.green_alert,
|
Styles.green_alert,
|
||||||
background="green",
|
background="green",
|
||||||
padding=0,
|
padding=0,
|
||||||
relief=tk.NONE,
|
relief=tk.RIDGE,
|
||||||
|
borderwidth=1,
|
||||||
font="TkDefaultFont",
|
font="TkDefaultFont",
|
||||||
)
|
)
|
||||||
style.configure(
|
style.configure(
|
||||||
Styles.yellow_alert,
|
Styles.yellow_alert,
|
||||||
background="yellow",
|
background="yellow",
|
||||||
padding=0,
|
padding=0,
|
||||||
relief=tk.NONE,
|
relief=tk.RIDGE,
|
||||||
|
borderwidth=1,
|
||||||
font="TkDefaultFont",
|
font="TkDefaultFont",
|
||||||
)
|
)
|
||||||
style.configure(
|
style.configure(
|
||||||
Styles.red_alert,
|
Styles.red_alert,
|
||||||
background="red",
|
background="red",
|
||||||
padding=0,
|
padding=0,
|
||||||
relief=tk.NONE,
|
relief=tk.RIDGE,
|
||||||
|
borderwidth=1,
|
||||||
font="TkDefaultFont",
|
font="TkDefaultFont",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -41,13 +41,12 @@ class Toolbar(ttk.Frame):
|
||||||
Core toolbar class
|
Core toolbar class
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, master: "Application", app: "Application", **kwargs):
|
def __init__(self, master: tk.Widget, app: "Application", **kwargs):
|
||||||
"""
|
"""
|
||||||
Create a CoreToolbar instance
|
Create a CoreToolbar instance
|
||||||
"""
|
"""
|
||||||
super().__init__(master, **kwargs)
|
super().__init__(master, **kwargs)
|
||||||
self.app = app
|
self.app = app
|
||||||
self.master = app.master
|
|
||||||
self.time = None
|
self.time = None
|
||||||
|
|
||||||
# design buttons
|
# design buttons
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue