-
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
Z-ordering of shapes #1516
Comments
Hi! I'd like to tackle this. I think this would help simplify things a lot. As you say, widget call order is coupling together interaction and draw order in a way that makes some things more cumbersome than they should. The plan you outline above sounds good. But I have a few questions / comments. First, how is this going to interact with the
Float sounds like the most flexible, because you can always sneak in a shape between every pair of shapes (as long as you're not within precision limits, but it's still better than an integer). As for 32 or 64 bits, I'm ambivalent. Egui seems to be using f32 everywhere else (Pos2, Rect, ...) so it sounds like
I assume you mean sorting on a compound key
Presumably, there will be a performance hit. I'm not sure if trying to keep things sorted incrementally (by not using a I'm back-linking to the issue from my repo so people can track discussion: setzer22/egui_node_graph#71. |
Thanks for thinking about this @setzer22! As you notice, most of the work is design rather than implementation :) This is all related to #2244 (overlapping widgets) too. Ideally we should be able to add widgets to the same Window to different ZIndex in any order, and have the top ZIndex get the interaction. I don't have a helpful plan yet (and don't really have time to think about it this week), but this feature is something I really want to get solved. Another use case for this feature is the resize-edges of Panels, which should be painted on top of all other panels, but below windows. |
Thanks! 😄
With some guidance, I'd be more than happy to lead the implementation efforts for this 😄
You could say overlapping interactive widgets is my exact use case, so I'm very interested in this too. The nodes in my library are conceptually just widgets you can drag around, even if they might look like a window. Implementing them as windows would be wrong, as that would have all sorts of weird interactions when drawing a graph editor inside a window. I have no problem handling the ordering of widget draw calls on my end as a user (and I already do that), but right now there's no good mechanism to detach interactivity from draw order. Some sort of Z-index sounds like the perfect solution to that. |
I think we should split One would be
|
Problem
egui and epaint are currently based on "painters algorithm", i.e. painting things from back-to-front in order to get some shapes to cover others. This means when painting widgets you need to do so back-to-front. Sometimes this is difficult, especially since immediate mode ties interaction and painting together. Sometimes you want to paint things that go in the background last, or things that go in the foreground first.
For instance, when painting the
egui::Frame
we need to wait until the contents has been added before we know how big to paint the frame. So the code adds a dummyShape::Noop
and gets aShapeIdx
where the background it later put. This is a bit ugly.Proposed solution
One way to make this less cumbersome is to introduce a
Z
value for eachShape
. This could be an integer or float, and shapes with a lower Z will always be behind those with a higher Z. Shapes with the same Z are painted in the order they are added.This could be implemented by having
PaintList
storeVec<(ZIndex, ClippedShape)>
, whereZIndex
is a a typedef for e.g.i32
. EachPaintList
would do a stable sort on the Z value before draining inGraphicLayers::drain
.egui::Painter
could have a setting for whichZ
value it uses so that one can set it for aPainter
and then pass thePainter
to a function that does the painting, with that function being agnostic to what Z it is painting to (just as it is agnostic to what paint layer it is painting to).Questions
What type for Z index:
i32
,i64
,f32
,f64
?Should we have standard indexes for foreground and background?
What are the performance implications of this?
Should we still have separate
PaintList
s inGraphicLayers
, or just put theLayerId
together withZIndex
andClippedShape
and stable-sort on that too while we're at it?Applications
The text was updated successfully, but these errors were encountered: