850 lines
30 KiB
QML
850 lines
30 KiB
QML
/*
|
|
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/>.
|
|
*/
|
|
|
|
import QtQuick 2.9
|
|
import QtMultimedia 5.8
|
|
import QtQuick.Window 2.2
|
|
import QtQuick.Controls 2.2
|
|
import "."
|
|
import "./components"
|
|
import "./styles"
|
|
//import QtQuick.Layouts 1.11
|
|
|
|
import com.itsblue.speedclimbingstopwatch 1.0
|
|
|
|
Window {
|
|
visible: true
|
|
width: 540
|
|
height: 960
|
|
title: qsTr("Speedclimbing stw")
|
|
property date currentTime: new Date()
|
|
property int millis: 0
|
|
|
|
onBeforeRendering: {
|
|
StyleSettings.refreshTheme()
|
|
}
|
|
|
|
Page {
|
|
id:root
|
|
anchors.fill: parent
|
|
|
|
property double startTime: 0
|
|
property double stoppedTime: 0
|
|
property double currTime
|
|
|
|
property double buzzer_offset: buzzerConn.offset
|
|
property double last_button_pressed: buzzerConn.lastTriggered
|
|
|
|
property var last_run : {
|
|
'stop_type': "", 'time': 0, 'react_time': 0
|
|
}
|
|
|
|
//array that contains all connections an their atatus
|
|
property var connections: {
|
|
'buzzer': buzzerConn.status,
|
|
'startpad': startpadConn.status,
|
|
'baseStation': baseConn.status
|
|
}
|
|
|
|
//set default state to IDLE
|
|
state: "IDLE"
|
|
|
|
Rectangle {
|
|
id: backgroundRect
|
|
anchors.fill: parent
|
|
color: StyleSettings.backgroundColor
|
|
}
|
|
|
|
Item {
|
|
id: connections
|
|
|
|
BuzzerConn {
|
|
id: buzzerConn
|
|
ipAdress: "192.168.4.10"
|
|
property var status: {'status': buzzerConn.state, 'progress': buzzerConn.progress}
|
|
onLastTriggeredChanged: {
|
|
timer_1.handleToppad()
|
|
}
|
|
}
|
|
|
|
Timer {
|
|
id: buzzerRefreshTimer
|
|
running: buzzerConn.state === "connected"
|
|
interval: root.state === "RUNNING" ? 1:1000
|
|
repeat: false
|
|
onTriggered: {
|
|
buzzerConn.refresh()
|
|
this.start()
|
|
}
|
|
}
|
|
|
|
StartpadConn {
|
|
id: startpadConn
|
|
ipAdress: "192.168.4.11"
|
|
property var status: {'status': startpadConn.state, 'progress': startpadConn.progress}
|
|
property string color: root.state === "RUNNING" ? "SET_LED_RUNNING":"SET_LED_STARTING"
|
|
onColorChanged: {
|
|
appendCommand(color)
|
|
}
|
|
|
|
onLastTriggeredChanged: {
|
|
timer_1.handleStartpad()
|
|
}
|
|
}
|
|
|
|
Timer {
|
|
id: startpadRefreshTimer
|
|
running: startpadConn.state === "connected"
|
|
interval: root.state === "RUNNING" || root.state === "STARTING" ? 1:1000
|
|
repeat: false
|
|
onTriggered: {
|
|
startpadConn.refresh()
|
|
this.start()
|
|
}
|
|
}
|
|
|
|
BaseStationConn {
|
|
id: baseConn
|
|
ipAdress: "localhost"
|
|
|
|
property var status: {'status': baseConn.state, 'progress': baseConn.progress, 'connections': baseConn.connections}
|
|
|
|
onNextRemoteActionChanged: {
|
|
switch(nextRemoteAction){
|
|
case "at_marks":
|
|
timer_1.text = "at your\nmarks"
|
|
break
|
|
case "ready":
|
|
timer_1.text = "ready"
|
|
break
|
|
case "start":
|
|
timer_1.text = "0.000 sec"
|
|
break
|
|
}
|
|
}
|
|
|
|
onNextRemoteActionDelayProgChanged: {
|
|
console.log(nextRemoteActionDelayProg)
|
|
prog.progress = baseConn.nextRemoteActionDelayProg * 100
|
|
console.log(prog.progress)
|
|
}
|
|
}
|
|
|
|
Timer {
|
|
id: baseRefreshTimer
|
|
running: false
|
|
repeat: false
|
|
|
|
interval: 1
|
|
onTriggered: {
|
|
switch(root.state){
|
|
case "RUNNING":
|
|
var baseReactTime = parseInt(baseConn.sendCommand("GET_REACTTIME"))
|
|
console.log(baseReactTime)
|
|
if(baseReactTime !== 0){
|
|
root.last_run.react_time = baseReactTime
|
|
}
|
|
timer_1.text = baseConn.getTime("readable") + " sec"
|
|
if(baseConn.sendCommand("GET_TIMER_STATE") === "STOPPED"){
|
|
root.stop("manual")
|
|
}
|
|
break
|
|
case "STARTING":
|
|
var baseReactTime = parseInt(baseConn.sendCommand("GET_REACTTIME"))
|
|
if(baseReactTime !== 0){
|
|
root.last_run.react_time = baseReactTime
|
|
}
|
|
|
|
var baseNextAction = baseConn.sendCommand("GET_NEXT_ACTION")
|
|
|
|
if(baseNextAction === "at_marks"){
|
|
timer_1.text = qsTr("at your\nmarks")
|
|
var baseNextActionDelay = parseFloat(baseConn.sendCommand("GET_NEXT_ACTION_DELAY_PROG"))
|
|
prog.progress = baseNextActionDelay * 100
|
|
}
|
|
else if(baseNextAction === "ready"){
|
|
timer_1.text = qsTr("ready")
|
|
var baseNextActionDelay = parseFloat(baseConn.sendCommand("GET_NEXT_ACTION_DELAY_PROG"))
|
|
prog.progress = baseNextActionDelay * 100
|
|
}
|
|
else if(baseNextAction === "start"){
|
|
timer_1.text = "0.000 sec"
|
|
}
|
|
|
|
|
|
|
|
var baseState = baseConn.sendCommand("GET_TIMER_STATE")
|
|
console.log(baseState)
|
|
if(baseState === "RUNNING"){
|
|
timer_1.start(1)
|
|
root.state = "RUNNING";
|
|
}
|
|
else if(baseState === "STOPPED"){
|
|
var baseReactTime = parseInt(baseConn.sendCommand("GET_REACTTIME"))
|
|
if(baseReactTime<0){
|
|
root.stop("false")
|
|
}
|
|
else{
|
|
root.stop("cancel")
|
|
}
|
|
|
|
|
|
root.state = "STOPPED"
|
|
}
|
|
break
|
|
}
|
|
start()
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
Timer {
|
|
id: next_actionTimer
|
|
|
|
property string action
|
|
property double started_at
|
|
|
|
running: false
|
|
repeat: false
|
|
onRunningChanged: {
|
|
if(!running){
|
|
started_at = 0
|
|
if(action == "NONE"){
|
|
timer_1.text = "0.000 sec"
|
|
}
|
|
return
|
|
}
|
|
|
|
if(action === "at_marks"){
|
|
started_at = new Date().getTime()
|
|
timer_1.text = "at your\nmarks"
|
|
}
|
|
else if(action === "ready"){
|
|
started_at = new Date().getTime()
|
|
timer_1.text = "ready"
|
|
}
|
|
}
|
|
onTriggered: {
|
|
if(action === "at_marks"){
|
|
at_marksSound.play()
|
|
}
|
|
else if(action === "ready"){
|
|
action = "NONE"
|
|
readySound.play()
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
Item {
|
|
id: sounds
|
|
SoundEffect {
|
|
id: at_marksSound
|
|
source: "qrc:/sounds/at_marks_1.wav"
|
|
|
|
onPlayingChanged: {
|
|
if(!playing && root.state==="STARTING"){
|
|
if(_cppAppSettings.loadSetting("ready_en") === "true"){
|
|
next_actionTimer.action = "ready"
|
|
next_actionTimer.interval = _cppAppSettings.loadSetting("ready_delay")>0 ? _cppAppSettings.loadSetting("ready_delay"):1
|
|
next_actionTimer.start()
|
|
}
|
|
else{
|
|
startSound.play()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
SoundEffect {
|
|
id: readySound
|
|
source: "qrc:/sounds/ready_1.wav"
|
|
onPlayingChanged: {
|
|
if(!playing && root.state==="STARTING"){
|
|
|
|
startSound.play()
|
|
}
|
|
}
|
|
}
|
|
|
|
SoundEffect {
|
|
//start sound
|
|
id: startSound
|
|
source: "qrc:/sounds/OFFICAL_IFSC_STARTIGNAL.wav"
|
|
|
|
onPlayingChanged: {
|
|
if(!playing && root.state==="STARTING"){
|
|
root.state = "RUNNING"
|
|
}
|
|
else if(playing) {
|
|
console.log("start sound started")
|
|
|
|
timer_1.start(3100)
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
SoundEffect {
|
|
//false-start sound
|
|
id: falseSound
|
|
source: "qrc:/sounds/false.wav"
|
|
}
|
|
}
|
|
/*------------------------
|
|
Timer text an upper line
|
|
------------------------*/
|
|
Item {
|
|
id: time_container
|
|
anchors {
|
|
top: parent.top
|
|
left: parent.left
|
|
right: root.landscape() ? startButt.left:parent.right
|
|
bottom: root.landscape() ? parent.bottom:startButt.top
|
|
bottomMargin: root.landscape() ? undefined:parent.height * 0.1
|
|
rightMargin: root.landscape() ? parent.width * 0.05:0
|
|
}
|
|
|
|
Rectangle {
|
|
anchors.fill: parent
|
|
color: StyleSettings.menuColor
|
|
}
|
|
|
|
SpeedTimer {
|
|
id: timer_1
|
|
anchors.centerIn: parent
|
|
elide: "ElideRight"
|
|
color: StyleSettings.textColor
|
|
toppadConn: buzzerConn
|
|
baseConn: baseConn
|
|
startpadConn: startpadConn
|
|
|
|
text: "0.000 sec"
|
|
|
|
onStateChanged: {
|
|
console.log(newState)
|
|
root.state = timer_1.getState()
|
|
}
|
|
|
|
onStopped: {
|
|
root.state = "STOPPED"
|
|
}
|
|
|
|
onStartCanceled: {
|
|
root.state = "STOPPED"
|
|
next_actionTimer.stop()
|
|
at_marksSound.stop()
|
|
readySound.stop()
|
|
startSound.stop()
|
|
if(falseStart && baseConn.state !== "connected"){
|
|
falseSound.play()
|
|
}
|
|
}
|
|
}
|
|
|
|
Label {
|
|
id: react_time
|
|
property int rtime: root.last_run.react_time
|
|
text: qsTr("reaction time (ms): ") + Math.round(rtime)
|
|
opacity: (root.state === "RUNNING" || root.sate === "STARTING" || root.state === "STOPPED") && rtime !== 0 ? 1:0
|
|
color: StyleSettings.textColor
|
|
anchors {
|
|
horizontalCenter: parent.horizontalCenter
|
|
top: timer_1.bottom
|
|
topMargin: parent.height * 0.1
|
|
}
|
|
Timer {
|
|
running: root.state === "RUNNING" || root.sate === "STARTING" || root.state === "STOPPED"
|
|
repeat: true
|
|
interval: 1
|
|
onTriggered: {
|
|
react_time.rtime = root.last_run.react_time
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
ConnectionIcon {
|
|
id: buzzerLogo
|
|
source: "qrc:/graphics/icons/buzzer_black.png"
|
|
status: root.connections["buzzer"].status
|
|
anchors {
|
|
top: parent.top
|
|
topMargin: 10
|
|
left: parent.left
|
|
leftMargin: 10
|
|
}
|
|
height: root.landscape()? root.height*0.1:root.width*0.1
|
|
}
|
|
|
|
ConnectionIcon {
|
|
id: startpadLogo
|
|
source: "qrc:/graphics/icons/startpad_black.png"
|
|
status: root.connections["startpad"].status
|
|
anchors {
|
|
top: parent.top
|
|
topMargin: 10
|
|
left: parent.left
|
|
leftMargin: 5 + buzzerLogo.width
|
|
}
|
|
height: root.landscape()? root.height*0.1:root.width*0.1
|
|
}
|
|
|
|
Rectangle {
|
|
id: upper_line
|
|
width: root.landscape() ? 1:parent.width
|
|
height: root.landscape() ? parent.height:1
|
|
color: StyleSettings.lineColor
|
|
anchors.left: root.landscape() ? time_container.right:parent.left
|
|
anchors.top: root.landscape() ? parent.top:time_container.bottom
|
|
anchors.bottom: root.landscape() ? parent.bottom:undefined
|
|
}
|
|
|
|
/*----------------------
|
|
Start / Stop / Reset button
|
|
----------------------*/
|
|
Button {
|
|
id : startButt
|
|
|
|
text: qsTr("start")
|
|
property int size: root.landscape() ? parent.width * 0.5:parent.height * 0.5
|
|
anchors {
|
|
bottom: parent.bottom
|
|
bottomMargin: root.height * 0.5 - height * 0.5
|
|
right: parent.right
|
|
rightMargin: root.width * 0.5 - width * 0.5
|
|
}
|
|
contentItem: Text {
|
|
//make text disappear
|
|
}
|
|
height: root.landscape() ? size > parent.height * 0.9 ? parent.height * 0.9:size : size
|
|
width: root.landscape() ? size : size > parent.width * 0.9 ? parent.width * 0.9:size
|
|
|
|
background: Rectangle {
|
|
color: parent.pressed ? StyleSettings.buttonPressedColor:StyleSettings.buttonColor
|
|
border.color: StyleSettings.buttonBorderColor
|
|
border.width: 1
|
|
radius: width / 2
|
|
Label {
|
|
id: startButt_text
|
|
text: startButt.text
|
|
anchors.centerIn: parent
|
|
font.pixelSize: parent.height * 0.16
|
|
font.family: "Helvetica"
|
|
color: enabled ? StyleSettings.textColor:StyleSettings.disabledTextColor
|
|
}
|
|
}
|
|
|
|
Behavior on text {
|
|
//animate a text change
|
|
enabled: true
|
|
FadeAnimation {
|
|
target: startButt_text
|
|
}
|
|
}
|
|
|
|
onClicked: {
|
|
switch(root.state) {
|
|
case "IDLE":
|
|
root.start()
|
|
break
|
|
case "RUNNING":
|
|
root.stop("manual")
|
|
break
|
|
case "STOPPED":
|
|
root.reset()
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
ProgressCircle {
|
|
id: prog
|
|
anchors.fill: startButt
|
|
opacity: baseConn.state !== "connected" ?
|
|
next_actionTimer.started_at > 0 ? 1:0
|
|
:progress > 0 ? 1:0
|
|
lineWidth: 5
|
|
property int progress: 0
|
|
arcBegin: 0
|
|
arcEnd: baseConn.state !== "connected" ? 360 * (( next_actionTimer.interval - ( new Date().getTime() - next_actionTimer.started_at ) ) / next_actionTimer.interval)
|
|
:(360/100) * progress
|
|
colorCircle: "grey"
|
|
onProgressChanged: {
|
|
console.log(progress)
|
|
}
|
|
|
|
animationDuration: baseConn.state === "connected" ? 150:0
|
|
|
|
Timer {
|
|
id: prog_refresh
|
|
running: parent.opacity === 1 && baseConn.state !== "connected"
|
|
interval: 1
|
|
repeat: false
|
|
onTriggered: {
|
|
console.log("prog refresh timer")
|
|
prog.arcEnd = 360 * (( next_actionTimer.interval - ( new Date().getTime() - next_actionTimer.started_at ) ) / next_actionTimer.interval)
|
|
prog_refresh.start()
|
|
}
|
|
}
|
|
}
|
|
|
|
/*----------------------
|
|
Cancel button
|
|
----------------------*/
|
|
RoundButton {
|
|
id: cancelButt
|
|
|
|
text: qsTr("cancel")
|
|
anchors {
|
|
right: startButt.right
|
|
bottom: startButt.bottom
|
|
}
|
|
contentItem: Text {
|
|
//make text disappear
|
|
}
|
|
height: startButt.height * 0.3
|
|
scale: 0
|
|
width: height
|
|
|
|
enabled: root.state === "STARTING"
|
|
|
|
onClicked: {
|
|
root.stop("cancel")
|
|
}
|
|
|
|
Behavior on scale {
|
|
PropertyAnimation {
|
|
duration: 200
|
|
}
|
|
}
|
|
background: Rectangle {
|
|
color: parent.pressed ? StyleSettings.buttonPressedColor:StyleSettings.buttonColor
|
|
border.color: StyleSettings.buttonBorderColor
|
|
border.width: 1
|
|
radius: width / 2
|
|
Label {
|
|
id: cancelButt_text
|
|
text: cancelButt.text
|
|
anchors.centerIn: parent
|
|
font.pixelSize: parent.height * 0.16
|
|
font.family: "Helvetica"
|
|
color: StyleSettings.textColor
|
|
}
|
|
}
|
|
}
|
|
|
|
/*------
|
|
Popups
|
|
------*/
|
|
SettingsDialog{
|
|
id: settingsDialog
|
|
connections: root.connections
|
|
onConnectRequested: {
|
|
switch(type){
|
|
case "buzzer":
|
|
buzzerConn.connect()
|
|
break
|
|
case "startpad":
|
|
startpadConn.connect()
|
|
break
|
|
case "baseStation":
|
|
baseConn.connectToHost()
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
ErrorDialog {
|
|
id: errorDialog
|
|
}
|
|
|
|
// ProfilesDialog {
|
|
// id: profilesDialog
|
|
// }
|
|
|
|
/*-------------------
|
|
lower line and menu
|
|
-------------------*/
|
|
Rectangle {
|
|
width: root.landscape() ? 1:parent.width
|
|
height: root.landscape() ? parent.height:1
|
|
color: StyleSettings.lineColor
|
|
anchors.right: root.landscape() ? menu_container.left:parent.right
|
|
anchors.bottom: root.landscape() ? parent.bottom:menu_container.top
|
|
anchors.top: root.landscape() ? parent.top:undefined
|
|
}
|
|
|
|
Item {
|
|
id: menu_container
|
|
anchors {
|
|
bottom: parent.bottom
|
|
right: parent.right
|
|
left: root.landscape() ? startButt.right:parent.left
|
|
top: root.landscape() ? parent.top:startButt.bottom
|
|
topMargin: root.landscape() ? undefined:parent.height * 0.1
|
|
leftMargin: root.landscape() ? parent.width * 0.05:0
|
|
}
|
|
|
|
Rectangle {
|
|
anchors.fill: parent
|
|
color: StyleSettings.menuColor
|
|
}
|
|
|
|
RoundButton {
|
|
id: settingsButt
|
|
|
|
anchors {
|
|
//center
|
|
verticalCenter: root.landscape() ? undefined:parent.verticalCenter
|
|
horizontalCenter: root.landscape() ? parent.horizontalCenter:undefined
|
|
//set anchors
|
|
left: root.landscape() ? undefined:parent.left
|
|
top: root.landscape() ? parent.top:undefined
|
|
//align in landscape mode
|
|
//for two buttons: topMargin: root.landscape() ? (parent.height - (height * 2)) / 3:undefined
|
|
topMargin: root.landscape() ? (parent.height * 0.5 - (height * 0.5)):undefined
|
|
//align in portrait mode
|
|
//for two buttons: leftMargin: root.landscape() ? undefined:(parent.width - width * 2) / 3
|
|
leftMargin: root.landscape() ? undefined:(parent.width * 0.5 - width * 0.5)
|
|
}
|
|
|
|
height: root.landscape() ? parent.width * 0.7:parent.height * 0.7
|
|
width: height
|
|
|
|
onClicked: {
|
|
settingsDialog.open()
|
|
}
|
|
|
|
background: Rectangle {
|
|
color: parent.pressed ? StyleSettings.buttonPressedColor:StyleSettings.buttonColor
|
|
border.color: StyleSettings.buttonBorderColor
|
|
border.width: 1
|
|
radius: width / 2
|
|
|
|
Image {
|
|
id: settungsButt_Image
|
|
source: StyleSettings.settIcon
|
|
anchors.centerIn: parent
|
|
height: parent.height * 0.7
|
|
width: parent.width * 0.7
|
|
mipmap: true
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
RoundButton {
|
|
id: profilesButt
|
|
|
|
anchors {
|
|
verticalCenter: root.landscape() ? undefined:parent.verticalCenter
|
|
horizontalCenter: root.landscape() ? parent.horizontalCenter:undefined
|
|
left: root.landscape() ? undefined:settingsButt.right
|
|
top: root.landscape() ? settingsButt.bottom:undefined
|
|
topMargin: root.landscape() ? (parent.height - (height * 2)) / 3:undefined
|
|
leftMargin: root.landscape() ? undefined:(parent.width - width * 2) / 3
|
|
}
|
|
|
|
height: root.landscape() ? parent.width * 0.7:parent.height * 0.7
|
|
width: height
|
|
|
|
onPressedChanged: {
|
|
if(pressed){
|
|
background.color = "lightgrey"
|
|
}
|
|
else {
|
|
background.color = "white"
|
|
}
|
|
}
|
|
|
|
onClicked: {
|
|
profilesDialog.open()
|
|
}
|
|
|
|
background: Rectangle {
|
|
color: "white"
|
|
border.color: "grey"
|
|
border.width: 1
|
|
radius: width / 2
|
|
|
|
Image {
|
|
id: profilesButt_Image
|
|
source: "qrc:/graphics/icons/user.png"
|
|
anchors.centerIn: parent
|
|
height: parent.height * 0.5
|
|
width: parent.width * 0.5
|
|
mipmap: true
|
|
}
|
|
}
|
|
}
|
|
*/
|
|
|
|
}
|
|
|
|
/*----------------------
|
|
Timer states
|
|
----------------------*/
|
|
states: [
|
|
State {
|
|
name: "IDLE"
|
|
//state for the start page
|
|
PropertyChanges { target: timer_1; pixelSize: root.landscape() ? parent.width * 0.1:parent.height * 0.3; scale: 1 }
|
|
PropertyChanges {
|
|
target: time_container;
|
|
anchors.bottomMargin: root.landscape() ? undefined:parent.height * 0.1;
|
|
anchors.rightMargin: root.landscape() ? parent.height * 0.05:0
|
|
}
|
|
PropertyChanges {
|
|
target: startButt;
|
|
enabled: true; text: qsTr("start");
|
|
size: root.landscape() ? parent.width * 0.5:parent.height * 0.5
|
|
anchors.bottomMargin: parent.height * 0.5 - startButt.height * 0.5
|
|
anchors.rightMargin: parent.width * 0.5 - startButt.width * 0.5
|
|
}
|
|
|
|
},
|
|
State {
|
|
name: "STARTING"
|
|
//state for the start sequence
|
|
PropertyChanges { target: startButt; enabled: false; text: qsTr("starting...");
|
|
anchors.rightMargin: root.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: root.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)
|
|
}
|
|
PropertyChanges { target: timer_1; pixelSize: root.landscape() ? parent.width * 0.2:parent.height * 0.3; scale: 1 }
|
|
PropertyChanges { target: cancelButt; scale: 1}
|
|
PropertyChanges { target: menu_container; }
|
|
},
|
|
State {
|
|
name: "RUNNING"
|
|
//state when the timer is running
|
|
PropertyChanges { target: timer_1; pixelSize: root.landscape() ? parent.width * 0.2:parent.height * 0.3; scale: 1 }
|
|
PropertyChanges { target: startButt; enabled: true;
|
|
text: "stop"
|
|
anchors.rightMargin: root.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: root.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)
|
|
}
|
|
|
|
},
|
|
|
|
State {
|
|
name: "STOPPED"
|
|
//state when the meassuring is over
|
|
PropertyChanges {
|
|
target: timer_1;
|
|
pixelSize: root.landscape() ? parent.width * 0.15:parent.height * 0.1;
|
|
scale: 1
|
|
}
|
|
PropertyChanges {
|
|
target: startButt;
|
|
enabled: true; text: qsTr("reset");
|
|
size: root.landscape() ? parent.height * 0.35:parent.height * 0.2;
|
|
anchors.bottomMargin: root.landscape() ? parent.height * 0.5 - startButt.height * 0.5:parent.height * 0.2 - startButt.height * 0.5
|
|
anchors.rightMargin: root.landscape() ? parent.height * 0.2 - startButt.height * 0.5:parent.width * 0.5 - startButt.width * 0.5
|
|
}
|
|
PropertyChanges {
|
|
target: time_container;
|
|
anchors.rightMargin: root.landscape() ? 0-startButt.width/2:undefined
|
|
anchors.bottomMargin: root.landscape() ? undefined:0-startButt.height/2
|
|
}
|
|
}
|
|
]
|
|
|
|
/*----------------------
|
|
Timer animations
|
|
----------------------*/
|
|
transitions: [
|
|
Transition {
|
|
NumberAnimation { properties: "size,rightMargin,height,width,bottomMargin,font.pixelSize,pixelSize"; easing.type: Easing.InOutQuad; duration: 700 }
|
|
},
|
|
Transition {
|
|
to: "STOPPED"
|
|
NumberAnimation { properties: "size,rightMargin,height,width,bottomMargin,font.pixelSize,pixelSize"; easing.type: Easing.InOutQuad; duration: 700 }
|
|
},
|
|
Transition {
|
|
to: "IDLE"
|
|
NumberAnimation { properties: "size,rightMargin,height,width,bottomMargin,font.pixelSize,pixelSize"; easing.type: Easing.InOutQuad; duration: 700 }
|
|
},
|
|
|
|
Transition {
|
|
to: "RUNNING"
|
|
//disable transitions for the RUNNING state
|
|
}
|
|
]
|
|
|
|
/*----------------------
|
|
Timer functions
|
|
----------------------*/
|
|
function landscape(){
|
|
return(root.height < root.width)
|
|
}
|
|
|
|
/*----Functions to control the stopwatch----*/
|
|
function start(){
|
|
if(baseConn.state === "connected"){
|
|
baseConn.startTimers()
|
|
return;
|
|
}
|
|
|
|
timer_1.setStarting()
|
|
if(_cppAppSettings.loadSetting("at_marks_en") === "true"){
|
|
next_actionTimer.action = "at_marks"
|
|
next_actionTimer.interval = _cppAppSettings.loadSetting("at_marks_delay")>0 ? _cppAppSettings.loadSetting("at_marks_delay"):1
|
|
next_actionTimer.start()
|
|
return
|
|
}
|
|
if(_cppAppSettings.loadSetting("ready_en") === "true"){
|
|
next_actionTimer.action = "ready"
|
|
next_actionTimer.interval = _cppAppSettings.loadSetting("ready_delay")>0 ? _cppAppSettings.loadSetting("ready_delay"):1
|
|
next_actionTimer.start()
|
|
return
|
|
}
|
|
|
|
startSound.play()
|
|
}
|
|
|
|
function stop(type){
|
|
if(baseConn.state === "connected"){
|
|
baseConn.stopTimers(type)
|
|
}
|
|
else {
|
|
timer_1.stop(type)
|
|
}
|
|
|
|
if(type === "manual" || type === "cancel"){
|
|
|
|
}
|
|
//root.state = "STOPPED"
|
|
//timer_1.stop(type)
|
|
}
|
|
|
|
function reset(){
|
|
if(baseConn.state === "connected"){
|
|
baseConn.resetTimers()
|
|
}
|
|
else {
|
|
timer_1.reset()
|
|
}
|
|
|
|
//
|
|
//root.state = "IDLE"
|
|
}
|
|
}
|
|
}
|