Merge branch 'coretk' of https://github.com/coreemu/core into coretk
This commit is contained in:
commit
5dda7396ef
11 changed files with 206 additions and 35 deletions
|
@ -12,6 +12,7 @@ from coretk.menubar import Menubar
|
|||
from coretk.nodeutils import NodeUtils
|
||||
from coretk.statusbar import StatusBar
|
||||
from coretk.toolbar import Toolbar
|
||||
from coretk.validation import InputValidation
|
||||
|
||||
|
||||
class Application(tk.Frame):
|
||||
|
@ -25,6 +26,7 @@ class Application(tk.Frame):
|
|||
self.toolbar = None
|
||||
self.canvas = None
|
||||
self.statusbar = None
|
||||
self.validation = None
|
||||
|
||||
# setup
|
||||
self.guiconfig = appconfig.read()
|
||||
|
@ -48,6 +50,7 @@ class Application(tk.Frame):
|
|||
image = Images.get(ImageEnum.CORE, 16)
|
||||
self.master.tk.call("wm", "iconphoto", self.master._w, image)
|
||||
self.pack(fill=tk.BOTH, expand=True)
|
||||
self.validation = InputValidation(self)
|
||||
|
||||
def center(self):
|
||||
width = 1000
|
||||
|
|
|
@ -86,6 +86,7 @@ class CoreClient:
|
|||
self.service_configs = {}
|
||||
self.file_configs = {}
|
||||
self.mobility_players = {}
|
||||
self.throughput = False
|
||||
|
||||
def reset(self):
|
||||
# helpers
|
||||
|
@ -180,22 +181,11 @@ class CoreClient:
|
|||
canvas_node.move(x, y)
|
||||
|
||||
def handle_throughputs(self, event):
|
||||
# interface_throughputs = event.interface_throughputs
|
||||
# # print(interface_throughputs)
|
||||
# # return
|
||||
# # for i in interface_throughputs:
|
||||
# # print("")
|
||||
# # # return
|
||||
# print(event)
|
||||
# throughputs_belong_to_session = []
|
||||
# print(self.node_ids)
|
||||
# for throughput in interface_throughputs:
|
||||
# if throughput.node_id in self.node_ids:
|
||||
# throughputs_belong_to_session.append(throughput)
|
||||
# print(throughputs_belong_to_session)
|
||||
self.app.canvas.throughput_draw.process_grpc_throughput_event(
|
||||
event.interface_throughputs
|
||||
)
|
||||
# print(event.interface_throughputs)
|
||||
if self.throughput:
|
||||
self.app.canvas.throughput_draw.process_grpc_throughput_event(
|
||||
event.interface_throughputs
|
||||
)
|
||||
|
||||
def join_session(self, session_id, query_location=True):
|
||||
# update session and title
|
||||
|
@ -595,8 +585,11 @@ class CoreClient:
|
|||
self.client.set_session_state(
|
||||
self.session_id, core_pb2.SessionState.DEFINITION
|
||||
)
|
||||
|
||||
# temp
|
||||
self.client.set_session_state(self.session_id, core_pb2.SessionState.DEFINITION)
|
||||
for node_proto in node_protos:
|
||||
if node_proto.id not in self.created_nodes:
|
||||
if node_proto.id not in self.created_nodes or True:
|
||||
response = self.client.add_node(self.session_id, node_proto)
|
||||
logging.debug("create node: %s", response)
|
||||
self.created_nodes.add(node_proto.id)
|
||||
|
@ -604,6 +597,7 @@ class CoreClient:
|
|||
if (
|
||||
tuple([link_proto.node_one_id, link_proto.node_two_id])
|
||||
not in self.created_links
|
||||
or True
|
||||
):
|
||||
response = self.client.add_link(
|
||||
self.session_id,
|
||||
|
|
|
@ -19,6 +19,7 @@ class SizeAndScaleDialog(Dialog):
|
|||
"""
|
||||
super().__init__(master, app, "Canvas Size and Scale", modal=True)
|
||||
self.canvas = self.app.canvas
|
||||
self.validation = app.validation
|
||||
self.section_font = font.Font(weight="bold")
|
||||
# get current canvas dimensions
|
||||
plot = self.canvas.find_withtag("rectangle")
|
||||
|
@ -59,11 +60,23 @@ class SizeAndScaleDialog(Dialog):
|
|||
frame.columnconfigure(3, weight=1)
|
||||
label = ttk.Label(frame, text="Width")
|
||||
label.grid(row=0, column=0, sticky="w", padx=PAD)
|
||||
entry = ttk.Entry(frame, textvariable=self.pixel_width)
|
||||
entry = ttk.Entry(
|
||||
frame,
|
||||
textvariable=self.pixel_width,
|
||||
validate="key",
|
||||
validatecommand=(self.validation.positive_int, "%P"),
|
||||
)
|
||||
entry.bind("<FocusOut>", self.validation.focus_out)
|
||||
entry.grid(row=0, column=1, sticky="ew", padx=PAD)
|
||||
label = ttk.Label(frame, text="x Height")
|
||||
label.grid(row=0, column=2, sticky="w", padx=PAD)
|
||||
entry = ttk.Entry(frame, textvariable=self.pixel_height)
|
||||
entry = ttk.Entry(
|
||||
frame,
|
||||
textvariable=self.pixel_height,
|
||||
validate="key",
|
||||
validatecommand=(self.validation.positive_int, "%P"),
|
||||
)
|
||||
entry.bind("<FocusOut>", self.validation.focus_out)
|
||||
entry.grid(row=0, column=3, sticky="ew", padx=PAD)
|
||||
label = ttk.Label(frame, text="Pixels")
|
||||
label.grid(row=0, column=4, sticky="w")
|
||||
|
@ -75,11 +88,23 @@ class SizeAndScaleDialog(Dialog):
|
|||
frame.columnconfigure(3, weight=1)
|
||||
label = ttk.Label(frame, text="Width")
|
||||
label.grid(row=0, column=0, sticky="w", padx=PAD)
|
||||
entry = ttk.Entry(frame, textvariable=self.meters_width)
|
||||
entry = ttk.Entry(
|
||||
frame,
|
||||
textvariable=self.meters_width,
|
||||
validate="key",
|
||||
validatecommand=(self.validation.positive_float, "%P"),
|
||||
)
|
||||
entry.bind("<FocusOut>", self.validation.focus_out)
|
||||
entry.grid(row=0, column=1, sticky="ew", padx=PAD)
|
||||
label = ttk.Label(frame, text="x Height")
|
||||
label.grid(row=0, column=2, sticky="w", padx=PAD)
|
||||
entry = ttk.Entry(frame, textvariable=self.meters_height)
|
||||
entry = ttk.Entry(
|
||||
frame,
|
||||
textvariable=self.meters_height,
|
||||
validate="key",
|
||||
validatecommand=(self.validation.positive_float, "%P"),
|
||||
)
|
||||
entry.bind("<FocusOut>", self.validation.focus_out)
|
||||
entry.grid(row=0, column=3, sticky="ew", padx=PAD)
|
||||
label = ttk.Label(frame, text="Meters")
|
||||
label.grid(row=0, column=4, sticky="w")
|
||||
|
@ -94,7 +119,13 @@ class SizeAndScaleDialog(Dialog):
|
|||
frame.columnconfigure(1, weight=1)
|
||||
label = ttk.Label(frame, text=f"{PIXEL_SCALE} Pixels =")
|
||||
label.grid(row=0, column=0, sticky="w", padx=PAD)
|
||||
entry = ttk.Entry(frame, textvariable=self.scale)
|
||||
entry = ttk.Entry(
|
||||
frame,
|
||||
textvariable=self.scale,
|
||||
validate="key",
|
||||
validatecommand=(self.validation.positive_float, "%P"),
|
||||
)
|
||||
entry.bind("<FocusOut>", self.validation.focus_out)
|
||||
entry.grid(row=0, column=1, sticky="ew", padx=PAD)
|
||||
label = ttk.Label(frame, text="Meters")
|
||||
label.grid(row=0, column=2, sticky="w")
|
||||
|
@ -116,12 +147,24 @@ class SizeAndScaleDialog(Dialog):
|
|||
|
||||
label = ttk.Label(frame, text="X")
|
||||
label.grid(row=0, column=0, sticky="w", padx=PAD)
|
||||
entry = ttk.Entry(frame, textvariable=self.x)
|
||||
entry = ttk.Entry(
|
||||
frame,
|
||||
textvariable=self.x,
|
||||
validate="key",
|
||||
validatecommand=(self.validation.positive_float, "%P"),
|
||||
)
|
||||
entry.bind("<FocusOut>", self.validation.focus_out)
|
||||
entry.grid(row=0, column=1, sticky="ew", padx=PAD)
|
||||
|
||||
label = ttk.Label(frame, text="Y")
|
||||
label.grid(row=0, column=2, sticky="w", padx=PAD)
|
||||
entry = ttk.Entry(frame, textvariable=self.y)
|
||||
entry = ttk.Entry(
|
||||
frame,
|
||||
textvariable=self.y,
|
||||
validate="key",
|
||||
validatecommand=(self.validation.positive_float, "%P"),
|
||||
)
|
||||
entry.bind("<FocusOut>", self.validation.focus_out)
|
||||
entry.grid(row=0, column=3, sticky="ew", padx=PAD)
|
||||
|
||||
label = ttk.Label(label_frame, text="Translates To")
|
||||
|
@ -135,17 +178,35 @@ class SizeAndScaleDialog(Dialog):
|
|||
|
||||
label = ttk.Label(frame, text="Lat")
|
||||
label.grid(row=0, column=0, sticky="w", padx=PAD)
|
||||
entry = ttk.Entry(frame, textvariable=self.lat)
|
||||
entry = ttk.Entry(
|
||||
frame,
|
||||
textvariable=self.lat,
|
||||
validate="key",
|
||||
validatecommand=(self.validation.positive_float, "%P"),
|
||||
)
|
||||
entry.bind("<FocusOut>", self.validation.focus_out)
|
||||
entry.grid(row=0, column=1, sticky="ew", padx=PAD)
|
||||
|
||||
label = ttk.Label(frame, text="Lon")
|
||||
label.grid(row=0, column=2, sticky="w", padx=PAD)
|
||||
entry = ttk.Entry(frame, textvariable=self.lon)
|
||||
entry = ttk.Entry(
|
||||
frame,
|
||||
textvariable=self.lon,
|
||||
validate="key",
|
||||
validatecommand=(self.validation.positive_float, "%P"),
|
||||
)
|
||||
entry.bind("<FocusOut>", self.validation.focus_out)
|
||||
entry.grid(row=0, column=3, sticky="ew", padx=PAD)
|
||||
|
||||
label = ttk.Label(frame, text="Alt")
|
||||
label.grid(row=0, column=4, sticky="w", padx=PAD)
|
||||
entry = ttk.Entry(frame, textvariable=self.alt)
|
||||
entry = ttk.Entry(
|
||||
frame,
|
||||
textvariable=self.alt,
|
||||
validate="key",
|
||||
validatecommand=(self.validation.positive_float, "%P"),
|
||||
)
|
||||
entry.bind("<FocusOut>", self.validation.focus_out)
|
||||
entry.grid(row=0, column=5, sticky="ew")
|
||||
|
||||
def draw_save_as_default(self):
|
||||
|
|
|
@ -69,7 +69,13 @@ class NodeConfigDialog(Dialog):
|
|||
# name field
|
||||
label = ttk.Label(frame, text="Name")
|
||||
label.grid(row=row, column=0, sticky="ew", padx=PAD, pady=PAD)
|
||||
entry = ttk.Entry(frame, textvariable=self.name)
|
||||
entry = ttk.Entry(
|
||||
frame,
|
||||
textvariable=self.name,
|
||||
validate="key",
|
||||
validatecommand=(self.app.validation.name, "%P"),
|
||||
)
|
||||
entry.bind("<FocusOut>", self.app.validation.name_focus_out)
|
||||
entry.grid(row=row, column=1, sticky="ew")
|
||||
row += 1
|
||||
|
||||
|
@ -206,5 +212,4 @@ class NodeConfigDialog(Dialog):
|
|||
|
||||
# redraw
|
||||
self.canvas_node.redraw()
|
||||
|
||||
self.destroy()
|
||||
|
|
|
@ -87,6 +87,7 @@ class NodeService(Dialog):
|
|||
self.current.listbox.delete(0, tk.END)
|
||||
for name in sorted(self.current_services):
|
||||
self.current.listbox.insert(tk.END, name)
|
||||
self.canvas_node.core_node.services[:] = self.current_services
|
||||
|
||||
def click_configure(self):
|
||||
current_selection = self.current.listbox.curselection()
|
||||
|
|
|
@ -92,6 +92,7 @@ class CanvasGraph(tk.Canvas):
|
|||
|
||||
# set the private variables to default value
|
||||
self.mode = GraphMode.SELECT
|
||||
self.annotation_type = None
|
||||
self.node_draw = None
|
||||
self.selected = None
|
||||
self.nodes.clear()
|
||||
|
|
|
@ -145,9 +145,6 @@ class CanvasNode:
|
|||
def on_leave(self, event):
|
||||
self.tooltip.on_leave(event)
|
||||
|
||||
def click(self, event):
|
||||
print("click")
|
||||
|
||||
def double_click(self, event):
|
||||
if self.app.core.is_runtime():
|
||||
self.canvas.core.launch_terminal(self.core_node.id)
|
||||
|
|
|
@ -149,3 +149,10 @@ class MenuAction:
|
|||
def show_about(self):
|
||||
dialog = AboutDialog(self.app, self.app)
|
||||
dialog.show()
|
||||
|
||||
def throughput(self):
|
||||
throughput = self.app.core.throughput
|
||||
if throughput:
|
||||
self.app.core.throughput = False
|
||||
else:
|
||||
self.app.core.throughput = True
|
||||
|
|
|
@ -422,7 +422,7 @@ class Menubar(tk.Menu):
|
|||
menu = tk.Menu(self)
|
||||
self.create_observer_widgets_menu(menu)
|
||||
self.create_adjacency_menu(menu)
|
||||
menu.add_command(label="Throughput", state=tk.DISABLED)
|
||||
menu.add_checkbutton(label="Throughput", command=self.menuaction.throughput)
|
||||
menu.add_separator()
|
||||
menu.add_command(label="Configure Adjacency...", state=tk.DISABLED)
|
||||
menu.add_command(label="Configure Throughput...", state=tk.DISABLED)
|
||||
|
|
89
coretk/coretk/validation.py
Normal file
89
coretk/coretk/validation.py
Normal file
|
@ -0,0 +1,89 @@
|
|||
"""
|
||||
input validation
|
||||
"""
|
||||
import logging
|
||||
import tkinter as tk
|
||||
|
||||
|
||||
class InputValidation:
|
||||
def __init__(self, app):
|
||||
self.master = app.master
|
||||
self.positive_int = None
|
||||
self.positive_float = None
|
||||
self.name = None
|
||||
self.register()
|
||||
|
||||
def register(self):
|
||||
self.positive_int = self.master.register(self.check_positive_int)
|
||||
self.positive_float = self.master.register(self.check_positive_float)
|
||||
self.name = self.master.register(self.check_node_name)
|
||||
|
||||
def focus_out(self, event):
|
||||
value = event.widget.get()
|
||||
if value == "":
|
||||
event.widget.insert(tk.END, 0)
|
||||
|
||||
def name_focus_out(self, event):
|
||||
logging.debug("name focus out")
|
||||
value = event.widget.get()
|
||||
if value == "":
|
||||
event.widget.insert(tk.END, "empty")
|
||||
|
||||
def check_positive_int(self, s):
|
||||
logging.debug("int validation...")
|
||||
if len(s) == 0:
|
||||
return True
|
||||
try:
|
||||
int_value = int(s)
|
||||
if int_value >= 0:
|
||||
return True
|
||||
return False
|
||||
except ValueError:
|
||||
return False
|
||||
|
||||
def check_positive_float(self, s):
|
||||
logging.debug("float validation...")
|
||||
if len(s) == 0:
|
||||
return True
|
||||
try:
|
||||
float_value = float(s)
|
||||
if float_value >= 0.0:
|
||||
return True
|
||||
return False
|
||||
except ValueError:
|
||||
return False
|
||||
|
||||
def check_node_name(self, s):
|
||||
logging.debug("node name validation...")
|
||||
if len(s) < 0:
|
||||
return False
|
||||
if len(s) == 0:
|
||||
return True
|
||||
for char in s:
|
||||
if not char.isalnum() and char != "_":
|
||||
return False
|
||||
return True
|
||||
|
||||
def check_canvas_int(sefl, s):
|
||||
logging.debug("int validation...")
|
||||
if len(s) == 0:
|
||||
return True
|
||||
try:
|
||||
int_value = int(s)
|
||||
if int_value >= 0:
|
||||
return True
|
||||
return False
|
||||
except ValueError:
|
||||
return False
|
||||
|
||||
def check_canvas_float(self, s):
|
||||
logging.debug("canvas float validation")
|
||||
if not s:
|
||||
return True
|
||||
try:
|
||||
float_value = float(s)
|
||||
if float_value >= 0.0:
|
||||
return True
|
||||
return False
|
||||
except ValueError:
|
||||
return False
|
|
@ -66,6 +66,7 @@ class FrameScroll(ttk.LabelFrame):
|
|||
class ConfigFrame(FrameScroll):
|
||||
def __init__(self, master, app, config, **kw):
|
||||
super().__init__(master, app, ttk.Notebook, **kw)
|
||||
self.app = app
|
||||
self.config = config
|
||||
self.values = {}
|
||||
|
||||
|
@ -120,11 +121,23 @@ class ConfigFrame(FrameScroll):
|
|||
entry.grid(row=index, column=1, sticky="ew", pady=pady)
|
||||
elif option.type in INT_TYPES:
|
||||
value.set(option.value)
|
||||
entry = ttk.Entry(frame, textvariable=value)
|
||||
entry = ttk.Entry(
|
||||
frame,
|
||||
textvariable=value,
|
||||
validate="key",
|
||||
validatecommand=(self.app.validation.positive_int, "%P"),
|
||||
)
|
||||
entry.bind("<FocusOut>", self.app.validation.focus_out)
|
||||
entry.grid(row=index, column=1, sticky="ew", pady=pady)
|
||||
elif option.type == core_pb2.ConfigOptionType.FLOAT:
|
||||
value.set(option.value)
|
||||
entry = ttk.Entry(frame, textvariable=value)
|
||||
entry = ttk.Entry(
|
||||
frame,
|
||||
textvariable=value,
|
||||
validate="key",
|
||||
validatecommand=(self.app.validation.positive_float, "%P"),
|
||||
)
|
||||
entry.bind("<FocusOut>", self.app.validation.focus_out)
|
||||
entry.grid(row=index, column=1, sticky="ew", pady=pady)
|
||||
else:
|
||||
logging.error("unhandled config option type: %s", option.type)
|
||||
|
|
Loading…
Reference in a new issue