Browse Source

[+] Lighten color

Azalea (on HyDEV-Daisy) 3 years ago
parent
commit
b62cc3f79e
3 changed files with 61 additions and 13 deletions
  1. 38 0
      hyfetch/color_util.py
  2. 12 3
      hyfetch/main.py
  3. 11 10
      hyfetch/presets.py

+ 38 - 0
hyfetch/color_util.py

@@ -1,6 +1,25 @@
+import colorsys
 from typing import NamedTuple
 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):
 class RGB(NamedTuple):
     r: int
     r: int
     g: int
     g: int
@@ -59,3 +78,22 @@ class RGB(NamedTuple):
         :return: ANSI 16 escape code
         :return: ANSI 16 escape code
         """
         """
         raise NotImplementedError()
         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)])

+ 12 - 3
hyfetch/main.py

@@ -9,8 +9,7 @@ from typing import Literal, Iterable
 from hypy_utils import printc, json_stringify, color
 from hypy_utils import printc, json_stringify, color
 
 
 from .neofetch_util import run_neofetch
 from .neofetch_util import run_neofetch
-from .presets import PRESETS
-
+from .presets import PRESETS, ColorProfile
 
 
 CONFIG_PATH = Path.home() / '.config/hyfetch.json'
 CONFIG_PATH = Path.home() / '.config/hyfetch.json'
 CONFIG_PATH.parent.mkdir(exist_ok=True, parents=True)
 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('-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('-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('-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()
     args = parser.parse_args()
 
 
@@ -146,5 +147,13 @@ def run():
     if args.mode:
     if args.mode:
         config.mode = 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
-    run_neofetch(PRESETS.get(config.preset))
+    run_neofetch(preset)

+ 11 - 10
hyfetch/presets.py

@@ -1,21 +1,23 @@
+from __future__ import annotations
+
 from dataclasses import dataclass
 from dataclasses import dataclass
 from typing import Literal
 from typing import Literal
 
 
 from .color_util import RGB
 from .color_util import RGB
 
 
 
 
-@dataclass
 class ColorProfile:
 class ColorProfile:
-    colors: list[str]
+    raw: list[str]
+    colors: list[RGB]
     spacing: Literal['equal', 'weighted'] = 'equal'
     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]:
     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)
         :param weights: Weights of each color (weights[i] = how many times color[i] appears)
         :return:
         :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]:
     def with_length(self, length: int) -> list[RGB]:
         """
         """