From 0a26a8f8e38a890cca9e720287ad667e4dea52c0 Mon Sep 17 00:00:00 2001 From: Huy Pham <42948410+hpham@users.noreply.github.com> Date: Tue, 3 Dec 2019 16:18:00 -0800 Subject: [PATCH] shape dialog, fix move shape --- coretk/coretk/dialogs/shapemod.py | 51 +++++++++++++++++++++++++++---- coretk/coretk/graph.py | 24 ++++++++++++--- coretk/coretk/shape.py | 5 +-- 3 files changed, 68 insertions(+), 12 deletions(-) diff --git a/coretk/coretk/dialogs/shapemod.py b/coretk/coretk/dialogs/shapemod.py index b76fc0d1..577d3821 100644 --- a/coretk/coretk/dialogs/shapemod.py +++ b/coretk/coretk/dialogs/shapemod.py @@ -11,8 +11,10 @@ BORDER_WIDTH = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] class ShapeDialog(Dialog): - def __init__(self, master, app): + def __init__(self, master, app, shape_id): super().__init__(master, app, "Add a new shape", modal=True) + self.canvas = app.canvas + self.id = shape_id self.shape_text = tk.StringVar(value="") self.font = tk.StringVar(value="Arial") self.font_size = tk.IntVar(value=12) @@ -20,6 +22,9 @@ class ShapeDialog(Dialog): self.fill_color = "#CFCFFF" self.border_color = "black" self.border_width = tk.IntVar(value=0) + self.bold = tk.IntVar(value=0) + self.italic = tk.IntVar(value=0) + self.underline = tk.IntVar(value=0) self.fill = None self.border = None @@ -57,11 +62,11 @@ class ShapeDialog(Dialog): frame.grid(row=1, column=0, sticky="nsew", padx=3, pady=3) frame = ttk.Frame(self.top) - button = ttk.Checkbutton(frame, text="Bold") + button = ttk.Checkbutton(frame, variable=self.bold, text="Bold") button.grid(row=0, column=0) - button = ttk.Checkbutton(frame, text="Italic") + button = ttk.Checkbutton(frame, variable=self.italic, text="Italic") button.grid(row=0, column=1, padx=3) - button = ttk.Checkbutton(frame, text="Underline") + button = ttk.Checkbutton(frame, variable=self.underline, text="Underline") button.grid(row=0, column=2) frame.grid(row=2, column=0, sticky="nsew", padx=3, pady=3) @@ -105,9 +110,9 @@ 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") + button = ttk.Button(frame, text="Add shape", command=self.add_shape) button.grid(row=0, column=0, sticky="e", padx=3) - button = ttk.Button(frame, text="Cancel", command=self.destroy) + button = ttk.Button(frame, text="Cancel", command=self.cancel) button.grid(row=0, column=1, sticky="w", pady=3) frame.grid(row=6, column=0, sticky="nsew", padx=3, pady=3) @@ -124,3 +129,37 @@ class ShapeDialog(Dialog): color = colorchooser.askcolor(color="black") self.border_color = color[1] self.border.config(background=color[1], text=color[1]) + + def cancel(self): + if not self.canvas.shapes[self.id].created: + self.canvas.delete(self.id) + self.canvas.shapes.pop(self.id) + self.destroy() + + def add_shape(self): + self.canvas.itemconfig( + self.id, + fill=self.fill_color, + dash="", + outline=self.border_color, + width=int(self.border_width.get()), + ) + shape = self.canvas.shapes[self.id] + shape_text = self.shape_text.get() + if shape.text is None: + size = int(self.font_size.get()) + x0, y0, x1, y1 = self.canvas.bbox(self.id) + text_y = y0 + 2 * 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") + shape.text = self.canvas.create_text( + text_x, text_y, text=shape_text, fill=self.text_color, font=f + ) + self.canvas.shapes[self.id].created = True + self.destroy() diff --git a/coretk/coretk/graph.py b/coretk/coretk/graph.py index c8c5ceba..c9c349ec 100644 --- a/coretk/coretk/graph.py +++ b/coretk/coretk/graph.py @@ -146,6 +146,7 @@ class CanvasGraph(tk.Canvas): self.bind("", self.click_context) self.bind("", self.press_delete) self.bind("", self.ctrl_click) + self.bind("", self.double_click) def draw_grid(self, width=1000, height=800): """ @@ -297,8 +298,9 @@ class CanvasGraph(tk.Canvas): if self.annotation_type in [ImageEnum.OVAL, ImageEnum.RECTANGLE]: self.focus_set() x, y = self.canvas_xy(event) - self.shapes[self.selected].shape_complete(x, y) - self.shape_drawing = False + if self.shape_drawing: + self.shapes[self.selected].shape_complete(x, y) + self.shape_drawing = False else: self.focus_set() self.selected = self.get_selected(event) @@ -312,6 +314,7 @@ class CanvasGraph(tk.Canvas): self.add_node(x, y) elif self.mode == GraphMode.PICKNODE: self.mode = GraphMode.NODE + self.selected = None def handle_edge_release(self, event): edge = self.drawing_edge @@ -372,7 +375,11 @@ class CanvasGraph(tk.Canvas): self.selected = shape.id self.shapes[shape.id] = shape self.shape_drawing = True - if self.mode == GraphMode.SELECT and "shape" in self.gettags(selected): + if ( + self.mode == GraphMode.SELECT + and selected is not None + and "shape" in self.gettags(selected) + ): x, y = self.canvas_xy(event) self.shapes[selected].cursor_x = x self.shapes[selected].cursor_y = y @@ -403,7 +410,11 @@ class CanvasGraph(tk.Canvas): ): x, y = self.canvas_xy(event) self.shapes[self.selected].shape_motion(x, y) - if self.mode == GraphMode.SELECT and "shape" in self.gettags(self.selected): + if ( + self.mode == GraphMode.SELECT + and self.selected is not None + and "shape" in self.gettags(self.selected) + ): self.shapes[self.selected].motion(event) def click_context(self, event): @@ -431,6 +442,11 @@ class CanvasGraph(tk.Canvas): nodes = self.canvas_management.delete_selected_nodes() self.core.delete_graph_nodes(nodes) + def double_click(self, event): + selected = self.get_selected(event) + if selected is not None and "shape" in self.gettags(selected): + print("bring up shape dialog ") + def add_node(self, x, y): if self.selected is None or "shape" in self.gettags(self.selected): core_node = self.core.create_node( diff --git a/coretk/coretk/shape.py b/coretk/coretk/shape.py index 696f1e5e..9c85837e 100644 --- a/coretk/coretk/shape.py +++ b/coretk/coretk/shape.py @@ -17,6 +17,8 @@ class Shape: self.y0 = top_y self.cursor_x = None self.cursor_y = None + self.created = False + self.text = None canvas.delete(canvas.find_withtag("selectednodes")) annotation_type = self.canvas.annotation_type if annotation_type == ImageEnum.OVAL: @@ -34,10 +36,9 @@ class Shape: self.canvas.coords(self.id, self.x0, self.y0, x1, y1) def shape_complete(self, x, y): - self.canvas.itemconfig(self.id, width=0, fill="#ccccff") for component in ABOVE_COMPONENT: self.canvas.tag_raise(component) - s = ShapeDialog(self.app, self.app) + s = ShapeDialog(self.app, self.app, self.id) s.show() def click_release(self, event):