Files
babi/babi/color_manager.py
Anthony Sottile 2123e6ee84 improve performance by ~.8%
apparently contextlib.suppress is enough to show up in profiles
2020-03-23 20:57:53 -07:00

48 lines
1.4 KiB
Python

import curses
from typing import Dict
from typing import NamedTuple
from typing import Optional
from typing import Tuple
from babi import color_kd
from babi.color import Color
def _color_to_curses(color: Color) -> Tuple[int, int, int]:
factor = 1000 / 255
return int(color.r * factor), int(color.g * factor), int(color.b * factor)
class ColorManager(NamedTuple):
colors: Dict[Color, int]
raw_pairs: Dict[Tuple[int, int], int]
def init_color(self, color: Color) -> None:
if curses.can_change_color():
n = min(self.colors.values(), default=256) - 1
self.colors[color] = n
curses.init_color(n, *_color_to_curses(color))
elif curses.COLORS >= 256:
self.colors[color] = color_kd.nearest(color, color_kd.make_256())
else:
self.colors[color] = -1
def color_pair(self, fg: Optional[Color], bg: Optional[Color]) -> int:
fg_i = self.colors[fg] if fg is not None else -1
bg_i = self.colors[bg] if bg is not None else -1
return self.raw_color_pair(fg_i, bg_i)
def raw_color_pair(self, fg: int, bg: int) -> int:
try:
return self.raw_pairs[(fg, bg)]
except KeyError:
pass
n = self.raw_pairs[(fg, bg)] = len(self.raw_pairs) + 1
curses.init_pair(n, fg, bg)
return n
@classmethod
def make(cls) -> 'ColorManager':
return cls({}, {})