Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
progress_bar.py145 linesDownload Raw Back to widget
1from __future__ import annotations2 3import typing4 5from .constants import BAR_SYMBOLS, Align, Sizing, WrapMode6from .text import Text7from .widget import Widget8 9if typing.TYPE_CHECKING:10    from collections.abc import Hashable11 12    from urwid.canvas import TextCanvas13 14 15class ProgressBar(Widget):16    _sizing = frozenset([Sizing.FLOW])17 18    eighths = BAR_SYMBOLS.HORISONTAL[:8]  # Full width line is made by style19 20    text_align = Align.CENTER21 22    def __init__(23        self,24        normal: Hashable | None,25        complete: Hashable | None,26        current: int = 0,27        done: int = 100,28        satt: Hashable | None = None,29    ) -> None:30        """31        :param normal: display attribute for incomplete part of progress bar32        :param complete: display attribute for complete part of progress bar33        :param current: current progress34        :param done: progress amount at 100%35        :param satt: display attribute for smoothed part of bar where the36                     foreground of satt corresponds to the normal part and the37                     background corresponds to the complete part.38                     If satt is ``None`` then no smoothing will be done.39 40        >>> from urwid import LineBox41        >>> pb = ProgressBar("a", "b")42        >>> pb43        <ProgressBar flow widget>44        >>> print(pb.get_text())45        0 %46        >>> pb.set_completion(34.42)47        >>> print(pb.get_text())48        34 %49        >>> class CustomProgressBar(ProgressBar):50        ...     def get_text(self):51        ...         return "Foobar"52        >>> cpb = CustomProgressBar("a", "b")53        >>> print(cpb.get_text())54        Foobar55        >>> for x in range(101):56        ...     cpb.set_completion(x)57        ...     s = cpb.render((10,))58        >>> cpb2 = CustomProgressBar("a", "b", satt="c")59        >>> for x in range(101):60        ...     cpb2.set_completion(x)61        ...     s = cpb2.render((10,))62        >>> pb = ProgressBar("a", "b", satt="c")63        >>> pb.set_completion(34.56)64        >>> print(LineBox(pb).render((20,)))65        ┌──────────────────┐66        │      ▏34 %       │67        └──────────────────┘68        """69        super().__init__()70        self.normal = normal71        self.complete = complete72        self._current = current73        self._done = done74        self.satt = satt75 76    def set_completion(self, current: int) -> None:77        """78        current -- current progress79        """80        self._current = current81        self._invalidate()82 83    current = property(lambda self: self._current, set_completion)84 85    @property86    def done(self):87        return self._done88 89    @done.setter90    def done(self, done):91        """92        done -- progress amount at 100%93        """94        self._done = done95        self._invalidate()96 97    def rows(self, size: tuple[int], focus: bool = False) -> int:98        return 199 100    def get_text(self) -> str:101        """102        Return the progress bar percentage text.103        You can override this method to display custom text.104        """105        percent = min(100, max(0, int(self.current * 100 / self.done)))106        return f"{percent!s} %"107 108    def render(109        self,110        size: tuple[int],  # type: ignore[override]111        focus: bool = False,112    ) -> TextCanvas:113        """114        Render the progress bar.115        """116        # pylint: disable=protected-access117        (maxcol,) = size118        c = Text(self.get_text(), self.text_align, WrapMode.CLIP).render((maxcol,))119 120        cf = float(self.current) * maxcol / self.done121        ccol_dirty = int(cf)122        ccol = len(c._text[0][:ccol_dirty].decode("utf-8", "ignore").encode("utf-8"))123        cs = 0124        if self.satt is not None:125            cs = int((cf - ccol) * 8)126        if ccol < 0 or (ccol == cs == 0):127            c._attr = [[(self.normal, maxcol)]]128        elif ccol >= maxcol:129            c._attr = [[(self.complete, maxcol)]]130        elif cs and c._text[0][ccol] == 32:131            t = c._text[0]132            cenc = self.eighths[cs].encode("utf-8")133            c._text[0] = t[:ccol] + cenc + t[ccol + 1 :]134            a = []135            if ccol > 0:136                a.append((self.complete, ccol))137            a.append((self.satt, len(cenc)))138            if maxcol - ccol - 1 > 0:139                a.append((self.normal, maxcol - ccol - 1))140            c._attr = [a]141            c._cs = [[(None, len(c._text[0]))]]142        else:143            c._attr = [[(self.complete, ccol), (self.normal, maxcol - ccol)]]144        return c145 
codekingpro/portable-devtools · Team Ai