-
-
Notifications
You must be signed in to change notification settings - Fork 346
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
feat(widgets): implement Widget for Widget refs #833
Conversation
Codecov ReportAttention:
Additional details and impacted files@@ Coverage Diff @@
## main #833 +/- ##
=======================================
- Coverage 92.3% 92.3% -0.1%
=======================================
Files 61 61
Lines 16096 16141 +45
=======================================
+ Hits 14872 14903 +31
- Misses 1224 1238 +14 ☔ View full report in Codecov by Sentry. |
Not all the examples have been updated, but this is about a good enough size to review as it stands. |
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.
As stated on discord I like this way of introducing render by reference. Approved!
Fun fact that I discovered earlier tonight.
impl Widget for Block<'_> {
fn render(self, area: Rect, buf: &mut Buffer) {
(&self).render(area, buf);
}
}
impl Widget for &Block<'_> {
fn render(self, area: Rect, buf: &mut Buffer) {
if area.is_empty() {
return;
}
self.render_borders(area, buf);
self.render_titles(area, buf);
}
} This allows you to do all the things you'd need to against a reference to the widget - you can store it, render a reference to it, etc. let block = Block::default().title("Block").borders(Borders::ALL);
// does not compile
terminal.draw(|frame| {
frame.render_widget(block, frame.size());
let _area = block.inner(Rect::default());
})?;
// compiles
terminal.draw(|frame| {
frame.render_widget(&block, frame.size());
let _area = block.inner(Rect::default());
})?; The upshot of this is that instead of adding two traits, we should instead implement Widget on &T more often. |
And instead of MutWidget we continue using the stateful widget strategy? I actually like that a lot. |
Seconding kd here, I think having |
What this does suggest is that we could do with some really clear docs on these scenarios. |
+1 for implementing on
Yep if we keep |
|
e2be756
to
9a4c18e
Compare
eef2054
to
45146ce
Compare
I rebased this on main, squashed to remove the RefWidget implmentation, and updated the commit message and PR comment to fit as a good changelog message. |
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.
Looks good, only the doc is a mandatory change for me.
I've pulled in the changes from main and finished off all the widgets except BarChart. |
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.
All good to me. We'll finally have render by ref! I still can't believe it was this simple.
Many widgets can be rendered without changing their state. This commit implements The `Widget` trait for various references to widgets and changes their implementations to be immutable. This allows us to render widgets without consuming them by passing a ref to the widget when calling `Frame::render_widget()`. ```rust // this might be stored in a struct let paragraph = Paragraph::new("Hello world!"); let [left, right] = area.split(&Layout::horizontal([20, 20])); frame.render_widget(¶graph, left); frame.render_widget(¶graph, right); // we can reuse the widget ``` - Clear - Block - Tabs - Sparkline - Paragraph - Gauge - Calendar Other widgets will be implemented in follow up commits. Fixes: #164 Replaces PRs: #122 and #16 Enables: #132 Validated as a viable working solution by: #836
4dc61c2
to
2269c5d
Compare
Many widgets can be rendered without changing their state.
This commit implements The
Widget
trait for references towidgets and changes their implementations to be immutable.
This allows us to render widgets without consuming them by passing a ref
to the widget when calling
Frame::render_widget()
.Implemented for all widgets except BarChart (which has an implementation that
modifies the internal state and requires a rewrite to fix.
Other widgets will be implemented in follow up commits.
Fixes: #164
Replaces PRs: #122 and #16
Enables: #132
Validated as a viable working solution by: #836