diff --git a/ProgressCircle.qml b/ProgressCircle.qml index c32679b..5febcbc 100644 --- a/ProgressCircle.qml +++ b/ProgressCircle.qml @@ -50,6 +50,9 @@ Item { } + function repaint(){ + canvas.requestPaint() + } Canvas { id: canvas diff --git a/SettingsDialog.qml b/SettingsDialog.qml index 3d15e71..6bb7d98 100644 --- a/SettingsDialog.qml +++ b/SettingsDialog.qml @@ -2,6 +2,7 @@ import QtQuick 2.9 import QtMultimedia 5.8 import QtQuick.Window 2.2 import QtQuick.Controls 2.2 +import QtQuick.Layouts 1.3 Popup { id: root @@ -13,19 +14,11 @@ Popup { dim: false enter: Transition { - NumberAnimation { properties: "scale"; from: 0; to: 1; duration: 300; easing.type: Easing.InCubic } + NumberAnimation { properties: "scale"; from: 0; to: 1; duration: 300; easing.type: Easing.Linear } } exit: Transition { - NumberAnimation { properties: "scale"; from: 1; to: 0; duration: 300; easing.type: Easing.OutCubic } - } - - function delay(delayTime, cb) { - timer = new Timer(); - timer.interval = delayTime; - timer.repeat = false; - //timer.triggered.connect(cb); - timer.start(); + NumberAnimation { properties: "scale"; from: 1; to: 0; duration: 300; easing.type: Easing.Linear } } background: Rectangle { @@ -33,8 +26,10 @@ Popup { color: "white" border.color: "grey" border.width: 1 + Label { - text: "Options" + id: head_text + text: options_stack.currentItem.title font.pixelSize: headlineUnderline.width * 0.1 anchors { horizontalCenter: parent.horizontalCenter @@ -57,6 +52,50 @@ Popup { leftMargin: parent.radius - Math.sqrt(Math.pow(parent.radius,2)-Math.pow(parent.radius-anchors.topMargin,2)) } } + + Button { + id: head_back + + anchors { + left: parent.left + leftMargin: parent.width * 0.17 + top:parent.top + topMargin: parent.height * 0.025 + } + height: parent.height * 0.1 + width:height + + background: Rectangle { + radius: width * 0.5 + color: "white" + border.color: "grey" + border.width: 1 + Image { + anchors.fill: parent + anchors.margins: parent.width * 0.2 + source: "qrc:/graphics/icons/back_black.png" + + } + } + + onClicked: { + options_stack.depth > 1 ? options_stack.pop():root.close() + } + + onPressedChanged: { + if(pressed){ + background.color = "lightgrey" + } + else { + background.color = "white" + } + } + Behavior on opacity { + NumberAnimation { + duration: 100 + } + } + } } ProgressCircle { @@ -64,7 +103,6 @@ Popup { property string text: "connecting.." anchors.centerIn: parent size: parent.height * 1.03 - //colorCircle: "grey" opacity: 0 lineWidth: 5 @@ -72,7 +110,8 @@ Popup { arcEnd: 0 Timer { - running: opacity === 1 + id: prog_refresh + running: false interval: 1 repeat: true onTriggered: { @@ -89,59 +128,304 @@ Popup { } } - Column { - id: settings_col - anchors.verticalCenter: parent.verticalCenter - anchors.left: parent.left - anchors.right: parent.right + StackView { + id: options_stack + property int text_pixelSize: headlineUnderline.width * 0.08 + initialItem: settings + width: headlineUnderline.width - ItemDelegate { - id: connect_del - width: parent.width - text: _cppBuzzerConn.get("connected")===1 ? "connected to buzzer":"connect to buzzer" - Timer { - running: connect_del.scale === 1 - repeat: true - interval: 10 - onTriggered: { - connect_del.text = _cppBuzzerConn.get("connected")===1 ? "connected to buzzer":"connect to buzzer" - } - } + anchors { + top: parent.top + left: parent.left + leftMargin: ( parent.width - headlineUnderline.width ) / 2 + topMargin: parent.height * 0.12 + bottom: parent.bottom + } - onClicked: { - root.closePolicy = Popup.NoAutoClose - connect_del.opacity = 0 - prog.arcEnd = 0 - prog.colorCircle = "grey" - prog.opacity = 1 - prog.text = "connecting..." + Behavior on opacity { + NumberAnimation {duration: 200} + } - connect_del.enabled = false + /*-----start page of the settings-----*/ + Component { + id: settings - if(_cppBuzzerConn.connect()){ - prog.colorCircle = "green" - prog.text = "success!" - } - else { - prog.colorCircle = "red" - prog.text = "error!" + Column { + property string title: "Options" + id: settings_col + + /*----Connect to buzzer----*/ + ItemDelegate { + id: connect_del + width: parent.width + text: _cppBuzzerConn.get("connected")===1 ? "connected to buzzer":"connect to buzzer" + font.pixelSize: options_stack.text_pixelSize + Timer { + running: connect_del.scale === 1 + repeat: true + interval: 10 + onTriggered: { + connect_del.text = _cppBuzzerConn.get("connected")===1 ? "connected to buzzer":"connect to buzzer" + } + } + + onClicked: { + root.closePolicy = Popup.NoAutoClose + options_stack.opacity = 0 + + prog.arcEnd = 0 + prog.colorCircle = "grey" + prog.opacity = 1 + prog.text = "connecting..." + prog_refresh.running = true + + if(_cppBuzzerConn.connect()){ + prog_refresh.running = false + prog.colorCircle = "green" + prog.text = "success!" + prog.arcEnd = 360 + } + else { + prog_refresh.running = false + prog.colorCircle = "red" + prog.text = "error!" + prog.arcEnd = 360 + } + + //make a short delay and go back to normal options + shortDelay.start() + } + Timer { + id: shortDelay + running: false + repeat: false + interval: 1000 + onTriggered: { + connect_del.enabled = true; + prog.opacity = 0; + options_stack.opacity = 1 + root.closePolicy = Popup.CloseOnPressOutside; + } + } } - //make a short delay and go back to normal options - shortDelay.start() - } - Timer { - id: shortDelay - running: false - repeat: false - interval: 1000 - onTriggered: { - connect_del.enabled = true; - prog.opacity = 0; - connect_del.opacity = 1; - root.closePolicy = Popup.CloseOnPressOutside; + /*----Automated Start----*/ + ItemDelegate { + id: autostart_del + text: "start sequence" + font.pixelSize: options_stack.text_pixelSize + width: parent.width + + Rectangle { + color: "grey" + height: 1 + width: parent.width * 0.9 + anchors { + horizontalCenter: parent.horizontalCenter + top: parent.top + } + } + + Image { + id: autostart_del_image + source: "qrc:/graphics/icons/back_black.png" + rotation: 180 + height: options_stack.text_pixelSize + width: height + anchors { + verticalCenter: parent.verticalCenter + right: parent.right + rightMargin: 10 + } + } + onClicked: { + options_stack.push(autostart) + } } } } + + /*-----Page to setup automatc start sequence-----*/ + Component { + id: autostart + + Column { + id: autostart_col + property string title: "Autostart" + + + SwitchDelegate { + id: ready_del + text: qsTr("say 'ready'") + checked: _cppAppSettings.loadSetting("ready_en") === "true" + width: parent.width + font.pixelSize: options_stack.text_pixelSize + + onCheckedChanged: { + _cppAppSettings.writeSetting("ready_en",checked) + } + + indicator: Rectangle { + implicitWidth: 48 + implicitHeight: 26 + x: ready_del.width - width - ready_del.rightPadding + y: parent.height / 2 - height / 2 + radius: 13 + color: ready_del.checked ? "#17a81a" : "transparent" + border.color: ready_del.checked ? "#17a81a" : "#cccccc" + Behavior on color{ + ColorAnimation{ + duration: 200 + } + } + + Rectangle { + x: ready_del.checked ? parent.width - width : 0 + width: 26 + height: 26 + radius: 13 + color: ready_del.down ? "#cccccc" : "#ffffff" + border.color: ready_del.checked ? (ready_del.down ? "#17a81a" : "#21be2b") : "#999999" + Behavior on x{ + NumberAnimation { + property: "x" + duration: 200 + easing.type: Easing.InOutQuad + } + } + } + } + } + + ItemDelegate { + id: ready_delay_del + text: "delay (ms)" + enabled: ready_del.checked + width: parent.width + font.pixelSize: options_stack.text_pixelSize + + TextField { + focus: true + placeholderText: "time" + width: parent.width * 0.3 + anchors.right: parent.right + inputMethodHints: Qt.ImhFormattedNumbersOnly + + text: _cppAppSettings.loadSetting("ready_delay") + + onTextChanged: { + _cppAppSettings.writeSetting("ready_delay", text) + } + } + } + + SwitchDelegate { + id: at_marks_del + text: qsTr("say\n'at your marks'") + checked: _cppAppSettings.loadSetting("at_marks_en") === "true" + width: parent.width + font.pixelSize: options_stack.text_pixelSize + + onCheckedChanged: { + _cppAppSettings.writeSetting("at_marks_en",at_marks_del.checked) + } + + indicator: Rectangle { + implicitWidth: 48 + implicitHeight: 26 + x: at_marks_del.width - width - at_marks_del.rightPadding + y: parent.height / 2 - height / 2 + radius: 13 + color: at_marks_del.checked ? "#17a81a" : "transparent" + border.color: at_marks_del.checked ? "#17a81a" : "#cccccc" + Behavior on color{ + ColorAnimation{ + duration: 200 + } + } + + Rectangle { + x: at_marks_del.checked ? parent.width - width : 0 + width: 26 + height: 26 + radius: 13 + color: at_marks_del.down ? "#cccccc" : "#ffffff" + border.color: at_marks_del.checked ? (at_marks_del.down ? "#17a81a" : "#21be2b") : "#999999" + Behavior on x{ + NumberAnimation { + property: "x" + duration: 200 + easing.type: Easing.InOutQuad + } + } + } + } + } + + ItemDelegate { + id: at_marks_delay_del + text: "delay (ms)" + enabled: at_marks_del.checked + width: parent.width + font.pixelSize: options_stack.text_pixelSize + + TextField { + focus: true + placeholderText: "time" + width: parent.width * 0.3 + anchors.right: parent.right + inputMethodHints: Qt.ImhFormattedNumbersOnly + + text: _cppAppSettings.loadSetting("at_marks_delay") + + onTextChanged: { + _cppAppSettings.writeSetting("at_marks_delay",text) + } + } + } + } + } + + /*-----Custom animations-----*/ + + pushEnter: Transition { + NumberAnimation { + property: "opacity" + from: 0 + to: 1 + duration: 200 + easing.type: Easing.InOutQuad + } + } + pushExit: Transition { + NumberAnimation { + property: "opacity" + from: 1 + to: 0 + duration: 200 + easing.type: Easing.InOutQuad + } + } + + popExit: Transition { + NumberAnimation { + property: "opacity" + from: 1 + to: 0 + duration: 200 + easing.type: Easing.InOutQuad + } + } + popEnter: Transition { + NumberAnimation { + property: "opacity" + from: 0 + to: 1 + duration: 200 + easing.type: Easing.InOutQuad + } + } } + + } diff --git a/appsettings.cpp b/appsettings.cpp new file mode 100644 index 0000000..fb352d8 --- /dev/null +++ b/appsettings.cpp @@ -0,0 +1,30 @@ +#include "appsettings.h" + +AppSettings::AppSettings(QObject* parent) + :QObject(parent) +{ + QString path = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); + qDebug(path.toLatin1()); + this->settingsManager = new QSettings(path+"/settings.ini", QSettings::IniFormat); +} + +QString AppSettings::loadSetting(const QString &key) +{ + this->settingsManager->beginGroup("AppSettings"); + QString value = this->settingsManager->value(key , false).toString(); + this->settingsManager->endGroup(); + return(value); +} + +void AppSettings::writeSetting(const QString &key, const QVariant &variant) +{ + this->settingsManager->beginGroup("AppSettings"); + this->settingsManager->setValue(key , variant); + this->settingsManager->endGroup(); +} + +AppSettings::~AppSettings() +{ + delete settingsManager; +} + diff --git a/appsettings.h b/appsettings.h new file mode 100644 index 0000000..b5459ec --- /dev/null +++ b/appsettings.h @@ -0,0 +1,26 @@ +#ifndef APPSETTINGS_H +#define APPSETTINGS_H + +#include +#include +#include + +class AppSettings : public QObject +{ + Q_OBJECT +public: + explicit AppSettings(QObject *parent = nullptr); + ~AppSettings(); + + Q_INVOKABLE QString loadSetting(const QString &key); + Q_INVOKABLE void writeSetting(const QString &key, const QVariant &variant); + + QSettings *settingsManager; + +signals: + +public slots: +}; +extern AppSettings * pGlobalAppSettings; + +#endif // APPSETTINGS_H diff --git a/graphics/icons/back.png b/graphics/icons/back.png new file mode 100644 index 0000000..d1740cd Binary files /dev/null and b/graphics/icons/back.png differ diff --git a/graphics/icons/back_black.png b/graphics/icons/back_black.png new file mode 100644 index 0000000..c55ab31 Binary files /dev/null and b/graphics/icons/back_black.png differ diff --git a/graphics/icons/drawer.png b/graphics/icons/drawer.png new file mode 100644 index 0000000..4e7899e Binary files /dev/null and b/graphics/icons/drawer.png differ diff --git a/graphics/icons/drawer_black.png b/graphics/icons/drawer_black.png new file mode 100644 index 0000000..eba3b6c Binary files /dev/null and b/graphics/icons/drawer_black.png differ diff --git a/graphics/icons/menu.png b/graphics/icons/menu.png new file mode 100644 index 0000000..5a0d148 Binary files /dev/null and b/graphics/icons/menu.png differ diff --git a/graphics/icons/menu_black.png b/graphics/icons/menu_black.png new file mode 100644 index 0000000..649c2a0 Binary files /dev/null and b/graphics/icons/menu_black.png differ diff --git a/main.cpp b/main.cpp index 0478a4a..b8d1882 100644 --- a/main.cpp +++ b/main.cpp @@ -34,6 +34,7 @@ #include "sqlstoragemodel.h" #include "sqlprofilemodel.h" #include "buzzerconn.h" +#include "appsettings.h" static void connectToDatabase() { @@ -76,6 +77,7 @@ int main(int argc, char *argv[]) connectToDatabase(); BuzzerConn * pBuzzerConn = new BuzzerConn; + AppSettings * pAppSettings = new AppSettings(); //setup the sql storage model as a qml model qmlRegisterType("com.itsblue.speedclimbingstopwatch", 1, 0, "SqlProfileModel"); @@ -87,6 +89,7 @@ int main(int argc, char *argv[]) return -1; engine.rootContext()->setContextProperty("_cppBuzzerConn", pBuzzerConn); + engine.rootContext()->setContextProperty("_cppAppSettings", pAppSettings); return app.exec(); } diff --git a/shared.qrc b/shared.qrc index 4ffc9a4..478f9bb 100644 --- a/shared.qrc +++ b/shared.qrc @@ -3,5 +3,11 @@ OFFICAL_IFSC_STARTIGNAL.wav graphics/icons/settings.png graphics/icons/user.png + graphics/icons/menu_black.png + graphics/icons/drawer_black.png + graphics/icons/back_black.png + graphics/icons/menu.png + graphics/icons/drawer.png + graphics/icons/back.png diff --git a/speedclimbing_stopwatch.pro b/speedclimbing_stopwatch.pro index 51c0fef..d2b6220 100644 --- a/speedclimbing_stopwatch.pro +++ b/speedclimbing_stopwatch.pro @@ -22,7 +22,8 @@ SOURCES += \ main.cpp \ sqlstoragemodel.cpp \ sqlprofilemodel.cpp \ - buzzerconn.cpp + buzzerconn.cpp \ + appsettings.cpp RESOURCES += qml.qrc \ shared.qrc @@ -52,4 +53,5 @@ android { HEADERS += \ sqlstoragemodel.h \ sqlprofilemodel.h \ - buzzerconn.h + buzzerconn.h \ + appsettings.h