pygui improved node context to properly use tk_popup, avoiding bandage code to compensate for other issues
This commit is contained in:
parent
65466909d3
commit
ac2d60dad6
3 changed files with 62 additions and 94 deletions
|
@ -58,7 +58,6 @@ class CanvasGraph(tk.Canvas):
|
|||
self.select_box = None
|
||||
self.selected = None
|
||||
self.node_draw = None
|
||||
self.context = None
|
||||
self.nodes = {}
|
||||
self.edges = {}
|
||||
self.shapes = {}
|
||||
|
@ -130,9 +129,6 @@ class CanvasGraph(tk.Canvas):
|
|||
client.
|
||||
:param session: session to draw
|
||||
"""
|
||||
# hide context
|
||||
self.hide_context()
|
||||
|
||||
# reset view options to default state
|
||||
self.show_node_labels.set(True)
|
||||
self.show_link_labels.set(True)
|
||||
|
@ -166,7 +162,6 @@ class CanvasGraph(tk.Canvas):
|
|||
self.bind("<ButtonPress-1>", self.click_press)
|
||||
self.bind("<ButtonRelease-1>", self.click_release)
|
||||
self.bind("<B1-Motion>", self.click_motion)
|
||||
self.bind("<ButtonRelease-3>", self.click_context)
|
||||
self.bind("<Delete>", self.press_delete)
|
||||
self.bind("<Control-1>", self.ctrl_click)
|
||||
self.bind("<Double-Button-1>", self.double_click)
|
||||
|
@ -176,11 +171,6 @@ class CanvasGraph(tk.Canvas):
|
|||
self.bind("<ButtonPress-3>", lambda e: self.scan_mark(e.x, e.y))
|
||||
self.bind("<B3-Motion>", lambda e: self.scan_dragto(e.x, e.y, gain=1))
|
||||
|
||||
def hide_context(self, event=None):
|
||||
if self.context:
|
||||
self.context.unpost()
|
||||
self.context = None
|
||||
|
||||
def get_actual_coords(self, x: float, y: float) -> [float, float]:
|
||||
actual_x = (x - self.offset[0]) / self.ratio
|
||||
actual_y = (y - self.offset[1]) / self.ratio
|
||||
|
@ -396,10 +386,6 @@ class CanvasGraph(tk.Canvas):
|
|||
x, y = self.canvas_xy(event)
|
||||
if not self.inside_canvas(x, y):
|
||||
return
|
||||
|
||||
if self.context:
|
||||
self.hide_context()
|
||||
else:
|
||||
if self.mode == GraphMode.ANNOTATION:
|
||||
self.focus_set()
|
||||
if self.shape_drawing:
|
||||
|
@ -422,9 +408,7 @@ class CanvasGraph(tk.Canvas):
|
|||
else:
|
||||
self.focus_set()
|
||||
self.selected = self.get_selected(event)
|
||||
logging.debug(
|
||||
f"click release selected({self.selected}) mode({self.mode})"
|
||||
)
|
||||
logging.debug(f"click release selected({self.selected}) mode({self.mode})")
|
||||
if self.mode == GraphMode.EDGE:
|
||||
self.handle_edge_release(event)
|
||||
elif self.mode == GraphMode.NODE:
|
||||
|
@ -717,19 +701,6 @@ class CanvasGraph(tk.Canvas):
|
|||
if self.select_box and self.mode == GraphMode.SELECT:
|
||||
self.select_box.shape_motion(x, y)
|
||||
|
||||
def click_context(self, event: tk.Event):
|
||||
logging.info("context: %s", self.context)
|
||||
if not self.context:
|
||||
selected = self.get_selected(event)
|
||||
canvas_node = self.nodes.get(selected)
|
||||
if canvas_node:
|
||||
logging.debug("node context: %s", selected)
|
||||
self.context = canvas_node.create_context()
|
||||
self.context.bind("<Unmap>", self.hide_context)
|
||||
self.context.post(event.x_root, event.y_root)
|
||||
else:
|
||||
self.hide_context()
|
||||
|
||||
def press_delete(self, _event: tk.Event):
|
||||
"""
|
||||
delete selected nodes and any data that relates to it
|
||||
|
|
|
@ -68,11 +68,14 @@ class CanvasNode:
|
|||
self.service_file_configs = {}
|
||||
self.config_service_configs = {}
|
||||
self.setup_bindings()
|
||||
self.context = tk.Menu(self.canvas)
|
||||
themes.style_menu(self.context)
|
||||
|
||||
def setup_bindings(self):
|
||||
self.canvas.tag_bind(self.id, "<Double-Button-1>", self.double_click)
|
||||
self.canvas.tag_bind(self.id, "<Enter>", self.on_enter)
|
||||
self.canvas.tag_bind(self.id, "<Leave>", self.on_leave)
|
||||
self.canvas.tag_bind(self.id, "<ButtonRelease-3>", self.show_context)
|
||||
|
||||
def delete(self):
|
||||
logging.debug("Delete canvas node for %s", self.core_node)
|
||||
|
@ -188,51 +191,55 @@ class CanvasNode:
|
|||
else:
|
||||
self.show_config()
|
||||
|
||||
def create_context(self) -> tk.Menu:
|
||||
def show_context(self, event: tk.Event) -> None:
|
||||
# clear existing menu
|
||||
self.context.delete(0, tk.END)
|
||||
is_wlan = self.core_node.type == NodeType.WIRELESS_LAN
|
||||
is_emane = self.core_node.type == NodeType.EMANE
|
||||
context = tk.Menu(self.canvas)
|
||||
themes.style_menu(context)
|
||||
if self.app.core.is_runtime():
|
||||
context.add_command(label="Configure", command=self.show_config)
|
||||
self.context.add_command(label="Configure", command=self.show_config)
|
||||
if NodeUtils.is_container_node(self.core_node.type):
|
||||
context.add_command(label="Services", state=tk.DISABLED)
|
||||
context.add_command(label="Config Services", state=tk.DISABLED)
|
||||
self.context.add_command(label="Services", state=tk.DISABLED)
|
||||
self.context.add_command(label="Config Services", state=tk.DISABLED)
|
||||
if is_wlan:
|
||||
context.add_command(label="WLAN Config", command=self.show_wlan_config)
|
||||
self.context.add_command(
|
||||
label="WLAN Config", command=self.show_wlan_config
|
||||
)
|
||||
if is_wlan and self.core_node.id in self.app.core.mobility_players:
|
||||
context.add_command(
|
||||
self.context.add_command(
|
||||
label="Mobility Player", command=self.show_mobility_player
|
||||
)
|
||||
context.add_command(label="Select Adjacent", state=tk.DISABLED)
|
||||
self.context.add_command(label="Select Adjacent", state=tk.DISABLED)
|
||||
if NodeUtils.is_container_node(self.core_node.type):
|
||||
context.add_command(label="Shell Window", state=tk.DISABLED)
|
||||
context.add_command(label="Tcpdump", state=tk.DISABLED)
|
||||
context.add_command(label="Tshark", state=tk.DISABLED)
|
||||
context.add_command(label="Wireshark", state=tk.DISABLED)
|
||||
context.add_command(label="View Log", state=tk.DISABLED)
|
||||
self.context.add_command(label="Shell Window", state=tk.DISABLED)
|
||||
self.context.add_command(label="Tcpdump", state=tk.DISABLED)
|
||||
self.context.add_command(label="Tshark", state=tk.DISABLED)
|
||||
self.context.add_command(label="Wireshark", state=tk.DISABLED)
|
||||
self.context.add_command(label="View Log", state=tk.DISABLED)
|
||||
else:
|
||||
context.add_command(label="Configure", command=self.show_config)
|
||||
self.context.add_command(label="Configure", command=self.show_config)
|
||||
if NodeUtils.is_container_node(self.core_node.type):
|
||||
context.add_command(label="Services", command=self.show_services)
|
||||
context.add_command(
|
||||
self.context.add_command(label="Services", command=self.show_services)
|
||||
self.context.add_command(
|
||||
label="Config Services", command=self.show_config_services
|
||||
)
|
||||
if is_emane:
|
||||
context.add_command(
|
||||
self.context.add_command(
|
||||
label="EMANE Config", command=self.show_emane_config
|
||||
)
|
||||
if is_wlan:
|
||||
context.add_command(label="WLAN Config", command=self.show_wlan_config)
|
||||
context.add_command(
|
||||
self.context.add_command(
|
||||
label="WLAN Config", command=self.show_wlan_config
|
||||
)
|
||||
self.context.add_command(
|
||||
label="Mobility Config", command=self.show_mobility_config
|
||||
)
|
||||
if NodeUtils.is_wireless_node(self.core_node.type):
|
||||
context.add_command(
|
||||
self.context.add_command(
|
||||
label="Link To Selected", command=self.wireless_link_selected
|
||||
)
|
||||
context.add_command(label="Select Members", state=tk.DISABLED)
|
||||
unlink_menu = tk.Menu(context)
|
||||
self.context.add_command(label="Select Members", state=tk.DISABLED)
|
||||
unlink_menu = tk.Menu(self.context)
|
||||
for edge in self.edges:
|
||||
other_id = edge.src
|
||||
if self.id == other_id:
|
||||
|
@ -243,14 +250,14 @@ class CanvasNode:
|
|||
label=other_node.core_node.name, command=func_unlink
|
||||
)
|
||||
themes.style_menu(unlink_menu)
|
||||
context.add_cascade(label="Unlink", menu=unlink_menu)
|
||||
edit_menu = tk.Menu(context)
|
||||
self.context.add_cascade(label="Unlink", menu=unlink_menu)
|
||||
edit_menu = tk.Menu(self.context)
|
||||
themes.style_menu(edit_menu)
|
||||
edit_menu.add_command(label="Cut", command=self.click_cut)
|
||||
edit_menu.add_command(label="Copy", command=self.canvas_copy)
|
||||
edit_menu.add_command(label="Delete", command=self.canvas_delete)
|
||||
context.add_cascade(label="Edit", menu=edit_menu)
|
||||
return context
|
||||
self.context.add_cascade(label="Edit", menu=edit_menu)
|
||||
self.context.tk_popup(event.x_root, event.y_root)
|
||||
|
||||
def click_cut(self) -> None:
|
||||
self.canvas_copy()
|
||||
|
@ -270,39 +277,32 @@ class CanvasNode:
|
|||
self.canvas.copy()
|
||||
|
||||
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)
|
||||
if not dialog.has_error:
|
||||
dialog.show()
|
||||
|
||||
def show_mobility_config(self):
|
||||
self.canvas.context = None
|
||||
dialog = MobilityConfigDialog(self.app, self.app, self)
|
||||
if not dialog.has_error:
|
||||
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()
|
||||
|
||||
def show_services(self):
|
||||
self.canvas.context = None
|
||||
dialog = NodeServiceDialog(self.app.master, self.app, self)
|
||||
dialog.show()
|
||||
|
||||
def show_config_services(self):
|
||||
self.canvas.context = None
|
||||
dialog = NodeConfigServiceDialog(self.app.master, self.app, self)
|
||||
dialog.show()
|
||||
|
||||
|
@ -324,7 +324,6 @@ class CanvasNode:
|
|||
return result
|
||||
|
||||
def wireless_link_selected(self):
|
||||
self.canvas.context = None
|
||||
for canvas_nid in [
|
||||
x for x in self.canvas.selection if "node" in self.canvas.gettags(x)
|
||||
]:
|
||||
|
|
|
@ -263,7 +263,6 @@ class Toolbar(ttk.Frame):
|
|||
Start session handler redraw buttons, send node and link messages to grpc
|
||||
server.
|
||||
"""
|
||||
self.app.canvas.hide_context()
|
||||
self.app.menubar.change_menubar_item_state(is_runtime=True)
|
||||
self.app.statusbar.progress_bar.start(5)
|
||||
self.app.canvas.mode = GraphMode.SELECT
|
||||
|
@ -453,7 +452,6 @@ class Toolbar(ttk.Frame):
|
|||
redraw buttons on the toolbar, send node and link messages to grpc server
|
||||
"""
|
||||
logging.info("Click stop button")
|
||||
self.app.canvas.hide_context()
|
||||
self.app.menubar.change_menubar_item_state(is_runtime=False)
|
||||
self.app.statusbar.progress_bar.start(5)
|
||||
self.time = time.perf_counter()
|
||||
|
|
Loading…
Reference in a new issue