summaryrefslogtreecommitdiff
path: root/scheme
diff options
context:
space:
mode:
author2 * r + 2 * t <61896496+soramanew@users.noreply.github.com>2025-06-14 15:42:20 +1000
committer2 * r + 2 * t <61896496+soramanew@users.noreply.github.com>2025-06-14 15:42:20 +1000
commitb5a91d3ca57d1369d0b7b502112c4b4c9849d26c (patch)
tree8ea45e54e0b0c826f65f54ebf82e41cb68163221 /scheme
parentfeat: impl pip subcommand (diff)
downloadcaelestia-cli-b5a91d3ca57d1369d0b7b502112c4b4c9849d26c.tar.gz
caelestia-cli-b5a91d3ca57d1369d0b7b502112c4b4c9849d26c.tar.bz2
caelestia-cli-b5a91d3ca57d1369d0b7b502112c4b4c9849d26c.zip
internal: remove all legacy fish scripts
Diffstat (limited to 'scheme')
-rwxr-xr-xscheme/autoadjust.py256
-rwxr-xr-xscheme/gen-print-scheme.fish36
-rwxr-xr-xscheme/gen-scheme.fish33
-rwxr-xr-xscheme/main.fish81
-rwxr-xr-xscheme/score.py134
5 files changed, 0 insertions, 540 deletions
diff --git a/scheme/autoadjust.py b/scheme/autoadjust.py
deleted file mode 100755
index 1c6dc2c..0000000
--- a/scheme/autoadjust.py
+++ /dev/null
@@ -1,256 +0,0 @@
-#!/usr/bin/env python3
-
-import sys
-from colorsys import hls_to_rgb, rgb_to_hls
-from pathlib import Path
-
-from materialyoucolor.blend import Blend
-from materialyoucolor.dynamiccolor.material_dynamic_colors import (
- DynamicScheme,
- MaterialDynamicColors,
-)
-from materialyoucolor.hct import Hct
-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
-
-light_colours = [
- "dc8a78",
- "dd7878",
- "ea76cb",
- "8839ef",
- "d20f39",
- "e64553",
- "fe640b",
- "df8e1d",
- "40a02b",
- "179299",
- "04a5e5",
- "209fb5",
- "1e66f5",
- "7287fd",
-]
-
-dark_colours = [
- "f5e0dc",
- "f2cdcd",
- "f5c2e7",
- "cba6f7",
- "f38ba8",
- "eba0ac",
- "fab387",
- "f9e2af",
- "a6e3a1",
- "94e2d5",
- "89dceb",
- "74c7ec",
- "89b4fa",
- "b4befe",
-]
-
-colour_names = [
- "rosewater",
- "flamingo",
- "pink",
- "mauve",
- "red",
- "maroon",
- "peach",
- "yellow",
- "green",
- "teal",
- "sky",
- "sapphire",
- "blue",
- "lavender",
- "success",
- "error",
-]
-
-HLS = tuple[float, float, float]
-
-
-def hex_to_rgb(hex: str) -> tuple[float, float, float]:
- """Convert a hex string to an RGB tuple in the range [0, 1]."""
- return tuple(int(hex[i : i + 2], 16) / 255 for i in (0, 2, 4))
-
-
-def rgb_to_hex(rgb: tuple[float, float, float]) -> str:
- """Convert an RGB tuple in the range [0, 1] to a hex string."""
- return "".join(f"{round(i * 255):02X}" for i in rgb)
-
-
-def hex_to_hls(hex: str) -> tuple[float, float, float]:
- return rgb_to_hls(*hex_to_rgb(hex))
-
-
-def hls_to_hex(h: str, l: str, s: str) -> str:
- return rgb_to_hex(hls_to_rgb(h, l, s))
-
-
-def hex_to_argb(hex: str) -> int:
- return int(f"0xFF{hex}", 16)
-
-
-def argb_to_hls(argb: int) -> HLS:
- return hex_to_hls(f"{argb:08X}"[2:])
-
-
-def grayscale(hls: HLS, light: bool) -> HLS:
- h, l, s = hls
- return h, 0.5 - l / 2 if light else l / 2 + 0.5, 0
-
-
-def mix(a: HLS, b: HLS, w: float) -> HLS:
- r1, g1, b1 = hls_to_rgb(*a)
- r2, g2, b2 = hls_to_rgb(*b)
- return rgb_to_hls(
- r1 * (1 - w) + r2 * w, g1 * (1 - w) + g2 * w, b1 * (1 - w) + b2 * w
- )
-
-
-def harmonize(a: str, b: int) -> HLS:
- return argb_to_hls(Blend.harmonize(hex_to_argb(a), b))
-
-
-def darken(colour: HLS, amount: float) -> HLS:
- h, l, s = colour
- return h, max(0, l - amount), s
-
-
-def distance(colour: HLS, base: str) -> float:
- h1, l1, s1 = colour
- h2, l2, s2 = hex_to_hls(base)
- return abs(h1 - h2) * 0.4 + abs(l1 - l2) * 0.3 + abs(s1 - s2) * 0.3
-
-
-def smart_sort(colours: list[HLS], base: list[str]) -> dict[str, HLS]:
- sorted_colours = [None] * len(colours)
- distances = {}
-
- for colour in colours:
- dist = [(i, distance(colour, b)) for i, b in enumerate(base)]
- dist.sort(key=lambda x: x[1])
- distances[colour] = dist
-
- for colour in colours:
- while len(distances[colour]) > 0:
- i, dist = distances[colour][0]
-
- if sorted_colours[i] is None:
- sorted_colours[i] = colour, dist
- break
- elif sorted_colours[i][1] > dist:
- old = sorted_colours[i][0]
- sorted_colours[i] = colour, dist
- colour = old
-
- distances[colour].pop(0)
-
- return {colour_names[i]: c[0] for i, c in enumerate(sorted_colours)}
-
-
-def get_scheme(scheme: str) -> DynamicScheme:
- if scheme == "content":
- return SchemeContent
- if scheme == "expressive":
- return SchemeExpressive
- if scheme == "fidelity":
- return SchemeFidelity
- if scheme == "fruitsalad":
- return SchemeFruitSalad
- if scheme == "monochrome":
- return SchemeMonochrome
- if scheme == "neutral":
- return SchemeNeutral
- if scheme == "rainbow":
- return SchemeRainbow
- if scheme == "tonalspot":
- return SchemeTonalSpot
- return SchemeVibrant
-
-
-def get_alt(i: int) -> str:
- names = ["default", "alt1", "alt2"]
- return names[i]
-
-
-if __name__ == "__main__":
- light = sys.argv[1] == "light"
- scheme = sys.argv[2]
- primaries = sys.argv[3].split(" ")
- colours_in = sys.argv[4].split(" ")
- out_path = sys.argv[5]
-
- base = light_colours if light else dark_colours
-
- # Convert to HLS
- base_colours = [hex_to_hls(c) for c in colours_in]
-
- # Sort colours and turn into dict
- base_colours = smart_sort(base_colours, base)
-
- # Adjust colours
- MatScheme = get_scheme(scheme)
- for name, hls in base_colours.items():
- if scheme == "monochrome":
- base_colours[name] = grayscale(hls, light)
- else:
- argb = hex_to_argb(hls_to_hex(*hls))
- mat_scheme = MatScheme(Hct.from_int(argb), not light, 0)
-
- colour = MaterialDynamicColors.primary.get_hct(mat_scheme)
-
- # Boost neutral scheme colours
- if scheme == "neutral":
- colour.chroma += 10
-
- base_colours[name] = hex_to_hls(
- "{:02X}{:02X}{:02X}".format(*colour.to_rgba()[:3])
- )
-
- # Layers and accents
- for i, primary in enumerate(primaries):
- material = {}
-
- primary_argb = hex_to_argb(primary)
- primary_scheme = MatScheme(Hct.from_int(primary_argb), not light, 0)
- for colour in vars(MaterialDynamicColors).keys():
- colour_name = getattr(MaterialDynamicColors, colour)
- if hasattr(colour_name, "get_hct"):
- rgb = colour_name.get_hct(primary_scheme).to_rgba()[:3]
- material[colour] = hex_to_hls("{:02X}{:02X}{:02X}".format(*rgb))
-
- # TODO: eventually migrate to material for layers
- colours = {
- **material,
- "text": material["onBackground"],
- "subtext1": material["onSurfaceVariant"],
- "subtext0": material["outline"],
- "overlay2": mix(material["surface"], material["outline"], 0.86),
- "overlay1": mix(material["surface"], material["outline"], 0.71),
- "overlay0": mix(material["surface"], material["outline"], 0.57),
- "surface2": mix(material["surface"], material["outline"], 0.43),
- "surface1": mix(material["surface"], material["outline"], 0.29),
- "surface0": mix(material["surface"], material["outline"], 0.14),
- "base": material["surface"],
- "mantle": darken(material["surface"], 0.03),
- "crust": darken(material["surface"], 0.05),
- "success": harmonize(base[8], primary_argb),
- }
-
- for name, hls in base_colours.items():
- colours[name] = harmonize(hls_to_hex(*hls), primary_argb)
-
- out_file = Path(f"{out_path}/{scheme}/{get_alt(i)}/{sys.argv[1]}.txt")
- out_file.parent.mkdir(parents=True, exist_ok=True)
- colour_arr = [
- f"{name} {hls_to_hex(*colour)}" for name, colour in colours.items()
- ]
- out_file.write_text("\n".join(colour_arr))
diff --git a/scheme/gen-print-scheme.fish b/scheme/gen-print-scheme.fish
deleted file mode 100755
index 6dfa482..0000000
--- a/scheme/gen-print-scheme.fish
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/usr/bin/env fish
-
-set -l src (dirname (status filename))
-
-. $src/../util.fish
-
-test -f "$argv[1]" && set -l img (realpath "$argv[1]") || set -l img $C_STATE/wallpaper/thumbnail.jpg
-
-# Thumbnail image if not already thumbnail
-if test $img != $C_STATE/wallpaper/thumbnail.jpg
- set -l thumb_path $C_CACHE/thumbnails/(sha1sum $img | cut -d ' ' -f 1).jpg
- if ! test -f $thumb_path
- magick -define jpeg:size=256x256 $img -thumbnail 128x128\> $thumb_path
- end
- set img $thumb_path
-end
-
-set -l variants vibrant tonalspot expressive fidelity fruitsalad rainbow neutral content monochrome
-contains -- "$argv[2]" $variants && set -l variant $argv[2] || set -l variant (cat $C_STATE/scheme/current-variant.txt 2> /dev/null)
-contains -- "$variant" $variants || set -l variant tonalspot
-
-set -l hash (sha1sum $img | cut -d ' ' -f 1)
-
-# Cache scheme
-if ! test -d $C_CACHE/schemes/$hash/$variant
- set -l colours ($src/score.py $img)
- $src/autoadjust.py dark $variant $colours $C_CACHE/schemes/$hash
- $src/autoadjust.py light $variant $colours $C_CACHE/schemes/$hash
-end
-
-# Get mode from image
-set -l lightness (magick $img -format '%[fx:int(mean*100)]' info:)
-test $lightness -ge 60 && set -l mode light || set -l mode dark
-
-# Print scheme
-cat $C_CACHE/schemes/$hash/$variant/default/$mode.txt
diff --git a/scheme/gen-scheme.fish b/scheme/gen-scheme.fish
deleted file mode 100755
index 35e0bc5..0000000
--- a/scheme/gen-scheme.fish
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/usr/bin/env fish
-
-set -l src (dirname (status filename))
-
-. $src/../util.fish
-
-test -f "$argv[1]" && set -l img (realpath "$argv[1]") || set -l img $C_STATE/wallpaper/thumbnail.jpg
-
-set -l variants vibrant tonalspot expressive fidelity fruitsalad rainbow neutral content monochrome
-contains -- "$argv[2]" $variants && set -l variant $argv[2] || set -l variant (cat $C_STATE/scheme/current-variant.txt 2> /dev/null)
-contains -- "$variant" $variants || set -l variant tonalspot
-
-set -l hash (sha1sum $img | cut -d ' ' -f 1)
-
-# Cache scheme
-if ! test -d $C_CACHE/schemes/$hash/$variant
- set -l colours ($src/score.py $img)
- $src/autoadjust.py dark $variant $colours $C_CACHE/schemes/$hash
- $src/autoadjust.py light $variant $colours $C_CACHE/schemes/$hash
-end
-
-# Copy scheme from cache
-rm -rf $src/../data/schemes/dynamic
-cp -r $C_CACHE/schemes/$hash/$variant $src/../data/schemes/dynamic
-
-# Update if current
-set -l variant (string match -gr 'dynamic-(.*)' (cat $C_STATE/scheme/current-name.txt 2> /dev/null))
-if test -n "$variant"
- # If variant doesn't exist, use default
- test -d $src/../data/schemes/dynamic/$variant || set -l variant default
- # Apply scheme
- $src/main.fish dynamic $variant $MODE > /dev/null
-end
diff --git a/scheme/main.fish b/scheme/main.fish
deleted file mode 100755
index 5e6ad03..0000000
--- a/scheme/main.fish
+++ /dev/null
@@ -1,81 +0,0 @@
-#!/usr/bin/env fish
-
-# Usage:
-# caelestia scheme <scheme> <flavour> [mode]
-# caelestia scheme <scheme> [flavour]
-# caelestia scheme [scheme]
-
-function set-scheme -a path name mode
- mkdir -p $C_STATE/scheme
-
- # Update scheme colours
- cp $path $C_STATE/scheme/current.txt
-
- # Update scheme name
- echo -n $name > $C_STATE/scheme/current-name.txt
-
- # Update scheme mode
- echo -n $mode > $C_STATE/scheme/current-mode.txt
-
- log "Changed scheme to $name ($mode)"
-end
-
-set -l src (dirname (status filename))/..
-set -l schemes $src/data/schemes
-
-. $src/util.fish
-
-set -l scheme $argv[1]
-set -l flavour $argv[2]
-set -l mode $argv[3]
-
-set -l valid_schemes (basename -a $schemes/*)
-
-test -z "$scheme" && set -l scheme (random choice $valid_schemes)
-
-if contains -- "$scheme" $valid_schemes
- set -l flavours (basename -a (find $schemes/$scheme/ -mindepth 1 -maxdepth 1 -type d) 2> /dev/null)
- set -l modes (basename -s .txt (find $schemes/$scheme/ -mindepth 1 -maxdepth 1 -type f) 2> /dev/null)
-
- if test -n "$modes"
- # Scheme only has one flavour, so second arg is mode
- set -l mode $flavour
- if test -z "$mode"
- # Try to use current mode if not provided and current mode exists for flavour, otherwise random mode
- set mode (cat $C_STATE/scheme/current-mode.txt 2> /dev/null)
- contains -- "$mode" $modes || set mode (random choice $modes)
- end
-
- if contains -- "$mode" $modes
- # Provided valid mode
- set-scheme $schemes/$scheme/$mode.txt $scheme $mode
- else
- error "Invalid mode for $scheme: $mode"
- end
- else
- # Scheme has multiple flavours, so second arg is flavour
- test -z "$flavour" && set -l flavour (random choice $flavours)
-
- if contains -- "$flavour" $flavours
- # Provided valid flavour
- set -l modes (basename -s .txt $schemes/$scheme/$flavour/*.txt)
- if test -z "$mode"
- # Try to use current mode if not provided and current mode exists for flavour, otherwise random mode
- set mode (cat $C_STATE/scheme/current-mode.txt 2> /dev/null)
- contains -- "$mode" $modes || set mode (random choice $modes)
- end
-
- if contains -- "$mode" $modes
- # Provided valid mode
- set-scheme $schemes/$scheme/$flavour/$mode.txt $scheme-$flavour $mode
- else
- error "Invalid mode for $scheme $flavour: $mode"
- end
- else
- # Invalid flavour
- error "Invalid flavour for $scheme: $flavour"
- end
- end
-else
- error "Invalid scheme: $scheme"
-end
diff --git a/scheme/score.py b/scheme/score.py
deleted file mode 100755
index 18ddc21..0000000
--- a/scheme/score.py
+++ /dev/null
@@ -1,134 +0,0 @@
-#!/usr/bin/env python
-
-import sys
-
-from materialyoucolor.dislike.dislike_analyzer import DislikeAnalyzer
-from materialyoucolor.hct import Hct
-from materialyoucolor.quantize import ImageQuantizeCelebi
-from materialyoucolor.utils.math_utils import difference_degrees, sanitize_degrees_int
-
-
-class Score:
- TARGET_CHROMA = 48.0
- WEIGHT_PROPORTION = 0.7
- WEIGHT_CHROMA_ABOVE = 0.3
- WEIGHT_CHROMA_BELOW = 0.1
- CUTOFF_CHROMA = 5.0
- CUTOFF_EXCITED_PROPORTION = 0.01
-
- def __init__(self):
- pass
-
- @staticmethod
- def score(colors_to_population: dict) -> tuple[list[Hct], list[Hct]]:
- desired = 14
- filter_enabled = False
- dislike_filter = True
-
- colors_hct = []
- hue_population = [0] * 360
- population_sum = 0
-
- for rgb, population in colors_to_population.items():
- hct = Hct.from_int(rgb)
- colors_hct.append(hct)
- hue = int(hct.hue)
- hue_population[hue] += population
- population_sum += population
-
- hue_excited_proportions = [0.0] * 360
-
- for hue in range(360):
- proportion = hue_population[hue] / population_sum
- for i in range(hue - 14, hue + 16):
- neighbor_hue = int(sanitize_degrees_int(i))
- hue_excited_proportions[neighbor_hue] += proportion
-
- # Score colours
- scored_hct = []
- for hct in colors_hct:
- hue = int(sanitize_degrees_int(round(hct.hue)))
- proportion = hue_excited_proportions[hue]
-
- if filter_enabled and (
- hct.chroma < Score.CUTOFF_CHROMA
- or proportion <= Score.CUTOFF_EXCITED_PROPORTION
- ):
- continue
-
- proportion_score = proportion * 100.0 * Score.WEIGHT_PROPORTION
- chroma_weight = (
- Score.WEIGHT_CHROMA_BELOW
- if hct.chroma < Score.TARGET_CHROMA
- else Score.WEIGHT_CHROMA_ABOVE
- )
- chroma_score = (hct.chroma - Score.TARGET_CHROMA) * chroma_weight
- score = proportion_score + chroma_score
- scored_hct.append({"hct": hct, "score": score})
-
- scored_hct.sort(key=lambda x: x["score"], reverse=True)
-
- # Choose distinct colours
- chosen_colors = []
- for difference_degrees_ in range(90, 0, -1):
- chosen_colors.clear()
- for item in scored_hct:
- hct = item["hct"]
- duplicate_hue = any(
- difference_degrees(hct.hue, chosen_hct.hue) < difference_degrees_
- for chosen_hct in chosen_colors
- )
- if not duplicate_hue:
- chosen_colors.append(hct)
- if len(chosen_colors) >= desired:
- break
- if len(chosen_colors) >= desired:
- break
-
- # Get primary colour
- primary = None
- for cutoff in range(20, 0, -1):
- for item in scored_hct:
- if item["hct"].chroma > cutoff and item["hct"].tone > cutoff * 3:
- primary = item["hct"]
- break
- if primary:
- break
-
- # Choose distinct primaries
- chosen_primaries = [primary]
- for difference_degrees_ in range(90, 14, -1):
- chosen_primaries = [primary]
- for item in scored_hct:
- hct = item["hct"]
- duplicate_hue = any(
- difference_degrees(hct.hue, chosen_hct.hue) < difference_degrees_
- for chosen_hct in chosen_primaries
- )
- if not duplicate_hue:
- chosen_primaries.append(hct)
- if len(chosen_primaries) >= 3:
- break
- if len(chosen_primaries) >= 3:
- break
-
- # Fix disliked colours
- if dislike_filter:
- for i, chosen_hct in enumerate(chosen_primaries):
- chosen_primaries[i] = DislikeAnalyzer.fix_if_disliked(chosen_hct)
- for i, chosen_hct in enumerate(chosen_colors):
- chosen_colors[i] = DislikeAnalyzer.fix_if_disliked(chosen_hct)
-
- return chosen_primaries, chosen_colors
-
-
-if __name__ == "__main__":
- img = sys.argv[1]
- mode = sys.argv[2] if len(sys.argv) > 2 else "hex"
-
- colours = Score.score(ImageQuantizeCelebi(img, 1, 128))
- for l in colours:
- if mode != "hex":
- print("".join(["\x1b[48;2;{};{};{}m \x1b[0m".format(*c.to_rgba()[:3]) for c in l]))
- if mode != "swatch":
- print(" ".join(["{:02X}{:02X}{:02X}".format(*c.to_rgba()[:3]) for c in l]))