diff --git a/magictk/select.py b/magictk/select.py new file mode 100644 index 0000000..d613385 --- /dev/null +++ b/magictk/select.py @@ -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("", pressrelease_v) diff --git a/photo2/res/selectarrow.json b/photo2/res/selectarrow.json new file mode 100644 index 0000000..f68b6b3 --- /dev/null +++ b/photo2/res/selectarrow.json @@ -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 + ] + ] +] \ No newline at end of file