pygui: moved shadow node code to same file as regular nodes
This commit is contained in:
parent
e7c721989f
commit
0fee29754d
3 changed files with 88 additions and 92 deletions
|
@ -4,22 +4,18 @@ import math
|
|||
import tkinter as tk
|
||||
from typing import TYPE_CHECKING, Optional, Tuple, Union
|
||||
|
||||
from PIL.ImageTk import PhotoImage
|
||||
|
||||
from core.api.grpc.wrappers import Interface, Link
|
||||
from core.gui import themes
|
||||
from core.gui.dialogs.linkconfig import LinkConfigurationDialog
|
||||
from core.gui.frames.link import EdgeInfoFrame, WirelessEdgeInfoFrame
|
||||
from core.gui.graph import tags
|
||||
from core.gui.images import ImageEnum
|
||||
from core.gui.nodeutils import ICON_SIZE
|
||||
from core.gui.utils import bandwidth_text, delay_jitter_text
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from core.gui.app import Application
|
||||
from core.gui.graph.graph import CanvasGraph
|
||||
from core.gui.graph.manager import CanvasManager
|
||||
from core.gui.graph.node import CanvasNode
|
||||
from core.gui.graph.node import CanvasNode, ShadowNode
|
||||
|
||||
TEXT_DISTANCE: int = 60
|
||||
EDGE_WIDTH: int = 3
|
||||
|
@ -82,89 +78,6 @@ def arc_edges(edges) -> None:
|
|||
edge.redraw()
|
||||
|
||||
|
||||
class ShadowNode:
|
||||
def __init__(
|
||||
self, app: "Application", canvas: "CanvasGraph", node: "CanvasNode"
|
||||
) -> None:
|
||||
self.app: "Application" = app
|
||||
self.canvas: "CanvasGraph" = canvas
|
||||
self.node: "CanvasNode" = node
|
||||
self.id: Optional[int] = None
|
||||
self.text_id: Optional[int] = None
|
||||
self.image: PhotoImage = self.app.get_icon(ImageEnum.SHADOW, ICON_SIZE)
|
||||
self.draw()
|
||||
self.setup_bindings()
|
||||
|
||||
def setup_bindings(self) -> None:
|
||||
self.canvas.tag_bind(self.id, "<Double-Button-1>", self.node.double_click)
|
||||
self.canvas.tag_bind(self.id, "<Enter>", self.node.on_enter)
|
||||
self.canvas.tag_bind(self.id, "<Leave>", self.node.on_leave)
|
||||
self.canvas.tag_bind(self.id, "<ButtonRelease-3>", self.node.show_context)
|
||||
self.canvas.tag_bind(self.id, "<Button-1>", self.node.show_info)
|
||||
|
||||
def draw(self) -> None:
|
||||
x, y = self.node.position()
|
||||
self.id: int = self.canvas.create_image(
|
||||
x, y, anchor=tk.CENTER, image=self.image, tags=tags.NODE
|
||||
)
|
||||
self.text_id = self.canvas.create_text(
|
||||
x,
|
||||
y + 20,
|
||||
text=f"{self.node.get_label()} [{self.node.canvas.id}]",
|
||||
tags=tags.NODE_LABEL,
|
||||
font=self.app.icon_text_font,
|
||||
fill="#0000CD",
|
||||
state=self.app.manager.show_node_labels.state(),
|
||||
justify=tk.CENTER,
|
||||
)
|
||||
self.canvas.shadow_nodes[self.id] = self
|
||||
self.canvas.shadow_core_nodes[self.node.core_node.id] = self
|
||||
|
||||
def position(self) -> Tuple[int, int]:
|
||||
return self.canvas.coords(self.id)
|
||||
|
||||
def should_delete(self) -> bool:
|
||||
for edge in self.node.edges:
|
||||
other_node = edge.other_node(self.node)
|
||||
if not other_node.is_wireless() and other_node.canvas == self.canvas:
|
||||
return False
|
||||
return True
|
||||
|
||||
def motion(self, x_offset, y_offset) -> None:
|
||||
original_position = self.position()
|
||||
self.canvas.move(self.id, x_offset, y_offset)
|
||||
|
||||
# check new position
|
||||
bbox = self.canvas.bbox(self.id)
|
||||
if not self.canvas.valid_position(*bbox):
|
||||
self.canvas.coords(self.id, original_position)
|
||||
return
|
||||
|
||||
# move text and selection box
|
||||
self.canvas.move(self.text_id, x_offset, y_offset)
|
||||
self.canvas.move_selection(self.id, x_offset, y_offset)
|
||||
|
||||
# move edges
|
||||
for edge in self.node.edges:
|
||||
edge.move_shadow(self)
|
||||
for edge in self.node.wireless_edges:
|
||||
edge.move_shadow(self)
|
||||
|
||||
def delete(self):
|
||||
self.canvas.shadow_nodes.pop(self.id, None)
|
||||
self.canvas.shadow_core_nodes.pop(self.node.core_node.id, None)
|
||||
self.canvas.delete(self.id)
|
||||
self.canvas.delete(self.text_id)
|
||||
|
||||
def hide(self) -> None:
|
||||
self.canvas.itemconfig(self.id, state=tk.HIDDEN)
|
||||
self.canvas.itemconfig(self.text_id, state=tk.HIDDEN)
|
||||
|
||||
def show(self) -> None:
|
||||
self.canvas.itemconfig(self.id, state=tk.NORMAL)
|
||||
self.canvas.itemconfig(self.text_id, state=tk.NORMAL)
|
||||
|
||||
|
||||
class Edge:
|
||||
tag: str = tags.EDGE
|
||||
|
||||
|
|
|
@ -11,9 +11,9 @@ from core.api.grpc.wrappers import Interface, Link
|
|||
from core.gui import appconfig
|
||||
from core.gui.dialogs.shapemod import ShapeDialog
|
||||
from core.gui.graph import tags
|
||||
from core.gui.graph.edges import EDGE_WIDTH, CanvasEdge, ShadowNode
|
||||
from core.gui.graph.edges import EDGE_WIDTH, CanvasEdge
|
||||
from core.gui.graph.enums import GraphMode, ScaleOption
|
||||
from core.gui.graph.node import CanvasNode
|
||||
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
|
||||
|
|
|
@ -2,7 +2,7 @@ import functools
|
|||
import logging
|
||||
import tkinter as tk
|
||||
from pathlib import Path
|
||||
from typing import TYPE_CHECKING, Dict, List, Set, Tuple
|
||||
from typing import TYPE_CHECKING, Dict, List, Optional, Set, Tuple
|
||||
|
||||
import grpc
|
||||
from PIL.ImageTk import PhotoImage
|
||||
|
@ -21,7 +21,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, NodeUtils
|
||||
from core.gui.nodeutils import ANTENNA_SIZE, ICON_SIZE, NodeUtils
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from core.gui.app import Application
|
||||
|
@ -461,3 +461,86 @@ class CanvasNode:
|
|||
|
||||
def validate_service(self, service: str) -> None:
|
||||
self._service_action(service, ServiceAction.VALIDATE)
|
||||
|
||||
|
||||
class ShadowNode:
|
||||
def __init__(
|
||||
self, app: "Application", canvas: "CanvasGraph", node: "CanvasNode"
|
||||
) -> None:
|
||||
self.app: "Application" = app
|
||||
self.canvas: "CanvasGraph" = canvas
|
||||
self.node: "CanvasNode" = node
|
||||
self.id: Optional[int] = None
|
||||
self.text_id: Optional[int] = None
|
||||
self.image: PhotoImage = self.app.get_icon(ImageEnum.SHADOW, ICON_SIZE)
|
||||
self.draw()
|
||||
self.setup_bindings()
|
||||
|
||||
def setup_bindings(self) -> None:
|
||||
self.canvas.tag_bind(self.id, "<Double-Button-1>", self.node.double_click)
|
||||
self.canvas.tag_bind(self.id, "<Enter>", self.node.on_enter)
|
||||
self.canvas.tag_bind(self.id, "<Leave>", self.node.on_leave)
|
||||
self.canvas.tag_bind(self.id, "<ButtonRelease-3>", self.node.show_context)
|
||||
self.canvas.tag_bind(self.id, "<Button-1>", self.node.show_info)
|
||||
|
||||
def draw(self) -> None:
|
||||
x, y = self.node.position()
|
||||
self.id: int = self.canvas.create_image(
|
||||
x, y, anchor=tk.CENTER, image=self.image, tags=tags.NODE
|
||||
)
|
||||
self.text_id = self.canvas.create_text(
|
||||
x,
|
||||
y + 20,
|
||||
text=f"{self.node.get_label()} [{self.node.canvas.id}]",
|
||||
tags=tags.NODE_LABEL,
|
||||
font=self.app.icon_text_font,
|
||||
fill="#0000CD",
|
||||
state=self.app.manager.show_node_labels.state(),
|
||||
justify=tk.CENTER,
|
||||
)
|
||||
self.canvas.shadow_nodes[self.id] = self
|
||||
self.canvas.shadow_core_nodes[self.node.core_node.id] = self
|
||||
|
||||
def position(self) -> Tuple[int, int]:
|
||||
return self.canvas.coords(self.id)
|
||||
|
||||
def should_delete(self) -> bool:
|
||||
for edge in self.node.edges:
|
||||
other_node = edge.other_node(self.node)
|
||||
if not other_node.is_wireless() and other_node.canvas == self.canvas:
|
||||
return False
|
||||
return True
|
||||
|
||||
def motion(self, x_offset, y_offset) -> None:
|
||||
original_position = self.position()
|
||||
self.canvas.move(self.id, x_offset, y_offset)
|
||||
|
||||
# check new position
|
||||
bbox = self.canvas.bbox(self.id)
|
||||
if not self.canvas.valid_position(*bbox):
|
||||
self.canvas.coords(self.id, original_position)
|
||||
return
|
||||
|
||||
# move text and selection box
|
||||
self.canvas.move(self.text_id, x_offset, y_offset)
|
||||
self.canvas.move_selection(self.id, x_offset, y_offset)
|
||||
|
||||
# move edges
|
||||
for edge in self.node.edges:
|
||||
edge.move_shadow(self)
|
||||
for edge in self.node.wireless_edges:
|
||||
edge.move_shadow(self)
|
||||
|
||||
def delete(self):
|
||||
self.canvas.shadow_nodes.pop(self.id, None)
|
||||
self.canvas.shadow_core_nodes.pop(self.node.core_node.id, None)
|
||||
self.canvas.delete(self.id)
|
||||
self.canvas.delete(self.text_id)
|
||||
|
||||
def hide(self) -> None:
|
||||
self.canvas.itemconfig(self.id, state=tk.HIDDEN)
|
||||
self.canvas.itemconfig(self.text_id, state=tk.HIDDEN)
|
||||
|
||||
def show(self) -> None:
|
||||
self.canvas.itemconfig(self.id, state=tk.NORMAL)
|
||||
self.canvas.itemconfig(self.text_id, state=tk.NORMAL)
|
||||
|
|
Loading…
Reference in a new issue