second commit
This commit is contained in:
9
env/lib/python3.11/site-packages/rich_toolkit/styles/__init__.py
vendored
Normal file
9
env/lib/python3.11/site-packages/rich_toolkit/styles/__init__.py
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
from .fancy import FancyStyle
|
||||
from .tagged import TaggedStyle
|
||||
from .minimal import MinimalStyle
|
||||
|
||||
__all__ = [
|
||||
"FancyStyle",
|
||||
"TaggedStyle",
|
||||
"MinimalStyle",
|
||||
]
|
BIN
env/lib/python3.11/site-packages/rich_toolkit/styles/__pycache__/__init__.cpython-311.pyc
vendored
Normal file
BIN
env/lib/python3.11/site-packages/rich_toolkit/styles/__pycache__/__init__.cpython-311.pyc
vendored
Normal file
Binary file not shown.
BIN
env/lib/python3.11/site-packages/rich_toolkit/styles/__pycache__/base.cpython-311.pyc
vendored
Normal file
BIN
env/lib/python3.11/site-packages/rich_toolkit/styles/__pycache__/base.cpython-311.pyc
vendored
Normal file
Binary file not shown.
BIN
env/lib/python3.11/site-packages/rich_toolkit/styles/__pycache__/fancy.cpython-311.pyc
vendored
Normal file
BIN
env/lib/python3.11/site-packages/rich_toolkit/styles/__pycache__/fancy.cpython-311.pyc
vendored
Normal file
Binary file not shown.
BIN
env/lib/python3.11/site-packages/rich_toolkit/styles/__pycache__/minimal.cpython-311.pyc
vendored
Normal file
BIN
env/lib/python3.11/site-packages/rich_toolkit/styles/__pycache__/minimal.cpython-311.pyc
vendored
Normal file
Binary file not shown.
BIN
env/lib/python3.11/site-packages/rich_toolkit/styles/__pycache__/tagged.cpython-311.pyc
vendored
Normal file
BIN
env/lib/python3.11/site-packages/rich_toolkit/styles/__pycache__/tagged.cpython-311.pyc
vendored
Normal file
Binary file not shown.
125
env/lib/python3.11/site-packages/rich_toolkit/styles/base.py
vendored
Normal file
125
env/lib/python3.11/site-packages/rich_toolkit/styles/base.py
vendored
Normal file
@ -0,0 +1,125 @@
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import Any, Generator, Iterable, List, Type, TypeVar
|
||||
from typing_extensions import Literal
|
||||
|
||||
from rich.color import Color
|
||||
from rich.console import (
|
||||
Console,
|
||||
ConsoleOptions,
|
||||
ConsoleRenderable,
|
||||
RenderableType,
|
||||
RenderResult,
|
||||
)
|
||||
from rich.segment import Segment
|
||||
from rich.text import Text
|
||||
|
||||
|
||||
from rich_toolkit.utils.colors import lighten
|
||||
|
||||
|
||||
ConsoleRenderableClass = TypeVar(
|
||||
"ConsoleRenderableClass", bound=Type[ConsoleRenderable]
|
||||
)
|
||||
|
||||
|
||||
ANIMATION_STATUS = Literal["started", "stopped", "error", "no_animation"]
|
||||
|
||||
|
||||
class BaseStyle(ABC):
|
||||
result_color: Color
|
||||
decoration_size: int
|
||||
|
||||
def __init__(self) -> None:
|
||||
self.padding = 2
|
||||
self.cursor_offset = 0
|
||||
|
||||
self._animation_counter = 0
|
||||
self.decoration_size = 2
|
||||
|
||||
def empty_line(self) -> Text:
|
||||
return Text(" ")
|
||||
|
||||
def with_decoration(
|
||||
self,
|
||||
*renderables: RenderableType,
|
||||
animation_status: ANIMATION_STATUS = "no_animation",
|
||||
**metadata: Any,
|
||||
) -> ConsoleRenderable:
|
||||
class WithDecoration:
|
||||
@staticmethod
|
||||
def __rich_console__(
|
||||
console: Console, options: ConsoleOptions
|
||||
) -> RenderResult:
|
||||
for content in renderables:
|
||||
# our styles are potentially adding some paddings on the left
|
||||
# and right sides, so we need to adjust the max_width to
|
||||
# make sure that rich takes that into account
|
||||
options = options.update(
|
||||
max_width=console.width - self.decoration_size
|
||||
)
|
||||
|
||||
lines = console.render_lines(content, options, pad=False)
|
||||
|
||||
for line in Segment.split_lines(
|
||||
self.decorate(
|
||||
lines=lines,
|
||||
console=console,
|
||||
animation_status=animation_status,
|
||||
**metadata,
|
||||
)
|
||||
):
|
||||
yield from line
|
||||
yield Segment.line()
|
||||
|
||||
return WithDecoration()
|
||||
|
||||
def decorate_class(
|
||||
self, klass: ConsoleRenderableClass, **metadata: Any
|
||||
) -> ConsoleRenderableClass:
|
||||
style = self
|
||||
|
||||
class Decorated(klass): # type: ignore[valid-type,misc]
|
||||
def __rich_console__(
|
||||
self, console: Console, options: ConsoleOptions
|
||||
) -> RenderResult:
|
||||
lines = Segment.split_lines(super().__rich_console__(console, options)) # type: ignore
|
||||
|
||||
yield from style.decorate(lines=lines, console=console, **metadata)
|
||||
|
||||
return Decorated # type: ignore
|
||||
|
||||
@abstractmethod
|
||||
def decorate(
|
||||
self,
|
||||
console: Console,
|
||||
lines: Iterable[List[Segment]],
|
||||
animation_status: ANIMATION_STATUS = "no_animation",
|
||||
**kwargs: Any,
|
||||
) -> Generator[Segment, None, None]:
|
||||
raise NotImplementedError()
|
||||
|
||||
def _get_animation_colors(
|
||||
self,
|
||||
console: Console,
|
||||
steps: int = 5,
|
||||
animation_status: ANIMATION_STATUS = "started",
|
||||
**metadata: Any,
|
||||
) -> List[Color]:
|
||||
animated = animation_status == "started"
|
||||
|
||||
if animation_status == "error":
|
||||
base_color = console.get_style("error").color
|
||||
|
||||
if base_color is None:
|
||||
base_color = Color.parse("red")
|
||||
|
||||
else:
|
||||
base_color = console.get_style("progress").bgcolor
|
||||
|
||||
if not base_color:
|
||||
base_color = Color.parse("white")
|
||||
|
||||
if animated and base_color.triplet is not None:
|
||||
return [lighten(base_color, 0.1 * i) for i in range(0, steps)]
|
||||
|
||||
return [base_color] * steps
|
63
env/lib/python3.11/site-packages/rich_toolkit/styles/fancy.py
vendored
Normal file
63
env/lib/python3.11/site-packages/rich_toolkit/styles/fancy.py
vendored
Normal file
@ -0,0 +1,63 @@
|
||||
from typing import Any, Generator, Iterable, List
|
||||
|
||||
from rich._loop import loop_first_last
|
||||
from rich.console import (
|
||||
Console,
|
||||
)
|
||||
from rich.segment import Segment
|
||||
from rich.style import Style
|
||||
from rich.text import Text
|
||||
|
||||
|
||||
from .base import ANIMATION_STATUS, BaseStyle
|
||||
|
||||
|
||||
class FancyStyle(BaseStyle):
|
||||
def __init__(self, *args, **kwargs) -> None:
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
self.cursor_offset = 2
|
||||
self.decoration_size = 2
|
||||
|
||||
def decorate(
|
||||
self,
|
||||
console: Console,
|
||||
lines: Iterable[List[Segment]],
|
||||
animation_status: ANIMATION_STATUS = "no_animation",
|
||||
**metadata: Any,
|
||||
) -> Generator[Segment, None, None]:
|
||||
if animation_status != "no_animation":
|
||||
colors = self._get_animation_colors(
|
||||
console, animation_status=animation_status, **metadata
|
||||
)
|
||||
|
||||
self._animation_counter += 1
|
||||
|
||||
color_index = self._animation_counter % len(colors)
|
||||
|
||||
for first, last, line in loop_first_last(lines):
|
||||
if first:
|
||||
yield Segment("◆ ", style=Style(color=colors[color_index]))
|
||||
else:
|
||||
yield Segment("│ ")
|
||||
yield from line
|
||||
yield Segment.line()
|
||||
|
||||
return
|
||||
|
||||
for first, last, line in loop_first_last(lines):
|
||||
if first:
|
||||
decoration = "┌ " if metadata.get("title", False) else "◆ "
|
||||
elif last:
|
||||
decoration = "└ "
|
||||
else:
|
||||
decoration = "│ "
|
||||
|
||||
yield Segment(decoration)
|
||||
yield from line
|
||||
|
||||
if not last:
|
||||
yield Segment.line()
|
||||
|
||||
def empty_line(self) -> Text:
|
||||
return Text("│")
|
59
env/lib/python3.11/site-packages/rich_toolkit/styles/minimal.py
vendored
Normal file
59
env/lib/python3.11/site-packages/rich_toolkit/styles/minimal.py
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
from typing import Any, Generator, Iterable, List
|
||||
|
||||
from rich._loop import loop_first_last
|
||||
from rich.console import (
|
||||
Console,
|
||||
)
|
||||
from rich.segment import Segment
|
||||
from rich.style import Style
|
||||
from rich.text import Text
|
||||
|
||||
|
||||
from .base import ANIMATION_STATUS, BaseStyle
|
||||
|
||||
|
||||
class MinimalStyle(BaseStyle):
|
||||
def __init__(self, *args, **kwargs) -> None:
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
self.cursor_offset = 2
|
||||
self.decoration_size = 2
|
||||
|
||||
def decorate(
|
||||
self,
|
||||
console: Console,
|
||||
lines: Iterable[List[Segment]],
|
||||
animation_status: ANIMATION_STATUS = "no_animation",
|
||||
**metadata: Any,
|
||||
) -> Generator[Segment, None, None]:
|
||||
if animation_status != "no_animation":
|
||||
block = "●"
|
||||
colors = self._get_animation_colors(
|
||||
console, animation_status=animation_status, **metadata
|
||||
)
|
||||
|
||||
self._animation_counter += 1
|
||||
|
||||
color_index = self._animation_counter % len(colors)
|
||||
|
||||
for first, last, line in loop_first_last(lines):
|
||||
if first:
|
||||
yield Segment(f"{block} ", style=Style(color=colors[color_index]))
|
||||
else:
|
||||
yield Segment(" " * 2)
|
||||
yield from line
|
||||
yield Segment.line()
|
||||
|
||||
return
|
||||
|
||||
for first, last, line in loop_first_last(lines):
|
||||
decoration = " " * 2
|
||||
|
||||
yield Segment(decoration)
|
||||
yield from line
|
||||
|
||||
if not last:
|
||||
yield Segment.line()
|
||||
|
||||
def empty_line(self) -> Text:
|
||||
return Text("")
|
100
env/lib/python3.11/site-packages/rich_toolkit/styles/tagged.py
vendored
Normal file
100
env/lib/python3.11/site-packages/rich_toolkit/styles/tagged.py
vendored
Normal file
@ -0,0 +1,100 @@
|
||||
from typing import Any, Generator, Iterable, List
|
||||
|
||||
from rich._loop import loop_first_last
|
||||
from rich.console import Console
|
||||
from rich.segment import Segment
|
||||
from rich.style import Style
|
||||
|
||||
from .base import ANIMATION_STATUS, BaseStyle
|
||||
|
||||
|
||||
class TaggedStyle(BaseStyle):
|
||||
def __init__(self, *args, **kwargs) -> None:
|
||||
self.tag_width = kwargs.pop("tag_width", 14)
|
||||
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
self.padding = 2
|
||||
self.cursor_offset = self.tag_width + self.padding
|
||||
self.decoration_size = self.tag_width + self.padding
|
||||
|
||||
def _render_tag(
|
||||
self,
|
||||
text: str,
|
||||
console: Console,
|
||||
**metadata: Any,
|
||||
) -> Generator[Segment, None, None]:
|
||||
style_name = "tag.title" if metadata.get("title", False) else "tag"
|
||||
|
||||
style = console.get_style(style_name)
|
||||
|
||||
if text:
|
||||
text = f" {text} "
|
||||
|
||||
left_padding = self.tag_width - len(text)
|
||||
left_padding = max(0, left_padding)
|
||||
|
||||
yield Segment(" " * left_padding)
|
||||
yield Segment(text, style=style)
|
||||
yield Segment(" " * self.padding)
|
||||
|
||||
def decorate(
|
||||
self,
|
||||
console: Console,
|
||||
lines: Iterable[List[Segment]],
|
||||
animation_status: ANIMATION_STATUS = "no_animation",
|
||||
**metadata: Any,
|
||||
) -> Generator[Segment, None, None]:
|
||||
if animation_status != "no_animation":
|
||||
yield from self.decorate_with_animation(
|
||||
lines=lines,
|
||||
console=console,
|
||||
animation_status=animation_status,
|
||||
**metadata,
|
||||
)
|
||||
|
||||
return
|
||||
|
||||
tag = metadata.get("tag", "")
|
||||
|
||||
for first, last, line in loop_first_last(lines):
|
||||
text = tag if first else ""
|
||||
yield from self._render_tag(text, console=console, **metadata)
|
||||
yield from line
|
||||
|
||||
if not last:
|
||||
yield Segment.line()
|
||||
|
||||
def decorate_with_animation(
|
||||
self,
|
||||
console: Console,
|
||||
lines: Iterable[List[Segment]],
|
||||
animation_status: ANIMATION_STATUS = "no_animation",
|
||||
**metadata: Any,
|
||||
) -> Generator[Segment, None, None]:
|
||||
block = "█"
|
||||
block_length = 5
|
||||
colors = self._get_animation_colors(
|
||||
console, steps=block_length, animation_status=animation_status, **metadata
|
||||
)
|
||||
|
||||
left_padding = self.tag_width - block_length
|
||||
left_padding = max(0, left_padding)
|
||||
|
||||
self._animation_counter += 1
|
||||
|
||||
for first, _, line in loop_first_last(lines):
|
||||
if first:
|
||||
yield Segment(" " * left_padding)
|
||||
|
||||
for j in range(block_length):
|
||||
color_index = (j + self._animation_counter) % len(colors)
|
||||
yield Segment(block, style=Style(color=colors[color_index]))
|
||||
|
||||
else:
|
||||
yield Segment(" " * self.tag_width)
|
||||
|
||||
yield Segment(" " * self.padding)
|
||||
|
||||
yield from line
|
||||
yield Segment.line()
|
Reference in New Issue
Block a user