QtQuick and Drag-and-Drop – One More Time

As a result of my last blog on QtQuick and DnD I was contacted by both Sebas and Marco. Both are active in the KDE project and face the same issues as I do. Apparently, the Plasma team are also working on DnD in QtQuick. Their approach is based around DragArea and DropArea, written in C++ and handles full X11 DnD, i.e. between processes. Marco summed it up nicely in his mail to me.

…in kde-runtime/plasma/declarativeimports/draganddrop/ …is imported as a c++ plugin and depends only from qt (started its life as a 3rd party plugin written by Gregory Schlomoff)…

My solution (will polish the code for release Anytime Soon) is written in QML/JavaScript and only works within a single process, e.g. for moving items between lists, etc.

KDE has been about extending and completing the Qt software stack to make it easier to build Qt-based software. In this process, they are working on QtQuick as well as Qt. A tips for anyone (including me) looking for missing pieces is to look in the KDE TechBase.

QtQuick and Drag-n-Drop

Implementing drag-n-drop (from now on DnD) in QtQuick is like traveling to an up-side-down world. Instead of dragging something and dropping it on a zone, the dragged item (or, rather, the MouseArea controlling the drag) is responsible for keeping track of where it is.

I’ve experimented with a few tricks to resolve this, and I believe that I’ve sorted the dragging half. The question is if I want to improve the receiving end. The concept is that you have a DragArea – which is just a fancy MouseArea. It has a property, zones, which is a list of QtObjects implementing methods to test if the zone is being hovered and to drop the item on the zone. This makes it possible for me to re-align the world with my brain, where the zones accepting the drops are playing an active role in the DnD.

Still, I have to think a bit about how to simplify the zones. Preferably, I’d like to be able to have a DropZone item that does all the fancy things and just lets the end-user (erhm, QtQuick developer, that is), indicate if the item can be dropped and then handle the onItemDropped event. Will see if I have time to polish this over Christmas.

By the way, the new Qt docs really confuse me. Could someone please reduce all the fancy effects, like having to expand each method to see the details. Also, having the Detailed Description on the top kind of reduces the need for a brief. It also slows down my average use-case, i.e. go to the page of a class, pick a method, click it and read. If I want details, I could go to the page of a class, click more and read. To get to the methods in the new layout, I have to scroll for a while, how much depends on the class, then click the item. Also, sending links to the details of specific methods is no longer readable.

QtQuick / QML Experiences

I’m in the middle, or rather, approaching the end of, my very first large QtQuick-based project. I cannot tell you that much, just that it includes a rather large code base of QML, and a semi-large run-time environment written in C++. In this blog entry, and probably some more, I’ll tell you about my experiences.

Productivity

The productivity of QtQuick feels amazing when doing small user interfaces. Especially when just putting something cool together to demonstrate the states and transitions abilities of QtQuick. However, as the deadline approaches I’ve learned that QtQuick development is quick only when compared to writing a Qt/C++ user interface consisting of 100% custom widgets.

Working with a design company, I had to identify potential components, write and test those components and then deploy them through-out the user interface. Simply importing full screens from Photoshop and blowing life into them just leads to code duplication.

The end results looks amazing. All that I’m saying is that having graphics on the screen in 15 minutes does not mean that you will be ready to leave by lunch.

Multi-step Transitions

Transitions in QtQuick is just amazing, but when designers start saying things like “scrub the timeline”, “initial movement to give a sense of direction”, et cetera, I hear “add complexity to your puny state-machine”. Currently, QtQuick lacks support for easily defining a transition over a complex path. The provided easing types do a lot – I, as a developer, thing that they look great, but being able to add key-frames to get that extra punch into the animations without having to use multiple states would be great.

One cool thing that I did learn in this process is that implementing a frame-by-frame animation from a set of PNGs is actually quite easy. Simply add a parallel animation group with the rest of your animations and  linearly iterate the “currentFrame” property, and use said property in the source property of your image element. Felt like an ugly hack, but worked great!

A Linter

QML really needs lint. My current deadline is due to smack me over the head real soon, so I have not got the time to looking into what can be done. However, double-checking names of states, ensuring that image files exist, looking for name-space issues (will talk about this later), et ceterea would be really helpful.

As Qt is open source, I guess it is easy to access a tree representing the parsed source. From there, it is simply a matter of applying rules. But, I have not looked in to this at all, so it might be much harder than I imagine.

qBound on Arm

When using qBound in combination with qreal, it is important to properly cast the upper and lower bounds, e.g.:

qreal x = qBound(qreal(0.2), v, qreal(1.5));

If you forget this, i.e by using the following code:

qreal x = qBound(0.2, v, 1.5);

Your code will happily work on x86, and some other platforms, but not on Arm. This is because qreal is a double on all other platforms than Arm. On Arm, it is a float. This leads to GCC complaining about not being able to instantiate the template.

Metamorphosis

When I first got to know Qt, it was a cross platform tool. That was really the reason for me to start using Qt. It was a great cross platform tool. At the time, I was using a Tru64 based system with real X-terminals. You know, the ones where the screen really is a stupid terminal connected to the network. Tru64 meant a real Unix, as in non-Linux, setup alongside Alpha CPUs. Great for what the school wanted us to do, i.e. use Matlab and latex.

In this setting, I wanted to program something with a user interface. My experiences from the time was GEM, from the good old Atari ST range, VisualBasic, I’ve used 1.0, 2.0, 3.0, 4.0 and 6.0 – without liking a single version, and some plain win32 from C. I did try MFC a couple of times, but I never grew fond of it. So, the first thing that I tried was xlib, which isn’t fun to use. So, along came Qt (and KDE). I believe that it was Qt 1.42 or something like that. One forgets as years passes by.

Qt configured and built beautifully, and the cannon tutorial had me hooked. Standard widgets, custom widgets, user driven, timer driven… this toolkit could do anything. And it was easy to use.

Years pass and the chronology gets mixed up. I met some fellow Qt users at QtForum. I made my way from a common user to moderator. Then, in a series of sad events, the site was sold and the old owner simply vanished from the Internet. The reaction was to start QtCentre together with the rest of the moderators and build a proper community. I cannot thank Witold enough for all the energy he still puts into this site. He really should get more credit for his work. There are other people there too who work hard, but Witold has been there from day one.

Qt progressed, the X11 version was GPLed. So was the OS X version. So was the win32 version. Qt 4 brought many goodies: modularization, webkit, graphicsview, model-based viewing widgets, etc. The toolkit embraced all platforms and is really a great tool for cross platform desktop development.

My self, I wrote the Independent Qt Tutorial for Qt 3, then the Foundations of Qt Development for Qt 4. I started working with Qt as my day time job. I started speaking about Qt at conferences and user group meetings. What I spoke of was the ultimate cross platform toolkit. My favorite example was that Qt tries to integrate well with Gnome – it does not even pick sides in the KDE vs Gnome competition. The whole root of Qt is its cross platform abilities, and there Qt excels.

Then came changes. Trolltech grew. Nokia bought them. The big fish eat the small.

With the Nokia acquisition came a great energy. Qt was put in the limelight. This was the technology that Nokia would base its future on. Developers were attracted to Qt. Qt DevDays had to move to a larger venue to fit them all in, and it still was crowded.

There where some big company things going on. Name changes – Trolltech, Qt Software, Qt Development Frameworks. Anything works. For me, personally, Trolltech had charm. Bug big companies sometimes act in strange ways. They don’t always agree with themselves and they might have contradicting policies and whatnot.

With Nokia came the push of Qt as a platform of its own. Qt on Harmattan/MeeGo and Qt on Symbian where all of a sudden the core focus of all Qt development. This is not surprising, given that this is where Nokia could apply Qt. The focus of Qt Developer Days changed. Out with the widgets, in with QtQuick and bling. The cross platform nature and roots of Qt where seemingly forgotten.

Do not get me wrong. QtQuick is a great piece of technology and something that I use daily in my job. It helps me be real productive and saves me from writing tons of code to drive rich user experiences.

Then came changes. The Qt strategy of Nokia was replaced with a WP7 strategy.

Not only was WP7 the official way forward. The Qt-based N9 is not to be sold in large markets. Despite positive reviews it looks like it will be a sad tribute to what Qt and QtQuick can do. The question is, who will pick up the ball again? Will there ever be another MeeGo handset? Most likely not, as Intel just pulled out of MeeGo, or just renamed it Tizen. The focus seems to have shifted from QtQuick to HTML5. The big question at the time of writing is what will be the underlaying engine. I’m sure everyone agrees that it will be WebKit, but will it be hosted by Qt or something else?

But now Qt has started to find its roots again. Lighthouse made porting easy. Necessitas puts Qt on Android. Qt for iOS is an ongoing community port. Qt will once again excel as the cross platform solution of choice. The question here is if it is wise to merge the desktops into the QtQuick API. I’m not convinced yet. Being cross platform on desktop also means integrating with the desktops. Current desktops are widget based, and to be true, widgets rock on desktop things. When controlling a machine or writing a mail I don’t want bling, I want predictable, stable widgets that looks like they are supposed to.

Compare this to common device user interfaces. Here there is a difference between applications such as mail and todo apps. Here you want common components that integrate with the platform – much like widgets. These elements usually fit into the limitations of widgets as well. Square, non-overlapping, etc.

Then you have completely custom applications, think Angry Birds, where QtQuick is the ultimate tool. As QtQuick can encapsulate both these user interfaces, it is the ideal tool for this type of device user interfaces.

And the current hype – HTML5? I believe that QtWebkit is the best system for building hybrid web/native applications out there. And integrating QObjects with the JavaScript space much resembles integrating them into QML space.

After chaos; Metamorphosis

I look forward to a new spring for Qt. Having a common Qt core for all applications. QtQuick for device user interfaces and QtWidgets for desktop. The QObject model that we have learned to love and the power of C++ will be available to all. Still, the user interface can be integrated with the platform of choice or fully customized with QtQuick. Code less, create more, deploy everywhere.

Opportunities

As fall approaches and the weather turns wet, I have happy announcement to make. Pelagicore, where I work, and our efforts in using Open Source in the in-vehicle infotainment business have been noticed. We just received 20MSEK investment from Fouriertransform (English / Swedish). This means even more Linux and Qt hacking for me! *happy*

N900^H^H – Less Could be More

I’m a happy user of the N900 – an ageing device. As I recall it, I saw it for the first time in real life at Qt DevDays 2009. So, basically, my phone is older than my laptop, and I’m happy about it.

Yesterday, Nokia removed two zeroes from my old workhorse and announced the N9 – a Qt driven phone. You can find a detailed spec here (thanks Ubuntufreak). What I’m excited about is:

  • Unibody. Nokia’s phones have been a bit on the plastic side for my taste in the past.
  • Capacitive (i.e. multi-point) touch. This has really been the N900’s weak point recently.
  • Proper Linux, i.e. MeeGo. No virtual machine layer as in Android, native binaries on a powerful platform.
  • Qt – everywhere!

So, now the only remaining question is – is this a device that will keep me happy for the next three years?

Necessitas

So, I’ve fought with Necessitas for a while now. I reported a bug on a flawed install, but then I hacked around it. Basically, what I did was the following:

  1. Create a directory: /data/data/eu.licentia.necessitas.ministro/files
  2. From that directory, create a symbolic link, qt, pointing at /opt/necessitas/Android/4.7.60

Then it works. I’ve built and deployed wiggly onto a poor old HTC Hero and it all seems to play nicely this far – just have to wait for Ministro to download Qt. Next step is an application built around plugins that I’d like to deploy. Looks like I might have to read up some more. Until then – thanks for the great work, BogDan!