diff --git a/ScStwLibraries/ScStwLibraries.pro b/ScStwLibraries/ScStwLibraries.pro index 533f655..73f691d 100644 --- a/ScStwLibraries/ScStwLibraries.pro +++ b/ScStwLibraries/ScStwLibraries.pro @@ -1,5 +1,9 @@ QT -= gui -QT += network multimedia +QT += network multimedia quick + +CONFIG(contains(QMAKE_LFLAGS_CONSOLE)){ +message("this is console") +} TEMPLATE = lib DEFINES += SCSTWLIBRARIES_LIBRARY @@ -20,6 +24,7 @@ DEFINES += QT_DEPRECATED_WARNINGS SOURCES += \ sources/ScStw.cpp \ sources/scstwclient.cpp \ + sources/scstwlibraries.cpp \ sources/scstwrace.cpp \ sources/scstwremotemonitorrace.cpp \ sources/scstwsoundplayer.cpp \ @@ -28,6 +33,7 @@ SOURCES += \ HEADERS += \ headers/ScStw.hpp \ headers/ScStwLibraries_global.h \ + headers/scstwlibraries.h \ headers/scstwrace.h \ headers/scstwclient.h \ headers/scstwremotemonitorrace.h \ diff --git a/ScStwLibraries/headers/ScStw.hpp b/ScStwLibraries/headers/ScStw.hpp index 9306e46..0dfbaaa 100644 --- a/ScStwLibraries/headers/ScStw.hpp +++ b/ScStwLibraries/headers/ScStw.hpp @@ -3,6 +3,7 @@ #include #include +#include /*! * \mainpage ScStw Libraries documentation @@ -222,6 +223,15 @@ public: */ static int firmwareCompare(QString a, QString b); + /*! + * \brief Function to convert a value to an enum + */ + template + static Enum toEnumValue(const int &value, bool *ok) + { + QMetaEnum enumeration = QMetaEnum::fromType(); + return static_cast(enumeration.keyToValue(enumeration.valueToKey(value), ok)); + } ScStw() : QObject(nullptr) {}; private: diff --git a/ScStwLibraries/headers/scstwclient.h b/ScStwLibraries/headers/scstwclient.h index 1955b70..ca3410a 100644 --- a/ScStwLibraries/headers/scstwclient.h +++ b/ScStwLibraries/headers/scstwclient.h @@ -33,6 +33,7 @@ class ScStwClient : public QObject Q_OBJECT Q_PROPERTY(State state READ getState NOTIFY stateChanged) Q_PROPERTY(QVariantList extensions READ getExtensions NOTIFY extensionsChanged) + Q_PROPERTY(QString ipAddress READ getIP WRITE setIP) public: /*! diff --git a/ScStwLibraries/headers/scstwlibraries.h b/ScStwLibraries/headers/scstwlibraries.h new file mode 100644 index 0000000..3a4f4ab --- /dev/null +++ b/ScStwLibraries/headers/scstwlibraries.h @@ -0,0 +1,24 @@ +#ifndef SCSTWLIBRARIES_H +#define SCSTWLIBRARIES_H + +#include +#include +#include "scstwclient.h" +#include "scstwtimer.h" +#include "scstwrace.h" + +class ScStwLibraries : public QObject +{ + Q_OBJECT + +public: + static void init(); + +private: + explicit ScStwLibraries(QObject *parent = nullptr); + +signals: + +}; + +#endif // SCSTWLIBRARIES_H diff --git a/ScStwLibraries/headers/scstwrace.h b/ScStwLibraries/headers/scstwrace.h index 1f20801..62ab2ed 100644 --- a/ScStwLibraries/headers/scstwrace.h +++ b/ScStwLibraries/headers/scstwrace.h @@ -94,24 +94,24 @@ public slots: * * \return 200: OK; 904: state not matching */ - int stop(); + virtual int stop(); /*! * \brief Function to reset a stopped race * \return */ - int reset(); - int cancel(); + virtual int reset(); + virtual int cancel(); // setters bool writeStartActionSetting(StartAction action, bool enabled, int delay); bool setSoundVolume(double volume); - bool addTimer(ScStwTimer *timer); + virtual bool addTimer(ScStwTimer *timer); // getters RaceState getState(); StartAction getNextStartAction(); - QVariantList getNextStartActionDetails(); + virtual QVariantList getNextStartActionDetails(); QVariantList getTimerDetailList(); protected slots: diff --git a/ScStwLibraries/headers/scstwremotemonitorrace.h b/ScStwLibraries/headers/scstwremotemonitorrace.h index a721dfb..95e87e5 100644 --- a/ScStwLibraries/headers/scstwremotemonitorrace.h +++ b/ScStwLibraries/headers/scstwremotemonitorrace.h @@ -8,7 +8,6 @@ class ScStwRemoteMonitorRace : public ScStwRace { Q_OBJECT - Q_PROPERTY(QVariantList nextStartActionDetails READ getNextStartActionDetails NOTIFY nextStartActionDetailsChanged) public: ScStwRemoteMonitorRace(ScStwClient *monitorClient, QObject *parent = nullptr); @@ -21,7 +20,7 @@ private: public slots: int start(); - void cancelStart(); + int cancel(); int stop(); int reset(); bool addTimer(ScStwTimer *timer); diff --git a/ScStwLibraries/sources/ScStw.cpp b/ScStwLibraries/sources/ScStw.cpp index 2855eb7..68a97ba 100644 --- a/ScStwLibraries/sources/ScStw.cpp +++ b/ScStwLibraries/sources/ScStw.cpp @@ -27,51 +27,30 @@ QString ScStw::baseStationSettingToString(ScStw::BaseStationSetting s) { } ScStw::BaseStationSetting ScStw::baseStationSettingfromInt(int i) { - if(i < 0 || i > 4) + bool ok; + BaseStationSetting s = ScStw::toEnumValue(i, &ok); + if(!ok) return InvalidSetting; else - return BaseStationSetting(i); + return s; } ScStw::SignalKey ScStw::signalKeyFromInt(int i) { - if(i < 9000 || i > 9003) + bool ok; + ScStw::SignalKey k = ScStw::toEnumValue(i, &ok); + if(!ok) return InvalidSignal; else - return SignalKey(i); + return k; } ScStw::SocketCommand ScStw::socketCommandFromInt(int i) { - QList allCommands = { - InitializeSessionCommand, - - StartTimersCommand, - StopTimersCommand, - ResetTimersCommand, - - GetRaceStateCommand, - GetNextStartActionCommand, - GetExtensionsCommand, - GetTimersCommand, - GetNextStartActionDetailsCommand, - - WriteSettingCommand, - ReadSettingCommand, - - LoginAthleteCommand, - CreateAthleteCommand, - DeleteAthleteCommand, - GetAtheletesCommand, - GetAthleteResultsCommand, - - UpdateFirmwareCommand, - UpdateSystemTimeCommand, - PairExtensionsCommand - }; - - if(!allCommands.contains(SocketCommand(i))) + bool ok; + SocketCommand c = ScStw::toEnumValue(i, &ok); + if(!ok) return InvalidCommand; else - return SocketCommand(i); + return c; } int ScStw::firmwareCompare(QString a, QString b) { diff --git a/ScStwLibraries/sources/scstwlibraries.cpp b/ScStwLibraries/sources/scstwlibraries.cpp new file mode 100644 index 0000000..439a636 --- /dev/null +++ b/ScStwLibraries/sources/scstwlibraries.cpp @@ -0,0 +1,16 @@ +#include "../headers/scstwlibraries.h" + +ScStwLibraries::ScStwLibraries(QObject *parent) : QObject(parent) +{ + +} + +void ScStwLibraries::init() { + qmlRegisterType("de.itsblue.ScStw", 2, 0, "ScStw"); + qRegisterMetaType("ScStw::BaseStationSetting"); + qRegisterMetaType("ScStw::SocketCommand"); + + qmlRegisterType("de.itsblue.ScStw", 2, 0, "ScStwRace"); + qmlRegisterType("de.itsblue.ScStw", 2, 0, "ScStwTimer"); + qmlRegisterType("de.itsblue.ScStw", 2, 0, "ScStwClient"); +} diff --git a/ScStwLibraries/sources/scstwremotemonitorrace.cpp b/ScStwLibraries/sources/scstwremotemonitorrace.cpp index e21cacf..8c769da 100644 --- a/ScStwLibraries/sources/scstwremotemonitorrace.cpp +++ b/ScStwLibraries/sources/scstwremotemonitorrace.cpp @@ -38,9 +38,9 @@ int ScStwRemoteMonitorRace::start() { return returnCode; } -void ScStwRemoteMonitorRace::cancelStart() { - this->stop(); - return; +int ScStwRemoteMonitorRace::cancel() { + return this->stop(); + } int ScStwRemoteMonitorRace::stop() { diff --git a/ScStwLibraries/sources/scstwsoundplayer.cpp b/ScStwLibraries/sources/scstwsoundplayer.cpp index 52cdff3..4cf768d 100644 --- a/ScStwLibraries/sources/scstwsoundplayer.cpp +++ b/ScStwLibraries/sources/scstwsoundplayer.cpp @@ -27,7 +27,7 @@ ScStwSoundPlayer::ScStwSoundPlayer(QObject *parent) : QObject(parent) } this->audioOutput = new QAudioOutput(format, this); - this->audioOutput->setCategory("ScStw start sound"); + this->audioOutput->setCategory("media"); connect(this->audioOutput, SIGNAL(stateChanged(QAudio::State)), this, SLOT(handleStateChanged(QAudio::State))); connect(this, &ScStwSoundPlayer::playbackStarted, this->waitLoop, &QEventLoop::quit); diff --git a/ScStwStyling/.gitignore b/ScStwStyling/.gitignore new file mode 100644 index 0000000..84c048a --- /dev/null +++ b/ScStwStyling/.gitignore @@ -0,0 +1 @@ +/build/ diff --git a/ScStwStyling/ScStwStyling.pri b/ScStwStyling/ScStwStyling.pri new file mode 100644 index 0000000..f15a69e --- /dev/null +++ b/ScStwStyling/ScStwStyling.pri @@ -0,0 +1,21 @@ +!isEmpty(SCSTWSTYLING_LIB):error("ScStwLibraries.pri already included") +SCSTWSTYLING_LIB = 1 + +#DEPENDS +CONFIG(release, debug|release): { + SCSTWSTYLING_LIB_OUTPUT_DIR="$$PWD/build/release" +} else { + SCSTWSTYLING_LIB_OUTPUT_DIR="$$PWD/build/debug" +} + +unix:LIBS += -L$$SCSTWSTYLING_LIB_OUTPUT_DIR -lScStwStyling + +win32:LIBS += -L$$SCSTWSTYLING_LIB_OUTPUT_DIR -lScStwStyling1 + +android { + ANDROID_EXTRA_LIBS += $$SCSTWSTYLING_LIB_OUTPUT_DIR/libScStwStyling.so +} + +QML_IMPORT_PATH = "$$PWD/resources/qml/lib" +INCLUDEPATH += "$$PWD" +INCLUDEPATH += "$$PWD"/headers diff --git a/ScStwStyling/ScStwStyling.pro b/ScStwStyling/ScStwStyling.pro new file mode 100644 index 0000000..5ccc3de --- /dev/null +++ b/ScStwStyling/ScStwStyling.pro @@ -0,0 +1,42 @@ +QT += gui qml + +TEMPLATE = lib +DEFINES += SCSTWSTYLING_LIBRARY + +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). Please consult the documentation of the +# deprecated API in order 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/scstwapptheme.cpp \ + sources/scstwappthememanager.cpp \ + sources/scstwstyling.cpp + +HEADERS += \ + headers/scstwapptheme.h \ + headers/scstwappthememanager.h \ + headers/scstwstyling.h + +RESOURCES += \ + resources/qml/ScStwStylingQml.qrc \ + resources/shared/ScStwStylingShared.qrc \ + +#DEPENDS +CONFIG(release, debug|release): { + DESTDIR="$$PWD/build/release" +} else { + DESTDIR="$$PWD/build/debug" +} + +# Default rules for deployment. +target.path = $$GLOBAL_TARGET_PATH/lib +!isEmpty(target.path): INSTALLS += target diff --git a/ScStwStyling/headers/scstwapptheme.h b/ScStwStyling/headers/scstwapptheme.h new file mode 100644 index 0000000..d0f7ba7 --- /dev/null +++ b/ScStwStyling/headers/scstwapptheme.h @@ -0,0 +1,43 @@ +#ifndef APPTHEME_H +#define APPTHEME_H + +#include +#include +#include + +class ScStwAppTheme : public QObject +{ + Q_OBJECT + Q_PROPERTY(QVariant colors READ getColors NOTIFY colorsChanged) + Q_PROPERTY(QVariant icons READ getIcons NOTIFY iconsChanged) + Q_PROPERTY(QVariant fonts READ getFonts NOTIFY fontsChanged) + Q_PROPERTY(QVariant images READ getImages NOTIFY imagesChanged) + + +public: + explicit ScStwAppTheme(QString name, QVariantMap colors = {}, QVariantMap icons = {}, QVariantMap fonts = {}, QVariantMap images = {}, QObject *parent = nullptr); + +private: + QString name; + QVariantMap colors; + QVariantMap icons; + QVariantMap fonts; + QVariantMap images; + +signals: + void colorsChanged(); + void iconsChanged(); + void fontsChanged(); + void imagesChanged(); + + +public slots: + QString getName(); + QVariant getColors(); + QVariant getIcons(); + QVariant getFonts(); + QVariant getImages(); +}; + + +#endif // APPTHEME_H diff --git a/ScStwStyling/headers/scstwappthememanager.h b/ScStwStyling/headers/scstwappthememanager.h new file mode 100644 index 0000000..fd74d9a --- /dev/null +++ b/ScStwStyling/headers/scstwappthememanager.h @@ -0,0 +1,33 @@ +#ifndef SCSTWAPPTHEMEMANAGER_H +#define SCSTWAPPTHEMEMANAGER_H + +#include +#include +#include "scstwapptheme.h" + +class ScStwAppThemeManager : public QObject +{ + Q_OBJECT + Q_PROPERTY(ScStwAppTheme* theme READ getTheme NOTIFY themeChanged) + +public: + explicit ScStwAppThemeManager(QObject *parent = nullptr); + +private: + QList themes; + ScStwAppTheme* currentTheme; + + ScStwAppTheme* findThemeByName(QString themeName); + + QString lighter(QString color, double factor); + +signals: + void themeChanged(); + +public slots: + ScStwAppTheme* getTheme(); + Q_INVOKABLE bool setTheme(QString themeName); + +}; + +#endif // SCSTWAPPTHEMEMANAGER_H diff --git a/ScStwStyling/headers/scstwstyling.h b/ScStwStyling/headers/scstwstyling.h new file mode 100644 index 0000000..174bb89 --- /dev/null +++ b/ScStwStyling/headers/scstwstyling.h @@ -0,0 +1,25 @@ +#ifndef SCSTWSTYLING_H +#define SCSTWSTYLING_H + +#include +#include + +#include "scstwapptheme.h" +#include "scstwappthememanager.h" + + +class ScStwStyling : public QObject +{ + Q_OBJECT + +public: + static void init(QQmlApplicationEngine *engine); + +private: + explicit ScStwStyling(QObject *parent = nullptr); + +signals: + +}; + +#endif // SCSTWSTYLING_H diff --git a/ScStwStyling/resources/qml/ScStwStylingQml.qrc b/ScStwStyling/resources/qml/ScStwStylingQml.qrc new file mode 100644 index 0000000..279cc27 --- /dev/null +++ b/ScStwStyling/resources/qml/ScStwStylingQml.qrc @@ -0,0 +1,10 @@ + + + lib/de/itsblue/ScStw/Styling/Components/BusyIndicator.qml + lib/de/itsblue/ScStw/Styling/Components/FadeAnimation.qml + lib/de/itsblue/ScStw/Styling/Components/Icon.qml + lib/de/itsblue/ScStw/Styling/Components/qmldir + lib/de/itsblue/ScStw/Styling/Components/Test.qml + lib/de/itsblue/ScStw/Styling/Components/TimerColumn.qml + + diff --git a/ScStwStyling/resources/qml/lib/de/itsblue/ScStw/Styling/Components/BusyIndicator.qml b/ScStwStyling/resources/qml/lib/de/itsblue/ScStw/Styling/Components/BusyIndicator.qml new file mode 100644 index 0000000..a911dac --- /dev/null +++ b/ScStwStyling/resources/qml/lib/de/itsblue/ScStw/Styling/Components/BusyIndicator.qml @@ -0,0 +1,31 @@ +import QtQuick 2.0 +import QtQuick.Templates 2.0 as T +import QtQuick.Controls 2.0 + +T.BusyIndicator { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + contentItem: Item { + Image { + id: holdImage + anchors.fill: parent + source: "qrc:/images/SpeedHold.png" + fillMode: Image.PreserveAspectFit + } + + RotationAnimation { + target: holdImage + running: control.running + duration: 1000 + loops: Animation.Infinite + from: 0 + to: 360 + easing.type: Easing.InOutQuad + } + } +} diff --git a/ScStwStyling/resources/qml/lib/de/itsblue/ScStw/Styling/Components/FadeAnimation.qml b/ScStwStyling/resources/qml/lib/de/itsblue/ScStw/Styling/Components/FadeAnimation.qml new file mode 100644 index 0000000..df750b1 --- /dev/null +++ b/ScStwStyling/resources/qml/lib/de/itsblue/ScStw/Styling/Components/FadeAnimation.qml @@ -0,0 +1,72 @@ +/* + 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 int fadeDuration: 150 + property int fadeDuration_in: fadeDuration + property int fadeDuration_out: fadeDuration + + property alias outValueScale: outAnimationScale.to + property alias inValueScale: inAnimationScale.to + + property alias outValueOpacity: outAnimationOpacity.to + property alias inValueOpacity: inAnimationOpacity.to + + property string easingType: "Quad" + ParallelAnimation { + NumberAnimation { // in the default case, fade scale to 0 + id: outAnimationScale + target: root.target + property: "scale" + duration: root.fadeDuration_in + to: 0.9 + easing.type: Easing["In"+root.easingType] + } + NumberAnimation { // in the default case, fade scale to 0 + id: outAnimationOpacity + target: root.target + property: "opacity" + 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 + ParallelAnimation { + NumberAnimation { // in the default case, fade scale back to 1 + id: inAnimationScale + target: root.target + property: "scale" + duration: root.fadeDuration_out + to: 1 + easing.type: Easing["Out"+root.easingType] + } + NumberAnimation { // in the default case, fade scale to 0 + id: inAnimationOpacity + target: root.target + property: "opacity" + duration: root.fadeDuration_in + to: 1 + easing.type: Easing["In"+root.easingType] + } + } + +} diff --git a/ScStwStyling/resources/qml/lib/de/itsblue/ScStw/Styling/Components/Icon.qml b/ScStwStyling/resources/qml/lib/de/itsblue/ScStw/Styling/Components/Icon.qml new file mode 100644 index 0000000..7d038c8 --- /dev/null +++ b/ScStwStyling/resources/qml/lib/de/itsblue/ScStw/Styling/Components/Icon.qml @@ -0,0 +1,27 @@ +import QtQuick 2.0 +import QtQuick.Controls 2.0 + +Item { + id: control + + property string fontName + property color color + property string icon: "\uf850" + + Label { + anchors.fill: parent + + text: control.icon + + font.styleName: control.fontName + color: control.color + + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + + fontSizeMode: Text.Fit + font.pixelSize: height + minimumPixelSize: 1 + + } +} diff --git a/ScStwStyling/resources/qml/lib/de/itsblue/ScStw/Styling/Components/Test.qml b/ScStwStyling/resources/qml/lib/de/itsblue/ScStw/Styling/Components/Test.qml new file mode 100644 index 0000000..dc79e1f --- /dev/null +++ b/ScStwStyling/resources/qml/lib/de/itsblue/ScStw/Styling/Components/Test.qml @@ -0,0 +1,5 @@ +import QtQuick 2.12 + +Item { + +} diff --git a/ScStwStyling/resources/qml/lib/de/itsblue/ScStw/Styling/Components/TimerColumn.qml b/ScStwStyling/resources/qml/lib/de/itsblue/ScStw/Styling/Components/TimerColumn.qml new file mode 100644 index 0000000..1170504 --- /dev/null +++ b/ScStwStyling/resources/qml/lib/de/itsblue/ScStw/Styling/Components/TimerColumn.qml @@ -0,0 +1,144 @@ +import QtQuick 2.0 +import QtQuick.Controls 2.0 +import de.itsblue.ScStw 2.0 +import de.itsblue.ScStwMonitor 2.0 + +Column { + id: control + + property var timers + property var colors + property var fontName + + opacity: backend.scStwClient.state === ScStwClient.CONNECTED ? 1:0 + + spacing: 0 + + Repeater { + id: timerRep + + property var clearedTimers: removeDisabledTimers(control.timers) + + function removeDisabledTimers(timers) { + var ret = [] + for(var i = 0; i < timers.length; i++) { + if(timers[i]["state"] !== ScStwTimer.DISABLED) + ret.push(timers[i]) + } + return ret + } + + model: clearedTimers.length + + delegate: Item { + id: timerDel + + width: parent.width + height: control.height / timerRep.model + + Label { + id: laneNameLa + + anchors { + left: parent.left + } + + leftPadding: parent.width * 0.03 + + width: parent.width * 0.15 + height: parent.height * 0.5 + + fontSizeMode: Text.Fit + + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignLeft + + text: ""//index === 0 ? "A":"B" + + color: control.colors.text + + font.pixelSize: height + font.styleName: control.fontName + } + + Label { + id: timerTextLa + + anchors.centerIn: parent + anchors.horizontalCenterOffset: laneNameLa.text !== "" ? parent.width * 0.06:0 + anchors.verticalCenterOffset: -(parent.height * 0.04 * reactTimeLa.opacity) + + width: parent.width * 0.8 + height: parent.height * 0.8 + + elide: "ElideRight" + color: ([ScStwTimer.WON].indexOf(timerRep.clearedTimers[index]["state"]) >= 0 ? control.colors.success : + [ScStwTimer.FAILED,ScStwTimer.LOST].indexOf(timerRep.clearedTimers[index]["state"]) >= 0 ? control.colors.error: + control.colors.text) + + text: timerRep.clearedTimers[index]["text"] + + fontSizeMode: Text.Fit + + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + + font.pixelSize: height + font.styleName: control.fontName + minimumPixelSize: 1 + } + + Label { + id: reactTimeLa + + property int rtime: timerRep.clearedTimers[index]["reactionTime"] + + anchors { + centerIn: parent + verticalCenterOffset: timerTextLa.contentHeight * 0.4 + reactTimeLa.contentHeight * 0.4 + timerTextLa.anchors.verticalCenterOffset + horizontalCenterOffset: parent.width * 0.06 + } + + width: parent.width * 0.6 + height: parent.height * 0.15 + + scale: enabled ? 1:0.9 + opacity: enabled ? 1:0 + + enabled: timerRep.clearedTimers[index]["state"] >= ScStwTimer.STARTING && rtime !== 0 + + fontSizeMode: Text.Fit + + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + + text: "reaction time (ms): " + Math.round(rtime) + + color: control.colors.text + + font.pixelSize: timerTextLa.font.pixelSize * 0.5 + font.styleName: control.fontName + minimumPixelSize: 1 + + Behavior on opacity { + NumberAnimation { + duration: 200 + } + } + + Behavior on scale { + NumberAnimation { + duration: 200 + } + } + + } + } + } + + Behavior on opacity { + NumberAnimation { + duration: 200 + } + } +} diff --git a/ScStwStyling/resources/qml/lib/de/itsblue/ScStw/Styling/Components/qmldir b/ScStwStyling/resources/qml/lib/de/itsblue/ScStw/Styling/Components/qmldir new file mode 100644 index 0000000..64f7890 --- /dev/null +++ b/ScStwStyling/resources/qml/lib/de/itsblue/ScStw/Styling/Components/qmldir @@ -0,0 +1,5 @@ +module de.itsblue.ScStw.Styling.Components +BusyIndicator 1.0 BusyIndicator.qml +Icon 1.0 Icon.qml +TimerColumn 1.0 TimerColumn.qml +FadeAnimation 1.0 FadeAnimation.qml diff --git a/ScStwStyling/resources/shared/ScStwStylingShared.qrc b/ScStwStyling/resources/shared/ScStwStylingShared.qrc new file mode 100644 index 0000000..875e9cb --- /dev/null +++ b/ScStwStyling/resources/shared/ScStwStylingShared.qrc @@ -0,0 +1,9 @@ + + + fonts/fa5solid.woff + images/BaseStationBlack.png + images/BaseStationWhite.png + images/SpeedHold.png + fonts/PTMono-Regular.ttf + + diff --git a/ScStwStyling/resources/shared/fonts/PTMono-Regular.ttf b/ScStwStyling/resources/shared/fonts/PTMono-Regular.ttf new file mode 100644 index 0000000..13a8004 Binary files /dev/null and b/ScStwStyling/resources/shared/fonts/PTMono-Regular.ttf differ diff --git a/ScStwStyling/resources/shared/fonts/fa5brands.woff b/ScStwStyling/resources/shared/fonts/fa5brands.woff new file mode 100644 index 0000000..2a89d52 Binary files /dev/null and b/ScStwStyling/resources/shared/fonts/fa5brands.woff differ diff --git a/ScStwStyling/resources/shared/fonts/fa5regular.woff b/ScStwStyling/resources/shared/fonts/fa5regular.woff new file mode 100644 index 0000000..24de566 Binary files /dev/null and b/ScStwStyling/resources/shared/fonts/fa5regular.woff differ diff --git a/ScStwStyling/resources/shared/fonts/fa5solid.woff b/ScStwStyling/resources/shared/fonts/fa5solid.woff new file mode 100644 index 0000000..beec791 Binary files /dev/null and b/ScStwStyling/resources/shared/fonts/fa5solid.woff differ diff --git a/ScStwStyling/resources/shared/images/BaseStationBlack.png b/ScStwStyling/resources/shared/images/BaseStationBlack.png new file mode 100644 index 0000000..333340f Binary files /dev/null and b/ScStwStyling/resources/shared/images/BaseStationBlack.png differ diff --git a/ScStwStyling/resources/shared/images/BaseStationWhite.png b/ScStwStyling/resources/shared/images/BaseStationWhite.png new file mode 100644 index 0000000..aea2a4d Binary files /dev/null and b/ScStwStyling/resources/shared/images/BaseStationWhite.png differ diff --git a/ScStwStyling/resources/shared/images/SpeedHold.png b/ScStwStyling/resources/shared/images/SpeedHold.png new file mode 100644 index 0000000..87738b4 Binary files /dev/null and b/ScStwStyling/resources/shared/images/SpeedHold.png differ diff --git a/ScStwStyling/sources/scstwapptheme.cpp b/ScStwStyling/sources/scstwapptheme.cpp new file mode 100644 index 0000000..cb9a770 --- /dev/null +++ b/ScStwStyling/sources/scstwapptheme.cpp @@ -0,0 +1,27 @@ +#include "headers/scstwapptheme.h" + +ScStwAppTheme::ScStwAppTheme(QString name, QVariantMap colors, QVariantMap icons, QVariantMap fonts, QVariantMap images, QObject *parent) : QObject(parent) +{ + this->name = name; + this->colors = colors; + this->icons = icons; + this->fonts = fonts; + this->images = images; +} + +QString ScStwAppTheme::getName() { + return this->name; +} + +QVariant ScStwAppTheme::getColors() { + return this->colors; +} +QVariant ScStwAppTheme::getIcons() { + return this->icons; +} +QVariant ScStwAppTheme::getFonts() { + return this->fonts; +} +QVariant ScStwAppTheme::getImages() { + return this->images; +} diff --git a/ScStwStyling/sources/scstwappthememanager.cpp b/ScStwStyling/sources/scstwappthememanager.cpp new file mode 100644 index 0000000..c6d18e9 --- /dev/null +++ b/ScStwStyling/sources/scstwappthememanager.cpp @@ -0,0 +1,156 @@ +#include "../headers/scstwappthememanager.h" + +ScStwAppThemeManager::ScStwAppThemeManager(QObject *parent) : QObject(parent) +{ + QFontDatabase::addApplicationFont(":/fonts/fa5solid.woff"); + QFontDatabase::addApplicationFont(":/fonts/PTMono-Regular.ttf"); + + QVariantMap icons = { + {"back", "\uf053"}, + {"settings", "\uf013"}, + {"toppad", "\uf10a"}, + {"startpad", "\uf3fa"}, + {"profiles", "\uf007"}, + {"confirm", "\uf00c"}, + {"volumeUp", "\uf028"}, + {"volumeDown", "\uf027"} + }; + + QVariantMap fonts= { + {"icons", "Font Awesome 5 Free"}, + {"timers", "PT Mono"} + }; + + ScStwAppTheme * lightTheme = new ScStwAppTheme ( + "Light", + { + {"accent", "#0094ff"}, + {"background", "white"}, + + {"button", "white"}, + {"buttonPressed", "lightgrey"}, + {"buttonBorder", "grey"}, + {"disabledButton", "#d5d5d5"}, + {"buttonText", "grey"}, + {"buttonPressedText",this->lighter("lightgrey", 0.5)}, + {"buttonDisabledText", this->lighter("lightgrey", 0.9)}, + + {"view", "white"}, + {"menu", "#f8f8f8"}, + + {"delegate1", "#202227"}, + {"delegate2", "#202227"}, + {"delegateBackground", "white"}, + {"delegatePressed", "#dddedf"}, + + {"text", "black"}, + {"textDark", "#232323"}, + {"disabledText", "grey"}, + + {"slider", "#6ccaf2"}, + + {"success", "#60de26"}, + {"error", "#ff0000"}, + {"warning", "#e0b928"}, + + {"line", "grey"}, + }, + icons, + fonts, + { + {"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:/images/BaseStationBlack.png"}, + {"profilesIcon", "qrc:/graphics/icons/user_black.png"}, + {"confirmIcon", "qrc:/graphics/icons/ok_black.png"} + }); + + ScStwAppTheme *darkTheme = new ScStwAppTheme( + "Dark", + { + {"accent", "#0094ff"}, + {"background", "#2d3037"}, + + {"button", "#202227"}, + {"buttonPressed", "#41454f"}, + {"buttonBorder", "grey"}, + {"disabledButton", "#555555"}, + {"buttonText", "white"}, + {"buttonPressedText",this->lighter("lightgrey", 0.8)}, + {"buttonDisabledText", this->lighter("lightgrey", 0.6)}, + + {"view", "#202227"}, + {"menu", "#292b32"}, + + {"delegate1", "#202227"}, + {"delegate2", "#202227"}, + {"delegateBackground", "#202227"}, + {"delegatePressed", "#41454f"}, + + {"text", "#ffffff"}, + {"textDark", "#232323"}, + {"disabledText", "#777777"}, + + {"slider", "#6ccaf2"}, + + {"success", "#6bd43b"}, + {"error", "#e03b2f"}, + {"warning", "#e0b928"}, + + {"line", "grey"}, + + {"iconFontName", "Font Awesome 5 Free"}, + }, + icons, + fonts, + { + {"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:/images/BaseStationWhite.png"}, + {"profilesIcon", "qrc:/graphics/icons/user.png"}, + {"confirmIcon", "qrc:/graphics/icons/ok.png"} + } + ); + + this->themes.append(lightTheme); + this->themes.append(darkTheme); + this->currentTheme = this->themes[0]; +} + +ScStwAppTheme* ScStwAppThemeManager::getTheme() { + return this->currentTheme; +} + +bool ScStwAppThemeManager::setTheme(QString themeName) { + ScStwAppTheme * foundTheme = this->findThemeByName(themeName); + + if(foundTheme == nullptr) + return false; + + this->currentTheme = foundTheme; + emit this->themeChanged(); + + return true; +} + +ScStwAppTheme * ScStwAppThemeManager::findThemeByName(QString themeName) { + foreach (ScStwAppTheme *theme, this->themes) { + if(theme->getName() == themeName) + return theme; + } + + return nullptr; +} + +QString ScStwAppThemeManager::lighter(QString color, double factor) { + QColor qcolor = QColor(color); + qcolor.toHsv(); + int h, s, v; + qcolor.getHsv(&h, &s, &v); + qcolor.setHsv(h,s,v * factor); + return qcolor.name(); +} diff --git a/ScStwStyling/sources/scstwstyling.cpp b/ScStwStyling/sources/scstwstyling.cpp new file mode 100644 index 0000000..f996d09 --- /dev/null +++ b/ScStwStyling/sources/scstwstyling.cpp @@ -0,0 +1,12 @@ +#include "../headers/scstwstyling.h" + +ScStwStyling::ScStwStyling(QObject *parent) : QObject(parent) +{ + +} + +void ScStwStyling::init(QQmlApplicationEngine *engine) { + qmlRegisterUncreatableType("de.itsblue.ScStw.Styling", 2, 0, "ScStwAppTheme", "The ScStwAppTheme has to be managed by a ScStwAppTheme manager and is therefore not creatable"); + qmlRegisterType("de.itsblue.ScStw.Styling", 2, 0, "ScStwAppThemeManager"); + engine->addImportPath(":/lib"); +} diff --git a/favicon.png b/favicon.png index 0b3888c..f89826e 100644 Binary files a/favicon.png and b/favicon.png differ diff --git a/favicon.xcf b/favicon.xcf index 06d097f..a2c5522 100644 Binary files a/favicon.xcf and b/favicon.xcf differ diff --git a/faviconNoOutline.png b/faviconNoOutline.png index ad6a158..bce4e96 100644 Binary files a/faviconNoOutline.png and b/faviconNoOutline.png differ