- Many styling improvements and additions
- Added some real commands -> App should be fully functional now, as soon as the esp is finished
This commit is contained in:
parent
28595d62bb
commit
fb7063de2c
17 changed files with 762 additions and 357 deletions
|
@ -1 +1 @@
|
|||
Subproject commit 0b053eaa88ffdcc0b32e533904e5e266b8e62fb3
|
||||
Subproject commit dad7187909e925b97bcc8e971b071f007d1a2ef5
|
|
@ -54,7 +54,8 @@ void OmobiDisplayBackend::handleBluetoothStateChange(QBluetoothLeUart::Bluetooth
|
|||
}
|
||||
|
||||
void OmobiDisplayBackend::handleBluetoothDeviceConected() {
|
||||
this->ble->sendData("Hallihallo ich bin Julia Mueller");
|
||||
this->ble->sendData("GET_TEXTS");
|
||||
this->ble->sendData("GET_BRIGHTNESS");
|
||||
|
||||
// get the existing model data!
|
||||
// TODO: implement some communication!
|
||||
|
@ -68,15 +69,66 @@ void OmobiDisplayBackend::handleFoundNewDevice(QBluetoothLeUartDevice* device) {
|
|||
qDebug() << "Found a device: name: " << device->getName() << " address: " << device->getAddress();
|
||||
}
|
||||
|
||||
void OmobiDisplayBackend::DataHandler(const QString &s){
|
||||
void OmobiDisplayBackend::DataHandler(QString s){
|
||||
qDebug() << "New data: " << s;
|
||||
if(s.startsWith("GET_TEXTS:")) {
|
||||
QJsonParseError parseError;
|
||||
QJsonDocument doc = QJsonDocument::fromJson(s.replace("GET_TEXTS:", "").toUtf8(), &parseError);
|
||||
|
||||
qDebug() << "NEw data: " << s;
|
||||
if(parseError.error != QJsonParseError::NoError)
|
||||
return;
|
||||
|
||||
QList<QMap<int, QVariant>> texts;
|
||||
|
||||
for(QVariant textMap : doc.toVariant().toList()) {
|
||||
QMap<int, QVariant> text;
|
||||
|
||||
static const QMap<QString, int> keyTranslations {
|
||||
{ "text", OmobiDisplayTextModel::TextRole },
|
||||
{ "active", OmobiDisplayTextModel::ActiveRole },
|
||||
{ "runtime", OmobiDisplayTextModel::RuntimeRole },
|
||||
{ "color", OmobiDisplayTextModel::ColorRole },
|
||||
{ "alignment", OmobiDisplayTextModel::AlignmentRole },
|
||||
{ "scroll", OmobiDisplayTextModel::ScrollRole },
|
||||
{ "scrollSpeed", OmobiDisplayTextModel::ScrollSpeedRole },
|
||||
{ "scrollCount", OmobiDisplayTextModel::ScrollCountRole },
|
||||
{ "index", OmobiDisplayTextModel::IndexRole }
|
||||
};
|
||||
|
||||
for(QString key : textMap.toMap().keys()) {
|
||||
if(keyTranslations.contains(key))
|
||||
text.insert(keyTranslations[key], textMap.toMap()[key]);
|
||||
}
|
||||
|
||||
texts.append(text);
|
||||
}
|
||||
|
||||
this->displayTextModel->setTexts(texts);
|
||||
}
|
||||
else if(s.startsWith("GET_BRIGHTNESS:")) {
|
||||
this->displayBrightness = s.replace("GET_BRIGHTNESS:", "").toInt();
|
||||
emit this->displayBrightnessChanged();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OmobiDisplayBackend::handleDisplayTextModelDataChanged() {
|
||||
qDebug() << "MODEL DATA CHANGED!";
|
||||
|
||||
QVariantList textList;
|
||||
|
||||
for(QMap<int, QVariant> text : this->displayTextModel->getTexts()) {
|
||||
QVariantHash textMap;
|
||||
|
||||
for(int key : text.keys()) {
|
||||
textMap.insert(this->displayTextModel->roleNames()[key], text[key]);
|
||||
}
|
||||
|
||||
textList.append(textMap);
|
||||
}
|
||||
|
||||
QJsonDocument doc = QJsonDocument::fromVariant(textList);
|
||||
|
||||
this->ble->sendData("SET_TEXTS:" + doc.toJson(QJsonDocument::Compact));
|
||||
}
|
||||
|
||||
QBluetoothLeUart* OmobiDisplayBackend::getBleController() {
|
||||
|
@ -102,3 +154,18 @@ void OmobiDisplayBackend::setState(OmobiDisplayAppState state) {
|
|||
if(this->state == Idle)
|
||||
this->ble->startScanningForDevices();
|
||||
}
|
||||
|
||||
int OmobiDisplayBackend::getDisplayBrightness() {
|
||||
return this->displayBrightness;
|
||||
}
|
||||
|
||||
void OmobiDisplayBackend::setDisplayBrightness(int brightness) {
|
||||
if(brightness == this->displayBrightness)
|
||||
return;
|
||||
|
||||
this->displayBrightness = brightness;
|
||||
|
||||
this->ble->sendData("SET_BRIGHTNESS:" + QString::number(this->displayBrightness));
|
||||
|
||||
emit this->displayBrightnessChanged();
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
#define OMOBIDISPLAYBACKEND_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QJsonDocument>
|
||||
|
||||
#include <qbluetoothleuart.h>
|
||||
#include <omobidisplaytextmodel.h>
|
||||
|
||||
|
@ -11,6 +13,7 @@ class OmobiDisplayBackend : public QObject
|
|||
Q_PROPERTY(QBluetoothLeUart* bleController READ getBleController NOTIFY bleControllerChanged)
|
||||
Q_PROPERTY(OmobiDisplayAppState state READ getState WRITE setState NOTIFY stateChanged)
|
||||
Q_PROPERTY(OmobiDisplayTextModel* displayTextModel READ getDisplayTextModel NOTIFY displayTextModelChanged)
|
||||
Q_PROPERTY(int displayBrightness READ getDisplayBrightness WRITE setDisplayBrightness NOTIFY displayBrightnessChanged)
|
||||
|
||||
public:
|
||||
explicit OmobiDisplayBackend(QObject *parent = nullptr);
|
||||
|
@ -28,17 +31,20 @@ private:
|
|||
OmobiDisplayAppState state;
|
||||
QBluetoothLeUart *ble;
|
||||
OmobiDisplayTextModel* displayTextModel;
|
||||
int displayBrightness;
|
||||
|
||||
public slots:
|
||||
Q_INVOKABLE void startScanning();
|
||||
Q_INVOKABLE QBluetoothLeUart* getBleController();
|
||||
Q_INVOKABLE OmobiDisplayAppState getState();
|
||||
Q_INVOKABLE OmobiDisplayTextModel* getDisplayTextModel();
|
||||
Q_INVOKABLE int getDisplayBrightness();
|
||||
Q_INVOKABLE void setDisplayBrightness(int brightness);
|
||||
|
||||
private slots:
|
||||
void handleBluetoothStateChange(QBluetoothLeUart::BluetoothLeUartState state);
|
||||
void handleFoundNewDevice(QBluetoothLeUartDevice* device);
|
||||
void DataHandler(const QString &s);
|
||||
void DataHandler(QString s);
|
||||
void handleBluetoothDeviceConected();
|
||||
|
||||
void handleDisplayTextModelDataChanged();
|
||||
|
@ -49,6 +55,7 @@ signals:
|
|||
void stateChanged();
|
||||
void bleControllerChanged();
|
||||
void displayTextModelChanged();
|
||||
void displayBrightnessChanged();
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -2,28 +2,6 @@
|
|||
|
||||
OmobiDisplayTextModel::OmobiDisplayTextModel(QObject* parent) : QAbstractListModel(parent)
|
||||
{
|
||||
QMap<int, QVariant> sampleText1 = {
|
||||
{ TextRole, "itsblue.de" },
|
||||
{ ActiveRole, true },
|
||||
{ RuntimeRole, 20 },
|
||||
{ ColorRole, "blue" },
|
||||
{ AlignmentRole, "center" },
|
||||
{ ScrollRole, true },
|
||||
{ ScrollCountRole, 20 }
|
||||
};
|
||||
|
||||
QMap<int, QVariant> sampleText2 = {
|
||||
{ TextRole, "Das ist ein tolles Display" },
|
||||
{ ActiveRole, false },
|
||||
{ RuntimeRole, 10 },
|
||||
{ ColorRole, "green" },
|
||||
{ AlignmentRole, "left" },
|
||||
{ ScrollRole, true },
|
||||
{ ScrollCountRole, 10 }
|
||||
};
|
||||
|
||||
this->texts.append(sampleText1);
|
||||
this->texts.append(sampleText2);
|
||||
}
|
||||
|
||||
|
||||
|
@ -34,9 +12,12 @@ int OmobiDisplayTextModel::rowCount(const QModelIndex &) const
|
|||
|
||||
QVariant OmobiDisplayTextModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (index.row() < rowCount())
|
||||
if(this->texts[index.row()].contains(role))
|
||||
if (index.row() < rowCount()) {
|
||||
if(role == IndexRole)
|
||||
return index.row();
|
||||
else if(this->texts[index.row()].contains(role))
|
||||
return this->texts[index.row()][role];
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
|
@ -51,7 +32,7 @@ QHash<int, QByteArray> OmobiDisplayTextModel::roleNames() const
|
|||
{ ScrollRole, "scroll" },
|
||||
{ ScrollSpeedRole, "scrollSpeed" },
|
||||
{ ScrollCountRole, "scrollCount" },
|
||||
{ BrightnessRole, "brightness" }
|
||||
{ IndexRole, "index" }
|
||||
};
|
||||
return roles;
|
||||
}
|
||||
|
@ -64,8 +45,7 @@ void OmobiDisplayTextModel::append(
|
|||
QString alignment,
|
||||
bool scroll,
|
||||
unsigned int scrollSpeed,
|
||||
unsigned int scrollCount,
|
||||
unsigned int brightness
|
||||
unsigned int scrollCount
|
||||
) {
|
||||
QMap<int, QVariant> roles = {
|
||||
{ TextRole, text },
|
||||
|
@ -75,8 +55,7 @@ void OmobiDisplayTextModel::append(
|
|||
{ AlignmentRole, alignment },
|
||||
{ ScrollRole, scroll },
|
||||
{ ScrollSpeedRole, scrollSpeed },
|
||||
{ ScrollCountRole, scrollCount },
|
||||
{ BrightnessRole, brightness }
|
||||
{ ScrollCountRole, scrollCount }
|
||||
};
|
||||
|
||||
this->append(roles);
|
||||
|
@ -118,6 +97,18 @@ void OmobiDisplayTextModel::clear() {
|
|||
this->remove(i);
|
||||
}
|
||||
|
||||
QString OmobiDisplayTextModel::getAsJson() {
|
||||
return "";
|
||||
bool OmobiDisplayTextModel::setTexts(QList<QMap<int, QVariant>> texts) {
|
||||
this->beginResetModel();
|
||||
this->resetInternalData();
|
||||
this->texts.clear();
|
||||
this->endResetModel();
|
||||
|
||||
for(QMap<int, QVariant> text : texts)
|
||||
this->append(text);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QList<QMap<int, QVariant>> OmobiDisplayTextModel::getTexts() {
|
||||
return this->texts;
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
#include <QColor>
|
||||
#include <QDebug>
|
||||
|
||||
|
||||
class OmobiDisplayTextModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@ -22,7 +21,7 @@ public:
|
|||
ScrollRole,
|
||||
ScrollSpeedRole,
|
||||
ScrollCountRole,
|
||||
BrightnessRole
|
||||
IndexRole
|
||||
};
|
||||
Q_ENUM(QBluetoothLeUartDeviceModelRole)
|
||||
|
||||
|
@ -38,8 +37,7 @@ public:
|
|||
QString alignment,
|
||||
bool scroll,
|
||||
unsigned int scrollSpeed,
|
||||
unsigned int scrollCount,
|
||||
unsigned int brightness
|
||||
unsigned int scrollCount
|
||||
);
|
||||
void append(const QMap<int, QVariant> &roles);
|
||||
|
||||
|
@ -50,8 +48,8 @@ public:
|
|||
protected:
|
||||
OmobiDisplayTextModel(QObject* parent = nullptr);
|
||||
|
||||
void reloadFromJson(QString json);
|
||||
QString getAsJson();
|
||||
bool setTexts(QList<QMap<int, QVariant>> json);
|
||||
QList<QMap<int, QVariant>> getTexts();
|
||||
|
||||
void clear();
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import QtQuick 2.0
|
||||
import QtQuick.Controls 2.0
|
||||
import QtQuick.Controls.Material 2.0
|
||||
|
||||
ItemDelegate {
|
||||
id: control
|
||||
|
|
96
OmobiDisplayApp/ressources/qml/ComboBoxDelegate.qml
Normal file
96
OmobiDisplayApp/ressources/qml/ComboBoxDelegate.qml
Normal file
|
@ -0,0 +1,96 @@
|
|||
import QtQuick 2.0
|
||||
import QtQuick.Controls 2.9
|
||||
import QtQuick.Controls.Material 2.0
|
||||
|
||||
ItemDelegate {
|
||||
id: control
|
||||
|
||||
property var model: []
|
||||
property string currentText: model[currentIndex]
|
||||
property int currentIndex: 0
|
||||
|
||||
onClicked: {
|
||||
if(currentText != "")
|
||||
currentIndex = model.indexOf(currentText)
|
||||
else
|
||||
currentIndex = 0
|
||||
|
||||
textEditDialog.open()
|
||||
}
|
||||
|
||||
Text {
|
||||
anchors {
|
||||
right: nextPageIconText.left
|
||||
verticalCenter: parent.verticalCenter
|
||||
rightMargin: control.padding
|
||||
}
|
||||
|
||||
font.pixelSize: parent.font.pixelSize
|
||||
|
||||
color: control.Material.foreground
|
||||
|
||||
text: currentText === "" ? "Not set": currentText
|
||||
}
|
||||
|
||||
Text {
|
||||
id: nextPageIconText
|
||||
|
||||
anchors {
|
||||
right: parent.right
|
||||
verticalCenter: parent.verticalCenter
|
||||
rightMargin: control.padding
|
||||
}
|
||||
|
||||
font.pixelSize: parent.height * 0.5
|
||||
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
|
||||
color: control.Material.foreground
|
||||
|
||||
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
|
||||
|
||||
standardButtons: Dialog.Ok | Dialog.Cancel
|
||||
|
||||
contentItem: ListView {
|
||||
id: listView
|
||||
|
||||
implicitHeight: childrenRect.height
|
||||
|
||||
delegate: RadioDelegate {
|
||||
width: parent.width
|
||||
checked: index === control.currentIndex
|
||||
ButtonGroup.group: buttonGroup
|
||||
text: modelData
|
||||
}
|
||||
}
|
||||
|
||||
onAboutToShow: {
|
||||
listView.model = []
|
||||
listView.model = control.model
|
||||
}
|
||||
|
||||
onAccepted: {
|
||||
control.currentText = buttonGroup.checkedButton.text
|
||||
}
|
||||
|
||||
ButtonGroup {
|
||||
id: buttonGroup
|
||||
}
|
||||
}
|
||||
}
|
|
@ -14,7 +14,7 @@ Page {
|
|||
ColumnLayout {
|
||||
anchors {
|
||||
fill: parent
|
||||
margins: parent.height * 0.05
|
||||
margins: parent.height * 0.01
|
||||
topMargin: 0
|
||||
}
|
||||
|
||||
|
@ -110,44 +110,21 @@ Page {
|
|||
onClicked: backend.bleController.connectToDevice(device)
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: "transparent"
|
||||
border.color: "lightgrey"
|
||||
border.width: 3
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
topMargin: - availableDevicesListView.spacing * 0.5
|
||||
}
|
||||
|
||||
color: "lightgrey"
|
||||
height: 1
|
||||
visible: index !== 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Popup {
|
||||
id: connectingPopup
|
||||
|
||||
property bool shouldBeOpened: false
|
||||
|
||||
parent: Overlay.overlay
|
||||
|
||||
x: (parent.width - width) / 2
|
||||
y: (parent.height - height) / 2
|
||||
|
||||
closePolicy: Popup.NoAutoClose
|
||||
|
||||
dim: true
|
||||
|
||||
contentItem: Column {
|
||||
BusyIndicator {
|
||||
running: true
|
||||
}
|
||||
}
|
||||
|
||||
onShouldBeOpenedChanged: {
|
||||
if(shouldBeOpened)
|
||||
connectingPopup.open()
|
||||
else
|
||||
connectingPopup.close()
|
||||
}
|
||||
}
|
||||
|
||||
states: [
|
||||
State {
|
||||
name: OmobiDisplayBackend.Idle
|
||||
|
|
|
@ -1,13 +1,67 @@
|
|||
import QtQuick 2.0
|
||||
import QtQuick.Controls 2.9
|
||||
import QtQuick.Layouts 1.0
|
||||
import QtQuick.Controls.Material 2.0
|
||||
|
||||
import de.itsblue.omobidisplayapp 1.0
|
||||
import de.itsblue.bluetoothleuart 1.0
|
||||
|
||||
Page {
|
||||
id: root
|
||||
|
||||
DisplayTextModelListView {
|
||||
anchors.fill: parent
|
||||
ColumnLayout {
|
||||
anchors {
|
||||
fill: parent
|
||||
margins: parent.height * 0.01
|
||||
topMargin: 0
|
||||
}
|
||||
|
||||
Text {
|
||||
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
|
||||
|
||||
from: 0
|
||||
to: 10
|
||||
stepSize: 1
|
||||
|
||||
value: backend.displayBrightness
|
||||
|
||||
onPressedChanged: {
|
||||
if(!pressed)
|
||||
backend.displayBrightness = value
|
||||
}
|
||||
}
|
||||
|
||||
DisplayTextModelListView {
|
||||
Layout.preferredWidth: parent.width
|
||||
Layout.fillHeight: true
|
||||
Layout.alignment: Layout.Center
|
||||
|
||||
clip: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,52 +1,118 @@
|
|||
import QtQuick 2.0
|
||||
import QtQuick.Controls 2.0
|
||||
import QtQuick.Layouts 1.0
|
||||
import QtQuick.Controls.Material 2.0
|
||||
|
||||
CollapsableItemDelegate {
|
||||
ItemDelegate {
|
||||
id: control
|
||||
|
||||
expandedComponent: Component {
|
||||
Item {
|
||||
implicitHeight: 200
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
|
||||
TextField {
|
||||
id: textTextInput
|
||||
Layout.preferredWidth: parent.width
|
||||
Layout.preferredHeight: 50
|
||||
text: model.text
|
||||
}
|
||||
|
||||
Button {
|
||||
Layout.preferredWidth: parent.width
|
||||
Layout.preferredHeight: 50
|
||||
|
||||
text: "apply"
|
||||
|
||||
onClicked: {
|
||||
model.text = textTextInput.text
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
id: labelText
|
||||
implicitHeight: 50
|
||||
|
||||
Rectangle {
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
margins: 5
|
||||
topMargin: - control.ListView.view.spacing * 0.5
|
||||
}
|
||||
|
||||
height: 70 - 2 * anchors.margins
|
||||
color: "lightgrey"
|
||||
height: 1
|
||||
visible: model.index !== 0
|
||||
}
|
||||
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
text: model.text
|
||||
|
||||
font.pixelSize: height * 0.4
|
||||
text: model.text
|
||||
contentItem: RowLayout {
|
||||
spacing: 5
|
||||
|
||||
Text {
|
||||
Layout.fillWidth: true
|
||||
|
||||
elide: Text.ElideRight
|
||||
|
||||
opacity: model.active ? 1:0.5
|
||||
|
||||
color: control.Material.foreground
|
||||
|
||||
text: control.text
|
||||
|
||||
Behavior on opacity {
|
||||
NumberAnimation {}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
Layout.fillHeight: true
|
||||
Layout.preferredWidth: model.scroll ? parent.width * 0.15 : 0
|
||||
|
||||
visible: model.scroll
|
||||
|
||||
radius: height * 0.1
|
||||
|
||||
color: model.active ? Material.accent:"lightgrey"
|
||||
|
||||
Behavior on color {
|
||||
ColorAnimation {}
|
||||
}
|
||||
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
|
||||
width: parent.width * 0.9
|
||||
height: parent.height * 0.8
|
||||
|
||||
font.pixelSize: height
|
||||
fontSizeMode: Text.Fit
|
||||
minimumPixelSize: 1
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
|
||||
color: "white"
|
||||
|
||||
text: model.scroll ? qsTr("scrolling"):qsTr("false")
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
Layout.preferredHeight: parent.height
|
||||
Layout.preferredWidth: parent.width * 0.15
|
||||
|
||||
radius: height * 0.1
|
||||
|
||||
color: model.active ? "green" : "red"
|
||||
|
||||
Behavior on color {
|
||||
ColorAnimation {}
|
||||
}
|
||||
|
||||
Text {
|
||||
id: activeText
|
||||
anchors.centerIn: parent
|
||||
|
||||
width: parent.width * 0.8
|
||||
height: parent.height * 0.8
|
||||
|
||||
font.pixelSize: height
|
||||
fontSizeMode: Text.Fit
|
||||
minimumPixelSize: 1
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
|
||||
color: "white"
|
||||
text: model.active ? qsTr(" active "):qsTr("inactive")
|
||||
}
|
||||
|
||||
Button {
|
||||
anchors.centerIn: parent
|
||||
width: parent.width
|
||||
height: parent.height * 1.4
|
||||
flat: true
|
||||
|
||||
onClicked: {
|
||||
model.active = !model.active
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,18 +1,30 @@
|
|||
import QtQuick 2.4
|
||||
import QtQuick.Controls 2.9
|
||||
import QtQuick.Layouts 1.9
|
||||
import de.itsblue.omobidisplayapp 1.0
|
||||
import QtQuick.Controls.Material 2.0
|
||||
|
||||
import de.itsblue.omobidisplayapp 1.0
|
||||
|
||||
ListView {
|
||||
id: control
|
||||
|
||||
|
||||
|
||||
model: backend.displayTextModel
|
||||
|
||||
add: Transition {
|
||||
NumberAnimation { property: "opacity"; from: 0; to: 1; duration: 200 }
|
||||
NumberAnimation { property: "scale"; from: 0.9; to: 1; duration: 200 }
|
||||
}
|
||||
|
||||
remove: Transition {
|
||||
NumberAnimation { property: "opacity"; from: 1; to: 0; duration: 200 }
|
||||
NumberAnimation { property: "scale"; from: 1; to: 0.9; duration: 200 }
|
||||
}
|
||||
|
||||
spacing: 5
|
||||
|
||||
delegate: DisplayTextDelegate {
|
||||
id: delegate
|
||||
|
||||
width: control.width
|
||||
|
||||
onClicked: {
|
||||
|
@ -27,12 +39,14 @@ ListView {
|
|||
bottomMargin: height * 0.25
|
||||
}
|
||||
|
||||
height: parent.width * 0.15
|
||||
height: implicitHeight * 1.3
|
||||
width: height
|
||||
|
||||
Material.background: Material.accent
|
||||
|
||||
text: ""
|
||||
|
||||
onClicked: popup.add()
|
||||
onClicked: popup.add(control.model)
|
||||
|
||||
Text {
|
||||
anchors.fill: parent
|
||||
|
@ -42,250 +56,21 @@ ListView {
|
|||
|
||||
font.pixelSize: height * 0.4
|
||||
|
||||
color: "white"
|
||||
|
||||
text: "+"
|
||||
}
|
||||
}
|
||||
|
||||
Dialog {
|
||||
TextEditDialog {
|
||||
id: popup
|
||||
|
||||
property bool editing
|
||||
property var editingModel
|
||||
|
||||
parent: Overlay.overlay
|
||||
|
||||
x: (parent.width - width) / 2
|
||||
|
||||
width: parent.width
|
||||
height: parent.height * 0.7
|
||||
|
||||
modal: true
|
||||
|
||||
title: editing ? "Edit item" : "New item"
|
||||
|
||||
onAccepted: {
|
||||
if(editing) {
|
||||
editingModel.active = activeSwitch.checked
|
||||
editingModel.text = textTextField.text
|
||||
editingModel.runtime = runtimeSpinBox.value
|
||||
editingModel.color = colorComboBox.currentText
|
||||
editingModel.alignment = alignmentComboBox.currentText
|
||||
editingModel.scroll = scrollSwitch.checked
|
||||
editingModel.scrollSpeed = scrollSpeedSpinBox.value
|
||||
editingModel.scrollCount = scrollCountSpinBox.value
|
||||
editingModel.brightness = brightnessSpinBox.value
|
||||
}
|
||||
else {
|
||||
control.model.append(textTextField.text,
|
||||
activeSwitch.checked,
|
||||
runtimeSpinBox.value,
|
||||
colorComboBox.currentText,
|
||||
alignmentComboBox.currentText,
|
||||
scrollSwitch.checked,
|
||||
scrollSpeedSpinBox.value,
|
||||
scrollCountSpinBox.value,
|
||||
brightnessSpinBox.value
|
||||
)
|
||||
}
|
||||
}
|
||||
Material.theme: control.Material.theme
|
||||
Material.accent: control.Material.accent
|
||||
|
||||
onDiscarded: {
|
||||
control.model.remove(0)
|
||||
control.model.remove(editingModel.index)
|
||||
popup.close()
|
||||
}
|
||||
|
||||
contentItem: GridLayout {
|
||||
|
||||
property int rowHeight: 50
|
||||
|
||||
columns: 2
|
||||
columnSpacing: 10
|
||||
|
||||
Label {
|
||||
font.bold: true
|
||||
text: "Active:"
|
||||
}
|
||||
|
||||
Switch {
|
||||
id: activeSwitch
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
Label {
|
||||
font.bold: true
|
||||
text: "Text:"
|
||||
}
|
||||
|
||||
TextField {
|
||||
id: textTextField
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
Label {
|
||||
font.bold: true
|
||||
text: "Runtime (in s):"
|
||||
}
|
||||
|
||||
SpinBox {
|
||||
id: runtimeSpinBox
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
Label {
|
||||
font.bold: true
|
||||
text: "Color:"
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
id: colorComboBox
|
||||
Layout.fillWidth: true
|
||||
model: ["white", "blue", "red", "green"]
|
||||
}
|
||||
|
||||
Label {
|
||||
font.bold: true
|
||||
text: "Alignment:"
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
id: alignmentComboBox
|
||||
Layout.fillWidth: true
|
||||
model: ["left", "center", "right"]
|
||||
}
|
||||
|
||||
Label {
|
||||
font.bold: true
|
||||
text: "Scroll:"
|
||||
}
|
||||
|
||||
Switch {
|
||||
id: scrollSwitch
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
Label {
|
||||
font.bold: true
|
||||
text: "Scroll speed:"
|
||||
}
|
||||
|
||||
SpinBox {
|
||||
id: scrollSpeedSpinBox
|
||||
Layout.fillWidth: true
|
||||
from: 0
|
||||
to: 10
|
||||
}
|
||||
|
||||
Label {
|
||||
font.bold: true
|
||||
text: "Scroll count:"
|
||||
}
|
||||
|
||||
SpinBox {
|
||||
id: scrollCountSpinBox
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
Label {
|
||||
font.bold: true
|
||||
text: "Brightness:"
|
||||
}
|
||||
|
||||
SpinBox {
|
||||
id: brightnessSpinBox
|
||||
Layout.fillWidth: true
|
||||
from: 0
|
||||
to: 10
|
||||
}
|
||||
}
|
||||
|
||||
footer: DialogButtonBox {
|
||||
|
||||
// alignment: Qt.AlignHCenter
|
||||
buttonLayout: DialogButtonBox.GnomeLayout
|
||||
|
||||
Button {
|
||||
|
||||
flat: true
|
||||
|
||||
text: "save"
|
||||
|
||||
DialogButtonBox.buttonRole: DialogButtonBox.AcceptRole
|
||||
}
|
||||
|
||||
Button {
|
||||
|
||||
flat: true
|
||||
|
||||
text: "cancel"
|
||||
|
||||
|
||||
DialogButtonBox.buttonRole: DialogButtonBox.RejectRole
|
||||
}
|
||||
|
||||
Button {
|
||||
visible: popup.editing
|
||||
|
||||
Material.background: Material.Red
|
||||
Material.foreground: "white"
|
||||
|
||||
flat: false
|
||||
|
||||
text: "delete"
|
||||
|
||||
|
||||
DialogButtonBox.buttonRole: DialogButtonBox.DestructiveRole
|
||||
}
|
||||
}
|
||||
|
||||
enter: Transition {
|
||||
ParallelAnimation {
|
||||
NumberAnimation { property: "opacity"; from: 0; to: 1 }
|
||||
NumberAnimation { property: "y"; from: popup.parent.height - popup.height * 0.75; to: popup.parent.height - popup.height }
|
||||
}
|
||||
}
|
||||
|
||||
exit: Transition {
|
||||
ParallelAnimation {
|
||||
NumberAnimation { property: "opacity"; from: 1; to: 0 }
|
||||
NumberAnimation { property: "y"; from: popup.parent.height - popup.height; to: popup.parent.height - popup.height * 0.75 }
|
||||
}
|
||||
}
|
||||
|
||||
function edit(model) {
|
||||
editingModel = model
|
||||
editing = true
|
||||
|
||||
reset()
|
||||
|
||||
activeSwitch.checked = editingModel.active
|
||||
textTextField.text = editingModel.text
|
||||
runtimeSpinBox.value = editingModel.runtime
|
||||
colorComboBox.currentIndex = colorComboBox.model.indexOf(editingModel.color)
|
||||
alignmentComboBox.currentIndex = alignmentComboBox.model.indexOf(editingModel.alignment)
|
||||
scrollSwitch.checked = editingModel.scroll
|
||||
scrollSpeedSpinBox = editingModel.scrollSpeed
|
||||
scrollCountSpinBox.value = editingModel.scrollCount
|
||||
brightnessSpinBox = editingModel.brightness
|
||||
|
||||
open()
|
||||
}
|
||||
|
||||
function add() {
|
||||
editing = false
|
||||
reset()
|
||||
open()
|
||||
}
|
||||
|
||||
function reset() {
|
||||
activeSwitch.checked = false
|
||||
textTextField.text = ""
|
||||
runtimeSpinBox.value = 0
|
||||
colorComboBox.currentIndex = 0
|
||||
alignmentComboBox.currentIndex = 0
|
||||
scrollSwitch.checked = false
|
||||
scrollSpeedSpinBox.value = 5
|
||||
scrollCountSpinBox.value = 0
|
||||
brightnessSpinBox.value = 10
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
6
OmobiDisplayApp/ressources/qml/NextPageDelegate.qml
Normal file
6
OmobiDisplayApp/ressources/qml/NextPageDelegate.qml
Normal file
|
@ -0,0 +1,6 @@
|
|||
import QtQuick 2.0
|
||||
import QtQuick.Controls 2.9
|
||||
|
||||
ItemDelegate {
|
||||
|
||||
}
|
75
OmobiDisplayApp/ressources/qml/SpinBoxDelegate.qml
Normal file
75
OmobiDisplayApp/ressources/qml/SpinBoxDelegate.qml
Normal file
|
@ -0,0 +1,75 @@
|
|||
import QtQuick 2.0
|
||||
import QtQuick.Controls 2.9
|
||||
import QtQuick.Controls.Material 2.0
|
||||
|
||||
ItemDelegate {
|
||||
id: control
|
||||
|
||||
property string value: ""
|
||||
property alias from: spinBox.from
|
||||
property alias to: spinBox.to
|
||||
|
||||
onClicked: {
|
||||
spinBox.value = control.value
|
||||
textEditDialog.open()
|
||||
}
|
||||
|
||||
Text {
|
||||
anchors {
|
||||
right: nextPageIconText.left
|
||||
verticalCenter: parent.verticalCenter
|
||||
rightMargin: control.padding
|
||||
}
|
||||
|
||||
font.pixelSize: parent.font.pixelSize
|
||||
|
||||
color: control.Material.foreground
|
||||
|
||||
text: value === "" ? "Not set": value + ""
|
||||
}
|
||||
|
||||
Text {
|
||||
id: nextPageIconText
|
||||
|
||||
anchors {
|
||||
right: parent.right
|
||||
verticalCenter: parent.verticalCenter
|
||||
rightMargin: control.padding
|
||||
}
|
||||
|
||||
font.pixelSize: parent.height * 0.5
|
||||
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
|
||||
color: control.Material.foreground
|
||||
|
||||
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
|
||||
|
||||
standardButtons: Dialog.Ok | Dialog.Cancel
|
||||
|
||||
contentItem: SpinBox {
|
||||
id: spinBox
|
||||
value: control.value
|
||||
}
|
||||
|
||||
onAccepted: {
|
||||
control.value = spinBox.value
|
||||
}
|
||||
}
|
||||
}
|
192
OmobiDisplayApp/ressources/qml/TextEditDialog.qml
Normal file
192
OmobiDisplayApp/ressources/qml/TextEditDialog.qml
Normal file
|
@ -0,0 +1,192 @@
|
|||
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
|
||||
|
||||
property bool editing
|
||||
property var editingModel
|
||||
|
||||
parent: Overlay.overlay
|
||||
|
||||
x: (parent.width - width) / 2
|
||||
y: (parent.height - height) / 2
|
||||
|
||||
width: parent.width * 0.9
|
||||
height: Math.min(parent.height * 0.9, control.implicitHeight)
|
||||
|
||||
modal: true
|
||||
|
||||
title: editing ? "Edit item" : "New item"
|
||||
|
||||
onAccepted: {
|
||||
if(editing) {
|
||||
editingModel.active = activeSwitch.checked
|
||||
editingModel.text = textTextField.value
|
||||
editingModel.runtime = runtimeSpinBox.value
|
||||
editingModel.color = colorComboBox.currentText
|
||||
editingModel.alignment = alignmentComboBox.currentText
|
||||
editingModel.scroll = scrollSwitch.checked
|
||||
editingModel.scrollSpeed = scrollSpeedSpinBox.value
|
||||
editingModel.scrollCount = scrollCountSpinBox.value
|
||||
}
|
||||
else {
|
||||
editingModel.append(textTextField.value,
|
||||
activeSwitch.checked,
|
||||
runtimeSpinBox.value,
|
||||
colorComboBox.currentText,
|
||||
alignmentComboBox.currentText,
|
||||
scrollSwitch.checked,
|
||||
scrollSpeedSpinBox.value,
|
||||
scrollCountSpinBox.value
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
contentItem: Flickable {
|
||||
|
||||
implicitHeight: dataFieldsGridLayout.height
|
||||
contentHeight: dataFieldsGridLayout.height
|
||||
|
||||
clip: true
|
||||
boundsBehavior: Flickable.OvershootBounds
|
||||
|
||||
ScrollBar.vertical: ScrollBar {
|
||||
interactive: false
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: dataFieldsGridLayout
|
||||
|
||||
property double fontSizeMultiplier: 0.14
|
||||
property double labelWidthMultiplier: 0.4
|
||||
|
||||
width: control.width * 0.9
|
||||
|
||||
SwitchDelegate {
|
||||
id: activeSwitch
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Active")
|
||||
}
|
||||
|
||||
TextInputDelegate {
|
||||
id: textTextField
|
||||
Layout.fillWidth: true
|
||||
required: true
|
||||
placeholderText: qsTr("Enter some text to be displayed")
|
||||
|
||||
text: qsTr("Text")
|
||||
}
|
||||
|
||||
SpinBoxDelegate {
|
||||
id: runtimeSpinBox
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Runtime (in s)")
|
||||
}
|
||||
|
||||
ComboBoxDelegate {
|
||||
id: colorComboBox
|
||||
Layout.fillWidth: true
|
||||
model: ["white", "blue", "red", "green"]
|
||||
text: qsTr("Color")
|
||||
}
|
||||
|
||||
ComboBoxDelegate {
|
||||
id: alignmentComboBox
|
||||
Layout.fillWidth: true
|
||||
model: ["left", "center", "right"]
|
||||
text: qsTr("Alignment")
|
||||
}
|
||||
|
||||
SwitchDelegate {
|
||||
id: scrollSwitch
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Scroll")
|
||||
}
|
||||
|
||||
SpinBoxDelegate {
|
||||
id: scrollSpeedSpinBox
|
||||
Layout.fillWidth: true
|
||||
from: 0
|
||||
to: 10
|
||||
text: qsTr("Scroll speed")
|
||||
}
|
||||
|
||||
SpinBoxDelegate {
|
||||
id: scrollCountSpinBox
|
||||
Layout.fillWidth: true
|
||||
from: 0
|
||||
text: qsTr("Scroll count:")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
footer: DialogButtonBox {
|
||||
|
||||
// alignment: Qt.AlignHCenter
|
||||
buttonLayout: DialogButtonBox.GnomeLayout
|
||||
|
||||
Material.background: "transparent"
|
||||
|
||||
Button {
|
||||
flat: true
|
||||
enabled: textTextField.value !== ""
|
||||
text: "save"
|
||||
DialogButtonBox.buttonRole: DialogButtonBox.AcceptRole
|
||||
}
|
||||
|
||||
Button {
|
||||
flat: true
|
||||
text: "cancel"
|
||||
DialogButtonBox.buttonRole: DialogButtonBox.RejectRole
|
||||
}
|
||||
|
||||
Button {
|
||||
visible: popup.editing
|
||||
Material.foreground: Material.Red
|
||||
flat: true
|
||||
text: "delete"
|
||||
DialogButtonBox.buttonRole: DialogButtonBox.DestructiveRole
|
||||
}
|
||||
}
|
||||
|
||||
function edit(model) {
|
||||
editingModel = model
|
||||
editing = true
|
||||
|
||||
reset()
|
||||
|
||||
activeSwitch.checked = editingModel.active
|
||||
textTextField.value = editingModel.text
|
||||
runtimeSpinBox.value = editingModel.runtime
|
||||
colorComboBox.currentIndex = colorComboBox.model.indexOf(editingModel.color)
|
||||
alignmentComboBox.currentIndex = alignmentComboBox.model.indexOf(editingModel.alignment)
|
||||
scrollSwitch.checked = editingModel.scroll
|
||||
scrollSpeedSpinBox.value = editingModel.scrollSpeed
|
||||
scrollCountSpinBox.value = editingModel.scrollCount
|
||||
|
||||
open()
|
||||
}
|
||||
|
||||
function add(model) {
|
||||
editingModel = model
|
||||
editing = false
|
||||
reset()
|
||||
open()
|
||||
}
|
||||
|
||||
function reset() {
|
||||
activeSwitch.checked = true
|
||||
textTextField.value = ""
|
||||
runtimeSpinBox.value = 0
|
||||
colorComboBox.currentIndex = 0
|
||||
alignmentComboBox.currentIndex = 0
|
||||
scrollSwitch.checked = false
|
||||
scrollSpeedSpinBox.value = 5
|
||||
scrollCountSpinBox.value = 0
|
||||
}
|
||||
}
|
82
OmobiDisplayApp/ressources/qml/TextInputDelegate.qml
Normal file
82
OmobiDisplayApp/ressources/qml/TextInputDelegate.qml
Normal file
|
@ -0,0 +1,82 @@
|
|||
import QtQuick 2.0
|
||||
import QtQuick.Controls 2.9
|
||||
import QtQuick.Controls.Material 2.0
|
||||
|
||||
ItemDelegate {
|
||||
id: control
|
||||
|
||||
property string value: ""
|
||||
property bool required: false
|
||||
property color textColor: control.required && value === "" ? "red":control.Material.foreground
|
||||
property string placeholderText: ""
|
||||
|
||||
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
|
||||
|
||||
color: control.textColor
|
||||
|
||||
text: value === "" ? "Not set": value + ""
|
||||
}
|
||||
|
||||
Text {
|
||||
id: nextPageIconText
|
||||
|
||||
anchors {
|
||||
right: parent.right
|
||||
verticalCenter: parent.verticalCenter
|
||||
rightMargin: control.padding
|
||||
}
|
||||
|
||||
font.pixelSize: parent.height * 0.5
|
||||
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
|
||||
color: control.textColor
|
||||
|
||||
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
|
||||
|
||||
standardButtons: Dialog.Ok | Dialog.Cancel
|
||||
|
||||
contentItem: TextField {
|
||||
id: textField
|
||||
|
||||
placeholderText: control.placeholderText
|
||||
text: control.value
|
||||
}
|
||||
|
||||
onAccepted: {
|
||||
control.value = textField.text
|
||||
}
|
||||
}
|
||||
}
|
|
@ -22,6 +22,9 @@ ApplicationWindow {
|
|||
|
||||
anchors.fill: parent
|
||||
|
||||
Material.accent: "#0094ff"
|
||||
Material.theme: Material.System
|
||||
|
||||
header: ToolBar {
|
||||
Material.background: "white"
|
||||
|
||||
|
@ -47,11 +50,11 @@ ApplicationWindow {
|
|||
property Component currentComponent
|
||||
|
||||
onCurrentComponentChanged: {
|
||||
//if(currentComponent != currentItem)
|
||||
//mainStack.replace(currentComponent)
|
||||
if(currentComponent != currentItem)
|
||||
mainStack.replace(currentComponent)
|
||||
}
|
||||
|
||||
initialItem: connectedPageComp
|
||||
//initialItem: connectedPageComp
|
||||
|
||||
Component {
|
||||
id: connectPageComp
|
||||
|
|
|
@ -6,5 +6,10 @@
|
|||
<file>DisplayTextDelegate.qml</file>
|
||||
<file>CollapsableItemDelegate.qml</file>
|
||||
<file>DisplayTextModelListView.qml</file>
|
||||
<file>TextEditDialog.qml</file>
|
||||
<file>TextInputDelegate.qml</file>
|
||||
<file>NextPageDelegate.qml</file>
|
||||
<file>SpinBoxDelegate.qml</file>
|
||||
<file>ComboBoxDelegate.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
Loading…
Reference in a new issue