diff --git a/magictk/submenu.py b/magictk/submenu.py index ffa0d18..bcd3d93 100644 --- a/magictk/submenu.py +++ b/magictk/submenu.py @@ -2,35 +2,15 @@ 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 + +from magictk import color_tmpl +from magictk import photoload +from magictk import fontconfig 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 = [] @@ -60,6 +40,7 @@ class Menu: __y_move = 0 ___last_move = 1 ___last_highlight = 0 + __load_y_size = 10 ht = 12 lt = 22 ft = 34 @@ -102,7 +83,8 @@ class Menu: n += 1 self.___last_move = self.__y_move n = 0 - for i in self.menuobj.menu_effect: + for i_tmp in range((-self.__real_y_move+self.__y_move)//self.ft, min((-self.__real_y_move+self.__y_move)//self.ft+len(self.__items), len(self.menuobj.menu_effect))): + i = self.menuobj.menu_effect[i_tmp] if (len(i) != 0): self.canvas.itemconfigure( self.__itemsf[n], justify=tkinter.LEFT, **i) @@ -119,29 +101,35 @@ class Menu: 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): + for i in self.__items: 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 + i, fill=self.color["background"]) + self.canvas.itemconfig( + self.__items[self.__last_highlight], fill=self.color["placeholder_light"]) def close(self, *args): self.__close_mode = 1 + if sys.platform.startswith('win'): + self.toplevel.unbind_all("") + elif sys.platform.startswith('darwin'): + self.toplevel.unbind_all("") + else: + self.toplevel.unbind_all( + "") + self.toplevel.unbind_all( + "") 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() + global use_font + use_font = fontconfig.getfont() self.__closecallback = closecallback self.font = (use_font, fontsize) self.__items = [] self.__itemsf = [] + self.__itemsid = [] + self.__real_y_move = 0 self.menuobj = menuobj self.w = w self.h = h @@ -177,11 +165,13 @@ class Menu: def __draw_menu(self): n = 0 - for i in self.menuobj.menu_lst: + for i_tmp in range(0, min(self.__load_y_size, len(self.menuobj.menu_lst))): + i = self.menuobj.menu_lst[i_tmp] 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"])) + self.__itemsid.append(n) n += 1 def __draw_corner(self, r_x, r_y, x, y, **kwargs): @@ -234,6 +224,8 @@ class Menu: def __bind_scroll(self): def scrollwheel(event: tkinter.Event, setdelta=None): + if (len(self.menuobj.menu_lst) <= 8): + return if (setdelta is None): delta = event.delta else: @@ -241,10 +233,33 @@ class Menu: if sys.platform.startswith('win'): delta //= 120 if delta > 0: - self.__y_move = min(0, self.__y_move+delta) + if (self.__real_y_move != 0): + self.__y_move += delta + self.__real_y_move = min(0, self.__real_y_move+delta) else: - self.__y_move = max( - -max(0, len(self.__items)*self.ft+self.ht-self.h), self.__y_move+delta) + if (self.__real_y_move != -(len(self.menuobj.menu_lst)*self.ft-self.h+8)): + self.__y_move += delta + self.__real_y_move = max(self.__real_y_move+delta, + -(len(self.menuobj.menu_lst)*self.ft-self.h+8)) + + if (self.__y_move > 0): + self.__y_move -= self.ft + self.__items.insert(0, self.__items.pop()) + self.__itemsf.insert(0, self.__itemsf.pop()) + self.__itemsid.insert(0, self.__itemsid.pop()-10) + self.__mouse_move(event) + if (self.__itemsid[0] >= 0): + self.canvas.itemconfigure( + self.__itemsf[0], text=self.menuobj.menu_lst[self.__itemsid[0]]) + elif (self.__y_move < -self.ft+1): + self.__y_move += self.ft + self.__items.append(self.__items.pop(0)) + self.__itemsf.append(self.__itemsf.pop(0)) + self.__itemsid.append(self.__itemsid.pop(0)+10) + self.__mouse_move(event) + if (self.__itemsid[-1] < len(self.menuobj.menu_lst)): + self.canvas.itemconfigure( + self.__itemsf[-1], text=self.menuobj.menu_lst[self.__itemsid[-1]]) if sys.platform.startswith('win'): self.toplevel.bind_all("", scrollwheel) @@ -258,8 +273,8 @@ class Menu: 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)): + -1, min(len(self.menuobj.menu_func), int((event.y-self.ht-self.__real_y_move)//self.ft))) + if (click_item == -1 or self.__last_highlight >= len(self.menuobj.menu_func)): return self.close() self.menuobj.menu_func[click_item](self, click_item)