Flake is the object library for KOffice. It provides a basic concept of a 'shape' which can be a square, circle or any other form. The shape can contain any sort of media because it is responsible for painting itself. This means that KWord can provide a textShape which has text flowing inside.
Flake also provides tools for manipulating these shapes. The effect we were after is that we have one library for handling all different types of objects in KOffice and therefore a uniform user experience. Moving a text in Krita will be handled exactly the same as moving a flag in Kivio. Flake objects can graphically be moved, rotated, scaled and sheared.
- Calligra/Libs/Flake/Tools And Pointers
- model view; multiple views of the same Shape, with different zoom levels.
- Allows grouping of shapes so they behave like one shape.
- Allow nesting of shapes. Nested shapes move/rotate etc at the same time as the parent does. Ideal for that arrow just outside the text area.
- Allow clipping of nested shapes. This makes sure that the nested shapes will be 'cropped' if it is bigger than the parent shape. This is useful to make cutouts of images without actually altering the source image.
- Borders. From a simple line all the way up to flowers running around the shapes border. Naturally there is no requirement for the shape to be square.
- Shapes can be given a size in millimeters, and they draw in the correct size on any monitor or on paper.
- All tools have undo/redo support.
- Shapes can be 'visible' and 'locked' but also have a checkbox for 'keep-aspect ratio' and be marked as not being selectable.
- Fully anti-aliased painting support.
- A shape has a QBrush as a background; which means gradients as well as (semi) transparent backgrounds are supported.
- A shape has an x, an y and a z-index so it can be located in 3 dimensions.
- A shape has hooks to draw non-printing items, like indicators showing there is more text then can be shown...
- Visible connectors on each shape (required by the OASIS spec)
- Excellent printing to PDF
- A shapeManager is provided, where we expect applications to use (at least) one per view. It is the main way of interacting with the shapes. It, for example, has a paint and a selection etc.
- Tools are 'sticky'. This means that, if the text tool is in use then clicking on another text shape should keep that tool. No (auto) unselecting and reselecting is done :)
- Double click to start using that shape's tool should work.
- Single click on the empty canvas will deselect all shapes. Combined with the previous point the default tool will become usable (to select another shape) but if the current tool is usable on the newly selected shape there it should be switched to immediately. In other words; switching shape by unselecting and reselecting should not forget the tool. (TODO)
Flake is the component library for KOffice. The goal is to allow major components like spreadsheets to be embedded in KWord and the text-engine to be embedded in Krita. In order to reach that goal we have to look back a little bit; in the KOffice1.n days (which lasted for the last 8 years) we had application components embedding based on widgets. This makes sense in some way since a widget really is a way to have a generic component that can be reused in other places easily.
Widgets have some shortcomings, though. The main shortcomings are:
- a widget is always square
- you can't rotate it.
- widget sizes are measured in pixels which makes it awkward to print at high resolution.
In KOffice we came up with Flake Shapes. A shape is a generic component that, just like a widget, you can reuse in other applications. Additionally we allow each shape to be zoomed, rotated and skewed. The shape doesn't even know its being deformed, which keeps it simple to program a new shape. A shape in its most pure form is only an area on screen or on paper that displays its own kind of information.
Example shapes here are a vector shape. Think a circle or even a tiger shape. Another example is a text shape. Anything from a one liner to a whole page of text. But the shape concept scales up to having a krita-image as a shape in KWord.
Shapes are typically designed to follow the Model View Controller (MVC) mechanism. This is a concept that separates concerns to allow more bug-free programming and easier understanding of structure. A shape has a paint() method and makes for the view. The data the shape holds (like text) is the model. The controller is the Tool, which will be looked into in a bit. To make clear the difference between the view (shape) and its model; you can have 5 shapes on screen that together show one large text document and individual shapes make up a 5 page document with that text. This means that the 5 shapes share one model -- the text document. And to make it a bit more complex; You can also create a new view on the same shape in the form of a new window showing page previews, for example. Multiple views on the view/shape. For maximum flexibility.
The second big part of flake are Flake Tools (the controller part hinted about above). If you want to show text you need a text shape, but the question quickly arises on how you can alter the text, or type new text. For this goal the textShape will ship a specialized text-tool that is capable of converting key and mouse events into the proper effects on the text shape. A tool is thus a piece of softare that all user input is routed into and which does something specific on the data-model for that shape. This can best be compared to having a paint application and its code to alter it abstracted into 2 parts; the painting part (shape) and the input-handling part (tool). The same for a word-processor; the text-painting part is the shape and the part that handles keypresses is the tool.
In short; each combination of a shape and its tool is a little application. Similarly there is a tool to move any shape around, as there is another tool to create and manipulate vector paths. Each button you see on the toolbox is a separate tool.
Each shape is a separate component. Shipped as a service (aka plugin) making it easy to share plugins with other applications. KOffice has a text-flake which is a plugin. And it has gotten quite simple to have a styles based text in krita or kivio now, for example.
Tools are service based, like shapes are, so again you can use those in any application that can load those services. The depth and broadness of Flake goes quite a bit further. Its got nested shapes and its got methods for generating dialogs for user input in a generic manner, etc.
Flake is a core part of the KOffice libraries and can be found in svn. under koffice/libs/flake. There is a test application useful for shape authors and for core developments. Its maintained outside of svn and can downloaded using Darcs here.
API docs can be found online on koffice.org
Flake & Embedding
KOffice applications create documents; it is seldom useful to embed a whole alien document into another application's document, but it is very useful to embed parts of those documents and have them optionally connected, or have different views on the same data in different places in the same document.
The following table organizes KOffice apps and determines which part of their documents could be an embedded flake document.
|Calligra/Stage||no (all features KPresenter uses are part of flake)|
|Calligra/Words||the text shape|
|Calligra/Flow||no (all features Kivio uses are part of flake)|
|Calligra/Karbon14||provides advanced vector manipulation for others to use|
|Krita||a base image with its full layer stack|
|Calligra/Tables||a square of cells is exported as a shape.|
|Kexi||merge data instead, e.g. into a KWord of KSpread document; one kind of Kexi reports can be KWord-like, so design mode can be very similar to KWord's editing session; whole frames of KOffice documents can be embedded as form widgets (r/w) or report frames as well|
|Calligra/Plan||each view is a usable shape; we may need to show the same data in different places in different or the same views|
|Calligra/KFormula||the formula is one big shape|
|Calligra/KChart||A chart is one big shape.|
Open Design Issues
- We defined that there is at least one tool that is able to edit a shape. So if I introduce a FooShape I have to also provide a FooTool which is capable of altering the FooShape. If I don't provide the tool then it can just be created and not altered at all (except for things like position).
- When a user pastes something it should end up at the right tool based on the type of data pasted. So if I paste data that should be handled by a StarShape, then the tool that is the buddy of the StarShape should get that paste data.
- That tool can then decide to either create a new shape or alter the current shape.
- The suggestion is to make a KoPasteTool that is not visible in the ToolManager but handles copy/paste data.
- How will we be able to provide Accessibility controls for each flake.