fix merge conflict

This commit is contained in:
Huy Pham 2019-12-09 16:37:24 -08:00
commit 542d632066
16 changed files with 247 additions and 130 deletions

View file

@ -98,6 +98,9 @@ class Application(tk.Frame):
def save_config(self): def save_config(self):
appconfig.save(self.guiconfig) appconfig.save(self.guiconfig)
def close(self):
self.master.destroy()
if __name__ == "__main__": if __name__ == "__main__":
log_format = "%(asctime)s - %(levelname)s - %(module)s:%(funcName)s - %(message)s" log_format = "%(asctime)s - %(levelname)s - %(module)s:%(funcName)s - %(message)s"

View file

@ -6,29 +6,20 @@ import logging
import os import os
import time import time
from pathlib import Path from pathlib import Path
from tkinter import messagebox
import grpc
from core.api.grpc import client, core_pb2 from core.api.grpc import client, core_pb2
from coretk import appconfig from coretk import appconfig
from coretk.dialogs.mobilityplayer import MobilityPlayer from coretk.dialogs.mobilityplayer import MobilityPlayer
from coretk.dialogs.sessions import SessionsDialog from coretk.dialogs.sessions import SessionsDialog
from coretk.graph import tags
from coretk.graph.shape import AnnotationData, Shape from coretk.graph.shape import AnnotationData, Shape
from coretk.graph.shapeutils import ShapeType from coretk.graph.shapeutils import ShapeType
from coretk.interface import InterfaceManager from coretk.interface import InterfaceManager
from coretk.nodeutils import NodeDraw, NodeUtils from coretk.nodeutils import NodeDraw, NodeUtils
LIFT_ORDER = [
"wallpaper",
"shape",
"gridline",
"shapetext",
"text",
"edge",
"antenna",
"nodename",
"linkinfo",
"node",
]
OBSERVERS = { OBSERVERS = {
"processes": "ps", "processes": "ps",
"ifconfig": "ifconfig", "ifconfig": "ifconfig",
@ -285,11 +276,17 @@ class CoreClient:
response = self.client.get_session_metadata(self.session_id) response = self.client.get_session_metadata(self.session_id)
self.parse_metadata(response.config) self.parse_metadata(response.config)
# update ui to represent current state
if self.is_runtime(): if self.is_runtime():
self.app.toolbar.runtime_frame.tkraise() self.app.toolbar.runtime_frame.tkraise()
self.app.toolbar.click_runtime_selection()
else: else:
self.app.toolbar.design_frame.tkraise() self.app.toolbar.design_frame.tkraise()
self.app.toolbar.select_button.invoke() # <<<<<<< HEAD
# self.app.toolbar.select_button.invoke()
# =======
self.app.toolbar.click_selection()
# >>>>>>> coretk
self.app.statusbar.progress_bar.stop() self.app.statusbar.progress_bar.stop()
def is_runtime(self): def is_runtime(self):
@ -301,12 +298,26 @@ class CoreClient:
logging.info("canvas metadata: %s", canvas_config) logging.info("canvas metadata: %s", canvas_config)
if canvas_config: if canvas_config:
canvas_config = json.loads(canvas_config) canvas_config = json.loads(canvas_config)
wallpaper_style = canvas_config["wallpaper-style"]
gridlines = canvas_config.get("gridlines", True)
self.app.canvas.show_grid.set(gridlines)
fit_image = canvas_config.get("fit_image", False)
self.app.canvas.adjust_to_dim.set(fit_image)
wallpaper_style = canvas_config.get("wallpaper-style", 1)
self.app.canvas.scale_option.set(wallpaper_style) self.app.canvas.scale_option.set(wallpaper_style)
wallpaper = canvas_config["wallpaper"]
width = self.app.guiconfig["preferences"]["width"]
height = self.app.guiconfig["preferences"]["height"]
width, height = canvas_config.get("dimensions", [width, height])
self.app.canvas.redraw_canvas(width, height)
wallpaper = canvas_config.get("wallpaper")
if wallpaper: if wallpaper:
wallpaper = str(appconfig.BACKGROUNDS_PATH.joinpath(wallpaper)) wallpaper = str(appconfig.BACKGROUNDS_PATH.joinpath(wallpaper))
self.app.canvas.set_wallpaper(wallpaper) self.app.canvas.set_wallpaper(wallpaper)
self.app.canvas.update_grid()
# load saved shapes # load saved shapes
shapes_config = config.get("shapes") shapes_config = config.get("shapes")
@ -337,7 +348,7 @@ class CoreClient:
except ValueError: except ValueError:
logging.exception("unknown shape: %s", shape_type) logging.exception("unknown shape: %s", shape_type)
for tag in LIFT_ORDER: for tag in tags.ABOVE_WALLPAPER_TAGS:
self.app.canvas.tag_raise(tag) self.app.canvas.tag_raise(tag)
def create_new_session(self): def create_new_session(self):
@ -372,6 +383,7 @@ class CoreClient:
:return: existing sessions :return: existing sessions
""" """
try:
self.client.connect() self.client.connect()
# get service information # get service information
@ -394,6 +406,13 @@ class CoreClient:
self.default_services = { self.default_services = {
x.node_type: set(x.services) for x in response.defaults x.node_type: set(x.services) for x in response.defaults
} }
except grpc.RpcError as e:
if e.code() == grpc.StatusCode.UNAVAILABLE:
messagebox.showerror("Server Error", "CORE Daemon Unavailable")
else:
messagebox.showerror("GRPC Error", e.details())
self.app.close()
def get_session_state(self): def get_session_state(self):
response = self.client.get_session(self.session_id) response = self.client.get_session(self.session_id)
@ -460,6 +479,9 @@ class CoreClient:
canvas_config = { canvas_config = {
"wallpaper": Path(self.app.canvas.wallpaper_file).name, "wallpaper": Path(self.app.canvas.wallpaper_file).name,
"wallpaper-style": self.app.canvas.scale_option.get(), "wallpaper-style": self.app.canvas.scale_option.get(),
"gridlines": self.app.canvas.show_grid.get(),
"fit_image": self.app.canvas.adjust_to_dim.get(),
"dimensions": self.app.canvas.width_and_height(),
} }
canvas_config = json.dumps(canvas_config) canvas_config = json.dumps(canvas_config)

View file

@ -196,7 +196,7 @@ class SizeAndScaleDialog(Dialog):
def click_apply(self): def click_apply(self):
width, height = self.pixel_width.get(), self.pixel_height.get() width, height = self.pixel_width.get(), self.pixel_height.get()
self.canvas.redraw_grid(width, height) self.canvas.redraw_canvas(width, height)
if self.canvas.wallpaper: if self.canvas.wallpaper:
self.canvas.redraw() self.canvas.redraw()
location = self.app.core.location location = self.app.core.location

View file

@ -9,6 +9,7 @@ DIALOG_PAD = 5
class Dialog(tk.Toplevel): class Dialog(tk.Toplevel):
def __init__(self, master, app, title, modal=False): def __init__(self, master, app, title, modal=False):
super().__init__(master) super().__init__(master)
self.geometry("800x600")
self.withdraw() self.withdraw()
self.app = app self.app = app
self.modal = modal self.modal = modal

View file

@ -5,6 +5,7 @@ import tkinter as tk
from tkinter import colorchooser, font, ttk from tkinter import colorchooser, font, ttk
from coretk.dialogs.dialog import Dialog from coretk.dialogs.dialog import Dialog
from coretk.graph import tags
from coretk.graph.shapeutils import is_draw_shape, is_shape_text from coretk.graph.shapeutils import is_draw_shape, is_shape_text
FONT_SIZES = [8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72] FONT_SIZES = [8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72]
@ -230,7 +231,7 @@ class ShapeDialog(Dialog):
text=shape_text, text=shape_text,
fill=self.text_color, fill=self.text_color,
font=text_font, font=text_font,
tags="shapetext", tags=tags.SHAPE_TEXT,
) )
self.shape.created = True self.shape.created = True
else: else:

View file

@ -1,5 +1,6 @@
import tkinter as tk import tkinter as tk
from coretk.graph import tags
from coretk.nodeutils import NodeUtils from coretk.nodeutils import NodeUtils
@ -10,7 +11,7 @@ class CanvasWirelessEdge:
self.dst = dst self.dst = dst
self.canvas = canvas self.canvas = canvas
self.id = self.canvas.create_line( self.id = self.canvas.create_line(
*position, tags="wireless", width=1.5, fill="#009933" *position, tags=tags.WIRELESS_EDGE, width=1.5, fill="#009933"
) )
def delete(self): def delete(self):
@ -40,7 +41,7 @@ class CanvasEdge:
self.dst_interface = None self.dst_interface = None
self.canvas = canvas self.canvas = canvas
self.id = self.canvas.create_line( self.id = self.canvas.create_line(
x1, y1, x2, y2, tags="edge", width=self.width, fill="#ff0000" x1, y1, x2, y2, tags=tags.EDGE, width=self.width, fill="#ff0000"
) )
self.token = None self.token = None
self.link_info = None self.link_info = None

View file

@ -5,6 +5,7 @@ from PIL import Image, ImageTk
from core.api.grpc import core_pb2 from core.api.grpc import core_pb2
from coretk.dialogs.shapemod import ShapeDialog from coretk.dialogs.shapemod import ShapeDialog
from coretk.graph import tags
from coretk.graph.edges import CanvasEdge, CanvasWirelessEdge from coretk.graph.edges import CanvasEdge, CanvasWirelessEdge
from coretk.graph.enums import GraphMode, ScaleOption from coretk.graph.enums import GraphMode, ScaleOption
from coretk.graph.linkinfo import LinkInfo, Throughput from coretk.graph.linkinfo import LinkInfo, Throughput
@ -14,20 +15,6 @@ from coretk.graph.shapeutils import is_draw_shape
from coretk.images import Images from coretk.images import Images
from coretk.nodeutils import NodeUtils from coretk.nodeutils import NodeUtils
ABOVE_WALLPAPER = ["edge", "linkinfo", "wireless", "antenna", "nodename", "node"]
CANVAS_COMPONENT_TAGS = [
"edge",
"node",
"nodename",
"wallpaper",
"linkinfo",
"antenna",
"wireless",
"selectednodes",
"shape",
"shapetext",
]
class CanvasGraph(tk.Canvas): class CanvasGraph(tk.Canvas):
def __init__(self, master, core, width, height, cnf=None, **kwargs): def __init__(self, master, core, width, height, cnf=None, **kwargs):
@ -49,10 +36,11 @@ class CanvasGraph(tk.Canvas):
self.drawing_edge = None self.drawing_edge = None
self.grid = None self.grid = None
self.setup_bindings() self.setup_bindings()
self.draw_grid(width, height)
self.core = core self.core = core
self.throughput_draw = Throughput(self, core) self.throughput_draw = Throughput(self, core)
self.shape_drawing = False self.shape_drawing = False
self.default_width = width
self.default_height = height
# background related # background related
self.wallpaper_id = None self.wallpaper_id = None
@ -63,6 +51,22 @@ class CanvasGraph(tk.Canvas):
self.show_grid = tk.BooleanVar(value=True) self.show_grid = tk.BooleanVar(value=True)
self.adjust_to_dim = tk.BooleanVar(value=False) self.adjust_to_dim = tk.BooleanVar(value=False)
# draw base canvas
self.draw_canvas()
self.draw_grid()
def draw_canvas(self):
self.grid = self.create_rectangle(
0,
0,
self.default_width,
self.default_height,
outline="#000000",
fill="#ffffff",
width=1,
tags="rectangle",
)
def reset_and_redraw(self, session): def reset_and_redraw(self, session):
""" """
Reset the private variables CanvasGraph object, redraw nodes given the new grpc Reset the private variables CanvasGraph object, redraw nodes given the new grpc
@ -72,7 +76,7 @@ class CanvasGraph(tk.Canvas):
:return: nothing :return: nothing
""" """
# delete any existing drawn items # delete any existing drawn items
for tag in CANVAS_COMPONENT_TAGS: for tag in tags.COMPONENT_TAGS:
self.delete(tag) self.delete(tag)
# set the private variables to default value # set the private variables to default value
@ -101,7 +105,7 @@ class CanvasGraph(tk.Canvas):
self.bind("<Control-1>", self.ctrl_click) self.bind("<Control-1>", self.ctrl_click)
self.bind("<Double-Button-1>", self.double_click) self.bind("<Double-Button-1>", self.double_click)
def draw_grid(self, width=1000, height=800): def draw_grid(self):
""" """
Create grid Create grid
@ -110,21 +114,14 @@ class CanvasGraph(tk.Canvas):
:return: nothing :return: nothing
""" """
self.grid = self.create_rectangle( width, height = self.width_and_height()
0, width = int(width)
0, height = int(height)
width,
height,
outline="#000000",
fill="#ffffff",
width=1,
tags="rectangle",
)
for i in range(0, width, 27): for i in range(0, width, 27):
self.create_line(i, 0, i, height, dash=(2, 4), tags="gridline") self.create_line(i, 0, i, height, dash=(2, 4), tags=tags.GRIDLINE)
for i in range(0, height, 27): for i in range(0, height, 27):
self.create_line(0, i, width, i, dash=(2, 4), tags="gridline") self.create_line(0, i, width, i, dash=(2, 4), tags=tags.GRIDLINE)
self.tag_lower("gridline") self.tag_lower(tags.GRIDLINE)
self.tag_lower(self.grid) self.tag_lower(self.grid)
def add_wireless_edge(self, src, dst): def add_wireless_edge(self, src, dst):
@ -195,7 +192,7 @@ class CanvasGraph(tk.Canvas):
canvas_node_two.interfaces.append(link.interface_two) canvas_node_two.interfaces.append(link.interface_two)
# raise the nodes so they on top of the links # raise the nodes so they on top of the links
self.tag_raise("node") self.tag_raise(tags.NODE)
def canvas_xy(self, event): def canvas_xy(self, event):
""" """
@ -317,7 +314,7 @@ class CanvasGraph(tk.Canvas):
(x0 - 6, y0 - 6, x1 + 6, y1 + 6), (x0 - 6, y0 - 6, x1 + 6, y1 + 6),
activedash=True, activedash=True,
dash="-", dash="-",
tags="selectednodes", tags=tags.SELECTION,
) )
self.selection[object_id] = selection_id self.selection[object_id] = selection_id
else: else:
@ -534,7 +531,7 @@ class CanvasGraph(tk.Canvas):
self.delete(self.wallpaper_id) self.delete(self.wallpaper_id)
# place left corner of image to the left corner of the canvas # place left corner of image to the left corner of the canvas
self.wallpaper_id = self.create_image( self.wallpaper_id = self.create_image(
(cropx / 2, cropy / 2), image=cropped_tk, tags="wallpaper" (cropx / 2, cropy / 2), image=cropped_tk, tags=tags.WALLPAPER
) )
self.wallpaper_drawn = cropped_tk self.wallpaper_drawn = cropped_tk
@ -562,7 +559,7 @@ class CanvasGraph(tk.Canvas):
# place the center of the image at the center of the canvas # place the center of the image at the center of the canvas
self.delete(self.wallpaper_id) self.delete(self.wallpaper_id)
self.wallpaper_id = self.create_image( self.wallpaper_id = self.create_image(
(canvas_w / 2, canvas_h / 2), image=cropped_tk, tags="wallpaper" (canvas_w / 2, canvas_h / 2), image=cropped_tk, tags=tags.WALLPAPER
) )
self.wallpaper_drawn = cropped_tk self.wallpaper_drawn = cropped_tk
@ -576,7 +573,7 @@ class CanvasGraph(tk.Canvas):
image = Images.create(self.wallpaper_file, int(canvas_w), int(canvas_h)) image = Images.create(self.wallpaper_file, int(canvas_w), int(canvas_h))
self.delete(self.wallpaper_id) self.delete(self.wallpaper_id)
self.wallpaper_id = self.create_image( self.wallpaper_id = self.create_image(
(canvas_w / 2, canvas_h / 2), image=image, tags="wallpaper" (canvas_w / 2, canvas_h / 2), image=image, tags=tags.WALLPAPER
) )
self.wallpaper_drawn = image self.wallpaper_drawn = image
@ -585,36 +582,31 @@ class CanvasGraph(tk.Canvas):
img_w = image_tk.width() img_w = image_tk.width()
img_h = image_tk.height() img_h = image_tk.height()
self.delete(self.wallpaper_id) self.delete(self.wallpaper_id)
self.delete("rectangle") self.redraw_canvas(img_w, img_h)
self.delete("gridline")
self.draw_grid(img_w, img_h)
self.wallpaper_id = self.create_image((img_w / 2, img_h / 2), image=image_tk) self.wallpaper_id = self.create_image((img_w / 2, img_h / 2), image=image_tk)
self.wallpaper_drawn = image_tk self.wallpaper_drawn = image_tk
def redraw_grid(self, width, height): def redraw_canvas(self, width, height):
""" """
redraw grid with new dimension redraw grid with new dimension
:return: nothing :return: nothing
""" """
# resize canvas and scrollregion
self.config(scrollregion=(0, 0, width + 200, height + 200)) self.config(scrollregion=(0, 0, width + 200, height + 200))
self.coords(self.grid, 0, 0, width, height)
# delete previous grid # redraw gridlines to new canvas size
self.delete("rectangle") self.delete(tags.GRIDLINE)
self.delete("gridline") self.draw_grid()
# redraw
self.draw_grid(width=width, height=height)
# hide/show grid
self.update_grid() self.update_grid()
def redraw(self): def redraw(self):
if self.adjust_to_dim.get(): if self.adjust_to_dim.get():
self.resize_to_wallpaper() self.resize_to_wallpaper()
else: else:
print(self.scale_option.get())
option = ScaleOption(self.scale_option.get()) option = ScaleOption(self.scale_option.get())
logging.info("canvas scale option: %s", option)
if option == ScaleOption.UPPER_LEFT: if option == ScaleOption.UPPER_LEFT:
self.wallpaper_upper_left() self.wallpaper_upper_left()
elif option == ScaleOption.CENTERED: elif option == ScaleOption.CENTERED:
@ -624,13 +616,16 @@ class CanvasGraph(tk.Canvas):
elif option == ScaleOption.TILED: elif option == ScaleOption.TILED:
logging.warning("tiled background not implemented yet") logging.warning("tiled background not implemented yet")
# raise items above wallpaper
for component in tags.ABOVE_WALLPAPER_TAGS:
self.tag_raise(component)
def update_grid(self): def update_grid(self):
logging.info("updating grid show: %s", self.show_grid.get()) logging.info("updating grid show: %s", self.show_grid.get())
if self.show_grid.get(): if self.show_grid.get():
self.itemconfig("gridline", state=tk.NORMAL) self.itemconfig(tags.GRIDLINE, state=tk.NORMAL)
self.tag_raise("gridline")
else: else:
self.itemconfig("gridline", state=tk.HIDDEN) self.itemconfig(tags.GRIDLINE, state=tk.HIDDEN)
def set_wallpaper(self, filename): def set_wallpaper(self, filename):
logging.info("setting wallpaper: %s", filename) logging.info("setting wallpaper: %s", filename)
@ -639,8 +634,6 @@ class CanvasGraph(tk.Canvas):
self.wallpaper = img self.wallpaper = img
self.wallpaper_file = filename self.wallpaper_file = filename
self.redraw() self.redraw()
for component in ABOVE_WALLPAPER:
self.tag_raise(component)
else: else:
if self.wallpaper_id is not None: if self.wallpaper_id is not None:
self.delete(self.wallpaper_id) self.delete(self.wallpaper_id)

View file

@ -5,6 +5,7 @@ import tkinter as tk
from tkinter import font from tkinter import font
from core.api.grpc import core_pb2 from core.api.grpc import core_pb2
from coretk.graph import tags
TEXT_DISTANCE = 0.30 TEXT_DISTANCE = 0.30
@ -52,10 +53,20 @@ class LinkInfo:
f"{self.link.interface_two.ip6}/{self.link.interface_two.ip6mask}\n" f"{self.link.interface_two.ip6}/{self.link.interface_two.ip6mask}\n"
) )
self.id1 = self.canvas.create_text( self.id1 = self.canvas.create_text(
x1, y1, text=label_one, justify=tk.CENTER, font=self.font, tags="linkinfo" x1,
y1,
text=label_one,
justify=tk.CENTER,
font=self.font,
tags=tags.LINK_INFO,
) )
self.id2 = self.canvas.create_text( self.id2 = self.canvas.create_text(
x2, y2, text=label_two, justify=tk.CENTER, font=self.font, tags="linkinfo" x2,
y2,
text=label_two,
justify=tk.CENTER,
font=self.font,
tags=tags.LINK_INFO,
) )
def recalculate_info(self): def recalculate_info(self):

View file

@ -7,6 +7,7 @@ from coretk.dialogs.emaneconfig import EmaneConfigDialog
from coretk.dialogs.mobilityconfig import MobilityConfigDialog from coretk.dialogs.mobilityconfig import MobilityConfigDialog
from coretk.dialogs.nodeconfig import NodeConfigDialog from coretk.dialogs.nodeconfig import NodeConfigDialog
from coretk.dialogs.wlanconfig import WlanConfigDialog from coretk.dialogs.wlanconfig import WlanConfigDialog
from coretk.graph import tags
from coretk.graph.enums import GraphMode from coretk.graph.enums import GraphMode
from coretk.graph.tooltip import CanvasTooltip from coretk.graph.tooltip import CanvasTooltip
from coretk.nodeutils import NodeUtils from coretk.nodeutils import NodeUtils
@ -23,7 +24,7 @@ class CanvasNode:
x = self.core_node.position.x x = self.core_node.position.x
y = self.core_node.position.y y = self.core_node.position.y
self.id = self.canvas.create_image( self.id = self.canvas.create_image(
x, y, anchor=tk.CENTER, image=self.image, tags="node" x, y, anchor=tk.CENTER, image=self.image, tags=tags.NODE
) )
image_box = self.canvas.bbox(self.id) image_box = self.canvas.bbox(self.id)
y = image_box[3] + NODE_TEXT_OFFSET y = image_box[3] + NODE_TEXT_OFFSET
@ -32,7 +33,7 @@ class CanvasNode:
x, x,
y, y,
text=self.core_node.name, text=self.core_node.name,
tags="nodename", tags=tags.NODE_NAME,
font=text_font, font=text_font,
fill="#0000CD", fill="#0000CD",
) )
@ -62,13 +63,12 @@ class CanvasNode:
def add_antenna(self): def add_antenna(self):
x, y = self.canvas.coords(self.id) x, y = self.canvas.coords(self.id)
offset = len(self.antennae) * 8 offset = len(self.antennae) * 8
antenna_id = self.canvas.create_image( antenna_id = self.canvas.create_image(
x - 16 + offset, x - 16 + offset,
y - 23, y - 23,
anchor=tk.CENTER, anchor=tk.CENTER,
image=NodeUtils.ANTENNA_ICON, image=NodeUtils.ANTENNA_ICON,
tags="antenna", tags=tags.ANTENNA,
) )
self.antennae.append(antenna_id) self.antennae.append(antenna_id)

View file

@ -1,10 +1,9 @@
import logging import logging
from coretk.dialogs.shapemod import ShapeDialog from coretk.dialogs.shapemod import ShapeDialog
from coretk.graph import tags
from coretk.graph.shapeutils import ShapeType from coretk.graph.shapeutils import ShapeType
ABOVE_COMPONENT = ["gridline", "edge", "linkinfo", "antenna", "node", "nodename"]
class AnnotationData: class AnnotationData:
def __init__( def __init__(
@ -70,7 +69,7 @@ class Shape:
self.y1, self.y1,
self.x2, self.x2,
self.y2, self.y2,
tags="shape", tags=tags.SHAPE,
dash=dash, dash=dash,
fill=self.shape_data.fill_color, fill=self.shape_data.fill_color,
outline=self.shape_data.border_color, outline=self.shape_data.border_color,
@ -83,7 +82,7 @@ class Shape:
self.y1, self.y1,
self.x2, self.x2,
self.y2, self.y2,
tags="shape", tags=tags.SHAPE,
dash=dash, dash=dash,
fill=self.shape_data.fill_color, fill=self.shape_data.fill_color,
outline=self.shape_data.border_color, outline=self.shape_data.border_color,
@ -95,7 +94,7 @@ class Shape:
self.id = self.canvas.create_text( self.id = self.canvas.create_text(
self.x1, self.x1,
self.y1, self.y1,
tags="shapetext", tags=tags.SHAPE_TEXT,
text=self.shape_data.text, text=self.shape_data.text,
fill=self.shape_data.text_color, fill=self.shape_data.text_color,
font=font, font=font,
@ -122,7 +121,7 @@ class Shape:
self.text_id = self.canvas.create_text( self.text_id = self.canvas.create_text(
x, x,
y, y,
tags="shapetext", tags=tags.SHAPE_TEXT,
text=self.shape_data.text, text=self.shape_data.text,
fill=self.shape_data.text_color, fill=self.shape_data.text_color,
font=font, font=font,
@ -132,7 +131,7 @@ class Shape:
self.canvas.coords(self.id, self.x1, self.y1, x1, y1) self.canvas.coords(self.id, self.x1, self.y1, x1, y1)
def shape_complete(self, x, y): def shape_complete(self, x, y):
for component in ABOVE_COMPONENT: for component in tags.ABOVE_SHAPE:
self.canvas.tag_raise(component) self.canvas.tag_raise(component)
s = ShapeDialog(self.app, self.app, self) s = ShapeDialog(self.app, self.app, self)
s.show() s.show()

View file

@ -0,0 +1,35 @@
GRIDLINE = "gridline"
SHAPE = "shape"
SHAPE_TEXT = "shapetext"
EDGE = "edge"
LINK_INFO = "linkinfo"
WIRELESS_EDGE = "wireless"
ANTENNA = "antenna"
NODE_NAME = "nodename"
NODE = "node"
WALLPAPER = "wallpaper"
SELECTION = "selectednodes"
ABOVE_WALLPAPER_TAGS = [
GRIDLINE,
SHAPE,
SHAPE_TEXT,
EDGE,
LINK_INFO,
WIRELESS_EDGE,
ANTENNA,
NODE,
NODE_NAME,
]
ABOVE_SHAPE = [GRIDLINE, EDGE, LINK_INFO, WIRELESS_EDGE, ANTENNA, NODE, NODE_NAME]
COMPONENT_TAGS = [
EDGE,
NODE,
NODE_NAME,
WALLPAPER,
LINK_INFO,
ANTENNA,
WIRELESS_EDGE,
SELECTION,
SHAPE,
SHAPE_TEXT,
]

View file

@ -109,7 +109,6 @@ class MenuAction:
self.app.statusbar.progress_bar.start(5) self.app.statusbar.progress_bar.start(5)
thread = threading.Thread(target=self.app.core.open_xml, args=([file_path])) thread = threading.Thread(target=self.app.core.open_xml, args=([file_path]))
thread.start() thread.start()
# self.app.core.open_xml(file_path)
def gui_preferences(self): def gui_preferences(self):
dialog = PreferencesDialog(self.app, self.app) dialog = PreferencesDialog(self.app, self.app)

View file

@ -25,33 +25,42 @@ class StatusBar(ttk.Frame):
self.columnconfigure(3, weight=1) self.columnconfigure(3, weight=1)
self.columnconfigure(4, weight=1) self.columnconfigure(4, weight=1)
frame = ttk.Frame(self, borderwidth=1, relief=tk.RIDGE)
frame.grid(row=0, column=0, sticky="ew")
frame.columnconfigure(0, weight=1)
self.progress_bar = ttk.Progressbar( self.progress_bar = ttk.Progressbar(
self, orient="horizontal", mode="indeterminate" frame, orient="horizontal", mode="indeterminate"
) )
self.progress_bar.grid(row=0, column=0, sticky="ew") self.progress_bar.grid(sticky="ew")
self.status = ttk.Label(self, textvariable=self.statusvar, anchor=tk.CENTER) self.status = ttk.Label(
self.statusvar.set("status") self,
textvariable=self.statusvar,
anchor=tk.CENTER,
borderwidth=1,
relief=tk.RIDGE,
)
self.status.grid(row=0, column=1, sticky="ew") self.status.grid(row=0, column=1, sticky="ew")
self.zoom = ttk.Label(self, text="zoom", anchor=tk.CENTER) self.zoom = ttk.Label(
self, text="ZOOM TBD", anchor=tk.CENTER, borderwidth=1, relief=tk.RIDGE
)
self.zoom.grid(row=0, column=2, sticky="ew") self.zoom.grid(row=0, column=2, sticky="ew")
self.cpu_usage = ttk.Label(self, text="cpu usage", anchor=tk.CENTER) self.cpu_usage = ttk.Label(
self, text="CPU TBD", anchor=tk.CENTER, borderwidth=1, relief=tk.RIDGE
)
self.cpu_usage.grid(row=0, column=3, sticky="ew") self.cpu_usage.grid(row=0, column=3, sticky="ew")
self.emulation_light = ttk.Label(self, text="emulation light", anchor=tk.CENTER) self.emulation_light = ttk.Label(
self, text="CEL TBD", anchor=tk.CENTER, borderwidth=1, relief=tk.RIDGE
)
self.emulation_light.grid(row=0, column=4, sticky="ew") self.emulation_light.grid(row=0, column=4, sticky="ew")
def start_session_callback(self, process_time): def start_session_callback(self, process_time):
num_nodes = len(self.app.core.canvas_nodes)
num_links = len(self.app.core.links)
self.progress_bar.stop() self.progress_bar.stop()
self.statusvar.set( self.statusvar.set(f"Session started in {process_time:.3f} seconds")
"Network topology instantiated in %s seconds (%s node(s) and %s link(s))"
% ("%.3f" % process_time, num_nodes, num_links)
)
def stop_session_callback(self, cleanup_time): def stop_session_callback(self, cleanup_time):
self.progress_bar.stop() self.progress_bar.stop()
self.statusvar.set("Cleanup completed in %s seconds" % "%.3f" % cleanup_time) self.statusvar.set(f"Stopped session in {cleanup_time:.3f} seconds")

View file

@ -88,6 +88,14 @@ def load(style):
}, },
"map": {"fieldbackground": [("disabled", Colors.frame)]}, "map": {"fieldbackground": [("disabled", Colors.frame)]},
}, },
"TSpinbox": {
"configure": {
"fieldbackground": Colors.white,
"foreground": Colors.black,
"padding": (2, 0),
},
"map": {"fieldbackground": [("disabled", Colors.frame)]},
},
"TCombobox": { "TCombobox": {
"configure": { "configure": {
"fieldbackground": Colors.white, "fieldbackground": Colors.white,

View file

@ -5,6 +5,7 @@ from functools import partial
from tkinter import ttk from tkinter import ttk
from coretk.dialogs.customnodes import CustomNodesDialog from coretk.dialogs.customnodes import CustomNodesDialog
from coretk.graph import tags
from coretk.graph.enums import GraphMode from coretk.graph.enums import GraphMode
from coretk.graph.shapeutils import ShapeType from coretk.graph.shapeutils import ShapeType
from coretk.images import ImageEnum, Images from coretk.images import ImageEnum, Images
@ -41,6 +42,7 @@ class Toolbar(ttk.Frame):
self.annotation_button = None self.annotation_button = None
# runtime buttons # runtime buttons
self.runtime_select_button = None
# frames # frames
self.design_frame = None self.design_frame = None
@ -91,6 +93,11 @@ class Toolbar(ttk.Frame):
self.annotation_button.state(["!pressed"]) self.annotation_button.state(["!pressed"])
button.state(["pressed"]) button.state(["pressed"])
def runtime_select(self, button):
logging.info("selecting runtime button: %s", button)
self.runtime_select_button.state(["!pressed"])
button.state(["pressed"])
def draw_runtime_frame(self): def draw_runtime_frame(self):
self.runtime_frame = ttk.Frame(self) self.runtime_frame = ttk.Frame(self)
self.runtime_frame.grid(row=0, column=0, sticky="nsew") self.runtime_frame.grid(row=0, column=0, sticky="nsew")
@ -102,10 +109,10 @@ class Toolbar(ttk.Frame):
self.click_stop, self.click_stop,
"stop the session", "stop the session",
) )
self.create_button( self.runtime_select_button = self.create_button(
self.runtime_frame, self.runtime_frame,
icon(ImageEnum.SELECT), icon(ImageEnum.SELECT),
self.click_selection, self.click_runtime_selection,
"selection tool", "selection tool",
) )
# self.create_observe_button() # self.create_observe_button()
@ -190,6 +197,11 @@ class Toolbar(ttk.Frame):
self.design_select(self.select_button) self.design_select(self.select_button)
self.app.canvas.mode = GraphMode.SELECT self.app.canvas.mode = GraphMode.SELECT
def click_runtime_selection(self):
logging.debug("clicked selection tool")
self.runtime_select(self.runtime_select_button)
self.app.canvas.mode = GraphMode.SELECT
def click_start(self): def click_start(self):
""" """
Start session handler redraw buttons, send node and link messages to grpc Start session handler redraw buttons, send node and link messages to grpc
@ -202,6 +214,7 @@ class Toolbar(ttk.Frame):
thread = threading.Thread(target=self.app.core.start_session) thread = threading.Thread(target=self.app.core.start_session)
thread.start() thread.start()
self.runtime_frame.tkraise() self.runtime_frame.tkraise()
self.click_runtime_selection()
def click_link(self): def click_link(self):
logging.debug("Click LINK button") logging.debug("Click LINK button")
@ -357,11 +370,9 @@ class Toolbar(ttk.Frame):
self.app.statusbar.progress_bar.start(5) self.app.statusbar.progress_bar.start(5)
thread = threading.Thread(target=self.app.core.stop_session) thread = threading.Thread(target=self.app.core.stop_session)
thread.start() thread.start()
for cid in self.app.canvas.find_withtag("wireless"): self.app.canvas.delete(tags.WIRELESS_EDGE)
self.app.canvas.itemconfig(cid, state="hidden")
# self.app.canvas.delete("wireless")
self.design_frame.tkraise() self.design_frame.tkraise()
self.click_selection()
def update_annotation(self, image, shape_type): def update_annotation(self, image, shape_type):
logging.info("clicked annotation: ") logging.info("clicked annotation: ")

View file

@ -1,7 +1,7 @@
import logging import logging
import tkinter as tk import tkinter as tk
from functools import partial from functools import partial
from tkinter import font, ttk from tkinter import filedialog, font, ttk
from tkinter.scrolledtext import ScrolledText from tkinter.scrolledtext import ScrolledText
from core.api.grpc import core_pb2 from core.api.grpc import core_pb2
@ -20,6 +20,12 @@ INT_TYPES = {
PAD = 5 PAD = 5
def file_button_click(value):
file_path = filedialog.askopenfilename(title="Select File")
if file_path:
value.set(file_path)
class FrameScroll(ttk.LabelFrame): class FrameScroll(ttk.LabelFrame):
def __init__(self, master, app, _cls=ttk.Frame, **kw): def __init__(self, master, app, _cls=ttk.Frame, **kw):
super().__init__(master, **kw) super().__init__(master, **kw)
@ -104,6 +110,16 @@ class ConfigFrame(FrameScroll):
combobox.grid(row=index, column=1, sticky="ew", pady=pady) combobox.grid(row=index, column=1, sticky="ew", pady=pady)
elif option.type == core_pb2.ConfigOptionType.STRING: elif option.type == core_pb2.ConfigOptionType.STRING:
value.set(option.value) value.set(option.value)
if "file" in option.label:
file_frame = ttk.Frame(frame)
file_frame.grid(row=index, column=1, sticky="ew", pady=pady)
file_frame.columnconfigure(0, weight=1)
entry = ttk.Entry(file_frame, textvariable=value)
entry.grid(row=0, column=0, sticky="ew", padx=padx)
func = partial(file_button_click, value)
button = ttk.Button(file_frame, text="...", command=func)
button.grid(row=0, column=1)
else:
entry = ttk.Entry(frame, textvariable=value) entry = ttk.Entry(frame, textvariable=value)
entry.grid(row=index, column=1, sticky="ew", pady=pady) entry.grid(row=index, column=1, sticky="ew", pady=pady)
elif option.type in INT_TYPES: elif option.type in INT_TYPES:
@ -193,3 +209,11 @@ class CodeText(ScrolledText):
relief=tk.FLAT, relief=tk.FLAT,
**kwargs **kwargs
) )
class Spinbox(ttk.Entry):
def __init__(self, master=None, **kwargs):
super().__init__(master, "ttk::spinbox", **kwargs)
def set(self, value):
self.tk.call(self._w, "set", value)