summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author2 * r + 2 * t <61896496+soramanew@users.noreply.github.com>2025-03-08 22:25:51 +1100
committer2 * r + 2 * t <61896496+soramanew@users.noreply.github.com>2025-03-08 22:25:51 +1100
commit08af99b57d246fffb7bd58f31d52ecd13716558f (patch)
tree5504891bb11b46491f58417ca8f9cce023d59b18
parentscheme: allow choosing material scheme (diff)
downloadcaelestia-cli-08af99b57d246fffb7bd58f31d52ecd13716558f.tar.gz
caelestia-cli-08af99b57d246fffb7bd58f31d52ecd13716558f.tar.bz2
caelestia-cli-08af99b57d246fffb7bd58f31d52ecd13716558f.zip
scheme: optimise dynamic scheme gen
Make material schemes flavours of dynamic instead Remove dynamic-scheme subcommand Optimise scheme generation
-rw-r--r--completions/caelestia.fish3
-rwxr-xr-xmain.fish7
-rwxr-xr-xscheme/gen-scheme.fish27
-rwxr-xr-xscheme/genmaterial.py124
-rwxr-xr-xwallpaper.fish22
5 files changed, 86 insertions, 97 deletions
diff --git a/completions/caelestia.fish b/completions/caelestia.fish
index 2dc5675..b2a2916 100644
--- a/completions/caelestia.fish
+++ b/completions/caelestia.fish
@@ -1,6 +1,6 @@
set -l seen '__fish_seen_subcommand_from'
set -l has_opt '__fish_contains_opt'
-set -l commands help install shell toggle workspace-action scheme dynamic-scheme screenshot record clipboard clipboard-delete emoji-picker wallpaper pip
+set -l commands help install shell toggle workspace-action scheme screenshot record clipboard clipboard-delete emoji-picker wallpaper pip
set -l not_seen "not $seen $commands"
# Disable file completions
@@ -13,7 +13,6 @@ complete -c caelestia -n $not_seen -a 'shell' -d 'Start the shell or message it'
complete -c caelestia -n $not_seen -a 'toggle' -d 'Toggle a special workspace'
complete -c caelestia -n $not_seen -a 'workspace-action' -d 'Exec a dispatcher in the current group'
complete -c caelestia -n $not_seen -a 'scheme' -d 'Switch the current colour scheme'
-complete -c caelestia -n $not_seen -a 'dynamic-scheme' -d 'Change the dynamic colour scheme'
complete -c caelestia -n $not_seen -a 'screenshot' -d 'Take a screenshot'
complete -c caelestia -n $not_seen -a 'record' -d 'Take a screen recording'
complete -c caelestia -n $not_seen -a 'clipboard' -d 'Open clipboard history'
diff --git a/main.fish b/main.fish
index ee126c6..bf27d6c 100755
--- a/main.fish
+++ b/main.fish
@@ -34,12 +34,6 @@ if test "$argv[1]" = scheme
exit
end
-if test "$argv[1]" = dynamic-scheme
- echo -n "$argv[2]" > $C_STATE/scheme/dynamic-scheme.txt
- $src/wallpaper.fish -f $C_STATE/wallpaper/current
- exit
-end
-
if test "$argv[1]" = install
set -l valid_modules scripts discord firefox fish foot fuzzel hypr safeeyes shell gtk vscode
if test "$argv[2]" = all
@@ -72,7 +66,6 @@ echo ' shell: start the shell or message it'
echo ' toggle: toggle a special workspace'
echo ' workspace-action: execute a Hyprland workspace dispatcher in the current group'
echo ' scheme: change the current colour scheme'
-echo ' dynamic-scheme: change the current dynamic material colour scheme'
echo ' screenshot: take a screenshot'
echo ' record: take a screen recording'
echo ' clipboard: open clipboard history'
diff --git a/scheme/gen-scheme.fish b/scheme/gen-scheme.fish
index 7ac0d0e..4e82882 100755
--- a/scheme/gen-scheme.fish
+++ b/scheme/gen-scheme.fish
@@ -4,18 +4,27 @@ set -l src (dirname (status filename))
. $src/../util.fish
-test -f "$argv[1]" && set -l img "$argv[1]" || set -l img $C_STATE/wallpaper/current
-set -l img (realpath $img)
+test -f "$argv[1]" && set -l img (realpath "$argv[1]") || set -l img $C_STATE/wallpaper/thumbnail.jpg
contains -- "$argv[2]" light dark && set -l theme $argv[2] || set -l theme dark
-test -n "$argv[3]" && set -l scheme $argv[3] || set -l scheme (cat $C_STATE/scheme/dynamic-scheme.txt 2> /dev/null || echo 'vibrant')
+
+set -l variants vibrant tonalspot expressive fidelity fruitsalad rainbow neutral content
# Generate colours
-if test $scheme = 'monochrome'
- $src/autoadjust.py $theme $scheme (okolors $img -k 14)
-else
- test $theme = light && set -l lightness 50 || set -l lightness 70
- $src/autoadjust.py $theme $scheme (okolors $img -k 14 -w 0 -l $lightness)
+test $theme = light && set -l lightness 50 || set -l lightness 70
+set -l colours (okolors $img -k 14 -w 0 -l $lightness)
+for variant in $variants
+ mkdir -p $src/../data/schemes/dynamic/$variant
+ $src/autoadjust.py $theme $variant $colours > $src/../data/schemes/dynamic/$variant/$theme.txt
end
+mkdir -p $src/../data/schemes/dynamic/monochrome
+$src/autoadjust.py $theme monochrome (okolors $img -k 14) > $src/../data/schemes/dynamic/monochrome/$theme.txt
+
+set -la variants monochrome
# Generate layers and accents
-$src/genmaterial.py $img $theme $scheme | head -c -1 # Trim trailing newline
+set -l tmp (mktemp)
+$src/genmaterial.py $img $theme > $tmp
+for variant in $variants
+ grep -FA 15 $variant $tmp | tail -15 | head -c -1 >> $src/../data/schemes/dynamic/$variant/$theme.txt
+end
+rm $tmp
diff --git a/scheme/genmaterial.py b/scheme/genmaterial.py
index 0ac4c71..0fb067f 100755
--- a/scheme/genmaterial.py
+++ b/scheme/genmaterial.py
@@ -6,9 +6,17 @@ from colorsys import hls_to_rgb, rgb_to_hls
from materialyoucolor.dynamiccolor.material_dynamic_colors import MaterialDynamicColors
from materialyoucolor.hct import Hct
-from materialyoucolor.quantize import QuantizeCelebi
+from materialyoucolor.quantize import ImageQuantizeCelebi
+from materialyoucolor.scheme.scheme_content import SchemeContent
+from materialyoucolor.scheme.scheme_expressive import SchemeExpressive
+from materialyoucolor.scheme.scheme_fidelity import SchemeFidelity
+from materialyoucolor.scheme.scheme_fruit_salad import SchemeFruitSalad
+from materialyoucolor.scheme.scheme_monochrome import SchemeMonochrome
+from materialyoucolor.scheme.scheme_neutral import SchemeNeutral
+from materialyoucolor.scheme.scheme_rainbow import SchemeRainbow
+from materialyoucolor.scheme.scheme_tonal_spot import SchemeTonalSpot
+from materialyoucolor.scheme.scheme_vibrant import SchemeVibrant
from materialyoucolor.score.score import Score
-from PIL import Image
def darken(rgb: tuple[int, int, int], amount: float) -> tuple[int, int, int]:
@@ -22,87 +30,55 @@ def mix(
return tuple(round(rgb1[i] * (1 - amount) + rgb2[i] * amount) for i in range(3))
-def calculate_optimal_size(
- width: int, height: int, bitmap_size: int = 128
-) -> (int, int):
- image_area = width * height
- bitmap_area = bitmap_size**2
- scale = math.sqrt(bitmap_area / image_area) if image_area > bitmap_area else 1
- return max(1, round(width * scale)), max(1, round(height * scale))
-
-
num_args = len(sys.argv)
if num_args < 2:
- print('Usage: <path/to/image> [ "light" | "dark" ] [ <material_scheme> ]')
+ print('Usage: <path/to/image> [ "light" | "dark" ]')
sys.exit(1)
img = sys.argv[1]
is_dark = num_args < 3 or sys.argv[2] != "light"
-scheme = "vibrant" if num_args < 4 else sys.argv[3]
-
-with Image.open(sys.argv[1]) as image:
- if image.format == "GIF":
- image.seek(1)
-
- if image.mode in ["L", "P"]:
- image = image.convert("RGB")
-
- width, height = image.size
- opt_width, opt_height = calculate_optimal_size(width, height)
- if opt_width < width or opt_height < height:
- image = image.resize((opt_width, opt_height), Image.Resampling.BICUBIC)
- colours = QuantizeCelebi(list(image.getdata()), 128)
-
- hct = Hct.from_int(Score.score(colours)[0])
-
-
-if scheme == "fruitsalad":
- from materialyoucolor.scheme.scheme_fruit_salad import SchemeFruitSalad as Scheme
-elif scheme == "expressive":
- from materialyoucolor.scheme.scheme_expressive import SchemeExpressive as Scheme
-elif scheme == "monochrome":
- from materialyoucolor.scheme.scheme_monochrome import SchemeMonochrome as Scheme
-elif scheme == "rainbow":
- from materialyoucolor.scheme.scheme_rainbow import SchemeRainbow as Scheme
-elif scheme == "tonalspot":
- from materialyoucolor.scheme.scheme_tonal_spot import SchemeTonalSpot as Scheme
-elif scheme == "neutral":
- from materialyoucolor.scheme.scheme_neutral import SchemeNeutral as Scheme
-elif scheme == "fidelity":
- from materialyoucolor.scheme.scheme_fidelity import SchemeFidelity as Scheme
-elif scheme == "content":
- from materialyoucolor.scheme.scheme_content import SchemeContent as Scheme
-else:
- from materialyoucolor.scheme.scheme_vibrant import SchemeVibrant as Scheme
-
-scheme = Scheme(hct, is_dark, 0.0)
+colours = ImageQuantizeCelebi(img, 1, 128)
+hct = Hct.from_int(Score.score(colours)[0])
+for Scheme in (
+ SchemeFruitSalad,
+ SchemeExpressive,
+ SchemeMonochrome,
+ SchemeRainbow,
+ SchemeTonalSpot,
+ SchemeNeutral,
+ SchemeFidelity,
+ SchemeContent,
+ SchemeVibrant,
+):
+ print("\n" + Scheme.__name__[6:].lower())
+ scheme = Scheme(hct, is_dark, 0.0)
-colours = {}
+ colours = {}
-for color in vars(MaterialDynamicColors).keys():
- color_name = getattr(MaterialDynamicColors, color)
- if hasattr(color_name, "get_hct"):
- colours[color] = color_name.get_hct(scheme).to_rgba()[0:3]
+ for color in vars(MaterialDynamicColors).keys():
+ color_name = getattr(MaterialDynamicColors, color)
+ if hasattr(color_name, "get_hct"):
+ colours[color] = color_name.get_hct(scheme).to_rgba()[:3]
-colours = {
- "primary": colours["primary"],
- "secondary": colours["secondary"],
- "tertiary": colours["tertiary"],
- "text": colours["onBackground"],
- "subtext1": colours["onSurfaceVariant"],
- "subtext0": colours["outline"],
- "overlay2": mix(colours["surface"], colours["outline"], 0.86),
- "overlay1": mix(colours["surface"], colours["outline"], 0.71),
- "overlay0": mix(colours["surface"], colours["outline"], 0.57),
- "surface2": mix(colours["surface"], colours["outline"], 0.43),
- "surface1": mix(colours["surface"], colours["outline"], 0.29),
- "surface0": mix(colours["surface"], colours["outline"], 0.14),
- "base": colours["surface"],
- "mantle": darken(colours["surface"], 0.03),
- "crust": darken(colours["surface"], 0.05),
-}
+ colours = {
+ "primary": colours["primary"],
+ "secondary": colours["secondary"],
+ "tertiary": colours["tertiary"],
+ "text": colours["onBackground"],
+ "subtext1": colours["onSurfaceVariant"],
+ "subtext0": colours["outline"],
+ "overlay2": mix(colours["surface"], colours["outline"], 0.86),
+ "overlay1": mix(colours["surface"], colours["outline"], 0.71),
+ "overlay0": mix(colours["surface"], colours["outline"], 0.57),
+ "surface2": mix(colours["surface"], colours["outline"], 0.43),
+ "surface1": mix(colours["surface"], colours["outline"], 0.29),
+ "surface0": mix(colours["surface"], colours["outline"], 0.14),
+ "base": colours["surface"],
+ "mantle": darken(colours["surface"], 0.03),
+ "crust": darken(colours["surface"], 0.05),
+ }
-for name, colour in colours.items():
- print("{} {:02X}{:02X}{:02X}".format(name, *colour))
+ for name, colour in colours.items():
+ print("{} {:02X}{:02X}{:02X}".format(name, *colour))
diff --git a/wallpaper.fish b/wallpaper.fish
index 24e5780..25c7090 100755
--- a/wallpaper.fish
+++ b/wallpaper.fish
@@ -106,13 +106,25 @@ else
# Unload unused wallpapers to preserve memory
hyprctl hyprpaper unload unused > /dev/null
+ # Thumbnail wallpaper for colour gen
+ set -l thumb_path $C_CACHE/thumbnails/(string replace -a '/' '-' (dirname $chosen_wallpaper | string sub -s 2))-(path change-extension '.jpg' (basename $chosen_wallpaper))
+ if test -f $thumb_path
+ # Use thumbnail from shell
+ cp $thumb_path $state_dir/thumbnail.jpg
+ else
+ magick -define jpeg:size=256x256 $chosen_wallpaper -thumbnail 128x128 $state_dir/thumbnail.jpg
+ end
+
# Generate colour scheme for wallpaper
set -l src (dirname (status filename))
- mkdir -p $src/data/schemes/dynamic
- $src/scheme/gen-scheme.fish $chosen_wallpaper dark > $src/data/schemes/dynamic/dark.txt
- $src/scheme/gen-scheme.fish $chosen_wallpaper light > $src/data/schemes/dynamic/light.txt
- if test "$(cat $C_STATE/scheme/current-name.txt 2> /dev/null)" = 'dynamic'
- caelestia scheme dynamic $_flag_T > /dev/null
+ $src/scheme/gen-scheme.fish $state_dir/thumbnail.jpg dark &
+ $src/scheme/gen-scheme.fish $state_dir/thumbnail.jpg light &
+ if test -f $C_STATE/scheme/current-name.txt
+ set -l variant (string match -gr 'dynamic-(.*)' (cat $C_STATE/scheme/current-name.txt))
+ if test -n "$variant"
+ wait
+ caelestia scheme dynamic $variant $_flag_T > /dev/null
+ end
end
# Store the wallpaper chosen