Sunday, 20 July 2014

Application Development : Text Controls (part 2) – Validator, TextArea

Validator
You can make sure that the user’s input conforms to a certain set of rules by specifying a Validator class for the TextField using its validator property. For example, for a password field you could ensure that it is of a certain length and that it contains at least a digit. You can use the validator’s mode property to specify when text validation should occur. For example, by setting the mode property to ValidationMode.Immediate, the user’s input will be validated as the user types along, and by setting the property to ValidationMode.FocusLost, the user’s input will be validated once the TextField has lost focus.  During validation, you can update the validator’s state by setting its state property, which can take one of the following values:
  • ValidatationState.Unknown: Validation state is unknown. This state is used for cases where the validation process has not been initiated.
  • ValidationState.InProgress: Validation is currently in progress.
  • ValidationState.Valid: Validation has succeeded.
  • ValidationState.Invalid: Validation has failed.
You should implement the actual validation in JavaScript by handling the validator’s validate signal, as illustrated in Listing 6.
Listing 6.  JavaScript Validation Using a Regular Expression
import bb.cascades 1.2
 
Page {
    Container {
        TextField {
            id: myField
            inputMode: TextFieldInputMode.NumbersAndPunctuation
            input {
                submitKey: SubmitKey.Go
                onSubmitted: {
                    // handle input when submit key is pressed
                    // by extracting value text from myField.text
                }
            }
            validator: Validator {
                mode: ValidationMode.Immediate
                errorMessage: "Invalid integer!"
                onValidate: {
                   // regexp for valid integer including optional sign
                    var regexp = /^\s*(\+|-)?\d+\s*$/;
                    var isValidInteger = regexp.test(myField.text);
                    if (regexp.test(myField.text))
                        state = ValidationState.Valid;
                    else
                        state = ValidationState.Invalid;
                }
            }
        }
    }
}
The regexp variable defines a valid integer (for example, 10, -99, and 0 are valid expressions, but 10.0 would be considered as invalid). The important point is that I am using the regexp variable to toggle the validator’s validation state.
Finally, here a few best practices to consider:
  • Use a text field to let users input a single line of text, such as an e-mail address, a password, or a contact name.
  • Include hint texts in text fields (by doing so, you won’t need to add a label describing the text field’s purpose).
  • Don’t use word prediction in e-mail, password, and contact name fields. Using word prediction in these cases will simply get in the user’s way.
  • Provide clear error messages when using validators.
TextArea
A TextArea is very similar to a TextField and shares many of its properties (which they both inherit from AbstractTextControl). The main difference comes from the fact that a TextArea can handle multiple lines of text, whereas a TextField provides a single line. You can set the TextArea’s inputMode using a TextAreaInputMode object (the possible values are TextAreaInputMode.Default, TextAreaInputMode.Text, TextAreaInputMode.Chat, TextAreaInputMode.Email, and TextAreaInputMode.Custom). Finally, you can also use the TextArea’s editor object to track the current cursor position or the current selected text (see Listing 4-13).
Listing 4-13.  TextArea Signal Handling
import bb.cascades 1.2
Page {
    Container {
        layout: DockLayout {
             
        }
        leftPadding: 20
        rightPadding: 20
         
        TextArea {
            id: myField
            inputMode: TextAreaInputMode.Chat
            hintText: "Enter some text"
            verticalAlignment: VerticalAlignment.Center
            preferredHeight: 500
             
            scrollMode: TextAreaScrollMode.Elastic
            onTextChanging: {
                console.log("text changing: "+text)
            }
             
            editor.onSelectionStartChanged: {
                console.log("selection start: "+selectionStart);
            }
            editor.onSelectionEndChanged: {
                console.log("selection end: "+selectionEnd);
            }
            editor.onSelectedTextChanged: {
                console.log("selectedTextChanged: " + selectedText)
            }
            editor.onCursorPositionChanged: {
                console.log("cursorPositionChanged: " + cursorPosition)
            }
        }
    }
}

Application Development : Text Controls (part 1) – TextField

TextField
A TextField is a single-line control that accepts text input. A TextField has fixed height and variable width. Just like a label, you can control the text styling using a TextStyleDefinition object (in other words, all the techniques described in the previous sections apply to text fields). You can specify how the text field behaves in relation to its text input by specifying its inputMode property. The following are some common values:
  • TextFieldInputMode.Default: This is the default input mode.
  • TextFieldInputMode.Text: An input mode for a wide variety of text.
  • TextFieldInputMode.EmailAddress: An input mode for e-mail addresses.
  • TextFieldInputMode.Password: An input mode for passwords.
  • TextFieldInputMode.NumericPassword: An input mode for numeric passwords.
  • TextFieldInputMode.Url: An input mode for URLs.
  • TextFieldInputMode.PhoneNumber: An input mode for phone numbers.
In fact, a TextFieldInputMode corresponds to default values for input and content flags. Input flags determine how the text that users type is parsed and interpreted by the text field. Content flags determine how the text that users type is displayed. In practice, using one of the default TextFieldInputMode types to preset the flags is more than adequate, and you should rarely need to set the input and content flags directly. The inputMode property value also determines the kind of virtual keyboard displayed to the user when entering text. For example, TextFieldInputMode.Text is the most flexible and suitable for a wide variety of text. This mode also includes word suggestions to help users type faster. The other input modes are optimized for specific tasks such as writing e-mails or entering numeric values. For example, Figures 1 and 2 illustrate the TextFieldInputMode.EmailAddress and TextFieldInputMode.NumericPassword respectively.

Figure 1. A virtual keyboard corresponding to an e-mail address input (image source: BlackBerry)
Figure 2. A virtual keyboard corresponding to numeric password input (image source: BlackBerry)
You can capture a TextField’s input using its input grouped property, as illustrated in Listing 5.
Listing 5.  Text Capture
import bb.cascades 1.2
 
Page {
    Container {
        TextField {
            id: myField
            inputMode: TextFieldInputMode.EmailAddress
            hintText: "Enter email address"
            input{
                submitKey: SubmitKey.Go
                onSubmitted: {
                    // handle input when submit key is pressed
                    // by extracting text from myField.text
                }
            }
        }
    }
}
The submitKey property controls the text that will appear on the virtual keyboard’s Submit key (the Submit key is always located on the lower-right side of the virtual keyboard). The property can take one of the following values: SubmitKey.Go, SubmitKey.Join, SubmitKey.Next, SubmitKey.Search, SubmitKey.Send, SubmitKey.Submit, SubmitKey.Done, SubmitKey.Connect, SubmitKey.EnterKey, and SubmitKey.Replace.
You can also use a TextField’s hintText property to suggest the purpose of the field to the user when there is no input (see Listing 5).

Application Development : Controls – Button

You can use buttons in order to capture touch events in your application. A Button can display some text, an image, or both. You can set the following properties on a Button:
  • For sizing, you can set the preferredWidth, minWidth, and maxWidth properties. A button’s height is fixed and you cannot change it. The button’s width is increased automatically in order to fit text and images. A button will truncate its text if the text content is wider than the maxWidth property.
  • The button’s text property specifies the text that will be displayed on the Button.
  • You can use the image or imageSource properties for specifying an image to be displayed on the Button. In most cases, you will use the imageSource property, which will usually correspond to the URL of an image located in a subfolder of your application’s assets folder (you can also use the image property to specify a Image wrapped as a QVariant).
The button will emit the clicked signal that you can handle in QML using the onClicked signal handler (see Listing 1).
Listing 1.  Button Clicked Signal
Button{
   id: button
   text: "mybutton"
   onClicked: {
      console.log("I was clicked!")
   }
}
The following best practices apply to buttons:
  • Set the button that users are most likely to tap as the default button. Also, don’t make a button associated with a destructive action as the default button.
  • Use single-word labels when possible.
  • Use verbs that describe the associated action (for example: Login, Cancel, Delete, or Save).

Application Development : Controls – Slider

Slider 
A Slider is a control that allows the selection of a value from a range of values (see Figure 1). You can set the range using the fromValue and toValue properties. You can handle the value using the onImmediateValueChanged signal handler. In practice, you will have to round to the closest integer the immediateValue passed to the handler (see Listing 1).
Figure 1. Slider
Listing 1.  Slider
import bb.cascades 1.0
Page {
    Container {
        TextField {
           id: texfield
        }
        Slider{
            id: slider
            fromValue: 0
            toValue: 100
            onImmediateValueChanged: {
                texfield.text = Math.round(immediateValue)
            }
        }
    }
}
Use a slider when a user needs to quickly set a value from a predetermined range of values.

Application Development : Selection Controls – RadioGroup

RadioGroup
A RadioGroup can be used to group a set of options together. However, only one option can be selected at a time. Options are displayed as radio buttons, with an optional text describing their purpose (see Figure 2).
Figure 2. RadioGroup
You can handle option selection by responding to the RadioGroup’s selectedOptionChanged signal (or alternatively, you could also directly handle the Option’s selectedChanged signal; see Listing 2).
Listing 2.  RadioGroup
// Create a RadioGroup with three options
Page {
    RadioGroup {
        Option {
            id: option1
            text: "Easy"
            onSelectedChanged: {
                if (selected) {
                    console.log("Easy selected");
                }
            }
        }
        Option {
            id: option2
            text: "Hard"
            selected: true
            onSelectedChanged: {
                if (selected) {
                    console.log("Hard selected");
                }
            }
        }
        Option {
            id: option3
            text: "Very Hard"
            onSelectedChanged: {
                if (selected) {
                    console.log("Very hard selected");
                }
            }
        }
    }
}
Use a RadioButton when users can choose between more than two mutually exclusive options.

Friday, 18 July 2014

Application Development : System Dialogs, Prompts, and Toasts – SystemToast

SystemToast
A toast is a simple pop-up message that is displayed for a predefined amount of time. The toast is for information purposes only and the user does not need to interact with it. Listing 4 shows you how to use a SystemToast to display a toast to the user.
Listing 4.  SystemToast
import bb.cascades 1.2
import bb.system 1.2
 
Page {
    Container {
        layout: DockLayout {
        }
        Button {
            text: "Show Dialog!"
            verticalAlignment: VerticalAlignment.Center
            horizontalAlignment: HorizontalAlignment.Center
            onClicked: {
                myToast.show();
            }
        }
        attachedObjects: [
            SystemToast {
                id: myToast
                body: "Happy New Year!"
            }
        ]
 
    }
}

Application Development : Controls – ScrollView

ScrollView:
A ScrollView is a container allowing the scrolling and zooming of its content. A ScrollView provides a viewport, which displays an area of the entire content. You can use a ScrollView when the content will not fit the UI entirely (for example, that would be the case if a container included many controls). Note that a ScrollView’s content can also be an ImageView or a WebView (for example, you can use a ScrollView to zoom in or out of a picture). You can control the scrolling behavior by setting the ScrollView’s scrollViewProperties property. Listing 1 shows you how to include a WebView in a ScrollView.
Listing 1.  ScrollView
Page {
    ScrollView {
        WebView {
            url: "http://www.nrcreddy.blogspot.com"
        }
        scrollViewProperties {
            scrollMode: ScrollMode.Vertical
            pinchToZoomEnabled: true
        }
    }
}
Use a ScrollView when
  • A control’s content does not fit the screen and you need to provide a viewport that you can navigate (by scrolling horizontally and/or vertically).
  • You need to zoom in or out of content using a pinch gesture.

Application Development : System Dialogs, Prompts, and Toasts – SystemPrompt

SystemPrompt
You can use a SystemPromptto ask for some input from the user before continuing with your application flow. The SystemPrompt will display two default buttons for accepting or rejecting the dialog box and an input field for user input. You can retrieve the user’s input by calling SystemPrompt.inputFieldTextEntry() (see Listing 2).
Listing 2.  SystemPrompt
import bb.cascades 1.2
import bb.system 1.2
 
Page {
    Container {
        layout: DockLayout {
             
        }
        Button {
            text: "Show Dialog!"
            verticalAlignment: VerticalAlignment.Center
            horizontalAlignment: HorizontalAlignment.Center
            onClicked: {
                myPrompt.show();
            }
        }
        attachedObjects: [
            SystemPrompt {
                title: "Enter a new file name"
                id: myPrompt
                onFinished: {
                    switch (value) {
                        case (SystemUiResult.ConfirmButtonSelection):
                            console.log("new file name is: "+myPrompt.inputFieldTextEntry())
                            break;
                        case (SystemUiResult.CancelButtonSelection):
                            console.log("new file canceled");
                            break;
                        default:
                            break;
                    }
                }
            }
        ]
 
    }
}
Figure  shows the SystemPrompt when displayed.
Figure . SystemPrompt

Application Development : System Dialogs, Prompts, and Toasts – SystemDialog

You can use the system dialog controls to pause your application flow and communicate important information to the user. System dialogs can be used to ask the user to confirm an action, notify the user of an event, or prompt the user for additional information.
SystemDialog
You can use a SystemDialog control to ask the user to confirm an action (see Listing 1). (Note that you need to import the bb.system 1.2 library.)
Listing 1.  SystemDialog with User Confirmation
import bb.cascades 1.2
import bb.system 1.2
 
Page {
    Container {
        layout: DockLayout {
        }
        Button {
            text: "Show Dialog!"
            verticalAlignment: VerticalAlignment.Center
            horizontalAlignment: HorizontalAlignment.Center
            onClicked: {
                myDialog.show();
            }
        }
        attachedObjects: [
            SystemDialog {
                title: "Save Changes"
                id: myDialog
                onFinished: {
                    switch (value) {
                        case (SystemUiResult.ConfirmButtonSelection):
                            console.log("save confirmed");
                            break;
                        case (SystemUiResult.CancelButtonSelection):
                            console.log("save canceled");
                            break;
                        default:
                            break;
                    }
                }
            }
        ]
 
    }
}
To display the dialog, you need to call SystemDialog.show(). To determine the user’s selection, you need to handle the SystemDialog.finished() signal. The SystemDialog’s text property will be displayed on the dialog’s title bar (see Figure 1).
Figure 1. SystemDialog

Thursday, 17 July 2014

Application Development : Application Templates – Tabbed Pane Template

The Momentics IDE’s New BlackBerry Project wizard is a great starting place for selecting your application scaffolding. You have the choice between four project templates, which basically cover most, if not all, of your needs in designing Cascades applications:
  • Standard empty project: This is the template you have been using until now for designing your applications. It provides you a single Page where you can add your own Cascades controls.
  • List view: Creates an application where the main UI element is a ListView displaying a list of items. The data for the list items is provided by an instance of a DataModel.
  • Tabbed pane: Creates an application where the user can switch between Tabs. Each Tab contains an instance of an AbstractPane (in practice, you can only add a Page or a NavigationPane to the Tab).
  • Navigation pane: Creates an application that uses a NavigationPane to display screens. Navigation is triggered when the user selects an action, which can be contextual or located on the Action bar (I will tell you more about actions and action bars in a moment).
Note that both the List view and the Navigation pane templates use navigation, which is a way to transition from one screen to another, in order to implement their functionality.
Let us now have a look at the main.qml files generated by each template (I am going to omit the standard empty project because you are already quite familiar with it).
Tabbed Pane Template
The main.qml file generated by the Tabbed Pane template is given in Listing 1.
Listing 1.  Tabbed Pane Template, main.qml
import bb.cascades 1.0
 
TabbedPane {
    showTabsOnActionBar: true
    Tab { //First tab
        // Localized text with the dynamic translation and locale updates support
        title: qsTr("Tab 1") + Retranslate.onLocaleOrLanguageChanged
        Page {
            Container {
                Label {
                    text: qsTr("First tab") + Retranslate.onLocaleOrLanguageChanged
                }
            }
        }
    } //End of first tab
    Tab { //Second tab
        title: qsTr("Tab 2") + Retranslate.onLocaleOrLanguageChanged
        Page {
            Container {
                Label {
                    text: qsTr("Second tab") + Retranslate.onLocaleOrLanguageChanged
                }
            }
        }
    } //End of second tab
}
A tabbed pane is an extremely convenient way of organizing your application in multiples screens. Each Tab can contain an instance of an AbstractPane (in other words, you can use a Page or a NavigationPane as a child control). Figure 1 illustrates a resulting UI where the second tab has been selected.
Figure 1. Tabs on Action bar with second Tab selected
You can specify how a TabbedPane will appear on the Action bar by setting its ShowTabsOnActionBar property. If you change the property to false (or if you don’t set it at all), the resulting layout will be identical to Figure 2.
Figure 2. Tabs in overflow menu
By touching the Tab1 icon, you will reveal the other tabs. Obviously, this layout is preferable if you have lots of tabs in your application.

Application Development : Text Controls – Text Styles

Text is probably the most ubiquitous control in any UI. Cascades therefore gives you lots of flexibility in handling text, as well as its appearance. You can customize the text styles by creating your own text style definitions. This section will review the three main text controls, which are Label, TextField, and TextArea, and show you how to customize their corresponding text style.
1. Text Styles
You can customize a text control’s appearance by setting its textStyle.base property, which is an instance of the TextStyle object. In practice, you will use a TextStyleDefinition attached object to create a new TextStyle instance (in other words, the TextStyleDefinition object is a factory for TextStyle objects).Using a TextStyleDefinition, you can customize visual attributes such as font weight (light, normal, and bold), color, size, and alignment. When specifying a TextStyleDefinition, you will always start with a system default base, TextStyle, which gives you an initial set of attributes to work from. The SystemDefaults.TextStyles class gives you the following default text styles:
  • SystemDefaults.TextStyles.BigText: The default text style for large text.
  • SystemDefaults.TextStyles.BodyText: The default text style for body text.
  • SystemDefaults.TextStyles.PrimaryText: The default text style for primary text.
  • SystemDefaults.TextStyles.SmallText: The default text style for small text.
  • SystemDefaults.TextStyles.SubtitleText: The default text style for subtitle text.
  • SystemDefaults.TextStyles.TitleText: The default text style for title text.
Listing 1 shows you how you can use the default system text styles with a Label.
Listing 1.  System Text Styles
import bb.cascades 1.2
Page {
    Container {
        Label {
            text: "This is big text"
            textStyle.base: SystemDefaults.TextStyles.BigText
        }
        Label {
            text: "This is title text"
            textStyle.base: SystemDefaults.TextStyles.TitleText
        }
        Label {
            text: "This is subtitle text"
            textStyle.base: SystemDefaults.TextStyles.SubtitleText
        }
        Label {
            text: "This is body text"
            textStyle.base: SystemDefaults.TextStyles.BodyText
        }
        Label{
            text: "This is primary text"
            textStyle.base: SystemDefaults.TextStyles.PrimaryText
        }
        Label{
            text: "This is small text"
            textStyle.base: SystemDefaults.TextStyles.SmallText
        }
    }
}
Listing 2 shows you how to customize a text style using a TextStyleDefintion.
Listing 2.  Custom Text Style
import bb.cascades 1.2
Page {
    Container {
        attachedObjects: [
            TextStyleDefinition {
                id: myStyle
                base: SystemDefaults.TextStyles.BigText
                color: Color.DarkBlue
                fontWeight: FontWeight.Bold
            }
        ]
        Label {
            text: "Some bold text"
            textStyle.base: myStyle.style
        }
    }
}
The advantage of specifying a TextStyleDefinition object is that you will be able to reuse it throughout your UI without redefining text styles for each control.

Application Development : Text Controls – Inline HTML and CSS

Inline HTML and CSS
Besides using TextStyleDefinition objects for customizing text appearance, you can also resort to inline HTML and CSS. The supported HTML tags are: <a>, <b>, <br/>, <i>, <span>, <p>, <div>, <em>, and <strong>. Listing 1 shows you how to apply inline HTML text styling to a label.
Listing 1.  Custom Text Style
import bb.cascades 1.2
  
Page {
    Label {
        text: "<html><b>Cascades</b> is <i>awesome!</i></html>"
    }
}
You can also embed a <style> tag inside <span> or <div> tags in order to apply CSS styling to your text, as shown in Listing 2.
Listing 2.  CSS Styling
import bb.cascades 1.2
  
Page {
    Label {
        text: "<html><span style='text-decoration:underline'>Cascades</span> is"+
              "<span style='font-size:xx-large;font-style:italic;color:green'>awesome!</span></html>"
    }
}
Note that not all CSS attributes are supported in style definitions, but you can rely on the following ones (for additional details on how to use the attributes, refer to one of the numerous online CSS tutorials; a good starting point is www.w3schools.com/css/):
  • background-color: Sets the text background color.
  • color: Sets the text color (for example: red, green, gray, etc…).
  • direction: Sets the text direction (for example: ltr which is left to right or rtl which is right to left)
  • font-family: Specifies the text font family (for example: font-family:”Courier New”, Courier, monospace;). The font-family property should hold several font names as a fallback system.  You should always start with the font you want and end with a generic family.
  • font-size: Specifies the font size (for example: medium, large, x-large, xx-large).
  • font-style: Specifies the font style (normal, italic, oblique).
  • font-weight: Specifies the font weight (normal, bold, lighter, bolder, 100, 200, 300, 400, 500, 600, 700, 800, 900). A normal font weight is 400 and bold is 700.
  • line-height: Specifies the height of a line of text.
  • text-align: Specifies the text’s horizontal alignment (left, right, center, justify).
  • text-decoration: Specifies whether the text should be underlined or strike-through (none, underline, line-through).
  • letter-spacing: Adjusts the space between letters in the text (see www.w3schools.com/cssref/pr_text_letter-spacing.asp).
3. Label
You can use a label control to display a single or multiple lines of read-only text by setting its text property.

Application Development : Selection Controls – SegmentedControl

SegmentedControl
A SegmentedControl displays a horizontal row of selectable options (in practice, you can display up to four visible options). A SegmentedControl is a great way of filtering content inside a view . Listing 1 shows you how to create a SegmentedControl in QML.
Listing 1.  SegmentedControl
Page {
    Container {
        SegmentedControl {
            id: segmented1
            Option {
                id: option1
                text: "Option 1"
                value: "option1"
                selected: true
            }
            Option {
                id: option2
                text: "Option 2"
                value: "option2"
            }
            Option {
                id: option3
                text: "Option 3"
                value: "option3"
            }
            onSelectedIndexChanged: {
                var value = segmented1.selectedValue
                console.debug("Selected value: " + value);
            }
        }
    }
}
And Figure 1 shows the corresponding UI.
Figure 1. SegmentedControl

Wednesday, 16 July 2014

Application Development : Defining the Application Structure – Single Page Applications – Page Actions

Single Page Applications
A single Page application is entirely built around a unique Page at the root of the scene graph. You have been essentially designing single Page applications until now. The biggest advantage of the single Page application structure is not only its simplicity, but also the capacity to provide the user a single screen where all content and Actions are presented in an extremely focused way during the entire application lifetime. You might think that building your application around a single Page might lack the flexibility required for more complex interactions. You will, however, see that you can provide a very enticing user experience based on the single Page design using the controls presented in the following sections (you will also be able to extend very naturally the concepts introduced for single Page applications to multiple Page or navigation-based apps).
Actions
I have informally mentioned Actions when I discussed the Action bar. This section will show you how to implement them in practice in your own applications. There are several places where you can define Actions:
  • You can add Actions to a Page by setting the Page’s Actions property. You can also specify whether the Actions are displayed on the Action bar or in the Action overflow menu (by default, page Actions are located in the overflow menu and only the most used Actions should appear on the Action bar).
  • You can add context Actions to a UIControl, which will be displayed in a context menu when the user touches and holds the control in your app.
  • Finally, you can add Actions to a TitleBar.
1 ActionItem
An ActionItem object represents the actual Action. You can specify the following properties when declaring an ActionItem:
  • ActionItem::title: A text string that will be displayed with the Action (for example, on the Action bar or in a menu).
  • ActionItem::imageSource: A URL specifying the image set on the Action.
When the user triggers the Action, the ActionItem::triggered() signal is emitted. You can therefore use the onTriggered: handler in QML in order to react to user Actions.
2 Page Actions
Listing 1 illustrates how Actions are added to a Page control.
Listing 1.  Actions
import bb.cascades 1.0
Page {
        actions: [
        ActionItem {
            id: action1
            title: "action1"
            onTriggered: {
                actionLabel.text = action1.title
            }
        },
        ActionItem {
            id: action2
            title: "action2"
            onTriggered: {
                actionLabel.text = action2.title
            }
 
       }
       ]
    Container {
        Label {
            id: actionLabel
            text: "Hello Actions"
            textStyle.base: SystemDefaults.TextStyles.BigText
            horizontalAlignment: HorizontalAlignment.Center
        }
    }
}
Figure 2 shows the action bar when all Actions are located in the overflow menu.
Figure 2. Actions overflow menu
And Figure 3 displays the expanded overflow menu.
Figure 3. Expanded overflow menu
If you want to display actions directly on the Action bar, you need to set the ActionItem’s ActionBar.placement property to ActionBarPlacement.OnBar (see Listing 2 and Figure 4).
Listing 2. Actions on Action Bar
import bb.cascades 1.0
 
Page {
        actions: [
        ActionItem {
            id: action1
            title: "action1"
            ActionBar.placement: ActionBarPlacement.OnBar
            onTriggered: {
                actionLabel.text = action1.title
            }
        },
        ActionItem {
            id: action2
            title: "action2"
            ActionBar.placement: ActionBarPlacement.OnBar
            onTriggered: {
                actionLabel.text = action2.title
            }
        }
        ]
    Container {
        Label {
            id: actionLabel
            text: "Hello Actions"
            textStyle.base: SystemDefaults.TextStyles.BigText
            horizontalAlignment: HorizontalAlignment.Center
            contextActions:[

        }
    }
}
Figure 4. Actions on Action bar
3 Context Actions
You can also associate actions to a UIControl by setting the UIControl::contextActions property (see Listing 3).
Listing 3.  Context Actions
import bb.cascades 1.0
 
Page {
    Container {
        Label {
            id: actionLabel
            text: "Hello Actions"
            textStyle.base: SystemDefaults.TextStyles.BigText
            horizontalAlignment: HorizontalAlignment.Center
            contextActions: [
                ActionSet {
                    Title:
                    ActionItem {
                        id: action1
                        title: "action1"
                        ActionBar.placement: ActionBarPlacement.OnBar
                        onTriggered: {
                            actionLabel.text = action1.title
                        }
                    }
                    ActionItem {
                        id: action2
                        title: "action2"
                        ActionBar.placement: ActionBarPlacement.OnBar
                        onTriggered: {
                            actionLabel.text = action2.title
                        }
 
                    }
                }
            ]
        }
    }
}
You need to touch and hold the Label in order to display the context Actions. Notice how the Actions are grouped in an Action set. (You can specify multiple Action sets, but at the moment, Cascades will take only the first one into account. This might change in future releases.)

Tuesday, 15 July 2014

Application Development : Application Templates – List View Template

List View Template
Listing 3 gives the main.qml generated by the List view template. (Listing 4 defines the page that is displayed when a ListView item is selected. Listing 5 defines the data to be loaded in the ListView.)
Listing 3.  List View Template, main.qml
import bb.cascades 1.0
NavigationPane {
    id: nav
    Page {
        Container {
            ListView {
                dataModel: XmlDataModel {
                    source: "data.xml"
                }
                onTriggered: {
 
                    if (indexPath.length > 1) {
                        var chosenItem = dataModel.data(indexPath);
                        var contentpage = itemPageDefinition.createObject();
 
                        contentpage.itemPageTitle = chosenItem.name
                        nav.push(contentpage);
                    }
                }
            }
 
        }
 
    }
    attachedObjects: [
        ComponentDefinition {
            id: itemPageDefinition
            source: "ItemPage.qml"
        }
    ]
    onPopTransitionEnded: {
        page.destroy();
    }
}
Listing 4.  List View Template, ItemPage.qml
import bb.cascades 1.0
 
Page {
    property alias itemPageTitle: titlebar.title
    titleBar: TitleBar {
        id: titlebar
    }
    Container {
 
    }
}
Listing 5.  data.xml
<root>
    <header title="Header 1">
        <item  name="Item 1"/>
        <item  name="Item 2"/>
        <item  name="Item 3"/>
        <item  name="Item 4"/>
        <item  name="Item 5"/>
    </header>
    <header title="Header 2">
        <item  name="Item 1"/>
        <item  name="Item 2"/>
        <item  name="Item 3"/>
        <item  name="Item 4"/>
        <item  name="Item 5"/>
        <item  name="Item Gorilla"/>
    </header>
</root>
Here are the most important aspects of the code to consider:
  • The root control is an instance of NavigationPane (again, this is a departure from the standard empty project that contained a Page control as the root container).  The NavigationPane provides the NavigationPane::push(bb::cascades::Page*) and the bb::cascades::Page* NavigationPane::pop() methods in order to implement navigation. If a page is pushed on the navigation stack, it will be displayed to the user. The opposite effect is achieved by popping the page off the stack. In this case, the page located at the top of the stack is displayed. You should note that a List view template is essentially a special case of a Navigation pane template where navigation is triggered by selecting data items in a ListView.
  • A ListView uses a DataModel in order to load its data. The ListView component has been designed around the MVC pattern. The DataModel implements the model part, the ListView plays the role of the controller, and a ListItemComponent handles the list view’s visuals.
  • The navigation pane’s attached object property includes a ComponentDefinition declaration, which is used to dynamically load a QML component (in this case, an instance of ItemPage, which is defined in ItemPage.qml, located in the same folder as main.qml). When you actually need to create the object, you will have to call ComponentDefinition.createObject().
  • Notice how the indexPath array length is checked before navigating to ItemPage to ensure that the user has selected an item element and not a header.
  • The root element index path will be the empty array. The header elements will have a one-element index path array and the item elements will have an index path array containing two elements.
Figure 3 illustrates the resulting application and Figure 4 UI when Item 2 is selected from the list.
Figure 3. Master view
Figure 4. Details view
By touching the Back icon, you will pop the current page from the NavigationPage’s stack and display the ListView, which will once again be at the top of the stack.