diff --git a/debug.py b/debug.py index a171b76..75b2245 100644 --- a/debug.py +++ b/debug.py @@ -81,7 +81,8 @@ if __name__ == "__main__": func=lambda s: kaoji(), w=130).pack(side='left') frame6.pack() - win.mainloop() + frame7 = magictk.Frame(win) + magictk.Entry(frame7, w=100).pack(side='left') + frame7.pack() -# from magictk import workspace -# print(workspace.get_gtk_workspace_size()) + win.mainloop() diff --git a/magictk/__init__.py b/magictk/__init__.py index b107b69..29f0f5f 100644 --- a/magictk/__init__.py +++ b/magictk/__init__.py @@ -5,3 +5,4 @@ from magictk.checkbox import Checkbox, RadioGroup from magictk.submenu import Menu, MenuObjs from magictk.select import Select from magictk.frame import Frame +from magictk.entry import Entry diff --git a/magictk/entry.py b/magictk/entry.py new file mode 100644 index 0000000..ccf9e8d --- /dev/null +++ b/magictk/entry.py @@ -0,0 +1,269 @@ +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 Entry: + 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 = "Input" + input_text = "" + + 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 __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="Input", color_list: None | dict = None, items=[]): + set_font() + self.input_text = "" + 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() + + 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["placeholder"]) + 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) + + 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 = 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() + # 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) + 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: tkinter.Event): + if (self.__is_hover == 1): + self.__is_hover = 0 + else: + self.__is_hover = 1 + self.top = tkinter.Toplevel() + self.top.geometry( + f"{self.w}x{self.h}+{event.x_root-event.x}+{event.y_root-event.y}") + self.top.wm_attributes("-alpha", 0.5) + self.__top_entry = ttk.Entry(self.top, width=self.w) + self.__top_entry.place(x=0, y=0, width=self.w, height=self.h) + self.__top_entry.focus_force() + + self.__update_color() + self.canvas.bind("", pressrelease_v)