Monday, December 24, 2012

Working with Cascade (2) - This is not the QML you know

Cascade supports QML syntax for UI creation. If you think this QML is the same as the QML we know from Nokia, think again.

One significant difference is the layout concept. Unlike the anchor concept for pure QML, Cascade offers three types of layout, Stack/Dock/Absolute. AbsoluteLayout is like using x,y for pure QML, Stack and Dock abstracts the layout to make it device-independent. At first StackLayout feels like Row/Column elements to me and I naturally looked for padding property to have spacing between the contained elements. The correct approach for StackLayout is to use the StackLayoutProperty to specify spaceQuota. The naming is obscured, it really is layoutPriority. The elements of the same priority are given equal amount of space. Keep this in mind when you first experiment with the layout.

The Eclipse IDE in the native SDK has QML preview feature similar to QtCreator. Unfortunately, Eclipse cannot handle Qt C++ components in attachedObjects so once you have them in your code, you can say goodbye to the preview feature. Therefore, I strongly suggest getting your UI right before connecting the bones of your Cascade app.

Speaking of IDE, in QtCreator the assets (like images, QML, splash screen, icons) are specified within .pro file. In Cascade, these are all specified in a bar-descriptor.xml. Two options not immediately obvious from the GUI interface is theme and run-in-background. They are configured by:


    <!-- Dark theme. -->
    <env var="CASCADES_THEME" value="dark"/>
   
    <!-- Run in background. -->
    <permission>run_when_backgrounded</permission>


Working with BlackBerry Cascade (1) - viewpoints from Nokia burning platforms

As mentioned in another article, I ported one of my apps to BlackBerry 10. In retrospect, I could have done this a lot sooner. But three months ago, the dev tool and documentation were not as mature as now so maybe that also hampered my progress.

I came from the burning platform that is Nokia. So my app was pure Qt/QML with heavy use of Qt components for UI. If you are of the same background, I hope my experience in porting to BB10 might be helpful to you.

First of all, you need to decide upfront which development environment you want to use:BlackBerry's

  • Cascade: You need to use BlackBerry Native SDK.
  • Pure Qt/QML: Use QtCreator 2.6+, all you need to know about making QtCreator 2.6+ works with BlackBerry 10 is at http://qt-project.org/wiki/blackberry.
    (I believe you can also use BB native SDK for pure QML now, but never tried that route.)

There are different issues for the two approaches, in my case they are:
  • Cascade: Learning Cascade, rewrite UI, more #ifdef in C++ for blackberry specific codes 
  • Pure Qt/QML:
    • I couldn't get QML Text component to use the text style I wanted.
    • Have to work around the lack of native BB10 Qt components, either by compiling Qt components for BB10 (there are pre-compiled libraries available on BlackBerry developer forum, but I never succeeded in using them. Nor have I been able to compile them from source), or by re-implementing the UI elements (which was not feasible for me....).
Whichever route you choose, you need to registered for code signing keys. I will skip the step since you can easily find reference on it. For pure Qt/QML, QtCreator 2.6 is good enough and if not for the font issue I encountered I might choose that. I ended up working with Cascade, and one thing I learned about Cascade was I felt the QML part was at times an afterthought. QML is kind of like an wrapper, but it is even more so in Cascade. Instead of thinking that you are working in javascript, think of using Cascade QML as if you are working in an "virtual machine" encapsulated in Qt C++. One powerful thing I learned is, the "attachedObjects" property is the bridge to expose Qt C++ objects directly into QML [1]. So instead of searching for QML elements to use in... well QML, you search for Qt C++ class to plug into attachedObjects scope. Or you can extend a class in C++ then register it into QML. The concept is different for me, and after stop thinking "why did BlackBerry implement like this," I started getting better progress.

Between beta and gold SDK, BlackBerry has added a few very useful elements in C++. This means that Qt elements such as QueryDialog{}, Sheet{} etc. have comparable elements in Cascade, just that you need to instantiate them in attachedObjects scope, not elsewhere. Gold SDK also simplified list manipulation and now header/data are just a string definition apart. Speaking of list manipulation, Cascade has separate DataAccess/DataSource class to populate list. In theory they are convenient but in reality, I found the lack of callback functions can limit their usefulness, e.g. if the data fetched is decorated with // for comment the DataSource ignores the data. Also Cascade uses indexPath, a QVariantList to specify the hierarchy within the list, and this can be confusing when you have headers. Cascade list provides more complex use cases, for example it offers context menu. One problem you will immediately find is that context menu seems to be isolated in its own scope and cannot access anything above it if you use "id.function()" syntax. There is a solution [2], and I found that context menu does have access to ListItemData property [3]. All API document can be conveniently found at [3], and a few useful UI component tutorials are at [4][5][6]. If you encounter any problem, first search BlackBerry developer forum. It is full of information and people there are willing to help.

Last but not least, there are free in-app icons available for BB10, courtesy of Myers Design [7]. I remember reading there is another one, but Myers' icons are awesome for me so I didn't search further.

Hope the above info is helpful. If you have questions, don't hesitate to leave a comment! Happy coding!

Reference
[2] "ContextActions inside ListItem can not access ContextProperty in QMLDocument" 
[3] "Cascade API documentation"
[4] "Cascade System Dialogs"
[5] "Cascade Sample Apps"
[6] "List Manipulation"
[7] "Free BB10 in-app icons"

Sunday, December 23, 2012

Ported BabyTime to BB10!

The release of gold BlackBerry native SDK really helped me get up to speed with Cascade development. And I finally ported my simpler app, BabyTime, to BlackBerry 10. Hurray!

Before that, I was struggling with Cascade development. Mainly it was the debugging, I forget why but I had a difficult time figuring out why the Cascade QML interface did not work. At one point I even gave up on Cascade and looked into pure Qt/QML approach. The problem with that was, I had to re-implement Qt components... and also for reasons I never figured out, the font style could not be changed for QML Text element. That was the final straw for Qt/QML and I went back to Cascade.

This was also the time when I tried revisiting the alpha device simulator. Again I forget the reason why I didn't use device simulator in the first place, but I didn't have any issue with gold SDK device simulator. To me that was the key turning point because it is faster to debug and experiment with UI layouts. Another key is I worked on BabyTime instead of Stockona. BabyTime is my second proper Qt app, and with the experience I complete separated the UI and the SQL backend to QML and Qt C++. This helped immensely because I could focus on re-implementing the UI in Cascade. The C++ SQL backend needed some changes because of the API differences between Qt AbstractModel and Cascade GroupDataModel. Even that was relatively minor, and this experience really makes me a believer of pure Qt C++ backend. 

My experience so far tells me to minimize code changes between Meego/Symbian and BB10, unsurprisingly, is to put database, network and list manipulation in Qt C++. More info about the porting experience will be documented in another article.