diff --git a/SpeedClimbingReactionTrainer.pro b/SpeedClimbingReactionTrainer.pro new file mode 100644 index 0000000..acca1b6 --- /dev/null +++ b/SpeedClimbingReactionTrainer.pro @@ -0,0 +1,49 @@ +QT += quick qml quickcontrols2 + +android { + QT += androidextras +} + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has been marked deprecated (the exact warnings +# depend on your compiler). Refer to the documentation for the +# deprecated API to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if it uses deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +SOURCES += \ + sources/main.cpp \ + sources/appsettings.cpp \ + sources/apptheme.cpp + +HEADERS += \ + headers/appsettings.h \ + headers/apptheme.h + +RESOURCES += qml/qml.qrc \ + shared/shared.qrc + +# Additional import path used to resolve QML modules in Qt Creator's code model +QML_IMPORT_PATH = + +# Additional import path used to resolve QML modules just for Qt Quick Designer +QML_DESIGNER_IMPORT_PATH = + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +android { + ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android-sources +} + +DISTFILES += \ + android-sources/AndroidManifest.xml + diff --git a/SpeedClimbingReactionTrainer.pro.user b/SpeedClimbingReactionTrainer.pro.user new file mode 100644 index 0000000..ee61a9c --- /dev/null +++ b/SpeedClimbingReactionTrainer.pro.user @@ -0,0 +1,635 @@ + + + + + + EnvironmentId + {73fd4d96-a4f7-426d-9695-506509aacee9} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + true + 0 + 8 + true + 1 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + true + + + + ProjectExplorer.Project.Target.0 + + Android for armeabi-v7a (Clang Qt 5.11.3 for Android ARMv7) + Android for armeabi-v7a (Clang Qt 5.11.3 for Android ARMv7) + {0c845c7b-f333-4cf9-be32-0bca6d080fce} + 1 + 0 + 0 + + /home/dorian/Documents/git/builds/build-SpeedClimbingReactionTrainer-Android_for_armeabi_v7a_Clang_Qt_5_11_3_for_Android_ARMv7-Debug + + + true + qmake + + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Make + + Qt4ProjectManager.MakeStep + + false + + + false + + + true + Copy application data + + Qt4ProjectManager.AndroidPackageInstallationStep + + + android-28 + + true + Build Android APK + + QmakeProjectManager.AndroidBuildApkStep + false + false + + 4 + Build + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + true + + + /home/dorian/Documents/git/builds/build-SpeedClimbingReactionTrainer-Android_for_armeabi_v7a_Clang_Qt_5_11_3_for_Android_ARMv7-Release + + + true + qmake + + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Make + + Qt4ProjectManager.MakeStep + + false + + + false + + + true + Copy application data + + Qt4ProjectManager.AndroidPackageInstallationStep + + + android-28 + /home/dorian/Documents/git/bluemessage/android_release.keystore + true + Build Android APK + + QmakeProjectManager.AndroidBuildApkStep + false + false + + 4 + Build + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + true + + + /home/dorian/Documents/git/builds/build-SpeedClimbingReactionTrainer-Android_for_armeabi_v7a_Clang_Qt_5_11_3_for_Android_ARMv7-Profile + + + true + qmake + + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Make + + Qt4ProjectManager.MakeStep + + false + + + false + + + true + Copy application data + + Qt4ProjectManager.AndroidPackageInstallationStep + + + android-28 + + true + Build Android APK + + QmakeProjectManager.AndroidBuildApkStep + false + false + + 4 + Build + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + true + + 3 + + + + true + Deploy to Android device + + Qt4ProjectManager.AndroidDeployQtStep + false + + 1 + Deploy + + ProjectExplorer.BuildSteps.Deploy + + 1 + Deploy to Android device + + Qt4ProjectManager.AndroidDeployConfiguration2 + + 1 + + MWS0216A15001488 + 24 + + + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + + + + 0 + + SpeedClimbingReactionTrainer + SpeedClimbingReactionTrainer + Qt4ProjectManager.AndroidRunConfiguration:/home/dorian/Documents/git/SpeedClimbingReactionTrainer/SpeedClimbingReactionTrainer.pro + + 3768 + false + true + false + false + true + + 1 + + + + ProjectExplorer.Project.Target.1 + + Desktop Qt 5.11.3 GCC 64bit + Desktop Qt 5.11.3 GCC 64bit + qt.qt5.5113.gcc_64_kit + 0 + 0 + 0 + + /home/dorian/Documents/git/builds/build-SpeedClimbingReactionTrainer-Desktop_Qt_5_11_3_GCC_64bit-Debug + + + true + qmake + + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Make + + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + true + + + /home/dorian/Documents/git/builds/build-SpeedClimbingReactionTrainer-Desktop_Qt_5_11_3_GCC_64bit-Release + + + true + qmake + + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Make + + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + true + + + /home/dorian/Documents/git/builds/build-SpeedClimbingReactionTrainer-Desktop_Qt_5_11_3_GCC_64bit-Profile + + + true + qmake + + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Make + + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + true + + 3 + + + 0 + Deploy + + ProjectExplorer.BuildSteps.Deploy + + 1 + Deploy Configuration + + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + SpeedClimbingReactionTrainer + + Qt4ProjectManager.Qt4RunConfiguration:/home/dorian/Documents/git/SpeedClimbingReactionTrainer/SpeedClimbingReactionTrainer.pro + SpeedClimbingReactionTrainer.pro + + 3768 + false + true + true + false + false + true + + + + 1 + + + + ProjectExplorer.Project.TargetCount + 2 + + + ProjectExplorer.Project.Updater.FileVersion + 20 + + + Version + 20 + + diff --git a/android-sources/AndroidManifest.xml b/android-sources/AndroidManifest.xml new file mode 100644 index 0000000..0413764 --- /dev/null +++ b/android-sources/AndroidManifest.xml @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android-sources/res/drawable-hdpi/icon.png b/android-sources/res/drawable-hdpi/icon.png new file mode 100644 index 0000000..c98ba7e Binary files /dev/null and b/android-sources/res/drawable-hdpi/icon.png differ diff --git a/android-sources/res/drawable-ldpi/icon.png b/android-sources/res/drawable-ldpi/icon.png new file mode 100644 index 0000000..c98ba7e Binary files /dev/null and b/android-sources/res/drawable-ldpi/icon.png differ diff --git a/android-sources/res/drawable-mdpi/icon.png b/android-sources/res/drawable-mdpi/icon.png new file mode 100644 index 0000000..c98ba7e Binary files /dev/null and b/android-sources/res/drawable-mdpi/icon.png differ diff --git a/headers/appsettings.h b/headers/appsettings.h new file mode 100644 index 0000000..7101f29 --- /dev/null +++ b/headers/appsettings.h @@ -0,0 +1,28 @@ +#ifndef APPSETTINGS_H +#define APPSETTINGS_H + +#include +#include +#include +#include +class AppSettings : public QObject +{ + Q_OBJECT +public: + explicit AppSettings(QObject *parent = nullptr); + ~AppSettings(); + + Q_INVOKABLE QString read(const QString &key); + Q_INVOKABLE void write(const QString &key, const QVariant &variant); + Q_INVOKABLE void setDefaultSetting(const QString &key, const QVariant &defaultVariant); + + QSettings *settingsManager; + +signals: + +public slots: + +}; +extern AppSettings * pGlobalAppSettings; + +#endif // APPSETTINGS_H diff --git a/headers/apptheme.h b/headers/apptheme.h new file mode 100644 index 0000000..60afe2f --- /dev/null +++ b/headers/apptheme.h @@ -0,0 +1,30 @@ +#ifndef APPTHEME_H +#define APPTHEME_H + +#include +#include +#include "appsettings.h" + +class AppTheme : public QObject +{ + Q_OBJECT + Q_PROPERTY(QVariant style READ getStyle NOTIFY styleChanged) +public: + explicit AppTheme(QObject *parent = nullptr); + +private: + + QList themes; + + QVariant * currentTheme; + + +signals: + void styleChanged(); + +public slots: + QVariant getStyle(); + Q_INVOKABLE void refreshTheme(); +}; + +#endif // APPTHEME_H diff --git a/qml/Components/FadeAnimation.qml b/qml/Components/FadeAnimation.qml new file mode 100644 index 0000000..bb05356 --- /dev/null +++ b/qml/Components/FadeAnimation.qml @@ -0,0 +1,49 @@ +/* + Speed Climbing Stopwatch - Simple Stopwatch for Climbers + Copyright (C) 2018 Itsblue Development - Dorian Zeder + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, version 3 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ + +import QtQuick 2.0 + +SequentialAnimation { + id: root + property QtObject target + property string fadeProperty: "scale" + property int fadeDuration: 150 + property int fadeDuration_in: fadeDuration + property int fadeDuration_out: fadeDuration + property alias outValue: outAnimation.to + property alias inValue: inAnimation.to + property alias outEasingType: outAnimation.easing.type + property alias inEasingType: inAnimation.easing.type + property string easingType: "Quad" + NumberAnimation { // in the default case, fade scale to 0 + id: outAnimation + target: root.target + property: root.fadeProperty + duration: root.fadeDuration_in + to: 0 + easing.type: Easing["In"+root.easingType] + } + PropertyAction { } // actually change the property targeted by the Behavior between the 2 other animations + NumberAnimation { // in the default case, fade scale back to 1 + id: inAnimation + target: root.target + property: root.fadeProperty + duration: root.fadeDuration_out + to: 1 + easing.type: Easing["Out"+root.easingType] + } +} diff --git a/qml/Components/FancyButton.qml b/qml/Components/FancyButton.qml new file mode 100644 index 0000000..2ec7623 --- /dev/null +++ b/qml/Components/FancyButton.qml @@ -0,0 +1,88 @@ +import QtQuick 2.9 +import QtQuick.Controls 2.4 +import QtGraphicalEffects 1.0 + +Button { + id: control + + property string image + property color backgroundColor: "white" + property color textColor: "black" + property real imageScale: 1 + property double glowRadius: 0.001 + property double glowSpread: 0.2 + property bool glowVisible: true + property double glowScale: 0.75 + property double glowOpacity: 1 + + scale: control.pressed ? 0.8:1 + + Behavior on scale { + PropertyAnimation { + duration: 100 + } + } + + Behavior on backgroundColor { + ColorAnimation { + duration: 200 + } + } + + contentItem: Text { + visible: false + } + + Text { + id: conetntText + text: qsTr(control.text) + anchors.centerIn: parent + font: parent.font + color: control.textColor + opacity: control.enabled ? 1:0.4 + } + + background: Item { + id: controlBackgroundContainer + + RectangularGlow { + id: effect + glowRadius: control.glowRadius + spread: control.glowSpread + color: "black" + + visible: control.glowVisible + + cornerRadius: controlBackground.radius + anchors.fill: controlBackground + scale: control.glowScale + opacity: control.glowOpacity + } + + Rectangle { + id: controlBackground + + anchors.fill: parent + + radius: height * 0.5 + + color: control.backgroundColor + + Image { + id: buttonIcon + source: control.image + + anchors.centerIn: parent + height: parent.height * 0.5 + width: height + + mipmap: true + + fillMode: Image.PreserveAspectFit + + scale: control.imageScale + } + } + } + +} diff --git a/qml/main.qml b/qml/main.qml new file mode 100644 index 0000000..a4fc2fc --- /dev/null +++ b/qml/main.qml @@ -0,0 +1,367 @@ +import QtQuick 2.9 +import QtQuick.Window 2.2 +import QtQuick.Controls 2.4 +import QtMultimedia 5.0 +import QtGraphicalEffects 1.0 +import QtQuick.Controls.Styles 1.4 + +import com.itsblue.SpeedClimbingStartTrainer 2.0 + +import "./Components" + +Window { + visible: true + width: 640 + height: 480 + title: qsTr("Hello World") + + Page { + id: app + + state: "IDLE" + + anchors.fill: parent + + property double startTime: -1 + property double stopTime: -1 + + property double reactionTime: 0 + + property int highscore: settings.read("highscore") + + AppSettings { + id: settings + } + + AppTheme { + id: theme + } + + Item { + id: soundsItm + + SoundEffect { + id: readySe + + source: "qrc:/sounds/ready_1.wav" + + muted: app.state === "WAITING" + + onPlayingChanged: { + if(!playing && app.state === "RUNNING"){ + startSe.play() + } + } + } + + SoundEffect { + id: startSe + + source: "qrc:/sounds/OFFICAL_IFSC_STARTIGNAL.wav" + + muted: app.state === "WAITING" + + onPlayingChanged: { + if(!playing){ + app.startTime = new Date().getTime() + console.log("offset: ", new Date().getTime() - app.startTime) + + if(app.state === "WAITING"){ + app.reactionTime = app.stopTime - app.startTime + app.state = "STOPPED" + } + } + } + } + + SoundEffect { + id: failedSe + source: "qrc:/sounds/false.wav" + } + + } + + Rectangle { + anchors.fill: parent + color: theme.style.backgroundColor + + Behavior on color { + + ColorAnimation { + duration: 200 + } + } + } + + Item { + id: topContainerItm + + anchors { + top: parent.top + left: parent.left + right: app.landscape() ? startBt.left:parent.right + bottom: app.landscape() ? parent.bottom:startBt.top + bottomMargin: app.landscape() ? undefined:parent.height * 0.1 + rightMargin: app.landscape() ? parent.width * 0.05:0 + } + + Text { + id: topLa + + anchors.centerIn: parent + + width: parent.width * 0.8 + + text: "" + color: theme.style.textColor + + fontSizeMode: Text.Fit + + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + + font.pixelSize: app.landscape() ? parent.width * 0.1 : parent.height * 0.4 + + minimumPixelSize: 0 + + Behavior on text { + FadeAnimation{ + target: topLa + } + } + } + + Text { + id: highscoreLa + + anchors { + top: topLa.bottom + horizontalCenter: parent.horizontalCenter + } + + width: topLa.width * 0.5 + height: topLa.height + + visible: text !== "highscore: -1" + + text: "" + + color: theme.style.textColor + + fontSizeMode: Text.Fit + + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + + font.pixelSize: app.landscape() ? parent.width * 0.1 : parent.height * 0.4 + + minimumPixelSize: 0 + + Behavior on text { + FadeAnimation{ + target: highscoreLa + } + } + } + + Switch { + anchors { + top: topLa.bottom + horizontalCenter: parent.horizontalCenter + horizontalCenterOffset: width * 0.1 + } + + checked: settings.read("theme") === "1" + + scale: 0.8 + + opacity: app.state === "IDLE" ? 1:0 + + onCheckedChanged: { + if(checked){ + settings.write("theme", 1) + } + else { + settings.write("theme", 0) + } + + theme.refreshTheme() + } + + indicator: Rectangle { + + property bool checked: parent.checked + property bool down: parent.down + + height: parent.height + width: height * 2 + + radius: height * 0.5 + color: parent.checked ? "#17a81a" : "transparent" + border.color: parent.checked ? "#17a81a" : "#cccccc" + + Behavior on color{ + ColorAnimation{ + duration: 200 + } + } + + Rectangle { + x: parent.checked ? parent.width - width : 0 + width: parent.height + height: parent.height + radius: height * 0.5 + color: parent.down ? theme.style.buttonPressedColor:theme.style.backgroundColor //"#cccccc" : "#ffffff" + border.color: parent.checked ? (parent.down ? "#17a81a" : "#21be2b") : "#999999" + Behavior on x{ + NumberAnimation { + property: "x" + duration: 200 + easing.type: Easing.InOutQuad + } + } + } + } + + Behavior on opacity { + NumberAnimation { + duration: 200 + } + } + } + } + + FancyButton { + id: startBt + + text: "start" + property int size: app.landscape() ? parent.width * 0.5:parent.height * 0.5 + + backgroundColor: theme.style.buttonColor + textColor: theme.style.textColor + + anchors { + bottom: parent.bottom + right: parent.right + bottomMargin: app.landscape() ? parent.height * 0.5 - startBt.height * 0.5:parent.height * 0.1 + rightMargin: app.landscape() ? parent.width * 0.05:parent.width * 0.5 - startBt.width * 0.5 + } + + font.pixelSize: height * 0.15 + + height: app.landscape() ? (size > parent.height * 0.9 ? parent.height * 0.9:size) : (size > parent.width * 0.9 ? parent.width * 0.9:size) + width: height + + onPressed: { + app.start() + } + + onReleased: { + app.stop() + } + } + + function landscape() { + return app.height < app.width + } + + function start() { + if(app.state !== "IDLE"){ + app.reset() + return + } + + app.state = "RUNNING" + readySe.play() + } + + function stop() { + + app.stopTime = new Date().getTime() + + if(app.state !== "RUNNING"){ + return + } + + if(startSe.playing){ + app.state = "WAITING" + + failedSe.play() + } + else if(readySe.playing){ + app.state = "IDLE" + } + + else { + app.state = "STOPPED" + + app.reactionTime = app.stopTime - app.startTime + + app.refreshHighscore() + } + } + + function refreshHighscore(){ + if(app.reactionTime > 0 && ( app.reactionTime < parseInt(settings.read("highscore")) || settings.read("highscore") === "-1" )){ + settings.write("highscore", app.reactionTime) + app.highscore = app.reactionTime + } + } + + function reset() { + app.state = "IDLE" + } + + states: [ + State { + name: "IDLE" + PropertyChanges { + target: topLa + text: "Hold down start to start" + } + }, + + State { + name: "RUNNING" + PropertyChanges { + target: topLa + text: "release to stop" + } + }, + + State { + name: "STOPPED" + PropertyChanges { + target: topLa + text: "Your reaction time: " + app.reactionTime + } + + PropertyChanges { + target: startBt + text: "reset" + } + + PropertyChanges { + target: highscoreLa + text: "highscore: " + app.highscore + } + }, + + State { + name: "WAITING" + PropertyChanges { + target: topLa + text: "please wait..." + } + + PropertyChanges { + target: startBt + enabled: false + text: "waiting..." + } + } + ] + + } + +} diff --git a/qml/qml.qrc b/qml/qml.qrc new file mode 100644 index 0000000..0e60d44 --- /dev/null +++ b/qml/qml.qrc @@ -0,0 +1,7 @@ + + + main.qml + Components/FadeAnimation.qml + Components/FancyButton.qml + + diff --git a/shared/graphics/Banner.png b/shared/graphics/Banner.png new file mode 100644 index 0000000..2d8337d Binary files /dev/null and b/shared/graphics/Banner.png differ diff --git a/shared/graphics/Banner.xcf b/shared/graphics/Banner.xcf new file mode 100644 index 0000000..d05d956 Binary files /dev/null and b/shared/graphics/Banner.xcf differ diff --git a/shared/graphics/SpeedClimbingStartTrainer.xcf b/shared/graphics/SpeedClimbingStartTrainer.xcf new file mode 100644 index 0000000..f3f3f65 Binary files /dev/null and b/shared/graphics/SpeedClimbingStartTrainer.xcf differ diff --git a/shared/graphics/favicon.png b/shared/graphics/favicon.png new file mode 100644 index 0000000..c98ba7e Binary files /dev/null and b/shared/graphics/favicon.png differ diff --git a/shared/graphics/faviconForGooglePlay.png b/shared/graphics/faviconForGooglePlay.png new file mode 100644 index 0000000..2d44424 Binary files /dev/null and b/shared/graphics/faviconForGooglePlay.png differ diff --git a/shared/shared.qrc b/shared/shared.qrc new file mode 100644 index 0000000..96d201d --- /dev/null +++ b/shared/shared.qrc @@ -0,0 +1,8 @@ + + + sounds/at_marks_1.wav + sounds/OFFICAL_IFSC_STARTIGNAL.wav + sounds/ready_1.wav + sounds/false.wav + + diff --git a/shared/sounds/OFFICAL_IFSC_STARTIGNAL.wav b/shared/sounds/OFFICAL_IFSC_STARTIGNAL.wav new file mode 100644 index 0000000..b3aa454 Binary files /dev/null and b/shared/sounds/OFFICAL_IFSC_STARTIGNAL.wav differ diff --git a/shared/sounds/at_marks_1.wav b/shared/sounds/at_marks_1.wav new file mode 100644 index 0000000..f73c703 Binary files /dev/null and b/shared/sounds/at_marks_1.wav differ diff --git a/shared/sounds/at_marks_2.wav b/shared/sounds/at_marks_2.wav new file mode 100644 index 0000000..54494c0 Binary files /dev/null and b/shared/sounds/at_marks_2.wav differ diff --git a/shared/sounds/false.wav b/shared/sounds/false.wav new file mode 100644 index 0000000..ae4daa7 Binary files /dev/null and b/shared/sounds/false.wav differ diff --git a/shared/sounds/ready_1.wav b/shared/sounds/ready_1.wav new file mode 100644 index 0000000..42f0867 Binary files /dev/null and b/shared/sounds/ready_1.wav differ diff --git a/shared/sounds/ready_2.wav b/shared/sounds/ready_2.wav new file mode 100644 index 0000000..abe5032 Binary files /dev/null and b/shared/sounds/ready_2.wav differ diff --git a/shared/sounds/sounds.aup b/shared/sounds/sounds.aup new file mode 100644 index 0000000..65a9068 --- /dev/null +++ b/shared/sounds/sounds.aup @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/shared/sounds/sounds_data/e00/d00/e0000260.au b/shared/sounds/sounds_data/e00/d00/e0000260.au new file mode 100644 index 0000000..2a99728 Binary files /dev/null and b/shared/sounds/sounds_data/e00/d00/e0000260.au differ diff --git a/shared/sounds/sounds_data/e00/d00/e0000290.au b/shared/sounds/sounds_data/e00/d00/e0000290.au new file mode 100644 index 0000000..ecea0e6 Binary files /dev/null and b/shared/sounds/sounds_data/e00/d00/e0000290.au differ diff --git a/shared/sounds/sounds_data/e00/d00/e0000457.au b/shared/sounds/sounds_data/e00/d00/e0000457.au new file mode 100644 index 0000000..2a99728 Binary files /dev/null and b/shared/sounds/sounds_data/e00/d00/e0000457.au differ diff --git a/shared/sounds/sounds_data/e00/d00/e0000542.au b/shared/sounds/sounds_data/e00/d00/e0000542.au new file mode 100644 index 0000000..fbc4417 Binary files /dev/null and b/shared/sounds/sounds_data/e00/d00/e0000542.au differ diff --git a/shared/sounds/sounds_data/e00/d00/e0000714.au b/shared/sounds/sounds_data/e00/d00/e0000714.au new file mode 100644 index 0000000..9ed3dfc Binary files /dev/null and b/shared/sounds/sounds_data/e00/d00/e0000714.au differ diff --git a/shared/sounds/sounds_data/e00/d00/e0000996.au b/shared/sounds/sounds_data/e00/d00/e0000996.au new file mode 100644 index 0000000..ecea0e6 Binary files /dev/null and b/shared/sounds/sounds_data/e00/d00/e0000996.au differ diff --git a/shared/sounds/sounds_data/e00/d00/e00009d0.au b/shared/sounds/sounds_data/e00/d00/e00009d0.au new file mode 100644 index 0000000..9ed3dfc Binary files /dev/null and b/shared/sounds/sounds_data/e00/d00/e00009d0.au differ diff --git a/shared/sounds/sounds_data/e00/d00/e0000ce4.au b/shared/sounds/sounds_data/e00/d00/e0000ce4.au new file mode 100644 index 0000000..fbc4417 Binary files /dev/null and b/shared/sounds/sounds_data/e00/d00/e0000ce4.au differ diff --git a/sources/appsettings.cpp b/sources/appsettings.cpp new file mode 100644 index 0000000..61e636d --- /dev/null +++ b/sources/appsettings.cpp @@ -0,0 +1,63 @@ +/* + Speed Climbing Stopwatch - Simple Stopwatch for Climbers + Copyright (C) 2018 Itsblue Development - Dorian Zeder + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, version 3 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ + +#include "headers/appsettings.h" + +AppSettings * pGlobalAppSettings = nullptr; + +AppSettings::AppSettings(QObject* parent) + :QObject(parent) +{ + QString path = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); + + this->settingsManager = new QSettings(path+"/settings.ini", QSettings::IniFormat); + + this->setDefaultSetting("highscore", "-1"); + this->setDefaultSetting("theme", "0"); + + pGlobalAppSettings = this; +} + +QString AppSettings::read(const QString &key) +{ + this->settingsManager->beginGroup("AppSettings"); + QString value = this->settingsManager->value(key , false).toString(); + this->settingsManager->endGroup(); + return(value); +} + +void AppSettings::write(const QString &key, const QVariant &variant) +{ + this->settingsManager->beginGroup("AppSettings"); + this->settingsManager->setValue(key , variant); + this->settingsManager->endGroup(); +} + +void AppSettings::setDefaultSetting(const QString &key, const QVariant &defaultVariant) +{ + QString value = this->read(key); + if(value == "false"){ + this->write(key, defaultVariant); + } + +} + +AppSettings::~AppSettings() +{ + delete settingsManager; +} + diff --git a/sources/apptheme.cpp b/sources/apptheme.cpp new file mode 100644 index 0000000..22e36f6 --- /dev/null +++ b/sources/apptheme.cpp @@ -0,0 +1,95 @@ +#include "headers/apptheme.h" + +AppTheme::AppTheme(QObject *parent) : QObject(parent) +{ + + QVariantMap tmpLightTheme = { + {"backgroundColor", "white"}, + + {"buttonColor", "white"}, + {"buttonPressedColor", "lightgrey"}, + {"buttonBorderColor", "grey"}, + {"disabledButtonColor", "#d5d5d5"}, + + {"viewColor", "white"}, + {"menuColor", "#f8f8f8"}, + + {"delegate1Color", "#202227"}, + {"delegate2Color", "#202227"}, + {"delegateBackgroundColor", "white"}, + {"delegatePressedColor", "#dddedf"}, + + {"textColor", "black"}, + {"textDarkColor", "#232323"}, + {"disabledTextColor", "grey"}, + + {"sliderColor", "#6ccaf2"}, + + {"errorColor", "#ba3f62"}, + {"infoColor", "#3fba62"}, + + {"lineColor", "grey"}, + + {"backIcon", "qrc:/graphics/icons/back_black.png"}, + {"settIcon", "qrc:/graphics/icons/settings_black.png"}, + {"buzzerIcon", "qrc:/graphics/icons/buzzer_black.png"}, + {"startpadIcon", "qrc:/graphics/icons/startpad_black.png"}, + {"baseStationIcon", "qrc:/graphics/icons/BaseStation_black.png"} + + }; + this->themes.append(tmpLightTheme); + + QVariantMap tmpDarkTheme = { + {"backgroundColor", "#2d3037"}, + + {"buttonColor", "#202227"}, + {"buttonPressedColor", "#6ccaf2"}, + {"buttonBorderColor", "grey"}, + {"disabledButtonColor", "#555555"}, + + {"viewColor", "#202227"}, + {"menuColor", "#292b32"}, + + {"delegate1Color", "#202227"}, + {"delegate2Color", "#202227"}, + {"delegateBackgroundColor", "#202227"}, + {"delegatePressedColor", "#41454f"}, + + {"textColor", "#ffffff"}, + {"textDarkColor", "#232323"}, + {"disabledTextColor", "#777777"}, + + {"sliderColor", "#6ccaf2"}, + + {"errorColor", "#ba3f62"}, + {"infoColor", "#3fba62"}, + + {"lineColor", "grey"}, + + {"backIcon", "qrc:/graphics/icons/back.png"}, + {"settIcon", "qrc:/graphics/icons/settings.png"}, + {"buzzerIcon", "qrc:/graphics/icons/buzzer.png"}, + {"startpadIcon", "qrc:/graphics/icons/startpad.png"}, + {"baseStationIcon", "qrc:/graphics/icons/BaseStation.png"} + + }; + this->themes.append(tmpDarkTheme); + + QString currentThemeString = pGlobalAppSettings->read("theme"); + + this->currentTheme = &this->themes[currentThemeString.toInt()]; + + qDebug() << currentThemeString << currentThemeString.toInt(); +} + +QVariant AppTheme::getStyle() { + return *this->currentTheme; +} + +void AppTheme::refreshTheme() { + QString currentThemeString = pGlobalAppSettings->read("theme"); + + this->currentTheme = &this->themes[currentThemeString.toInt()]; + + emit this->styleChanged(); +} diff --git a/sources/main.cpp b/sources/main.cpp new file mode 100644 index 0000000..c6f1c9d --- /dev/null +++ b/sources/main.cpp @@ -0,0 +1,45 @@ +#include +#include + +#include "headers/apptheme.h" +#include "headers/appsettings.h" + +#ifdef Q_OS_ANDROID +#include +#endif + +int main(int argc, char *argv[]) +{ + QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + + QGuiApplication app(argc, argv); + +#ifdef Q_OS_ANDROID + //set the standard volume to media + QAndroidJniObject jactivity=QtAndroid::androidActivity(); + if(jactivity.isValid()) + jactivity.callMethod("setVolumeControlStream","(I)V",3); + + //set statusbar color + QtAndroid::runOnAndroidThread([=]() + { + QAndroidJniObject window = QtAndroid::androidActivity().callObjectMethod("getWindow", "()Landroid/view/Window;"); + window.callMethod("addFlags", "(I)V", 0x80000000); + window.callMethod("clearFlags", "(I)V", 0x04000000); + //window.callMethod("setStatusBarColor", "(I)V", 0x202227); // Desired statusbar color + //QAndroidJniObject decorView = window.callObjectMethod("getDecorView", "()Landroid/view/View;"); + //decorView.callMethod("setSystemUiVisibility", "(I)V", 0x00002000); + }); +#endif + + qmlRegisterType("com.itsblue.SpeedClimbingStartTrainer", 2, 0, "AppTheme"); + qmlRegisterType("com.itsblue.SpeedClimbingStartTrainer", 2, 0, "AppSettings"); + + + QQmlApplicationEngine engine; + engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); + if (engine.rootObjects().isEmpty()) + return -1; + + return app.exec(); +}