working on delete node

This commit is contained in:
Huy Pham 2019-11-07 13:23:02 -08:00
parent a789498f5c
commit dcfd7f8795
5 changed files with 138 additions and 15 deletions

View file

@ -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

View file

@ -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)

View file

@ -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}")

View file

@ -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):

View 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