The Belt app shows you how to create a game that tests your BlackBerry Classic navigation skills (and how to handle the user's key presses and trackpad input in QML). You can download and import the Belt sample app from GitHub.
After the game starts, you tap a button to generate a random grid that contains rows of buttons. The buttons are labelled "call", "end", "menu", "back", or "trackpad".
To win, you clear the buttons on the grid by using the trackpad to navigate to each button and pressing the corresponding key on your device. A function in the app clears the button by setting the text to an empty string and the color of the button to gray.

The UI is straightforward. It uses custom components to represent a row of buttons and each individual button. There are two interesting parts of the app that we want to explore: generating the grid of buttons and handling the user's key presses and trackpad input.
Generating the grid
The main.qml file generates the UI using two basic Container objects. The first container includes a Label with the instructions for how to play the game and three attached objects, which represent rows of buttons, a divider, and a DisplayInfo object. The second container includes a Button to generate the grid and a Label to update when the user wins the game.
The DisplayInfo object is attached to the first container. The app can access the screen width and height so that it can dynamically create the correct number of rows of buttons to fill the screen.
// Retrieve screen height and width var height = displayInfo.pixelSize.height var width = displayInfo.pixelSize.width // Calculation to determine number of buttons // in a row based on screen width var columns = (width - ui.du(10) - (ui.du(25) / 2)) columns = (columns / ui.du(25)) // Take height and subtract padding height = (height - ui.du(30)) // 65 is the height of button plus padding var rows = height / 65 // Calculation to determine number of rows based on screen height rows = (height - (rows * ui.du(2))) / 56 // Generate the column rows of buttons for(var i = 0; i < rows; i++) { var createdObject = row.createObject() createdObject.createButtons(columns, beltText, beltColors) createdObject.topMargin = ui.du(2) root.add(createdObject) }
The custom component that is defined in Row.qml creates the random sequencing of buttons in each row.

The custom component also tracks which buttons in each row have to be checked to see if the user performed the correct action for that button. Each row is made up of buttons that are defined using the BeltButton custom component.
Handling user input
The custom component that is defined in BeltButton.qml defines each button on the grid. Each button has a simple definition:
Button { id: button maxWidth: ui.du(25) minWidth: ui.du(25) text: root.text color: Color.create(root.color)
Each button also has a set of DeviceShortcut listeners that allow the app to intercept key press events on the BlackBerry Classic. If the text of the button matches the key that the user pressed, the button is cleared on the grid.
// Shortcuts representing each button on the belt. // These allow us to intercept key press events. shortcuts: [ // The Send button (phone call initiation) DeviceShortcut { type: DeviceShortcuts.SendTap onTriggered: { if(text.indexOf("call") >= 0) { clearButton() } } }, // The Menu button DeviceShortcut { type: DeviceShortcuts.MenuTap onTriggered: { if(text.indexOf("menu") >= 0) { clearButton() } } }, // The Back button DeviceShortcut { type: DeviceShortcuts.BackTap onTriggered: { if(text.indexOf("back") >= 0) { clearButton() } } }, // The End button (end call) DeviceShortcut { type: DeviceShortcuts.EndTap onTriggered: { if(text.indexOf("end") >= 0) { clearButton() } } } ]
Finally, a TrackpadHandler is attached to the button to handle the user's interaction with the trackpad. If the text of the button is "trackpad" and the user presses and releases the trackpad, the button is cleared.
// Event handler for tracking user interaction with // the belt trackpad. eventHandlers: [ TrackpadHandler { onTrackpad: { switch (event.trackpadEventType) { // User has started to trackpad interaction case TrackpadEventType.Begin: { console.log("TrackpadEventType.Begin"); break; } // Trackpad continuing to be swiped //(moving finger over trackpad) case TrackpadEventType.Move: { console.log("TrackpadEventType.Move: x:" + event.deltaX + " y:" + event.deltaY); break; } // User has ended trackpad interaction case TrackpadEventType.End: { console.log("TrackpadEventType.End"); break; } // User has pressed the trackpad case TrackpadEventType.Press: { console.log("TrackpadEventType.Press"); break; } // User released the trackpad case TrackpadEventType.Release: { console.log("TrackpadEventType.Release"); if(button.text == "trackpad") { clearButton() } break; } // Interaction has been canceled case TrackpadEventType.Cancel: { console.log("TrackpadEventType.Cancel"); break; } } } } ]
That's it! Have fun playing with this app on your BlackBerry Classic. And feel free to reuse some of these techniques in your own app. For more information about the BlackBerry Classic, check out Device characteristics and BlackBerry Classic navigation keys.
P.S. If you are looking for a sample app that targets the BlackBerry Passport, check out the Gears app in GitHub.