diff --git a/coretk/coretk/app.py b/coretk/coretk/app.py index 9c9c0d2f..faaf1c20 100644 --- a/coretk/coretk/app.py +++ b/coretk/coretk/app.py @@ -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( diff --git a/coretk/coretk/coreclient.py b/coretk/coretk/coreclient.py index f4135269..5369b829 100644 --- a/coretk/coretk/coreclient.py +++ b/coretk/coretk/coreclient.py @@ -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, diff --git a/coretk/coretk/coretoolbar.py b/coretk/coretk/coretoolbar.py index aeccb54f..aaed37a9 100644 --- a/coretk/coretk/coretoolbar.py +++ b/coretk/coretk/coretoolbar.py @@ -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("", lambda e: self.hide_pickers()) + self.wait_window(picker) + self.app.unbind_all("") + + 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("", lambda e: func()) button.pack(side=tk.LEFT, pady=1) - CreateToolTip(button, btt_message) - button.bind("", 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("", lambda e: frame.destroy()) - self.master.bind("", 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("") - 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) diff --git a/coretk/coretk/graph.py b/coretk/coretk/graph.py index 448a6f1d..eb2362c6 100644 --- a/coretk/coretk/graph.py +++ b/coretk/coretk/graph.py @@ -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