made name and code modifiable
This commit is contained in:
parent
2edc225c35
commit
72ab73b280
15 changed files with 338 additions and 19 deletions
|
@ -1,4 +1,4 @@
|
|||
QT += quick bluetooth
|
||||
QT += quick bluetooth quickcontrols2
|
||||
CONFIG += c++11
|
||||
|
||||
TARGET = OmobiDisplayApp
|
||||
|
|
|
@ -209,16 +209,14 @@ void OmobiDisplayBackend::handleBluetoothDataReceived(QString s){
|
|||
this->refreshLoadingState();
|
||||
break;
|
||||
}
|
||||
case SetTextSetParameterCommand: {
|
||||
case SetTextSetParameterCommand:
|
||||
case SetDisplayBrightnessCommand:
|
||||
case SetDisplayCodeCommand:
|
||||
case SetDisplayNameCommand:
|
||||
// TODO: Error handling
|
||||
this->refreshLoadingState();
|
||||
break;
|
||||
}
|
||||
case SetDisplayBrightnessCommand: {
|
||||
// TODO: Error handling
|
||||
this->refreshLoadingState();
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -296,3 +294,13 @@ void OmobiDisplayBackend::setDisplayBrightness(int brightness) {
|
|||
|
||||
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}});
|
||||
}
|
||||
|
|
|
@ -41,7 +41,9 @@ private:
|
|||
GetTextSetParameterCommand = 11,
|
||||
GetDisplayBrightnessCommand = 12,
|
||||
SetTextSetParameterCommand = 20,
|
||||
SetDisplayBrightnessCommand = 21
|
||||
SetDisplayBrightnessCommand = 21,
|
||||
SetDisplayCodeCommand = 22,
|
||||
SetDisplayNameCommand = 23
|
||||
};
|
||||
|
||||
enum OmobiDisplayStatusCode {
|
||||
|
@ -65,6 +67,8 @@ public slots:
|
|||
Q_INVOKABLE OmobiDisplayTextModel* getDisplayTextModel();
|
||||
Q_INVOKABLE int getDisplayBrightness();
|
||||
Q_INVOKABLE void setDisplayBrightness(int brightness);
|
||||
Q_INVOKABLE void setDisplayCode(QString code);
|
||||
Q_INVOKABLE void setDisplayName(QString name);
|
||||
|
||||
private slots:
|
||||
void handleBluetoothStateChange(QBluetoothLeUart::BluetoothLeUartState state);
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.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 {
|
||||
id: control
|
||||
|
@ -15,6 +19,7 @@ Item {
|
|||
property bool glowVisible: true
|
||||
property double glowScale: 0.9
|
||||
property double glowOpacity: Math.pow( control.opacity, 100 )
|
||||
property bool interactive: true
|
||||
|
||||
signal clicked
|
||||
|
||||
|
@ -49,10 +54,42 @@ Item {
|
|||
anchors.fill: parent
|
||||
color: control.color
|
||||
radius: height * 0.5
|
||||
clip: true
|
||||
|
||||
Behavior on color {
|
||||
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 {
|
||||
|
@ -75,7 +112,7 @@ Item {
|
|||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
enabled: control.enabled
|
||||
enabled: control.enabled && control.interactive
|
||||
onClicked: control.clicked()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import QtQuick.Layouts 1.0
|
|||
import de.itsblue.omobidisplayapp 1.0
|
||||
import de.itsblue.bluetoothleuart 1.0
|
||||
import QtQuick.Controls.Material 2.0
|
||||
import QtGraphicalEffects 1.0
|
||||
|
||||
Page {
|
||||
id: root
|
||||
|
|
|
@ -2,6 +2,7 @@ import QtQuick 2.0
|
|||
import QtQuick.Controls 2.9
|
||||
import QtQuick.Layouts 1.0
|
||||
import QtQuick.Controls.Material 2.0
|
||||
import QtGraphicalEffects 1.0
|
||||
|
||||
import de.itsblue.omobidisplayapp 1.0
|
||||
import de.itsblue.bluetoothleuart 1.0
|
||||
|
@ -30,7 +31,28 @@ Page {
|
|||
|
||||
color: root.Material.foreground
|
||||
|
||||
text: "Omobi Display 1" //backend.bleController.currentDevice.name
|
||||
text: backend.bleController.currentDevice === null ? "":backend.bleController.currentDevice.name
|
||||
|
||||
ToolButton {
|
||||
id: editButton
|
||||
anchors {
|
||||
verticalCenter: parent.verticalCenter
|
||||
left: parent.right
|
||||
margins: parent.height * 0.1
|
||||
}
|
||||
|
||||
height: parent.height * 0.7
|
||||
width: height
|
||||
|
||||
font.styleName: fontAwesome.name
|
||||
font.pixelSize: height * 0.3
|
||||
|
||||
flat: true
|
||||
|
||||
text: "\uf044"
|
||||
|
||||
onClicked: displayEditDialog.edit()
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
|
@ -65,6 +87,10 @@ Page {
|
|||
}
|
||||
}
|
||||
|
||||
DisplayEditDialog {
|
||||
id: displayEditDialog
|
||||
}
|
||||
|
||||
Dialog {
|
||||
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.bleController.currentDevice.name
|
||||
|
||||
open()
|
||||
}
|
||||
|
||||
function add(model) {
|
||||
editingModel = model
|
||||
editing = false
|
||||
reset()
|
||||
open()
|
||||
}
|
||||
|
||||
function reset() {
|
||||
nameTextField.value = ""
|
||||
codeTextField.value = ""
|
||||
}
|
||||
}
|
119
OmobiDisplayApp/ressources/qml/PasswordInputDelegate.qml
Normal file
119
OmobiDisplayApp/ressources/qml/PasswordInputDelegate.qml
Normal file
|
@ -0,0 +1,119 @@
|
|||
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
|
||||
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
|
||||
text: ">"
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
|
@ -62,9 +62,6 @@ Dialog {
|
|||
ColumnLayout {
|
||||
id: dataFieldsGridLayout
|
||||
|
||||
property double fontSizeMultiplier: 0.14
|
||||
property double labelWidthMultiplier: 0.4
|
||||
|
||||
width: control.width * 0.9
|
||||
|
||||
SwitchDelegate {
|
||||
|
|
|
@ -42,6 +42,11 @@ ApplicationWindow {
|
|||
id: backend
|
||||
}
|
||||
|
||||
FontLoader {
|
||||
id: fontAwesome
|
||||
source: "qrc:/fa5regular.woff"
|
||||
}
|
||||
|
||||
StackView {
|
||||
id: mainStack
|
||||
|
||||
|
|
|
@ -13,5 +13,7 @@
|
|||
<file>ColorPickerDelegate.qml</file>
|
||||
<file>ColorPicker.qml</file>
|
||||
<file>Chip.qml</file>
|
||||
<file>DisplayEditDialog.qml</file>
|
||||
<file>PasswordInputDelegate.qml</file>
|
||||
</qresource>
|
||||
</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="/">
|
||||
<file>omobi.png</file>
|
||||
<file>itsblue.png</file>
|
||||
<file>fa5regular.woff</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
|
@ -33,12 +33,15 @@ private:
|
|||
GetTextSetParameterCommand = 11,
|
||||
GetDisplayBrightnessCommand = 12,
|
||||
SetTextSetParameterCommand = 20,
|
||||
SetDisplayBrightnessCommand = 21
|
||||
SetDisplayBrightnessCommand = 21,
|
||||
SetDisplayCodeCommand = 22,
|
||||
SetDisplayNameCommand = 23
|
||||
};
|
||||
|
||||
enum OmobiDisplayStatusCode
|
||||
{
|
||||
Success = 200,
|
||||
BadRequestError = 400,
|
||||
Unauthorized = 401,
|
||||
InternalError = 500,
|
||||
DisplayControllerError = 501
|
||||
|
|
|
@ -12,12 +12,13 @@ OmobiLedDisplay::OmobiLedDisplay(String deviceName, Adafruit_NeoMatrix *ledDispl
|
|||
this->ledDisplayController = new LedDisplayController(ledDisplayMatrix);
|
||||
this->ledDisplayController->registerEepromUnit(this->eepromManager);
|
||||
|
||||
// init ble server
|
||||
this->bleServer = new BluetoothLeUartServer("Omobi Display", "92fecb20-1406-426a-afa5-cd5c1f306462", "92fecb21-1406-426a-afa5-cd5c1f306462", "92fecb22-1406-426a-afa5-cd5c1f306462");
|
||||
this->bleServer->setCallbacks(this);
|
||||
|
||||
// register eeprom for this class
|
||||
this->eepromUnit = this->eepromManager->registerEempromUnit(sizeof(DisplayProperties));
|
||||
this->loadProperties();
|
||||
|
||||
// init ble server
|
||||
this->bleServer = new BluetoothLeUartServer(this->properties.deviceName, "92fecb20-1406-426a-afa5-cd5c1f306462", "92fecb21-1406-426a-afa5-cd5c1f306462", "92fecb22-1406-426a-afa5-cd5c1f306462");
|
||||
this->bleServer->setCallbacks(this);
|
||||
}
|
||||
|
||||
void OmobiLedDisplay::loop()
|
||||
|
@ -170,6 +171,30 @@ void OmobiLedDisplay::onDataReceived(String dataString)
|
|||
replyStatus = Success;
|
||||
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:
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue