(origin)add window class

This commit is contained in:
cxy_kevin 2024-03-17 16:20:21 +08:00 committed by cxykevin
parent bc58b9c392
commit 2b6d3b1d19
19 changed files with 1196 additions and 0 deletions

104
.gitignore vendored Normal file
View File

@ -0,0 +1,104 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
.pytest_cache/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# pyenv
.python-version
.idea/
# celery beat schedule file
celerybeat-schedule
workspace.xml
# SageMath parsed files
*.sage.py
.idea/workspace.xml
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/

22
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,22 @@
{
// 使 IntelliSense
//
// 访: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Python 调试程序: 当前文件",
"type": "debugpy",
"request": "launch",
"program": "debug.py",
"console": "integratedTerminal"
},
{
"name": "重新生成资源包",
"type": "debugpy",
"request": "launch",
"program": "photo2/run.py",
"console": "integratedTerminal"
}
]
}

5
debug.py Normal file
View File

@ -0,0 +1,5 @@
import magictk
if __name__ == "__main__":
win = magictk.window.Window()
win.mainloop()

1
magictk/__init__.py Normal file
View File

@ -0,0 +1 @@
from magictk import window

232
magictk/_window_ctl.py Normal file
View File

@ -0,0 +1,232 @@
import tkinter
from tkinter import ttk
try:
import color_tmpl
except:
from magictk import color_tmpl
try:
import photoload
except:
from magictk import photoload
def exit_btn_set(self, root):
img_exit = photoload.loadimg("close")
img_act_exit = photoload.loadimg("close_active")
self.style.configure(
'BarExitButton.TFrame', background=self.color["background"])
self.style.configure(
'BarExitButton.TLabel', background=self.color["background"])
exit_btn = ttk.Frame(root, style='BarExitButton.TFrame',
height=self.top_h, width=48)
exit_btn.pack(anchor="n", side='right')
exit_btn_flash = 0 # total 6f
exit_btn_flash_mode = 0
label = ttk.Label(
exit_btn, style='BarExitButton.TLabel', image=img_exit, anchor=tkinter.CENTER)
label.place(width=48, height=self.top_h, x=0, y=0)
def animation():
nonlocal exit_btn_flash, exit_btn_flash_mode
if (exit_btn_flash_mode == 0 and exit_btn_flash > 0):
exit_btn_flash -= 1
self.style.configure(
'BarExitButton.TFrame', background=color_tmpl.mix_color(self.color["background"], "#C42B1C", exit_btn_flash/6))
self.style.configure(
'BarExitButton.TLabel', background=color_tmpl.mix_color(self.color["background"], "#C42B1C", exit_btn_flash/6))
if (exit_btn_flash >= 3):
label.configure(image=img_act_exit)
else:
label.configure(image=img_exit)
if (exit_btn_flash_mode == 1 and exit_btn_flash < 6):
exit_btn_flash += 1
self.style.configure(
'BarExitButton.TFrame', background=color_tmpl.mix_color(self.color["background"], "#C42B1C", exit_btn_flash/6))
self.style.configure(
'BarExitButton.TLabel', background=color_tmpl.mix_color(self.color["background"], "#C42B1C", exit_btn_flash/6))
if (exit_btn_flash >= 3):
label.configure(image=img_act_exit)
else:
label.configure(image=img_exit)
if (exit_btn_flash_mode == 2):
exit_btn_flash = 6
self.style.configure(
'BarExitButton.TFrame', background="#94141E")
self.style.configure(
'BarExitButton.TLabel', background="#94141E")
if (exit_btn_flash >= 3):
label.configure(image=img_act_exit)
else:
label.configure(image=img_exit)
self.anim.append(animation)
def enters_exit(event):
nonlocal exit_btn_flash_mode
exit_btn_flash_mode = 1
def leaves_exit(event):
nonlocal exit_btn_flash_mode
exit_btn_flash_mode = 0
def presshold_exit(event):
nonlocal exit_btn_flash_mode
exit_btn_flash_mode = 2
def press_exit(event):
nonlocal exit_btn_flash_mode
if (exit_btn_flash_mode == 2):
exit_btn_flash_mode = 0
self.quit()
else:
exit_btn_flash_mode = 0
exit_btn.bind("<Enter>", enters_exit)
exit_btn.bind("<Leave>", leaves_exit)
exit_btn.bind("<Button-1>", presshold_exit)
exit_btn.bind("<ButtonRelease-1>", press_exit)
label.bind("<Enter>", enters_exit)
label.bind("<Leave>", leaves_exit)
label.bind("<Button-1>", presshold_exit)
label.bind("<ButtonRelease-1>", press_exit)
def zoom_btn_set(self, root):
img_default = photoload.loadimg("zoom")
img_inzoom = photoload.loadimg("zoom2normal")
self.style.configure(
'BarZoomButton.TFrame', background=self.color["background"])
self.style.configure(
'BarZoomButton.TLabel', background=self.color["background"])
zoom_btn = ttk.Frame(root, style='BarZoomButton.TFrame',
height=self.top_h, width=48)
zoom_btn.pack(anchor="n", side='right')
zoom_btn_flash = 0 # total 4f
zoom_btn_flash_mode = 0
label = ttk.Label(
zoom_btn, style='BarZoomButton.TLabel', image=img_default, anchor=tkinter.CENTER)
label.place(width=48, height=self.top_h, x=0, y=0)
def animation():
nonlocal zoom_btn_flash, zoom_btn_flash_mode
if (zoom_btn_flash_mode == 0 and zoom_btn_flash > 0):
zoom_btn_flash -= 1
self.style.configure(
'BarZoomButton.TFrame', background=color_tmpl.mix_color(self.color["background"], self.color["border_base"], zoom_btn_flash/4))
self.style.configure(
'BarZoomButton.TLabel', background=color_tmpl.mix_color(self.color["background"], self.color["border_base"], zoom_btn_flash/4))
if (zoom_btn_flash_mode == 1 and zoom_btn_flash < 4):
zoom_btn_flash += 1
self.style.configure(
'BarZoomButton.TFrame', background=color_tmpl.mix_color(self.color["background"], self.color["border_base"], zoom_btn_flash/4))
self.style.configure(
'BarZoomButton.TLabel', background=color_tmpl.mix_color(self.color["background"], self.color["border_base"], zoom_btn_flash/4))
if (zoom_btn_flash_mode == 2):
zoom_btn_flash = 4
self.style.configure(
'BarZoomButton.TFrame', background=color_tmpl.setlight(self.color["border_base"], 0.76))
self.style.configure(
'BarZoomButton.TLabel', background=color_tmpl.setlight(self.color["border_base"], 0.76))
self.anim.append(animation)
def enters_zoom(event):
nonlocal zoom_btn_flash_mode
zoom_btn_flash_mode = 1
def leaves_zoom(event):
nonlocal zoom_btn_flash_mode
zoom_btn_flash_mode = 0
def presshold_zoom(event):
nonlocal zoom_btn_flash_mode
zoom_btn_flash_mode = 2
def press_zoom(event):
nonlocal zoom_btn_flash_mode
if (zoom_btn_flash_mode == 2):
zoom_btn_flash_mode = 0
self.zoom()
else:
zoom_btn_flash_mode = 0
def update_icon(*args):
if (self.fullscreen):
label.configure(image=img_inzoom)
else:
label.configure(image=img_default)
self.update_icon = update_icon
zoom_btn.bind("<Enter>", enters_zoom)
zoom_btn.bind("<Leave>", leaves_zoom)
zoom_btn.bind("<Button-1>", presshold_zoom)
zoom_btn.bind("<ButtonRelease-1>", press_zoom)
label.bind("<Enter>", enters_zoom)
label.bind("<Leave>", leaves_zoom)
label.bind("<Button-1>", presshold_zoom)
label.bind("<ButtonRelease-1>", press_zoom)
def iconic_btn_set(self, root):
img_iconic = photoload.loadimg("iconic")
self.style.configure(
'BarIconicButton.TFrame', background=self.color["background"])
self.style.configure(
'BarIconicButton.TLabel', background=self.color["background"])
iconic_btn = ttk.Frame(root, style='BarIconicButton.TFrame',
height=self.top_h, width=48)
iconic_btn.pack(anchor="n", side='right')
iconic_btn_flash = 0 # total 4f
iconic_btn_flash_mode = 0
label = ttk.Label(
iconic_btn, style='BarIconicButton.TLabel', image=img_iconic, anchor=tkinter.CENTER)
label.place(width=48, height=self.top_h, x=0, y=0)
def animation():
nonlocal iconic_btn_flash, iconic_btn_flash_mode
if (iconic_btn_flash_mode == 0 and iconic_btn_flash > 0):
iconic_btn_flash -= 1
self.style.configure(
'BarIconicButton.TFrame', background=color_tmpl.mix_color(self.color["background"], self.color["border_light"], iconic_btn_flash/4))
self.style.configure(
'BarIconicButton.TLabel', background=color_tmpl.mix_color(self.color["background"], self.color["border_light"], iconic_btn_flash/4))
if (iconic_btn_flash_mode == 1 and iconic_btn_flash < 4):
iconic_btn_flash += 1
self.style.configure(
'BarIconicButton.TFrame', background=color_tmpl.mix_color(self.color["background"], self.color["border_light"], iconic_btn_flash/4))
self.style.configure(
'BarIconicButton.TLabel', background=color_tmpl.mix_color(self.color["background"], self.color["border_light"], iconic_btn_flash/4))
if (iconic_btn_flash_mode == 2):
iconic_btn_flash = 4
self.style.configure(
'BarIconicButton.TFrame', background=color_tmpl.setlight(self.color["border_base"], 0.76))
self.style.configure(
'BarIconicButton.TLabel', background=color_tmpl.setlight(self.color["border_base"], 0.76))
self.anim.append(animation)
def enters_iconic(event):
nonlocal iconic_btn_flash_mode
iconic_btn_flash_mode = 1
def leaves_iconic(event):
nonlocal iconic_btn_flash_mode
iconic_btn_flash_mode = 0
def presshold_iconic(event):
nonlocal iconic_btn_flash_mode
iconic_btn_flash_mode = 2
def press_iconic(event):
nonlocal iconic_btn_flash_mode
if (iconic_btn_flash_mode == 2):
iconic_btn_flash_mode = 0
self.iconify()
else:
iconic_btn_flash_mode = 0
iconic_btn.bind("<Enter>", enters_iconic)
iconic_btn.bind("<Leave>", leaves_iconic)
iconic_btn.bind("<Button-1>", presshold_iconic)
iconic_btn.bind("<ButtonRelease-1>", press_iconic)
label.bind("<Enter>", enters_iconic)
label.bind("<Leave>", leaves_iconic)
label.bind("<Button-1>", presshold_iconic)
label.bind("<ButtonRelease-1>", press_iconic)

414
magictk/_window_size.py Normal file
View File

@ -0,0 +1,414 @@
import tkinter
from tkinter import ttk
def place_move_up(self, root):
global change_bar_move_up, up_move_start, up_move
move_up = ttk.Frame(
root, style="Size.TFrame", height=6, width=self.tk_w_without_bar.get(), cursor="top_side")
def change_bar_move_up(*args, **kwargs):
move_up.configure(width=self.tk_w_without_bar.get())
self.tk_w_without_bar.trace_add('write', change_bar_move_up)
move_up.place(x=0, y=0)
upstart_h = self.h
upstart_y = self.y
def up_move_start(event: tkinter.Event):
# self.disable_move = True
# print(1)
nonlocal upstart_h, upstart_y
upstart_h = self.h-self.top_h
upstart_y = event.y_root
def up_move(event: tkinter.Event):
nonlocal upstart_h, upstart_y
if (self.fullscreen):
return
now_y = event.y_root
delta_y = upstart_y-now_y
now_h = upstart_h+delta_y
if (now_h < self.min_h):
return
self.normal_x = -1
self.y = upstart_y-delta_y
self.h = now_h+self.top_h
self.update_size()
self.main_tk.update()
move_up.bind("<Button-1>", up_move_start)
move_up.bind("<B1-Motion>", up_move)
def place_move_up_bar(self, root):
move_up_bar = ttk.Frame(
root, style="Size.TFrame", height=1, width=48*3, cursor="top_side")
def change_bar_move_up(*args, **kwargs):
move_up_bar.place(x=self.tk_w_without_bar.get(), y=0)
self.tk_w_without_bar.trace_add('write', change_bar_move_up)
self.tk_w_without_bar.trace_add('write', change_bar_move_up)
move_up_bar.place(y=0, x=self.tk_w_without_bar.get())
move_up_bar.bind("<Button-1>", up_move_start)
move_up_bar.bind("<B1-Motion>", up_move)
def place_move_down(self, root):
global down_move_start, down_move
move_down = ttk.Frame(
root, style="Size.TFrame", height=4, width=self.tk_w_without_bar.get(), cursor="bottom_side")
def change_bar_move_up(*args, **kwargs):
move_down.place(x=0, y=self.top_h+self.h-4, relwidth=1)
self.tk_w_without_bar.trace_add('write', change_bar_move_up)
move_down.place(x=0, y=self.top_h+self.h-4, relwidth=1)
downstart_h = self.h
downstart_y = self.y
def down_move_start(event: tkinter.Event):
nonlocal downstart_h, downstart_y
downstart_h = self.h-self.top_h
downstart_y = event.y_root
def down_move(event: tkinter.Event):
nonlocal downstart_h, downstart_y
if (self.fullscreen):
return
now_y = event.y_root
delta_y = downstart_y-now_y
now_h = downstart_h-delta_y
if (now_h < self.min_h):
return
self.normal_x = -1
self.h = now_h+self.top_h
self.update_size()
self.main_tk.update()
move_down.bind("<Button-1>", down_move_start)
move_down.bind("<B1-Motion>", down_move)
def place_move_left(self, root):
global left_move_start, left_move
move_left = ttk.Frame(
root, style="Size.TFrame", width=6, height=self.top_h, cursor="left_side")
move_left.place(x=0, y=0)
leftstart_w = self.w
leftstart_x = self.x
def left_move_start(event: tkinter.Event):
# self.disable_move = True
# print(1)
nonlocal leftstart_w, leftstart_x
leftstart_w = self.w
leftstart_x = event.x_root
def left_move(event: tkinter.Event):
nonlocal leftstart_w, leftstart_x
if (self.fullscreen):
return
now_x = event.x_root
delta_x = leftstart_x-now_x
now_w = leftstart_w+delta_x
if (now_w < self.min_w):
return
self.normal_x = -1
self.x = leftstart_x-delta_x
self.w = now_w
self.update_size()
self.main_tk.update()
move_left.bind("<Button-1>", left_move_start)
move_left.bind("<B1-Motion>", left_move)
def place_move_left_bar(self, root):
move_left = ttk.Frame(
root, style="Size.TFrame", width=4, height=self.h, cursor="left_side")
def change_bar_move_up(*args, **kwargs):
move_left.configure(height=self.h)
self.tk_w_without_bar.trace_add('write', change_bar_move_up)
move_left.place(x=0, y=self.top_h)
move_left.bind("<Button-1>", left_move_start)
move_left.bind("<B1-Motion>", left_move)
def place_move_right(self, root):
global right_move, right_move_start
move_right = ttk.Frame(
root, style="Size.TFrame", width=1, height=self.top_h, cursor="right_side")
def change_bar_move(*args, **kwargs):
move_right.place(x=self.w-1, y=0)
self.tk_w_without_bar.trace_add('write', change_bar_move)
move_right.place(x=self.w-1, y=0)
rightstart_w = self.w
rightstart_x = self.x
def right_move_start(event: tkinter.Event):
# self.disable_move = True
# print(1)
nonlocal rightstart_w, rightstart_x
rightstart_w = self.w
rightstart_x = event.x_root
def right_move(event: tkinter.Event):
nonlocal rightstart_w, rightstart_x
if (self.fullscreen):
return
now_x = event.x_root
delta_x = rightstart_x-now_x
now_w = rightstart_w-delta_x
if (now_w < self.min_w):
return
self.normal_x = -1
self.w = now_w
self.update_size()
self.main_tk.update()
move_right.bind("<Button-1>", right_move_start)
move_right.bind("<B1-Motion>", right_move)
def place_move_right_bar(self, root):
move_right = ttk.Frame(
root, style="Size.TFrame", width=4, height=self.h, cursor="right_side")
def change_bar_move_right(*args, **kwargs):
move_right.place(x=self.w-4, y=self.top_h)
move_right.configure(height=self.h)
self.tk_w_without_bar.trace_add('write', change_bar_move_right)
move_right.place(x=self.w-4, y=self.top_h)
move_right.bind("<Button-1>", right_move_start)
move_right.bind("<B1-Motion>", right_move)
def place_move_LT_bar(self, root):
move_LT = ttk.Frame(
root, style="Size.TFrame", width=8, height=8, cursor="top_left_corner")
move_LT.place(x=0, y=0)
leftstart_w = self.w
leftstart_x = self.x
upstart_h = self.h
upstart_y = self.y
def LT_move_start(event=None):
nonlocal leftstart_w, leftstart_x
leftstart_w = self.w
leftstart_x = event.x_root
nonlocal upstart_h, upstart_y
upstart_h = self.h-self.top_h
upstart_y = event.y_root
def LT_move(event=None):
while 1:
nonlocal leftstart_w, leftstart_x
if (self.fullscreen):
break
now_x = event.x_root
delta_x = leftstart_x-now_x
now_w = leftstart_w+delta_x
if (now_w < self.min_w):
break
self.normal_x = -1
self.x = leftstart_x-delta_x
self.w = now_w
break
while 1:
nonlocal upstart_h, upstart_y
if (self.fullscreen):
break
now_y = event.y_root
delta_y = upstart_y-now_y
now_h = upstart_h+delta_y
if (now_h < self.min_h):
break
self.normal_x = -1
self.y = upstart_y-delta_y
self.h = now_h+self.top_h
break
self.update_size()
self.main_tk.update()
move_LT.bind("<Button-1>", LT_move_start)
move_LT.bind("<B1-Motion>", LT_move)
def place_move_RT_bar(self, root):
move_RT = ttk.Frame(
root, style="Size.TFrame", width=2, height=2, cursor="top_right_corner")
def change_bar_move(*args, **kwargs):
move_RT.place(x=self.w-2, y=0)
self.tk_w_without_bar.trace_add('write', change_bar_move)
move_RT.place(x=self.w-2, y=0)
upstart_h = self.h
upstart_y = self.y
rightstart_w = self.w
rightstart_x = self.x
def RT_move_start(event=None):
nonlocal upstart_h, upstart_y
upstart_h = self.h-self.top_h
upstart_y = event.y_root
nonlocal rightstart_w, rightstart_x
rightstart_w = self.w
rightstart_x = event.x_root
def RT_move(event=None):
while 1:
nonlocal upstart_h, upstart_y
if (self.fullscreen):
break
now_y = event.y_root
delta_y = upstart_y-now_y
now_h = upstart_h+delta_y
if (now_h < self.min_h):
break
self.normal_x = -1
self.y = upstart_y-delta_y
self.h = now_h+self.top_h
break
while 1:
nonlocal rightstart_w, rightstart_x
if (self.fullscreen):
break
now_x = event.x_root
delta_x = rightstart_x-now_x
now_w = rightstart_w-delta_x
if (now_w < self.min_w):
break
self.normal_x = -1
self.w = now_w
break
self.update_size()
self.main_tk.update()
move_RT.bind("<Button-1>", RT_move_start)
move_RT.bind("<B1-Motion>", RT_move)
def place_move_RB_bar(self, root):
move_RB = ttk.Frame(
root, style="Size.TFrame", width=6, height=6, cursor="bottom_right_corner")
def change_bar_move(*args, **kwargs):
move_RB.place(x=self.w-6, y=self.h-6+self.top_h)
self.tk_w_without_bar.trace_add('write', change_bar_move)
move_RB.place(x=self.w-6, y=self.h-6+self.top_h)
rightstart_x = self.x
rightstart_w = self.w
downstart_h = self.h
downstart_y = self.y
def RB_move_start(event=None):
nonlocal rightstart_w, rightstart_x
rightstart_w = self.w
rightstart_x = event.x_root
nonlocal downstart_h, downstart_y
downstart_h = self.h-self.top_h
downstart_y = event.y_root
def RB_move(event=None):
while 1:
nonlocal rightstart_w, rightstart_x
if (self.fullscreen):
break
now_x = event.x_root
delta_x = rightstart_x-now_x
now_w = rightstart_w-delta_x
if (now_w < self.min_w):
break
self.normal_x = -1
self.w = now_w
break
while 1:
nonlocal downstart_h, downstart_y
if (self.fullscreen):
break
now_y = event.y_root
delta_y = downstart_y-now_y
now_h = downstart_h-delta_y
if (now_h < self.min_h):
break
self.normal_x = -1
self.h = now_h+self.top_h
break
self.update_size()
self.main_tk.update()
move_RB.bind("<Button-1>", RB_move_start)
move_RB.bind("<B1-Motion>", RB_move)
def place_move_LB_bar(self, root):
move_LB = ttk.Frame(
root, style="Size.TFrame", width=4, height=4, cursor="bottom_left_corner")
def change_bar_move(*args, **kwargs):
move_LB.place(x=0, y=self.h-4+self.top_h)
self.tk_w_without_bar.trace_add('write', change_bar_move)
move_LB.place(x=0, y=self.h-4+self.top_h)
leftstart_w = self.w
leftstart_x = self.x
downstart_h = self.h
downstart_y = self.y
def LB_move_start(event=None):
nonlocal leftstart_w, leftstart_x
leftstart_w = self.w
leftstart_x = event.x_root
nonlocal downstart_h, downstart_y
downstart_h = self.h-self.top_h
downstart_y = event.y_root
def LB_move(event=None):
while 1:
nonlocal leftstart_w, leftstart_x
if (self.fullscreen):
break
now_x = event.x_root
delta_x = leftstart_x-now_x
now_w = leftstart_w+delta_x
if (now_w < self.min_w):
break
self.normal_x = -1
self.x = leftstart_x-delta_x
self.w = now_w
break
while 1:
nonlocal downstart_h, downstart_y
if (self.fullscreen):
break
now_y = event.y_root
delta_y = downstart_y-now_y
now_h = downstart_h-delta_y
if (now_h < self.min_h):
break
self.normal_x = -1
self.h = now_h+self.top_h
break
self.update_size()
self.main_tk.update()
move_LB.bind("<Button-1>", LB_move_start)
move_LB.bind("<B1-Motion>", LB_move)
def placeall(self, root):
place_move_up(self, root)
place_move_up_bar(self, root)
place_move_down(self, root)
place_move_left(self, root)
place_move_left_bar(self, root)
place_move_right(self, root)
place_move_right_bar(self, root)
place_move_LT_bar(self, root)
place_move_RT_bar(self, root)
place_move_LB_bar(self, root)
place_move_RB_bar(self, root)

48
magictk/color_tmpl.py Normal file
View File

@ -0,0 +1,48 @@
import colorsys
default_color = {
"primary": "#409EFF",
"success": "#67C23A",
"warning": "#E6A23C",
"danger": "#F56C6C",
"info": "#909399",
"primary_text": "#303133",
"regular_text": "#606266",
"secondary_text": "#909399",
"placeholder": "#C0C4CC",
"border_base": "#DCDFE6",
"border_light": "#E4E7ED",
"background": "#FFFFFF"
}
def hex2rgb(color: str):
return (int(color[1:3], 16), int(color[3:5], 16), int(color[5:7], 16))
def rgb2hex(r, g, b):
return f"#{str(hex(int(r)))[2:].upper():0>2}{str(hex(int(g)))[2:].upper():0>2}{str(hex(int(b)))[2:].upper():0>2}"
def hex2hls(color: str):
r, g, b = hex2rgb(color)
return colorsys.rgb_to_hls(r/255, g/255, b/255)
def hls2hex(h, l, s):
r, g, b = colorsys.hls_to_rgb(h, l, s)
return rgb2hex(r*255, g*255, b*255)
def setlight(color: str, light: float):
h, l, s = hex2hls(color)
return hls2hex(h, light, s)
def mix_color(c1: str, c2: str, alpha: float):
r2, g2, b2 = hex2rgb(c1)
r1, g1, b1 = hex2rgb(c2)
r3 = int(r1*alpha+r2*(1-alpha))
g3 = int(g1*alpha+g2*(1-alpha))
b3 = int(b1*alpha+b2*(1-alpha))
return rgb2hex(r3, g3, b3)

BIN
magictk/icon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

24
magictk/photoload.py Normal file
View File

@ -0,0 +1,24 @@
import pickle
import os
import tkinter
import base64
image_all = None
load_cache = {}
def fresh_image():
global image_all
if (image_all == None):
with open(os.path.dirname(__file__).replace("\\", "/")+"/res.pickle", "rb") as file:
image_all = pickle.load(file)
fresh_image()
def loadimg(imgid: str):
global image_all
if imgid not in load_cache:
load_cache[imgid] = tkinter.PhotoImage(
data=base64.b64decode(image_all[imgid]))
return load_cache[imgid]

BIN
magictk/res.pickle Normal file

Binary file not shown.

264
magictk/window.py Normal file
View File

@ -0,0 +1,264 @@
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
WIN_INF = 10000
class Window():
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.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=color_tmpl.setlight(self.color["border_base"], 0.8))
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)
def __init__(self, w=500, h=350, title="MagicTk", color_list: None | dict = None) -> None:
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)
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_windwow)
self.__fake_tk.resizable(0, 0)
self.__init_weights(self.main_tk)
self.main_tk.iconbitmap(os.path.dirname(__file__)+os.sep+"icon.ico")
self.__fake_tk.iconbitmap(os.path.dirname(__file__)+os.sep+"icon.ico")
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()
for i in self.anim:
i()
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_windwow(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_windwow()
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_windwow()
self.update_icon()

68
magictk/workspace.py Normal file
View File

@ -0,0 +1,68 @@
import os
import subprocess
import sys
from typing import Optional, Tuple
def get_windows_workspace_size() -> Optional[Tuple[int, int, int, int]]:
try:
import win32api
import win32gui
# 获取工作区(不包括任务栏)的尺寸
work_area = win32api.GetMonitorInfo(
win32api.MonitorFromPoint((0, 0))).get('Work')
x, y, width, height = work_area
width -= x
height -= y
return x, y, width, height
except ImportError:
print("pywin32 library is not installed.")
except Exception as e:
print(f"An error occurred: {e}")
return (0, 0, 1920, 1002)
def get_linux_workspace_size() -> Optional[Tuple[int, int, int, int]]:
try:
output = subprocess.check_output(['xrandr']).decode('utf-8')
lines = output.split('\n')
primary_monitor = None
for line in lines:
if 'primary' in line:
primary_monitor = line.split()[-1]
if primary_monitor and primary_monitor in line:
dimensions = line.split()[0].split('x')
width = int(dimensions[0])
height = int(dimensions[1])
# xrandr does not provide the top-left corner directly, assuming (0, 0)
return 0, 0, width, height
except subprocess.CalledProcessError:
pass
return None
def get_macos_workspace_size() -> Optional[Tuple[int, int, int, int]]:
try:
output = subprocess.check_output(
['system_profiler', 'SPDisplaysDataType']).decode('utf-8')
lines = output.split('\n')
for line in lines:
if 'Resolution:' in line:
dimensions = line.split(':')[1].strip().split('x')
width = int(dimensions[0])
height = int(dimensions[1])
# system_profiler does not provide the top-left corner directly, assuming (0, 0)
return 0, 0, width, height
except subprocess.CalledProcessError:
pass
return None
def get_workspace_size() -> Optional[Tuple[int, int, int, int]]:
if sys.platform.startswith('win'):
return get_windows_workspace_size()
elif sys.platform.startswith('linux'):
return get_linux_workspace_size()
elif sys.platform.startswith('darwin'):
return get_macos_workspace_size()
return None

BIN
photo2/res/close.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 B

BIN
photo2/res/close_active.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 B

BIN
photo2/res/icon.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 253 B

BIN
photo2/res/iconic.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 B

BIN
photo2/res/zoom.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 B

BIN
photo2/res/zoom2normal.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 B

14
photo2/run.py Normal file
View File

@ -0,0 +1,14 @@
import os
import pickle
import base64
paths = os.path.dirname(__file__).replace("\\", "/")
pickle_jar = {}
print("packing...")
for i in os.listdir(paths+"/res"):
print(f"pack {i}")
with open(paths+"/res/"+i, "rb") as file:
pickle_jar[i.split(".")[0]] = base64.b64encode(file.read())
print("write...")
with open(paths+"/../magictk/res.pickle", "wb") as file:
pickle.dump(pickle_jar, file)
print("done!")