(ui): provide a view/widget that can be overlayed on 3D scenes
Description
Currently, we abuse SliderView
to overlay widgets on top of 3D scenes, like in SightViewer for instance. However, this class was not really designed for this. Its usage is very verbose in XML. And more importantly, it suffers from two bugs:
- depending on the desktop managers (KDE for instance), the views may not follow the window movement,
- with NVidia mobile drivers, the transparency does not work and is replaced by a black color.
Proposal
- Use a different Qt layout? View?
- Use some magic QML?
- Or directly use Ogre to draw those widgets? (I would prefer not, there would be a lot of code to do...)
First things first. Why is that SlideView thing so problematic, and why do we need it to draw things on top of 3D scenes? We use the Ogre render to draw our 3D scenes. Ogre only can draw scenes in native windows, because it draws directly in windows framebuffers. Meanwhile, Qt supports widget stacking: it will draw widgets on bottom first, then widgets on top, so that all widgets are drawn correctly... Unfortunately, this doesn't work well with Ogre. This is because Qt and Ogre don't really communicate with each other, and if we try to put a widget on a Ogre scene 3D, Ogre will typically redraw on top of it, thus hiding these widgets. The current solution is pretty simple: the widgets that must be on top on the scene 3D are native windows themselves. This means that we delegate the stacking responsibility to the window manager (KDE, GNOME, Windows, etc.), as they know which windows are on top of which, and will draw them in the right order. Unfortunately, this solution has some problems, as described in Description.
Delegating the responsibility to the window manager is the current solution, as described in the previous paragraph. There is some other solutions.
Give the responsibility to Ogre. That is, use Ogre to draw those widgets. QWidget::render with a QPixmap, and ask Ogre to draw that QPixmap. This might be done using Ogre::Overlay, and maybe OgreBites::Trays as well. But this means that either the widget must know on top of which scene it is, in order to send its image to it, or that the scene knows which widget is in top of it. And there also might be some problem when the widget moves or the scene is hidden/shown. How to know which is the new scene to draw the widget on?
Use ImGUI. This means to completely replace the overlay Qt widgets by ImGUI widgets. As we will deal with ImGUI widgets and not Qt widgets, this means that we won't be able to use Qt functionality such as signals/slots and events, and doing graphic tests might be harder. In addition, this adds yet another dependency for our project.
Give the responsibility to Qt. Give Qt the control of the drawing on the surface, so there is no stacking problems. We may use QOpenGLWidget, which works around this problem by drawing on an offscreen framebuffer, and copies this onscreen when needed. Generally speaking, this solution should provide a better integration of the scene 3D inside the application, since it will be treated like a typical widget. However, it means that a potentially heavy refactoring of classes in modules/viz/scene3dQt might have to be done.
Functional specifications
Workflow, UX/UI design, screenshots, etc...
Technical specifications
Details of the implementation
Test plan
Describe how you will verify that the implementation fulfils the specifications