fix merge conflict

This commit is contained in:
Huy Pham 2020-01-15 15:27:33 -08:00
commit 5c087141bd
86 changed files with 3313 additions and 1832 deletions

View file

@ -1,9 +1,13 @@
import tkinter as tk
from tkinter import ttk
from typing import TYPE_CHECKING
from core.gui.dialogs.dialog import Dialog
from core.gui.widgets import CodeText
if TYPE_CHECKING:
from core.gui.app import Application
LICENSE = """\
Copyright (c) 2005-2020, the Boeing Company.
@ -31,7 +35,7 @@ THE POSSIBILITY OF SUCH DAMAGE.\
class AboutDialog(Dialog):
def __init__(self, master, app):
def __init__(self, master: "Application", app: "Application"):
super().__init__(master, app, "About CORE", modal=True)
self.draw()

View file

@ -3,15 +3,19 @@ check engine light
"""
import tkinter as tk
from tkinter import ttk
from typing import TYPE_CHECKING
from core.api.grpc.core_pb2 import ExceptionLevel
from core.gui.dialogs.dialog import Dialog
from core.gui.themes import PADX, PADY
from core.gui.widgets import CodeText
if TYPE_CHECKING:
from core.gui.app import Application
class AlertsDialog(Dialog):
def __init__(self, master, app):
def __init__(self, master: "Application", app: "Application"):
super().__init__(master, app, "Alerts", modal=True)
self.app = app
self.tree = None
@ -110,7 +114,7 @@ class AlertsDialog(Dialog):
dialog = DaemonLog(self, self.app)
dialog.show()
def click_select(self, event):
def click_select(self, event: tk.Event):
current = self.tree.selection()[0]
alarm = self.alarm_map[current]
self.codetext.text.config(state=tk.NORMAL)
@ -120,7 +124,7 @@ class AlertsDialog(Dialog):
class DaemonLog(Dialog):
def __init__(self, master, app):
def __init__(self, master: tk.Widget, app: "Application"):
super().__init__(master, app, "core-daemon log", modal=True)
self.columnconfigure(0, weight=1)
self.path = tk.StringVar(value="/var/log/core-daemon.log")

View file

@ -3,19 +3,21 @@ size and scale
"""
import tkinter as tk
from tkinter import font, ttk
from typing import TYPE_CHECKING
from core.gui.dialogs.dialog import Dialog
from core.gui.themes import FRAME_PAD, PADX, PADY
if TYPE_CHECKING:
from core.gui.app import Application
PIXEL_SCALE = 100
class SizeAndScaleDialog(Dialog):
def __init__(self, master, app):
def __init__(self, master: "Application", app: "Application"):
"""
create an instance for size and scale object
:param app: main application
"""
super().__init__(master, app, "Canvas Size and Scale", modal=True)
self.canvas = self.app.canvas

View file

@ -4,6 +4,7 @@ set wallpaper
import logging
import tkinter as tk
from tkinter import ttk
from typing import TYPE_CHECKING
from core.gui.appconfig import BACKGROUNDS_PATH
from core.gui.dialogs.dialog import Dialog
@ -11,13 +12,14 @@ from core.gui.images import Images
from core.gui.themes import PADX, PADY
from core.gui.widgets import image_chooser
if TYPE_CHECKING:
from core.gui.app import Application
class CanvasWallpaperDialog(Dialog):
def __init__(self, master, app):
def __init__(self, master: "Application", app: "Application"):
"""
create an instance of CanvasWallpaper object
:param coretk.app.Application app: root application
"""
super().__init__(master, app, "Canvas Background", modal=True)
self.canvas = self.app.canvas
@ -140,8 +142,6 @@ class CanvasWallpaperDialog(Dialog):
def click_clear(self):
"""
delete like shown in image link entry if there is any
:return: nothing
"""
# delete entry
self.filename.set("")

View file

@ -4,12 +4,16 @@ custom color picker
import logging
import tkinter as tk
from tkinter import ttk
from typing import TYPE_CHECKING, Any
from core.gui.dialogs.dialog import Dialog
if TYPE_CHECKING:
from core.gui.app import Application
class ColorPickerDialog(Dialog):
def __init__(self, master, app, initcolor="#000000"):
def __init__(self, master: Any, app: "Application", initcolor: str = "#000000"):
super().__init__(master, app, "color picker", modal=True)
self.red_entry = None
self.blue_entry = None
@ -31,7 +35,7 @@ class ColorPickerDialog(Dialog):
self.draw()
self.set_bindings()
def askcolor(self):
def askcolor(self) -> str:
self.show()
return self.color
@ -175,19 +179,16 @@ class ColorPickerDialog(Dialog):
self.color = self.hex.get()
self.destroy()
def get_hex(self):
def get_hex(self) -> str:
"""
convert current RGB values into hex color
:rtype: str
:return: hex color
"""
red = self.red_entry.get()
blue = self.blue_entry.get()
green = self.green_entry.get()
return "#%02x%02x%02x" % (int(red), int(green), int(blue))
def current_focus(self, focus):
def current_focus(self, focus: str):
self.focus = focus
def update_color(self, arg1=None, arg2=None, arg3=None):
@ -210,35 +211,31 @@ class ColorPickerDialog(Dialog):
self.set_entry(red, green, blue)
self.set_scale(red, green, blue)
self.display.config(background=hex_code)
self.set_label(red, green, blue)
self.set_label(str(red), str(green), str(blue))
def scale_callback(self, var, color_var):
def scale_callback(self, var: tk.IntVar, color_var: tk.IntVar):
color_var.set(var.get())
self.focus = "rgb"
self.update_color()
def set_scale(self, red, green, blue):
def set_scale(self, red: int, green: int, blue: int):
self.red_scale.set(red)
self.green_scale.set(green)
self.blue_scale.set(blue)
def set_entry(self, red, green, blue):
def set_entry(self, red: int, green: int, blue: int):
self.red.set(red)
self.green.set(green)
self.blue.set(blue)
def set_label(self, red, green, blue):
def set_label(self, red: str, green: str, blue: str):
self.red_label.configure(background="#%02x%02x%02x" % (int(red), 0, 0))
self.green_label.configure(background="#%02x%02x%02x" % (0, int(green), 0))
self.blue_label.configure(background="#%02x%02x%02x" % (0, 0, int(blue)))
def get_rgb(self, hex_code):
def get_rgb(self, hex_code: str) -> [int, int, int]:
"""
convert a valid hex code to RGB values
:param string hex_code: color in hex
:rtype: tuple(int, int, int)
:return: the RGB values
"""
if len(hex_code) == 4:
red = hex_code[1]

View file

@ -5,14 +5,18 @@ copy service config dialog
import logging
import tkinter as tk
from tkinter import ttk
from typing import TYPE_CHECKING, Any, Tuple
from core.gui.dialogs.dialog import Dialog
from core.gui.themes import FRAME_PAD, PADX
from core.gui.widgets import CodeText
if TYPE_CHECKING:
from core.gui.app import Application
class CopyServiceConfigDialog(Dialog):
def __init__(self, master, app, node_id):
def __init__(self, master: Any, app: "Application", node_id: int):
super().__init__(master, app, f"Copy services to node {node_id}", modal=True)
self.parent = master
self.app = app
@ -128,6 +132,7 @@ class CopyServiceConfigDialog(Dialog):
def click_view(self):
selected = self.tree.selection()
data = ""
if selected:
item = self.tree.item(selected[0])
if "file" in item["tags"]:
@ -157,7 +162,7 @@ class CopyServiceConfigDialog(Dialog):
)
dialog.show()
def get_node_service(self, selected):
def get_node_service(self, selected: Tuple[str]) -> [int, str]:
service_tree_id = self.tree.parent(selected[0])
service_name = self.tree.item(service_tree_id)["text"]
node_tree_id = self.tree.parent(service_tree_id)
@ -166,7 +171,14 @@ class CopyServiceConfigDialog(Dialog):
class ViewConfigDialog(Dialog):
def __init__(self, master, app, node_id, data, filename=None):
def __init__(
self,
master: Any,
app: "Application",
node_id: int,
data: str,
filename: str = None,
):
super().__init__(master, app, f"n{node_id} config data", modal=True)
self.data = data
self.service_data = None

View file

@ -2,6 +2,7 @@ import logging
import tkinter as tk
from pathlib import Path
from tkinter import ttk
from typing import TYPE_CHECKING, Any, Set
from core.gui import nodeutils
from core.gui.appconfig import ICONS_PATH
@ -11,9 +12,12 @@ from core.gui.nodeutils import NodeDraw
from core.gui.themes import FRAME_PAD, PADX, PADY
from core.gui.widgets import CheckboxList, ListboxScroll, image_chooser
if TYPE_CHECKING:
from core.gui.app import Application
class ServicesSelectDialog(Dialog):
def __init__(self, master, app, current_services):
def __init__(self, master: Any, app: "Application", current_services: Set[str]):
super().__init__(master, app, "Node Services", modal=True)
self.groups = None
self.services = None
@ -71,7 +75,7 @@ class ServicesSelectDialog(Dialog):
# trigger group change
self.groups.listbox.event_generate("<<ListboxSelect>>")
def handle_group_change(self, event):
def handle_group_change(self, event: tk.Event):
selection = self.groups.listbox.curselection()
if selection:
index = selection[0]
@ -81,7 +85,7 @@ class ServicesSelectDialog(Dialog):
checked = name in self.current_services
self.services.add(name, checked)
def service_clicked(self, name, var):
def service_clicked(self, name: str, var: tk.BooleanVar):
if var.get() and name not in self.current_services:
self.current_services.add(name)
elif not var.get() and name in self.current_services:
@ -96,7 +100,7 @@ class ServicesSelectDialog(Dialog):
class CustomNodesDialog(Dialog):
def __init__(self, master, app):
def __init__(self, master: "Application", app: "Application"):
super().__init__(master, app, "Custom Nodes", modal=True)
self.edit_button = None
self.delete_button = None
@ -241,7 +245,7 @@ class CustomNodesDialog(Dialog):
self.nodes_list.listbox.selection_clear(0, tk.END)
self.nodes_list.listbox.event_generate("<<ListboxSelect>>")
def handle_node_select(self, event):
def handle_node_select(self, event: tk.Event):
selection = self.nodes_list.listbox.curselection()
if selection:
self.selected_index = selection[0]

View file

@ -1,12 +1,18 @@
import tkinter as tk
from tkinter import ttk
from typing import TYPE_CHECKING
from core.gui.images import ImageEnum, Images
from core.gui.themes import DIALOG_PAD
if TYPE_CHECKING:
from core.gui.app import Application
class Dialog(tk.Toplevel):
def __init__(self, master, app, title, modal=False):
def __init__(
self, master: tk.Widget, app: "Application", title: str, modal: bool = False
):
super().__init__(master)
self.withdraw()
self.app = app
@ -30,7 +36,7 @@ class Dialog(tk.Toplevel):
self.grab_set()
self.wait_window()
def draw_spacer(self, row=None):
def draw_spacer(self, row: int = None):
frame = ttk.Frame(self.top)
frame.grid(row=row, sticky="nsew")
frame.rowconfigure(0, weight=1)

View file

@ -5,18 +5,24 @@ import logging
import tkinter as tk
import webbrowser
from tkinter import ttk
from typing import TYPE_CHECKING, Any
import grpc
from core.api.grpc import core_pb2
from core.gui.dialogs.dialog import Dialog
from core.gui.errors import show_grpc_error
from core.gui.images import ImageEnum, Images
from core.gui.themes import PADX, PADY
from core.gui.widgets import ConfigFrame
if TYPE_CHECKING:
from core.gui.app import Application
from core.gui.graph.node import CanvasNode
class GlobalEmaneDialog(Dialog):
def __init__(self, master, app):
def __init__(self, master: Any, app: "Application"):
super().__init__(master, app, "EMANE Configuration", modal=True)
self.config_frame = None
self.draw()
@ -47,7 +53,14 @@ class GlobalEmaneDialog(Dialog):
class EmaneModelDialog(Dialog):
def __init__(self, master, app, node, model, interface=None):
def __init__(
self,
master: Any,
app: "Application",
node: core_pb2.Node,
model: str,
interface: int = None,
):
super().__init__(master, app, f"{node.name} {model} Configuration", modal=True)
self.node = node
self.model = f"emane_{model}"
@ -91,7 +104,9 @@ class EmaneModelDialog(Dialog):
class EmaneConfigDialog(Dialog):
def __init__(self, master, app, canvas_node):
def __init__(
self, master: "Application", app: "Application", canvas_node: "CanvasNode"
):
super().__init__(
master, app, f"{canvas_node.core_node.name} EMANE Configuration", modal=True
)
@ -116,8 +131,6 @@ class EmaneConfigDialog(Dialog):
def draw_emane_configuration(self):
"""
draw the main frame for emane configuration
:return: nothing
"""
label = ttk.Label(
self.top,
@ -143,8 +156,6 @@ class EmaneConfigDialog(Dialog):
def draw_emane_models(self):
"""
create a combobox that has all the known emane models
:return: nothing
"""
frame = ttk.Frame(self.top)
frame.grid(sticky="ew", pady=PADY)
@ -210,8 +221,6 @@ class EmaneConfigDialog(Dialog):
def click_model_config(self):
"""
draw emane model configuration
:return: nothing
"""
model_name = self.emane_model.get()
logging.info("configuring emane model: %s", model_name)
@ -220,12 +229,9 @@ class EmaneConfigDialog(Dialog):
)
dialog.show()
def emane_model_change(self, event):
def emane_model_change(self, event: tk.Event):
"""
update emane model options button
:param event:
:return: nothing
"""
model_name = self.emane_model.get()
self.emane_model_button.config(text=f"{model_name} options")

View file

@ -1,14 +1,18 @@
import tkinter as tk
from tkinter import ttk
from typing import TYPE_CHECKING, Any
from core.api.grpc import core_pb2
from core.gui.dialogs.dialog import Dialog
from core.gui.themes import PADX, PADY
from core.gui.widgets import CodeText, ListboxScroll
if TYPE_CHECKING:
from core.gui.app import Application
class HookDialog(Dialog):
def __init__(self, master, app):
def __init__(self, master: Any, app: "Application"):
super().__init__(master, app, "Hook", modal=True)
self.name = tk.StringVar()
self.codetext = None
@ -62,11 +66,11 @@ class HookDialog(Dialog):
button = ttk.Button(frame, text="Cancel", command=lambda: self.destroy())
button.grid(row=0, column=1, sticky="ew")
def state_change(self, event):
def state_change(self, event: tk.Event):
state_name = self.state.get()
self.name.set(f"{state_name.lower()}_hook.sh")
def set(self, hook):
def set(self, hook: core_pb2.Hook):
self.hook = hook
self.name.set(hook.file)
self.codetext.text.delete(1.0, tk.END)
@ -84,7 +88,7 @@ class HookDialog(Dialog):
class HooksDialog(Dialog):
def __init__(self, master, app):
def __init__(self, master: "Application", app: "Application"):
super().__init__(master, app, "Hooks", modal=True)
self.listbox = None
self.edit_button = None
@ -140,7 +144,7 @@ class HooksDialog(Dialog):
self.edit_button.config(state=tk.DISABLED)
self.delete_button.config(state=tk.DISABLED)
def select(self, event):
def select(self, event: tk.Event):
if self.listbox.curselection():
index = self.listbox.curselection()[0]
self.selected = self.listbox.get(index)

View file

@ -4,14 +4,19 @@ link configuration
import logging
import tkinter as tk
from tkinter import ttk
from typing import TYPE_CHECKING, Union
from core.api.grpc import core_pb2
from core.gui.dialogs.colorpicker import ColorPickerDialog
from core.gui.dialogs.dialog import Dialog
from core.gui.themes import PADX, PADY
if TYPE_CHECKING:
from core.gui.app import Application
from core.gui.graph.graph import CanvasGraph, CanvasEdge
def get_int(var):
def get_int(var: tk.StringVar) -> Union[int, None]:
value = var.get()
if value != "":
return int(value)
@ -19,7 +24,7 @@ def get_int(var):
return None
def get_float(var):
def get_float(var: tk.StringVar) -> Union[float, None]:
value = var.get()
if value != "":
return float(value)
@ -28,7 +33,7 @@ def get_float(var):
class LinkConfigurationDialog(Dialog):
def __init__(self, master, app, edge):
def __init__(self, master: "CanvasGraph", app: "Application", edge: "CanvasEdge"):
super().__init__(master, app, "Link Configuration", modal=True)
self.app = app
self.edge = edge
@ -103,7 +108,7 @@ class LinkConfigurationDialog(Dialog):
button = ttk.Button(frame, text="Cancel", command=self.destroy)
button.grid(row=0, column=1, sticky="ew")
def get_frame(self):
def get_frame(self) -> ttk.Frame:
frame = ttk.Frame(self.top)
frame.columnconfigure(1, weight=1)
if self.is_symmetric:
@ -339,8 +344,6 @@ class LinkConfigurationDialog(Dialog):
def load_link_config(self):
"""
populate link config to the table
:return: nothing
"""
width = self.app.canvas.itemcget(self.edge.id, "width")
self.width.set(width)

View file

@ -4,15 +4,21 @@ marker dialog
import tkinter as tk
from tkinter import ttk
from typing import TYPE_CHECKING
from core.gui.dialogs.colorpicker import ColorPickerDialog
from core.gui.dialogs.dialog import Dialog
if TYPE_CHECKING:
from core.gui.app import Application
MARKER_THICKNESS = [3, 5, 8, 10]
class MarkerDialog(Dialog):
def __init__(self, master, app, initcolor="#000000"):
def __init__(
self, master: "Application", app: "Application", initcolor: str = "#000000"
):
super().__init__(master, app, "marker tool", modal=False)
self.app = app
self.color = initcolor
@ -53,13 +59,13 @@ class MarkerDialog(Dialog):
for i in canvas.find_withtag("marker"):
canvas.delete(i)
def change_color(self, event):
def change_color(self, event: tk.Event):
color_picker = ColorPickerDialog(self, self.app, self.color)
color = color_picker.askcolor()
event.widget.configure(background=color)
self.color = color
def change_thickness(self, event):
def change_thickness(self, event: tk.Event):
self.radius = self.marker_thickness.get()
def show(self):

View file

@ -2,6 +2,7 @@
mobility configuration
"""
from tkinter import ttk
from typing import TYPE_CHECKING
import grpc
@ -10,9 +11,15 @@ from core.gui.errors import show_grpc_error
from core.gui.themes import PADX, PADY
from core.gui.widgets import ConfigFrame
if TYPE_CHECKING:
from core.gui.app import Application
from core.gui.graph.node import CanvasNode
class MobilityConfigDialog(Dialog):
def __init__(self, master, app, canvas_node):
def __init__(
self, master: "Application", app: "Application", canvas_node: "CanvasNode"
):
super().__init__(
master,
app,

View file

@ -1,5 +1,6 @@
import tkinter as tk
from tkinter import ttk
from typing import TYPE_CHECKING, Any
import grpc
@ -9,11 +10,21 @@ from core.gui.errors import show_grpc_error
from core.gui.images import ImageEnum, Images
from core.gui.themes import PADX, PADY
if TYPE_CHECKING:
from core.gui.app import Application
from core.gui.graph.node import CanvasNode
ICON_SIZE = 16
class MobilityPlayer:
def __init__(self, master, app, canvas_node, config):
def __init__(
self,
master: "Application",
app: "Application",
canvas_node: "CanvasNode",
config,
):
self.master = master
self.app = app
self.canvas_node = canvas_node
@ -57,7 +68,9 @@ class MobilityPlayer:
class MobilityPlayerDialog(Dialog):
def __init__(self, master, app, canvas_node, config):
def __init__(
self, master: Any, app: "Application", canvas_node: "CanvasNode", config
):
super().__init__(
master, app, f"{canvas_node.core_node.name} Mobility Player", modal=False
)

View file

@ -2,6 +2,7 @@ import logging
import tkinter as tk
from functools import partial
from tkinter import ttk
from typing import TYPE_CHECKING
from core.gui import nodeutils
from core.gui.appconfig import ICONS_PATH
@ -12,20 +13,32 @@ from core.gui.nodeutils import NodeUtils
from core.gui.themes import FRAME_PAD, PADX, PADY
from core.gui.widgets import ListboxScroll, image_chooser
if TYPE_CHECKING:
from core.gui.app import Application
from core.gui.graph.node import CanvasNode
def mac_auto(is_auto, entry):
def mac_auto(is_auto: tk.BooleanVar, entry: ttk.Entry):
logging.info("mac auto clicked")
if is_auto.get():
logging.info("disabling mac")
entry.var.set("")
entry.delete(0, tk.END)
entry.insert(tk.END, "")
entry.config(state=tk.DISABLED)
else:
entry.var.set("00:00:00:00:00:00")
entry.delete(0, tk.END)
entry.insert(tk.END, "00:00:00:00:00:00")
entry.config(state=tk.NORMAL)
class InterfaceData:
def __init__(self, is_auto, mac, ip4, ip6):
def __init__(
self,
is_auto: tk.BooleanVar,
mac: tk.StringVar,
ip4: tk.StringVar,
ip6: tk.StringVar,
):
self.is_auto = is_auto
self.mac = mac
self.ip4 = ip4
@ -33,13 +46,11 @@ class InterfaceData:
class NodeConfigDialog(Dialog):
def __init__(self, master, app, canvas_node):
def __init__(
self, master: "Application", app: "Application", canvas_node: "CanvasNode"
):
"""
create an instance of node configuration
:param master: dialog master
:param coretk.app.Application: main app
:param coretk.graph.CanvasNode canvas_node: canvas node object
"""
super().__init__(
master, app, f"{canvas_node.core_node.name} Configuration", modal=True
@ -217,7 +228,7 @@ class NodeConfigDialog(Dialog):
button = ttk.Button(frame, text="Cancel", command=self.destroy)
button.grid(row=0, column=1, sticky="ew")
def click_emane_config(self, emane_model, interface_id):
def click_emane_config(self, emane_model: str, interface_id: int):
dialog = EmaneModelDialog(self, self.app, self.node, emane_model, interface_id)
dialog.show()
@ -248,7 +259,7 @@ class NodeConfigDialog(Dialog):
self.canvas_node.redraw()
self.destroy()
def interface_select(self, event):
def interface_select(self, event: tk.Event):
listbox = event.widget
cur = listbox.curselection()
if cur:

View file

@ -3,15 +3,26 @@ core node services
"""
import tkinter as tk
from tkinter import messagebox, ttk
from typing import TYPE_CHECKING, Any, Set
from core.gui.dialogs.dialog import Dialog
from core.gui.dialogs.serviceconfig import ServiceConfigDialog
from core.gui.themes import FRAME_PAD, PADX, PADY
from core.gui.widgets import CheckboxList, ListboxScroll
if TYPE_CHECKING:
from core.gui.app import Application
from core.gui.graph.node import CanvasNode
class NodeServiceDialog(Dialog):
def __init__(self, master, app, canvas_node, services=None):
def __init__(
self,
master: Any,
app: "Application",
canvas_node: "CanvasNode",
services: Set[str] = None,
):
title = f"{canvas_node.core_node.name} Services"
super().__init__(master, app, title, modal=True)
self.app = app
@ -87,7 +98,7 @@ class NodeServiceDialog(Dialog):
# trigger group change
self.groups.listbox.event_generate("<<ListboxSelect>>")
def handle_group_change(self, event=None):
def handle_group_change(self, event: tk.Event = None):
selection = self.groups.listbox.curselection()
if selection:
index = selection[0]
@ -97,7 +108,7 @@ class NodeServiceDialog(Dialog):
checked = name in self.current_services
self.services.add(name, checked)
def service_clicked(self, name, var):
def service_clicked(self, name: str, var: tk.IntVar):
if var.get() and name not in self.current_services:
self.current_services.add(name)
elif not var.get() and name in self.current_services:
@ -150,7 +161,7 @@ class NodeServiceDialog(Dialog):
checkbutton.invoke()
return
def is_custom_service(self, service):
def is_custom_service(self, service: str) -> bool:
service_configs = self.app.core.service_configs
file_configs = self.app.core.file_configs
if self.node_id in service_configs and service in service_configs[self.node_id]:

View file

@ -1,14 +1,18 @@
import tkinter as tk
from tkinter import ttk
from typing import TYPE_CHECKING
from core.gui.coreclient import Observer
from core.gui.dialogs.dialog import Dialog
from core.gui.themes import PADX, PADY
from core.gui.widgets import ListboxScroll
if TYPE_CHECKING:
from core.gui.app import Application
class ObserverDialog(Dialog):
def __init__(self, master, app):
def __init__(self, master: "Application", app: "Application"):
super().__init__(master, app, "Observer Widgets", modal=True)
self.observers = None
self.save_button = None
@ -126,7 +130,7 @@ class ObserverDialog(Dialog):
self.save_button.config(state=tk.DISABLED)
self.delete_button.config(state=tk.DISABLED)
def handle_observer_change(self, event):
def handle_observer_change(self, event: tk.Event):
selection = self.observers.curselection()
if selection:
self.selected_index = selection[0]

View file

@ -1,14 +1,18 @@
import logging
import tkinter as tk
from tkinter import ttk
from typing import TYPE_CHECKING
from core.gui import appconfig
from core.gui.dialogs.dialog import Dialog
from core.gui.themes import FRAME_PAD, PADX, PADY
if TYPE_CHECKING:
from core.gui.app import Application
class PreferencesDialog(Dialog):
def __init__(self, master, app):
def __init__(self, master: "Application", app: "Application"):
super().__init__(master, app, "Preferences", modal=True)
preferences = self.app.guiconfig["preferences"]
self.editor = tk.StringVar(value=preferences["editor"])
@ -72,7 +76,7 @@ class PreferencesDialog(Dialog):
button = ttk.Button(frame, text="Cancel", command=self.destroy)
button.grid(row=0, column=1, sticky="ew")
def theme_change(self, event):
def theme_change(self, event: tk.Event):
theme = self.theme.get()
logging.info("changing theme: %s", theme)
self.app.style.theme_use(theme)

View file

@ -1,18 +1,22 @@
import tkinter as tk
from tkinter import ttk
from typing import TYPE_CHECKING
from core.gui.coreclient import CoreServer
from core.gui.dialogs.dialog import Dialog
from core.gui.themes import FRAME_PAD, PADX, PADY
from core.gui.widgets import ListboxScroll
if TYPE_CHECKING:
from core.gui.app import Application
DEFAULT_NAME = "example"
DEFAULT_ADDRESS = "127.0.0.1"
DEFAULT_PORT = 50051
class ServersDialog(Dialog):
def __init__(self, master, app):
def __init__(self, master: "Application", app: "Application"):
super().__init__(master, app, "CORE Servers", modal=True)
self.name = tk.StringVar(value=DEFAULT_NAME)
self.address = tk.StringVar(value=DEFAULT_ADDRESS)
@ -155,7 +159,7 @@ class ServersDialog(Dialog):
self.save_button.config(state=tk.DISABLED)
self.delete_button.config(state=tk.DISABLED)
def handle_server_change(self, event):
def handle_server_change(self, event: tk.Event):
selection = self.servers.curselection()
if selection:
self.selected_index = selection[0]

View file

@ -1,6 +1,9 @@
"Service configuration dialog"
"""
Service configuration dialog
"""
import tkinter as tk
from tkinter import ttk
from typing import TYPE_CHECKING, Any, List
import grpc
@ -12,9 +15,14 @@ from core.gui.images import ImageEnum, Images
from core.gui.themes import FRAME_PAD, PADX, PADY
from core.gui.widgets import CodeText, ListboxScroll
if TYPE_CHECKING:
from core.gui.app import Application
class ServiceConfigDialog(Dialog):
def __init__(self, master, app, service_name, node_id):
def __init__(
self, master: Any, app: "Application", service_name: str, node_id: int
):
title = f"{service_name} Service"
super().__init__(master, app, title, modal=True)
self.master = master
@ -225,7 +233,7 @@ class ServiceConfigDialog(Dialog):
for i in range(3):
tab.rowconfigure(i, weight=1)
self.notebook.add(tab, text="Startup/Shutdown")
commands = []
# tab 3
for i in range(3):
label_frame = None
@ -345,7 +353,7 @@ class ServiceConfigDialog(Dialog):
button = ttk.Button(frame, text="Cancel", command=self.destroy)
button.grid(row=0, column=3, sticky="ew")
def add_filename(self, event):
def add_filename(self, event: tk.Event):
# not worry about it for now
return
frame_contains_button = event.widget.master
@ -354,7 +362,7 @@ class ServiceConfigDialog(Dialog):
if filename not in combobox["values"]:
combobox["values"] += (filename,)
def delete_filename(self, event):
def delete_filename(self, event: tk.Event):
# not worry about it for now
return
frame_comntains_button = event.widget.master
@ -364,7 +372,7 @@ class ServiceConfigDialog(Dialog):
combobox["values"] = tuple([x for x in combobox["values"] if x != filename])
combobox.set("")
def add_command(self, event):
def add_command(self, event: tk.Event):
frame_contains_button = event.widget.master
listbox = frame_contains_button.master.grid_slaves(row=1, column=0)[0].listbox
command_to_add = frame_contains_button.grid_slaves(row=0, column=0)[0].get()
@ -375,7 +383,7 @@ class ServiceConfigDialog(Dialog):
return
listbox.insert(tk.END, command_to_add)
def update_entry(self, event):
def update_entry(self, event: tk.Event):
listbox = event.widget
current_selection = listbox.curselection()
if len(current_selection) > 0:
@ -386,7 +394,7 @@ class ServiceConfigDialog(Dialog):
entry.delete(0, "end")
entry.insert(0, cmd)
def delete_command(self, event):
def delete_command(self, event: tk.Event):
button = event.widget
frame_contains_button = button.master
listbox = frame_contains_button.master.grid_slaves(row=1, column=0)[0].listbox
@ -439,13 +447,13 @@ class ServiceConfigDialog(Dialog):
show_grpc_error(e)
self.destroy()
def display_service_file_data(self, event):
def display_service_file_data(self, event: tk.Event):
combobox = event.widget
filename = combobox.get()
self.service_file_data.text.delete(1.0, "end")
self.service_file_data.text.insert("end", self.temp_service_files[filename])
def update_temp_service_file_data(self, event):
def update_temp_service_file_data(self, event: tk.Event):
scrolledtext = event.widget
filename = self.filename_combobox.get()
self.temp_service_files[filename] = scrolledtext.get(1.0, "end")
@ -490,7 +498,9 @@ class ServiceConfigDialog(Dialog):
dialog = CopyServiceConfigDialog(self, self.app, self.node_id)
dialog.show()
def append_commands(self, commands, listbox, to_add):
def append_commands(
self, commands: List[str], listbox: tk.Listbox, to_add: List[str]
):
for cmd in to_add:
commands.append(cmd)
listbox.insert(tk.END, cmd)

View file

@ -1,5 +1,6 @@
import logging
from tkinter import ttk
from typing import TYPE_CHECKING
import grpc
@ -8,9 +9,12 @@ from core.gui.errors import show_grpc_error
from core.gui.themes import PADX, PADY
from core.gui.widgets import ConfigFrame
if TYPE_CHECKING:
from core.gui.app import Application
class SessionOptionsDialog(Dialog):
def __init__(self, master, app):
def __init__(self, master: "Application", app: "Application"):
super().__init__(master, app, "Session Options", modal=True)
self.config_frame = None
self.config = self.get_config()

View file

@ -1,6 +1,7 @@
import logging
import tkinter as tk
from tkinter import ttk
from typing import TYPE_CHECKING, Iterable
import grpc
@ -11,9 +12,14 @@ from core.gui.images import ImageEnum, Images
from core.gui.task import BackgroundTask
from core.gui.themes import PADX, PADY
if TYPE_CHECKING:
from core.gui.app import Application
class SessionsDialog(Dialog):
def __init__(self, master, app, is_start_app=False):
def __init__(
self, master: "Application", app: "Application", is_start_app: bool = False
):
super().__init__(master, app, "Sessions", modal=True)
self.is_start_app = is_start_app
self.selected = False
@ -22,7 +28,7 @@ class SessionsDialog(Dialog):
self.sessions = self.get_sessions()
self.draw()
def get_sessions(self):
def get_sessions(self) -> Iterable[core_pb2.SessionSummary]:
try:
response = self.app.core.client.get_sessions()
logging.info("sessions: %s", response)
@ -41,7 +47,6 @@ class SessionsDialog(Dialog):
def draw_description(self):
"""
write a short description
:return: nothing
"""
label = ttk.Label(
self.top,
@ -154,7 +159,7 @@ class SessionsDialog(Dialog):
self.app.core.create_new_session()
self.destroy()
def click_select(self, event):
def click_select(self, event: tk.Event):
item = self.tree.selection()
session_id = int(self.tree.item(item, "text"))
self.selected = True
@ -163,8 +168,6 @@ class SessionsDialog(Dialog):
def click_connect(self):
"""
if no session is selected yet, create a new one else join that session
:return: nothing
"""
if self.selected and self.selected_id is not None:
self.join_session(self.selected_id)
@ -177,8 +180,6 @@ class SessionsDialog(Dialog):
"""
if no session is currently selected create a new session else shut the selected
session down.
:return: nothing
"""
if self.selected and self.selected_id is not None:
self.shutdown_session(self.selected_id)
@ -187,18 +188,18 @@ class SessionsDialog(Dialog):
else:
logging.error("querysessiondrawing.py invalid state")
def join_session(self, session_id):
def join_session(self, session_id: int):
self.app.statusbar.progress_bar.start(5)
task = BackgroundTask(self.app, self.app.core.join_session, args=(session_id,))
task.start()
self.destroy()
def on_selected(self, event):
def on_selected(self, event: tk.Event):
item = self.tree.selection()
sid = int(self.tree.item(item, "text"))
self.join_session(sid)
def shutdown_session(self, sid):
def shutdown_session(self, sid: int):
self.app.core.stop_session(sid)
self.click_new()
self.destroy()

View file

@ -3,6 +3,7 @@ shape input dialog
"""
import tkinter as tk
from tkinter import font, ttk
from typing import TYPE_CHECKING, List, Union
from core.gui.dialogs.colorpicker import ColorPickerDialog
from core.gui.dialogs.dialog import Dialog
@ -10,12 +11,16 @@ from core.gui.graph import tags
from core.gui.graph.shapeutils import is_draw_shape, is_shape_text
from core.gui.themes import FRAME_PAD, PADX, PADY
if TYPE_CHECKING:
from core.gui.app import Application
from core.gui.graph.shape import Shape
FONT_SIZES = [8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72]
BORDER_WIDTH = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
class ShapeDialog(Dialog):
def __init__(self, master, app, shape):
def __init__(self, master: "Application", app: "Application", shape: "Shape"):
if is_draw_shape(shape.shape_type):
title = "Add Shape"
else:
@ -162,10 +167,9 @@ class ShapeDialog(Dialog):
self.add_text()
self.destroy()
def make_font(self):
def make_font(self) -> List[Union[int, str]]:
"""
create font for text or shape label
:return: list(font specifications)
"""
size = int(self.font_size.get())
text_font = [self.font.get(), size]
@ -180,8 +184,6 @@ class ShapeDialog(Dialog):
def save_text(self):
"""
save info related to text or shape label
:return: nothing
"""
data = self.shape.shape_data
data.text = self.shape_text.get()
@ -195,8 +197,6 @@ class ShapeDialog(Dialog):
def save_shape(self):
"""
save info related to shape
:return: nothing
"""
data = self.shape.shape_data
data.fill_color = self.fill_color
@ -206,8 +206,6 @@ class ShapeDialog(Dialog):
def add_text(self):
"""
add text to canvas
:return: nothing
"""
text = self.shape_text.get()
text_font = self.make_font()

View file

@ -3,14 +3,18 @@ throughput dialog
"""
import tkinter as tk
from tkinter import ttk
from typing import TYPE_CHECKING
from core.gui.dialogs.colorpicker import ColorPickerDialog
from core.gui.dialogs.dialog import Dialog
from core.gui.themes import FRAME_PAD, PADX, PADY
if TYPE_CHECKING:
from core.gui.app import Application
class ThroughputDialog(Dialog):
def __init__(self, master, app):
def __init__(self, master: "Application", app: "Application"):
super().__init__(master, app, "Throughput Config", modal=False)
self.app = app
self.canvas = app.canvas

View file

@ -3,6 +3,7 @@ wlan configuration
"""
from tkinter import ttk
from typing import TYPE_CHECKING
import grpc
@ -11,9 +12,15 @@ from core.gui.errors import show_grpc_error
from core.gui.themes import PADX, PADY
from core.gui.widgets import ConfigFrame
if TYPE_CHECKING:
from core.gui.app import Application
from core.gui.graph.node import CanvasNode
class WlanConfigDialog(Dialog):
def __init__(self, master, app, canvas_node):
def __init__(
self, master: "Application", app: "Application", canvas_node: "CanvasNode"
):
super().__init__(
master, app, f"{canvas_node.core_node.name} Wlan Configuration", modal=True
)
@ -38,8 +45,6 @@ class WlanConfigDialog(Dialog):
def draw_apply_buttons(self):
"""
create node configuration options
:return: nothing
"""
frame = ttk.Frame(self.top)
frame.grid(sticky="ew")
@ -55,8 +60,6 @@ class WlanConfigDialog(Dialog):
def click_apply(self):
"""
retrieve user's wlan configuration and store the new configuration values
:return: nothing
"""
config = self.config_frame.parse_config()
self.app.core.wlan_configs[self.node.id] = self.config