2019-12-17 19:47:05 +00:00
|
|
|
import logging
|
2020-04-14 18:47:42 +01:00
|
|
|
import math
|
2019-12-05 19:12:25 +00:00
|
|
|
import tkinter as tk
|
2020-06-20 07:24:07 +01:00
|
|
|
from typing import TYPE_CHECKING, Optional, Tuple
|
2019-12-05 19:12:25 +00:00
|
|
|
|
2020-04-14 18:47:42 +01:00
|
|
|
from core.api.grpc import core_pb2
|
2020-06-20 07:24:07 +01:00
|
|
|
from core.api.grpc.core_pb2 import Interface, Link
|
2019-12-19 17:30:21 +00:00
|
|
|
from core.gui import themes
|
2019-12-19 17:50:58 +00:00
|
|
|
from core.gui.dialogs.linkconfig import LinkConfigurationDialog
|
2019-12-19 17:30:21 +00:00
|
|
|
from core.gui.graph import tags
|
2020-04-14 18:47:42 +01:00
|
|
|
from core.gui.nodeutils import NodeUtils
|
2019-12-06 00:37:48 +00:00
|
|
|
|
2020-01-14 19:06:52 +00:00
|
|
|
if TYPE_CHECKING:
|
|
|
|
from core.gui.graph.graph import CanvasGraph
|
|
|
|
|
2020-06-20 07:24:07 +01:00
|
|
|
TEXT_DISTANCE: float = 0.30
|
|
|
|
EDGE_WIDTH: int = 3
|
|
|
|
EDGE_COLOR: str = "#ff0000"
|
|
|
|
WIRELESS_WIDTH: float = 1.5
|
|
|
|
WIRELESS_COLOR: str = "#009933"
|
|
|
|
ARC_DISTANCE: int = 50
|
2019-12-19 00:51:05 +00:00
|
|
|
|
2019-12-05 19:12:25 +00:00
|
|
|
|
2020-04-14 23:51:28 +01:00
|
|
|
def create_edge_token(src: int, dst: int, network: int = None) -> Tuple[int, ...]:
|
|
|
|
values = [src, dst]
|
|
|
|
if network is not None:
|
|
|
|
values.append(network)
|
|
|
|
return tuple(sorted(values))
|
|
|
|
|
|
|
|
|
|
|
|
def arc_edges(edges) -> None:
|
|
|
|
if not edges:
|
|
|
|
return
|
|
|
|
mid_index = len(edges) // 2
|
|
|
|
if mid_index == 0:
|
|
|
|
arc_step = ARC_DISTANCE
|
|
|
|
else:
|
|
|
|
arc_step = ARC_DISTANCE / mid_index
|
|
|
|
# below edges
|
|
|
|
arc = 0
|
|
|
|
for edge in edges[:mid_index]:
|
|
|
|
arc -= arc_step
|
|
|
|
edge.arc = arc
|
|
|
|
edge.redraw()
|
|
|
|
# mid edge
|
|
|
|
if len(edges) % 2 != 0:
|
|
|
|
arc = 0
|
|
|
|
edge = edges[mid_index]
|
|
|
|
edge.arc = arc
|
|
|
|
edge.redraw()
|
|
|
|
mid_index += 1
|
|
|
|
# above edges
|
|
|
|
arc = 0
|
|
|
|
for edge in edges[mid_index:]:
|
|
|
|
arc += arc_step
|
|
|
|
edge.arc = arc
|
|
|
|
edge.redraw()
|
2020-04-14 18:47:42 +01:00
|
|
|
|
|
|
|
|
2020-06-24 06:53:48 +01:00
|
|
|
def bandwidth_label(bandwidth: int) -> str:
|
|
|
|
size = {0: "bps", 1: "Kbps", 2: "Mbps", 3: "Gbps"}
|
|
|
|
unit = 1000
|
|
|
|
i = 0
|
|
|
|
while bandwidth > unit:
|
|
|
|
bandwidth /= unit
|
|
|
|
i += 1
|
|
|
|
if i == 3:
|
|
|
|
break
|
|
|
|
return f"{bandwidth} {size[i]}"
|
|
|
|
|
|
|
|
|
2020-04-14 18:47:42 +01:00
|
|
|
class Edge:
|
2020-06-20 07:24:07 +01:00
|
|
|
tag: str = tags.EDGE
|
2020-04-14 18:47:42 +01:00
|
|
|
|
|
|
|
def __init__(self, canvas: "CanvasGraph", src: int, dst: int = None) -> None:
|
|
|
|
self.canvas = canvas
|
2020-06-20 07:24:07 +01:00
|
|
|
self.id: Optional[int] = None
|
|
|
|
self.src: int = src
|
|
|
|
self.dst: int = dst
|
|
|
|
self.arc: int = 0
|
|
|
|
self.token: Optional[Tuple[int, ...]] = None
|
|
|
|
self.src_label: Optional[int] = None
|
|
|
|
self.middle_label: Optional[int] = None
|
|
|
|
self.dst_label: Optional[int] = None
|
|
|
|
self.color: str = EDGE_COLOR
|
|
|
|
self.width: int = EDGE_WIDTH
|
2020-04-14 18:47:42 +01:00
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def create_token(cls, src: int, dst: int) -> Tuple[int, ...]:
|
|
|
|
return tuple(sorted([src, dst]))
|
|
|
|
|
2020-04-15 20:41:09 +01:00
|
|
|
def scaled_width(self) -> float:
|
|
|
|
return self.width * self.canvas.app.app_scale
|
|
|
|
|
2020-04-14 23:51:28 +01:00
|
|
|
def _get_arcpoint(
|
2020-04-14 18:47:42 +01:00
|
|
|
self, src_pos: Tuple[float, float], dst_pos: Tuple[float, float]
|
|
|
|
) -> Tuple[float, float]:
|
|
|
|
src_x, src_y = src_pos
|
|
|
|
dst_x, dst_y = dst_pos
|
2020-04-14 23:51:28 +01:00
|
|
|
mp_x = (src_x + dst_x) / 2
|
|
|
|
mp_y = (src_y + dst_y) / 2
|
|
|
|
slope_denominator = src_x - dst_x
|
|
|
|
slope_numerator = src_y - dst_y
|
|
|
|
# vertical line
|
|
|
|
if slope_denominator == 0:
|
|
|
|
return mp_x + self.arc, mp_y
|
|
|
|
# horizontal line
|
|
|
|
if slope_numerator == 0:
|
|
|
|
return mp_x, mp_y + self.arc
|
|
|
|
# everything else
|
|
|
|
m = slope_numerator / slope_denominator
|
|
|
|
perp_m = -1 / m
|
|
|
|
b = mp_y - (perp_m * mp_x)
|
|
|
|
# get arc x and y
|
|
|
|
offset = math.sqrt(self.arc ** 2 / (1 + (1 / m ** 2)))
|
|
|
|
arc_x = mp_x
|
|
|
|
if self.arc >= 0:
|
|
|
|
arc_x += offset
|
|
|
|
else:
|
|
|
|
arc_x -= offset
|
|
|
|
arc_y = (perp_m * arc_x) + b
|
|
|
|
return arc_x, arc_y
|
2020-04-14 18:47:42 +01:00
|
|
|
|
|
|
|
def draw(self, src_pos: Tuple[float, float], dst_pos: Tuple[float, float]) -> None:
|
2020-04-14 23:51:28 +01:00
|
|
|
arc_pos = self._get_arcpoint(src_pos, dst_pos)
|
2019-12-05 19:12:25 +00:00
|
|
|
self.id = self.canvas.create_line(
|
2020-04-14 18:47:42 +01:00
|
|
|
*src_pos,
|
2020-04-14 23:51:28 +01:00
|
|
|
*arc_pos,
|
2020-04-14 18:47:42 +01:00
|
|
|
*dst_pos,
|
|
|
|
smooth=True,
|
|
|
|
tags=self.tag,
|
2020-04-15 20:41:09 +01:00
|
|
|
width=self.scaled_width(),
|
2020-04-14 18:47:42 +01:00
|
|
|
fill=self.color,
|
2019-12-05 19:12:25 +00:00
|
|
|
)
|
|
|
|
|
2020-06-20 07:24:07 +01:00
|
|
|
def redraw(self) -> None:
|
2020-04-15 20:41:09 +01:00
|
|
|
self.canvas.itemconfig(self.id, width=self.scaled_width(), fill=self.color)
|
2020-04-14 23:51:28 +01:00
|
|
|
src_x, src_y, _, _, _, _ = self.canvas.coords(self.id)
|
2020-04-15 20:51:35 +01:00
|
|
|
src_pos = src_x, src_y
|
|
|
|
self.move_src(src_pos)
|
2020-04-14 23:51:28 +01:00
|
|
|
|
2020-04-15 20:41:09 +01:00
|
|
|
def middle_label_pos(self) -> Tuple[float, float]:
|
|
|
|
_, _, x, y, _, _ = self.canvas.coords(self.id)
|
|
|
|
return x, y
|
|
|
|
|
|
|
|
def middle_label_text(self, text: str) -> None:
|
|
|
|
if self.middle_label is None:
|
|
|
|
x, y = self.middle_label_pos()
|
|
|
|
self.middle_label = self.canvas.create_text(
|
2020-04-19 23:47:07 +01:00
|
|
|
x,
|
|
|
|
y,
|
|
|
|
font=self.canvas.app.edge_font,
|
|
|
|
text=text,
|
|
|
|
tags=tags.LINK_LABEL,
|
2020-06-24 06:53:48 +01:00
|
|
|
justify=tk.CENTER,
|
2020-04-19 23:47:07 +01:00
|
|
|
state=self.canvas.show_link_labels.state(),
|
2020-04-15 20:41:09 +01:00
|
|
|
)
|
|
|
|
else:
|
|
|
|
self.canvas.itemconfig(self.middle_label, text=text)
|
|
|
|
|
2020-06-23 22:48:27 +01:00
|
|
|
def clear_middle_label(self) -> None:
|
|
|
|
self.canvas.delete(self.middle_label)
|
|
|
|
self.middle_label = None
|
|
|
|
|
2020-04-15 21:39:11 +01:00
|
|
|
def node_label_positions(self) -> Tuple[Tuple[float, float], Tuple[float, float]]:
|
|
|
|
src_x, src_y, _, _, dst_x, dst_y = self.canvas.coords(self.id)
|
|
|
|
v1 = dst_x - src_x
|
|
|
|
v2 = dst_y - src_y
|
|
|
|
ux = TEXT_DISTANCE * v1
|
|
|
|
uy = TEXT_DISTANCE * v2
|
|
|
|
src_x = src_x + ux
|
|
|
|
src_y = src_y + uy
|
|
|
|
dst_x = dst_x - ux
|
|
|
|
dst_y = dst_y - uy
|
|
|
|
return (src_x, src_y), (dst_x, dst_y)
|
|
|
|
|
|
|
|
def src_label_text(self, text: str) -> None:
|
|
|
|
if self.src_label is None:
|
|
|
|
src_pos, _ = self.node_label_positions()
|
|
|
|
self.src_label = self.canvas.create_text(
|
|
|
|
*src_pos,
|
|
|
|
text=text,
|
|
|
|
justify=tk.CENTER,
|
|
|
|
font=self.canvas.app.edge_font,
|
2020-04-19 23:47:07 +01:00
|
|
|
tags=tags.LINK_LABEL,
|
|
|
|
state=self.canvas.show_link_labels.state(),
|
2020-04-15 21:39:11 +01:00
|
|
|
)
|
|
|
|
else:
|
|
|
|
self.canvas.itemconfig(self.src_label, text=text)
|
|
|
|
|
|
|
|
def dst_label_text(self, text: str) -> None:
|
|
|
|
if self.dst_label is None:
|
|
|
|
_, dst_pos = self.node_label_positions()
|
|
|
|
self.dst_label = self.canvas.create_text(
|
|
|
|
*dst_pos,
|
|
|
|
text=text,
|
|
|
|
justify=tk.CENTER,
|
|
|
|
font=self.canvas.app.edge_font,
|
2020-04-19 23:47:07 +01:00
|
|
|
tags=tags.LINK_LABEL,
|
|
|
|
state=self.canvas.show_link_labels.state(),
|
2020-04-15 21:39:11 +01:00
|
|
|
)
|
|
|
|
else:
|
|
|
|
self.canvas.itemconfig(self.dst_label, text=text)
|
|
|
|
|
2020-04-15 20:51:35 +01:00
|
|
|
def move_node(self, node_id: int, pos: Tuple[float, float]) -> None:
|
2020-04-14 18:47:42 +01:00
|
|
|
if self.src == node_id:
|
2020-04-15 20:51:35 +01:00
|
|
|
self.move_src(pos)
|
2020-04-14 18:47:42 +01:00
|
|
|
else:
|
2020-04-15 20:51:35 +01:00
|
|
|
self.move_dst(pos)
|
2020-04-14 18:47:42 +01:00
|
|
|
|
2020-04-15 20:51:35 +01:00
|
|
|
def move_dst(self, dst_pos: Tuple[float, float]) -> None:
|
2020-04-14 18:47:42 +01:00
|
|
|
src_x, src_y, _, _, _, _ = self.canvas.coords(self.id)
|
2020-04-15 20:51:35 +01:00
|
|
|
src_pos = src_x, src_y
|
2020-04-15 20:41:09 +01:00
|
|
|
self.moved(src_pos, dst_pos)
|
2020-04-14 18:47:42 +01:00
|
|
|
|
2020-04-15 20:51:35 +01:00
|
|
|
def move_src(self, src_pos: Tuple[float, float]) -> None:
|
2020-04-14 18:47:42 +01:00
|
|
|
_, _, _, _, dst_x, dst_y = self.canvas.coords(self.id)
|
2020-04-15 20:51:35 +01:00
|
|
|
dst_pos = dst_x, dst_y
|
2020-04-15 20:41:09 +01:00
|
|
|
self.moved(src_pos, dst_pos)
|
|
|
|
|
|
|
|
def moved(self, src_pos: Tuple[float, float], dst_pos: Tuple[float, float]) -> None:
|
2020-04-14 23:51:28 +01:00
|
|
|
arc_pos = self._get_arcpoint(src_pos, dst_pos)
|
|
|
|
self.canvas.coords(self.id, *src_pos, *arc_pos, *dst_pos)
|
2020-04-15 20:41:09 +01:00
|
|
|
if self.middle_label:
|
|
|
|
self.canvas.coords(self.middle_label, *arc_pos)
|
2020-04-15 21:39:11 +01:00
|
|
|
src_pos, dst_pos = self.node_label_positions()
|
|
|
|
if self.src_label:
|
|
|
|
self.canvas.coords(self.src_label, *src_pos)
|
|
|
|
if self.dst_label:
|
|
|
|
self.canvas.coords(self.dst_label, *dst_pos)
|
2020-04-14 18:47:42 +01:00
|
|
|
|
|
|
|
def delete(self) -> None:
|
2020-04-15 21:39:11 +01:00
|
|
|
logging.debug("deleting canvas edge, id: %s", self.id)
|
2019-12-05 19:12:25 +00:00
|
|
|
self.canvas.delete(self.id)
|
2020-04-15 21:39:11 +01:00
|
|
|
self.canvas.delete(self.src_label)
|
|
|
|
self.canvas.delete(self.dst_label)
|
2020-06-23 22:48:27 +01:00
|
|
|
self.clear_middle_label()
|
2020-04-15 21:39:11 +01:00
|
|
|
self.id = None
|
|
|
|
self.src_label = None
|
|
|
|
self.dst_label = None
|
2019-12-05 19:12:25 +00:00
|
|
|
|
|
|
|
|
2020-04-14 18:47:42 +01:00
|
|
|
class CanvasWirelessEdge(Edge):
|
|
|
|
tag = tags.WIRELESS_EDGE
|
|
|
|
|
|
|
|
def __init__(
|
|
|
|
self,
|
|
|
|
canvas: "CanvasGraph",
|
|
|
|
src: int,
|
|
|
|
dst: int,
|
|
|
|
src_pos: Tuple[float, float],
|
|
|
|
dst_pos: Tuple[float, float],
|
2020-06-20 07:24:07 +01:00
|
|
|
token: Tuple[int, ...],
|
2020-04-14 18:47:42 +01:00
|
|
|
) -> None:
|
|
|
|
logging.debug("drawing wireless link from node %s to node %s", src, dst)
|
|
|
|
super().__init__(canvas, src, dst)
|
2020-06-20 07:24:07 +01:00
|
|
|
self.token: Tuple[int, ...] = token
|
|
|
|
self.width: float = WIRELESS_WIDTH
|
|
|
|
self.color: str = WIRELESS_COLOR
|
2020-04-14 18:47:42 +01:00
|
|
|
self.draw(src_pos, dst_pos)
|
|
|
|
|
|
|
|
|
|
|
|
class CanvasEdge(Edge):
|
2019-12-05 19:12:25 +00:00
|
|
|
"""
|
|
|
|
Canvas edge class
|
|
|
|
"""
|
|
|
|
|
2020-01-14 19:06:52 +00:00
|
|
|
def __init__(
|
|
|
|
self,
|
|
|
|
canvas: "CanvasGraph",
|
2020-04-14 18:47:42 +01:00
|
|
|
src: int,
|
|
|
|
src_pos: Tuple[float, float],
|
|
|
|
dst_pos: Tuple[float, float],
|
|
|
|
) -> None:
|
2019-12-05 19:12:25 +00:00
|
|
|
"""
|
|
|
|
Create an instance of canvas edge object
|
|
|
|
"""
|
2020-04-14 18:47:42 +01:00
|
|
|
super().__init__(canvas, src)
|
2020-06-20 07:24:07 +01:00
|
|
|
self.src_iface: Optional[Interface] = None
|
|
|
|
self.dst_iface: Optional[Interface] = None
|
|
|
|
self.text_src: Optional[int] = None
|
|
|
|
self.text_dst: Optional[int] = None
|
|
|
|
self.link: Optional[Link] = None
|
|
|
|
self.asymmetric_link: Optional[Link] = None
|
|
|
|
self.throughput: Optional[float] = None
|
2020-04-14 18:47:42 +01:00
|
|
|
self.draw(src_pos, dst_pos)
|
2019-12-17 19:47:05 +00:00
|
|
|
self.set_binding()
|
2020-06-20 07:24:07 +01:00
|
|
|
self.context: tk.Menu = tk.Menu(self.canvas)
|
2020-05-02 16:41:10 +01:00
|
|
|
self.create_context()
|
|
|
|
|
2020-06-20 07:24:07 +01:00
|
|
|
def create_context(self) -> None:
|
2020-05-02 16:41:10 +01:00
|
|
|
themes.style_menu(self.context)
|
|
|
|
self.context.add_command(label="Configure", command=self.click_configure)
|
|
|
|
self.context.add_command(label="Delete", command=self.click_delete)
|
2019-12-17 19:47:05 +00:00
|
|
|
|
2020-04-14 18:47:42 +01:00
|
|
|
def set_binding(self) -> None:
|
2020-05-02 16:41:10 +01:00
|
|
|
self.canvas.tag_bind(self.id, "<ButtonRelease-3>", self.show_context)
|
2019-12-05 19:12:25 +00:00
|
|
|
|
2020-06-20 07:24:07 +01:00
|
|
|
def set_link(self, link: Link) -> None:
|
2019-12-19 00:51:05 +00:00
|
|
|
self.link = link
|
|
|
|
self.draw_labels()
|
|
|
|
|
2020-06-16 17:30:16 +01:00
|
|
|
def iface_label(self, iface: core_pb2.Interface) -> str:
|
2020-04-19 23:47:07 +01:00
|
|
|
label = ""
|
2020-06-16 17:30:16 +01:00
|
|
|
if iface.name and self.canvas.show_iface_names.get():
|
|
|
|
label = f"{iface.name}"
|
|
|
|
if iface.ip4 and self.canvas.show_ip4s.get():
|
2020-04-19 23:47:07 +01:00
|
|
|
label = f"{label}\n" if label else ""
|
2020-06-17 06:05:36 +01:00
|
|
|
label += f"{iface.ip4}/{iface.ip4_mask}"
|
2020-06-16 17:30:16 +01:00
|
|
|
if iface.ip6 and self.canvas.show_ip6s.get():
|
2020-04-19 23:47:07 +01:00
|
|
|
label = f"{label}\n" if label else ""
|
2020-06-17 06:05:36 +01:00
|
|
|
label += f"{iface.ip6}/{iface.ip6_mask}"
|
2020-04-19 23:47:07 +01:00
|
|
|
return label
|
|
|
|
|
2020-04-15 21:39:11 +01:00
|
|
|
def create_node_labels(self) -> Tuple[str, str]:
|
2020-06-13 00:52:41 +01:00
|
|
|
label1 = None
|
2020-06-16 17:30:16 +01:00
|
|
|
if self.link.HasField("iface1"):
|
|
|
|
label1 = self.iface_label(self.link.iface1)
|
2020-06-13 00:52:41 +01:00
|
|
|
label2 = None
|
2020-06-16 17:30:16 +01:00
|
|
|
if self.link.HasField("iface2"):
|
|
|
|
label2 = self.iface_label(self.link.iface2)
|
2020-06-13 00:52:41 +01:00
|
|
|
return label1, label2
|
2020-03-04 19:38:24 +00:00
|
|
|
|
2020-04-14 18:47:42 +01:00
|
|
|
def draw_labels(self) -> None:
|
2020-04-15 21:39:11 +01:00
|
|
|
src_text, dst_text = self.create_node_labels()
|
|
|
|
self.src_label_text(src_text)
|
|
|
|
self.dst_label_text(dst_text)
|
2020-06-24 06:53:48 +01:00
|
|
|
self.draw_link_options()
|
2019-12-19 00:51:05 +00:00
|
|
|
|
2020-04-14 18:47:42 +01:00
|
|
|
def redraw(self) -> None:
|
2020-04-14 23:51:28 +01:00
|
|
|
super().redraw()
|
2020-04-15 21:39:11 +01:00
|
|
|
self.draw_labels()
|
2019-12-27 08:32:10 +00:00
|
|
|
|
2020-04-14 18:47:42 +01:00
|
|
|
def set_throughput(self, throughput: float) -> None:
|
2019-12-27 08:32:10 +00:00
|
|
|
throughput = 0.001 * throughput
|
2020-04-15 20:41:09 +01:00
|
|
|
text = f"{throughput:.3f} kbps"
|
|
|
|
self.middle_label_text(text)
|
2019-12-27 08:32:10 +00:00
|
|
|
if throughput > self.canvas.throughput_threshold:
|
|
|
|
color = self.canvas.throughput_color
|
|
|
|
width = self.canvas.throughput_width
|
|
|
|
else:
|
2020-04-15 20:41:09 +01:00
|
|
|
color = self.color
|
|
|
|
width = self.scaled_width()
|
2019-12-27 08:32:10 +00:00
|
|
|
self.canvas.itemconfig(self.id, fill=color, width=width)
|
2019-12-19 00:51:05 +00:00
|
|
|
|
2020-04-14 18:47:42 +01:00
|
|
|
def complete(self, dst: int) -> None:
|
2019-12-05 19:12:25 +00:00
|
|
|
self.dst = dst
|
2020-04-14 18:47:42 +01:00
|
|
|
self.token = create_edge_token(self.src, self.dst)
|
2020-04-15 20:51:35 +01:00
|
|
|
dst_pos = self.canvas.coords(self.dst)
|
|
|
|
self.move_dst(dst_pos)
|
2019-12-06 00:37:48 +00:00
|
|
|
self.check_wireless()
|
2020-01-30 00:08:36 +00:00
|
|
|
logging.debug("Draw wired link from node %s to node %s", self.src, dst)
|
2019-12-05 19:12:25 +00:00
|
|
|
|
2020-04-14 18:47:42 +01:00
|
|
|
def is_wireless(self) -> bool:
|
2019-12-06 00:37:48 +00:00
|
|
|
src_node = self.canvas.nodes[self.src]
|
|
|
|
dst_node = self.canvas.nodes[self.dst]
|
|
|
|
src_node_type = src_node.core_node.type
|
|
|
|
dst_node_type = dst_node.core_node.type
|
|
|
|
is_src_wireless = NodeUtils.is_wireless_node(src_node_type)
|
|
|
|
is_dst_wireless = NodeUtils.is_wireless_node(dst_node_type)
|
2020-02-18 23:58:18 +00:00
|
|
|
|
|
|
|
# update the wlan/EMANE network
|
|
|
|
wlan_network = self.canvas.wireless_network
|
|
|
|
if is_src_wireless and not is_dst_wireless:
|
|
|
|
if self.src not in wlan_network:
|
|
|
|
wlan_network[self.src] = set()
|
|
|
|
wlan_network[self.src].add(self.dst)
|
|
|
|
elif not is_src_wireless and is_dst_wireless:
|
|
|
|
if self.dst not in wlan_network:
|
|
|
|
wlan_network[self.dst] = set()
|
|
|
|
wlan_network[self.dst].add(self.src)
|
2019-12-27 08:32:10 +00:00
|
|
|
return is_src_wireless or is_dst_wireless
|
|
|
|
|
2020-04-14 18:47:42 +01:00
|
|
|
def check_wireless(self) -> None:
|
2019-12-27 08:32:10 +00:00
|
|
|
if self.is_wireless():
|
2019-12-06 00:37:48 +00:00
|
|
|
self.canvas.itemconfig(self.id, state=tk.HIDDEN)
|
|
|
|
self._check_antenna()
|
|
|
|
|
2020-04-14 18:47:42 +01:00
|
|
|
def _check_antenna(self) -> None:
|
2019-12-06 00:37:48 +00:00
|
|
|
src_node = self.canvas.nodes[self.src]
|
|
|
|
dst_node = self.canvas.nodes[self.dst]
|
|
|
|
src_node_type = src_node.core_node.type
|
|
|
|
dst_node_type = dst_node.core_node.type
|
|
|
|
is_src_wireless = NodeUtils.is_wireless_node(src_node_type)
|
|
|
|
is_dst_wireless = NodeUtils.is_wireless_node(dst_node_type)
|
|
|
|
if is_src_wireless or is_dst_wireless:
|
|
|
|
if is_src_wireless and not is_dst_wireless:
|
|
|
|
dst_node.add_antenna()
|
|
|
|
elif not is_src_wireless and is_dst_wireless:
|
|
|
|
src_node.add_antenna()
|
|
|
|
else:
|
|
|
|
src_node.add_antenna()
|
|
|
|
|
2020-04-14 18:47:42 +01:00
|
|
|
def reset(self) -> None:
|
2020-04-15 20:41:09 +01:00
|
|
|
self.canvas.delete(self.middle_label)
|
|
|
|
self.middle_label = None
|
|
|
|
self.canvas.itemconfig(self.id, fill=self.color, width=self.scaled_width())
|
2019-12-17 19:47:05 +00:00
|
|
|
|
2020-05-02 16:41:10 +01:00
|
|
|
def show_context(self, event: tk.Event) -> None:
|
|
|
|
state = tk.DISABLED if self.canvas.core.is_runtime() else tk.NORMAL
|
|
|
|
self.context.entryconfigure(1, state=state)
|
|
|
|
self.context.tk_popup(event.x_root, event.y_root)
|
2019-12-17 19:47:05 +00:00
|
|
|
|
2020-06-20 07:24:07 +01:00
|
|
|
def click_delete(self) -> None:
|
2020-05-02 07:47:37 +01:00
|
|
|
self.canvas.delete_edge(self)
|
|
|
|
|
2020-05-02 16:41:10 +01:00
|
|
|
def click_configure(self) -> None:
|
2020-05-05 06:50:59 +01:00
|
|
|
dialog = LinkConfigurationDialog(self.canvas.app, self)
|
2019-12-17 19:47:05 +00:00
|
|
|
dialog.show()
|
2020-06-24 06:53:48 +01:00
|
|
|
|
|
|
|
def draw_link_options(self):
|
|
|
|
options = self.link.options
|
|
|
|
lines = []
|
|
|
|
bandwidth = options.bandwidth
|
|
|
|
if bandwidth > 0:
|
|
|
|
lines.append(bandwidth_label(bandwidth))
|
|
|
|
delay = options.delay
|
|
|
|
jitter = options.jitter
|
|
|
|
if delay > 0 and jitter > 0:
|
|
|
|
lines.append(f"{delay} us (\u00B1{jitter} us)")
|
|
|
|
elif jitter > 0:
|
|
|
|
lines.append(f"0 us (\u00B1{jitter} us)")
|
|
|
|
loss = options.loss
|
|
|
|
if loss > 0:
|
|
|
|
lines.append(f"loss={loss}%")
|
|
|
|
dup = options.dup
|
|
|
|
if dup > 0:
|
|
|
|
lines.append(f"dup={dup}%")
|
|
|
|
label = "\n".join(lines)
|
|
|
|
self.middle_label_text(label)
|