2023-01-22 01:35:32 +02:00
|
|
|
from json import JSONDecodeError, dumps, loads
|
2023-01-23 13:22:54 +02:00
|
|
|
from os import path
|
|
|
|
from os import name as osname
|
|
|
|
from tkinter import Misc, PhotoImage
|
2023-01-22 18:53:55 +02:00
|
|
|
from typing import Any, Literal
|
2023-01-22 01:35:32 +02:00
|
|
|
|
2023-01-22 01:22:08 +02:00
|
|
|
import darkdetect
|
|
|
|
|
2023-01-22 01:35:32 +02:00
|
|
|
|
2023-01-22 01:22:08 +02:00
|
|
|
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]
|
|
|
|
|
2023-01-22 18:53:55 +02:00
|
|
|
def use_dark_mode(no_config=False) -> bool:
|
2023-01-22 01:22:08 +02:00
|
|
|
"""Return whether dark mode should be used
|
|
|
|
|
|
|
|
### Returns:
|
|
|
|
* `bool`: True if yes and False if no
|
|
|
|
"""
|
|
|
|
|
2023-01-22 18:53:55 +02:00
|
|
|
if no_config is True:
|
|
|
|
return bool(darkdetect.isDark())
|
|
|
|
|
2023-01-22 01:22:08 +02:00
|
|
|
if configGet("dark_mode_auto") is True:
|
|
|
|
return bool(darkdetect.isDark())
|
|
|
|
else:
|
2023-01-22 18:53:55 +02:00
|
|
|
return configGet("dark_mode")
|
|
|
|
|
|
|
|
def get_string_mode() -> Literal["dark", "light"]:
|
|
|
|
"""Return whether dark mode is used
|
|
|
|
|
|
|
|
### Returns:
|
|
|
|
* `Literal["dark", "light"]`
|
|
|
|
"""
|
|
|
|
|
2023-01-23 13:22:54 +02:00
|
|
|
return "dark" if use_dark_mode() is True else "light"
|
|
|
|
|
2023-01-23 17:38:47 +02:00
|
|
|
def resize_window(me: Misc, width: int, height: int) -> None:
|
|
|
|
me.window_width = width
|
|
|
|
me.window_height = height
|
|
|
|
|
|
|
|
me.screen_width = me.winfo_screenwidth()
|
|
|
|
me.screen_height = me.winfo_screenheight()
|
|
|
|
|
|
|
|
me.center_x = int(me.screen_width/2 - me.window_width / 2)
|
|
|
|
me.center_y = int(me.screen_height/2 - me.window_height / 2)
|
|
|
|
|
|
|
|
me.geometry(f'{me.window_width}x{me.window_height}+{me.center_x}+{me.center_y}')
|
|
|
|
|
2023-01-23 13:22:54 +02:00
|
|
|
def set_icon(me: Misc) -> None:
|
|
|
|
if osname == "nt":
|
|
|
|
me.iconbitmap(path.join("assets", "favicon.ico"))
|
|
|
|
else:
|
|
|
|
me.iconphoto(True, PhotoImage(file=path.join("assets", "favicon.png")))
|