pygui: refactoring of nodeutils and its usage, fixed issue with drawing custom nodes and copying services

This commit is contained in:
Blake Harnden 2021-02-18 10:47:20 -08:00
parent 422a1a500e
commit 47ac4c850d
12 changed files with 194 additions and 191 deletions

View file

@ -9,6 +9,7 @@ from PIL.ImageTk import PhotoImage
from core.api.grpc.wrappers import Interface, Link
from core.gui import appconfig
from core.gui import nodeutils as nutils
from core.gui.dialogs.shapemod import ShapeDialog
from core.gui.graph import tags
from core.gui.graph.edges import EDGE_WIDTH, CanvasEdge
@ -17,7 +18,6 @@ from core.gui.graph.node import CanvasNode, ShadowNode
from core.gui.graph.shape import Shape
from core.gui.graph.shapeutils import ShapeType, is_draw_shape, is_marker
from core.gui.images import TypeToImage
from core.gui.nodeutils import NodeUtils
if TYPE_CHECKING:
from core.gui.app import Application
@ -803,9 +803,7 @@ class CanvasGraph(tk.Canvas):
def scale_graph(self) -> None:
for nid, canvas_node in self.nodes.items():
img = None
if NodeUtils.is_custom(
canvas_node.core_node.type, canvas_node.core_node.model
):
if nutils.is_custom(canvas_node.core_node):
for custom_node in self.app.guiconfig.nodes:
if custom_node.name == canvas_node.core_node.model:
img = self.app.get_custom_icon(custom_node.image, ICON_SIZE)

View file

@ -5,6 +5,7 @@ from tkinter import BooleanVar, messagebox, ttk
from typing import TYPE_CHECKING, Any, Dict, Optional, Tuple, ValuesView
from core.api.grpc.wrappers import Link, LinkType, Node, Session, ThroughputsEvent
from core.gui import nodeutils as nutils
from core.gui.graph import tags
from core.gui.graph.edges import (
CanvasEdge,
@ -17,7 +18,7 @@ from core.gui.graph.graph import CanvasGraph
from core.gui.graph.node import CanvasNode
from core.gui.graph.shapeutils import ShapeType
from core.gui.images import ImageEnum
from core.gui.nodeutils import ICON_SIZE, NodeDraw, NodeUtils
from core.gui.nodeutils import ICON_SIZE, NodeDraw
if TYPE_CHECKING:
from core.gui.app import Application
@ -235,7 +236,7 @@ class CanvasManager:
# create session nodes
for core_node in session.nodes.values():
# add node, avoiding ignored nodes
if NodeUtils.is_ignore_node(core_node):
if nutils.should_ignore(core_node):
continue
self.add_core_node(core_node)
@ -300,7 +301,7 @@ class CanvasManager:
logging.info("adding core node canvas(%s): %s", core_node.name, canvas_id)
canvas = self.get(canvas_id)
# if the gui can't find node's image, default to the "edit-node" image
image = NodeUtils.node_image(core_node, self.app.guiconfig, self.app.app_scale)
image = nutils.get_icon(core_node, self.app.guiconfig, self.app.app_scale)
if not image:
image = self.app.get_icon(ImageEnum.EDITNODE, ICON_SIZE)
x = core_node.position.x

View file

@ -9,7 +9,8 @@ from PIL.ImageTk import PhotoImage
from core.api.grpc.services_pb2 import ServiceAction
from core.api.grpc.wrappers import Interface, Node, NodeType
from core.gui import nodeutils, themes
from core.gui import nodeutils as nutils
from core.gui import themes
from core.gui.dialogs.emaneconfig import EmaneConfigDialog
from core.gui.dialogs.mobilityconfig import MobilityConfigDialog
from core.gui.dialogs.nodeconfig import NodeConfigDialog
@ -21,7 +22,7 @@ from core.gui.graph import tags
from core.gui.graph.edges import CanvasEdge, CanvasWirelessEdge
from core.gui.graph.tooltip import CanvasTooltip
from core.gui.images import ImageEnum, Images
from core.gui.nodeutils import ANTENNA_SIZE, ICON_SIZE, NodeUtils
from core.gui.nodeutils import ANTENNA_SIZE, ICON_SIZE
if TYPE_CHECKING:
from core.gui.app import Application
@ -190,7 +191,7 @@ class CanvasNode:
def on_enter(self, event: tk.Event) -> None:
is_runtime = self.app.core.is_runtime()
has_observer = self.app.core.observer is not None
is_container = NodeUtils.is_container_node(self.core_node)
is_container = nutils.is_container(self.core_node)
if is_runtime and has_observer and is_container:
self.tooltip.text.set("waiting...")
self.tooltip.on_enter(event)
@ -205,7 +206,7 @@ class CanvasNode:
def double_click(self, event: tk.Event) -> None:
if self.app.core.is_runtime():
if NodeUtils.is_container_node(self.core_node):
if nutils.is_container(self.core_node):
self.canvas.core.launch_terminal(self.core_node.id)
else:
self.show_config()
@ -233,7 +234,7 @@ class CanvasNode:
self.context.add_command(
label="Mobility Player", command=self.show_mobility_player
)
if NodeUtils.is_container_node(self.core_node):
if nutils.is_container(self.core_node):
services_menu = tk.Menu(self.context)
for service in sorted(self.core_node.services):
service_menu = tk.Menu(services_menu)
@ -251,7 +252,7 @@ class CanvasNode:
self.context.add_cascade(label="Services", menu=services_menu)
else:
self.context.add_command(label="Configure", command=self.show_config)
if NodeUtils.is_container_node(self.core_node):
if nutils.is_container(self.core_node):
self.context.add_command(label="Services", command=self.show_services)
self.context.add_command(
label="Config Services", command=self.show_config_services
@ -268,7 +269,7 @@ class CanvasNode:
self.context.add_command(
label="Mobility Config", command=self.show_mobility_config
)
if NodeUtils.is_wireless_node(self.core_node):
if nutils.is_wireless(self.core_node):
self.context.add_command(
label="Link To Selected", command=self.wireless_link_selected
)
@ -402,7 +403,7 @@ class CanvasNode:
logging.error(f"node icon does not exist: {icon_path}")
return
self.core_node.icon = icon_path
self.image = Images.create(icon_path, nodeutils.ICON_SIZE)
self.image = Images.create(icon_path)
self.canvas.itemconfig(self.id, image=self.image)
def is_linkable(self, node: "CanvasNode") -> bool:
@ -410,22 +411,19 @@ class CanvasNode:
if self == node:
return False
# rj45 nodes can only support one link
if NodeUtils.is_rj45_node(self.core_node) and self.edges:
if nutils.is_rj45(self.core_node) and self.edges:
return False
if NodeUtils.is_rj45_node(node.core_node) and node.edges:
if nutils.is_rj45(node.core_node) and node.edges:
return False
# only 1 link between bridge based nodes
is_src_bridge = NodeUtils.is_bridge_node(self.core_node)
is_dst_bridge = NodeUtils.is_bridge_node(node.core_node)
is_src_bridge = nutils.is_bridge(self.core_node)
is_dst_bridge = nutils.is_bridge(node.core_node)
common_links = self.edges & node.edges
if all([is_src_bridge, is_dst_bridge, common_links]):
return False
# valid link
return True
def is_wireless(self) -> bool:
return NodeUtils.is_wireless_node(self.core_node)
def hide(self) -> None:
self.hidden = True
self.canvas.itemconfig(self.id, state=tk.HIDDEN)
@ -481,6 +479,9 @@ class CanvasNode:
def validate_service(self, service: str) -> None:
self._service_action(service, ServiceAction.VALIDATE)
def is_wireless(self) -> bool:
return nutils.is_wireless(self.core_node)
class ShadowNode:
def __init__(