Orientation

Orientation is an important feature of most applications. You need to consider the purpose of your application when choosing which orientation(s) to support. Portrait view for applications such as e-readers can make it easier to digest the displayed information. Landscape view for applications such as movies or games can offer distinct benefits and provide a better experience for all-touch device users. Depending on your application, you may want to support both portrait and landscape views and provide a different user experience for each view.

The navigator service on the BlackBerry 10 OS handles the entire application window lifecycle and matches the application's orientation with the device orientation. Orientation changes are reported as events that contain both direction and angular measurement attributes. Usually, you will want to use the angular measurements to determine when rotation is necessary and ignore the direction. If you haven't specified an orientation, the default orientation when the application starts is portrait for a smartphone and landscape for a tablet.

You can specify which types of orientation you want to support in the BAR application descriptor file, bar-descriptor.xml. The navigator service sends your app rotation events based on what you specified in bar-descriptor.xml. If you specified only portrait or landscape, the navigator service will not send any orientation change events. If you configure your application to support orientation changes, your app needs to listen for change events from the BlackBerry 10 OS and respond to them.

There are three key components when managing the orientation of your device.

  • bps/bps.h
    Use the BPS library to set up events and listen for events. You must initialize BPS before you can request events. Add the following header files and function call to your application:
    #include <bps/bps.h>   // for initializing the BPS service
    #include <bps/event.h> // for creating and/or querying events
                    
    bps_initialize();      // initialize BPS; allows application to call BPS functions
  • bps/navigator.h

    Use the navigator service to determine the current orientation of the device. The navigator service informs the application when it needs to rotate and initiates the rotation sequence by sending the application a rotate event (NAVIGATOR_ORIENTATION_CHECK).

  • screen/screen.h

    Use the screen service along with the BPS library to coordinate orientation events with the display.

Setting orientation in bar-descriptor.xml

You can lock your application to a particular orientation in the BAR application descriptor file (bar-descriptor.xml). For example, the HelloWorldDisplay sample application locks the orientation to landscape.

In the BAR application descriptor file, you can set orientation to Default, Auto-orient, Landscape, or Portrait.
Table 1. Orientation Settings
Orientation Setting Result
Default Uses the device type to orient your application to the default orientation for your device type. The default is TOP_UP orientation, meaning the typical position of the device when used. For a smartphone that means portrait and for a tablet that means landscape.
Auto-orient Uses the physical position of the device to orient your application. The screen changes the orientation of the displayed application to match the physical positioning of the device. For example, if you are holding the device in portrait orientation, and turn the device 90 degrees to be in landscape orientation, then the display will re-orient to show the application in landscape mode.
Landscape Locks the orientation of your application to landscape. Regardless of the physical position of the device, the application is only displayed in landscape mode.
Portrait Locks the orientation of your application to portrait. Regardless of the physical position of the device, the application is only displayed in portrait mode.

Setting orientation in the Momentics IDE

In the Momentics IDE for BlackBerry, open the bar-descriptor.xml file for your project from the Project Explorer, and click the Application tab.

Select your orientation setting from the Orientation drop-down list and save your changes. For applications that are locked to Landscape or Portrait, the navigator handles the 180 degree flips as required.

For example, choose Landscape, and then click Source. The bar-descriptor.xml source includes the following entry:

<initialWindow>
    <aspectRatio>landscape</aspectRatio>
    <autoOrients>false</autoOrients>
    <systemChrome>none</systemChrome>
    <transparent>false</transparent>
</initialWindow>

If autoOrients is set to true:

  • aspectRatio is ignored and you receive all orientation change events. The orientation environment variable is set to reflect the current orientation of your device.

If autoOrients is set to false:

  • You may specify the desired aspectRatio
  • If aspectRatio is set to portrait or landscape, you only receive in-aspect orientation change events. For example, if you specified landscape, you receive events of 0-180 transitions.

Setting up your application window

There are two environment variables that contain the initial width and height of your app. You can retrieve these values by querying the width and height environment variables when your application is launched. If the height of the screen is greater than its width, then the application is initially running in portrait mode; otherwise the application is running in landscape mode.

The following code snippet illustrates how your application can query the environment variables for its initial width and height:
int screen_resolution[2];
screen_resolution[0] = atoi(getenv("WIDTH")); //get width
screen_resolution[1] = atoi(getenv("HEIGHT")); //get height
                
Your application should fetch these values at startup, and then use those values to create and set up its window as follows:
screen_create_window(&screen_win, context);
rc = screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_SIZE, 
                                   screen_resolution);
if (rc) {
    //handle error …
}
rc = screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_BUFFER_SIZE, 
                                   screen_resolution);
if (rc) {
    //handle error …
}

Handling orientation changes

The navigator service populates the initial width and height environment variables based on the BAR application descriptor file settings. If the application's orientation is locked to landscape, then the width and height will correspond to the device's resolution in landscape mode. Similarly, if the application's orientation is locked to portrait, then the width and height will correspond to the device's resolution in portrait mode. If orientation in the BAR application description file is set to either Auto-orient or Default, the width and height will correspond to the orientation of the device when the application starts.

Your application can both initiate rotations and receive rotation events from the device. For applications that specify autoOrients as true, the application must handle both rotations initiated by the user and by the application.

The GoodCitizen sample is an example of an application that responds to orientation changes. The BAR file for this application looks like this:

<initialWindow>
    <autoOrients>true</autoOrients>
    <systemChrome>none</systemChrome>
    <transparent>false</transparent>
</initialWindow>

User-initiated rotations

The following list provides a general overview of how the navigator service handles user-initiated rotations:
  1. Your application registers for navigator events including orientation change events by calling navigator_request_events().
  2. When a user changes the orientation of the device, if LANDSCAPE or PORTRAIT have not been set in the BAR file, the navigator service sends a NAVIGATOR_ORIENTATION_CHECK event to your application with either LANDSCAPE or PORTRAIT and the rotation edge as the parameters.
  3. Your application must respond to the NAVIGATOR_ORIENTATION_CHECK event by calling navigator_orientation_check_response() with the parameter will_rotate set to true (to initiate the rotation sequence described in the following steps), or with will_rotate set to false (if your application will not rotate). Not responding to the event is considered equivalent to calling navigator_orientation_check_response() with will_rotate set to false and no NAVIGATOR_ORIENTATION event is sent.
If you called navigator_orientation_check_response() with will_rotate set to true, then complete the rotation sequence by performing the following steps:
  1. Your application gets a NAVIGATOR_ORIENTATION event and resizes its window buffers by making calls to the screen function screen_set_window_property_iv() for the buffer size and again for the source size. The app then redraws all windows and child windows.
  2. Your application then informs the navigator service that it's finished handling the rotation by calling navigator_done_orientation().
  3. The navigator service completes the rotation of the device (such as rotating other applications) and sends a NAVIGATOR_ORIENTATION_DONE event to your application.

Some window actions can’t be performed while a rotation is happening. These include creating new windows or joining window groups. Wait until you receive the NAVIGATOR_ORIENTATION_DONE event to perform these actions.

Application-initiated rotations

Your application can also request orientation changes on its own. Any application can request a rotation even if it is locked to a particular orientation, enabled rotation is locked for the window, or the device is locked by the user. When the request is successful, the navigator service initiates the rotation sequence using the same steps as in User initiated rotations.

To initiate a rotation, the application calls navigator_orientation_check_response() with the will_rotate parameter set to true. The navigator service initiates the rotation when the device is in an acceptable state to support it.

Compatibility with the BlackBerry PlayBook

Using the BlackBerry 10 Native SDK to support your application on BlackBerry PlayBook OS 2.0 won't require any code changes on your part as everything will work as before. With the BlackBerry PlayBook, there are no width and height environment variables. You just need to query the ORIENTATION environment variable and, based on its value, query the window angle that the screen service gives you. If the values are off by 90 degrees, you swap the width and height.

When writing applications for BlackBerry PlayBook OS 2.0, you needed to write extra logic to rotate your window based on the state of the ORIENTATION environment variable. With BlackBerry 10 OS, this code is no longer needed and applications are discouraged from querying for their width and height using the screen service.

If you want to port your application to BlackBerry 10 OS, your code must get the width and height parameters using the environment variables. It is recommended that you update your code to use the parameters you receive from the navigator service.

Related resources

Last modified: 2013-12-24

comments powered by Disqus