From 283870e39be08e89050377cf2e4584b453cdc4e2 Mon Sep 17 00:00:00 2001 From: Alex Blasche Date: Tue, 28 Feb 2017 15:30:46 +0100 Subject: Add new heartrate example MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The example is a redesign by Lasse Räihä based in the heartrate-listener example. Change-Id: Iec0f48603408b37c7054839d520368eb1e436895 Reviewed-by: Oliver Wolff --- examples/bluetooth/bluetooth.pro | 1 + examples/bluetooth/heartrate-game/README.md | 7 + .../heartrate-game/bluetoothbaseclass.cpp | 77 +++++ .../bluetooth/heartrate-game/bluetoothbaseclass.h | 72 +++++ .../bluetooth/heartrate-game/connectionhandler.cpp | 71 +++++ .../bluetooth/heartrate-game/connectionhandler.h | 71 +++++ examples/bluetooth/heartrate-game/devicefinder.cpp | 159 ++++++++++ examples/bluetooth/heartrate-game/devicefinder.h | 91 ++++++ .../bluetooth/heartrate-game/devicehandler.cpp | 319 +++++++++++++++++++++ examples/bluetooth/heartrate-game/devicehandler.h | 131 +++++++++ examples/bluetooth/heartrate-game/deviceinfo.cpp | 80 ++++++ examples/bluetooth/heartrate-game/deviceinfo.h | 69 +++++ .../bluetooth/heartrate-game/heartrate-game.pro | 28 ++ examples/bluetooth/heartrate-game/images.qrc | 7 + examples/bluetooth/heartrate-game/main.cpp | 67 +++++ examples/bluetooth/heartrate-game/qml.qrc | 18 ++ examples/bluetooth/heartrate-game/qml/App.qml | 120 ++++++++ .../heartrate-game/qml/BluetoothAlarmDialog.qml | 112 ++++++++ .../bluetooth/heartrate-game/qml/BottomLine.qml | 49 ++++ examples/bluetooth/heartrate-game/qml/Connect.qml | 143 +++++++++ .../bluetooth/heartrate-game/qml/GameButton.qml | 78 +++++ examples/bluetooth/heartrate-game/qml/GamePage.qml | 83 ++++++ .../bluetooth/heartrate-game/qml/GameSettings.qml | 91 ++++++ examples/bluetooth/heartrate-game/qml/Measure.qml | 234 +++++++++++++++ .../bluetooth/heartrate-game/qml/SplashScreen.qml | 80 ++++++ examples/bluetooth/heartrate-game/qml/Stats.qml | 89 ++++++ .../bluetooth/heartrate-game/qml/StatsLabel.qml | 72 +++++ examples/bluetooth/heartrate-game/qml/TitleBar.qml | 87 ++++++ .../heartrate-game/qml/images/bt_off_to_on.png | Bin 0 -> 6143 bytes .../bluetooth/heartrate-game/qml/images/heart.png | Bin 0 -> 2664 bytes .../bluetooth/heartrate-game/qml/images/logo.png | Bin 0 -> 31915 bytes examples/bluetooth/heartrate-game/qml/main.qml | 95 ++++++ examples/bluetooth/heartrate-game/qml/qmldir | 1 + 33 files changed, 2602 insertions(+) create mode 100644 examples/bluetooth/heartrate-game/README.md create mode 100644 examples/bluetooth/heartrate-game/bluetoothbaseclass.cpp create mode 100644 examples/bluetooth/heartrate-game/bluetoothbaseclass.h create mode 100644 examples/bluetooth/heartrate-game/connectionhandler.cpp create mode 100644 examples/bluetooth/heartrate-game/connectionhandler.h create mode 100644 examples/bluetooth/heartrate-game/devicefinder.cpp create mode 100644 examples/bluetooth/heartrate-game/devicefinder.h create mode 100644 examples/bluetooth/heartrate-game/devicehandler.cpp create mode 100644 examples/bluetooth/heartrate-game/devicehandler.h create mode 100644 examples/bluetooth/heartrate-game/deviceinfo.cpp create mode 100644 examples/bluetooth/heartrate-game/deviceinfo.h create mode 100644 examples/bluetooth/heartrate-game/heartrate-game.pro create mode 100644 examples/bluetooth/heartrate-game/images.qrc create mode 100644 examples/bluetooth/heartrate-game/main.cpp create mode 100644 examples/bluetooth/heartrate-game/qml.qrc create mode 100644 examples/bluetooth/heartrate-game/qml/App.qml create mode 100644 examples/bluetooth/heartrate-game/qml/BluetoothAlarmDialog.qml create mode 100644 examples/bluetooth/heartrate-game/qml/BottomLine.qml create mode 100644 examples/bluetooth/heartrate-game/qml/Connect.qml create mode 100644 examples/bluetooth/heartrate-game/qml/GameButton.qml create mode 100644 examples/bluetooth/heartrate-game/qml/GamePage.qml create mode 100644 examples/bluetooth/heartrate-game/qml/GameSettings.qml create mode 100644 examples/bluetooth/heartrate-game/qml/Measure.qml create mode 100644 examples/bluetooth/heartrate-game/qml/SplashScreen.qml create mode 100644 examples/bluetooth/heartrate-game/qml/Stats.qml create mode 100644 examples/bluetooth/heartrate-game/qml/StatsLabel.qml create mode 100644 examples/bluetooth/heartrate-game/qml/TitleBar.qml create mode 100644 examples/bluetooth/heartrate-game/qml/images/bt_off_to_on.png create mode 100644 examples/bluetooth/heartrate-game/qml/images/heart.png create mode 100644 examples/bluetooth/heartrate-game/qml/images/logo.png create mode 100644 examples/bluetooth/heartrate-game/qml/main.qml create mode 100644 examples/bluetooth/heartrate-game/qml/qmldir (limited to 'examples') diff --git a/examples/bluetooth/bluetooth.pro b/examples/bluetooth/bluetooth.pro index 1c09dade..39a28174 100644 --- a/examples/bluetooth/bluetooth.pro +++ b/examples/bluetooth/bluetooth.pro @@ -13,4 +13,5 @@ qtHaveModule(quick): SUBDIRS += scanner \ pingpong \ lowenergyscanner \ heartlistener \ + heartrate-game \ chat 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 + +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..6ca3f1d7 --- /dev/null +++ b/examples/bluetooth/heartrate-game/connectionhandler.cpp @@ -0,0 +1,71 @@ +/*************************************************************************** +** +** 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 "connectionhandler.h" +#include + +ConnectionHandler::ConnectionHandler(QObject *parent) : QObject(parent) +{ + connect(&m_localDevice, &QBluetoothLocalDevice::hostModeStateChanged, + this, &ConnectionHandler::hostModeChanged); +} + +bool ConnectionHandler::alive() const +{ +#ifdef Q_OS_WIN32 + return true; +#else + return m_localDevice.isValid() && m_localDevice.hostMode() != QBluetoothLocalDevice::HostPoweredOff; +#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..8c38b8ca --- /dev/null +++ b/examples/bluetooth/heartrate-game/connectionhandler.h @@ -0,0 +1,71 @@ +/*************************************************************************** +** +** 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 +#include + +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_OBJECT +public: + explicit ConnectionHandler(QObject *parent = 0); + + bool alive() 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..0579ad4a --- /dev/null +++ b/examples/bluetooth/heartrate-game/devicefinder.cpp @@ -0,0 +1,159 @@ +/*************************************************************************** +** +** 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" + +#include + +DeviceFinder::DeviceFinder(DeviceHandler *handler, QObject *parent): + BluetoothBaseClass(parent), + m_deviceHandler(handler) +{ + m_deviceDiscoveryAgent = new QBluetoothDeviceDiscoveryAgent(this); + + connect(m_deviceDiscoveryAgent, &QBluetoothDeviceDiscoveryAgent::deviceDiscovered, this, &DeviceFinder::addDevice); + connect(m_deviceDiscoveryAgent, static_cast(&QBluetoothDeviceDiscoveryAgent::error), + this, &DeviceFinder::scanError); + + connect(m_deviceDiscoveryAgent, &QBluetoothDeviceDiscoveryAgent::finished, this, &DeviceFinder::scanFinished); + connect(m_deviceDiscoveryAgent, &QBluetoothDeviceDiscoveryAgent::canceled, this, &DeviceFinder::scanFinished); + + +#ifdef Q_OS_WIN32 + 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 Q_OS_WIN32 + m_demoTimer.start(); +#else + m_deviceDiscoveryAgent->start(); +#endif + emit scanningChanged(); + setInfo(tr("Scanning for devices...")); +} + +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...")); + emit devicesChanged(); + } +} + +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 Q_OS_WIN32 + // Only for testing + for (int i = 0; i < 5; 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 Q_OS_WIN32 + 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..d9ad66ad --- /dev/null +++ b/examples/bluetooth/heartrate-game/devicefinder.h @@ -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$ +** +****************************************************************************/ + +#ifndef DEVICEFINDER_H +#define DEVICEFINDER_H + +#include "bluetoothbaseclass.h" + +#include +#include +#include +#include + +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 m_devices; + +#ifdef Q_OS_WIN32 + 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..da643ff5 --- /dev/null +++ b/examples/bluetooth/heartrate-game/devicehandler.cpp @@ -0,0 +1,319 @@ +/*************************************************************************** +** +** 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 "devicehandler.h" +#include "deviceinfo.h" +#include + +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 Q_OS_WIN32 + m_demoTimer.setSingleShot(false); + m_demoTimer.setInterval(2000); + connect(&m_demoTimer, &QTimer::timeout, this, &DeviceHandler::updateDemoHR); + m_demoTimer.start(); + updateDemoHR(); +#endif +} + +void DeviceHandler::setDevice(DeviceInfo *device) +{ + clearMessages(); + m_currentDevice = device; + +#ifdef Q_OS_WIN32 + 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 + m_control = new QLowEnergyController(m_currentDevice->getDevice(), this); + connect(m_control, &QLowEnergyController::serviceDiscovered, + this, &DeviceHandler::serviceDiscovered); + connect(m_control, &QLowEnergyController::discoveryFinished, + this, &DeviceHandler::serviceScanDone); + + connect(m_control, static_cast(&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(); + } +} + +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(); +} + +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; + } +} + +void DeviceHandler::serviceScanDone() +{ + setInfo("Service scan done."); + + // Delete old service if available + if (m_service) { + delete m_service; + m_service = 0; + } + + // 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."); + } +} + +// Service functions +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(); +} + +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(value.constData()); + quint8 flags = data[0]; + + //Heart Rate + int hrvalue = 0; + if (flags & 0x1) // HR 16 bit? otherwise 8 bit + hrvalue = (int)qFromLittleEndian(data[1]); + else + hrvalue = (int)data[1]; + + addMeasurement(hrvalue); +} + +#ifdef Q_OS_WIN32 +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("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_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 Q_OS_WIN32 + 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/heartrate-game/devicehandler.h b/examples/bluetooth/heartrate-game/devicehandler.h new file mode 100644 index 00000000..d00f0406 --- /dev/null +++ b/examples/bluetooth/heartrate-game/devicehandler.h @@ -0,0 +1,131 @@ +/*************************************************************************** +** +** 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 DEVICEHANDLER_H +#define DEVICEHANDLER_H + +#include "bluetoothbaseclass.h" + +#include +#include +#include +#include +#include + +class DeviceInfo; + +class DeviceHandler : public BluetoothBaseClass +{ + Q_OBJECT + + 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) + +public: + DeviceHandler(QObject *parent = 0); + + void setDevice(DeviceInfo *device); + bool measuring() const; + bool alive() const; + + // Statistics + int hr() const; + int time() const; + float average() const; + int maxHR() const; + int minHR() const; + float calories() const; + +signals: + void measuringChanged(); + void aliveChanged(); + void statsChanged(); + +public slots: + void startMeasurement(); + void stopMeasurement(); + void disconnectService(); + +private: + //QLowEnergyController + void serviceDiscovered(const QBluetoothUuid &); + void serviceScanDone(); + + //QLowEnergyService + void serviceStateChanged(QLowEnergyService::ServiceState s); + void updateHeartRateValue(const QLowEnergyCharacteristic &c, + const QByteArray &value); + void confirmedDescriptorWrite(const QLowEnergyDescriptor &d, + const QByteArray &value); + +#ifdef Q_OS_WIN32 + void updateDemoHR(); +#endif +private: + void addMeasurement(int value); + + QLowEnergyController *m_control; + QLowEnergyService *m_service; + QLowEnergyDescriptor m_notificationDesc; + 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; + + QVector m_measurements; + +#ifdef Q_OS_WIN32 + QTimer m_demoTimer; +#endif +}; + +#endif // DEVICEHANDLER_H diff --git a/examples/bluetooth/heartrate-game/deviceinfo.cpp b/examples/bluetooth/heartrate-game/deviceinfo.cpp new file mode 100644 index 00000000..4d1a3498 --- /dev/null +++ b/examples/bluetooth/heartrate-game/deviceinfo.cpp @@ -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$ +** +****************************************************************************/ + +#include "deviceinfo.h" +#include +#include + +DeviceInfo::DeviceInfo(const QBluetoothDeviceInfo &info): + QObject(), m_device(info) +{ +} + +QBluetoothDeviceInfo DeviceInfo::getDevice() const +{ + return m_device; +} + +QString DeviceInfo::getName() const +{ +#ifdef Q_OS_WIN32 + return "Demo device"; +#else + return m_device.name(); +#endif +} + +QString DeviceInfo::getAddress() const +{ +#ifdef Q_OS_WIN32 + return "00:11:22:33:44:55"; +#elif Q_OS_DARWIN + // workaround for Core Bluetooth: + return m_device.deviceUuid().toString(); +#else + return m_device.address().toString(); +#endif +} + +void DeviceInfo::setDevice(const QBluetoothDeviceInfo &device) +{ + m_device = device; + emit deviceChanged(); +} diff --git a/examples/bluetooth/heartrate-game/deviceinfo.h b/examples/bluetooth/heartrate-game/deviceinfo.h new file mode 100644 index 00000000..bbddbdd4 --- /dev/null +++ b/examples/bluetooth/heartrate-game/deviceinfo.h @@ -0,0 +1,69 @@ +/*************************************************************************** +** +** 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 DEVICEINFO_H +#define DEVICEINFO_H + +#include +#include +#include + +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; + QString getAddress() const; + QBluetoothDeviceInfo getDevice() const; + +signals: + void deviceChanged(); + +private: + QBluetoothDeviceInfo m_device; +}; + +#endif // DEVICEINFO_H diff --git a/examples/bluetooth/heartrate-game/heartrate-game.pro b/examples/bluetooth/heartrate-game/heartrate-game.pro new file mode 100644 index 00000000..5a856b9c --- /dev/null +++ b/examples/bluetooth/heartrate-game/heartrate-game.pro @@ -0,0 +1,28 @@ +TEMPLATE = app +TARGET = heartrate-game + +QT += qml quick bluetooth +CONFIG += c++11 + +HEADERS += \ + connectionhandler.h \ + deviceinfo.h \ + devicefinder.h \ + devicehandler.h \ + bluetoothbaseclass.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/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 @@ + + + qml/images/logo.png + qml/images/bt_off_to_on.png + qml/images/heart.png + + diff --git a/examples/bluetooth/heartrate-game/main.cpp b/examples/bluetooth/heartrate-game/main.cpp new file mode 100644 index 00000000..039b0668 --- /dev/null +++ b/examples/bluetooth/heartrate-game/main.cpp @@ -0,0 +1,67 @@ +/*************************************************************************** +** +** 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 +#include +#include +#include + +#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); + + ConnectionHandler connectionHandler; + DeviceHandler deviceHandler; + DeviceFinder deviceFinder(&deviceHandler); + + 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 @@ + + + qml/BluetoothAlarmDialog.qml + qml/main.qml + qml/SplashScreen.qml + qml/GameSettings.qml + qml/App.qml + qml/TitleBar.qml + qml/Connect.qml + qml/Measure.qml + qml/Stats.qml + qml/GameButton.qml + qml/GamePage.qml + qml/BottomLine.qml + qml/StatsLabel.qml + qml/qmldir + + 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/heartrate-game/qml/BottomLine.qml b/examples/bluetooth/heartrate-game/qml/BottomLine.qml new file mode 100644 index 00000000..af644228 --- /dev/null +++ b/examples/bluetooth/heartrate-game/qml/BottomLine.qml @@ -0,0 +1,49 @@ +/*************************************************************************** +** +** 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 { + anchors.horizontalCenter: parent.horizontalCenter + 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..d3b4a733 --- /dev/null +++ b/examples/bluetooth/heartrate-game/qml/Connect.qml @@ -0,0 +1,143 @@ +/*************************************************************************** +** +** 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 { + + errorMessage: deviceFinder.error + infoMessage: deviceFinder.info + + Rectangle { + id: viewContainer + anchors.top: parent.top + anchors.bottom: 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: 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/heartrate-game/qml/Stats.qml b/examples/bluetooth/heartrate-game/qml/Stats.qml new file mode 100644 index 00000000..6e34d3bc --- /dev/null +++ b/examples/bluetooth/heartrate-game/qml/Stats.qml @@ -0,0 +1,89 @@ +/*************************************************************************** +** +** 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 { + + Column { + anchors.centerIn: parent + width: parent.width + + Text { + anchors.horizontalCenter: parent.horizontalCenter + font.pixelSize: GameSettings.hugeFontSize + color: GameSettings.textColor + text: qsTr("RESULT") + } + + 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) + } + + 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/heartrate-game/qml/StatsLabel.qml b/examples/bluetooth/heartrate-game/qml/StatsLabel.qml new file mode 100644 index 00000000..dd57852f --- /dev/null +++ b/examples/bluetooth/heartrate-game/qml/StatsLabel.qml @@ -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$ +** +****************************************************************************/ + +import QtQuick 2.5 +import "." + +Item { + height: GameSettings.fieldHeight + width: parent.width + + property alias title: leftText.text + property alias value: rightText.text + + Text { + id: leftText + anchors.left: parent.left + height: parent.height + width: parent.width * 0.45 + horizontalAlignment: Text.AlignRight + verticalAlignment: Text.AlignVCenter + font.pixelSize: GameSettings.mediumFontSize + color: GameSettings.textColor + } + + 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 Binary files /dev/null and b/examples/bluetooth/heartrate-game/qml/images/bt_off_to_on.png 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 Binary files /dev/null and b/examples/bluetooth/heartrate-game/qml/images/heart.png 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 Binary files /dev/null and b/examples/bluetooth/heartrate-game/qml/images/logo.png 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 -- cgit v1.2.3