-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Calculating a UI's size without rendering it #606
Comments
Maybe this could be implemented in Lines 12 to 32 in 784bac5
or maybe just by having an empty clip rect? |
Perfect! This seems to suffice, at least for vertical and horizontal layouts: fn measure_pattern(&self, ui: &mut Ui, pat: &PatternVis, graph: &GraphVis) -> Response {
let old_clip_rect = ui.clip_rect();
let old_cursor = ui.cursor();
ui.set_clip_rect(Rect::NOTHING);
let r = self.pattern(ui, pat, graph, None);
ui.set_clip_rect(old_clip_rect);
ui.set_cursor(old_cursor);
r
} I.e. before measuring we cache the Now we can take the I would like to make this a supported Api in |
Having something like this would be useful, but it can quickly lead to an exponential explosion of runtime. If An alternative that I have been thinking about is to have an optional pre-pass, where we call all the apps Ui code once without any paining, and with a special "this is a prepass" flag in the Context. This will allow widgets to store sizes which can be recalled in the second and final pass. This requires a bit of design work though. |
Couldn't the ones already calculated memoize their dimensions though? Doesn't avoid the 2^N but does prevent recalc. Also, isn't N simply the depth of the tree? So in most cases it won't be 'terrible' |
@DanielJoyce the problem is that you don't know when you would have to recalc. You could store the rect from the previous measurement, but I don't think we have a way of knowing if the size could be different this frame. So my idea would be to just let the user handle when to measure his Uis. We could still cache the last measured sizes, but the user will have to make sure they can use them, and this might not work so well. So it would be nice if we could detect changes somehow if we are going to cache things.. Edit: oh, I am just now putting your comment into context.. yes, this would probably work well, for the measurements of a single frame, we should definitely cache sizes and reuse them, then empty all caches for the next frame. Maybe later this resetting can be disabled for Uis we know didn't change. |
I wrote down my thoughts on a two-pass solution to this problem in #843 Many of the concerns there apply equally to the "measure" approach. |
I definitely support this approach. :D |
In the current version I don't see |
+1, don't see no |
It's there but it's a crate private function egui/crates/egui/src/placer.rs Line 72 in 083d61f
I made a fork and added it to Ui's public interface to use it. |
It would be cool if we were able to get a widgets size before actually rendering it. I know this is a fundamental limitation of immediate mode UIs, but it should be easily possible to do this, right? Basically we just make all of the calls except the ones that take any effect on the screen.
My situation is that I have a row of items with different sizes, and I want the entire row to have the same height. When I add the tallest item first, this works, because then the later elements know their height. But when the tallest element is not the first, then the first item will not know how tall it should be. So I would like to iterate through all elements before rendering them, to calculate their sizes and find the max height, then set use that height for all elements when rendering them.
The idea is basically to render to an offscreen buffer, just to get the final size of the
Ui
, without actually rendering anything. If there is some way to know if theUi
changed it would also be possible to cache something here, but I doubt that this will be possible without compromising developer experience.The text was updated successfully, but these errors were encountered: