merged latest from coretk
This commit is contained in:
commit
be36940bd1
5 changed files with 170 additions and 35 deletions
|
@ -289,7 +289,6 @@ class CoreClient:
|
|||
logging.info("delete nodes %s", response)
|
||||
|
||||
def delete_links(self, delete_session=None):
|
||||
# sid = None
|
||||
if delete_session is None:
|
||||
sid = self.session_id
|
||||
else:
|
||||
|
@ -312,7 +311,10 @@ class CoreClient:
|
|||
mobility_configs = self.get_mobility_configs_proto()
|
||||
emane_model_configs = self.get_emane_model_configs_proto()
|
||||
hooks = list(self.hooks.values())
|
||||
if self.emane_config:
|
||||
emane_config = {x: self.emane_config[x].value for x in self.emane_config}
|
||||
else:
|
||||
emane_config = None
|
||||
response = self.client.start_session(
|
||||
self.session_id,
|
||||
nodes,
|
||||
|
@ -407,23 +409,6 @@ class CoreClient:
|
|||
else:
|
||||
return self.reusable.pop(0)
|
||||
|
||||
# def add_node(self, node_type, model, x, y, name, node_id):
|
||||
# position = core_pb2.Position(x=x, y=y)
|
||||
# node = core_pb2.Node(id=node_id, type=node_type, position=position, model=model)
|
||||
# self.node_ids.append(node_id)
|
||||
# response = self.client.add_node(self.session_id, node)
|
||||
# logging.info("created node: %s", response)
|
||||
# if node_type == core_pb2.NodeType.WIRELESS_LAN:
|
||||
# d = OrderedDict()
|
||||
# d["basic_range"] = "275"
|
||||
# d["bandwidth"] = "54000000"
|
||||
# d["jitter"] = "0"
|
||||
# d["delay"] = "20000"
|
||||
# d["error"] = "0"
|
||||
# r = self.client.set_wlan_config(self.session_id, node_id, d)
|
||||
# logging.debug("set wlan config %s", r)
|
||||
# return response.node_id
|
||||
|
||||
def add_graph_node(self, session_id, canvas_id, x, y, name):
|
||||
"""
|
||||
Add node, with information filled in, to grpc manager
|
||||
|
@ -478,6 +463,59 @@ class CoreClient:
|
|||
name,
|
||||
)
|
||||
|
||||
def delete_wanted_graph_nodes(self, canvas_ids, tokens):
|
||||
"""
|
||||
remove the nodes selected by the user and anything related to that node
|
||||
such as link, configurations, interfaces
|
||||
|
||||
:param list(int) canvas_ids: list of canvas node ids
|
||||
:return: nothing
|
||||
"""
|
||||
# keep reference to the core ids
|
||||
core_node_ids = [self.nodes[x].node_id for x in canvas_ids]
|
||||
node_interface_pairs = []
|
||||
|
||||
# delete the nodes
|
||||
for i in canvas_ids:
|
||||
try:
|
||||
n = self.nodes.pop(i)
|
||||
self.reusable.append(n.node_id)
|
||||
except KeyError:
|
||||
logging.error("coreclient.py INVALID NODE CANVAS ID")
|
||||
|
||||
self.reusable.sort()
|
||||
|
||||
# delete the edges and interfaces
|
||||
for i in tokens:
|
||||
try:
|
||||
e = self.edges.pop(i)
|
||||
if e.interface_1 is not None:
|
||||
node_interface_pairs.append(tuple([e.id1, e.interface_1.id]))
|
||||
if e.interface_2 is not None:
|
||||
node_interface_pairs.append(tuple([e.id2, e.interface_2.id]))
|
||||
|
||||
except KeyError:
|
||||
logging.error("coreclient.py invalid edge token ")
|
||||
|
||||
# delete global emane config if there no longer exist any emane cloud
|
||||
if core_pb2.NodeType.EMANE not in [x.type for x in self.nodes.values()]:
|
||||
self.emane_config = None
|
||||
|
||||
# delete any mobility configuration, wlan configuration
|
||||
for i in core_node_ids:
|
||||
if i in self.mobilityconfig_management.configurations:
|
||||
self.mobilityconfig_management.configurations.pop(i)
|
||||
if i in self.wlanconfig_management.configurations:
|
||||
self.wlanconfig_management.configurations.pop(i)
|
||||
|
||||
# delete emane configurations
|
||||
for i in node_interface_pairs:
|
||||
if i in self.emaneconfig_management.configurations:
|
||||
self.emaneconfig_management.configurations.pop(i)
|
||||
for i in core_node_ids:
|
||||
if tuple([i, None]) in self.emaneconfig_management.configurations:
|
||||
self.emaneconfig_management.configurations.pop(tuple([i, None]))
|
||||
|
||||
def add_preexisting_node(self, canvas_node, session_id, core_node, name):
|
||||
"""
|
||||
Add preexisting nodes to grpc manager
|
||||
|
@ -531,20 +569,6 @@ class CoreClient:
|
|||
self.preexisting.clear()
|
||||
logging.debug("Next id: %s, Reusable: %s", self.id, self.reusable)
|
||||
|
||||
def delete_node(self, canvas_id):
|
||||
"""
|
||||
Delete a node from the session
|
||||
|
||||
:param int canvas_id: node's id in the canvas
|
||||
:return: thing
|
||||
"""
|
||||
try:
|
||||
self.nodes.pop(canvas_id)
|
||||
self.reusable.append(canvas_id)
|
||||
self.reusable.sort()
|
||||
except KeyError:
|
||||
logging.error("grpcmanagement.py INVALID NODE CANVAS ID")
|
||||
|
||||
def create_interface(self, node_type, gui_interface):
|
||||
"""
|
||||
create a protobuf interface given the interface object stored by the programmer
|
||||
|
|
|
@ -24,7 +24,7 @@ class WlanConfigDialog(Dialog):
|
|||
self.config = config
|
||||
|
||||
self.name = tk.StringVar(value=canvas_node.name)
|
||||
self.range_var = tk.StringVar(value=config["basic_range"])
|
||||
self.range_var = tk.StringVar(value=config["range"])
|
||||
self.bandwidth_var = tk.StringVar(value=config["bandwidth"])
|
||||
self.delay_var = tk.StringVar(value=config["delay"])
|
||||
self.loss_var = tk.StringVar(value=config["error"])
|
||||
|
|
|
@ -8,6 +8,7 @@ from coretk.graph_helper import GraphHelper, WlanAntennaManager
|
|||
from coretk.images import Images
|
||||
from coretk.interface import Interface
|
||||
from coretk.linkinfo import LinkInfo, Throughput
|
||||
from coretk.nodedelete import CanvasComponentManagement
|
||||
from coretk.wirelessconnection import WirelessConnection
|
||||
|
||||
|
||||
|
@ -41,7 +42,11 @@ class CanvasGraph(tk.Canvas):
|
|||
self.drawing_edge = None
|
||||
self.grid = None
|
||||
self.meters_per_pixel = 1.5
|
||||
|
||||
self.canvas_management = CanvasComponentManagement(self, core)
|
||||
|
||||
self.canvas_action = CanvasAction(master, self)
|
||||
|
||||
self.setup_menus()
|
||||
self.setup_bindings()
|
||||
self.draw_grid()
|
||||
|
@ -101,6 +106,7 @@ class CanvasGraph(tk.Canvas):
|
|||
self.bind("<ButtonRelease-1>", self.click_release)
|
||||
self.bind("<B1-Motion>", self.click_motion)
|
||||
self.bind("<Button-3>", self.context)
|
||||
self.bind("<Delete>", self.press_delete)
|
||||
|
||||
def draw_grid(self, width=1000, height=800):
|
||||
"""
|
||||
|
@ -377,6 +383,37 @@ class CanvasGraph(tk.Canvas):
|
|||
self.node_context.unpost()
|
||||
self.is_node_context_opened = False
|
||||
|
||||
# TODO rather than delete, might move the data to somewhere else in order to reuse
|
||||
# TODO when the user undo
|
||||
def press_delete(self, event):
|
||||
"""
|
||||
delete selected nodes and any data that relates to it
|
||||
:param event:
|
||||
:return:
|
||||
"""
|
||||
# hide nodes, links, link information that shows on the GUI
|
||||
to_delete_nodes, to_delete_edge_tokens = (
|
||||
self.canvas_management.delete_selected_nodes()
|
||||
)
|
||||
|
||||
# delete nodes and link info stored in CanvasGraph object
|
||||
for nid in to_delete_nodes:
|
||||
self.nodes.pop(nid)
|
||||
for token in to_delete_edge_tokens:
|
||||
self.edges.pop(token)
|
||||
|
||||
# delete the edge data inside of canvas node
|
||||
canvas_node_link_to_delete = []
|
||||
for canvas_id, node in self.nodes.items():
|
||||
for e in node.edges:
|
||||
if e.token in to_delete_edge_tokens:
|
||||
canvas_node_link_to_delete.append(tuple([canvas_id, e]))
|
||||
for nid, edge in canvas_node_link_to_delete:
|
||||
self.nodes[nid].edges.remove(edge)
|
||||
|
||||
# delete the related data from core
|
||||
self.core.delete_wanted_graph_nodes(to_delete_nodes, to_delete_edge_tokens)
|
||||
|
||||
def add_node(self, x, y, image, node_name):
|
||||
plot_id = self.find_all()[0]
|
||||
logging.info("add node event: %s - %s", plot_id, self.selected)
|
||||
|
@ -474,11 +511,15 @@ class CanvasNode:
|
|||
self.canvas.tag_bind(self.id, "<B1-Motion>", self.motion)
|
||||
self.canvas.tag_bind(self.id, "<Button-3>", self.context)
|
||||
self.canvas.tag_bind(self.id, "<Double-Button-1>", self.double_click)
|
||||
self.canvas.tag_bind(self.id, "<Control-1>", self.select_multiple)
|
||||
|
||||
self.edges = set()
|
||||
self.wlans = []
|
||||
self.moving = None
|
||||
|
||||
def click(self, event):
|
||||
print("click")
|
||||
|
||||
def double_click(self, event):
|
||||
node_id = self.canvas.core.nodes[self.id].node_id
|
||||
state = self.canvas.core.get_session_state()
|
||||
|
@ -501,7 +542,8 @@ class CanvasNode:
|
|||
def click_press(self, event):
|
||||
logging.debug(f"node click press {self.name}: {event}")
|
||||
self.moving = self.canvas.canvas_xy(event)
|
||||
# return "break"
|
||||
|
||||
self.canvas.canvas_management.node_select(self)
|
||||
|
||||
def click_release(self, event):
|
||||
logging.debug(f"node click release {self.name}: {event}")
|
||||
|
@ -521,6 +563,7 @@ class CanvasNode:
|
|||
self.canvas.move(self.id, offset_x, offset_y)
|
||||
self.canvas.move(self.text_id, offset_x, offset_y)
|
||||
self.antenna_draw.update_antennas_position(offset_x, offset_y)
|
||||
self.canvas.canvas_management.node_drag(self, offset_x, offset_y)
|
||||
|
||||
new_x, new_y = self.canvas.coords(self.id)
|
||||
|
||||
|
@ -540,5 +583,8 @@ class CanvasNode:
|
|||
old_x, old_y, new_x, new_y, self.wlans
|
||||
)
|
||||
|
||||
def select_multiple(self, event):
|
||||
self.canvas.canvas_management.node_select(self, True)
|
||||
|
||||
def context(self, event):
|
||||
logging.debug(f"context click {self.name}: {event}")
|
||||
|
|
|
@ -10,6 +10,10 @@ from core.api.grpc import core_pb2
|
|||
|
||||
class MobilityNodeConfig:
|
||||
def __init__(self):
|
||||
"""
|
||||
create an instance of MobilityConfig object
|
||||
"""
|
||||
# dict that maps node id to mobility configuration
|
||||
self.configurations = {}
|
||||
|
||||
def set_default_configuration(self, node_type, node_id):
|
||||
|
|
61
coretk/coretk/nodedelete.py
Normal file
61
coretk/coretk/nodedelete.py
Normal file
|
@ -0,0 +1,61 @@
|
|||
"""
|
||||
manage deletion
|
||||
"""
|
||||
|
||||
|
||||
class CanvasComponentManagement:
|
||||
def __init__(self, canvas, core):
|
||||
self.app = core
|
||||
self.canvas = canvas
|
||||
|
||||
# dictionary that maps node to box
|
||||
self.selected = {}
|
||||
|
||||
def node_select(self, canvas_node, choose_multiple=False):
|
||||
"""
|
||||
create a bounding box when a node is selected
|
||||
|
||||
:param coretk.graph.CanvasNode canvas_node: canvas node object
|
||||
:return: nothing
|
||||
"""
|
||||
|
||||
if not choose_multiple:
|
||||
self.delete_current_bbox()
|
||||
|
||||
# draw a bounding box if node hasn't been selected yet
|
||||
if canvas_node.id not in self.selected:
|
||||
x0, y0, x1, y1 = self.canvas.bbox(canvas_node.id)
|
||||
bbox_id = self.canvas.create_rectangle(
|
||||
(x0 - 6, y0 - 6, x1 + 6, y1 + 6), activedash=True, dash="-"
|
||||
)
|
||||
self.selected[canvas_node.id] = bbox_id
|
||||
|
||||
def node_drag(self, canvas_node, offset_x, offset_y):
|
||||
self.canvas.move(self.selected[canvas_node.id], offset_x, offset_y)
|
||||
|
||||
def delete_current_bbox(self):
|
||||
for bbid in self.selected.values():
|
||||
self.canvas.delete(bbid)
|
||||
self.selected.clear()
|
||||
|
||||
def delete_selected_nodes(self):
|
||||
selected_nodes = list(self.selected.keys())
|
||||
edges = set()
|
||||
for n in selected_nodes:
|
||||
edges = edges.union(self.canvas.nodes[n].edges)
|
||||
edge_canvas_ids = [x.id for x in edges]
|
||||
edge_tokens = [x.token for x in edges]
|
||||
link_infos = [x.link_info.id1 for x in edges] + [x.link_info.id2 for x in edges]
|
||||
|
||||
for i in edge_canvas_ids:
|
||||
self.canvas.itemconfig(i, state="hidden")
|
||||
|
||||
for i in link_infos:
|
||||
self.canvas.itemconfig(i, state="hidden")
|
||||
|
||||
for cnid, bbid in self.selected.items():
|
||||
self.canvas.itemconfig(cnid, state="hidden")
|
||||
self.canvas.itemconfig(bbid, state="hidden")
|
||||
self.canvas.itemconfig(self.canvas.nodes[cnid].text_id, state="hidden")
|
||||
self.selected.clear()
|
||||
return selected_nodes, edge_tokens
|
Loading…
Reference in a new issue