87 lines
2.5 KiB
Python
87 lines
2.5 KiB
Python
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
from typing import Iterable
|
||
|
|
|
||
|
|
from rich.console import RenderableType
|
||
|
|
from rich.segment import Segment
|
||
|
|
from rich.style import Style
|
||
|
|
from rich.terminal_theme import TerminalTheme
|
||
|
|
|
||
|
|
from textual.color import TRANSPARENT, Color
|
||
|
|
from textual.filter import ANSIToTruecolor
|
||
|
|
|
||
|
|
|
||
|
|
class Tint:
|
||
|
|
"""Applies a color on top of an existing renderable."""
|
||
|
|
|
||
|
|
def __init__(
|
||
|
|
self,
|
||
|
|
renderable: RenderableType,
|
||
|
|
color: Color,
|
||
|
|
) -> None:
|
||
|
|
"""Wrap a renderable to apply a tint color.
|
||
|
|
|
||
|
|
Args:
|
||
|
|
renderable: A renderable.
|
||
|
|
color: A color (presumably with alpha).
|
||
|
|
"""
|
||
|
|
self.renderable = renderable
|
||
|
|
self.color = color
|
||
|
|
|
||
|
|
@classmethod
|
||
|
|
def process_segments(
|
||
|
|
cls,
|
||
|
|
segments: Iterable[Segment],
|
||
|
|
color: Color,
|
||
|
|
ansi_theme: TerminalTheme,
|
||
|
|
background: Color = TRANSPARENT,
|
||
|
|
) -> Iterable[Segment]:
|
||
|
|
"""Apply tint to segments.
|
||
|
|
|
||
|
|
Args:
|
||
|
|
segments: Incoming segments.
|
||
|
|
color: Color of tint.
|
||
|
|
ansi_theme: The TerminalTheme defining how to map ansi colors to hex.
|
||
|
|
background: Background color.
|
||
|
|
|
||
|
|
Returns:
|
||
|
|
Segments with applied tint.
|
||
|
|
"""
|
||
|
|
from_rich_color = Color.from_rich_color
|
||
|
|
style_from_color = Style.from_color
|
||
|
|
_Segment = Segment
|
||
|
|
|
||
|
|
truecolor_style = ANSIToTruecolor(ansi_theme).truecolor_style
|
||
|
|
background_rich_color = background.rich_color
|
||
|
|
|
||
|
|
NULL_STYLE = Style()
|
||
|
|
for segment in segments:
|
||
|
|
text, style, control = segment
|
||
|
|
if control:
|
||
|
|
yield segment
|
||
|
|
else:
|
||
|
|
style = (
|
||
|
|
truecolor_style(style, background_rich_color)
|
||
|
|
if style is not None
|
||
|
|
else NULL_STYLE
|
||
|
|
)
|
||
|
|
yield _Segment(
|
||
|
|
text,
|
||
|
|
(
|
||
|
|
style
|
||
|
|
+ style_from_color(
|
||
|
|
(
|
||
|
|
(from_rich_color(style.color) + color).rich_color
|
||
|
|
if style.color is not None
|
||
|
|
else None
|
||
|
|
),
|
||
|
|
(
|
||
|
|
(from_rich_color(style.bgcolor) + color).rich_color
|
||
|
|
if style.bgcolor is not None
|
||
|
|
else None
|
||
|
|
),
|
||
|
|
)
|
||
|
|
),
|
||
|
|
control,
|
||
|
|
)
|