- finished implementing protocol

- added Initializing and Loading states
- added color picker
This commit is contained in:
Dorian Zedler 2020-10-14 23:54:12 +02:00
parent 6fbae42867
commit ce6d436c85
Signed by: dorian
GPG key ID: D3B255CB8BC7CD37
13 changed files with 518 additions and 116 deletions

View file

@ -4,12 +4,17 @@ OmobiDisplayBackend::OmobiDisplayBackend(QObject *parent) : QObject(parent)
{ {
this->ble = new QBluetoothLeUart(); this->ble = new QBluetoothLeUart();
this->displayTextModel = new OmobiDisplayTextModel(this); this->displayTextModel = new OmobiDisplayTextModel(this);
this->textSetsBuffer.clear();
this->displayBrightness = -1;
this->waitingCommands = 0;
connect(this->ble, &QBluetoothLeUart::stateChanged, this, &OmobiDisplayBackend::handleBluetoothStateChange); connect(this->ble, &QBluetoothLeUart::stateChanged, this, &OmobiDisplayBackend::handleBluetoothStateChange);
connect(this->ble, &QBluetoothLeUart::foundNewDevice, this, &OmobiDisplayBackend::handleFoundNewDevice); connect(this->ble, &QBluetoothLeUart::foundNewDevice, this, &OmobiDisplayBackend::handleFoundNewDevice);
connect(this->ble, &QBluetoothLeUart::dataReceived, this, &OmobiDisplayBackend::DataHandler); connect(this->ble, &QBluetoothLeUart::dataReceived, this, &OmobiDisplayBackend::handleBluetoothDataReceived);
connect(this->ble, &QBluetoothLeUart::connectedToDevice, this, &OmobiDisplayBackend::handleBluetoothDeviceConected); connect(this->ble, &QBluetoothLeUart::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::rowsRemoved, this, &OmobiDisplayBackend::handleDisplayTextModelRowsRemoved);
this->setState(Idle); this->setState(Idle);
this->ble->startScanningForDevices(); this->ble->startScanningForDevices();
@ -54,96 +59,145 @@ void OmobiDisplayBackend::handleBluetoothStateChange(QBluetoothLeUart::Bluetooth
} }
void OmobiDisplayBackend::handleBluetoothDeviceConected() { void OmobiDisplayBackend::handleBluetoothDeviceConected() {
this->ble->sendData("GET_TEXTS"); this->setState(Initing);
this->ble->sendData("GET_BRIGHTNESS");
// get the existing model data! // tell display to send over existing model data
// TODO: implement some communication! this->sendBluetoothCommand(GetAllTextSetsCommand);
this->sendBluetoothCommand(GetDisplayBrightnessCommand);
QString currentDisplayText = "[[],[]]";
this->setState(Connected);
} }
void OmobiDisplayBackend::handleFoundNewDevice(QBluetoothLeUartDevice* device) { void OmobiDisplayBackend::handleFoundNewDevice(QBluetoothLeUartDevice* device) {
qDebug() << "Found a device: name: " << device->getName() << " address: " << device->getAddress(); qDebug() << "Found a device: name: " << device->getName() << " address: " << device->getAddress();
} }
void OmobiDisplayBackend::DataHandler(QString s){ void OmobiDisplayBackend::handleDisplayTextModelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles) {
qDebug() << "New data: " << s;
if(s.startsWith("GET_TEXTS:")) {
QJsonParseError parseError;
QJsonDocument doc = QJsonDocument::fromJson(s.replace("GET_TEXTS:", "").toUtf8(), &parseError);
if(parseError.error != QJsonParseError::NoError) qDebug() << "Data changed: topLeft: " << topLeft << " bottomRight: " << bottomRight << " roles: " << roles;
for(int role : roles)
this->updateDisplayTextSetParameter(topLeft.row(), role);
}
void OmobiDisplayBackend::handleDisplayTextModelRowsInserted(const QModelIndex &parent, int first, int last) {
qDebug() << "Rows inserted: parent: " << parent << " first: " << first << " last " << last;
for(int i = 0; i < OmobiDisplayTextModel::OmobiDisplayTextModelRoleCount; i++) {
this->updateDisplayTextSetParameter(first, i);
}
}
void OmobiDisplayBackend::handleDisplayTextModelRowsRemoved(const QModelIndex &parent, int first, int last) {
qDebug() << "Rows removed: parent: " << parent << " first: " << first << " last " << last;
// Setting Text to "" will delete the item
this->updateDisplayTextSetParameter(first, OmobiDisplayTextModel::TextRole, "");
}
void OmobiDisplayBackend::sendBluetoothCommand(OmobiDisplayCommand command, QVariant data) {
QVariantMap commandMap = {
{"header", command},
{"data", data}
};
QJsonDocument doc = QJsonDocument::fromVariant(commandMap);
qDebug() << "Sending command: \n" << qPrintable(doc.toJson(QJsonDocument::Indented));
this->waitingCommands ++;
if(this->state == Connected)
this->setState(Loading);
this->ble->sendData(doc.toJson(QJsonDocument::Compact));
}
void OmobiDisplayBackend::handleBluetoothDataReceived(QString s){
qDebug() << "New data: \n" << qPrintable(s);
QJsonParseError parseError;
QJsonDocument doc = QJsonDocument::fromJson(s.toUtf8(), &parseError);
if(parseError.error != QJsonParseError::NoError)
return;
OmobiDisplayCommand header = OmobiDisplayCommand(doc.toVariant().toMap()["header"].toInt());
QVariantMap data = doc.toVariant().toMap()["data"].toMap();
OmobiDisplayStatusCode status = OmobiDisplayStatusCode(doc.toVariant().toMap()["status"].toInt());
switch (header) {
case GetAllTextSetsCommand: {
// indicates that all existing txt sets have been sent over after GetAllTextSetsCommand was called
if(status != Success)
// TODO: handle error
break;
this->displayTextModel->maximumTextLength = data["maximumTextLength"].toInt();
this->displayTextModel->maximumTextSets = data["maximumTextSets"].toInt();
this->displayTextModel->setTexts(this->textSetsBuffer);
this->textSetsBuffer.clear();
this->refreshLoadingState();
break;
}
case GetTextSetParameterCommand: {
int index = data["index"].toInt();
if(index < 0)
return; return;
QList<QMap<int, QVariant>> texts; if(this->textSetsBuffer.length() <= index)
this->textSetsBuffer.append(QMap<int, QVariant>());
for(QVariant textMap : doc.toVariant().toList()) { int parameter = data["parameter"].toInt();
QMap<int, QVariant> text;
static const QMap<QString, int> keyTranslations { if(!this->textSetsBuffer[index].contains(parameter))
{ "text", OmobiDisplayTextModel::TextRole }, this->textSetsBuffer[index].insert(parameter, QVariant());
{ "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()) { this->textSetsBuffer[index][parameter] = data["value"].toString();
if(keyTranslations.contains(key)) {
if(key == "color") {
QVariantMap colorMap = textMap.toMap()[key].toMap();
QColor color(colorMap["r"].toInt(), colorMap["g"].toInt(), colorMap["b"].toInt());
text.insert(keyTranslations[key], color.name());
}
else
text.insert(keyTranslations[key], textMap.toMap()[key]);
}
}
texts.append(text); if(this->state != Initing)
} this->refreshLoadingState();
this->displayTextModel->setTexts(texts); break;
} }
else if(s.startsWith("GET_BRIGHTNESS:")) { case GetDisplayBrightnessCommand: {
this->displayBrightness = s.replace("GET_BRIGHTNESS:", "").toInt(); this->setDisplayBrightness(data["displayBrightness"].toInt());
emit this->displayBrightnessChanged(); this->refreshLoadingState();
break;
}
case SetTextSetParameterCommand: {
// TODO: Error handling
this->refreshLoadingState();
break;
}
case SetDisplayBrightnessCommand: {
// TODO: Error handling
this->refreshLoadingState();
break;
}
} }
} }
void OmobiDisplayBackend::handleDisplayTextModelDataChanged() { void OmobiDisplayBackend::updateDisplayTextSetParameter(int index, int parameter) {
this->updateDisplayTextSetParameter(index, parameter, this->displayTextModel->data(index, parameter).toString());
}
QVariantList textList; void OmobiDisplayBackend::updateDisplayTextSetParameter(int index, int parameter, QString value) {
if(this->state == Initing)
return;
qDebug() << "Updating data at index: " << index << " parameter: " << parameter << " and value: " << value;
for(QMap<int, QVariant> text : this->displayTextModel->getTexts()) { QVariantMap dataMap = {
QVariantHash textMap; {"index", index},
{"parameter", parameter},
{"value", value}
};
for(int key : text.keys()) { this->sendBluetoothCommand(SetTextSetParameterCommand, dataMap);
if(key == OmobiDisplayTextModel::ColorRole) {
QColor color = QColor(text[key].toString());
color = color.toRgb();
QVariantMap colorMap = {{"r", color.red()}, {"g", color.green()}, {"b", color.blue()}};
}
else
textMap.insert(this->displayTextModel->roleNames()[key], text[key]);
}
textList.append(textMap);
}
QJsonDocument doc = QJsonDocument::fromVariant(textList);
qDebug() << doc.toJson(QJsonDocument::Indented);
this->ble->sendData("SET_TEXTS:" + doc.toJson(QJsonDocument::Compact));
} }
QBluetoothLeUart* OmobiDisplayBackend::getBleController() { QBluetoothLeUart* OmobiDisplayBackend::getBleController() {
@ -159,6 +213,20 @@ OmobiDisplayBackend::OmobiDisplayAppState OmobiDisplayBackend::getState() {
return this->state; return this->state;
} }
void OmobiDisplayBackend::refreshLoadingState() {
if(this->state != Initing && this->state != Loading)
return;
qDebug() << "Refreshing loading state! Waiting: " << this->waitingCommands;
if(this->waitingCommands <= 1) {
this->waitingCommands = 0;
this->setState(Connected);
}
else
this->waitingCommands--;
}
void OmobiDisplayBackend::setState(OmobiDisplayAppState state) { void OmobiDisplayBackend::setState(OmobiDisplayAppState state) {
if(state == this->state) if(state == this->state)
return; return;
@ -166,6 +234,8 @@ void OmobiDisplayBackend::setState(OmobiDisplayAppState state) {
this->state = state; this->state = state;
emit this->stateChanged(); emit this->stateChanged();
qDebug() << "Now in " << state << " state";
if(this->state == Idle) if(this->state == Idle)
this->ble->startScanningForDevices(); this->ble->startScanningForDevices();
} }
@ -180,7 +250,7 @@ void OmobiDisplayBackend::setDisplayBrightness(int brightness) {
this->displayBrightness = brightness; this->displayBrightness = brightness;
this->ble->sendData("SET_BRIGHTNESS:" + QString::number(this->displayBrightness)); this->sendBluetoothCommand(SetDisplayBrightnessCommand, this->displayBrightness);
emit this->displayBrightnessChanged(); emit this->displayBrightnessChanged();
} }

View file

@ -23,24 +23,31 @@ public:
Scanning, Scanning,
ReadyToConnect, ReadyToConnect,
Connecting, Connecting,
Connected Initing,
Connected,
Loading
}; };
Q_ENUM(OmobiDisplayAppState) Q_ENUM(OmobiDisplayAppState)
typedef struct text_set_t
{
const char text[5];
uint time_ms;
uint color;
bool text_scroll;
uint text_scroll_pass;
bool active;
} text_set_t;
private: private:
enum OmobiDisplayCommand {
GetAllTextSetsCommand = 10,
GetTextSetParameterCommand = 11,
GetDisplayBrightnessCommand = 12,
SetTextSetParameterCommand = 20,
SetDisplayBrightnessCommand = 21
};
enum OmobiDisplayStatusCode {
Success = 200,
DisplayControllerError = 501
};
OmobiDisplayAppState state; OmobiDisplayAppState state;
QBluetoothLeUart *ble; QBluetoothLeUart *ble;
OmobiDisplayTextModel* displayTextModel; OmobiDisplayTextModel* displayTextModel;
int waitingCommands;
QList<QMap<int, QVariant>> textSetsBuffer;
int displayBrightness; int displayBrightness;
public slots: public slots:
@ -54,11 +61,18 @@ public slots:
private slots: private slots:
void handleBluetoothStateChange(QBluetoothLeUart::BluetoothLeUartState state); void handleBluetoothStateChange(QBluetoothLeUart::BluetoothLeUartState state);
void handleFoundNewDevice(QBluetoothLeUartDevice* device); void handleFoundNewDevice(QBluetoothLeUartDevice* device);
void DataHandler(QString s);
void handleBluetoothDeviceConected(); void handleBluetoothDeviceConected();
void handleDisplayTextModelDataChanged(); void handleDisplayTextModelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles = QVector<int>());
void handleDisplayTextModelRowsInserted(const QModelIndex &parent, int first, int last);
void handleDisplayTextModelRowsRemoved(const QModelIndex &parent, int first, int last);
void sendBluetoothCommand(OmobiDisplayCommand command, QVariant data = QVariant());
void handleBluetoothDataReceived(QString s);
void updateDisplayTextSetParameter(int index, int parameter);
void updateDisplayTextSetParameter(int index, int parameter, QString value);
void refreshLoadingState();
void setState(OmobiDisplayAppState state); void setState(OmobiDisplayAppState state);
signals: signals:

View file

@ -2,6 +2,11 @@
OmobiDisplayTextModel::OmobiDisplayTextModel(QObject* parent) : QAbstractListModel(parent) OmobiDisplayTextModel::OmobiDisplayTextModel(QObject* parent) : QAbstractListModel(parent)
{ {
this->maximumTextSets = 0;
this->maximumTextLength = 0;
connect(this, &OmobiDisplayTextModel::rowsInserted, this, &OmobiDisplayTextModel::rowCountChanged);
connect(this, &OmobiDisplayTextModel::rowsRemoved, this, &OmobiDisplayTextModel::rowCountChanged);
} }
@ -12,11 +17,19 @@ int OmobiDisplayTextModel::rowCount(const QModelIndex &) const
QVariant OmobiDisplayTextModel::data(const QModelIndex &index, int role) const QVariant OmobiDisplayTextModel::data(const QModelIndex &index, int role) const
{ {
if (index.row() < rowCount()) { return this->data(index.row(), role);
if(role == IndexRole) }
return index.row();
else if(this->texts[index.row()].contains(role)) QVariant OmobiDisplayTextModel::data(int row, int role) const {
return this->texts[index.row()][role]; if (row < rowCount()) {
if(this->texts[row].contains(role)) {
if(role == IndexRole)
return row;
QVariant value = this->texts[row][role];
value.convert(this->roleDataTypes[OmobiDisplayTextModelRole(role)]);
return value;
}
} }
return QVariant(); return QVariant();
} }
@ -48,10 +61,13 @@ void OmobiDisplayTextModel::append(
unsigned int scrollCount unsigned int scrollCount
) { ) {
// the current Maximum is 5 // check length maximums
if(this->texts.length() >= 5) if(this->texts.length() >= this->maximumTextSets)
return; return;
if(text.length() > this->maximumTextLength)
text = text.left(this->maximumTextLength);
QMap<int, QVariant> roles = { QMap<int, QVariant> roles = {
{ TextRole, text }, { TextRole, text },
{ ActiveRole, active }, { ActiveRole, active },
@ -80,11 +96,16 @@ bool OmobiDisplayTextModel::setData(const QModelIndex &index, const QVariant &va
if(this->texts[index.row()][role] == value) if(this->texts[index.row()][role] == value)
return true; return true;
this->texts[index.row()][role] = value; if(role == TextRole && value.toString().length() > this->maximumTextLength)
this->texts[index.row()][role] = value.toString().left(this->maximumTextLength);
else
this->texts[index.row()][role] = value;
emit dataChanged(index, index); qDebug() << "setting index: " << index << " role: " << role << " value " << value;
return QAbstractItemModel::setData(index, value, role); emit dataChanged(index, index, QVector<int>({role}));
return true;
} }
void OmobiDisplayTextModel::remove(int row) void OmobiDisplayTextModel::remove(int row)
@ -117,3 +138,15 @@ bool OmobiDisplayTextModel::setTexts(QList<QMap<int, QVariant>> texts) {
QList<QMap<int, QVariant>> OmobiDisplayTextModel::getTexts() { QList<QMap<int, QVariant>> OmobiDisplayTextModel::getTexts() {
return this->texts; return this->texts;
} }
QMap<int, QVariant> OmobiDisplayTextModel::getText(const QModelIndex &index) {
if (index.row() < this->rowCount())
return this->texts[index.row()];
return QMap<int, QVariant>();
}
int OmobiDisplayTextModel::getMaximumTextSets() {
return this->maximumTextSets;
}

View file

@ -9,6 +9,9 @@
class OmobiDisplayTextModel : public QAbstractListModel class OmobiDisplayTextModel : public QAbstractListModel
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY(int rowCount READ rowCount NOTIFY rowCountChanged)
Q_PROPERTY(int maximumTextSets READ getMaximumTextSets NOTIFY maximumTextSetsChanged)
public: public:
friend class OmobiDisplayBackend; friend class OmobiDisplayBackend;
@ -21,21 +24,21 @@ public:
ScrollRole, ScrollRole,
ScrollSpeedRole, ScrollSpeedRole,
ScrollCountRole, ScrollCountRole,
IndexRole IndexRole,
OmobiDisplayTextModelRoleCount
}; };
Q_ENUM(OmobiDisplayTextModelRole) Q_ENUM(OmobiDisplayTextModelRole)
enum OmobiDisplayTextAlignment
{
AlignLeft,
AlignCenter,
AlignRignt
};
enum text_align_t Q_INVOKABLE int rowCount(const QModelIndex & = QModelIndex()) const;
{
AlignLeft,
AlignCenter,
AlignRignt
};
int rowCount(const QModelIndex & = QModelIndex()) const;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
QVariant data(int i, int role = Qt::DisplayRole) const;
QHash<int, QByteArray> roleNames() const; QHash<int, QByteArray> roleNames() const;
Q_INVOKABLE void append( Q_INVOKABLE void append(
@ -54,16 +57,38 @@ public:
Q_INVOKABLE void remove(int row); Q_INVOKABLE void remove(int row);
Q_INVOKABLE int getMaximumTextSets();
protected: protected:
OmobiDisplayTextModel(QObject* parent = nullptr); OmobiDisplayTextModel(QObject* parent = nullptr);
bool setTexts(QList<QMap<int, QVariant>> json); bool setTexts(QList<QMap<int, QVariant>> json);
QList<QMap<int, QVariant>> getTexts(); QList<QMap<int, QVariant>> getTexts();
QMap<int, QVariant> getText(const QModelIndex &index);
void clear(); void clear();
private: private:
QList<QMap<int, QVariant>> texts; QList<QMap<int, QVariant>> texts;
int maximumTextSets;
int maximumTextLength;
const QMap<OmobiDisplayTextModelRole, QVariant::Type> roleDataTypes = {
{TextRole, QVariant::String},
{ActiveRole, QVariant::Bool},
{RuntimeRole, QVariant::Int},
{ColorRole, QVariant::String},
{AlignmentRole, QVariant::Int},
{ScrollRole, QVariant::Bool},
{ScrollSpeedRole, QVariant::Int},
{ScrollCountRole, QVariant::Int},
{IndexRole, QVariant::Int}
};
signals:
void rowCountChanged();
void maximumTextSetsChanged();
}; };
#endif // OMOBIDISPLAYTEXTMODEL_H #endif // OMOBIDISPLAYTEXTMODEL_H

View file

@ -0,0 +1,92 @@
import QtQuick 2.0
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.0
import QtQuick.Controls.Material 2.0
Rectangle {
id: control
property string value: ""
property string currentColor: rgbToHex(redSlider.value, greenSlider.value, blueSlider.value)
property bool isDarkColor: control.checkIsDarkColor(value)
implicitHeight: width
onValueChanged: {
var rgb = hexToRgb(value)
redSlider.value = rgb.r
greenSlider.value = rgb.g
blueSlider.value = rgb.b
}
onCurrentColorChanged: {
value = currentColor
}
function rgbToHex(r, g, b) {
return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
}
function hexToRgb(hex) {
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result ? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16)
} : null;
}
function checkIsDarkColor(color) {
var temp = Qt.darker(color, 1) //Force conversion to color QML type object
var a = 1 - ( 0.299 * temp.r + 0.587 * temp.g + 0.114 * temp.b);
return temp.a > 0 && a >= 0.3
}
ColumnLayout {
anchors.fill: parent
Rectangle {
Layout.fillWidth: true
Layout.preferredHeight: parent.height * 0.5
color: control.currentColor
}
Slider {
id: redSlider
Layout.fillWidth: true
Layout.fillHeight: true
from: 0
to: 255
stepSize: 1
Material.accent: Material.Red
}
Slider {
id: greenSlider
Layout.fillWidth: true
Layout.fillHeight: true
from: 0
to: 255
stepSize: 1
Material.accent: Material.Green
}
Slider {
id: blueSlider
Layout.fillWidth: true
Layout.fillHeight: true
from: 0
to: 255
stepSize: 1
Material.accent: Material.Blue
}
}
}

View file

@ -0,0 +1,89 @@
import QtQuick 2.0
import QtQuick.Controls 2.9
import QtQuick.Controls.Material 2.0
ItemDelegate {
id: control
property string value: ""
onClicked: {
colorPicker.value = value
textEditDialog.open()
}
Rectangle {
anchors {
right: nextPageIconText.left
verticalCenter: parent.verticalCenter
rightMargin: control.padding
}
width: parent.width * 0.15
height: parent.height * 0.6
radius: height * 0.1
color: control.value === "" ? "transparent":control.value
border.width: 2
border.color: control.value === "" ? "lightgrey":control.value
Text {
anchors.fill: parent
anchors.margins: parent.height * 0.1
font.pixelSize: height * 0.5
fontSizeMode: Text.Fit
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
color: colorPicker.isDarkColor && control.value !== "" ? "white":"black"
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
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: ColorPicker {
id: colorPicker
value: control.value
}
onAccepted: {
control.value = colorPicker.value
}
}
}

View file

@ -77,6 +77,10 @@ ItemDelegate {
checked: index === control.currentIndex checked: index === control.currentIndex
ButtonGroup.group: buttonGroup ButtonGroup.group: buttonGroup
text: modelData text: modelData
onClicked: {
control.currentIndex = index
textEditDialog.close()
}
} }
} }
@ -85,10 +89,6 @@ ItemDelegate {
listView.model = control.model listView.model = control.model
} }
onAccepted: {
control.currentText = buttonGroup.checkedButton.text
}
ButtonGroup { ButtonGroup {
id: buttonGroup id: buttonGroup
} }

View file

@ -166,6 +166,20 @@ Page {
statusText: "trying to connect..." statusText: "trying to connect..."
working: true working: true
} }
},
State {
name: OmobiDisplayBackend.Initing
PropertyChanges {
target: availableDevicesListView
enabled: false
}
PropertyChanges {
target: root
statusText: "loading data..."
working: true
}
} }
] ]
} }

View file

@ -64,4 +64,50 @@ Page {
clip: true clip: true
} }
} }
Dialog {
id: loadingDialog
property bool shouldBeOpen: false
onShouldBeOpenChanged: {
if(shouldBeOpen)
open()
else
close()
}
parent: Overlay.overlay
x: (parent.width - width) / 2
y: (parent.height - height) / 2
closePolicy: Popup.NoAutoClose
modal: true
contentItem: ColumnLayout {
BusyIndicator {
}
Text {
Layout.alignment: Layout.Center
text: qsTr("loading...")
}
}
}
states: [
State {
name: OmobiDisplayBackend.Connected
},
State {
name: OmobiDisplayBackend.Loading
PropertyChanges {
target: loadingDialog
shouldBeOpen: true
}
}
]
} }

View file

@ -42,6 +42,8 @@ ListView {
height: implicitHeight * 1.3 height: implicitHeight * 1.3
width: height width: height
enabled: control.model.rowCount < control.model.maximumTextSets
Material.background: Material.accent Material.background: Material.accent
text: "" text: ""

View file

@ -28,8 +28,8 @@ Dialog {
editingModel.active = activeSwitch.checked editingModel.active = activeSwitch.checked
editingModel.text = textTextField.value editingModel.text = textTextField.value
editingModel.runtime = runtimeSpinBox.value editingModel.runtime = runtimeSpinBox.value
editingModel.color = colorComboBox.currentText editingModel.color = colorColorPicker.value
editingModel.alignment = alignmentComboBox.currentText editingModel.alignment = alignmentComboBox.currentIndex
editingModel.scroll = scrollSwitch.checked editingModel.scroll = scrollSwitch.checked
editingModel.scrollSpeed = scrollSpeedSpinBox.value editingModel.scrollSpeed = scrollSpeedSpinBox.value
editingModel.scrollCount = scrollCountSpinBox.value editingModel.scrollCount = scrollCountSpinBox.value
@ -38,7 +38,7 @@ Dialog {
editingModel.append(textTextField.value, editingModel.append(textTextField.value,
activeSwitch.checked, activeSwitch.checked,
runtimeSpinBox.value, runtimeSpinBox.value,
colorComboBox.currentText, colorColorPicker.value,
alignmentComboBox.currentText, alignmentComboBox.currentText,
scrollSwitch.checked, scrollSwitch.checked,
scrollSpeedSpinBox.value, scrollSpeedSpinBox.value,
@ -88,10 +88,9 @@ Dialog {
text: qsTr("Runtime (in s)") text: qsTr("Runtime (in s)")
} }
ComboBoxDelegate { ColorPickerDelegate {
id: colorComboBox id: colorColorPicker
Layout.fillWidth: true Layout.fillWidth: true
model: ["white", "blue", "red", "green"]
text: qsTr("Color") text: qsTr("Color")
} }
@ -163,8 +162,8 @@ Dialog {
activeSwitch.checked = editingModel.active activeSwitch.checked = editingModel.active
textTextField.value = editingModel.text textTextField.value = editingModel.text
runtimeSpinBox.value = editingModel.runtime runtimeSpinBox.value = editingModel.runtime
colorComboBox.currentIndex = colorComboBox.model.indexOf(editingModel.color) colorColorPicker.value = editingModel.color
alignmentComboBox.currentIndex = alignmentComboBox.model.indexOf(editingModel.alignment) alignmentComboBox.currentIndex = editingModel.alignment
scrollSwitch.checked = editingModel.scroll scrollSwitch.checked = editingModel.scroll
scrollSpeedSpinBox.value = editingModel.scrollSpeed scrollSpeedSpinBox.value = editingModel.scrollSpeed
scrollCountSpinBox.value = editingModel.scrollCount scrollCountSpinBox.value = editingModel.scrollCount
@ -183,7 +182,7 @@ Dialog {
activeSwitch.checked = true activeSwitch.checked = true
textTextField.value = "" textTextField.value = ""
runtimeSpinBox.value = 0 runtimeSpinBox.value = 0
colorComboBox.currentIndex = 0 colorColorPicker.value = ""
alignmentComboBox.currentIndex = 0 alignmentComboBox.currentIndex = 0
scrollSwitch.checked = false scrollSwitch.checked = false
scrollSpeedSpinBox.value = 5 scrollSpeedSpinBox.value = 5

View file

@ -54,7 +54,7 @@ ApplicationWindow {
mainStack.replace(currentComponent) mainStack.replace(currentComponent)
} }
//initialItem: connectedPageComp initialItem: connectedPageComp
Component { Component {
id: connectPageComp id: connectPageComp
@ -104,12 +104,28 @@ ApplicationWindow {
} }
}, },
State {
name: OmobiDisplayBackend.Initing
PropertyChanges {
target: mainStack
currentComponent: connectPageComp
}
},
State { State {
name: OmobiDisplayBackend.Connected name: OmobiDisplayBackend.Connected
PropertyChanges { PropertyChanges {
target: mainStack target: mainStack
currentComponent: connectedPageComp currentComponent: connectedPageComp
} }
},
State {
name: OmobiDisplayBackend.Loading
PropertyChanges {
target: mainStack
currentComponent: connectedPageComp
}
} }
] ]
} }

View file

@ -11,5 +11,7 @@
<file>NextPageDelegate.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>ColorPicker.qml</file>
</qresource> </qresource>
</RCC> </RCC>