For the last year or so, several trolls have worked on ramping up Qt’s GUI capabilities by adding features and flexibility to our widget model, extending Qt with an animation framework, and investigating internal changes to our graphics system to meet the demand for highly animated GUIs (including excessive use of OpenGL). Some of the graphics improvements are merged into Qt 4.5, and available in snapshots. Today we’re sharing the rest of our code with you all, so you can see what’s going on.
* Labs project page: http://labs.trolltech.com/page/Projects/Graphics/Kinetic
* Git clone URL: git://labs.trolltech.com/qt/kinetic
The name of this project is “Kinetic”. Our goal is to make it easier for you as a developer to create highly animated, high-performance GUIs, without the hassle of managing complex structures, timers, and easing curves, not to mention the large state graphs that all animated GUIs tend to be full of. We’re investigating building blocks that you need in order to make the simple things easy, and everything else possible. Some parts are C++, some parts are XML.
We’d like to bring out the best from every good animation framework out there, and look for a way that makes animations fit neatly into Qt. If we can make an animation API that looks like it has always been there, and which inspires you to add nifty animations to your applications, then we have been successful.
For example, if you’d like to define two states for a widget’s geometry and an animated transition, you might do this:
QStateGroup *group = new QStateGroup;
QState *a = new QState(group);
QState *b = new QState(group);
a->setGeometry(w, QRect(100, 100, 200, 200));
b->setGeometry(w, QRect(200, 200, 150, 150));
QTransition *transition = new QTransition(a, b);
transition->addAnimation(new QAnimation(w, “geometry”));
Performance is extremely important; especially when the elements that define your UI suddenly rely on it. A sluggish animated UI is hopeless and defeats the purpose of having animations in the first place. It’s amazing how a slow animation can turn a good experience into a bad one. Kinetic places a whole new set of requirements on our graphics system. Performance starts with graphics hardware capabilities at one end of the scale, and “do what I mean” on the other end of the scale. There’s work to be done in between. We need to find ways to ensure that new UI effects are as pleasing to the eye as they are to the developer.
As for graphical effects; you might have seen recent posts from the Graphics Dojo about how cool effects are possible to do using Qt today. As part of Kinetic, we’d like to investigate how these effects can integrate neatly into the UI framework. Can we add composition effects like blurring, dropshadows, blooming, colorizing (e.g., backdrop darkening, fading from white, etc.), while keeping the APIs easy to use and the performance at 100%?
Our widget model poses some restrictions on animations. We’d like to “break out of this box”. We’re investigating how Graphics View can loosen up some of the basic constraints by allowing widgets to be scaled, rotated, faded and blurred. For the end user, a standard form looks the same by itself or embedded in Graphics View. But once you can combine widgets with custom items, and add animations and effects to the puzzle, we think you can create magic. In C++ all the details are exposed, but with XML it doesn’t have to be. We’re investigating how to evolve our UI format, which has essentially been the same for many years. Let’s face it… it’s time for a workout. We’re making a different format now, that has the same expressive power as the .UI format, but also allows you to embed states and animated transitions. This final part of the project is called “Declarative UI”.
Here’s a sample XML file that describes a simple animated UI (as a png because I can’t get Wordpress’s verbatim and pre tags to do what they should!).

So, please take this as an invitation to join us. You can find the new project on Labs and a Qt Solution for the Animation Framework in usual pages. There’s not a lot of bling there yet, because at this point it is mostly code. But there will be bling. ;-).
16 Responses to “Welcome to Kinetic”
I think most people will be wowed by all that animation stuff, but I’m really pleased to see the declarative UI format. It is such an improvement over the ui designer format.
Are there any docs for the XML format?
I haven’t looked to closely at the framework yet but it certainly looks interesting.
Can you tell me if it supports providing items with a new target translation during an animation so that the item then heads towards the new location and maintains the same velocity as it originally had? (i.e. I want to specify the velocity of an item including a nice accel/decel at the beginning and end but the target location might change. The item would then have to reaccelerate, maintain its speed, or rapidly decelerate depending on the new target location).
Thanks.
Last night I broke into the new API.
Immediately, I have complaints:
I wished you called “States” “KeyFrames” (for Flash programmers)
I wished you called “Transitions” “Tweens” (for Flash programmers)
I found QtAnimation group crashes deterministically (always) (duration() cannot be resolved?) with zero, 1, or more animations in the group.
But immediately I had praise:
The API is well thought out, clean and effective. Overall I am very happy with it.
A TON eases are provided (and work well).
The same API is used for Widgets as for GraphicsItems
I had comments:
I wished you mentioned that opacity, and axis rotations required experimental Qt versions (I spent a while tryign to animate opacity, only to go digging through the code.)
I wished there existed some relative, on-the-fly positioning. Either get coordinates from two layouts, or from some calculation like setTargetValue(RelativeTo(otherItem, (Top|Left), myItem, Top|Left)) (RelativeTo() would return a QPointF);
I wished the single-line QtAnimation also supported a StartValue.
Ugg. Please do not name ANY part of the API after Flash.
Flash scripters can learn and conform to the current method and api. Not the other way around.
One more thing… it would be cool if we could create a raster object proxy for any QGraphicsItems. This proxy would then provide raster effects like blur and maybe opacity. You should then be able to re-use that for the QGraphicsWidgetProxy to provide the same raster effects for widgets as for regular items
QGraphicsRasterProxy rp(QGraphicsRect(0,0,40,40));
rp.blur(1);
rp.glow(1);
QtAnimation blurAnim = QtAnimation(&rp, “blur”) … or
QtAnimation::blurAnimation(&rp, 5, 1000, Ease::Linear)…
One more thing… (I feel like Jobs an Apple event)
We should be able to register any function for the property
QPixmap rasterFunction(QGraphicsItem source, QVariant param);
registerRasterFunction(”reflection”, reflectionRasterFunction);
The only question is how do you control the evaluation order of the functions? For instance, if you have a reflection function that creates a Pixmap 1×1.5 times the original, you’d be computationally better off doing the enlarging last, rather than pass the enlarged pixmap down the line. (You have to process additional pixels at each subsequent step.)
One such way is to support a manual pipeline order. Another way is to supply a fictional pixmap when register the raster function. The results return the resulting computation are then ranked in order from least to greatest. Assume we have 1×1 pixmap, we call the functions for each raster effect in the pipeline. The results come back as .5, 2, 1. We then auto-order the pipeline to .5, 1, 2, because this would result in the least amount of pixels being processed. This would have fast, low quality results. Or, for HighQ, reverse sort it. 2,1,.5 Finally, it seems we need to support manual ordering, because final decorations should come last (like shadows, so they are consistent with all other shadows, regarless of input size).
This has me wondering if Qt should have a CUDA or similar optimization engine…
Will we, interface designers/developers, get a nice and shiny visual editor for this declarative UI?
When we have it it will be like, well, the heaven!
@Scorp1us: IMHO it makes no sense to use completely nonsensical words just because Flash uses them. “States” and “Transitions” are commonly understood words, they also have clear definitions in the context of computer science. “KeyFrames” is a lot harder to understand and “Tweens” is completely incomprehensible if you don’t already know what it means. Catering to Flash programmers should not make the API useless for everyone else, but using Flash-specific jargon does exactly that.
Diogo: We’re making demos as we speak, they will be announced as they are ready for public display.
Richard: Not yet; the markup is in a premature state and is missing documentation. Coming up though!
Wizard: This is one of the core problems we have been trying to solve. It’s tricky to solve this in a general way. If anyone has ideas on how to solve this problem in a good way, please let us know.
Scorp1us: Kevin answered the naming question, and I agree with him. The names State and Transition are used in Flex, so they aren’t completely alien to the Flash world. The crash in QtAnimationGroup is being fixed as we speak. On the area of relative positioning, we have a few solutions in mind for this - on one side there’s script binding functionality that lets you bind the target of an animation to a script expression, which might include relative positioning. On the other hand we’re investigating anchor layouts, which may also help quite a bit.
Paulo: First things first; we’re focusing on getting the foundation to work properly. Having a visual editor would be great.
Thanks Andreas, Keven. I understand, thanks foe clarifying. I didn’t know Flex adopted those terms. I had been studying Flash in case this didn’t get released soon. And don’t get me wrong. What was done was fantastic. That’s just some nit-picking.
(Although QState is relatively ambiguous, is it a SCXML state? - just for namespace clarity)
There is one more thing that I came up with, but it is “deep”. I’d like to be able to expose component parts of graphics items and animate those. Crazy, I know. But let me provide a few examples:
Circle : center (QPoint), radius (qreal)
Line: start (QPoint), end (QPoint), or start (QPoint), angle (qreal), length(qreal)
Polygon: point(int p, QPoint)
My impetus for this was the Indiana Jones line-on-a map (where it shows him traveling in a plane) Or, a cool shatter-glass effect I saw at a NIN-concert. I realize this only makes a lot of sense for geometric shapes, however, if you could work out the abstraction, so I can set a “start” and “end” property to be animated, I could take the value and provide a function to just modify the GraphicsItem.
The one thing I did discover is that relative positioning is complicated by parent qidget coordiantes. If you try to align an item to another from another parent, you’ve got to do some mapping.
But I absolutely love it so far!!!
Andreas, Cesar,
One of the things I do for a cheap “visual” editor is I subclass my items and override the move event. In there, I print (qDebug()) the coordinates. Then I set the ItemIsMovable (or whatever it is) flag. Then I can drag items around with the mouse, recording the coordinates at the opportune time. It shouldn’t be much harder to have a side pane listview. When you double click the object it adds the point to the list has you create a named point. Hrm, one other thing is a drop-down to select the property being modified. Sort the list view by time. Then serialize the data, grouping by property, into animation groups, between data points, sorted by time. I don’t know if yu want to go the flash route of having a graphical keyframe widget…
If I have some time I’ll see what I can do, but I have to warn you, it’ll suck compared to what a troll can come up with. Also, I think not being able to speficy the start point for an animation will be a problem. You now have to have a special exception for start point. (another reason why a troll could do better, he can modify the API ![]()
Kinetic running on S60:
I’ve been update to get Kinetic from the git to compile.
The one error is in file: qgraphicsanchorlayout.cpp around line 365:
Changing the line from:
QGraphicsWidget *w = parentWidget();
to
QGraphicsWidget *w = 0;
fixes the problem as parentWidget() is not defined. Probable not the best way to fix it though
Jani, that is so hot.