Notes on how to make Krita's canvas embeddable into QML graph
===========================================
General considerations
-------------------------
1) QML can render arbitrary openGL/DirectX/Metal code below or under QML graph. See example [[ https://doc.qt.io/qt-5/qtquick-scenegraph-openglunderqml-example.html | here ]].
2) There is also an option to make a full-featured QML object that would render its contents using GPU directly and choose rendering API on the fly. See another example [[ https://doc.qt.io/qt-5/qtquick-scenegraph-rendernode-example.html | here ]].
3) Both options above are already available in Qt5.
4) In Qt6 QML will be using some weird RHI interface that would abstract graphics API somehow. I didn't manage to understand what it is going to be and whether we would be able to use that.
Roadmap for porting Krita to QML
--------------------------------------
1) We have a special class `KisAbstractCanvasWidget` that abstracts the graphical API. So we would need to make implmentations of it for openGL, DirectX and/or PHI.
2) `KisAbstractCanvasWidget::widget()` will have to be refactored into some higher-level interface. It is used for three purposes actually.
* issue repaint for `QOpenGLWidget` with `canvas->widget()->update(rc)`
* setup event filter on it in `KisInputManager`
* for scrolling in `KoCanvasControllerWidget`
3) `KoCanvasControllerWidget` will have to be refactored for not using `QScrollArea` and use the QML version instead. It already inherits from an abstract `KoCanvasController`, so in theory it should be "not difficult". The problem is that after splitting from Calligra we didn't keep this abstraction clean (there was only one implementation), so the refactoring may become a bit painful. It might happen that the whole zooming infrastructure will have to be refactored (though it would be nice to do that even without porting to QML).
4) `KisViewManager::statusBar()` will have to be refactored into some abstract interface, like `KoProgressProxy` plus something.
5) `KisViewManager::paintOpBox()` will have to be removed and replaced with some abstract interface (and the whole `KisControlFrame` will have to be rewritten in QML).
6) `KisViewManager::mainWindow()` will have to go. We use it in rather surprising contexts. E.g. in `KisNodeManager::slotTryRestartIsolatedMode()` we check if we are the active window and skip restarting for non-active windows.
7) All the actions are now loaded by `KXmlGuiWindow`. We will have to extract this code somehow and create `KActionCollection` manually.
8) Some zoom actions are implemented by accessing "widgets" instead of abstract controllers. Specifically, `KisZoomAction` uses `KoZoomAction` widget to switch between predefined zoom levels on wheel events (12.5%,25%,50%,100%). This functionality will have to be moved into a generic class, e.g. `KoZoomController` (I don't know why it is not there atm).
Questions to be answered/investigated
-------------------------------------------
1) Qt6 is going to [[ https://www.qt.io/blog/2019/08/07/technical-vision-qt-6 | drop support of ANGLE ]]. Will RHI interface provide us any usable abstractions? Or we will have to implement our canvas code for three native interfaces: openGL, DirectX and Metal?
UPD: as far as I can tell, RHI is going to be an internal API and not available to the users. At least for now.
2) Qt6's LTS releases are going to be [[ https://www.qt.io/blog/qt-offering-changes-2020 | closed-source only ]] (well, with 1 year delay), so we will have to maintain it somehow ourselves. How are we going to do that?
3) Porting Krita to QML will be a huge investment of work. Given that we have plans for GUI redesign anyway, perhaps we could start thinking about some other options we have?