Skip to content
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

Add block bar #361

Merged
merged 7 commits into from Oct 16, 2020
Merged

Add block bar #361

merged 7 commits into from Oct 16, 2020

Conversation

megaserg
Copy link
Contributor

@megaserg megaserg commented Oct 8, 2020

Type of changes

  • Bug fix
  • New feature
  • Documentation / docstrings
  • Tests
  • Other

Checklist

  • I've run the latest black with default args on new code.
  • I've updated CHANGELOG.md and CONTRIBUTORS.md where appropriate.
  • I've added tests for new code.
  • I accept that @willmcgugan may be pedantic in the code review.

Description

This implements a solid block bar, as requested in #293.
Try with: python -m rich.block_bar

Implemented:

  • Block elements support
    • left-aligned bars with 1/8-of-a-cell granularity on the right side
    • right-aligned bars with 1/2-of-a-cell granularity on the left side
  • Render nothing when value is min

Not implemented:

  • Render nothing when value is max
  • Color gradient blends between colors

Note: BlockBar might not be the best name. Let me know!

@codecov
Copy link

codecov bot commented Oct 8, 2020

Codecov Report

Merging #361 into master will increase coverage by 0.00%.
The diff coverage is 100.00%.

Impacted file tree graph

@@           Coverage Diff           @@
##           master     #361   +/-   ##
=======================================
  Coverage   99.11%   99.12%           
=======================================
  Files          50       51    +1     
  Lines        4308     4357   +49     
=======================================
+ Hits         4270     4319   +49     
  Misses         38       38           
Flag Coverage Δ
#unittests 99.12% <100.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
rich/console.py 100.00% <ø> (ø)
rich/syntax.py 95.77% <ø> (ø)
rich/block_bar.py 100.00% <100.00%> (ø)
rich/bar.py 100.00% <0.00%> (ø)
rich/box.py 100.00% <0.00%> (ø)
rich/progress.py 94.66% <0.00%> (ø)
rich/traceback.py 100.00% <0.00%> (ø)
rich/default_styles.py 100.00% <0.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update e75649a...8320e83. Read the comment docs.

@willmcgugan
Copy link
Collaborator

Bravo for attempting this.

It might be a mistake to duplicate some of the arguments from the progress bar. I can see this being a more general purpose thing, which would have different uses beyond progress.

I'm thinking it should have a width (in cells), plus a start and end argument as a float (which could be internally converted to 1/8ths). Plus a foreground and background color.

You're absolutely correct that there are only left aligned block characters. But flip the foreground and background colors, and you have the equivalent of right aligned. :-)

rich/bar.py Outdated
style: StyleType = "bar.back",
complete_style: StyleType = "bar.complete",
finished_style: StyleType = "bar.finished",
blend_colors: bool = False,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that we probably don't want to implement blending here. This class could be a primitive that you could extend to add the blend functionality.

It should probably use colors, rather than styles. Since much of the attributes (italic / bold) etc don't make sense for a solid bar.

Here's what I'm thinking for the constructor:

width: Optional[float],  # Number of cells to use, or None for full width
size: float, # Value for end of the bar
start: float,  # Start point (in 0 -> size units)
end: float,  # End point
color: Union[Color, str] = "default",
background: Union[Color, str] = "default", 

A union for the colors, so you can pass a Color or a string to call Color.parse with.

What do you think?

@megaserg
Copy link
Contributor Author

megaserg commented Oct 8, 2020

You're absolutely correct that there are only left aligned block characters. But flip the foreground and background colors, and you have the equivalent of right aligned. :-)

That's a nice trick @willmcgugan! I got it working. But in my iTerm, if I set some non-zero window transparency, the background color from the flipped Style looks faded compared to the foreground color from the non-flipped Style, unless I set checkbox "Keep background colors opaque". Is there anything I can do? 🤔

Also, how can I flip colors in case they are both "default"?

@willmcgugan
Copy link
Collaborator

But in my iTerm, if I set some non-zero window transparency, the background color from the flipped Style looks faded compared to the foreground color from the non-flipped Style, unless I set checkbox "Keep background colors opaque". Is there anything I can do? 🤔

Ah that's a shame.

There is an "right half block" character (▐) . You could have the 1/8 granularity for the right hand side of the bar, and the 1/2 block granularity for the left.

Also, how can I flip colors in case they are both "default"?

Good point. If we don't use the flipping colors trick and use the right half block, then this won't be an issue.

Alternatively we could disallow default colors for the bar, and document the transparency issue.

I'll leave it up to you.

BTW would love to see screenshots!

@megaserg
Copy link
Contributor Author

megaserg commented Oct 9, 2020

Sure, this is a checkbox I'm talking about:
checkbox
I've made a bar with color = "bright_green" and bgcolor = "bright_red".

With checkbox unchecked, notice how on the light background the rightmost red (where it's the background color) is less saturated than the leftmost red (where it's the foreground color after flip).
unchecked_light
Similarly, on the dark background a bit of green on the left (where it's the background color after flip) is less saturated than the the rest of the green (where it's the foreground color).
unchecked_dark

With checkbox checked, it's looking good on light and dark backgrounds:
checked_light
checked_dark

@willmcgugan
Copy link
Collaborator

Just had a thought. Rather than swap the foreground / background manually, what if you were to set inverse=True on the style? I think that may work better. And it should also solve the "default on default" issue.

@willmcgugan
Copy link
Collaborator

Would you mind also adding an example in examples/ ?

Something very simple, a few lines that show how you might use it in practice.

@megaserg
Copy link
Contributor Author

megaserg commented Oct 9, 2020

Do you mean reverse=True? I tried it, and the problem of non-opaque background color is still there 😔 For "default on default" issue, it did switch the colors but made black the foreground color which made it non-transparent.
black_reverse

@megaserg
Copy link
Contributor Author

@willmcgugan I would go with a 1/2 granularity on the left side 😌 (actually there is also right-aligned 1/8 block character, so there's a choice of three characters: 1/8, 1/2, full). Added the example too!

@willmcgugan
Copy link
Collaborator

Thanks @megaserg This looks great. I'll merge this soon.

@willmcgugan willmcgugan added the accepted Task was accepted label Oct 14, 2020
@willmcgugan willmcgugan merged commit e1cb479 into Textualize:master Oct 16, 2020
@willmcgugan
Copy link
Collaborator

Thanks @megaserg !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
accepted Task was accepted
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants