pygui: revamped config to leverage classes mapped to yaml, removes need for using keys all over and type hinting on glasses, future changes should support defaults better
This commit is contained in:
parent
d9f48d14a7
commit
86ae87eafe
16 changed files with 251 additions and 208 deletions
|
@ -43,7 +43,7 @@ class Application(ttk.Frame):
|
||||||
|
|
||||||
# setup
|
# setup
|
||||||
self.guiconfig = appconfig.read()
|
self.guiconfig = appconfig.read()
|
||||||
self.app_scale = self.guiconfig["scale"]
|
self.app_scale = self.guiconfig.scale
|
||||||
self.setup_scaling()
|
self.setup_scaling()
|
||||||
self.style = ttk.Style()
|
self.style = ttk.Style()
|
||||||
self.setup_theme()
|
self.setup_theme()
|
||||||
|
@ -65,7 +65,7 @@ class Application(ttk.Frame):
|
||||||
themes.load(self.style)
|
themes.load(self.style)
|
||||||
self.master.bind_class("Menu", "<<ThemeChanged>>", themes.theme_change_menu)
|
self.master.bind_class("Menu", "<<ThemeChanged>>", themes.theme_change_menu)
|
||||||
self.master.bind("<<ThemeChanged>>", themes.theme_change)
|
self.master.bind("<<ThemeChanged>>", themes.theme_change)
|
||||||
self.style.theme_use(self.guiconfig["preferences"]["theme"])
|
self.style.theme_use(self.guiconfig.preferences.theme)
|
||||||
|
|
||||||
def setup_app(self):
|
def setup_app(self):
|
||||||
self.master.title("CORE")
|
self.master.title("CORE")
|
||||||
|
@ -103,8 +103,8 @@ class Application(ttk.Frame):
|
||||||
self.menubar = Menubar(self.master, self)
|
self.menubar = Menubar(self.master, self)
|
||||||
|
|
||||||
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
|
||||||
canvas_frame = ttk.Frame(self.right_frame)
|
canvas_frame = ttk.Frame(self.right_frame)
|
||||||
canvas_frame.rowconfigure(0, weight=1)
|
canvas_frame.rowconfigure(0, weight=1)
|
||||||
canvas_frame.columnconfigure(0, weight=1)
|
canvas_frame.columnconfigure(0, weight=1)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from typing import List, Optional
|
||||||
|
|
||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
|
@ -37,11 +38,6 @@ TERMINALS = {
|
||||||
"gnome-terminal": "gnome-terminal --window --",
|
"gnome-terminal": "gnome-terminal --window --",
|
||||||
}
|
}
|
||||||
EDITORS = ["$EDITOR", "vim", "emacs", "gedit", "nano", "vi"]
|
EDITORS = ["$EDITOR", "vim", "emacs", "gedit", "nano", "vi"]
|
||||||
DEFAULT_IP4S = ["10.0.0.0", "192.168.0.0", "172.16.0.0"]
|
|
||||||
DEFAULT_IP4 = DEFAULT_IP4S[0]
|
|
||||||
DEFAULT_IP6S = ["2001::", "2002::", "a::"]
|
|
||||||
DEFAULT_IP6 = DEFAULT_IP6S[0]
|
|
||||||
DEFAULT_MAC = "00:00:00:aa:00:00"
|
|
||||||
|
|
||||||
|
|
||||||
class IndentDumper(yaml.Dumper):
|
class IndentDumper(yaml.Dumper):
|
||||||
|
@ -49,13 +45,151 @@ class IndentDumper(yaml.Dumper):
|
||||||
return super().increase_indent(flow, False)
|
return super().increase_indent(flow, False)
|
||||||
|
|
||||||
|
|
||||||
def copy_files(current_path, new_path):
|
class CustomNode(yaml.YAMLObject):
|
||||||
|
yaml_tag = "!CustomNode"
|
||||||
|
yaml_loader = yaml.SafeLoader
|
||||||
|
|
||||||
|
def __init__(self, name: str, image: str, services: List[str]) -> None:
|
||||||
|
self.name = name
|
||||||
|
self.image = image
|
||||||
|
self.services = services
|
||||||
|
|
||||||
|
|
||||||
|
class CoreServer(yaml.YAMLObject):
|
||||||
|
yaml_tag = "!CoreServer"
|
||||||
|
yaml_loader = yaml.SafeLoader
|
||||||
|
|
||||||
|
def __init__(self, name: str, address: str) -> None:
|
||||||
|
self.name = name
|
||||||
|
self.address = address
|
||||||
|
|
||||||
|
|
||||||
|
class Observer(yaml.YAMLObject):
|
||||||
|
yaml_tag = "!Observer"
|
||||||
|
yaml_loader = yaml.SafeLoader
|
||||||
|
|
||||||
|
def __init__(self, name: str, cmd: str) -> None:
|
||||||
|
self.name = name
|
||||||
|
self.cmd = cmd
|
||||||
|
|
||||||
|
|
||||||
|
class PreferencesConfig(yaml.YAMLObject):
|
||||||
|
yaml_tag = "!PreferencesConfig"
|
||||||
|
yaml_loader = yaml.SafeLoader
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
editor: str = EDITORS[1],
|
||||||
|
terminal: str = None,
|
||||||
|
theme: str = themes.THEME_DARK,
|
||||||
|
gui3d: str = "/usr/local/bin/std3d.sh",
|
||||||
|
width: int = 1000,
|
||||||
|
height: int = 750,
|
||||||
|
) -> None:
|
||||||
|
self.theme = theme
|
||||||
|
self.editor = editor
|
||||||
|
self.terminal = terminal
|
||||||
|
self.gui3d = gui3d
|
||||||
|
self.width = width
|
||||||
|
self.height = height
|
||||||
|
|
||||||
|
|
||||||
|
class LocationConfig(yaml.YAMLObject):
|
||||||
|
yaml_tag = "!LocationConfig"
|
||||||
|
yaml_loader = yaml.SafeLoader
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
x: float = 0.0,
|
||||||
|
y: float = 0.0,
|
||||||
|
z: float = 0.0,
|
||||||
|
lat: float = 47.5791667,
|
||||||
|
lon: float = -122.132322,
|
||||||
|
alt: float = 2.0,
|
||||||
|
scale: float = 150.0,
|
||||||
|
) -> None:
|
||||||
|
self.x = x
|
||||||
|
self.y = y
|
||||||
|
self.z = z
|
||||||
|
self.lat = lat
|
||||||
|
self.lon = lon
|
||||||
|
self.alt = alt
|
||||||
|
self.scale = scale
|
||||||
|
|
||||||
|
|
||||||
|
class IpConfigs(yaml.YAMLObject):
|
||||||
|
yaml_tag = "!IpConfigs"
|
||||||
|
yaml_loader = yaml.SafeLoader
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
ip4: str = None,
|
||||||
|
ip6: str = None,
|
||||||
|
ip4s: List[str] = None,
|
||||||
|
ip6s: List[str] = None,
|
||||||
|
) -> None:
|
||||||
|
if ip4s is None:
|
||||||
|
ip4s = ["10.0.0.0", "192.168.0.0", "172.16.0.0"]
|
||||||
|
self.ip4s = ip4s
|
||||||
|
if ip6s is None:
|
||||||
|
ip6s = ["2001::", "2002::", "a::"]
|
||||||
|
self.ip6s = ip6s
|
||||||
|
if ip4 is None:
|
||||||
|
ip4 = self.ip4s[0]
|
||||||
|
self.ip4 = ip4
|
||||||
|
if ip6 is None:
|
||||||
|
ip6 = self.ip6s[0]
|
||||||
|
self.ip6 = ip6
|
||||||
|
|
||||||
|
|
||||||
|
class GuiConfig(yaml.YAMLObject):
|
||||||
|
yaml_tag = "!GuiConfig"
|
||||||
|
yaml_loader = yaml.SafeLoader
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
preferences: PreferencesConfig = None,
|
||||||
|
location: LocationConfig = None,
|
||||||
|
servers: List[CoreServer] = None,
|
||||||
|
nodes: List[CustomNode] = None,
|
||||||
|
recentfiles: List[str] = None,
|
||||||
|
observers: List[Observer] = None,
|
||||||
|
scale: float = 1.0,
|
||||||
|
ips: IpConfigs = None,
|
||||||
|
mac: str = "00:00:00:aa:00:00",
|
||||||
|
) -> None:
|
||||||
|
if preferences is None:
|
||||||
|
preferences = PreferencesConfig()
|
||||||
|
self.preferences = preferences
|
||||||
|
if location is None:
|
||||||
|
location = LocationConfig()
|
||||||
|
self.location = location
|
||||||
|
if servers is None:
|
||||||
|
servers = []
|
||||||
|
self.servers = servers
|
||||||
|
if nodes is None:
|
||||||
|
nodes = []
|
||||||
|
self.nodes = nodes
|
||||||
|
if recentfiles is None:
|
||||||
|
recentfiles = []
|
||||||
|
self.recentfiles = recentfiles
|
||||||
|
if observers is None:
|
||||||
|
observers = []
|
||||||
|
self.observers = observers
|
||||||
|
self.scale = scale
|
||||||
|
if ips is None:
|
||||||
|
ips = IpConfigs()
|
||||||
|
self.ips = ips
|
||||||
|
self.mac = mac
|
||||||
|
|
||||||
|
|
||||||
|
def copy_files(current_path, new_path) -> None:
|
||||||
for current_file in current_path.glob("*"):
|
for current_file in current_path.glob("*"):
|
||||||
new_file = new_path.joinpath(current_file.name)
|
new_file = new_path.joinpath(current_file.name)
|
||||||
shutil.copy(current_file, new_file)
|
shutil.copy(current_file, new_file)
|
||||||
|
|
||||||
|
|
||||||
def find_terminal():
|
def find_terminal() -> Optional[str]:
|
||||||
for term in sorted(TERMINALS):
|
for term in sorted(TERMINALS):
|
||||||
cmd = TERMINALS[term]
|
cmd = TERMINALS[term]
|
||||||
if shutil.which(term):
|
if shutil.which(term):
|
||||||
|
@ -63,7 +197,7 @@ def find_terminal():
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def check_directory():
|
def check_directory() -> None:
|
||||||
if HOME_PATH.exists():
|
if HOME_PATH.exists():
|
||||||
return
|
return
|
||||||
HOME_PATH.mkdir()
|
HOME_PATH.mkdir()
|
||||||
|
@ -85,45 +219,16 @@ def check_directory():
|
||||||
editor = EDITORS[0]
|
editor = EDITORS[0]
|
||||||
else:
|
else:
|
||||||
editor = EDITORS[1]
|
editor = EDITORS[1]
|
||||||
config = {
|
preferences = PreferencesConfig(editor, terminal)
|
||||||
"preferences": {
|
config = GuiConfig(preferences=preferences)
|
||||||
"theme": themes.THEME_DARK,
|
|
||||||
"editor": editor,
|
|
||||||
"terminal": terminal,
|
|
||||||
"gui3d": "/usr/local/bin/std3d.sh",
|
|
||||||
"width": 1000,
|
|
||||||
"height": 750,
|
|
||||||
},
|
|
||||||
"location": {
|
|
||||||
"x": 0.0,
|
|
||||||
"y": 0.0,
|
|
||||||
"z": 0.0,
|
|
||||||
"lat": 47.5791667,
|
|
||||||
"lon": -122.132322,
|
|
||||||
"alt": 2.0,
|
|
||||||
"scale": 150.0,
|
|
||||||
},
|
|
||||||
"servers": [],
|
|
||||||
"nodes": [],
|
|
||||||
"recentfiles": [],
|
|
||||||
"observers": [],
|
|
||||||
"scale": 1.0,
|
|
||||||
"ips": {
|
|
||||||
"ip4": DEFAULT_IP4,
|
|
||||||
"ip6": DEFAULT_IP6,
|
|
||||||
"ip4s": DEFAULT_IP4S,
|
|
||||||
"ip6s": DEFAULT_IP6S,
|
|
||||||
},
|
|
||||||
"mac": DEFAULT_MAC,
|
|
||||||
}
|
|
||||||
save(config)
|
save(config)
|
||||||
|
|
||||||
|
|
||||||
def read():
|
def read() -> GuiConfig:
|
||||||
with CONFIG_PATH.open("r") as f:
|
with CONFIG_PATH.open("r") as f:
|
||||||
return yaml.load(f, Loader=yaml.SafeLoader)
|
return yaml.load(f, Loader=yaml.SafeLoader)
|
||||||
|
|
||||||
|
|
||||||
def save(config):
|
def save(config: GuiConfig) -> None:
|
||||||
with CONFIG_PATH.open("w") as f:
|
with CONFIG_PATH.open("w") as f:
|
||||||
yaml.dump(config, f, Dumper=IndentDumper, default_flow_style=False)
|
yaml.dump(config, f, Dumper=IndentDumper, default_flow_style=False)
|
||||||
|
|
|
@ -34,19 +34,6 @@ if TYPE_CHECKING:
|
||||||
GUI_SOURCE = "gui"
|
GUI_SOURCE = "gui"
|
||||||
|
|
||||||
|
|
||||||
class CoreServer:
|
|
||||||
def __init__(self, name: str, address: str, port: int):
|
|
||||||
self.name = name
|
|
||||||
self.address = address
|
|
||||||
self.port = port
|
|
||||||
|
|
||||||
|
|
||||||
class Observer:
|
|
||||||
def __init__(self, name: str, cmd: str):
|
|
||||||
self.name = name
|
|
||||||
self.cmd = cmd
|
|
||||||
|
|
||||||
|
|
||||||
class CoreClient:
|
class CoreClient:
|
||||||
def __init__(self, app: "Application", proxy: bool):
|
def __init__(self, app: "Application", proxy: bool):
|
||||||
"""
|
"""
|
||||||
|
@ -126,22 +113,17 @@ class CoreClient:
|
||||||
self.observer = value
|
self.observer = value
|
||||||
|
|
||||||
def read_config(self):
|
def read_config(self):
|
||||||
# read distributed server
|
# read distributed servers
|
||||||
for config in self.app.guiconfig.get("servers", []):
|
for server in self.app.guiconfig.servers:
|
||||||
server = CoreServer(config["name"], config["address"], config["port"])
|
|
||||||
self.servers[server.name] = server
|
self.servers[server.name] = server
|
||||||
|
|
||||||
# read custom nodes
|
# read custom nodes
|
||||||
for config in self.app.guiconfig.get("nodes", []):
|
for custom_node in self.app.guiconfig.nodes:
|
||||||
name = config["name"]
|
node_draw = NodeDraw.from_custom(custom_node)
|
||||||
image_file = config["image"]
|
self.custom_nodes[custom_node.name] = node_draw
|
||||||
services = set(config["services"])
|
|
||||||
node_draw = NodeDraw.from_custom(name, image_file, services)
|
|
||||||
self.custom_nodes[name] = node_draw
|
|
||||||
|
|
||||||
# read observers
|
# read observers
|
||||||
for config in self.app.guiconfig.get("observers", []):
|
for observer in self.app.guiconfig.observers:
|
||||||
observer = Observer(config["name"], config["cmd"])
|
|
||||||
self.custom_observers[observer.name] = observer
|
self.custom_observers[observer.name] = observer
|
||||||
|
|
||||||
def handle_events(self, event: core_pb2.Event):
|
def handle_events(self, event: core_pb2.Event):
|
||||||
|
@ -367,8 +349,8 @@ class CoreClient:
|
||||||
self.app.canvas.adjust_to_dim.set(fit_image)
|
self.app.canvas.adjust_to_dim.set(fit_image)
|
||||||
wallpaper_style = canvas_config.get("wallpaper-style", 1)
|
wallpaper_style = canvas_config.get("wallpaper-style", 1)
|
||||||
self.app.canvas.scale_option.set(wallpaper_style)
|
self.app.canvas.scale_option.set(wallpaper_style)
|
||||||
width = self.app.guiconfig["preferences"]["width"]
|
width = self.app.guiconfig.preferences.width
|
||||||
height = self.app.guiconfig["preferences"]["height"]
|
height = self.app.guiconfig.preferences.height
|
||||||
dimensions = canvas_config.get("dimensions", [width, height])
|
dimensions = canvas_config.get("dimensions", [width, height])
|
||||||
self.app.canvas.redraw_canvas(dimensions)
|
self.app.canvas.redraw_canvas(dimensions)
|
||||||
wallpaper = canvas_config.get("wallpaper")
|
wallpaper = canvas_config.get("wallpaper")
|
||||||
|
@ -418,15 +400,15 @@ class CoreClient:
|
||||||
try:
|
try:
|
||||||
response = self.client.create_session()
|
response = self.client.create_session()
|
||||||
logging.info("created session: %s", response)
|
logging.info("created session: %s", response)
|
||||||
location_config = self.app.guiconfig["location"]
|
location_config = self.app.guiconfig.location
|
||||||
self.location = core_pb2.SessionLocation(
|
self.location = core_pb2.SessionLocation(
|
||||||
x=location_config["x"],
|
x=location_config.x,
|
||||||
y=location_config["y"],
|
y=location_config.y,
|
||||||
z=location_config["z"],
|
z=location_config.z,
|
||||||
lat=location_config["lat"],
|
lat=location_config.lat,
|
||||||
lon=location_config["lon"],
|
lon=location_config.lon,
|
||||||
alt=location_config["alt"],
|
alt=location_config.alt,
|
||||||
scale=location_config["scale"],
|
scale=location_config.scale,
|
||||||
)
|
)
|
||||||
self.join_session(response.session_id, query_location=False)
|
self.join_session(response.session_id, query_location=False)
|
||||||
except grpc.RpcError as e:
|
except grpc.RpcError as e:
|
||||||
|
@ -585,7 +567,7 @@ class CoreClient:
|
||||||
|
|
||||||
def launch_terminal(self, node_id: int):
|
def launch_terminal(self, node_id: int):
|
||||||
try:
|
try:
|
||||||
terminal = self.app.guiconfig["preferences"]["terminal"]
|
terminal = self.app.guiconfig.preferences.terminal
|
||||||
if not terminal:
|
if not terminal:
|
||||||
messagebox.showerror(
|
messagebox.showerror(
|
||||||
"Terminal Error",
|
"Terminal Error",
|
||||||
|
|
|
@ -241,16 +241,16 @@ class SizeAndScaleDialog(Dialog):
|
||||||
location.alt = self.alt.get()
|
location.alt = self.alt.get()
|
||||||
location.scale = self.scale.get()
|
location.scale = self.scale.get()
|
||||||
if self.save_default.get():
|
if self.save_default.get():
|
||||||
location_config = self.app.guiconfig["location"]
|
location_config = self.app.guiconfig.location
|
||||||
location_config["x"] = location.x
|
location_config.x = location.x
|
||||||
location_config["y"] = location.y
|
location_config.y = location.y
|
||||||
location_config["z"] = location.z
|
location_config.z = location.z
|
||||||
location_config["lat"] = location.lat
|
location_config.lat = location.lat
|
||||||
location_config["lon"] = location.lon
|
location_config.lon = location.lon
|
||||||
location_config["alt"] = location.alt
|
location_config.alt = location.alt
|
||||||
location_config["scale"] = location.scale
|
location_config.scale = location.scale
|
||||||
preferences = self.app.guiconfig["preferences"]
|
preferences = self.app.guiconfig.preferences
|
||||||
preferences["width"] = width
|
preferences.width = width
|
||||||
preferences["height"] = height
|
preferences.height = height
|
||||||
self.app.save_config()
|
self.app.save_config()
|
||||||
self.destroy()
|
self.destroy()
|
||||||
|
|
|
@ -5,7 +5,7 @@ from tkinter import ttk
|
||||||
from typing import TYPE_CHECKING, Set
|
from typing import TYPE_CHECKING, Set
|
||||||
|
|
||||||
from core.gui import nodeutils
|
from core.gui import nodeutils
|
||||||
from core.gui.appconfig import ICONS_PATH
|
from core.gui.appconfig import ICONS_PATH, CustomNode
|
||||||
from core.gui.dialogs.dialog import Dialog
|
from core.gui.dialogs.dialog import Dialog
|
||||||
from core.gui.images import Images
|
from core.gui.images import Images
|
||||||
from core.gui.nodeutils import NodeDraw
|
from core.gui.nodeutils import NodeDraw
|
||||||
|
@ -201,17 +201,12 @@ class CustomNodesDialog(Dialog):
|
||||||
self.services.update(dialog.current_services)
|
self.services.update(dialog.current_services)
|
||||||
|
|
||||||
def click_save(self):
|
def click_save(self):
|
||||||
self.app.guiconfig["nodes"].clear()
|
self.app.guiconfig.nodes.clear()
|
||||||
for name in sorted(self.app.core.custom_nodes):
|
for name in self.app.core.custom_nodes:
|
||||||
node_draw = self.app.core.custom_nodes[name]
|
node_draw = self.app.core.custom_nodes[name]
|
||||||
self.app.guiconfig["nodes"].append(
|
custom_node = CustomNode(name, node_draw.image_file, node_draw.services)
|
||||||
{
|
self.app.guiconfig.nodes.append(custom_node)
|
||||||
"name": name,
|
logging.info("saving custom nodes: %s", self.app.guiconfig.nodes)
|
||||||
"image": node_draw.image_file,
|
|
||||||
"services": list(node_draw.services),
|
|
||||||
}
|
|
||||||
)
|
|
||||||
logging.info("saving custom nodes: %s", self.app.guiconfig["nodes"])
|
|
||||||
self.app.save_config()
|
self.app.save_config()
|
||||||
self.destroy()
|
self.destroy()
|
||||||
|
|
||||||
|
@ -219,7 +214,8 @@ class CustomNodesDialog(Dialog):
|
||||||
name = self.name.get()
|
name = self.name.get()
|
||||||
if name not in self.app.core.custom_nodes:
|
if name not in self.app.core.custom_nodes:
|
||||||
image_file = Path(self.image_file).stem
|
image_file = Path(self.image_file).stem
|
||||||
node_draw = NodeDraw.from_custom(name, image_file, set(self.services))
|
custom_node = CustomNode(name, image_file, list(self.services))
|
||||||
|
node_draw = NodeDraw.from_custom(custom_node)
|
||||||
logging.info(
|
logging.info(
|
||||||
"created new custom node (%s), image file (%s), services: (%s)",
|
"created new custom node (%s), image file (%s), services: (%s)",
|
||||||
name,
|
name,
|
||||||
|
|
|
@ -45,7 +45,7 @@ class FindDialog(Dialog):
|
||||||
)
|
)
|
||||||
self.tree.grid(sticky="nsew", pady=PADY)
|
self.tree.grid(sticky="nsew", pady=PADY)
|
||||||
style = ttk.Style()
|
style = ttk.Style()
|
||||||
heading_size = int(self.app.guiconfig["scale"] * 10)
|
heading_size = int(self.app.guiconfig.scale * 10)
|
||||||
style.configure("Treeview.Heading", font=(None, heading_size, "bold"))
|
style.configure("Treeview.Heading", font=(None, heading_size, "bold"))
|
||||||
self.tree.column("nodeid", stretch=tk.YES, anchor="center")
|
self.tree.column("nodeid", stretch=tk.YES, anchor="center")
|
||||||
self.tree.heading("nodeid", text="Node ID")
|
self.tree.heading("nodeid", text="Node ID")
|
||||||
|
@ -124,7 +124,7 @@ class FindDialog(Dialog):
|
||||||
canvas_node = self.app.core.canvas_nodes[node_id]
|
canvas_node = self.app.core.canvas_nodes[node_id]
|
||||||
|
|
||||||
x0, y0, x1, y1 = self.app.canvas.bbox(canvas_node.id)
|
x0, y0, x1, y1 = self.app.canvas.bbox(canvas_node.id)
|
||||||
dist = 5 * self.app.guiconfig["scale"]
|
dist = 5 * self.app.guiconfig.scale
|
||||||
self.app.canvas.create_oval(
|
self.app.canvas.create_oval(
|
||||||
x0 - dist,
|
x0 - dist,
|
||||||
y0 - dist,
|
y0 - dist,
|
||||||
|
@ -132,7 +132,7 @@ class FindDialog(Dialog):
|
||||||
y1 + dist,
|
y1 + dist,
|
||||||
tags="find",
|
tags="find",
|
||||||
outline="red",
|
outline="red",
|
||||||
width=3.0 * self.app.guiconfig["scale"],
|
width=3.0 * self.app.guiconfig.scale,
|
||||||
)
|
)
|
||||||
|
|
||||||
_x, _y, _, _ = self.app.canvas.bbox(canvas_node.id)
|
_x, _y, _, _ = self.app.canvas.bbox(canvas_node.id)
|
||||||
|
|
|
@ -4,7 +4,6 @@ from typing import TYPE_CHECKING
|
||||||
|
|
||||||
import netaddr
|
import netaddr
|
||||||
|
|
||||||
from core.gui import appconfig
|
|
||||||
from core.gui.dialogs.dialog import Dialog
|
from core.gui.dialogs.dialog import Dialog
|
||||||
from core.gui.themes import FRAME_PAD, PADX, PADY
|
from core.gui.themes import FRAME_PAD, PADX, PADY
|
||||||
from core.gui.widgets import ListboxScroll
|
from core.gui.widgets import ListboxScroll
|
||||||
|
@ -16,11 +15,10 @@ if TYPE_CHECKING:
|
||||||
class IpConfigDialog(Dialog):
|
class IpConfigDialog(Dialog):
|
||||||
def __init__(self, app: "Application") -> None:
|
def __init__(self, app: "Application") -> None:
|
||||||
super().__init__(app, "IP Configuration")
|
super().__init__(app, "IP Configuration")
|
||||||
ip_config = self.app.guiconfig.setdefault("ips")
|
self.ip4 = self.app.guiconfig.ips.ip4
|
||||||
self.ip4 = ip_config.setdefault("ip4", appconfig.DEFAULT_IP4)
|
self.ip6 = self.app.guiconfig.ips.ip6
|
||||||
self.ip6 = ip_config.setdefault("ip6", appconfig.DEFAULT_IP6)
|
self.ip4s = self.app.guiconfig.ips.ip4s
|
||||||
self.ip4s = ip_config.setdefault("ip4s", appconfig.DEFAULT_IP4S)
|
self.ip6s = self.app.guiconfig.ips.ip6s
|
||||||
self.ip6s = ip_config.setdefault("ip6s", appconfig.DEFAULT_IP6S)
|
|
||||||
self.ip4_entry = None
|
self.ip4_entry = None
|
||||||
self.ip4_listbox = None
|
self.ip4_listbox = None
|
||||||
self.ip6_entry = None
|
self.ip6_entry = None
|
||||||
|
@ -143,11 +141,11 @@ class IpConfigDialog(Dialog):
|
||||||
for index in range(self.ip6_listbox.listbox.size()):
|
for index in range(self.ip6_listbox.listbox.size()):
|
||||||
ip6 = self.ip6_listbox.listbox.get(index)
|
ip6 = self.ip6_listbox.listbox.get(index)
|
||||||
ip6s.append(ip6)
|
ip6s.append(ip6)
|
||||||
ip_config = self.app.guiconfig["ips"]
|
ip_config = self.app.guiconfig.ips
|
||||||
ip_config["ip4"] = self.ip4
|
ip_config.ip4 = self.ip4
|
||||||
ip_config["ip6"] = self.ip6
|
ip_config.ip6 = self.ip6
|
||||||
ip_config["ip4s"] = ip4s
|
ip_config.ip4s = ip4s
|
||||||
ip_config["ip6s"] = ip6s
|
ip_config.ip6s = ip6s
|
||||||
self.app.core.interfaces_manager.update_ips(self.ip4, self.ip6)
|
self.app.core.interfaces_manager.update_ips(self.ip4, self.ip6)
|
||||||
self.app.save_config()
|
self.app.save_config()
|
||||||
self.destroy()
|
self.destroy()
|
||||||
|
|
|
@ -4,7 +4,6 @@ from typing import TYPE_CHECKING
|
||||||
|
|
||||||
import netaddr
|
import netaddr
|
||||||
|
|
||||||
from core.gui import appconfig
|
|
||||||
from core.gui.dialogs.dialog import Dialog
|
from core.gui.dialogs.dialog import Dialog
|
||||||
from core.gui.themes import PADX, PADY
|
from core.gui.themes import PADX, PADY
|
||||||
|
|
||||||
|
@ -15,7 +14,7 @@ if TYPE_CHECKING:
|
||||||
class MacConfigDialog(Dialog):
|
class MacConfigDialog(Dialog):
|
||||||
def __init__(self, app: "Application") -> None:
|
def __init__(self, app: "Application") -> None:
|
||||||
super().__init__(app, "MAC Configuration")
|
super().__init__(app, "MAC Configuration")
|
||||||
mac = self.app.guiconfig.get("mac", appconfig.DEFAULT_MAC)
|
mac = self.app.guiconfig.mac
|
||||||
self.mac_var = tk.StringVar(value=mac)
|
self.mac_var = tk.StringVar(value=mac)
|
||||||
self.draw()
|
self.draw()
|
||||||
|
|
||||||
|
@ -57,6 +56,6 @@ class MacConfigDialog(Dialog):
|
||||||
messagebox.showerror("MAC Error", f"{mac} is an invalid mac")
|
messagebox.showerror("MAC Error", f"{mac} is an invalid mac")
|
||||||
else:
|
else:
|
||||||
self.app.core.interfaces_manager.mac = netaddr.EUI(mac)
|
self.app.core.interfaces_manager.mac = netaddr.EUI(mac)
|
||||||
self.app.guiconfig["mac"] = mac
|
self.app.guiconfig.mac = mac
|
||||||
self.app.save_config()
|
self.app.save_config()
|
||||||
self.destroy()
|
self.destroy()
|
||||||
|
|
|
@ -2,7 +2,7 @@ import tkinter as tk
|
||||||
from tkinter import messagebox, ttk
|
from tkinter import messagebox, ttk
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
from core.gui.coreclient import Observer
|
from core.gui.appconfig import Observer
|
||||||
from core.gui.dialogs.dialog import Dialog
|
from core.gui.dialogs.dialog import Dialog
|
||||||
from core.gui.themes import PADX, PADY
|
from core.gui.themes import PADX, PADY
|
||||||
from core.gui.widgets import ListboxScroll
|
from core.gui.widgets import ListboxScroll
|
||||||
|
@ -89,11 +89,9 @@ class ObserverDialog(Dialog):
|
||||||
button.grid(row=0, column=1, sticky="ew")
|
button.grid(row=0, column=1, sticky="ew")
|
||||||
|
|
||||||
def click_save_config(self):
|
def click_save_config(self):
|
||||||
observers = []
|
self.app.guiconfig.observers.clear()
|
||||||
for name in sorted(self.app.core.custom_observers):
|
for observer in self.app.core.custom_observers.values():
|
||||||
observer = self.app.core.custom_observers[name]
|
self.app.guiconfig.observers.append(observer)
|
||||||
observers.append({"name": observer.name, "cmd": observer.cmd})
|
|
||||||
self.app.guiconfig["observers"] = observers
|
|
||||||
self.app.save_config()
|
self.app.save_config()
|
||||||
self.destroy()
|
self.destroy()
|
||||||
|
|
||||||
|
|
|
@ -19,11 +19,11 @@ class PreferencesDialog(Dialog):
|
||||||
def __init__(self, app: "Application"):
|
def __init__(self, app: "Application"):
|
||||||
super().__init__(app, "Preferences")
|
super().__init__(app, "Preferences")
|
||||||
self.gui_scale = tk.DoubleVar(value=self.app.app_scale)
|
self.gui_scale = tk.DoubleVar(value=self.app.app_scale)
|
||||||
preferences = self.app.guiconfig["preferences"]
|
preferences = self.app.guiconfig.preferences
|
||||||
self.editor = tk.StringVar(value=preferences["editor"])
|
self.editor = tk.StringVar(value=preferences.editor)
|
||||||
self.theme = tk.StringVar(value=preferences["theme"])
|
self.theme = tk.StringVar(value=preferences.theme)
|
||||||
self.terminal = tk.StringVar(value=preferences["terminal"])
|
self.terminal = tk.StringVar(value=preferences.terminal)
|
||||||
self.gui3d = tk.StringVar(value=preferences["gui3d"])
|
self.gui3d = tk.StringVar(value=preferences.gui3d)
|
||||||
self.draw()
|
self.draw()
|
||||||
|
|
||||||
def draw(self):
|
def draw(self):
|
||||||
|
@ -110,15 +110,14 @@ class PreferencesDialog(Dialog):
|
||||||
self.app.style.theme_use(theme)
|
self.app.style.theme_use(theme)
|
||||||
|
|
||||||
def click_save(self):
|
def click_save(self):
|
||||||
preferences = self.app.guiconfig["preferences"]
|
preferences = self.app.guiconfig.preferences
|
||||||
preferences["terminal"] = self.terminal.get()
|
preferences.terminal = self.terminal.get()
|
||||||
preferences["editor"] = self.editor.get()
|
preferences.editor = self.editor.get()
|
||||||
preferences["gui3d"] = self.gui3d.get()
|
preferences.gui3d = self.gui3d.get()
|
||||||
preferences["theme"] = self.theme.get()
|
preferences.theme = self.theme.get()
|
||||||
self.gui_scale.set(round(self.gui_scale.get(), 2))
|
self.gui_scale.set(round(self.gui_scale.get(), 2))
|
||||||
app_scale = self.gui_scale.get()
|
app_scale = self.gui_scale.get()
|
||||||
self.app.guiconfig["scale"] = app_scale
|
self.app.guiconfig.scale = app_scale
|
||||||
|
|
||||||
self.app.save_config()
|
self.app.save_config()
|
||||||
self.scale_adjust()
|
self.scale_adjust()
|
||||||
self.destroy()
|
self.destroy()
|
||||||
|
|
|
@ -2,7 +2,7 @@ import tkinter as tk
|
||||||
from tkinter import ttk
|
from tkinter import ttk
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
from core.gui.coreclient import CoreServer
|
from core.gui.appconfig import CoreServer
|
||||||
from core.gui.dialogs.dialog import Dialog
|
from core.gui.dialogs.dialog import Dialog
|
||||||
from core.gui.themes import FRAME_PAD, PADX, PADY
|
from core.gui.themes import FRAME_PAD, PADX, PADY
|
||||||
from core.gui.widgets import ListboxScroll
|
from core.gui.widgets import ListboxScroll
|
||||||
|
@ -20,7 +20,6 @@ class ServersDialog(Dialog):
|
||||||
super().__init__(app, "CORE Servers")
|
super().__init__(app, "CORE Servers")
|
||||||
self.name = tk.StringVar(value=DEFAULT_NAME)
|
self.name = tk.StringVar(value=DEFAULT_NAME)
|
||||||
self.address = tk.StringVar(value=DEFAULT_ADDRESS)
|
self.address = tk.StringVar(value=DEFAULT_ADDRESS)
|
||||||
self.port = tk.IntVar(value=DEFAULT_PORT)
|
|
||||||
self.servers = None
|
self.servers = None
|
||||||
self.selected_index = None
|
self.selected_index = None
|
||||||
self.selected = None
|
self.selected = None
|
||||||
|
@ -54,31 +53,17 @@ class ServersDialog(Dialog):
|
||||||
frame.grid(pady=PADY, sticky="ew")
|
frame.grid(pady=PADY, 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)
|
|
||||||
|
|
||||||
label = ttk.Label(frame, text="Name")
|
label = ttk.Label(frame, text="Name")
|
||||||
label.grid(row=0, column=0, sticky="w", padx=PADX, pady=PADY)
|
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="Address")
|
label = ttk.Label(frame, text="Address")
|
||||||
label.grid(row=0, column=2, sticky="w", padx=PADX, pady=PADY)
|
label.grid(row=0, column=2, sticky="w", padx=PADX)
|
||||||
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.grid(row=0, column=4, sticky="w", padx=PADX, pady=PADY)
|
|
||||||
entry = ttk.Entry(
|
|
||||||
frame,
|
|
||||||
textvariable=self.port,
|
|
||||||
validate="key",
|
|
||||||
validatecommand=(self.app.validation.positive_int, "%P"),
|
|
||||||
)
|
|
||||||
entry.bind(
|
|
||||||
"<FocusOut>", lambda event: self.app.validation.focus_out(event, "50051")
|
|
||||||
)
|
|
||||||
entry.grid(row=0, column=5, sticky="ew")
|
|
||||||
|
|
||||||
def draw_servers_buttons(self):
|
def draw_servers_buttons(self):
|
||||||
frame = ttk.Frame(self.top)
|
frame = ttk.Frame(self.top)
|
||||||
frame.grid(pady=PADY, sticky="ew")
|
frame.grid(pady=PADY, sticky="ew")
|
||||||
|
@ -113,13 +98,9 @@ class ServersDialog(Dialog):
|
||||||
button.grid(row=0, column=1, sticky="ew")
|
button.grid(row=0, column=1, sticky="ew")
|
||||||
|
|
||||||
def click_save_configuration(self):
|
def click_save_configuration(self):
|
||||||
servers = []
|
self.app.guiconfig.servers.clear()
|
||||||
for name in sorted(self.app.core.servers):
|
for server in self.app.core.servers.values():
|
||||||
server = self.app.core.servers[name]
|
self.app.guiconfig.servers.append(server)
|
||||||
servers.append(
|
|
||||||
{"name": server.name, "address": server.address, "port": server.port}
|
|
||||||
)
|
|
||||||
self.app.guiconfig["servers"] = servers
|
|
||||||
self.app.save_config()
|
self.app.save_config()
|
||||||
self.destroy()
|
self.destroy()
|
||||||
|
|
||||||
|
@ -127,8 +108,7 @@ class ServersDialog(Dialog):
|
||||||
name = self.name.get()
|
name = self.name.get()
|
||||||
if name not in self.app.core.servers:
|
if name not in self.app.core.servers:
|
||||||
address = self.address.get()
|
address = self.address.get()
|
||||||
port = self.port.get()
|
server = CoreServer(name, address)
|
||||||
server = CoreServer(name, address, port)
|
|
||||||
self.app.core.servers[name] = server
|
self.app.core.servers[name] = server
|
||||||
self.servers.insert(tk.END, name)
|
self.servers.insert(tk.END, name)
|
||||||
|
|
||||||
|
@ -140,7 +120,6 @@ class ServersDialog(Dialog):
|
||||||
server = self.app.core.servers.pop(previous_name)
|
server = self.app.core.servers.pop(previous_name)
|
||||||
server.name = name
|
server.name = name
|
||||||
server.address = self.address.get()
|
server.address = self.address.get()
|
||||||
server.port = self.port.get()
|
|
||||||
self.app.core.servers[name] = server
|
self.app.core.servers[name] = server
|
||||||
self.servers.delete(self.selected_index)
|
self.servers.delete(self.selected_index)
|
||||||
self.servers.insert(self.selected_index, name)
|
self.servers.insert(self.selected_index, name)
|
||||||
|
@ -154,7 +133,6 @@ class ServersDialog(Dialog):
|
||||||
self.selected_index = None
|
self.selected_index = None
|
||||||
self.name.set(DEFAULT_NAME)
|
self.name.set(DEFAULT_NAME)
|
||||||
self.address.set(DEFAULT_ADDRESS)
|
self.address.set(DEFAULT_ADDRESS)
|
||||||
self.port.set(DEFAULT_PORT)
|
|
||||||
self.servers.selection_clear(0, tk.END)
|
self.servers.selection_clear(0, tk.END)
|
||||||
self.save_button.config(state=tk.DISABLED)
|
self.save_button.config(state=tk.DISABLED)
|
||||||
self.delete_button.config(state=tk.DISABLED)
|
self.delete_button.config(state=tk.DISABLED)
|
||||||
|
@ -167,7 +145,6 @@ class ServersDialog(Dialog):
|
||||||
server = self.app.core.servers[self.selected]
|
server = self.app.core.servers[self.selected]
|
||||||
self.name.set(server.name)
|
self.name.set(server.name)
|
||||||
self.address.set(server.address)
|
self.address.set(server.address)
|
||||||
self.port.set(server.port)
|
|
||||||
self.save_button.config(state=tk.NORMAL)
|
self.save_button.config(state=tk.NORMAL)
|
||||||
self.delete_button.config(state=tk.NORMAL)
|
self.delete_button.config(state=tk.NORMAL)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -70,7 +70,7 @@ class SessionsDialog(Dialog):
|
||||||
selectmode=tk.BROWSE,
|
selectmode=tk.BROWSE,
|
||||||
)
|
)
|
||||||
style = ttk.Style()
|
style = ttk.Style()
|
||||||
heading_size = int(self.app.guiconfig["scale"] * 10)
|
heading_size = int(self.app.guiconfig.scale * 10)
|
||||||
style.configure("Treeview.Heading", font=(None, heading_size, "bold"))
|
style.configure("Treeview.Heading", font=(None, heading_size, "bold"))
|
||||||
self.tree.grid(sticky="nsew")
|
self.tree.grid(sticky="nsew")
|
||||||
self.tree.column("id", stretch=tk.YES, anchor="center")
|
self.tree.column("id", stretch=tk.YES, anchor="center")
|
||||||
|
|
|
@ -1002,10 +1002,10 @@ class CanvasGraph(tk.Canvas):
|
||||||
if NodeUtils.is_custom(
|
if NodeUtils.is_custom(
|
||||||
canvas_node.core_node.type, canvas_node.core_node.model
|
canvas_node.core_node.type, canvas_node.core_node.model
|
||||||
):
|
):
|
||||||
for custom_node in self.app.guiconfig["nodes"]:
|
for custom_node in self.app.guiconfig.nodes:
|
||||||
if custom_node["name"] == canvas_node.core_node.model:
|
if custom_node.name == canvas_node.core_node.model:
|
||||||
img = Images.get_custom(
|
img = Images.get_custom(
|
||||||
custom_node["image"], int(ICON_SIZE * self.app.app_scale)
|
custom_node.image, int(ICON_SIZE * self.app.app_scale)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
image_enum = TypeToImage.get(
|
image_enum = TypeToImage.get(
|
||||||
|
|
|
@ -4,7 +4,6 @@ from typing import TYPE_CHECKING, Any, List, Optional, Set, Tuple
|
||||||
import netaddr
|
import netaddr
|
||||||
from netaddr import EUI, IPNetwork
|
from netaddr import EUI, IPNetwork
|
||||||
|
|
||||||
from core.gui import appconfig
|
|
||||||
from core.gui.nodeutils import NodeUtils
|
from core.gui.nodeutils import NodeUtils
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
@ -44,14 +43,13 @@ class Subnets:
|
||||||
class InterfaceManager:
|
class InterfaceManager:
|
||||||
def __init__(self, app: "Application") -> None:
|
def __init__(self, app: "Application") -> None:
|
||||||
self.app = app
|
self.app = app
|
||||||
ip_config = self.app.guiconfig.get("ips", {})
|
ip4 = self.app.guiconfig.ips.ip4
|
||||||
ip4 = ip_config.get("ip4", appconfig.DEFAULT_IP4)
|
ip6 = self.app.guiconfig.ips.ip6
|
||||||
ip6 = ip_config.get("ip6", appconfig.DEFAULT_IP6)
|
|
||||||
self.ip4_mask = 24
|
self.ip4_mask = 24
|
||||||
self.ip6_mask = 64
|
self.ip6_mask = 64
|
||||||
self.ip4_subnets = IPNetwork(f"{ip4}/{self.ip4_mask}")
|
self.ip4_subnets = IPNetwork(f"{ip4}/{self.ip4_mask}")
|
||||||
self.ip6_subnets = IPNetwork(f"{ip6}/{self.ip6_mask}")
|
self.ip6_subnets = IPNetwork(f"{ip6}/{self.ip6_mask}")
|
||||||
mac = self.app.guiconfig.get("mac", appconfig.DEFAULT_MAC)
|
mac = self.app.guiconfig.mac
|
||||||
self.mac = EUI(mac, dialect=netaddr.mac_unix_expanded)
|
self.mac = EUI(mac, dialect=netaddr.mac_unix_expanded)
|
||||||
self.current_mac = None
|
self.current_mac = None
|
||||||
self.current_subnets = None
|
self.current_subnets = None
|
||||||
|
|
|
@ -93,7 +93,7 @@ class Menubar(tk.Menu):
|
||||||
)
|
)
|
||||||
self.app.bind_all("<Control-o>", self.click_open_xml)
|
self.app.bind_all("<Control-o>", self.click_open_xml)
|
||||||
self.recent_menu = tk.Menu(menu)
|
self.recent_menu = tk.Menu(menu)
|
||||||
for i in self.app.guiconfig["recentfiles"]:
|
for i in self.app.guiconfig.recentfiles:
|
||||||
self.recent_menu.add_command(
|
self.recent_menu.add_command(
|
||||||
label=i, command=partial(self.open_recent_files, i)
|
label=i, command=partial(self.open_recent_files, i)
|
||||||
)
|
)
|
||||||
|
@ -298,7 +298,7 @@ class Menubar(tk.Menu):
|
||||||
|
|
||||||
def update_recent_files(self) -> None:
|
def update_recent_files(self) -> None:
|
||||||
self.recent_menu.delete(0, tk.END)
|
self.recent_menu.delete(0, tk.END)
|
||||||
for i in self.app.guiconfig["recentfiles"]:
|
for i in self.app.guiconfig.recentfiles:
|
||||||
self.recent_menu.add_command(
|
self.recent_menu.add_command(
|
||||||
label=i, command=partial(self.open_recent_files, i)
|
label=i, command=partial(self.open_recent_files, i)
|
||||||
)
|
)
|
||||||
|
@ -350,7 +350,7 @@ class Menubar(tk.Menu):
|
||||||
dialog.show()
|
dialog.show()
|
||||||
|
|
||||||
def add_recent_file_to_gui_config(self, file_path) -> None:
|
def add_recent_file_to_gui_config(self, file_path) -> None:
|
||||||
recent_files = self.app.guiconfig["recentfiles"]
|
recent_files = self.app.guiconfig.recentfiles
|
||||||
num_files = len(recent_files)
|
num_files = len(recent_files)
|
||||||
if num_files == 0:
|
if num_files == 0:
|
||||||
recent_files.insert(0, file_path)
|
recent_files.insert(0, file_path)
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import logging
|
import logging
|
||||||
from typing import TYPE_CHECKING, Dict, List, Optional, Set, Union
|
from typing import TYPE_CHECKING, List, Optional, Set
|
||||||
|
|
||||||
from core.api.grpc.core_pb2 import Node, NodeType
|
from core.api.grpc.core_pb2 import Node, NodeType
|
||||||
|
from core.gui.appconfig import CustomNode, GuiConfig
|
||||||
from core.gui.images import ImageEnum, Images, TypeToImage
|
from core.gui.images import ImageEnum, Images, TypeToImage
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
@ -41,16 +42,16 @@ class NodeDraw:
|
||||||
return node_draw
|
return node_draw
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_custom(cls, name: str, image_file: str, services: Set[str]):
|
def from_custom(cls, custom_node: CustomNode):
|
||||||
node_draw = NodeDraw()
|
node_draw = NodeDraw()
|
||||||
node_draw.custom = True
|
node_draw.custom = True
|
||||||
node_draw.image_file = image_file
|
node_draw.image_file = custom_node.image
|
||||||
node_draw.image = Images.get_custom(image_file, ICON_SIZE)
|
node_draw.image = Images.get_custom(custom_node.image, ICON_SIZE)
|
||||||
node_draw.node_type = NodeType.DEFAULT
|
node_draw.node_type = NodeType.DEFAULT
|
||||||
node_draw.services = services
|
node_draw.services = custom_node.services
|
||||||
node_draw.label = name
|
node_draw.label = custom_node.name
|
||||||
node_draw.model = name
|
node_draw.model = custom_node.name
|
||||||
node_draw.tooltip = name
|
node_draw.tooltip = custom_node.name
|
||||||
return node_draw
|
return node_draw
|
||||||
|
|
||||||
|
|
||||||
|
@ -97,11 +98,7 @@ class NodeUtils:
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def node_icon(
|
def node_icon(
|
||||||
cls,
|
cls, node_type: NodeType, model: str, gui_config: GuiConfig, scale=1.0
|
||||||
node_type: NodeType,
|
|
||||||
model: str,
|
|
||||||
gui_config: Dict[str, List[Dict[str, str]]],
|
|
||||||
scale=1.0,
|
|
||||||
) -> "ImageTk.PhotoImage":
|
) -> "ImageTk.PhotoImage":
|
||||||
|
|
||||||
image_enum = TypeToImage.get(node_type, model)
|
image_enum = TypeToImage.get(node_type, model)
|
||||||
|
@ -114,10 +111,7 @@ class NodeUtils:
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def node_image(
|
def node_image(
|
||||||
cls,
|
cls, core_node: "core_pb2.Node", gui_config: GuiConfig, scale=1.0
|
||||||
core_node: "core_pb2.Node",
|
|
||||||
gui_config: Dict[str, List[Dict[str, str]]],
|
|
||||||
scale=1.0,
|
|
||||||
) -> "ImageTk.PhotoImage":
|
) -> "ImageTk.PhotoImage":
|
||||||
image = cls.node_icon(core_node.type, core_node.model, gui_config, scale)
|
image = cls.node_icon(core_node.type, core_node.model, gui_config, scale)
|
||||||
if core_node.icon:
|
if core_node.icon:
|
||||||
|
@ -132,20 +126,17 @@ class NodeUtils:
|
||||||
return node_type == NodeType.DEFAULT and model not in cls.NODE_MODELS
|
return node_type == NodeType.DEFAULT and model not in cls.NODE_MODELS
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_custom_node_services(
|
def get_custom_node_services(cls, gui_config: GuiConfig, name: str) -> List[str]:
|
||||||
cls, gui_config: Dict[str, List[Dict[str, str]]], name: str
|
for custom_node in gui_config.nodes:
|
||||||
) -> List[str]:
|
if custom_node.name == name:
|
||||||
for m in gui_config["nodes"]:
|
return custom_node.services
|
||||||
if m["name"] == name:
|
|
||||||
return m["services"]
|
|
||||||
return []
|
return []
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_image_file(cls, gui_config, name: str) -> Union[str, None]:
|
def get_image_file(cls, gui_config: GuiConfig, name: str) -> Optional[str]:
|
||||||
if "nodes" in gui_config:
|
for custom_node in gui_config.nodes:
|
||||||
for m in gui_config["nodes"]:
|
if custom_node.name == name:
|
||||||
if m["name"] == name:
|
return custom_node.image
|
||||||
return m["image"]
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|
Loading…
Add table
Reference in a new issue