Add support for multi viewports and windows to UI
Objective
Add support for presenting each UI tree on a specific window and viewport, while making as few breaking changes as possible.
This PR is meant to resolve the following issues at once, since they're all related.
- Resolves #5622
- Resolves #5570
- Resolves #5621
Solution
Add a new optional component that can be inserted to UI root nodes to specify which camera it should render onto. This is then used to get the render target and the viewport for that UI tree. Since this component is optional, the default behavior should be to render on the main window using the default camera. This reduces the complexity for users while giving control in contexts where it matters.
This comes with a lot of changes to the flexbox code, mainly because each node that's rendered now depends on information that's stored on its root (the scaling factor coming from the render target and viewport) which requires recursive iteration of the nodes instead of a simple query iteration.
What needs to be done to publish PR
- [ ] Decide on the final concept for the UI root component. I feel like it could replace the existing
UiCameraConfigsince they're similar. - [ ] Add proper rendering support. Flexbox and input are mostly there, but a solution must be found to only render the extracted UI nodes on the wanted target. I will look into this, but may need some pointers since I'm not even sure if this is something that's supported at the moment.
Possible future improvements
- [ ] Add support for
RenderTarget::Imageif it's even possible and a wanted feature.
Changelog
- Adds support for selecting which window and viewport each UI tree should be presented on.
Migration Guide
UI roots (UI nodes with no parent) are now fully independent from each other in the tree. Prior to these changes, they all belonged to a common flexbox node with default Style internally. Any UI code that spawned multiple UI roots that were positioned relative to each other will need to be updated.
The simplest way to fix existing UI's in that case is to move your current root nodes to a new single root that's spawned as a transparent NodeBundle::default().