Screens

You can use a Page to represent a screen in your app. In QML, you can specify the content that the Page should display by using the content property. This property accepts a UI control as the root control that's displayed on the screen. Here's how to create a Page with a Button as its root control:

import bb.cascades 1.0
 
Page {
    content: Button {
        text: "Root button"
    }
}

The content property is the default property of a Page, meaning that you don't need to use "content:" explicitly when you want to add a control as the root. You can simply add the control directly to the Page:

import bb.cascades 1.0
 
Page {
    Button {
        text: "Root button"
    }
}

In C++, you can set the content of a Page by calling setContent():

Page* myPage = new Page;
myPage->setContent(Button::create("Root button"));

Page accepts only one control as its content. In the example above, the content of the Page is only the single Button; you can't add another Button, or any other control, to the content of the Page. If you call setContent() and specify a different control, the new control replaces the previous control as the content of the Page. Because of this, it can be a good idea to use a  Container as the content of your Page, and then add all other controls to the Container.

Here's how to create a Page that uses a Container as its content, in both QML and C++. The Container includes several other UI controls that are displayed on the screen.

Code sample: Specifying content in QML

import bb.cascades 1.0
 
Page {
    content: Container {
        Label {
            text: "A label"
        }
 
        Button {
            text: "A button"
        }
         
        Slider {
        }
    }
}

Code sample: Specifying content in C++

Page* myPage = new Page;
Container* rootContainer = new Container;
 
rootContainer->add(Label::create("A label"));
rootContainer->add(Button::create("A button"));
rootContainer->add(Slider::create());
 
myPage->setContent(rootContainer);

Adding actions

You can add actions to a  Page by using the actions property. Actions are displayed as buttons at the bottom of the screen and represent actions that users might want to perform on that screen. For example, a screen for composing a new email might include actions to send the email, file it to complete later, or delete it.

You use an  ActionItem to represent an action. An ActionItem can include both descriptive text and an image, and it emits the  triggered() signal when it's selected. You can respond to this signal by using the predefined onTriggered signal handler in QML, or by connecting the signal to a slot in C++. When you use an image on an ActionItem, the image is centered on the action button. If you don't specify an image, one is added automatically for you.

Screen showing a set of actions at the bottom of a screen.

By default, actions that you add to a Page appear in an action menu, which is positioned on the right side of the action bar and looks like a series of three dots arranged vertically. Users can tap this menu to display the actions for the screen.


Screens illustrating how to display the action menu.

You can specify that you want an action to appear on the action bar by using the ActionBar.placement property. This property accepts enumeration values from the ActionBarPlacement class: InOverflow or OnBar. Actions that use ActionBarPlacement::OnBar are added to the action bar until there's no more room for additional actions. When the action bar is full, any extra actions are added to the action menu. Actions that use ActionBarPlacement::InOverflow are placed in the action menu but aren't displayed on the action bar.

It's important to note that the action menu is displayed only if you add actions that don't use the ActionBarPlacement::OnBar value (or if the action bar is full, as described above). In addition, if an action menu is displayed, the menu contains all of the actions for the Page, including those actions that already appear on the action bar. Consider the following examples that illustrate this behavior:

If you add an action that uses ActionBarPlacement::OnBar and another action that uses ActionBarPlacement::InOverflow, an action menu that contains both actions is displayed and only the first action appears on the action bar.

Screen showing a single action on the action bar, along with an action menu.

If you add two actions that both use ActionBarPlacement::OnBar, an action menu isn't displayed and both actions appear on the action bar.

Screen showing two actions on the action bar, without an action menu.
If you add two actions and neither one uses ActionBarPlacement::OnBar, an action menu is displayed that includes both actions and neither action appears on the action bar.
Screen showing no actions on the action bar, with an action menu.

Here's how to create a Page in QML with two actions, both of which are placed on the action bar using the ActionBar.placement property. When selected, each action changes the text of a Label:

import bb.cascades 1.0
 
Page {
    content: Container {
        Label {
            id: myLabel
            text: "Initial text"
        }
    }
     
    actions: [
        ActionItem {
            title: "Action 1"
            ActionBar.placement: ActionBarPlacement.OnBar
             
            onTriggered: {
                myLabel.text = "Action 1 selected!"
            }
        },        
        ActionItem {
            title: "Action 2"
            ActionBar.placement: ActionBarPlacement.OnBar
             
            onTriggered: {
                myLabel.text = "Action 2 selected!"
            }
        }  
    ]
}

Here's how to do the same thing in C++. The handleAction1() and handleAction2() functions are slots that handle the actions on the Page, and are connected to the triggered() signals of the actions.

// The variable myLabel is of type Label, and is declared in a
// header file so that the slots can access it. The slot functions
// handleAction1() and handleAction2() are also declared in the
// header file.
 
Page* root = new Page;
 
// Create the container and label
Container* topContainer = new Container;
mLabel = Label::create("Initial text");
topContainer->add(myLabel);
 
// Create actions for the screen, and connect the triggered()
// signal of each action to slot functions. Make sure to
// test the return value to detect any errors.
ActionItem* action1 = ActionItem::create()
        .title("Action 1");
ActionItem* action2 = ActionItem::create()
        .title("Action 2");
bool res = QObject::connect(action1, SIGNAL(triggered()), this,
                            SLOT(handleAction1()));
                            
// If any Q_ASSERT statement(s) indicate that the slot failed to
// connect to the signal, make sure you know exactly why this has
// happened. This is not normal, and will cause your app to stop
// working.
Q_ASSERT(res);
res = QObject::connect(action2, SIGNAL(triggered()), this,
                       SLOT(handleAction2()));
Q_ASSERT(res);
 
// Indicate that the variable res isn't used in the rest of the
// app, to prevent a compiler warning.
Q_UNUSED(res);
                  
// Add the actions to the page.
root->addAction(action1, ActionBarPlacement::OnBar);
root->addAction(action2, ActionBarPlacement::OnBar);
 
// Set the content of the page and display it.
root->setContent(root);
Application::setScene(root);

// The slot function for action 1
void App::handleAction1()
{
    mLabel->setText("Action 1 selected!");
}
 
// The slot function for action 2
void App::handleAction2()
{
    mLabel->setText("Action 2 selected!");
}

Using sheets

Page is designed to represent an entire screen in your app, and you can add Page objects to other navigation elements, such as a  NavigationPane or  TabbedPane. To learn how, see Drill down and Tabs.

Cascades includes another control to represent an entire screen in your app: a  Sheet. A Sheet is displayed as a layer on top of the current screen and represents a separate flow, or detour, from the main navigation of your app. For example, you might use a Sheet to allow users to compose an email or create a new contact.

Sheet can contain other navigation controls, such as  NavigationPane TabbedPane, or  Page, and it can include actions that appear in the action bar or action menu. When you open a Sheet, it appears from the right of the screen and covers the entire screen (including any other Sheet objects that might be open).


Screens showing how a sheet is displayed.

Any Sheet objects that you want to display are included in the attachedObjects list. Here's how to create and show a Sheet in QML:

import bb.cascades 1.0
 
Page {
    attachedObjects: [
        Sheet {
            id: mySheet
            content: Page {
                Label {
                    text: "This is a sheet."
                }
                 
                actions: [
                    ActionItem {
                        title: "Close Sheet"
                        ActionBar.placement: ActionBarPlacement.OnBar
                         
                        // When this action is selected, close
                        // the sheet
                        onTriggered: {
                            mySheet.close();
                        }
                    }
                ]
            }
        }    
    ]
     
    actions: [
        ActionItem {
            title: "Open Sheet"
            ActionBar.placement: ActionBarPlacement.OnBar
             
            // When this action is selected, open
            // the sheet
            onTriggered: {
               mySheet.open();
            }
        }
    ]
}

Here's how to do the same thing in C++:

// Create the UI controls
Page *root = new Page;
Sheet *mySheet = new Sheet;
Page *sheetPage = new Page;
Label* sheetLabel = Label::create("This is a sheet.");
 
// Create the actions to open and close the sheet, and add the actions
// to their appropriate pages
ActionItem *openSheet = ActionItem::create()
                         .title("Open Sheet")
                         .onTriggered(mySheet, SLOT(open()));
ActionItem *closeSheet = ActionItem::create()
                         .title("Close Sheet")
                         .onTriggered(mySheet, SLOT(close()));
sheetPage->addAction(closeSheet, ActionBarPlacement::OnBar);
root->addAction(openSheet, ActionBarPlacement::OnBar);
 
// Set the content of each page
sheetPage->setContent(sheetLabel);
mySheet->setContent(sheetPage);

Last modified: 2013-12-21

comments powered by Disqus