diff --git a/coretk/coretk/dialogs/nodeconfig.py b/coretk/coretk/dialogs/nodeconfig.py index 8f4ad8a9..c71a1b34 100644 --- a/coretk/coretk/dialogs/nodeconfig.py +++ b/coretk/coretk/dialogs/nodeconfig.py @@ -46,6 +46,7 @@ class NodeConfigDialog(Dialog): self.canvas_node = canvas_node self.node = canvas_node.core_node self.image = canvas_node.image + self.image_file = None self.image_button = None self.name = tk.StringVar(value=self.node.name) self.type = tk.StringVar(value=self.node.model) @@ -201,6 +202,7 @@ class NodeConfigDialog(Dialog): if file_path: self.image = Images.create(file_path, nodeutils.ICON_SIZE) self.image_button.config(image=self.image) + self.image_file = file_path def config_apply(self): # update core node @@ -211,6 +213,10 @@ class NodeConfigDialog(Dialog): if NodeUtils.is_container_node(self.node.type) and server != "localhost": self.node.server = server + # set custom icon + if self.image_file: + self.node.icon = self.image_file + # update canvas node self.canvas_node.image = self.image diff --git a/coretk/coretk/graph/graph.py b/coretk/coretk/graph/graph.py index e439b842..baa18170 100644 --- a/coretk/coretk/graph/graph.py +++ b/coretk/coretk/graph/graph.py @@ -4,6 +4,7 @@ import tkinter as tk from PIL import Image, ImageTk from core.api.grpc import core_pb2 +from coretk import nodeutils from coretk.dialogs.shapemod import ShapeDialog from coretk.graph import tags from coretk.graph.edges import CanvasEdge, CanvasWirelessEdge @@ -12,6 +13,7 @@ from coretk.graph.linkinfo import LinkInfo, Throughput from coretk.graph.node import CanvasNode from coretk.graph.shape import Shape from coretk.graph.shapeutils import ShapeType, is_draw_shape +from coretk.images import Images from coretk.nodeutils import NodeUtils ZOOM_IN = 1.1 @@ -186,12 +188,19 @@ class CanvasGraph(tk.Canvas): """ # draw existing nodes for core_node in session.nodes: + logging.info("drawing core node: %s", core_node) # peer to peer node is not drawn on the GUI if NodeUtils.is_ignore_node(core_node.type): continue # draw nodes on the canvas image = NodeUtils.node_icon(core_node.type, core_node.model) + if core_node.icon: + try: + image = Images.create(core_node.icon, nodeutils.ICON_SIZE) + except OSError: + logging.error("invalid icon: %s", core_node.icon) + x = core_node.position.x y = core_node.position.y node = CanvasNode(self.master, x, y, core_node, image) diff --git a/daemon/core/api/grpc/server.py b/daemon/core/api/grpc/server.py index dac09427..fd1a73c3 100644 --- a/daemon/core/api/grpc/server.py +++ b/daemon/core/api/grpc/server.py @@ -393,15 +393,14 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): position = core_pb2.Position( x=node.position.x, y=node.position.y, z=node.position.z ) - services = getattr(node, "services", []) if services is None: services = [] services = [x.name for x in services] - emane_model = None if isinstance(node, EmaneNet): emane_model = node.model.name + image = getattr(node, "image", None) node_proto = core_pb2.Node( id=node.id, @@ -411,6 +410,8 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): type=node_type.value, position=position, services=services, + icon=node.icon, + image=image, ) if isinstance(node, (DockerNode, LxcNode)): node_proto.image = node.image