more work on configurations

This commit is contained in:
Huy Pham 2019-10-30 13:33:22 -07:00
parent f662846f9e
commit 46127b44f9
7 changed files with 419 additions and 59 deletions

View file

@ -0,0 +1,38 @@
"""
canvas graph action
"""
# import tkinter as tk
from core.api.grpc import core_pb2
from coretk.nodeconfigtable import NodeConfig
from coretk.wlanconfiguration import WlanConfiguration
NODE_TO_TYPE = {
"router": core_pb2.NodeType.DEFAULT,
"wlan": core_pb2.NodeType.WIRELESS_LAN,
}
class CanvasAction:
def __init__(self, master, canvas):
self.master = master
self.canvas = canvas
self.node_to_show_config = None
def display_configuration(self, canvas_node):
pb_type = NODE_TO_TYPE[canvas_node.node_type]
self.node_to_show_config = canvas_node
if pb_type == core_pb2.NodeType.DEFAULT:
self.display_node_configuration()
elif pb_type == core_pb2.NodeType.WIRELESS_LAN:
self.display_wlan_configuration()
def display_node_configuration(self):
NodeConfig(self.canvas, self.node_to_show_config)
self.node_to_show_config = None
def display_wlan_configuration(self):
WlanConfiguration(self.canvas, self.node_to_show_config)
self.node_to_show_config = None

View file

@ -3,12 +3,14 @@ import logging
import tkinter as tk import tkinter as tk
from core.api.grpc import core_pb2 from core.api.grpc import core_pb2
from coretk.canvasaction import CanvasAction
from coretk.graph_helper import GraphHelper, WlanAntennaManager from coretk.graph_helper import GraphHelper, WlanAntennaManager
from coretk.grpcmanagement import GrpcManager from coretk.grpcmanagement import GrpcManager
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 from coretk.linkinfo import LinkInfo
from coretk.nodeconfigtable import NodeConfig
# from coretk.nodeconfigtable import NodeConfig
class GraphMode(enum.Enum): class GraphMode(enum.Enum):
@ -19,6 +21,12 @@ class GraphMode(enum.Enum):
OTHER = 4 OTHER = 4
CORE_NODES = ["router"]
CORE_WIRED_NETWORK_NODES = []
CORE_WIRELESS_NODE = ["wlan"]
CORE_EMANE = ["emane"]
class CanvasGraph(tk.Canvas): class CanvasGraph(tk.Canvas):
def __init__(self, master=None, grpc=None, cnf=None, **kwargs): def __init__(self, master=None, grpc=None, cnf=None, **kwargs):
if cnf is None: if cnf is None:
@ -36,6 +44,7 @@ class CanvasGraph(tk.Canvas):
self.grid = None self.grid = None
self.meters_per_pixel = 1.5 self.meters_per_pixel = 1.5
self.canvas_action = CanvasAction(master, self)
self.setup_menus() self.setup_menus()
self.setup_bindings() self.setup_bindings()
self.draw_grid() self.draw_grid()
@ -44,15 +53,30 @@ class CanvasGraph(tk.Canvas):
self.grpc_manager = GrpcManager(grpc) self.grpc_manager = GrpcManager(grpc)
self.helper = GraphHelper(self, grpc) self.helper = GraphHelper(self, grpc)
self.is_node_context_opened = False
# self.core_id_to_canvas_id = {} # self.core_id_to_canvas_id = {}
# self.core_map = CoreToCanvasMapping() # self.core_map = CoreToCanvasMapping()
# self.draw_existing_component() # self.draw_existing_component()
def test(self):
print("testing the button")
print(self.node_context.winfo_rootx())
def setup_menus(self): def setup_menus(self):
self.node_context = tk.Menu(self.master) self.node_context = tk.Menu(self.master)
self.node_context.add_command(label="One") self.node_context.add_command(
self.node_context.add_command(label="Two") label="Configure", command=self.canvas_action.display_node_configuration
self.node_context.add_command(label="Three") )
self.node_context.add_command(label="Select adjacent")
self.node_context.add_command(label="Create link to")
self.node_context.add_command(label="Assign to")
self.node_context.add_command(label="Move to")
self.node_context.add_command(label="Cut")
self.node_context.add_command(label="Copy")
self.node_context.add_command(label="Paste")
self.node_context.add_command(label="Delete")
self.node_context.add_command(label="Hide")
self.node_context.add_command(label="Services")
def canvas_reset_and_redraw(self, new_grpc): def canvas_reset_and_redraw(self, new_grpc):
""" """
@ -74,14 +98,11 @@ class CanvasGraph(tk.Canvas):
self.edges = {} self.edges = {}
self.drawing_edge = None self.drawing_edge = None
print("graph.py create a new grpc manager")
self.grpc_manager = GrpcManager(new_grpc) self.grpc_manager = GrpcManager(new_grpc)
# new grpc # new grpc
self.core_grpc = new_grpc self.core_grpc = new_grpc
print("grpah.py draw existing component")
self.draw_existing_component() self.draw_existing_component()
print(self.grpc_manager.edges)
def setup_bindings(self): def setup_bindings(self):
""" """
@ -218,8 +239,6 @@ class CanvasGraph(tk.Canvas):
].interfaces.append(if2) ].interfaces.append(if2)
# lift the nodes so they on top of the links # lift the nodes so they on top of the links
# for i in core_id_to_canvas_id.values():
# self.lift(i)
for i in self.find_withtag("node"): for i in self.find_withtag("node"):
self.lift(i) self.lift(i)
@ -272,6 +291,10 @@ class CanvasGraph(tk.Canvas):
:param event: mouse event :param event: mouse event
:return: nothing :return: nothing
""" """
if self.is_node_context_opened:
self.node_context.unpost()
self.is_node_context_opened = False
else:
self.focus_set() self.focus_set()
self.selected = self.get_selected(event) self.selected = self.get_selected(event)
logging.debug(f"click release selected: {self.selected}") logging.debug(f"click release selected: {self.selected}")
@ -367,11 +390,17 @@ class CanvasGraph(tk.Canvas):
self.coords(self.drawing_edge.id, x1, y1, x2, y2) self.coords(self.drawing_edge.id, x1, y1, x2, y2)
def context(self, event): def context(self, event):
if not self.is_node_context_opened:
selected = self.get_selected(event) selected = self.get_selected(event)
nodes = self.find_withtag("node") nodes = self.find_withtag("node")
if selected in nodes: if selected in nodes:
logging.debug(f"node context: {selected}") logging.debug(f"node context: {selected}")
self.node_context.post(event.x_root, event.y_root) self.node_context.post(event.x_root, event.y_root)
self.canvas_action.node_to_show_config = self.nodes[selected]
self.is_node_context_opened = True
else:
self.node_context.unpost()
self.is_node_context_opened = False
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]
@ -482,8 +511,15 @@ class CanvasNode:
if state == core_pb2.SessionState.RUNTIME: if state == core_pb2.SessionState.RUNTIME:
self.canvas.core_grpc.launch_terminal(node_id) self.canvas.core_grpc.launch_terminal(node_id)
else: else:
print("config table show up") self.canvas.canvas_action.display_configuration(self)
NodeConfig(self, self.image, self.node_type, self.name) # if self.node_type in CORE_NODES:
# self.canvas.canvas_action.node_to_show_config = self
# self.canvas.canvas_action.display_node_configuration()
# elif self.node_type in CORE_WIRED_NETWORK_NODES:
# return
# elif self.node_type in CORE_WIRELESS_NODE:
# return
# elif self
def update_coords(self): def update_coords(self):
self.x_coord, self.y_coord = self.canvas.coords(self.id) self.x_coord, self.y_coord = self.canvas.coords(self.id)

View file

@ -169,7 +169,6 @@ class GrpcManager:
# update the next available id # update the next available id
core_id = core_node.id core_id = core_node.id
print(core_id)
if self.id is None or core_id >= self.id: if self.id is None or core_id >= self.id:
self.id = core_id + 1 self.id = core_id + 1
self.preexisting.append(core_id) self.preexisting.append(core_id)

View file

@ -0,0 +1,91 @@
"""
node image modification
"""
import os
import tkinter as tk
from tkinter import filedialog
from PIL import Image, ImageTk
PATH = os.path.abspath(os.path.dirname(__file__))
ICONS_DIR = os.path.join(PATH, "icons")
class ImageModification:
def __init__(self, canvas, canvas_node, node_config):
"""
create an instance of ImageModification
:param coretk.graph.CanvasGraph canvas: canvas object
:param coretk.graph.CanvasNode canvas_node: node object
:param coretk.nodeconfigtable.NodeConfig node_config: node configuration object
"""
self.canvas = canvas
self.image = canvas_node.image
self.node_type = canvas_node.node_type
self.name = canvas_node.name
self.canvas_node = canvas_node
self.node_configuration = node_config
self.p_top = node_config.top
self.top = tk.Toplevel()
self.top.title(self.name + " image")
self.image_modification()
def open_icon_dir(self, toplevel, entry_text):
filename = filedialog.askopenfilename(
initialdir=ICONS_DIR,
title="Open",
filetypes=(
("images", "*.gif *.jpg *.png *.bmp *pcx *.tga ..."),
("All Files", "*"),
),
)
if len(filename) > 0:
img = Image.open(filename)
tk_img = ImageTk.PhotoImage(img)
lb = toplevel.grid_slaves(1, 0)[0]
lb.configure(image=tk_img)
lb.image = tk_img
entry_text.set(filename)
def click_apply(self, toplevel, entry_text):
imgfile = entry_text.get()
if imgfile:
img = Image.open(imgfile)
tk_img = ImageTk.PhotoImage(img)
f = self.p_top.grid_slaves(row=0, column=0)[0]
lb = f.grid_slaves(row=0, column=3)[0]
lb.configure(image=tk_img)
lb.image = tk_img
self.image = tk_img
self.node_configuration.image = tk_img
toplevel.destroy()
def image_modification(self):
f = tk.Frame(self.top)
entry_text = tk.StringVar()
image_file_label = tk.Label(f, text="Image file: ")
image_file_label.grid(row=0, column=0)
image_file_entry = tk.Entry(f, textvariable=entry_text, width=32, bg="white")
image_file_entry.grid(row=0, column=1)
image_file_button = tk.Button(
f, text="...", command=lambda: self.open_icon_dir(self.top, entry_text)
)
image_file_button.grid(row=0, column=2)
f.grid()
img = tk.Label(self.top, image=self.image)
img.grid()
f = tk.Frame(self.top)
apply_button = tk.Button(
f, text="Apply", command=lambda: self.click_apply(self.top, entry_text)
)
apply_button.grid(row=0, column=0)
apply_to_multiple_button = tk.Button(f, text="Apply to multiple...")
apply_to_multiple_button.grid(row=0, column=1)
cancel_button = tk.Button(f, text="Cancel", command=self.top.destroy)
cancel_button.grid(row=0, column=2)
f.grid()

View file

@ -8,6 +8,8 @@ from tkinter import filedialog
from PIL import Image, ImageTk from PIL import Image, ImageTk
from coretk.imagemodification import ImageModification
PATH = os.path.abspath(os.path.dirname(__file__)) PATH = os.path.abspath(os.path.dirname(__file__))
ICONS_DIR = os.path.join(PATH, "icons") ICONS_DIR = os.path.join(PATH, "icons")
@ -16,14 +18,15 @@ DEFAULTNODES = ["router", "host", "PC"]
class NodeConfig: class NodeConfig:
def __init__(self, canvas_node, image, node_type, name): def __init__(self, canvas, canvas_node):
self.image = image self.canvas = canvas
self.node_type = node_type self.image = canvas_node.image
self.name = name self.node_type = canvas_node.node_type
self.name = canvas_node.name
self.canvas_node = canvas_node self.canvas_node = canvas_node
self.top = tk.Toplevel() self.top = tk.Toplevel()
self.top.title(node_type + " configuration") self.top.title(canvas_node.node_type + " configuration")
self.namevar = tk.StringVar(self.top, value="default name") self.namevar = tk.StringVar(self.top, value="default name")
self.name_and_image_definition() self.name_and_image_definition()
self.type_and_service_definition() self.type_and_service_definition()
@ -58,65 +61,67 @@ class NodeConfig:
toplevel.destroy() toplevel.destroy()
def img_modification(self): def img_modification(self):
print("image modification")
t = tk.Toplevel() t = tk.Toplevel()
t.title(self.name + " image") t.title(self.name + " image")
f = tk.Frame(t) f = tk.Frame(t)
entry_text = tk.StringVar() entry_text = tk.StringVar()
image_file_label = tk.Label(f, text="Image file: ") image_file_label = tk.Label(f, text="Image file: ")
image_file_label.pack(side=tk.LEFT, padx=2, pady=2) image_file_label.grid(row=0, column=0)
image_file_entry = tk.Entry(f, textvariable=entry_text, width=60) image_file_entry = tk.Entry(f, textvariable=entry_text, width=32, bg="white")
image_file_entry.pack(side=tk.LEFT, padx=2, pady=2) image_file_entry.grid(row=0, column=1)
image_file_button = tk.Button( image_file_button = tk.Button(
f, text="...", command=lambda: self.open_icon_dir(t, entry_text) f, text="...", command=lambda: self.open_icon_dir(t, entry_text)
) )
image_file_button.pack(side=tk.LEFT, padx=2, pady=2) image_file_button.grid(row=0, column=2)
f.grid(sticky=tk.W + tk.E) f.grid()
img = tk.Label(t, image=self.image) img = tk.Label(t, image=self.image)
img.grid(sticky=tk.W + tk.E) img.grid()
f = tk.Frame(t) f = tk.Frame(t)
apply_button = tk.Button( apply_button = tk.Button(
f, text="Apply", command=lambda: self.click_apply(t, entry_text) f, text="Apply", command=lambda: self.click_apply(t, entry_text)
) )
apply_button.pack(side=tk.LEFT, padx=2, pady=2) apply_button.grid(row=0, column=0)
apply_to_multiple_button = tk.Button(f, text="Apply to multiple...") apply_to_multiple_button = tk.Button(f, text="Apply to multiple...")
apply_to_multiple_button.pack(side=tk.LEFT, padx=2, pady=2) apply_to_multiple_button.grid(row=0, column=1)
cancel_button = tk.Button(f, text="Cancel", command=t.destroy) cancel_button = tk.Button(f, text="Cancel", command=t.destroy)
cancel_button.pack(side=tk.LEFT, padx=2, pady=2) cancel_button.grid(row=0, column=2)
f.grid(sticky=tk.E + tk.W) f.grid()
def name_and_image_definition(self): def name_and_image_definition(self):
name_label = tk.Label(self.top, text="Node name: ") f = tk.Frame(self.top, bg="#d9d9d9")
name_label.grid() name_label = tk.Label(f, text="Node name: ", bg="#d9d9d9")
name_entry = tk.Entry(self.top, textvariable=self.namevar) name_label.grid(padx=2, pady=2)
name_entry.grid(row=0, column=1) name_entry = tk.Entry(f, textvariable=self.namevar)
name_entry.grid(row=0, column=1, padx=2, pady=2)
core_button = tk.Button(self.top, text="None") core_button = tk.Button(f, text="None")
core_button.grid(row=0, column=2) core_button.grid(row=0, column=2, padx=2, pady=2)
img_button = tk.Button( img_button = tk.Button(
self.top, f,
image=self.image, image=self.image,
width=40, width=40,
height=40, height=40,
command=self.img_modification, command=lambda: ImageModification(self.canvas, self.canvas_node, self),
bg="#d9d9d9",
) )
img_button.grid(row=0, column=3) img_button.grid(row=0, column=3, padx=4, pady=4)
f.grid(padx=4, pady=4)
def type_and_service_definition(self): def type_and_service_definition(self):
f = tk.Frame(self.top) f = tk.Frame(self.top)
type_label = tk.Label(f, text="Type: ") type_label = tk.Label(f, text="Type: ")
type_label.pack(side=tk.LEFT) type_label.grid(row=0, column=0)
type_button = tk.Button(f, text="None") type_button = tk.Button(f, text="None")
type_button.pack(side=tk.LEFT) type_button.grid(row=0, column=1)
service_button = tk.Button(f, text="Services...") service_button = tk.Button(f, text="Services...")
service_button.pack(side=tk.LEFT) service_button.grid(row=0, column=2)
f.grid(row=1, column=1, columnspan=2, sticky=tk.W) f.grid(padx=2, pady=2)
def config_apply(self): def config_apply(self):
""" """
@ -140,10 +145,10 @@ class NodeConfig:
def select_definition(self): def select_definition(self):
f = tk.Frame(self.top) f = tk.Frame(self.top)
apply_button = tk.Button(f, text="Apply", command=self.config_apply) apply_button = tk.Button(f, text="Apply", command=self.config_apply)
apply_button.pack(side=tk.LEFT) apply_button.grid(row=0, column=0)
cancel_button = tk.Button(f, text="Cancel", command=self.config_cancel) cancel_button = tk.Button(f, text="Cancel", command=self.config_cancel)
cancel_button.pack(side=tk.LEFT) cancel_button.grid(row=0, column=1)
f.grid(row=3, column=1, sticky=tk.W) f.grid()
def network_node_config(self): def network_node_config(self):
self.name_and_image_definition() self.name_and_image_definition()

View file

@ -0,0 +1,10 @@
"""
service configuration
"""
# import tkinter as tk
class ServiceConfiguration:
def __init__(self):
return

View file

@ -0,0 +1,181 @@
"""
wlan configuration
"""
import ast
import tkinter as tk
from functools import partial
class WlanConfiguration:
def __init__(self, canvas, canvas_node):
self.canvas = canvas
self.image = canvas_node.image
self.node_type = canvas_node.node_type
self.name = canvas_node.name
self.canvas_node = canvas_node
self.top = tk.Toplevel()
self.top.title("wlan configuration")
self.node_name = tk.StringVar()
self.range_var = tk.DoubleVar()
self.range_var.set(275.0)
self.bandwidth_var = tk.IntVar()
self.bandwidth_var.set(54000000)
self.delay_var = tk.StringVar()
self.image_modification()
self.wlan_configuration()
self.subnet()
self.wlan_options()
self.config_option()
def image_modification(self):
f = tk.Frame(self.top, bg="#d9d9d9")
lbl = tk.Label(f, text="Node name: ", bg="#d9d9d9")
lbl.grid(row=0, column=0, padx=3, pady=3)
e = tk.Entry(f, textvariable=self.node_name, bg="white")
e.grid(row=0, column=1, padx=3, pady=3)
b = tk.Button(f, text="None")
b.grid(row=0, column=2, padx=3, pady=3)
b = tk.Button(f, text="not implemented")
b.grid(row=0, column=3, padx=3, pady=3)
f.grid(padx=2, pady=2, ipadx=2, ipady=2)
def create_string_var(self, val):
v = tk.StringVar()
v.set(val)
return v
def scrollbar_command(self, entry_widget, delta, event):
try:
value = int(entry_widget.get())
except ValueError:
value = ast.literal_eval(entry_widget.get())
entry_widget.delete(0, tk.END)
if event == "-1":
entry_widget.insert(tk.END, str(round(value + delta, 1)))
elif event == "1":
entry_widget.insert(tk.END, str(round(value - delta, 1)))
def wlan_configuration(self):
lbl = tk.Label(self.top, text="Wireless")
lbl.grid(sticky=tk.W, padx=3, pady=3)
f = tk.Frame(
self.top,
highlightbackground="#b3b3b3",
highlightcolor="#b3b3b3",
highlightthickness=0.5,
bd=0,
bg="#d9d9d9",
)
lbl = tk.Label(
f,
text="The basic range model calculates on/off connectivity based on pixel distance between nodes.",
bg="#d9d9d9",
)
lbl.grid(padx=4, pady=4)
f1 = tk.Frame(f, bg="#d9d9d9")
lbl = tk.Label(f1, text="Range: ", bg="#d9d9d9")
lbl.grid(row=0, column=0)
e = tk.Entry(f1, textvariable=self.range_var, width=5, bg="white")
e.grid(row=0, column=1)
lbl = tk.Label(f1, text="Bandwidth (bps): ", bg="#d9d9d9")
lbl.grid(row=0, column=2)
f11 = tk.Frame(f1, bg="#d9d9d9")
sb = tk.Scrollbar(f11, orient=tk.VERTICAL)
e = tk.Entry(f11, textvariable=self.bandwidth_var, width=10, bg="white")
sb.config(command=partial(self.scrollbar_command, e, 1000000))
e.grid()
sb.grid(row=0, column=1)
f11.grid(row=0, column=3)
# e = tk.Entry(f1, textvariable=self.bandwidth_var, width=10)
# e.grid(row=0, column=4)
f1.grid(sticky=tk.W, padx=4, pady=4)
f2 = tk.Frame(f, bg="#d9d9d9")
lbl = tk.Label(f2, text="Delay (us): ", bg="#d9d9d9")
lbl.grid(row=0, column=0)
f21 = tk.Frame(f2, bg="#d9d9d9")
sb = tk.Scrollbar(f21, orient=tk.VERTICAL)
e = tk.Entry(f21, textvariable=self.create_string_var(20000), bg="white")
sb.config(command=partial(self.scrollbar_command, e, 5000))
e.grid()
sb.grid(row=0, column=1)
f21.grid(row=0, column=1)
lbl = tk.Label(f2, text="Loss (%): ", bg="#d9d9d9")
lbl.grid(row=0, column=2)
f22 = tk.Frame(f2, bg="#d9d9d9")
sb = tk.Scrollbar(f22, orient=tk.VERTICAL)
e = tk.Entry(f22, textvariable=self.create_string_var(0), bg="white")
sb.config(command=partial(self.scrollbar_command, e, 0.1))
e.grid()
sb.grid(row=0, column=1)
f22.grid(row=0, column=3)
# e = tk.Entry(f2, textvariable=self.create_string_var(0))
# e.grid(row=0, column=3)
f2.grid(sticky=tk.W, padx=4, pady=4)
f3 = tk.Frame(f, bg="#d9d9d9")
lbl = tk.Label(f3, text="Jitter (us): ", bg="#d9d9d9")
lbl.grid()
f31 = tk.Frame(f3, bg="#d9d9d9")
sb = tk.Scrollbar(f31, orient=tk.VERTICAL)
e = tk.Entry(f31, textvariable=self.create_string_var(0), bg="white")
sb.config(command=partial(self.scrollbar_command, e, 5000))
e.grid()
sb.grid(row=0, column=1)
f31.grid(row=0, column=1)
f3.grid(sticky=tk.W, padx=4, pady=4)
f.grid(padx=3, pady=3)
def subnet(self):
f = tk.Frame(self.top)
f1 = tk.Frame(f)
lbl = tk.Label(f1, text="IPv4 subnet")
lbl.grid()
e = tk.Entry(f1, width=30, bg="white")
e.grid(row=0, column=1)
f1.grid()
f2 = tk.Frame(f)
lbl = tk.Label(f2, text="IPv6 subnet")
lbl.grid()
e = tk.Entry(f2, width=30, bg="white")
e.grid(row=0, column=1)
f2.grid()
f.grid(sticky=tk.W, padx=3, pady=3)
def wlan_options(self):
f = tk.Frame(self.top)
b = tk.Button(f, text="ns-2 mobility script...")
b.pack(side=tk.LEFT, padx=1)
b = tk.Button(f, text="Link to all routers")
b.pack(side=tk.LEFT, padx=1)
b = tk.Button(f, text="Choose WLAN members")
b.pack(side=tk.LEFT, padx=1)
f.grid(sticky=tk.W)
def config_option(self):
f = tk.Frame(self.top, bg="#d9d9d9")
b = tk.Button(f, text="Apply", bg="#d9d9d9")
b.grid(padx=2, pady=2)
b = tk.Button(f, text="Cancel", bg="#d9d9d9", command=self.top.destroy)
b.grid(row=0, column=1, padx=2, pady=2)
f.grid(padx=4, pady=4)