Canvas and Flake
Flake does not specify a canvas widget: every application needs to provide its own specialized canvas widget. There is a base canvas interface, but it is not necessary that the class that implements that interface is a widget. Some applications may provide more than one canvas widget. Krita, for instance, has an opengl-based canvas widget (QGLWidget) and a QPainter based canvas widget (QWidget). (And a generic QPaintDevice based canvas with either a QImage or a KisPaintDevice::QPaintDevice backend).
Around your canvas widget a canvas controller is placed: KoCanvasController. KoCanvasController takes care of the scrollbars (sizing the thumbs, registrering scrolling, placing the thumbs) as well as the gray (or perhaps decorated?) border around your canvas, centering your canvas widget if the view is smaller than the widget and initiating drag and drop from the shape selector to your canvas.
Because QGLWidget needs to be supported as a canvas widget, and because the size of a QGLWidget cannot exceed the size of a single texture (which may be as small as 1024x1024!), the ordinary QScrollArea is not suitable. QScrollArea resized the widget it contains to the size of the document in pixels -- imagine a 5000x5000 pixel image, zoomed at 1600%, or a 700 page KWord document.
KoCanvasController is based on QAbstractScrollArea. The size of the canvas widget no longer depends on the size of the document: the canvas widget will always be as big as or smaller than the KoCanvasController viewport. The canvas widget is now a window on a rectangle of your document. And thus, given this viewport in pixels on your document, you need to be able to compute where to start painting and where in your document keyboard and mouse events are happening.
Because we need to set the size of the scrollbar thumbnails, KoCanvasController needs to know how big your document is in pixels.
There is already a class in flake that can do the conversion between view pixels and document coordinates at the right zoom level: KoViewConverter, with its implementation KoZoomHandler.
- Setting the size of the margin: the "canvasmargin" settting in the app's .rc file determines the size of the margin. By default it's 0 pixels. (If necessary, we could have four settings, so the canvas margin can differ top, left, right and bottom). No usecase springs to my mind, though.
- Since we now know which area is visible of the document it becomes feasible to prescale that visible area to the right zoom level before painting. Other optimizations, for instance when scrolling, are possible, too.