working on shapes and texts

This commit is contained in:
Huy Pham 2019-12-06 09:03:21 -08:00
parent 7e2ebb4a2c
commit 4a34aaa30d
5 changed files with 222 additions and 123 deletions

View file

@ -10,7 +10,7 @@ from core.api.grpc import client, core_pb2
from coretk import appconfig
from coretk.dialogs.mobilityplayer import MobilityPlayer
from coretk.dialogs.sessions import SessionsDialog
from coretk.graph.shape import Shape, ShapeData
from coretk.graph.shape import AnnotationData, Shape
from coretk.interface import InterfaceManager
from coretk.nodeutils import NodeDraw, NodeUtils
@ -136,6 +136,7 @@ class CoreClient:
self.custom_observers[observer.name] = observer
def handle_events(self, event):
print(event)
if event.HasField("link_event"):
logging.info("link event: %s", event)
self.handle_link_event(event.link_event)
@ -160,6 +161,8 @@ class CoreClient:
self.handle_node_event(event.node_event)
elif event.HasField("config_event"):
logging.info("config event: %s", event)
elif event.HasField("throughput_event"):
print("throughput")
else:
logging.info("unhandled event: %s", event)
@ -189,7 +192,7 @@ class CoreClient:
interface_throughputs = event.interface_throughputs
for i in interface_throughputs:
print("")
return
# return
throughputs_belong_to_session = []
for if_tp in interface_throughputs:
if if_tp.node_id in self.node_ids:
@ -312,8 +315,7 @@ class CoreClient:
config_type = annotation_config["type"]
if config_type in ["rectangle", "oval"]:
coords = tuple(annotation_config["iconcoords"])
data = ShapeData(
False,
data = AnnotationData(
annotation_config["label"],
annotation_config["fontfamily"],
annotation_config["fontsize"],

View file

@ -5,6 +5,7 @@ import tkinter as tk
from tkinter import colorchooser, font, ttk
from coretk.dialogs.dialog import Dialog
from coretk.images import ImageEnum
FONT_SIZES = [8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72]
BORDER_WIDTH = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
@ -12,9 +13,17 @@ BORDER_WIDTH = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
class ShapeDialog(Dialog):
def __init__(self, master, app, shape):
super().__init__(master, app, "Add a new shape", modal=True)
self.annotation_type = app.canvas.annotation_type
self.canvas = app.canvas
if self.is_shape():
super().__init__(master, app, "Add a new shape", modal=True)
self.id = shape.id
self.fill = None
self.border = None
else:
super().__init__(master, app, "Add a new text", modal=True)
self.shape = shape
data = shape.shape_data
self.shape_text = tk.StringVar(value=data.text)
self.font = tk.StringVar(value=data.font)
@ -26,11 +35,18 @@ class ShapeDialog(Dialog):
self.bold = tk.IntVar(value=data.bold)
self.italic = tk.IntVar(value=data.italic)
self.underline = tk.IntVar(value=data.underline)
self.fill = None
self.border = None
self.top.columnconfigure(0, weight=1)
self.draw()
def is_shape(self):
return (
self.annotation_type == ImageEnum.OVAL
or self.annotation_type == ImageEnum.RECTANGLE
)
def is_text(self):
return self.annotation_type == ImageEnum.TEXT
def draw(self):
frame = ttk.Frame(self.top)
frame.columnconfigure(0, weight=1)
@ -69,13 +85,16 @@ class ShapeDialog(Dialog):
button.grid(row=0, column=2)
frame.grid(row=2, column=0, sticky="nsew", padx=3, pady=3)
if self.is_shape():
frame = ttk.Frame(self.top)
frame.columnconfigure(0, weight=1)
frame.columnconfigure(1, weight=1)
frame.columnconfigure(2, weight=1)
label = ttk.Label(frame, text="Fill color")
label.grid(row=0, column=0, sticky="nsew")
self.fill = ttk.Label(frame, text=self.fill_color, background=self.fill_color)
self.fill = ttk.Label(
frame, text=self.fill_color, background=self.fill_color
)
self.fill.grid(row=0, column=1, sticky="nsew", padx=3)
button = ttk.Button(frame, text="Color", command=self.choose_fill_color)
button.grid(row=0, column=2, sticky="nsew")
@ -101,7 +120,10 @@ class ShapeDialog(Dialog):
label = ttk.Label(frame, text="Border width:")
label.grid(row=0, column=0, sticky="nsew")
combobox = ttk.Combobox(
frame, textvariable=self.border_width, values=BORDER_WIDTH, state="readonly"
frame,
textvariable=self.border_width,
values=BORDER_WIDTH,
state="readonly",
)
combobox.grid(row=0, column=1, sticky="nsew")
frame.grid(row=5, column=0, sticky="nsew", padx=3, pady=3)
@ -109,7 +131,7 @@ class ShapeDialog(Dialog):
frame = ttk.Frame(self.top)
frame.columnconfigure(0, weight=1)
frame.columnconfigure(1, weight=1)
button = ttk.Button(frame, text="Add shape", command=self.add_shape)
button = ttk.Button(frame, text="Add shape", command=self.click_add)
button.grid(row=0, column=0, sticky="e", padx=3)
button = ttk.Button(frame, text="Cancel", command=self.cancel)
button.grid(row=0, column=1, sticky="w", pady=3)
@ -130,11 +152,86 @@ class ShapeDialog(Dialog):
self.border.config(background=color[1], text=color[1])
def cancel(self):
if not self.canvas.shapes[self.id].created:
if self.is_shape() and not self.canvas.shapes[self.id].created:
self.canvas.delete(self.id)
self.canvas.shapes.pop(self.id)
self.destroy()
def click_add(self):
if self.is_shape():
self.add_shape()
elif self.is_text():
self.add_text()
self.destroy()
def make_font(self):
"""
create font for text or shape label
:return: list(font specifications)
"""
size = int(self.font_size.get())
text_font = [self.font.get(), size]
if self.bold.get() == 1:
text_font.append("bold")
if self.italic.get() == 1:
text_font.append("italic")
if self.underline.get() == 1:
text_font.append("underline")
return text_font
def save_text(self):
"""
save info related to text or shape label
:return: nothing
"""
data = self.shape.shape_data
data.text = self.shape_text.get()
data.font = self.font.get()
data.font_size = int(self.font_size.get())
data.text_color = self.text_color
data.bold = self.bold.get()
data.italic = self.italic.get()
data.underline = self.underline.get()
def save_shape(self):
"""
save info related to shape
:return: nothing
"""
data = self.shape.shape_data
data.fill_color = self.fill_color
data.border_color = self.border_color
data.border_width = int(self.border_width.get())
def add_text(self):
"""
add text to canvas
:return: nothing
"""
text = self.shape_text.get()
x = self.shape.x0
y = self.shape.y0
text_font = self.make_font()
if self.shape.text_id is None:
tid = self.canvas.create_text(
x, y, text=text, fill=self.text_color, font=text_font, tags="text"
)
self.shape.text_id = tid
self.id = tid
self.shape.id = tid
self.canvas.texts[tid] = self.shape
self.shape.created = True
self.save_text()
print(self.canvas.texts)
# self.canvas.shapes[self.id].created = True
# else:
# self.canvas.itemconfig(
# self.shape.text_id, text=text, fill=self.text_color, font=f
# )
def add_shape(self):
self.canvas.itemconfig(
self.id,
@ -143,42 +240,28 @@ class ShapeDialog(Dialog):
outline=self.border_color,
width=int(self.border_width.get()),
)
shape = self.canvas.shapes[self.id]
shape_text = self.shape_text.get()
size = int(self.font_size.get())
x0, y0, x1, y1 = self.canvas.bbox(self.id)
text_y = y0 + 1.5 * size
text_x = (x0 + x1) / 2
f = [self.font.get(), size]
if self.bold.get() == 1:
f.append("bold")
if self.italic.get() == 1:
f.append("italic")
if self.underline.get() == 1:
f.append("underline")
if shape.text_id is None:
shape.text_id = self.canvas.create_text(
text_x,
text_y,
_y = y0 + 1.5 * size
_x = (x0 + x1) / 2
text_font = self.make_font()
if self.shape.text_id is None:
self.shape.text_id = self.canvas.create_text(
_x,
_y,
text=shape_text,
fill=self.text_color,
font=f,
font=text_font,
tags="shapetext",
)
self.canvas.shapes[self.id].created = True
self.shape.created = True
else:
self.canvas.itemconfig(
shape.text_id, text=shape_text, fill=self.text_color, font=f
self.shape.text_id,
text=shape_text,
fill=self.text_color,
font=text_font,
)
data = self.canvas.shapes[self.id].shape_data
data.text = shape_text
data.font = self.font.get()
data.font_size = int(self.font_size.get())
data.text_color = self.text_color
data.fill_color = self.fill_color
data.border_color = self.border_color
data.border_width = int(self.border_width.get())
data.bold = self.bold.get()
data.italic = self.italic.get()
data.underline = self.underline.get()
self.destroy()
self.save_text()
self.save_shape()

View file

@ -0,0 +1,26 @@
"""
text dialog
"""
import tkinter as tk
from tkinter import ttk
from coretk.dialogs.dialog import Dialog
class TextDialog(Dialog):
def __init__(self, master, app):
super().__init__(master, app, "Add a new text", modal=True)
self.canvas = app.canvas
self.text = tk.StringVar(value="")
self.draw()
def draw(self):
frame = ttk.Frame(self.top)
frame.columnconfigure(0, weight=1)
frame.columnconfigure(1, weight=4)
label = ttk.Label(frame, text="Text for top of text: ")
label.grid(row=0, column=0)
entry = ttk.Entry(frame, textvariable=self.text)
entry.grid(row=0, column=1)
frame.grid(row=0, column=0, sticky="nsew")

View file

@ -34,6 +34,7 @@ class CanvasGraph(tk.Canvas):
self.nodes = {}
self.edges = {}
self.shapes = {}
self.texts = {}
self.wireless_edges = {}
self.drawing_edge = None
self.grid = None
@ -276,6 +277,8 @@ class CanvasGraph(tk.Canvas):
if self.shape_drawing:
self.shapes[self.selected].shape_complete(x, y)
self.shape_drawing = False
elif self.annotation_type == ImageEnum.TEXT:
self.text.shape_complete(self.text.cursor_x, self.text.cursor_y)
else:
self.focus_set()
self.selected = self.get_selected(event)
@ -424,16 +427,19 @@ class CanvasGraph(tk.Canvas):
if self.mode == GraphMode.EDGE and is_node:
x, y = self.coords(selected)
self.drawing_edge = CanvasEdge(x, y, x, y, selected, self)
if (
self.mode == GraphMode.ANNOTATION
and self.annotation_type in [ImageEnum.OVAL, ImageEnum.RECTANGLE]
and selected is None
):
if self.mode == GraphMode.ANNOTATION and selected is None:
if self.annotation_type in [ImageEnum.OVAL, ImageEnum.RECTANGLE]:
x, y = self.canvas_xy(event)
shape = Shape(self.app, self, x, y)
self.selected = shape.id
self.shapes[shape.id] = shape
self.shape_drawing = True
elif self.annotation_type == ImageEnum.TEXT:
x, y = self.canvas_xy(event)
self.text = Shape(self.app, self, x, y)
# self.shapes[shape.id] = shape
if self.mode == GraphMode.SELECT:
if selected is not None:
if selected in self.shapes:

View file

@ -1,41 +1,27 @@
"""
class for shapes
"""
import logging
from coretk.dialogs.shapemod import ShapeDialog
from coretk.images import ImageEnum
ABOVE_COMPONENT = ["gridline", "edge", "linkinfo", "antenna", "node", "nodename"]
class ShapeData:
class AnnotationData:
def __init__(
self,
is_default=True,
text=None,
font=None,
font_size=None,
text_color=None,
fill_color=None,
border_color=None,
border_width=None,
text="",
font="Arial",
font_size=12,
text_color="#000000",
fill_color="#CFCFFF",
border_color="#000000",
border_width=0,
bold=0,
italic=0,
underline=0,
):
if is_default:
self.text = ""
self.font = "Arial"
self.font_size = 12
self.text_color = "#000000"
self.fill_color = "#CFCFFF"
self.border_color = "#000000"
self.border_width = 0
self.bold = 0
self.italic = 0
self.underline = 0
else:
self.text = text
self.font = font
self.font_size = font_size
@ -66,7 +52,7 @@ class Shape:
self.y0 = top_y
self.created = False
self.text_id = None
self.shape_data = ShapeData()
self.shape_data = AnnotationData()
canvas.delete(canvas.find_withtag("selectednodes"))
annotation_type = self.canvas.annotation_type
if annotation_type == ImageEnum.OVAL:
@ -112,7 +98,6 @@ class Shape:
self.shape_data = data
self.cursor_x = None
self.cursor_y = None
self.canvas.tag_bind(self.id, "<ButtonRelease-1>", self.click_release)
def shape_motion(self, x1, y1):
self.canvas.coords(self.id, self.x0, self.y0, x1, y1)
@ -123,9 +108,6 @@ class Shape:
s = ShapeDialog(self.app, self.app, self)
s.show()
def click_release(self, event):
logging.debug("Click release on shape %s", self.id)
def motion(self, event, delta_x=None, delta_y=None):
if event is not None:
delta_x = event.x - self.cursor_x