updated canvas dialogs to make use of common canvas redraw/wallpaper logic
This commit is contained in:
parent
4d2b84b107
commit
aec1126a14
4 changed files with 159 additions and 241 deletions
|
@ -21,9 +21,6 @@ class Application(tk.Frame):
|
|||
self.canvas = None
|
||||
self.statusbar = None
|
||||
|
||||
# variables
|
||||
self.set_wallpaper = None
|
||||
|
||||
# setup
|
||||
self.config = appconfig.read()
|
||||
self.style = ttk.Style()
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
"""
|
||||
set wallpaper
|
||||
"""
|
||||
import enum
|
||||
import logging
|
||||
import tkinter as tk
|
||||
from tkinter import filedialog, ttk
|
||||
|
||||
from PIL import Image, ImageTk
|
||||
from PIL import Image
|
||||
|
||||
from coretk.appconfig import BACKGROUNDS_PATH
|
||||
from coretk.dialogs.dialog import Dialog
|
||||
|
@ -15,14 +14,6 @@ from coretk.images import Images
|
|||
PADX = 5
|
||||
|
||||
|
||||
class ScaleOption(enum.Enum):
|
||||
NONE = 0
|
||||
UPPER_LEFT = 1
|
||||
CENTERED = 2
|
||||
SCALED = 3
|
||||
TILED = 4
|
||||
|
||||
|
||||
class CanvasBackgroundDialog(Dialog):
|
||||
def __init__(self, master, app):
|
||||
"""
|
||||
|
@ -33,8 +24,8 @@ class CanvasBackgroundDialog(Dialog):
|
|||
super().__init__(master, app, "Canvas Background", modal=True)
|
||||
self.canvas = self.app.canvas
|
||||
self.scale_option = tk.IntVar(value=self.canvas.scale_option.get())
|
||||
self.show_grid = tk.IntVar(value=self.canvas.show_grid.get())
|
||||
self.adjust_to_dim = tk.IntVar(value=self.canvas.adjust_to_dim.get())
|
||||
self.show_grid = tk.BooleanVar(value=self.canvas.show_grid.get())
|
||||
self.adjust_to_dim = tk.BooleanVar(value=self.canvas.adjust_to_dim.get())
|
||||
self.filename = tk.StringVar(value=self.canvas.wallpaper_file)
|
||||
self.image_label = None
|
||||
self.options = []
|
||||
|
@ -124,9 +115,6 @@ class CanvasBackgroundDialog(Dialog):
|
|||
)
|
||||
checkbutton.grid(row=5, column=0, sticky="ew", padx=PADX)
|
||||
|
||||
self.show_grid.set(1)
|
||||
self.adjust_to_dim.set(0)
|
||||
|
||||
def draw_buttons(self):
|
||||
frame = ttk.Frame(self.top)
|
||||
frame.grid(row=6, column=0, pady=5, sticky="ew")
|
||||
|
@ -171,202 +159,40 @@ class CanvasBackgroundDialog(Dialog):
|
|||
|
||||
def click_adjust_canvas(self):
|
||||
# deselect all radio buttons and grey them out
|
||||
if self.adjust_to_dim.get() == 1:
|
||||
if self.adjust_to_dim.get():
|
||||
self.scale_option.set(0)
|
||||
for option in self.options:
|
||||
option.config(state=tk.DISABLED)
|
||||
# turn back the radio button to active state so that user can choose again
|
||||
elif self.adjust_to_dim.get() == 0:
|
||||
else:
|
||||
self.scale_option.set(1)
|
||||
for option in self.options:
|
||||
option.config(state=tk.NORMAL)
|
||||
else:
|
||||
logging.error("canvasbackground.py adjust_canvas_size invalid value")
|
||||
|
||||
def delete_canvas_components(self, tag_list):
|
||||
"""
|
||||
delete canvas items whose tag is in the tag list
|
||||
|
||||
:param list[string] tag_list: list of tags
|
||||
:return: nothing
|
||||
"""
|
||||
for tag in tag_list:
|
||||
for i in self.canvas.find_withtag(tag):
|
||||
self.canvas.delete(i)
|
||||
|
||||
def get_canvas_width_and_height(self):
|
||||
"""
|
||||
retrieve canvas width and height in pixels
|
||||
|
||||
:return: nothing
|
||||
"""
|
||||
grid = self.canvas.find_withtag("rectangle")[0]
|
||||
x0, y0, x1, y1 = self.canvas.coords(grid)
|
||||
canvas_w = abs(x0 - x1)
|
||||
canvas_h = abs(y0 - y1)
|
||||
return canvas_w, canvas_h
|
||||
|
||||
def determine_cropped_image_dimension(self):
|
||||
"""
|
||||
determine the dimension of the image after being cropped
|
||||
|
||||
:return: nothing
|
||||
"""
|
||||
return
|
||||
|
||||
def upper_left(self, img):
|
||||
tk_img = ImageTk.PhotoImage(img)
|
||||
|
||||
# crop image if it is bigger than canvas
|
||||
canvas_w, canvas_h = self.get_canvas_width_and_height()
|
||||
|
||||
cropx = img_w = tk_img.width()
|
||||
cropy = img_h = tk_img.height()
|
||||
|
||||
if img_w > canvas_w:
|
||||
cropx -= img_w - canvas_w
|
||||
if img_h > canvas_h:
|
||||
cropy -= img_h - canvas_h
|
||||
cropped = img.crop((0, 0, cropx, cropy))
|
||||
cropped_tk = ImageTk.PhotoImage(cropped)
|
||||
|
||||
# place left corner of image to the left corner of the canvas
|
||||
self.canvas.wallpaper_drawn = cropped_tk
|
||||
self.delete_canvas_components(["wallpaper"])
|
||||
wid = self.canvas.create_image(
|
||||
(cropx / 2, cropy / 2), image=cropped_tk, tags="wallpaper"
|
||||
)
|
||||
self.canvas.wallpaper_id = wid
|
||||
|
||||
def center(self, img):
|
||||
"""
|
||||
place the image at the center of canvas
|
||||
|
||||
:param Image img: image object
|
||||
:return: nothing
|
||||
"""
|
||||
tk_img = ImageTk.PhotoImage(img)
|
||||
canvas_w, canvas_h = self.get_canvas_width_and_height()
|
||||
|
||||
cropx = img_w = tk_img.width()
|
||||
cropy = img_h = tk_img.height()
|
||||
|
||||
# dimension of the cropped image
|
||||
if img_w > canvas_w:
|
||||
cropx -= img_w - canvas_w
|
||||
if img_h > canvas_h:
|
||||
cropy -= img_h - canvas_h
|
||||
|
||||
x0 = (img_w - cropx) / 2
|
||||
y0 = (img_h - cropy) / 2
|
||||
x1 = x0 + cropx
|
||||
y1 = y0 + cropy
|
||||
cropped = img.crop((x0, y0, x1, y1))
|
||||
cropped_tk = ImageTk.PhotoImage(cropped)
|
||||
|
||||
# place the center of the image at the center of the canvas
|
||||
self.delete_canvas_components(["wallpaper"])
|
||||
# self.delete_previous_wallpaper()
|
||||
wid = self.canvas.create_image(
|
||||
(canvas_w / 2, canvas_h / 2), image=cropped_tk, tags="wallpaper"
|
||||
)
|
||||
self.canvas.wallpaper_id = wid
|
||||
self.canvas.wallpaper_drawn = cropped_tk
|
||||
|
||||
def scaled(self, img):
|
||||
"""
|
||||
scale image based on canvas dimension
|
||||
|
||||
:param Image img: image object
|
||||
:return: nothing
|
||||
"""
|
||||
canvas_w, canvas_h = self.get_canvas_width_and_height()
|
||||
resized_image = img.resize((int(canvas_w), int(canvas_h)), Image.ANTIALIAS)
|
||||
image_tk = ImageTk.PhotoImage(resized_image)
|
||||
self.delete_canvas_components(["wallpaper"])
|
||||
wid = self.canvas.create_image(
|
||||
(canvas_w / 2, canvas_h / 2), image=image_tk, tags="wallpaper"
|
||||
)
|
||||
self.canvas.wallpaper_id = wid
|
||||
self.canvas.wallpaper_drawn = image_tk
|
||||
|
||||
def tiled(self, img):
|
||||
return
|
||||
|
||||
def draw_new_canvas(self, canvas_width, canvas_height):
|
||||
"""
|
||||
delete the old canvas and draw a new one
|
||||
|
||||
:param int canvas_width: canvas width in pixel
|
||||
:param int canvas_height: canvas height in pixel
|
||||
:return:
|
||||
"""
|
||||
self.delete_canvas_components(["rectangle", "gridline"])
|
||||
self.canvas.draw_grid(canvas_width, canvas_height)
|
||||
|
||||
def canvas_to_image_dimension(self, img):
|
||||
image_tk = ImageTk.PhotoImage(img)
|
||||
img_w = image_tk.width()
|
||||
img_h = image_tk.height()
|
||||
self.delete_canvas_components(["wallpaper"])
|
||||
self.draw_new_canvas(img_w, img_h)
|
||||
wid = self.canvas.create_image((img_w / 2, img_h / 2), image=image_tk)
|
||||
self.canvas.wallpaper_id = wid
|
||||
self.canvas.wallpaper_drawn = image_tk
|
||||
|
||||
def draw_grid(self):
|
||||
self.canvas.adjust_to_dim.set(self.adjust_to_dim.get())
|
||||
if self.show_grid.get() == 0:
|
||||
for i in self.canvas.find_withtag("gridline"):
|
||||
self.canvas.itemconfig(i, state=tk.HIDDEN)
|
||||
elif self.show_grid.get() == 1:
|
||||
for i in self.canvas.find_withtag("gridline"):
|
||||
self.canvas.itemconfig(i, state=tk.NORMAL)
|
||||
self.canvas.lift(i)
|
||||
else:
|
||||
logging.error("canvasbackground.py show_grid invalid value")
|
||||
|
||||
def save_wallpaper_options(self):
|
||||
def click_apply(self):
|
||||
self.canvas.scale_option.set(self.scale_option.get())
|
||||
self.canvas.show_grid.set(self.show_grid.get())
|
||||
self.canvas.adjust_to_dim.set(self.adjust_to_dim.get())
|
||||
self.canvas.update_grid()
|
||||
|
||||
def click_apply(self):
|
||||
filename = self.filename.get()
|
||||
if not filename:
|
||||
self.delete_canvas_components(["wallpaper"])
|
||||
self.destroy()
|
||||
self.canvas.delete(self.canvas.wallpaper_id)
|
||||
self.canvas.wallpaper = None
|
||||
self.canvas.wallpaper_file = None
|
||||
self.save_wallpaper_options()
|
||||
self.destroy()
|
||||
return
|
||||
|
||||
try:
|
||||
img = Image.open(filename)
|
||||
self.canvas.wallpaper = img
|
||||
self.canvas.wallpaper_file = filename
|
||||
self.canvas.redraw()
|
||||
except FileNotFoundError:
|
||||
logging.error("invalid background: %s", filename)
|
||||
if self.canvas.wallpaper_id:
|
||||
self.canvas.delete(self.canvas.wallpaper_id)
|
||||
self.canvas.wallpaper_id = None
|
||||
self.destroy()
|
||||
return
|
||||
self.canvas.wallpaper_file = None
|
||||
|
||||
self.canvas.adjust_to_dim.set(self.adjust_to_dim.get())
|
||||
if self.adjust_to_dim.get() == 0:
|
||||
self.canvas.scale_option.set(self.scale_option.get())
|
||||
option = ScaleOption(self.scale_option.get())
|
||||
if option == ScaleOption.UPPER_LEFT:
|
||||
self.upper_left(img)
|
||||
elif option == ScaleOption.CENTERED:
|
||||
self.center(img)
|
||||
elif option == ScaleOption.SCALED:
|
||||
self.scaled(img)
|
||||
elif option == ScaleOption.TILED:
|
||||
logging.warning("tiled background not implemented yet")
|
||||
elif self.adjust_to_dim.get() == 1:
|
||||
self.canvas_to_image_dimension(img)
|
||||
|
||||
self.draw_grid()
|
||||
self.destroy()
|
||||
|
|
|
@ -1,14 +1,11 @@
|
|||
"""
|
||||
size and scale
|
||||
"""
|
||||
import logging
|
||||
import tkinter as tk
|
||||
from tkinter import font, ttk
|
||||
|
||||
from coretk.dialogs.canvasbackground import ScaleOption
|
||||
from coretk.dialogs.dialog import Dialog
|
||||
|
||||
DRAW_OBJECT_TAGS = ["edge", "node", "nodename", "linkinfo", "antenna"]
|
||||
FRAME_PAD = 5
|
||||
PADX = 5
|
||||
|
||||
|
@ -172,47 +169,11 @@ class SizeAndScaleDialog(Dialog):
|
|||
button = ttk.Button(frame, text="Cancel", command=self.destroy)
|
||||
button.grid(row=0, column=1, sticky="ew")
|
||||
|
||||
def redraw_grid(self):
|
||||
"""
|
||||
redraw grid with new dimension
|
||||
|
||||
:return: nothing
|
||||
"""
|
||||
width, height = self.pixel_width.get(), self.pixel_height.get()
|
||||
self.canvas.config(scrollregion=(0, 0, width + 200, height + 200))
|
||||
|
||||
# delete old plot and redraw
|
||||
for i in self.canvas.find_withtag("gridline"):
|
||||
self.canvas.delete(i)
|
||||
for i in self.canvas.find_withtag("rectangle"):
|
||||
self.canvas.delete(i)
|
||||
|
||||
self.canvas.draw_grid(width=width, height=height)
|
||||
# lift anything that is drawn on the plot before
|
||||
for tag in DRAW_OBJECT_TAGS:
|
||||
for i in self.canvas.find_withtag(tag):
|
||||
self.canvas.lift(i)
|
||||
|
||||
def click_apply(self):
|
||||
meter_per_pixel = float(self.scale.get()) / 100
|
||||
width, height = self.pixel_width.get(), self.pixel_height.get()
|
||||
self.canvas.meters_per_pixel = meter_per_pixel
|
||||
self.redraw_grid()
|
||||
# if there is a current wallpaper showing, redraw it based on current
|
||||
# wallpaper options
|
||||
wallpaper_tool = self.app.set_wallpaper
|
||||
wallpaper = self.canvas.wallpaper
|
||||
if wallpaper:
|
||||
if self.canvas.adjust_to_dim.get() == 0:
|
||||
scale_option = ScaleOption(self.canvas.scale_option.get())
|
||||
if scale_option == ScaleOption.UPPER_LEFT:
|
||||
wallpaper_tool.upper_left(wallpaper)
|
||||
elif scale_option == ScaleOption.CENTERED:
|
||||
wallpaper_tool.center(wallpaper)
|
||||
elif scale_option == ScaleOption.SCALED:
|
||||
wallpaper_tool.scaled(wallpaper)
|
||||
elif scale_option == ScaleOption.TILED:
|
||||
logging.warning("tiled background not implemented")
|
||||
elif self.canvas.adjust_to_dim.get() == 1:
|
||||
wallpaper_tool.canvas_to_image_dimension(wallpaper)
|
||||
wallpaper_tool.show_grid()
|
||||
self.canvas.redraw_grid(width, height)
|
||||
if self.canvas.wallpaper:
|
||||
self.canvas.redraw()
|
||||
self.destroy()
|
||||
|
|
|
@ -2,6 +2,8 @@ import enum
|
|||
import logging
|
||||
import tkinter as tk
|
||||
|
||||
from PIL import ImageTk
|
||||
|
||||
from core.api.grpc import core_pb2
|
||||
from coretk.canvasaction import CanvasAction
|
||||
from coretk.canvastooltip import CanvasTooltip
|
||||
|
@ -21,6 +23,14 @@ class GraphMode(enum.Enum):
|
|||
OTHER = 4
|
||||
|
||||
|
||||
class ScaleOption(enum.Enum):
|
||||
NONE = 0
|
||||
UPPER_LEFT = 1
|
||||
CENTERED = 2
|
||||
SCALED = 3
|
||||
TILED = 4
|
||||
|
||||
|
||||
CORE_NODES = ["router"]
|
||||
CORE_WIRED_NETWORK_NODES = []
|
||||
CORE_WIRELESS_NODE = ["wlan"]
|
||||
|
@ -60,8 +70,8 @@ class CanvasGraph(tk.Canvas):
|
|||
self.wallpaper_drawn = None
|
||||
self.wallpaper_file = ""
|
||||
self.scale_option = tk.IntVar(value=1)
|
||||
self.show_grid = tk.IntVar(value=1)
|
||||
self.adjust_to_dim = tk.IntVar(value=0)
|
||||
self.show_grid = tk.BooleanVar(value=True)
|
||||
self.adjust_to_dim = tk.BooleanVar(value=False)
|
||||
|
||||
def setup_menus(self):
|
||||
self.node_context = tk.Menu(self.master)
|
||||
|
@ -132,11 +142,12 @@ class CanvasGraph(tk.Canvas):
|
|||
width=1,
|
||||
tags="rectangle",
|
||||
)
|
||||
self.tag_lower(self.grid)
|
||||
for i in range(0, width, 27):
|
||||
self.create_line(i, 0, i, height, dash=(2, 4), tags="gridline")
|
||||
for i in range(0, height, 27):
|
||||
self.create_line(0, i, width, i, dash=(2, 4), tags="gridline")
|
||||
self.tag_lower("gridline")
|
||||
self.tag_lower(self.grid)
|
||||
|
||||
def draw_existing_component(self, session):
|
||||
"""
|
||||
|
@ -228,9 +239,8 @@ class CanvasGraph(tk.Canvas):
|
|||
if2
|
||||
)
|
||||
|
||||
# lift the nodes so they on top of the links
|
||||
for i in self.find_withtag("node"):
|
||||
self.lift(i)
|
||||
# raise the nodes so they on top of the links
|
||||
self.tag_raise("node")
|
||||
|
||||
def canvas_xy(self, event):
|
||||
"""
|
||||
|
@ -426,6 +436,132 @@ class CanvasGraph(tk.Canvas):
|
|||
self.core.add_graph_node(self.core.session_id, node.id, x, y, node_name)
|
||||
return node
|
||||
|
||||
def width_and_height(self):
|
||||
"""
|
||||
retrieve canvas width and height in pixels
|
||||
|
||||
:return: nothing
|
||||
"""
|
||||
grid = self.find_withtag("rectangle")[0]
|
||||
x0, y0, x1, y1 = self.coords(grid)
|
||||
canvas_w = abs(x0 - x1)
|
||||
canvas_h = abs(y0 - y1)
|
||||
return canvas_w, canvas_h
|
||||
|
||||
def wallpaper_upper_left(self):
|
||||
tk_img = ImageTk.PhotoImage(self.wallpaper)
|
||||
# crop image if it is bigger than canvas
|
||||
canvas_w, canvas_h = self.width_and_height()
|
||||
cropx = img_w = tk_img.width()
|
||||
cropy = img_h = tk_img.height()
|
||||
if img_w > canvas_w:
|
||||
cropx -= img_w - canvas_w
|
||||
if img_h > canvas_h:
|
||||
cropy -= img_h - canvas_h
|
||||
cropped = self.wallpaper.crop((0, 0, cropx, cropy))
|
||||
cropped_tk = ImageTk.PhotoImage(cropped)
|
||||
self.delete(self.wallpaper_id)
|
||||
# place left corner of image to the left corner of the canvas
|
||||
self.wallpaper_id = self.create_image(
|
||||
(cropx / 2, cropy / 2), image=cropped_tk, tags="wallpaper"
|
||||
)
|
||||
self.wallpaper_drawn = cropped_tk
|
||||
|
||||
def wallpaper_center(self):
|
||||
"""
|
||||
place the image at the center of canvas
|
||||
|
||||
:param Image img: image object
|
||||
:return: nothing
|
||||
"""
|
||||
tk_img = ImageTk.PhotoImage(self.wallpaper)
|
||||
canvas_w, canvas_h = self.width_and_height()
|
||||
cropx = img_w = tk_img.width()
|
||||
cropy = img_h = tk_img.height()
|
||||
# dimension of the cropped image
|
||||
if img_w > canvas_w:
|
||||
cropx -= img_w - canvas_w
|
||||
if img_h > canvas_h:
|
||||
cropy -= img_h - canvas_h
|
||||
x0 = (img_w - cropx) / 2
|
||||
y0 = (img_h - cropy) / 2
|
||||
x1 = x0 + cropx
|
||||
y1 = y0 + cropy
|
||||
cropped = self.wallpaper.crop((x0, y0, x1, y1))
|
||||
cropped_tk = ImageTk.PhotoImage(cropped)
|
||||
# place the center of the image at the center of the canvas
|
||||
self.delete(self.wallpaper_id)
|
||||
self.wallpaper_id = self.create_image(
|
||||
(canvas_w / 2, canvas_h / 2), image=cropped_tk, tags="wallpaper"
|
||||
)
|
||||
self.wallpaper_drawn = cropped_tk
|
||||
|
||||
def wallpaper_scaled(self):
|
||||
"""
|
||||
scale image based on canvas dimension
|
||||
|
||||
:param Image img: image object
|
||||
:return: nothing
|
||||
"""
|
||||
canvas_w, canvas_h = self.width_and_height()
|
||||
image = Images.create(self.wallpaper_file, int(canvas_w), int(canvas_h))
|
||||
self.delete(self.wallpaper_id)
|
||||
self.wallpaper_id = self.create_image(
|
||||
(canvas_w / 2, canvas_h / 2), image=image, tags="wallpaper"
|
||||
)
|
||||
self.wallpaper_drawn = image
|
||||
|
||||
def resize_to_wallpaper(self):
|
||||
image_tk = ImageTk.PhotoImage(self.wallpaper)
|
||||
img_w = image_tk.width()
|
||||
img_h = image_tk.height()
|
||||
self.delete(self.wallpaper_id)
|
||||
self.delete("rectangle")
|
||||
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_drawn = image_tk
|
||||
|
||||
def redraw_grid(self, width, height):
|
||||
"""
|
||||
redraw grid with new dimension
|
||||
|
||||
:return: nothing
|
||||
"""
|
||||
self.config(scrollregion=(0, 0, width + 200, height + 200))
|
||||
|
||||
# delete previous grid
|
||||
self.delete("rectangle")
|
||||
self.delete("gridline")
|
||||
|
||||
# redraw
|
||||
self.draw_grid(width=width, height=height)
|
||||
|
||||
# hide/show grid
|
||||
self.update_grid()
|
||||
|
||||
def redraw(self):
|
||||
if self.adjust_to_dim.get():
|
||||
self.resize_to_wallpaper()
|
||||
else:
|
||||
option = ScaleOption(self.scale_option.get())
|
||||
if option == ScaleOption.UPPER_LEFT:
|
||||
self.wallpaper_upper_left()
|
||||
elif option == ScaleOption.CENTERED:
|
||||
self.wallpaper_center()
|
||||
elif option == ScaleOption.SCALED:
|
||||
self.wallpaper_scaled()
|
||||
elif option == ScaleOption.TILED:
|
||||
logging.warning("tiled background not implemented yet")
|
||||
|
||||
def update_grid(self):
|
||||
logging.info("updating grid show: %s", self.show_grid.get())
|
||||
if self.show_grid.get():
|
||||
self.itemconfig("gridline", state=tk.NORMAL)
|
||||
self.tag_raise("gridline")
|
||||
else:
|
||||
self.itemconfig("gridline", state=tk.HIDDEN)
|
||||
|
||||
|
||||
class CanvasEdge:
|
||||
"""
|
||||
|
@ -469,8 +605,6 @@ class CanvasEdge:
|
|||
self.link_info = None
|
||||
self.throughput = None
|
||||
self.wired = is_wired
|
||||
# TODO resolve this
|
||||
# self.canvas.tag_lower(self.id)
|
||||
|
||||
def complete(self, dst, x, y):
|
||||
self.dst = dst
|
||||
|
@ -478,8 +612,8 @@ class CanvasEdge:
|
|||
x1, y1, _, _ = self.canvas.coords(self.id)
|
||||
self.canvas.coords(self.id, x1, y1, x, y)
|
||||
self.canvas.helper.draw_wireless_case(self.src, self.dst, self)
|
||||
self.canvas.lift(self.src)
|
||||
self.canvas.lift(self.dst)
|
||||
self.canvas.tag_raise(self.src)
|
||||
self.canvas.tag_raise(self.dst)
|
||||
|
||||
def delete(self):
|
||||
self.canvas.delete(self.id)
|
||||
|
|
Loading…
Add table
Reference in a new issue