cleanup for app toolbar, updated toolbar to use grid layout
This commit is contained in:
parent
2873c32c23
commit
4970fb0d55
4 changed files with 234 additions and 462 deletions
|
@ -50,10 +50,8 @@ class Application(tk.Frame):
|
|||
self.master.config(menu=self.menubar)
|
||||
|
||||
def draw_toolbar(self):
|
||||
edit_frame = tk.Frame(self)
|
||||
edit_frame.pack(side=tk.LEFT, fill=tk.Y, ipadx=2, ipady=2)
|
||||
self.core_editbar = CoreToolbar(self, edit_frame, self.menubar)
|
||||
self.core_editbar.create_toolbar()
|
||||
self.core_editbar = CoreToolbar(self, self)
|
||||
self.core_editbar.pack(side=tk.LEFT, fill=tk.Y, ipadx=2, ipady=2)
|
||||
|
||||
def draw_canvas(self):
|
||||
self.canvas = CanvasGraph(
|
||||
|
|
|
@ -13,8 +13,8 @@ from coretk.interface import Interface, InterfaceManager
|
|||
from coretk.mobilitynodeconfig import MobilityNodeConfig
|
||||
from coretk.wlannodeconfig import WlanNodeConfig
|
||||
|
||||
link_layer_nodes = ["switch", "hub", "wlan", "rj45", "tunnel"]
|
||||
network_layer_nodes = ["router", "host", "PC", "mdr", "prouter", "OVS"]
|
||||
link_layer_nodes = ["switch", "hub", "wlan", "rj45", "tunnel", "emane"]
|
||||
network_layer_nodes = ["router", "host", "PC", "mdr", "prouter"]
|
||||
|
||||
|
||||
class Node:
|
||||
|
@ -205,11 +205,9 @@ class CoreClient:
|
|||
|
||||
# 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()
|
||||
self.app.core_editbar.runtime_frame.tkraise()
|
||||
else:
|
||||
self.app.core_editbar.destroy_children_widgets()
|
||||
self.app.core_editbar.create_toolbar()
|
||||
self.app.core_editbar.design_frame.tkraise()
|
||||
|
||||
def create_new_session(self):
|
||||
"""
|
||||
|
@ -447,26 +445,26 @@ class CoreClient:
|
|||
node_type = core_pb2.NodeType.WIRELESS_LAN
|
||||
elif name == "rj45":
|
||||
node_type = core_pb2.NodeType.RJ45
|
||||
elif name == "emane":
|
||||
node_type = core_pb2.NodeType.EMANE
|
||||
elif name == "tunnel":
|
||||
node_type = core_pb2.NodeType.TUNNEL
|
||||
elif name in network_layer_nodes:
|
||||
node_type = core_pb2.NodeType.DEFAULT
|
||||
node_model = name
|
||||
else:
|
||||
logging.error("grpcmanagemeny.py INVALID node name")
|
||||
logging.error("invalid node name: %s", name)
|
||||
nid = self.get_id()
|
||||
create_node = Node(session_id, nid, node_type, node_model, x, y, name)
|
||||
|
||||
# set default configuration for wireless node
|
||||
self.wlanconfig_management.set_default_config(node_type, nid)
|
||||
|
||||
self.mobilityconfig_management.set_default_configuration(node_type, nid)
|
||||
|
||||
self.nodes[canvas_id] = create_node
|
||||
self.core_mapping.map_core_id_to_canvas_id(nid, canvas_id)
|
||||
# self.core_id_to_canvas_id[nid] = canvas_id
|
||||
logging.debug(
|
||||
"Adding node to GrpcManager.. Session id: %s, Coords: (%s, %s), Name: %s",
|
||||
"Adding node to core.. session id: %s, coords: (%s, %s), name: %s",
|
||||
session_id,
|
||||
x,
|
||||
y,
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import logging
|
||||
import tkinter as tk
|
||||
from functools import partial
|
||||
|
||||
from coretk.coretoolbarhelp import CoreToolbarHelp
|
||||
from coretk.dialogs.customnodes import CustomNodesDialog
|
||||
|
@ -8,21 +9,20 @@ from coretk.images import ImageEnum, Images
|
|||
from coretk.tooltip import CreateToolTip
|
||||
|
||||
|
||||
class CoreToolbar(object):
|
||||
class CoreToolbar(tk.Frame):
|
||||
"""
|
||||
Core toolbar class
|
||||
"""
|
||||
|
||||
def __init__(self, app, edit_frame, menubar):
|
||||
def __init__(self, master, app, cnf={}, **kwargs):
|
||||
"""
|
||||
Create a CoreToolbar instance
|
||||
|
||||
:param tkinter.Frame edit_frame: edit frame
|
||||
"""
|
||||
super().__init__(master, cnf, **kwargs)
|
||||
self.app = app
|
||||
self.master = app.master
|
||||
self.edit_frame = edit_frame
|
||||
self.menubar = menubar
|
||||
self.radio_value = tk.IntVar()
|
||||
self.exec_radio_value = tk.IntVar()
|
||||
|
||||
|
@ -30,44 +30,144 @@ class CoreToolbar(object):
|
|||
self.width = 32
|
||||
self.height = 32
|
||||
|
||||
self.selection_tool_button = None
|
||||
|
||||
# Reference to the option menus
|
||||
self.selection_tool_button = None
|
||||
self.link_layer_option_menu = None
|
||||
self.marker_option_menu = None
|
||||
self.network_layer_option_menu = None
|
||||
|
||||
self.canvas = None
|
||||
self.node_button = None
|
||||
self.network_button = None
|
||||
self.annotation_button = None
|
||||
|
||||
def destroy_previous_frame(self):
|
||||
"""
|
||||
Destroy any extra frame from previous before drawing a new one
|
||||
# frames
|
||||
self.design_frame = None
|
||||
self.runtime_frame = None
|
||||
self.node_picker = None
|
||||
self.network_picker = None
|
||||
self.annotation_picker = None
|
||||
|
||||
:return: nothing
|
||||
"""
|
||||
if (
|
||||
self.network_layer_option_menu
|
||||
and self.network_layer_option_menu.winfo_exists()
|
||||
):
|
||||
self.network_layer_option_menu.destroy()
|
||||
if self.link_layer_option_menu and self.link_layer_option_menu.winfo_exists():
|
||||
self.link_layer_option_menu.destroy()
|
||||
if self.marker_option_menu and self.marker_option_menu.winfo_exists():
|
||||
self.marker_option_menu.destroy()
|
||||
# draw components
|
||||
self.draw()
|
||||
|
||||
def destroy_children_widgets(self):
|
||||
"""
|
||||
Destroy all children of a parent widget
|
||||
def draw(self):
|
||||
self.columnconfigure(0, weight=1)
|
||||
self.rowconfigure(0, weight=1)
|
||||
self.draw_design_frame()
|
||||
self.draw_runtime_frame()
|
||||
self.design_frame.tkraise()
|
||||
|
||||
:param tkinter.Frame parent: parent frame
|
||||
:return: nothing
|
||||
"""
|
||||
def draw_design_frame(self):
|
||||
self.design_frame = tk.Frame(self)
|
||||
self.design_frame.grid(row=0, column=0, sticky="nsew")
|
||||
self.design_frame.columnconfigure(0, weight=1)
|
||||
|
||||
for i in self.edit_frame.winfo_children():
|
||||
if i.winfo_name() != "!frame":
|
||||
i.destroy()
|
||||
self.create_regular_button(
|
||||
self.design_frame,
|
||||
Images.get(ImageEnum.START),
|
||||
self.click_start_session_tool,
|
||||
"start the session",
|
||||
)
|
||||
self.create_radio_button(
|
||||
self.design_frame,
|
||||
Images.get(ImageEnum.SELECT),
|
||||
self.click_selection_tool,
|
||||
self.radio_value,
|
||||
1,
|
||||
"selection tool",
|
||||
)
|
||||
self.create_radio_button(
|
||||
self.design_frame,
|
||||
Images.get(ImageEnum.LINK),
|
||||
self.click_link_tool,
|
||||
self.radio_value,
|
||||
2,
|
||||
"link tool",
|
||||
)
|
||||
self.create_node_button()
|
||||
self.create_link_layer_button()
|
||||
self.create_marker_button()
|
||||
self.radio_value.set(1)
|
||||
|
||||
def create_button(self, img, func, frame, main_button, btt_message):
|
||||
def draw_runtime_frame(self):
|
||||
self.runtime_frame = tk.Frame(self)
|
||||
self.runtime_frame.grid(row=0, column=0, sticky="nsew")
|
||||
self.runtime_frame.columnconfigure(0, weight=1)
|
||||
|
||||
self.create_regular_button(
|
||||
self.runtime_frame,
|
||||
Images.get(ImageEnum.STOP),
|
||||
self.click_stop_button,
|
||||
"stop the session",
|
||||
)
|
||||
self.create_radio_button(
|
||||
self.runtime_frame,
|
||||
Images.get(ImageEnum.SELECT),
|
||||
self.click_selection_tool,
|
||||
self.exec_radio_value,
|
||||
1,
|
||||
"selection tool",
|
||||
)
|
||||
self.create_observe_button()
|
||||
self.create_radio_button(
|
||||
self.runtime_frame,
|
||||
Images.get(ImageEnum.PLOT),
|
||||
self.click_plot_button,
|
||||
self.exec_radio_value,
|
||||
2,
|
||||
"plot",
|
||||
)
|
||||
self.create_radio_button(
|
||||
self.runtime_frame,
|
||||
Images.get(ImageEnum.MARKER),
|
||||
self.click_marker_button,
|
||||
self.exec_radio_value,
|
||||
3,
|
||||
"marker",
|
||||
)
|
||||
self.create_radio_button(
|
||||
self.runtime_frame,
|
||||
Images.get(ImageEnum.TWONODE),
|
||||
self.click_two_node_button,
|
||||
self.exec_radio_value,
|
||||
4,
|
||||
"run command from one node to another",
|
||||
)
|
||||
self.create_regular_button(
|
||||
self.runtime_frame, Images.get(ImageEnum.RUN), self.click_run_button, "run"
|
||||
)
|
||||
self.exec_radio_value.set(1)
|
||||
|
||||
def draw_node_picker(self):
|
||||
self.hide_pickers()
|
||||
self.node_picker = tk.Frame(self.master, padx=1, pady=1)
|
||||
nodes = [
|
||||
(ImageEnum.ROUTER, "router"),
|
||||
(ImageEnum.HOST, "host"),
|
||||
(ImageEnum.PC, "PC"),
|
||||
(ImageEnum.MDR, "mdr"),
|
||||
(ImageEnum.PROUTER, "prouter"),
|
||||
(ImageEnum.EDITNODE, "custom node types"),
|
||||
]
|
||||
for image_enum, tooltip in nodes:
|
||||
self.create_button(
|
||||
Images.get(image_enum),
|
||||
partial(self.update_button, self.node_button, image_enum, tooltip),
|
||||
self.node_picker,
|
||||
tooltip,
|
||||
)
|
||||
self.show_picker(self.node_button, self.node_picker)
|
||||
|
||||
def show_picker(self, button, picker):
|
||||
first_button = self.winfo_children()[0]
|
||||
x = button.winfo_rootx() - first_button.winfo_rootx() + 40
|
||||
y = button.winfo_rooty() - first_button.winfo_rooty() - 1
|
||||
picker.place(x=x, y=y)
|
||||
self.app.bind_all("<Button-1>", lambda e: self.hide_pickers())
|
||||
self.wait_window(picker)
|
||||
self.app.unbind_all("<Button-1>")
|
||||
|
||||
def create_button(self, img, func, frame, tooltip):
|
||||
"""
|
||||
Create button and put it on the frame
|
||||
|
||||
|
@ -78,9 +178,9 @@ class CoreToolbar(object):
|
|||
:return: nothing
|
||||
"""
|
||||
button = tk.Button(frame, width=self.width, height=self.height, image=img)
|
||||
button.bind("<Button-1>", lambda e: func())
|
||||
button.pack(side=tk.LEFT, pady=1)
|
||||
CreateToolTip(button, btt_message)
|
||||
button.bind("<Button-1>", lambda mb: func(main_button))
|
||||
CreateToolTip(button, tooltip)
|
||||
|
||||
def create_radio_button(self, frame, image, func, variable, value, tooltip_msg):
|
||||
button = tk.Radiobutton(
|
||||
|
@ -93,326 +193,108 @@ class CoreToolbar(object):
|
|||
variable=variable,
|
||||
command=func,
|
||||
)
|
||||
button.pack(side=tk.TOP, pady=1)
|
||||
button.grid()
|
||||
CreateToolTip(button, tooltip_msg)
|
||||
|
||||
def create_regular_button(self, frame, image, func, btt_message):
|
||||
def create_regular_button(self, frame, image, func, tooltip):
|
||||
button = tk.Button(
|
||||
frame, width=self.width, height=self.height, image=image, command=func
|
||||
)
|
||||
button.pack(side=tk.TOP, pady=1)
|
||||
CreateToolTip(button, btt_message)
|
||||
|
||||
def draw_button_menu_frame(self, edit_frame, option_frame, main_button):
|
||||
"""
|
||||
Draw option menu frame right next to the main button
|
||||
|
||||
:param tkinter.Frame edit_frame: parent frame of the main button
|
||||
:param tkinter.Frame option_frame: option frame to draw
|
||||
:param tkinter.Radiobutton main_button: the main button
|
||||
:return: nothing
|
||||
"""
|
||||
|
||||
first_button = edit_frame.winfo_children()[0]
|
||||
_x = main_button.winfo_rootx() - first_button.winfo_rootx() + 40
|
||||
_y = main_button.winfo_rooty() - first_button.winfo_rooty() - 1
|
||||
option_frame.place(x=_x, y=_y)
|
||||
|
||||
def bind_widgets_before_frame_hide(self, frame):
|
||||
"""
|
||||
Bind the widgets to a left click, when any of the widgets is clicked, the menu option frame is destroyed before
|
||||
any further action is performed
|
||||
|
||||
:param tkinter.Frame frame: the frame to be destroyed
|
||||
:return: nothing
|
||||
"""
|
||||
self.menubar.bind("<Button-1>", lambda e: frame.destroy())
|
||||
self.master.bind("<Button-1>", lambda e: frame.destroy())
|
||||
|
||||
def unbind_widgets_after_frame_hide(self):
|
||||
"""
|
||||
Unbind the widgets to make sure everything works normally again after the menu option frame is destroyed
|
||||
|
||||
:return: nothing
|
||||
"""
|
||||
self.master.unbind("<Button-1>")
|
||||
self.menubar.unbind("Button-1>")
|
||||
button.grid()
|
||||
CreateToolTip(button, tooltip)
|
||||
|
||||
def click_selection_tool(self):
|
||||
logging.debug("Click SELECTION TOOL")
|
||||
logging.debug("clicked selection tool")
|
||||
self.canvas.mode = GraphMode.SELECT
|
||||
|
||||
def click_start_session_tool(self):
|
||||
"""
|
||||
Start session handler: redraw buttons, send node and link messages to grpc server
|
||||
Start session handler redraw buttons, send node and link messages to grpc
|
||||
server.
|
||||
|
||||
:return: nothing
|
||||
"""
|
||||
logging.debug("Click START STOP SESSION button")
|
||||
logging.debug("clicked start button")
|
||||
helper = CoreToolbarHelp(self.app)
|
||||
self.destroy_children_widgets()
|
||||
self.canvas.mode = GraphMode.SELECT
|
||||
|
||||
# set configuration state
|
||||
# state = self.canvas.core_grpc.get_session_state()
|
||||
# if state == core_pb2.SessionState.SHUTDOWN or self.application.is_open_xml:
|
||||
# self.canvas.core_grpc.set_session_state(SessionStateEnum.DEFINITION.value)
|
||||
# self.application.is_open_xml = False
|
||||
#
|
||||
# self.canvas.core_grpc.set_session_state(SessionStateEnum.CONFIGURATION.value)
|
||||
# helper.add_nodes()
|
||||
# helper.add_edges()
|
||||
# self.canvas.core_grpc.set_session_state(SessionStateEnum.INSTANTIATION.value)
|
||||
helper.gui_start_session()
|
||||
self.create_runtime_toolbar()
|
||||
|
||||
# for node in self.canvas.grpc_manager.nodes.values():
|
||||
# print(node.type, node.model, int(node.x), int(node.y), node.name, node.node_id)
|
||||
# self.canvas.core_grpc.add_node(
|
||||
# node.type, node.model, int(node.x), int(node.y), node.name, node.node_id
|
||||
# )
|
||||
|
||||
# print(len(self.canvas.grpc_manager.edges))
|
||||
# for edge in self.canvas.grpc_manager.edges.values():
|
||||
# print(edge.id1, edge.id2, edge.type1, edge.type2)
|
||||
# self.canvas.core_grpc.add_link(
|
||||
# edge.id1, edge.id2, edge.type1, edge.type2, edge
|
||||
# )
|
||||
# self.canvas.core_grpc.get_session()
|
||||
# self.application.is_open_xml = False
|
||||
self.runtime_frame.tkraise()
|
||||
|
||||
def click_link_tool(self):
|
||||
logging.debug("Click LINK button")
|
||||
self.canvas.mode = GraphMode.EDGE
|
||||
|
||||
def pick_router(self, main_button):
|
||||
logging.debug("Pick router option")
|
||||
self.network_layer_option_menu.destroy()
|
||||
main_button.configure(image=Images.get(ImageEnum.ROUTER))
|
||||
self.canvas.mode = GraphMode.PICKNODE
|
||||
self.canvas.draw_node_image = Images.get(ImageEnum.ROUTER)
|
||||
self.canvas.draw_node_name = "router"
|
||||
def update_button(self, button, image_enum, name):
|
||||
logging.info("update button(%s): %s, %s", button, image_enum, name)
|
||||
self.hide_pickers()
|
||||
if image_enum == ImageEnum.EDITNODE:
|
||||
dialog = CustomNodesDialog(self.app, self.app)
|
||||
dialog.show()
|
||||
else:
|
||||
image = Images.get(image_enum)
|
||||
logging.info("updating button(%s): %s", button, name)
|
||||
button.configure(image=image)
|
||||
self.canvas.mode = GraphMode.NODE
|
||||
self.canvas.draw_node_image = image
|
||||
self.canvas.draw_node_name = name
|
||||
|
||||
def pick_host(self, main_button):
|
||||
logging.debug("Pick host option")
|
||||
self.network_layer_option_menu.destroy()
|
||||
main_button.configure(image=Images.get(ImageEnum.HOST))
|
||||
self.canvas.mode = GraphMode.PICKNODE
|
||||
self.canvas.draw_node_image = Images.get(ImageEnum.HOST)
|
||||
self.canvas.draw_node_name = "host"
|
||||
def hide_pickers(self):
|
||||
logging.info("hiding pickers")
|
||||
if self.node_picker:
|
||||
self.node_picker.destroy()
|
||||
self.node_picker = None
|
||||
if self.network_picker:
|
||||
self.network_picker.destroy()
|
||||
self.network_picker = None
|
||||
if self.annotation_picker:
|
||||
self.annotation_picker.destroy()
|
||||
self.annotation_picker = None
|
||||
|
||||
def pick_pc(self, main_button):
|
||||
logging.debug("Pick PC option")
|
||||
self.network_layer_option_menu.destroy()
|
||||
main_button.configure(image=Images.get(ImageEnum.PC))
|
||||
self.canvas.mode = GraphMode.PICKNODE
|
||||
self.canvas.draw_node_image = Images.get(ImageEnum.PC)
|
||||
self.canvas.draw_node_name = "PC"
|
||||
|
||||
def pick_mdr(self, main_button):
|
||||
logging.debug("Pick MDR option")
|
||||
self.network_layer_option_menu.destroy()
|
||||
main_button.configure(image=Images.get(ImageEnum.MDR))
|
||||
self.canvas.mode = GraphMode.PICKNODE
|
||||
self.canvas.draw_node_image = Images.get(ImageEnum.MDR)
|
||||
self.canvas.draw_node_name = "mdr"
|
||||
|
||||
def pick_prouter(self, main_button):
|
||||
logging.debug("Pick prouter option")
|
||||
self.network_layer_option_menu.destroy()
|
||||
main_button.configure(image=Images.get(ImageEnum.PROUTER))
|
||||
self.canvas.mode = GraphMode.PICKNODE
|
||||
self.canvas.draw_node_image = Images.get(ImageEnum.PROUTER)
|
||||
self.canvas.draw_node_name = "prouter"
|
||||
|
||||
def pick_ovs(self, main_button):
|
||||
logging.debug("Pick OVS option")
|
||||
self.network_layer_option_menu.destroy()
|
||||
main_button.configure(image=Images.get(ImageEnum.OVS))
|
||||
self.canvas.mode = GraphMode.PICKNODE
|
||||
self.canvas.draw_node_image = Images.get(ImageEnum.OVS)
|
||||
self.canvas.draw_node_name = "OVS"
|
||||
|
||||
def pick_editnode(self, main_button):
|
||||
self.network_layer_option_menu.destroy()
|
||||
main_button.configure(image=Images.get(ImageEnum.EDITNODE))
|
||||
logging.debug("Pick editnode option")
|
||||
dialog = CustomNodesDialog(self.app, self.app)
|
||||
dialog.show()
|
||||
|
||||
def draw_network_layer_options(self, network_layer_button):
|
||||
"""
|
||||
Draw the options for network-layer button
|
||||
|
||||
:param tkinter.Radiobutton network_layer_button: network-layer button
|
||||
:return: nothing
|
||||
"""
|
||||
# create a frame and add buttons to it
|
||||
self.destroy_previous_frame()
|
||||
option_frame = tk.Frame(self.master, padx=1, pady=1)
|
||||
img_list = [
|
||||
Images.get(ImageEnum.ROUTER),
|
||||
Images.get(ImageEnum.HOST),
|
||||
Images.get(ImageEnum.PC),
|
||||
Images.get(ImageEnum.MDR),
|
||||
Images.get(ImageEnum.PROUTER),
|
||||
Images.get(ImageEnum.OVS),
|
||||
Images.get(ImageEnum.EDITNODE),
|
||||
]
|
||||
func_list = [
|
||||
self.pick_router,
|
||||
self.pick_host,
|
||||
self.pick_pc,
|
||||
self.pick_mdr,
|
||||
self.pick_prouter,
|
||||
self.pick_ovs,
|
||||
self.pick_editnode,
|
||||
]
|
||||
tooltip_list = [
|
||||
"router",
|
||||
"host",
|
||||
"PC",
|
||||
"mdr",
|
||||
"prouter",
|
||||
"OVS",
|
||||
"edit node types",
|
||||
]
|
||||
for i in range(len(img_list)):
|
||||
self.create_button(
|
||||
img_list[i],
|
||||
func_list[i],
|
||||
option_frame,
|
||||
network_layer_button,
|
||||
tooltip_list[i],
|
||||
)
|
||||
|
||||
# place frame at a calculated position as well as keep a reference of that frame
|
||||
self.draw_button_menu_frame(self.edit_frame, option_frame, network_layer_button)
|
||||
self.network_layer_option_menu = option_frame
|
||||
|
||||
# destroy the frame before any further actions on other widgets
|
||||
self.bind_widgets_before_frame_hide(option_frame)
|
||||
option_frame.wait_window(option_frame)
|
||||
self.unbind_widgets_after_frame_hide()
|
||||
|
||||
def create_network_layer_button(self):
|
||||
def create_node_button(self):
|
||||
"""
|
||||
Create network layer button
|
||||
|
||||
:return: nothing
|
||||
"""
|
||||
router_image = Images.get(ImageEnum.ROUTER)
|
||||
network_layer_button = tk.Radiobutton(
|
||||
self.edit_frame,
|
||||
self.node_button = tk.Radiobutton(
|
||||
self.design_frame,
|
||||
indicatoron=False,
|
||||
variable=self.radio_value,
|
||||
value=3,
|
||||
width=self.width,
|
||||
height=self.height,
|
||||
image=router_image,
|
||||
command=lambda: self.draw_network_layer_options(network_layer_button),
|
||||
command=self.draw_node_picker,
|
||||
)
|
||||
network_layer_button.pack(side=tk.TOP, pady=1)
|
||||
CreateToolTip(network_layer_button, "Network-layer virtual nodes")
|
||||
self.node_button.grid()
|
||||
CreateToolTip(self.node_button, "Network-layer virtual nodes")
|
||||
|
||||
def pick_hub(self, main_button):
|
||||
logging.debug("Pick link-layer node HUB")
|
||||
self.link_layer_option_menu.destroy()
|
||||
main_button.configure(image=Images.get(ImageEnum.HUB))
|
||||
self.canvas.mode = GraphMode.PICKNODE
|
||||
self.canvas.draw_node_image = Images.get(ImageEnum.HUB)
|
||||
self.canvas.draw_node_name = "hub"
|
||||
|
||||
def pick_switch(self, main_button):
|
||||
logging.debug("Pick link-layer node SWITCH")
|
||||
self.link_layer_option_menu.destroy()
|
||||
main_button.configure(image=Images.get(ImageEnum.SWITCH))
|
||||
self.canvas.mode = GraphMode.PICKNODE
|
||||
self.canvas.draw_node_image = Images.get(ImageEnum.SWITCH)
|
||||
self.canvas.draw_node_name = "switch"
|
||||
|
||||
def pick_wlan(self, main_button):
|
||||
logging.debug("Pick link-layer node WLAN")
|
||||
self.link_layer_option_menu.destroy()
|
||||
main_button.configure(image=Images.get(ImageEnum.WLAN))
|
||||
self.canvas.mode = GraphMode.PICKNODE
|
||||
self.canvas.draw_node_image = Images.get(ImageEnum.WLAN)
|
||||
self.canvas.draw_node_name = "wlan"
|
||||
|
||||
def pick_rj45(self, main_button):
|
||||
logging.debug("Pick link-layer node RJ45")
|
||||
self.link_layer_option_menu.destroy()
|
||||
main_button.configure(image=Images.get(ImageEnum.RJ45))
|
||||
self.canvas.mode = GraphMode.PICKNODE
|
||||
self.canvas.draw_node_image = Images.get(ImageEnum.RJ45)
|
||||
self.canvas.draw_node_name = "rj45"
|
||||
|
||||
def pick_tunnel(self, main_button):
|
||||
logging.debug("Pick link-layer node TUNNEL")
|
||||
self.link_layer_option_menu.destroy()
|
||||
main_button.configure(image=Images.get(ImageEnum.TUNNEL))
|
||||
self.canvas.mode = GraphMode.PICKNODE
|
||||
self.canvas.draw_node_image = Images.get(ImageEnum.TUNNEL)
|
||||
self.canvas.draw_node_name = "tunnel"
|
||||
|
||||
def pick_emane(self, main_button):
|
||||
self.link_layer_option_menu.destroy()
|
||||
main_button.configure(image=Images.get(ImageEnum.EMANE))
|
||||
self.canvas.mode = GraphMode.PICKNODE
|
||||
self.canvas.draw_node_image = Images.get(ImageEnum.EMANE)
|
||||
self.canvas.draw_node_name = "emane"
|
||||
|
||||
def draw_link_layer_options(self, link_layer_button):
|
||||
def draw_network_picker(self):
|
||||
"""
|
||||
Draw the options for link-layer button
|
||||
|
||||
:param tkinter.RadioButton link_layer_button: link-layer button
|
||||
:return: nothing
|
||||
"""
|
||||
# create a frame and add buttons to it
|
||||
self.destroy_previous_frame()
|
||||
option_frame = tk.Frame(self.master, padx=1, pady=1)
|
||||
img_list = [
|
||||
Images.get(ImageEnum.HUB),
|
||||
Images.get(ImageEnum.SWITCH),
|
||||
Images.get(ImageEnum.WLAN),
|
||||
Images.get(ImageEnum.EMANE),
|
||||
Images.get(ImageEnum.RJ45),
|
||||
Images.get(ImageEnum.TUNNEL),
|
||||
self.hide_pickers()
|
||||
self.network_picker = tk.Frame(self.master, padx=1, pady=1)
|
||||
nodes = [
|
||||
(ImageEnum.HUB, "hub", "ethernet hub"),
|
||||
(ImageEnum.SWITCH, "switch", "ethernet switch"),
|
||||
(ImageEnum.WLAN, "wlan", "wireless LAN"),
|
||||
(ImageEnum.EMANE, "emane", "EMANE"),
|
||||
(ImageEnum.RJ45, "rj45", "rj45 physical interface tool"),
|
||||
(ImageEnum.TUNNEL, "tunnel", "tunnel tool"),
|
||||
]
|
||||
func_list = [
|
||||
self.pick_hub,
|
||||
self.pick_switch,
|
||||
self.pick_wlan,
|
||||
self.pick_emane,
|
||||
self.pick_rj45,
|
||||
self.pick_tunnel,
|
||||
]
|
||||
tooltip_list = [
|
||||
"ethernet hub",
|
||||
"ethernet switch",
|
||||
"wireless LAN",
|
||||
"emane",
|
||||
"rj45 physical interface tool",
|
||||
"tunnel tool",
|
||||
]
|
||||
for i in range(len(img_list)):
|
||||
for image_enum, name, tooltip in nodes:
|
||||
self.create_button(
|
||||
img_list[i],
|
||||
func_list[i],
|
||||
option_frame,
|
||||
link_layer_button,
|
||||
tooltip_list[i],
|
||||
Images.get(image_enum),
|
||||
partial(self.update_button, self.network_button, image_enum, name),
|
||||
self.network_picker,
|
||||
tooltip,
|
||||
)
|
||||
|
||||
# place frame at a calculated position as well as keep a reference of the frame
|
||||
self.draw_button_menu_frame(self.edit_frame, option_frame, link_layer_button)
|
||||
self.link_layer_option_menu = option_frame
|
||||
|
||||
# destroy the frame before any further actions on other widgets
|
||||
self.bind_widgets_before_frame_hide(option_frame)
|
||||
option_frame.wait_window(option_frame)
|
||||
self.unbind_widgets_after_frame_hide()
|
||||
self.show_picker(self.network_button, self.network_picker)
|
||||
|
||||
def create_link_layer_button(self):
|
||||
"""
|
||||
|
@ -421,75 +303,42 @@ class CoreToolbar(object):
|
|||
:return: nothing
|
||||
"""
|
||||
hub_image = Images.get(ImageEnum.HUB)
|
||||
link_layer_button = tk.Radiobutton(
|
||||
self.edit_frame,
|
||||
self.network_button = tk.Radiobutton(
|
||||
self.design_frame,
|
||||
indicatoron=False,
|
||||
variable=self.radio_value,
|
||||
value=4,
|
||||
width=self.width,
|
||||
height=self.height,
|
||||
image=hub_image,
|
||||
command=lambda: self.draw_link_layer_options(link_layer_button),
|
||||
command=self.draw_network_picker,
|
||||
)
|
||||
link_layer_button.pack(side=tk.TOP, pady=1)
|
||||
CreateToolTip(link_layer_button, "link-layer nodes")
|
||||
self.network_button.grid()
|
||||
CreateToolTip(self.network_button, "link-layer nodes")
|
||||
|
||||
def pick_marker(self, main_button):
|
||||
self.marker_option_menu.destroy()
|
||||
main_button.configure(image=Images.get(ImageEnum.MARKER))
|
||||
logging.debug("Pick MARKER")
|
||||
|
||||
def pick_oval(self, main_button):
|
||||
self.marker_option_menu.destroy()
|
||||
main_button.configure(image=Images.get(ImageEnum.OVAL))
|
||||
logging.debug("Pick OVAL")
|
||||
|
||||
def pick_rectangle(self, main_button):
|
||||
self.marker_option_menu.destroy()
|
||||
main_button.configure(image=Images.get(ImageEnum.RECTANGLE))
|
||||
logging.debug("Pick RECTANGLE")
|
||||
|
||||
def pick_text(self, main_button):
|
||||
self.marker_option_menu.destroy()
|
||||
main_button.configure(image=Images.get(ImageEnum.TEXT))
|
||||
logging.debug("Pick TEXT")
|
||||
|
||||
def draw_marker_options(self, main_button):
|
||||
def draw_annotation_picker(self):
|
||||
"""
|
||||
Draw the options for marker button
|
||||
|
||||
:param tkinter.Radiobutton main_button: the main button
|
||||
:return: nothing
|
||||
"""
|
||||
# create a frame and add buttons to it
|
||||
self.destroy_previous_frame()
|
||||
option_frame = tk.Frame(self.master, padx=1, pady=1)
|
||||
img_list = [
|
||||
Images.get(ImageEnum.MARKER),
|
||||
Images.get(ImageEnum.OVAL),
|
||||
Images.get(ImageEnum.RECTANGLE),
|
||||
Images.get(ImageEnum.TEXT),
|
||||
self.hide_pickers()
|
||||
self.annotation_picker = tk.Frame(self.master, padx=1, pady=1)
|
||||
nodes = [
|
||||
(ImageEnum.MARKER, "marker"),
|
||||
(ImageEnum.OVAL, "oval"),
|
||||
(ImageEnum.RECTANGLE, "rectangle"),
|
||||
(ImageEnum.TEXT, "text"),
|
||||
]
|
||||
func_list = [
|
||||
self.pick_marker,
|
||||
self.pick_oval,
|
||||
self.pick_rectangle,
|
||||
self.pick_text,
|
||||
]
|
||||
tooltip_list = ["marker", "oval", "rectangle", "text"]
|
||||
for i in range(len(img_list)):
|
||||
for image_enum, tooltip in nodes:
|
||||
self.create_button(
|
||||
img_list[i], func_list[i], option_frame, main_button, tooltip_list[i]
|
||||
Images.get(image_enum),
|
||||
partial(self.update_annotation, image_enum),
|
||||
self.annotation_picker,
|
||||
tooltip,
|
||||
)
|
||||
|
||||
# place the frame at a calculated position as well as keep a reference of that frame
|
||||
self.draw_button_menu_frame(self.edit_frame, option_frame, main_button)
|
||||
self.marker_option_menu = option_frame
|
||||
|
||||
# destroy the frame before any further actions on other widgets
|
||||
self.bind_widgets_before_frame_hide(option_frame)
|
||||
option_frame.wait_window(option_frame)
|
||||
self.unbind_widgets_after_frame_hide()
|
||||
self.show_picker(self.annotation_button, self.annotation_picker)
|
||||
|
||||
def create_marker_button(self):
|
||||
"""
|
||||
|
@ -498,55 +347,22 @@ class CoreToolbar(object):
|
|||
:return: nothing
|
||||
"""
|
||||
marker_image = Images.get(ImageEnum.MARKER)
|
||||
marker_main_button = tk.Radiobutton(
|
||||
self.edit_frame,
|
||||
self.annotation_button = tk.Radiobutton(
|
||||
self.design_frame,
|
||||
indicatoron=False,
|
||||
variable=self.radio_value,
|
||||
value=5,
|
||||
width=self.width,
|
||||
height=self.height,
|
||||
image=marker_image,
|
||||
command=lambda: self.draw_marker_options(marker_main_button),
|
||||
command=self.draw_annotation_picker,
|
||||
)
|
||||
marker_main_button.pack(side=tk.TOP, pady=1)
|
||||
CreateToolTip(marker_main_button, "background annotation tools")
|
||||
|
||||
def create_toolbar(self):
|
||||
"""
|
||||
Create buttons for toolbar in edit mode
|
||||
|
||||
:return: nothing
|
||||
"""
|
||||
self.create_regular_button(
|
||||
self.edit_frame,
|
||||
Images.get(ImageEnum.START),
|
||||
self.click_start_session_tool,
|
||||
"start the session",
|
||||
)
|
||||
self.create_radio_button(
|
||||
self.edit_frame,
|
||||
Images.get(ImageEnum.SELECT),
|
||||
self.click_selection_tool,
|
||||
self.radio_value,
|
||||
1,
|
||||
"selection tool",
|
||||
)
|
||||
self.create_radio_button(
|
||||
self.edit_frame,
|
||||
Images.get(ImageEnum.LINK),
|
||||
self.click_link_tool,
|
||||
self.radio_value,
|
||||
2,
|
||||
"link tool",
|
||||
)
|
||||
self.create_network_layer_button()
|
||||
self.create_link_layer_button()
|
||||
self.create_marker_button()
|
||||
self.radio_value.set(1)
|
||||
self.annotation_button.grid()
|
||||
CreateToolTip(self.annotation_button, "background annotation tools")
|
||||
|
||||
def create_observe_button(self):
|
||||
menu_button = tk.Menubutton(
|
||||
self.edit_frame,
|
||||
self.runtime_frame,
|
||||
image=Images.get(ImageEnum.OBSERVE),
|
||||
width=self.width,
|
||||
height=self.height,
|
||||
|
@ -555,7 +371,7 @@ class CoreToolbar(object):
|
|||
)
|
||||
menu_button.menu = tk.Menu(menu_button, tearoff=0)
|
||||
menu_button["menu"] = menu_button.menu
|
||||
menu_button.pack(side=tk.TOP, pady=1)
|
||||
menu_button.grid()
|
||||
|
||||
menu_button.menu.add_command(label="None")
|
||||
menu_button.menu.add_command(label="processes")
|
||||
|
@ -581,9 +397,13 @@ class CoreToolbar(object):
|
|||
:return: nothing
|
||||
"""
|
||||
logging.debug("Click on STOP button ")
|
||||
self.destroy_children_widgets()
|
||||
self.app.core.stop_session()
|
||||
self.create_toolbar()
|
||||
self.design_frame.tkraise()
|
||||
|
||||
def update_annotation(self, image_enum):
|
||||
logging.info("clicked annotation: ")
|
||||
self.hide_pickers()
|
||||
self.annotation_button.configure(image=Images.get(image_enum))
|
||||
|
||||
def click_run_button(self):
|
||||
logging.debug("Click on RUN button")
|
||||
|
@ -596,48 +416,3 @@ class CoreToolbar(object):
|
|||
|
||||
def click_two_node_button(self):
|
||||
logging.debug("Click TWONODE button")
|
||||
|
||||
def create_runtime_toolbar(self):
|
||||
self.create_regular_button(
|
||||
self.edit_frame,
|
||||
Images.get(ImageEnum.STOP),
|
||||
self.click_stop_button,
|
||||
"stop the session",
|
||||
)
|
||||
self.create_radio_button(
|
||||
self.edit_frame,
|
||||
Images.get(ImageEnum.SELECT),
|
||||
self.click_selection_tool,
|
||||
self.exec_radio_value,
|
||||
1,
|
||||
"selection tool",
|
||||
)
|
||||
self.create_observe_button()
|
||||
self.create_radio_button(
|
||||
self.edit_frame,
|
||||
Images.get(ImageEnum.PLOT),
|
||||
self.click_plot_button,
|
||||
self.exec_radio_value,
|
||||
2,
|
||||
"plot",
|
||||
)
|
||||
self.create_radio_button(
|
||||
self.edit_frame,
|
||||
Images.get(ImageEnum.MARKER),
|
||||
self.click_marker_button,
|
||||
self.exec_radio_value,
|
||||
3,
|
||||
"marker",
|
||||
)
|
||||
self.create_radio_button(
|
||||
self.edit_frame,
|
||||
Images.get(ImageEnum.TWONODE),
|
||||
self.click_two_node_button,
|
||||
self.exec_radio_value,
|
||||
4,
|
||||
"run command from one node to another",
|
||||
)
|
||||
self.create_regular_button(
|
||||
self.edit_frame, Images.get(ImageEnum.RUN), self.click_run_button, "run"
|
||||
)
|
||||
self.exec_radio_value.set(1)
|
||||
|
|
|
@ -272,7 +272,7 @@ class CanvasGraph(tk.Canvas):
|
|||
else:
|
||||
self.focus_set()
|
||||
self.selected = self.get_selected(event)
|
||||
logging.debug(f"click release selected: {self.selected}")
|
||||
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:
|
||||
|
@ -379,6 +379,7 @@ class CanvasGraph(tk.Canvas):
|
|||
|
||||
def add_node(self, x, y, image, node_name):
|
||||
plot_id = self.find_all()[0]
|
||||
logging.info("add node event: %s - %s", plot_id, self.selected)
|
||||
if self.selected == plot_id:
|
||||
node = CanvasNode(
|
||||
x=x,
|
||||
|
@ -498,12 +499,12 @@ class CanvasNode:
|
|||
self.x_coord, self.y_coord = self.canvas.coords(self.id)
|
||||
|
||||
def click_press(self, event):
|
||||
logging.debug(f"click press {self.name}: {event}")
|
||||
logging.debug(f"node click press {self.name}: {event}")
|
||||
self.moving = self.canvas.canvas_xy(event)
|
||||
# return "break"
|
||||
|
||||
def click_release(self, event):
|
||||
logging.debug(f"click release {self.name}: {event}")
|
||||
logging.debug(f"node click release {self.name}: {event}")
|
||||
self.update_coords()
|
||||
self.canvas.core.update_node_location(self.id, self.x_coord, self.y_coord)
|
||||
self.moving = None
|
||||
|
|
Loading…
Reference in a new issue