summaryrefslogtreecommitdiffstats
path: root/examples
diff options
context:
space:
mode:
Diffstat (limited to 'examples')
-rw-r--r--examples/bluetooth/bluetooth.pro2
-rw-r--r--examples/bluetooth/btchat/chatserver.cpp1
-rw-r--r--examples/bluetooth/heartlistener/assets/blue_heart.pngbin7283 -> 0 bytes
-rw-r--r--examples/bluetooth/heartlistener/assets/blue_heart_small.pngbin250 -> 0 bytes
-rw-r--r--examples/bluetooth/heartlistener/assets/busy_dark.pngbin1130 -> 0 bytes
-rw-r--r--examples/bluetooth/heartlistener/assets/draw.js74
-rw-r--r--examples/bluetooth/heartlistener/assets/home.qml186
-rw-r--r--examples/bluetooth/heartlistener/assets/monitor.qml154
-rw-r--r--examples/bluetooth/heartlistener/assets/results.qml291
-rw-r--r--examples/bluetooth/heartlistener/assets/star.pngbin262 -> 0 bytes
-rw-r--r--examples/bluetooth/heartlistener/doc/images/heartratefound.pngbin26494 -> 0 bytes
-rw-r--r--examples/bluetooth/heartlistener/doc/images/heartratemonitor.pngbin46437 -> 0 bytes
-rw-r--r--examples/bluetooth/heartlistener/doc/images/heartrateresults.pngbin45087 -> 0 bytes
-rw-r--r--examples/bluetooth/heartlistener/heartlistener.pro20
-rw-r--r--examples/bluetooth/heartlistener/heartrate.cpp445
-rw-r--r--examples/bluetooth/heartlistener/resources.qrc16
-rw-r--r--examples/bluetooth/heartrate-game/README.md7
-rw-r--r--examples/bluetooth/heartrate-game/bluetoothbaseclass.cpp77
-rw-r--r--examples/bluetooth/heartrate-game/bluetoothbaseclass.h72
-rw-r--r--examples/bluetooth/heartrate-game/connectionhandler.cpp82
-rw-r--r--examples/bluetooth/heartrate-game/connectionhandler.h73
-rw-r--r--examples/bluetooth/heartrate-game/devicefinder.cpp167
-rw-r--r--examples/bluetooth/heartrate-game/devicefinder.h92
-rw-r--r--examples/bluetooth/heartrate-game/devicehandler.cpp354
-rw-r--r--examples/bluetooth/heartrate-game/devicehandler.h (renamed from examples/bluetooth/heartlistener/heartrate.h)139
-rw-r--r--examples/bluetooth/heartrate-game/deviceinfo.cpp (renamed from examples/bluetooth/heartlistener/deviceinfo.cpp)21
-rw-r--r--examples/bluetooth/heartrate-game/deviceinfo.h (renamed from examples/bluetooth/heartlistener/deviceinfo.h)10
-rw-r--r--examples/bluetooth/heartrate-game/doc/images/heartgame-result.pngbin0 -> 9468 bytes
-rw-r--r--examples/bluetooth/heartrate-game/doc/images/heartgame-running.pngbin0 -> 10951 bytes
-rw-r--r--examples/bluetooth/heartrate-game/doc/images/heartgame-search.pngbin0 -> 14591 bytes
-rw-r--r--examples/bluetooth/heartrate-game/doc/images/heartgame-start.pngbin0 -> 13214 bytes
-rw-r--r--examples/bluetooth/heartrate-game/doc/src/heartrate-game.qdoc (renamed from examples/bluetooth/heartlistener/doc/src/heartlistener.qdoc)37
-rw-r--r--examples/bluetooth/heartrate-game/heartrate-game.pro29
-rw-r--r--examples/bluetooth/heartrate-game/heartrate-global.h (renamed from examples/bluetooth/heartlistener/assets/Point.qml)20
-rw-r--r--examples/bluetooth/heartrate-game/images.qrc7
-rw-r--r--examples/bluetooth/heartrate-game/main.cpp (renamed from examples/bluetooth/heartlistener/main.cpp)34
-rw-r--r--examples/bluetooth/heartrate-game/qml.qrc18
-rw-r--r--examples/bluetooth/heartrate-game/qml/App.qml120
-rw-r--r--examples/bluetooth/heartrate-game/qml/BluetoothAlarmDialog.qml112
-rw-r--r--examples/bluetooth/heartrate-game/qml/BottomLine.qml (renamed from examples/bluetooth/heartlistener/assets/dialog.qml)24
-rw-r--r--examples/bluetooth/heartrate-game/qml/Connect.qml178
-rw-r--r--examples/bluetooth/heartrate-game/qml/GameButton.qml78
-rw-r--r--examples/bluetooth/heartrate-game/qml/GamePage.qml83
-rw-r--r--examples/bluetooth/heartrate-game/qml/GameSettings.qml91
-rw-r--r--examples/bluetooth/heartrate-game/qml/Measure.qml234
-rw-r--r--examples/bluetooth/heartrate-game/qml/SplashScreen.qml80
-rw-r--r--examples/bluetooth/heartrate-game/qml/Stats.qml (renamed from examples/bluetooth/heartlistener/assets/main.qml)77
-rw-r--r--examples/bluetooth/heartrate-game/qml/StatsLabel.qml (renamed from examples/bluetooth/heartlistener/assets/Button.qml)53
-rw-r--r--examples/bluetooth/heartrate-game/qml/TitleBar.qml87
-rw-r--r--examples/bluetooth/heartrate-game/qml/images/bt_off_to_on.pngbin0 -> 6143 bytes
-rw-r--r--examples/bluetooth/heartrate-game/qml/images/heart.pngbin0 -> 2664 bytes
-rw-r--r--examples/bluetooth/heartrate-game/qml/images/logo.pngbin0 -> 31915 bytes
-rw-r--r--examples/bluetooth/heartrate-game/qml/main.qml95
-rw-r--r--examples/bluetooth/heartrate-game/qml/qmldir1
-rw-r--r--examples/bluetooth/heartrate-server/doc/src/heartrate-server.qdoc2
-rw-r--r--examples/bluetooth/heartrate-server/main.cpp2
56 files changed, 2349 insertions, 1396 deletions
diff --git a/examples/bluetooth/bluetooth.pro b/examples/bluetooth/bluetooth.pro
index 1c09dade..bc18f571 100644
--- a/examples/bluetooth/bluetooth.pro
+++ b/examples/bluetooth/bluetooth.pro
@@ -12,5 +12,5 @@ qtHaveModule(quick): SUBDIRS += scanner \
picturetransfer \
pingpong \
lowenergyscanner \
- heartlistener \
+ heartrate-game \
chat
diff --git a/examples/bluetooth/btchat/chatserver.cpp b/examples/bluetooth/btchat/chatserver.cpp
index 6b21a507..dc1cda57 100644
--- a/examples/bluetooth/btchat/chatserver.cpp
+++ b/examples/bluetooth/btchat/chatserver.cpp
@@ -85,7 +85,6 @@ void ChatServer::startServer(const QBluetoothAddress& localAdapter)
classId.prepend(QVariant::fromValue(QBluetoothUuid(serviceUuid)));
serviceInfo.setAttribute(QBluetoothServiceInfo::ServiceClassIds, classId);
- serviceInfo.setAttribute(QBluetoothServiceInfo::BluetoothProfileDescriptorList,classId);
//! [Class Uuuid must contain at least 1 entry]
diff --git a/examples/bluetooth/heartlistener/assets/blue_heart.png b/examples/bluetooth/heartlistener/assets/blue_heart.png
deleted file mode 100644
index 997ee699..00000000
--- a/examples/bluetooth/heartlistener/assets/blue_heart.png
+++ /dev/null
Binary files differ
diff --git a/examples/bluetooth/heartlistener/assets/blue_heart_small.png b/examples/bluetooth/heartlistener/assets/blue_heart_small.png
deleted file mode 100644
index 7bd1f981..00000000
--- a/examples/bluetooth/heartlistener/assets/blue_heart_small.png
+++ /dev/null
Binary files differ
diff --git a/examples/bluetooth/heartlistener/assets/busy_dark.png b/examples/bluetooth/heartlistener/assets/busy_dark.png
deleted file mode 100644
index 3a105953..00000000
--- a/examples/bluetooth/heartlistener/assets/busy_dark.png
+++ /dev/null
Binary files differ
diff --git a/examples/bluetooth/heartlistener/assets/draw.js b/examples/bluetooth/heartlistener/assets/draw.js
deleted file mode 100644
index f884d472..00000000
--- a/examples/bluetooth/heartlistener/assets/draw.js
+++ /dev/null
@@ -1,74 +0,0 @@
-/***************************************************************************
-**
-** Copyright (C) 2013 BlackBerry Limited. All rights reserved.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtBluetooth 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 The Qt Company Ltd 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$
-**
-****************************************************************************/
-
-var component;
-var size = 0;
-var counter = 0;
-var difference = 0;
-
-function start() {
- size = heartRate.measurementsSize();
- difference = (plot.width-topbar.width)/size;
- console.log(size +" "+ plot.width);
- for (var i = 0; i< size; i++) {
- var value = heartRate.measurements(i);
-
- drawIt(value);
- counter++;
- }
-}
-
-function drawIt(value) {
- if (component == null)
- component = Qt.createComponent("Point.qml");
- if (component.status == Component.Ready) {
- var dynamicObject = component.createObject(plot);
- if (dynamicObject == null) {
- console.log("error creating block");
- console.log(component.errorString());
- return false;
- }
- dynamicObject.x = 10+(counter*difference);
- console.log(plot.height)
- dynamicObject.y = plot.height -value;
-
- }
-}
-
diff --git a/examples/bluetooth/heartlistener/assets/home.qml b/examples/bluetooth/heartlistener/assets/home.qml
deleted file mode 100644
index e77081ae..00000000
--- a/examples/bluetooth/heartlistener/assets/home.qml
+++ /dev/null
@@ -1,186 +0,0 @@
-/***************************************************************************
-**
-** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the examples of the QtBluetooth 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 The Qt Company Ltd 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 2.0
-
-Rectangle {
- id: screen
- color: "#F0EBED"
- property string message: heartRate.message
- onMessageChanged: {
- if (heartRate.message != "Scanning for devices..." && heartRate.message != "Low Energy device found. Scanning for more...") {
- background.visible = false;
- demoMode.visible = true;
- }
- else {
- demoMode.visible = false;
- background.visible = true;
- }
- }
-
- Rectangle {
- id:select
- width: parent.width
- anchors.top: parent.top
- height: 80
- color: "#F0EBED"
- border.color: "#3870BA"
- border.width: 2
- radius: 10
-
- Text {
- id: selectText
- color: "#3870BA"
- font.pixelSize: 34
- anchors.centerIn: parent
- text: "Select Device"
- }
- }
-
- Rectangle {
- id: spinner
- width: parent.width
- anchors.top: select.bottom
- anchors.bottom: demoMode.top
- visible: false
- color: "#F0EBED"
- z: 100
-
- Rectangle {
- id: inside
- anchors.centerIn: parent
- Image {
- id: background
-
- width:100
- height:100
- anchors.horizontalCenter: parent.horizontalCenter
-
- source: "busy_dark.png"
- fillMode: Image.PreserveAspectFit
- NumberAnimation on rotation { duration: 3000; from:0; to: 360; loops: Animation.Infinite}
- }
-
- Text {
- id: infotext
- anchors.horizontalCenter: parent.horizontalCenter
- anchors.top: background.bottom
- text: heartRate.message
- color: "#8F8F8F"
- }
- }
- }
-
- Component.onCompleted: {
- heartRate.deviceSearch();
- spinner.visible=true;
- }
-
- ListView {
- id: theListView
- width: parent.width
- onModelChanged: spinner.visible=false
- anchors.top: select.bottom
- anchors.bottom: demoMode.top
- model: heartRate.name
-
- delegate: Rectangle {
- id: box
- height:140
- width: parent.width
- color: "#3870BA"
- border.color: "#F0EBED"
- border.width: 5
- radius: 15
-
- MouseArea {
- anchors.fill: parent
- onPressed: { box.color= "#3265A7"; box.height=110}
- onClicked: {
- heartRate.connectToService(modelData.deviceAddress);
- pageLoader.source="monitor.qml";
- }
- }
-
- Text {
- id: device
- font.pixelSize: 30
- text: modelData.deviceName
- anchors.top: parent.top
- anchors.topMargin: 5
- anchors.horizontalCenter: parent.horizontalCenter
- color: "#F0EBED"
- }
-
- Text {
- id: deviceAddress
- font.pixelSize: 30
- text: modelData.deviceAddress
- anchors.bottom: parent.bottom
- anchors.bottomMargin: 5
- anchors.horizontalCenter: parent.horizontalCenter
- color: "#F0EBED"
- }
- }
- }
-
- Button {
- id:demoMode
- buttonWidth: parent.width
- buttonHeight: 0.1*parent.height
- anchors.horizontalCenter: parent.horizontalCenter
- anchors.bottom: scanAgain.top
- text: "Run Demo"
- onButtonClick: {
- heartRate.startDemo();
- pageLoader.source="monitor.qml";
- }
- }
-
- Button {
- id:scanAgain
- buttonWidth: parent.width
- buttonHeight: 0.1*parent.height
- anchors.horizontalCenter: parent.horizontalCenter
- anchors.bottom: parent.bottom
- text: "Menu"
- onButtonClick: pageLoader.source="main.qml"
- }
-}
diff --git a/examples/bluetooth/heartlistener/assets/monitor.qml b/examples/bluetooth/heartlistener/assets/monitor.qml
deleted file mode 100644
index 1d74ad84..00000000
--- a/examples/bluetooth/heartlistener/assets/monitor.qml
+++ /dev/null
@@ -1,154 +0,0 @@
-/***************************************************************************
-**
-** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the examples of the QtBluetooth 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 The Qt Company Ltd 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 2.0
-import QtQuick.Particles 2.0
-
-Rectangle {
- id: screenMonitor
- color: "#F0EBED"
-
- Button {
- id:menu
- buttonWidth: parent.width
- buttonHeight: 0.1 * parent.height
- anchors.horizontalCenter: parent.horizontalCenter
- anchors.top: parent.top
- text: "Menu"
- onButtonClick: {
- heartRate.disconnectService();
- pageLoader.source="home.qml";
- }
- }
-
- Text {
- id: hrValue
- font.pointSize: 24; font.bold: true
- anchors.top:menu.bottom
- anchors.horizontalCenter: parent.horizontalCenter
- anchors.topMargin: 25
-
- color: "#3870BA"
- text: heartRate.hr
- onTextChanged: {
- if (heartRate.hr > 0 && updatei != null && heartRate.numDevices() > 0) {
- updatei.destroy()
- }
- }
- }
-
- Rectangle {
- id: updatei
- width: parent.width
- height: 80
- anchors.bottom: stop.top
-
- color: "#F0EBED"
- border.color: "#3870BA"
- border.width: 2
-
- Text {
- id: logi
- text: heartRate.message
- anchors.centerIn: updatei
- color: "#3870BA"
- }
- }
-
- Image {
- id: background
- width: 300
- height: width
- anchors.centerIn: parent
- source: "blue_heart.png"
- fillMode: Image.PreserveAspectFit
- NumberAnimation on width {
- running: heartRate.hr > 0;
- duration: heartRate.hr/60*250;
- from:300; to: 350;
- loops: Animation.Infinite;
- }
-
- ParticleSystem {
- id: systwo
- anchors.fill: parent
-
- ImageParticle {
- system: systwo
- id: cptwo
- source: "star.png"
- colorVariation: 0.4
- color: "#000000FF"
- }
-
- Emitter {
- //burst on click
- id: burstytwo
- system: systwo
- enabled: true
- x: 160
- y: 150
- emitRate: heartRate.hr*100
- maximumEmitted: 4000
- acceleration: AngleDirection {angleVariation: 360; magnitude: 360; }
- size: 4
- endSize: 8
- sizeVariation: 4
- }
-
-
- }
-
- }
-
- Button {
- id:stop
- buttonWidth: parent.width
- buttonHeight: 0.1*parent.height
- anchors.horizontalCenter: parent.horizontalCenter
- anchors.bottom: parent.bottom
- text: "Stop Monitoring"
- onButtonClick: {
- burstytwo.enabled = false;
- heartRate.disconnectService();
- pageLoader.source = "results.qml";
- }
- }
-}
diff --git a/examples/bluetooth/heartlistener/assets/results.qml b/examples/bluetooth/heartlistener/assets/results.qml
deleted file mode 100644
index 301762c3..00000000
--- a/examples/bluetooth/heartlistener/assets/results.qml
+++ /dev/null
@@ -1,291 +0,0 @@
-/***************************************************************************
-**
-** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the examples of the QtBluetooth 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 The Qt Company Ltd 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 2.0
-import "draw.js" as DrawGraph
-
-Rectangle {
- id: results
- color: "#F0EBED"
-
- Component.onCompleted: heartRate.obtainResults()
-
- function getTime() {
- var t = heartRate.time;
- var min = Math.floor(t/60);
- var sec = t%60;
- var r = min + " min " + sec + " sec ";
- return r;
- }
-
- function drawGraph() {
- var b = plot.height/200;
- var ctx = canvas1.getContext('2d');
- ctx.beginPath()
- ctx.moveTo(10, plot.height- (b*60))
- var size = heartRate.measurementsSize();
- var difference = (plot.width-topbar.width)/size;
-
- for (var i = 0; i< size; i++) {
- var value = heartRate.measurements(i);
- if (i == 0) {
- ctx.moveTo(10+2, (plot.height- (value*b) + 2));
- ctx.rect((10 + i*difference), (plot.height- (value*b)), 4, 4);
-
- }
- else {
- ctx.lineTo((10+2 + i*difference), (plot.height- (value*b) + 2));
- ctx.rect((10 + i*difference), (plot.height- (value*b)), 4, 4);
- }
-
- }
- ctx.fillStyle = "#3870BA"
- ctx.fill()
- ctx.strokeStyle = "#3870BA"
- ctx.stroke()
- ctx.closePath()
- }
-
- Rectangle {
- id: res
- width: parent.width
- anchors.top: parent.top
- height: 80
- color: "#F0EBED"
- border.color: "#3870BA"
- border.width: 2
- radius: 10
- Text {
- id: restText
- color: "#3870BA"
- font.pixelSize: 34
- anchors.centerIn: parent
- text: "Results"
- }
- }
-
- Text {
- id: topbar
- text: "200"
- anchors.left: parent.left
- anchors.top: res.bottom
- anchors.rightMargin: 4
- color: "#3870BA"
- z: 50
- }
-
- Rectangle {
- id: level
- anchors.left: topbar.right
-
- anchors.top: res.bottom
- height: ((results.height -(res.height + menuLast.height + start.height ))/2)
- width: 3
- color: "#3870BA"
- }
-
- Text {
- id: middlebar
- anchors.verticalCenter: level.verticalCenter
- anchors.left: parent.left
- text: "100"
- color: "#3870BA"
- z: 50
- }
-
- Rectangle{
- id: downlevel
- anchors.bottom: cover.top
- width: parent.width
- anchors.left: level.right
- height: 3
- color: "#3870BA"
- z: 50
- }
-
- Rectangle {
- id: plot
- anchors.left: level.right
- anchors.leftMargin: 15
- width: results.width
- height: ((parent.height-(res.height+menuLast.height+start.height))/2)
-
- anchors.top: res.bottom
- color: "#F0EBED"
- Canvas {
- id: canvas1
- anchors.fill: parent
- z: 150
- onPaint: drawGraph()
- }
- }
-
- Rectangle {
- id: cover
- anchors.top: plot.bottom
- anchors.bottom: menuLast.top
- width: parent.width
- height: ((parent.height-(res.height+menuLast.height+start.height))/2)
- color: "#F0EBED"
- radius: 10
- border.color: "#3870BA"
- border.width: 2
-
- Flickable {
- id: scroll
- anchors.fill: parent
- anchors.margins: 5
- clip: true
- contentWidth: parent.width
- contentHeight: stresult.height
-
- Rectangle {
- id: stresult
- width: parent.width
- height: (results.height - (res.height + menuLast.height + start.height - 100))
- color: "#F0EBED"
- radius: 10
-
- Text {
- id: averageHR
- font.pixelSize: 30;
- anchors.horizontalCenter: parent.horizontalCenter
- anchors.top: parent.top
-
- color: "#3870BA"
- text: "Average Heart Rate"
- }
-
- Text {
- id: averageHRt
- font.pixelSize: 40; font.bold: true
- anchors.top: averageHR.bottom
- anchors.horizontalCenter: parent.horizontalCenter
- anchors.topMargin: 10
- color: "#3870BA"
- text: heartRate.average
- }
-
- Text {
- id: time
- font.pixelSize: 30;
- anchors.top: averageHRt.bottom
- anchors.horizontalCenter: parent.horizontalCenter
- anchors.topMargin: 10
- color: "#3870BA"
- text: "Seconds measured:"
- }
-
- Text {
- id: timet
- font.pixelSize: 40; font.bold: true
- anchors.top: time.bottom
- anchors.horizontalCenter: parent.horizontalCenter
- anchors.topMargin: 10
- color: "#3870BA"
- text: getTime()
- }
- Text {
- id: maxi
- font.pixelSize: 30;
- anchors.top: timet.bottom
- anchors.horizontalCenter: parent.horizontalCenter
- anchors.topMargin: 20
- color: "#3870BA"
- text: " Max || Min "
- }
-
- Text {
- id: mini
- font.pixelSize: 40; font.bold: true
- anchors.top:maxi.bottom
- anchors.horizontalCenter: parent.horizontalCenter
- anchors.topMargin: 10
- color: "#3870BA"
- text: " " + heartRate.maxHR + " || " + heartRate.minHR
- }
-
- Text {
- id: calories
- font.pixelSize: 30;
- anchors.top: mini.bottom
- anchors.horizontalCenter: parent.horizontalCenter
- anchors.topMargin: 10
- color: "#3870BA"
- text: " Calories "
- }
-
- Text {
- id: caloriestext
- font.pixelSize: 40; font.bold: true
- anchors.top:calories.bottom
- anchors.horizontalCenter: parent.horizontalCenter
- anchors.topMargin: 10
- color: "#3870BA"
- text: heartRate.calories.toFixed(3)
- }
- }
- }
- }
-
- Button {
- id:menuLast
- buttonWidth: parent.width
- buttonHeight: 0.1*parent.height
- anchors.horizontalCenter: parent.horizontalCenter
- anchors.bottom: start.top
- text: "Menu"
- onButtonClick: { pageLoader.source="main.qml"}
- }
-
- Button {
- id:start
- buttonWidth: parent.width
- buttonHeight: 0.1*parent.height
- anchors.horizontalCenter: parent.horizontalCenter
- anchors.bottom: parent.bottom
- text: "Start Monitoring"
- onButtonClick: {
- heartRate.connectToService(heartRate.deviceAddress());
- pageLoader.source="monitor.qml";
- }
- }
-}
diff --git a/examples/bluetooth/heartlistener/assets/star.png b/examples/bluetooth/heartlistener/assets/star.png
deleted file mode 100644
index defbde53..00000000
--- a/examples/bluetooth/heartlistener/assets/star.png
+++ /dev/null
Binary files differ
diff --git a/examples/bluetooth/heartlistener/doc/images/heartratefound.png b/examples/bluetooth/heartlistener/doc/images/heartratefound.png
deleted file mode 100644
index 89517aa4..00000000
--- a/examples/bluetooth/heartlistener/doc/images/heartratefound.png
+++ /dev/null
Binary files differ
diff --git a/examples/bluetooth/heartlistener/doc/images/heartratemonitor.png b/examples/bluetooth/heartlistener/doc/images/heartratemonitor.png
deleted file mode 100644
index ed51ba86..00000000
--- a/examples/bluetooth/heartlistener/doc/images/heartratemonitor.png
+++ /dev/null
Binary files differ
diff --git a/examples/bluetooth/heartlistener/doc/images/heartrateresults.png b/examples/bluetooth/heartlistener/doc/images/heartrateresults.png
deleted file mode 100644
index 8180d1a4..00000000
--- a/examples/bluetooth/heartlistener/doc/images/heartrateresults.png
+++ /dev/null
Binary files differ
diff --git a/examples/bluetooth/heartlistener/heartlistener.pro b/examples/bluetooth/heartlistener/heartlistener.pro
deleted file mode 100644
index 7856b64e..00000000
--- a/examples/bluetooth/heartlistener/heartlistener.pro
+++ /dev/null
@@ -1,20 +0,0 @@
-TEMPLATE = app
-TARGET = heartlistener
-
-QT += quick bluetooth
-
-# Input
-HEADERS += deviceinfo.h \
- heartrate.h
-SOURCES += deviceinfo.cpp \
- heartrate.cpp \
- main.cpp
-
-OTHER_FILES += assets/*.qml \
- assets/*.js
-
-RESOURCES += \
- resources.qrc
-
-target.path = $$[QT_INSTALL_EXAMPLES]/bluetooth/heartlistener
-INSTALLS += target
diff --git a/examples/bluetooth/heartlistener/heartrate.cpp b/examples/bluetooth/heartlistener/heartrate.cpp
deleted file mode 100644
index c206b69e..00000000
--- a/examples/bluetooth/heartlistener/heartrate.cpp
+++ /dev/null
@@ -1,445 +0,0 @@
-/***************************************************************************
-**
-** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the examples of the QtBluetooth 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 The Qt Company Ltd 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$
-**
-****************************************************************************/
-
-#include "heartrate.h"
-
-#include <QtEndian>
-
-HeartRate::HeartRate():
- m_currentDevice(QBluetoothDeviceInfo()), foundHeartRateService(false),
- m_max(0), m_min(0), calories(0), m_control(0), timer(0),
- m_service(0)
-{
- //! [devicediscovery-1]
- m_deviceDiscoveryAgent = new QBluetoothDeviceDiscoveryAgent(this);
- m_deviceDiscoveryAgent->setLowEnergyDiscoveryTimeout(5000);
-
- connect(m_deviceDiscoveryAgent, SIGNAL(deviceDiscovered(const QBluetoothDeviceInfo&)),
- this, SLOT(addDevice(const QBluetoothDeviceInfo&)));
- connect(m_deviceDiscoveryAgent, SIGNAL(error(QBluetoothDeviceDiscoveryAgent::Error)),
- this, SLOT(deviceScanError(QBluetoothDeviceDiscoveryAgent::Error)));
- connect(m_deviceDiscoveryAgent, SIGNAL(finished()), this, SLOT(scanFinished()));
- //! [devicediscovery-1]
-
- // initialize random seed for demo mode
- qsrand(QTime::currentTime().msec());
-}
-
-HeartRate::~HeartRate()
-{
- qDeleteAll(m_devices);
- m_devices.clear();
-}
-
-void HeartRate::deviceSearch()
-{
- qDeleteAll(m_devices);
- m_devices.clear();
- //! [devicediscovery-2]
- m_deviceDiscoveryAgent->start(QBluetoothDeviceDiscoveryAgent::LowEnergyMethod);
- //! [devicediscovery-2]
- setMessage("Scanning for devices...");
-}
-
-//! [devicediscovery-3]
-void HeartRate::addDevice(const QBluetoothDeviceInfo &device)
-{
- if (device.coreConfigurations() & QBluetoothDeviceInfo::LowEnergyCoreConfiguration) {
- qWarning() << "Discovered LE Device name: " << device.name() << " Address: "
- << device.address().toString();
-//! [devicediscovery-3]
- DeviceInfo *dev = new DeviceInfo(device);
- m_devices.append(dev);
- setMessage("Low Energy device found. Scanning for more...");
-//! [devicediscovery-4]
- }
- //...
-}
-//! [devicediscovery-4]
-
-void HeartRate::scanFinished()
-{
- if (m_devices.size() == 0)
- setMessage("No Low Energy devices found");
- Q_EMIT nameChanged();
-}
-
-void HeartRate::deviceScanError(QBluetoothDeviceDiscoveryAgent::Error error)
-{
- if (error == QBluetoothDeviceDiscoveryAgent::PoweredOffError)
- setMessage("The Bluetooth adaptor is powered off, power it on before doing discovery.");
- else if (error == QBluetoothDeviceDiscoveryAgent::InputOutputError)
- setMessage("Writing or reading from the device resulted in an error.");
- else
- setMessage("An unknown error has occurred.");
-}
-
-
-void HeartRate::setMessage(QString message)
-{
- m_info = message;
- Q_EMIT messageChanged();
-}
-
-QString HeartRate::message() const
-{
- return m_info;
-}
-
-QVariant HeartRate::name()
-{
- return QVariant::fromValue(m_devices);
-}
-
-void HeartRate::connectToService(const QString &address)
-{
- m_measurements.clear();
-
- bool deviceFound = false;
- for (int i = 0; i < m_devices.size(); i++) {
- if (((DeviceInfo*)m_devices.at(i))->getAddress() == address ) {
- m_currentDevice.setDevice(((DeviceInfo*)m_devices.at(i))->getDevice());
- setMessage("Connecting to device...");
- deviceFound = true;
- break;
- }
- }
- // we are running demo mode
- if (!deviceFound) {
- startDemo();
- return;
- }
-
- if (m_control) {
- m_control->disconnectFromDevice();
- delete m_control;
- m_control = 0;
-
- }
- //! [Connect signals]
- m_control = new QLowEnergyController(m_currentDevice.getDevice(), this);
- connect(m_control, SIGNAL(serviceDiscovered(QBluetoothUuid)),
- this, SLOT(serviceDiscovered(QBluetoothUuid)));
- connect(m_control, SIGNAL(discoveryFinished()),
- this, SLOT(serviceScanDone()));
- connect(m_control, SIGNAL(error(QLowEnergyController::Error)),
- this, SLOT(controllerError(QLowEnergyController::Error)));
- connect(m_control, SIGNAL(connected()),
- this, SLOT(deviceConnected()));
- connect(m_control, SIGNAL(disconnected()),
- this, SLOT(deviceDisconnected()));
-
- m_control->connectToDevice();
- //! [Connect signals]
-}
-
-//! [Connecting to service]
-
-void HeartRate::deviceConnected()
-{
- m_control->discoverServices();
-}
-
-void HeartRate::deviceDisconnected()
-{
- setMessage("Heart Rate service disconnected");
- qWarning() << "Remote device disconnected";
-}
-
-//! [Connecting to service]
-
-//! [Filter HeartRate service 1]
-void HeartRate::serviceDiscovered(const QBluetoothUuid &gatt)
-{
- if (gatt == QBluetoothUuid(QBluetoothUuid::HeartRate)) {
- setMessage("Heart Rate service discovered. Waiting for service scan to be done...");
- foundHeartRateService = true;
- }
-}
-//! [Filter HeartRate service 1]
-
-void HeartRate::serviceScanDone()
-{
- delete m_service;
- m_service = 0;
-
- //! [Filter HeartRate service 2]
- if (foundHeartRateService) {
- setMessage("Connecting to service...");
- m_service = m_control->createServiceObject(
- QBluetoothUuid(QBluetoothUuid::HeartRate), this);
- }
-
- if (!m_service) {
- setMessage("Heart Rate Service not found.");
- return;
- }
-
- connect(m_service, SIGNAL(stateChanged(QLowEnergyService::ServiceState)),
- this, SLOT(serviceStateChanged(QLowEnergyService::ServiceState)));
- connect(m_service, SIGNAL(characteristicChanged(QLowEnergyCharacteristic,QByteArray)),
- this, SLOT(updateHeartRateValue(QLowEnergyCharacteristic,QByteArray)));
- connect(m_service, SIGNAL(descriptorWritten(QLowEnergyDescriptor,QByteArray)),
- this, SLOT(confirmedDescriptorWrite(QLowEnergyDescriptor,QByteArray)));
-
- m_service->discoverDetails();
- //! [Filter HeartRate service 2]
-}
-
-void HeartRate::disconnectService()
-{
- foundHeartRateService = false;
- m_stop = QDateTime::currentDateTime();
-
- if (m_devices.isEmpty()) {
- if (timer)
- timer->stop();
- return;
- }
-
- //disable notifications before disconnecting
- if (m_notificationDesc.isValid() && m_service
- && m_notificationDesc.value() == QByteArray::fromHex("0100"))
- {
- m_service->writeDescriptor(m_notificationDesc, QByteArray::fromHex("0000"));
- } else {
- m_control->disconnectFromDevice();
- delete m_service;
- m_service = 0;
- }
-}
-
-//! [Error handling]
-void HeartRate::controllerError(QLowEnergyController::Error error)
-{
- setMessage("Cannot connect to remote device.");
- qWarning() << "Controller Error:" << error;
-}
-//! [Error handling]
-
-
-//! [Find HRM characteristic]
-void HeartRate::serviceStateChanged(QLowEnergyService::ServiceState s)
-{
- switch (s) {
- case QLowEnergyService::ServiceDiscovered:
- {
- const QLowEnergyCharacteristic hrChar = m_service->characteristic(
- QBluetoothUuid(QBluetoothUuid::HeartRateMeasurement));
- if (!hrChar.isValid()) {
- setMessage("HR Data not found.");
- break;
- }
-
- m_notificationDesc = hrChar.descriptor(
- QBluetoothUuid::ClientCharacteristicConfiguration);
- if (m_notificationDesc.isValid()) {
- m_service->writeDescriptor(m_notificationDesc, QByteArray::fromHex("0100"));
- setMessage("Measuring");
- m_start = QDateTime::currentDateTime();
- }
-
- break;
- }
- default:
- //nothing for now
- break;
- }
-}
-//! [Find HRM characteristic]
-
-void HeartRate::serviceError(QLowEnergyService::ServiceError e)
-{
- switch (e) {
- case QLowEnergyService::DescriptorWriteError:
- setMessage("Cannot obtain HR notifications");
- break;
- default:
- qWarning() << "HR service error:" << e;
- }
-}
-
-//! [Reading value 1]
-void HeartRate::updateHeartRateValue(const QLowEnergyCharacteristic &c,
- const QByteArray &value)
-{
- // ignore any other characteristic change -> shouldn't really happen though
- if (c.uuid() != QBluetoothUuid(QBluetoothUuid::HeartRateMeasurement))
- return;
-
-
- const quint8 *data = reinterpret_cast<const quint8 *>(value.constData());
- quint8 flags = data[0];
-
- //Heart Rate
- if (flags & 0x1) { // HR 16 bit? otherwise 8 bit
- const quint16 heartRate = qFromLittleEndian<quint16>(data[1]);
- //qDebug() << "16 bit HR value:" << heartRate;
- m_measurements.append(heartRate);
- } else {
- const quint8 *heartRate = &data[1];
- m_measurements.append(*heartRate);
- //qDebug() << "8 bit HR value:" << *heartRate;
- }
-
- //Energy Expended
- if (flags & 0x8) {
- int index = (flags & 0x1) ? 5 : 3;
- const quint16 energy = qFromLittleEndian<quint16>(data[index]);
- qDebug() << "Used Energy:" << energy;
- }
- //! [Reading value 1]
-
- Q_EMIT hrChanged();
-//! [Reading value 2]
-}
-//! [Reading value 2]
-
-void HeartRate::confirmedDescriptorWrite(const QLowEnergyDescriptor &d,
- const QByteArray &value)
-{
- if (d.isValid() && d == m_notificationDesc && value == QByteArray::fromHex("0000")) {
- //disabled notifications -> assume disconnect intent
- m_control->disconnectFromDevice();
- delete m_service;
- m_service = 0;
- }
-}
-
-int HeartRate::hR() const
-{
- if (m_measurements.isEmpty())
- return 0;
- return m_measurements.last();
-}
-
-void HeartRate::obtainResults()
-{
- Q_EMIT timeChanged();
- Q_EMIT averageChanged();
- Q_EMIT caloriesChanged();
-}
-
-int HeartRate::time()
-{
- return m_start.secsTo(m_stop);
-}
-
-int HeartRate::maxHR() const
-{
- return m_max;
-}
-
-int HeartRate::minHR() const
-{
- return m_min;
-}
-
-float HeartRate::average()
-{
- if (m_measurements.size() == 0) {
- return 0;
- } else {
- m_max = 0;
- m_min = 1000;
- int sum = 0;
- for (int i = 0; i < m_measurements.size(); i++) {
- sum += (int) m_measurements.value(i);
- if (((int)m_measurements.value(i)) > m_max)
- m_max = (int)m_measurements.value(i);
- if (((int)m_measurements.value(i)) < m_min)
- m_min = (int)m_measurements.value(i);
- }
- return sum/m_measurements.size();
- }
-}
-
-int HeartRate::measurements(int index) const
-{
- if (index > m_measurements.size())
- return 0;
- else
- return (int)m_measurements.value(index);
-}
-
-int HeartRate::measurementsSize() const
-{
- return m_measurements.size();
-}
-
-QString HeartRate::deviceAddress() const
-{
- return m_currentDevice.getAddress();
-}
-
-float HeartRate::caloriesCalculation()
-{
- calories = ((-55.0969 + (0.6309 * average()) + (0.1988 * 94) + (0.2017 * 24)) / 4.184) * 60 * time()/3600 ;
- return calories;
-}
-
-int HeartRate::numDevices() const
-{
- return m_devices.size();
-}
-
-void HeartRate::startDemo()
-{
- m_start = QDateTime::currentDateTime();
- if (!timer) {
- timer = new QTimer(this);
- connect(timer, SIGNAL(timeout()), this, SLOT(receiveDemo()));
- }
- timer->start(1000);
- setMessage("This is Demo mode");
-}
-
-void HeartRate::receiveDemo()
-{
- m_measurements.append(randomPulse());
- Q_EMIT hrChanged();
-}
-
-int HeartRate::randomPulse() const
-{
- // random number between 50 and 70
- return qrand() % (70 - 50) + 50;
-}
diff --git a/examples/bluetooth/heartlistener/resources.qrc b/examples/bluetooth/heartlistener/resources.qrc
deleted file mode 100644
index ac6f9c83..00000000
--- a/examples/bluetooth/heartlistener/resources.qrc
+++ /dev/null
@@ -1,16 +0,0 @@
-<RCC>
- <qresource prefix="/">
- <file>assets/blue_heart.png</file>
- <file>assets/busy_dark.png</file>
- <file>assets/Button.qml</file>
- <file>assets/dialog.qml</file>
- <file>assets/draw.js</file>
- <file>assets/home.qml</file>
- <file>assets/main.qml</file>
- <file>assets/monitor.qml</file>
- <file>assets/Point.qml</file>
- <file>assets/results.qml</file>
- <file>assets/star.png</file>
- <file>assets/blue_heart_small.png</file>
- </qresource>
-</RCC>
diff --git a/examples/bluetooth/heartrate-game/README.md b/examples/bluetooth/heartrate-game/README.md
new file mode 100644
index 00000000..fd7c6fd6
--- /dev/null
+++ b/examples/bluetooth/heartrate-game/README.md
@@ -0,0 +1,7 @@
+# HeartRateGame #
+
+Demonstrates how to check a Bluetooth-connection, discover LE-devices, connect
+to devices, discover services and finally connect to a heartrate-service.
+The purpose of the game is increase the heartrate so much as possible in 60s.
+Relax before starting the game. Don't be too nervous, it increases the heartrate!
+
diff --git a/examples/bluetooth/heartrate-game/bluetoothbaseclass.cpp b/examples/bluetooth/heartrate-game/bluetoothbaseclass.cpp
new file mode 100644
index 00000000..0d7f0bbe
--- /dev/null
+++ b/examples/bluetooth/heartrate-game/bluetoothbaseclass.cpp
@@ -0,0 +1,77 @@
+/***************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the QtBluetooth 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 The Qt Company Ltd 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$
+**
+****************************************************************************/
+
+#include "bluetoothbaseclass.h"
+
+BluetoothBaseClass::BluetoothBaseClass(QObject *parent) : QObject(parent)
+{
+}
+
+QString BluetoothBaseClass::error() const
+{
+ return m_error;
+}
+
+QString BluetoothBaseClass::info() const
+{
+ return m_info;
+}
+
+void BluetoothBaseClass::setError(const QString &error)
+{
+ if (m_error != error) {
+ m_error = error;
+ emit errorChanged();
+ }
+}
+
+void BluetoothBaseClass::setInfo(const QString &info)
+{
+ if (m_info != info) {
+ m_info = info;
+ emit infoChanged();
+ }
+}
+
+void BluetoothBaseClass::clearMessages()
+{
+ setInfo("");
+ setError("");
+}
diff --git a/examples/bluetooth/heartrate-game/bluetoothbaseclass.h b/examples/bluetooth/heartrate-game/bluetoothbaseclass.h
new file mode 100644
index 00000000..ccdb60e3
--- /dev/null
+++ b/examples/bluetooth/heartrate-game/bluetoothbaseclass.h
@@ -0,0 +1,72 @@
+/***************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the QtBluetooth 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 The Qt Company Ltd 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$
+**
+****************************************************************************/
+
+#ifndef BLUETOOTHBASECLASS_H
+#define BLUETOOTHBASECLASS_H
+
+#include <QObject>
+
+class BluetoothBaseClass : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QString error READ error WRITE setError NOTIFY errorChanged)
+ Q_PROPERTY(QString info READ info WRITE setInfo NOTIFY infoChanged)
+
+public:
+ explicit BluetoothBaseClass(QObject *parent = 0);
+
+ QString error() const;
+ void setError(const QString& error);
+
+ QString info() const;
+ void setInfo(const QString& info);
+
+ void clearMessages();
+
+signals:
+ void errorChanged();
+ void infoChanged();
+
+private:
+ QString m_error;
+ QString m_info;
+};
+
+#endif // BLUETOOTHBASECLASS_H
diff --git a/examples/bluetooth/heartrate-game/connectionhandler.cpp b/examples/bluetooth/heartrate-game/connectionhandler.cpp
new file mode 100644
index 00000000..40572b71
--- /dev/null
+++ b/examples/bluetooth/heartrate-game/connectionhandler.cpp
@@ -0,0 +1,82 @@
+/***************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the QtBluetooth 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 The Qt Company Ltd 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$
+**
+****************************************************************************/
+
+#include "heartrate-global.h"
+#include "connectionhandler.h"
+#include <QtBluetooth/qtbluetooth-config.h>
+
+ConnectionHandler::ConnectionHandler(QObject *parent) : QObject(parent)
+{
+ connect(&m_localDevice, &QBluetoothLocalDevice::hostModeStateChanged,
+ this, &ConnectionHandler::hostModeChanged);
+}
+
+bool ConnectionHandler::alive() const
+{
+#ifdef SIMULATOR
+ return true;
+#else
+ return m_localDevice.isValid() && m_localDevice.hostMode() != QBluetoothLocalDevice::HostPoweredOff;
+#endif
+}
+
+bool ConnectionHandler::requiresAddressType() const
+{
+#if QT_CONFIG(bluez)
+ return true;
+#else
+ return false;
+#endif
+}
+
+QString ConnectionHandler::name() const
+{
+ return m_localDevice.name();
+}
+
+QString ConnectionHandler::address() const
+{
+ return m_localDevice.address().toString();
+}
+
+void ConnectionHandler::hostModeChanged(QBluetoothLocalDevice::HostMode /*mode*/)
+{
+ emit deviceChanged();
+}
diff --git a/examples/bluetooth/heartrate-game/connectionhandler.h b/examples/bluetooth/heartrate-game/connectionhandler.h
new file mode 100644
index 00000000..23168b28
--- /dev/null
+++ b/examples/bluetooth/heartrate-game/connectionhandler.h
@@ -0,0 +1,73 @@
+/***************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the QtBluetooth 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 The Qt Company Ltd 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$
+**
+****************************************************************************/
+
+#ifndef CONNECTIONHANDLER_H
+#define CONNECTIONHANDLER_H
+
+#include <QObject>
+#include <QBluetoothLocalDevice>
+
+class ConnectionHandler : public QObject
+{
+ Q_PROPERTY(bool alive READ alive NOTIFY deviceChanged)
+ Q_PROPERTY(QString name READ name NOTIFY deviceChanged)
+ Q_PROPERTY(QString address READ address NOTIFY deviceChanged)
+ Q_PROPERTY(bool requiresAddressType READ requiresAddressType CONSTANT)
+
+ Q_OBJECT
+public:
+ explicit ConnectionHandler(QObject *parent = 0);
+
+ bool alive() const;
+ bool requiresAddressType() const;
+ QString name() const;
+ QString address() const;
+
+signals:
+ void deviceChanged();
+
+private slots:
+ void hostModeChanged(QBluetoothLocalDevice::HostMode mode);
+
+private:
+ QBluetoothLocalDevice m_localDevice;
+};
+
+#endif // CONNECTIONHANDLER_H
diff --git a/examples/bluetooth/heartrate-game/devicefinder.cpp b/examples/bluetooth/heartrate-game/devicefinder.cpp
new file mode 100644
index 00000000..aed47b6c
--- /dev/null
+++ b/examples/bluetooth/heartrate-game/devicefinder.cpp
@@ -0,0 +1,167 @@
+/***************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the QtBluetooth 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 The Qt Company Ltd 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$
+**
+****************************************************************************/
+
+#include "devicefinder.h"
+#include "devicehandler.h"
+#include "deviceinfo.h"
+
+DeviceFinder::DeviceFinder(DeviceHandler *handler, QObject *parent):
+ BluetoothBaseClass(parent),
+ m_deviceHandler(handler)
+{
+ //! [devicediscovery-1]
+ m_deviceDiscoveryAgent = new QBluetoothDeviceDiscoveryAgent(this);
+ m_deviceDiscoveryAgent->setLowEnergyDiscoveryTimeout(5000);
+
+ connect(m_deviceDiscoveryAgent, &QBluetoothDeviceDiscoveryAgent::deviceDiscovered, this, &DeviceFinder::addDevice);
+ connect(m_deviceDiscoveryAgent, static_cast<void (QBluetoothDeviceDiscoveryAgent::*)(QBluetoothDeviceDiscoveryAgent::Error)>(&QBluetoothDeviceDiscoveryAgent::error),
+ this, &DeviceFinder::scanError);
+
+ connect(m_deviceDiscoveryAgent, &QBluetoothDeviceDiscoveryAgent::finished, this, &DeviceFinder::scanFinished);
+ connect(m_deviceDiscoveryAgent, &QBluetoothDeviceDiscoveryAgent::canceled, this, &DeviceFinder::scanFinished);
+ //! [devicediscovery-1]
+
+
+#ifdef SIMULATOR
+ m_demoTimer.setSingleShot(true);
+ m_demoTimer.setInterval(2000);
+ connect(&m_demoTimer, &QTimer::timeout, this, &DeviceFinder::scanFinished);
+#endif
+}
+
+DeviceFinder::~DeviceFinder()
+{
+ qDeleteAll(m_devices);
+ m_devices.clear();
+}
+
+void DeviceFinder::startSearch()
+{
+ clearMessages();
+ m_deviceHandler->setDevice(0);
+ qDeleteAll(m_devices);
+ m_devices.clear();
+
+ emit devicesChanged();
+
+#ifdef SIMULATOR
+ m_demoTimer.start();
+#else
+ //! [devicediscovery-2]
+ m_deviceDiscoveryAgent->start(QBluetoothDeviceDiscoveryAgent::LowEnergyMethod);
+ //! [devicediscovery-2]
+#endif
+ emit scanningChanged();
+ setInfo(tr("Scanning for devices..."));
+}
+
+//! [devicediscovery-3]
+void DeviceFinder::addDevice(const QBluetoothDeviceInfo &device)
+{
+ // If device is LowEnergy-device, add it to the list
+ if (device.coreConfigurations() & QBluetoothDeviceInfo::LowEnergyCoreConfiguration) {
+ m_devices.append(new DeviceInfo(device));
+ setInfo(tr("Low Energy device found. Scanning more..."));
+//! [devicediscovery-3]
+ emit devicesChanged();
+//! [devicediscovery-4]
+ }
+ //...
+}
+//! [devicediscovery-4]
+
+void DeviceFinder::scanError(QBluetoothDeviceDiscoveryAgent::Error error)
+{
+ if (error == QBluetoothDeviceDiscoveryAgent::PoweredOffError)
+ setError(tr("The Bluetooth adaptor is powered off."));
+ else if (error == QBluetoothDeviceDiscoveryAgent::InputOutputError)
+ setError(tr("Writing or reading from the device resulted in an error."));
+ else
+ setError(tr("An unknown error has occurred."));
+}
+
+void DeviceFinder::scanFinished()
+{
+#ifdef SIMULATOR
+ // Only for testing
+ for (int i = 0; i < 4; i++)
+ m_devices.append(new DeviceInfo(QBluetoothDeviceInfo()));
+#endif
+
+ if (m_devices.size() == 0)
+ setError(tr("No Low Energy devices found."));
+ else
+ setInfo(tr("Scanning done."));
+
+ emit scanningChanged();
+ emit devicesChanged();
+}
+
+void DeviceFinder::connectToService(const QString &address)
+{
+ m_deviceDiscoveryAgent->stop();
+
+ DeviceInfo *currentDevice = 0;
+ for (int i = 0; i < m_devices.size(); i++) {
+ if (((DeviceInfo*)m_devices.at(i))->getAddress() == address ) {
+ currentDevice = (DeviceInfo*)m_devices.at(i);
+ break;
+ }
+ }
+
+ if (currentDevice)
+ m_deviceHandler->setDevice(currentDevice);
+
+ clearMessages();
+}
+
+bool DeviceFinder::scanning() const
+{
+#ifdef SIMULATOR
+ return m_demoTimer.isActive();
+#else
+ return m_deviceDiscoveryAgent->isActive();
+#endif
+}
+
+QVariant DeviceFinder::devices()
+{
+ return QVariant::fromValue(m_devices);
+}
diff --git a/examples/bluetooth/heartrate-game/devicefinder.h b/examples/bluetooth/heartrate-game/devicefinder.h
new file mode 100644
index 00000000..c82c0fe5
--- /dev/null
+++ b/examples/bluetooth/heartrate-game/devicefinder.h
@@ -0,0 +1,92 @@
+/***************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the QtBluetooth 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 The Qt Company Ltd 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$
+**
+****************************************************************************/
+
+#ifndef DEVICEFINDER_H
+#define DEVICEFINDER_H
+
+#include "heartrate-global.h"
+#include "bluetoothbaseclass.h"
+
+#include <QTimer>
+#include <QBluetoothDeviceDiscoveryAgent>
+#include <QBluetoothDeviceInfo>
+#include <QVariant>
+
+class DeviceInfo;
+class DeviceHandler;
+
+class DeviceFinder: public BluetoothBaseClass
+{
+ Q_OBJECT
+
+ Q_PROPERTY(bool scanning READ scanning NOTIFY scanningChanged)
+ Q_PROPERTY(QVariant devices READ devices NOTIFY devicesChanged)
+
+public:
+ DeviceFinder(DeviceHandler *handler, QObject *parent = 0);
+ ~DeviceFinder();
+
+ bool scanning() const;
+ QVariant devices();
+
+public slots:
+ void startSearch();
+ void connectToService(const QString &address);
+
+private slots:
+ void addDevice(const QBluetoothDeviceInfo&);
+ void scanError(QBluetoothDeviceDiscoveryAgent::Error error);
+ void scanFinished();
+
+signals:
+ void scanningChanged();
+ void devicesChanged();
+
+private:
+ DeviceHandler *m_deviceHandler;
+ QBluetoothDeviceDiscoveryAgent *m_deviceDiscoveryAgent;
+ QList<QObject*> m_devices;
+
+#ifdef SIMULATOR
+ QTimer m_demoTimer;
+#endif
+};
+
+#endif // DEVICEFINDER_H
diff --git a/examples/bluetooth/heartrate-game/devicehandler.cpp b/examples/bluetooth/heartrate-game/devicehandler.cpp
new file mode 100644
index 00000000..dfc514b5
--- /dev/null
+++ b/examples/bluetooth/heartrate-game/devicehandler.cpp
@@ -0,0 +1,354 @@
+/***************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the QtBluetooth 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 The Qt Company Ltd 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$
+**
+****************************************************************************/
+
+#include "heartrate-global.h"
+#include "devicehandler.h"
+#include "deviceinfo.h"
+#include <QtEndian>
+
+DeviceHandler::DeviceHandler(QObject *parent) :
+ BluetoothBaseClass(parent),
+ m_control(0),
+ m_service(0),
+ m_currentDevice(0),
+ m_foundHeartRateService(false),
+ m_measuring(false),
+ m_currentValue(0),
+ m_min(0), m_max(0), m_sum(0), m_avg(0), m_calories(0)
+{
+#ifdef SIMULATOR
+ m_demoTimer.setSingleShot(false);
+ m_demoTimer.setInterval(2000);
+ connect(&m_demoTimer, &QTimer::timeout, this, &DeviceHandler::updateDemoHR);
+ m_demoTimer.start();
+ updateDemoHR();
+#endif
+}
+
+void DeviceHandler::setAddressType(AddressType type)
+{
+ switch (type) {
+ case DeviceHandler::AddressType::PublicAddress:
+ m_addressType = QLowEnergyController::PublicAddress;
+ break;
+ case DeviceHandler::AddressType::RandomAddress:
+ m_addressType = QLowEnergyController::RandomAddress;
+ break;
+ }
+}
+
+DeviceHandler::AddressType DeviceHandler::addressType() const
+{
+ if (m_addressType == QLowEnergyController::RandomAddress)
+ return DeviceHandler::AddressType::RandomAddress;
+
+ return DeviceHandler::AddressType::PublicAddress;
+}
+
+void DeviceHandler::setDevice(DeviceInfo *device)
+{
+ clearMessages();
+ m_currentDevice = device;
+
+#ifdef SIMULATOR
+ setInfo(tr("Demo device connected."));
+ return;
+#endif
+
+ // Disconnect and delete old connection
+ if (m_control) {
+ m_control->disconnectFromDevice();
+ delete m_control;
+ m_control = 0;
+ }
+
+ // Create new controller and connect it if device available
+ if (m_currentDevice) {
+
+ // Make connections
+ //! [Connect-Signals-1]
+ m_control = new QLowEnergyController(m_currentDevice->getDevice(), this);
+ //! [Connect-Signals-1]
+ m_control->setRemoteAddressType(m_addressType);
+ //! [Connect-Signals-2]
+ connect(m_control, &QLowEnergyController::serviceDiscovered,
+ this, &DeviceHandler::serviceDiscovered);
+ connect(m_control, &QLowEnergyController::discoveryFinished,
+ this, &DeviceHandler::serviceScanDone);
+
+ connect(m_control, static_cast<void (QLowEnergyController::*)(QLowEnergyController::Error)>(&QLowEnergyController::error),
+ this, [this](QLowEnergyController::Error error) {
+ Q_UNUSED(error);
+ setError("Cannot connect to remote device.");
+ });
+ connect(m_control, &QLowEnergyController::connected, this, [this]() {
+ setInfo("Controller connected. Search services...");
+ m_control->discoverServices();
+ });
+ connect(m_control, &QLowEnergyController::disconnected, this, [this]() {
+ setError("LowEnergy controller disconnected");
+ });
+
+ // Connect
+ m_control->connectToDevice();
+ //! [Connect-Signals-2]
+ }
+}
+
+void DeviceHandler::startMeasurement()
+{
+ if (alive()) {
+ m_start = QDateTime::currentDateTime();
+ m_min = 0;
+ m_max = 0;
+ m_avg = 0;
+ m_sum = 0;
+ m_calories = 0;
+ m_measuring = true;
+ m_measurements.clear();
+ emit measuringChanged();
+ }
+}
+
+void DeviceHandler::stopMeasurement()
+{
+ m_measuring = false;
+ emit measuringChanged();
+}
+
+//! [Filter HeartRate service 1]
+void DeviceHandler::serviceDiscovered(const QBluetoothUuid &gatt)
+{
+ if (gatt == QBluetoothUuid(QBluetoothUuid::HeartRate)) {
+ setInfo("Heart Rate service discovered. Waiting for service scan to be done...");
+ m_foundHeartRateService = true;
+ }
+}
+//! [Filter HeartRate service 1]
+
+void DeviceHandler::serviceScanDone()
+{
+ setInfo("Service scan done.");
+
+ // Delete old service if available
+ if (m_service) {
+ delete m_service;
+ m_service = 0;
+ }
+
+//! [Filter HeartRate service 2]
+ // If heartRateService found, create new service
+ if (m_foundHeartRateService)
+ m_service = m_control->createServiceObject(QBluetoothUuid(QBluetoothUuid::HeartRate), this);
+
+ if (m_service) {
+ connect(m_service, &QLowEnergyService::stateChanged, this, &DeviceHandler::serviceStateChanged);
+ connect(m_service, &QLowEnergyService::characteristicChanged, this, &DeviceHandler::updateHeartRateValue);
+ connect(m_service, &QLowEnergyService::descriptorWritten, this, &DeviceHandler::confirmedDescriptorWrite);
+ m_service->discoverDetails();
+ } else {
+ setError("Heart Rate Service not found.");
+ }
+//! [Filter HeartRate service 2]
+}
+
+// Service functions
+//! [Find HRM characteristic]
+void DeviceHandler::serviceStateChanged(QLowEnergyService::ServiceState s)
+{
+ switch (s) {
+ case QLowEnergyService::DiscoveringServices:
+ setInfo(tr("Discovering services..."));
+ break;
+ case QLowEnergyService::ServiceDiscovered:
+ {
+ setInfo(tr("Service discovered."));
+
+ const QLowEnergyCharacteristic hrChar = m_service->characteristic(QBluetoothUuid(QBluetoothUuid::HeartRateMeasurement));
+ if (!hrChar.isValid()) {
+ setError("HR Data not found.");
+ break;
+ }
+
+ m_notificationDesc = hrChar.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration);
+ if (m_notificationDesc.isValid())
+ m_service->writeDescriptor(m_notificationDesc, QByteArray::fromHex("0100"));
+
+ break;
+ }
+ default:
+ //nothing for now
+ break;
+ }
+
+ emit aliveChanged();
+}
+//! [Find HRM characteristic]
+
+//! [Reading value]
+void DeviceHandler::updateHeartRateValue(const QLowEnergyCharacteristic &c, const QByteArray &value)
+{
+ // ignore any other characteristic change -> shouldn't really happen though
+ if (c.uuid() != QBluetoothUuid(QBluetoothUuid::HeartRateMeasurement))
+ return;
+
+ const quint8 *data = reinterpret_cast<const quint8 *>(value.constData());
+ quint8 flags = data[0];
+
+ //Heart Rate
+ int hrvalue = 0;
+ if (flags & 0x1) // HR 16 bit? otherwise 8 bit
+ hrvalue = (int)qFromLittleEndian<quint16>(data[1]);
+ else
+ hrvalue = (int)data[1];
+
+ addMeasurement(hrvalue);
+}
+//! [Reading value]
+
+#ifdef SIMULATOR
+void DeviceHandler::updateDemoHR()
+{
+ int randomValue = 0;
+ if (m_currentValue < 30) { // Initial value
+ randomValue = 55 + qrand()%30;
+ } else if (!m_measuring) { // Value when relax
+ randomValue = qBound(55, m_currentValue - 2 + qrand()%5, 75);
+ } else { // Measuring
+ randomValue = m_currentValue + qrand()%10 - 2;
+ }
+
+ addMeasurement(randomValue);
+}
+#endif
+
+void DeviceHandler::confirmedDescriptorWrite(const QLowEnergyDescriptor &d, const QByteArray &value)
+{
+ if (d.isValid() && d == m_notificationDesc && value == QByteArray::fromHex("0000")) {
+ //disabled notifications -> assume disconnect intent
+ m_control->disconnectFromDevice();
+ delete m_service;
+ m_service = 0;
+ }
+}
+
+void DeviceHandler::disconnectService()
+{
+ m_foundHeartRateService = false;
+
+ //disable notifications
+ if (m_notificationDesc.isValid() && m_service
+ && m_notificationDesc.value() == QByteArray::fromHex("0100")) {
+ m_service->writeDescriptor(m_notificationDesc, QByteArray::fromHex("0000"));
+ } else {
+ if (m_control)
+ m_control->disconnectFromDevice();
+
+ delete m_service;
+ m_service = 0;
+ }
+}
+
+bool DeviceHandler::measuring() const
+{
+ return m_measuring;
+}
+
+bool DeviceHandler::alive() const
+{
+#ifdef SIMULATOR
+ return true;
+#endif
+
+ if (m_service)
+ return m_service->state() == QLowEnergyService::ServiceDiscovered;
+
+ return false;
+}
+
+int DeviceHandler::hr() const
+{
+ return m_currentValue;
+}
+
+int DeviceHandler::time() const
+{
+ return m_start.secsTo(m_stop);
+}
+
+int DeviceHandler::maxHR() const
+{
+ return m_max;
+}
+
+int DeviceHandler::minHR() const
+{
+ return m_min;
+}
+
+float DeviceHandler::average() const
+{
+ return m_avg;
+}
+
+float DeviceHandler::calories() const
+{
+ return m_calories;
+}
+
+void DeviceHandler::addMeasurement(int value)
+{
+ m_currentValue = value;
+
+ // If measuring and value is appropriate
+ if (m_measuring && value > 30 && value < 250) {
+
+ m_stop = QDateTime::currentDateTime();
+ m_measurements << value;
+
+ m_min = m_min == 0 ? value : qMin(value, m_min);
+ m_max = qMax(value, m_max);
+ m_sum += value;
+ m_avg = (double)m_sum / m_measurements.size();
+ m_calories = ((-55.0969 + (0.6309 * m_avg) + (0.1988 * 94) + (0.2017 * 24)) / 4.184) * 60 * time()/3600;
+ }
+
+ emit statsChanged();
+}
diff --git a/examples/bluetooth/heartlistener/heartrate.h b/examples/bluetooth/heartrate-game/devicehandler.h
index 1766ce3a..950ed6e9 100644
--- a/examples/bluetooth/heartlistener/heartrate.h
+++ b/examples/bluetooth/heartrate-game/devicehandler.h
@@ -1,7 +1,6 @@
/***************************************************************************
**
-** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
-** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2017 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the examples of the QtBluetooth module of the Qt Toolkit.
@@ -39,73 +38,71 @@
**
****************************************************************************/
-#ifndef HEARTRATE_H
-#define HEARTRATE_H
+#ifndef DEVICEHANDLER_H
+#define DEVICEHANDLER_H
-#include "deviceinfo.h"
+#include "bluetoothbaseclass.h"
-#include <QString>
-#include <QDebug>
#include <QDateTime>
#include <QVector>
#include <QTimer>
-#include <QBluetoothDeviceDiscoveryAgent>
-#include <QBluetoothDeviceInfo>
#include <QLowEnergyController>
#include <QLowEnergyService>
+class DeviceInfo;
-QT_USE_NAMESPACE
-class HeartRate: public QObject
+class DeviceHandler : public BluetoothBaseClass
{
Q_OBJECT
- Q_PROPERTY(QVariant name READ name NOTIFY nameChanged)
- Q_PROPERTY(QString message READ message NOTIFY messageChanged)
- Q_PROPERTY(int hr READ hR NOTIFY hrChanged)
- Q_PROPERTY(int maxHR READ maxHR NOTIFY averageChanged)
- Q_PROPERTY(int minHR READ minHR NOTIFY averageChanged)
- Q_PROPERTY(float average READ average NOTIFY averageChanged)
- Q_PROPERTY(int time READ time NOTIFY timeChanged)
- Q_PROPERTY(float calories READ caloriesCalculation NOTIFY caloriesChanged)
+
+ Q_PROPERTY(bool measuring READ measuring NOTIFY measuringChanged)
+ Q_PROPERTY(bool alive READ alive NOTIFY aliveChanged)
+ Q_PROPERTY(int hr READ hr NOTIFY statsChanged)
+ Q_PROPERTY(int maxHR READ maxHR NOTIFY statsChanged)
+ Q_PROPERTY(int minHR READ minHR NOTIFY statsChanged)
+ Q_PROPERTY(float average READ average NOTIFY statsChanged)
+ Q_PROPERTY(int time READ time NOTIFY statsChanged)
+ Q_PROPERTY(float calories READ calories NOTIFY statsChanged)
+ Q_PROPERTY(AddressType addressType READ addressType WRITE setAddressType)
public:
- HeartRate();
- ~HeartRate();
- void setMessage(QString message);
- QString message() const;
- QVariant name();
- int hR() const;
- int time();
- float average();
+ enum class AddressType {
+ PublicAddress,
+ RandomAddress
+ };
+ Q_ENUM(AddressType)
+
+ DeviceHandler(QObject *parent = 0);
+
+ void setDevice(DeviceInfo *device);
+ void setAddressType(AddressType type);
+ AddressType addressType() const;
+
+ bool measuring() const;
+ bool alive() const;
+
+ // Statistics
+ int hr() const;
+ int time() const;
+ float average() const;
int maxHR() const;
int minHR() const;
- float caloriesCalculation();
+ float calories() const;
+
+signals:
+ void measuringChanged();
+ void aliveChanged();
+ void statsChanged();
public slots:
- void deviceSearch();
- void connectToService(const QString &address);
+ void startMeasurement();
+ void stopMeasurement();
void disconnectService();
- void startDemo();
-
- void obtainResults();
- int measurements(int index) const;
- int measurementsSize() const;
- QString deviceAddress() const;
- int numDevices() const;
-
-private slots:
- //QBluetothDeviceDiscoveryAgent
- void addDevice(const QBluetoothDeviceInfo&);
- void scanFinished();
- void deviceScanError(QBluetoothDeviceDiscoveryAgent::Error);
+private:
//QLowEnergyController
void serviceDiscovered(const QBluetoothUuid &);
void serviceScanDone();
- void controllerError(QLowEnergyController::Error);
- void deviceConnected();
- void deviceDisconnected();
-
//QLowEnergyService
void serviceStateChanged(QLowEnergyService::ServiceState s);
@@ -113,37 +110,33 @@ private slots:
const QByteArray &value);
void confirmedDescriptorWrite(const QLowEnergyDescriptor &d,
const QByteArray &value);
- void serviceError(QLowEnergyService::ServiceError e);
-
- //DemoMode
- void receiveDemo();
-
-Q_SIGNALS:
- void messageChanged();
- void nameChanged();
- void hrChanged();
- void averageChanged();
- void timeChanged();
- void caloriesChanged();
+#ifdef SIMULATOR
+ void updateDemoHR();
+#endif
private:
- int randomPulse() const;
+ void addMeasurement(int value);
- DeviceInfo m_currentDevice;
- QBluetoothDeviceDiscoveryAgent *m_deviceDiscoveryAgent;
+ QLowEnergyController *m_control;
+ QLowEnergyService *m_service;
QLowEnergyDescriptor m_notificationDesc;
- QList<QObject*> m_devices;
- QString m_info;
- bool foundHeartRateService;
- QVector<quint16> m_measurements;
+ DeviceInfo *m_currentDevice;
+
+ bool m_foundHeartRateService;
+ bool m_measuring;
+ int m_currentValue, m_min, m_max, m_sum;
+ float m_avg, m_calories;
+
+ // Statistics
QDateTime m_start;
QDateTime m_stop;
- int m_max;
- int m_min;
- float calories;
- QLowEnergyController *m_control;
- QTimer *timer; // for demo application
- QLowEnergyService *m_service;
+
+ QVector<int> m_measurements;
+ QLowEnergyController::RemoteAddressType m_addressType = QLowEnergyController::PublicAddress;
+
+#ifdef SIMULATOR
+ QTimer m_demoTimer;
+#endif
};
-#endif // HEARTRATE_H
+#endif // DEVICEHANDLER_H
diff --git a/examples/bluetooth/heartlistener/deviceinfo.cpp b/examples/bluetooth/heartrate-game/deviceinfo.cpp
index cfddf56d..cf364393 100644
--- a/examples/bluetooth/heartlistener/deviceinfo.cpp
+++ b/examples/bluetooth/heartrate-game/deviceinfo.cpp
@@ -1,7 +1,6 @@
/***************************************************************************
**
-** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
-** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2017 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the examples of the QtBluetooth module of the Qt Toolkit.
@@ -39,9 +38,10 @@
**
****************************************************************************/
-#include <qbluetoothuuid.h>
-
+#include "heartrate-global.h"
#include "deviceinfo.h"
+#include <QBluetoothAddress>
+#include <QBluetoothUuid>
DeviceInfo::DeviceInfo(const QBluetoothDeviceInfo &info):
QObject(), m_device(info)
@@ -53,9 +53,20 @@ QBluetoothDeviceInfo DeviceInfo::getDevice() const
return m_device;
}
+QString DeviceInfo::getName() const
+{
+#ifdef SIMULATOR
+ return "Demo device";
+#else
+ return m_device.name();
+#endif
+}
+
QString DeviceInfo::getAddress() const
{
-#ifdef Q_OS_MAC
+#ifdef SIMULATOR
+ return "00:11:22:33:44:55";
+#elif defined Q_OS_DARWIN
// workaround for Core Bluetooth:
return m_device.deviceUuid().toString();
#else
diff --git a/examples/bluetooth/heartlistener/deviceinfo.h b/examples/bluetooth/heartrate-game/deviceinfo.h
index 636f7905..bbddbdd4 100644
--- a/examples/bluetooth/heartlistener/deviceinfo.h
+++ b/examples/bluetooth/heartrate-game/deviceinfo.h
@@ -1,7 +1,6 @@
/***************************************************************************
**
-** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
-** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2017 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the examples of the QtBluetooth module of the Qt Toolkit.
@@ -44,18 +43,19 @@
#include <QString>
#include <QObject>
-#include <qbluetoothdeviceinfo.h>
-#include <qbluetoothaddress.h>
+#include <QBluetoothDeviceInfo>
class DeviceInfo: public QObject
{
Q_OBJECT
Q_PROPERTY(QString deviceName READ getName NOTIFY deviceChanged)
Q_PROPERTY(QString deviceAddress READ getAddress NOTIFY deviceChanged)
+
public:
DeviceInfo(const QBluetoothDeviceInfo &device);
+
void setDevice(const QBluetoothDeviceInfo &device);
- QString getName() const { return m_device.name(); }
+ QString getName() const;
QString getAddress() const;
QBluetoothDeviceInfo getDevice() const;
diff --git a/examples/bluetooth/heartrate-game/doc/images/heartgame-result.png b/examples/bluetooth/heartrate-game/doc/images/heartgame-result.png
new file mode 100644
index 00000000..2dad1b30
--- /dev/null
+++ b/examples/bluetooth/heartrate-game/doc/images/heartgame-result.png
Binary files differ
diff --git a/examples/bluetooth/heartrate-game/doc/images/heartgame-running.png b/examples/bluetooth/heartrate-game/doc/images/heartgame-running.png
new file mode 100644
index 00000000..05485f0e
--- /dev/null
+++ b/examples/bluetooth/heartrate-game/doc/images/heartgame-running.png
Binary files differ
diff --git a/examples/bluetooth/heartrate-game/doc/images/heartgame-search.png b/examples/bluetooth/heartrate-game/doc/images/heartgame-search.png
new file mode 100644
index 00000000..4b0b0497
--- /dev/null
+++ b/examples/bluetooth/heartrate-game/doc/images/heartgame-search.png
Binary files differ
diff --git a/examples/bluetooth/heartrate-game/doc/images/heartgame-start.png b/examples/bluetooth/heartrate-game/doc/images/heartgame-start.png
new file mode 100644
index 00000000..21cc641f
--- /dev/null
+++ b/examples/bluetooth/heartrate-game/doc/images/heartgame-start.png
Binary files differ
diff --git a/examples/bluetooth/heartlistener/doc/src/heartlistener.qdoc b/examples/bluetooth/heartrate-game/doc/src/heartrate-game.qdoc
index 2bb59ae1..2b2b75d0 100644
--- a/examples/bluetooth/heartlistener/doc/src/heartlistener.qdoc
+++ b/examples/bluetooth/heartrate-game/doc/src/heartrate-game.qdoc
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2017 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the documentation of the Qt Toolkit.
@@ -26,19 +26,18 @@
****************************************************************************/
/*!
- \example heartlistener
- \title Bluetooth Low Energy Heart Listener Example
- \brief An example demonstrating the interaction with a Bluetooth Low Energy Heart Rate
- device/service. The example demonstrates the use of all Qt Bluetooth
- Low Energy classes.
+ \example heartrate-game
+ \title Bluetooth Low Energy Heart Rate Game
+ \brief A game demonstrating the interaction with a Bluetooth Low Energy Heart Rate
+ device/service.
- The Bluetooth Low Energy Heart Listener Example shows how to develop a Bluetooth
- Low Energy application using the Qt Bluetooth API. The application covers
- the scanning for Bluetooth Low Energy devices, connecting to a Heart Rate service
- on the device, writing characteristics and descriptors and receiving updates from device
- once the heart rate has changed.
+ The Bluetooth Low Energy Heart Rate Game shows how to develop a Bluetooth Low Energy
+ application using the Qt Bluetooth API. The application covers the scanning for
+ Bluetooth Low Energy devices, connecting to a Heart Rate service on the device, writing
+ characteristics and descriptors, and receiving updates from the device once the heart rate
+ has changed.
- \image heartratemonitor.png
+ \image heartgame-start.png
The example introduces the following Qt classes:
@@ -56,6 +55,8 @@
If no such device can be found, the example uses a demo mode which creates and displays
random values.
+ The goal of the game is to increase the measured heart rate as much as possible.
+
The \l {lowenergyscanner}{Bluetooth Low Energy Scanner} example might be more suitable
if a heart rate device is not available. The scanner example works with any type of Bluetooth
Low Energy peripheral device.
@@ -66,20 +67,20 @@
The application searches for all Bluetooth Low Energy peripheral devices in the vicinity.
It is assumed that the remote devices advertise their presence. The found devices are
- presented in a list. Note that it shows all Bluetooth Low Energy devices even those which
- do not offer a Heart Rate service.
+ presented in a list. Note that all found Bluetooth Low Energy devices are listed even
+ if they do not offer a Heart Rate service.
- \image heartratefound.png
+ \image heartgame-search.png
After the user has selected a target device, the example connects to its Heart Rate service
if one is available. It automatically enables notification updates for the Heart Rate value
and presents the current value on the screen.
- \image heartratemonitor.png
+ \image heartgame-running.png
Once the monitoring process is canceled, a small graph presents a summary of the received
values.
- \image heartrateresults.png
-*/
+ \image heartgame-result.png
+*/
diff --git a/examples/bluetooth/heartrate-game/heartrate-game.pro b/examples/bluetooth/heartrate-game/heartrate-game.pro
new file mode 100644
index 00000000..fcec0bd2
--- /dev/null
+++ b/examples/bluetooth/heartrate-game/heartrate-game.pro
@@ -0,0 +1,29 @@
+TEMPLATE = app
+TARGET = heartrate-game
+
+QT += qml quick bluetooth
+CONFIG += c++11
+
+HEADERS += \
+ connectionhandler.h \
+ deviceinfo.h \
+ devicefinder.h \
+ devicehandler.h \
+ bluetoothbaseclass.h \
+ heartrate-global.h
+
+SOURCES += main.cpp \
+ connectionhandler.cpp \
+ deviceinfo.cpp \
+ devicefinder.cpp \
+ devicehandler.cpp \
+ bluetoothbaseclass.cpp
+
+RESOURCES += qml.qrc \
+ images.qrc
+
+# Additional import path used to resolve QML modules in Qt Creator's code model
+QML_IMPORT_PATH =
+
+target.path = $$[QT_INSTALL_EXAMPLES]/bluetooth/heartrate-game
+INSTALLS += target
diff --git a/examples/bluetooth/heartlistener/assets/Point.qml b/examples/bluetooth/heartrate-game/heartrate-global.h
index 0341d11a..376c7990 100644
--- a/examples/bluetooth/heartlistener/assets/Point.qml
+++ b/examples/bluetooth/heartrate-game/heartrate-global.h
@@ -1,6 +1,6 @@
/***************************************************************************
**
-** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
+** Copyright (C) 2017 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the examples of the QtBluetooth module of the Qt Toolkit.
@@ -38,14 +38,14 @@
**
****************************************************************************/
-import QtQuick 2.0
+#ifndef HEARTRATEGLOBAL_H
+#define HEARTRATEGLOBAL_H
-Rectangle {
- id: point
+//#define USE_SIMULATOR
- Image {
- width: 10; height: 7
- smooth: true
- source: "blue_heart_small.png"
- }
-}
+#if defined(Q_OS_WIN32) || defined(USE_SIMULATOR)
+#define SIMULATOR
+#endif
+
+
+#endif // HEARTRATEGLOBAL_H
diff --git a/examples/bluetooth/heartrate-game/images.qrc b/examples/bluetooth/heartrate-game/images.qrc
new file mode 100644
index 00000000..38058de0
--- /dev/null
+++ b/examples/bluetooth/heartrate-game/images.qrc
@@ -0,0 +1,7 @@
+<RCC>
+ <qresource prefix="/">
+ <file>qml/images/logo.png</file>
+ <file>qml/images/bt_off_to_on.png</file>
+ <file>qml/images/heart.png</file>
+ </qresource>
+</RCC>
diff --git a/examples/bluetooth/heartlistener/main.cpp b/examples/bluetooth/heartrate-game/main.cpp
index 7aa17080..0b0cae12 100644
--- a/examples/bluetooth/heartlistener/main.cpp
+++ b/examples/bluetooth/heartrate-game/main.cpp
@@ -1,7 +1,6 @@
/***************************************************************************
**
-** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
-** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2017 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the examples of the QtBluetooth module of the Qt Toolkit.
@@ -39,23 +38,32 @@
**
****************************************************************************/
-#include <QtCore/QLoggingCategory>
-#include <QQmlContext>
#include <QGuiApplication>
-#include <QQuickView>
-#include "heartrate.h"
+#include <QQmlApplicationEngine>
+#include <QQmlContext>
+#include <QtCore/QLoggingCategory>
+
+#include "connectionhandler.h"
+#include "devicefinder.h"
+#include "devicehandler.h"
int main(int argc, char *argv[])
{
//QLoggingCategory::setFilterRules(QStringLiteral("qt.bluetooth* = true"));
QGuiApplication app(argc, argv);
- HeartRate heartRate;
- QQuickView *view = new QQuickView;
- view->rootContext()->setContextProperty("heartRate", &heartRate);
- view->setSource(QUrl("qrc:/assets/main.qml"));
- view->setResizeMode(QQuickView::SizeRootObjectToView);
- view->show();
- return app.exec();
+ ConnectionHandler connectionHandler;
+ DeviceHandler deviceHandler;
+ DeviceFinder deviceFinder(&deviceHandler);
+
+ qmlRegisterUncreatableType<DeviceHandler>("Shared", 1, 0, "AddressType", "Enum is not a type");
+
+ QQmlApplicationEngine engine;
+ engine.rootContext()->setContextProperty("connectionHandler", &connectionHandler);
+ engine.rootContext()->setContextProperty("deviceFinder", &deviceFinder);
+ engine.rootContext()->setContextProperty("deviceHandler", &deviceHandler);
+ engine.load(QUrl(QStringLiteral("qrc:/qml/main.qml")));
+
+ return app.exec();
}
diff --git a/examples/bluetooth/heartrate-game/qml.qrc b/examples/bluetooth/heartrate-game/qml.qrc
new file mode 100644
index 00000000..bab96355
--- /dev/null
+++ b/examples/bluetooth/heartrate-game/qml.qrc
@@ -0,0 +1,18 @@
+<RCC>
+ <qresource prefix="/">
+ <file>qml/BluetoothAlarmDialog.qml</file>
+ <file>qml/main.qml</file>
+ <file>qml/SplashScreen.qml</file>
+ <file>qml/GameSettings.qml</file>
+ <file>qml/App.qml</file>
+ <file>qml/TitleBar.qml</file>
+ <file>qml/Connect.qml</file>
+ <file>qml/Measure.qml</file>
+ <file>qml/Stats.qml</file>
+ <file>qml/GameButton.qml</file>
+ <file>qml/GamePage.qml</file>
+ <file>qml/BottomLine.qml</file>
+ <file>qml/StatsLabel.qml</file>
+ <file>qml/qmldir</file>
+ </qresource>
+</RCC>
diff --git a/examples/bluetooth/heartrate-game/qml/App.qml b/examples/bluetooth/heartrate-game/qml/App.qml
new file mode 100644
index 00000000..fc8b1c89
--- /dev/null
+++ b/examples/bluetooth/heartrate-game/qml/App.qml
@@ -0,0 +1,120 @@
+/***************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the QtBluetooth 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 The Qt Company Ltd 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 2.5
+
+Item {
+ id: app
+ anchors.fill: parent
+ opacity: 0.0
+
+ Behavior on opacity { NumberAnimation { duration: 500 } }
+
+ property var lastPages: []
+ property int __currentIndex: 0
+
+ function init()
+ {
+ opacity = 1.0
+ showPage("Connect.qml")
+ }
+
+ function prevPage()
+ {
+ lastPages.pop()
+ pageLoader.setSource(lastPages[lastPages.length-1])
+ __currentIndex = lastPages.length-1;
+ }
+
+ function showPage(name)
+ {
+ lastPages.push(name)
+ pageLoader.setSource(name)
+ __currentIndex = lastPages.length-1;
+ }
+
+ TitleBar {
+ id: titleBar
+ currentIndex: __currentIndex
+
+ onTitleClicked: {
+ if (index < __currentIndex)
+ pageLoader.item.close()
+ }
+ }
+
+ Loader {
+ id: pageLoader
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.top: titleBar.bottom
+ anchors.bottom: parent.bottom
+
+ onStatusChanged: {
+ if (status === Loader.Ready)
+ {
+ pageLoader.item.init();
+ pageLoader.item.forceActiveFocus()
+ }
+ }
+ }
+
+ Keys.onReleased: {
+ switch (event.key) {
+ case Qt.Key_Escape:
+ case Qt.Key_Back: {
+ if (__currentIndex > 0) {
+ pageLoader.item.close()
+ event.accepted = true
+ } else {
+ Qt.quit()
+ }
+ break;
+ }
+ default: break;
+ }
+ }
+
+ BluetoothAlarmDialog {
+ id: btAlarmDialog
+ anchors.fill: parent
+ visible: !connectionHandler.alive
+ }
+}
diff --git a/examples/bluetooth/heartrate-game/qml/BluetoothAlarmDialog.qml b/examples/bluetooth/heartrate-game/qml/BluetoothAlarmDialog.qml
new file mode 100644
index 00000000..ef32f5ea
--- /dev/null
+++ b/examples/bluetooth/heartrate-game/qml/BluetoothAlarmDialog.qml
@@ -0,0 +1,112 @@
+/***************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the QtBluetooth 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 The Qt Company Ltd 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 2.5
+
+Item {
+ id: root
+ anchors.fill: parent
+
+ Rectangle {
+ anchors.fill: parent
+ color: "black"
+ opacity: 0.9
+ }
+
+ MouseArea {
+ id: eventEater
+ }
+
+ Rectangle {
+ id: dialogFrame
+
+ anchors.centerIn: parent
+ width: parent.width * 0.8
+ height: parent.height * 0.6
+ border.color: "#454545"
+ color: GameSettings.backgroundColor
+ radius: width * 0.05
+
+ Item {
+ id: dialogContainer
+ anchors.fill: parent
+ anchors.margins: parent.width*0.05
+
+ Image {
+ id: offOnImage
+ anchors.left: quitButton.left
+ anchors.right: quitButton.right
+ anchors.top: parent.top
+ height: GameSettings.heightForWidth(width, sourceSize)
+ source: "images/bt_off_to_on.png"
+ }
+
+ Text {
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.top: offOnImage.bottom
+ anchors.bottom: quitButton.top
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ wrapMode: Text.WordWrap
+ font.pixelSize: GameSettings.mediumFontSize
+ color: GameSettings.textColor
+ text: qsTr("This application cannot be used without Bluetooth. Please switch Bluetooth ON to continue.")
+ }
+
+ GameButton {
+ id: quitButton
+ anchors.bottom: parent.bottom
+ anchors.horizontalCenter: parent.horizontalCenter
+ width: dialogContainer.width * 0.6
+ height: GameSettings.buttonHeight
+ onClicked: Qt.quit()
+
+ Text {
+ anchors.centerIn: parent
+ color: GameSettings.textColor
+ font.pixelSize: GameSettings.bigFontSize
+ text: qsTr("Quit")
+ }
+ }
+ }
+ }
+}
+
diff --git a/examples/bluetooth/heartlistener/assets/dialog.qml b/examples/bluetooth/heartrate-game/qml/BottomLine.qml
index bcaf299f..af644228 100644
--- a/examples/bluetooth/heartlistener/assets/dialog.qml
+++ b/examples/bluetooth/heartrate-game/qml/BottomLine.qml
@@ -1,6 +1,6 @@
/***************************************************************************
**
-** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
+** Copyright (C) 2017 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the examples of the QtBluetooth module of the Qt Toolkit.
@@ -38,24 +38,12 @@
**
****************************************************************************/
-import QtQuick 2.0
+import QtQuick 2.5
Rectangle {
- id: root
- opacity: 0.8
- color: "#E0DEDF"
anchors.horizontalCenter: parent.horizontalCenter
-
- property int hr: heartRate.hr
- Text {
- text: heartRate.message
- color: "#3870BA"
-
- }
-
- onHrChanged: {
- if (heartRate.hr > 0) {
- root.destroy()
- }
- }
+ anchors.bottom: parent.bottom
+ width: parent.width * 0.85
+ height: parent.height * 0.05
+ radius: height*0.5
}
diff --git a/examples/bluetooth/heartrate-game/qml/Connect.qml b/examples/bluetooth/heartrate-game/qml/Connect.qml
new file mode 100644
index 00000000..9e4efb17
--- /dev/null
+++ b/examples/bluetooth/heartrate-game/qml/Connect.qml
@@ -0,0 +1,178 @@
+/***************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the QtBluetooth 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 The Qt Company Ltd 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 2.5
+import Shared 1.0
+
+GamePage {
+
+ errorMessage: deviceFinder.error
+ infoMessage: deviceFinder.info
+
+ Rectangle {
+ id: viewContainer
+ anchors.top: parent.top
+ anchors.bottom:
+ // only BlueZ platform has address type selection
+ connectionHandler.requiresAddressType ? addressTypeButton.top : searchButton.top
+ anchors.topMargin: GameSettings.fieldMargin + messageHeight
+ anchors.bottomMargin: GameSettings.fieldMargin
+ anchors.horizontalCenter: parent.horizontalCenter
+ width: parent.width - GameSettings.fieldMargin*2
+ color: GameSettings.viewColor
+ radius: GameSettings.buttonRadius
+
+
+ Text {
+ id: title
+ width: parent.width
+ height: GameSettings.fieldHeight
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ color: GameSettings.textColor
+ font.pixelSize: GameSettings.mediumFontSize
+ text: qsTr("FOUND DEVICES")
+
+ BottomLine {
+ height: 1;
+ width: parent.width
+ color: "#898989"
+ }
+ }
+
+
+ ListView {
+ id: devices
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.bottom: parent.bottom
+ anchors.top: title.bottom
+ model: deviceFinder.devices
+ clip: true
+
+ delegate: Rectangle {
+ id: box
+ height:GameSettings.fieldHeight * 1.2
+ width: parent.width
+ color: index % 2 === 0 ? GameSettings.delegate1Color : GameSettings.delegate2Color
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ deviceFinder.connectToService(modelData.deviceAddress);
+ app.showPage("Measure.qml")
+ }
+ }
+
+ Text {
+ id: device
+ font.pixelSize: GameSettings.smallFontSize
+ text: modelData.deviceName
+ anchors.top: parent.top
+ anchors.topMargin: parent.height * 0.1
+ anchors.leftMargin: parent.height * 0.1
+ anchors.left: parent.left
+ color: GameSettings.textColor
+ }
+
+ Text {
+ id: deviceAddress
+ font.pixelSize: GameSettings.smallFontSize
+ text: modelData.deviceAddress
+ anchors.bottom: parent.bottom
+ anchors.bottomMargin: parent.height * 0.1
+ anchors.rightMargin: parent.height * 0.1
+ anchors.right: parent.right
+ color: Qt.darker(GameSettings.textColor)
+ }
+ }
+ }
+ }
+
+ GameButton {
+ id: addressTypeButton
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.bottom: searchButton.top
+ anchors.bottomMargin: GameSettings.fieldMargin*0.5
+ width: viewContainer.width
+ height: GameSettings.fieldHeight
+ visible: connectionHandler.requiresAddressType // only required on BlueZ
+ state: "public"
+ onClicked: state == "public" ? state = "random" : state = "public"
+
+ states: [
+ State {
+ name: "public"
+ PropertyChanges { target: addressTypeText; text: qsTr("Public Address") }
+ PropertyChanges { target: deviceHandler; addressType: AddressType.PublicAddress }
+ },
+ State {
+ name: "random"
+ PropertyChanges { target: addressTypeText; text: qsTr("Random Address") }
+ PropertyChanges { target: deviceHandler; addressType: AddressType.RandomAddress }
+ }
+ ]
+
+ Text {
+ id: addressTypeText
+ anchors.centerIn: parent
+ font.pixelSize: GameSettings.tinyFontSize
+ color: GameSettings.textColor
+ }
+ }
+
+ GameButton {
+ id: searchButton
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.bottom: parent.bottom
+ anchors.bottomMargin: GameSettings.fieldMargin
+ width: viewContainer.width
+ height: GameSettings.fieldHeight
+ enabled: !deviceFinder.scanning
+ onClicked: deviceFinder.startSearch()
+
+ Text {
+ anchors.centerIn: parent
+ font.pixelSize: GameSettings.tinyFontSize
+ text: qsTr("START SEARCH")
+ color: searchButton.enabled ? GameSettings.textColor : GameSettings.disabledTextColor
+ }
+ }
+}
diff --git a/examples/bluetooth/heartrate-game/qml/GameButton.qml b/examples/bluetooth/heartrate-game/qml/GameButton.qml
new file mode 100644
index 00000000..e7fc36af
--- /dev/null
+++ b/examples/bluetooth/heartrate-game/qml/GameButton.qml
@@ -0,0 +1,78 @@
+/***************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the QtBluetooth 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 The Qt Company Ltd 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 2.5
+import "."
+
+Rectangle {
+ id: button
+ color: baseColor
+ onEnabledChanged: checkColor()
+ radius: GameSettings.buttonRadius
+
+ property color baseColor: GameSettings.buttonColor
+ property color pressedColor: GameSettings.buttonPressedColor
+ property color disabledColor: GameSettings.disabledButtonColor
+
+ signal clicked()
+
+ function checkColor()
+ {
+ if (!button.enabled) {
+ button.color = disabledColor
+ } else {
+ if (mouseArea.containsPress)
+ button.color = pressedColor
+ else
+ button.color = baseColor
+ }
+ }
+
+ MouseArea {
+ id: mouseArea
+ anchors.fill: parent
+ onPressed: checkColor()
+ onReleased: checkColor()
+ onClicked: {
+ checkColor()
+ button.clicked()
+ }
+ }
+}
diff --git a/examples/bluetooth/heartrate-game/qml/GamePage.qml b/examples/bluetooth/heartrate-game/qml/GamePage.qml
new file mode 100644
index 00000000..663eb047
--- /dev/null
+++ b/examples/bluetooth/heartrate-game/qml/GamePage.qml
@@ -0,0 +1,83 @@
+/***************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the QtBluetooth 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 The Qt Company Ltd 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 2.5
+import "."
+
+Item {
+ anchors.fill: parent
+
+ property string errorMessage: ""
+ property string infoMessage: ""
+ property real messageHeight: msg.height
+ property bool hasError: errorMessage != ""
+ property bool hasInfo: infoMessage != ""
+
+ function init()
+ {
+ }
+
+ function close()
+ {
+ app.prevPage()
+ }
+
+ Rectangle {
+ id: msg
+ anchors.top: parent.top
+ anchors.left: parent.left
+ anchors.right: parent.right
+ height: GameSettings.fieldHeight
+ color: hasError ? GameSettings.errorColor : GameSettings.infoColor
+ visible: hasError || hasInfo
+
+ Text {
+ id: error
+ anchors.fill: parent
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ minimumPixelSize: 5
+ font.pixelSize: GameSettings.smallFontSize
+ fontSizeMode: Text.Fit
+ color: GameSettings.textColor
+ text: hasError ? errorMessage : infoMessage
+ }
+ }
+}
diff --git a/examples/bluetooth/heartrate-game/qml/GameSettings.qml b/examples/bluetooth/heartrate-game/qml/GameSettings.qml
new file mode 100644
index 00000000..868f32ac
--- /dev/null
+++ b/examples/bluetooth/heartrate-game/qml/GameSettings.qml
@@ -0,0 +1,91 @@
+/***************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the QtBluetooth 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 The Qt Company Ltd 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$
+**
+****************************************************************************/
+
+pragma Singleton
+import QtQuick 2.5
+
+Item {
+ property int wHeight
+ property int wWidth
+
+ // Colors
+ readonly property color backgroundColor: "#2d3037"
+ readonly property color buttonColor: "#202227"
+ readonly property color buttonPressedColor: "#6ccaf2"
+ readonly property color disabledButtonColor: "#555555"
+ readonly property color viewColor: "#202227"
+ readonly property color delegate1Color: Qt.darker(viewColor, 1.2)
+ readonly property color delegate2Color: Qt.lighter(viewColor, 1.2)
+ readonly property color textColor: "#ffffff"
+ readonly property color textDarkColor: "#232323"
+ readonly property color disabledTextColor: "#777777"
+ readonly property color sliderColor: "#6ccaf2"
+ readonly property color errorColor: "#ba3f62"
+ readonly property color infoColor: "#3fba62"
+
+ // Font sizes
+ property real microFontSize: hugeFontSize * 0.2
+ property real tinyFontSize: hugeFontSize * 0.4
+ property real smallTinyFontSize: hugeFontSize * 0.5
+ property real smallFontSize: hugeFontSize * 0.6
+ property real mediumFontSize: hugeFontSize * 0.7
+ property real bigFontSize: hugeFontSize * 0.8
+ property real largeFontSize: hugeFontSize * 0.9
+ property real hugeFontSize: (wWidth + wHeight) * 0.03
+ property real giganticFontSize: (wWidth + wHeight) * 0.04
+
+ // Some other values
+ property real fieldHeight: wHeight * 0.08
+ property real fieldMargin: fieldHeight * 0.5
+ property real buttonHeight: wHeight * 0.08
+ property real buttonRadius: buttonHeight * 0.1
+
+ // Some help functions
+ function widthForHeight(h, ss)
+ {
+ return h/ss.height * ss.width;
+ }
+
+ function heightForWidth(w, ss)
+ {
+ return w/ss.width * ss.height;
+ }
+
+}
diff --git a/examples/bluetooth/heartrate-game/qml/Measure.qml b/examples/bluetooth/heartrate-game/qml/Measure.qml
new file mode 100644
index 00000000..f8c51eb4
--- /dev/null
+++ b/examples/bluetooth/heartrate-game/qml/Measure.qml
@@ -0,0 +1,234 @@
+/***************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the QtBluetooth 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 The Qt Company Ltd 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 2.5
+
+GamePage {
+ id: measurePage
+
+ errorMessage: deviceHandler.error
+ infoMessage: deviceHandler.info
+
+ property real __timeCounter: 0;
+ property real __maxTimeCount: 60
+ property string relaxText: qsTr("Relax!\nWhen you are ready, press Start. You have %1s time to increase heartrate so much as possible.\nGood luck!").arg(__maxTimeCount)
+
+ function close()
+ {
+ deviceHandler.stopMeasurement();
+ deviceHandler.disconnectService();
+ app.prevPage();
+ }
+
+ function start()
+ {
+ if (!deviceHandler.measuring) {
+ __timeCounter = 0;
+ deviceHandler.startMeasurement()
+ }
+ }
+
+ function stop()
+ {
+ if (deviceHandler.measuring) {
+ deviceHandler.stopMeasurement()
+ }
+
+ app.showPage("Stats.qml")
+ }
+
+ Timer {
+ id: measureTimer
+ interval: 1000
+ running: deviceHandler.measuring
+ repeat: true
+ onTriggered: {
+ __timeCounter++;
+ if (__timeCounter >= __maxTimeCount)
+ measurePage.stop()
+ }
+ }
+
+ Column {
+ anchors.centerIn: parent
+ spacing: GameSettings.fieldHeight * 0.5
+
+ Rectangle {
+ id: circle
+ anchors.horizontalCenter: parent.horizontalCenter
+ width: Math.min(measurePage.width, measurePage.height-GameSettings.fieldHeight*4) - 2*GameSettings.fieldMargin
+ height: width
+ radius: width*0.5
+ color: GameSettings.viewColor
+
+ Text {
+ id: hintText
+ anchors.centerIn: parent
+ anchors.verticalCenterOffset: -parent.height*0.1
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ width: parent.width * 0.8
+ height: parent.height * 0.6
+ wrapMode: Text.WordWrap
+ text: measurePage.relaxText
+ visible: !deviceHandler.measuring
+ color: GameSettings.textColor
+ fontSizeMode: Text.Fit
+ minimumPixelSize: 10
+ font.pixelSize: GameSettings.mediumFontSize
+ }
+
+ Text {
+ id: text
+ anchors.centerIn: parent
+ anchors.verticalCenterOffset: -parent.height*0.15
+ font.pixelSize: parent.width * 0.45
+ text: deviceHandler.hr
+ visible: deviceHandler.measuring
+ color: GameSettings.textColor
+ }
+
+ Item {
+ id: minMaxContainer
+ anchors.horizontalCenter: parent.horizontalCenter
+ width: parent.width*0.7
+ height: parent.height * 0.15
+ anchors.bottom: parent.bottom
+ anchors.bottomMargin: parent.height*0.16
+ visible: deviceHandler.measuring
+
+ Text {
+ anchors.left: parent.left
+ anchors.verticalCenter: parent.verticalCenter
+ text: deviceHandler.minHR
+ color: GameSettings.textColor
+ font.pixelSize: GameSettings.hugeFontSize
+
+ Text {
+ anchors.left: parent.left
+ anchors.bottom: parent.top
+ font.pixelSize: parent.font.pixelSize*0.8
+ color: parent.color
+ text: "MIN"
+ }
+ }
+
+ Text {
+ anchors.right: parent.right
+ anchors.verticalCenter: parent.verticalCenter
+ text: deviceHandler.maxHR
+ color: GameSettings.textColor
+ font.pixelSize: GameSettings.hugeFontSize
+
+ Text {
+ anchors.right: parent.right
+ anchors.bottom: parent.top
+ font.pixelSize: parent.font.pixelSize*0.8
+ color: parent.color
+ text: "MAX"
+ }
+ }
+ }
+
+ Image {
+ id: heart
+ anchors.horizontalCenter: minMaxContainer.horizontalCenter
+ anchors.verticalCenter: minMaxContainer.bottom
+ width: parent.width * 0.2
+ height: width
+ source: "images/heart.png"
+ smooth: true
+ antialiasing: true
+
+ SequentialAnimation{
+ id: heartAnim
+ running: deviceHandler.alive
+ loops: Animation.Infinite
+ alwaysRunToEnd: true
+ PropertyAnimation { target: heart; property: "scale"; to: 1.2; duration: 500; easing.type: Easing.InQuad }
+ PropertyAnimation { target: heart; property: "scale"; to: 1.0; duration: 500; easing.type: Easing.OutQuad }
+ }
+ }
+ }
+
+ Rectangle {
+ id: timeSlider
+ color: GameSettings.viewColor
+ anchors.horizontalCenter: parent.horizontalCenter
+ width: circle.width
+ height: GameSettings.fieldHeight
+ radius: GameSettings.buttonRadius
+
+ Rectangle {
+ height: parent.height
+ radius: parent.radius
+ color: GameSettings.sliderColor
+ width: Math.min(1.0,__timeCounter / __maxTimeCount) * parent.width
+ }
+
+ Text {
+ anchors.centerIn: parent
+ color: "gray"
+ text: (__maxTimeCount - __timeCounter).toFixed(0) + " s"
+ font.pixelSize: GameSettings.bigFontSize
+ }
+ }
+ }
+
+ GameButton {
+ id: startButton
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.bottom: parent.bottom
+ anchors.bottomMargin: GameSettings.fieldMargin
+ width: circle.width
+ height: GameSettings.fieldHeight
+ enabled: !deviceHandler.measuring
+ radius: GameSettings.buttonRadius
+
+ onClicked: start()
+
+ Text {
+ anchors.centerIn: parent
+ font.pixelSize: GameSettings.tinyFontSize
+ text: qsTr("START")
+ color: startButton.enabled ? GameSettings.textColor : GameSettings.disabledTextColor
+ }
+ }
+}
diff --git a/examples/bluetooth/heartrate-game/qml/SplashScreen.qml b/examples/bluetooth/heartrate-game/qml/SplashScreen.qml
new file mode 100644
index 00000000..f480125e
--- /dev/null
+++ b/examples/bluetooth/heartrate-game/qml/SplashScreen.qml
@@ -0,0 +1,80 @@
+/***************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the QtBluetooth 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 The Qt Company Ltd 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 2.5
+import "."
+
+Item {
+ id: root
+ anchors.fill: parent
+
+ property bool appIsReady: false
+ property bool splashIsReady: false
+
+ property bool ready: appIsReady && splashIsReady
+ onReadyChanged: if (ready) readyToGo();
+
+ signal readyToGo()
+
+ function appReady()
+ {
+ appIsReady = true
+ }
+
+ function errorInLoadingApp()
+ {
+ Qt.quit()
+ }
+
+ Image {
+ anchors.centerIn: parent
+ width: Math.min(parent.height, parent.width)*0.6
+ height: GameSettings.heightForWidth(width, sourceSize)
+ source: "images/logo.png"
+ }
+
+ Timer {
+ id: splashTimer
+ interval: 1000
+ onTriggered: splashIsReady = true
+ }
+
+ Component.onCompleted: splashTimer.start()
+}
diff --git a/examples/bluetooth/heartlistener/assets/main.qml b/examples/bluetooth/heartrate-game/qml/Stats.qml
index 89d9f600..6e34d3bc 100644
--- a/examples/bluetooth/heartlistener/assets/main.qml
+++ b/examples/bluetooth/heartrate-game/qml/Stats.qml
@@ -1,6 +1,6 @@
/***************************************************************************
**
-** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
+** Copyright (C) 2017 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the examples of the QtBluetooth module of the Qt Toolkit.
@@ -38,47 +38,52 @@
**
****************************************************************************/
-import QtQuick 2.0
+import QtQuick 2.5
-Item {
- width: 400
- height: 600
- id: begin
+GamePage {
- Rectangle {
- color: "#F0EBED"
- anchors.fill: parent
- Rectangle {
- id: about
- width: 0.75*parent.width
- height: 0.1*parent.height
- anchors.top: parent.top
- anchors.topMargin: 20
+ Column {
+ anchors.centerIn: parent
+ width: parent.width
+
+ Text {
anchors.horizontalCenter: parent.horizontalCenter
- color: "#F0EBED"
- border.color: "#3870BA"
- border.width: 2
- radius: 10
- Text {
- id: aboutinfo
- anchors.centerIn: parent
- color: "#3870BA"
- text: "Welcome to the Heart Listener Application"
- }
+ font.pixelSize: GameSettings.hugeFontSize
+ color: GameSettings.textColor
+ text: qsTr("RESULT")
}
- Button {
- id:call
- buttonWidth: 0.75*parent.width
- buttonHeight: 0.15*parent.height
- anchors.centerIn: parent
- text: "Scan for Devices"
- onButtonClick: pageLoader.source="home.qml"
+ Text {
+ anchors.horizontalCenter: parent.horizontalCenter
+ font.pixelSize: GameSettings.giganticFontSize*3
+ color: GameSettings.textColor
+ text: (deviceHandler.maxHR - deviceHandler.minHR).toFixed(0)
+ }
+
+ Item {
+ height: GameSettings.fieldHeight
+ width: 1
+ }
+
+ StatsLabel {
+ title: qsTr("MIN")
+ value: deviceHandler.minHR.toFixed(0)
}
- }
- Loader {
- id: pageLoader
- anchors.fill: parent
+ StatsLabel {
+ title: qsTr("MAX")
+ value: deviceHandler.maxHR.toFixed(0)
+ }
+
+ StatsLabel {
+ title: qsTr("AVG")
+ value: deviceHandler.average.toFixed(1)
+ }
+
+
+ StatsLabel {
+ title: qsTr("CALORIES")
+ value: deviceHandler.calories.toFixed(3)
+ }
}
}
diff --git a/examples/bluetooth/heartlistener/assets/Button.qml b/examples/bluetooth/heartrate-game/qml/StatsLabel.qml
index 51c377b1..dd57852f 100644
--- a/examples/bluetooth/heartlistener/assets/Button.qml
+++ b/examples/bluetooth/heartrate-game/qml/StatsLabel.qml
@@ -1,6 +1,6 @@
/***************************************************************************
**
-** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
+** Copyright (C) 2017 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the examples of the QtBluetooth module of the Qt Toolkit.
@@ -38,40 +38,35 @@
**
****************************************************************************/
-import QtQuick 2.0
+import QtQuick 2.5
+import "."
-Rectangle {
- id:button
- //color: "#3870BA"
+Item {
+ height: GameSettings.fieldHeight
+ width: parent.width
- property real buttonWidth: 300
- property real buttonHeight: 80
- property string text: "Button"
-
- signal buttonClick()
- width: click.pressed ? (buttonWidth - 15) : buttonWidth
- height: click.pressed ? (buttonHeight - 15) :buttonHeight
-
- color: click.pressed ? "#3265A7" : "#3870BA"
-
- border.color: "#F0EBED"
- border.width: 5
- radius: 10
+ property alias title: leftText.text
+ property alias value: rightText.text
Text {
- id: label
- font.pixelSize: 30; font.bold: true
- horizontalAlignment: Text.AlignHCenter
+ id: leftText
+ anchors.left: parent.left
+ height: parent.height
+ width: parent.width * 0.45
+ horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
- anchors.fill: parent
- elide: Text.ElideMiddle
- color: "#F0EBED"
- text: button.text
+ font.pixelSize: GameSettings.mediumFontSize
+ color: GameSettings.textColor
}
- MouseArea {
- id: click
- anchors.fill: parent
- onClicked: buttonClick()
+ Text {
+ id: rightText
+ anchors.right: parent.right
+ height: parent.height
+ width: parent.width * 0.45
+ horizontalAlignment: Text.AlignLeft
+ verticalAlignment: Text.AlignVCenter
+ font.pixelSize: GameSettings.mediumFontSize
+ color: GameSettings.textColor
}
}
diff --git a/examples/bluetooth/heartrate-game/qml/TitleBar.qml b/examples/bluetooth/heartrate-game/qml/TitleBar.qml
new file mode 100644
index 00000000..46d641e6
--- /dev/null
+++ b/examples/bluetooth/heartrate-game/qml/TitleBar.qml
@@ -0,0 +1,87 @@
+/***************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the QtBluetooth 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 The Qt Company Ltd 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 2.5
+
+Rectangle {
+ id: titleBar
+ anchors.top: parent.top
+ anchors.left: parent.left
+ anchors.right: parent.right
+ height: GameSettings.fieldHeight
+ color: GameSettings.viewColor
+
+ property var __titles: ["CONNECT", "MEASURE", "STATS"]
+ property int currentIndex: 0
+
+ signal titleClicked(int index)
+
+ Repeater {
+ model: 3
+ Text {
+ width: titleBar.width / 3
+ height: titleBar.height
+ x: index * width
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ text: __titles[index]
+ font.pixelSize: GameSettings.tinyFontSize
+ color: titleBar.currentIndex === index ? GameSettings.textColor : GameSettings.disabledTextColor
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: titleClicked(index)
+ }
+ }
+ }
+
+
+ Item {
+ anchors.bottom: parent.bottom
+ width: parent.width / 3
+ height: parent.height
+ x: currentIndex * width
+
+ BottomLine{}
+
+ Behavior on x { NumberAnimation { duration: 200 } }
+ }
+
+}
diff --git a/examples/bluetooth/heartrate-game/qml/images/bt_off_to_on.png b/examples/bluetooth/heartrate-game/qml/images/bt_off_to_on.png
new file mode 100644
index 00000000..5ea1f3f0
--- /dev/null
+++ b/examples/bluetooth/heartrate-game/qml/images/bt_off_to_on.png
Binary files differ
diff --git a/examples/bluetooth/heartrate-game/qml/images/heart.png b/examples/bluetooth/heartrate-game/qml/images/heart.png
new file mode 100644
index 00000000..f2b3c0a3
--- /dev/null
+++ b/examples/bluetooth/heartrate-game/qml/images/heart.png
Binary files differ
diff --git a/examples/bluetooth/heartrate-game/qml/images/logo.png b/examples/bluetooth/heartrate-game/qml/images/logo.png
new file mode 100644
index 00000000..ea0af7e0
--- /dev/null
+++ b/examples/bluetooth/heartrate-game/qml/images/logo.png
Binary files differ
diff --git a/examples/bluetooth/heartrate-game/qml/main.qml b/examples/bluetooth/heartrate-game/qml/main.qml
new file mode 100644
index 00000000..66649a7a
--- /dev/null
+++ b/examples/bluetooth/heartrate-game/qml/main.qml
@@ -0,0 +1,95 @@
+/***************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the QtBluetooth 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 The Qt Company Ltd 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 2.7
+import QtQuick.Window 2.2
+import "."
+
+Window {
+ id: wroot
+ visible: true
+ width: 720 * .7
+ height: 1240 * .7
+ title: qsTr("HeartRateGame")
+ color: GameSettings.backgroundColor
+
+ Component.onCompleted: {
+ GameSettings.wWidth = Qt.binding(function() {return width})
+ GameSettings.wHeight = Qt.binding(function() {return height})
+ }
+
+ Loader {
+ id: splashLoader
+ anchors.fill: parent
+ source: "SplashScreen.qml"
+ asynchronous: false
+ visible: true
+
+ onStatusChanged: {
+ if (status === Loader.Ready) {
+ appLoader.setSource("App.qml");
+ }
+ }
+ }
+
+ Connections {
+ target: splashLoader.item
+ onReadyToGo: {
+ appLoader.visible = true
+ appLoader.item.init()
+ splashLoader.visible = false
+ splashLoader.setSource("")
+ appLoader.item.forceActiveFocus();
+ }
+ }
+
+ Loader {
+ id: appLoader
+ anchors.fill: parent
+ visible: false
+ asynchronous: true
+ onStatusChanged: {
+ if (status === Loader.Ready)
+ splashLoader.item.appReady()
+ if (status === Loader.Error)
+ splashLoader.item.errorInLoadingApp();
+ }
+ }
+}
diff --git a/examples/bluetooth/heartrate-game/qml/qmldir b/examples/bluetooth/heartrate-game/qml/qmldir
new file mode 100644
index 00000000..5e0d2b54
--- /dev/null
+++ b/examples/bluetooth/heartrate-game/qml/qmldir
@@ -0,0 +1 @@
+singleton GameSettings 1.0 GameSettings.qml
diff --git a/examples/bluetooth/heartrate-server/doc/src/heartrate-server.qdoc b/examples/bluetooth/heartrate-server/doc/src/heartrate-server.qdoc
index 22c6fcd1..34f1b633 100644
--- a/examples/bluetooth/heartrate-server/doc/src/heartrate-server.qdoc
+++ b/examples/bluetooth/heartrate-server/doc/src/heartrate-server.qdoc
@@ -51,7 +51,7 @@
\endlist
The example implements a server application, which means it has no graphical user interface.
- To visualize what it is doing, you can use the \l {heartlistener}{Heart Listener}
+ To visualize what it is doing, you can use the \l {heartrate-game}{Heart Rate Game}
example, which is basically the client-side counterpart to this application.
\note On Linux, advertising requires privileged access, so you need to run
diff --git a/examples/bluetooth/heartrate-server/main.cpp b/examples/bluetooth/heartrate-server/main.cpp
index 779dbb6a..5822831c 100644
--- a/examples/bluetooth/heartrate-server/main.cpp
+++ b/examples/bluetooth/heartrate-server/main.cpp
@@ -49,11 +49,13 @@
#include <QtCore/qbytearray.h>
#include <QtCore/qcoreapplication.h>
#include <QtCore/qlist.h>
+#include <QtCore/qloggingcategory.h>
#include <QtCore/qscopedpointer.h>
#include <QtCore/qtimer.h>
int main(int argc, char *argv[])
{
+ //QLoggingCategory::setFilterRules(QStringLiteral("qt.bluetooth* = true"));
QCoreApplication app(argc, argv);
//! [Advertising Data]