Active Frames

Active Frames are dynamic app covers that are displayed on the home screen when your app is minimized. Every app uses app covers by default. Just swipe up from the bottom bezel within an app and the app cover is displayed automatically. Tapping the app cover takes you back into the app.Diagram showing how to initiate Active Frames in an app.

An app cover is a noninteractive scene that the Cascades framework automatically updates whenever the cover changes. By default, the app cover displays a scaled-down version of the scene that's being displayed in the app. For many apps, using the default app cover might be the best option because it displays the current visual state of the app for the user.

However, there might be instances where you want to display specific information in the app cover. For example, in a weather app you could display the current temperature. You can create your own app covers using the SceneCover class.

For best practices for using app covers, see the Active Frames topic in the UI Guidelines.

Creating a cover

An app cover is similar to any other screen that you might create in your app. You can create the content for the cover using either QML or C++ and the app cover can support whichever controls that you want to display.

Although the root node of the scene needs to be an AbstractPane subclass, the root of a cover can be a Control. The major difference is that users can't interact with a cover, and it doesn't support animations.

You can download the Cascades Cookbook app, which demonstrates how to create covers using both C++ and QML, from the Sample Apps page.

Because it doesn't have a custom cover, the app displays a scaled-down version of the current scene. Here's what the cover might look like when the home screen of the app is being displayed.

Screen showing the cover of the Cookbook sample.

The process of creating a cover in QML involves defining the UI in QML. First, you create the QML document while specifying the QML file that contains the UI for the cover.

After you verify that the QML document is free of errors, you retrieve the root container, set it as the content of a SceneCover, and then set the cover on your app instance.

Screen showing the Active Frame created from the sample code that follows.
QmlDocument *qmlCover = 
    QmlDocument::create("asset:///AppCover.qml").parent(this);

if (!qmlCover->hasErrors()) {
	// Create the QML Container from using the QMLDocument
	Container *coverContainer = 
        qmlCover->createRootObject<Container>();

	// Create a SceneCover and set the app cover
	SceneCover *sceneCover = 
        SceneCover::create().content(coverContainer);
	Application::instance()->setCover(sceneCover);
}

Here's the QML that defines the components for the cover.

import bb.cascades 1.0

Container {
    Container {        
        layout: DockLayout {}
        background: Color.Black
        
        ImageView {
            imageSource: "asset:///images/app-cover.png"
            scalingMethod: ScalingMethod.AspectFit
        }
        
        Container {
            bottomPadding: 31
            horizontalAlignment: HorizontalAlignment.Center
            verticalAlignment: VerticalAlignment.Bottom
            
            Container {
                preferredWidth: 300
                preferredHeight: 42
                background: Color.create("#121212")
                layout: DockLayout {}
                
                Label {
                    objectName: "TheLabel"
                    horizontalAlignment: HorizontalAlignment.Center
                    verticalAlignment: VerticalAlignment.Center
                    text: "QML"
                    textStyle.color: Color.create("#ebebeb")
                    textStyle.fontSize: FontSize.PointValue
                    textStyle.fontSizeValue: 6
                }
            }
        }
    }
}

When the user minimizes the app, the custom app cover is displayed instead of the default cover.

To create the content for a cover in C++, you need to create the controls and add them to a root container. The custom cover for the Cascades Cookbook app contains a 334 x 396 pixel image for the background, a Label indicating the name of the cookbook, and various containers and layouts for positioning the controls.

The background image is designed specifically for the dimensions of the BlackBerry Z10. If your app also targets devices with a physical keyboard, you need another background image that is 310 x 211 pixels. Since the cover itself is small compared to a regular screen, the label uses a custom TextStyle with a Small FontSize.

Screen showing the Active Frame created from the sample code that follows.
// A small UI consisting of just an ImageView in a Container
// is set up and used as the cover for the app when running 
// in minimized mode

Container *coverContainer = Container::create().background(
		Color::fromRGBA(0, 0, 0, 1));
coverContainer->setLayout(new DockLayout());

// A background image for the app cover
ImageView *coverImage = ImageView::create(
		"asset:///images/app-cover.png").scalingMethod(
		ScalingMethod::AspectFit);

Container *titleContainer = Container::create().bottom(31);
titleContainer->setHorizontalAlignment(HorizontalAlignment::Center);
titleContainer->setVerticalAlignment(VerticalAlignment::Bottom);

Container *labelContainer =
		Container::create().preferredSize(84, 42).background(
				Color::fromARGB(0xff121212));
labelContainer->setLayout(new DockLayout());

// A title for the "book" cover so that one can see that it 
// is the C++ version of the cookbook that is running
Label* title = Label::create("C++");
title->textStyle()->setColor(Color::fromARGB(0xffebebeb));
title->textStyle()->setFontSize(FontSize::PointValue);
title->textStyle()->setFontSizeValue(6);
title->setHorizontalAlignment(HorizontalAlignment::Center);
title->setVerticalAlignment(VerticalAlignment::Bottom);

// Setting up the title Container with a title
labelContainer->add(title);
titleContainer->add(labelContainer);

// Adding the background image and the title Container
coverContainer->add(coverImage);
coverContainer->add(titleContainer);

After you add the components to the root container, you create an instance of SceneCover using the root container, retrieve an instance of Application, and set the cover.

// Create a SceneCover and set the app cover
SceneCover *sceneCover = 
    SceneCover::create().content(coverContainer);
Application::instance()->setCover(sceneCover);

When the user minimizes the app, the custom app cover is displayed instead of the default cover.

Not applicable

Multiple covers 10.3

The BlackBerry Passport smartphone can display two sizes of Active Frames (also known as app covers):

  • Large Active Frames, which are 440 pixels wide by 486 pixels high
  • Small Active Frames, which are 440 pixels wide by 195 pixels high

By default, a minimized app uses a large Active Frame. The large Active Frame is created using an app cover with a CoverDetailLevel of High.

If there are more than six minimized apps running on a BlackBerry Passport, an app cover of the next app that's minimized uses a small Active Frame.

A small Active Frame is created using an app cover with a CoverDetailLevel of Medium.

Screen showing the different sizes of Active Frames on a BlackBerry Passport.

This technique might not create the user experience that you expect if the small Active Frame doesn't illustrate your app clearly. You can create multiple covers to improve your user experience.

To define more than one app cover in your app, you can use the MultiCover class. In a MultiCover, you can specify either two SceneCover objects or one SceneCover and one ApplicationViewCover.

Using two SceneCover objects allows you to design the large and small app covers to show specific parts of your app, including dynamic content in your app.

Using a SceneCover and an ApplicationViewCover allows you to design one specific app cover and let the other app cover be a scaled version of the current scene in your app. Setting the CoverDetailLevel determines which app cover is used. A CoverDetailLevelof High indicates that this app cover is used for large Active Frames. A CoverDetailLevel of Medium indicates that this app cover is used for small Active Frames.

The following code sample shows how to create a MultiCover using two SceneCover objects:

import bb.cascades 1.3

Page {
    content: Container {
        // This is the UI of your app
    }
    
    onCreationCompleted: {
        Application.setCover(multiCover)
    }
    
    attachedObjects: [
        MultiCover {
            id: multiCover
            
            SceneCover {
                id: bigCover
                // Use this cover when a large cover is required
                MultiCover.level: CoverDetailLevel.High
                content: Container {
                    // Your large cover layout
                    Label {
                        text: "My Large Cover"
                        textStyle.color: Color.Magenta
                        textStyle.fontSizeValue: 10.0
                    }
                }
                function update() {
                    // Update the large cover dynamically
                }
            } // sceneCover HIGH
            
            SceneCover {
                id: smallCover
                // Use this cover when a small cover is required
                MultiCover.level: CoverDetailLevel.Medium
                content: Container {
                    // Your small cover layout
                    Label {
                        text: "My Small Cover"
                        textStyle.color: Color.Cyan
                        textStyle.fontSizeValue: 5.0
                    }
                }
                function update() {
                    // Update the small cover dynamically
                }
            } // sceneCover MEDIUM
            
            function update() {
                bigCover.update()
                smallCover.update()
            }
        }
    ]
}
#include "applicationui.hpp"

#include <bb/cascades/Application>
#include <bb/cascades/QmlDocument>
#include <bb/cascades/AbstractPane>
#include <bb/cascades/LocaleHandler>
#include <bb/cascades/Page>
#include <bb/cascades/Container>
#include <bb/cascades/Button>
#include <bb/cascades/Label>
#include <bb/cascades/SceneCover>
#include <bb/cascades/MultiCover>

using namespace bb::cascades;

ApplicationUI::ApplicationUI() :
        QObject()
{

    // Create your UI
    Container *contentContainer = Container::create()
        .add(Button::create().text("My Application"));

    // Create a container for the big cover
    Container *bigContainer = Container::create();
    Label* bigLabel=Label::create("My Large Cover");
    bigLabel->textStyle()->setColor(Color::Magenta);
    bigLabel->textStyle()->setFontSizeValue(10.0);
    bigContainer->add(bigLabel);


    // Create a big SceneCover
    SceneCover* bigCover =
            SceneCover::create().content(bigContainer);

    // Create a container for the small cover
    Container *smallContainer = Container::create();
    Label* smallLabel=Label::create("My Small Cover");
    smallLabel->textStyle()->setColor(Color::Cyan);
    smallLabel->textStyle()->setFontSizeValue(5.0);
    smallContainer->add(smallLabel);

    // Create a small SceneCover
    SceneCover* smallCover =
            SceneCover::create().content(smallContainer);

    // Create a MultiCover with the big SceneCover
    // used when a large Active Frame is required
    // and the small SceneCover used when
    // a small Active Frame is required
    AbstractCover* cover = MultiCover::create()
        .add(bigCover, CoverDetailLevel::High)
        .add(smallCover, CoverDetailLevel::Medium);

    // Create a page using the root container
    // and set the scene
    Page *page = new Page();
    page->setContent(contentContainer);
    Application::instance()->setScene(page);

    Application::instance()->setCover(cover);
}

Not applicable

The following code sample demonstrates how to create one SceneCover and one ApplicationViewCover:

import bb.cascades 1.3

Page {
    content: Container {
        // This is the UI of your app
    }
    
    onCreationCompleted: {
        Application.setCover(multiCover)
    }
    
    attachedObjects: [
        MultiCover {
            id: multiCover
            
            SceneCover {
                id: bigCover
                // Use this cover when a large cover is required
                MultiCover.level: CoverDetailLevel.High
                content: Container {
                    // Your large cover layout
                    Label {
                        text: "My Large Cover"
                        textStyle.color: Color.Magenta
                        textStyle.fontSizeValue: 10.0
                }
                function update() {
                    // Update the large cover dynamically
                    }
                } // sceneCover HIGH
            }
            
            ApplicationViewCover {
                id: appViewCover
                // Use this cover when a small cover is required
                MultiCover.level: CoverDetailLevel.Medium
            }
            
            function update() {
                bigCover.update()
            }
        }
    ]
}
#include "applicationui.hpp"

#include <bb/cascades/Page>
#include <bb/cascades/Application>
#include <bb/cascades/QmlDocument>
#include <bb/cascades/AbstractPane>
#include <bb/cascades/Container>
#include <bb/cascades/Button>
#include <bb/cascades/ApplicationViewCover>
#include <bb/cascades/SceneCover>
#include <bb/cascades/MultiCover>

using namespace bb::cascades;

ApplicationUI::ApplicationUI() :
        QObject()
{
    // Create your UI
    Container *contentContainer = Container::create()
        .add(Button::create().text("My Application"));

    // Add a SceneCover to your UI
    SceneCover* sceneCover = 
            SceneCover::create().content(contentContainer);

    // Create an ApplicationViewCover
    ApplicationViewCover* appViewCover = 
            ApplicationViewCover::create();

    // Create a MultiCover with the SceneCover
    // used when a large Active Frame is required
    // and the ApplicationViewCover used when
    // a small Active Frame is required
    AbstractCover* cover = MultiCover::create()
        .add(sceneCover, CoverDetailLevel::High)
        .add(appViewCover, CoverDetailLevel::Medium);

    // Create a page using the root container
    // and set the scene
    Page *page = new Page();
    page->setContent(contentContainer);
    Application::instance()->setScene(page);

    Application::instance()->setCover(cover);

}

Not applicable

Related resources

Web-based training

Design guidelines

 

Last modified: 2015-04-16



Got questions about leaving a comment? Get answers from our Disqus FAQ.

comments powered by Disqus