added node config interface display and updated canvas nodes to use core node porotbuf directly for display and saving data

This commit is contained in:
bharnden 2019-11-20 10:59:30 -08:00
parent 695f5c3e66
commit c43e5f999c
7 changed files with 124 additions and 49 deletions

View file

@ -30,7 +30,7 @@ class CanvasAction:
def display_wlan_configuration(self, canvas_node):
wlan_config = self.master.core.wlanconfig_management.configurations[
canvas_node.core_id
canvas_node.core_node.id
]
dialog = WlanConfigDialog(
self.master, self.master, self.node_to_show_config, wlan_config

View file

@ -20,6 +20,7 @@ class EmaneConfiguration(Dialog):
super().__init__(master, app, "emane configuration", modal=False)
self.app = app
self.canvas_node = canvas_node
self.node = canvas_node.core_node
self.radiovar = tk.IntVar()
self.radiovar.set(1)
self.columnconfigure(0, weight=1)
@ -122,20 +123,15 @@ class EmaneConfiguration(Dialog):
# add string emane_ infront for grpc call
response = self.app.core.client.set_emane_model_config(
self.app.core.session_id,
self.canvas_node.core_id,
"emane_" + model_name,
config,
self.app.core.session_id, self.node.id, f"emane_{model_name}", config
)
logging.info(
"emaneconfig.py config emane model (%s), result: %s",
self.canvas_node.core_id,
response,
"emaneconfig.py config emane model (%s), result: %s", self.node.id, response
)
# store the change locally
self.app.core.emaneconfig_management.set_custom_emane_cloud_config(
self.canvas_node.core_id, "emane_" + model_name
self.node.id, f"emane_{model_name}"
)
self.emane_model_dialog.destroy()
@ -161,7 +157,7 @@ class EmaneConfiguration(Dialog):
session_id = self.app.core.session_id
# add string emane_ before model name for grpc call
response = self.app.core.client.get_emane_model_config(
session_id, self.canvas_node.core_id, "emane_" + model_name
session_id, self.node.id, f"emane_{model_name}"
)
logging.info("emane model config %s", response)

View file

@ -19,9 +19,10 @@ class MobilityConfigDialog(Dialog):
"""
super().__init__(master, app, "ns2script configuration", modal=True)
self.canvas_node = canvas_node
self.node = canvas_node.core_node
logging.info(app.canvas.core.mobilityconfig_management.configurations)
self.node_config = app.canvas.core.mobilityconfig_management.configurations[
canvas_node.core_id
self.node.id
]
self.mobility_script_parameters()
@ -208,7 +209,7 @@ class MobilityConfigDialog(Dialog):
else:
loop = "0"
self.app.canvas.core.mobilityconfig_management.set_custom_configuration(
node_id=self.canvas_node.core_id,
node_id=self.node.id,
file=file,
refresh_ms=refresh_time,
loop=loop,

View file

@ -1,14 +1,36 @@
import logging
import tkinter as tk
from functools import partial
from tkinter import ttk
from coretk.dialogs.dialog import Dialog
from coretk.dialogs.icondialog import IconDialog
from coretk.dialogs.nodeservice import NodeService
from coretk.widgets import FrameScroll
DEFAULT_NODES = {"router", "host", "PC", "mdr", "prouter"}
PAD = 5
def mac_auto(is_auto, entry):
logging.info("mac auto clicked")
if is_auto.get():
logging.info("disabling mac")
entry.var.set("")
entry.config(state=tk.DISABLED)
else:
entry.var.set("00:00:00:00:00:00")
entry.config(state=tk.NORMAL)
class InterfaceData:
def __init__(self, is_auto, mac, ip4, ip6):
self.is_auto = is_auto
self.mac = mac
self.ip4 = ip4
self.ip6 = ip6
class NodeConfigDialog(Dialog):
def __init__(self, master, app, canvas_node):
"""
@ -18,13 +40,20 @@ class NodeConfigDialog(Dialog):
:param coretk.app.Application: main app
:param coretk.graph.CanvasNode canvas_node: canvas node object
"""
super().__init__(master, app, f"{canvas_node.name} Configuration", modal=True)
super().__init__(
master, app, f"{canvas_node.core_node.name} Configuration", modal=True
)
self.canvas_node = canvas_node
self.node = canvas_node.core_node
self.image = canvas_node.image
self.image_button = None
self.name = tk.StringVar(value=canvas_node.name)
self.type = tk.StringVar(value=canvas_node.core_node.model)
self.server = tk.StringVar()
self.name = tk.StringVar(value=self.node.name)
self.type = tk.StringVar(value=self.node.model)
server = "localhost"
if self.node.server:
server = self.node.server
self.server = tk.StringVar(value=server)
self.interfaces = {}
self.draw()
def draw(self):
@ -82,8 +111,50 @@ class NodeConfigDialog(Dialog):
button = ttk.Button(self.top, text="Services", command=self.click_services)
button.grid(sticky="ew", pady=PAD)
# interfaces
if self.canvas_node.interfaces:
self.draw_interfaces()
self.draw_buttons()
def draw_interfaces(self):
scroll = FrameScroll(self.top, self.app, text="Interfaces")
scroll.grid(sticky="nsew")
scroll.frame.columnconfigure(0, weight=1)
scroll.frame.rowconfigure(0, weight=1)
for interface in self.canvas_node.interfaces:
logging.info("interface: %s", interface)
frame = ttk.LabelFrame(scroll.frame, text=interface.name, padding=PAD)
frame.grid(sticky="ew", pady=PAD)
frame.columnconfigure(1, weight=1)
frame.columnconfigure(2, weight=1)
label = ttk.Label(frame, text="MAC")
label.grid(row=0, column=0, padx=PAD, pady=PAD)
is_auto = tk.BooleanVar(value=True)
checkbutton = ttk.Checkbutton(frame, text="Auto?", variable=is_auto)
checkbutton.var = is_auto
checkbutton.grid(row=0, column=1, padx=PAD)
mac = tk.StringVar(value=interface.mac)
entry = ttk.Entry(frame, textvariable=mac, state=tk.DISABLED)
entry.grid(row=0, column=2, sticky="ew")
func = partial(mac_auto, is_auto, entry)
checkbutton.config(command=func)
label = ttk.Label(frame, text="IPv4")
label.grid(row=1, column=0, padx=PAD, pady=PAD)
ip4 = tk.StringVar(value=f"{interface.ip4}/{interface.ip4mask}")
entry = ttk.Entry(frame, textvariable=ip4)
entry.grid(row=1, column=1, columnspan=2, sticky="ew")
label = ttk.Label(frame, text="IPv6")
label.grid(row=2, column=0, padx=PAD, pady=PAD)
ip6 = tk.StringVar(value=f"{interface.ip6}/{interface.ip6mask}")
entry = ttk.Entry(frame, textvariable=ip6)
entry.grid(row=2, column=1, columnspan=2, sticky="ew")
self.interfaces[interface.id] = InterfaceData(is_auto, mac, ip4, ip6)
def draw_buttons(self):
frame = ttk.Frame(self.top)
frame.grid(sticky="ew")
@ -101,16 +172,20 @@ class NodeConfigDialog(Dialog):
dialog.show()
def click_icon(self):
dialog = IconDialog(
self, self.app, self.canvas_node.name, self.canvas_node.image
)
dialog = IconDialog(self, self.app, self.node.name, self.canvas_node.image)
dialog.show()
if dialog.image:
self.image = dialog.image
self.image_button.config(image=self.image)
def config_apply(self):
self.canvas_node.name = self.name.get()
# update core node
self.node.name = self.name.get()
# update canvas node
self.canvas_node.image = self.image
self.canvas_node.canvas.itemconfig(self.canvas_node.id, image=self.image)
# redraw
self.canvas_node.redraw()
self.destroy()

View file

@ -13,13 +13,14 @@ from coretk.dialogs.mobilityconfig import MobilityConfigDialog
class WlanConfigDialog(Dialog):
def __init__(self, master, app, canvas_node, config):
super().__init__(
master, app, f"{canvas_node.name} Wlan Configuration", modal=True
master, app, f"{canvas_node.core_node.name} Wlan Configuration", modal=True
)
self.image = canvas_node.image
self.canvas_node = canvas_node
self.node = canvas_node.core_node
self.config = config
self.name = tk.StringVar(value=canvas_node.name)
self.name = tk.StringVar(value=self.node.name)
self.range_var = tk.StringVar(value=config["range"])
self.bandwidth_var = tk.StringVar(value=config["bandwidth"])
self.delay_var = tk.StringVar(value=config["delay"])
@ -169,9 +170,7 @@ class WlanConfigDialog(Dialog):
dialog.show()
def click_icon(self):
dialog = IconDialog(
self, self.app, self.canvas_node.name, self.canvas_node.image
)
dialog = IconDialog(self, self.app, self.node.name, self.canvas_node.image)
dialog.show()
if dialog.image:
self.image = dialog.image
@ -192,7 +191,7 @@ class WlanConfigDialog(Dialog):
# set wireless node configuration here
wlanconfig_manager = self.app.core.wlanconfig_management
wlanconfig_manager.set_custom_config(
node_id=self.canvas_node.core_id,
node_id=self.node.id,
range=basic_range,
bandwidth=bandwidth,
jitter=jitter,

View file

@ -155,21 +155,22 @@ class CanvasGraph(tk.Canvas):
# draw nodes on the canvas
image = NodeUtils.node_icon(core_node.type, core_node.model)
position = core_node.position
node = CanvasNode(position.x, position.y, image, self.master, core_node)
node = CanvasNode(self.master, core_node, image)
self.nodes[node.id] = node
self.core.canvas_nodes[core_node.id] = node
# draw existing links
for link in session.links:
canvas_node_one = self.core.canvas_nodes[link.node_one_id]
node_one = canvas_node_one.core_node
canvas_node_two = self.core.canvas_nodes[link.node_two_id]
node_two = canvas_node_two.core_node
is_wired = link.type == core_pb2.LinkType.WIRED
edge = CanvasEdge(
canvas_node_one.x_coord,
canvas_node_one.y_coord,
canvas_node_two.x_coord,
canvas_node_two.y_coord,
node_one.position.x,
node_one.position.y,
node_two.position.x,
node_two.position.y,
canvas_node_one.id,
self,
is_wired=is_wired,
@ -402,7 +403,7 @@ class CanvasGraph(tk.Canvas):
core_node = self.core.create_node(
int(x), int(y), self.node_draw.node_type, self.node_draw.model
)
node = CanvasNode(x, y, self.node_draw.image, self.master, core_node)
node = CanvasNode(self.master, core_node, self.node_draw.image)
self.core.canvas_nodes[core_node.id] = node
self.nodes[node.id] = node
return node
@ -590,19 +591,18 @@ class CanvasEdge:
class CanvasNode:
def __init__(self, x, y, image, app, core_node):
self.image = image
def __init__(self, app, core_node, image):
self.app = app
self.canvas = app.canvas
self.image = image
self.core_node = core_node
x = self.core_node.position.x
y = self.core_node.position.y
self.id = self.canvas.create_image(
x, y, anchor=tk.CENTER, image=self.image, tags="node"
)
self.core_node = core_node
self.name = core_node.name
self.x_coord = x
self.y_coord = y
self.text_id = self.canvas.create_text(
x, y + 20, text=self.name, tags="nodename"
x, y + 20, text=self.core_node.name, tags="nodename"
)
self.antenna_draw = WlanAntennaManager(self.canvas, self.id)
self.tooltip = CanvasTooltip(self.canvas)
@ -620,6 +620,10 @@ class CanvasNode:
self.wlans = []
self.moving = None
def redraw(self):
self.canvas.itemconfig(self.id, image=self.image)
self.canvas.itemconfig(self.text_id, text=self.core_node.name)
def on_enter(self, event):
if self.app.core.is_runtime() and self.app.core.observer:
self.tooltip.text.set("waiting...")
@ -640,18 +644,18 @@ class CanvasNode:
self.canvas.canvas_action.display_configuration(self)
def update_coords(self):
self.x_coord, self.y_coord = self.canvas.coords(self.id)
self.core_node.position.x = int(self.x_coord)
self.core_node.position.y = int(self.y_coord)
x, y = self.canvas.coords(self.id)
self.core_node.position.x = int(x)
self.core_node.position.y = int(y)
def click_press(self, event):
logging.debug(f"node click press {self.name}: {event}")
logging.debug(f"node click press {self.core_node.name}: {event}")
self.moving = self.canvas.canvas_xy(event)
self.canvas.canvas_management.node_select(self)
def click_release(self, event):
logging.debug(f"node click release {self.name}: {event}")
logging.debug(f"node click release {self.core_node.name}: {event}")
self.update_coords()
self.moving = None
@ -681,7 +685,6 @@ class CanvasNode:
else:
self.canvas.coords(edge.id, x1, y1, new_x, new_y)
edge.link_info.recalculate_info()
# self.canvas.core_grpc.throughput_draw.update_throughtput_location(edge)
self.canvas.helper.update_wlan_connection(
old_x, old_y, new_x, new_y, self.wlans
@ -691,4 +694,4 @@ class CanvasNode:
self.canvas.canvas_management.node_select(self, True)
def context(self, event):
logging.debug(f"context click {self.name}: {event}")
logging.debug(f"context click {self.core_node.name}: {event}")

View file

@ -85,7 +85,8 @@ def load(style):
"fieldbackground": Colors.white,
"foreground": Colors.black,
"padding": (2, 0),
}
},
"map": {"fieldbackground": [("disabled", Colors.frame)]},
},
"TCombobox": {
"configure": {