diff --git a/headers/baseconn.h b/headers/baseconn.h
index e3ead24..8c96b9e 100644
--- a/headers/baseconn.h
+++ b/headers/baseconn.h
@@ -96,8 +96,12 @@ public slots:
void gotError(QAbstractSocket::SocketError err);
+ // --- socket communication handling ---
+
Q_INVOKABLE QVariantMap sendCommand(int header, QJsonValue data = "");
+ // --- helper functions ---
+
Q_INVOKABLE int writeRemoteSetting(QString key, QString value);
Q_INVOKABLE bool refreshConnections();
@@ -116,6 +120,10 @@ public slots:
private slots:
void readyRead();
+ void processSocketMessage(QString message);
+
+ void socketReplyRecieved(QString reply);
+
void socketStateChanged(QAbstractSocket::SocketState socketState);
};
extern BaseConn * pGlobalBaseConn;
diff --git a/qml/ProfilesDialog.qml b/qml/ProfilesDialog.qml
index fc675be..3dba153 100644
--- a/qml/ProfilesDialog.qml
+++ b/qml/ProfilesDialog.qml
@@ -131,7 +131,7 @@ Popup {
loadData: function () {
status = 905
- listData = {}
+ //listData = {}
var retData = speedBackend.getAthletes()
if(retData === undefined){
@@ -151,8 +151,7 @@ Popup {
text: profileList.listData[index]["fullName"]
width: profileList.width - (swipeDelegate.x)
-
-
+ height: profileList.height / 5
font.pixelSize: profiles_stack.text_pixelSize
@@ -164,8 +163,35 @@ Popup {
profiles_stack.openResults(profileList.listData[index]["userName"])
}
+ contentItem: Text {
+ visible: false
+ }
+
+ Text {
+
+ anchors {
+ verticalCenter: parent.verticalCenter
+ left: parent.left
+ leftMargin: swipeDelegate.width * 0.05
+ right: parent.right
+ rightMargin: swipeDelegate.rightPadding
+ }
+
+ text: swipeDelegate.text
+ color: appTheme.style.textColor
+
+ verticalAlignment: Text.AlignVCenter
+ horizontalAlignment: Text.AlignLeft
+
+ fontSizeMode: Text.Fit
+
+ font.pixelSize: swipeDelegate.height * 0.4
+
+ minimumPixelSize: 1
+ }
+
background: Rectangle {
- color: Qt.darker( pressed ? Qt.darker("white", 1.1):"white", swipeDelegate.active ? 1.1:0 )
+ color: pressed ? appTheme.style.delegatePressedColor : appTheme.style.delegateBackgroundColor
Behavior on color {
@@ -205,6 +231,7 @@ Popup {
radius: width * 0.2
border.color: control.down ? "#17a81a" : "#21be2b"
+ color: control.down ? appTheme.style.delegatePressedColor : appTheme.style.delegateBackgroundColor
Rectangle {
width: parent.width * 0.65
@@ -273,7 +300,7 @@ Popup {
Label {
id: deleteLabel
text: qsTr("Delete")
- color: "white"
+ color: appTheme.style.textColor
verticalAlignment: Label.AlignVCenter
padding: 12
height: parent.height
@@ -353,6 +380,7 @@ Popup {
signal opened()
+
onOpened: {
loadData()
}
@@ -364,14 +392,18 @@ Popup {
status = listData.lenght !== false ? 200:0
}
- delegate: ItemDelegate {
+ delegate: SmoothItemDelegate {
id: resultDel
width: parent.width
+ height: resultView.height / 4
- font.pixelSize: profiles_stack.text_pixelSize
+ backgroundRect.radius: 0
- text: "result: " + (listData[index]["result"] / 1000).toFixed(3) + " sec \nreaction time: " + listData[index]["reactionTime"].toFixed(0) + " ms"
+ function getDateText(){
+ var date = new Date(listData[index]["timestamp"]*1000).toLocaleString(Qt.locale(), "dddd, dd.MMM HH:mm")
+ return date
+ }
Rectangle {
color: "grey"
@@ -384,18 +416,47 @@ Popup {
}
}
- Label {
- anchors.top: parent.top
- anchors.left: parent.left
+ Column {
+ anchors.fill: parent
+ anchors.leftMargin: parent.width * 0.05
- font.pixelSize: 10
+ Label {
+ id: dateLa
- text: " " + getText()
+ height: parent.height / parent.children.length
- function getText(){
- var date = new Date(listData[index]["timestamp"]*1000).toLocaleDateString(Qt.locale("de_DE"))
- return date
- console.log(date)
+ font.pixelSize: height * 0.8
+ fontSizeMode: Text.Fit
+
+ color: appTheme.style.textColor
+
+ text: resultDel.getDateText()
+ }
+
+ Label {
+ id: resultLa
+
+ height: parent.height / parent.children.length
+
+ font.pixelSize: height * 0.8
+ fontSizeMode: Text.Fit
+
+ color: appTheme.style.textColor
+
+ text: qsTr("result: ") + (listData[index]["result"] / 1000).toFixed(3) + " s"
+ }
+
+ Label {
+ id: reactionTimeLa
+
+ height: parent.height / parent.children.length
+
+ font.pixelSize: height * 0.8
+ fontSizeMode: Text.Fit
+
+ color: appTheme.style.textColor
+
+ text: qsTr("reaction time: ") + listData[index]["reactionTime"].toFixed(0) + " ms"
}
}
}
@@ -548,6 +609,8 @@ Popup {
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
+ color: appTheme.style.textColor
+
text: profiles_stack.currentItem.title
}
@@ -611,6 +674,9 @@ Popup {
leftMargin: parent.width/2 - width/2
}
opacity: profiles_stack.currentItem.secondButt === "add" ? 1:0
+
+ color: appTheme.style.textColor
+
text: "+"
font.pixelSize: parent.height
}
diff --git a/qml/SettingsDialog.qml b/qml/SettingsDialog.qml
index 4487de4..b71938f 100644
--- a/qml/SettingsDialog.qml
+++ b/qml/SettingsDialog.qml
@@ -192,7 +192,6 @@ Popup {
glowOpacity: Math.pow( root.opacity, 100 )
- backgroundColor: appTheme.style.buttonColor
image: appTheme.style.backIcon
onClicked: {
diff --git a/qml/components/FancyButton.qml b/qml/components/FancyButton.qml
index c5f5f7b..28dd8a3 100644
--- a/qml/components/FancyButton.qml
+++ b/qml/components/FancyButton.qml
@@ -6,7 +6,7 @@ Button {
id: control
property string image
- property color backgroundColor: "white"
+ property color backgroundColor: appTheme.style.buttonColor
property real imageScale: 1
property double glowRadius: 0.001
property double glowSpread: 0.2
@@ -16,7 +16,7 @@ Button {
- scale: control.pressed ? 0.8:1
+ //scale: control.pressed ? 0.8:1
Behavior on scale {
PropertyAnimation {
@@ -24,12 +24,6 @@ Button {
}
}
- Behavior on backgroundColor {
- ColorAnimation {
- duration: 200
- }
- }
-
background: Item {
id: controlBackgroundContainer
@@ -48,13 +42,19 @@ Button {
}
Rectangle {
- id: controlBackground
+ id: controlBackground
anchors.fill: parent
radius: height * 0.5
- color: control.backgroundColor
+ color: control.down ? Qt.darker(control.backgroundColor, 1.2) : control.backgroundColor
+
+ Behavior on color {
+ ColorAnimation {
+ duration: 200
+ }
+ }
Image {
id: buttonIcon
diff --git a/qml/components/RemoteDataListView.qml b/qml/components/RemoteDataListView.qml
index e8bc730..e184bab 100644
--- a/qml/components/RemoteDataListView.qml
+++ b/qml/components/RemoteDataListView.qml
@@ -1,4 +1,4 @@
-import QtQuick 2.9
+import QtQuick 2.10
import QtQuick.Controls 2.4
Item {
@@ -7,6 +7,7 @@ Item {
property var loadData
property var listData: ({})
property Component delegate
+ property alias view: listView
property int status: -1
@@ -23,11 +24,12 @@ Item {
anchors.fill: parent
+ boundsBehavior: Flickable.DragOverBounds
+ boundsMovement: Flickable.StopAtBounds
+
//enabled: status === 200 || status === 902
//opacity: enabled ? 1:0
- boundsBehavior: ListView.StopAtBounds
-
ScrollBar.vertical: ScrollBar {
parent: listView.parent
diff --git a/qml/components/SmoothItemDelegate.qml b/qml/components/SmoothItemDelegate.qml
index a1547de..c3627d0 100644
--- a/qml/components/SmoothItemDelegate.qml
+++ b/qml/components/SmoothItemDelegate.qml
@@ -4,8 +4,8 @@ import QtQuick.Controls 2.2
ItemDelegate {
id: control
text: ""
- font.pixelSize: options_stack.text_pixelSize
property color textColor: appTheme.style.textColor
+ property alias backgroundRect: backgroundRect
opacity: enabled ? 1 : 0.2
@@ -26,16 +26,20 @@ ItemDelegate {
text: control.text
color: appTheme.style.textColor
+ verticalAlignment: Text.AlignVCenter
+ horizontalAlignment: Text.AlignLeft
+
fontSizeMode: Text.Fit
font.pixelSize: control.height * 0.4
- minimumPixelSize: 0
+ minimumPixelSize: 1
}
width: parent.width
background: Rectangle {
+ id: backgroundRect
color: control.down ? appTheme.style.delegatePressedColor : appTheme.style.delegateBackgroundColor
radius: height * 0.3
diff --git a/sources/baseconn.cpp b/sources/baseconn.cpp
index effe924..7dd55d2 100644
--- a/sources/baseconn.cpp
+++ b/sources/baseconn.cpp
@@ -122,6 +122,10 @@ void BaseConn::gotError(QAbstractSocket::SocketError err)
qDebug() << "got socket error: " << strError;
}
+// -------------------------------------
+// --- socket communication handling ---
+// -------------------------------------
+
QVariantMap BaseConn::sendCommand(int header, QJsonValue data){
if(this->state != "connected"){
return {{"status", 910}, {"data", "not connected"}};
@@ -178,8 +182,6 @@ QVariantMap BaseConn::sendCommand(int header, QJsonValue data){
// stop the timer as the connection has been established
timer.stop();
- timer.deleteLater();
-
return {{"status", reply.value("header").toInt()}, {"data", reply.value("data").toVariant()}};
}
@@ -189,17 +191,64 @@ void BaseConn::readyRead() {
//qDebug() << "ready to ready " << socket->bytesAvailable() << " bytes" ;
QString reply = socket->readAll();
- if(!reply.endsWith("")){
- this->readBuffer += reply;
+ //qWarning() << "socket read: " << reply;
+
+ processSocketMessage(reply);
+}
+
+void BaseConn::processSocketMessage(QString message){
+ QString startKey = "";
+ QString endKey = "";
+
+ //qWarning() << "... processing message now ... : " << message;
+
+ if(message == ""){
return;
}
- else {
+
+ if((message.startsWith(startKey) && message.endsWith(endKey)) && (message.count(startKey) == 1 && message.count(endKey) == 1)){
+ // non-split message ( e.g.: 123456789
+ }
+ else if(!message.contains(endKey) && (!this->readBuffer.isEmpty() || message.startsWith(startKey))){
+ // begin of a split message ( e.g.: 123 )
+ // or middle of a split message ( e.g.: 456 )
+ //qWarning() << "this is a begin or middle of split a message";
+ this->readBuffer += message;
+ return;
+ }
+ else if(!message.contains(startKey) && message.endsWith(endKey)) {
+ // end of a split message ( e.g.: 789 )
+
if(!this->readBuffer.isEmpty()){
- reply = readBuffer + reply;
+ message = readBuffer + message;
readBuffer.clear();
}
}
+ else if((message.count(startKey) > 1 || message.count(endKey) > 1) || (message.contains(endKey) && !message.endsWith(endKey) && message.contains(startKey) && !message.startsWith(startKey))) {
+ // multiple messages in one packet ( e.g.: 123456789987654321 )
+ // or multiple message fragments in one message ( e.g.: 56789987654321 or 5678998765 )
+ //qDebug() << "detected multiple messages";
+ int startOfSecondMessage = message.lastIndexOf(startKey);
+ // process first part of message
+ QString firstMessage = message.left(startOfSecondMessage);
+ this->processSocketMessage(firstMessage);
+ // process second part of message
+ QString secondMessage = message.right(message.length() - startOfSecondMessage);
+ this->processSocketMessage(secondMessage);
+
+ return;
+ }
+ else {
+ // invalid message
+ return;
+ }
+
+ //qWarning() << "... done processing, message: " << message;
+ this->socketReplyRecieved(message);
+}
+
+void BaseConn::socketReplyRecieved(QString reply) {
reply.replace("", "");
reply.replace("", "");
@@ -216,7 +265,9 @@ void BaseConn::readyRead() {
for(int i = 0; i < this->waitingRequests.length(); i++){
if(this->waitingRequests[i].id == id){
this->waitingRequests[i].reply = replyObj;
- this->waitingRequests[i].loop->quit();
+ if(this->waitingRequests[i].loop != nullptr){
+ this->waitingRequests[i].loop->quit();
+ }
return;
}
}
@@ -224,9 +275,12 @@ void BaseConn::readyRead() {
latestReadReply = reply;
emit gotUnexpectedReply(reply);
-
}
+// ------------------------
+// --- helper functions ---
+// ------------------------
+
int BaseConn::writeRemoteSetting(QString key, QString value) {
QJsonArray requestData;
requestData.append(key);
@@ -257,6 +311,7 @@ void BaseConn::socketStateChanged(QAbstractSocket::SocketState socketState) {
switch (socketState) {
case QAbstractSocket::UnconnectedState:
{
+ this->deInit();
this->setState("disconnected");
break;
}