diff --git a/debug.py b/debug.py index 75b2245..acd768f 100644 --- a/debug.py +++ b/debug.py @@ -82,7 +82,11 @@ if __name__ == "__main__": frame6.pack() frame7 = magictk.Frame(win) - magictk.Entry(frame7, w=100).pack(side='left') + magictk.Entry(frame7, w=200).pack(side='left') frame7.pack() + frame8 = magictk.Frame(win) + magictk.ScrollBar(frame8, h=200, allh=100).pack(side='left') + frame8.pack() + win.mainloop() diff --git a/magictk/__init__.py b/magictk/__init__.py index 41f998f..b95bf43 100644 --- a/magictk/__init__.py +++ b/magictk/__init__.py @@ -7,3 +7,4 @@ from magictk.submenu import Menu, MenuObjs from magictk.select import Select from magictk.frame import Frame from magictk.entry import Entry +from magictk.scrollbar import ScrollBar diff --git a/magictk/res.pickle b/magictk/res.pickle index 91bc1f1..3bb3f39 100644 Binary files a/magictk/res.pickle and b/magictk/res.pickle differ diff --git a/magictk/scrollbar.py b/magictk/scrollbar.py new file mode 100644 index 0000000..5e7e3ac --- /dev/null +++ b/magictk/scrollbar.py @@ -0,0 +1,207 @@ +import json +import tkinter +from tkinter import ttk +from magictk import color_tmpl +from magictk import photoload + + +class ScrollBar: + color = color_tmpl.default_color + __fill_obj = {} + progress = 0.0 + __progress_pixel = 0 + __move_progress_pixel = 0 + max_flash = 4 + scroll_y = 0 + y_size = 1.0 + bar_len = 100 + + def cal_bar(self): + self.bar_len = max(self.h*self._r_maxh//self._r_allh, 20) + self.y_size = self._r_allh/(self.h-self.bar_len) + + def __draw_corner(self, r_x, r_y, x, y, colors="#000000", rid="", bgcolor=None, **kwargs): + if bgcolor is None: + bgcolor = self.color["border_light"] + self.__fill_obj[rid] = [] + self.__fill_obj[rid+"_pos"] = [] + self.__fill_obj[rid+"_pos2"] = [] + self.border_info = json.loads(photoload.loadres("scrollbarborder")) + y_n = 0 + for i in self.border_info: + x_n = 0 + for j in i: + if (r_x == 0): + px = x+x_n+1 + else: + px = x+6-x_n + if (r_y == 0): + py = y+y_n+1 + else: + py = y+3-y_n-1 + if (j < 0): + lcolor = -j + else: + lcolor = j + # if(lcolor==255): + # continue + g_color = color_tmpl.mix_color( + bgcolor, colors, int((1-lcolor/255)*1000)/1000) + + obj = self.canvas.create_rectangle( + px, py, px, py, width=0, fill=g_color) + + self.__fill_obj[rid].append(obj) + self.__fill_obj[rid+"_pos"].append([px, py]) + self.__fill_obj[rid+"_pos2"].append([y_n, x_n]) + + x_n += 1 + y_n += 1 + + def __init__(self, master=None, root_anim=None, w=None, h=8, colors="primary", color_list: dict = None, allh=100, + maxh=50): + self._r_allh = allh + self._r_maxh = maxh + self.w = 8 + self.h = h + self.__master = master + self.colors = colors + 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.cal_bar() + + self.__draw() + self.bind_event() + self.update_pos() + + def pack(self, *args, **kwargs): + self.canvas.pack(*args, **kwargs) + + def grid(self, *args, **kwargs): + self.canvas.grid(*args, **kwargs) + + def place(self, *args, **kwargs): + self.canvas.place(*args, **kwargs) + + def update_pos(self): + for i in range(len(self.__fill_obj["upside"])): + self.canvas.coords( + self.__fill_obj["upside"][i], int(self.__fill_obj["upside_pos"][i][0]), self.__fill_obj["upside_pos"][i][1]+self.scroll_y, int(self.__fill_obj["upside_pos"][i][0]), self.__fill_obj["upside_pos"][i][1]+self.scroll_y) + self.canvas.coords( + self.__fill_obj["fgbar"][0], 1, 4+self.scroll_y, self.w-1, self.scroll_y+self.bar_len-4+1) + for i in range(len(self.__fill_obj["bottomside"])): + self.canvas.coords( + self.__fill_obj["bottomside"][i], int(self.__fill_obj["bottomside_pos"][i][0]), self.__fill_obj["bottomside_pos"][i][1]+self.scroll_y, int(self.__fill_obj["bottomside_pos"][i][0]), self.__fill_obj["bottomside_pos"][i][1]+self.scroll_y) + + def bind_event(self): + def mouse_press(event: tkinter.Event): + if (event.y >= self.scroll_y and event.y <= self.scroll_y+self.bar_len): + pass + else: + self.scroll_y = min(self.h-self.bar_len, + max(0, event.y-self.bar_len//2)) + self.move_start = event.y-self.scroll_y + for i in range(len(self.__fill_obj["upside"])): + self.canvas.itemconfig( + self.__fill_obj["upside"][i], fill=color_tmpl.mix_color( + self.color["background"], self.color["border_base"], int((1-self.border_info[self.__fill_obj["upside_pos2"][i][0]][self.__fill_obj["upside_pos2"][i][1]]/255)*1000)/1000)) + self.canvas.itemconfig( + self.__fill_obj["fgbar"][0], fill=self.color["border_base"]) + for i in range(len(self.__fill_obj["bottomside"])): + self.canvas.itemconfig( + self.__fill_obj["bottomside"][i], fill=color_tmpl.mix_color( + self.color["background"], self.color["border_base"], int((1-self.border_info[self.__fill_obj["bottomside_pos2"][i][0]][self.__fill_obj["bottomside_pos2"][i][1]]/255)*1000)/1000)) + self.update_pos() + + def mouse_move(event: tkinter.Event): + delta_y = event.y-self.scroll_y + self.scroll_y = min(self.h-self.bar_len, + max(0, self.scroll_y+delta_y-self.move_start)) + print(self.get()) + self.update_pos() + + def mouse_release(event: tkinter.Event): + for i in range(len(self.__fill_obj["upside"])): + self.canvas.itemconfig( + self.__fill_obj["upside"][i], fill=color_tmpl.mix_color( + self.color["background"], self.color["border_light"], int((1-self.border_info[self.__fill_obj["upside_pos2"][i][0]][self.__fill_obj["upside_pos2"][i][1]]/255)*1000)/1000)) + self.canvas.itemconfig( + self.__fill_obj["fgbar"][0], fill=self.color["border_light"]) + for i in range(len(self.__fill_obj["bottomside"])): + self.canvas.itemconfig( + self.__fill_obj["bottomside"][i], fill=color_tmpl.mix_color( + self.color["background"], self.color["border_light"], int((1-self.border_info[self.__fill_obj["bottomside_pos2"][i][0]][self.__fill_obj["bottomside_pos2"][i][1]]/255)*1000)/1000)) + + self.canvas.bind("", mouse_move) + self.canvas.bind("", mouse_press) + self.canvas.bind("", mouse_release) + + def __draw(self): + self.__draw_corner(0, 0, 0, self.scroll_y, + self.color["border_light"], "upside", bgcolor=self.color["background"]) + self.__fill_obj["fgbar"] = [ + self.canvas.create_rectangle(1, 4+self.scroll_y, self.w-1, self.scroll_y+self.bar_len-4+1, width=0, fill=self.color["border_light"])] + self.__draw_corner(0, 1, 0, self.scroll_y+self.bar_len-4+1, + self.color["border_light"], "bottomside", bgcolor=self.color["background"]) + + def __update_pixel(self): + self.__move_progress_pixel = max(4, int((self.w-6)*self.progress)) + + def add_progress(self, n): + self.progress = max(min(self.progress+n, 1.0), 0.0) + self.__update_pixel() + + def set_progress(self, n): + self.progress = max(min(n, 1.0), 0.0) + self.__update_pixel() + + def bind_anim(self): + def anim_magictk(): + if (int(self.__progress_pixel) < int(self.__move_progress_pixel)): + if (self.__move_progress_pixel-self.__progress_pixel > 8): + self.__progress_pixel += 8 + else: + add_n = int( + (self.__progress_pixel-self.__move_progress_pixel)/2) + if (add_n <= 2): + self.__progress_pixel = self.__move_progress_pixel + else: + self.__progress_pixel += add_n + self.__update_prog() + elif (int(self.__progress_pixel) > int(self.__move_progress_pixel)): + if (self.__progress_pixel-self.__move_progress_pixel > 8): + self.__progress_pixel -= 8 + else: + add_n = int( + (self.__progress_pixel-self.__move_progress_pixel)/2) + if (add_n <= 2): + self.__progress_pixel = self.__move_progress_pixel + else: + self.__progress_pixel -= add_n + self.__update_prog() + + def anim_normal(*args): + 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 get(self): + if (self.scroll_y+self.bar_len >= self.h): + return self._r_allh + else: + return int(min(self.scroll_y*self.y_size, self._r_allh)) diff --git a/photo2/res/scrollbarborder.json b/photo2/res/scrollbarborder.json new file mode 100644 index 0000000..93d6dd8 --- /dev/null +++ b/photo2/res/scrollbarborder.json @@ -0,0 +1,26 @@ +[ + [ + 255, + 157, + 22, + 22, + 157, + 255 + ], + [ + 157, + 0, + 0, + 0, + 0, + 157 + ], + [ + 22, + 0, + 0, + 0, + 0, + 22 + ] +] \ No newline at end of file