core-extra/daemon/core/gui/dialogs/shapemod.py

252 lines
8.8 KiB
Python

"""
shape input dialog
"""
import tkinter as tk
from tkinter import font, ttk
from core.gui.dialogs.colorpicker import ColorPickerDialog
from core.gui.dialogs.dialog import Dialog
from core.gui.graph import tags
from core.gui.graph.shapeutils import is_draw_shape, is_shape_text
from core.gui.themes import FRAME_PAD, PADX, PADY
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]
class ShapeDialog(Dialog):
def __init__(self, master, app, shape):
if is_draw_shape(shape.shape_type):
title = "Add Shape"
else:
title = "Add Text"
super().__init__(master, app, title, modal=True)
self.canvas = app.canvas
self.fill = None
self.border = None
self.shape = shape
data = shape.shape_data
self.shape_text = tk.StringVar(value=data.text)
self.font = tk.StringVar(value=data.font)
self.font_size = tk.IntVar(value=data.font_size)
self.text_color = data.text_color
fill_color = data.fill_color
if not fill_color:
fill_color = "#CFCFFF"
self.fill_color = fill_color
self.border_color = data.border_color
self.border_width = tk.IntVar(value=0)
self.bold = tk.BooleanVar(value=data.bold)
self.italic = tk.BooleanVar(value=data.italic)
self.underline = tk.BooleanVar(value=data.underline)
self.draw()
def draw(self):
self.top.columnconfigure(0, weight=1)
self.draw_label_options()
if is_draw_shape(self.shape.shape_type):
self.draw_shape_options()
self.draw_spacer()
self.draw_buttons()
def draw_label_options(self):
label_frame = ttk.LabelFrame(self.top, text="Label", padding=FRAME_PAD)
label_frame.grid(sticky="ew")
label_frame.columnconfigure(0, weight=1)
entry = ttk.Entry(label_frame, textvariable=self.shape_text)
entry.grid(sticky="ew", pady=PADY)
# font options
frame = ttk.Frame(label_frame)
frame.grid(sticky="nsew", pady=PADY)
frame.columnconfigure(0, weight=1)
frame.columnconfigure(1, weight=1)
frame.columnconfigure(2, weight=1)
combobox = ttk.Combobox(
frame,
textvariable=self.font,
values=sorted(font.families()),
state="readonly",
)
combobox.grid(row=0, column=0, sticky="nsew")
combobox = ttk.Combobox(
frame, textvariable=self.font_size, values=FONT_SIZES, state="readonly"
)
combobox.grid(row=0, column=1, padx=PADX, sticky="nsew")
button = ttk.Button(frame, text="Color", command=self.choose_text_color)
button.grid(row=0, column=2, sticky="nsew")
# style options
frame = ttk.Frame(label_frame)
frame.grid(sticky="ew")
for i in range(3):
frame.columnconfigure(i, weight=1)
button = ttk.Checkbutton(frame, variable=self.bold, text="Bold")
button.grid(row=0, column=0, sticky="ew")
button = ttk.Checkbutton(frame, variable=self.italic, text="Italic")
button.grid(row=0, column=1, padx=PADX, sticky="ew")
button = ttk.Checkbutton(frame, variable=self.underline, text="Underline")
button.grid(row=0, column=2, sticky="ew")
def draw_shape_options(self):
label_frame = ttk.LabelFrame(self.top, text="Shape", padding=FRAME_PAD)
label_frame.grid(sticky="ew", pady=PADY)
label_frame.columnconfigure(0, weight=1)
frame = ttk.Frame(label_frame)
frame.grid(sticky="ew")
for i in range(1, 3):
frame.columnconfigure(i, weight=1)
label = ttk.Label(frame, text="Fill Color")
label.grid(row=0, column=0, padx=PADX, sticky="w")
self.fill = ttk.Label(frame, text=self.fill_color, background=self.fill_color)
self.fill.grid(row=0, column=1, sticky="ew", padx=PADX)
button = ttk.Button(frame, text="Color", command=self.choose_fill_color)
button.grid(row=0, column=2, sticky="ew")
label = ttk.Label(frame, text="Border Color")
label.grid(row=1, column=0, sticky="w", padx=PADX)
self.border = ttk.Label(
frame, text=self.border_color, background=self.border_color
)
self.border.grid(row=1, column=1, sticky="ew", padx=PADX)
button = ttk.Button(frame, text="Color", command=self.choose_border_color)
button.grid(row=1, column=2, sticky="ew")
frame = ttk.Frame(label_frame)
frame.grid(sticky="ew", pady=PADY)
frame.columnconfigure(1, weight=1)
label = ttk.Label(frame, text="Border Width")
label.grid(row=0, column=0, sticky="w", padx=PADX)
combobox = ttk.Combobox(
frame, textvariable=self.border_width, values=BORDER_WIDTH, state="readonly"
)
combobox.grid(row=0, column=1, sticky="nsew")
def draw_buttons(self):
frame = ttk.Frame(self.top)
frame.grid(sticky="nsew")
frame.columnconfigure(0, weight=1)
frame.columnconfigure(1, weight=1)
button = ttk.Button(frame, text="Add shape", command=self.click_add)
button.grid(row=0, column=0, sticky="ew", padx=PADX)
button = ttk.Button(frame, text="Cancel", command=self.cancel)
button.grid(row=0, column=1, sticky="ew")
def choose_text_color(self):
color_picker = ColorPickerDialog(self, self.app, "#000000")
color = color_picker.askcolor()
self.text_color = color
def choose_fill_color(self):
color_picker = ColorPickerDialog(self, self.app, self.fill_color)
color = color_picker.askcolor()
self.fill_color = color
self.fill.config(background=color, text=color)
def choose_border_color(self):
color_picker = ColorPickerDialog(self, self.app, self.border_color)
color = color_picker.askcolor()
self.border_color = color
self.border.config(background=color, text=color)
def cancel(self):
self.shape.delete()
self.canvas.shapes.pop(self.shape.id)
self.destroy()
def click_add(self):
if is_draw_shape(self.shape.shape_type):
self.add_shape()
elif is_shape_text(self.shape.shape_type):
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():
text_font.append("bold")
if self.italic.get():
text_font.append("italic")
if self.underline.get():
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()
text_font = self.make_font()
self.canvas.itemconfig(
self.shape.id, text=text, fill=self.text_color, font=text_font
)
self.save_text()
def add_shape(self):
self.canvas.itemconfig(
self.shape.id,
fill=self.fill_color,
dash="",
outline=self.border_color,
width=int(self.border_width.get()),
)
shape_text = self.shape_text.get()
size = int(self.font_size.get())
x0, y0, x1, y1 = self.canvas.bbox(self.shape.id)
_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=text_font,
tags=tags.SHAPE_TEXT,
)
self.shape.created = True
else:
self.canvas.itemconfig(
self.shape.text_id,
text=shape_text,
fill=self.text_color,
font=text_font,
)
self.save_text()
self.save_shape()