Library migration #36

Merged
dorian merged 62 commits from library_migration into master 2024-10-17 17:52:36 +02:00
13 changed files with 1821 additions and 593 deletions
Showing only changes of commit 9656cdbfdc - Show all commits

View file

@ -22,11 +22,9 @@
<action android:name="android.intent.action.MAIN"/> <action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/> <category android:name="android.intent.category.LAUNCHER"/>
</intent-filter> </intent-filter>
<!-- Application arguments --> <!-- Application arguments -->
<!-- meta-data android:name="android.app.arguments" android:value="arg1 arg2 arg3"/ --> <!-- meta-data android:name="android.app.arguments" android:value="arg1 arg2 arg3"/ -->
<!-- Application arguments --> <!-- Application arguments -->
<meta-data android:name="android.app.lib_name" android:value="speedclimbing_stw"/> <meta-data android:name="android.app.lib_name" android:value="speedclimbing_stw"/>
<meta-data android:name="android.app.qt_sources_resource_id" android:resource="@array/qt_sources"/> <meta-data android:name="android.app.qt_sources_resource_id" android:resource="@array/qt_sources"/>
<meta-data android:name="android.app.repository" android:value="default"/> <meta-data android:name="android.app.repository" android:value="default"/>
@ -49,12 +47,10 @@
<meta-data android:value="@string/ministro_needed_msg" android:name="android.app.ministro_needed_msg"/> <meta-data android:value="@string/ministro_needed_msg" android:name="android.app.ministro_needed_msg"/>
<meta-data android:value="@string/fatal_error_msg" android:name="android.app.fatal_error_msg"/> <meta-data android:value="@string/fatal_error_msg" android:name="android.app.fatal_error_msg"/>
<!-- Messages maps --> <!-- Messages maps -->
<!-- Splash screen --> <!-- Splash screen -->
<!-- meta-data android:name="android.app.splash_screen_drawable" android:resource="@drawable/logo"/ --> <!-- meta-data android:name="android.app.splash_screen_drawable" android:resource="@drawable/logo"/ -->
<!-- meta-data android:name="android.app.splash_screen_sticky" android:value="true"/ --> <!-- meta-data android:name="android.app.splash_screen_sticky" android:value="true"/ -->
<!-- Splash screen --> <!-- Splash screen -->
<!-- Background running --> <!-- Background running -->
<!-- Warning: changing this value to true may cause unexpected crashes if the <!-- Warning: changing this value to true may cause unexpected crashes if the
application still try to draw after application still try to draw after
@ -62,11 +58,9 @@
signal is sent! --> signal is sent! -->
<meta-data android:name="android.app.background_running" android:value="false"/> <meta-data android:name="android.app.background_running" android:value="false"/>
<!-- Background running --> <!-- Background running -->
<!-- auto screen scale factor --> <!-- auto screen scale factor -->
<meta-data android:name="android.app.auto_screen_scale_factor" android:value="false"/> <meta-data android:name="android.app.auto_screen_scale_factor" android:value="false"/>
<!-- auto screen scale factor --> <!-- auto screen scale factor -->
<!-- extract android style --> <!-- extract android style -->
<!-- available android:values : <!-- available android:values :
* full - useful QWidget & Quick Controls 1 apps * full - useful QWidget & Quick Controls 1 apps
@ -75,14 +69,11 @@
--> -->
<meta-data android:name="android.app.extract_android_style" android:value="full"/> <meta-data android:name="android.app.extract_android_style" android:value="full"/>
<!-- extract android style --> <!-- extract android style -->
</activity> </activity>
<!-- For adding service(s) please check: https://wiki.qt.io/AndroidServices --> <!-- For adding service(s) please check: https://wiki.qt.io/AndroidServices -->
</application> </application>
<uses-sdk android:minSdkVersion="16" android:targetSdkVersion="28"/> <uses-sdk android:minSdkVersion="16" android:targetSdkVersion="29"/>
<supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/> <supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/>
<!-- The following comment will be replaced upon deployment with default permissions based on the dependencies of the application. <!-- The following comment will be replaced upon deployment with default permissions based on the dependencies of the application.

View file

@ -21,6 +21,6 @@ public class MainActivity extends org.qtproject.qt5.android.bindings.QtActivity
public void onCreate(android.os.Bundle savedInstanceState){ public void onCreate(android.os.Bundle savedInstanceState){
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
this.getWindow().addFlags(android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); this.getWindow().addFlags(android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
//this.getWindow().setVolumeControlStream(android.view.AudioManager.STREAM_MUSIC); //this.setVolumeControlStream(android.view.AudioManager.STREAM_MUSIC);
} }
} }

View file

@ -0,0 +1,112 @@
import QtQuick 2.0
import QtQuick.Controls 2.0
import "../components"
import "../components/layout"
import de.itsblue.ScStw.Styling 2.0
import de.itsblue.ScStw.Styling.Components 1.0
ToolBar {
id: control
/*
Grid {
id: loweMenuGrd
property int spacingMultiplier: 200 * (getActiveChildren() - 1)
property int activeChildren: getActiveChildren()
function getActiveChildren() {
var childrenCount = 0
for (var i = 0; i < children.length; i++)
{
if(children[i].enabled){
childrenCount ++
}
}
return childrenCount
}
anchors.centerIn: parent
height: childrenRect.height
width: childrenRect.width
rows: app.landscape() ? activeChildren:1
columns: app.landscape() ? 1:activeChildren
spacing: 0// app.landscape() ? parent.height * spacingMultiplier * 0.001:parent.width * spacingMultiplier * 0.001
Behavior on spacingMultiplier {
NumberAnimation {
duration: 200
}
}
FancyButton {
id: settingsButt
height: app.landscape() ? menu_container.width * 0.7:menu_container.height * 0.7
width: height
onClicked: {
settingsDialog.open()
}
image: appTheme.theme.images.settIcon
backgroundColor: parent.pressed ? appTheme.theme.colors.buttonPressed:appTheme.theme.colors.button
}
Item {
height: profilesButt.height
width: profilesButt.height
}
FancyButton {
id: profilesButt
enabled: height > 0
state: speedBackend.scStwClient.state === ScStwClient.CONNECTED ? "visible":"hidden"
width: height
onClicked: {
profilesDialog.open()
}
image: appTheme.theme.images.profilesIcon
backgroundColor: parent.pressed ? appTheme.theme.colors.buttonPressed:appTheme.theme.colors.button
states: [
State {
name: "hidden"
PropertyChanges {
target: profilesButt
height: 0
}
},
State {
name: "visible"
PropertyChanges {
target: profilesButt
height: app.landscape() ? menu_container.width * 0.7:menu_container.height * 0.7
}
}
]
transitions: [
Transition {
NumberAnimation {
properties: "height"
}
}
]
}
}*/
}

View file

@ -0,0 +1,341 @@
import QtQuick 2.0
import QtQuick.Controls 2.0
import QtGraphicalEffects 1.0
import QtQuick.Layouts 1.0
import "../components"
import "../components/layout"
import de.itsblue.ScStw 2.0
import de.itsblue.ScStw.Styling 2.0
import de.itsblue.ScStw.Styling.Components 1.0
Item {
id: control
// ----------------------------------
// -- Start / Stop / Reset button ---
// ----------------------------------
GridLayout {
id: centerLayout
anchors.centerIn: parent
width: parent.width
height: parent.height
columns: app.landscape() ? 2:1
rows: app.landscape() ? 1:2
Item {
Rectangle {
anchors.fill: parent
color: "green"
}
}
FancyButton {
id: mainActionButton
property double size
Layout.alignment: Layout.Center
Layout.preferredHeight: app.landscape() ? width:Math.min(control.width * size, control.height * size)
Layout.preferredWidth: app.landscape() ? Math.min(control.width * size, control.height * size):height
onClicked: {
var ret;
switch(speedBackend.race.state) {
case ScStwRace.IDLE:
ret = speedBackend.race.start()
break;
case ScStwRace.PREPAIRING:
case ScStwRace.WAITING:
case ScStwRace.STARTING:
ret = speedBackend.race.cancel()
break;
case ScStwRace.RUNNING:
ret = speedBackend.race.stop()
break;
case ScStwRace.STOPPED:
ret = speedBackend.race.reset()
break;
}
if(ret !== 200)
console.log("Error executing main button action: " + ret)
}
/*Behavior on Layout.preferredWidth {
enabled: !app.landscape()
NumberAnimation {
duration: 3000
}
}
Behavior on Layout.preferredHeight {
enabled: app.landscape()
NumberAnimation {
duration: 3000
}
}*/
}
}
states: [
State {
name: ScStwRace.IDLE
PropertyChanges {
target: mainActionButton
size: 0.8
Layout.preferredHeight: app.landscape() ? control.height * 0.8 : Math.min(control.width * 0.8, control.height * 0.8)
Layout.preferredWidth: app.landscape() ? Math.min(control.width * 0.8, control.height * 0.8) : control.width * 0.8
text: "start"
}
PropertyChanges {
target: centerLayout
anchors.verticalCenterOffset: 0
anchors.horizontalCenterOffset: 0
}
},
State {
name: ScStwRace.PREPAIRING
PropertyChanges {
target: mainActionButton
size: 0.8
text: "cancel"
}
},
State {
name: ScStwRace.WAITING
PropertyChanges {
target: mainActionButton
size: 0.8
text: "cancel"
}
},
State {
name: ScStwRace.STARTING
PropertyChanges {
target: mainActionButton
size: 0.8
text: "cancel"
}
},
State {
name: ScStwRace.STOPPED
PropertyChanges {
target: mainActionButton
size: 0.8
Layout.preferredHeight: app.landscape() ? control.height * 0.8 : Math.min(control.width * 0.8, control.height * 0.8)
Layout.preferredWidth: app.landscape() ? Math.min(control.width * 0.8, control.height * 0.8) : control.width * 0.8
text: "reset"
}
PropertyChanges {
target: centerLayout
//anchors.verticalCenterOffset: app.landscape() ? 0:-centerLayout.height * 0.5
//anchors.horizontalCenterOffset: app.landscape() ? -centerLayout.width * 0.5:0
}
}
]
/*
DelayButton {
id : startButt
text: "start"
property int size: app.landscape() ? parent.width * 0.5:parent.height * 0.5
property color backgroundColor: appTheme.theme.colors.button
property bool progressControlActivated: speedBackend.scStwClient.state === ScStwClient.CONNECTED && app.state === "RUNNING"
delay: progressControlActivated ? 2000:0
anchors {
bottom: parent.bottom
bottomMargin: app.height * 0.5 - height * 0.5
right: parent.right
rightMargin: app.width * 0.5 - width * 0.5
}
height: app.landscape() ? Math.min(size, parent.height * 0.9) : Math.min(size, parent.width * 0.9)
width: height
Text {
id: startButt_text
text: startButt.text
anchors.centerIn: parent
font.pixelSize: parent.height * 0.16
font.family: "Helvetica"
color: enabled ? appTheme.theme.colors.text:appTheme.theme.colors.disabledText
}
Behavior on text {
//animate a text change
enabled: true
FadeAnimation {
target: startButt_text
}
}
onClicked: {
if(startButt.progressControlActivated && progress < 1.0)
return
startButt.progress = 0
switch(app.state) {
case "IDLE":
app.start()
break
case "RUNNING":
app.stop()
break
case "STOPPED":
case "INCIDENT":
app.reset()
break
}
}
contentItem: Text {
}
background: Item {
RectangularGlow {
glowRadius: 0.001
spread: 0.2
color: "black"
visible: true
cornerRadius: startButtBackground.radius
anchors.fill: startButtBackground
scale: 0.75
opacity: Math.pow( startButt.opacity, 100 )
}
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()
}
}
}
}
}
ProgressCircle {
id: prog
property double progress: speedBackend.race.nextStartActionDetails[ScStwRace.NextStartActionDelayProgress]
anchors.fill: startButt
opacity: app.state === "STARTING" ? 1:0
scale: startButt.scale
lineWidth: prog.width * 0.02
arcBegin: 0
arcEnd: 360 * (1 - (progress > 0 ? progress:1))
colorCircle: "grey"
Behavior on opacity {
NumberAnimation {
duration: 200
}
}
animationDuration: 0
}
FancyButton {
id: cancelButt
text: "cancel"
anchors {
right: startButt.right
bottom: startButt.bottom
}
contentItem: Text {
//make text disappear
}
height: startButt.height * 0.3
scale: 0
width: height
enabled: app.state === "STARTING"
onClicked: {
app.cancel()
}
Behavior on scale {
PropertyAnimation {
duration: 200
}
}
Text {
id: cancelButt_text
text: cancelButt.text
anchors.centerIn: parent
font.pixelSize: parent.height * 0.16
font.family: "Helvetica"
color: appTheme.theme.colors.text
}
backgroundColor: appTheme.theme.colors.button
}*/
}

View file

@ -0,0 +1,255 @@
import QtQuick 2.0
import QtQuick.Controls 2.0
import "../components"
import "../components/layout"
import de.itsblue.ScStw.Styling 2.0
import de.itsblue.ScStw.Styling.Components 1.0
ToolBar {
id: control
/*states: [
State {
name: ScStwRace.IDLE
PropertyChanges {
target: mainActionButton
size: 0.8
text: "start"
}
PropertyChanges {
target: centerLayout
anchors.verticalCenterOffset: 0
anchors.horizontalCenterOffset: 0
}
},
State {
name: ScStwRace.PREPAIRING
PropertyChanges {
target: mainActionButton
size: 0.8
text: "cancel"
}
},
State {
name: ScStwRace.WAITING
PropertyChanges {
target: mainActionButton
size: 0.8
text: "cancel"
}
},
State {
name: ScStwRace.STARTING
PropertyChanges {
target: mainActionButton
size: 0.8
text: "cancel"
}
},
State {
name: ScStwRace.STOPPED
PropertyChanges {
target: mainActionButton
size: 0.75
text: "reset"
}
PropertyChanges {
target: centerLayout
anchors.verticalCenterOffset: app.landscape() ? 0:-centerLayout.height * 0.5
anchors.horizontalCenterOffset: app.landscape() ? -centerLayout.width * 0.5:0
}
}
]
/*
Text {
id: raceStateLabel
anchors.centerIn: parent
opacity: ( speedBackend.race.state < ScStwRace.RUNNING ) ? 1:0
width: parent.width * 0.7
height: parent.height * 0.7
text: ""
color: appTheme.theme.colors.text
fontSizeMode: Text.Fit
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
font.pixelSize: app.landscape() ? app.width * 0.15 : app.height * 0.4
minimumPixelSize: 1
Behavior on text {
FadeAnimation{
target: topLa
fadeDuration: 100
}
}
}
TimerColumn {
id: timerColumn
anchors.fill: parent
anchors.topMargin: app.landscape() ? 0:parent.height * 0.1
anchors.bottomMargin: app.landscape() ? 0:parent.height * 0.1
timers: speedBackend.race.timers
colors: appTheme.theme.colors
fontName: appTheme.theme.fonts.timers
showTimerLetter: speedBackend.race.state === ScStwRace.STOPPED
// make text smaller for much better performance
textScale: app.landscape() ? 0.7 : 0.5
opacity: ( speedBackend.race.state < ScStwRace.RUNNING ) ? 0:1
Behavior on opacity {
NumberAnimation {
duration: 200
}
}
}
Item {
id: connectionIconContainer
anchors {
top: parent.top
left: parent.left
right: parent.right
bottom: parent.bottom
bottomMargin: app.landscape() ? 0:parent.height * 0.8
rightMargin: app.landscape() ? parent.width * 0.8:0
}
opacity: speedBackend.race.state === ScStwRace.IDLE ? 1:0
ConnectionIcon {
id: baseConnConnIcon
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)
source: appTheme.theme.images.baseStationIcon
anchors {
top: parent.top
topMargin: 10
left: parent.left
leftMargin: 10
}
scale: 1.3
height: !app.landscape()? parent.height*0.3:parent.width*0.3
}
Row {
id: extensionStatusRow
anchors {
top: parent.top
topMargin: 10
left: baseConnConnIcon.right
leftMargin: 1
}
height: baseConnConnIcon.height * 0.4
spacing: 5
Repeater {
id: extensionStatusRep
model: Object.keys(speedBackend.scStwClient.extensions)
delegate: Rectangle {
property string thisLetter: modelData
width: height
height: parent.height
radius: width * 0.1
color: appTheme.theme.colors.success // TODO
Component.onCompleted: {
refreshConnectionState()
}
function refreshConnectionState() {
var extensions = speedBackend.scStwClient.extensions[modelData]
for(var i = 0; i < extensions.length; i++) {
console.log(JSON.stringify(extensions[i]))
// TODO!!
}
}
Text {
anchors.fill: parent
text: parent.thisLetter
fontSizeMode: Text.Fit
font.pixelSize: height
font.bold: true
color: appTheme.theme.colors.background
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
}
}
}
}
Behavior on opacity {
NumberAnimation {
duration: 200
}
}
}
Rectangle {
id: upper_line
width: app.landscape() ? 1:parent.width
height: app.landscape() ? parent.height:1
color: appTheme.theme.colors.line
anchors.left: app.landscape() ? topContainerItm.right:parent.left
anchors.top: app.landscape() ? parent.top:topContainerItm.bottom
anchors.bottom: app.landscape() ? parent.bottom:undefined
visible: false
}
*/
}

View file

@ -2,6 +2,9 @@ import QtQuick 2.9
import QtQuick.Controls 2.2 import QtQuick.Controls 2.2
import QtGraphicalEffects 1.0 import QtGraphicalEffects 1.0
import de.itsblue.ScStw.Styling 2.0
import de.itsblue.ScStw.Styling.Components 1.0
Button { Button {
id: control id: control
@ -14,16 +17,16 @@ Button {
property double glowScale: 0.75 property double glowScale: 0.75
property double glowOpacity: Math.pow( control.opacity, 100 ) property double glowOpacity: Math.pow( control.opacity, 100 )
Behavior on text {
//animate a text change
//scale: control.pressed ? 0.8:1 enabled: true
FadeAnimation {
Behavior on scale { target: text
PropertyAnimation {
duration: 100
} }
} }
contentItem: Item {}
background: Item { background: Item {
id: controlBackgroundContainer id: controlBackgroundContainer
@ -56,6 +59,26 @@ Button {
} }
} }
Text {
id: text
anchors.centerIn: parent
anchors.verticalCenterOffset: -height * 0.05
height: parent.height * 0.6
width: parent.width * 0.6
fontSizeMode: Text.Fit
font.pixelSize: Math.max(parent.height * 0.16, parent.width * 0.16)
font.family: "Helvetica"
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
text: control.text
color: enabled ? appTheme.theme.colors.text:appTheme.theme.colors.disabledText
}
Image { Image {
id: buttonIcon id: buttonIcon
source: control.image source: control.image

View file

@ -0,0 +1,48 @@
import QtQuick 2.0
import QtQuick.Controls 2.0
import QtGraphicalEffects 1.0
import QtQuick.Layouts 1.0
Rectangle {
id: control
property double size: sizes[sizeMode]
property string sizeMode: "small"
property var sizes: {
"tiny": 0,
"small": 0.15,
"medium": 0.25,
"large": 0.8
}
Layout.preferredHeight: app.landscape() ? app.height : app.height * size
Layout.preferredWidth: app.landscape() ? app.width * size : app.width
Behavior on size {
NumberAnimation {
duration: 3000
easing.type: Easing.InOutQuad
}
}
RectangularGlow {
glowRadius: 7
spread: 0.02
color: "black"
opacity: 0.18
anchors.fill: headerBackgroundRectangle
scale: 1
}
Rectangle {
id: headerBackgroundRectangle
anchors.fill: parent
color: appTheme.theme.colors.menu
Behavior on color {
ColorAnimation {
duration: 200
}
}
}
}

894
resources/qml/main.old.qml Normal file
View file

@ -0,0 +1,894 @@
/*
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 QtGraphicalEffects 1.0
import "."
import "./components"
import "./ProfilesDialog"
import "./SettingsDialog"
//import QtQuick.Layouts 1.11
import de.itsblue.ScStw 2.0
import de.itsblue.ScStw.Styling 2.0
import de.itsblue.ScStw.Styling.Components 1.0
import de.itsblue.ScStwApp 2.0
Window {
visible: true
width: 540
height: 960
title: "ScStwApp"
property date currentTime: new Date()
property int millis: 0
Page {
id:app
anchors.fill: parent
//set default state to IDLE
state: ScStwRace.IDLE
Rectangle {
id: backgroundRect
anchors.fill: parent
color: appTheme.theme.colors.background
Behavior on color {
ColorAnimation {
duration: 200
}
}
}
ScStw {
id: scStw
}
SpeedBackend {
id: speedBackend
}
Connections {
target: speedBackend.race
onStateChanged: {
var stateString
console.log("race state changed to: " + speedBackend.race.state)
switch (speedBackend.race.state){
case ScStwRace.IDLE:
stateString = "IDLE"
break;
case ScStwRace.PREPAIRING:
stateString = "PREPAIRING"
settingsDialog.close()
profilesDialog.close()
break;
case ScStwRace.WAITING:
stateString = "WAITING"
settingsDialog.close()
profilesDialog.close()
break;
case ScStwRace.STARTING:
stateString = "STARTING"
settingsDialog.close()
profilesDialog.close()
break;
case ScStwRace.WAITING:
stateString = "WAITING"
settingsDialog.close()
profilesDialog.close()
break;
case ScStwRace.RUNNING:
stateString = "RUNNING"
settingsDialog.close()
profilesDialog.close()
break;
case ScStwRace.STOPPED:
stateString = "STOPPED"
settingsDialog.close()
profilesDialog.close()
break;
case ScStwRace.INCIDENT:
stateString = "INCIDENT"
settingsDialog.close()
profilesDialog.close()
break;
}
app.state = stateString
}
}
ScStwAppThemeManager {
id: appTheme
property ScStwSetting setting: speedBackend.settings.getSetting(ScStwAppSettings.AppThemeSetting, ScStwAppSettings.KeyLevel)
themeName: setting.value
}
/*------------------------
Timer text an upper line
------------------------*/
RectangularGlow {
id: effect_2
glowRadius: 7
spread: 0.02
color: "black"
opacity: 0.18
anchors.fill: topContainerItm
scale: 1
}
Item {
id: topContainerItm
anchors {
top: parent.top
left: parent.left
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
}
Rectangle {
anchors.fill: parent
color: appTheme.theme.colors.menu
Behavior on color {
ColorAnimation {
duration: 200
}
}
}
Text {
id: topLa
anchors.centerIn: parent
opacity: ( speedBackend.race.state < ScStwRace.RUNNING ) ? 1:0
width: parent.width * 0.7
height: parent.height * 0.7
text: ""
color: appTheme.theme.colors.text
fontSizeMode: Text.Fit
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
font.pixelSize: app.landscape() ? app.width * 0.15 : app.height * 0.4
minimumPixelSize: 1
Behavior on text {
FadeAnimation{
target: topLa
fadeDuration: 100
}
}
}
TimerColumn {
anchors.fill: parent
anchors.topMargin: app.landscape() ? 0:parent.height * 0.1
anchors.bottomMargin: app.landscape() ? 0:parent.height * 0.1
timers: speedBackend.race.timers
colors: appTheme.theme.colors
fontName: appTheme.theme.fonts.timers
showTimerLetter: speedBackend.race.state === ScStwRace.STOPPED
// make text smaller for much better performance
textScale: app.landscape() ? 0.7 : 0.5
opacity: ( speedBackend.race.state < ScStwRace.RUNNING ) ? 0:1
Behavior on opacity {
NumberAnimation {
duration: 200
}
}
}
Behavior on opacity {
NumberAnimation {
duration: 200
}
}
}
Item {
id: connectionIconContainer
anchors {
top: parent.top
left: parent.left
right: parent.right
bottom: parent.bottom
bottomMargin: app.landscape() ? 0:parent.height * 0.8
rightMargin: app.landscape() ? parent.width * 0.8:0
}
opacity: speedBackend.race.state === ScStwRace.IDLE ? 1:0
ConnectionIcon {
id: baseConnConnIcon
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)
source: appTheme.theme.images.baseStationIcon
anchors {
top: parent.top
topMargin: 10
left: parent.left
leftMargin: 10
}
scale: 1.3
height: !app.landscape()? parent.height*0.3:parent.width*0.3
}
Row {
id: extensionStatusRow
anchors {
top: parent.top
topMargin: 10
left: baseConnConnIcon.right
leftMargin: 1
}
height: baseConnConnIcon.height * 0.4
spacing: 5
Repeater {
id: extensionStatusRep
model: Object.keys(speedBackend.scStwClient.extensions)
delegate: Rectangle {
property string thisLetter: modelData
width: height
height: parent.height
radius: width * 0.1
color: appTheme.theme.colors.success // TODO
Component.onCompleted: {
refreshConnectionState()
}
function refreshConnectionState() {
var extensions = speedBackend.scStwClient.extensions[modelData]
for(var i = 0; i < extensions.length; i++) {
console.log(JSON.stringify(extensions[i]))
// TODO!!
}
}
Text {
anchors.fill: parent
text: parent.thisLetter
fontSizeMode: Text.Fit
font.pixelSize: height
font.bold: true
color: appTheme.theme.colors.background
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
}
}
}
}
Behavior on opacity {
NumberAnimation {
duration: 200
}
}
}
Rectangle {
id: upper_line
width: app.landscape() ? 1:parent.width
height: app.landscape() ? parent.height:1
color: appTheme.theme.colors.line
anchors.left: app.landscape() ? topContainerItm.right:parent.left
anchors.top: app.landscape() ? parent.top:topContainerItm.bottom
anchors.bottom: app.landscape() ? parent.bottom:undefined
visible: false
}
// ----------------------------------
// -- Start / Stop / Reset button ---
// ----------------------------------
DelayButton {
id : startButt
text: "start"
property int size: app.landscape() ? parent.width * 0.5:parent.height * 0.5
property color backgroundColor: appTheme.theme.colors.button
property bool progressControlActivated: speedBackend.scStwClient.state === ScStwClient.CONNECTED && app.state === "RUNNING"
delay: progressControlActivated ? 2000:0
anchors {
bottom: parent.bottom
bottomMargin: app.height * 0.5 - height * 0.5
right: parent.right
rightMargin: app.width * 0.5 - width * 0.5
}
height: app.landscape() ? Math.min(size, parent.height * 0.9) : Math.min(size, parent.width * 0.9)
width: height
Text {
id: startButt_text
text: startButt.text
anchors.centerIn: parent
font.pixelSize: parent.height * 0.16
font.family: "Helvetica"
color: enabled ? appTheme.theme.colors.text:appTheme.theme.colors.disabledText
}
Behavior on text {
//animate a text change
enabled: true
FadeAnimation {
target: startButt_text
}
}
onClicked: {
if(startButt.progressControlActivated && progress < 1.0)
return
startButt.progress = 0
switch(app.state) {
case "IDLE":
app.start()
break
case "RUNNING":
app.stop()
break
case "STOPPED":
case "INCIDENT":
app.reset()
break
}
}
contentItem: Text {
}
background: Item {
RectangularGlow {
glowRadius: 0.001
spread: 0.2
color: "black"
visible: true
cornerRadius: startButtBackground.radius
anchors.fill: startButtBackground
scale: 0.75
opacity: Math.pow( startButt.opacity, 100 )
}
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()
}
}
}
}
}
ProgressCircle {
id: prog
property double progress: speedBackend.race.nextStartActionDetails[ScStwRace.NextStartActionDelayProgress]
anchors.fill: startButt
opacity: app.state === "STARTING" ? 1:0
scale: startButt.scale
lineWidth: prog.width * 0.02
arcBegin: 0
arcEnd: 360 * (1 - (progress > 0 ? progress:1))
colorCircle: "grey"
Behavior on opacity {
NumberAnimation {
duration: 200
}
}
animationDuration: 0
}
/*----------------------
Cancel button
----------------------*/
FancyButton {
id: cancelButt
text: "cancel"
anchors {
right: startButt.right
bottom: startButt.bottom
}
contentItem: Text {
//make text disappear
}
height: startButt.height * 0.3
scale: 0
width: height
enabled: app.state === "STARTING"
onClicked: {
app.cancel()
}
Behavior on scale {
PropertyAnimation {
duration: 200
}
}
Text {
id: cancelButt_text
text: cancelButt.text
anchors.centerIn: parent
font.pixelSize: parent.height * 0.16
font.family: "Helvetica"
color: appTheme.theme.colors.text
}
backgroundColor: appTheme.theme.colors.button
}
/*------
Popups
------*/
SettingsDialog{
id: settingsDialog
x: startButt.x
y: startButt.y
width: startButt.width
height: startButt.height
}
ProfilesDialog {
id: profilesDialog
property int margin: app.landscape() ? app.height * 0.05:app.width * 0.05
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
}
/*-------------------
lower line and menu
-------------------*/
Rectangle {
id: lowerLine
width: app.landscape() ? 1:parent.width
height: app.landscape() ? parent.height:1
color: appTheme.theme.colors.line
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
visible: false
}
RectangularGlow {
id: effect
glowRadius: 7
spread: 0.02
color: "black"
opacity: 0.18
anchors.fill: menu_container
scale: 1
}
Item {
id: menu_container
anchors {
bottom: parent.bottom
right: parent.right
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
}
Rectangle {
id: lowerMenuBackground
anchors.fill: parent
color: appTheme.theme.colors.menu
Behavior on color {
ColorAnimation {
duration: 200
}
}
}
Grid {
id: loweMenuGrd
property int spacingMultiplier: 200 * (getActiveChildren() - 1)
property int activeChildren: getActiveChildren()
function getActiveChildren() {
var childrenCount = 0
for (var i = 0; i < children.length; i++)
{
if(children[i].enabled){
childrenCount ++
}
}
return childrenCount
}
anchors.centerIn: parent
height: childrenRect.height
width: childrenRect.width
rows: app.landscape() ? activeChildren:1
columns: app.landscape() ? 1:activeChildren
spacing: 0// app.landscape() ? parent.height * spacingMultiplier * 0.001:parent.width * spacingMultiplier * 0.001
Behavior on spacingMultiplier {
NumberAnimation {
duration: 200
}
}
FancyButton {
id: settingsButt
height: app.landscape() ? menu_container.width * 0.7:menu_container.height * 0.7
width: height
onClicked: {
settingsDialog.open()
}
image: appTheme.theme.images.settIcon
backgroundColor: parent.pressed ? appTheme.theme.colors.buttonPressed:appTheme.theme.colors.button
}
Item {
height: profilesButt.height
width: profilesButt.height
}
FancyButton {
id: profilesButt
enabled: height > 0
state: speedBackend.scStwClient.state === ScStwClient.CONNECTED ? "visible":"hidden"
width: height
onClicked: {
profilesDialog.open()
}
image: appTheme.theme.images.profilesIcon
backgroundColor: parent.pressed ? appTheme.theme.colors.buttonPressed:appTheme.theme.colors.button
states: [
State {
name: "hidden"
PropertyChanges {
target: profilesButt
height: 0
}
},
State {
name: "visible"
PropertyChanges {
target: profilesButt
height: app.landscape() ? menu_container.width * 0.7:menu_container.height * 0.7
}
}
]
transitions: [
Transition {
NumberAnimation {
properties: "height"
}
}
]
}
}
}
/*----------------------
Timer states
----------------------*/
states: [
State {
name: "IDLE"
//state for the start page
PropertyChanges {
target: topContainerItm;
anchors.bottomMargin: app.landscape() ? undefined:parent.height * 0.1;
anchors.rightMargin: app.landscape() ? parent.height * 0.05:0
}
PropertyChanges {
target: startButt;
enabled: true;
text: "start";
size: app.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
}
PropertyChanges {
target: topLa
text: "click start to start"
}
},
State {
name: "PREPAIRING"
//state for the start sequence
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)
}
PropertyChanges { target: cancelButt; scale: 1}
PropertyChanges { target: menu_container; }
PropertyChanges {
target: topLa
text: "At your marks"
}
},
State {
name: "WAITING"
PropertyChanges {
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)
}
PropertyChanges { target: cancelButt; scale: 0; enabled: false}
PropertyChanges { target: menu_container; }
PropertyChanges {
target: topLa
implicitText: "Ready"
}
},
State {
name: "STARTING"
//state for the start sequence
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)
}
PropertyChanges { target: cancelButt; scale: 1}
PropertyChanges { target: menu_container; }
PropertyChanges {
target: topLa
implicitText: "Starting"
}
},
State {
name: "RUNNING"
//state when the timer is running
PropertyChanges { target: startButt; enabled: true;
text: speedBackend.scStwClient.state === ScStwClient.CONNECTED ? "cancel":"stop"
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)
}
PropertyChanges {
target: topLa
implicitText: ""
}
},
State {
name: "STOPPED"
//state when the meassuring is over
PropertyChanges {
target: startButt;
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
}
PropertyChanges {
target: topContainerItm;
anchors.rightMargin: app.landscape() ? 0-startButt.width/2:undefined
anchors.bottomMargin: app.landscape() ? undefined:0-startButt.height/2
}
PropertyChanges {
target: topLa
text: ""
}
},
State {
name: "INCIDENT"
//state when the meassuring is over
PropertyChanges {
target: startButt;
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
}
PropertyChanges {
target: topContainerItm;
anchors.rightMargin: app.landscape() ? 0-startButt.width/2:undefined
anchors.bottomMargin: app.landscape() ? undefined:0-startButt.height/2
}
PropertyChanges {
target: topLa
text: ""
}
}
]
/*----------------------
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 {
from: "STARTING"
to: "RUNNING"
//disable transitions for the RUNNING state
},
Transition {
from: "RUNNING"
to: "WAITING"
//disable transitions for the RUNNING state
}
]*/
/*----------------------
Timer functions
----------------------*/
function landscape(){
return(app.height < app.width)
}
/*----Functions to control the stopwatch----*/
function start(){
var ret = speedBackend.race.start()
if(ret !== 200){
console.log("+ --- error starting race: " + ret)
}
}
function cancel() {
var ret = speedBackend.race.cancel()
if(ret !== 200){
console.log("+ --- error canellingr race: " + ret)
}
}
function stop(){
var ret = speedBackend.race.stop()
if(ret !== 200){
console.log("+ --- error stopping race: " + ret)
}
}
function reset(){
var ret = speedBackend.race.reset()
if(ret !== 200){
console.log("+ --- error resetting race: " + ret)
}
}
}
}

View file

@ -17,13 +17,17 @@
import QtQuick 2.9 import QtQuick 2.9
import QtMultimedia 5.8 import QtMultimedia 5.8
import QtQuick.Window 2.2 import QtQuick.Window 2.0
import QtQuick.Controls 2.2 import QtQuick.Controls 2.12
import QtGraphicalEffects 1.0 import QtGraphicalEffects 1.0
import QtQuick.Layouts 1.0
import "." import "."
import "./components" import "./components"
import "./ProfilesDialog" import "./ProfilesDialog"
import "./SettingsDialog" import "./SettingsDialog"
import "./components/layout"
import "./MainPage"
//import QtQuick.Layouts 1.11 //import QtQuick.Layouts 1.11
import de.itsblue.ScStw 2.0 import de.itsblue.ScStw 2.0
@ -40,11 +44,11 @@ Window {
property int millis: 0 property int millis: 0
Page { Page {
id:app id: app
anchors.fill: parent anchors.fill: parent
//set default state to IDLE //set default state to IDLE
state: "IDLE" state: ScStwRace.IDLE
Rectangle { Rectangle {
id: backgroundRect id: backgroundRect
@ -71,31 +75,12 @@ Window {
onStateChanged: { onStateChanged: {
var stateString var stateString
console.log("race state changed to: " + speedBackend.race.state) console.log("race state changed to: " + speedBackend.race.state)
switch (speedBackend.race.state){
case ScStwRace.IDLE: if(speedBackend.race.state != ScStwRace.IDLE) {
stateString = "IDLE" //settingsDialog.close()
break;
case ScStwRace.STARTING:
stateString = "STARTING"
settingsDialog.close()
profilesDialog.close()
break;
case ScStwRace.WAITING:
stateString = "WAITING"
settingsDialog.close()
profilesDialog.close()
break;
case ScStwRace.RUNNING:
stateString = "RUNNING"
settingsDialog.close()
profilesDialog.close()
break;
case ScStwRace.STOPPED:
stateString = "STOPPED"
settingsDialog.close()
profilesDialog.close()
} }
app.state = stateString
app.state = speedBackend.race.state
} }
} }
@ -105,415 +90,106 @@ Window {
themeName: setting.value themeName: setting.value
} }
/*------------------------ // ---------------
Timer text an upper line // - Main layout -
------------------------*/ // ---------------
RectangularGlow {
id: effect_2
glowRadius: 7
spread: 0.02
color: "black"
opacity: 0.18
anchors.fill: topContainerItm
scale: 1
}
Item { GridLayout {
id: topContainerItm id: mainLayout
anchors {
top: parent.top
left: parent.left
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
}
Rectangle {
anchors.fill: parent
color: appTheme.theme.colors.menu
Behavior on color {
ColorAnimation {
duration: 200
}
}
}
Text {
id: topLa
property string implicitText: ""
anchors.centerIn: parent
opacity: ( speedBackend.race.state < ScStwRace.RUNNING ) ? 1:0
width: parent.width * 0.7
height: parent.height * 0.7
text: implicitText === "NEXT_START_ACTION" ?
["", "at your \nmarks", "ready", "starting..."][speedBackend.race.nextStartActionDetails[ScStwRace.NextStartAction]+1]:implicitText
color: appTheme.theme.colors.text
fontSizeMode: Text.Fit
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
font.pixelSize: app.landscape() ? parent.width * 0.15 : parent.height * 0.4
minimumPixelSize: 1
Behavior on text {
FadeAnimation{
target: topLa
fadeDuration: 100
}
}
}
TimerColumn {
anchors.fill: parent
anchors.topMargin: app.landscape() ? 0:parent.height * 0.1
anchors.bottomMargin: app.landscape() ? 0:parent.height * 0.1
timers: speedBackend.race.timers
colors: appTheme.theme.colors
fontName: appTheme.theme.fonts.timers
showTimerLetter: speedBackend.race.state === ScStwRace.STOPPED
// make text smaller for much better performance
textScale: app.landscape() ? 0.7 : 0.5
opacity: ( speedBackend.race.state < ScStwRace.RUNNING ) ? 0:1
Behavior on opacity {
NumberAnimation {
duration: 200
}
}
}
Behavior on opacity {
NumberAnimation {
duration: 200
}
}
}
Item {
id: connectionIconContainer
anchors {
top: parent.top
left: parent.left
right: parent.right
bottom: parent.bottom
bottomMargin: app.landscape() ? 0:parent.height * 0.8
rightMargin: app.landscape() ? parent.width * 0.8:0
}
opacity: speedBackend.race.state === ScStwRace.IDLE ? 1:0
ConnectionIcon {
id: baseConnConnIcon
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)
source: appTheme.theme.images.baseStationIcon
anchors {
top: parent.top
topMargin: 10
left: parent.left
leftMargin: 10
}
scale: 1.3
height: !app.landscape()? parent.height*0.3:parent.width*0.3
}
Row {
id: extensionStatusRow
anchors {
top: parent.top
topMargin: 10
left: baseConnConnIcon.right
leftMargin: 1
}
height: baseConnConnIcon.height * 0.4
spacing: 5
Repeater {
id: extensionStatusRep
model: Object.keys(speedBackend.scStwClient.extensions)
delegate: Rectangle {
property string thisLetter: modelData
width: height
height: parent.height
radius: width * 0.1
color: appTheme.theme.colors.success // TODO
Component.onCompleted: {
refreshConnectionState()
}
function refreshConnectionState() {
var extensions = speedBackend.scStwClient.extensions[modelData]
for(var i = 0; i < extensions.length; i++) {
console.log(JSON.stringify(extensions[i]))
// TODO!!
}
}
Text {
anchors.fill: parent anchors.fill: parent
text: parent.thisLetter columns: app.landscape() ? 3:1
rows: app.landscape() ? 1:3
fontSizeMode: Text.Fit TopToolBar {
font.pixelSize: height id: topToolBar
font.bold: true
color: appTheme.theme.colors.background state: app.state
verticalAlignment: Text.AlignVCenter sizeMode: "large"
horizontalAlignment: Text.AlignHCenter
} }
}
} CenterContent {
id: centerContent
state: app.state
Layout.fillWidth: true
Layout.fillHeight: true
} }
Behavior on opacity { BottomToolBar {
NumberAnimation { id: bottomToolBar
duration: 200
} sizeMode: "tiny"
} }
} }
Rectangle { states: [
id: upper_line State {
width: app.landscape() ? 1:parent.width name: ScStwRace.IDLE
height: app.landscape() ? parent.height:1
color: appTheme.theme.colors.line PropertyChanges {
anchors.left: app.landscape() ? topContainerItm.right:parent.left target: topToolBar
anchors.top: app.landscape() ? parent.top:topContainerItm.bottom sizeMode: "small"
anchors.bottom: app.landscape() ? parent.bottom:undefined
visible: false
} }
// ---------------------------------- PropertyChanges {
// -- Start / Stop / Reset button --- target: bottomToolBar
// ---------------------------------- sizeMode: "small"
DelayButton { }
id : startButt },
text: "start" State {
property int size: app.landscape() ? parent.width * 0.5:parent.height * 0.5 name: ScStwRace.PREPAIRING
property color backgroundColor: appTheme.theme.colors.button
property bool progressControlActivated: speedBackend.scStwClient.state === ScStwClient.CONNECTED && app.state === "RUNNING"
delay: progressControlActivated ? 2000:0
anchors { PropertyChanges {
bottom: parent.bottom target: topToolBar
bottomMargin: app.height * 0.5 - height * 0.5 sizeMode: "medium"
right: parent.right
rightMargin: app.width * 0.5 - width * 0.5
} }
height: app.landscape() ? Math.min(size, parent.height * 0.9) : Math.min(size, parent.width * 0.9) PropertyChanges {
width: height target: bottomToolBar
sizeMode: "tiny"
}
},
Text { State {
id: startButt_text name: ScStwRace.WAITING
text: startButt.text
anchors.centerIn: parent PropertyChanges {
font.pixelSize: parent.height * 0.16 target: topToolBar
font.family: "Helvetica" sizeMode: "medium"
color: enabled ? appTheme.theme.colors.text:appTheme.theme.colors.disabledText
} }
Behavior on text { PropertyChanges {
//animate a text change target: bottomToolBar
enabled: true sizeMode: "tiny"
FadeAnimation {
target: startButt_text
} }
},
State {
name: ScStwRace.STARTING
PropertyChanges {
target: topToolBar
sizeMode: "medium"
} }
onClicked: { PropertyChanges {
if(startButt.progressControlActivated && progress < 1.0) target: bottomToolBar
return sizeMode: "tiny"
startButt.progress = 0
switch(app.state) {
case "IDLE":
app.start()
break
case "RUNNING":
app.stop()
break
case "STOPPED":
app.reset()
break
} }
} }
]
contentItem: Text {
}
background: Item {
RectangularGlow {
glowRadius: 0.001
spread: 0.2
color: "black"
visible: true
cornerRadius: startButtBackground.radius
anchors.fill: startButtBackground
scale: 0.75
opacity: Math.pow( startButt.opacity, 100 )
}
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()
}
}
}
}
}
ProgressCircle {
id: prog
property double progress: speedBackend.race.nextStartActionDetails[ScStwRace.NextStartActionDelayProgress]
anchors.fill: startButt
opacity: app.state === "STARTING" ? 1:0
scale: startButt.scale
lineWidth: prog.width * 0.02
arcBegin: 0
arcEnd: 360 * (1 - (progress > 0 ? progress:1))
colorCircle: "grey"
Behavior on opacity {
NumberAnimation {
duration: 200
}
}
animationDuration: 0
}
/*----------------------
Cancel button
----------------------*/
FancyButton {
id: cancelButt
text: "cancel"
anchors {
right: startButt.right
bottom: startButt.bottom
}
contentItem: Text {
//make text disappear
}
height: startButt.height * 0.3
scale: 0
width: height
enabled: app.state === "STARTING"
onClicked: {
app.cancel()
}
Behavior on scale {
PropertyAnimation {
duration: 200
}
}
Text {
id: cancelButt_text
text: cancelButt.text
anchors.centerIn: parent
font.pixelSize: parent.height * 0.16
font.family: "Helvetica"
color: appTheme.theme.colors.text
}
backgroundColor: appTheme.theme.colors.button
}
/*------ /*------
Popups Popups
------*/ ------
SettingsDialog{ SettingsDialog{
id: settingsDialog id: settingsDialog
@ -534,157 +210,6 @@ Window {
height: !app.landscape() ? app.height - topContainerItm.height - menu_container.height - margin * 2 : app.height - margin * 2 height: !app.landscape() ? app.height - topContainerItm.height - menu_container.height - margin * 2 : app.height - margin * 2
} }
/*-------------------
lower line and menu
-------------------*/
Rectangle {
id: lowerLine
width: app.landscape() ? 1:parent.width
height: app.landscape() ? parent.height:1
color: appTheme.theme.colors.line
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
visible: false
}
RectangularGlow {
id: effect
glowRadius: 7
spread: 0.02
color: "black"
opacity: 0.18
anchors.fill: menu_container
scale: 1
}
Item {
id: menu_container
anchors {
bottom: parent.bottom
right: parent.right
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
}
Rectangle {
id: lowerMenuBackground
anchors.fill: parent
color: appTheme.theme.colors.menu
Behavior on color {
ColorAnimation {
duration: 200
}
}
}
Grid {
id: loweMenuGrd
property int spacingMultiplier: 200 * (getActiveChildren() - 1)
property int activeChildren: getActiveChildren()
function getActiveChildren() {
var childrenCount = 0
for (var i = 0; i < children.length; i++)
{
if(children[i].enabled){
childrenCount ++
}
}
return childrenCount
}
anchors.centerIn: parent
height: childrenRect.height
width: childrenRect.width
rows: app.landscape() ? activeChildren:1
columns: app.landscape() ? 1:activeChildren
spacing: 0// app.landscape() ? parent.height * spacingMultiplier * 0.001:parent.width * spacingMultiplier * 0.001
Behavior on spacingMultiplier {
NumberAnimation {
duration: 200
}
}
FancyButton {
id: settingsButt
height: app.landscape() ? menu_container.width * 0.7:menu_container.height * 0.7
width: height
onClicked: {
settingsDialog.open()
}
image: appTheme.theme.images.settIcon
backgroundColor: parent.pressed ? appTheme.theme.colors.buttonPressed:appTheme.theme.colors.button
}
Item {
height: profilesButt.height
width: profilesButt.height
}
FancyButton {
id: profilesButt
enabled: height > 0
state: speedBackend.scStwClient.state === ScStwClient.CONNECTED ? "visible":"hidden"
width: height
onClicked: {
profilesDialog.open()
}
image: appTheme.theme.images.profilesIcon
backgroundColor: parent.pressed ? appTheme.theme.colors.buttonPressed:appTheme.theme.colors.button
states: [
State {
name: "hidden"
PropertyChanges {
target: profilesButt
height: 0
}
},
State {
name: "visible"
PropertyChanges {
target: profilesButt
height: app.landscape() ? menu_container.width * 0.7:menu_container.height * 0.7
}
}
]
transitions: [
Transition {
NumberAnimation {
properties: "height"
}
}
]
}
}
}
/*----------------------
Timer states
----------------------*/
states: [ states: [
State { State {
name: "IDLE" name: "IDLE"
@ -696,20 +221,34 @@ Window {
} }
PropertyChanges { PropertyChanges {
target: startButt; target: startButt;
enabled: true; text: "start"; enabled: true;
text: "start";
size: app.landscape() ? parent.width * 0.5:parent.height * 0.5 size: app.landscape() ? parent.width * 0.5:parent.height * 0.5
anchors.bottomMargin: parent.height * 0.5 - startButt.height * 0.5 anchors.bottomMargin: parent.height * 0.5 - startButt.height * 0.5
anchors.rightMargin: parent.width * 0.5 - startButt.width * 0.5 anchors.rightMargin: parent.width * 0.5 - startButt.width * 0.5
} }
PropertyChanges { PropertyChanges {
target: topLa target: topLa
implicitText: "click start to start" text: "click start to start"
} }
}, },
State {
name: "PREPAIRING"
//state for the start sequence
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)
}
PropertyChanges { target: cancelButt; scale: 1}
PropertyChanges { target: menu_container; }
PropertyChanges {
target: topLa
text: "At your marks"
}
},
State { State {
name: "WAITING" name: "WAITING"
//state when a false start occured and waiting for time calculation
PropertyChanges { PropertyChanges {
target: startButt; enabled: false; text: "waiting..."; 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.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)
@ -719,7 +258,7 @@ Window {
PropertyChanges { target: menu_container; } PropertyChanges { target: menu_container; }
PropertyChanges { PropertyChanges {
target: topLa target: topLa
implicitText: "please wait..." implicitText: "Ready"
} }
}, },
State { State {
@ -733,7 +272,7 @@ Window {
PropertyChanges { target: menu_container; } PropertyChanges { target: menu_container; }
PropertyChanges { PropertyChanges {
target: topLa target: topLa
implicitText: "NEXT_START_ACTION" implicitText: "Starting"
} }
}, },
@ -770,13 +309,34 @@ Window {
target: topLa target: topLa
text: "" text: ""
} }
},
State {
name: "INCIDENT"
//state when the meassuring is over
PropertyChanges {
target: startButt;
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
}
PropertyChanges {
target: topContainerItm;
anchors.rightMargin: app.landscape() ? 0-startButt.width/2:undefined
anchors.bottomMargin: app.landscape() ? undefined:0-startButt.height/2
}
PropertyChanges {
target: topLa
text: ""
}
} }
] ]
/*---------------------- /*----------------------
Timer animations Timer animations
----------------------*/ ----------------------*/
transitions: [ /*transitions: [
Transition { Transition {
NumberAnimation { properties: "size,rightMargin,height,width,bottomMargin,font.pixelSize,pixelSize"; easing.type: Easing.InOutQuad; duration: 700 } NumberAnimation { properties: "size,rightMargin,height,width,bottomMargin,font.pixelSize,pixelSize"; easing.type: Easing.InOutQuad; duration: 700 }
}, },
@ -799,7 +359,7 @@ Window {
to: "WAITING" to: "WAITING"
//disable transitions for the RUNNING state //disable transitions for the RUNNING state
} }
] ]*/
/*---------------------- /*----------------------
Timer functions Timer functions

View file

@ -22,5 +22,10 @@
<file>SettingsDialog/SettingsStartSequencePage.qml</file> <file>SettingsDialog/SettingsStartSequencePage.qml</file>
<file>SettingsDialog/SettingsBaseStationPage.qml</file> <file>SettingsDialog/SettingsBaseStationPage.qml</file>
<file>SettingsDialog/SettingsExtensionsPage.qml</file> <file>SettingsDialog/SettingsExtensionsPage.qml</file>
<file>main.old.qml</file>
<file>components/layout/ToolBar.qml</file>
<file>MainPage/TopToolBar.qml</file>
<file>MainPage/CenterContent.qml</file>
<file>MainPage/BottomToolBar.qml</file>
</qresource> </qresource>
</RCC> </RCC>

@ -1 +1 @@
Subproject commit 60fec7dc51b3a61e33ef7cdb30250516021e74f7 Subproject commit 6460714b62b8f7452f112596de01eeef196dcae0

View file

@ -96,8 +96,5 @@ int main(int argc, char *argv[])
if (engine.rootObjects().isEmpty()) if (engine.rootObjects().isEmpty())
return -1; return -1;
int iRet = 0; return app.exec();
iRet = app.exec();
return iRet;
} }

View file

@ -203,6 +203,8 @@ void ScStwAppBackend::reloadRaceSettings() {
this->getRace()->setSoundVolume(1); this->getRace()->setSoundVolume(1);
this->getRace()->setAllowAutomaticTimerDisable(true);
} }
void ScStwAppBackend::reloadBaseStationIpAdress() { void ScStwAppBackend::reloadBaseStationIpAdress() {