Compare commits

..

6 Commits

Author SHA1 Message Date
cxykevin 8912864b9e 更新调试界面,添加frame 2024-04-07 21:39:09 +08:00
cxykevin 4d644b3011 添加选择器 2024-04-07 21:38:58 +08:00
cxykevin 8046c09321 添加菜单 2024-04-07 21:38:42 +08:00
cxykevin bc0f82125c 添加进度条 2024-04-07 21:38:29 +08:00
cxykevin c60307aa4c 更新button和window 2024-04-07 21:38:07 +08:00
cxykevin 913c4a3496 添加单/多选框 2024-04-07 21:37:14 +08:00
15 changed files with 2043 additions and 46 deletions

View File

@ -1,21 +1,86 @@
import magictk
import random
from multiprocessing import Process
if __name__ == "__main__":
win = magictk.Window()
pb = magictk.ProgressBar(win)
pb.pack()
magictk.Button(win, text="Default(+)",
func=lambda s: pb.add_progress(0.1)).pack()
magictk.ButtonFill(win, text="Primary(-)",
func=lambda s: pb.add_progress(-0.1)).pack()
magictk.ButtonFill(win, color_type="success", text="Success(+)",
func=lambda s: pb.add_progress(0.02)).pack()
magictk.ButtonFill(win, color_type="info", text="Info(-)",
func=lambda s: pb.add_progress(-0.02)).pack()
magictk.ButtonFill(win, color_type="warning", text="Warning(+)",
func=lambda s: pb.add_progress(0.3)).pack()
magictk.ButtonFill(win, color_type="danger", text="Danger(-)",
func=lambda s: pb.add_progress(-0.3)).pack()
frame = magictk.Frame(win)
magictk.Button(frame, text="Default",
func=lambda s: print("Btn 1")).pack(side='left')
magictk.ButtonFill(frame, text="Primary",
func=lambda s: print("Btn 2")).pack(side='left')
magictk.ButtonFill(frame, color_type="success", text="Success",
func=lambda s: print("Btn 3")).pack(side='left')
magictk.ButtonFill(frame, color_type="info", text="Info",
func=lambda s: print("Btn 4")).pack(side='left')
magictk.ButtonFill(frame, color_type="warning", text="Warning",
func=lambda s: print("Btn 5")).pack(side='left')
magictk.ButtonFill(frame, color_type="danger", text="Danger",
func=lambda s: print("Btn 6")).pack(side='left')
frame.pack()
frame2 = magictk.Frame(win)
magictk.Select(frame2, text="Select", items=[
f"Option {i}" for i in range(1, 6)]).pack(side='left')
magictk.Select(frame2, text="Select(1000 items)", items=[
f"Option {i}" for i in range(1, 1001)]).pack(side='left')
obj1 = magictk.MenuObjs()
for i in range(1, 10):
obj1.addmenu(f"Option {i}", lambda s, t: print(i))
magictk.Button(frame2, text="Menu",
func=lambda s: magictk.Menu(win, menuobj=obj1), w=60).pack()
frame2.pack()
frame3 = magictk.Frame(win)
groups = magictk.RadioGroup()
magictk.Checkbox(frame3, text="Radio 1", w=100,
group=groups).pack(side='left')
magictk.Checkbox(frame3, text="Radio 2", w=100,
group=groups).pack(side='left')
magictk.Checkbox(frame3, text="Radio 3", w=100,
group=groups).pack(side='left')
magictk.Checkbox(frame3, text="Radio 4", w=100,
group=groups).pack(side='left')
frame3.pack()
frame4 = magictk.Frame(win)
magictk.Checkbox(frame4, text="Option 1", w=100).pack(side='left')
magictk.Checkbox(frame4, text="Option 2", w=100).pack(side='left')
frame4.pack()
frame5 = magictk.Frame(win)
pb = magictk.ProgressBar(frame5)
pb.pack(side='left')
magictk.Button(frame5, text="+",
func=lambda s: pb.add_progress(0.1), w=30).pack(side='left')
magictk.Button(frame5, text="-",
func=lambda s: pb.add_progress(-0.1), w=30).pack(side='left')
magictk.Button(frame5, text="++",
func=lambda s: pb.add_progress(0.3), w=40).pack(side='left')
magictk.Button(frame5, text="--",
func=lambda s: pb.add_progress(-0.3), w=40).pack(side='left')
frame5.pack()
frame6 = magictk.Frame(win)
def kaoji():
def test(*args):
p = []
size = 10000000
for i in range(1, size):
if (i % 100000 == 0):
print(f"make data... {i*100//size}%")
p.append(random.randint(1, size))
print("sort...")
p.sort()
print("finish!")
del p
ts = Process(target=test)
ts.start()
magictk.Button(frame6, text="Performance Test",
func=lambda s: kaoji(), w=130).pack(side='left')
frame6.pack()
win.mainloop()
# from magictk import workspace

View File

@ -1,3 +1,7 @@
from magictk.window import Window
from magictk.button import Button, ButtonFill
from magictk.progressbar import ProgressBar
from magictk.checkbox import Checkbox, RadioGroup
from magictk.submenu import Menu, MenuObjs
from magictk.select import Select
from magictk.frame import Frame

View File

@ -108,16 +108,16 @@ class Button:
def __init__(self, master=None, root_anim=None, w=80, h=30, text="Button", func=lambda s: print("Press"), color_list: None | dict = None):
set_font()
self.__func = func
self.w = max(80, w)
self.w = max(30, w)
self.h = max(30, h)
self.text = text
self.__master = master
if (color_list is not None):
self.color = color_list
if (root_anim == None):
self.__root = master
self.root = master.root
else:
self.__root = root_anim
self.root = root_anim
self.canvas = tkinter.Canvas(
master, bg=self.color["background"], width=self.w, height=self.h, borderwidth=0, bd=0, highlightcolor=self.color["background"], highlightthickness=0)
@ -198,12 +198,12 @@ class Button:
def bind_anim(self):
def anim_magictk():
if (self.__is_hover == 1 and self.__flash_t < self.max_flash):
self.__flash_t += (1 if (len(self.__root.anim) > 6) else 1)
self.__flash_t += (1 if (len(self.root.anim) > 6) else 1)
self.__flash_t = min(self.__flash_t, self.max_flash)
self.hover_mode = self.__flash_t/self.max_flash
self.__update_color()
elif (self.__is_hover == 0 and self.__flash_t > 0):
self.__flash_t -= (1 if (len(self.__root.anim) > 6) else 1)
self.__flash_t -= (1 if (len(self.root.anim) > 6) else 1)
self.__flash_t = max(self.__flash_t, 0)
self.hover_mode = self.__flash_t/self.max_flash
self.__update_color()
@ -220,16 +220,16 @@ class Button:
self.__flash_t -= 1
self.hover_mode = self.__flash_t/self.max_flash
self.__update_color()
self.__root.after(anim_normal, 16)
self.root.after(anim_normal, 16)
try:
self.__root.anim == 0
self.root.anim == 0
except:
self.__root.after(anim_normal, 16)
self.root.after(anim_normal, 16)
else:
if (anim_magictk not in self.__root.anim):
self.__root.anim.append(anim_magictk)
self.__anim_obj_id = self.__root.anim[-1]
if (anim_magictk not in self.root.anim):
self.root.anim.append(anim_magictk)
self.__anim_obj_id = self.root.anim[-1]
def __bind_event(self):
def enter_v(*args):
@ -347,16 +347,16 @@ class ButtonFill(Button):
self.__color_fg = color_type
self.__color_fg1 = color_type+"_light3"
self.__color_fg2 = color_type+"_dark"
self.w = max(80, w)
self.w = max(30, w)
self.h = max(30, h)
self.text = text
self.__master = master
if (color_list is not None):
self.color = color_list
if (root_anim == None):
self.__root = master
self.root = master.root
else:
self.__root = root_anim
self.root = root_anim
self.canvas = tkinter.Canvas(
master, bg=self.color["background"], width=self.w, height=self.h, borderwidth=0, bd=0, highlightcolor=self.color["background"], highlightthickness=0)
@ -428,12 +428,12 @@ class ButtonFill(Button):
def bind_anim(self):
def anim_magictk():
if (self.__is_hover == 1 and self.__flash_t < self.max_flash):
self.__flash_t += (1 if (len(self.__root.anim) > 6) else 1)
self.__flash_t += (1 if (len(self.root.anim) > 6) else 1)
self.__flash_t = min(self.__flash_t, self.max_flash)
self.hover_mode = self.__flash_t/self.max_flash
self.__update_color()
elif (self.__is_hover == 0 and self.__flash_t > 0):
self.__flash_t -= (1 if (len(self.__root.anim) > 6) else 1)
self.__flash_t -= (1 if (len(self.root.anim) > 6) else 1)
self.__flash_t = max(self.__flash_t, 0)
self.hover_mode = self.__flash_t/self.max_flash
self.__update_color()
@ -450,16 +450,16 @@ class ButtonFill(Button):
self.__flash_t -= 1
self.hover_mode = self.__flash_t/self.max_flash
self.__update_color()
self.__root.after(anim_normal, 16)
self.root.after(anim_normal, 16)
try:
self.__root.anim == 0
self.root.anim == 0
except:
self.__root.after(anim_normal, 16)
self.root.after(anim_normal, 16)
else:
if (anim_magictk not in self.__root.anim):
self.__root.anim.append(anim_magictk)
self.__anim_obj_id = self.__root.anim[-1]
if (anim_magictk not in self.root.anim):
self.root.anim.append(anim_magictk)
self.__anim_obj_id = self.root.anim[-1]
def __bind_event(self):
def enter_v(*args):

319
magictk/checkbox.py Normal file
View File

@ -0,0 +1,319 @@
import json
import tkinter
from tkinter import ttk
from tkinter import font as tkfont
try:
import color_tmpl
except ImportError:
from magictk import color_tmpl
try:
import photoload
except ImportError:
from magictk import photoload
def set_font():
global use_font
font_family = ["Helvetica Neue", "Helvetica", "PingFang SC", "Hiragino Sans GB",
"Microsoft YaHei",
"微软雅黑",
"Arial", "sans-serif"]
t_family = tkfont.families(root=None, displayof=None)
for i in font_family:
if i in t_family:
use_font = i
break
else:
print("Unknown font")
class Checkbox:
__color_bd = "border_base"
__color_bg = "background"
__color_fg = "primary"
__color_fg1 = "primary"
__color_fg2 = "primary_dark"
color = color_tmpl.default_color
__fill_obj = []
__fill_func = []
__fill_gc = []
__fill_fc = []
__fill_hc = []
hover_mode = 0.0
ishover = 0
__flash_t = 0
max_flash = 4
__anim_obj_id = -1
checked = False
text = "ButtonFill"
_group_id = 0
disable_unhover = 0
def callback(*args): return None
def __draw_corner(self, r_x, r_y, x, y, **kwargs):
border_info = json.loads(photoload.loadres("checkboxborder"))
y_n = 0
for i in border_info:
x_n = 0
for j in i:
if (r_x == 0):
px = x+x_n+1
else:
px = x+2-x_n-1
if (r_y == 0):
py = y+y_n+1
else:
py = y+2-y_n-1
if (j < 0):
lcolor = 255+j
else:
lcolor = 255-j
if (j < 0):
g_color = color_tmpl.mix_color(
self.color[self.__color_bg], self.color[self.__color_bd], int((1-lcolor/255)*1000)/1000)
else:
g_color = color_tmpl.mix_color(
self.color["background"], self.color[self.__color_bd], int((1-lcolor/255)*1000)/1000)
if (j < 0):
f_color = color_tmpl.mix_color(
self.color[self.__color_fg1], self.color[self.__color_fg1], int((1-lcolor/255)*1000)/1000)
else:
f_color = color_tmpl.mix_color(
self.color["background"], self.color[self.__color_fg1], int((1-lcolor/255)*1000)/1000)
if (j < 0):
h_color = color_tmpl.mix_color(
self.color[self.__color_fg2], self.color[self.__color_fg2], int((1-lcolor/255)*1000)/1000)
else:
h_color = color_tmpl.mix_color(
self.color["background"], self.color[self.__color_fg2], int((1-lcolor/255)*1000)/1000)
obj = self.canvas.create_rectangle(
px, py, px, py, width=0, fill=g_color)
def update_color(obj, g_color, f_color, h_color):
if (self.ishover == 2):
self.canvas.itemconfig(
obj, fill=h_color)
elif (self.__flash_t <= self.max_flash):
self.canvas.itemconfig(
obj, fill=color_tmpl.mix_color(g_color, f_color, self.hover_mode))
self.__fill_func.append(update_color)
self.__fill_gc.append(g_color)
self.__fill_fc.append(f_color)
self.__fill_hc.append(h_color)
self.__fill_obj.append(obj)
x_n += 1
y_n += 1
def __draw_img(self, x, y, **kwargs):
border_info = json.loads(photoload.loadres("checkbox"))
y_n = 0
for i in border_info:
x_n = 0
for j in i:
px = x+x_n+1
py = y+y_n+1
if (j < 0):
lcolor = 255+j
else:
lcolor = 255-j
g_color = self.color[self.__color_fg]
f_color = color_tmpl.mix_color(
self.color["background"], self.color[self.__color_fg], int((1-lcolor/255)*1000)/1000)
h_color = color_tmpl.mix_color(
self.color["background"], self.color[self.__color_fg2], int((1-lcolor/255)*1000)/1000)
obj = self.canvas.create_rectangle(
px, py, px, py, width=0, fill=g_color)
def update_color(obj, g_color, f_color, h_color):
if (self.__flash_t > self.max_flash):
self.canvas.itemconfig(
obj, fill=color_tmpl.mix_color(g_color, f_color, (self.__flash_t-self.max_flash)/self.max_flash))
else:
self.canvas.itemconfig(
obj, fill=color_tmpl.mix_color(self.color["background"], self.color[self.__color_fg1], self.hover_mode))
self.__fill_func.append(update_color)
self.__fill_gc.append(g_color)
self.__fill_fc.append(f_color)
self.__fill_hc.append(h_color)
self.__fill_obj.append(obj)
x_n += 1
y_n += 1
def __update_color(self):
n = 0
for i in self.__fill_func:
i(self.__fill_obj[n], self.__fill_gc[n],
self.__fill_fc[n], self.__fill_hc[n])
n += 1
def __init__(self, master=None, root_anim=None, color_type="primary", w=80, h=16, text="Button", color_list: None | dict = None, group: None = None):
set_font()
self.w = max(80, w)
self.h = 16
self.text = text
self.__master = master
if (color_list is not None):
self.color = color_list
if (root_anim == None):
self.root = master.root
else:
self.root = root_anim
self.canvas = tkinter.Canvas(
master, bg=self.color["background"], width=self.w, height=self.h, borderwidth=0, bd=0, highlightcolor=self.color["background"], highlightthickness=0)
self.__draw()
self.__update_color()
self.__bind_event()
self.bind_anim()
if (group is not None):
group._add_checkbox(self)
def pack(self, *args, **kwargs):
self.canvas.pack(*args, **kwargs)
def guid(self, *args, **kwargs):
self.canvas.guid(*args, **kwargs)
def place(self, *args, **kwargs):
self.canvas.place(*args, **kwargs)
def __draw(self):
self.__draw_corner(0, 0, 0, 0)
self.__draw_corner(1, 0, 12, 0)
self.__draw_corner(0, 1, 0, 12)
self.__draw_corner(1, 1, 12, 12)
def update_color(obj, g_color, f_color, h_color):
if (self.ishover == 2):
self.canvas.itemconfig(
obj, fill=h_color)
elif (self.__flash_t <= self.max_flash):
self.canvas.itemconfig(
obj, fill=color_tmpl.mix_color(g_color, f_color, self.hover_mode))
self.__fill_fc.append(self.color[self.__color_fg1])
self.__fill_gc.append(self.color[self.__color_bd])
self.__fill_hc.append(self.color[self.__color_fg2])
self.__fill_func.append(update_color)
self.__fill_obj.append(self.canvas.create_line(
1, 3, 1, 12, width=1, fill=self.color[self.__color_bd]))
self.__fill_fc.append(self.color[self.__color_fg1])
self.__fill_gc.append(self.color[self.__color_bd])
self.__fill_hc.append(self.color[self.__color_fg2])
self.__fill_func.append(update_color)
self.__fill_obj.append(self.canvas.create_line(
3, 1, 12, 1, width=1, fill=self.color[self.__color_fg1]))
self.__fill_fc.append(self.color[self.__color_fg1])
self.__fill_gc.append(self.color[self.__color_bd])
self.__fill_hc.append(self.color[self.__color_fg2])
self.__fill_func.append(update_color)
self.__fill_obj.append(self.canvas.create_line(
13, 3, 13, 12, width=1, fill=self.color[self.__color_fg1]))
self.__fill_fc.append(self.color[self.__color_fg1])
self.__fill_gc.append(self.color[self.__color_bd])
self.__fill_hc.append(self.color[self.__color_fg2])
self.__fill_func.append(update_color)
self.__fill_obj.append(self.canvas.create_line(
3, 13, 12, 13, width=1, fill=self.color[self.__color_fg1]))
self.__fill_fc.append(self.color[self.__color_fg1])
self.__fill_gc.append(self.color["background"])
self.__fill_hc.append(self.color[self.__color_fg2])
self.__fill_func.append(update_color)
self.__fill_obj.append(self.canvas.create_rectangle(
2, 3, 13, 12, width=0, fill=self.color[self.__color_fg2]))
self.__fill_fc.append(self.color[self.__color_fg1])
self.__fill_gc.append(self.color["background"])
self.__fill_hc.append(self.color[self.__color_fg2])
self.__fill_func.append(update_color)
self.__fill_obj.append(self.canvas.create_rectangle(
3, 2, 12, 13, width=0, fill=self.color[self.__color_fg2]))
self.__draw_img(2, 2)
self.__fill_fc.append(self.color[self.__color_fg])
self.__fill_gc.append(self.color["regular_text"])
self.__fill_hc.append("#FFFFFF")
self.__fill_func.append(update_color)
self.__fill_obj.append(
self.canvas.create_text(14+int((self.w-14)/2), 6, text=self.text, font=(use_font, 10)))
def bind_anim(self):
def anim_magictk():
if (self.ishover == 1 and self.__flash_t < self.max_flash*2):
self.__flash_t += (1 if (len(self.root.anim) > 6) else 1)
self.__flash_t = min(self.__flash_t, self.max_flash*2)
self.hover_mode = self.__flash_t/self.max_flash
self.__update_color()
elif (self.ishover == 0 and self.__flash_t > 0):
self.__flash_t -= (1 if (len(self.root.anim) > 6) else 1)
self.__flash_t = max(self.__flash_t, 0)
self.hover_mode = self.__flash_t/self.max_flash
self.__update_color()
# elif (self.__is_hover == 0 and self.__flash_t <= 0):
# if self.__anim_obj_id != -1:
# self.__anim_obj_id = None
def anim_normal(*args):
if (self.ishover == 1 and self.__flash_t < self.max_flash*2):
self.__flash_t += 1
self.hover_mode = self.__flash_t/self.max_flash
self.__update_color()
elif (self.ishover == 0 and self.__flash_t > 0):
self.__flash_t -= 1
self.hover_mode = self.__flash_t/self.max_flash
self.__update_color()
self.root.after(anim_normal, 16)
try:
self.root.anim == 0
except:
self.root.after(anim_normal, 16)
else:
if (anim_magictk not in self.root.anim):
self.root.anim.append(anim_magictk)
self.__anim_obj_id = self.root.anim[-1]
def __bind_event(self):
def press_v(*args):
if (self.ishover == 1):
if (self.disable_unhover == 0):
self.ishover = 0
else:
self.ishover = 1
self.callback(self)
self.__update_color()
self.canvas.bind("<Button-1>", press_v)
def pressrelease_v(*args):
self.__update_color()
self.canvas.bind("<ButtonRelease-1>", pressrelease_v)
class RadioGroup:
value = 1
__g_list = []
def __change(self, btn):
for i in self.__g_list:
self.value = btn._group_id
if (i != btn):
i.ishover = 0
else:
i.ishover = 1
def _add_checkbox(self, cb: Checkbox):
self.__g_list.append(cb)
cb.callback = self.__change
cb._group_id = len(self.__g_list)
cb.max_flash = 3
cb.disable_unhover = 1
if (len(self.__g_list) == 1):
cb.ishover = 1

View File

@ -30,6 +30,7 @@ default_color = {
"regular_text": "#606266",
"secondary_text": "#909399",
"placeholder": "#C0C4CC",
"placeholder_light": "#F5F7FA",
"border_base": "#DCDFE6",
"border_light": "#E4E7ED",
"background": "#FFFFFF"

16
magictk/frame.py Normal file
View File

@ -0,0 +1,16 @@
import tkinter
from tkinter import ttk
try:
import color_tmpl
except ImportError:
from magictk import color_tmpl
class Frame(tkinter.Frame):
color = color_tmpl.default_color
def __init__(self, master, color=None, *args, **kwargs):
self.root = master.root
kwargs["bg"] = self.color["background"]
super().__init__(master, *args, **kwargs)
self.configure()

View File

@ -58,7 +58,6 @@ class ProgressBar:
x_n += 1
y_n += 1
def __init__(self, master=None, root_anim=None, w=200, h=8, colors="primary", color_list: None | dict = None):
self.w = max(200, w)
self.h = 8
@ -67,7 +66,7 @@ class ProgressBar:
if (color_list is not None):
self.color = color_list
if (root_anim == None):
self.__root = master
self.__root = master.root
else:
self.__root = root_anim
@ -94,7 +93,8 @@ class ProgressBar:
self.color["border_light"], "rightside", bgcolor=self.color["background"])
self.__fill_obj["fgbar"] = [
self.canvas.create_rectangle(4, 1, self.__progress_pixel+4, self.h-1, width=0, fill=self.color[self.colors])]
self.__draw_corner(0, 0, 1, 0, self.color[self.colors], "leftside",bgcolor=self.color["background"])
self.__draw_corner(
0, 0, 1, 0, self.color[self.colors], "leftside", bgcolor=self.color["background"])
self.__draw_corner(1, 0, self.__progress_pixel+3, 0,
self.color[self.colors], "rightprog")

Binary file not shown.

309
magictk/select.py Normal file
View File

@ -0,0 +1,309 @@
import json
import tkinter
import sys
from tkinter import ttk
from tkinter import font as tkfont
try:
import color_tmpl
except ImportError:
from magictk import color_tmpl
try:
import photoload
except ImportError:
from magictk import photoload
try:
import submenu
except ImportError:
from magictk import submenu
def set_font():
global use_font
font_family = ["Helvetica Neue", "Helvetica", "PingFang SC", "Hiragino Sans GB",
"Microsoft YaHei",
"微软雅黑",
"Arial", "sans-serif"]
t_family = tkfont.families(root=None, displayof=None)
for i in font_family:
if i in t_family:
use_font = i
break
else:
print("Unknown font")
class Select:
color = color_tmpl.default_color
__fill_obj = []
__fill_func = []
__fill_gc = []
__fill_fc = []
__fill_hc = []
hover_mode = 0.0
__is_hover = 0
__flash_t = 0
max_flash = 6
__anim_obj_id = -1
__color_bd = "border_base"
__color_bg = "background"
__color_fg = "primary"
__color_fg1 = "primary"
__color_fg2 = "background"
text = "Select"
def __draw_corner(self, r_x, r_y, x, y, **kwargs):
border_info = json.loads(photoload.loadres("buttonborder"))
y_n = 0
for i in border_info:
x_n = 0
for j in i:
if (r_x == 0):
px = x+x_n+1
else:
px = x+4-x_n-1
if (r_y == 0):
py = y+y_n+1
else:
py = y+4-y_n-1
if (j < 0):
lcolor = -j
else:
lcolor = j
g_color = color_tmpl.mix_color(
self.color["background"], self.color[self.__color_bd], int((1-lcolor/255)*1000)/1000)
if (j < 0):
f_color = color_tmpl.mix_color(
self.color[self.__color_fg2], self.color[self.__color_fg1], int((1-lcolor/255)*1000)/1000)
else:
f_color = color_tmpl.mix_color(
self.color["background"], self.color[self.__color_fg1], int((1-lcolor/255)*1000)/1000)
if (j < 0):
h_color = color_tmpl.mix_color(
self.color[self.__color_fg2], self.color[self.__color_fg], int((1-lcolor/255)*1000)/1000)
else:
h_color = color_tmpl.mix_color(
self.color["background"], self.color[self.__color_fg], int((1-lcolor/255)*1000)/1000)
obj = self.canvas.create_rectangle(
px, py, px, py, width=0, fill=g_color)
def update_color(obj, g_color, f_color, h_color):
if (self.__is_hover == 2):
self.canvas.itemconfig(
obj, fill=h_color)
else:
self.canvas.itemconfig(
obj, fill=color_tmpl.mix_color(g_color, f_color, self.hover_mode))
self.__fill_func.append(update_color)
self.__fill_gc.append(g_color)
self.__fill_fc.append(f_color)
self.__fill_hc.append(h_color)
self.__fill_obj.append(obj)
x_n += 1
y_n += 1
def __draw_arrow(self, x, y, **kwargs):
border_info = self.__arrow_json[0]
self.__arrow_list = []
y_n = 0
for i in border_info:
x_n = 0
self.__arrow_list.append([])
for j in i:
px = x+x_n+1
py = y+y_n+1
lcolor = j
g_color = color_tmpl.mix_color(
self.color["background"], self.color[self.__color_bd], int((1-lcolor/255)*1000)/1000)
obj = self.canvas.create_rectangle(
px, py, px, py, width=0, fill=g_color)
self.__arrow_list[-1].append(obj)
x_n += 1
y_n += 1
def __update_color(self):
n = 0
for i in self.__fill_func:
i(self.__fill_obj[n], self.__fill_gc[n],
self.__fill_fc[n], self.__fill_hc[n])
n += 1
def __init__(self, master=None, root_anim=None, w=200, h=30, text="Select", color_list: None | dict = None, items=[]):
set_font()
self.__arrow_json = json.loads(photoload.loadres("selectarrow"))
self.items = items
self.w = max(120, w)
self.h = max(30, h)
self.text = text
self.choose = -1
self.__master = master
if (color_list is not None):
self.color = color_list
if (root_anim == None):
self.root = master.root
else:
self.root = root_anim
self.canvas = tkinter.Canvas(
master, bg=self.color["background"], width=self.w, height=self.h, borderwidth=0, bd=0, highlightcolor=self.color["background"], highlightthickness=0)
self.__draw()
self.__update_color()
self.__bind_event()
self.bind_anim()
self.__menuobj = submenu.MenuObjs()
self.__last = 0
for i in self.items:
self.__menuobj.addmenu(i, self.__callback_menu)
def pack(self, *args, **kwargs):
self.canvas.pack(*args, **kwargs)
def guid(self, *args, **kwargs):
self.canvas.guid(*args, **kwargs)
def place(self, *args, **kwargs):
self.canvas.place(*args, **kwargs)
def __draw(self):
self.__draw_corner(0, 0, 0, 0)
self.__draw_corner(1, 0, self.w-4, 0)
self.__draw_corner(0, 1, 0, self.h-5)
self.__draw_corner(1, 1, self.w-4, self.h-5)
def update_color(obj, g_color, f_color, h_color):
if (self.__is_hover == 2):
self.canvas.itemconfig(
obj, fill=h_color)
else:
self.canvas.itemconfig(
obj, fill=color_tmpl.mix_color(g_color, f_color, self.hover_mode))
self.__fill_fc.append(self.color[self.__color_fg1])
self.__fill_gc.append(self.color[self.__color_bd])
self.__fill_hc.append(self.color[self.__color_fg])
self.__fill_func.append(update_color)
self.__fill_obj.append(self.canvas.create_line(
1, 5, 1, self.h-5, width=1, fill=self.color[self.__color_bd]))
self.__fill_fc.append(self.color[self.__color_fg1])
self.__fill_gc.append(self.color[self.__color_bd])
self.__fill_hc.append(self.color[self.__color_fg])
self.__fill_func.append(update_color)
self.__fill_obj.append(self.canvas.create_line(
5, 1, self.w-4, 1, width=1, fill=self.color[self.__color_fg1]))
self.__fill_fc.append(self.color[self.__color_fg1])
self.__fill_gc.append(self.color[self.__color_bd])
self.__fill_hc.append(self.color[self.__color_fg])
self.__fill_func.append(update_color)
self.__fill_obj.append(self.canvas.create_line(
self.w-1, 5, self.w-1, self.h-5, width=1, fill=self.color[self.__color_fg1]))
self.__fill_fc.append(self.color[self.__color_fg1])
self.__fill_gc.append(self.color[self.__color_bd])
self.__fill_hc.append(self.color[self.__color_fg])
self.__fill_func.append(update_color)
self.__fill_obj.append(self.canvas.create_line(
5, self.h-2, self.w-4, self.h-2, width=1, fill=self.color[self.__color_fg1]))
self.__fill_fc.append(self.color[self.__color_fg2])
self.__fill_gc.append(self.color["background"])
self.__fill_hc.append(self.color[self.__color_fg2])
self.__fill_func.append(update_color)
self.__fill_obj.append(self.canvas.create_rectangle(
2, 5, self.w-1, self.h-5, width=0, fill=self.color[self.__color_fg2]))
self.__fill_fc.append(self.color[self.__color_fg2])
self.__fill_gc.append(self.color["background"])
self.__fill_hc.append(self.color[self.__color_fg2])
self.__fill_func.append(update_color)
self.__fill_obj.append(self.canvas.create_rectangle(
5, 2, self.w-4, self.h-2, width=0, fill=self.color[self.__color_fg2]))
self.__text_obj = self.canvas.create_text(
20, int(self.h/2), text=self.text, font=(use_font, 10), justify="left")
self.__fill_fc.append(self.color["placeholder"])
self.__fill_gc.append(self.color["regular_text"])
self.__fill_hc.append(self.color["placeholder"])
self.__fill_func.append(update_color)
self.__fill_obj.append(self.__text_obj)
self.canvas.moveto(self.__text_obj, 16, self.h//2-10)
self.__draw_arrow(self.w-30, (self.h-12)//2)
def bind_anim(self):
def update_arrow():
datas = self.__arrow_json[self.__flash_t]
y_n = 0
for i in datas:
x_n = 0
for j in i:
self.canvas.itemconfigure(self.__arrow_list[y_n][x_n], fill=(color_tmpl.mix_color(
self.color["background"], self.color[self.__color_bd], int((1-j/255)*1000)/1000)))
x_n += 1
y_n += 1
def anim_magictk():
if (self.__is_hover == 1 and self.__flash_t < self.max_flash):
self.__flash_t += (1 if (len(self.root.anim) > 6) else 1)
self.__flash_t = min(self.__flash_t, self.max_flash)
self.hover_mode = self.__flash_t/self.max_flash
self.__update_color()
elif (self.__is_hover == 0 and self.__flash_t > 0):
self.__flash_t -= (1 if (len(self.root.anim) > 6) else 1)
self.__flash_t = max(self.__flash_t, 0)
self.hover_mode = self.__flash_t/self.max_flash
self.__update_color()
update_arrow()
# elif (self.__is_hover == 0 and self.__flash_t <= 0):
# if self.__anim_obj_id != -1:
# self.__anim_obj_id = None
def anim_normal(*args):
if (self.__is_hover == 1 and self.__flash_t < self.max_flash):
self.__flash_t += 1
self.hover_mode = self.__flash_t/self.max_flash
self.__update_color()
elif (self.__is_hover == 0 and self.__flash_t > 0):
self.__flash_t -= 1
self.hover_mode = self.__flash_t/self.max_flash
self.__update_color()
self.root.after(anim_normal, 16)
update_arrow()
try:
self.root.anim == 0
except:
self.root.after(anim_normal, 16)
else:
if (anim_magictk not in self.root.anim):
self.root.anim.append(anim_magictk)
self.__anim_obj_id = self.root.anim[-1]
def __callback_menu(self, obj, ids):
self.__menuobj.menu_effect[self.__last] = {}
self.__menuobj.menu_effect[ids] = {
"fill": self.color["primary"], "font": (obj.font[0], obj.font[1], "bold")}
self.__last = ids
self.canvas.itemconfigure(self.__text_obj, text=self.items[ids])
self.canvas.moveto(self.__text_obj, 16, self.h//2-10)
def __bind_event(self):
def closecallback(obj):
self.__is_hover = 0
def pressrelease_v(event):
if (self.__is_hover == 1):
self.menus.close()
else:
self.__is_hover = 1
self.menus = submenu.Menu(
x=event.x_root-event.x,
y=event.y_root-event.y+self.h+4,
w=self.w,
h=min(8*34, len(self.items)*34+12+4),
root=self.root, menuobj=self.__menuobj, closecallback=closecallback
)
self.__update_color()
self.canvas.bind("<ButtonRelease-1>", pressrelease_v)

265
magictk/submenu.py Normal file
View File

@ -0,0 +1,265 @@
import json
import tkinter
import sys
from tkinter import ttk
from tkinter import font as tkfont
try:
import color_tmpl
except ImportError:
from magictk import color_tmpl
try:
import photoload
except ImportError:
from magictk import photoload
transcolor = "#41342F"
usetrans = sys.platform.startswith('win')
def set_font():
global use_font
font_family = ["Helvetica Neue", "Helvetica", "PingFang SC", "Hiragino Sans GB",
"Microsoft YaHei",
"微软雅黑",
"Arial", "sans-serif"]
t_family = tkfont.families(root=None, displayof=None)
for i in font_family:
if i in t_family:
use_font = i
break
else:
print("Unknown font")
class MenuObjs:
def __init__(self):
self.menu_lst = []
self.menu_func = []
self.menu_effect = []
def first_action(self, menuobj):
pass
def addmenu(self, name, func, effect={}):
self.menu_lst.append(name)
self.menu_func.append(func)
self.menu_effect.append(effect)
class Menu:
__relh = 0
__color_bd = "border_base"
__color_bg = "background"
__color_fg = "primary"
__color_fg1 = "primary_light"
__color_fg2 = "primary_light2"
color = color_tmpl.default_color
__close_mode = 0
__last_highlight = 0
__y_move = 0
___last_move = 1
___last_highlight = 0
ht = 12
lt = 22
ft = 34
def __anim(self, *args):
if (self.__close_mode == 0):
if (self.__relh != self.h):
if (self.h-self.__relh <= 1):
self.__relh = self.h
elif (self.h-self.__relh > 32):
self.__relh += 32
else:
self.__relh += (self.h-self.__relh) >> 1
self.toplevel.geometry(
f"{self.w}x{self.__relh}+{self.x}+{self.y}")
elif self.__close_mode == 1:
if (self.__relh != 0):
if (self.__relh-0 <= 1):
self.toplevel.destroy()
self.__close_mode = 2
return
elif (self.__relh-0 > 32):
self.__relh -= 32
else:
self.__relh -= (self.__relh-0) >> 1
self.toplevel.geometry(
f"{self.w}x{self.__relh}+{self.x}+{self.y}")
else:
return -1
if (self.___last_move != self.__y_move):
n = 0
for i in self.__itemsf:
self.canvas.moveto(i, 24, n*self.ft+self.ht +
self.__y_move+(self.ft-self.font[1]*2.5)//2)
n += 1
n = 0
for i in self.__items:
self.canvas.moveto(i, 2, n*self.ft+self.ht-4 +
self.__y_move)
n += 1
self.___last_move = self.__y_move
n = 0
for i in self.menuobj.menu_effect:
if (len(i) != 0):
self.canvas.itemconfigure(
self.__itemsf[n], justify=tkinter.LEFT, **i)
self.canvas.moveto(self.__itemsf[n], 24, n*self.ft+self.ht +
self.__y_move+(self.ft-self.font[1]*2.5)//2)
else:
self.canvas.itemconfigure(
self.__itemsf[n], justify=tkinter.LEFT, fill=self.color["regular_text"], font=self.font)
self.canvas.moveto(self.__itemsf[n], 24, n*self.ft+self.ht +
self.__y_move+(self.ft-self.font[1]*2.5)//2)
n += 1
def __mouse_move(self, event: tkinter.Event):
y = event.y
self.__last_highlight = max(
-1, min(len(self.__items), int((y-self.ht-self.__y_move)//self.ft)))
if (self.__last_highlight == -1 or self.__last_highlight >= len(self.__items)):
if (self.___last_highlight != -2):
self.canvas.itemconfig(
self.__items[self.___last_highlight], fill=self.color["background"])
self.___last_highlight = -2
elif (self.___last_highlight != self.__last_highlight):
self.canvas.itemconfig(
self.__items[self.__last_highlight], fill=self.color["placeholder_light"])
self.canvas.itemconfig(
self.__items[self.___last_highlight], fill=self.color["background"])
self.___last_highlight = self.__last_highlight
def close(self, *args):
self.__close_mode = 1
if (self.__closecallback is not None):
self.__closecallback(self)
def __init__(self, root, menuobj: MenuObjs, w=200, h=300, x=100, y=300, color_list: None | dict = None, closeonleave=True, fontsize=10, closecallback=None):
set_font()
self.__closecallback = closecallback
self.font = (use_font, fontsize)
self.__items = []
self.__itemsf = []
self.menuobj = menuobj
self.w = w
self.h = h
self.x = x
self.y = y
if (color_list is not None):
self.color = color_list
self.toplevel = tkinter.Toplevel(bg=transcolor)
self.toplevel.wm_attributes('-topmost', True)
self.toplevel.overrideredirect(True)
self.toplevel.geometry(f"{self.w}x{self.__relh}+{self.x}+{self.y}")
if (usetrans):
self.toplevel.wm_attributes('-transparentcolor', transcolor)
self.root = root
self.canvas = tkinter.Canvas(
self.toplevel, bg=self.color["background"], highlightthickness=0, width=self.w+1, height=self.h+1)
self.canvas.place(x=-1, y=-1)
self.root.anim.append(self.__anim)
self.toplevel.focus()
self.__draw_menu()
self.__draws()
if (closeonleave):
self.toplevel.bind("<FocusOut>", self.close)
if (not usetrans):
self.toplevel.bind("<Leave>", self.close)
self.canvas.bind("<Motion>", self.__mouse_move)
self.__bind_scroll()
self.canvas.bind("<ButtonRelease-1>", self.__click)
self.toplevel.bind_all("<Escape>", self.close)
self.toplevel.bind_all("<Return>", self.__click)
def __draw_menu(self):
n = 0
for i in self.menuobj.menu_lst:
self.__items.append(self.canvas.create_rectangle(
2, n*self.ft+self.ht, self.w, (n+1)*self.ft+self.ht, fill=self.color["background"], width=0))
self.__itemsf.append(self.canvas.create_text(
10, n*self.ft+self.ht, text=i, font=self.font, justify=tkinter.LEFT, fill=self.color["regular_text"]))
n += 1
def __draw_corner(self, r_x, r_y, x, y, **kwargs):
border_info = json.loads(photoload.loadres("menuborder"))
y_n = 0
for i in border_info:
x_n = 0
for j in i:
if (r_x == 0):
px = x+x_n+1
else:
px = x+4-x_n-1
if (r_y == 0):
py = y+y_n+1
else:
py = y+4-y_n-1
if (j < 0):
lcolor = -j
else:
lcolor = j
if (lcolor == 255):
x_n += 1
continue
if (j < 0):
if (usetrans):
g_color = transcolor
else:
g_color = self.color["background"]
else:
g_color = color_tmpl.mix_color(
self.color["background"], self.color[self.__color_bd], int((1-lcolor/255)*1000)/1000)
self.canvas.create_rectangle(
px, py, px, py, width=0, fill=g_color)
x_n += 1
y_n += 1
def __draws(self):
self.__draw_corner(0, 0, 0, 0)
self.__draw_corner(1, 0, self.w-4+1, 0)
self.__draw_corner(0, 1, 0, self.h-4+1)
self.__draw_corner(1, 1, self.w-4+1, self.h-4+1)
self.canvas.create_line(
1, 5, 1, self.h-3, width=1, fill=self.color[self.__color_bd])
self.canvas.create_line(
5, 1, self.w-3, 1, width=1, fill=self.color[self.__color_bd])
self.canvas.create_line(
self.w, 5, self.w, self.h-3, width=1, fill=self.color[self.__color_bd])
self.canvas.create_line(
5, self.h, self.w-3, self.h, width=1, fill=self.color[self.__color_bd])
def __bind_scroll(self):
def scrollwheel(event: tkinter.Event, setdelta=None):
if (setdelta is None):
delta = event.delta
else:
delta = setdelta
if sys.platform.startswith('win'):
delta //= 120
if delta > 0:
self.__y_move = min(0, self.__y_move+delta)
else:
self.__y_move = max(
-max(0, len(self.__items)*self.ft+self.ht-self.h), self.__y_move+delta)
if sys.platform.startswith('win'):
self.toplevel.bind_all("<MouseWheel>", scrollwheel)
elif sys.platform.startswith('darwin'):
self.toplevel.bind_all("<MouseWheel>", scrollwheel)
else:
self.toplevel.bind_all(
"<Button-4>", lambda event: scrollwheel(event, 8))
self.toplevel.bind_all(
"<Button-5>", lambda event: scrollwheel(event, -8))
def __click(self, event):
click_item = max(
-1, min(len(self.__items), int((event.y-self.ht-self.__y_move)//self.ft)))
if (click_item == -1 or self.__last_highlight >= len(self.__items)):
return
self.close()
self.menuobj.menu_func[click_item](self, click_item)

View File

@ -22,6 +22,7 @@ try:
import photoload
except ImportError:
from magictk import photoload
import sys
WIN_INF = -10000
@ -152,6 +153,7 @@ class Window(ttk.Frame):
titles.bind("<ButtonRelease-1>", special_move)
def __init__(self, w=500, h=350, title="MagicTk", color_list: None | dict = None) -> None:
self.root = self
self.title = title
self.w = w
self.h = h
@ -196,9 +198,13 @@ class Window(ttk.Frame):
delta_t = time.time()-t_start
if (delta_t > 0.02): # flash animation
t_start = time.time()
n = 0
for i in self.anim:
if (i is not None):
i()
retn = i()
if (retn == -1):
self.anim[n] = None
n += 1
self.anim = [i for i in self.anim if i is not None]
else:
pass

122
photo2/res/checkbox.json Normal file
View File

@ -0,0 +1,122 @@
[
[
255,
255,
255,
255,
255,
255,
255,
255,
224,
255
],
[
255,
255,
255,
255,
255,
255,
255,
255,
224,
255
],
[
255,
255,
255,
255,
255,
255,
255,
201,
0,
193
],
[
255,
255,
255,
255,
255,
255,
201,
0,
158,
255
],
[
255,
180,
255,
255,
255,
201,
0,
158,
255,
255
],
[
193,
0,
170,
255,
201,
0,
158,
255,
224,
255
],
[
255,
189,
0,
134,
0,
158,
255,
255,
224,
255
],
[
255,
255,
166,
0,
112,
255,
255,
255,
224,
255
],
[
255,
255,
255,
146,
255,
255,
255,
255,
224,
255
],
[
255,
255,
255,
255,
255,
255,
255,
255,
224,
255
]
]

View File

@ -0,0 +1,10 @@
[
[
98,
243
],
[
243,
-255
]
]

View File

@ -0,0 +1,26 @@
[
[
-1,
-1,
64,
14
],
[
-1,
34,
155,
245
],
[
64,
155,
255,
255
],
[
14,
245,
255,
255
]
]

854
photo2/res/selectarrow.json Normal file
View File

@ -0,0 +1,854 @@
[
[
[
255,
255,
255,
255,
255,
255,
255,
255,
255,
255
],
[
255,
255,
255,
255,
255,
255,
255,
255,
255,
255
],
[
180,
255,
255,
255,
255,
255,
255,
255,
255,
180
],
[
20,
100,
255,
255,
255,
255,
255,
255,
100,
20
],
[
255,
0,
60,
255,
255,
255,
255,
60,
0,
255
],
[
255,
255,
0,
20,
255,
255,
10,
0,
255,
255
],
[
255,
255,
255,
0,
0,
0,
0,
255,
255,
255
],
[
255,
255,
255,
255,
0,
0,
255,
255,
255,
255
],
[
255,
255,
255,
255,
255,
255,
255,
255,
255,
255
],
[
255,
255,
255,
255,
255,
255,
255,
255,
255,
255
]
],
[
[
255,
255,
255,
255,
255,
255,
255,
255,
255,
255
],
[
200,
255,
255,
255,
255,
255,
255,
255,
255,
255
],
[
170,
190,
255,
255,
255,
255,
255,
255,
255,
255
],
[
120,
70,
255,
255,
255,
255,
255,
255,
255,
255
],
[
180,
20,
110,
255,
255,
255,
255,
255,
255,
255
],
[
255,
20,
90,
255,
255,
255,
255,
200,
170,
210
],
[
255,
180,
10,
170,
200,
140,
50,
30,
110,
200
],
[
255,
255,
10,
0,
0,
10,
110,
190,
255,
255
],
[
255,
255,
100,
30,
110,
200,
255,
255,
255,
255
],
[
255,
255,
255,
255,
255,
255,
255,
255,
255,
255
]
],
[
[
255,
255,
180,
255,
255,
255,
255,
255,
255,
255
],
[
255,
140,
90,
255,
255,
255,
255,
255,
255,
255
],
[
255,
130,
20,
255,
255,
255,
255,
255,
255,
255
],
[
255,
130,
20,
255,
255,
255,
255,
255,
255,
255
],
[
255,
130,
20,
255,
255,
255,
255,
255,
255,
255
],
[
255,
130,
20,
255,
255,
255,
255,
255,
255,
255
],
[
255,
90,
20,
255,
255,
255,
255,
255,
255
],
[
255,
255,
0,
20,
20,
20,
20,
20,
20,
180
],
[
255,
255,
255,
90,
130,
130,
130,
130,
130,
255
],
[
255,
255,
255,
255,
255,
255,
255,
255,
255,
255
]
],
[
[
255,
255,
180,
20,
255,
255,
255,
255,
255,
255
],
[
255,
255,
255,
100,
0,
255,
255,
255,
255,
255
],
[
255,
255,
255,
255,
60,
0,
255,
255,
255,
255
],
[
255,
255,
255,
255,
255,
20,
0,
255,
255,
255
],
[
255,
255,
255,
255,
255,
255,
0,
0,
255,
255
],
[
255,
255,
255,
255,
255,
255,
0,
0,
255,
255
],
[
255,
255,
255,
255,
255,
10,
0,
255,
255,
255
],
[
255,
255,
255,
255,
60,
0,
255,
255,
255,
255
],
[
255,
255,
255,
100,
0,
255,
255,
255,
255,
255
],
[
255,
255,
180,
20,
255,
255,
255,
255,
255,
255
]
],
[
[
255,
255,
255,
255,
255,
255,
255,
255,
255,
255
],
[
255,
255,
255,
90,
130,
130,
130,
130,
130,
255
],
[
255,
255,
0,
20,
20,
20,
20,
20,
20,
180
],
[
255,
90,
20,
255,
255,
255,
255,
255,
255
],
[
255,
130,
20,
255,
255,
255,
255,
255,
255,
255
],
[
255,
130,
20,
255,
255,
255,
255,
255,
255,
255
],
[
255,
130,
20,
255,
255,
255,
255,
255,
255,
255
],
[
255,
130,
20,
255,
255,
255,
255,
255,
255,
255
],
[
255,
140,
90,
255,
255,
255,
255,
255,
255,
255
],
[
255,
255,
180,
255,
255,
255,
255,
255,
255,
255
]
],
[
[
255,
255,
255,
255,
255,
255,
255,
255,
255,
255
],
[
255,
255,
100,
30,
110,
200,
255,
255,
255,
255
],
[
255,
255,
10,
0,
0,
10,
110,
190,
255,
255
],
[
255,
180,
10,
170,
200,
140,
50,
30,
110,
200
],
[
255,
20,
90,
255,
255,
255,
255,
200,
170,
210
],
[
180,
20,
110,
255,
255,
255,
255,
255,
255,
255
],
[
120,
70,
255,
255,
255,
255,
255,
255,
255,
255
],
[
170,
190,
255,
255,
255,
255,
255,
255,
255,
255
],
[
200,
255,
255,
255,
255,
255,
255,
255,
255,
255
],
[
255,
255,
255,
255,
255,
255,
255,
255,
255,
255
]
],
[
[
255,
255,
255,
255,
255,
255,
255,
255,
255,
255
],
[
255,
255,
255,
255,
255,
255,
255,
255,
255,
255
],
[
255,
255,
255,
255,
0,
0,
255,
255,
255,
255
],
[
255,
255,
255,
0,
0,
0,
0,
255,
255,
255
],
[
255,
255,
0,
20,
255,
255,
10,
0,
255,
255
],
[
255,
0,
60,
255,
255,
255,
255,
60,
0,
255
],
[
20,
100,
255,
255,
255,
255,
255,
255,
100,
20
],
[
180,
255,
255,
255,
255,
255,
255,
255,
255,
180
],
[
255,
255,
255,
255,
255,
255,
255,
255,
255,
255
],
[
255,
255,
255,
255,
255,
255,
255,
255,
255,
255
]
]
]