ListViews...within a ListView

I've been trying to figure out how to put ListViews within a ListView for certain use-cases that warrant the UI to be able to swipe through multple screens, either horizontally or vertically.  While a ListView on it's own is usefuly for showing various different items in a nice layout, there are many instances where it may be benificial to incorporate another ListView within a ListView.  I personally incorporated into my BetaZone app, Kloudmix, which has a different UI for Keyboard devices and portrait devices for userpages and profiles.  The main use-case that most will probably be familiar with is the featured carousel, where a screen has a vertical listview with one item being a horizontal listview that let's the user swipe through various featured items.  Another use-case may be user profiles, allowing users to swipe through different panes or containers of information.  Long story short, I spent some time tweaking around with it and reading a support forum post to create this nice and simple tutorial and sample app for you!


Simple Active Frames

One of the features that make Native Cascades stand out from Android ports, as well as from competitors like iOS is Active Frames.  Active Frames are a useful tool that can provide important app information to users in the active frames pane on BlakcBerry 10.  Information such as recently viewed articles in an RSS feed app, or latest tweets can provide useful information for users without having to enter the application.  Developers have the ability to pick and choose what they want to show users in active frames and aren't restricted to one definition or use-case.  I personally like to add a nice cover image to the active frame even if I'm not going to invest the time into coding some important information for my active frames.  It looks more professional and visually appealing to users to give them that all-around BlackBerry 10 experience.


In-App Purchases Made Simple

The process of adding in-app purchases to a Cascades app has proven daunting for many of you out there, but today I will attempt to make life easier for all of you.  About 6 months ago, when I first attempted to add in-app purchases to a Cascades app, there was a lot of head scratching and staring at the screen, but eventually it clicked well enough for me to implement.  After that, I spent a lot of time really wrapping my head around the code, and I am finally at a point where I can simplify the presentation of this code. Interested? Keep reading...


Meggy Jr RGB

Recently, a friend introduced me to Arduino.  Rather, he’s been trying to introduce me for a while and I’ve just been too darned busy to play with it. 

So, I took on some projects and spent some energy on it this last month.  As a result, I have a handful of posts coming up about open source hardware :)

First up, Meggy Jr from evil mad scientist.

Not really an arduino, it was a great way to warm back up to soldering and electronics.  The entire kit took about two hours to assemble, and requires some hand tools as outlined in the manual.  I went ahead and picked up a tool kit from SparkFun as my old soldering iron has seen better days – which is another interesting (albiet expensive) electronics company I have purchased from in the past.

At the same time, I also purchased an Arduino Esplora + TFT from CanadaRobotix – but more on that later.


Example of a First Run Tutorial in Cascades

I'm sure many of you have installed an app onto your device that displayed a brief tutorial the first time you launched it, right?  If you have ever wondered how you could do that in your own app, this sample application will show you one simple way to accomplish this in a Cascades app. 


This sample app utilizes QSettings, so see my previous tutorial about QSettings if you need some help there.

This post will not be a full-fledged tutorial, but I do want to explain some of the aspects of the sample application. First, here are some of the "stuffs" used in the sample application...

QML elements/components used:

  • Sheet {}
  • Page {}
  • Container {}
  • Label {}
  • ListView {}

QML Signals used:

  • onCreationCompleted:
  • onClicked:
  • onTriggered:

Other used:

  • DockLayout
  • StackLayout
  • XmlDataModel 

 How does the application work?

The application is pretty simple, and it uses QSettings to store a bool (true/false) property that is used to determine if the tutorial should open or not when the app is launched.  By default the bool property is set to true and therefore the tutorial fires up when the app is launched. If the user taps the close button to close the tutorial, the tutorial closes, but it will open up again when the user launches the app the next time.  However, if the user taps the Dismiss button to close the tutorial, the tutorial is closed forever or until the app is uninstalled, reinstallled, and relaunched.  

FirstRunImage 1

For the purposes of this sample app I placed a button on the main.qml file that is visible when the tutorial is closed. This button allows you to restore the tutorial popup functionailty without having to uninstall the app. There is also a Label above to button that displays whether the tutorial pop up is disabled or enabled.  

  FirstRunImage 2 

So, head over to the OSBB GitHub and check it out and I have attached a prebuilt and presigned bar file to this post that can be side loaded onto your device (Q10/Q5/Z10/Dev Alpha).  

If you have issues or REALLY want a tutorial, sound off in the comments, and I will whip one up. Also, if you have specific questions, hit me up on twitter @BerryInformed or via the comment section below.

Thanks guys and happy coding!


The Power of Ant Build

There's several official ways for WebWorks developers to package their apps: Ripple (which I have personally never actually used) and the command line (my former favorite) being the big two. However, Tim Windsor from the BlackBerry Dev Relations team created what is, in my opinion, the best and easiest way to package and sign your WebWorks apps: the Ant Build Script.

If you want to skip the rest of this post and read Tim's excellent documentation on getting it all set up, just head over to But if you're not convinced yet, read on.

First, why is the Ant Build Script awesome? 

It's awesome because it lets you quickly and easily compile your apps via the command line in a variety of ways. Before I had the Ant Build Script, I'd write my app, add it to a zip, move it to a folder I set up for signing/packaging, open the command line, and type "bbwp c:/apps/ -g mypassword -buildId 0"; if I wanted to say add web inspector, I'd have to add -d, and there were a few other operators that I've forgoten. Then I'd drag it to a sideloading bat to sideload it onto my BlackBerry.

With the Ant Build Script, all I have to do is open the command line tool in the app folder (shift+right click) and type "ant build" and my bar is compiled and sideloaded to my BlackBerry. That simple.

If that convinced you that the Ant Build Script is awesome (if it didn't, read it again), then here's how to get it set up:

Set Up

1Download the Ant Build Script from and extract it to somewhere you don't mind keeping it.

2Open the buildTasks.xml (it's in the tools folder) with a program like Notepad++ and edit the variables you need, such as the location of your SDKs and your signing key password.

3Download Apache Ant from (you want the binary zip)

4Unzip Apache ant anywhere you want (I put it into the root of my C drive)

5Add Ant_Home to your System Variables

The easiest way to do this is to type "System Variables" into the Windows Search bar. You can also get to it by right clicking on the computer icon.Click the "New" Button.
For Variable Name, type ANT_BUILD For Variable Value, enter the directory of the Ant build folder. For me, that was C:/ApacheAnt

6Now, whenever you want to package a new app, copy the build.xml file from the Ant Build Script folder, edit it to suit your needs, and run "ant build"

That should be it! If you have any problems with my instructions, check out Tim's to see if he explained something better than I did, or email us here at OSBB to let us know.


WebWorks File API Framework

One of the things I love about developing for BlackBerry 10 is that BlackBerry has really done well at implementing HTML5 standards (and a quick visit to confirms it). While this is awesome as far as creating robust HTML5 apps is concerned, it means that developers have to learn new technologies that might not be fully implemented in your web browser. As an example, webkitGetUserMedia only recently showed up in Chrome.

The File API isn't all that new (it's been around a while now), but it's something that I couldn't find a whole lot of documentation for it. There is a very, very good article at, but it's (in my opinion) a fairly involved API.

The great folks over at BlackBerry have implemented the File API, but that doesn't necessarily mean it's easy for developers to start using. And since the web is all about frameworks these days (JQuery, Sencha, etc), I figured I'd do a mini framework of BlackBerry specific File API functions to make things easy for other WebWorks Devs to implement saving and loading (including backup and restore) to their apps!

This framework is Open Source (so you can browse my typos without even downloading it), and you can check it out at My Github.

You can check out the readme in the github link to see how it works, but here's the quick how-to:

1. Include the javascript in your index.html

Example: <script type="text/javascript" src="/cssjs/bbfiles.js"></script>

2. Add the required feature IDs to your config.xml:

<feature id="blackberry.invoke.card" />
<feature id="" />
<feature id="blackberry.ui.toast" />

3. Create a function for whatever you want to do. Functions that are available: 

Save text to a specified file:
saveText(Text to save, save location and file name)
Example: saveText('Hello World!', '/accounts/1000/shared/misc/helloWorld.txt')

Save text to a file of the user's choice:
saveText(Text to save, location to open the file picker, 'picker')
Example: saveText('Hello World', '/accounts/1000/shared/misc/', 'picker')

Load text from a file:
loadData(location of document)
Example: loadData('/accounts/1000/shared/misc/helloWorld.txt')

Load text from a file of the user's choice:
loadData(location to open the file picker, 'picker')
Example: loadData('/accounts/1000/shared/misc/', 'picker')

Delete a specified file:
deleteFile(file location and name)
Example: deleteFile('/accounts/1000/shared/misc/helloWorld.txt')

Delete a file of the user's choice:
deleteFile(location to open the file picker, 'picker')
Example: deleteFile('/accounts/1000/shared/misc/', 'picker')

Create a folder:
createFolder(folder to create)
Example: createFolder('/accounts/1000/shared/misc/New')

Delete a folder:
deleteFolder(folder to delete)
Example: deleteFolder('/accounts/1000/shared/misc/New')

Move a file:
moveFile(location to move the file to, current file location and name)
Example: moveFile('/accounts/1000/shared/misc/downloads/', '/accounts/1000/shared/misc/helloWorld.txt')

Move a file of the user's choice:
moveFile(location to move the file to, location to open the file picker, 'picker')
Example: moveFile('/accounts/1000/shared/misc/downloads/', '/accounts/1000/shared/misc/', 'picker')

Move and Rename a file:
moveRenameFile(location to move the file to, current file location and current file name, new name)
Example: moveRenameFile('/accounts/1000/shared/misc/downloads/', '/accounts/1000/shared/misc/helloWorld.txt', 'newFile.txt')

Move and Rename a file of the user's choice:
moveRenameFile(location to move the file to, location to open the file picker, new name, 'picker')
Example: moveRenameFile('/accounts/1000/shared/misc/downloads/', '/accounts/1000/shared/misc/', 'newFile.txt', 'picker')

Copy a file:
copyFile(location to move the file to, current file location and file namee)
Example: copyFile('/accounts/1000/shared/misc/downloads/', '/accounts/1000/shared/misc/helloWorld.txt')

Copy a file of the user's choice:
copyFile(location to move the file to, location to open the file picker, 'picker')
Example: copyFile('/accounts/1000/shared/misc/downloads/', '/accounts/1000/shared/misc/', 'picker')

Copy and Rename a file:
copyRenameFile(location to copy the file to, current file location and current file name, new name)
Example: copyRenameFile('/accounts/1000/shared/misc/downloads/', '/accounts/1000/shared/misc/helloWorld.txt', 'newFile.txt')

Copy and Rename a file of the user's choice:
copyRenameFile(location to copy the file to, location to open the file picker, new name, 'picker')
Example: copyRenameFile('/accounts/1000/shared/misc/downloads/', '/accounts/1000/shared/misc/', 'newFile.txt', 'picker')

Rename a file:
renameFile(file location and current name, new name)
Example: renameFile('/accounts/1000/shared/misc/helloWorld.txt', 'yay.txt')

Rename a file of the user's choice:
renameFile(file location, new name, 'picker')
Example: renameFile('/accounts/1000/shared/misc/', 'yay.txt', 'picker')

Save Canvas to an image:
saveCanvas(canvas element, location and name you want to save canvas to)
Example: saveCanvas(document.getElementById('canvas'), '/accounts/1000/shared/misc/image.png')

Save Canvas to an image of the user's choice:
saveCanvas(canvas element, location to open the file picker, 'picker')
Example: saveCanvas(document.getElementById('canvas'), '/accounts/1000/shared/misc/', 'picker')

Load image to Canvas:
loadCanvas(canvas element, image to load', 'nopicker', width you want image to load, height you want image to load)
loadCanvas(document.getElementById('canvas'), '/accounts/1000/shared/misc/image.png', 'nopicker', 500, 300)
Note: 'nopicker' can be any text except 'picker'. It is optional, unless you specify a height and width (which are also optional).

Save image of the user's choice to Canvas:
loadCanvas(canvas element, location to open the file picker, 'picker', width you want image to load, height you want image to load)
loadCanvas(document.getElementById('canvas'), '/accounts/1000/shared/misc/', 'picker', 500, 300)

That's it! Maybe not as simple as simple can get, but a lot better than writing the function out yourself :)


Running a C++ Functions from QML

When I first read about Cascades "they" said use QML for the UI and C++ for the logic.  Okay, great so I wrote a function in C++ and made a pretty UI in QML... Now what?  In this example I'll go through the steps it takes to call a C++ function from the QML.  However this example won't have a pretty UI.

Subscribe to this RSS feed
Subscribe to the official OSBB BBM Channel!



Back to top