While designing my first app that is intended for media consumption (rather than my usual puzzle games), I quickly realized that it is necessary to to take into account orientation changes. The orientation is the direction the device is being held, either landscape or portrait. The idea of properly handling orientation is to effectively use screen real estate for both use cases.

Luckily, like many other things in Cascades, dealing with orientation changes is very easy. Prior to changing any code, if you go to the “Application” tab of the bar-descriptor.xml you will see an orientation dropdown. If it is set to auto-orient, Cascades will know when the orientation changes and attempt to reposition your objects to display properly. Usually this is not ideal, but it's worth taking a look to see how your app looks with Cascades adjusting auto-magically.
Assuming the auto adjust from Cascades is not what you’d like for your app, you can also easily adjust and move around components manually. Let’s take a look at two scenarios/methods for handling orientation changes.

Adjusting Component Properties

This first method will take advantage of adjusting component properties. Take a look at the two screenshots below.


The portrait view has 6 components (only 3 visible), stack one on top of each other in a ScrollView that scrolls vertically. The landscape view has the same 6 components, however they are now stacked left to right and the ScrollView scrolls horizontally.


To control these properties we need to attach the OrientationHandler to our Page. Then within that, the signal onOrientationAboutToChange is fired when the user changes the orientation of the device. So we could have code that looks like:

import bb.cascades 1.0 Page { attachedObjects: [ OrientationHandler { onOrientationAboutToChange: { if (orientation == UIOrientation.Landscape) { scrollContainer.layout.orientation = LayoutOrientation.LeftToRight; scrollMain.scrollViewProperties.scrollMode = ScrollMode.Horizontal; } else { scrollContainer.layout.orientation = LayoutOrientation.TopToBottom; scrollMain.scrollViewProperties.scrollMode = ScrollMode.Vertical; } } } ] //... }

Using Custom Components

Much like I used a custom component in my Asset Selector example, custom components can be used in the Orientation handler. Take a look at these two screenshots for portrait and landscape.


They each contain the same 9 components, however they are arranged so differently that it would be a pain to account for adjusting all the properties. Therefore it is best to define separate user interfaces for each. So I created PortView.qml and LandView.qml files that contained the UI for each view. Then I used a ControlDelgate in conjunction with the onOrientationAboutToChange signal to dynamically load each UI depending on the orientation. The code would look something like this:

import bb.cascades 1.0 Page { attachedObjects: [ OrientationHandler { onOrientationAboutToChange: { if (orientation == UIOrientation.Landscape) { myDelegate.source = "LandView.qml" } else { myDelegate.source = "PortView.qml" } } } ] Container { //Todo: fill me with QML Label{ text: "AWESOME TITLE!" textStyle.fontSize: FontSize.XLarge textStyle.fontWeight: FontWeight.W100 } ControlDelegate { id: myDelegate source: "PortView.qml" horizontalAlignment: HorizontalAlignment.Center } } }

That about does it for handling orientation changes. One more thing to note, Q series (720x720) devices will ignore this code always displaying the portrait UI. Check out the full source code for these two samples from the link below and sound off in the comments with any thoughts!

Read more