charmbracelet/bubbles

Feature: Partial block characters for progress bar

DeadlySurgeon opened this issue · 5 comments

I noticed that the progress bar uses whole blocks instead of the partial blocks: , , , , , ,

While the Empty character wouldn't really go well with it, using partial blocks does provide for a much cleaner looking progress bar.

Here is an example with a width of 30, cycling through by various delays.
progress_bar_2

Also, I created a Gist for this a while back showcasing how to basically create a progress bar using these partial blocks, however the gist is a bit old and does not have the color gradient like the Gif example does (but it is pretty straight forward to add). The TL;DR: on how to add support to this is calculate the remainder percent after filling the width with whole blocks, and then getting the remainder percent out of that from the blocks, and using that instead of a whole block.
https://gist.github.com/DeadlySurgeon/4012083474ff4b4ef0fa464417deed9a

I think it would be good that if this is added, it would be opt'd in with something like a progress.UsePartialBlocks() option.

Another thing I was playing with (but don't have as an example right now), was having the background be the same color gradient as the bar but darkened, in place of the empty character. This made it look like it was filling out space meant for the colors, but to be honest was a mixed bag with how it looked compared to just having the space be dark grey or just empty.

The main reason I sought after using partial blocks, is because for my project I have a width of 10, and need to display it decreasing over 30 seconds, which doesn't look all too good if whole blocks are being used. For bars that are long using whole blocks isn't too bad, but the shorter it is the worst it looks in my opinion.

Welp, this is pretty awesome and we should totally do it. To be honest the areas where the s butt up against each other has never been ideal anyway. If you're up for it, please do feel free to open a PR.

I think that the is good if you're doing whole blocks, as it allows you to shade in the area without having to know the terminal's background color, which is why on one of my PoCs I have it be the same gradient but darkened (finally not lazy enough to record it one sec). In the gif I provided, the background color is only darker than the surrounding terminal color, but its static. It wouldn't look the same or as good on a terminal with a purple background, or green background. Right now I'm trying to figure out what might be good on most terminals.

(ignore the low quality gif, was having a hard time with converting the screen recording into a gif to begin with and tbh don't really know of a good way other than just throwing it into OBS and wishing for the best)
2023-07-19 16-10-59

I wouldn't mind doing an implementation and opening a PR at some point, but I am curious as to thoughts on the background color or replacement to the empty character, as that's the one thing I'm not sure would be best here, and my solution of just a static color like dark grey likely wouldn't be ideal.

Something else I noticed, I think that the percent being printed right now is rounded instead of floored, leading to .996 becoming 100% instead of 99%, which while normally not likely to be problematic, if some reason a process is printing out a progress bar and it gets trapped on that last .5%, it'll show it as completed when it actually was hung, leading to users potentially getting confused.

https://github.com/charmbracelet/bubbles/blob/master/progress/progress.go#L330-L338

Doing a math.Floor, or converting the float into an integer to drop off the trailing percent, would show a more accurate percentage.