-
Notifications
You must be signed in to change notification settings - Fork 326
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
List: Create a WidgetList where each item in the list is a Widget rather than Text #132
Comments
Hello, I hope I can help implementing this feature. I am working on it |
Alright, keep us posted ! |
Sweet - looking forward to seeing how you go with this @karthago1. It's been on my todo list for a while, but hasn't been the top item. Happy to look on as you develop this. If you want to do a work in progress PR for feedback, that can works well. Given there's a few different ways this might be implemented, perhaps it would be worth fleshing out a plan in this issue before going at it? |
@joshka I have created a draft PR #155. maybe it can describe the idea better. I included a trait SizeHint which is required to be implemented by every widget, which should be supported by the WidgetList. for the moment the WidgetList supports only Paragraph, which enable implementing the application in upper video. Todo: except of organizing the current Code, I need some time to check other UI libraries how they are solving a similar issue. But I think without knowing the size before rendering it will be hard to implement it. (hence something similar to the SizeHint tait may be necessary) Feel free to suggest improvements or other ideas. |
@karthago1 I've just implemented something similar, maybe it is of some help https://github.com/preiter93/tui-widget-list :) It would be nice to see it in the ratatui library. Did you think about how to i) highlight the selected item and ii) support a list of stateful widgets? |
Neat - I definitely think we could do with a Selectable trait in the main library to make it so that we can render widgets differently based on whether they are selected or not (useful for Lists, and perhaps other things like tabs or perhaps blocks or other widgets in a layout. I'm wondering whether it's possible that this could be folded into the normal list rather than making a new widgetlist, where the existing behavior of a list that shows text is just a List with a Paragraph widget. |
@preiter93 thanks I will take a look. maybe you can also review changes and suggest improvements for #155. @joshka why we don't leave it to the user, what to draw? in the widget_list example in #155 the user can change the style, widget looking or even the widget type if he is using the
I think we need different Widget if you want to stay backwards compatible. But we can implement the There is only 1 missing feature I need to implement in #155. A Shrink and Fill feature for every |
We might start planning a release for including the new features if there is a need towards that direction. But before that, I think @joshka needs to finish the implementation. |
I tried the changes in #217 but couldn't get the text list item to draw dynamically based on text size, maybe I did something wrong. Used |
Yeah #217 was mostly a PoC that didn't yet implement sizing (I haven't looked at it for a few weeks now):
I'm not entirely sure what makes sense in terms of autosizing contents. I came across a neat library the other day that could be worth exploring for that part generally across ratatui: https://crates.io/crates/taffy The issue of sizing Text is that wrapping isn't part of the text struct, it's part of the paragraph right now. So we're waiting on some of the resolution of #242 for that part. The main blocker though on the widget using the #217 implementation is #122. That change allows From a perspective of unblocking yourself: |
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
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
Many widgets can be rendered without changing their state. This commit implements The `Widget` trait for 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 ``` 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
This feature would be really helpful in my specific case. |
There haven't been, but the recent experimental changes in 0.26.0 to make WidgetRef and StatefulWidgetRef traits might make this possible to progress on. As an intermediate step, I think making the traits have an optional size_hint function similar to |
See tui-widget-list for one approach to implementing this (a list that accepts a closure that returns a (widget, height) tuple, the widget is a single widget, not a generic one, but this seems like it would be ok) |
Problem
Sometimes the layout options available in providing a
List
withText
are not quite enough.Solution
Create
widgets::WidgetList
which hasWidgetListItems
as a parallel to the currentList
widget. The algorithm for deciding what is rendered will be similar to the current list (effectively a viewport that contains the currently selected Text item, scrolled into view if necessary, and that only renders the items in the current view)widgets::WidgetList
might be a slightly confusing nameAlternatives
Text
(or evenSpan
s) should be migrated to accept a widget instead. Does it make sense to set the title of a block to a widget perhaps? What about the highlight character of a list? Should tables contain widgets instead of text? Pros: really flexible. Cons: really big change with some difficult backwards compatibility constraints.Additional context
My particular use case for this is for https://github.com/joshka/tooters where I want to be able to do some neat things like show images using a widget wrapped around https://docs.rs/viuer/latest/viuer/ and make URLs clickable by wrapping them in OSC 8 escape sequences (as a UrlWidget, not just as text).
The text was updated successfully, but these errors were encountered: