pygui initial implementation for supporting the view menu for showing and hiding canvas elements

This commit is contained in:
Blake Harnden 2020-04-19 15:47:07 -07:00
parent f45a11076f
commit d26c4fc4ab
9 changed files with 119 additions and 61 deletions

View file

@ -20,15 +20,6 @@ WIRELESS_COLOR = "#009933"
ARC_DISTANCE = 50
def interface_label(interface: core_pb2.Interface) -> str:
label = ""
if interface.ip4:
label = f"{interface.ip4}/{interface.ip4mask}"
if interface.ip6:
label = f"{label}\n{interface.ip6}/{interface.ip6mask}"
return label
def create_edge_token(src: int, dst: int, network: int = None) -> Tuple[int, ...]:
values = [src, dst]
if network is not None:
@ -143,7 +134,12 @@ class Edge:
if self.middle_label is None:
x, y = self.middle_label_pos()
self.middle_label = self.canvas.create_text(
x, y, font=self.canvas.app.edge_font, text=text
x,
y,
font=self.canvas.app.edge_font,
text=text,
tags=tags.LINK_LABEL,
state=self.canvas.show_link_labels.state(),
)
else:
self.canvas.itemconfig(self.middle_label, text=text)
@ -168,7 +164,8 @@ class Edge:
text=text,
justify=tk.CENTER,
font=self.canvas.app.edge_font,
tags=tags.LINK_INFO,
tags=tags.LINK_LABEL,
state=self.canvas.show_link_labels.state(),
)
else:
self.canvas.itemconfig(self.src_label, text=text)
@ -181,7 +178,8 @@ class Edge:
text=text,
justify=tk.CENTER,
font=self.canvas.app.edge_font,
tags=tags.LINK_INFO,
tags=tags.LINK_LABEL,
state=self.canvas.show_link_labels.state(),
)
else:
self.canvas.itemconfig(self.dst_label, text=text)
@ -278,13 +276,25 @@ class CanvasEdge(Edge):
self.link = link
self.draw_labels()
def interface_label(self, interface: core_pb2.Interface) -> str:
label = ""
if interface.name and self.canvas.show_interface_names.get():
label = f"{interface.name}"
if interface.ip4 and self.canvas.show_ip4s.get():
label = f"{label}\n" if label else ""
label += f"{interface.ip4}/{interface.ip4mask}"
if interface.ip6 and self.canvas.show_ip6s.get():
label = f"{label}\n" if label else ""
label += f"{interface.ip6}/{interface.ip6mask}"
return label
def create_node_labels(self) -> Tuple[str, str]:
label_one = None
if self.link.HasField("interface_one"):
label_one = interface_label(self.link.interface_one)
label_one = self.interface_label(self.link.interface_one)
label_two = None
if self.link.HasField("interface_two"):
label_two = interface_label(self.link.interface_two)
label_two = self.interface_label(self.link.interface_two)
return label_one, label_two
def draw_labels(self) -> None:

View file

@ -1,5 +1,6 @@
import logging
import tkinter as tk
from tkinter import BooleanVar
from typing import TYPE_CHECKING, Tuple
from PIL import Image, ImageTk
@ -30,6 +31,19 @@ ZOOM_OUT = 0.9
ICON_SIZE = 48
class ShowVar(BooleanVar):
def __init__(self, canvas: "CanvasGraph", tag: str, value: bool) -> None:
super().__init__(value=value)
self.canvas = canvas
self.tag = tag
def state(self) -> str:
return tk.NORMAL if self.get() else tk.HIDDEN
def click_handler(self):
self.canvas.itemconfigure(self.tag, state=self.state())
class CanvasGraph(tk.Canvas):
def __init__(
self, master: "Application", core: "CoreClient", width: int, height: int
@ -69,7 +83,6 @@ class CanvasGraph(tk.Canvas):
self.wallpaper_drawn = None
self.wallpaper_file = ""
self.scale_option = tk.IntVar(value=1)
self.show_grid = tk.BooleanVar(value=True)
self.adjust_to_dim = tk.BooleanVar(value=False)
# throughput related
@ -77,6 +90,17 @@ class CanvasGraph(tk.Canvas):
self.throughput_width = 10
self.throughput_color = "#FF0000"
# drawing related
self.show_node_labels = ShowVar(self, tags.NODE_LABEL, value=True)
self.show_link_labels = ShowVar(self, tags.LINK_LABEL, value=True)
self.show_grid = ShowVar(self, tags.GRIDLINE, value=True)
self.show_shapes = ShowVar(self, tags.SHAPE, value=True)
self.show_shape_labels = ShowVar(self, tags.SHAPE_TEXT, value=True)
self.show_marker = ShowVar(self, tags.MARKER, value=True)
self.show_interface_names = BooleanVar(value=False)
self.show_ip4s = BooleanVar(value=True)
self.show_ip6s = BooleanVar(value=True)
# bindings
self.setup_bindings()
@ -562,6 +586,7 @@ class CanvasGraph(tk.Canvas):
fill=self.app.toolbar.marker_tool.color,
outline="",
tags=tags.MARKER,
state=self.show_marker.state(),
)
return
if selected is None:
@ -818,7 +843,7 @@ class CanvasGraph(tk.Canvas):
# redraw gridlines to new canvas size
self.delete(tags.GRIDLINE)
self.draw_grid()
self.update_grid()
self.app.canvas.show_grid.click_handler()
def redraw_wallpaper(self):
if self.adjust_to_dim.get():
@ -840,13 +865,6 @@ class CanvasGraph(tk.Canvas):
for component in tags.ABOVE_WALLPAPER_TAGS:
self.tag_raise(component)
def update_grid(self):
logging.debug("updating grid show grid: %s", self.show_grid.get())
if self.show_grid.get():
self.itemconfig(tags.GRIDLINE, state=tk.NORMAL)
else:
self.itemconfig(tags.GRIDLINE, state=tk.HIDDEN)
def set_wallpaper(self, filename: str):
logging.debug("setting wallpaper: %s", filename)
if filename:
@ -906,7 +924,8 @@ class CanvasGraph(tk.Canvas):
self.master, scaled_x, scaled_y, copy, self.nodes[canvas_nid].image
)
# add new node to modified_service_nodes set if that set contains the to_copy node
# add new node to modified_service_nodes set if that set contains the
# to_copy node
if self.app.core.service_been_modified(core_node.id):
self.app.core.modified_service_nodes.add(copy.id)

View file

@ -47,9 +47,10 @@ class CanvasNode:
x,
label_y,
text=self.core_node.name,
tags=tags.NODE_NAME,
tags=tags.NODE_LABEL,
font=self.app.icon_text_font,
fill="#0000CD",
state=self.canvas.show_node_labels.state(),
)
self.tooltip = CanvasTooltip(self.canvas)
self.edges = set()
@ -195,7 +196,6 @@ class CanvasNode:
label="Mobility Player", command=self.show_mobility_player
)
context.add_command(label="Select Adjacent", state=tk.DISABLED)
context.add_command(label="Hide", 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)
@ -228,7 +228,6 @@ class CanvasNode:
edit_menu.add_command(label="Cut", state=tk.DISABLED)
edit_menu.add_command(label="Copy", command=self.canvas_copy)
edit_menu.add_command(label="Delete", command=self.canvas_delete)
edit_menu.add_command(label="Hide", state=tk.DISABLED)
context.add_cascade(label="Edit", menu=edit_menu)
return context

View file

@ -85,6 +85,7 @@ class Shape:
fill=self.shape_data.fill_color,
outline=self.shape_data.border_color,
width=self.shape_data.border_width,
state=self.canvas.show_shapes.state(),
)
self.draw_shape_text()
elif self.shape_type == ShapeType.RECTANGLE:
@ -98,6 +99,7 @@ class Shape:
fill=self.shape_data.fill_color,
outline=self.shape_data.border_color,
width=self.shape_data.border_width,
state=self.canvas.show_shapes.state(),
)
self.draw_shape_text()
elif self.shape_type == ShapeType.TEXT:
@ -109,6 +111,7 @@ class Shape:
text=self.shape_data.text,
fill=self.shape_data.text_color,
font=font,
state=self.canvas.show_shapes.state(),
)
else:
logging.error("unknown shape type: %s", self.shape_type)
@ -136,6 +139,7 @@ class Shape:
text=self.shape_data.text,
fill=self.shape_data.text_color,
font=font,
state=self.canvas.show_shape_labels.state(),
)
def shape_motion(self, x1: float, y1: float):

View file

@ -2,10 +2,10 @@ GRIDLINE = "gridline"
SHAPE = "shape"
SHAPE_TEXT = "shapetext"
EDGE = "edge"
LINK_INFO = "linkinfo"
LINK_LABEL = "linklabel"
WIRELESS_EDGE = "wireless"
ANTENNA = "antenna"
NODE_NAME = "nodename"
NODE_LABEL = "nodename"
NODE = "node"
WALLPAPER = "wallpaper"
SELECTION = "selectednodes"
@ -15,19 +15,19 @@ ABOVE_WALLPAPER_TAGS = [
SHAPE,
SHAPE_TEXT,
EDGE,
LINK_INFO,
LINK_LABEL,
WIRELESS_EDGE,
ANTENNA,
NODE,
NODE_NAME,
NODE_LABEL,
]
ABOVE_SHAPE = [GRIDLINE, EDGE, LINK_INFO, WIRELESS_EDGE, ANTENNA, NODE, NODE_NAME]
ABOVE_SHAPE = [GRIDLINE, EDGE, LINK_LABEL, WIRELESS_EDGE, ANTENNA, NODE, NODE_LABEL]
COMPONENT_TAGS = [
EDGE,
NODE,
NODE_NAME,
NODE_LABEL,
WALLPAPER,
LINK_INFO,
LINK_LABEL,
ANTENNA,
WIRELESS_EDGE,
SELECTION,