Merge pull request #444 from coreemu/enhancement/pygui-config
Enhancement/pygui config
This commit is contained in:
commit
944040608e
16 changed files with 251 additions and 209 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,10 +1,10 @@
|
||||||
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
|
||||||
|
|
||||||
# gui home paths
|
|
||||||
from core.gui import themes
|
from core.gui import themes
|
||||||
|
|
||||||
HOME_PATH = Path.home().joinpath(".coretk")
|
HOME_PATH = Path.home().joinpath(".coretk")
|
||||||
|
@ -37,11 +37,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 +44,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 +196,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 +218,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…
Reference in a new issue