reload custom node image when open xml, if the gui doesn't know about the custom image, use a default one
This commit is contained in:
parent
b4b71eda0e
commit
4c0254ec10
3 changed files with 57 additions and 11 deletions
|
@ -12,6 +12,7 @@ from core.gui.graph.enums import GraphMode, ScaleOption
|
||||||
from core.gui.graph.node import CanvasNode
|
from core.gui.graph.node import CanvasNode
|
||||||
from core.gui.graph.shape import Shape
|
from core.gui.graph.shape import Shape
|
||||||
from core.gui.graph.shapeutils import ShapeType, is_draw_shape, is_marker
|
from core.gui.graph.shapeutils import ShapeType, is_draw_shape, is_marker
|
||||||
|
from core.gui.images import ImageEnum, Images
|
||||||
from core.gui.nodeutils import EdgeUtils, NodeUtils
|
from core.gui.nodeutils import EdgeUtils, NodeUtils
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
@ -20,6 +21,7 @@ if TYPE_CHECKING:
|
||||||
|
|
||||||
ZOOM_IN = 1.1
|
ZOOM_IN = 1.1
|
||||||
ZOOM_OUT = 0.9
|
ZOOM_OUT = 0.9
|
||||||
|
ICON_SIZE = 48
|
||||||
|
|
||||||
|
|
||||||
class CanvasGraph(tk.Canvas):
|
class CanvasGraph(tk.Canvas):
|
||||||
|
@ -217,7 +219,10 @@ class CanvasGraph(tk.Canvas):
|
||||||
# peer to peer node is not drawn on the GUI
|
# peer to peer node is not drawn on the GUI
|
||||||
if NodeUtils.is_ignore_node(core_node.type):
|
if NodeUtils.is_ignore_node(core_node.type):
|
||||||
continue
|
continue
|
||||||
image = NodeUtils.node_image(core_node)
|
image = NodeUtils.node_image(core_node, self.app.guiconfig)
|
||||||
|
# if the gui can't find node's image, default to the "edit-node" image
|
||||||
|
if not image:
|
||||||
|
image = Images.get(ImageEnum.EDITNODE, ICON_SIZE)
|
||||||
x = core_node.position.x
|
x = core_node.position.x
|
||||||
y = core_node.position.y
|
y = core_node.position.y
|
||||||
node = CanvasNode(self.master, x, y, core_node, image)
|
node = CanvasNode(self.master, x, y, core_node, image)
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
|
from tkinter import messagebox
|
||||||
|
|
||||||
from PIL import Image, ImageTk
|
from PIL import Image, ImageTk
|
||||||
|
|
||||||
|
@ -22,15 +23,32 @@ class Images:
|
||||||
cls.images[image.stem] = str(image)
|
cls.images[image.stem] = str(image)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get(cls, image_enum: Enum, width: int, height: int = None):
|
def get(
|
||||||
|
cls, image_enum: Enum, width: int, height: int = None
|
||||||
|
) -> ImageTk.PhotoImage:
|
||||||
file_path = cls.images[image_enum.value]
|
file_path = cls.images[image_enum.value]
|
||||||
return cls.create(file_path, width, height)
|
return cls.create(file_path, width, height)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_custom(cls, name: str, width: int, height: int = None):
|
def get_with_image_file(
|
||||||
file_path = cls.images[name]
|
cls, stem: str, width: int, height: int = None
|
||||||
|
) -> ImageTk.PhotoImage:
|
||||||
|
file_path = cls.images[stem]
|
||||||
return cls.create(file_path, width, height)
|
return cls.create(file_path, width, height)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_custom(
|
||||||
|
cls, name: str, width: int, height: int = None
|
||||||
|
) -> ImageTk.PhotoImage:
|
||||||
|
try:
|
||||||
|
file_path = cls.images[name]
|
||||||
|
return cls.create(file_path, width, height)
|
||||||
|
except KeyError:
|
||||||
|
messagebox.showwarning(
|
||||||
|
"Missing image file",
|
||||||
|
f"{name}.png is missing at daemon/core/gui/data/icons, drop image file at daemon/core/gui/data/icons and restart the gui",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class ImageEnum(Enum):
|
class ImageEnum(Enum):
|
||||||
SWITCH = "lanswitch"
|
SWITCH = "lanswitch"
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import logging
|
import logging
|
||||||
from typing import TYPE_CHECKING, Optional, Set, Tuple
|
from typing import TYPE_CHECKING, Dict, List, Optional, Set, Tuple, Union
|
||||||
|
|
||||||
from core.api.grpc.core_pb2 import NodeType
|
from core.api.grpc.core_pb2 import NodeType
|
||||||
from core.gui.images import ImageEnum, Images
|
from core.gui.images import ImageEnum, Images
|
||||||
|
@ -91,14 +91,27 @@ class NodeUtils:
|
||||||
return node_type in cls.RJ45_NODES
|
return node_type in cls.RJ45_NODES
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def node_icon(cls, node_type: NodeType, model: str) -> "ImageTk.PhotoImage":
|
def node_icon(
|
||||||
|
cls,
|
||||||
|
node_type: NodeType,
|
||||||
|
model: str,
|
||||||
|
gui_config: Dict[str, List[Dict[str, str]]],
|
||||||
|
) -> "ImageTk.PhotoImage":
|
||||||
if model == "":
|
if model == "":
|
||||||
model = None
|
model = None
|
||||||
return cls.NODE_ICONS[(node_type, model)]
|
try:
|
||||||
|
image = cls.NODE_ICONS[(node_type, model)]
|
||||||
|
return image
|
||||||
|
except KeyError:
|
||||||
|
image_stem = cls.get_image_file(gui_config, model)
|
||||||
|
if image_stem:
|
||||||
|
return Images.get_with_image_file(image_stem, ICON_SIZE)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def node_image(cls, core_node: "core_pb2.Node") -> "ImageTk.PhotoImage":
|
def node_image(
|
||||||
image = cls.node_icon(core_node.type, core_node.model)
|
cls, core_node: "core_pb2.Node", gui_config: Dict[str, List[Dict[str, str]]]
|
||||||
|
) -> "ImageTk.PhotoImage":
|
||||||
|
image = cls.node_icon(core_node.type, core_node.model, gui_config)
|
||||||
if core_node.icon:
|
if core_node.icon:
|
||||||
try:
|
try:
|
||||||
image = Images.create(core_node.icon, ICON_SIZE)
|
image = Images.create(core_node.icon, ICON_SIZE)
|
||||||
|
@ -107,16 +120,26 @@ class NodeUtils:
|
||||||
return image
|
return image
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def is_custom(cls, model):
|
def is_custom(cls, model: str) -> bool:
|
||||||
return model not in cls.NODE_MODELS
|
return model not in cls.NODE_MODELS
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_custom_node_services(cls, gui_config, name):
|
def get_custom_node_services(
|
||||||
|
cls, gui_config: Dict[str, List[Dict[str, str]]], name: str
|
||||||
|
) -> List[str]:
|
||||||
for m in gui_config["nodes"]:
|
for m in gui_config["nodes"]:
|
||||||
if m["name"] == name:
|
if m["name"] == name:
|
||||||
return m["services"]
|
return m["services"]
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_image_file(cls, gui_config, name: str) -> Union[str, None]:
|
||||||
|
if "nodes" in gui_config:
|
||||||
|
for m in gui_config["nodes"]:
|
||||||
|
if m["name"] == name:
|
||||||
|
return m["image"]
|
||||||
|
return None
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def setup(cls):
|
def setup(cls):
|
||||||
nodes = [
|
nodes = [
|
||||||
|
|
Loading…
Add table
Reference in a new issue