change to appropriate toolbar when join session, emane config, emane model config
This commit is contained in:
parent
68da6c0c14
commit
20637da140
7 changed files with 217 additions and 110 deletions
|
@ -7,6 +7,7 @@ from tkinter import ttk
|
||||||
class ConfigType(enum.Enum):
|
class ConfigType(enum.Enum):
|
||||||
STRING = 10
|
STRING = 10
|
||||||
BOOL = 11
|
BOOL = 11
|
||||||
|
EMANECONFIG = 7
|
||||||
|
|
||||||
|
|
||||||
def create_config(master, config, padx=2, pady=2):
|
def create_config(master, config, padx=2, pady=2):
|
||||||
|
@ -52,8 +53,13 @@ def create_config(master, config, padx=2, pady=2):
|
||||||
else:
|
else:
|
||||||
value.set("Off")
|
value.set("Off")
|
||||||
elif config_type == ConfigType.STRING:
|
elif config_type == ConfigType.STRING:
|
||||||
|
value.set(option.value)
|
||||||
entry = tk.Entry(frame, textvariable=value)
|
entry = tk.Entry(frame, textvariable=value)
|
||||||
entry.grid(row=index, column=1, sticky="ew", pady=pady)
|
entry.grid(row=index, column=1, sticky="ew", pady=pady)
|
||||||
|
elif config_type == ConfigType.EMANECONFIG:
|
||||||
|
value.set(option.value)
|
||||||
|
entry = tk.Entry(frame, textvariable=value, bg="white")
|
||||||
|
entry.grid(row=index, column=1, sticky="ew", pady=pady)
|
||||||
else:
|
else:
|
||||||
logging.error("unhandled config option type: %s", config_type)
|
logging.error("unhandled config option type: %s", config_type)
|
||||||
values[key] = value
|
values[key] = value
|
||||||
|
@ -68,7 +74,6 @@ def create_config(master, config, padx=2, pady=2):
|
||||||
canvas.bind(
|
canvas.bind(
|
||||||
"<Configure>", lambda event: canvas.itemconfig(frame_id, width=event.width)
|
"<Configure>", lambda event: canvas.itemconfig(frame_id, width=event.width)
|
||||||
)
|
)
|
||||||
|
|
||||||
return values
|
return values
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -80,6 +80,7 @@ class CoreClient:
|
||||||
self.core_mapping = CoreToCanvasMapping()
|
self.core_mapping = CoreToCanvasMapping()
|
||||||
self.wlanconfig_management = WlanNodeConfig()
|
self.wlanconfig_management = WlanNodeConfig()
|
||||||
self.mobilityconfig_management = MobilityNodeConfig()
|
self.mobilityconfig_management = MobilityNodeConfig()
|
||||||
|
self.emane_config = None
|
||||||
|
|
||||||
def handle_events(self, event):
|
def handle_events(self, event):
|
||||||
logging.info("event: %s", event)
|
logging.info("event: %s", event)
|
||||||
|
@ -110,11 +111,15 @@ class CoreClient:
|
||||||
self.nodes.clear()
|
self.nodes.clear()
|
||||||
self.edges.clear()
|
self.edges.clear()
|
||||||
self.hooks.clear()
|
self.hooks.clear()
|
||||||
|
self.wlanconfig_management.configurations.clear()
|
||||||
|
self.mobilityconfig_management.configurations.clear()
|
||||||
|
self.emane_config = None
|
||||||
|
|
||||||
# get session data
|
# get session data
|
||||||
response = self.client.get_session(self.session_id)
|
response = self.client.get_session(self.session_id)
|
||||||
logging.info("joining session(%s): %s", self.session_id, response)
|
logging.info("joining session(%s): %s", self.session_id, response)
|
||||||
session = response.session
|
session = response.session
|
||||||
|
session_state = session.state
|
||||||
self.client.events(self.session_id, self.handle_events)
|
self.client.events(self.session_id, self.handle_events)
|
||||||
|
|
||||||
# get hooks
|
# get hooks
|
||||||
|
@ -140,6 +145,11 @@ class CoreClient:
|
||||||
config = {x: node_config[x].value for x in node_config}
|
config = {x: node_config[x].value for x in node_config}
|
||||||
self.mobilityconfig_management.configurations[node_id] = config
|
self.mobilityconfig_management.configurations[node_id] = config
|
||||||
|
|
||||||
|
# get emane config
|
||||||
|
response = self.client.get_emane_config(self.session_id)
|
||||||
|
logging.info("emane config: %s", response)
|
||||||
|
self.emane_config = response.config
|
||||||
|
|
||||||
# determine next node id and reusable nodes
|
# determine next node id and reusable nodes
|
||||||
max_id = 1
|
max_id = 1
|
||||||
for node in session.nodes:
|
for node in session.nodes:
|
||||||
|
@ -154,6 +164,14 @@ class CoreClient:
|
||||||
# draw session
|
# draw session
|
||||||
self.app.canvas.canvas_reset_and_redraw(session)
|
self.app.canvas.canvas_reset_and_redraw(session)
|
||||||
|
|
||||||
|
# draw tool bar appropritate with session state
|
||||||
|
if session_state == core_pb2.SessionState.RUNTIME:
|
||||||
|
self.app.core_editbar.destroy_children_widgets()
|
||||||
|
self.app.core_editbar.create_runtime_toolbar()
|
||||||
|
else:
|
||||||
|
self.app.core_editbar.destroy_children_widgets()
|
||||||
|
self.app.core_editbar.create_toolbar()
|
||||||
|
|
||||||
def create_new_session(self):
|
def create_new_session(self):
|
||||||
"""
|
"""
|
||||||
Create a new session
|
Create a new session
|
||||||
|
@ -298,6 +316,7 @@ class CoreClient:
|
||||||
links,
|
links,
|
||||||
hooks=list(self.hooks.values()),
|
hooks=list(self.hooks.values()),
|
||||||
wlan_configs=wlan_configs,
|
wlan_configs=wlan_configs,
|
||||||
|
emane_config=emane_config,
|
||||||
)
|
)
|
||||||
logging.debug("Start session %s, result: %s", self.session_id, response.result)
|
logging.debug("Start session %s, result: %s", self.session_id, response.result)
|
||||||
|
|
||||||
|
|
|
@ -7,18 +7,6 @@ from coretk.graph import GraphMode
|
||||||
from coretk.images import ImageEnum, Images
|
from coretk.images import ImageEnum, Images
|
||||||
from coretk.tooltip import CreateToolTip
|
from coretk.tooltip import CreateToolTip
|
||||||
|
|
||||||
# from enum import Enum
|
|
||||||
|
|
||||||
|
|
||||||
# class SessionStateEnum(Enum):
|
|
||||||
# NONE = "none"
|
|
||||||
# DEFINITION = "definition"
|
|
||||||
# CONFIGURATION = "configuration"
|
|
||||||
# RUNTIME = "runtime"
|
|
||||||
# DATACOLLECT = "datacollect"
|
|
||||||
# SHUTDOWN = "shutdown"
|
|
||||||
# INSTANTIATION = "instantiation"
|
|
||||||
|
|
||||||
|
|
||||||
class CoreToolbar(object):
|
class CoreToolbar(object):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -3,6 +3,8 @@ CoreToolbar help to draw on canvas, and make grpc client call
|
||||||
"""
|
"""
|
||||||
from core.api.grpc.client import core_pb2
|
from core.api.grpc.client import core_pb2
|
||||||
|
|
||||||
|
# from coretk import configutils
|
||||||
|
|
||||||
|
|
||||||
class CoreToolbarHelp:
|
class CoreToolbarHelp:
|
||||||
def __init__(self, app):
|
def __init__(self, app):
|
||||||
|
@ -85,6 +87,15 @@ class CoreToolbarHelp:
|
||||||
links = self.get_link_list()
|
links = self.get_link_list()
|
||||||
wlan_configs = self.get_wlan_configuration_list()
|
wlan_configs = self.get_wlan_configuration_list()
|
||||||
mobility_configs = self.get_mobility_configuration_list()
|
mobility_configs = self.get_mobility_configuration_list()
|
||||||
|
|
||||||
|
# get emane config
|
||||||
|
pb_emane_config = self.app.core.emane_config
|
||||||
|
emane_config = {x: pb_emane_config[x].value for x in pb_emane_config}
|
||||||
|
|
||||||
self.app.core.start_session(
|
self.app.core.start_session(
|
||||||
nodes, links, wlan_configs=wlan_configs, mobility_configs=mobility_configs
|
nodes,
|
||||||
|
links,
|
||||||
|
wlan_configs=wlan_configs,
|
||||||
|
mobility_configs=mobility_configs,
|
||||||
|
emane_config=emane_config,
|
||||||
)
|
)
|
||||||
|
|
|
@ -5,11 +5,15 @@ emane configuration
|
||||||
import logging
|
import logging
|
||||||
import tkinter as tk
|
import tkinter as tk
|
||||||
import webbrowser
|
import webbrowser
|
||||||
|
from tkinter import ttk
|
||||||
|
|
||||||
|
from coretk import configutils
|
||||||
from coretk.dialogs.dialog import Dialog
|
from coretk.dialogs.dialog import Dialog
|
||||||
from coretk.dialogs.mobilityconfig import MobilityConfiguration
|
|
||||||
from coretk.images import ImageEnum, Images
|
from coretk.images import ImageEnum, Images
|
||||||
|
|
||||||
|
PAD_X = 2
|
||||||
|
PAD_Y = 2
|
||||||
|
|
||||||
|
|
||||||
class EmaneConfiguration(Dialog):
|
class EmaneConfiguration(Dialog):
|
||||||
def __init__(self, master, app, canvas_node):
|
def __init__(self, master, app, canvas_node):
|
||||||
|
@ -20,6 +24,13 @@ class EmaneConfiguration(Dialog):
|
||||||
self.radiovar.set(1)
|
self.radiovar.set(1)
|
||||||
self.columnconfigure(0, weight=1)
|
self.columnconfigure(0, weight=1)
|
||||||
|
|
||||||
|
# list(string) of emane models
|
||||||
|
self.emane_models = None
|
||||||
|
|
||||||
|
self.emane_dialog = Dialog(self, app, "emane configuration", modal=False)
|
||||||
|
self.emane_model_dialog = None
|
||||||
|
self.emane_model_combobox = None
|
||||||
|
|
||||||
# draw
|
# draw
|
||||||
self.node_name_and_image()
|
self.node_name_and_image()
|
||||||
self.emane_configuration()
|
self.emane_configuration()
|
||||||
|
@ -27,8 +38,10 @@ class EmaneConfiguration(Dialog):
|
||||||
self.emane_options()
|
self.emane_options()
|
||||||
self.draw_apply_and_cancel()
|
self.draw_apply_and_cancel()
|
||||||
|
|
||||||
def browse_emane_wiki(self):
|
self.values = None
|
||||||
webbrowser.open_new("https://github.com/adjacentlink/emane/wiki")
|
self.options = app.core.emane_config
|
||||||
|
self.model_options = None
|
||||||
|
self.model_values = None
|
||||||
|
|
||||||
def create_text_variable(self, val):
|
def create_text_variable(self, val):
|
||||||
"""
|
"""
|
||||||
|
@ -52,20 +65,109 @@ class EmaneConfiguration(Dialog):
|
||||||
e = tk.Entry(f, textvariable=self.create_text_variable(""), bg="white")
|
e = tk.Entry(f, textvariable=self.create_text_variable(""), bg="white")
|
||||||
e.grid(row=0, column=1, padx=2, pady=2)
|
e.grid(row=0, column=1, padx=2, pady=2)
|
||||||
|
|
||||||
om = tk.OptionMenu(
|
cbb = ttk.Combobox(f, values=["(none)", "core1", "core2"], state="readonly")
|
||||||
f,
|
cbb.current(0)
|
||||||
self.create_text_variable("None"),
|
cbb.grid(row=0, column=2, padx=2, pady=2)
|
||||||
"(none)",
|
|
||||||
"core1",
|
|
||||||
"core2",
|
|
||||||
command=self.choose_core,
|
|
||||||
)
|
|
||||||
om.grid(row=0, column=2, padx=2, pady=2)
|
|
||||||
|
|
||||||
b = tk.Button(f, image=self.canvas_node.image)
|
b = tk.Button(f, image=self.canvas_node.image)
|
||||||
b.grid(row=0, column=3, padx=2, pady=2)
|
b.grid(row=0, column=3, padx=2, pady=2)
|
||||||
|
|
||||||
f.grid(row=0, column=0, sticky=tk.N + tk.S + tk.E + tk.W)
|
f.grid(row=0, column=0, sticky="nsew")
|
||||||
|
|
||||||
|
def save_emane_option(self):
|
||||||
|
configutils.parse_config(self.options, self.values)
|
||||||
|
self.emane_dialog.destroy()
|
||||||
|
|
||||||
|
def draw_emane_options(self):
|
||||||
|
if not self.emane_dialog.winfo_exists():
|
||||||
|
self.emane_dialog = Dialog(
|
||||||
|
self, self.app, "emane configuration", modal=False
|
||||||
|
)
|
||||||
|
b1 = tk.Button(self.emane_dialog, text="Appy", command=self.save_emane_option)
|
||||||
|
b2 = tk.Button(
|
||||||
|
self.emane_dialog, text="Cancel", command=self.emane_dialog.destroy
|
||||||
|
)
|
||||||
|
|
||||||
|
if self.options is None:
|
||||||
|
session_id = self.app.core.session_id
|
||||||
|
response = self.app.core.client.get_emane_config(session_id)
|
||||||
|
logging.info("emane config: %s", response)
|
||||||
|
self.options = response.config
|
||||||
|
self.values = configutils.create_config(
|
||||||
|
self.emane_dialog, self.options, PAD_X, PAD_Y
|
||||||
|
)
|
||||||
|
b1.grid(row=1, column=0)
|
||||||
|
b2.grid(row=1, column=1)
|
||||||
|
self.emane_dialog.show()
|
||||||
|
|
||||||
|
def save_emane_model_options(self):
|
||||||
|
"""
|
||||||
|
configure the node's emane model on the fly
|
||||||
|
|
||||||
|
:return: nothing
|
||||||
|
"""
|
||||||
|
# get model name
|
||||||
|
model_name = self.emane_models[self.emane_model_combobox.current()]
|
||||||
|
|
||||||
|
# parse configuration
|
||||||
|
configutils.parse_config(self.model_options, self.model_values)
|
||||||
|
config = {x: self.model_options[x].value for x in self.model_options}
|
||||||
|
|
||||||
|
# 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,
|
||||||
|
)
|
||||||
|
logging.info(
|
||||||
|
"emaneconfig.py config emane model (%s), result: %s",
|
||||||
|
self.canvas_node.core_id,
|
||||||
|
response,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.emane_model_dialog.destroy()
|
||||||
|
|
||||||
|
def draw_model_options(self):
|
||||||
|
"""
|
||||||
|
draw emane model configuration
|
||||||
|
|
||||||
|
:return: nothing
|
||||||
|
"""
|
||||||
|
# get model name
|
||||||
|
model_name = self.emane_models[self.emane_model_combobox.current()]
|
||||||
|
|
||||||
|
# create the dialog and the necessry widget
|
||||||
|
if not self.emane_model_dialog or not self.emane_model_dialog.winfo_exists():
|
||||||
|
self.emane_model_dialog = Dialog(
|
||||||
|
self, self.app, model_name + " configuration", modal=False
|
||||||
|
)
|
||||||
|
|
||||||
|
b1 = tk.Button(
|
||||||
|
self.emane_model_dialog, text="Apply", command=self.save_emane_model_options
|
||||||
|
)
|
||||||
|
b2 = tk.Button(
|
||||||
|
self.emane_model_dialog,
|
||||||
|
text="Cancel",
|
||||||
|
command=self.emane_model_dialog.destroy,
|
||||||
|
)
|
||||||
|
|
||||||
|
# query for configurations
|
||||||
|
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
|
||||||
|
)
|
||||||
|
logging.info("emane model config %s", response)
|
||||||
|
|
||||||
|
self.model_options = response.config
|
||||||
|
self.model_values = configutils.create_config(
|
||||||
|
self.emane_model_dialog, self.model_options, PAD_X, PAD_Y
|
||||||
|
)
|
||||||
|
|
||||||
|
b1.grid(row=1, column=0, sticky="nsew")
|
||||||
|
b2.grid(row=1, column=1, sticky="nsew")
|
||||||
|
self.emane_model_dialog.show()
|
||||||
|
|
||||||
def draw_option_buttons(self, parent):
|
def draw_option_buttons(self, parent):
|
||||||
f = tk.Frame(parent, bg="#d9d9d9")
|
f = tk.Frame(parent, bg="#d9d9d9")
|
||||||
|
@ -73,60 +175,53 @@ class EmaneConfiguration(Dialog):
|
||||||
f.columnconfigure(1, weight=1)
|
f.columnconfigure(1, weight=1)
|
||||||
b = tk.Button(
|
b = tk.Button(
|
||||||
f,
|
f,
|
||||||
text="model options",
|
text=self.emane_models[0] + " options",
|
||||||
image=Images.get(ImageEnum.EDITNODE),
|
image=Images.get(ImageEnum.EDITNODE),
|
||||||
compound=tk.RIGHT,
|
compound=tk.RIGHT,
|
||||||
bg="#d9d9d9",
|
bg="#d9d9d9",
|
||||||
state=tk.DISABLED,
|
command=self.draw_model_options,
|
||||||
)
|
)
|
||||||
b.grid(row=0, column=0, padx=10, pady=2, sticky=tk.N + tk.S + tk.E + tk.W)
|
b.grid(row=0, column=0, padx=10, pady=2, sticky="nsew")
|
||||||
b = tk.Button(
|
b = tk.Button(
|
||||||
f,
|
f,
|
||||||
text="EMANE options",
|
text="EMANE options",
|
||||||
image=Images.get(ImageEnum.EDITNODE),
|
image=Images.get(ImageEnum.EDITNODE),
|
||||||
compound=tk.RIGHT,
|
compound=tk.RIGHT,
|
||||||
bg="#d9d9d9",
|
bg="#d9d9d9",
|
||||||
|
command=self.draw_emane_options,
|
||||||
)
|
)
|
||||||
b.grid(row=0, column=1, padx=10, pady=2, sticky=tk.N + tk.S + tk.E + tk.W)
|
b.grid(row=0, column=1, padx=10, pady=2, sticky="nsew")
|
||||||
f.grid(row=4, column=0, sticky=tk.N + tk.S + tk.E + tk.W)
|
f.grid(row=4, column=0, sticky="nsew")
|
||||||
|
|
||||||
def radiobutton_text(self, val):
|
def combobox_select(self, event):
|
||||||
"""
|
"""
|
||||||
get appropriate text based on radio value
|
update emane model options button
|
||||||
|
|
||||||
:return: the text value to configure button
|
:param event:
|
||||||
|
:return: nothing
|
||||||
"""
|
"""
|
||||||
if val == 1:
|
# get model name
|
||||||
return "none"
|
model_name = self.emane_models[self.emane_model_combobox.current()]
|
||||||
elif val == 2:
|
|
||||||
return "rfpipe options"
|
|
||||||
elif val == 3:
|
|
||||||
return "ieee80211abg options"
|
|
||||||
elif val == 4:
|
|
||||||
return "commeffect options"
|
|
||||||
elif val == 5:
|
|
||||||
return "bypass options"
|
|
||||||
elif val == 6:
|
|
||||||
return "tdma options"
|
|
||||||
else:
|
|
||||||
logging.debug("emaneconfig.py invalid radio value")
|
|
||||||
return ""
|
|
||||||
|
|
||||||
def click_radio_button(self):
|
# get the button and configure button text
|
||||||
print(type(self.radiovar.get()))
|
|
||||||
config_frame = self.grid_slaves(row=2, column=0)[0]
|
config_frame = self.grid_slaves(row=2, column=0)[0]
|
||||||
option_button_frame = config_frame.grid_slaves(row=4, column=0)[0]
|
option_button_frame = config_frame.grid_slaves(row=4, column=0)[0]
|
||||||
b = option_button_frame.grid_slaves(row=0, column=0)[0]
|
b = option_button_frame.grid_slaves(row=0, column=0)[0]
|
||||||
text = self.radiobutton_text(self.radiovar.get())
|
b.config(text=model_name + " options")
|
||||||
if text == "none":
|
|
||||||
state = tk.DISABLED
|
|
||||||
else:
|
|
||||||
state = tk.NORMAL
|
|
||||||
b.config(text=text, state=state)
|
|
||||||
# b.config(text=)
|
|
||||||
|
|
||||||
def draw_emane_models(self, parent):
|
def draw_emane_models(self, parent):
|
||||||
models = ["none", "rfpipe", "ieee80211abg", "commeffect", "bypass", "tdma"]
|
"""
|
||||||
|
create a combobox that has all the known emane models
|
||||||
|
|
||||||
|
:param parent: parent
|
||||||
|
:return: nothing
|
||||||
|
"""
|
||||||
|
# query for all the known model names
|
||||||
|
session_id = self.app.core.session_id
|
||||||
|
response = self.app.core.client.get_emane_models(session_id)
|
||||||
|
self.emane_models = [x.split("_")[1] for x in response.models]
|
||||||
|
|
||||||
|
# create combo box and its binding
|
||||||
f = tk.Frame(
|
f = tk.Frame(
|
||||||
parent,
|
parent,
|
||||||
bg="#d9d9d9",
|
bg="#d9d9d9",
|
||||||
|
@ -135,20 +230,12 @@ class EmaneConfiguration(Dialog):
|
||||||
highlightthickness=0.5,
|
highlightthickness=0.5,
|
||||||
bd=0,
|
bd=0,
|
||||||
)
|
)
|
||||||
value = 1
|
self.emane_model_combobox = ttk.Combobox(
|
||||||
for m in models:
|
f, values=self.emane_models, state="readonly"
|
||||||
b = tk.Radiobutton(
|
)
|
||||||
f,
|
self.emane_model_combobox.grid()
|
||||||
text=m,
|
self.emane_model_combobox.current(0)
|
||||||
variable=self.radiovar,
|
self.emane_model_combobox.bind("<<ComboboxSelected>>", self.combobox_select)
|
||||||
indicatoron=True,
|
|
||||||
value=value,
|
|
||||||
bg="#d9d9d9",
|
|
||||||
highlightthickness=0,
|
|
||||||
command=self.click_radio_button,
|
|
||||||
)
|
|
||||||
b.grid(sticky=tk.W)
|
|
||||||
value = value + 1
|
|
||||||
f.grid(row=3, column=0, sticky=tk.W + tk.E)
|
f.grid(row=3, column=0, sticky=tk.W + tk.E)
|
||||||
|
|
||||||
def draw_text_label_and_entry(self, parent, label_text, entry_text):
|
def draw_text_label_and_entry(self, parent, label_text, entry_text):
|
||||||
|
@ -164,11 +251,19 @@ class EmaneConfiguration(Dialog):
|
||||||
lbl.grid(row=0, column=0)
|
lbl.grid(row=0, column=0)
|
||||||
e = tk.Entry(f, textvariable=var, bg="white")
|
e = tk.Entry(f, textvariable=var, bg="white")
|
||||||
e.grid(row=0, column=1)
|
e.grid(row=0, column=1)
|
||||||
f.grid(stick=tk.W)
|
f.grid(stick=tk.W, padx=2, pady=2)
|
||||||
|
|
||||||
def emane_configuration(self):
|
def emane_configuration(self):
|
||||||
|
"""
|
||||||
|
draw the main frame for emane configuration
|
||||||
|
|
||||||
|
:return: nothing
|
||||||
|
"""
|
||||||
|
# draw label
|
||||||
lbl = tk.Label(self, text="Emane")
|
lbl = tk.Label(self, text="Emane")
|
||||||
lbl.grid(row=1, column=0)
|
lbl.grid(row=1, column=0)
|
||||||
|
|
||||||
|
# main frame that has emane wiki, a short description, emane models and the configure buttons
|
||||||
f = tk.Frame(
|
f = tk.Frame(
|
||||||
self,
|
self,
|
||||||
bg="#d9d9d9",
|
bg="#d9d9d9",
|
||||||
|
@ -187,7 +282,9 @@ class EmaneConfiguration(Dialog):
|
||||||
compound=tk.RIGHT,
|
compound=tk.RIGHT,
|
||||||
relief=tk.RAISED,
|
relief=tk.RAISED,
|
||||||
bg="#d9d9d9",
|
bg="#d9d9d9",
|
||||||
command=self.browse_emane_wiki,
|
command=lambda: webbrowser.open_new(
|
||||||
|
"https://github.com/adjacentlink/emane/wiki"
|
||||||
|
),
|
||||||
)
|
)
|
||||||
b.grid(row=0, column=0, sticky=tk.W)
|
b.grid(row=0, column=0, sticky=tk.W)
|
||||||
|
|
||||||
|
@ -197,54 +294,47 @@ class EmaneConfiguration(Dialog):
|
||||||
"\nusing pluggable MAC and PHY modules. Refer to the wiki for configuration option details",
|
"\nusing pluggable MAC and PHY modules. Refer to the wiki for configuration option details",
|
||||||
bg="#d9d9d9",
|
bg="#d9d9d9",
|
||||||
)
|
)
|
||||||
lbl.grid(row=1, column=0, sticky=tk.N + tk.S + tk.E + tk.W)
|
lbl.grid(row=1, column=0, sticky="nsew")
|
||||||
|
|
||||||
lbl = tk.Label(f, text="EMANE Models", bg="#d9d9d9")
|
lbl = tk.Label(f, text="EMANE Models", bg="#d9d9d9")
|
||||||
lbl.grid(row=2, column=0, sticky=tk.W)
|
lbl.grid(row=2, column=0, sticky=tk.W)
|
||||||
self.draw_option_buttons(f)
|
|
||||||
self.draw_emane_models(f)
|
self.draw_emane_models(f)
|
||||||
f.grid(row=2, column=0, sticky=tk.N + tk.S + tk.E + tk.W)
|
self.draw_option_buttons(f)
|
||||||
|
|
||||||
|
f.grid(row=2, column=0, sticky="nsew")
|
||||||
|
|
||||||
def draw_ip_subnets(self):
|
def draw_ip_subnets(self):
|
||||||
self.draw_text_label_and_entry(self, "IPv4 subnet", "")
|
self.draw_text_label_and_entry(self, "IPv4 subnet", "")
|
||||||
self.draw_text_label_and_entry(self, "IPv6 subnet", "")
|
self.draw_text_label_and_entry(self, "IPv6 subnet", "")
|
||||||
|
|
||||||
def click_ns2_mobility_script(self):
|
|
||||||
dialog = MobilityConfiguration(self, self.app, self.canvas_node)
|
|
||||||
dialog.show()
|
|
||||||
|
|
||||||
def emane_options(self):
|
def emane_options(self):
|
||||||
"""
|
"""
|
||||||
create wireless node options
|
create wireless node options
|
||||||
|
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
f = tk.Frame(self)
|
f = tk.Frame(self, bg="#d9d9d9")
|
||||||
f.columnconfigure(0, weight=1)
|
f.columnconfigure(0, weight=1)
|
||||||
f.columnconfigure(1, weight=1)
|
f.columnconfigure(1, weight=1)
|
||||||
f.columnconfigure(2, weight=1)
|
b = tk.Button(f, text="Link to all routers", bg="#d9d9d9")
|
||||||
b = tk.Button(
|
b.grid(row=0, column=0, padx=10, pady=2, sticky="nsew")
|
||||||
f,
|
b = tk.Button(f, text="Choose WLAN members", bg="#d9d9d9")
|
||||||
text="ns-2 mobility script...",
|
b.grid(row=0, column=1, padx=10, pady=2, sticky="nsew")
|
||||||
command=lambda: self.click_ns2_mobility_script(),
|
f.grid(row=5, column=0, sticky="nsew")
|
||||||
)
|
|
||||||
# b.pack(side=tk.LEFT, padx=1)
|
def apply(self):
|
||||||
b.grid(row=0, column=0, padx=10, pady=2, sticky=tk.N + tk.S + tk.E + tk.W)
|
# save emane configuration
|
||||||
b = tk.Button(f, text="Link to all routers")
|
self.app.core.emane_config = self.options
|
||||||
b.grid(row=0, column=1, padx=10, pady=2, sticky=tk.N + tk.S + tk.E + tk.W)
|
self.destroy()
|
||||||
# b.pack(side=tk.LEFT, padx=1)
|
|
||||||
b = tk.Button(f, text="Choose WLAN members")
|
|
||||||
b.grid(row=0, column=2, padx=10, pady=2, sticky=tk.N + tk.S + tk.E + tk.W)
|
|
||||||
# b.pack(side=tk.LEFT, padx=1)
|
|
||||||
f.grid(row=5, column=0, sticky=tk.N + tk.S + tk.E + tk.W)
|
|
||||||
|
|
||||||
def draw_apply_and_cancel(self):
|
def draw_apply_and_cancel(self):
|
||||||
f = tk.Frame(self, bg="#d9d9d9")
|
f = tk.Frame(self, bg="#d9d9d9")
|
||||||
f.columnconfigure(0, weight=1)
|
f.columnconfigure(0, weight=1)
|
||||||
f.columnconfigure(1, weight=1)
|
f.columnconfigure(1, weight=1)
|
||||||
b = tk.Button(f, text="Apply", bg="#d9d9d9")
|
b = tk.Button(f, text="Apply", bg="#d9d9d9", command=self.apply)
|
||||||
b.grid(row=0, column=0, padx=10, pady=2, sticky=tk.N + tk.S + tk.E + tk.W)
|
b.grid(row=0, column=0, padx=10, pady=2, sticky="nsew")
|
||||||
b = tk.Button(f, text="Cancel", bg="#d9d9d9", command=self.destroy)
|
b = tk.Button(f, text="Cancel", bg="#d9d9d9", command=self.destroy)
|
||||||
b.grid(row=0, column=1, padx=10, pady=2, sticky=tk.N + tk.S + tk.E + tk.W)
|
b.grid(row=0, column=1, padx=10, pady=2, sticky="nsew")
|
||||||
|
|
||||||
f.grid(sticky=tk.N + tk.S + tk.E + tk.W)
|
f.grid(sticky="nsew")
|
||||||
|
|
|
@ -223,12 +223,6 @@ class CanvasGraph(tk.Canvas):
|
||||||
for i in self.find_withtag("node"):
|
for i in self.find_withtag("node"):
|
||||||
self.lift(i)
|
self.lift(i)
|
||||||
|
|
||||||
# def delete_components(self):
|
|
||||||
# tags = ["node", "edge", "linkinfo", "nodename"]
|
|
||||||
# for i in tags:
|
|
||||||
# for id in self.find_withtag(i):
|
|
||||||
# self.delete(id)
|
|
||||||
|
|
||||||
def canvas_xy(self, event):
|
def canvas_xy(self, event):
|
||||||
"""
|
"""
|
||||||
Convert window coordinate to canvas coordinate
|
Convert window coordinate to canvas coordinate
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"root": {
|
"root": {
|
||||||
"level": "INFO",
|
"level": "DEBUG",
|
||||||
"handlers": ["console"]
|
"handlers": ["console"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue