From b62cc3f79eefe5f69d7914bd06bc9a9109f4e397 Mon Sep 17 00:00:00 2001 From: "Azalea (on HyDEV-Daisy)" Date: Sun, 10 Apr 2022 06:12:59 -0400 Subject: [PATCH] [+] Lighten color --- hyfetch/color_util.py | 38 ++++++++++++++++++++++++++++++++++++++ hyfetch/main.py | 15 ++++++++++++--- hyfetch/presets.py | 21 +++++++++++---------- 3 files changed, 61 insertions(+), 13 deletions(-) diff --git a/hyfetch/color_util.py b/hyfetch/color_util.py index 04b0f8c2..cf7b0ad7 100644 --- a/hyfetch/color_util.py +++ b/hyfetch/color_util.py @@ -1,6 +1,25 @@ +import colorsys from typing import NamedTuple +def redistribute_rgb(r: int, g: int, b: int) -> tuple[int, int, int]: + """ + Redistribute RGB after lightening + + Credit: https://stackoverflow.com/a/141943/7346633 + """ + threshold = 255.999 + m = max(r, g, b) + if m <= threshold: + return int(r), int(g), int(b) + total = r + g + b + if total >= 3 * threshold: + return int(threshold), int(threshold), int(threshold) + x = (3 * threshold - total) / (3 * m - total) + gray = threshold - x * m + return int(gray + x * r), int(gray + x * g), int(gray + x * b) + + class RGB(NamedTuple): r: int g: int @@ -59,3 +78,22 @@ class RGB(NamedTuple): :return: ANSI 16 escape code """ raise NotImplementedError() + + def lighten(self, multiplier: float) -> 'RGB': + """ + Lighten the color by a multiplier + + :param multiplier: Multiplier + :return: Lightened color (original isn't modified) + """ + return RGB(*redistribute_rgb(*[v * multiplier for v in self])) + + def set_light(self, light: int) -> 'RGB': + """ + Set HSL lightness value + + :param light: Lightness value + :return: New color (original isn't modified) + """ + h, l, s = colorsys.rgb_to_hls(*[v / 255.0 for v in self]) + return RGB(*[round(v * 255.0) for v in colorsys.hls_to_rgb(h, light, s)]) diff --git a/hyfetch/main.py b/hyfetch/main.py index da8d004b..a073c425 100755 --- a/hyfetch/main.py +++ b/hyfetch/main.py @@ -9,8 +9,7 @@ from typing import Literal, Iterable from hypy_utils import printc, json_stringify, color from .neofetch_util import run_neofetch -from .presets import PRESETS - +from .presets import PRESETS, ColorProfile CONFIG_PATH = Path.home() / '.config/hyfetch.json' CONFIG_PATH.parent.mkdir(exist_ok=True, parents=True) @@ -130,6 +129,8 @@ def run(): parser.add_argument('-c', '--config', action='store_true', help=color(f'Configure {hyfetch}')) parser.add_argument('-p', '--preset', help=f'Use preset', choices=PRESETS.keys()) parser.add_argument('-m', '--mode', help=f'Color mode', choices=['ansi', '8bit', 'rgb']) + parser.add_argument('--c-scale', dest='scale', help=f'Lighten colors by a multiplier', type=float) + parser.add_argument('--c-set-l', dest='light', help=f'Set lightness value of the colors', type=float) args = parser.parse_args() @@ -146,5 +147,13 @@ def run(): if args.mode: config.mode = args.mode + preset = PRESETS.get(config.preset) + + # Lighten + if args.scale: + preset = ColorProfile([c.lighten(args.scale) for c in preset.colors]) + if args.light: + preset = ColorProfile([c.set_light(args.light) for c in preset.colors]) + # Run - run_neofetch(PRESETS.get(config.preset)) + run_neofetch(preset) diff --git a/hyfetch/presets.py b/hyfetch/presets.py index 826bfd11..bf27b74b 100644 --- a/hyfetch/presets.py +++ b/hyfetch/presets.py @@ -1,21 +1,23 @@ +from __future__ import annotations + from dataclasses import dataclass from typing import Literal from .color_util import RGB -@dataclass class ColorProfile: - colors: list[str] + raw: list[str] + colors: list[RGB] spacing: Literal['equal', 'weighted'] = 'equal' - def decode(self) -> list[RGB]: - """ - Decode to a list of RGBs + def __init__(self, colors: list[str] | list[RGB]): + if isinstance(colors[0], str): + self.raw = colors + self.colors = [RGB.from_hex(c) for c in colors] + else: + self.colors = colors - :return: List of RGBs - """ - return [RGB.from_hex(c) for c in self.colors] def with_weights(self, weights: list[int]) -> list[RGB]: """ @@ -24,8 +26,7 @@ class ColorProfile: :param weights: Weights of each color (weights[i] = how many times color[i] appears) :return: """ - colors = self.decode() - return [c for i, w in enumerate(weights) for c in [colors[i]] * w] + return [c for i, w in enumerate(weights) for c in [self.colors[i]] * w] def with_length(self, length: int) -> list[RGB]: """