application.qml Example File
demos/mobile/guitartuner/src/application.qml
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtDeclarative module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
** the names of its contributors may be used to endorse or promote
** products derived from this software without specific prior written
** permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
** $QT_END_LICENSE$
**
****************************************************************************/
import QtQuick 1.0
import "mycomponents"
/* The base canvas for all QML drawing. */
Rectangle {
id: application
property int targetNoteIndex: 0
property alias frequency: noteChooser.currentFrequency
//Data provided to C++.
property bool isInput: true
property bool isMuted: false
property bool isAuto: true
property alias maxVoiceDifference: voiceDifferenceMeter.maxValue
property real volume: 0.5
property real sensitivity: 0.5
//Signals to C++.
signal volumeChanged(real volume)
signal microphoneSensitivityChanged(real sensitivity)
signal targetFrequencyChanged(real frequency)
signal modeChanged(bool isInput)
signal muteStateChanged(bool isMuted)
//Slots for signals coming from C++.
function voiceDifferenceChanged(difference) {
if (isAuto) timer.running = true;
voiceDifferenceMeter.valueChanged(difference);
noteImage.glowing = false
}
function correctFrequencyObtained() {
noteImage.glowing = true
}
function lowVoice() {
noteImage.glowing = false
}
//Private function for changing the target frequency automatically.
function calculateTargetFrequency(difference) {
var tempDifference = Math.abs(difference);
var tempIndex = targetNoteIndex
while (!(difference < 0 && tempIndex == 0) &&
tempDifference >= notes.get(tempIndex-(difference<0)).interval/2) {
tempDifference -= notes.get(tempIndex-(difference<0)).interval;
tempIndex += difference/Math.abs(difference);
}
if (tempIndex != targetNoteIndex) {
targetNoteIndex = tempIndex
noteChooser.currentFrequency = notes.get(targetNoteIndex).frequency;
targetFrequencyChanged(frequency);
}
}
width: 360; height: 640
color: "black"
//Provides data for functions.
NotesModel {id: notes}
/* A timer for changing the target frequency automatically.
* This is needed for avoiding recursion. */
Timer {
id: timer
interval: 1
onTriggered: calculateTargetFrequency(voiceDifferenceMeter.value)
}
//A meter for showing the difference between current and target frequency.
Meter {
id: voiceDifferenceMeter
maxValue: 12
minValue: -maxValue
height: imageSize.height/background.sourceSize.height*parent.height
width: imageSize.width/background.sourceSize.width*parent.width
anchors {
topMargin: 100/background.sourceSize.height*parent.height
horizontalCenter: parent.horizontalCenter
top: parent.top
}
}
Image {
id: background
anchors.fill: parent
smooth: true
source: "./mycomponents/images/guitartuner_skin.png"
}
//A button for quitting the application.
Image {
id: quitButton
width: sourceSize.width/background.sourceSize.width*parent.width
height: sourceSize.height/background.sourceSize.height*parent.height
source: "./mycomponents/images/power.png"
smooth: true
KeyNavigation.up: volumeAdjuster
KeyNavigation.down: modeButton
Keys.onEnterPressed: Qt.quit()
anchors{
leftMargin: 297/background.sourceSize.width*parent.width
left: parent.left;
topMargin: 17/background.sourceSize.height*parent.height
top: parent.top
}
MouseArea {
anchors.fill: parent
onClicked: Qt.quit()
}
}
//An image for showing the target note.
Image {
id: noteImage
property bool glowing: false
width: sourceSize.width/background.sourceSize.width*parent.width
height: sourceSize.height/background.sourceSize.height*parent.height
source: glowing ? notes.get(targetNoteIndex).glowSource : notes.get(targetNoteIndex).bigSource
anchors {
topMargin: 273/background.sourceSize.height*parent.height
top: parent.top
horizontalCenter: parent.horizontalCenter
}
}
//A button for choosing the input/output mode.
Image {
id: modeButton
function buttonPressed() {
isInput = !isInput
modeChanged(isInput)
if (isInput) {
soundIcons.source = "./mycomponents/images/sensitivity.png"
source = "./mycomponents/images/voicemode_off.png"
volumeAdjuster.setValue(sensitivity)
}
else {
//Change off from "auto" mode
if (isAuto) {
noteChooser.pushButton(targetNoteIndex)
}
if (isMuted) {
soundIcons.source = "./mycomponents/images/volume_off.png";
}
else
soundIcons.source = "./mycomponents/images/volume.png"
source = "./mycomponents/images/voicemode_on.png"
volumeAdjuster.setValue(volume)
}
}
width: sourceSize.width/background.sourceSize.width*parent.width
height: sourceSize.height/background.sourceSize.height*parent.height
smooth: true
source: "./mycomponents/images/voicemode_off.png"
KeyNavigation.up: quitButton
KeyNavigation.down: noteChooser
Keys.onEnterPressed: buttonPressed()
anchors {
leftMargin: 16/background.sourceSize.width*parent.width
left: parent.left
topMargin: 353/background.sourceSize.height*parent.height
top: parent.top
}
MouseArea {
anchors.fill: parent
onPressed: {
parent.focus = true
parent.scale = 0.95
}
onReleased: {
parent.scale = 1/0.95
}
onClicked: parent.buttonPressed()
}
}
//Buttons for choosing the target note.
NoteButtonView {
id: noteChooser
width: parent.width*0.95; height: width/model.count
onNoteSelected: {
if (note == "Auto") {
if (!isAuto) {
isAuto = true
}
if (!isInput) {
modeButton.buttonPressed()
}
}
else {
timer.running = false;
isAuto = false
targetNoteIndex = index
targetFrequencyChanged(frequency)
}
focus = true
}
KeyNavigation.up: modeButton
KeyNavigation.down: soundIcons
anchors {
horizontalCenter: parent.horizontalCenter
topMargin: 454/background.sourceSize.height*parent.height
top: parent.top
}
}
//An element for showing the mode and changing the mute state.
Image {
id: soundIcons
function stateChanged() {
isMuted = !isMuted
muteStateChanged(isMuted)
if (isMuted) {
source = "qrc:/src/mycomponents/images/volume_off.png"
}
else {
source = "qrc:/src/mycomponents/images/volume.png"
}
}
width: sourceSize.width/background.sourceSize.width*parent.width
height: sourceSize.height/background.sourceSize.height*parent.height
smooth: true
source: "./mycomponents/images/sensitivity.png"
Keys.onEnterPressed: stateChanged()
KeyNavigation.up: noteChooser
KeyNavigation.down: quitButton
KeyNavigation.left: volumeAdjuster
KeyNavigation.right: volumeAdjuster
anchors {
leftMargin: 42/background.sourceSize.width*parent.width
left: parent.left
topMargin: 565/background.sourceSize.height*parent.height
top: parent.top
}
MouseArea {
anchors.fill: parent
onClicked: {
if (!isInput) {
parent.stateChanged()
}
parent.focus = true
}
}
}
//An element for adjusting volume.
Adjuster {
id: volumeAdjuster
max: 1
value: 0.5
width: 222/background.sourceSize.width*parent.width
height: parent.height*0.1
onFocusChangedByClick: focus = true
onArrowPressedWhenValueOverLimits: soundIcons.focus = true
KeyNavigation.up: modeButton
KeyNavigation.down: quitButton
anchors {
leftMargin: 98/background.sourceSize.width*parent.width
left: parent.left
verticalCenter: soundIcons.verticalCenter
}
onValueChanged: {
if (isInput) {
sensitivity = value;
microphoneSensitivityChanged(1-sensitivity)
}
else {
volume = value
volumeChanged(volume)
}
}
}
}