load shapes from xml
This commit is contained in:
commit
a44fc0b6f9
17 changed files with 296 additions and 331 deletions
|
@ -5,12 +5,12 @@ from tkinter import ttk
|
|||
|
||||
from coretk import appconfig, themes
|
||||
from coretk.coreclient import CoreClient
|
||||
from coretk.graph import CanvasGraph
|
||||
from coretk.graph.graph import CanvasGraph
|
||||
from coretk.images import ImageEnum, Images
|
||||
from coretk.menuaction import MenuAction
|
||||
from coretk.menubar import Menubar
|
||||
from coretk.nodeutils import NodeUtils
|
||||
from coretk.status import StatusBar
|
||||
from coretk.statusbar import StatusBar
|
||||
from coretk.toolbar import Toolbar
|
||||
|
||||
|
||||
|
|
|
@ -10,9 +10,23 @@ from core.api.grpc import client, core_pb2
|
|||
from coretk import appconfig
|
||||
from coretk.dialogs.mobilityplayer import MobilityPlayer
|
||||
from coretk.dialogs.sessions import SessionsDialog
|
||||
from coretk.graph.shape import Shape, ShapeData
|
||||
from coretk.interface import InterfaceManager
|
||||
from coretk.nodeutils import NodeDraw, NodeUtils
|
||||
from coretk.shape import ShapeData
|
||||
|
||||
LIFT_ORDER = [
|
||||
"wallpaper",
|
||||
"shape",
|
||||
"gridline",
|
||||
"shapetext",
|
||||
"text",
|
||||
"edge",
|
||||
"antenna",
|
||||
"nodename",
|
||||
"linkinfo",
|
||||
"node",
|
||||
]
|
||||
|
||||
|
||||
OBSERVERS = {
|
||||
"processes": "ps",
|
||||
|
@ -282,48 +296,7 @@ class CoreClient:
|
|||
return self.state == core_pb2.SessionState.RUNTIME
|
||||
|
||||
def parse_metadata(self, config):
|
||||
# for key, value in config.items():
|
||||
# if "global_options" != key:
|
||||
# canvas_config = parsedata.parse(value)
|
||||
# print(canvas_config)
|
||||
# if canvas_config.get("type"):
|
||||
# config_type = canvas_config["type"]
|
||||
# if config_type == "rectangle" or config_type == "oval":
|
||||
# data = ShapeData(
|
||||
# False,
|
||||
# canvas_config["label"],
|
||||
# canvas_config["fontfamily"],
|
||||
# canvas_config["fontsize"],
|
||||
# canvas_config["labelcolor"],
|
||||
# canvas_config["color"],
|
||||
# canvas_config["border"],
|
||||
# canvas_config["width"],
|
||||
# )
|
||||
# coords = tuple(
|
||||
# [float(x) for x in canvas_config["iconcoords"].split()]
|
||||
# )
|
||||
# shape = Shape(
|
||||
# self.app,
|
||||
# self.app.canvas,
|
||||
# None,
|
||||
# None,
|
||||
# coords,
|
||||
# data,
|
||||
# config_type,
|
||||
# )
|
||||
# self.app.canvas.shapes[shape.id] = shape
|
||||
# elif canvas_config["type"] == "text":
|
||||
# print("not implemented")
|
||||
# else:
|
||||
# if "wallpaper" in canvas_config:
|
||||
# logging.info("canvas metadata: %s", canvas_config)
|
||||
# wallpaper_style = canvas_config["wallpaper-style"]
|
||||
# self.app.canvas.scale_option.set(wallpaper_style)
|
||||
# wallpaper = canvas_config["wallpaper"]
|
||||
# wallpaper = str(appconfig.BACKGROUNDS_PATH.joinpath(wallpaper))
|
||||
# self.app.canvas.set_wallpaper(wallpaper)
|
||||
# canvas settings
|
||||
print(config)
|
||||
# canvas setting
|
||||
canvas_config = config.get("canvas")
|
||||
if canvas_config:
|
||||
logging.info("canvas metadata: %s", canvas_config)
|
||||
|
@ -350,7 +323,14 @@ class CoreClient:
|
|||
annotation_config["border"],
|
||||
annotation_config["width"],
|
||||
)
|
||||
print(data, coords)
|
||||
shape = Shape(
|
||||
self.app, self.app.canvas, None, None, coords, data, config_type
|
||||
)
|
||||
self.app.canvas.shapes[shape.id] = shape
|
||||
else:
|
||||
logging.debug("not implemented")
|
||||
for tag in LIFT_ORDER:
|
||||
self.app.canvas.tag_raise(tag)
|
||||
|
||||
def create_new_session(self):
|
||||
"""
|
||||
|
|
|
@ -267,7 +267,7 @@ router ospf6
|
|||
</session_options>
|
||||
<session_metadata>
|
||||
<configuration name="annotation a0" value='{"iconcoords": [612.0, 492.0], "type": "text", "label": "wireless network", "labelcolor": "black", "fontfamily": "Arial", "fontsize": 12, "effects": "bold", "canvas": "c1"}'/>
|
||||
<configuration name="annotation a1" value='{"iconcoords": [142.0, 112.0, 393.0, 291.0], "type": "rectangle", "label": "", "labelcolor": "black", "fontfamily": "Arial", "fontsize": 12, "color": "#ebebde", "width": 1, "border": "#ffffff", "rad": 25, "canvas": "c1"}'/>
|
||||
<configuration name="annotation a1" value='{"iconcoords": [142.0, 112.0, 393.0, 291.0], "type": "rectangle", "label": "circle", "labelcolor": "black", "fontfamily": "Arial", "fontsize": 12, "color": "#ebebde", "width": 1, "border": "#ffffff", "rad": 25, "canvas": "c1"}'/>
|
||||
<configuration name="annotation a2" value='{"iconcoords": [492.0, 384.0], "type": "text", "label": "gateway", "labelcolor": "black", "fontfamily": "Arial", "fontsize": 12, "effects": "bold", "canvas": "c1"}'/>
|
||||
<configuration name="canvas" value='{"name": "Canvas1", "wallpaper-style": 1, "wallpaper": "sample1-bg.gif"}'/>
|
||||
<configuration name="global_options" value='{"interface_names": false, "ip_addresses": true, "ipv6_addresses": false, "node_labels": true, "link_labels": true, "show_api": false, "background_images": false, "annotations": true, "grid": false, "traffic_start": false}'/>
|
||||
|
|
|
@ -147,7 +147,7 @@ class ShapeDialog(Dialog):
|
|||
shape_text = self.shape_text.get()
|
||||
size = int(self.font_size.get())
|
||||
x0, y0, x1, y1 = self.canvas.bbox(self.id)
|
||||
text_y = y0 + 2 * size
|
||||
text_y = y0 + 1.5 * size
|
||||
text_x = (x0 + x1) / 2
|
||||
f = [self.font.get(), size]
|
||||
if self.bold.get() == 1:
|
||||
|
|
0
coretk/coretk/graph/__init__.py
Normal file
0
coretk/coretk/graph/__init__.py
Normal file
70
coretk/coretk/graph/edges.py
Normal file
70
coretk/coretk/graph/edges.py
Normal file
|
@ -0,0 +1,70 @@
|
|||
import tkinter as tk
|
||||
|
||||
|
||||
class CanvasWirelessEdge:
|
||||
def __init__(self, token, position, src, dst, canvas):
|
||||
self.token = token
|
||||
self.src = src
|
||||
self.dst = dst
|
||||
self.canvas = canvas
|
||||
self.id = self.canvas.create_line(
|
||||
*position, tags="wireless", width=1.5, fill="#009933"
|
||||
)
|
||||
|
||||
def delete(self):
|
||||
self.canvas.delete(self.id)
|
||||
|
||||
|
||||
class CanvasEdge:
|
||||
"""
|
||||
Canvas edge class
|
||||
"""
|
||||
|
||||
width = 1.4
|
||||
|
||||
def __init__(self, x1, y1, x2, y2, src, canvas, is_wired=None):
|
||||
"""
|
||||
Create an instance of canvas edge object
|
||||
:param int x1: source x-coord
|
||||
:param int y1: source y-coord
|
||||
:param int x2: destination x-coord
|
||||
:param int y2: destination y-coord
|
||||
:param int src: source id
|
||||
:param tkinter.Canvas canvas: canvas object
|
||||
"""
|
||||
self.src = src
|
||||
self.dst = None
|
||||
self.src_interface = None
|
||||
self.dst_interface = None
|
||||
self.canvas = canvas
|
||||
if is_wired is None or is_wired is True:
|
||||
self.id = self.canvas.create_line(
|
||||
x1, y1, x2, y2, tags="edge", width=self.width, fill="#ff0000"
|
||||
)
|
||||
else:
|
||||
self.id = self.canvas.create_line(
|
||||
x1,
|
||||
y1,
|
||||
x2,
|
||||
y2,
|
||||
tags="edge",
|
||||
width=self.width,
|
||||
fill="#ff0000",
|
||||
state=tk.HIDDEN,
|
||||
)
|
||||
self.token = None
|
||||
self.link_info = None
|
||||
self.throughput = None
|
||||
self.wired = is_wired
|
||||
|
||||
def complete(self, dst, x, y):
|
||||
self.dst = dst
|
||||
self.token = tuple(sorted((self.src, self.dst)))
|
||||
x1, y1, _, _ = self.canvas.coords(self.id)
|
||||
self.canvas.coords(self.id, x1, y1, x, y)
|
||||
self.canvas.helper.draw_wireless_case(self.src, self.dst, self)
|
||||
self.canvas.tag_raise(self.src)
|
||||
self.canvas.tag_raise(self.dst)
|
||||
|
||||
def delete(self):
|
||||
self.canvas.delete(self.id)
|
23
coretk/coretk/graph/enums.py
Normal file
23
coretk/coretk/graph/enums.py
Normal file
|
@ -0,0 +1,23 @@
|
|||
import enum
|
||||
|
||||
|
||||
class GraphMode(enum.Enum):
|
||||
SELECT = 0
|
||||
EDGE = 1
|
||||
PICKNODE = 2
|
||||
NODE = 3
|
||||
ANNOTATION = 4
|
||||
OTHER = 5
|
||||
|
||||
|
||||
class ScaleOption(enum.Enum):
|
||||
NONE = 0
|
||||
UPPER_LEFT = 1
|
||||
CENTERED = 2
|
||||
SCALED = 3
|
||||
TILED = 4
|
||||
|
||||
|
||||
class ShapeType(enum.Enum):
|
||||
OVAL = 0
|
||||
RECTANGLE = 1
|
|
@ -1,51 +1,24 @@
|
|||
import enum
|
||||
import logging
|
||||
import tkinter as tk
|
||||
from tkinter import font
|
||||
|
||||
from PIL import Image, ImageTk
|
||||
|
||||
from core.api.grpc import core_pb2
|
||||
from core.api.grpc.core_pb2 import NodeType
|
||||
from coretk.canvastooltip import CanvasTooltip
|
||||
from coretk.dialogs.emaneconfig import EmaneConfigDialog
|
||||
from coretk.dialogs.mobilityconfig import MobilityConfigDialog
|
||||
from coretk.dialogs.nodeconfig import NodeConfigDialog
|
||||
from coretk.dialogs.shapemod import ShapeDialog
|
||||
from coretk.dialogs.wlanconfig import WlanConfigDialog
|
||||
from coretk.graph_helper import GraphHelper, WlanAntennaManager
|
||||
from coretk.graph.edges import CanvasEdge, CanvasWirelessEdge
|
||||
from coretk.graph.enums import GraphMode, ScaleOption
|
||||
from coretk.graph.graph_helper import GraphHelper
|
||||
from coretk.graph.linkinfo import LinkInfo, Throughput
|
||||
from coretk.graph.node import CanvasNode
|
||||
from coretk.graph.nodedelete import CanvasComponentManagement
|
||||
from coretk.graph.shape import Shape
|
||||
from coretk.images import ImageEnum, Images
|
||||
from coretk.linkinfo import LinkInfo, Throughput
|
||||
from coretk.nodedelete import CanvasComponentManagement
|
||||
from coretk.nodeutils import NodeUtils
|
||||
from coretk.shape import Shape
|
||||
|
||||
NODE_TEXT_OFFSET = 5
|
||||
ABOVE_WALLPAPER = ["edge", "linkinfo", "wireless", "antenna", "nodename", "node"]
|
||||
|
||||
|
||||
class GraphMode(enum.Enum):
|
||||
SELECT = 0
|
||||
EDGE = 1
|
||||
PICKNODE = 2
|
||||
NODE = 3
|
||||
ANNOTATION = 4
|
||||
OTHER = 5
|
||||
|
||||
|
||||
class ScaleOption(enum.Enum):
|
||||
NONE = 0
|
||||
UPPER_LEFT = 1
|
||||
CENTERED = 2
|
||||
SCALED = 3
|
||||
TILED = 4
|
||||
|
||||
|
||||
class ShapeType(enum.Enum):
|
||||
OVAL = 0
|
||||
RECTANGLE = 1
|
||||
|
||||
|
||||
class CanvasGraph(tk.Canvas):
|
||||
def __init__(self, master, core, width, height, cnf=None, **kwargs):
|
||||
if cnf is None:
|
||||
|
@ -620,222 +593,3 @@ class CanvasGraph(tk.Canvas):
|
|||
|
||||
def is_selection_mode(self):
|
||||
return self.mode == GraphMode.SELECT
|
||||
|
||||
|
||||
class CanvasWirelessEdge:
|
||||
def __init__(self, token, position, src, dst, canvas):
|
||||
self.token = token
|
||||
self.src = src
|
||||
self.dst = dst
|
||||
self.canvas = canvas
|
||||
self.id = self.canvas.create_line(
|
||||
*position, tags="wireless", width=1.5, fill="#009933"
|
||||
)
|
||||
|
||||
def delete(self):
|
||||
self.canvas.delete(self.id)
|
||||
|
||||
|
||||
class CanvasEdge:
|
||||
"""
|
||||
Canvas edge class
|
||||
"""
|
||||
|
||||
width = 1.4
|
||||
|
||||
def __init__(self, x1, y1, x2, y2, src, canvas, is_wired=None):
|
||||
"""
|
||||
Create an instance of canvas edge object
|
||||
:param int x1: source x-coord
|
||||
:param int y1: source y-coord
|
||||
:param int x2: destination x-coord
|
||||
:param int y2: destination y-coord
|
||||
:param int src: source id
|
||||
:param tkinter.Canvas canvas: canvas object
|
||||
"""
|
||||
self.src = src
|
||||
self.dst = None
|
||||
self.src_interface = None
|
||||
self.dst_interface = None
|
||||
self.canvas = canvas
|
||||
if is_wired is None or is_wired is True:
|
||||
self.id = self.canvas.create_line(
|
||||
x1, y1, x2, y2, tags="edge", width=self.width, fill="#ff0000"
|
||||
)
|
||||
else:
|
||||
self.id = self.canvas.create_line(
|
||||
x1,
|
||||
y1,
|
||||
x2,
|
||||
y2,
|
||||
tags="edge",
|
||||
width=self.width,
|
||||
fill="#ff0000",
|
||||
state=tk.HIDDEN,
|
||||
)
|
||||
self.token = None
|
||||
self.link_info = None
|
||||
self.throughput = None
|
||||
self.wired = is_wired
|
||||
|
||||
def complete(self, dst, x, y):
|
||||
self.dst = dst
|
||||
self.token = tuple(sorted((self.src, self.dst)))
|
||||
x1, y1, _, _ = self.canvas.coords(self.id)
|
||||
self.canvas.coords(self.id, x1, y1, x, y)
|
||||
self.canvas.helper.draw_wireless_case(self.src, self.dst, self)
|
||||
self.canvas.tag_raise(self.src)
|
||||
self.canvas.tag_raise(self.dst)
|
||||
|
||||
def delete(self):
|
||||
self.canvas.delete(self.id)
|
||||
|
||||
|
||||
class CanvasNode:
|
||||
def __init__(self, app, core_node, image):
|
||||
self.app = app
|
||||
self.canvas = app.canvas
|
||||
self.image = image
|
||||
self.core_node = core_node
|
||||
x = self.core_node.position.x
|
||||
y = self.core_node.position.y
|
||||
self.id = self.canvas.create_image(
|
||||
x, y, anchor=tk.CENTER, image=self.image, tags="node"
|
||||
)
|
||||
image_box = self.canvas.bbox(self.id)
|
||||
y = image_box[3] + NODE_TEXT_OFFSET
|
||||
text_font = font.Font(family="TkIconFont", size=12)
|
||||
self.text_id = self.canvas.create_text(
|
||||
x,
|
||||
y,
|
||||
text=self.core_node.name,
|
||||
tags="nodename",
|
||||
font=text_font,
|
||||
fill="#0000CD",
|
||||
)
|
||||
self.antenna_draw = WlanAntennaManager(self.canvas, self.id)
|
||||
self.tooltip = CanvasTooltip(self.canvas)
|
||||
self.canvas.tag_bind(self.id, "<ButtonPress-1>", self.click_press)
|
||||
self.canvas.tag_bind(self.id, "<ButtonRelease-1>", self.click_release)
|
||||
self.canvas.tag_bind(self.id, "<B1-Motion>", self.motion)
|
||||
self.canvas.tag_bind(self.id, "<Double-Button-1>", self.double_click)
|
||||
self.canvas.tag_bind(self.id, "<Control-1>", self.select_multiple)
|
||||
self.canvas.tag_bind(self.id, "<Enter>", self.on_enter)
|
||||
self.canvas.tag_bind(self.id, "<Leave>", self.on_leave)
|
||||
self.edges = set()
|
||||
self.interfaces = []
|
||||
self.wireless_edges = set()
|
||||
self.moving = None
|
||||
|
||||
def redraw(self):
|
||||
self.canvas.itemconfig(self.id, image=self.image)
|
||||
self.canvas.itemconfig(self.text_id, text=self.core_node.name)
|
||||
|
||||
def move(self, x, y, update=True):
|
||||
old_x = self.core_node.position.x
|
||||
old_y = self.core_node.position.y
|
||||
x_offset = x - old_x
|
||||
y_offset = y - old_y
|
||||
self.core_node.position.x = int(x)
|
||||
self.core_node.position.y = int(y)
|
||||
self.canvas.move(self.id, x_offset, y_offset)
|
||||
self.canvas.move(self.text_id, x_offset, y_offset)
|
||||
self.antenna_draw.update_antennas_position(x_offset, y_offset)
|
||||
self.canvas.canvas_management.node_drag(self, x_offset, y_offset)
|
||||
for edge in self.edges:
|
||||
x1, y1, x2, y2 = self.canvas.coords(edge.id)
|
||||
if edge.src == self.id:
|
||||
self.canvas.coords(edge.id, x, y, x2, y2)
|
||||
else:
|
||||
self.canvas.coords(edge.id, x1, y1, x, y)
|
||||
edge.link_info.recalculate_info()
|
||||
for edge in self.wireless_edges:
|
||||
x1, y1, x2, y2 = self.canvas.coords(edge.id)
|
||||
if edge.src == self.id:
|
||||
self.canvas.coords(edge.id, x, y, x2, y2)
|
||||
else:
|
||||
self.canvas.coords(edge.id, x1, y1, x, y)
|
||||
if self.app.core.is_runtime() and update:
|
||||
self.app.core.edit_node(self.core_node.id, int(x), int(y))
|
||||
|
||||
def on_enter(self, event):
|
||||
if self.app.core.is_runtime() and self.app.core.observer:
|
||||
self.tooltip.text.set("waiting...")
|
||||
self.tooltip.on_enter(event)
|
||||
output = self.app.core.run(self.core_node.id)
|
||||
self.tooltip.text.set(output)
|
||||
|
||||
def on_leave(self, event):
|
||||
self.tooltip.on_leave(event)
|
||||
|
||||
def click(self, event):
|
||||
print("click")
|
||||
|
||||
def double_click(self, event):
|
||||
if self.app.core.is_runtime():
|
||||
self.canvas.core.launch_terminal(self.core_node.id)
|
||||
else:
|
||||
self.show_config()
|
||||
|
||||
def update_coords(self):
|
||||
x, y = self.canvas.coords(self.id)
|
||||
self.core_node.position.x = int(x)
|
||||
self.core_node.position.y = int(y)
|
||||
|
||||
def click_press(self, event):
|
||||
logging.debug(f"node click press {self.core_node.name}: {event}")
|
||||
self.moving = self.canvas.canvas_xy(event)
|
||||
if self.id not in self.canvas.canvas_management.selected:
|
||||
self.canvas.canvas_management.node_select(self)
|
||||
self.canvas.selected = self.id
|
||||
|
||||
def click_release(self, event):
|
||||
logging.debug(f"node click release {self.core_node.name}: {event}")
|
||||
self.update_coords()
|
||||
self.moving = None
|
||||
|
||||
def motion(self, event):
|
||||
if self.canvas.mode == GraphMode.EDGE:
|
||||
return
|
||||
x, y = self.canvas.canvas_xy(event)
|
||||
my_x = self.core_node.position.x
|
||||
my_y = self.core_node.position.y
|
||||
self.move(x, y)
|
||||
# move other selected components
|
||||
for nid, bboxid in self.canvas.canvas_management.selected.items():
|
||||
if nid != self.id and nid in self.canvas.nodes:
|
||||
other_old_x = self.canvas.nodes[nid].core_node.position.x
|
||||
other_old_y = self.canvas.nodes[nid].core_node.position.y
|
||||
other_new_x = x + other_old_x - my_x
|
||||
other_new_y = y + other_old_y - my_y
|
||||
self.canvas.nodes[nid].move(other_new_x, other_new_y)
|
||||
if nid != self.id and nid in self.canvas.shapes:
|
||||
self.canvas.shapes[nid].motion(None, x - my_x, y - my_y)
|
||||
|
||||
def select_multiple(self, event):
|
||||
self.canvas.canvas_management.node_select(self, True)
|
||||
|
||||
def show_config(self):
|
||||
self.canvas.context = None
|
||||
dialog = NodeConfigDialog(self.app, self.app, self)
|
||||
dialog.show()
|
||||
|
||||
def show_wlan_config(self):
|
||||
self.canvas.context = None
|
||||
dialog = WlanConfigDialog(self.app, self.app, self)
|
||||
dialog.show()
|
||||
|
||||
def show_mobility_config(self):
|
||||
self.canvas.context = None
|
||||
dialog = MobilityConfigDialog(self.app, self.app, self)
|
||||
dialog.show()
|
||||
|
||||
def show_mobility_player(self):
|
||||
self.canvas.context = None
|
||||
mobility_player = self.app.core.mobility_players[self.core_node.id]
|
||||
mobility_player.show()
|
||||
|
||||
def show_emane_config(self):
|
||||
self.canvas.context = None
|
||||
dialog = EmaneConfigDialog(self.app, self.app, self)
|
||||
dialog.show()
|
163
coretk/coretk/graph/node.py
Normal file
163
coretk/coretk/graph/node.py
Normal file
|
@ -0,0 +1,163 @@
|
|||
import logging
|
||||
import tkinter as tk
|
||||
from tkinter import font
|
||||
|
||||
from coretk.dialogs.emaneconfig import EmaneConfigDialog
|
||||
from coretk.dialogs.mobilityconfig import MobilityConfigDialog
|
||||
from coretk.dialogs.nodeconfig import NodeConfigDialog
|
||||
from coretk.dialogs.wlanconfig import WlanConfigDialog
|
||||
from coretk.graph.canvastooltip import CanvasTooltip
|
||||
from coretk.graph.enums import GraphMode
|
||||
from coretk.graph.graph_helper import WlanAntennaManager
|
||||
|
||||
NODE_TEXT_OFFSET = 5
|
||||
|
||||
|
||||
class CanvasNode:
|
||||
def __init__(self, app, core_node, image):
|
||||
self.app = app
|
||||
self.canvas = app.canvas
|
||||
self.image = image
|
||||
self.core_node = core_node
|
||||
x = self.core_node.position.x
|
||||
y = self.core_node.position.y
|
||||
self.id = self.canvas.create_image(
|
||||
x, y, anchor=tk.CENTER, image=self.image, tags="node"
|
||||
)
|
||||
image_box = self.canvas.bbox(self.id)
|
||||
y = image_box[3] + NODE_TEXT_OFFSET
|
||||
text_font = font.Font(family="TkIconFont", size=12)
|
||||
self.text_id = self.canvas.create_text(
|
||||
x,
|
||||
y,
|
||||
text=self.core_node.name,
|
||||
tags="nodename",
|
||||
font=text_font,
|
||||
fill="#0000CD",
|
||||
)
|
||||
self.antenna_draw = WlanAntennaManager(self.canvas, self.id)
|
||||
self.tooltip = CanvasTooltip(self.canvas)
|
||||
self.canvas.tag_bind(self.id, "<ButtonPress-1>", self.click_press)
|
||||
self.canvas.tag_bind(self.id, "<ButtonRelease-1>", self.click_release)
|
||||
self.canvas.tag_bind(self.id, "<B1-Motion>", self.motion)
|
||||
self.canvas.tag_bind(self.id, "<Double-Button-1>", self.double_click)
|
||||
self.canvas.tag_bind(self.id, "<Control-1>", self.select_multiple)
|
||||
self.canvas.tag_bind(self.id, "<Enter>", self.on_enter)
|
||||
self.canvas.tag_bind(self.id, "<Leave>", self.on_leave)
|
||||
self.edges = set()
|
||||
self.interfaces = []
|
||||
self.wireless_edges = set()
|
||||
self.moving = None
|
||||
|
||||
def redraw(self):
|
||||
self.canvas.itemconfig(self.id, image=self.image)
|
||||
self.canvas.itemconfig(self.text_id, text=self.core_node.name)
|
||||
|
||||
def move(self, x, y, update=True):
|
||||
old_x = self.core_node.position.x
|
||||
old_y = self.core_node.position.y
|
||||
x_offset = x - old_x
|
||||
y_offset = y - old_y
|
||||
self.core_node.position.x = int(x)
|
||||
self.core_node.position.y = int(y)
|
||||
self.canvas.move(self.id, x_offset, y_offset)
|
||||
self.canvas.move(self.text_id, x_offset, y_offset)
|
||||
self.antenna_draw.update_antennas_position(x_offset, y_offset)
|
||||
self.canvas.canvas_management.node_drag(self, x_offset, y_offset)
|
||||
for edge in self.edges:
|
||||
x1, y1, x2, y2 = self.canvas.coords(edge.id)
|
||||
if edge.src == self.id:
|
||||
self.canvas.coords(edge.id, x, y, x2, y2)
|
||||
else:
|
||||
self.canvas.coords(edge.id, x1, y1, x, y)
|
||||
edge.link_info.recalculate_info()
|
||||
for edge in self.wireless_edges:
|
||||
x1, y1, x2, y2 = self.canvas.coords(edge.id)
|
||||
if edge.src == self.id:
|
||||
self.canvas.coords(edge.id, x, y, x2, y2)
|
||||
else:
|
||||
self.canvas.coords(edge.id, x1, y1, x, y)
|
||||
if self.app.core.is_runtime() and update:
|
||||
self.app.core.edit_node(self.core_node.id, int(x), int(y))
|
||||
|
||||
def on_enter(self, event):
|
||||
if self.app.core.is_runtime() and self.app.core.observer:
|
||||
self.tooltip.text.set("waiting...")
|
||||
self.tooltip.on_enter(event)
|
||||
output = self.app.core.run(self.core_node.id)
|
||||
self.tooltip.text.set(output)
|
||||
|
||||
def on_leave(self, event):
|
||||
self.tooltip.on_leave(event)
|
||||
|
||||
def click(self, event):
|
||||
print("click")
|
||||
|
||||
def double_click(self, event):
|
||||
if self.app.core.is_runtime():
|
||||
self.canvas.core.launch_terminal(self.core_node.id)
|
||||
else:
|
||||
self.show_config()
|
||||
|
||||
def update_coords(self):
|
||||
x, y = self.canvas.coords(self.id)
|
||||
self.core_node.position.x = int(x)
|
||||
self.core_node.position.y = int(y)
|
||||
|
||||
def click_press(self, event):
|
||||
logging.debug(f"node click press {self.core_node.name}: {event}")
|
||||
self.moving = self.canvas.canvas_xy(event)
|
||||
if self.id not in self.canvas.canvas_management.selected:
|
||||
self.canvas.canvas_management.node_select(self)
|
||||
self.canvas.selected = self.id
|
||||
|
||||
def click_release(self, event):
|
||||
logging.debug(f"node click release {self.core_node.name}: {event}")
|
||||
self.update_coords()
|
||||
self.moving = None
|
||||
|
||||
def motion(self, event):
|
||||
if self.canvas.mode == GraphMode.EDGE:
|
||||
return
|
||||
x, y = self.canvas.canvas_xy(event)
|
||||
my_x = self.core_node.position.x
|
||||
my_y = self.core_node.position.y
|
||||
self.move(x, y)
|
||||
# move other selected components
|
||||
for nid, bboxid in self.canvas.canvas_management.selected.items():
|
||||
if nid != self.id and nid in self.canvas.nodes:
|
||||
other_old_x = self.canvas.nodes[nid].core_node.position.x
|
||||
other_old_y = self.canvas.nodes[nid].core_node.position.y
|
||||
other_new_x = x + other_old_x - my_x
|
||||
other_new_y = y + other_old_y - my_y
|
||||
self.canvas.nodes[nid].move(other_new_x, other_new_y)
|
||||
if nid != self.id and nid in self.canvas.shapes:
|
||||
self.canvas.shapes[nid].motion(None, x - my_x, y - my_y)
|
||||
|
||||
def select_multiple(self, event):
|
||||
self.canvas.canvas_management.node_select(self, True)
|
||||
|
||||
def show_config(self):
|
||||
self.canvas.context = None
|
||||
dialog = NodeConfigDialog(self.app, self.app, self)
|
||||
dialog.show()
|
||||
|
||||
def show_wlan_config(self):
|
||||
self.canvas.context = None
|
||||
dialog = WlanConfigDialog(self.app, self.app, self)
|
||||
dialog.show()
|
||||
|
||||
def show_mobility_config(self):
|
||||
self.canvas.context = None
|
||||
dialog = MobilityConfigDialog(self.app, self.app, self)
|
||||
dialog.show()
|
||||
|
||||
def show_mobility_player(self):
|
||||
self.canvas.context = None
|
||||
mobility_player = self.app.core.mobility_players[self.core_node.id]
|
||||
mobility_player.show()
|
||||
|
||||
def show_emane_config(self):
|
||||
self.canvas.context = None
|
||||
dialog = EmaneConfigDialog(self.app, self.app, self)
|
||||
dialog.show()
|
|
@ -105,9 +105,11 @@ class Shape:
|
|||
width=data.border_width,
|
||||
)
|
||||
_x = (x0 + x1) / 2
|
||||
_y = (y0 + y1) / 2
|
||||
_y = y0 + 1.5 * data.font_size
|
||||
print("create text with text: ", data.text)
|
||||
print(data.text_color)
|
||||
self.text_id = self.canvas.create_text(
|
||||
_x, _y, text=data.text, fill=data.text_color
|
||||
_x, _y, tags="shapetext", text=data.text, fill=data.text_color
|
||||
)
|
||||
self.shape_data = data
|
||||
self.cursor_x = None
|
|
@ -1,27 +0,0 @@
|
|||
"""
|
||||
parse meta data
|
||||
"""
|
||||
|
||||
|
||||
def parse(meta_string):
|
||||
parsed = {}
|
||||
if meta_string[0] == "{" and meta_string[len(meta_string) - 1] == "}":
|
||||
meta_string = meta_string[1:-1]
|
||||
for key_value in meta_string.split("} {"):
|
||||
if key_value[len(key_value) - 1] == "}":
|
||||
key, value = key_value[:-1].split(" {")
|
||||
if key == "wallpaper-style":
|
||||
if value == "upperleft":
|
||||
parsed[key] = 1
|
||||
elif value == "centered":
|
||||
parsed[key] = 2
|
||||
elif value == "scaled":
|
||||
parsed[key] = 3
|
||||
elif value == "tiled":
|
||||
parsed[key] = 4
|
||||
else:
|
||||
parsed[key] = value
|
||||
else:
|
||||
key, value = tuple(key_value.split())
|
||||
parsed[key] = value
|
||||
return parsed
|
|
@ -5,7 +5,7 @@ from functools import partial
|
|||
from tkinter import ttk
|
||||
|
||||
from coretk.dialogs.customnodes import CustomNodesDialog
|
||||
from coretk.graph import GraphMode
|
||||
from coretk.graph.enums import GraphMode
|
||||
from coretk.images import ImageEnum, Images
|
||||
from coretk.nodeutils import NodeUtils
|
||||
from coretk.tooltip import Tooltip
|
||||
|
|
Loading…
Add table
Reference in a new issue