Initial commit
This commit is contained in:
52
modules/dark_titlebar.py
Normal file
52
modules/dark_titlebar.py
Normal file
@@ -0,0 +1,52 @@
|
||||
import ctypes
|
||||
import os
|
||||
import platform
|
||||
import sys
|
||||
import tkinter
|
||||
from typing import Literal
|
||||
from distutils.version import StrictVersion as Version
|
||||
|
||||
def dark_title_bar(window, mode: Literal["dark", "light"]):
|
||||
"""
|
||||
MORE INFO:
|
||||
https://learn.microsoft.com/en-us/windows/win32/api/dwmapi/ne-dwmapi-dwmwindowattribute
|
||||
"""
|
||||
|
||||
if mode == "dark":
|
||||
value = 1
|
||||
elif mode == "light":
|
||||
value = 0
|
||||
else:
|
||||
raise ValueError()
|
||||
|
||||
try:
|
||||
|
||||
window.update()
|
||||
|
||||
if sys.platform.startswith("win"):
|
||||
|
||||
hwnd = ctypes.windll.user32.GetParent(window.winfo_id())
|
||||
DWMWA_USE_IMMERSIVE_DARK_MODE = 20
|
||||
DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1 = 19
|
||||
|
||||
# try with DWMWA_USE_IMMERSIVE_DARK_MODE
|
||||
if ctypes.windll.dwmapi.DwmSetWindowAttribute(hwnd, DWMWA_USE_IMMERSIVE_DARK_MODE, ctypes.byref(ctypes.c_int(value)), ctypes.sizeof(ctypes.c_int(value))) != 0:
|
||||
|
||||
# try with DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20h1
|
||||
ctypes.windll.dwmapi.DwmSetWindowAttribute(hwnd, DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1, ctypes.byref(ctypes.c_int(value)), ctypes.sizeof(ctypes.c_int(value)))
|
||||
|
||||
elif sys.platform == "darwin":
|
||||
|
||||
if value == 1:
|
||||
if Version(platform.python_version()) < Version("3.10"):
|
||||
if Version(tkinter.Tcl().call("info", "patchlevel")) >= Version("8.6.9"): # Tcl/Tk >= 8.6.9
|
||||
os.system("defaults write -g NSRequiresAquaSystemAppearance -bool No")
|
||||
# This command allows dark-mode for all programs
|
||||
else:
|
||||
if Version(platform.python_version()) < Version("3.10"):
|
||||
if Version(tkinter.Tcl().call("info", "patchlevel")) >= Version("8.6.9"): # Tcl/Tk >= 8.6.9
|
||||
os.system("defaults delete -g NSRequiresAquaSystemAppearance")
|
||||
# This command reverts the dark-mode setting for all programs.
|
||||
|
||||
except Exception as err:
|
||||
print(err)
|
3
modules/logger.py
Normal file
3
modules/logger.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from logging import Logger
|
||||
|
||||
logger = Logger("default")
|
80
modules/utils.py
Normal file
80
modules/utils.py
Normal file
@@ -0,0 +1,80 @@
|
||||
from json import JSONDecodeError, loads, dumps
|
||||
from typing import Any
|
||||
import darkdetect
|
||||
|
||||
def jsonLoad(filename):
|
||||
"""Loads arg1 as json and returns its contents"""
|
||||
with open(filename, "r", encoding='utf8') as file:
|
||||
try:
|
||||
output = loads(file.read())
|
||||
except JSONDecodeError:
|
||||
raise
|
||||
except FileNotFoundError:
|
||||
raise
|
||||
return output
|
||||
|
||||
def jsonSave(contents, filename):
|
||||
"""Dumps dict/list arg1 to file arg2"""
|
||||
try:
|
||||
with open(filename, "w", encoding='utf8') as file:
|
||||
file.write(dumps(contents, ensure_ascii=False, indent=4))
|
||||
except Exception as exp:
|
||||
raise
|
||||
return
|
||||
|
||||
|
||||
def nested_set(dic, keys, value, create_missing=True):
|
||||
d = dic
|
||||
for key in keys[:-1]:
|
||||
if key in d:
|
||||
d = d[key]
|
||||
elif create_missing:
|
||||
d = d.setdefault(key, {})
|
||||
else:
|
||||
return dic
|
||||
if keys[-1] in d or create_missing:
|
||||
d[keys[-1]] = value
|
||||
return dic
|
||||
|
||||
def configSet(keys: list, value: Any, create_missing=True) -> None:
|
||||
"""Set config's value to provided one
|
||||
|
||||
### Args:
|
||||
* keys (`list`): List of keys from the highest one to target.
|
||||
* value (`Any`): Needed value.
|
||||
* create_missing (`bool`, optional): Create missing items on the way. Defaults to True.
|
||||
"""
|
||||
this_dict = jsonLoad("config.json")
|
||||
this_dict = nested_set(this_dict, keys, value, create_missing=create_missing)
|
||||
jsonSave(this_dict, "config.json")
|
||||
return
|
||||
|
||||
def configGet(key: str, *args: str) -> Any:
|
||||
"""Get value of the config key
|
||||
### Args:
|
||||
* key (`str`): The last key of the keys path.
|
||||
* *args (`str`): Path to key like: dict[args][key].
|
||||
### Returns:
|
||||
* any: Value of provided key
|
||||
"""
|
||||
try:
|
||||
this_dict = jsonLoad("config.json")
|
||||
except FileNotFoundError:
|
||||
print("Config file not found!", flush=True)
|
||||
exit()
|
||||
this_key = this_dict
|
||||
for dict_key in args:
|
||||
this_key = this_key[dict_key]
|
||||
return this_key[key]
|
||||
|
||||
def use_dark_mode() -> bool:
|
||||
"""Return whether dark mode should be used
|
||||
|
||||
### Returns:
|
||||
* `bool`: True if yes and False if no
|
||||
"""
|
||||
|
||||
if configGet("dark_mode_auto") is True:
|
||||
return bool(darkdetect.isDark())
|
||||
else:
|
||||
return configGet("dark_mode")
|
Reference in New Issue
Block a user