Merge branch 'master' of https://git.itsblue.de/Fenoglio/omobileddisplay
This commit is contained in:
commit
a21f06cb37
30 changed files with 955 additions and 208 deletions
|
@ -1,4 +1,4 @@
|
||||||
QT += quick bluetooth
|
QT += quick bluetooth quickcontrols2
|
||||||
CONFIG += c++11
|
CONFIG += c++11
|
||||||
|
|
||||||
TARGET = OmobiDisplayApp
|
TARGET = OmobiDisplayApp
|
||||||
|
@ -20,7 +20,11 @@ HEADERS += \
|
||||||
|
|
||||||
RESOURCES += \
|
RESOURCES += \
|
||||||
ressources/qml/qml.qrc \
|
ressources/qml/qml.qrc \
|
||||||
ressources/shared/shared.qrc
|
ressources/shared/shared.qrc \
|
||||||
|
ressources/translations/translations.qrc
|
||||||
|
|
||||||
|
TRANSLATIONS += \
|
||||||
|
ressources/translations/de.ts
|
||||||
|
|
||||||
# Additional import path used to resolve QML modules in Qt Creator's code model
|
# Additional import path used to resolve QML modules in Qt Creator's code model
|
||||||
QML_IMPORT_PATH =
|
QML_IMPORT_PATH =
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 76e457593e889885fd410fdbcdd659706a1eceb8
|
Subproject commit 534277a19867f2e41a2699fc863e1cae48dee741
|
|
@ -1,7 +1,8 @@
|
||||||
#include <QGuiApplication>
|
#include <QGuiApplication>
|
||||||
#include <QQmlApplicationEngine>
|
#include <QQmlApplicationEngine>
|
||||||
#include <QQuickStyle>
|
#include <QQuickStyle>
|
||||||
#include <qbluetoothleuart.h>
|
#include <qbluetoothleuartclient.h>
|
||||||
|
#include <QTranslator>
|
||||||
|
|
||||||
#include "omobidisplaybackend.h"
|
#include "omobidisplaybackend.h"
|
||||||
#include "omobidisplaytextmodel.h"
|
#include "omobidisplaytextmodel.h"
|
||||||
|
@ -12,9 +13,14 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
QGuiApplication app(argc, argv);
|
QGuiApplication app(argc, argv);
|
||||||
|
|
||||||
|
QTranslator translator;
|
||||||
|
translator.load(":/" + QLocale::system().name() + ".qm");
|
||||||
|
translator.load(":/de.qm");
|
||||||
|
app.installTranslator(&translator);
|
||||||
|
|
||||||
qmlRegisterType<OmobiDisplayBackend>("de.itsblue.omobidisplayapp", 1, 0, "OmobiDisplayBackend");
|
qmlRegisterType<OmobiDisplayBackend>("de.itsblue.omobidisplayapp", 1, 0, "OmobiDisplayBackend");
|
||||||
qmlRegisterUncreatableType<OmobiDisplayTextModel>("de.itsblue.omobidisplayapp", 1, 0, "OmobiDisplayTextModel", "OmobiDisplayTextModel cannot be created");
|
qmlRegisterUncreatableType<OmobiDisplayTextModel>("de.itsblue.omobidisplayapp", 1, 0, "OmobiDisplayTextModel", "OmobiDisplayTextModel cannot be created");
|
||||||
QBluetoothLeUart::init();
|
QBluetoothLeUartClient::init();
|
||||||
|
|
||||||
QQuickStyle::setStyle("Material");
|
QQuickStyle::setStyle("Material");
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
OmobiDisplayBackend::OmobiDisplayBackend(QObject *parent) : QObject(parent)
|
OmobiDisplayBackend::OmobiDisplayBackend(QObject *parent) : QObject(parent)
|
||||||
{
|
{
|
||||||
this->ble = new QBluetoothLeUart();
|
this->bleClient = new QBluetoothLeUartClient();
|
||||||
this->ble->setUUIDs("92fecb20-1406-426a-afa5-cd5c1f306462", "92fecb21-1406-426a-afa5-cd5c1f306462", "92fecb22-1406-426a-afa5-cd5c1f306462");
|
this->bleClient->setUUIDs("92fecb20-1406-426a-afa5-cd5c1f306462", "92fecb21-1406-426a-afa5-cd5c1f306462", "92fecb22-1406-426a-afa5-cd5c1f306462");
|
||||||
this->displayTextModel = new OmobiDisplayTextModel(this);
|
this->displayTextModel = new OmobiDisplayTextModel(this);
|
||||||
this->textSetsBuffer.clear();
|
this->textSetsBuffer.clear();
|
||||||
this->displayBrightness = -1;
|
this->displayBrightness = -1;
|
||||||
|
@ -14,72 +14,74 @@ OmobiDisplayBackend::OmobiDisplayBackend(QObject *parent) : QObject(parent)
|
||||||
this->keepAliveTimer->setSingleShot(false);
|
this->keepAliveTimer->setSingleShot(false);
|
||||||
connect(this->keepAliveTimer, &QTimer::timeout, this, &OmobiDisplayBackend::sendBluetoothKeepAlive);
|
connect(this->keepAliveTimer, &QTimer::timeout, this, &OmobiDisplayBackend::sendBluetoothKeepAlive);
|
||||||
|
|
||||||
connect(this->ble, &QBluetoothLeUart::stateChanged, this, &OmobiDisplayBackend::handleBluetoothStateChange);
|
connect(this->bleClient, &QBluetoothLeUartClient::stateChanged, this, &OmobiDisplayBackend::handleBluetoothStateChange);
|
||||||
connect(this->ble, &QBluetoothLeUart::foundNewDevice, this, &OmobiDisplayBackend::handleFoundNewDevice);
|
connect(this->bleClient, &QBluetoothLeUartClient::foundNewDevice, this, &OmobiDisplayBackend::handleFoundNewDevice);
|
||||||
connect(this->ble, &QBluetoothLeUart::dataReceived, this, &OmobiDisplayBackend::handleBluetoothDataReceived);
|
connect(this->bleClient, &QBluetoothLeUartClient::dataReceived, this, &OmobiDisplayBackend::handleBluetoothDataReceived);
|
||||||
connect(this->ble, &QBluetoothLeUart::connectedToDevice, this, &OmobiDisplayBackend::handleBluetoothDeviceConected);
|
connect(this->bleClient, &QBluetoothLeUartClient::connectedToDevice, this, &OmobiDisplayBackend::handleBluetoothDeviceConected);
|
||||||
connect(this->displayTextModel, &OmobiDisplayTextModel::dataChanged, this, &OmobiDisplayBackend::handleDisplayTextModelDataChanged);
|
connect(this->displayTextModel, &OmobiDisplayTextModel::dataChanged, this, &OmobiDisplayBackend::handleDisplayTextModelDataChanged);
|
||||||
connect(this->displayTextModel, &OmobiDisplayTextModel::rowsInserted, this, &OmobiDisplayBackend::handleDisplayTextModelRowsInserted);
|
connect(this->displayTextModel, &OmobiDisplayTextModel::rowsInserted, this, &OmobiDisplayBackend::handleDisplayTextModelRowsInserted);
|
||||||
connect(this->displayTextModel, &OmobiDisplayTextModel::rowsRemoved, this, &OmobiDisplayBackend::handleDisplayTextModelRowsRemoved);
|
connect(this->displayTextModel, &OmobiDisplayTextModel::rowsRemoved, this, &OmobiDisplayBackend::handleDisplayTextModelRowsRemoved);
|
||||||
|
|
||||||
this->setState(Idle);
|
this->setState(Idle);
|
||||||
this->ble->startScanningForDevices();
|
this->bleClient->startScanningForDevices();
|
||||||
|
|
||||||
qDebug() << QCryptographicHash::hash("HalloTest", QCryptographicHash::Sha256).toHex();
|
|
||||||
// dd86fcfda3a20cbb8fbb3026a84550e0d70c2c79e7e8e36d6ffa04b9eef0401f
|
|
||||||
// dd86fcfda3a20cbb8fbb3026a84550e0d70c2c79e7e8e36d6ffa04b9eef0401f
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void OmobiDisplayBackend::startScanning() {
|
void OmobiDisplayBackend::startScanning() {
|
||||||
this->ble->startScanningForDevices();
|
this->bleClient->startScanningForDevices();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OmobiDisplayBackend::handleBluetoothStateChange(QBluetoothLeUart::BluetoothLeUartState state){
|
void OmobiDisplayBackend::authenticate(QString code) {
|
||||||
|
// tell display to send over existing model data
|
||||||
|
this->setState(Authenticating);
|
||||||
|
QString combinedCode = this->bleClient->getCurrentDevice()->getAddress().toUpper() + code;
|
||||||
|
QString secret = QCryptographicHash::hash(combinedCode.toUtf8(), QCryptographicHash::Sha256).toHex();
|
||||||
|
|
||||||
|
this->sendBluetoothCommand(AuthorizeSessionCommand, QVariantMap{{"secret", secret}});
|
||||||
|
}
|
||||||
|
|
||||||
|
void OmobiDisplayBackend::handleBluetoothStateChange(QBluetoothLeUartClient::BluetoothLeUartClientState state){
|
||||||
switch(state){
|
switch(state){
|
||||||
case QBluetoothLeUart::Idle: {
|
case QBluetoothLeUartClient::Idle: {
|
||||||
this->setState(Idle);
|
this->setState(Idle);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case QBluetoothLeUart::Scanning: {
|
case QBluetoothLeUartClient::Scanning: {
|
||||||
this->setState(Scanning);
|
this->setState(Scanning);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case QBluetoothLeUart::ScanFinished: {
|
case QBluetoothLeUartClient::ScanFinished: {
|
||||||
this->setState(ReadyToConnect);
|
this->setState(ReadyToConnect);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case QBluetoothLeUart::Connecting: {
|
case QBluetoothLeUartClient::Connecting: {
|
||||||
this->setState(Connecting);
|
this->setState(Connecting);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case QBluetoothLeUart::ScanningForService: {
|
case QBluetoothLeUartClient::ScanningForService: {
|
||||||
this->setState(Connecting);
|
this->setState(Connecting);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case QBluetoothLeUart::ServiceFound: {
|
case QBluetoothLeUartClient::ServiceFound: {
|
||||||
this->setState(Connecting);
|
this->setState(Connecting);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case QBluetoothLeUart::Connected:
|
case QBluetoothLeUartClient::Connected:
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(state == QBluetoothLeUart::Connected)
|
if(state == QBluetoothLeUartClient::Connected)
|
||||||
this->keepAliveTimer->start();
|
this->keepAliveTimer->start();
|
||||||
else if(this->keepAliveTimer->isActive())
|
else if(this->keepAliveTimer->isActive())
|
||||||
this->keepAliveTimer->stop();
|
this->keepAliveTimer->stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OmobiDisplayBackend::handleBluetoothDeviceConected() {
|
void OmobiDisplayBackend::handleBluetoothDeviceConected() {
|
||||||
this->setState(Initing);
|
this->setState(AuthenticationRequired);
|
||||||
|
this->authenticate("1234");
|
||||||
// tell display to send over existing model data
|
// TODO: stuff
|
||||||
this->sendBluetoothCommand(AuthorizeSessionCommand, QVariantMap{{"secret", QCryptographicHash::hash("1234", QCryptographicHash::Sha256).toHex()}});
|
|
||||||
this->sendBluetoothCommand(GetAllTextSetsCommand);
|
|
||||||
this->sendBluetoothCommand(GetDisplayBrightnessCommand);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OmobiDisplayBackend::handleFoundNewDevice(QBluetoothLeUartDevice* device) {
|
void OmobiDisplayBackend::handleFoundNewDevice(QBluetoothLeUartDevice* device) {
|
||||||
|
@ -123,7 +125,7 @@ void OmobiDisplayBackend::sendBluetoothCommand(OmobiDisplayCommand command, QVar
|
||||||
if(this->state == Connected)
|
if(this->state == Connected)
|
||||||
this->setState(Loading);
|
this->setState(Loading);
|
||||||
|
|
||||||
this->ble->sendData(doc.toJson(QJsonDocument::Compact));
|
this->bleClient->sendData(doc.toJson(QJsonDocument::Compact));
|
||||||
}
|
}
|
||||||
|
|
||||||
void OmobiDisplayBackend::sendBluetoothKeepAlive() {
|
void OmobiDisplayBackend::sendBluetoothKeepAlive() {
|
||||||
|
@ -131,7 +133,7 @@ void OmobiDisplayBackend::sendBluetoothKeepAlive() {
|
||||||
|
|
||||||
qDebug() << "Sending keep alive: \n" << qPrintable(doc.toJson(QJsonDocument::Indented));
|
qDebug() << "Sending keep alive: \n" << qPrintable(doc.toJson(QJsonDocument::Indented));
|
||||||
|
|
||||||
this->ble->sendData(doc.toJson(QJsonDocument::Compact));
|
this->bleClient->sendData(doc.toJson(QJsonDocument::Compact));
|
||||||
}
|
}
|
||||||
|
|
||||||
void OmobiDisplayBackend::handleBluetoothDataReceived(QString s){
|
void OmobiDisplayBackend::handleBluetoothDataReceived(QString s){
|
||||||
|
@ -149,8 +151,16 @@ void OmobiDisplayBackend::handleBluetoothDataReceived(QString s){
|
||||||
|
|
||||||
switch (header) {
|
switch (header) {
|
||||||
case AuthorizeSessionCommand: {
|
case AuthorizeSessionCommand: {
|
||||||
// TODO: handle error
|
if(status != Success) {
|
||||||
this->refreshLoadingState();
|
this->setState(AuthenticationRequired);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->waitingCommands = 0;
|
||||||
|
this->setState(Initing);
|
||||||
|
this->sendBluetoothCommand(GetAllTextSetsCommand);
|
||||||
|
this->sendBluetoothCommand(GetDisplayBrightnessCommand);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case KeepAliveCommand: {
|
case KeepAliveCommand: {
|
||||||
|
@ -200,16 +210,14 @@ void OmobiDisplayBackend::handleBluetoothDataReceived(QString s){
|
||||||
this->refreshLoadingState();
|
this->refreshLoadingState();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SetTextSetParameterCommand: {
|
case SetTextSetParameterCommand:
|
||||||
|
case SetDisplayBrightnessCommand:
|
||||||
|
case SetDisplayCodeCommand:
|
||||||
|
case SetDisplayNameCommand:
|
||||||
// TODO: Error handling
|
// TODO: Error handling
|
||||||
this->refreshLoadingState();
|
this->refreshLoadingState();
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case SetDisplayBrightnessCommand: {
|
|
||||||
// TODO: Error handling
|
|
||||||
this->refreshLoadingState();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -233,8 +241,8 @@ void OmobiDisplayBackend::updateDisplayTextSetParameter(int index, int parameter
|
||||||
this->sendBluetoothCommand(SetTextSetParameterCommand, dataMap);
|
this->sendBluetoothCommand(SetTextSetParameterCommand, dataMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
QBluetoothLeUart* OmobiDisplayBackend::getBleController() {
|
QBluetoothLeUartClient* OmobiDisplayBackend::getBleClient() {
|
||||||
return this->ble;
|
return this->bleClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -270,7 +278,7 @@ void OmobiDisplayBackend::setState(OmobiDisplayAppState state) {
|
||||||
qDebug() << "Now in " << state << " state";
|
qDebug() << "Now in " << state << " state";
|
||||||
|
|
||||||
if(this->state == Idle)
|
if(this->state == Idle)
|
||||||
this->ble->startScanningForDevices();
|
this->bleClient->startScanningForDevices();
|
||||||
}
|
}
|
||||||
|
|
||||||
int OmobiDisplayBackend::getDisplayBrightness() {
|
int OmobiDisplayBackend::getDisplayBrightness() {
|
||||||
|
@ -287,3 +295,13 @@ void OmobiDisplayBackend::setDisplayBrightness(int brightness) {
|
||||||
|
|
||||||
emit this->displayBrightnessChanged();
|
emit this->displayBrightnessChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void OmobiDisplayBackend::setDisplayCode(QString code) {
|
||||||
|
this->sendBluetoothCommand(SetDisplayCodeCommand, QVariantMap{{"displayCode",code}});
|
||||||
|
}
|
||||||
|
|
||||||
|
void OmobiDisplayBackend::setDisplayName(QString name) {
|
||||||
|
// This will restart the display!!
|
||||||
|
this->sendBluetoothCommand(SetDisplayNameCommand, QVariantMap{{"displayName", name}});
|
||||||
|
}
|
||||||
|
|
|
@ -6,13 +6,13 @@
|
||||||
#include <QJsonDocument>
|
#include <QJsonDocument>
|
||||||
#include <QCryptographicHash>
|
#include <QCryptographicHash>
|
||||||
|
|
||||||
#include <qbluetoothleuart.h>
|
#include <qbluetoothleuartclient.h>
|
||||||
#include <omobidisplaytextmodel.h>
|
#include <omobidisplaytextmodel.h>
|
||||||
|
|
||||||
class OmobiDisplayBackend : public QObject
|
class OmobiDisplayBackend : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY(QBluetoothLeUart* bleController READ getBleController NOTIFY bleControllerChanged)
|
Q_PROPERTY(QBluetoothLeUartClient* bleClient READ getBleClient NOTIFY bleClientChanged)
|
||||||
Q_PROPERTY(OmobiDisplayAppState state READ getState WRITE setState NOTIFY stateChanged)
|
Q_PROPERTY(OmobiDisplayAppState state READ getState WRITE setState NOTIFY stateChanged)
|
||||||
Q_PROPERTY(OmobiDisplayTextModel* displayTextModel READ getDisplayTextModel NOTIFY displayTextModelChanged)
|
Q_PROPERTY(OmobiDisplayTextModel* displayTextModel READ getDisplayTextModel NOTIFY displayTextModelChanged)
|
||||||
Q_PROPERTY(int displayBrightness READ getDisplayBrightness WRITE setDisplayBrightness NOTIFY displayBrightnessChanged)
|
Q_PROPERTY(int displayBrightness READ getDisplayBrightness WRITE setDisplayBrightness NOTIFY displayBrightnessChanged)
|
||||||
|
@ -25,6 +25,8 @@ public:
|
||||||
Scanning,
|
Scanning,
|
||||||
ReadyToConnect,
|
ReadyToConnect,
|
||||||
Connecting,
|
Connecting,
|
||||||
|
AuthenticationRequired,
|
||||||
|
Authenticating,
|
||||||
Initing,
|
Initing,
|
||||||
Connected,
|
Connected,
|
||||||
Loading
|
Loading
|
||||||
|
@ -39,7 +41,9 @@ private:
|
||||||
GetTextSetParameterCommand = 11,
|
GetTextSetParameterCommand = 11,
|
||||||
GetDisplayBrightnessCommand = 12,
|
GetDisplayBrightnessCommand = 12,
|
||||||
SetTextSetParameterCommand = 20,
|
SetTextSetParameterCommand = 20,
|
||||||
SetDisplayBrightnessCommand = 21
|
SetDisplayBrightnessCommand = 21,
|
||||||
|
SetDisplayCodeCommand = 22,
|
||||||
|
SetDisplayNameCommand = 23
|
||||||
};
|
};
|
||||||
|
|
||||||
enum OmobiDisplayStatusCode {
|
enum OmobiDisplayStatusCode {
|
||||||
|
@ -48,7 +52,7 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
OmobiDisplayAppState state;
|
OmobiDisplayAppState state;
|
||||||
QBluetoothLeUart *ble;
|
QBluetoothLeUartClient *bleClient;
|
||||||
QTimer *keepAliveTimer;
|
QTimer *keepAliveTimer;
|
||||||
OmobiDisplayTextModel* displayTextModel;
|
OmobiDisplayTextModel* displayTextModel;
|
||||||
int waitingCommands;
|
int waitingCommands;
|
||||||
|
@ -57,14 +61,17 @@ private:
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
Q_INVOKABLE void startScanning();
|
Q_INVOKABLE void startScanning();
|
||||||
Q_INVOKABLE QBluetoothLeUart* getBleController();
|
Q_INVOKABLE void authenticate(QString secret);
|
||||||
|
Q_INVOKABLE QBluetoothLeUartClient* getBleClient();
|
||||||
Q_INVOKABLE OmobiDisplayAppState getState();
|
Q_INVOKABLE OmobiDisplayAppState getState();
|
||||||
Q_INVOKABLE OmobiDisplayTextModel* getDisplayTextModel();
|
Q_INVOKABLE OmobiDisplayTextModel* getDisplayTextModel();
|
||||||
Q_INVOKABLE int getDisplayBrightness();
|
Q_INVOKABLE int getDisplayBrightness();
|
||||||
Q_INVOKABLE void setDisplayBrightness(int brightness);
|
Q_INVOKABLE void setDisplayBrightness(int brightness);
|
||||||
|
Q_INVOKABLE void setDisplayCode(QString code);
|
||||||
|
Q_INVOKABLE void setDisplayName(QString name);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void handleBluetoothStateChange(QBluetoothLeUart::BluetoothLeUartState state);
|
void handleBluetoothStateChange(QBluetoothLeUartClient::BluetoothLeUartClientState state);
|
||||||
void handleFoundNewDevice(QBluetoothLeUartDevice* device);
|
void handleFoundNewDevice(QBluetoothLeUartDevice* device);
|
||||||
void handleBluetoothDeviceConected();
|
void handleBluetoothDeviceConected();
|
||||||
|
|
||||||
|
@ -83,7 +90,7 @@ private slots:
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void stateChanged();
|
void stateChanged();
|
||||||
void bleControllerChanged();
|
void bleClientChanged();
|
||||||
void displayTextModelChanged();
|
void displayTextModelChanged();
|
||||||
void displayBrightnessChanged();
|
void displayBrightnessChanged();
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
import QtQuick 2.12
|
import QtQuick 2.12
|
||||||
import QtQuick.Controls 2.12
|
import QtQuick.Controls 2.12
|
||||||
import QtGraphicalEffects 1.12
|
import QtGraphicalEffects 1.12
|
||||||
|
import QtQuick.Templates 2.12 as T
|
||||||
|
import QtQuick.Controls.impl 2.12
|
||||||
|
import QtQuick.Controls.Material 2.12
|
||||||
|
import QtQuick.Controls.Material.impl 2.12
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: control
|
id: control
|
||||||
|
@ -10,11 +14,12 @@ Item {
|
||||||
property string text: ""
|
property string text: ""
|
||||||
property string color: ""
|
property string color: ""
|
||||||
property bool isDarkColor: control.checkIsDarkColor(color)
|
property bool isDarkColor: control.checkIsDarkColor(color)
|
||||||
property double glowRadius: 0.001
|
property double glowRadius: 0.01
|
||||||
property double glowSpread: 0.2
|
property double glowSpread: 0.01
|
||||||
property bool glowVisible: true
|
property bool glowVisible: true
|
||||||
property double glowScale: 0.9
|
property double glowScale: 1
|
||||||
property double glowOpacity: Math.pow( control.opacity, 100 )
|
property double glowOpacity: Math.pow( control.opacity, 100 ) * 0.5
|
||||||
|
property bool interactive: true
|
||||||
|
|
||||||
signal clicked
|
signal clicked
|
||||||
|
|
||||||
|
@ -49,10 +54,42 @@ Item {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
color: control.color
|
color: control.color
|
||||||
radius: height * 0.5
|
radius: height * 0.5
|
||||||
|
clip: true
|
||||||
|
|
||||||
Behavior on color {
|
Behavior on color {
|
||||||
ColorAnimation {}
|
ColorAnimation {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Ripple {
|
||||||
|
id: ripple
|
||||||
|
clipRadius: height
|
||||||
|
clip: true
|
||||||
|
width: parent.width
|
||||||
|
height: parent.height
|
||||||
|
pressed: mouseArea.pressed
|
||||||
|
anchor: background
|
||||||
|
active: mouseArea.pressed || mouseArea.visualFocus || mouseArea.containsMouse
|
||||||
|
color: control.Material.rippleColor
|
||||||
|
|
||||||
|
layer.enabled: true
|
||||||
|
layer.effect: OpacityMask {
|
||||||
|
maskSource: Item {
|
||||||
|
width: ripple.width
|
||||||
|
height: ripple.height
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
radius: Math.min(width, height) * 0.5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ColorOverlay {
|
||||||
|
source: ripple
|
||||||
|
color: "red"
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
|
@ -75,7 +112,7 @@ Item {
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: mouseArea
|
id: mouseArea
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
enabled: control.enabled
|
enabled: control.enabled && control.interactive
|
||||||
onClicked: control.clicked()
|
onClicked: control.clicked()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,10 +44,11 @@ ItemDelegate {
|
||||||
}
|
}
|
||||||
|
|
||||||
font.pixelSize: parent.height * 0.5
|
font.pixelSize: parent.height * 0.5
|
||||||
|
font.styleName: fontAwesome.name
|
||||||
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
|
||||||
text: ">"
|
text: "\uf105"
|
||||||
}
|
}
|
||||||
|
|
||||||
Dialog {
|
Dialog {
|
||||||
|
|
|
@ -42,12 +42,13 @@ ItemDelegate {
|
||||||
}
|
}
|
||||||
|
|
||||||
font.pixelSize: parent.height * 0.5
|
font.pixelSize: parent.height * 0.5
|
||||||
|
font.styleName: fontAwesome.name
|
||||||
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
|
||||||
color: control.Material.foreground
|
color: control.Material.foreground
|
||||||
|
|
||||||
text: ">"
|
text: "\uf105"
|
||||||
}
|
}
|
||||||
|
|
||||||
Dialog {
|
Dialog {
|
||||||
|
|
|
@ -4,38 +4,72 @@ import QtQuick.Layouts 1.0
|
||||||
import de.itsblue.omobidisplayapp 1.0
|
import de.itsblue.omobidisplayapp 1.0
|
||||||
import de.itsblue.bluetoothleuart 1.0
|
import de.itsblue.bluetoothleuart 1.0
|
||||||
import QtQuick.Controls.Material 2.0
|
import QtQuick.Controls.Material 2.0
|
||||||
|
import QtGraphicalEffects 1.0
|
||||||
|
|
||||||
Page {
|
Page {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
property bool actionButtonVisible: false
|
||||||
|
property bool backButtonVisible: false
|
||||||
property string statusText
|
property string statusText
|
||||||
property bool working
|
property bool working
|
||||||
|
|
||||||
|
title: qsTr("Available displays")
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
|
id: mainLayout
|
||||||
anchors {
|
anchors {
|
||||||
fill: parent
|
fill: parent
|
||||||
margins: parent.height * 0.01
|
margins: Math.min(parent.height, parent.width) * 0.05
|
||||||
topMargin: 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
Chip {
|
||||||
Layout.preferredWidth: parent.width * 0.6
|
Layout.fillWidth: true
|
||||||
Layout.preferredHeight: parent.height * 0.1
|
Layout.preferredHeight: mainLayout.height * 0.05
|
||||||
Layout.alignment: Layout.Center
|
Layout.alignment: Layout.Center
|
||||||
|
|
||||||
|
color: "white"
|
||||||
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
onClicked: {
|
||||||
horizontalAlignment: Text.AlignHCenter
|
backend.bleClient.startScanningForDevices()
|
||||||
|
}
|
||||||
|
|
||||||
fontSizeMode: Text.Fit
|
RowLayout {
|
||||||
font.pixelSize: 500
|
spacing: mainLayout.anchors.margins
|
||||||
minimumPixelSize: 1
|
|
||||||
|
|
||||||
text: qsTr("Available devices")
|
anchors.fill: parent
|
||||||
|
anchors.leftMargin: width * 0.05
|
||||||
|
anchors.rightMargin: 0
|
||||||
|
|
||||||
|
Text {
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.fillWidth: true
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
font.pixelSize: parent.height * 0.4
|
||||||
|
text: root.statusText
|
||||||
|
}
|
||||||
|
|
||||||
|
BusyIndicator {
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.preferredWidth: height
|
||||||
|
|
||||||
|
id: busyIndicator
|
||||||
|
|
||||||
|
scale: 0.8
|
||||||
|
|
||||||
|
opacity: root.working ? 1:0
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: mainLayout.height * 0.025
|
||||||
}
|
}
|
||||||
|
|
||||||
ListView {
|
ListView {
|
||||||
id: availableDevicesListView
|
id: availableDisplaysListView
|
||||||
|
|
||||||
Layout.preferredWidth: parent.width
|
Layout.preferredWidth: parent.width
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
|
@ -44,7 +78,7 @@ Page {
|
||||||
clip: true
|
clip: true
|
||||||
boundsBehavior: Flickable.OvershootBounds
|
boundsBehavior: Flickable.OvershootBounds
|
||||||
|
|
||||||
model: backend.bleController.availableDevicesModel
|
model: backend.bleClient.availableDevicesModel
|
||||||
|
|
||||||
add: Transition {
|
add: Transition {
|
||||||
NumberAnimation { property: "opacity"; from: 0; to: 1; duration: 200 }
|
NumberAnimation { property: "opacity"; from: 0; to: 1; duration: 200 }
|
||||||
|
@ -58,64 +92,19 @@ Page {
|
||||||
|
|
||||||
spacing: 5
|
spacing: 5
|
||||||
|
|
||||||
header: ItemDelegate {
|
|
||||||
id: headerDelegate
|
|
||||||
|
|
||||||
width: parent.width
|
|
||||||
height: implicitHeight * 0.8
|
|
||||||
|
|
||||||
topInset: 10
|
|
||||||
bottomInset: 10
|
|
||||||
|
|
||||||
text: root.statusText
|
|
||||||
|
|
||||||
onClicked: backend.bleController.startScanningForDevices()
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
anchors.fill: parent
|
|
||||||
anchors.topMargin: 10
|
|
||||||
anchors.bottomMargin: 10
|
|
||||||
color: "transparent"
|
|
||||||
border.color: "lightgrey"
|
|
||||||
border.width: 3
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
anchors {
|
|
||||||
right: parent.right
|
|
||||||
rightMargin: parent.height * 0.15
|
|
||||||
verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
height: (parent.height - 20) * 0.7
|
|
||||||
width: height
|
|
||||||
|
|
||||||
BusyIndicator {
|
|
||||||
id: busyIndicator
|
|
||||||
|
|
||||||
anchors.centerIn: parent
|
|
||||||
|
|
||||||
width: parent.width
|
|
||||||
height: parent.height
|
|
||||||
|
|
||||||
opacity: root.working ? 1:0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
delegate: ItemDelegate {
|
delegate: ItemDelegate {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
|
|
||||||
text: name
|
text: name
|
||||||
|
|
||||||
onClicked: backend.bleController.connectToDevice(device)
|
onClicked: backend.bleClient.connectToDevice(device)
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors {
|
anchors {
|
||||||
top: parent.top
|
top: parent.top
|
||||||
left: parent.left
|
left: parent.left
|
||||||
right: parent.right
|
right: parent.right
|
||||||
topMargin: - availableDevicesListView.spacing * 0.5
|
topMargin: - availableDisplaysListView.spacing * 0.5
|
||||||
}
|
}
|
||||||
|
|
||||||
color: "lightgrey"
|
color: "lightgrey"
|
||||||
|
@ -123,6 +112,100 @@ Page {
|
||||||
visible: index !== 0
|
visible: index !== 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
|
||||||
|
width: Math.min(parent.height, parent.width)
|
||||||
|
height: Math.min(parent.height, parent.width)
|
||||||
|
|
||||||
|
opacity: availableDisplaysListView.model.rowCount === 0 ? 1:0
|
||||||
|
|
||||||
|
Behavior on opacity {
|
||||||
|
NumberAnimation {}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: noDisplaysRect
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
top: parent.top
|
||||||
|
topMargin: parent.height * 0.2
|
||||||
|
horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
width: parent.width * 0.7
|
||||||
|
height: width * 0.3
|
||||||
|
|
||||||
|
color: "transparent"
|
||||||
|
|
||||||
|
border.width: height * 0.15
|
||||||
|
border.color: "lightgrey"
|
||||||
|
|
||||||
|
Text {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
anchors.verticalCenterOffset: text === "..." ? -height * 0.25:0
|
||||||
|
color: "lightgrey"
|
||||||
|
font.pixelSize: parent.height * 0.6
|
||||||
|
font.bold: true
|
||||||
|
text: parseInt(root.state) === OmobiDisplayBackend.Scanning ? "...":"?"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: noDisplaysText
|
||||||
|
anchors {
|
||||||
|
top: noDisplaysRect.bottom
|
||||||
|
topMargin: noDisplaysRect.height * 0.15
|
||||||
|
horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
font.bold: true
|
||||||
|
font.pixelSize: noDisplaysRect.height * 0.3
|
||||||
|
|
||||||
|
color: Qt.darker("lightgrey", 1.1)
|
||||||
|
text: parseInt(root.state) === OmobiDisplayBackend.Scanning ? qsTr("Still scanning"):qsTr("No displays found")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Dialog {
|
||||||
|
id: authenticationDialog
|
||||||
|
|
||||||
|
property bool shouldBeOpened: false
|
||||||
|
|
||||||
|
parent: Overlay.overlay
|
||||||
|
x: (parent.width - width) / 2
|
||||||
|
y: (parent.height - height) / 2
|
||||||
|
|
||||||
|
width: parent.width * 0.9
|
||||||
|
|
||||||
|
modal: true
|
||||||
|
closePolicy: Popup.NoAutoClose
|
||||||
|
standardButtons: Dialog.Ok | Dialog.Cancel
|
||||||
|
|
||||||
|
title: qsTr("Input code")
|
||||||
|
|
||||||
|
onShouldBeOpenedChanged: {
|
||||||
|
if(shouldBeOpened)
|
||||||
|
open()
|
||||||
|
else
|
||||||
|
close()
|
||||||
|
}
|
||||||
|
|
||||||
|
onAccepted: {
|
||||||
|
backend.authenticate(secretTextInput.text)
|
||||||
|
}
|
||||||
|
|
||||||
|
onRejected: {
|
||||||
|
backend.bleClient.disconnectFromDevice()
|
||||||
|
}
|
||||||
|
|
||||||
|
contentItem: TextField {
|
||||||
|
id: secretTextInput
|
||||||
|
placeholderText: qsTr("code")
|
||||||
|
Keys.onReturnPressed: authenticationDialog.accept()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,7 +215,7 @@ Page {
|
||||||
|
|
||||||
PropertyChanges {
|
PropertyChanges {
|
||||||
target: root
|
target: root
|
||||||
statusText: "Tap here to scan"
|
statusText: qsTr("Tap here to scan")
|
||||||
working: false
|
working: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -141,7 +224,7 @@ Page {
|
||||||
|
|
||||||
PropertyChanges {
|
PropertyChanges {
|
||||||
target: root
|
target: root
|
||||||
statusText: "Scanning..."
|
statusText: qsTr("Scanning...")
|
||||||
working: true
|
working: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -150,21 +233,56 @@ Page {
|
||||||
|
|
||||||
PropertyChanges {
|
PropertyChanges {
|
||||||
target: root
|
target: root
|
||||||
statusText: availableDevicesListView.model.rowCount() > 0 ? "Please select a device or tap to scan again":"No devices found. Tap to scan again"
|
statusText: availableDisplaysListView.model.rowCount > 0 ? qsTr("Please select a device or tap to scan again"):qsTr("No displays found. Tap to scan again")
|
||||||
working: false
|
working: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
State {
|
State {
|
||||||
name: OmobiDisplayBackend.Connecting
|
name: OmobiDisplayBackend.AuthenticationRequired
|
||||||
|
|
||||||
PropertyChanges {
|
PropertyChanges {
|
||||||
target: availableDevicesListView
|
target: authenticationDialog
|
||||||
|
shouldBeOpened: true
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertyChanges {
|
||||||
|
target: availableDisplaysListView
|
||||||
enabled: false
|
enabled: false
|
||||||
}
|
}
|
||||||
|
|
||||||
PropertyChanges {
|
PropertyChanges {
|
||||||
target: root
|
target: root
|
||||||
statusText: "trying to connect..."
|
statusText: qsTr("trying to authenticate...")
|
||||||
|
working: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: OmobiDisplayBackend.Authenticating
|
||||||
|
|
||||||
|
PropertyChanges {
|
||||||
|
target: availableDisplaysListView
|
||||||
|
enabled: false
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertyChanges {
|
||||||
|
target: root
|
||||||
|
statusText: qsTr("trying to authenticate...")
|
||||||
|
working: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
State {
|
||||||
|
name: OmobiDisplayBackend.Connecting
|
||||||
|
|
||||||
|
PropertyChanges {
|
||||||
|
target: availableDisplaysListView
|
||||||
|
enabled: false
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertyChanges {
|
||||||
|
target: root
|
||||||
|
statusText: qsTr("trying to connect...")
|
||||||
working: true
|
working: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -172,13 +290,13 @@ Page {
|
||||||
name: OmobiDisplayBackend.Initing
|
name: OmobiDisplayBackend.Initing
|
||||||
|
|
||||||
PropertyChanges {
|
PropertyChanges {
|
||||||
target: availableDevicesListView
|
target: availableDisplaysListView
|
||||||
enabled: false
|
enabled: false
|
||||||
}
|
}
|
||||||
|
|
||||||
PropertyChanges {
|
PropertyChanges {
|
||||||
target: root
|
target: root
|
||||||
statusText: "loading data..."
|
statusText: qsTr("loading data...")
|
||||||
working: true
|
working: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ import QtQuick 2.0
|
||||||
import QtQuick.Controls 2.9
|
import QtQuick.Controls 2.9
|
||||||
import QtQuick.Layouts 1.0
|
import QtQuick.Layouts 1.0
|
||||||
import QtQuick.Controls.Material 2.0
|
import QtQuick.Controls.Material 2.0
|
||||||
|
import QtGraphicalEffects 1.0
|
||||||
|
|
||||||
import de.itsblue.omobidisplayapp 1.0
|
import de.itsblue.omobidisplayapp 1.0
|
||||||
import de.itsblue.bluetoothleuart 1.0
|
import de.itsblue.bluetoothleuart 1.0
|
||||||
|
@ -9,53 +10,79 @@ import de.itsblue.bluetoothleuart 1.0
|
||||||
Page {
|
Page {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
property bool actionButtonVisible: true
|
||||||
|
property bool backButtonVisible: true
|
||||||
|
|
||||||
|
title: backend.bleClient.currentDevice === null ? "":backend.bleClient.currentDevice.name
|
||||||
|
|
||||||
|
function backButtonClicked() {
|
||||||
|
backend.bleClient.disconnectFromDevice()
|
||||||
|
}
|
||||||
|
|
||||||
|
function actionButtonClicked() {
|
||||||
|
displayEditDialog.edit()
|
||||||
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
|
id: mainLayout
|
||||||
anchors {
|
anchors {
|
||||||
fill: parent
|
fill: parent
|
||||||
margins: parent.height * 0.01
|
margins: Math.min(parent.height, parent.width) * 0.05
|
||||||
topMargin: 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
Chip {
|
||||||
Layout.preferredWidth: parent.width * 0.6
|
|
||||||
Layout.preferredHeight: parent.height * 0.1
|
|
||||||
Layout.alignment: Layout.Center
|
|
||||||
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
|
|
||||||
fontSizeMode: Text.Fit
|
|
||||||
font.pixelSize: 500
|
|
||||||
minimumPixelSize: 1
|
|
||||||
|
|
||||||
color: root.Material.foreground
|
|
||||||
|
|
||||||
text: "Omobi Display 1" //backend.bleController.currentDevice.name
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
Layout.alignment: Layout.Center
|
|
||||||
|
|
||||||
color: root.Material.foreground
|
|
||||||
|
|
||||||
text: qsTr("Brightness:")
|
|
||||||
}
|
|
||||||
|
|
||||||
Slider {
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: mainLayout.height * 0.05
|
||||||
|
Layout.alignment: Layout.Center
|
||||||
|
|
||||||
from: 0
|
interactive: false
|
||||||
to: 10
|
|
||||||
stepSize: 1
|
|
||||||
|
|
||||||
value: backend.displayBrightness
|
color: "white"
|
||||||
|
|
||||||
onPressedChanged: {
|
RowLayout {
|
||||||
if(!pressed)
|
spacing: mainLayout.anchors.margins
|
||||||
backend.displayBrightness = value
|
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.leftMargin: width * 0.05
|
||||||
|
anchors.rightMargin: anchors.leftMargin
|
||||||
|
|
||||||
|
Text {
|
||||||
|
Layout.fillHeight: true
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
font.pixelSize: parent.height * 0.5
|
||||||
|
text: "\uf186"
|
||||||
|
}
|
||||||
|
|
||||||
|
Slider {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
|
||||||
|
from: 0
|
||||||
|
to: 10
|
||||||
|
stepSize: 1
|
||||||
|
|
||||||
|
value: backend.displayBrightness
|
||||||
|
|
||||||
|
onPressedChanged: {
|
||||||
|
if(!pressed)
|
||||||
|
backend.displayBrightness = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
Layout.fillHeight: true
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
font.pixelSize: parent.height * 0.5
|
||||||
|
text: "\uf185"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: mainLayout.height * 0.025
|
||||||
|
}
|
||||||
|
|
||||||
DisplayTextModelListView {
|
DisplayTextModelListView {
|
||||||
Layout.preferredWidth: parent.width
|
Layout.preferredWidth: parent.width
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
|
@ -65,6 +92,10 @@ Page {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DisplayEditDialog {
|
||||||
|
id: displayEditDialog
|
||||||
|
}
|
||||||
|
|
||||||
Dialog {
|
Dialog {
|
||||||
id: loadingDialog
|
id: loadingDialog
|
||||||
|
|
||||||
|
|
91
OmobiDisplayApp/ressources/qml/DisplayEditDialog.qml
Normal file
91
OmobiDisplayApp/ressources/qml/DisplayEditDialog.qml
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
import QtQuick 2.12
|
||||||
|
import QtQuick.Controls 2.12
|
||||||
|
import QtQuick.Layouts 1.9
|
||||||
|
import QtQuick.Controls.Material 2.0
|
||||||
|
|
||||||
|
import de.itsblue.omobidisplayapp 1.0
|
||||||
|
|
||||||
|
Dialog {
|
||||||
|
id: control
|
||||||
|
|
||||||
|
parent: Overlay.overlay
|
||||||
|
|
||||||
|
x: (parent.width - width) / 2
|
||||||
|
y: (parent.height - height) / 2
|
||||||
|
|
||||||
|
width: parent.width * 0.9
|
||||||
|
|
||||||
|
modal: true
|
||||||
|
|
||||||
|
title: qsTr("Edit display settings")
|
||||||
|
|
||||||
|
onAccepted: {
|
||||||
|
backend.setDisplayCode(codeTextField.value)
|
||||||
|
backend.setDisplayName(nameTextField.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
contentItem: ColumnLayout {
|
||||||
|
id: dataFieldsGridLayout
|
||||||
|
|
||||||
|
width: control.width * 0.9
|
||||||
|
|
||||||
|
TextInputDelegate {
|
||||||
|
id: nameTextField
|
||||||
|
Layout.fillWidth: true
|
||||||
|
required: true
|
||||||
|
text: qsTr("Display name\n(needs restart)")
|
||||||
|
}
|
||||||
|
|
||||||
|
PasswordInputDelegate {
|
||||||
|
id: codeTextField
|
||||||
|
Layout.fillWidth: true
|
||||||
|
required: true
|
||||||
|
text: qsTr("Display code (4 digits)")
|
||||||
|
placeholderText: qsTr("Enter new display code")
|
||||||
|
repeatPlaceholderText: qsTr("Enter new display code again")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
footer: DialogButtonBox {
|
||||||
|
|
||||||
|
// alignment: Qt.AlignHCenter
|
||||||
|
buttonLayout: DialogButtonBox.GnomeLayout
|
||||||
|
|
||||||
|
Material.background: "transparent"
|
||||||
|
|
||||||
|
Button {
|
||||||
|
flat: true
|
||||||
|
enabled: nameTextField.value !== ""
|
||||||
|
text: "save"
|
||||||
|
DialogButtonBox.buttonRole: DialogButtonBox.AcceptRole
|
||||||
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
flat: true
|
||||||
|
text: "cancel"
|
||||||
|
DialogButtonBox.buttonRole: DialogButtonBox.RejectRole
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function edit() {
|
||||||
|
|
||||||
|
reset()
|
||||||
|
|
||||||
|
nameTextField.value = backend.bleClient.currentDevice.name
|
||||||
|
|
||||||
|
open()
|
||||||
|
}
|
||||||
|
|
||||||
|
function add(model) {
|
||||||
|
editingModel = model
|
||||||
|
editing = false
|
||||||
|
reset()
|
||||||
|
open()
|
||||||
|
}
|
||||||
|
|
||||||
|
function reset() {
|
||||||
|
nameTextField.value = ""
|
||||||
|
codeTextField.value = ""
|
||||||
|
}
|
||||||
|
}
|
|
@ -56,7 +56,7 @@ ItemDelegate {
|
||||||
ColorAnimation {}
|
ColorAnimation {}
|
||||||
}
|
}
|
||||||
|
|
||||||
text: model.scroll ? qsTr("scrolling"):qsTr("false")
|
text: model.scroll ? qsTr("scrolling"):""
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
control.clicked()
|
control.clicked()
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
import QtQuick 2.0
|
|
||||||
import QtQuick.Controls 2.9
|
|
||||||
|
|
||||||
ItemDelegate {
|
|
||||||
|
|
||||||
}
|
|
120
OmobiDisplayApp/ressources/qml/PasswordInputDelegate.qml
Normal file
120
OmobiDisplayApp/ressources/qml/PasswordInputDelegate.qml
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
import QtQuick 2.0
|
||||||
|
import QtQuick.Controls 2.9
|
||||||
|
import QtQuick.Controls.Material 2.0
|
||||||
|
import QtQuick.Layouts 1.0
|
||||||
|
|
||||||
|
ItemDelegate {
|
||||||
|
id: control
|
||||||
|
|
||||||
|
property string value: ""
|
||||||
|
property bool required: false
|
||||||
|
property color textColor: control.required && value === "" ? "red":control.Material.foreground
|
||||||
|
property string placeholderText: ""
|
||||||
|
property string repeatPlaceholderText: ""
|
||||||
|
property int minimumLength: 4
|
||||||
|
property int maximumLength: 4
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
textField.text = value
|
||||||
|
textEditDialog.open()
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
anchors {
|
||||||
|
right: nextPageIconText.left
|
||||||
|
verticalCenter: parent.verticalCenter
|
||||||
|
rightMargin: control.padding
|
||||||
|
}
|
||||||
|
|
||||||
|
width: parent.width * 0.6
|
||||||
|
elide: Text.ElideRight
|
||||||
|
font.pixelSize: parent.font.pixelSize
|
||||||
|
|
||||||
|
horizontalAlignment: Text.AlignRight
|
||||||
|
|
||||||
|
text: "****"
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: nextPageIconText
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
right: parent.right
|
||||||
|
verticalCenter: parent.verticalCenter
|
||||||
|
rightMargin: control.padding
|
||||||
|
}
|
||||||
|
|
||||||
|
font.pixelSize: parent.height * 0.5
|
||||||
|
font.styleName: fontAwesome.name
|
||||||
|
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
|
||||||
|
text: "\uf105"
|
||||||
|
}
|
||||||
|
|
||||||
|
Dialog {
|
||||||
|
id: textEditDialog
|
||||||
|
parent: Overlay.overlay
|
||||||
|
|
||||||
|
x: (parent.width - width) / 2
|
||||||
|
y: (parent.height - height) / 2
|
||||||
|
|
||||||
|
width: parent.width * 0.9
|
||||||
|
|
||||||
|
Material.theme: control.Material.theme
|
||||||
|
Material.accent: control.Material.accent
|
||||||
|
modal: true
|
||||||
|
|
||||||
|
title: control.text
|
||||||
|
|
||||||
|
contentItem: ColumnLayout {
|
||||||
|
TextField {
|
||||||
|
id: textField
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
placeholderText: control.placeholderText
|
||||||
|
text: control.value
|
||||||
|
|
||||||
|
color: text.length < 4 || text.length > 4 ? "red":control.Material.foreground
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField {
|
||||||
|
id: repeatTextField
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
placeholderText: control.repeatPlaceholderText
|
||||||
|
text: control.value
|
||||||
|
|
||||||
|
color: repeatTextField.text !== textField.text ? "red":control.Material.foreground
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
footer: DialogButtonBox {
|
||||||
|
|
||||||
|
// alignment: Qt.AlignHCenter
|
||||||
|
buttonLayout: DialogButtonBox.GnomeLayout
|
||||||
|
|
||||||
|
Material.background: "transparent"
|
||||||
|
|
||||||
|
Button {
|
||||||
|
flat: true
|
||||||
|
enabled: !(textField.text.length < 4 || textField.text.length > 4) && textField.text === repeatTextField.text
|
||||||
|
text: "save"
|
||||||
|
DialogButtonBox.buttonRole: DialogButtonBox.AcceptRole
|
||||||
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
flat: true
|
||||||
|
text: "cancel"
|
||||||
|
DialogButtonBox.buttonRole: DialogButtonBox.RejectRole
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onAccepted: {
|
||||||
|
control.value = textField.text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -38,12 +38,13 @@ ItemDelegate {
|
||||||
}
|
}
|
||||||
|
|
||||||
font.pixelSize: parent.height * 0.5
|
font.pixelSize: parent.height * 0.5
|
||||||
|
font.styleName: fontAwesome.name
|
||||||
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
|
||||||
color: control.Material.foreground
|
color: control.Material.foreground
|
||||||
|
|
||||||
text: ">"
|
text: "\uf105"
|
||||||
}
|
}
|
||||||
|
|
||||||
Dialog {
|
Dialog {
|
||||||
|
|
|
@ -62,9 +62,6 @@ Dialog {
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: dataFieldsGridLayout
|
id: dataFieldsGridLayout
|
||||||
|
|
||||||
property double fontSizeMultiplier: 0.14
|
|
||||||
property double labelWidthMultiplier: 0.4
|
|
||||||
|
|
||||||
width: control.width * 0.9
|
width: control.width * 0.9
|
||||||
|
|
||||||
SwitchDelegate {
|
SwitchDelegate {
|
||||||
|
@ -119,7 +116,7 @@ Dialog {
|
||||||
id: scrollCountSpinBox
|
id: scrollCountSpinBox
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
from: 0
|
from: 0
|
||||||
text: qsTr("Scroll count:")
|
text: qsTr("Scroll count")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ ItemDelegate {
|
||||||
rightMargin: control.padding
|
rightMargin: control.padding
|
||||||
}
|
}
|
||||||
|
|
||||||
width: parent.width * 0.6
|
width: parent.width * 0.4
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
font.pixelSize: parent.font.pixelSize
|
font.pixelSize: parent.font.pixelSize
|
||||||
|
|
||||||
|
@ -43,12 +43,13 @@ ItemDelegate {
|
||||||
}
|
}
|
||||||
|
|
||||||
font.pixelSize: parent.height * 0.5
|
font.pixelSize: parent.height * 0.5
|
||||||
|
font.styleName: fontAwesome.name
|
||||||
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
|
||||||
color: control.textColor
|
color: control.textColor
|
||||||
|
|
||||||
text: ">"
|
text: "\uf105"
|
||||||
}
|
}
|
||||||
|
|
||||||
Dialog {
|
Dialog {
|
||||||
|
@ -73,6 +74,8 @@ ItemDelegate {
|
||||||
|
|
||||||
placeholderText: control.placeholderText
|
placeholderText: control.placeholderText
|
||||||
text: control.value
|
text: control.value
|
||||||
|
|
||||||
|
Keys.onReturnPressed: textEditDialog.accept()
|
||||||
}
|
}
|
||||||
|
|
||||||
onAccepted: {
|
onAccepted: {
|
||||||
|
|
|
@ -4,12 +4,13 @@ import QtQuick.Window 2.12
|
||||||
import de.itsblue.omobidisplayapp 1.0
|
import de.itsblue.omobidisplayapp 1.0
|
||||||
import de.itsblue.bluetoothleuart 1.0
|
import de.itsblue.bluetoothleuart 1.0
|
||||||
import QtQuick.Controls.Material 2.0
|
import QtQuick.Controls.Material 2.0
|
||||||
|
import QtQuick.Layouts 1.0
|
||||||
|
|
||||||
ApplicationWindow {
|
ApplicationWindow {
|
||||||
width: 540
|
width: 540
|
||||||
height: 960
|
height: 960
|
||||||
visible: true
|
visible: true
|
||||||
title: qsTr("Hello World")
|
title: qsTr("Itsblue smart display")
|
||||||
|
|
||||||
Page {
|
Page {
|
||||||
id: app
|
id: app
|
||||||
|
@ -26,22 +27,84 @@ ApplicationWindow {
|
||||||
Material.theme: Material.System
|
Material.theme: Material.System
|
||||||
|
|
||||||
header: ToolBar {
|
header: ToolBar {
|
||||||
|
id: headerToolBar
|
||||||
|
|
||||||
|
height: 50
|
||||||
|
implicitWidth: parent.width
|
||||||
|
|
||||||
Material.background: "white"
|
Material.background: "white"
|
||||||
|
|
||||||
Image {
|
RowLayout {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: parent.height * 0.1
|
|
||||||
|
|
||||||
fillMode: Image.PreserveAspectFit
|
ToolButton {
|
||||||
source: "qrc:/omobi.png"
|
id: backToolButton
|
||||||
|
|
||||||
|
enabled: false
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.preferredWidth: height
|
||||||
|
|
||||||
|
opacity: mainStack.currentItem.backButtonVisible ? 1:0
|
||||||
|
|
||||||
|
font.styleName: fontAwesome.name
|
||||||
|
font.pixelSize: height * 0.6
|
||||||
|
Material.foreground: "black"
|
||||||
|
|
||||||
|
text: "\uf104"
|
||||||
|
|
||||||
|
contentItem: Item {}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
font.pixelSize: parent.font.pixelSize
|
||||||
|
text: parent.text
|
||||||
|
}
|
||||||
|
|
||||||
|
onClicked: mainStack.currentItem.backButtonClicked()
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.alignment: Layout.Center
|
||||||
|
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
|
||||||
|
text: mainStack.currentItem.title
|
||||||
|
}
|
||||||
|
|
||||||
|
ToolButton {
|
||||||
|
id: actionToolButton
|
||||||
|
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.preferredWidth: height
|
||||||
|
|
||||||
|
opacity: mainStack.currentItem.actionButtonVisible ? 1:0
|
||||||
|
|
||||||
|
font.styleName: fontAwesome.name
|
||||||
|
font.pixelSize: height * 0.4
|
||||||
|
Material.foreground: "black"
|
||||||
|
|
||||||
|
flat: true
|
||||||
|
|
||||||
|
text: "\uf013"
|
||||||
|
|
||||||
|
onClicked: mainStack.currentItem.actionButtonClicked()
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OmobiDisplayBackend {
|
OmobiDisplayBackend {
|
||||||
id: backend
|
id: backend
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FontLoader {
|
||||||
|
id: fontAwesome
|
||||||
|
source: "qrc:/fa5regular.woff"
|
||||||
|
}
|
||||||
|
|
||||||
StackView {
|
StackView {
|
||||||
id: mainStack
|
id: mainStack
|
||||||
|
|
||||||
|
@ -56,6 +119,22 @@ ApplicationWindow {
|
||||||
|
|
||||||
initialItem: connectedPageComp
|
initialItem: connectedPageComp
|
||||||
|
|
||||||
|
replaceEnter: Transition {
|
||||||
|
NumberAnimation {
|
||||||
|
properties: "opacity"
|
||||||
|
from: 0
|
||||||
|
to: 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
replaceExit: Transition {
|
||||||
|
NumberAnimation {
|
||||||
|
properties: "opacity"
|
||||||
|
from: 1
|
||||||
|
to: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
id: connectPageComp
|
id: connectPageComp
|
||||||
ConnectPage {
|
ConnectPage {
|
||||||
|
@ -66,6 +145,7 @@ ApplicationWindow {
|
||||||
Component {
|
Component {
|
||||||
id: connectedPageComp
|
id: connectedPageComp
|
||||||
ConnectedPage {
|
ConnectedPage {
|
||||||
|
opacity: 0
|
||||||
state: app.state
|
state: app.state
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -104,6 +184,22 @@ ApplicationWindow {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
State {
|
||||||
|
name: OmobiDisplayBackend.AuthenticationRequired
|
||||||
|
PropertyChanges {
|
||||||
|
target: mainStack
|
||||||
|
currentComponent: connectPageComp
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
State {
|
||||||
|
name: OmobiDisplayBackend.Authenticating
|
||||||
|
PropertyChanges {
|
||||||
|
target: mainStack
|
||||||
|
currentComponent: connectPageComp
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
State {
|
State {
|
||||||
name: OmobiDisplayBackend.Initing
|
name: OmobiDisplayBackend.Initing
|
||||||
PropertyChanges {
|
PropertyChanges {
|
||||||
|
@ -118,6 +214,14 @@ ApplicationWindow {
|
||||||
target: mainStack
|
target: mainStack
|
||||||
currentComponent: connectedPageComp
|
currentComponent: connectedPageComp
|
||||||
}
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: headerToolBar
|
||||||
|
state: "open"
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: backToolButton
|
||||||
|
enabled: true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
State {
|
State {
|
||||||
|
@ -126,6 +230,14 @@ ApplicationWindow {
|
||||||
target: mainStack
|
target: mainStack
|
||||||
currentComponent: connectedPageComp
|
currentComponent: connectedPageComp
|
||||||
}
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: headerToolBar
|
||||||
|
state: "open"
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: backToolButton
|
||||||
|
enabled: true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,11 +7,12 @@
|
||||||
<file>DisplayTextModelListView.qml</file>
|
<file>DisplayTextModelListView.qml</file>
|
||||||
<file>TextEditDialog.qml</file>
|
<file>TextEditDialog.qml</file>
|
||||||
<file>TextInputDelegate.qml</file>
|
<file>TextInputDelegate.qml</file>
|
||||||
<file>NextPageDelegate.qml</file>
|
|
||||||
<file>SpinBoxDelegate.qml</file>
|
<file>SpinBoxDelegate.qml</file>
|
||||||
<file>ComboBoxDelegate.qml</file>
|
<file>ComboBoxDelegate.qml</file>
|
||||||
<file>ColorPickerDelegate.qml</file>
|
<file>ColorPickerDelegate.qml</file>
|
||||||
<file>ColorPicker.qml</file>
|
<file>ColorPicker.qml</file>
|
||||||
<file>Chip.qml</file>
|
<file>Chip.qml</file>
|
||||||
|
<file>DisplayEditDialog.qml</file>
|
||||||
|
<file>PasswordInputDelegate.qml</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|
BIN
OmobiDisplayApp/ressources/shared/fa5regular.woff
Normal file
BIN
OmobiDisplayApp/ressources/shared/fa5regular.woff
Normal file
Binary file not shown.
|
@ -2,5 +2,6 @@
|
||||||
<qresource prefix="/">
|
<qresource prefix="/">
|
||||||
<file>omobi.png</file>
|
<file>omobi.png</file>
|
||||||
<file>itsblue.png</file>
|
<file>itsblue.png</file>
|
||||||
|
<file>fa5regular.woff</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|
BIN
OmobiDisplayApp/ressources/translations/de.qm
Normal file
BIN
OmobiDisplayApp/ressources/translations/de.qm
Normal file
Binary file not shown.
163
OmobiDisplayApp/ressources/translations/de.ts
Normal file
163
OmobiDisplayApp/ressources/translations/de.ts
Normal file
|
@ -0,0 +1,163 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!DOCTYPE TS>
|
||||||
|
<TS version="2.1" language="de_DE" sourcelanguage="en">
|
||||||
|
<context>
|
||||||
|
<name>ConnectPage</name>
|
||||||
|
<message>
|
||||||
|
<source>Available devices</source>
|
||||||
|
<translation type="vanished">Verfügbare Geräte</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Input code</source>
|
||||||
|
<translation>Geben sie den Code ein</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>code</source>
|
||||||
|
<translation>Code</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Tap here to scan</source>
|
||||||
|
<translation>Tippe hier um zu suchen</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Scanning...</source>
|
||||||
|
<translation>Suchen...</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Please select a device or tap to scan again</source>
|
||||||
|
<translation>Wähle ein Display, oder tippe um erneut zu suchen</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>trying to authenticate...</source>
|
||||||
|
<translation>Versuche anzumelden...</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>trying to connect...</source>
|
||||||
|
<translation>Versuche zu verbinden...</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>loading data...</source>
|
||||||
|
<translation>Lade Daten...</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Available displays</source>
|
||||||
|
<translation>Verfügbare Displays</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Still scanning</source>
|
||||||
|
<translation>Suche läuft</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>No displays found</source>
|
||||||
|
<translation>Keine Displays gefunden</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>No displays found. Tap to scan again</source>
|
||||||
|
<translation>Keine Displays gefunden. Tippe um erneut zu suchen</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>ConnectedPage</name>
|
||||||
|
<message>
|
||||||
|
<source>Brightness:</source>
|
||||||
|
<translation type="vanished">Helligkeit:</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>loading...</source>
|
||||||
|
<translation>laden...</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>DisplayEditDialog</name>
|
||||||
|
<message>
|
||||||
|
<source>Edit display settings</source>
|
||||||
|
<translation>Display Einstellungen bearbeiten</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Display name
|
||||||
|
(needs restart)</source>
|
||||||
|
<translation>Displayname\n(neutstart nötig)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Display code (4 digits)</source>
|
||||||
|
<translation>Display Code (4 Zeichen)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Enter new display code</source>
|
||||||
|
<translation>Geben sie den neuen Display Code ein</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Enter new display code again</source>
|
||||||
|
<translation>Geben sie den neuen Display Code erneut ein</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>DisplayTextDelegate</name>
|
||||||
|
<message>
|
||||||
|
<source>scrolling</source>
|
||||||
|
<translation>scrollen</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>false</source>
|
||||||
|
<translation type="vanished">nein</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source> active </source>
|
||||||
|
<translation> aktiv </translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>inactive</source>
|
||||||
|
<translation>inaktiv</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>TextEditDialog</name>
|
||||||
|
<message>
|
||||||
|
<source>Active</source>
|
||||||
|
<translation>Aktiv</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Enter some text to be displayed</source>
|
||||||
|
<translation>Geben sie den anzuzeigenden Text ein</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Text</source>
|
||||||
|
<translation>Text</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Runtime (in s)</source>
|
||||||
|
<translation>Laufzeit (in s)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Color</source>
|
||||||
|
<translation>Farbe</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Alignment</source>
|
||||||
|
<translation>Ausrichtung</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Scroll</source>
|
||||||
|
<translation>Scrollen</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Scroll speed</source>
|
||||||
|
<translation>Scrollgeschwindigkeit</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Scroll count:</source>
|
||||||
|
<translation type="vanished">Scrolldurchläufe</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Scroll count</source>
|
||||||
|
<translation>Scrolldurchläufe</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>main</name>
|
||||||
|
<message>
|
||||||
|
<source>Itsblue smart display</source>
|
||||||
|
<translation>Itsblue smart display</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
</TS>
|
5
OmobiDisplayApp/ressources/translations/translations.qrc
Normal file
5
OmobiDisplayApp/ressources/translations/translations.qrc
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
<RCC>
|
||||||
|
<qresource prefix="/">
|
||||||
|
<file>de.qm</file>
|
||||||
|
</qresource>
|
||||||
|
</RCC>
|
|
@ -62,6 +62,8 @@ public:
|
||||||
bool getDeviceConnected();
|
bool getDeviceConnected();
|
||||||
bool disconnectCurrentDevice();
|
bool disconnectCurrentDevice();
|
||||||
|
|
||||||
|
String getDeviceAddress();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// callbacks for BLEServer
|
// callbacks for BLEServer
|
||||||
void onConnect(BLEServer *pServer, esp_ble_gatts_cb_param_t *param) override;
|
void onConnect(BLEServer *pServer, esp_ble_gatts_cb_param_t *param) override;
|
||||||
|
|
|
@ -27,25 +27,22 @@ private:
|
||||||
template <typename T>
|
template <typename T>
|
||||||
const T &writeToEeprom(int address, size_t size, const T &t)
|
const T &writeToEeprom(int address, size_t size, const T &t)
|
||||||
{
|
{
|
||||||
Serial.println("Writing at: " + String(address) + " size: " + String(sizeof(T)));
|
|
||||||
|
|
||||||
if (sizeof(T) > size) {
|
if (sizeof(T) > size) {
|
||||||
Serial.println("Error writing: Size should be: " + String(size));
|
Serial.println("[Error][EepromManager] writing: Size should be: " + String(size) + " but was: " + String(sizeof(T)));
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
const T &res = EEPROM.put(address, t);
|
const T &res = EEPROM.put(address, t);
|
||||||
Serial.println("Eeprom commit returned: " + String(EEPROM.commit()));
|
EEPROM.commit();
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T &readFromEeprom(int address, size_t size, T &t)
|
T &readFromEeprom(int address, size_t size, T &t)
|
||||||
{
|
{
|
||||||
Serial.println("Reading at: " + String(address) + " size: " + String(sizeof(T)));
|
|
||||||
|
|
||||||
if (sizeof(T) > size) {
|
if (sizeof(T) > size) {
|
||||||
Serial.println("Error reading: Size should be: " + String(size));
|
Serial.println("[Error][EepromManager] reading: Size should be: " + String(size) + " but was: " + String(sizeof(T)));
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,12 +54,15 @@ private:
|
||||||
GetTextSetParameterCommand = 11,
|
GetTextSetParameterCommand = 11,
|
||||||
GetDisplayBrightnessCommand = 12,
|
GetDisplayBrightnessCommand = 12,
|
||||||
SetTextSetParameterCommand = 20,
|
SetTextSetParameterCommand = 20,
|
||||||
SetDisplayBrightnessCommand = 21
|
SetDisplayBrightnessCommand = 21,
|
||||||
|
SetDisplayCodeCommand = 22,
|
||||||
|
SetDisplayNameCommand = 23
|
||||||
};
|
};
|
||||||
|
|
||||||
enum OmobiDisplayStatusCode
|
enum OmobiDisplayStatusCode
|
||||||
{
|
{
|
||||||
Success = 200,
|
Success = 200,
|
||||||
|
BadRequestError = 400,
|
||||||
Unauthorized = 401,
|
Unauthorized = 401,
|
||||||
InternalError = 500,
|
InternalError = 500,
|
||||||
DisplayControllerError = 501
|
DisplayControllerError = 501
|
||||||
|
|
|
@ -56,6 +56,27 @@ void BluetoothLeUartServer::sendData(String data)
|
||||||
txCharacteristic->notify();
|
txCharacteristic->notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BluetoothLeUartServer::getDeviceConnected()
|
||||||
|
{
|
||||||
|
return this->deviceConnected;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BluetoothLeUartServer::disconnectCurrentDevice() {
|
||||||
|
if(!this->getDeviceConnected())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
this->bleServer->disconnect(this->deviceConnectionId);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
String BluetoothLeUartServer::getDeviceAddress() {
|
||||||
|
|
||||||
|
String address = BLEDevice::getAddress().toString().c_str();
|
||||||
|
address.toUpperCase();
|
||||||
|
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
|
||||||
void BluetoothLeUartServer::onConnect(BLEServer* pServer, esp_ble_gatts_cb_param_t *param)
|
void BluetoothLeUartServer::onConnect(BLEServer* pServer, esp_ble_gatts_cb_param_t *param)
|
||||||
{
|
{
|
||||||
// only allow one device
|
// only allow one device
|
||||||
|
@ -85,16 +106,3 @@ void BluetoothLeUartServer::onWrite(BLECharacteristic *rxCharacteristic)
|
||||||
if (this->callbacks != nullptr)
|
if (this->callbacks != nullptr)
|
||||||
this->callbacks->onDataReceived(rxCharacteristic->getValue().c_str());
|
this->callbacks->onDataReceived(rxCharacteristic->getValue().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BluetoothLeUartServer::getDeviceConnected()
|
|
||||||
{
|
|
||||||
return this->deviceConnected;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BluetoothLeUartServer::disconnectCurrentDevice() {
|
|
||||||
if(!this->getDeviceConnected())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
this->bleServer->disconnect(this->deviceConnectionId);
|
|
||||||
return true;
|
|
||||||
}
|
|
|
@ -8,7 +8,6 @@ EepromManager::EepromManager()
|
||||||
|
|
||||||
EepromUnit *EepromManager::registerEempromUnit(size_t size)
|
EepromUnit *EepromManager::registerEempromUnit(size_t size)
|
||||||
{
|
{
|
||||||
Serial.println("Registering new EepromUnit with size: " + String(size) + " at " + String(this->currentAddressEnding));
|
|
||||||
// create a new Unit at the current address ending
|
// create a new Unit at the current address ending
|
||||||
EepromUnit *newUnit = new EepromUnit(this, this->currentAddressEnding, size);
|
EepromUnit *newUnit = new EepromUnit(this, this->currentAddressEnding, size);
|
||||||
// move the new address ending
|
// move the new address ending
|
||||||
|
|
|
@ -48,18 +48,21 @@ void OmobiLedDisplay::onDataReceived(String dataString)
|
||||||
OmobiDisplayStatusCode replyStatus = InternalError;
|
OmobiDisplayStatusCode replyStatus = InternalError;
|
||||||
JsonObject replyData = replyDoc.createNestedObject("data");
|
JsonObject replyData = replyDoc.createNestedObject("data");
|
||||||
|
|
||||||
if (requestHeader != AuthorizeSessionCommand && !this->sessionAuthorized)
|
if (requestHeader > KeepAliveCommand && !this->sessionAuthorized)
|
||||||
replyStatus = Unauthorized;
|
replyStatus = Unauthorized;
|
||||||
else
|
else
|
||||||
switch (requestHeader)
|
switch (requestHeader)
|
||||||
{
|
{
|
||||||
case AuthorizeSessionCommand:
|
case AuthorizeSessionCommand:
|
||||||
{
|
{
|
||||||
|
String combinedCode = this->bleServer->getDeviceAddress() + String(this->properties.deviceCode);
|
||||||
|
String secret = this->sha256(combinedCode);
|
||||||
|
|
||||||
if (this->sessionAuthorized)
|
if (this->sessionAuthorized)
|
||||||
{
|
{
|
||||||
replyStatus = Success;
|
replyStatus = Success;
|
||||||
}
|
}
|
||||||
else if (requestData["secret"] == this->sha256(this->properties.deviceCode))
|
else if (requestData["secret"] == secret)
|
||||||
{
|
{
|
||||||
replyStatus = Success;
|
replyStatus = Success;
|
||||||
this->sessionAuthorized = true;
|
this->sessionAuthorized = true;
|
||||||
|
@ -150,6 +153,30 @@ void OmobiLedDisplay::onDataReceived(String dataString)
|
||||||
replyStatus = Success;
|
replyStatus = Success;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case SetDisplayCodeCommand: {
|
||||||
|
String code = requestData["displayCode"];
|
||||||
|
if(code.length() != 4) {
|
||||||
|
replyStatus = BadRequestError;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
strncpy(this->properties.deviceCode, code.c_str(), sizeof(this->properties.deviceCode));
|
||||||
|
this->storeProperties();
|
||||||
|
replyStatus = Success;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SetDisplayNameCommand: {
|
||||||
|
String name = requestData["displayName"];
|
||||||
|
if(name.length() <= 0) {
|
||||||
|
replyStatus = BadRequestError;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
strncpy(this->properties.deviceName, name.c_str(), sizeof(this->properties.deviceName));
|
||||||
|
this->storeProperties();
|
||||||
|
replyStatus = Success;
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue