cleanup for app toolbar, updated toolbar to use grid layout

This commit is contained in:
bharnden 2019-11-07 14:37:08 -08:00
parent 2873c32c23
commit 4970fb0d55
4 changed files with 234 additions and 462 deletions

View file

@ -50,10 +50,8 @@ class Application(tk.Frame):
self.master.config(menu=self.menubar) self.master.config(menu=self.menubar)
def draw_toolbar(self): def draw_toolbar(self):
edit_frame = tk.Frame(self) self.core_editbar = CoreToolbar(self, self)
edit_frame.pack(side=tk.LEFT, fill=tk.Y, ipadx=2, ipady=2) self.core_editbar.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()
def draw_canvas(self): def draw_canvas(self):
self.canvas = CanvasGraph( self.canvas = CanvasGraph(

View file

@ -13,8 +13,8 @@ from coretk.interface import Interface, InterfaceManager
from coretk.mobilitynodeconfig import MobilityNodeConfig from coretk.mobilitynodeconfig import MobilityNodeConfig
from coretk.wlannodeconfig import WlanNodeConfig from coretk.wlannodeconfig import WlanNodeConfig
link_layer_nodes = ["switch", "hub", "wlan", "rj45", "tunnel"] link_layer_nodes = ["switch", "hub", "wlan", "rj45", "tunnel", "emane"]
network_layer_nodes = ["router", "host", "PC", "mdr", "prouter", "OVS"] network_layer_nodes = ["router", "host", "PC", "mdr", "prouter"]
class Node: class Node:
@ -205,11 +205,9 @@ class CoreClient:
# draw tool bar appropritate with session state # draw tool bar appropritate with session state
if session_state == core_pb2.SessionState.RUNTIME: if session_state == core_pb2.SessionState.RUNTIME:
self.app.core_editbar.destroy_children_widgets() self.app.core_editbar.runtime_frame.tkraise()
self.app.core_editbar.create_runtime_toolbar()
else: else:
self.app.core_editbar.destroy_children_widgets() self.app.core_editbar.design_frame.tkraise()
self.app.core_editbar.create_toolbar()
def create_new_session(self): def create_new_session(self):
""" """
@ -447,26 +445,26 @@ class CoreClient:
node_type = core_pb2.NodeType.WIRELESS_LAN node_type = core_pb2.NodeType.WIRELESS_LAN
elif name == "rj45": elif name == "rj45":
node_type = core_pb2.NodeType.RJ45 node_type = core_pb2.NodeType.RJ45
elif name == "emane":
node_type = core_pb2.NodeType.EMANE
elif name == "tunnel": elif name == "tunnel":
node_type = core_pb2.NodeType.TUNNEL node_type = core_pb2.NodeType.TUNNEL
elif name in network_layer_nodes: elif name in network_layer_nodes:
node_type = core_pb2.NodeType.DEFAULT node_type = core_pb2.NodeType.DEFAULT
node_model = name node_model = name
else: else:
logging.error("grpcmanagemeny.py INVALID node name") logging.error("invalid node name: %s", name)
nid = self.get_id() nid = self.get_id()
create_node = Node(session_id, nid, node_type, node_model, x, y, name) create_node = Node(session_id, nid, node_type, node_model, x, y, name)
# set default configuration for wireless node # set default configuration for wireless node
self.wlanconfig_management.set_default_config(node_type, nid) self.wlanconfig_management.set_default_config(node_type, nid)
self.mobilityconfig_management.set_default_configuration(node_type, nid) self.mobilityconfig_management.set_default_configuration(node_type, nid)
self.nodes[canvas_id] = create_node self.nodes[canvas_id] = create_node
self.core_mapping.map_core_id_to_canvas_id(nid, canvas_id) self.core_mapping.map_core_id_to_canvas_id(nid, canvas_id)
# self.core_id_to_canvas_id[nid] = canvas_id
logging.debug( 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, session_id,
x, x,
y, y,

View file

@ -1,5 +1,6 @@
import logging import logging
import tkinter as tk import tkinter as tk
from functools import partial
from coretk.coretoolbarhelp import CoreToolbarHelp from coretk.coretoolbarhelp import CoreToolbarHelp
from coretk.dialogs.customnodes import CustomNodesDialog from coretk.dialogs.customnodes import CustomNodesDialog
@ -8,21 +9,20 @@ from coretk.images import ImageEnum, Images
from coretk.tooltip import CreateToolTip from coretk.tooltip import CreateToolTip
class CoreToolbar(object): class CoreToolbar(tk.Frame):
""" """
Core toolbar class Core toolbar class
""" """
def __init__(self, app, edit_frame, menubar): def __init__(self, master, app, cnf={}, **kwargs):
""" """
Create a CoreToolbar instance Create a CoreToolbar instance
:param tkinter.Frame edit_frame: edit frame :param tkinter.Frame edit_frame: edit frame
""" """
super().__init__(master, cnf, **kwargs)
self.app = app self.app = app
self.master = app.master self.master = app.master
self.edit_frame = edit_frame
self.menubar = menubar
self.radio_value = tk.IntVar() self.radio_value = tk.IntVar()
self.exec_radio_value = tk.IntVar() self.exec_radio_value = tk.IntVar()
@ -30,44 +30,144 @@ class CoreToolbar(object):
self.width = 32 self.width = 32
self.height = 32 self.height = 32
self.selection_tool_button = None
# Reference to the option menus # Reference to the option menus
self.selection_tool_button = None
self.link_layer_option_menu = None self.link_layer_option_menu = None
self.marker_option_menu = None self.marker_option_menu = None
self.network_layer_option_menu = None self.network_layer_option_menu = None
self.canvas = None self.canvas = None
self.node_button = None
self.network_button = None
self.annotation_button = None
def destroy_previous_frame(self): # frames
""" self.design_frame = None
Destroy any extra frame from previous before drawing a new one self.runtime_frame = None
self.node_picker = None
self.network_picker = None
self.annotation_picker = None
:return: nothing # draw components
""" self.draw()
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()
def destroy_children_widgets(self): def draw(self):
""" self.columnconfigure(0, weight=1)
Destroy all children of a parent widget self.rowconfigure(0, weight=1)
self.draw_design_frame()
self.draw_runtime_frame()
self.design_frame.tkraise()
:param tkinter.Frame parent: parent frame def draw_design_frame(self):
:return: nothing 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(): self.create_regular_button(
if i.winfo_name() != "!frame": self.design_frame,
i.destroy() 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 Create button and put it on the frame
@ -78,9 +178,9 @@ class CoreToolbar(object):
:return: nothing :return: nothing
""" """
button = tk.Button(frame, width=self.width, height=self.height, image=img) 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) button.pack(side=tk.LEFT, pady=1)
CreateToolTip(button, btt_message) CreateToolTip(button, tooltip)
button.bind("<Button-1>", lambda mb: func(main_button))
def create_radio_button(self, frame, image, func, variable, value, tooltip_msg): def create_radio_button(self, frame, image, func, variable, value, tooltip_msg):
button = tk.Radiobutton( button = tk.Radiobutton(
@ -93,326 +193,108 @@ class CoreToolbar(object):
variable=variable, variable=variable,
command=func, command=func,
) )
button.pack(side=tk.TOP, pady=1) button.grid()
CreateToolTip(button, tooltip_msg) 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( button = tk.Button(
frame, width=self.width, height=self.height, image=image, command=func frame, width=self.width, height=self.height, image=image, command=func
) )
button.pack(side=tk.TOP, pady=1) button.grid()
CreateToolTip(button, btt_message) CreateToolTip(button, tooltip)
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>")
def click_selection_tool(self): def click_selection_tool(self):
logging.debug("Click SELECTION TOOL") logging.debug("clicked selection tool")
self.canvas.mode = GraphMode.SELECT self.canvas.mode = GraphMode.SELECT
def click_start_session_tool(self): 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 :return: nothing
""" """
logging.debug("Click START STOP SESSION button") logging.debug("clicked start button")
helper = CoreToolbarHelp(self.app) helper = CoreToolbarHelp(self.app)
self.destroy_children_widgets()
self.canvas.mode = GraphMode.SELECT 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() helper.gui_start_session()
self.create_runtime_toolbar() self.runtime_frame.tkraise()
# 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
def click_link_tool(self): def click_link_tool(self):
logging.debug("Click LINK button") logging.debug("Click LINK button")
self.canvas.mode = GraphMode.EDGE self.canvas.mode = GraphMode.EDGE
def pick_router(self, main_button): def update_button(self, button, image_enum, name):
logging.debug("Pick router option") logging.info("update button(%s): %s, %s", button, image_enum, name)
self.network_layer_option_menu.destroy() self.hide_pickers()
main_button.configure(image=Images.get(ImageEnum.ROUTER)) if image_enum == ImageEnum.EDITNODE:
self.canvas.mode = GraphMode.PICKNODE dialog = CustomNodesDialog(self.app, self.app)
self.canvas.draw_node_image = Images.get(ImageEnum.ROUTER) dialog.show()
self.canvas.draw_node_name = "router" 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): def hide_pickers(self):
logging.debug("Pick host option") logging.info("hiding pickers")
self.network_layer_option_menu.destroy() if self.node_picker:
main_button.configure(image=Images.get(ImageEnum.HOST)) self.node_picker.destroy()
self.canvas.mode = GraphMode.PICKNODE self.node_picker = None
self.canvas.draw_node_image = Images.get(ImageEnum.HOST) if self.network_picker:
self.canvas.draw_node_name = "host" 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): def create_node_button(self):
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):
""" """
Create network layer button Create network layer button
:return: nothing :return: nothing
""" """
router_image = Images.get(ImageEnum.ROUTER) router_image = Images.get(ImageEnum.ROUTER)
network_layer_button = tk.Radiobutton( self.node_button = tk.Radiobutton(
self.edit_frame, self.design_frame,
indicatoron=False, indicatoron=False,
variable=self.radio_value, variable=self.radio_value,
value=3, value=3,
width=self.width, width=self.width,
height=self.height, height=self.height,
image=router_image, 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) self.node_button.grid()
CreateToolTip(network_layer_button, "Network-layer virtual nodes") CreateToolTip(self.node_button, "Network-layer virtual nodes")
def pick_hub(self, main_button): def draw_network_picker(self):
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):
""" """
Draw the options for link-layer button Draw the options for link-layer button
:param tkinter.RadioButton link_layer_button: link-layer button :param tkinter.RadioButton link_layer_button: link-layer button
:return: nothing :return: nothing
""" """
# create a frame and add buttons to it self.hide_pickers()
self.destroy_previous_frame() self.network_picker = tk.Frame(self.master, padx=1, pady=1)
option_frame = tk.Frame(self.master, padx=1, pady=1) nodes = [
img_list = [ (ImageEnum.HUB, "hub", "ethernet hub"),
Images.get(ImageEnum.HUB), (ImageEnum.SWITCH, "switch", "ethernet switch"),
Images.get(ImageEnum.SWITCH), (ImageEnum.WLAN, "wlan", "wireless LAN"),
Images.get(ImageEnum.WLAN), (ImageEnum.EMANE, "emane", "EMANE"),
Images.get(ImageEnum.EMANE), (ImageEnum.RJ45, "rj45", "rj45 physical interface tool"),
Images.get(ImageEnum.RJ45), (ImageEnum.TUNNEL, "tunnel", "tunnel tool"),
Images.get(ImageEnum.TUNNEL),
] ]
func_list = [ for image_enum, name, tooltip in nodes:
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)):
self.create_button( self.create_button(
img_list[i], Images.get(image_enum),
func_list[i], partial(self.update_button, self.network_button, image_enum, name),
option_frame, self.network_picker,
link_layer_button, tooltip,
tooltip_list[i],
) )
self.show_picker(self.network_button, self.network_picker)
# 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()
def create_link_layer_button(self): def create_link_layer_button(self):
""" """
@ -421,75 +303,42 @@ class CoreToolbar(object):
:return: nothing :return: nothing
""" """
hub_image = Images.get(ImageEnum.HUB) hub_image = Images.get(ImageEnum.HUB)
link_layer_button = tk.Radiobutton( self.network_button = tk.Radiobutton(
self.edit_frame, self.design_frame,
indicatoron=False, indicatoron=False,
variable=self.radio_value, variable=self.radio_value,
value=4, value=4,
width=self.width, width=self.width,
height=self.height, height=self.height,
image=hub_image, 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) self.network_button.grid()
CreateToolTip(link_layer_button, "link-layer nodes") CreateToolTip(self.network_button, "link-layer nodes")
def pick_marker(self, main_button): def draw_annotation_picker(self):
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):
""" """
Draw the options for marker button Draw the options for marker button
:param tkinter.Radiobutton main_button: the main button :param tkinter.Radiobutton main_button: the main button
:return: nothing :return: nothing
""" """
# create a frame and add buttons to it self.hide_pickers()
self.destroy_previous_frame() self.annotation_picker = tk.Frame(self.master, padx=1, pady=1)
option_frame = tk.Frame(self.master, padx=1, pady=1) nodes = [
img_list = [ (ImageEnum.MARKER, "marker"),
Images.get(ImageEnum.MARKER), (ImageEnum.OVAL, "oval"),
Images.get(ImageEnum.OVAL), (ImageEnum.RECTANGLE, "rectangle"),
Images.get(ImageEnum.RECTANGLE), (ImageEnum.TEXT, "text"),
Images.get(ImageEnum.TEXT),
] ]
func_list = [ for image_enum, tooltip in nodes:
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)):
self.create_button( 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,
) )
self.show_picker(self.annotation_button, self.annotation_picker)
# 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()
def create_marker_button(self): def create_marker_button(self):
""" """
@ -498,55 +347,22 @@ class CoreToolbar(object):
:return: nothing :return: nothing
""" """
marker_image = Images.get(ImageEnum.MARKER) marker_image = Images.get(ImageEnum.MARKER)
marker_main_button = tk.Radiobutton( self.annotation_button = tk.Radiobutton(
self.edit_frame, self.design_frame,
indicatoron=False, indicatoron=False,
variable=self.radio_value, variable=self.radio_value,
value=5, value=5,
width=self.width, width=self.width,
height=self.height, height=self.height,
image=marker_image, 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) self.annotation_button.grid()
CreateToolTip(marker_main_button, "background annotation tools") CreateToolTip(self.annotation_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)
def create_observe_button(self): def create_observe_button(self):
menu_button = tk.Menubutton( menu_button = tk.Menubutton(
self.edit_frame, self.runtime_frame,
image=Images.get(ImageEnum.OBSERVE), image=Images.get(ImageEnum.OBSERVE),
width=self.width, width=self.width,
height=self.height, height=self.height,
@ -555,7 +371,7 @@ class CoreToolbar(object):
) )
menu_button.menu = tk.Menu(menu_button, tearoff=0) menu_button.menu = tk.Menu(menu_button, tearoff=0)
menu_button["menu"] = menu_button.menu 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="None")
menu_button.menu.add_command(label="processes") menu_button.menu.add_command(label="processes")
@ -581,9 +397,13 @@ class CoreToolbar(object):
:return: nothing :return: nothing
""" """
logging.debug("Click on STOP button ") logging.debug("Click on STOP button ")
self.destroy_children_widgets()
self.app.core.stop_session() 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): def click_run_button(self):
logging.debug("Click on RUN button") logging.debug("Click on RUN button")
@ -596,48 +416,3 @@ class CoreToolbar(object):
def click_two_node_button(self): def click_two_node_button(self):
logging.debug("Click TWONODE button") 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)

View file

@ -272,7 +272,7 @@ class CanvasGraph(tk.Canvas):
else: 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}) mode({self.mode})")
if self.mode == GraphMode.EDGE: if self.mode == GraphMode.EDGE:
self.handle_edge_release(event) self.handle_edge_release(event)
elif self.mode == GraphMode.NODE: elif self.mode == GraphMode.NODE:
@ -379,6 +379,7 @@ class CanvasGraph(tk.Canvas):
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]
logging.info("add node event: %s - %s", plot_id, self.selected)
if self.selected == plot_id: if self.selected == plot_id:
node = CanvasNode( node = CanvasNode(
x=x, x=x,
@ -498,12 +499,12 @@ class CanvasNode:
self.x_coord, self.y_coord = self.canvas.coords(self.id) self.x_coord, self.y_coord = self.canvas.coords(self.id)
def click_press(self, event): 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) self.moving = self.canvas.canvas_xy(event)
# return "break" # return "break"
def click_release(self, event): 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.update_coords()
self.canvas.core.update_node_location(self.id, self.x_coord, self.y_coord) self.canvas.core.update_node_location(self.id, self.x_coord, self.y_coord)
self.moving = None self.moving = None