292 lines
10 KiB
Python
292 lines
10 KiB
Python
import time
|
|
import tkinter
|
|
import os
|
|
from tkinter import ttk
|
|
try:
|
|
import color_tmpl
|
|
except ImportError:
|
|
from magictk import color_tmpl
|
|
try:
|
|
import _window_ctl
|
|
except ImportError:
|
|
from magictk import _window_ctl
|
|
try:
|
|
import _window_size
|
|
except ImportError:
|
|
from magictk import _window_size
|
|
try:
|
|
import workspace
|
|
except ImportError:
|
|
from magictk import workspace
|
|
try:
|
|
import photoload
|
|
except ImportError:
|
|
from magictk import photoload
|
|
import sys
|
|
|
|
WIN_INF = -10000
|
|
|
|
|
|
class Window(ttk.Frame):
|
|
x = 200
|
|
y = 200
|
|
w = 500
|
|
h = 350
|
|
normal_x = -1
|
|
normal_y = 1
|
|
top_h = 28
|
|
__break_win = True
|
|
fullscreen = False
|
|
minmode = False
|
|
color = color_tmpl.default_color
|
|
anim = []
|
|
disable_move = False
|
|
min_w = 200
|
|
min_h = 100
|
|
|
|
def update_size(self) -> None:
|
|
self.tk_w_without_bar.set(self.w-48*3)
|
|
self.place(x=8, y=self.top_h+1+8, width=self.w-16, height=self.h-1-16)
|
|
self.main_tk.geometry(
|
|
f"{self.w}x{self.h+self.top_h}+{self.x}+{self.y}")
|
|
self.__fake_tk.geometry(
|
|
f"{self.w}x{self.h}+{WIN_INF}+{WIN_INF}")
|
|
|
|
def __load_color(self) -> None:
|
|
self.main_tk.configure(bg=self.color["background"])
|
|
self.style.configure(
|
|
'Test1.TFrame', background="#FF0000")
|
|
self.style.configure(
|
|
'Test2.TFrame', background="#00FF00")
|
|
self.style.configure(
|
|
'Test3.TFrame', background="#0000FF")
|
|
self.style.configure(
|
|
'Main.TFrame', background=self.color["background"])
|
|
self.style.configure(
|
|
'Root.TFrame', background=self.color["background"])
|
|
self.style.configure(
|
|
'Splitline.TFrame', background=self.color["border_light"])
|
|
self.style.configure(
|
|
'BarExitButton.TFrame', background=self.color["background"])
|
|
self.style.configure(
|
|
'LabBarZoomButton.TLabel', background=self.color["background"])
|
|
self.style.configure(
|
|
'LabBarIcon.TLabel', background=self.color["background"])
|
|
self.style.configure(
|
|
'LabTitle.TLabel', background=self.color["background"], fg=self.color["primary_text"])
|
|
self.style.configure(
|
|
'BarIconicButton.TFrame', background=self.color["background"])
|
|
self.style.configure(
|
|
'Size.TFrame', background=self.color["background"])
|
|
self.style.configure(
|
|
'LabelTitle.TFrame', background=self.color["background"])
|
|
|
|
def __init_weights(self, root: tkinter.Frame) -> None:
|
|
top_bar = ttk.Frame(root, style='Root.TFrame', height=self.top_h)
|
|
startmove_x = 0
|
|
startmove_y = 0
|
|
title_frame = ttk.Frame(
|
|
top_bar, style="LabelTitle.TFrame", height=self.top_h)
|
|
|
|
def start_move(event: tkinter.Event):
|
|
if (self.disable_move):
|
|
return
|
|
nonlocal startmove_x, startmove_y
|
|
startmove_x = event.x_root-self.main_tk.winfo_x()
|
|
startmove_y = event.y_root-self.main_tk.winfo_y()
|
|
if (self.fullscreen):
|
|
self.zoom()
|
|
self.x = event.x_root-(event.x_root-self.main_tk.winfo_x())
|
|
self.y = event.y_root-(event.y_root-self.main_tk.winfo_y())
|
|
startmove_x = int(self.w/2)
|
|
startmove_y = int(self.top_h/2)
|
|
self.update_size()
|
|
title_frame.configure(cursor="arrow")
|
|
|
|
def move_win(event: tkinter.Event):
|
|
if (self.disable_move):
|
|
return
|
|
nonlocal startmove_x, startmove_y
|
|
if (self.fullscreen):
|
|
return
|
|
self.x = event.x_root-startmove_x
|
|
self.y = event.y_root-startmove_y
|
|
if (event.y_root < 5):
|
|
title_frame.configure(cursor="dotbox")
|
|
else:
|
|
title_frame.configure(cursor="fleur")
|
|
self.update_size()
|
|
|
|
def special_move(event: tkinter.Event):
|
|
if (event.y_root < 5):
|
|
self.y = 50
|
|
self.zoom()
|
|
title_frame.configure(cursor="arrow")
|
|
top_bar.place(x=0, y=0, relwidth=1)
|
|
ttk.Frame(root, style='Splitline.TFrame',
|
|
height=1).place(x=0, y=self.top_h, relwidth=1)
|
|
|
|
icons = ttk.Label(top_bar, image=photoload.loadimg(
|
|
"icon"), width=2, compound="center", justify="center", style="LabBarIcon.TLabel")
|
|
icons.bind("<ButtonRelease-2>", lambda event=None: self.quit())
|
|
icons.pack(anchor="center", side='left', padx=8, pady=4)
|
|
|
|
title_frame.pack(anchor="center", side='left',
|
|
fill=tkinter.X, expand=True)
|
|
control_frame = ttk.Frame(
|
|
top_bar, style="Root.TFrame", height=self.top_h, width=48*3)
|
|
control_frame.pack(anchor="e", side='right')
|
|
title_frame.bind("<Button-1>", start_move)
|
|
title_frame.bind("<B1-Motion>", move_win)
|
|
title_frame.bind("<ButtonRelease-1>", special_move)
|
|
|
|
_window_ctl.exit_btn_set(self, root)
|
|
_window_ctl.zoom_btn_set(self, root)
|
|
_window_ctl.iconic_btn_set(self, root)
|
|
_window_size.placeall(self, root)
|
|
|
|
titles = ttk.Label(title_frame, text=self.title,
|
|
style="LabTitle.TLabel")
|
|
titles.pack()
|
|
titles.bind("<Button-1>", start_move)
|
|
titles.bind("<B1-Motion>", move_win)
|
|
titles.bind("<ButtonRelease-1>", special_move)
|
|
|
|
def __init__(self, w=500, h=350, title="MagicTk", color_list: dict = None) -> None:
|
|
self.root = self
|
|
self.title = title
|
|
self.w = w
|
|
self.h = h
|
|
if (color_list is not None):
|
|
self.color = color_list
|
|
self.main_tk = tkinter.Tk()
|
|
self.main_tk.overrideredirect(True)
|
|
self.__fake_tk = tkinter.Tk()
|
|
self.style = ttk.Style()
|
|
self.__load_color()
|
|
self.tk_w_without_bar = tkinter.IntVar()
|
|
self.tk_w_without_bar.set(self.w-48*3)
|
|
|
|
ttk.Widget.__init__(self, self.main_tk, "ttk::frame", {
|
|
"style": "Main.TFrame"})
|
|
self.place(x=8, y=self.top_h+1+8, width=self.w-16, height=self.h-1-16)
|
|
|
|
self.update_size()
|
|
self.__fake_tk.title(self.title)
|
|
self.main_tk.title(self.title)
|
|
self.__fake_tk.protocol("WM_DELETE_WINDOW", self.quit)
|
|
self.__fake_tk.bind('<FocusIn>', self.__top_window)
|
|
self.__fake_tk.resizable(0, 0)
|
|
self.__init_weights(self.main_tk)
|
|
try:
|
|
self.main_tk.iconbitmap(
|
|
os.path.dirname(__file__)+os.sep+"icon.ico")
|
|
self.__fake_tk.iconbitmap(
|
|
os.path.dirname(__file__)+os.sep+"icon.ico")
|
|
except:
|
|
# What's fuck in Linux
|
|
self.zoom()
|
|
self.main_tk.update()
|
|
self.__fake_tk.update()
|
|
self.zoom()
|
|
self.main_tk.update()
|
|
self.__fake_tk.update()
|
|
|
|
def mainloop(self) -> None:
|
|
t_start = time.time()
|
|
while (self.__break_win):
|
|
delta_t = time.time()-t_start
|
|
if (delta_t > 0.02): # flash animation
|
|
t_start = time.time()
|
|
n = 0
|
|
for i in self.anim:
|
|
if (i is not None):
|
|
retn = i()
|
|
if (retn == -1):
|
|
self.anim[n] = None
|
|
n += 1
|
|
self.anim = [i for i in self.anim if i is not None]
|
|
else:
|
|
pass
|
|
if (self.__fake_tk.state() == "iconic"):
|
|
if (self.normal_x == -1):
|
|
self.normal_x = self.x
|
|
self.normal_y = self.y
|
|
self.x = WIN_INF
|
|
self.y = WIN_INF
|
|
self.minmode = True
|
|
self.fullscreen = False
|
|
self.update_size()
|
|
else:
|
|
if (self.normal_x != -1):
|
|
self.x = self.normal_x
|
|
self.y = self.normal_y
|
|
self.normal_x = -1
|
|
self.minmode = False
|
|
self.update_size()
|
|
self.main_tk.update()
|
|
self.__fake_tk.update()
|
|
self.main_tk.destroy()
|
|
self.__fake_tk.destroy()
|
|
self.main_tk.mainloop()
|
|
self.__break_win = None
|
|
|
|
def quit(self) -> None:
|
|
self.__break_win = False
|
|
|
|
def iconify(self) -> None:
|
|
if (self.fullscreen == True):
|
|
self.zoom()
|
|
self.__fake_tk.iconify()
|
|
|
|
def __top_window(self, event=None) -> None:
|
|
self.main_tk.state("normal")
|
|
self.main_tk.focus_set()
|
|
self.main_tk.attributes('-topmost', 'true')
|
|
self.main_tk.update()
|
|
self.main_tk.attributes('-topmost', 'false')
|
|
|
|
def zoom(self) -> None:
|
|
if (self.fullscreen == False):
|
|
self.normal_w = self.w
|
|
self.normal_h = self.h
|
|
self.old_x = self.x
|
|
self.old_y = self.y
|
|
nx = 0
|
|
ny = 0
|
|
nw, nh = self.__fake_tk.maxsize()
|
|
try:
|
|
wsp = workspace.get_workspace_size()
|
|
nx = wsp[0]
|
|
ny = wsp[1]
|
|
nw = wsp[2]
|
|
nh = wsp[3]-self.top_h
|
|
except:
|
|
pass
|
|
self.normal_x = -1
|
|
self.x = nx
|
|
self.y = ny
|
|
self.main_tk.geometry(
|
|
f"+{self.x}+{self.y}")
|
|
self.main_tk.update()
|
|
self.w = nw
|
|
self.h = nh
|
|
self.update_size()
|
|
self.fullscreen = True
|
|
self.minmode = False
|
|
self.__top_window()
|
|
else:
|
|
self.normal_x = -1
|
|
self.x = self.old_x
|
|
self.y = self.old_y
|
|
self.main_tk.geometry(
|
|
f"+{self.x}+{self.y}")
|
|
self.main_tk.update()
|
|
self.w = self.normal_w
|
|
self.h = self.normal_h
|
|
self.fullscreen = False
|
|
self.minmode = False
|
|
self.update_size()
|
|
self.__top_window()
|
|
self.update_icon()
|