more on type hinting, remove unecessary function comments
This commit is contained in:
parent
7bbd6aa353
commit
eb5f2c5648
34 changed files with 169 additions and 326 deletions
|
@ -204,7 +204,7 @@ class CoreClient:
|
|||
self.handling_throughputs.cancel()
|
||||
self.handling_throughputs = None
|
||||
|
||||
def handle_throughputs(self, event):
|
||||
def handle_throughputs(self, event: core_pb2.ThroughputsEvent):
|
||||
if event.session_id != self.session_id:
|
||||
logging.warning(
|
||||
"ignoring throughput event session(%s) current(%s)",
|
||||
|
@ -303,7 +303,7 @@ class CoreClient:
|
|||
def is_runtime(self) -> bool:
|
||||
return self.state == core_pb2.SessionState.RUNTIME
|
||||
|
||||
def parse_metadata(self, config):
|
||||
def parse_metadata(self, config: Dict[str, str]):
|
||||
# canvas setting
|
||||
canvas_config = config.get("canvas")
|
||||
logging.info("canvas metadata: %s", canvas_config)
|
||||
|
@ -367,8 +367,6 @@ class CoreClient:
|
|||
def create_new_session(self):
|
||||
"""
|
||||
Create a new session
|
||||
|
||||
:return: nothing
|
||||
"""
|
||||
try:
|
||||
response = self.client.create_session()
|
||||
|
@ -399,8 +397,6 @@ class CoreClient:
|
|||
def set_up(self):
|
||||
"""
|
||||
Query sessions, if there exist any, prompt whether to join one
|
||||
|
||||
:return: existing sessions
|
||||
"""
|
||||
try:
|
||||
self.client.connect()
|
||||
|
@ -534,9 +530,6 @@ class CoreClient:
|
|||
def save_xml(self, file_path: str):
|
||||
"""
|
||||
Save core session as to an xml file
|
||||
|
||||
:param str file_path: file path that user pick
|
||||
:return: nothing
|
||||
"""
|
||||
try:
|
||||
if self.state != core_pb2.SessionState.RUNTIME:
|
||||
|
@ -552,9 +545,6 @@ class CoreClient:
|
|||
def open_xml(self, file_path: str):
|
||||
"""
|
||||
Open core xml
|
||||
|
||||
:param str file_path: file to open
|
||||
:return: session id
|
||||
"""
|
||||
try:
|
||||
response = self.client.open_xml(file_path)
|
||||
|
@ -596,7 +586,7 @@ class CoreClient:
|
|||
return response.data
|
||||
|
||||
def set_node_service_file(
|
||||
self, node_id: int, service_name: str, file_name: str, data: str
|
||||
self, node_id: int, service_name: str, file_name: str, data: bytes
|
||||
):
|
||||
response = self.client.set_node_service_file(
|
||||
self.session_id, node_id, service_name, file_name, data
|
||||
|
@ -606,8 +596,6 @@ class CoreClient:
|
|||
def create_nodes_and_links(self):
|
||||
"""
|
||||
create nodes and links that have not been created yet
|
||||
|
||||
:return: nothing
|
||||
"""
|
||||
node_protos = [x.core_node for x in self.canvas_nodes.values()]
|
||||
link_protos = [x.link for x in self.links.values()]
|
||||
|
@ -634,8 +622,6 @@ class CoreClient:
|
|||
def send_data(self):
|
||||
"""
|
||||
send to daemon all session info, but don't start the session
|
||||
|
||||
:return: nothing
|
||||
"""
|
||||
self.create_nodes_and_links()
|
||||
for config_proto in self.get_wlan_configs_proto():
|
||||
|
@ -680,18 +666,13 @@ class CoreClient:
|
|||
def close(self):
|
||||
"""
|
||||
Clean ups when done using grpc
|
||||
|
||||
:return: nothing
|
||||
"""
|
||||
logging.debug("close grpc")
|
||||
self.client.close()
|
||||
|
||||
def next_node_id(self):
|
||||
def next_node_id(self) -> int:
|
||||
"""
|
||||
Get the next usable node id.
|
||||
|
||||
:return: the next id to be used
|
||||
:rtype: int
|
||||
"""
|
||||
i = 1
|
||||
while True:
|
||||
|
@ -743,9 +724,6 @@ class CoreClient:
|
|||
"""
|
||||
remove the nodes selected by the user and anything related to that node
|
||||
such as link, configurations, interfaces
|
||||
|
||||
:param list canvas_nodes: list of nodes to delete
|
||||
:return: nothing
|
||||
"""
|
||||
edges = set()
|
||||
for canvas_node in canvas_nodes:
|
||||
|
@ -767,9 +745,6 @@ class CoreClient:
|
|||
if edge in edges:
|
||||
continue
|
||||
edges.add(edge)
|
||||
#
|
||||
# if edge.token not in self.links:
|
||||
# logging.error("unknown edge: %s", edge.token)
|
||||
self.links.pop(edge.token, None)
|
||||
|
||||
def create_interface(self, canvas_node: CanvasNode) -> core_pb2.Interface:
|
||||
|
@ -795,12 +770,6 @@ class CoreClient:
|
|||
"""
|
||||
Create core link for a pair of canvas nodes, with token referencing
|
||||
the canvas edge.
|
||||
|
||||
:param edge: edge for link
|
||||
:param canvas_src_node: canvas node one
|
||||
:param canvas_dst_node: canvas node two
|
||||
|
||||
:return: nothing
|
||||
"""
|
||||
src_node = canvas_src_node.core_node
|
||||
dst_node = canvas_dst_node.core_node
|
||||
|
|
|
@ -110,7 +110,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)
|
||||
|
|
|
@ -14,8 +14,6 @@ class SizeAndScaleDialog(Dialog):
|
|||
def __init__(self, master, app):
|
||||
"""
|
||||
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
|
||||
|
|
|
@ -140,8 +140,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("")
|
||||
|
|
|
@ -31,7 +31,7 @@ class ColorPickerDialog(Dialog):
|
|||
self.draw()
|
||||
self.set_bindings()
|
||||
|
||||
def askcolor(self):
|
||||
def askcolor(self) -> str:
|
||||
self.show()
|
||||
return self.color
|
||||
|
||||
|
@ -175,12 +175,9 @@ 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()
|
||||
|
@ -210,35 +207,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]
|
||||
|
|
|
@ -5,6 +5,7 @@ copy service config dialog
|
|||
import logging
|
||||
import tkinter as tk
|
||||
from tkinter import ttk
|
||||
from typing import Tuple
|
||||
|
||||
from core.gui.dialogs.dialog import Dialog
|
||||
from core.gui.themes import FRAME_PAD, PADX
|
||||
|
@ -147,7 +148,7 @@ class CopyServiceConfigDialog(Dialog):
|
|||
dialog = ViewConfigDialog(self, self.app, self.node_id, data)
|
||||
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)
|
||||
|
|
|
@ -71,7 +71,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 +81,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:
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import tkinter as tk
|
||||
from tkinter import ttk
|
||||
from typing import Optional
|
||||
|
||||
from core.gui.images import ImageEnum, Images
|
||||
from core.gui.themes import DIALOG_PAD
|
||||
|
@ -30,7 +31,7 @@ class Dialog(tk.Toplevel):
|
|||
self.grab_set()
|
||||
self.wait_window()
|
||||
|
||||
def draw_spacer(self, row=None):
|
||||
def draw_spacer(self, row: Optional[int] = None):
|
||||
frame = ttk.Frame(self.top)
|
||||
frame.grid(row=row, sticky="nsew")
|
||||
frame.rowconfigure(0, weight=1)
|
||||
|
|
|
@ -116,8 +116,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 +141,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 +206,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 +214,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")
|
||||
|
|
|
@ -62,11 +62,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)
|
||||
|
@ -140,7 +140,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)
|
||||
|
|
|
@ -4,6 +4,7 @@ link configuration
|
|||
import logging
|
||||
import tkinter as tk
|
||||
from tkinter import ttk
|
||||
from typing import Union
|
||||
|
||||
from core.api.grpc import core_pb2
|
||||
from core.gui.dialogs.colorpicker import ColorPickerDialog
|
||||
|
@ -11,7 +12,7 @@ from core.gui.dialogs.dialog import Dialog
|
|||
from core.gui.themes import PADX, PADY
|
||||
|
||||
|
||||
def get_int(var):
|
||||
def get_int(var: tk.StringVar) -> Union[int, None]:
|
||||
value = var.get()
|
||||
if value != "":
|
||||
return int(value)
|
||||
|
@ -19,7 +20,7 @@ def get_int(var):
|
|||
return None
|
||||
|
||||
|
||||
def get_float(var):
|
||||
def get_float(var: tk.StringVar) -> Union[int, None]:
|
||||
value = var.get()
|
||||
if value != "":
|
||||
return float(value)
|
||||
|
@ -103,7 +104,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 +340,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)
|
||||
|
|
|
@ -53,13 +53,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):
|
||||
|
|
|
@ -13,7 +13,7 @@ from core.gui.themes import FRAME_PAD, PADX, PADY
|
|||
from core.gui.widgets import ListboxScroll, image_chooser
|
||||
|
||||
|
||||
def mac_auto(is_auto, entry):
|
||||
def mac_auto(is_auto, entry: ttk.Entry):
|
||||
logging.info("mac auto clicked")
|
||||
if is_auto.get():
|
||||
logging.info("disabling mac")
|
||||
|
@ -217,7 +217,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 +248,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:
|
||||
|
|
|
@ -87,7 +87,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 +97,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 +150,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]:
|
||||
|
|
|
@ -126,7 +126,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]
|
||||
|
|
|
@ -72,7 +72,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)
|
||||
|
|
|
@ -155,7 +155,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]
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
"Service configuration dialog"
|
||||
import tkinter as tk
|
||||
from tkinter import ttk
|
||||
from typing import List
|
||||
|
||||
import grpc
|
||||
|
||||
|
@ -345,7 +346,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 +355,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 +365,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 +376,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 +387,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 +440,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 +491,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)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import logging
|
||||
import tkinter as tk
|
||||
from tkinter import ttk
|
||||
from typing import Iterable
|
||||
|
||||
import grpc
|
||||
|
||||
|
@ -21,7 +22,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)
|
||||
|
@ -40,7 +41,6 @@ class SessionsDialog(Dialog):
|
|||
def draw_description(self):
|
||||
"""
|
||||
write a short description
|
||||
:return: nothing
|
||||
"""
|
||||
label = ttk.Label(
|
||||
self.top,
|
||||
|
@ -129,7 +129,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
|
||||
|
@ -138,8 +138,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)
|
||||
|
@ -152,8 +150,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)
|
||||
|
@ -162,18 +158,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()
|
||||
|
|
|
@ -38,8 +38,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 +53,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
|
||||
|
|
|
@ -14,7 +14,14 @@ EDGE_COLOR = "#ff0000"
|
|||
|
||||
|
||||
class CanvasWirelessEdge:
|
||||
def __init__(self, token: Tuple[int, int], position, src: int, dst: int, canvas):
|
||||
def __init__(
|
||||
self,
|
||||
token: Tuple[int, int],
|
||||
position: Tuple[int, int, int, int],
|
||||
src: int,
|
||||
dst: int,
|
||||
canvas,
|
||||
):
|
||||
self.token = token
|
||||
self.src = src
|
||||
self.dst = dst
|
||||
|
@ -35,11 +42,6 @@ class CanvasEdge:
|
|||
def __init__(self, x1: int, y1: int, x2: int, y2: int, src: int, canvas):
|
||||
"""
|
||||
Create an instance of canvas edge object
|
||||
:param int x1: source x-coord
|
||||
:param int y1: source y-coord
|
||||
:param int x2: destination x-coord
|
||||
:param int y2: destination y-coord
|
||||
:param int src: source id
|
||||
:param coretk.graph.graph.GraphCanvas canvas: canvas object
|
||||
"""
|
||||
self.src = src
|
||||
|
@ -67,7 +69,7 @@ class CanvasEdge:
|
|||
self.link = link
|
||||
self.draw_labels()
|
||||
|
||||
def get_coordinates(self):
|
||||
def get_coordinates(self) -> [int, int, int, int]:
|
||||
x1, y1, x2, y2 = self.canvas.coords(self.id)
|
||||
v1 = x2 - x1
|
||||
v2 = y2 - y1
|
||||
|
@ -79,7 +81,7 @@ class CanvasEdge:
|
|||
y2 = y2 - uy
|
||||
return x1, y1, x2, y2
|
||||
|
||||
def get_midpoint(self):
|
||||
def get_midpoint(self) -> [float, float]:
|
||||
x1, y1, x2, y2 = self.canvas.coords(self.id)
|
||||
x = (x1 + x2) / 2
|
||||
y = (y1 + y2) / 2
|
||||
|
@ -119,8 +121,6 @@ class CanvasEdge:
|
|||
def update_labels(self):
|
||||
"""
|
||||
Move edge labels based on current position.
|
||||
|
||||
:return: nothing
|
||||
"""
|
||||
x1, y1, x2, y2 = self.get_coordinates()
|
||||
self.canvas.coords(self.text_src, x1, y1)
|
||||
|
@ -158,7 +158,7 @@ class CanvasEdge:
|
|||
self.canvas.tag_raise(self.src)
|
||||
self.canvas.tag_raise(self.dst)
|
||||
|
||||
def is_wireless(self):
|
||||
def is_wireless(self) -> [bool, bool]:
|
||||
src_node = self.canvas.nodes[self.src]
|
||||
dst_node = self.canvas.nodes[self.dst]
|
||||
src_node_type = src_node.core_node.type
|
||||
|
@ -184,7 +184,6 @@ class CanvasEdge:
|
|||
dst_node.add_antenna()
|
||||
elif not is_src_wireless and is_dst_wireless:
|
||||
src_node.add_antenna()
|
||||
# TODO: remove this? dont allow linking wireless nodes?
|
||||
else:
|
||||
src_node.add_antenna()
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import logging
|
||||
import tkinter as tk
|
||||
from typing import List, Optional
|
||||
|
||||
from PIL import Image, ImageTk
|
||||
|
||||
|
@ -84,13 +85,11 @@ class CanvasGraph(tk.Canvas):
|
|||
)
|
||||
self.configure(scrollregion=self.bbox(tk.ALL))
|
||||
|
||||
def reset_and_redraw(self, session):
|
||||
def reset_and_redraw(self, session: core_pb2.Session):
|
||||
"""
|
||||
Reset the private variables CanvasGraph object, redraw nodes given the new grpc
|
||||
client.
|
||||
|
||||
:param core.api.grpc.core_pb2.Session session: session to draw
|
||||
:return: nothing
|
||||
"""
|
||||
# hide context
|
||||
self.hide_context()
|
||||
|
@ -114,8 +113,6 @@ class CanvasGraph(tk.Canvas):
|
|||
def setup_bindings(self):
|
||||
"""
|
||||
Bind any mouse events or hot keys to the matching action
|
||||
|
||||
:return: nothing
|
||||
"""
|
||||
self.bind("<ButtonPress-1>", self.click_press)
|
||||
self.bind("<ButtonRelease-1>", self.click_release)
|
||||
|
@ -135,28 +132,28 @@ class CanvasGraph(tk.Canvas):
|
|||
self.context.unpost()
|
||||
self.context = None
|
||||
|
||||
def get_actual_coords(self, x, y):
|
||||
def get_actual_coords(self, x: float, y: float) -> [float, float]:
|
||||
actual_x = (x - self.offset[0]) / self.ratio
|
||||
actual_y = (y - self.offset[1]) / self.ratio
|
||||
return actual_x, actual_y
|
||||
|
||||
def get_scaled_coords(self, x, y):
|
||||
def get_scaled_coords(self, x: float, y: float) -> [float, float]:
|
||||
scaled_x = (x * self.ratio) + self.offset[0]
|
||||
scaled_y = (y * self.ratio) + self.offset[1]
|
||||
return scaled_x, scaled_y
|
||||
|
||||
def inside_canvas(self, x, y):
|
||||
def inside_canvas(self, x: float, y: float) -> [bool, bool]:
|
||||
x1, y1, x2, y2 = self.bbox(self.grid)
|
||||
valid_x = x1 <= x <= x2
|
||||
valid_y = y1 <= y <= y2
|
||||
return valid_x and valid_y
|
||||
|
||||
def valid_position(self, x1, y1, x2, y2):
|
||||
def valid_position(self, x1: int, y1: int, x2: int, y2: int) -> [bool, bool]:
|
||||
valid_topleft = self.inside_canvas(x1, y1)
|
||||
valid_bottomright = self.inside_canvas(x2, y2)
|
||||
return valid_topleft and valid_bottomright
|
||||
|
||||
def set_throughputs(self, throughputs_event):
|
||||
def set_throughputs(self, throughputs_event: core_pb2.ThroughputsEvent):
|
||||
for interface_throughput in throughputs_event.interface_throughputs:
|
||||
node_id = interface_throughput.node_id
|
||||
interface_id = interface_throughput.interface_id
|
||||
|
@ -174,8 +171,6 @@ class CanvasGraph(tk.Canvas):
|
|||
def draw_grid(self):
|
||||
"""
|
||||
Create grid.
|
||||
|
||||
:return: nothing
|
||||
"""
|
||||
width, height = self.width_and_height()
|
||||
width = int(width)
|
||||
|
@ -187,13 +182,12 @@ class CanvasGraph(tk.Canvas):
|
|||
self.tag_lower(tags.GRIDLINE)
|
||||
self.tag_lower(self.grid)
|
||||
|
||||
def add_wireless_edge(self, src, dst):
|
||||
def add_wireless_edge(self, src: CanvasNode, dst: CanvasNode):
|
||||
"""
|
||||
add a wireless edge between 2 canvas nodes
|
||||
|
||||
:param CanvasNode src: source node
|
||||
:param CanvasNode dst: destination node
|
||||
:return: nothing
|
||||
"""
|
||||
token = tuple(sorted((src.id, dst.id)))
|
||||
x1, y1 = self.coords(src.id)
|
||||
|
@ -206,18 +200,16 @@ class CanvasGraph(tk.Canvas):
|
|||
self.tag_raise(src.id)
|
||||
self.tag_raise(dst.id)
|
||||
|
||||
def delete_wireless_edge(self, src, dst):
|
||||
def delete_wireless_edge(self, src: CanvasNode, dst: CanvasNode):
|
||||
token = tuple(sorted((src.id, dst.id)))
|
||||
edge = self.wireless_edges.pop(token)
|
||||
edge.delete()
|
||||
src.wireless_edges.remove(edge)
|
||||
dst.wireless_edges.remove(edge)
|
||||
|
||||
def draw_session(self, session):
|
||||
def draw_session(self, session: core_pb2.Session):
|
||||
"""
|
||||
Draw existing session.
|
||||
|
||||
:return: nothing
|
||||
"""
|
||||
# draw existing nodes
|
||||
for core_node in session.nodes:
|
||||
|
@ -296,25 +288,17 @@ class CanvasGraph(tk.Canvas):
|
|||
for edge in self.edges.values():
|
||||
edge.reset()
|
||||
|
||||
def canvas_xy(self, event):
|
||||
def canvas_xy(self, event: tk.Event) -> [float, float]:
|
||||
"""
|
||||
Convert window coordinate to canvas coordinate
|
||||
|
||||
:param event:
|
||||
:rtype: (int, int)
|
||||
:return: x, y canvas coordinate
|
||||
"""
|
||||
x = self.canvasx(event.x)
|
||||
y = self.canvasy(event.y)
|
||||
return x, y
|
||||
|
||||
def get_selected(self, event):
|
||||
def get_selected(self, event: tk.Event) -> int:
|
||||
"""
|
||||
Retrieve the item id that is on the mouse position
|
||||
|
||||
:param event: mouse event
|
||||
:rtype: int
|
||||
:return: the item that the mouse point to
|
||||
"""
|
||||
x, y = self.canvas_xy(event)
|
||||
overlapping = self.find_overlapping(x, y, x, y)
|
||||
|
@ -332,7 +316,7 @@ class CanvasGraph(tk.Canvas):
|
|||
|
||||
return selected
|
||||
|
||||
def click_release(self, event):
|
||||
def click_release(self, event: tk.Event):
|
||||
"""
|
||||
Draw a node or finish drawing an edge according to the current graph mode
|
||||
|
||||
|
@ -380,7 +364,7 @@ class CanvasGraph(tk.Canvas):
|
|||
self.mode = GraphMode.NODE
|
||||
self.selected = None
|
||||
|
||||
def handle_edge_release(self, event):
|
||||
def handle_edge_release(self, event: tk.Event):
|
||||
edge = self.drawing_edge
|
||||
self.drawing_edge = None
|
||||
|
||||
|
@ -417,7 +401,7 @@ class CanvasGraph(tk.Canvas):
|
|||
node_dst.edges.add(edge)
|
||||
self.core.create_link(edge, node_src, node_dst)
|
||||
|
||||
def select_object(self, object_id, choose_multiple=False):
|
||||
def select_object(self, object_id: int, choose_multiple: Optional[bool] = False):
|
||||
"""
|
||||
create a bounding box when a node is selected
|
||||
"""
|
||||
|
@ -441,19 +425,17 @@ class CanvasGraph(tk.Canvas):
|
|||
def clear_selection(self):
|
||||
"""
|
||||
Clear current selection boxes.
|
||||
|
||||
:return: nothing
|
||||
"""
|
||||
for _id in self.selection.values():
|
||||
self.delete(_id)
|
||||
self.selection.clear()
|
||||
|
||||
def move_selection(self, object_id, x_offset, y_offset):
|
||||
def move_selection(self, object_id: int, x_offset: float, y_offset: float):
|
||||
select_id = self.selection.get(object_id)
|
||||
if select_id is not None:
|
||||
self.move(select_id, x_offset, y_offset)
|
||||
|
||||
def delete_selection_objects(self):
|
||||
def delete_selection_objects(self) -> List[CanvasNode]:
|
||||
edges = set()
|
||||
nodes = []
|
||||
for object_id in self.selection:
|
||||
|
@ -499,7 +481,7 @@ class CanvasGraph(tk.Canvas):
|
|||
self.selection.clear()
|
||||
return nodes
|
||||
|
||||
def zoom(self, event, factor=None):
|
||||
def zoom(self, event: tk.Event, factor: Optional[float] = None):
|
||||
if not factor:
|
||||
factor = ZOOM_IN if event.delta > 0 else ZOOM_OUT
|
||||
event.x, event.y = self.canvasx(event.x), self.canvasy(event.y)
|
||||
|
@ -517,12 +499,9 @@ class CanvasGraph(tk.Canvas):
|
|||
if self.wallpaper:
|
||||
self.redraw_wallpaper()
|
||||
|
||||
def click_press(self, event):
|
||||
def click_press(self, event: tk.Event):
|
||||
"""
|
||||
Start drawing an edge if mouse click is on a node
|
||||
|
||||
:param event: mouse event
|
||||
:return: nothing
|
||||
"""
|
||||
x, y = self.canvas_xy(event)
|
||||
if not self.inside_canvas(x, y):
|
||||
|
@ -581,7 +560,7 @@ class CanvasGraph(tk.Canvas):
|
|||
self.select_box = shape
|
||||
self.clear_selection()
|
||||
|
||||
def ctrl_click(self, event):
|
||||
def ctrl_click(self, event: tk.Event):
|
||||
# update cursor location
|
||||
x, y = self.canvas_xy(event)
|
||||
if not self.inside_canvas(x, y):
|
||||
|
@ -599,12 +578,9 @@ class CanvasGraph(tk.Canvas):
|
|||
):
|
||||
self.select_object(selected, choose_multiple=True)
|
||||
|
||||
def click_motion(self, event):
|
||||
def click_motion(self, event: tk.Event):
|
||||
"""
|
||||
Redraw drawing edge according to the current position of the mouse
|
||||
|
||||
:param event: mouse event
|
||||
:return: nothing
|
||||
"""
|
||||
x, y = self.canvas_xy(event)
|
||||
if not self.inside_canvas(x, y):
|
||||
|
@ -658,7 +634,7 @@ class CanvasGraph(tk.Canvas):
|
|||
if self.select_box and self.mode == GraphMode.SELECT:
|
||||
self.select_box.shape_motion(x, y)
|
||||
|
||||
def click_context(self, event):
|
||||
def click_context(self, event: tk.Event):
|
||||
logging.info("context event: %s", self.context)
|
||||
if not self.context:
|
||||
selected = self.get_selected(event)
|
||||
|
@ -670,24 +646,22 @@ class CanvasGraph(tk.Canvas):
|
|||
else:
|
||||
self.hide_context()
|
||||
|
||||
def press_delete(self, event):
|
||||
def press_delete(self, event: tk.Event):
|
||||
"""
|
||||
delete selected nodes and any data that relates to it
|
||||
:param event:
|
||||
:return:
|
||||
"""
|
||||
logging.debug("press delete key")
|
||||
nodes = self.delete_selection_objects()
|
||||
self.core.delete_graph_nodes(nodes)
|
||||
|
||||
def double_click(self, event):
|
||||
def double_click(self, event: tk.Event):
|
||||
selected = self.get_selected(event)
|
||||
if selected is not None and selected in self.shapes:
|
||||
shape = self.shapes[selected]
|
||||
dialog = ShapeDialog(self.app, self.app, shape)
|
||||
dialog.show()
|
||||
|
||||
def add_node(self, x, y):
|
||||
def add_node(self, x: float, y: float) -> CanvasNode:
|
||||
if self.selected is None or self.selected in self.shapes:
|
||||
actual_x, actual_y = self.get_actual_coords(x, y)
|
||||
core_node = self.core.create_node(
|
||||
|
@ -701,26 +675,28 @@ class CanvasGraph(tk.Canvas):
|
|||
def width_and_height(self):
|
||||
"""
|
||||
retrieve canvas width and height in pixels
|
||||
|
||||
:return: nothing
|
||||
"""
|
||||
x0, y0, x1, y1 = self.coords(self.grid)
|
||||
canvas_w = abs(x0 - x1)
|
||||
canvas_h = abs(y0 - y1)
|
||||
return canvas_w, canvas_h
|
||||
|
||||
def get_wallpaper_image(self):
|
||||
def get_wallpaper_image(self) -> Image.Image:
|
||||
width = int(self.wallpaper.width * self.ratio)
|
||||
height = int(self.wallpaper.height * self.ratio)
|
||||
image = self.wallpaper.resize((width, height), Image.ANTIALIAS)
|
||||
return image
|
||||
|
||||
def draw_wallpaper(self, image, x=None, y=None):
|
||||
def draw_wallpaper(
|
||||
self,
|
||||
image: ImageTk.PhotoImage,
|
||||
x: Optional[float] = None,
|
||||
y: Optional[float] = None,
|
||||
):
|
||||
if x is None and y is None:
|
||||
x1, y1, x2, y2 = self.bbox(self.grid)
|
||||
x = (x1 + x2) / 2
|
||||
y = (y1 + y2) / 2
|
||||
|
||||
self.wallpaper_id = self.create_image((x, y), image=image, tags=tags.WALLPAPER)
|
||||
self.wallpaper_drawn = image
|
||||
|
||||
|
@ -748,8 +724,6 @@ class CanvasGraph(tk.Canvas):
|
|||
def wallpaper_center(self):
|
||||
"""
|
||||
place the image at the center of canvas
|
||||
|
||||
:return: nothing
|
||||
"""
|
||||
self.delete(self.wallpaper_id)
|
||||
|
||||
|
@ -773,8 +747,6 @@ class CanvasGraph(tk.Canvas):
|
|||
def wallpaper_scaled(self):
|
||||
"""
|
||||
scale image based on canvas dimension
|
||||
|
||||
:return: nothing
|
||||
"""
|
||||
self.delete(self.wallpaper_id)
|
||||
canvas_w, canvas_h = self.width_and_height()
|
||||
|
@ -788,7 +760,7 @@ class CanvasGraph(tk.Canvas):
|
|||
self.redraw_canvas((image.width(), image.height()))
|
||||
self.draw_wallpaper(image)
|
||||
|
||||
def redraw_canvas(self, dimensions=None):
|
||||
def redraw_canvas(self, dimensions: Optional[List[int]] = None):
|
||||
logging.info("redrawing canvas to dimensions: %s", dimensions)
|
||||
|
||||
# reset scale and move back to original position
|
||||
|
@ -836,7 +808,7 @@ class CanvasGraph(tk.Canvas):
|
|||
else:
|
||||
self.itemconfig(tags.GRIDLINE, state=tk.HIDDEN)
|
||||
|
||||
def set_wallpaper(self, filename):
|
||||
def set_wallpaper(self, filename: str):
|
||||
logging.info("setting wallpaper: %s", filename)
|
||||
if filename:
|
||||
img = Image.open(filename)
|
||||
|
@ -849,16 +821,12 @@ class CanvasGraph(tk.Canvas):
|
|||
self.wallpaper = None
|
||||
self.wallpaper_file = None
|
||||
|
||||
def is_selection_mode(self):
|
||||
def is_selection_mode(self) -> bool:
|
||||
return self.mode == GraphMode.SELECT
|
||||
|
||||
def create_edge(self, source, dest):
|
||||
def create_edge(self, source: CanvasNode, dest: CanvasNode):
|
||||
"""
|
||||
create an edge between source node and destination node
|
||||
|
||||
:param CanvasNode source: source node
|
||||
:param CanvasNode dest: destination node
|
||||
:return: nothing
|
||||
"""
|
||||
if (source.id, dest.id) not in self.edges:
|
||||
pos0 = source.core_node.position
|
||||
|
|
|
@ -20,7 +20,7 @@ NODE_TEXT_OFFSET = 5
|
|||
|
||||
|
||||
class CanvasNode:
|
||||
def __init__(self, app, x: int, y: int, core_node: core_pb2.Node, image):
|
||||
def __init__(self, app, x: float, y: float, core_node: core_pb2.Node, image):
|
||||
self.app = app
|
||||
self.canvas = app.canvas
|
||||
self.image = image
|
||||
|
@ -70,8 +70,6 @@ class CanvasNode:
|
|||
def delete_antenna(self):
|
||||
"""
|
||||
delete one antenna
|
||||
|
||||
:return: nothing
|
||||
"""
|
||||
if self.antennae:
|
||||
antenna_id = self.antennae.pop()
|
||||
|
@ -80,8 +78,6 @@ class CanvasNode:
|
|||
def delete_antennae(self):
|
||||
"""
|
||||
delete all antennas
|
||||
|
||||
:return: nothing
|
||||
"""
|
||||
for antenna_id in self.antennae:
|
||||
self.canvas.delete(antenna_id)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import logging
|
||||
from typing import List, Optional, Union
|
||||
|
||||
from core.gui.dialogs.shapemod import ShapeDialog
|
||||
from core.gui.graph import tags
|
||||
|
@ -8,16 +9,16 @@ from core.gui.graph.shapeutils import ShapeType
|
|||
class AnnotationData:
|
||||
def __init__(
|
||||
self,
|
||||
text="",
|
||||
font="Arial",
|
||||
font_size=12,
|
||||
text_color="#000000",
|
||||
fill_color="",
|
||||
border_color="#000000",
|
||||
border_width=1,
|
||||
bold=False,
|
||||
italic=False,
|
||||
underline=False,
|
||||
text: Optional[str] = "",
|
||||
font: Optional[str] = "Arial",
|
||||
font_size: Optional[int] = 12,
|
||||
text_color: Optional[str] = "#000000",
|
||||
fill_color: Optional[str] = "",
|
||||
border_color: Optional[str] = "#000000",
|
||||
border_width: Optional[int] = 1,
|
||||
bold: Optional[bool] = False,
|
||||
italic: Optional[bool] = False,
|
||||
underline: Optional[bool] = False,
|
||||
):
|
||||
self.text = text
|
||||
self.font = font
|
||||
|
@ -99,7 +100,7 @@ class Shape:
|
|||
logging.error("unknown shape type: %s", self.shape_type)
|
||||
self.created = True
|
||||
|
||||
def get_font(self):
|
||||
def get_font(self) -> List[Union[int, str]]:
|
||||
font = [self.shape_data.font, self.shape_data.font_size]
|
||||
if self.shape_data.bold:
|
||||
font.append("bold")
|
||||
|
@ -123,10 +124,10 @@ class Shape:
|
|||
font=font,
|
||||
)
|
||||
|
||||
def shape_motion(self, x1: int, y1: int):
|
||||
def shape_motion(self, x1: float, y1: float):
|
||||
self.canvas.coords(self.id, self.x1, self.y1, x1, y1)
|
||||
|
||||
def shape_complete(self, x, y):
|
||||
def shape_complete(self, x: float, y: float):
|
||||
for component in tags.ABOVE_SHAPE:
|
||||
self.canvas.tag_raise(component)
|
||||
s = ShapeDialog(self.app, self.app, self)
|
||||
|
@ -135,7 +136,7 @@ class Shape:
|
|||
def disappear(self):
|
||||
self.canvas.delete(self.id)
|
||||
|
||||
def motion(self, x_offset: int, y_offset: int):
|
||||
def motion(self, x_offset: float, y_offset: float):
|
||||
original_position = self.canvas.coords(self.id)
|
||||
self.canvas.move(self.id, x_offset, y_offset)
|
||||
coords = self.canvas.coords(self.id)
|
||||
|
|
|
@ -11,13 +11,13 @@ class ShapeType(enum.Enum):
|
|||
SHAPES = {ShapeType.OVAL, ShapeType.RECTANGLE}
|
||||
|
||||
|
||||
def is_draw_shape(shape_type):
|
||||
def is_draw_shape(shape_type: ShapeType) -> bool:
|
||||
return shape_type in SHAPES
|
||||
|
||||
|
||||
def is_shape_text(shape_type):
|
||||
def is_shape_text(shape_type: ShapeType) -> bool:
|
||||
return shape_type == ShapeType.TEXT
|
||||
|
||||
|
||||
def is_marker(shape_type):
|
||||
def is_marker(shape_type: ShapeType) -> bool:
|
||||
return shape_type == ShapeType.MARKER
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import tkinter as tk
|
||||
from tkinter import ttk
|
||||
from typing import Optional
|
||||
|
||||
from core.gui.themes import Styles
|
||||
|
||||
|
@ -30,10 +31,10 @@ class CanvasTooltip:
|
|||
self.id = None
|
||||
self.tw = None
|
||||
|
||||
def on_enter(self, event=None):
|
||||
def on_enter(self, event: Optional[tk.Event] = None):
|
||||
self.schedule()
|
||||
|
||||
def on_leave(self, event=None):
|
||||
def on_leave(self, event: Optional[tk.Event] = None):
|
||||
self.unschedule()
|
||||
self.hide()
|
||||
|
||||
|
@ -47,7 +48,7 @@ class CanvasTooltip:
|
|||
if id_:
|
||||
self.canvas.after_cancel(id_)
|
||||
|
||||
def show(self, event=None):
|
||||
def show(self, event: Optional[tk.Event] = None):
|
||||
def tip_pos_calculator(canvas, label, *, tip_delta=(10, 5), pad=(5, 3, 5, 3)):
|
||||
c = canvas
|
||||
s_width, s_height = c.winfo_screenwidth(), c.winfo_screenheight()
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
import logging
|
||||
import random
|
||||
from typing import Optional, Set
|
||||
|
||||
from netaddr import IPNetwork
|
||||
|
||||
from core.gui.graph.node import CanvasNode
|
||||
from core.gui.nodeutils import NodeUtils
|
||||
|
||||
|
||||
|
@ -11,7 +13,9 @@ def random_mac():
|
|||
|
||||
|
||||
class InterfaceManager:
|
||||
def __init__(self, app, address="10.0.0.0", mask=24):
|
||||
def __init__(
|
||||
self, app, address: Optional[str] = "10.0.0.0", mask: Optional[int] = 24
|
||||
):
|
||||
self.app = app
|
||||
self.mask = mask
|
||||
self.base_prefix = max(self.mask - 8, 0)
|
||||
|
@ -38,7 +42,7 @@ class InterfaceManager:
|
|||
def reset(self):
|
||||
self.current_subnet = None
|
||||
|
||||
def get_ips(self, node_id):
|
||||
def get_ips(self, node_id: int):
|
||||
ip4 = self.current_subnet[node_id]
|
||||
ip6 = ip4.ipv6()
|
||||
prefix = self.current_subnet.prefixlen
|
||||
|
@ -48,7 +52,9 @@ class InterfaceManager:
|
|||
def get_subnet(cls, interface):
|
||||
return IPNetwork(f"{interface.ip4}/{interface.ip4mask}").cidr
|
||||
|
||||
def determine_subnet(self, canvas_src_node, canvas_dst_node):
|
||||
def determine_subnet(
|
||||
self, canvas_src_node: CanvasNode, canvas_dst_node: CanvasNode
|
||||
):
|
||||
src_node = canvas_src_node.core_node
|
||||
dst_node = canvas_dst_node.core_node
|
||||
is_src_container = NodeUtils.is_container_node(src_node.type)
|
||||
|
@ -70,7 +76,7 @@ class InterfaceManager:
|
|||
else:
|
||||
logging.info("ignoring subnet change for link between network nodes")
|
||||
|
||||
def find_subnet(self, canvas_node, visited=None):
|
||||
def find_subnet(self, canvas_node: CanvasNode, visited: Optional[Set[int]] = None):
|
||||
logging.info("finding subnet for node: %s", canvas_node.core_node.name)
|
||||
canvas = self.app.canvas
|
||||
cidr = None
|
||||
|
|
|
@ -32,14 +32,14 @@ class MenuAction:
|
|||
self.app = app
|
||||
self.canvas = app.canvas
|
||||
|
||||
def cleanup_old_session(self, quitapp: bool = False):
|
||||
def cleanup_old_session(self, quitapp: Optional[bool] = False):
|
||||
logging.info("cleaning up old session")
|
||||
self.app.core.stop_session()
|
||||
self.app.core.delete_session()
|
||||
# if quitapp:
|
||||
# self.app.quit()
|
||||
|
||||
def prompt_save_running_session(self, quitapp: bool = False):
|
||||
def prompt_save_running_session(self, quitapp: Optional[bool] = False):
|
||||
"""
|
||||
Prompt use to stop running session before application is closed
|
||||
|
||||
|
|
|
@ -13,10 +13,6 @@ class Menubar(tk.Menu):
|
|||
def __init__(self, master, app, cnf={}, **kwargs):
|
||||
"""
|
||||
Create a CoreMenubar instance
|
||||
|
||||
:param master:
|
||||
:param tkinter.Menu menubar: menubar object
|
||||
:param coretk.app.Application app: application object
|
||||
"""
|
||||
super().__init__(master, cnf, **kwargs)
|
||||
self.master.config(menu=self)
|
||||
|
@ -27,8 +23,6 @@ class Menubar(tk.Menu):
|
|||
def draw(self):
|
||||
"""
|
||||
Create core menubar and bind the hot keys to their matching command
|
||||
|
||||
:return: nothing
|
||||
"""
|
||||
self.draw_file_menu()
|
||||
self.draw_edit_menu()
|
||||
|
@ -42,8 +36,6 @@ class Menubar(tk.Menu):
|
|||
def draw_file_menu(self):
|
||||
"""
|
||||
Create file menu
|
||||
|
||||
:return: nothing
|
||||
"""
|
||||
menu = tk.Menu(self)
|
||||
menu.add_command(
|
||||
|
@ -81,8 +73,6 @@ class Menubar(tk.Menu):
|
|||
def draw_edit_menu(self):
|
||||
"""
|
||||
Create edit menu
|
||||
|
||||
:return: nothing
|
||||
"""
|
||||
menu = tk.Menu(self)
|
||||
menu.add_command(label="Preferences", command=self.menuaction.gui_preferences)
|
||||
|
@ -112,8 +102,6 @@ class Menubar(tk.Menu):
|
|||
def draw_canvas_menu(self):
|
||||
"""
|
||||
Create canvas menu
|
||||
|
||||
:return: nothing
|
||||
"""
|
||||
menu = tk.Menu(self)
|
||||
menu.add_command(
|
||||
|
@ -136,8 +124,6 @@ class Menubar(tk.Menu):
|
|||
def draw_view_menu(self):
|
||||
"""
|
||||
Create view menu
|
||||
|
||||
:return: nothing
|
||||
"""
|
||||
view_menu = tk.Menu(self)
|
||||
self.create_show_menu(view_menu)
|
||||
|
@ -152,9 +138,6 @@ class Menubar(tk.Menu):
|
|||
def create_show_menu(self, view_menu: tk.Menu):
|
||||
"""
|
||||
Create the menu items in View/Show
|
||||
|
||||
:param tkinter.Menu view_menu: the view menu
|
||||
:return: nothing
|
||||
"""
|
||||
menu = tk.Menu(view_menu)
|
||||
menu.add_command(label="All", state=tk.DISABLED)
|
||||
|
@ -172,9 +155,6 @@ class Menubar(tk.Menu):
|
|||
def create_experimental_menu(self, tools_menu: tk.Menu):
|
||||
"""
|
||||
Create experimental menu item and the sub menu items inside
|
||||
|
||||
:param tkinter.Menu tools_menu: tools menu
|
||||
:return: nothing
|
||||
"""
|
||||
menu = tk.Menu(tools_menu)
|
||||
menu.add_command(label="Plugins...", state=tk.DISABLED)
|
||||
|
@ -185,9 +165,6 @@ class Menubar(tk.Menu):
|
|||
def create_random_menu(self, topology_generator_menu: tk.Menu):
|
||||
"""
|
||||
Create random menu item and the sub menu items inside
|
||||
|
||||
:param tkinter.Menu topology_generator_menu: topology generator menu
|
||||
:return: nothing
|
||||
"""
|
||||
menu = tk.Menu(topology_generator_menu)
|
||||
# list of number of random nodes to create
|
||||
|
@ -200,9 +177,6 @@ class Menubar(tk.Menu):
|
|||
def create_grid_menu(self, topology_generator_menu: tk.Menu):
|
||||
"""
|
||||
Create grid menu item and the sub menu items inside
|
||||
|
||||
:param tkinter.Menu topology_generator_menu: topology_generator_menu
|
||||
:return: nothing
|
||||
"""
|
||||
menu = tk.Menu(topology_generator_menu)
|
||||
# list of number of nodes to create
|
||||
|
@ -215,9 +189,6 @@ class Menubar(tk.Menu):
|
|||
def create_connected_grid_menu(self, topology_generator_menu: tk.Menu):
|
||||
"""
|
||||
Create connected grid menu items and the sub menu items inside
|
||||
|
||||
:param tkinter.Menu topology_generator_menu: topology generator menu
|
||||
:return: nothing
|
||||
"""
|
||||
menu = tk.Menu(topology_generator_menu)
|
||||
for i in range(1, 11, 1):
|
||||
|
@ -232,9 +203,6 @@ class Menubar(tk.Menu):
|
|||
def create_chain_menu(self, topology_generator_menu: tk.Menu):
|
||||
"""
|
||||
Create chain menu item and the sub menu items inside
|
||||
|
||||
:param tkinter.Menu topology_generator_menu: topology generator menu
|
||||
:return: nothing
|
||||
"""
|
||||
menu = tk.Menu(topology_generator_menu)
|
||||
# number of nodes to create
|
||||
|
@ -247,9 +215,6 @@ class Menubar(tk.Menu):
|
|||
def create_star_menu(self, topology_generator_menu: tk.Menu):
|
||||
"""
|
||||
Create star menu item and the sub menu items inside
|
||||
|
||||
:param tkinter.Menu topology_generator_menu: topology generator menu
|
||||
:return: nothing
|
||||
"""
|
||||
menu = tk.Menu(topology_generator_menu)
|
||||
for i in range(3, 26, 1):
|
||||
|
@ -260,9 +225,6 @@ class Menubar(tk.Menu):
|
|||
def create_cycle_menu(self, topology_generator_menu: tk.Menu):
|
||||
"""
|
||||
Create cycle menu item and the sub items inside
|
||||
|
||||
:param tkinter.Menu topology_generator_menu: topology generator menu
|
||||
:return: nothing
|
||||
"""
|
||||
menu = tk.Menu(topology_generator_menu)
|
||||
for i in range(3, 25, 1):
|
||||
|
@ -273,9 +235,6 @@ class Menubar(tk.Menu):
|
|||
def create_wheel_menu(self, topology_generator_menu: tk.Menu):
|
||||
"""
|
||||
Create wheel menu item and the sub menu items inside
|
||||
|
||||
:param tkinter.Menu topology_generator_menu: topology generator menu
|
||||
:return: nothing
|
||||
"""
|
||||
menu = tk.Menu(topology_generator_menu)
|
||||
for i in range(4, 26, 1):
|
||||
|
@ -286,9 +245,6 @@ class Menubar(tk.Menu):
|
|||
def create_cube_menu(self, topology_generator_menu: tk.Menu):
|
||||
"""
|
||||
Create cube menu item and the sub menu items inside
|
||||
|
||||
:param tkinter.Menu topology_generator_menu: topology generator menu
|
||||
:return: nothing
|
||||
"""
|
||||
menu = tk.Menu(topology_generator_menu)
|
||||
for i in range(2, 7, 1):
|
||||
|
@ -299,9 +255,6 @@ class Menubar(tk.Menu):
|
|||
def create_clique_menu(self, topology_generator_menu: tk.Menu):
|
||||
"""
|
||||
Create clique menu item and the sub menu items inside
|
||||
|
||||
:param tkinter.Menu topology_generator_menu: topology generator menu
|
||||
:return: nothing
|
||||
"""
|
||||
menu = tk.Menu(topology_generator_menu)
|
||||
for i in range(3, 25, 1):
|
||||
|
@ -312,9 +265,6 @@ class Menubar(tk.Menu):
|
|||
def create_bipartite_menu(self, topology_generator_menu: tk.Menu):
|
||||
"""
|
||||
Create bipartite menu item and the sub menu items inside
|
||||
|
||||
:param tkinter.Menu topology_generator_menu: topology_generator_menu
|
||||
:return: nothing
|
||||
"""
|
||||
menu = tk.Menu(topology_generator_menu)
|
||||
temp = 24
|
||||
|
@ -331,10 +281,6 @@ class Menubar(tk.Menu):
|
|||
def create_topology_generator_menu(self, tools_menu: tk.Menu):
|
||||
"""
|
||||
Create topology menu item and its sub menu items
|
||||
|
||||
:param tkinter.Menu tools_menu: tools menu
|
||||
|
||||
:return: nothing
|
||||
"""
|
||||
menu = tk.Menu(tools_menu)
|
||||
self.create_random_menu(menu)
|
||||
|
@ -352,8 +298,6 @@ class Menubar(tk.Menu):
|
|||
def draw_tools_menu(self):
|
||||
"""
|
||||
Create tools menu
|
||||
|
||||
:return: nothing
|
||||
"""
|
||||
menu = tk.Menu(self)
|
||||
menu.add_command(label="Auto rearrange all", state=tk.DISABLED)
|
||||
|
@ -374,9 +318,6 @@ class Menubar(tk.Menu):
|
|||
def create_observer_widgets_menu(self, widget_menu: tk.Menu):
|
||||
"""
|
||||
Create observer widget menu item and create the sub menu items inside
|
||||
|
||||
:param tkinter.Menu widget_menu: widget_menu
|
||||
:return: nothing
|
||||
"""
|
||||
var = tk.StringVar(value="none")
|
||||
menu = tk.Menu(widget_menu)
|
||||
|
@ -412,9 +353,6 @@ class Menubar(tk.Menu):
|
|||
def create_adjacency_menu(self, widget_menu: tk.Menu):
|
||||
"""
|
||||
Create adjacency menu item and the sub menu items inside
|
||||
|
||||
:param tkinter.Menu widget_menu: widget menu
|
||||
:return: nothing
|
||||
"""
|
||||
menu = tk.Menu(widget_menu)
|
||||
menu.add_command(label="OSPFv2", state=tk.DISABLED)
|
||||
|
@ -426,8 +364,6 @@ class Menubar(tk.Menu):
|
|||
def draw_widgets_menu(self):
|
||||
"""
|
||||
Create widget menu
|
||||
|
||||
:return: nothing
|
||||
"""
|
||||
menu = tk.Menu(self)
|
||||
self.create_observer_widgets_menu(menu)
|
||||
|
@ -443,8 +379,6 @@ class Menubar(tk.Menu):
|
|||
def draw_session_menu(self):
|
||||
"""
|
||||
Create session menu
|
||||
|
||||
:return: nothing
|
||||
"""
|
||||
menu = tk.Menu(self)
|
||||
menu.add_command(
|
||||
|
@ -461,8 +395,6 @@ class Menubar(tk.Menu):
|
|||
def draw_help_menu(self):
|
||||
"""
|
||||
Create help menu
|
||||
|
||||
:return: nothing
|
||||
"""
|
||||
menu = tk.Menu(self)
|
||||
menu.add_command(
|
||||
|
|
|
@ -53,31 +53,31 @@ class NodeUtils:
|
|||
ANTENNA_ICON = None
|
||||
|
||||
@classmethod
|
||||
def is_ignore_node(cls, node_type):
|
||||
def is_ignore_node(cls, node_type) -> bool:
|
||||
return node_type in cls.IGNORE_NODES
|
||||
|
||||
@classmethod
|
||||
def is_container_node(cls, node_type):
|
||||
def is_container_node(cls, node_type) -> bool:
|
||||
return node_type in cls.CONTAINER_NODES
|
||||
|
||||
@classmethod
|
||||
def is_model_node(cls, node_type):
|
||||
def is_model_node(cls, node_type) -> bool:
|
||||
return node_type == NodeType.DEFAULT
|
||||
|
||||
@classmethod
|
||||
def is_image_node(cls, node_type):
|
||||
def is_image_node(cls, node_type) -> bool:
|
||||
return node_type in cls.IMAGE_NODES
|
||||
|
||||
@classmethod
|
||||
def is_wireless_node(cls, node_type):
|
||||
def is_wireless_node(cls, node_type) -> bool:
|
||||
return node_type in cls.WIRELESS_NODES
|
||||
|
||||
@classmethod
|
||||
def is_rj45_node(cls, node_type):
|
||||
def is_rj45_node(cls, node_type) -> bool:
|
||||
return node_type in cls.RJ45_NODES
|
||||
|
||||
@classmethod
|
||||
def node_icon(cls, node_type, model):
|
||||
def node_icon(cls, node_type, model: str) -> bool:
|
||||
if model == "":
|
||||
model = None
|
||||
return cls.NODE_ICONS[(node_type, model)]
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
"status bar"
|
||||
"""
|
||||
status bar
|
||||
"""
|
||||
import tkinter as tk
|
||||
from tkinter import ttk
|
||||
|
||||
|
|
|
@ -4,6 +4,9 @@ import tkinter as tk
|
|||
from functools import partial
|
||||
from tkinter import messagebox, ttk
|
||||
from tkinter.font import Font
|
||||
from typing import Callable
|
||||
|
||||
from PIL import ImageTk
|
||||
|
||||
from core.api.grpc import core_pb2
|
||||
from core.gui.dialogs.customnodes import CustomNodesDialog
|
||||
|
@ -196,7 +199,9 @@ class Toolbar(ttk.Frame):
|
|||
self.wait_window(picker)
|
||||
self.app.unbind_all("<ButtonRelease-1>")
|
||||
|
||||
def create_picker_button(self, image, func, frame: ttk.Frame, label: str):
|
||||
def create_picker_button(
|
||||
self, image: ImageTk.PhotoImage, func: Callable, frame: ttk.Frame, label: str
|
||||
):
|
||||
"""
|
||||
Create button and put it on the frame
|
||||
|
||||
|
@ -204,7 +209,6 @@ class Toolbar(ttk.Frame):
|
|||
:param func: the command that is executed when button is clicked
|
||||
:param tkinter.Frame frame: frame that contains the button
|
||||
:param str label: button label
|
||||
:return: nothing
|
||||
"""
|
||||
button = ttk.Button(
|
||||
frame, image=image, text=label, compound=tk.TOP, style=Styles.picker_button
|
||||
|
@ -213,7 +217,9 @@ class Toolbar(ttk.Frame):
|
|||
button.bind("<ButtonRelease-1>", lambda e: func())
|
||||
button.grid(pady=1)
|
||||
|
||||
def create_button(self, frame: ttk.Frame, image, func, tooltip: str):
|
||||
def create_button(
|
||||
self, frame: ttk.Frame, image: ImageTk.PhotoImage, func: Callable, tooltip: str
|
||||
):
|
||||
button = ttk.Button(frame, image=image, command=func)
|
||||
button.image = image
|
||||
button.grid(sticky="ew")
|
||||
|
@ -234,8 +240,6 @@ class Toolbar(ttk.Frame):
|
|||
"""
|
||||
Start session handler redraw buttons, send node and link messages to grpc
|
||||
server.
|
||||
|
||||
:return: nothing
|
||||
"""
|
||||
self.app.canvas.hide_context()
|
||||
self.app.statusbar.progress_bar.start(5)
|
||||
|
@ -299,8 +303,6 @@ class Toolbar(ttk.Frame):
|
|||
def create_node_button(self):
|
||||
"""
|
||||
Create network layer button
|
||||
|
||||
:return: nothing
|
||||
"""
|
||||
image = icon(ImageEnum.ROUTER)
|
||||
self.node_button = ttk.Button(
|
||||
|
@ -313,8 +315,6 @@ class Toolbar(ttk.Frame):
|
|||
def draw_network_picker(self):
|
||||
"""
|
||||
Draw the options for link-layer button.
|
||||
|
||||
:return: nothing
|
||||
"""
|
||||
self.hide_pickers()
|
||||
self.network_picker = ttk.Frame(self.master)
|
||||
|
@ -338,8 +338,6 @@ class Toolbar(ttk.Frame):
|
|||
"""
|
||||
Create link-layer node button and the options that represent different
|
||||
link-layer node types.
|
||||
|
||||
:return: nothing
|
||||
"""
|
||||
image = icon(ImageEnum.HUB)
|
||||
self.network_button = ttk.Button(
|
||||
|
@ -352,8 +350,6 @@ class Toolbar(ttk.Frame):
|
|||
def draw_annotation_picker(self):
|
||||
"""
|
||||
Draw the options for marker button.
|
||||
|
||||
:return: nothing
|
||||
"""
|
||||
self.hide_pickers()
|
||||
self.annotation_picker = ttk.Frame(self.master)
|
||||
|
@ -380,8 +376,6 @@ class Toolbar(ttk.Frame):
|
|||
def create_annotation_button(self):
|
||||
"""
|
||||
Create marker button and options that represent different marker types
|
||||
|
||||
:return: nothing
|
||||
"""
|
||||
image = icon(ImageEnum.MARKER)
|
||||
self.annotation_button = ttk.Button(
|
||||
|
@ -418,8 +412,6 @@ class Toolbar(ttk.Frame):
|
|||
def click_stop(self):
|
||||
"""
|
||||
redraw buttons on the toolbar, send node and link messages to grpc server
|
||||
|
||||
:return: nothing
|
||||
"""
|
||||
self.app.canvas.hide_context()
|
||||
self.app.statusbar.progress_bar.start(5)
|
||||
|
|
|
@ -40,7 +40,7 @@ class InputValidation:
|
|||
if value == "":
|
||||
event.widget.insert(tk.END, default)
|
||||
|
||||
def check_positive_int(self, s: str):
|
||||
def check_positive_int(self, s: str) -> bool:
|
||||
if len(s) == 0:
|
||||
return True
|
||||
try:
|
||||
|
@ -51,7 +51,7 @@ class InputValidation:
|
|||
except ValueError:
|
||||
return False
|
||||
|
||||
def check_positive_float(self, s: str):
|
||||
def check_positive_float(self, s: str) -> bool:
|
||||
if len(s) == 0:
|
||||
return True
|
||||
try:
|
||||
|
@ -62,7 +62,7 @@ class InputValidation:
|
|||
except ValueError:
|
||||
return False
|
||||
|
||||
def check_node_name(self, s: str):
|
||||
def check_node_name(self, s: str) -> bool:
|
||||
if len(s) < 0:
|
||||
return False
|
||||
if len(s) == 0:
|
||||
|
@ -72,7 +72,7 @@ class InputValidation:
|
|||
return False
|
||||
return True
|
||||
|
||||
def check_canvas_int(self, s: str):
|
||||
def check_canvas_int(self, s: str) -> bool:
|
||||
if len(s) == 0:
|
||||
return True
|
||||
try:
|
||||
|
@ -83,7 +83,7 @@ class InputValidation:
|
|||
except ValueError:
|
||||
return False
|
||||
|
||||
def check_canvas_float(self, s: str):
|
||||
def check_canvas_float(self, s: str) -> bool:
|
||||
if not s:
|
||||
return True
|
||||
try:
|
||||
|
@ -94,7 +94,7 @@ class InputValidation:
|
|||
except ValueError:
|
||||
return False
|
||||
|
||||
def check_ip4(self, s: str):
|
||||
def check_ip4(self, s: str) -> bool:
|
||||
if not s:
|
||||
return True
|
||||
pat = re.compile("^([0-9]+[.])*[0-9]*$")
|
||||
|
@ -113,7 +113,7 @@ class InputValidation:
|
|||
else:
|
||||
return False
|
||||
|
||||
def check_rbg(self, s: str):
|
||||
def check_rbg(self, s: str) -> bool:
|
||||
if not s:
|
||||
return True
|
||||
if s.startswith("0") and len(s) >= 2:
|
||||
|
@ -127,7 +127,7 @@ class InputValidation:
|
|||
except ValueError:
|
||||
return False
|
||||
|
||||
def check_hex(self, s: str):
|
||||
def check_hex(self, s: str) -> bool:
|
||||
if not s:
|
||||
return True
|
||||
pat = re.compile("^([#]([0-9]|[a-f])+)$|^[#]$")
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import logging
|
||||
import tkinter as tk
|
||||
from functools import partial
|
||||
from pathlib import PosixPath
|
||||
from tkinter import filedialog, font, ttk
|
||||
|
||||
from core.api.grpc import core_pb2
|
||||
|
@ -19,7 +20,7 @@ INT_TYPES = {
|
|||
}
|
||||
|
||||
|
||||
def file_button_click(value, parent):
|
||||
def file_button_click(value: tk.StringVar, parent: tk.Widget):
|
||||
file_path = filedialog.askopenfilename(title="Select File", parent=parent)
|
||||
if file_path:
|
||||
value.set(file_path)
|
||||
|
@ -49,13 +50,13 @@ class FrameScroll(ttk.Frame):
|
|||
self.frame.bind("<Configure>", self._configure_frame)
|
||||
self.canvas.bind("<Configure>", self._configure_canvas)
|
||||
|
||||
def _configure_frame(self, event):
|
||||
def _configure_frame(self, event: tk.Event):
|
||||
req_width = self.frame.winfo_reqwidth()
|
||||
if req_width != self.canvas.winfo_reqwidth():
|
||||
self.canvas.configure(width=req_width)
|
||||
self.canvas.configure(scrollregion=self.canvas.bbox("all"))
|
||||
|
||||
def _configure_canvas(self, event):
|
||||
def _configure_canvas(self, event: tk.Event):
|
||||
self.canvas.itemconfig(self.frame_id, width=event.width)
|
||||
|
||||
def clear(self):
|
||||
|
@ -238,7 +239,7 @@ class Spinbox(ttk.Entry):
|
|||
self.tk.call(self._w, "set", value)
|
||||
|
||||
|
||||
def image_chooser(parent, path):
|
||||
def image_chooser(parent: tk.Widget, path: PosixPath):
|
||||
return filedialog.askopenfilename(
|
||||
parent=parent,
|
||||
initialdir=str(path),
|
||||
|
|
Loading…
Add table
Reference in a new issue