Skip to content

Commit 58e5656

Browse files
committed
feat(bar): Add support for custom icons
You can super a textual.renderable.bar.Bar class and change `HALF_BAR_LEFT`, `BAR`, and `HALF_BAR_RIGHT`, before passing the class as an keyword argument in the textual.widgets.ProgressBar widget as `bar_renderable`. The keyword arg's name is weird, I'm not sure what to name it
1 parent 9ba69c3 commit 58e5656

File tree

2 files changed

+26
-15
lines changed

2 files changed

+26
-15
lines changed

src/textual/renderables/bar.py

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ class Bar:
1818
gradient: Optional gradient object.
1919
"""
2020

21+
HALF_BAR_LEFT: str = "╺"
22+
BAR: str = "━"
23+
HALF_BAR_RIGHT: str = "╸"
24+
2125
def __init__(
2226
self,
2327
highlight_range: tuple[float, float] = (0, 0),
@@ -40,10 +44,6 @@ def __rich_console__(
4044
highlight_style = console.get_style(self.highlight_style)
4145
background_style = console.get_style(self.background_style)
4246

43-
half_bar_right = "╸"
44-
half_bar_left = "╺"
45-
bar = "━"
46-
4747
width = self.width or options.max_width
4848
start, end = self.highlight_range
4949

@@ -53,7 +53,7 @@ def __rich_console__(
5353
output_bar = Text("", end="")
5454

5555
if start == end == 0 or end < 0 or start > end:
56-
output_bar.append(Text(bar * width, style=background_style, end=""))
56+
output_bar.append(Text(self.BAR * width, style=background_style, end=""))
5757
yield output_bar
5858
return
5959

@@ -67,34 +67,40 @@ def __rich_console__(
6767

6868
# Initial non-highlighted portion of bar
6969
output_bar.append(
70-
Text(bar * (int(start - 0.5)), style=background_style, end="")
70+
Text(self.BAR * (int(start - 0.5)), style=background_style, end="")
7171
)
7272
if not half_start and start > 0:
73-
output_bar.append(Text(half_bar_right, style=background_style, end=""))
73+
output_bar.append(Text(self.HALF_BAR_RIGHT, style=background_style, end=""))
7474

7575
highlight_bar = Text("", end="")
7676
# The highlighted portion
7777
bar_width = int(end) - int(start)
7878
if half_start:
7979
highlight_bar.append(
8080
Text(
81-
half_bar_left + bar * (bar_width - 1), style=highlight_style, end=""
81+
self.HALF_BAR_LEFT + self.BAR * (bar_width - 1),
82+
style=highlight_style,
83+
end="",
8284
)
8385
)
8486
else:
85-
highlight_bar.append(Text(bar * bar_width, style=highlight_style, end=""))
87+
highlight_bar.append(
88+
Text(self.BAR * bar_width, style=highlight_style, end="")
89+
)
8690
if half_end:
87-
highlight_bar.append(Text(half_bar_right, style=highlight_style, end=""))
91+
highlight_bar.append(
92+
Text(self.HALF_BAR_RIGHT, style=highlight_style, end="")
93+
)
8894

8995
if self.gradient is not None:
9096
_apply_gradient(highlight_bar, self.gradient, width)
9197
output_bar.append(highlight_bar)
9298

9399
# The non-highlighted tail
94100
if not half_end and end - width != 0:
95-
output_bar.append(Text(half_bar_left, style=background_style, end=""))
101+
output_bar.append(Text(self.HALF_BAR_LEFT, style=background_style, end=""))
96102
output_bar.append(
97-
Text(bar * (int(width) - int(end) - 1), style=background_style, end="")
103+
Text(self.BAR * (int(width) - int(end) - 1), style=background_style, end="")
98104
)
99105

100106
# Fire actions when certain ranges are clicked (e.g. for tabs)

src/textual/widgets/_progress_bar.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,13 @@ def __init__(
7272
disabled: bool = False,
7373
clock: Clock | None = None,
7474
gradient: Gradient | None = None,
75+
bar_renderable: BarRenderable = BarRenderable,
7576
):
7677
"""Create a bar for a [`ProgressBar`][textual.widgets.ProgressBar]."""
7778
self._clock = (clock or Clock()).clone()
7879
super().__init__(name=name, id=id, classes=classes, disabled=disabled)
7980
self.set_reactive(Bar.gradient, gradient)
81+
self.bar_renderable = bar_renderable
8082

8183
def _validate_percentage(self, percentage: float | None) -> float | None:
8284
"""Avoid updating the bar, if the percentage increase is too small to render."""
@@ -104,7 +106,7 @@ def render(self) -> RenderResult:
104106
if self.percentage < 1
105107
else self.get_component_rich_style("bar--complete")
106108
)
107-
return BarRenderable(
109+
return self.bar_renderable(
108110
highlight_range=(0, self.size.width * self.percentage),
109111
highlight_style=Style.from_color(bar_style.color),
110112
background_style=Style.from_color(bar_style.bgcolor),
@@ -133,7 +135,7 @@ def render_indeterminate(self) -> RenderResult:
133135
end = start + highlighted_bar_width
134136

135137
bar_style = self.get_component_rich_style("bar--indeterminate")
136-
return BarRenderable(
138+
return self.bar_renderable(
137139
highlight_range=(max(0, start), min(end, width)),
138140
highlight_style=Style.from_color(bar_style.color),
139141
background_style=Style.from_color(bar_style.bgcolor),
@@ -239,6 +241,7 @@ def __init__(
239241
disabled: bool = False,
240242
clock: Clock | None = None,
241243
gradient: Gradient | None = None,
244+
bar_renderable: BarRenderable = BarRenderable,
242245
):
243246
"""Create a Progress Bar widget.
244247
@@ -265,6 +268,7 @@ def key_space(self):
265268
disabled: Whether the widget is disabled or not.
266269
clock: An optional clock object (leave as default unless testing).
267270
gradient: An optional Gradient object (will replace CSS styles in the bar).
271+
bar_renderable: A custom Bar object that is rendered as the bar.
268272
"""
269273
self._clock = clock or Clock()
270274
self._eta = ETA()
@@ -274,6 +278,7 @@ def key_space(self):
274278
self.show_percentage = show_percentage
275279
self.show_eta = show_eta
276280
self.set_reactive(ProgressBar.gradient, gradient)
281+
self.bar_renderable = bar_renderable
277282

278283
def on_mount(self) -> None:
279284
self.update()
@@ -283,7 +288,7 @@ def on_mount(self) -> None:
283288
def compose(self) -> ComposeResult:
284289
if self.show_bar:
285290
yield (
286-
Bar(id="bar", clock=self._clock)
291+
Bar(id="bar", clock=self._clock, bar_renderable=self.bar_renderable)
287292
.data_bind(ProgressBar.percentage)
288293
.data_bind(ProgressBar.gradient)
289294
)

0 commit comments

Comments
 (0)