[SCRIPT] Updated
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
from .service import MaterialService
|
||||
|
||||
__all__ = ["MaterialService"]
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,11 @@
|
||||
import os
|
||||
import ignis
|
||||
from ignis.utils import Utils
|
||||
|
||||
|
||||
MATERIAL_CACHE_DIR = f"{ignis.CACHE_DIR}/material" # type: ignore
|
||||
|
||||
TEMPLATES = Utils.get_current_dir() + "/templates"
|
||||
SAMPLE_WALL = Utils.get_current_dir() + "/sample_wall.png"
|
||||
|
||||
os.makedirs(MATERIAL_CACHE_DIR, exist_ok=True)
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.1 MiB |
@@ -0,0 +1,144 @@
|
||||
#!/usr/bin/python
|
||||
import os
|
||||
|
||||
from jinja2 import Template
|
||||
from PIL import Image
|
||||
from materialyoucolor.quantize import QuantizeCelebi
|
||||
from materialyoucolor.hct import Hct
|
||||
from materialyoucolor.scheme.scheme_tonal_spot import SchemeTonalSpot
|
||||
from materialyoucolor.dynamiccolor.material_dynamic_colors import MaterialDynamicColors
|
||||
from materialyoucolor.score.score import Score
|
||||
|
||||
from ignis.utils import Utils
|
||||
from ignis.app import IgnisApp
|
||||
from ignis.base_service import BaseService
|
||||
from ignis.services.wallpaper import CACHE_WALLPAPER_PATH
|
||||
from gi.repository import GObject # type: ignore
|
||||
from ignis.services.wallpaper import WallpaperService
|
||||
from ignis.services.options import OptionsService
|
||||
|
||||
from .constants import MATERIAL_CACHE_DIR, TEMPLATES, SAMPLE_WALL
|
||||
from .util import rgba_to_hex, calculate_optimal_size
|
||||
|
||||
app = IgnisApp.get_default()
|
||||
|
||||
|
||||
class MaterialService(BaseService):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
self._wallpaper = WallpaperService.get_default()
|
||||
|
||||
options = OptionsService.get_default()
|
||||
opt_group = options.create_group(name="material", exists_ok=True)
|
||||
self._dark_mode_opt = opt_group.create_option(
|
||||
name="dark_mode", default=True, exists_ok=True
|
||||
)
|
||||
self._colors_opt = opt_group.create_option(
|
||||
name="colors", default={}, exists_ok=True
|
||||
)
|
||||
|
||||
if not os.path.exists(CACHE_WALLPAPER_PATH):
|
||||
self.__on_colors_not_found()
|
||||
if self.colors == {}:
|
||||
self.__on_colors_not_found()
|
||||
|
||||
@GObject.Property
|
||||
def dark_mode(self) -> bool:
|
||||
return self._dark_mode_opt.value
|
||||
|
||||
@dark_mode.setter
|
||||
def dark_mode(self, value: bool) -> None:
|
||||
self._dark_mode_opt.value = value
|
||||
self.generate_colors(CACHE_WALLPAPER_PATH)
|
||||
|
||||
@GObject.Property
|
||||
def colors(self) -> dict:
|
||||
return self._colors_opt.value
|
||||
|
||||
def __on_colors_not_found(self) -> None:
|
||||
self._wallpaper.set_wallpaper(SAMPLE_WALL)
|
||||
self.generate_colors(SAMPLE_WALL)
|
||||
Utils.exec_sh_async("hyprctl reload")
|
||||
|
||||
def get_colors_from_img(self, path: str, dark_mode: bool) -> dict[str, str]:
|
||||
image = Image.open(path)
|
||||
wsize, hsize = image.size
|
||||
wsize_new, hsize_new = calculate_optimal_size(wsize, hsize, 128)
|
||||
if wsize_new < wsize or hsize_new < hsize:
|
||||
image = image.resize((wsize_new, hsize_new), Image.Resampling.BICUBIC) # type: ignore
|
||||
|
||||
pixel_len = image.width * image.height
|
||||
image_data = image.getdata()
|
||||
pixel_array = [image_data[_] for _ in range(0, pixel_len, 1)]
|
||||
|
||||
colors = QuantizeCelebi(pixel_array, 128)
|
||||
argb = Score.score(colors)[0]
|
||||
|
||||
hct = Hct.from_int(argb)
|
||||
scheme = SchemeTonalSpot(hct, dark_mode, 0.0)
|
||||
|
||||
material_colors = {}
|
||||
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()
|
||||
material_colors[color] = rgba_to_hex(rgba)
|
||||
|
||||
return material_colors
|
||||
|
||||
def generate_colors(self, path: str) -> None:
|
||||
colors = self.get_colors_from_img(path, self.dark_mode)
|
||||
dark_colors = self.get_colors_from_img(path, True)
|
||||
self._colors_opt.value = colors
|
||||
self.__render_templates(colors, dark_colors)
|
||||
self.__setup(path)
|
||||
|
||||
def __render_templates(self, colors: dict, dark_colors: dict) -> None:
|
||||
for template in os.listdir(TEMPLATES):
|
||||
self.render_template(
|
||||
colors=colors,
|
||||
dark_mode=self.dark_mode,
|
||||
input_file=f"{TEMPLATES}/{template}",
|
||||
output_file=f"{MATERIAL_CACHE_DIR}/{template}",
|
||||
)
|
||||
|
||||
for template in os.listdir(TEMPLATES):
|
||||
self.render_template(
|
||||
colors=dark_colors,
|
||||
dark_mode=True,
|
||||
input_file=f"{TEMPLATES}/{template}",
|
||||
output_file=f"{MATERIAL_CACHE_DIR}/dark_{template}",
|
||||
)
|
||||
|
||||
def render_template(
|
||||
self,
|
||||
colors: dict,
|
||||
input_file: str,
|
||||
output_file: str,
|
||||
dark_mode: bool | None = None,
|
||||
) -> None:
|
||||
if dark_mode is None:
|
||||
colors["dark_mode"] = str(self.dark_mode).lower()
|
||||
else:
|
||||
colors["dark_mode"] = str(dark_mode).lower()
|
||||
with open(input_file) as file:
|
||||
template_rendered = Template(file.read()).render(colors)
|
||||
|
||||
with open(output_file, "w") as file:
|
||||
file.write(template_rendered)
|
||||
|
||||
def __reload_gtk_theme(self) -> None:
|
||||
THEME_CMD = "gsettings set org.gnome.desktop.interface gtk-theme {}"
|
||||
COLOR_SCHEME_CMD = "gsettings set org.gnome.desktop.interface color-scheme {}"
|
||||
Utils.exec_sh_async(THEME_CMD.format("Adwaita"))
|
||||
Utils.exec_sh_async(THEME_CMD.format("Material"))
|
||||
Utils.exec_sh_async(COLOR_SCHEME_CMD.format("default"))
|
||||
Utils.exec_sh_async(COLOR_SCHEME_CMD.format("prefer-dark"))
|
||||
Utils.exec_sh_async(COLOR_SCHEME_CMD.format("default"))
|
||||
|
||||
def __setup(self, image_path: str) -> None:
|
||||
Utils.exec_sh_async("pkill -SIGUSR1 kitty")
|
||||
self._wallpaper.set_wallpaper(image_path)
|
||||
app.reload_css()
|
||||
self.__reload_gtk_theme()
|
||||
@@ -0,0 +1,7 @@
|
||||
$primary = rgb({{ primary | replace("#", "") }})
|
||||
$surface = rgb({{ surface | replace("#", "") }})
|
||||
$onSurface = rgb({{ onSurface | replace("#", "") }})
|
||||
|
||||
$primaryHex = #{{ primary }}
|
||||
$surfaceHex = #{{ surface }}
|
||||
$onSurfaceHex = #{{ onSurface }}
|
||||
@@ -0,0 +1,27 @@
|
||||
foreground {{ onSurface }}
|
||||
background {{ surface }}
|
||||
cursor {{ onSurface }}
|
||||
|
||||
color0 {{ surface }}
|
||||
color8 {{ surface }}
|
||||
|
||||
color1 {{ error }}
|
||||
color9 {{ error }}
|
||||
|
||||
color2 {{ inversePrimary }}
|
||||
color10 {{ inversePrimary }}
|
||||
|
||||
color3 {{ error }}
|
||||
color11 {{ error }}
|
||||
|
||||
color4 {{ primaryContainer }}
|
||||
color12 {{ primaryContainer }}
|
||||
|
||||
color5 {{ onSecondaryContainer }}
|
||||
color13 {{ onSecondaryContainer }}
|
||||
|
||||
color6 {{ primary }}
|
||||
color14 {{ primary }}
|
||||
|
||||
color7 {{ onSurface }}
|
||||
color15 {{ onSurface }}
|
||||
@@ -0,0 +1,55 @@
|
||||
$primary_paletteKeyColor: {{ primary_paletteKeyColor }};
|
||||
$secondary_paletteKeyColor: {{ secondary_paletteKeyColor }};
|
||||
$tertiary_paletteKeyColor: {{ tertiary_paletteKeyColor }};
|
||||
$neutral_paletteKeyColor: {{ neutral_paletteKeyColor }};
|
||||
$neutral_variant_paletteKeyColor: {{ neutral_variant_paletteKeyColor }};
|
||||
$background: {{ background }};
|
||||
$onBackground: {{ onBackground }};
|
||||
$surface: {{ surface }};
|
||||
$surfaceDim: {{ surfaceDim }};
|
||||
$surfaceBright: {{ surfaceBright }};
|
||||
$surfaceContainerLowest: {{ surfaceContainerLowest }};
|
||||
$surfaceContainerLow: {{ surfaceContainerLow }};
|
||||
$surfaceContainer: {{ surfaceContainer }};
|
||||
$surfaceContainerHigh: {{ surfaceContainerHigh }};
|
||||
$surfaceContainerHighest: {{ surfaceContainerHighest }};
|
||||
$onSurface: {{ onSurface }};
|
||||
$surfaceVariant: {{ surfaceVariant }};
|
||||
$onSurfaceVariant: {{ onSurfaceVariant }};
|
||||
$inverseSurface: {{ inverseSurface }};
|
||||
$inverseOnSurface: {{ inverseOnSurface }};
|
||||
$outline: {{ outline }};
|
||||
$outlineVariant: {{ outlineVariant }};
|
||||
$shadow: {{ shadow }};
|
||||
$scrim: {{ scrim }};
|
||||
$surfaceTint: {{ surfaceTint }};
|
||||
$primary: {{ primary }};
|
||||
$onPrimary: {{ onPrimary }};
|
||||
$primaryContainer: {{ primaryContainer }};
|
||||
$onPrimaryContainer: {{ onPrimaryContainer }};
|
||||
$inversePrimary: {{ inversePrimary }};
|
||||
$secondary: {{ secondary }};
|
||||
$onSecondary: {{ onSecondary }};
|
||||
$secondaryContainer: {{ secondaryContainer }};
|
||||
$onSecondaryContainer: {{ onSecondaryContainer }};
|
||||
$tertiary: {{ tertiary }};
|
||||
$onTertiary: {{ onTertiary }};
|
||||
$tertiaryContainer: {{ tertiaryContainer }};
|
||||
$onTertiaryContainer: {{ onTertiaryContainer }};
|
||||
$error: {{ error }};
|
||||
$onError: {{ onError }};
|
||||
$errorContainer: {{ errorContainer }};
|
||||
$onErrorContainer: {{ onErrorContainer }};
|
||||
$primaryFixed: {{ primaryFixed }};
|
||||
$primaryFixedDim: {{ primaryFixedDim }};
|
||||
$onPrimaryFixed: {{ onPrimaryFixed }};
|
||||
$onPrimaryFixedVariant: {{ onPrimaryFixedVariant }};
|
||||
$secondaryFixed: {{ secondaryFixed }};
|
||||
$secondaryFixedDim: {{ secondaryFixedDim }};
|
||||
$onSecondaryFixed: {{ onSecondaryFixed }};
|
||||
$onSecondaryFixedVariant: {{ onSecondaryFixedVariant }};
|
||||
$tertiaryFixed: {{ tertiaryFixed }};
|
||||
$tertiaryFixedDim: {{ tertiaryFixedDim }};
|
||||
$onTertiaryFixed: {{ onTertiaryFixed }};
|
||||
$onTertiaryFixedVariant: {{ onTertiaryFixedVariant }};
|
||||
$darkmode: {{ dark_mode }};
|
||||
@@ -0,0 +1,50 @@
|
||||
@define-color accent_color {{ primary }};
|
||||
@define-color accent_bg_color {{ primary }};
|
||||
@define-color accent_fg_color {{ surface }};
|
||||
@define-color destructive_color {{ errorContainer }};
|
||||
@define-color destructive_bg_color {{ errorContainer }};
|
||||
@define-color destructive_fg_color {{ onSurface }};
|
||||
@define-color success_color {{ tertiary }};
|
||||
@define-color success_bg_color {{ tertiary }};
|
||||
@define-color success_fg_color {{ onSurface }};
|
||||
@define-color warning_color {{ secondary }};
|
||||
@define-color warning_bg_color {{ secondary }};
|
||||
@define-color warning_fg_color {{ onSurface }};
|
||||
@define-color error_color {{ errorContainer }};
|
||||
@define-color error_bg_color {{ errorContainer }};
|
||||
@define-color error_fg_color {{ onSurface }};
|
||||
@define-color window_bg_color {{ surface }};
|
||||
@define-color window_fg_color {{ onSurface }};
|
||||
@define-color view_bg_color {{ surface }};
|
||||
@define-color view_fg_color {{ onSurface }};
|
||||
@define-color headerbar_bg_color {{ surface }};
|
||||
@define-color headerbar_fg_color {{ onSurface }};
|
||||
@define-color headerbar_border_color {{ outline }};
|
||||
@define-color headerbar_backdrop_color {{ surface }};
|
||||
@define-color headerbar_shade_color {{ outline }};
|
||||
@define-color sidebar_bg_color {{ surfaceContainer }};
|
||||
@define-color sidebar_fg_color {{ onSurface }};
|
||||
@define-color sidebar_backdrop_color {{ surfaceContainer }};
|
||||
@define-color card_bg_color {{ surfaceContainer }};
|
||||
@define-color card_fg_color {{ onSurface }};
|
||||
@define-color card_shade_color rgba(0, 0, 0, 0.07);
|
||||
@define-color thumbnail_bg_color {{ surface }};
|
||||
@define-color thumbnail_fg_color {{ onSurface }};
|
||||
@define-color dialog_bg_color {{ surface }};
|
||||
@define-color dialog_fg_color {{ onSurface }};
|
||||
@define-color popover_bg_color {{ surfaceContainer }};
|
||||
@define-color popover_fg_color {{ onSurface }};
|
||||
@define-color shade_color rgba(0, 0, 0, 0.36);
|
||||
@define-color scrollbar_outline_color {{ outline }};
|
||||
|
||||
.navigation-sidebar {
|
||||
background-color: {{ surfaceContainer }};
|
||||
}
|
||||
|
||||
switch:checked {
|
||||
background-color: {{ primary }};
|
||||
}
|
||||
|
||||
switch:checked slider {
|
||||
background-color: {{ onPrimary }};
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
# ---------------------SETTINGS---------------------------#
|
||||
daemonize
|
||||
show-failed-attempts
|
||||
clock
|
||||
screenshot
|
||||
ignore-empty-password
|
||||
indicator
|
||||
font=JetBrainsMono
|
||||
indicator-radius=200
|
||||
indicator-thickness=20
|
||||
|
||||
|
||||
#----------------------EFFECTS----------------------------#
|
||||
effect-blur=9x5
|
||||
effect-vignette=0.5:0.5
|
||||
|
||||
#--------------------INPUT IGNORE-------------------------#
|
||||
grace-no-mouse
|
||||
grace-no-touch
|
||||
|
||||
|
||||
#--------------------DATE & TIME--------------------------#
|
||||
datestr=%a,%e %B
|
||||
timestr=%H:%M
|
||||
fade-in=0.2
|
||||
|
||||
|
||||
#----------------------COLORS-----------------------------#
|
||||
bs-hl-color={{ error }}
|
||||
inside-color=#FFFFFF00
|
||||
ring-color=#FFFFFF00
|
||||
line-color=#FFFFFF00
|
||||
separator-color=#FFFFFF00
|
||||
key-hl-color={{ primaryFixedDim }}
|
||||
text-color={{ primaryFixedDim }}
|
||||
text-caps-lock-color={{ tertiary }}
|
||||
|
||||
ring-clear-color=#FFFFFF00
|
||||
text-clear-color={{ onTertiary }}
|
||||
inside-clear-color={{ tertiary }}
|
||||
line-clear-color=#FFFFFF00
|
||||
|
||||
ring-ver-color=#FFFFFF00
|
||||
text-ver-color={{ onSecondary }}
|
||||
inside-ver-color={{ secondary }}
|
||||
line-ver-color=#FFFFFF00
|
||||
|
||||
ring-wrong-color=#FFFFFF00
|
||||
text-wrong-color={{ onError }}
|
||||
inside-wrong-color={{ error }}
|
||||
line-wrong-color=#FFFFFF00
|
||||
@@ -0,0 +1,18 @@
|
||||
import math
|
||||
|
||||
|
||||
def rgba_to_hex(rgba: list) -> str:
|
||||
return "#{:02x}{:02x}{:02x}".format(*rgba)
|
||||
|
||||
|
||||
def calculate_optimal_size(width: int, height: int, bitmap_size: int) -> tuple:
|
||||
image_area = width * height
|
||||
bitmap_area = bitmap_size**2
|
||||
scale = math.sqrt(bitmap_area / image_area) if image_area > bitmap_area else 1
|
||||
new_width = round(width * scale)
|
||||
new_height = round(height * scale)
|
||||
if new_width == 0:
|
||||
new_width = 1
|
||||
if new_height == 0:
|
||||
new_height = 1
|
||||
return new_width, new_height
|
||||
Reference in New Issue
Block a user