-
-
Notifications
You must be signed in to change notification settings - Fork 946
feat(bar): Add support for custom icons #5963
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
src/textual/widgets/_progress_bar.py
Outdated
@@ -72,11 +72,13 @@ def __init__( | |||
disabled: bool = False, | |||
clock: Clock | None = None, | |||
gradient: Gradient | None = None, | |||
bar_renderable: BarRenderable = BarRenderable, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not convinced this is something that warrants being in the constructor. It feels more like an internal detail than configuration.
How about we expose the bar renderable as a classvar?
Something like this:
class FancyProgress(ProgressBar):
BAR_RENDERABLE_CLASS = FancyBar
Then you wouldn't have to specify it everywhere you use the progress bar.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the bar renderable is passed in as a class variable into the Bar element, what about the main ProgressBar element?
I'm not sure how the ProgressBar element can receive the Bar Renderable to be passed to the Bar widget as a class variable before being rendered
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm also a tad bit confused on the comment, because your review comment is on the Bar element while your code example is for the ProgressBar element
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the idea of a classvar, but I see your problem, @NSPC911. It is ProgressBar -> Bar -> BarRenderable and you want to change the renderable. It feels a bit heavy-handed to create two classvars where every user should have to do:
class FancyBarRenderable(BarRenderable):
...
class FancyBar(Bar):
BAR_RENDERABLE_CLASS = FancyBarRenderable
class FancyProgressBar(ProgressBar):
BAR_CLASS = FancyBar
where the whole FancyBar
is just needed to connect the dots between FancyProgressBar
and FancyBarRenderable
. Maybe use a classvar only on ProgressBar
and do pass the BarRenderable
into the constructor of Bar
? So the user can do:
class FancyBarRenderable(BarRenderable):
...
class FancyProgressBar(ProgressBar):
BAR_RENDERABLE_CLASS = FancyBarRenderable
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How should ProgressBar send the renderable to the Bar widget without it having an input in the constructor of the Bar class?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How should ProgressBar send the renderable to the Bar widget without it having an input in the constructor of the Bar class?
Don't use it in the init of ProgressBar, but do use it in the init of Bar. So you get the benefit of quickly defining your fancy progress bar without having to pass in the renderable every time you need it or needing to override the init. You just pass it as a class var. Internally, the ProgressBar does pass on the renderable from the classvar to the Bar widget.
58e5656
to
1339ce7
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
1339ce7
to
b2aded2
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had two comments regarding type hinting, otherwise seems to work great!
I see that you are force pushing commits to this PR instead of pushing new commits. I've never done that myself, but is there a benefit to that I'm unfamiliar with? |
keeps changes to a single commit, I'm just used to doing this |
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
b2aded2
to
f23a571
Compare
The downside of force-pushing is that git complains when I want to test your new changes:
I'll force it and have another look. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is ready, pending @willmcgugan's blessing.
git fetch
git reset --hard <remote>/<branch> usually solves it for me |
You can now super a
textual.renderable.bar.Bar
class and change HALF_BAR_LEFT, BAR, and HALF_BAR_RIGHT, before passing the class as a keyword argument in thetextual.widgets.ProgressBar
widget as bar_renderable. The keyword arg's name might be weird.resolves #5350
Image:

Code Snippet
Please review the following checklist.