working on delete node
This commit is contained in:
parent
a789498f5c
commit
dcfd7f8795
5 changed files with 138 additions and 15 deletions
|
@ -500,6 +500,41 @@ class CoreClient:
|
||||||
name,
|
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]
|
||||||
|
|
||||||
|
# delete the nodes
|
||||||
|
for i in canvas_ids:
|
||||||
|
try:
|
||||||
|
self.nodes.pop(i)
|
||||||
|
self.reusable.append(i)
|
||||||
|
except KeyError:
|
||||||
|
logging.error("coreclient.py INVALID NODE CANVAS ID")
|
||||||
|
|
||||||
|
self.reusable.sort()
|
||||||
|
|
||||||
|
# delete the edges and interfaces
|
||||||
|
for i in tokens:
|
||||||
|
try:
|
||||||
|
self.edges.pop(i)
|
||||||
|
except KeyError:
|
||||||
|
logging.error("coreclient.py invalid edge token ")
|
||||||
|
|
||||||
|
# delete any configurations
|
||||||
|
for i in core_node_ids:
|
||||||
|
if i in self.mobilityconfig_management.configurations:
|
||||||
|
self.mobilityconfig_management.pop(i)
|
||||||
|
if i in self.wlanconfig_management.configurations:
|
||||||
|
self.wlanconfig_management.pop(i)
|
||||||
|
|
||||||
def add_preexisting_node(self, canvas_node, session_id, core_node, name):
|
def add_preexisting_node(self, canvas_node, session_id, core_node, name):
|
||||||
"""
|
"""
|
||||||
Add preexisting nodes to grpc manager
|
Add preexisting nodes to grpc manager
|
||||||
|
@ -553,20 +588,6 @@ class CoreClient:
|
||||||
self.preexisting.clear()
|
self.preexisting.clear()
|
||||||
logging.debug("Next id: %s, Reusable: %s", self.id, self.reusable)
|
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):
|
def create_interface(self, node_type, gui_interface):
|
||||||
"""
|
"""
|
||||||
create a protobuf interface given the interface object stored by the programmer
|
create a protobuf interface given the interface object stored by the programmer
|
||||||
|
|
|
@ -110,3 +110,6 @@ class CoreToolbarHelp:
|
||||||
emane_config=emane_config,
|
emane_config=emane_config,
|
||||||
emane_model_configs=emane_model_configs,
|
emane_model_configs=emane_model_configs,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
response = self.app.core.client.get_session(self.app.core.session_id)
|
||||||
|
print(response)
|
||||||
|
|
|
@ -8,6 +8,7 @@ from coretk.graph_helper import GraphHelper, WlanAntennaManager
|
||||||
from coretk.images import Images
|
from coretk.images import Images
|
||||||
from coretk.interface import Interface
|
from coretk.interface import Interface
|
||||||
from coretk.linkinfo import LinkInfo, Throughput
|
from coretk.linkinfo import LinkInfo, Throughput
|
||||||
|
from coretk.nodedelete import CanvasComponentManagement
|
||||||
from coretk.wirelessconnection import WirelessConnection
|
from coretk.wirelessconnection import WirelessConnection
|
||||||
|
|
||||||
|
|
||||||
|
@ -41,7 +42,11 @@ class CanvasGraph(tk.Canvas):
|
||||||
self.drawing_edge = None
|
self.drawing_edge = None
|
||||||
self.grid = None
|
self.grid = None
|
||||||
self.meters_per_pixel = 1.5
|
self.meters_per_pixel = 1.5
|
||||||
|
|
||||||
|
self.canvas_management = CanvasComponentManagement(self, core)
|
||||||
|
|
||||||
self.canvas_action = CanvasAction(master, self)
|
self.canvas_action = CanvasAction(master, self)
|
||||||
|
|
||||||
self.setup_menus()
|
self.setup_menus()
|
||||||
self.setup_bindings()
|
self.setup_bindings()
|
||||||
self.draw_grid()
|
self.draw_grid()
|
||||||
|
@ -101,6 +106,7 @@ class CanvasGraph(tk.Canvas):
|
||||||
self.bind("<ButtonRelease-1>", self.click_release)
|
self.bind("<ButtonRelease-1>", self.click_release)
|
||||||
self.bind("<B1-Motion>", self.click_motion)
|
self.bind("<B1-Motion>", self.click_motion)
|
||||||
self.bind("<Button-3>", self.context)
|
self.bind("<Button-3>", self.context)
|
||||||
|
self.bind("<Delete>", self.press_delete)
|
||||||
|
|
||||||
def draw_grid(self, width=1000, height=800):
|
def draw_grid(self, width=1000, height=800):
|
||||||
"""
|
"""
|
||||||
|
@ -377,6 +383,25 @@ class CanvasGraph(tk.Canvas):
|
||||||
self.node_context.unpost()
|
self.node_context.unpost()
|
||||||
self.is_node_context_opened = False
|
self.is_node_context_opened = False
|
||||||
|
|
||||||
|
def press_delete(self, event):
|
||||||
|
# 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)
|
||||||
|
|
||||||
|
self.core.delete_wanted_graph_nodes(to_delete_nodes, to_delete_edge_tokens)
|
||||||
|
# delete any configuration related to the links and nodes
|
||||||
|
|
||||||
|
# delete selected node
|
||||||
|
|
||||||
|
# delete links connected to the selected nodes
|
||||||
|
|
||||||
def add_node(self, x, y, image, node_name):
|
def add_node(self, x, y, image, node_name):
|
||||||
plot_id = self.find_all()[0]
|
plot_id = self.find_all()[0]
|
||||||
if self.selected == plot_id:
|
if self.selected == plot_id:
|
||||||
|
@ -473,11 +498,15 @@ class CanvasNode:
|
||||||
self.canvas.tag_bind(self.id, "<B1-Motion>", self.motion)
|
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, "<Button-3>", self.context)
|
||||||
self.canvas.tag_bind(self.id, "<Double-Button-1>", self.double_click)
|
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.edges = set()
|
||||||
self.wlans = []
|
self.wlans = []
|
||||||
self.moving = None
|
self.moving = None
|
||||||
|
|
||||||
|
def click(self, event):
|
||||||
|
print("click")
|
||||||
|
|
||||||
def double_click(self, event):
|
def double_click(self, event):
|
||||||
node_id = self.canvas.core.nodes[self.id].node_id
|
node_id = self.canvas.core.nodes[self.id].node_id
|
||||||
state = self.canvas.core.get_session_state()
|
state = self.canvas.core.get_session_state()
|
||||||
|
@ -500,7 +529,8 @@ class CanvasNode:
|
||||||
def click_press(self, event):
|
def click_press(self, event):
|
||||||
logging.debug(f"click press {self.name}: {event}")
|
logging.debug(f"click press {self.name}: {event}")
|
||||||
self.moving = self.canvas.canvas_xy(event)
|
self.moving = self.canvas.canvas_xy(event)
|
||||||
# return "break"
|
|
||||||
|
self.canvas.canvas_management.node_select(self)
|
||||||
|
|
||||||
def click_release(self, event):
|
def click_release(self, event):
|
||||||
logging.debug(f"click release {self.name}: {event}")
|
logging.debug(f"click release {self.name}: {event}")
|
||||||
|
@ -520,6 +550,7 @@ class CanvasNode:
|
||||||
self.canvas.move(self.id, offset_x, offset_y)
|
self.canvas.move(self.id, offset_x, offset_y)
|
||||||
self.canvas.move(self.text_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.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)
|
new_x, new_y = self.canvas.coords(self.id)
|
||||||
|
|
||||||
|
@ -539,5 +570,8 @@ class CanvasNode:
|
||||||
old_x, old_y, new_x, new_y, self.wlans
|
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):
|
def context(self, event):
|
||||||
logging.debug(f"context click {self.name}: {event}")
|
logging.debug(f"context click {self.name}: {event}")
|
||||||
|
|
|
@ -10,6 +10,10 @@ from core.api.grpc import core_pb2
|
||||||
|
|
||||||
class MobilityNodeConfig:
|
class MobilityNodeConfig:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
"""
|
||||||
|
create an instance of MobilityConfig object
|
||||||
|
"""
|
||||||
|
# dict that maps node id to mobility configuration
|
||||||
self.configurations = {}
|
self.configurations = {}
|
||||||
|
|
||||||
def set_default_configuration(self, node_type, node_id):
|
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…
Add table
Reference in a new issue