2018-08-12 20:51:57 +02:00
/ *
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 < https: //www.gnu.org/licenses/>.
* /
2018-07-17 19:17:25 +02:00
import QtQuick 2.9
import QtMultimedia 5.8
import QtQuick . Window 2.2
import QtQuick . Controls 2.2
2019-03-08 15:36:32 +01:00
import QtGraphicalEffects 1.0
2018-08-28 23:03:35 +02:00
import "."
import "./components"
2019-06-08 11:14:18 +02:00
import "./ProfilesDialog"
2019-10-18 16:10:41 +02:00
import "./SettingsDialog"
2018-07-22 21:08:11 +02:00
//import QtQuick.Layouts 1.11
2018-07-22 16:47:55 +02:00
2019-03-07 17:18:24 +01:00
import com . itsblue . speedclimbingstopwatch 2.0
2018-07-17 19:17:25 +02:00
Window {
visible: true
width: 540
height: 960
2019-09-08 15:08:50 +02:00
title: "Speedclimbing stw"
2018-07-17 19:17:25 +02:00
property date currentTime: new Date ( )
property int millis: 0
Page {
2019-09-08 15:08:50 +02:00
id:app
2018-07-17 19:17:25 +02:00
anchors.fill: parent
2018-08-14 17:07:42 +02:00
//set default state to IDLE
2018-07-22 16:47:55 +02:00
state: "IDLE"
2018-08-28 23:03:35 +02:00
Rectangle {
id: backgroundRect
anchors.fill: parent
2019-03-08 18:03:27 +01:00
color: appTheme . style . backgroundColor
2019-03-24 21:31:59 +01:00
Behavior on color {
ColorAnimation {
duration: 200
}
}
2018-07-25 00:32:20 +02:00
}
2020-04-17 19:57:33 +02:00
ScStw {
id: scStw
}
2019-03-07 17:18:24 +01:00
SpeedBackend {
id: speedBackend
2020-04-15 21:47:55 +02:00
}
2019-03-07 17:18:24 +01:00
2020-04-15 21:47:55 +02:00
Connections {
target: speedBackend . race
2019-03-07 17:18:24 +01:00
onStateChanged: {
var stateString
2020-04-19 13:09:46 +02:00
console . log ( "race state changed to: " + speedBackend . race . state )
switch ( speedBackend . race . state ) {
2020-04-17 19:57:33 +02:00
case ScStwRace.IDLE:
2019-03-07 17:18:24 +01:00
stateString = "IDLE"
break ;
2020-04-17 19:57:33 +02:00
case ScStwRace.STARTING:
2019-03-07 17:18:24 +01:00
stateString = "STARTING"
2019-03-08 15:36:32 +01:00
settingsDialog . close ( )
2019-08-20 22:55:37 +02:00
profilesDialog . close ( )
2019-03-07 17:18:24 +01:00
break ;
2020-04-17 19:57:33 +02:00
case ScStwRace.WAITING:
2019-04-15 13:33:31 +02:00
stateString = "WAITING"
2019-03-08 15:36:32 +01:00
settingsDialog . close ( )
2019-08-20 22:55:37 +02:00
profilesDialog . close ( )
2019-03-07 17:18:24 +01:00
break ;
2020-04-17 19:57:33 +02:00
case ScStwRace.RUNNING:
2019-04-15 13:33:31 +02:00
stateString = "RUNNING"
settingsDialog . close ( )
2019-08-20 22:55:37 +02:00
profilesDialog . close ( )
2019-04-15 13:33:31 +02:00
break ;
2020-04-17 19:57:33 +02:00
case ScStwRace.STOPPED:
2019-03-07 17:18:24 +01:00
stateString = "STOPPED"
2019-03-08 15:36:32 +01:00
settingsDialog . close ( )
2019-08-20 22:55:37 +02:00
profilesDialog . close ( )
2019-03-07 17:18:24 +01:00
}
2019-09-08 15:08:50 +02:00
app . state = stateString
2018-10-04 18:35:29 +02:00
}
2018-08-28 23:03:35 +02:00
}
2019-03-08 18:03:27 +01:00
AppTheme {
id: appTheme
2020-05-18 11:28:48 +02:00
Component.onCompleted: {
appTheme . setTheme ( speedBackend . readSetting ( "theme" ) )
}
2019-03-08 18:03:27 +01:00
}
2018-07-22 16:47:55 +02:00
/ * - - - - - - - - - - - - - - - - - - - - - - - -
Timer text an upper line
-- -- -- -- -- -- -- -- -- -- -- -- * /
2019-03-08 15:36:32 +01:00
RectangularGlow {
id: effect_2
glowRadius: 7
spread: 0.02
color: "black"
opacity: 0.18
2019-04-15 13:33:31 +02:00
anchors.fill: topContainerItm
2019-03-08 15:36:32 +01:00
scale: 1
}
2018-07-17 19:17:25 +02:00
Item {
2019-04-15 13:33:31 +02:00
id: topContainerItm
2018-07-17 19:17:25 +02:00
anchors {
top: parent . top
left: parent . left
2019-09-08 15:08:50 +02:00
right: app . landscape ( ) ? startButt.left: parent . right
bottom: app . landscape ( ) ? parent.bottom: startButt . top
bottomMargin: app . landscape ( ) ? undefined: parent . height * 0.1
rightMargin: app . landscape ( ) ? parent . width * 0.05 : 0
2018-07-17 19:17:25 +02:00
}
2018-08-28 23:03:35 +02:00
Rectangle {
anchors.fill: parent
2019-03-08 18:03:27 +01:00
color: appTheme . style . menuColor
2019-03-24 21:31:59 +01:00
Behavior on color {
ColorAnimation {
duration: 200
}
}
2018-08-28 23:03:35 +02:00
}
2019-04-15 13:33:31 +02:00
Text {
id: topLa
2019-10-13 16:42:38 +02:00
property string implicitText: ""
2018-07-17 19:17:25 +02:00
anchors.centerIn: parent
2019-04-15 13:33:31 +02:00
2020-04-17 19:57:33 +02:00
opacity: ( speedBackend . race . state < ScStwRace . RUNNING ) ? 1 : 0
2019-04-15 13:33:31 +02:00
2019-04-27 22:50:22 +02:00
width: parent . width * 0.7
2019-10-13 16:42:38 +02:00
height: parent . height * 0.7
2019-04-15 13:33:31 +02:00
2020-04-17 19:57:33 +02:00
text: implicitText === "NEXT_START_ACTION" ?
[ "" , "at your \nmarks" , "ready" , "starting..." ] [ speedBackend . race . nextStartActionDetails [ ScStwRace . NextStartAction ] + 1 ] : implicitText
2019-04-15 13:33:31 +02:00
2019-03-08 18:03:27 +01:00
color: appTheme . style . textColor
2018-10-04 18:35:29 +02:00
2019-04-15 13:33:31 +02:00
fontSizeMode: Text . Fit
verticalAlignment: Text . AlignVCenter
horizontalAlignment: Text . AlignHCenter
2019-09-08 15:08:50 +02:00
font.pixelSize: app . landscape ( ) ? parent . width * 0.15 : parent . height * 0.4
2018-10-14 18:39:39 +02:00
2019-06-15 14:38:33 +02:00
minimumPixelSize: 1
2018-10-04 18:35:29 +02:00
2019-03-07 17:18:24 +01:00
Behavior on text {
2019-04-15 13:33:31 +02:00
FadeAnimation {
target: topLa
2019-05-02 22:39:22 +02:00
fadeDuration: 100
2018-08-14 17:07:42 +02:00
}
}
2018-07-17 19:17:25 +02:00
}
2018-08-29 18:33:39 +02:00
2019-04-15 13:33:31 +02:00
Column {
id: timerCol
anchors.fill: parent
2019-09-08 15:08:50 +02:00
anchors.bottomMargin: app . landscape ( ) ? 0 : parent . height * 0.1
2019-04-15 13:33:31 +02:00
2020-04-17 19:57:33 +02:00
opacity: ( speedBackend . race . state < ScStwRace . RUNNING ) ? 0 : 1
2019-04-15 13:33:31 +02:00
spacing: height * 0.05
Repeater {
id: timerRep
2020-04-17 19:57:33 +02:00
model: speedBackend . race . timers . length
2019-04-15 13:33:31 +02:00
delegate: Item {
id: timerDel
width: parent . width
height: timerRep . model > 1 ? ( timerCol . height * 0.9 ) / timerRep.model: timerCol . height
Label {
id: timerTextLa
anchors.centerIn: parent
width: ( parent . width * 0.8 )
height: parent . height
elide: "ElideRight"
2020-04-19 13:09:46 +02:00
color: [ ScStwTimer . WON ] . includes ( speedBackend . race . timers [ index ] [ "state" ] ) ? appTheme.style.successColor :
[ ScStwTimer . LOST , ScStwTimer . FAILED ] . includes ( speedBackend . race . timers [ index ] [ "state" ] ) ? appTheme.style.errorColor:
2019-10-13 16:42:38 +02:00
appTheme . style . textColor
2019-09-08 00:50:03 +02:00
2020-04-17 19:57:33 +02:00
enabled: speedBackend . race . timers [ index ] [ "state" ] !== ScStwTimer . DISABLED
2019-04-15 13:33:31 +02:00
2020-04-17 19:57:33 +02:00
text: speedBackend . race . timers [ index ] [ "text" ]
2019-04-15 13:33:31 +02:00
fontSizeMode: Text . Fit
verticalAlignment: Text . AlignVCenter
horizontalAlignment: Text . AlignHCenter
2019-09-08 15:08:50 +02:00
font.pixelSize: app . landscape ( ) ? parent . width * 0.15 : parent . height * 0.4
2019-04-15 13:33:31 +02:00
2019-06-15 14:38:33 +02:00
minimumPixelSize: 1
2019-04-15 13:33:31 +02:00
2019-09-22 16:07:41 +02:00
/ * B e h a v i o r o n t e x t {
enabled: ! [ "RUNNING" , "STOPPED" , "WON" , "LOST" , "FAILED" , "CANCELLED" ] . includes ( app . state )
2019-04-15 13:33:31 +02:00
FadeAnimation {
target: timerTextLa
}
2019-09-22 16:07:41 +02:00
} * /
2019-04-15 13:33:31 +02:00
}
Label {
id: react_time
2020-04-17 19:57:33 +02:00
property int rtime: speedBackend . race . timers [ index ] [ "reactionTime" ]
2019-04-15 13:33:31 +02:00
anchors {
centerIn: parent
2019-09-08 15:08:50 +02:00
verticalCenterOffset: timerTextLa . font . pixelSize * 0.5 + react_time . font . pixelSize * 0.5
2019-04-15 13:33:31 +02:00
}
width: ( parent . width * 0.6 )
height: parent . height
fontSizeMode: Text . Fit
verticalAlignment: Text . AlignVCenter
horizontalAlignment: Text . AlignHCenter
2019-09-08 15:08:50 +02:00
text: "reaction time (ms): " + Math . round ( rtime )
2019-04-15 13:33:31 +02:00
2019-09-08 15:08:50 +02:00
opacity: ( app . state === "RUNNING" || app . state === "STOPPED" ) && rtime !== 0 ? 1 : 0
2019-04-15 13:33:31 +02:00
color: appTheme . style . textColor
font.pixelSize: timerTextLa . font . pixelSize * 0.5
}
}
}
Behavior on opacity {
NumberAnimation {
duration: 200
}
}
}
Behavior on opacity {
NumberAnimation {
duration: 200
2018-08-29 18:33:39 +02:00
}
}
2018-08-02 12:50:55 +02:00
}
2019-03-24 21:16:16 +01:00
Item {
id: connectionIconContainer
anchors {
top: p arent . top
left: parent . left
right: parent . right
bottom: parent . bottom
2019-09-08 15:08:50 +02:00
bottomMargin: app . landscape ( ) ? 0 : parent . height * 0.8
rightMargin: app . landscape ( ) ? parent . width * 0.8 : 0
2019-03-24 21:16:16 +01:00
}
ConnectionIcon {
id: baseConnConnIcon
2020-04-19 13:09:46 +02:00
function clientStateToString ( state ) {
switch ( state ) {
case ScStwClient.DISCONNECTED:
return "disconnected"
case ScStwClient.CONNECTING:
return "connecting"
case ScStwClient.INITIALISING:
return "connecting"
case ScStwClient.CONNECTED:
return "connected"
}
}
status: clientStateToString ( speedBackend . scStwClient . state )
2019-03-24 21:16:16 +01:00
2019-03-24 21:31:59 +01:00
source: appTheme . style . baseStationIcon
2019-03-24 21:16:16 +01:00
anchors {
top: parent . top
topMargin: 10
left: parent . left
leftMargin: 10
}
scale: 1.3
2019-09-08 15:08:50 +02:00
height: ! app . landscape ( ) ? parent . height * 0.3 : parent . width * 0.3
2019-03-24 21:16:16 +01:00
}
2019-03-27 22:26:45 +01:00
Row {
id: connectedExtensionsRow
2019-03-24 21:16:16 +01:00
anchors {
top: parent . top
topMargin: 10
left: baseConnConnIcon . right
leftMargin: 1
}
2019-03-27 22:26:45 +01:00
height: parent . height
width: parent . width
Repeater {
id: connectedExtensionsRep
anchors.fill: parent
2020-05-17 21:53:29 +02:00
model: speedBackend . scStwClient . extensions . length
2019-03-27 22:26:45 +01:00
delegate: ConnectionIcon {
id: buzzerConnIcon
2020-05-17 21:53:29 +02:00
status: speedBackend . scStwClient . extensions [ index ] [ "state" ]
2019-03-27 22:26:45 +01:00
source: {
var source
2020-05-17 21:53:29 +02:00
switch ( speedBackend . scStwClient . extensions [ index ] [ "type" ] ) {
2019-03-27 22:26:45 +01:00
case "STARTPAD" :
source = appTheme . style . startpadIcon
break
case "TOPPAD" :
source = appTheme . style . buzzerIcon
break
}
}
2019-03-29 23:42:56 +01:00
scale: 0
2019-09-08 15:08:50 +02:00
height: ! app . landscape ( ) ? parent . height * 0.17 : parent . width * 0.17
2019-04-08 18:03:23 +02:00
width: status === "disconnected" ? 0 : height
2019-03-29 23:42:56 +01:00
Component.onCompleted: {
scale = 1
}
Behavior on scale {
NumberAnimation {
duration: 200
}
}
2019-04-08 18:03:23 +02:00
Behavior on width {
NumberAnimation {
duration: 200
}
}
2019-03-27 22:26:45 +01:00
}
2019-03-24 21:16:16 +01:00
}
}
}
2018-08-02 12:50:55 +02:00
Rectangle {
id: upper_line
2019-09-08 15:08:50 +02:00
width: app . landscape ( ) ? 1 : parent . width
height: app . landscape ( ) ? parent.height: 1
2019-03-08 18:03:27 +01:00
color: appTheme . style . lineColor
2019-09-08 15:08:50 +02:00
anchors.left: app . landscape ( ) ? topContainerItm.right: parent . left
anchors.top: app . landscape ( ) ? parent.top: topContainerItm . bottom
anchors.bottom: app . landscape ( ) ? parent.bottom: undefined
2019-03-08 15:36:32 +01:00
visible: false
2018-07-17 19:17:25 +02:00
}
2019-03-29 23:42:56 +01:00
// ----------------------------------
// -- Start / Stop / Reset button ---
// ----------------------------------
2019-10-02 19:12:06 +02:00
DelayButton {
2018-07-25 00:32:20 +02:00
id : startButt
2018-07-17 19:17:25 +02:00
2019-09-08 15:08:50 +02:00
text: "start"
property int size: app . landscape ( ) ? parent . width * 0.5 : parent . height * 0.5
2019-10-02 19:12:06 +02:00
property color backgroundColor: appTheme . style . buttonColor
2020-04-19 13:09:46 +02:00
property bool progressControlActivated: speedBackend . scStwClient . state === ScStwClient . CONNECTED && app . state === "RUNNING"
2019-10-02 19:12:06 +02:00
delay: progressControlActivated ? 2000 : 0
2018-07-17 19:17:25 +02:00
anchors {
bottom: parent . bottom
2019-09-08 15:08:50 +02:00
bottomMargin: app . height * 0.5 - height * 0.5
2018-07-22 16:47:55 +02:00
right: parent . right
2019-09-08 15:08:50 +02:00
rightMargin: app . width * 0.5 - width * 0.5
2018-07-25 00:32:20 +02:00
}
2019-10-02 19:12:06 +02:00
2019-09-08 15:08:50 +02:00
height: app . landscape ( ) ? ( size > parent . height * 0.9 ? parent . height * 0.9 : size ) : ( size > parent . width * 0.9 ? parent . width * 0.9 : size )
2019-03-27 22:26:45 +01:00
width: height
2018-07-17 19:17:25 +02:00
2019-03-08 15:36:32 +01:00
Label {
id: startButt_text
text: startButt . text
anchors.centerIn: parent
font.pixelSize: parent . height * 0.16
font.family: "Helvetica"
2019-03-08 18:03:27 +01:00
color: enabled ? appTheme.style.textColor: appTheme . style . disabledTextColor
2018-07-17 19:17:25 +02:00
}
2018-07-22 16:47:55 +02:00
2018-08-14 17:07:42 +02:00
Behavior on text {
//animate a text change
enabled: true
FadeAnimation {
target: startButt_text
}
}
2018-07-25 00:32:20 +02:00
onClicked: {
2019-10-02 19:12:06 +02:00
if ( startButt . progressControlActivated && progress < 1.0 )
return
startButt . progress = 0
2019-09-08 15:08:50 +02:00
switch ( app . state ) {
2018-07-25 00:32:20 +02:00
case "IDLE" :
2019-09-08 15:08:50 +02:00
app . start ( )
2018-07-25 00:32:20 +02:00
break
case "RUNNING" :
2020-04-17 19:57:33 +02:00
app . stop ( )
2018-07-25 00:32:20 +02:00
break
case "STOPPED" :
2019-09-08 15:08:50 +02:00
app . reset ( )
2018-07-25 00:32:20 +02:00
break
2018-07-22 16:47:55 +02:00
}
}
2019-10-02 19:12:06 +02:00
contentItem: Text {
}
background: Item {
RectangularGlow {
glowRadius: 0.001
spread: 0.2
color: "black"
visible: true
cornerRadius: startButtBackground . radius
anchors.fill: startButtBackground
scale: 0.75
2019-11-02 15:22:50 +01:00
opacity: Math . pow ( startButt . opacity , 100 )
2019-10-02 19:12:06 +02:00
}
Rectangle {
id: startButtBackground
implicitWidth: 100
implicitHeight: 100
color: startButt . down ? Qt . darker ( startButt . backgroundColor , 1.2 ) : startButt . backgroundColor
radius: size / 2
readonly property real size: Math . min ( startButt . width , startButt . height )
width: size
height: size
anchors.fill: parent
Behavior on color {
ColorAnimation {
duration: 200
}
}
Canvas {
id: canvas
anchors.fill: parent
visible: startButt . progressControlActivated
Connections {
target: startButt
onProgressChanged: canvas . requestPaint ( )
}
onPaint: {
var ctx = getContext ( "2d" )
ctx . clearRect ( 0 , 0 , width , height )
ctx . strokeStyle = "grey"
ctx . lineWidth = parent . width * 0.02
ctx . beginPath ( )
var startAngle = Math . PI * 0.5
var endAngle = startAngle + startButt . progress * Math . PI * 2
ctx . arc ( width / 2 , height / 2 , width / 2 - ctx . lineWidth / 2 - 2 , startAngle , endAngle )
ctx . stroke ( )
}
}
}
} }
2018-07-28 21:17:41 +02:00
ProgressCircle {
id: prog
2020-04-17 19:57:33 +02:00
property double progress: speedBackend . race . nextStartActionDetails [ ScStwRace . NextStartActionDelayProgress ]
2018-07-28 21:17:41 +02:00
anchors.fill: startButt
2019-11-03 13:00:42 +01:00
opacity: app . state === "STARTING" ? 1 : 0
2019-03-07 17:18:24 +01:00
2019-03-08 15:36:32 +01:00
scale: startButt . scale
2019-10-02 19:12:06 +02:00
lineWidth: prog . width * 0.02
2019-03-07 17:18:24 +01:00
2018-07-28 21:17:41 +02:00
arcBegin: 0
2020-04-17 19:57:33 +02:00
arcEnd: 360 * ( 1 - ( progress > 0 ? progress: 1 ) )
2018-07-28 21:17:41 +02:00
2019-03-07 17:18:24 +01:00
colorCircle: "grey"
2018-07-28 21:17:41 +02:00
2019-03-07 17:18:24 +01:00
Behavior on opacity {
NumberAnimation {
duration: 200
2018-07-28 21:17:41 +02:00
}
}
2019-03-07 17:18:24 +01:00
2019-10-13 16:42:38 +02:00
animationDuration: 0
2018-07-22 16:47:55 +02:00
}
/ * - - - - - - - - - - - - - - - - - - - - - -
Cancel button
-- -- -- -- -- -- -- -- -- -- -- * /
2019-03-08 15:36:32 +01:00
FancyButton {
2018-07-22 16:47:55 +02:00
id: cancelButt
2019-09-08 15:08:50 +02:00
text: "cancel"
2018-07-22 16:47:55 +02:00
anchors {
right: startButt . right
bottom: startButt . bottom
}
2018-07-25 00:32:20 +02:00
contentItem: Text {
//make text disappear
}
2018-07-22 16:47:55 +02:00
height: startButt . height * 0.3
scale: 0
width: height
2019-09-08 15:08:50 +02:00
enabled: app . state === "STARTING"
2018-07-22 16:47:55 +02:00
2018-07-25 00:32:20 +02:00
onClicked: {
2020-04-17 19:57:33 +02:00
app . cancel ( )
2018-07-25 00:32:20 +02:00
}
2018-07-22 16:47:55 +02:00
Behavior on scale {
PropertyAnimation {
duration: 200
}
}
2019-03-08 15:36:32 +01:00
Label {
id: cancelButt_text
text: cancelButt . text
anchors.centerIn: parent
font.pixelSize: parent . height * 0.16
font.family: "Helvetica"
2019-03-08 18:03:27 +01:00
color: appTheme . style . textColor
2018-07-25 00:32:20 +02:00
}
2019-03-08 15:36:32 +01:00
2019-03-08 18:03:27 +01:00
backgroundColor: appTheme . style . buttonColor
2018-07-25 00:32:20 +02:00
}
/ * - - - - - -
Popups
-- -- -- * /
SettingsDialog {
2018-08-02 12:50:55 +02:00
id: settingsDialog
2019-08-19 15:14:11 +02:00
x: startButt . x
y: startButt . y
width: startButt . width
height: startButt . height
2018-07-22 16:47:55 +02:00
}
2019-04-30 23:44:04 +02:00
ProfilesDialog {
id: profilesDialog
2019-09-08 15:08:50 +02:00
property int margin: app . landscape ( ) ? app . height * 0.05 : app . width * 0.05
2019-04-30 23:44:04 +02:00
2019-09-08 15:08:50 +02:00
x: app . landscape ( ) ? topContainerItm . width + margin: topContainerItm . x + margin
y: ! app . landscape ( ) ? topContainerItm . height + margin: topContainerItm . x + margin
width: app . landscape ( ) ? app . width - topContainerItm . width - menu_container . width - margin * 2 : app . width - margin * 2
height: ! app . landscape ( ) ? app . height - topContainerItm . height - menu_container . height - margin * 2 : app . height - margin * 2
2019-04-30 23:44:04 +02:00
}
2018-07-25 00:32:20 +02:00
2018-07-22 16:47:55 +02:00
/ * - - - - - - - - - - - - - - - - - - -
lower line and menu
-- -- -- -- -- -- -- -- -- - * /
2019-03-08 15:36:32 +01:00
2018-07-22 16:47:55 +02:00
Rectangle {
2019-03-08 15:36:32 +01:00
id: lowerLine
2019-09-08 15:08:50 +02:00
width: app . landscape ( ) ? 1 : parent . width
height: app . landscape ( ) ? parent.height: 1
2019-03-08 18:03:27 +01:00
color: appTheme . style . lineColor
2019-09-08 15:08:50 +02:00
anchors.right: app . landscape ( ) ? menu_container.left: parent . right
anchors.bottom: app . landscape ( ) ? parent.bottom: menu_container . top
anchors.top: app . landscape ( ) ? parent.top: undefined
2019-03-08 15:36:32 +01:00
visible: false
}
RectangularGlow {
id: effect
glowRadius: 7
spread: 0.02
color: "black"
opacity: 0.18
anchors.fill: menu_container
scale: 1
2018-07-22 16:47:55 +02:00
}
Item {
id: menu_container
2019-04-30 23:44:04 +02:00
2018-07-22 16:47:55 +02:00
anchors {
bottom: parent . bottom
right: parent . right
2019-09-08 15:08:50 +02:00
left: app . landscape ( ) ? startButt.right: parent . left
top: app . landscape ( ) ? parent.top: startButt . bottom
topMargin: app . landscape ( ) ? undefined: parent . height * 0.1
leftMargin: app . landscape ( ) ? parent . width * 0.05 : 0
2018-07-22 16:47:55 +02:00
}
2018-08-28 23:03:35 +02:00
Rectangle {
2019-03-08 15:36:32 +01:00
id: lowerMenuBackground
2018-08-28 23:03:35 +02:00
anchors.fill: parent
2019-03-08 18:03:27 +01:00
color: appTheme . style . menuColor
2019-03-24 21:31:59 +01:00
Behavior on color {
ColorAnimation {
duration: 200
}
}
2018-08-28 23:03:35 +02:00
}
2019-04-30 23:44:04 +02:00
Grid {
id: loweMenuGrd
2018-07-22 16:47:55 +02:00
2019-04-30 23:44:04 +02:00
property int spacingMultiplier: 200 * ( getActiveChildren ( ) - 1 )
property int activeChildren: getActiveChildren ( )
2018-07-25 00:32:20 +02:00
2019-04-30 23:44:04 +02:00
function getActiveChildren ( ) {
var childrenCount = 0
for ( var i = 0 ; i < children . length ; i ++ )
{
if ( children [ i ] . enabled ) {
childrenCount ++
}
}
2018-07-22 16:47:55 +02:00
2019-04-30 23:44:04 +02:00
return childrenCount
2018-07-22 16:47:55 +02:00
}
2019-04-30 23:44:04 +02:00
anchors.centerIn: parent
2019-03-08 15:36:32 +01:00
2019-04-30 23:44:04 +02:00
height: childrenRect . height
width: childrenRect . width
2019-03-08 15:36:32 +01:00
2019-09-08 15:08:50 +02:00
rows: app . landscape ( ) ? activeChildren: 1
columns: app . landscape ( ) ? 1 : activeChildren
2018-07-25 00:32:20 +02:00
2019-09-08 15:08:50 +02:00
spacing: 0 // app.landscape() ? parent.height * spacingMultiplier * 0.001:parent.width * spacingMultiplier * 0.001
2018-07-22 16:47:55 +02:00
2019-04-30 23:44:04 +02:00
Behavior on spacingMultiplier {
NumberAnimation {
duration: 200
}
2018-07-22 16:47:55 +02:00
}
2019-04-30 23:44:04 +02:00
FancyButton {
id: settingsButt
2018-07-22 16:47:55 +02:00
2019-09-08 15:08:50 +02:00
height: app . landscape ( ) ? menu_container . width * 0.7 : menu_container . height * 0.7
2019-04-30 23:44:04 +02:00
width: height
onClicked: {
settingsDialog . open ( )
2018-07-25 00:32:20 +02:00
}
2019-04-30 23:44:04 +02:00
image: appTheme . style . settIcon
backgroundColor: parent . pressed ? appTheme.style.buttonPressedColor: appTheme . style . buttonColor
2018-07-22 16:47:55 +02:00
}
2019-04-30 23:44:04 +02:00
Item {
height: profilesButt . height
width: profilesButt . height
2018-07-22 16:47:55 +02:00
}
2018-07-17 19:17:25 +02:00
2019-04-30 23:44:04 +02:00
FancyButton {
id: profilesButt
enabled: height > 0
2020-04-19 13:09:46 +02:00
state: speedBackend . scStwClient . state === ScStwClient . CONNECTED ? "visible" : "hidden"
2019-04-30 23:44:04 +02:00
width: height
onClicked: {
profilesDialog . open ( )
}
image: appTheme . style . profilesIcon
backgroundColor: parent . pressed ? appTheme.style.buttonPressedColor: appTheme . style . buttonColor
2019-06-15 14:38:33 +02:00
states: [
State {
name: "hidden"
PropertyChanges {
target: profilesButt
height: 0
}
} ,
State {
name: "visible"
PropertyChanges {
target: profilesButt
2019-09-08 15:08:50 +02:00
height: app . landscape ( ) ? menu_container . width * 0.7 : menu_container . height * 0.7
2019-06-15 14:38:33 +02:00
}
2019-04-30 23:44:04 +02:00
}
2019-06-15 14:38:33 +02:00
]
transitions: [
Transition {
NumberAnimation {
properties: "height"
}
}
]
2018-07-17 19:17:25 +02:00
}
}
}
2018-07-22 16:47:55 +02:00
/ * - - - - - - - - - - - - - - - - - - - - - -
Timer states
-- -- -- -- -- -- -- -- -- -- -- * /
2018-07-17 19:17:25 +02:00
states: [
2018-07-22 16:47:55 +02:00
State {
name: "IDLE"
//state for the start page
PropertyChanges {
2019-04-15 13:33:31 +02:00
target: topContainerItm ;
2019-09-08 15:08:50 +02:00
anchors.bottomMargin: app . landscape ( ) ? undefined: parent . height * 0.1 ;
anchors.rightMargin: app . landscape ( ) ? parent . height * 0.05 : 0
2018-07-22 16:47:55 +02:00
}
PropertyChanges {
target: startButt ;
2019-09-08 15:08:50 +02:00
enabled: true ; text: "start" ;
size: app . landscape ( ) ? parent . width * 0.5 : parent . height * 0.5
2018-07-22 16:47:55 +02:00
anchors.bottomMargin: parent . height * 0.5 - startButt . height * 0.5
anchors.rightMargin: parent . width * 0.5 - startButt . width * 0.5
}
2019-04-15 13:33:31 +02:00
PropertyChanges {
target: topLa
2019-10-13 16:42:38 +02:00
implicitText: "click start to start"
2019-04-15 13:33:31 +02:00
}
2018-07-22 16:47:55 +02:00
} ,
2019-04-15 13:33:31 +02:00
State {
name: "WAITING"
//state when a false start occured and waiting for time calculation
PropertyChanges {
2019-09-08 15:08:50 +02:00
target: startButt ; enabled: false ; text: "waiting..." ;
anchors.rightMargin: app . landscape ( ) ? parent . width * 0.05 : parent . width * 0.5 - startButt . width * 0.5 //put the button more to the right to hide the menu (only in landscape mode)
anchors.bottomMargin: app . landscape ( ) ? parent . height * 0.5 - startButt . height * 0.5 : parent . height * 0.1 //put the button lower to hide the menu (only in portrait mode)
2019-04-15 13:33:31 +02:00
}
PropertyChanges { target: cancelButt ; scale: 0 ; enabled: false }
PropertyChanges { target: menu_container ; }
PropertyChanges {
target: topLa
2019-10-13 16:42:38 +02:00
implicitText: "please wait..."
2019-04-15 13:33:31 +02:00
}
} ,
2018-07-22 16:47:55 +02:00
State {
name: "STARTING"
//state for the start sequence
2019-09-08 15:08:50 +02:00
PropertyChanges { target: startButt ; enabled: false ; text: "starting..." ;
anchors.rightMargin: app . landscape ( ) ? parent . width * 0.05 : parent . width * 0.5 - startButt . width * 0.5 //put the button more to the right to hide the menu (only in landscape mode)
anchors.bottomMargin: app . landscape ( ) ? parent . height * 0.5 - startButt . height * 0.5 : parent . height * 0.1 //put the button lower to hide the menu (only in portrait mode)
2018-07-22 16:47:55 +02:00
}
PropertyChanges { target: cancelButt ; scale: 1 }
PropertyChanges { target: menu_container ; }
2019-04-15 13:33:31 +02:00
PropertyChanges {
target: topLa
2019-10-13 16:42:38 +02:00
implicitText: "NEXT_START_ACTION"
2019-04-15 13:33:31 +02:00
}
2018-07-22 16:47:55 +02:00
} ,
State {
name: "RUNNING"
//state when the timer is running
PropertyChanges { target: startButt ; enabled: true ;
2019-10-02 19:12:06 +02:00
text: speedBackend . baseStationState === "connected" ? "cancel" : "stop"
2019-09-08 15:08:50 +02:00
anchors.rightMargin: app . landscape ( ) ? parent . width * 0.05 : parent . width * 0.5 - startButt . width * 0.5 //put the button more to the right to hide the menu (only in landscape mode)
anchors.bottomMargin: app . landscape ( ) ? parent . height * 0.5 - startButt . height * 0.5 : parent . height * 0.1 //put the button lower to hide the menu (only in portrait mode)
2018-07-22 16:47:55 +02:00
}
2019-05-19 14:06:05 +02:00
PropertyChanges {
target: topLa
2019-10-13 16:42:38 +02:00
implicitText: ""
2019-05-19 14:06:05 +02:00
}
2018-07-22 16:47:55 +02:00
} ,
State {
name: "STOPPED"
//state when the meassuring is over
PropertyChanges {
target: startButt ;
2019-09-08 15:08:50 +02:00
enabled: true ; text: "reset" ;
size: app . landscape ( ) ? parent . height * 0.35 : parent . height * 0.2 ;
anchors.bottomMargin: app . landscape ( ) ? parent . height * 0.5 - startButt . height * 0.5 : parent . height * 0.2 - startButt . height * 0.5
anchors.rightMargin: app . landscape ( ) ? parent . height * 0.2 - startButt . height * 0.5 : parent . width * 0.5 - startButt . width * 0.5
2018-07-22 16:47:55 +02:00
}
PropertyChanges {
2019-04-15 13:33:31 +02:00
target: topContainerItm ;
2019-09-08 15:08:50 +02:00
anchors.rightMargin: app . landscape ( ) ? 0 - startButt . width / 2 : undefined
anchors.bottomMargin: app . landscape ( ) ? undefined: 0 - startButt . height / 2
2018-07-22 16:47:55 +02:00
}
2019-05-19 14:06:05 +02:00
PropertyChanges {
target: topLa
text: ""
}
2018-07-22 16:47:55 +02:00
}
]
/ * - - - - - - - - - - - - - - - - - - - - - -
Timer animations
-- -- -- -- -- -- -- -- -- -- -- * /
2018-07-17 19:17:25 +02:00
transitions: [
Transition {
2018-10-04 18:35:29 +02:00
NumberAnimation { properties: "size,rightMargin,height,width,bottomMargin,font.pixelSize,pixelSize" ; easing.type: Easing . InOutQuad ; duration: 700 }
2018-07-17 19:17:25 +02:00
} ,
Transition {
2018-07-18 14:06:04 +02:00
to: "STOPPED"
2018-10-04 18:35:29 +02:00
NumberAnimation { properties: "size,rightMargin,height,width,bottomMargin,font.pixelSize,pixelSize" ; easing.type: Easing . InOutQuad ; duration: 700 }
2018-07-18 14:06:04 +02:00
} ,
Transition {
to: "IDLE"
2018-10-04 18:35:29 +02:00
NumberAnimation { properties: "size,rightMargin,height,width,bottomMargin,font.pixelSize,pixelSize" ; easing.type: Easing . InOutQuad ; duration: 700 }
2018-07-18 14:06:04 +02:00
} ,
Transition {
2019-03-09 15:06:48 +01:00
from: "STARTING"
2018-07-18 14:06:04 +02:00
to: "RUNNING"
//disable transitions for the RUNNING state
2019-05-02 22:39:22 +02:00
} ,
Transition {
from: "RUNNING"
to: "WAITING"
//disable transitions for the RUNNING state
2018-07-17 19:17:25 +02:00
}
]
2018-07-22 16:47:55 +02:00
/ * - - - - - - - - - - - - - - - - - - - - - -
Timer functions
-- -- -- -- -- -- -- -- -- -- -- * /
function landscape ( ) {
2019-09-08 15:08:50 +02:00
return ( app . height < app . width )
2018-07-22 16:47:55 +02:00
}
2018-08-14 17:07:42 +02:00
/*----Functions to control the stopwatch----*/
function start ( ) {
2020-04-15 21:47:55 +02:00
var ret = speedBackend . race . start ( )
2020-04-17 19:57:33 +02:00
if ( ret !== 200 ) {
console . log ( "+ --- error starting race: " + ret )
2019-03-07 17:18:24 +01:00
}
2018-08-14 17:07:42 +02:00
}
2020-04-17 19:57:33 +02:00
function cancel ( ) {
var ret = speedBackend . race . cancelStart ( false )
if ( ret !== 200 ) {
console . log ( "+ --- error canellingr race: " + ret )
}
}
2019-03-07 17:18:24 +01:00
2020-04-17 19:57:33 +02:00
function stop ( ) {
2019-03-07 17:18:24 +01:00
2020-04-17 19:57:33 +02:00
var ret = speedBackend . race . stop ( )
if ( ret !== 200 ) {
console . log ( "+ --- error stopping race: " + ret )
2019-03-07 17:18:24 +01:00
}
2018-08-14 17:07:42 +02:00
}
function reset ( ) {
2019-03-07 17:18:24 +01:00
2020-04-17 19:57:33 +02:00
var ret = speedBackend . race . reset ( )
2019-03-07 17:18:24 +01:00
if ( ret !== 200 ) {
2020-04-17 19:57:33 +02:00
console . log ( "+ --- error resetting race: " + ret )
2019-03-07 17:18:24 +01:00
}
2018-08-14 17:07:42 +02:00
}
2018-07-17 19:17:25 +02:00
}
}