diff --git a/README.md b/README.md
index 224bc9a..a2ad7e1 100644
--- a/README.md
+++ b/README.md
@@ -24,7 +24,7 @@
-
+
diff --git a/config/material-colors/generate.py b/config/material-colors/generate.py
index 5f43db1..32504e0 100644
--- a/config/material-colors/generate.py
+++ b/config/material-colors/generate.py
@@ -1,40 +1,28 @@
-import argparse
-import hashlib
-import json
import os
-import pickle
import random
-import re
import subprocess
-
-import numpy as np
-from materialyoucolor.dynamiccolor.material_dynamic_colors import (
- MaterialDynamicColors,
-) # type: ignore # noqa
-from materialyoucolor.hct import Hct # type: ignore
-from materialyoucolor.quantize import QuantizeCelebi # type: ignore
-from materialyoucolor.scheme.dynamic_scheme import DynamicScheme # type: ignore # noqa
-from materialyoucolor.scheme.scheme_content import SchemeContent # type: ignore # noqa
-from materialyoucolor.scheme.scheme_expressive import (
- SchemeExpressive,
-) # type: ignore # noqa
-from materialyoucolor.scheme.scheme_fidelity import (
- SchemeFidelity,
-) # type: ignore # noqa
-from materialyoucolor.scheme.scheme_fruit_salad import (
- SchemeFruitSalad,
-) # type: ignore # noqa
-from materialyoucolor.scheme.scheme_monochrome import (
- SchemeMonochrome,
-) # type: ignore # noqa
-from materialyoucolor.scheme.scheme_neutral import SchemeNeutral # type: ignore # noqa
-from materialyoucolor.scheme.scheme_rainbow import SchemeRainbow # type: ignore # noqa
-from materialyoucolor.scheme.scheme_tonal_spot import (
- SchemeTonalSpot,
-) # type: ignore # noqa
-from materialyoucolor.scheme.scheme_vibrant import SchemeVibrant # type: ignore # noqa
-from materialyoucolor.score.score import Score # type: ignore
+import json
from PIL import Image
+import argparse
+from materialyoucolor.quantize import QuantizeCelebi # type: ignore
+from materialyoucolor.score.score import Score # type: ignore
+from materialyoucolor.hct import Hct # type: ignore
+from materialyoucolor.dynamiccolor.material_dynamic_colors import MaterialDynamicColors # type: ignore # noqa
+from materialyoucolor.scheme.dynamic_scheme import DynamicScheme # type: ignore # noqa
+from materialyoucolor.scheme.scheme_tonal_spot import SchemeTonalSpot # type: ignore # noqa
+from materialyoucolor.scheme.scheme_expressive import SchemeExpressive # type: ignore # noqa
+from materialyoucolor.scheme.scheme_fruit_salad import SchemeFruitSalad # type: ignore # noqa
+from materialyoucolor.scheme.scheme_monochrome import SchemeMonochrome # type: ignore # noqa
+from materialyoucolor.scheme.scheme_rainbow import SchemeRainbow # type: ignore # noqa
+from materialyoucolor.scheme.scheme_vibrant import SchemeVibrant # type: ignore # noqa
+from materialyoucolor.scheme.scheme_neutral import SchemeNeutral # type: ignore # noqa
+from materialyoucolor.scheme.scheme_fidelity import SchemeFidelity # type: ignore # noqa
+from materialyoucolor.scheme.scheme_content import SchemeContent # type: ignore # noqa
+import hashlib
+import pickle
+import numpy as np
+import re
+
schemes = {
"tonalSpot": SchemeTonalSpot,
@@ -53,7 +41,7 @@ def join(*args):
return os.path.join(*args)
-home = os.path.expanduser("~")
+home = os.path.expanduser('~')
script_dir = os.path.dirname(os.path.abspath(__file__))
cache_path = f"{home}/.cache/material/"
@@ -61,14 +49,14 @@ os.makedirs(cache_path, exist_ok=True)
def rgb_to_hex(rgb):
- return "#{:02x}{:02x}{:02x}".format(*rgb[:3])
+ return '#{:02x}{:02x}{:02x}'.format(*rgb[:3])
def rgba_to_rgb(rgba):
- return f"{rgba[0]}, {rgba[1]}, {rgba[2]}"
+ return f'{rgba[0]}, {rgba[1]}, {rgba[2]}'
-class Color:
+class Color():
def __init__(self, scheme) -> None:
self.scheme = scheme
@@ -82,12 +70,8 @@ class Color:
class ColorsCache:
def __init__(
- self,
- colors: DynamicScheme | dict,
- wallpaper: str,
- original_color: int,
- contrast_level: int,
- scheme_name: str,
+ self, colors: DynamicScheme | dict, wallpaper: str,
+ original_color: int, contrast_level: int, scheme_name: str
) -> None:
self.colors: dict[str, str] = {}
self.wallpaper = wallpaper
@@ -111,7 +95,7 @@ def colors_dict(cache: ColorsCache):
"colors": cache.colors,
"original_color": cache.original_color,
"contrast_level": cache.contrast_level,
- "scheme_name": cache.scheme_name,
+ "scheme_name": cache.scheme_name
}
return dict
@@ -124,7 +108,10 @@ def get_cache_object(object: dict | str):
original_color = object["original_color"]
contrast_level = object.get("contrast_level", 0)
scheme_name = object.get("scheme_name", "tonalSpot")
- return ColorsCache(colors, wallpaper, original_color, contrast_level, scheme_name)
+ return ColorsCache(
+ colors, wallpaper, original_color,
+ contrast_level, scheme_name
+ )
def get_file_list(folder_path):
@@ -137,9 +124,11 @@ def get_file_list(folder_path):
ready_templates = {
"colors.css": "@define-color {name} {hex};\n",
- "colors.scss": "${name}: {hex};\n",
+ "colors.scss": "${name}: {hex};\n"
+}
+additional = {
+ "onBackground": "foreground"
}
-additional = {"onBackground": "foreground"}
def generate_color_map(scheme: DynamicScheme):
@@ -158,23 +147,25 @@ class ColorFormatter:
def apply_transformations(self, value, transformations):
intermediate_transforms = [
- t for t in transformations if not (t.startswith("strip") or t == "rgb")
+ t for t in transformations
+ if not (t.startswith("strip") or t == "rgb")
]
final_transforms = [
- t for t in transformations if t.startswith("strip") or t == "rgb"
+ t for t in transformations
+ if t.startswith("strip") or t == "rgb"
]
for transform in intermediate_transforms:
if transform.startswith("lighten"):
- percent = int(re.search(r"\d+", transform).group())
+ percent = int(re.search(r'\d+', transform).group())
value = self.adjust_brightness(value, percent)
elif transform.startswith("darken"):
- percent = int(re.search(r"\d+", transform).group())
+ percent = int(re.search(r'\d+', transform).group())
value = self.adjust_brightness(value, -percent)
for transform in final_transforms:
if transform.startswith("strip"):
- value = value.lstrip("#")
+ value = value.lstrip('#')
elif transform == "rgb":
value = self.hex_to_rgb(value)
@@ -184,22 +175,24 @@ class ColorFormatter:
def min_max(v):
return min(255, max(0, v))
- hex_color = hex_color.lstrip("#")
- r, g, b = (int(hex_color[i : i + 2], 16) for i in (0, 2, 4))
+ hex_color = hex_color.lstrip('#')
+ r, g, b = (int(hex_color[i:i+2], 16) for i in (0, 2, 4))
r = min_max(int(r * (1 + factor / 100)))
g = min_max(int(g * (1 + factor / 100)))
b = min_max(int(b * (1 + factor / 100)))
- return f"#{r:02X}{g:02X}{b:02X}".lower()
+ return f'#{r:02X}{g:02X}{b:02X}'.lower()
def hex_to_rgb(self, hex_color):
- hex_color = hex_color.lstrip("#")
- r, g, b = (int(hex_color[i : i + 2], 16) for i in (0, 2, 4))
- return f"{r},{g},{b}"
+ hex_color = hex_color.lstrip('#')
+ r, g, b = (int(hex_color[i:i+2], 16) for i in (0, 2, 4))
+ return f'{r},{g},{b}'
def parse_transformations(self, transformations_str):
- transformations = re.findall(r"(\w+)(?:\((\d*)\))?", transformations_str)
+ transformations = re.findall(
+ r'(\w+)(?:\((\d*)\))?', transformations_str
+ )
result = []
for command, arg in transformations:
if command:
@@ -210,7 +203,7 @@ class ColorFormatter:
return result
def format(self, text):
- pattern = r"(<(\w+)(?:\.(.+))?>)"
+ pattern = r'(<(\w+)(?:\.(.+))?>)'
matches = re.findall(pattern, text)
result = []
last_end = 0
@@ -218,30 +211,27 @@ class ColorFormatter:
for match in matches:
full_match, key, transformations_str = match
if key in self.color_map:
- result.append(text[last_end : text.find(full_match, last_end)])
+ result.append(text[last_end:text.find(full_match, last_end)])
value = self.color_map[key]
if transformations_str:
- transformations = self.parse_transformations(transformations_str)
+ transformations = self.parse_transformations(
+ transformations_str
+ )
value = self.apply_transformations(value, transformations)
result.append(value)
last_end = text.find(full_match, last_end) + len(full_match)
result.append(text[last_end:])
- result = "".join(result)
- pattern = r"<\\\\([^>]+)>"
+ result = ''.join(result)
+ pattern = r'<\\\\([^>]+)>'
- result = re.sub(pattern, r"<\1>", result)
+ result = re.sub(pattern, r'<\1>', result)
return result
-def generate_templates(
- folder: str,
- output_folder: str,
- scheme: DynamicScheme,
- color_scheme: str,
- wallpaper: str = "",
-):
+def generate_templates(folder: str, output_folder: str, scheme: DynamicScheme,
+ color_scheme: str, wallpaper: str = ''):
if not os.path.exists(output_folder):
os.makedirs(output_folder)
if not os.path.exists(folder):
@@ -254,14 +244,41 @@ def generate_templates(
formatter = ColorFormatter(scheme)
template = formatter.format(template)
template = (
- template.replace("", color_scheme)
+ template
+ .replace("", color_scheme)
.replace("", output_folder)
.replace("", wallpaper)
)
new_path = join(output_folder, os.path.basename(file_path))
- with open(new_path, "w") as f:
+ with open(new_path, 'w') as f:
f.write(template)
+ for file in ready_templates:
+ _template = ""
+ for color in vars(MaterialDynamicColors).keys():
+ color_name = getattr(MaterialDynamicColors, color)
+ if hasattr(color_name, "get_hct"):
+ rgba = color_name.get_hct(scheme).to_rgba()
+ hex_color = rgb_to_hex(rgba)
+ rgb_color = rgba_to_rgb(rgba)
+ new_line = ready_templates[file].format(
+ name=color,
+ hex=hex_color,
+ rgb=rgb_color
+ )
+ _template += new_line
+ if color in additional:
+ new_line = ready_templates[file].format(
+ name=additional[color],
+ hex=hex_color,
+ rgb=rgb_color
+ )
+ _template += new_line
+
+ new_path = join(output_folder, os.path.basename(file))
+ with open(new_path, 'w') as f:
+ f.write(_template)
+
def run_hooks(folder: str):
if not os.path.exists(folder):
@@ -270,9 +287,9 @@ def run_hooks(folder: str):
for file_path in file_list:
file_name = os.path.basename(file_path)
if str(file_name).endswith(".py"):
- subprocess.run(["python", "-O", file_path])
+ subprocess.run(['python', '-O', file_path])
elif str(file_name).endswith(".sh"):
- subprocess.run(["sh", file_path])
+ subprocess.run(['sh', file_path])
def process_image(image_path, quality=2, num_colors=128):
@@ -280,18 +297,18 @@ def process_image(image_path, quality=2, num_colors=128):
global cache_path
_cache_path = join(cache_path, "cached_colors")
hash_object = hashlib.md5(image_path.encode())
- cache_filename = hash_object.hexdigest() + ".pkl"
+ cache_filename = hash_object.hexdigest() + '.pkl'
os.makedirs(_cache_path, exist_ok=True)
return join(_cache_path, cache_filename)
def load_from_cache(cache_path):
if os.path.exists(cache_path):
- with open(cache_path, "rb") as f:
+ with open(cache_path, 'rb') as f:
return pickle.load(f)
return None
def save_to_cache(cache_path, data):
- with open(cache_path, "wb") as f:
+ with open(cache_path, 'wb') as f:
pickle.dump(data, f)
cache_path = get_cache_path(image_path)
@@ -300,7 +317,7 @@ def process_image(image_path, quality=2, num_colors=128):
if cached_result is not None:
return cached_result
- image = Image.open(image_path).convert("RGB")
+ image = Image.open(image_path).convert('RGB')
image_data = np.array(image)
pixel_array = image_data[::quality, ::quality].reshape(-1, 3)
@@ -315,11 +332,8 @@ def process_image(image_path, quality=2, num_colors=128):
def main(
- color_scheme: str,
- image_path: str,
- use_color: int | None = None,
- scheme_name: str | None = None,
- contrast_level: int = 0,
+ color_scheme: str, image_path: str, use_color: int | None = None,
+ scheme_name: str | None = None, contrast_level: int = 0
):
scheme_name = scheme_name or "tonalSpot"
scheme = schemes[scheme_name]
@@ -330,24 +344,34 @@ def main(
else:
color = use_color
- scheme = scheme(Hct.from_int(color), is_dark, contrast_level)
+ scheme = scheme(
+ Hct.from_int(color),
+ is_dark,
+ contrast_level
+ )
# for color in vars(MaterialDynamicColors).keys():
# color_name = getattr(MaterialDynamicColors, color)
# if hasattr(color_name, "get_hct"):
# print(color, rgb_to_hex(color_name.get_hct(scheme).to_rgba()))
- with open(join(cache_path, "colors.json"), "w") as f:
- object = ColorsCache(scheme, image_path, color, contrast_level, scheme_name)
+ with open(join(cache_path, "colors.json"), 'w') as f:
+ object = ColorsCache(
+ scheme, image_path, color, contrast_level, scheme_name
+ )
json.dump(colors_dict(object), f, indent=2)
generate_templates(
f"{script_dir}/templates", cache_path, scheme, color_scheme, image_path
)
+ generate_templates(
+ f"{script_dir}/templates/svg", join(cache_path, "svg/"), scheme,
+ color_scheme, image_path
+ )
if is_dark:
- subprocess.run(["sh", join(script_dir, "gtk-material.sh")])
+ subprocess.run(['sh', join(script_dir, 'gtk-material.sh')])
else:
- subprocess.run(["sh", join(script_dir, "gtk-material.sh"), "--light"])
+ subprocess.run(['sh', join(script_dir, 'gtk-material.sh'), '--light'])
run_hooks(join(script_dir, "hooks"))
@@ -355,27 +379,26 @@ def main(
def _argparse() -> tuple[bool, bool, str, str, str, str]:
parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group(required=True)
- group.add_argument("-R", help="Restore previous colorscheme.", action="store_true")
group.add_argument(
- "-w", help="Use last used wallpaper for color generation.", action="store_true"
+ "-R", help="Restore previous colorscheme.", action='store_true'
+ )
+ group.add_argument(
+ "-w", help="Use last used wallpaper for color generation.",
+ action='store_true'
+ )
+ group.add_argument(
+ "--image", type=str, help="Image for color scheme generation"
)
- group.add_argument("--image", type=str, help="Image for color scheme generation")
group.add_argument(
"--color", type=str, help="Main color for color scheme generation"
)
parser.add_argument(
- "--color-scheme",
- type=str,
- default="dark",
- choices=["dark", "light"],
- help="Color scheme variant",
+ '--color-scheme', type=str, default='dark', choices=['dark', 'light'],
+ help="Color scheme variant"
)
parser.add_argument(
- "--scheme",
- type=str,
- default="",
- choices=list(schemes.keys()),
- help="Scheme for color generation",
+ '--scheme', type=str, default="",
+ choices=list(schemes.keys()), help="Scheme for color generation"
)
args = parser.parse_args()
@@ -387,23 +410,15 @@ def _argparse() -> tuple[bool, bool, str, str, str, str]:
use_color = args.color
scheme = args.scheme
return (
- restore_palette,
- use_last_used_wallpaper,
- image,
- color_scheme,
- use_color,
- scheme,
+ restore_palette, use_last_used_wallpaper, image,
+ color_scheme, use_color, scheme
)
def _main():
(
- restore_palette,
- use_last_used_wallpaper,
- image,
- color_scheme,
- use_color,
- scheme,
+ restore_palette, use_last_used_wallpaper, image,
+ color_scheme, use_color, scheme
) = _argparse()
if not scheme:
scheme = None
@@ -412,17 +427,13 @@ def _main():
with open(join(cache_path, "colors.json")) as f:
content = get_cache_object(f.read())
main(
- color_scheme,
- image_path=content.wallpaper,
- use_color=int(use_color.lstrip("#"), 16),
- scheme_name=scheme,
+ color_scheme, image_path=content.wallpaper,
+ use_color=int(use_color.lstrip('#'), 16), scheme_name=scheme
)
except Exception:
main(
- color_scheme,
- image_path="/dev/null",
- use_color=int(use_color.lstrip("#"), 16),
- scheme_name=scheme,
+ color_scheme, image_path="/dev/null",
+ use_color=int(use_color.lstrip('#'), 16), scheme_name=scheme
)
elif restore_palette:
@@ -433,7 +444,7 @@ def _main():
image_path=content.wallpaper,
use_color=content.original_color,
scheme_name=scheme or content.scheme_name,
- contrast_level=content.contrast_level,
+ contrast_level=content.contrast_level
)
elif use_last_used_wallpaper:
with open(join(cache_path, "colors.json")) as f:
@@ -442,12 +453,13 @@ def _main():
color_scheme,
image_path=content.wallpaper,
scheme_name=scheme or content.scheme_name,
- contrast_level=content.contrast_level,
+ contrast_level=content.contrast_level
)
else:
if os.path.isdir(image):
files = [
- f for f in os.listdir(image) if f.endswith((".png", ".jpg", ".jpeg"))
+ f for f in os.listdir(image)
+ if f.endswith(('.png', '.jpg', '.jpeg'))
]
if files:
image = join(image, random.choice(files))
diff --git a/config/dark-theme.sh b/config/scripts/dark-theme.sh
similarity index 92%
rename from config/dark-theme.sh
rename to config/scripts/dark-theme.sh
index fcb5461..a43afcf 100755
--- a/config/dark-theme.sh
+++ b/config/scripts/dark-theme.sh
@@ -14,8 +14,8 @@ get_relative_path() {
}
# Assign relative paths to variables
-GENERATOR=$(get_relative_path "./material-colors/generate.py")
-SETTINGS_FILE=$(get_relative_path "./assets/settings.json")
+GENERATOR=$(get_relative_path "../material-colors/generate.py")
+SETTINGS_FILE=$(get_relative_path "../assets/settings.json")
# Function to read a value from the JSON file
get_json_value() {
diff --git a/config/wallpaper.py b/config/scripts/wallpaper.py
similarity index 99%
rename from config/wallpaper.py
rename to config/scripts/wallpaper.py
index 1703b5a..02c8403 100644
--- a/config/wallpaper.py
+++ b/config/scripts/wallpaper.py
@@ -22,7 +22,7 @@ def get_relative_path(path: str, level: int = 1) -> str:
lock_file_path = "/tmp/wallpaper.lock"
-settings_file_path = get_relative_path("../config/assets/settings.json")
+settings_file_path = get_relative_path("../assets/settings.json")
def acquire_lock():
diff --git a/config/wayland-idle-inhibitor.py b/config/scripts/wayland-idle-inhibitor.py
similarity index 100%
rename from config/wayland-idle-inhibitor.py
rename to config/scripts/wayland-idle-inhibitor.py
diff --git a/modules/launcher/components/wallpapers.py b/modules/launcher/components/wallpapers.py
index bf05e60..869a6c7 100644
--- a/modules/launcher/components/wallpapers.py
+++ b/modules/launcher/components/wallpapers.py
@@ -156,7 +156,7 @@ class WallpaperSelector(Box):
new_mode = "dark" if not current_state else "light"
# Call the shell script with the --set argument
- command = f"bash {get_relative_path('../../../config/dark-theme.sh')} --set {new_mode}"
+ command = f"bash {get_relative_path('../../../config/scripts/dark-theme.sh')} --set {new_mode}"
GLib.spawn_command_line_async(command)
# Set the appropriate icon based on the mode