Color scheme tester
This example application demonstrates how the color scheme can be changed. In addition to the base theme there are a total of 18 different color themes available (numbered from 2 to 19). It is actually quite easy to change the theme, you just need to set the theme.colorScheme property in the QML code.
The application looks like shown below. This time I tried the build the user interface a bit more like the standard N9 applications. Basically this just requires that the page margins, header dimensions and font properties are set according to the N9 UI guidelines.
The view-header dimensions and text position depend on the screen orientation. I have annotated the relevant parameters into the following figures.
To make the parameter usage a bit easier I saved all the constants into a javascript library. I followed the UI constants naming conventions but adjusted the values a bit to get a better match with the standard N9 applications. The library can be created by selecting Add>New and then QML and JS File.
I’ll name the file appConstants.js. The file contents is shown below. Basically the file just assigns values to a set of javascript variables. The variable names become available in the QML file by using the import command.
// Application specific UI constants .pragma library var colorScheme = 2; var DefaultMargin = 16; var RadioButtonSpacing = 24; var HeaderDefaultHeightPortrait = 72; var HeaderDefaultTopSpacingPortrait = 15; var HeaderDefaultBottomSpacingPortrait = 15; var HeaderDefaultHeightLandscape = 64; var HeaderDefaultTopSpacingLandscape = 9; var HeaderDefaultBottomSpacingLandscape = 13; var fontFamily = "Nokia Pure Text Light"; var fontSizeLarge = 32; var fontSizeSmall = 24; var fontFamilyButton = "Nokia Pure Text" var fontSizeButton = 20;
Here is the main.qml file. Note the import command in the beginning of the file. After importing the appConstants.js the variables can be used directly or by assigning the variable values to properties. I will use properties to define the header dimensions as they depend on the orientation. I can use the onInPortraitChanged event handler to set the property values.
import QtQuick 1.1
import com.nokia.meego 1.0
import "appConstants.js" as AppConstants
PageStackWindow {
id: appWindow
// UI constants
property int defaultMargin : AppConstants.DefaultMargin
property int headerFontSize : AppConstants.fontSizeLarge
property string headerFontFamily : AppConstants.fontFamily
property string buttonFontFamily : AppConstants.fontFamilyButton
property int buttonFontSize : AppConstants.fontSizeButton
// UI variables (may change due to orientation change)
property int headerHeight
property int headerTopSpacing
property int headerBottomSpacing
property int nColumns
property string promptFontColor : "black"
showStatusBar: false
initialPage: mainPage
MainPage {
id: mainPage
}
ToolBarLayout {
id: commonTools
visible: true
ToolIcon {
platformIconId: "toolbar-view-menu"
anchors.right: (parent === undefined) ? undefined : parent.right
onClicked: (myMenu.status === DialogStatus.Closed) ? myMenu.open() : myMenu.close()
}
}
Menu {
id: myMenu
visualParent: pageStack
MenuLayout {
MenuItem { text: qsTr("Sample menu item") }
}
}
// adjust orientation dependent variables
onInPortraitChanged: {
headerHeight =
(inPortrait)?AppConstants.HeaderDefaultHeightPortrait:
AppConstants.HeaderDefaultHeightLandscape
headerTopSpacing =
(inPortrait)?AppConstants.HeaderDefaultTopSpacingPortrait:
AppConstants.HeaderDefaultTopSpacingLandscape
headerBottomSpacing =
(inPortrait)?AppConstants.HeaderDefaultBottomSpacingPortrait:
AppConstants.HeaderDefaultBottomSpacingLandscape
nColumns = (inPortrait)?3:5
}
}
The header is defined in the file Header.qml. The header depends on the main.qml properties that define the header dimensional parameters. The header text is set with the headerText property that will be defined when the header is instantiated in the MainPage.qml file.
The header and the header button images are loaded from the standard theme directory (image://theme) depending on the currently chosen color scheme (theme.colorScheme).
Note also the usage of the theme.inverted property (can be toggled with the Invert button).
import QtQuick 1.1
import com.nokia.meego 1.0
Item {
property alias headerText: titleLabel.text
property string buttonBackground: "image://theme/color"+theme.colorScheme+"-meegotouch-button-accent-background"
property string viewHeader: "image://theme/color"+theme.colorScheme+"-meegotouch-view-header-fixed"
// header dimensions
height: headerHeight
width: parent.width
ButtonStyle {
id: buttonStyle
textColor: "white"
fontFamily: buttonFontFamily
fontPixelSize: buttonFontSize
background: buttonBackground
pressedBackground: buttonBackground+"-pressed"
}
LabelStyle {
id: labelStyle
textColor: "white"
fontFamily: headerFontFamily
fontPixelSize: headerFontSize
}
// Header background image
Image {
id: titleImage
height: parent.height
width: parent.width
source: viewHeader
}
// Header text
Label {
id: titleLabel
platformStyle: labelStyle
anchors {
top:parent.top; topMargin:headerTopSpacing;
bottom:parent.bottom; bottomMargin:headerBottomSpacing;
left:parent.left; leftMargin:defaultMargin
}
}
// Theme invert button
Button {
id: titleButton
width: 130
height: 40
anchors { right: titleImage.right; rightMargin: defaultMargin
verticalCenter: titleImage.verticalCenter}
platformStyle: buttonStyle
text: "Invert"
onClicked: {
theme.inverted=!theme.inverted
promptFontColor=theme.inverted?"White":"Black"
}
}
}
The MainPage.qml file loads the Header component from Header.qml and sets the header text (“TestApp11”). The currentColor property is used to keep track of the currently chosen color scheme. The color selection is done with a set of radio buttons arranged inside a Grid component. Note that the number of columns in the grid is dynamically set based on the screen orientation (nColumns is set in main.qml).
import QtQuick 1.1
import com.nokia.meego 1.0
import "appConstants.js" as AppConstants
Page {
property int currentColor : AppConstants.colorScheme
tools: commonTools
// the page header element
Header {
id: header
headerText: "TestApp11"
}
// detect change in the currentColor property
onCurrentColorChanged: {
// apply the current color to the color scheme, header image and header button
theme.colorScheme=currentColor
// set the clicked button as checked
radio2.checked = currentColor==2
radio3.checked = currentColor==3
radio4.checked = currentColor==4
radio5.checked = currentColor==5
radio6.checked = currentColor==6
radio7.checked = currentColor==7
radio8.checked = currentColor==8
radio9.checked = currentColor==9
radio10.checked = currentColor==10
radio11.checked = currentColor==11
radio12.checked = currentColor==12
radio13.checked = currentColor==13
radio14.checked = currentColor==14
radio15.checked = currentColor==15
radio16.checked = currentColor==16
radio17.checked = currentColor==17
radio18.checked = currentColor==18
radio19.checked = currentColor==19
}
// the page contents
Item {
// anchor below header and use the default margins
anchors {top: header.bottom;bottom: parent.bottom;
left: parent.left; right: parent.right;
leftMargin:defaultMargin;topMargin:defaultMargin}
Text {
id: prompt
text: qsTr("Please select a color scheme")
font.pixelSize: AppConstants.fontSizeSmall
color: promptFontColor
}
// position the radio buttons using a grid layout
Grid {
columns: nColumns // depends on orientation
flow: Grid.TopToBottom
spacing: AppConstants.RadioButtonSpacing
anchors {top: prompt.bottom; topMargin: defaultMargin}
RadioButton { id: radio2; text: "Color2"; onClicked: currentColor=2}
RadioButton { id: radio3; text: "Color3"; onClicked: currentColor=3}
RadioButton { id: radio4; text: "Color4"; onClicked: currentColor=4}
RadioButton { id: radio5; text: "Color5"; onClicked: currentColor=5}
RadioButton { id: radio6; text: "Color6"; onClicked: currentColor=6}
RadioButton { id: radio7; text: "Color7"; onClicked: currentColor=7}
RadioButton { id: radio8; text: "Color8"; onClicked: currentColor=8}
RadioButton { id: radio9; text: "Color9"; onClicked: currentColor=9}
RadioButton { id: radio10; text: "Color10"; onClicked: currentColor=10}
RadioButton { id: radio11; text: "Color11"; onClicked: currentColor=11}
RadioButton { id: radio12; text: "Color12"; onClicked: currentColor=12}
RadioButton { id: radio13; text: "Color13"; onClicked: currentColor=13}
RadioButton { id: radio14; text: "Color14"; onClicked: currentColor=14}
RadioButton { id: radio15; text: "Color15"; onClicked: currentColor=15}
RadioButton { id: radio16; text: "Color16"; onClicked: currentColor=16}
RadioButton { id: radio17; text: "Color17"; onClicked: currentColor=17}
RadioButton { id: radio18; text: "Color18"; onClicked: currentColor=18}
RadioButton { id: radio19; text: "Color19"; onClicked: currentColor=19}
}
}
}
Let’s run the application in the simulator. When a color button is clicked the theme changes accordingly. And the invert button will invert the theme.





