优化checkbox

This commit is contained in:
cxykevin 2024-04-12 22:25:57 +08:00
parent 19ee0bb25e
commit d13aaf5278
2 changed files with 147 additions and 167 deletions

View File

@ -94,7 +94,7 @@ class Button:
self._color_fg3 = "primary_light2" self._color_fg3 = "primary_light2"
self._color_text = None self._color_text = None
self.w = max(30, w) self.w = max(30, w)
self.h = max(30, h) self.h = h
self.text = text self.text = text
self.__master = master self.__master = master
if (color_list is not None): if (color_list is not None):
@ -109,7 +109,7 @@ class Button:
self._draw() self._draw()
self._update_color() self._update_color()
self.__bind_event() self._bind_event()
self.bind_anim() self.bind_anim()
def pack(self, *args, **kwargs): def pack(self, *args, **kwargs):
@ -220,7 +220,7 @@ class Button:
self.root.anim.append(anim_magictk) self.root.anim.append(anim_magictk)
self._anim_obj_id = self.root.anim[-1] self._anim_obj_id = self.root.anim[-1]
def __bind_event(self): def _bind_event(self):
def enter_v(*args): def enter_v(*args):
self.bind_anim() self.bind_anim()
if (self._is_hover == 0): if (self._is_hover == 0):
@ -304,14 +304,15 @@ class ButtonFill(Button):
x_n += 1 x_n += 1
y_n += 1 y_n += 1
def __init__(self, master=None, root_anim=None, color_type="primary", w=80, h=30, text="Button", func=lambda s: print("Press"), color_list: None | dict = None): def __init__(self, master=None, root_anim=None, color_type="primary", w=80, h=30, text="Button", func=lambda s: print("Press"), color_list: None | dict = None, _dis_color=None):
self._color_bd = color_type if (_dis_color is None):
self._color_bg = color_type self._color_bd = color_type
self._color_bg1 = color_type self._color_bg = color_type
self._color_fg = color_type+"_light3" self._color_bg1 = color_type
self._color_fg1 = color_type+"_dark" self._color_fg = color_type+"_light3"
self._color_fg2 = color_type+"_light3" self._color_fg1 = color_type+"_dark"
self._color_fg3 = color_type+"_dark" self._color_fg2 = color_type+"_light3"
self._color_text = "#FFFFFF" self._color_fg3 = color_type+"_dark"
self._color_text = "#FFFFFF"
super().__init__(master=master, root_anim=root_anim, w=w, h=h, super().__init__(master=master, root_anim=root_anim, w=w, h=h,
text=text, color_list=color_list, func=func, _set_defaultcolor=True) text=text, color_list=color_list, func=func, _set_defaultcolor=True)

View File

@ -1,56 +1,25 @@
import json import json
import tkinter import tkinter
from tkinter import ttk from tkinter import ttk
from tkinter import font as tkfont from magictk import color_tmpl
try: from magictk import photoload
import color_tmpl from magictk import fontconfig
except ImportError: from magictk import button
from magictk import color_tmpl
try:
import photoload
except ImportError:
from magictk import photoload
def set_font(): class Checkbox(button.ButtonFill):
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 hover_mode = 0.0
ishover = 0 ishover = 0
__flash_t = 0 _flash_t = 0
max_flash = 4 max_flash = 4
__anim_obj_id = -1 _anim_obj_id = -1
checked = False checked = False
text = "ButtonFill" text = "ButtonFill"
_group_id = 0 _group_id = 0
disable_unhover = 0 disable_unhover = 0
def callback(*args): return None def callback(*args): return None
def __draw_corner(self, r_x, r_y, x, y, **kwargs): def _draw_corner(self, r_x, r_y, x, y, **kwargs):
border_info = json.loads(photoload.loadres("checkboxborder")) border_info = json.loads(photoload.loadres("checkboxborder"))
y_n = 0 y_n = 0
for i in border_info: for i in border_info:
@ -70,22 +39,22 @@ class Checkbox:
lcolor = 255-j lcolor = 255-j
if (j < 0): if (j < 0):
g_color = color_tmpl.mix_color( g_color = color_tmpl.mix_color(
self.color[self.__color_bg], self.color[self.__color_bd], int((1-lcolor/255)*1000)/1000) self.color[self._color_bg], self.color[self._color_bd], int((1-lcolor/255)*1000)/1000)
else: else:
g_color = color_tmpl.mix_color( g_color = color_tmpl.mix_color(
self.color["background"], self.color[self.__color_bd], int((1-lcolor/255)*1000)/1000) self.color["background"], self.color[self._color_bd], int((1-lcolor/255)*1000)/1000)
if (j < 0): if (j < 0):
f_color = color_tmpl.mix_color( f_color = color_tmpl.mix_color(
self.color[self.__color_fg1], self.color[self.__color_fg1], int((1-lcolor/255)*1000)/1000) self.color[self._color_fg1], self.color[self._color_fg1], int((1-lcolor/255)*1000)/1000)
else: else:
f_color = color_tmpl.mix_color( f_color = color_tmpl.mix_color(
self.color["background"], self.color[self.__color_fg1], int((1-lcolor/255)*1000)/1000) self.color["background"], self.color[self._color_fg1], int((1-lcolor/255)*1000)/1000)
if (j < 0): if (j < 0):
h_color = color_tmpl.mix_color( h_color = color_tmpl.mix_color(
self.color[self.__color_fg2], self.color[self.__color_fg2], int((1-lcolor/255)*1000)/1000) self.color[self._color_fg2], self.color[self._color_fg2], int((1-lcolor/255)*1000)/1000)
else: else:
h_color = color_tmpl.mix_color( h_color = color_tmpl.mix_color(
self.color["background"], self.color[self.__color_fg2], int((1-lcolor/255)*1000)/1000) self.color["background"], self.color[self._color_fg2], int((1-lcolor/255)*1000)/1000)
obj = self.canvas.create_rectangle( obj = self.canvas.create_rectangle(
px, py, px, py, width=0, fill=g_color) px, py, px, py, width=0, fill=g_color)
@ -94,19 +63,19 @@ class Checkbox:
if (self.ishover == 2): if (self.ishover == 2):
self.canvas.itemconfig( self.canvas.itemconfig(
obj, fill=h_color) obj, fill=h_color)
elif (self.__flash_t <= self.max_flash): elif (self._flash_t <= self.max_flash):
self.canvas.itemconfig( self.canvas.itemconfig(
obj, fill=color_tmpl.mix_color(g_color, f_color, self.hover_mode)) obj, fill=color_tmpl.mix_color(g_color, f_color, self.hover_mode))
self.__fill_func.append(update_color) self._fill_func.append(update_color)
self.__fill_gc.append(g_color) self._fill_gc.append(g_color)
self.__fill_fc.append(f_color) self._fill_fc.append(f_color)
self.__fill_hc.append(h_color) self._fill_hc.append(h_color)
self.__fill_obj.append(obj) self._fill_obj.append(obj)
x_n += 1 x_n += 1
y_n += 1 y_n += 1
def __draw_img(self, x, y, **kwargs): def _draw_img(self, x, y, **kwargs):
border_info = json.loads(photoload.loadres("checkbox")) border_info = json.loads(photoload.loadres("checkbox"))
y_n = 0 y_n = 0
for i in border_info: for i in border_info:
@ -118,58 +87,68 @@ class Checkbox:
lcolor = 255+j lcolor = 255+j
else: else:
lcolor = 255-j lcolor = 255-j
g_color = self.color[self.__color_fg] g_color = self.color[self._color_fg]
f_color = color_tmpl.mix_color( f_color = color_tmpl.mix_color(
self.color["background"], self.color[self.__color_fg], int((1-lcolor/255)*1000)/1000) self.color["background"], self.color[self._color_fg], int((1-lcolor/255)*1000)/1000)
h_color = color_tmpl.mix_color( h_color = color_tmpl.mix_color(
self.color["background"], self.color[self.__color_fg2], int((1-lcolor/255)*1000)/1000) self.color["background"], self.color[self._color_fg2], int((1-lcolor/255)*1000)/1000)
obj = self.canvas.create_rectangle( obj = self.canvas.create_rectangle(
px, py, px, py, width=0, fill=g_color) px, py, px, py, width=0, fill=g_color)
def update_color(obj, g_color, f_color, h_color): def update_color(obj, g_color, f_color, h_color):
if (self.__flash_t > self.max_flash): if (self._flash_t > self.max_flash):
self.canvas.itemconfig( self.canvas.itemconfig(
obj, fill=color_tmpl.mix_color(g_color, f_color, (self.__flash_t-self.max_flash)/self.max_flash)) obj, fill=color_tmpl.mix_color(g_color, f_color, (self._flash_t-self.max_flash)/self.max_flash))
else: else:
self.canvas.itemconfig( self.canvas.itemconfig(
obj, fill=color_tmpl.mix_color(self.color["background"], self.color[self.__color_fg1], self.hover_mode)) 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_func.append(update_color)
self.__fill_gc.append(g_color) self._fill_gc.append(g_color)
self.__fill_fc.append(f_color) self._fill_fc.append(f_color)
self.__fill_hc.append(h_color) self._fill_hc.append(h_color)
self.__fill_obj.append(obj) self._fill_obj.append(obj)
x_n += 1 x_n += 1
y_n += 1 y_n += 1
def __update_color(self): def _update_color(self):
n = 0 n = 0
for i in self.__fill_func: for i in self._fill_func:
i(self.__fill_obj[n], self.__fill_gc[n], i(self._fill_obj[n], self._fill_gc[n],
self.__fill_fc[n], self.__fill_hc[n]) self._fill_fc[n], self._fill_hc[n])
n += 1 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): 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() global use_font
self.w = max(80, w) use_font = fontconfig.getfont()
self.h = 16 self._color_bd = "border_base"
self.text = text self._color_bg = "background"
self.__master = master self._color_fg = "primary"
if (color_list is not None): self._color_fg1 = "primary"
self.color = color_list self._color_fg2 = "primary_dark"
if (root_anim == None): super().__init__(master=master, root_anim=root_anim, w=w, h=h,
self.root = master.root text=text, color_list=color_list, color_type=color_type, _dis_color=True)
else:
self.root = root_anim
self.canvas = tkinter.Canvas( # self.w = max(80, w)
master, bg=self.color["background"], width=self.w, height=self.h, borderwidth=0, bd=0, highlightcolor=self.color["background"], highlightthickness=0) # self.h = 16
# self.text = text
# self._fill_func = []
# 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.__draw() # self.canvas = tkinter.Canvas(
self.__update_color() # master, bg=self.color["background"], width=self.w, height=self.h, borderwidth=0, bd=0, highlightcolor=self.color["background"], highlightthickness=0)
self.__bind_event()
self.bind_anim() # self._draw()
# self.__update_color()
# self.__bind_event()
# self.bind_anim()
if (group is not None): if (group is not None):
group._add_checkbox(self) group._add_checkbox(self)
@ -183,91 +162,90 @@ class Checkbox:
def place(self, *args, **kwargs): def place(self, *args, **kwargs):
self.canvas.place(*args, **kwargs) self.canvas.place(*args, **kwargs)
def __draw(self): def _draw(self):
self.__draw_corner(0, 0, 0, 0) self._draw_corner(0, 0, 0, 0)
self.__draw_corner(1, 0, 12, 0) self._draw_corner(1, 0, 12, 0)
self.__draw_corner(0, 1, 0, 12) self._draw_corner(0, 1, 0, 12)
self.__draw_corner(1, 1, 12, 12) self._draw_corner(1, 1, 12, 12)
def update_color(obj, g_color, f_color, h_color): def update_color(obj, g_color, f_color, h_color):
if (self.ishover == 2): if (self.ishover == 2):
self.canvas.itemconfig( self.canvas.itemconfig(
obj, fill=h_color) obj, fill=h_color)
elif (self.__flash_t <= self.max_flash): elif (self._flash_t <= self.max_flash):
self.canvas.itemconfig( self.canvas.itemconfig(
obj, fill=color_tmpl.mix_color(g_color, f_color, self.hover_mode)) obj, fill=color_tmpl.mix_color(g_color, f_color, self.hover_mode))
self.__fill_fc.append(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_gc.append(self.color[self._color_bd])
self.__fill_hc.append(self.color[self.__color_fg2]) self._fill_hc.append(self.color[self._color_fg2])
self.__fill_func.append(update_color) self._fill_func.append(update_color)
self.__fill_obj.append(self.canvas.create_line( self._fill_obj.append(self.canvas.create_line(
1, 3, 1, 12, width=1, fill=self.color[self.__color_bd])) 1, 3, 1, 12, width=1, fill=self.color[self._color_bd]))
self.__fill_fc.append(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_gc.append(self.color[self._color_bd])
self.__fill_hc.append(self.color[self.__color_fg2]) self._fill_hc.append(self.color[self._color_fg2])
self.__fill_func.append(update_color) self._fill_func.append(update_color)
self.__fill_obj.append(self.canvas.create_line( self._fill_obj.append(self.canvas.create_line(
3, 1, 12, 1, width=1, fill=self.color[self.__color_fg1])) 3, 1, 12, 1, width=1, fill=self.color[self._color_fg1]))
self.__fill_fc.append(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_gc.append(self.color[self._color_bd])
self.__fill_hc.append(self.color[self.__color_fg2]) self._fill_hc.append(self.color[self._color_fg2])
self.__fill_func.append(update_color) self._fill_func.append(update_color)
self.__fill_obj.append(self.canvas.create_line( self._fill_obj.append(self.canvas.create_line(
13, 3, 13, 12, width=1, fill=self.color[self.__color_fg1])) 13, 3, 13, 12, width=1, fill=self.color[self._color_fg1]))
self.__fill_fc.append(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_gc.append(self.color[self._color_bd])
self.__fill_hc.append(self.color[self.__color_fg2]) self._fill_hc.append(self.color[self._color_fg2])
self.__fill_func.append(update_color) self._fill_func.append(update_color)
self.__fill_obj.append(self.canvas.create_line( self._fill_obj.append(self.canvas.create_line(
3, 13, 12, 13, width=1, fill=self.color[self.__color_fg1])) 3, 13, 12, 13, width=1, fill=self.color[self._color_fg1]))
self.__fill_fc.append(self.color[self.__color_fg1]) self._fill_fc.append(self.color[self._color_fg])
self.__fill_gc.append(self.color["background"]) self._fill_gc.append(self.color["background"])
self.__fill_hc.append(self.color[self.__color_fg2]) self._fill_hc.append(self.color[self._color_fg2])
self.__fill_func.append(update_color) self._fill_func.append(update_color)
self.__fill_obj.append(self.canvas.create_rectangle( self._fill_obj.append(self.canvas.create_rectangle(
2, 3, 13, 12, width=0, fill=self.color[self.__color_fg2])) 2, 3, 13, 12, width=0, fill=self.color[self._color_fg2]))
self.__fill_fc.append(self.color[self.__color_fg1]) self._fill_fc.append(self.color[self._color_fg])
self.__fill_gc.append(self.color["background"]) self._fill_gc.append(self.color["background"])
self.__fill_hc.append(self.color[self.__color_fg2]) self._fill_hc.append(self.color[self._color_fg2])
self.__fill_func.append(update_color) self._fill_func.append(update_color)
self.__fill_obj.append(self.canvas.create_rectangle( self._fill_obj.append(self.canvas.create_rectangle(
3, 2, 12, 13, width=0, fill=self.color[self.__color_fg2])) 3, 2, 12, 13, width=0, fill=self.color[self._color_fg2]))
self.__draw_img(2, 2) self._draw_img(2, 2)
self.__fill_fc.append(self.color[self.__color_fg]) self._fill_fc.append(self.color[self._color_fg])
self.__fill_gc.append(self.color["regular_text"]) self._fill_gc.append(self.color["regular_text"])
self.__fill_hc.append("#FFFFFF") self._fill_hc.append("#FFFFFF")
self.__fill_func.append(update_color) self._fill_func.append(update_color)
self.__fill_obj.append( self._fill_obj.append(
self.canvas.create_text(14+int((self.w-14)/2), 6, text=self.text, font=(use_font, 10))) self.canvas.create_text(14+int((self.w-14)/2), 6, text=self.text, font=(use_font, 10)))
def bind_anim(self): def bind_anim(self):
def anim_magictk(): def anim_magictk():
if (self.ishover == 1 and self.__flash_t < self.max_flash*2): 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 += (1 if (len(self.root.anim) > 6) else 1)
self.__flash_t = min(self.__flash_t, self.max_flash*2) self._flash_t = min(self._flash_t, self.max_flash*2)
self.hover_mode = self.__flash_t/self.max_flash self.hover_mode = self._flash_t/self.max_flash
self.__update_color() self._update_color()
elif (self.ishover == 0 and self.__flash_t > 0): elif (self.ishover == 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._flash_t = max(self._flash_t, 0)
self.hover_mode = self.__flash_t/self.max_flash self.hover_mode = self._flash_t/self.max_flash
self.__update_color() self._update_color()
# elif (self.__is_hover == 0 and self.__flash_t <= 0): elif (self._is_hover == 0 and self._flash_t <= 0):
# if self.__anim_obj_id != -1: return -1
# self.__anim_obj_id = None
def anim_normal(*args): def anim_normal(*args):
if (self.ishover == 1 and self.__flash_t < self.max_flash*2): if (self.ishover == 1 and self._flash_t < self.max_flash*2):
self.__flash_t += 1 self._flash_t += 1
self.hover_mode = self.__flash_t/self.max_flash self.hover_mode = self._flash_t/self.max_flash
self.__update_color() self.__update_color()
elif (self.ishover == 0 and self.__flash_t > 0): elif (self.ishover == 0 and self._flash_t > 0):
self.__flash_t -= 1 self._flash_t -= 1
self.hover_mode = self.__flash_t/self.max_flash self.hover_mode = self._flash_t/self.max_flash
self.__update_color() self.__update_color()
self.root.after(anim_normal, 16) self.root.after(anim_normal, 16)
@ -278,22 +256,23 @@ class Checkbox:
else: else:
if (anim_magictk not in self.root.anim): if (anim_magictk not in self.root.anim):
self.root.anim.append(anim_magictk) self.root.anim.append(anim_magictk)
self.__anim_obj_id = self.root.anim[-1] self._anim_obj_id = self.root.anim[-1]
def __bind_event(self): def _bind_event(self):
def press_v(*args): def press_v(*args):
self.bind_anim()
if (self.ishover == 1): if (self.ishover == 1):
if (self.disable_unhover == 0): if (self.disable_unhover == 0):
self.ishover = 0 self.ishover = 0
else: else:
self.ishover = 1 self.ishover = 1
self.callback(self) self.callback(self)
self.__update_color() self._update_color()
self.canvas.bind("<Button-1>", press_v) self.canvas.bind("<Button-1>", press_v)
def pressrelease_v(*args): def pressrelease_v(*args):
self.__update_color() self._update_color()
self.canvas.bind("<ButtonRelease-1>", pressrelease_v) self.canvas.bind("<ButtonRelease-1>", pressrelease_v)