Heyo, I'm refactoring my UI lib to support widgets that can be dragged on top of eachother, and am wondering if there's a conventional way to solve this.
I currently have a simple, naive widget graph. It starts with a “Screen” construct, which the developer can add child widgets to (then add child widgets to those widgets, etc). When I'm propagating events through this graph, I iterate through the top-level list of widgets doing hit tests on each one, and I follow the first path that returns true. I continue until I either get no hits, or I hit a leaf widget that handles the event.
Because of this setup, when I have 2 widgets on top of eachother, whichever one happens to be earliest in the graph will get the event. Instead, I need a way to set one widget as being in front of another, and I need to use this info to pass events appropriately.
I know about Z-ordering and figure it's probably the solution, but I'm getting confused on the specifics. I assume you have the developer set Z values on each widget and follow an event propagation algorithm like:
- Iterate all children and build a list of the ones that are hit
- Compare the Z values of all hit children and pass the event to the one furthest in front
It seems like that would work fine, but how does setting the Z values actually work? Do children inherit their parent's value? Do I make a “Window" widget and only attach Z values to those? Do values get changed as things get dragged around? Is the default value somewhere in the middle of the range, or all the way back?
I could use some help getting on the right track. Thanks!