Problems using ratatui #552
Replies: 3 comments 5 replies
-
Thanks for starting this discussion! There's lots of interesting pieces here to talk about, and it'll be good to have more people weigh in on this and discuss how best to address these issues. Slightly unrelated, is your code public? |
Beta Was this translation helpful? Give feedback.
-
Looks great! I have some ideas about a bunch of those points.
All up, I agree with every single point you're making. Ratatui doesn't do any of those. You could build most of that on top of Ratatui though (and many apps have done bits and pieces of all that. https://poignardazur.github.io/2023/02/02/masonry-01-and-my-vision-for-rust-ui is a particularly good article that I re-read from time to time. It has a whole suite of things that a good rust GUI library should be able to do, and there are many inspirations for things to add to Ratatui or a framework built on top of Ratatui.
All of that said, I suspect that there probably are some things that can be added to Ratatui to make some of the above more able to work well with this sort of application approach. I'm not 100% sure what all those things are, so keep that feedback coming. It's really useful. |
Beta Was this translation helpful? Give feedback.
-
It's also worth reading https://raphlinus.github.io/rust/gui/2022/05/07/ui-architecture.html which covers a similar set of gaps. |
Beta Was this translation helpful? Give feedback.
-
I am working on an interactive commit selector for source control tooling. It looks like this:
record-720p.mov
Here are some problems with
tui-rs
/ratatui
that I had to work around in my own code, which might inform future development. Let me know if you have any solutions.LinearLayout
that renders components in sequence in a certain direction. I haven't implemented this; I simply modified the rendering system to return the actually-drawnRect
, and then do math to position the next widget after it.render_widget
accepts aRect
with unsigned x-/y-coordinates.Rect
into the displayable area, but it's not easy to write widgets that behave well in this paradigm. When being rendered, the widget either has to do math to figure out what part of itself will be in the displayableRect
and only render there (not tenable in my experience), or else render to a virtual canvas internally and then copy the relevant portion to be displayed in theRect
.Rect
to be rendered to. Imagine that you're implementing a scrolling widget: you would want to render the entire widget content to theRect
, and have only a portion of it visible on the screen.Id
type and stores a map fromId
to actually renderedRect
. When clicking, to identify the clicked widget, it looks for the "top-most" (most-recently-rendered) widget that has been rendered to that position. There are subtleties dealing with the fact that only some kinds of renders want to create a logically-new clickable widget; for example, text is usually not its own clickable entity, but part of the parent widget. This approach results in infectious generics, so it may not be suitable for inclusion in the framework.match
es to help manage this.Beta Was this translation helpful? Give feedback.
All reactions