CoolFace
Apppublic

Aluode/PerceptionLabPortable

sourceHugging Faceupdated 9mo agoView on Hugging Face
0likes
spinner.py133 linesDownload Raw Back to rich
1from typing import TYPE_CHECKING, List, Optional, Union, cast2 3from ._spinners import SPINNERS4from .measure import Measurement5from .table import Table6from .text import Text7 8if TYPE_CHECKING:9    from .console import Console, ConsoleOptions, RenderableType, RenderResult10    from .style import StyleType11 12 13class Spinner:14    """A spinner animation.15 16    Args:17        name (str): Name of spinner (run python -m rich.spinner).18        text (RenderableType, optional): A renderable to display at the right of the spinner (str or Text typically). Defaults to "".19        style (StyleType, optional): Style for spinner animation. Defaults to None.20        speed (float, optional): Speed factor for animation. Defaults to 1.0.21 22    Raises:23        KeyError: If name isn't one of the supported spinner animations.24    """25 26    def __init__(27        self,28        name: str,29        text: "RenderableType" = "",30        *,31        style: Optional["StyleType"] = None,32        speed: float = 1.0,33    ) -> None:34        try:35            spinner = SPINNERS[name]36        except KeyError:37            raise KeyError(f"no spinner called {name!r}")38        self.text: "Union[RenderableType, Text]" = (39            Text.from_markup(text) if isinstance(text, str) else text40        )41        self.name = name42        self.frames = cast(List[str], spinner["frames"])[:]43        self.interval = cast(float, spinner["interval"])44        self.start_time: Optional[float] = None45        self.style = style46        self.speed = speed47        self.frame_no_offset: float = 0.048        self._update_speed = 0.049 50    def __rich_console__(51        self, console: "Console", options: "ConsoleOptions"52    ) -> "RenderResult":53        yield self.render(console.get_time())54 55    def __rich_measure__(56        self, console: "Console", options: "ConsoleOptions"57    ) -> Measurement:58        text = self.render(0)59        return Measurement.get(console, options, text)60 61    def render(self, time: float) -> "RenderableType":62        """Render the spinner for a given time.63 64        Args:65            time (float): Time in seconds.66 67        Returns:68            RenderableType: A renderable containing animation frame.69        """70        if self.start_time is None:71            self.start_time = time72 73        frame_no = ((time - self.start_time) * self.speed) / (74            self.interval / 1000.075        ) + self.frame_no_offset76        frame = Text(77            self.frames[int(frame_no) % len(self.frames)], style=self.style or ""78        )79 80        if self._update_speed:81            self.frame_no_offset = frame_no82            self.start_time = time83            self.speed = self._update_speed84            self._update_speed = 0.085 86        if not self.text:87            return frame88        elif isinstance(self.text, (str, Text)):89            return Text.assemble(frame, " ", self.text)90        else:91            table = Table.grid(padding=1)92            table.add_row(frame, self.text)93            return table94 95    def update(96        self,97        *,98        text: "RenderableType" = "",99        style: Optional["StyleType"] = None,100        speed: Optional[float] = None,101    ) -> None:102        """Updates attributes of a spinner after it has been started.103 104        Args:105            text (RenderableType, optional): A renderable to display at the right of the spinner (str or Text typically). Defaults to "".106            style (StyleType, optional): Style for spinner animation. Defaults to None.107            speed (float, optional): Speed factor for animation. Defaults to None.108        """109        if text:110            self.text = Text.from_markup(text) if isinstance(text, str) else text111        if style:112            self.style = style113        if speed:114            self._update_speed = speed115 116 117if __name__ == "__main__":  # pragma: no cover118    from time import sleep119 120    from .console import Group121    from .live import Live122 123    all_spinners = Group(124        *[125            Spinner(spinner_name, text=Text(repr(spinner_name), style="green"))126            for spinner_name in sorted(SPINNERS.keys())127        ]128    )129 130    with Live(all_spinners, refresh_per_second=20) as live:131        while True:132            sleep(0.1)133 
Aluode/PerceptionLabPortable · CoolFace