pygui: able to start session with multiple canvases, just using 1 canvas for now

This commit is contained in:
Blake Harnden 2020-12-12 00:03:03 -08:00
parent 6f43d0e88f
commit 9621df6bc4
5 changed files with 34 additions and 24 deletions

View file

@ -13,7 +13,6 @@ from core.gui.coreclient import CoreClient
from core.gui.dialogs.error import ErrorDialog from core.gui.dialogs.error import ErrorDialog
from core.gui.frames.base import InfoFrameBase from core.gui.frames.base import InfoFrameBase
from core.gui.frames.default import DefaultInfoFrame from core.gui.frames.default import DefaultInfoFrame
from core.gui.graph.graph import CanvasGraph
from core.gui.graph.manager import CanvasManager from core.gui.graph.manager import CanvasManager
from core.gui.images import ImageEnum, Images from core.gui.images import ImageEnum, Images
from core.gui.menubar import Menubar from core.gui.menubar import Menubar
@ -37,7 +36,6 @@ class Application(ttk.Frame):
self.toolbar: Optional[Toolbar] = None self.toolbar: Optional[Toolbar] = None
self.right_frame: Optional[ttk.Frame] = None self.right_frame: Optional[ttk.Frame] = None
self.manager: Optional[CanvasManager] = None self.manager: Optional[CanvasManager] = None
self.canvas: Optional[CanvasGraph] = None
self.statusbar: Optional[StatusBar] = None self.statusbar: Optional[StatusBar] = None
self.progress: Optional[Progressbar] = None self.progress: Optional[Progressbar] = None
self.infobar: Optional[ttk.Frame] = None self.infobar: Optional[ttk.Frame] = None

View file

@ -555,6 +555,8 @@ class CoreClient:
mobility_player.show() mobility_player.show()
def set_metadata(self) -> None: def set_metadata(self) -> None:
# TODO: handle metadata for multiple canvases
return
# create canvas data # create canvas data
wallpaper_path = None wallpaper_path = None
if self.app.canvas.wallpaper_file: if self.app.canvas.wallpaper_file:

View file

@ -145,7 +145,7 @@ class Edge:
text=text, text=text,
tags=tags.LINK_LABEL, tags=tags.LINK_LABEL,
justify=tk.CENTER, justify=tk.CENTER,
state=self.canvas.show_link_labels.state(), state=self.canvas.manager.show_link_labels.state(),
) )
else: else:
self.canvas.itemconfig(self.middle_label, text=text) self.canvas.itemconfig(self.middle_label, text=text)
@ -177,7 +177,7 @@ class Edge:
justify=tk.CENTER, justify=tk.CENTER,
font=self.canvas.app.edge_font, font=self.canvas.app.edge_font,
tags=tags.LINK_LABEL, tags=tags.LINK_LABEL,
state=self.canvas.show_link_labels.state(), state=self.canvas.manager.show_link_labels.state(),
) )
else: else:
self.canvas.itemconfig(self.src_label, text=text) self.canvas.itemconfig(self.src_label, text=text)
@ -191,7 +191,7 @@ class Edge:
justify=tk.CENTER, justify=tk.CENTER,
font=self.canvas.app.edge_font, font=self.canvas.app.edge_font,
tags=tags.LINK_LABEL, tags=tags.LINK_LABEL,
state=self.canvas.show_link_labels.state(), state=self.canvas.manager.show_link_labels.state(),
) )
else: else:
self.canvas.itemconfig(self.dst_label, text=text) self.canvas.itemconfig(self.dst_label, text=text)
@ -256,7 +256,7 @@ class CanvasWirelessEdge(Edge):
self.width: float = WIRELESS_WIDTH self.width: float = WIRELESS_WIDTH
color = link.color if link.color else WIRELESS_COLOR color = link.color if link.color else WIRELESS_COLOR
self.color: str = color self.color: str = color
self.draw(src_pos, dst_pos, self.canvas.show_wireless.state()) self.draw(src_pos, dst_pos, self.canvas.manager.show_wireless.state())
if link.label: if link.label:
self.middle_label_text(link.label) self.middle_label_text(link.label)
self.set_binding() self.set_binding()
@ -311,12 +311,12 @@ class CanvasEdge(Edge):
def iface_label(self, iface: Interface) -> str: def iface_label(self, iface: Interface) -> str:
label = "" label = ""
if iface.name and self.canvas.show_iface_names.get(): if iface.name and self.canvas.manager.show_iface_names.get():
label = f"{iface.name}" label = f"{iface.name}"
if iface.ip4 and self.canvas.show_ip4s.get(): if iface.ip4 and self.canvas.manager.show_ip4s.get():
label = f"{label}\n" if label else "" label = f"{label}\n" if label else ""
label += f"{iface.ip4}/{iface.ip4_mask}" label += f"{iface.ip4}/{iface.ip4_mask}"
if iface.ip6 and self.canvas.show_ip6s.get(): if iface.ip6 and self.canvas.manager.show_ip6s.get():
label = f"{label}\n" if label else "" label = f"{label}\n" if label else ""
label += f"{iface.ip6}/{iface.ip6_mask}" label += f"{iface.ip6}/{iface.ip6_mask}"
return label return label
@ -350,7 +350,7 @@ class CanvasEdge(Edge):
else: else:
state = tk.NORMAL state = tk.NORMAL
self.canvas.dtag(self.id, tags.LOSS_EDGES) self.canvas.dtag(self.id, tags.LOSS_EDGES)
if self.canvas.show_loss_links.state() == tk.HIDDEN: if self.canvas.manager.show_loss_links.state() == tk.HIDDEN:
self.canvas.itemconfigure(self.id, state=state) self.canvas.itemconfigure(self.id, state=state)
def set_throughput(self, throughput: float) -> None: def set_throughput(self, throughput: float) -> None:

View file

@ -1,7 +1,7 @@
import logging import logging
import tkinter as tk import tkinter as tk
from tkinter import BooleanVar, messagebox, ttk from tkinter import BooleanVar, messagebox, ttk
from typing import TYPE_CHECKING, Dict, Optional, Set, Tuple from typing import TYPE_CHECKING, Dict, Optional, Set, Tuple, ValuesView
from core.api.grpc.wrappers import Session from core.api.grpc.wrappers import Session
from core.gui.graph import tags from core.gui.graph import tags
@ -77,20 +77,28 @@ class CanvasManager:
self.notebook = ttk.Notebook(self.master) self.notebook = ttk.Notebook(self.master)
self.notebook.grid(sticky=tk.NSEW, pady=1) self.notebook.grid(sticky=tk.NSEW, pady=1)
def next_id(self) -> int: def _next_id(self) -> int:
_id = 1 _id = 1
tab_ids = set(self.unique_ids.values()) tab_ids = set(self.unique_ids.values())
while _id in tab_ids: while _id in tab_ids:
_id += 1 _id += 1
return _id return _id
def current(self) -> CanvasGraph:
unique_id = self.notebook.select()
tab_id = self.unique_ids[unique_id]
return self.canvases[tab_id]
def all(self) -> ValuesView[CanvasGraph]:
return self.canvases.values()
def add_canvas(self) -> CanvasGraph: def add_canvas(self) -> CanvasGraph:
# create tab frame # create tab frame
tab = ttk.Frame(self.notebook, padding=0) tab = ttk.Frame(self.notebook, padding=0)
tab.grid(sticky=tk.NSEW) tab.grid(sticky=tk.NSEW)
tab.columnconfigure(0, weight=1) tab.columnconfigure(0, weight=1)
tab.rowconfigure(0, weight=1) tab.rowconfigure(0, weight=1)
tab_id = self.next_id() tab_id = self._next_id()
self.notebook.add(tab, text=f"Canvas {tab_id}") self.notebook.add(tab, text=f"Canvas {tab_id}")
unique_id = self.notebook.tabs()[-1] unique_id = self.notebook.tabs()[-1]
logging.info("tab(%s) is %s", unique_id, tab_id) logging.info("tab(%s) is %s", unique_id, tab_id)

View file

@ -144,7 +144,8 @@ class MarkerFrame(ttk.Frame):
Tooltip(self.color_frame, "Marker Color") Tooltip(self.color_frame, "Marker Color")
def click_clear(self) -> None: def click_clear(self) -> None:
self.app.canvas.delete(tags.MARKER) canvas = self.app.manager.current()
canvas.delete(tags.MARKER)
def click_color(self, _event: tk.Event) -> None: def click_color(self, _event: tk.Event) -> None:
dialog = ColorPickerDialog(self.app, self.app, self.color) dialog = ColorPickerDialog(self.app, self.app, self.color)
@ -283,7 +284,7 @@ class Toolbar(ttk.Frame):
def click_runtime_selection(self) -> None: def click_runtime_selection(self) -> None:
self.runtime_frame.select_radio(self.runtime_select_button) self.runtime_frame.select_radio(self.runtime_select_button)
self.app.canvas.mode = GraphMode.SELECT self.app.manager.mode = GraphMode.SELECT
self.hide_marker() self.hide_marker()
def click_start(self) -> None: def click_start(self) -> None:
@ -292,7 +293,7 @@ class Toolbar(ttk.Frame):
server. server.
""" """
self.app.menubar.change_menubar_item_state(is_runtime=True) self.app.menubar.change_menubar_item_state(is_runtime=True)
self.app.canvas.mode = GraphMode.SELECT self.app.manager.mode = GraphMode.SELECT
enable_buttons(self.design_frame, enabled=False) enable_buttons(self.design_frame, enabled=False)
task = ProgressTask( task = ProgressTask(
self.app, "Start", self.app.core.start_session, self.start_callback self.app, "Start", self.app.core.start_session, self.start_callback
@ -348,8 +349,8 @@ class Toolbar(ttk.Frame):
Draw the options for link-layer button. Draw the options for link-layer button.
""" """
self.hide_marker() self.hide_marker()
self.app.canvas.mode = GraphMode.NODE self.app.manager.mode = GraphMode.NODE
self.app.canvas.node_draw = self.current_network self.app.manager.node_draw = self.current_network
self.design_frame.select_radio(self.network_button) self.design_frame.select_radio(self.network_button)
self.picker = PickerFrame(self.app, self.network_button) self.picker = PickerFrame(self.app, self.network_button)
for node_draw in NodeUtils.NETWORK_NODES: for node_draw in NodeUtils.NETWORK_NODES:
@ -364,8 +365,8 @@ class Toolbar(ttk.Frame):
Draw the options for marker button. Draw the options for marker button.
""" """
self.design_frame.select_radio(self.annotation_button) self.design_frame.select_radio(self.annotation_button)
self.app.canvas.mode = GraphMode.ANNOTATION self.app.manager.mode = GraphMode.ANNOTATION
self.app.canvas.annotation_type = self.current_annotation self.app.manager.annotation_type = self.current_annotation
if is_marker(self.current_annotation): if is_marker(self.current_annotation):
self.show_marker() self.show_marker()
self.picker = PickerFrame(self.app, self.annotation_button) self.picker = PickerFrame(self.app, self.annotation_button)
@ -406,7 +407,8 @@ class Toolbar(ttk.Frame):
def stop_callback(self, result: bool) -> None: def stop_callback(self, result: bool) -> None:
self.set_design() self.set_design()
self.app.canvas.stopped_session() for canvas in self.app.manager.all():
canvas.stopped_session()
def update_annotation( def update_annotation(
self, shape_type: ShapeType, image_enum: ImageEnum, image: PhotoImage self, shape_type: ShapeType, image_enum: ImageEnum, image: PhotoImage
@ -414,7 +416,7 @@ class Toolbar(ttk.Frame):
logging.debug("clicked annotation") logging.debug("clicked annotation")
self.annotation_button.configure(image=image) self.annotation_button.configure(image=image)
self.annotation_button.image = image self.annotation_button.image = image
self.app.canvas.annotation_type = shape_type self.app.manager.annotation_type = shape_type
self.current_annotation = shape_type self.current_annotation = shape_type
self.annotation_enum = image_enum self.annotation_enum = image_enum
if is_marker(shape_type): if is_marker(shape_type):
@ -435,8 +437,8 @@ class Toolbar(ttk.Frame):
def click_marker_button(self) -> None: def click_marker_button(self) -> None:
self.runtime_frame.select_radio(self.runtime_marker_button) self.runtime_frame.select_radio(self.runtime_marker_button)
self.app.canvas.mode = GraphMode.ANNOTATION self.app.manager.mode = GraphMode.ANNOTATION
self.app.canvas.annotation_type = ShapeType.MARKER self.app.manager.annotation_type = ShapeType.MARKER
self.show_marker() self.show_marker()
def scale_button( def scale_button(