From 3467e77679104ca5ff1853da14feca0a6b59a071 Mon Sep 17 00:00:00 2001 From: Dorian Zedler Date: Mon, 5 Oct 2020 20:41:42 +0200 Subject: [PATCH] added a very fancy indicator for timer rady state during waiting state of race --- resources/qml/MainPage/CenterContent.qml | 147 +++++++++++- resources/qml/MainPage/TopToolBar.qml | 4 +- resources/qml/components/MainActionButton.qml | 27 ++- resources/qml/components/StateIndicator.qml | 212 ++++++++++++++++++ resources/qml/qml.qrc | 1 + 5 files changed, 378 insertions(+), 13 deletions(-) create mode 100644 resources/qml/components/StateIndicator.qml diff --git a/resources/qml/MainPage/CenterContent.qml b/resources/qml/MainPage/CenterContent.qml index aa3dc42..cd55662 100644 --- a/resources/qml/MainPage/CenterContent.qml +++ b/resources/qml/MainPage/CenterContent.qml @@ -30,9 +30,105 @@ Item { rows: app.landscape() ? 1:2 Item { - Rectangle { + id: centerExtraContentTop + + property double size + + Layout.preferredHeight: app.landscape() ? centerLayout.height:Math.min(centerLayout.width * size, centerLayout.height * size) + Layout.preferredWidth: app.landscape() ? Math.min(centerLayout.width * size, centerLayout.height * size):centerLayout.width + + + Behavior on size { + NumberAnimation { + duration: 800 + easing.type: Easing.InOutQuart + } + } + + StackView { + id: centerExtraContentTopStack + anchors.fill: parent - color: "green" + anchors.margins: parent.width * 0.1 + + property QtObject newItem: emptyComp + + onNewItemChanged: { + centerExtraContentTopStack.replace(newItem) + } + + replaceEnter: Transition { + SequentialAnimation { + PauseAnimation { + duration: 400 + } + + NumberAnimation { + property: "opacity" + from: 0 + to: 1 + duration: 400 + easing.type: Easing.InOutQuart + } + } + } + + replaceExit: Transition { + NumberAnimation { + property: "opacity" + from: 1 + to: 0 + duration: 400 + easing.type: Easing.InOutQuart + } + } + + + Component { + id: waitingDetailsComp + + Item { + + opacity: 0 + scale: 0.9 + + Row { + anchors.fill: parent + + spacing: centerExtraContentTopStack.anchors.margins + + StateIndicator { + width: parent.width * 0.5 - parent.spacing * 0.5 + height: parent.height + + backgroundColor: appTheme.theme.colors.background + successColor: appTheme.theme.colors.success + + state: speedBackend.race.timers[0]["readyState"] === ScStwTimer.IsReady ? "success":"warn" + + onStateChanged: { + console.log("STATE CHANGED: " + JSON.stringify( speedBackend.race.timers[0])) + } + } + + StateIndicator { + width: parent.width * 0.5 - parent.spacing * 0.5 + height: parent.height + + backgroundColor: appTheme.theme.colors.background + successColor: appTheme.theme.colors.success + + state: speedBackend.race.timers[1]["readyState"] === ScStwTimer.IsReady ? "success":"warn" + } + } + } + } + + Component { + id: emptyComp + Item {} + } + } } @@ -47,7 +143,6 @@ Item { Layout.preferredHeight: app.landscape() ? width:Math.min(centerLayout.width * size, centerLayout.height * size) Layout.preferredWidth: app.landscape() ? Math.min(centerLayout.width * size, centerLayout.height * size):height - onClicked: { if(progressControlActivated && progress < 1.0) return @@ -59,7 +154,7 @@ Item { ret = speedBackend.race.start() break; case ScStwRace.WAITING: - if(!speedBackend.race.readySoundEnabled) + if(!speedBackend.race.readySoundEnabled && speedBackend.race.isReadyForNextState) ret = speedBackend.race.start() else ret = speedBackend.race.cancel() @@ -90,6 +185,23 @@ Item { } } } + + Item { + id: centerExtraContentBottom + + property double size + + Layout.preferredHeight: app.landscape() ? centerLayout.height:Math.min(centerLayout.width * size, centerLayout.height * size) + Layout.preferredWidth: app.landscape() ? Math.min(centerLayout.width * size, centerLayout.height * size):centerLayout.width + + Behavior on size { + NumberAnimation { + duration: 400 + easing.type: Easing.InOutQuart + } + } + } + } states: [ @@ -120,11 +232,30 @@ Item { State { name: ScStwRace.WAITING + PropertyChanges { target: mainActionButton - size: 0.9 - text: speedBackend.race.readySoundEnabled ? "cancel":"ready" - enabled: speedBackend.race.readySoundEnabled ? true:speedBackend.race.isReadyForNextState + size: speedBackend.race.competitionMode ? 0.3:0.9 + text: speedBackend.race.readySoundEnabled ? "cancel": speedBackend.race.isReadyForNextState ? "ready":"cancel" + progressControlActivated: speedBackend.race.competitionMode && !speedBackend.race.readySoundEnabled && !speedBackend.race.isReadyForNextState + } + + PropertyChanges { + target: centerExtraContentTop + + size: speedBackend.race.competitionMode ? 0.7:0 + } + + PropertyChanges { + target: centerExtraContentBottom + + size: speedBackend.race.competitionMode ? 0.05:0 + } + + PropertyChanges { + target: centerExtraContentTopStack + + newItem: speedBackend.race.competitionMode ? waitingDetailsComp:emptyComp } }, @@ -143,7 +274,7 @@ Item { target: mainActionButton size: 0.9 text: speedBackend.race.competitionMode ? "cancel":"stop" - progressControlActivated: speedBackend.scStwClient.state === ScStwClient.CONNECTED && speedBackend.race.competitionMode + progressControlActivated: speedBackend.race.competitionMode } }, diff --git a/resources/qml/MainPage/TopToolBar.qml b/resources/qml/MainPage/TopToolBar.qml index 09ca6a8..d70d4c0 100644 --- a/resources/qml/MainPage/TopToolBar.qml +++ b/resources/qml/MainPage/TopToolBar.qml @@ -204,7 +204,7 @@ ToolBar { PropertyChanges { target: control - statusText: "Press start" + statusText: app.landscape() ? "Press\nstart":"Press start" } PropertyChanges { @@ -278,7 +278,7 @@ ToolBar { PropertyChanges { target: control - statusText: "Technical incident!" + statusText: app.landscape() ? "Technical\nincident!":"Technical incident!" } PropertyChanges { diff --git a/resources/qml/components/MainActionButton.qml b/resources/qml/components/MainActionButton.qml index 4f8f87f..6d0184f 100644 --- a/resources/qml/components/MainActionButton.qml +++ b/resources/qml/components/MainActionButton.qml @@ -13,8 +13,20 @@ DelayButton { property color backgroundColor: appTheme.theme.colors.button property bool progressControlActivated: false property double startProgress + property double oldStartProgress: -1 + delay: progressControlActivated ? 2000:0 + onStartProgressChanged: { + if(startProgress > oldStartProgress) + oldStartProgress = startProgress + else { + startProgressAnimation.from = oldStartProgress + startProgressAnimation.to = startProgress + startProgressAnimation.start() + } + } + Text { id: labelText text: control.text @@ -24,6 +36,15 @@ DelayButton { color: enabled ? appTheme.theme.colors.text:appTheme.theme.colors.disabledText } + NumberAnimation { + id: startProgressAnimation + + to: 0 + target: control + properties: "oldStartProgress" + duration: 200 + } + Behavior on text { //animate a text change enabled: true @@ -74,17 +95,17 @@ DelayButton { Connections { target: control onProgressChanged: canvas.requestPaint() - onStartProgressChanged: canvas.requestPaint() + onOldStartProgressChanged: canvas.requestPaint() } onPaint: { var progress - var showHoldProgress = ((control.startProgress <= 0 || control.startProgress === 1) && control.progressControlActivated) + var showHoldProgress = ((control.oldSartProgress <= 0 || control.oldStartProgress === 1) && control.progressControlActivated) if(showHoldProgress) progress = control.progress else - progress = control.startProgress < 0 ? 0:1-control.startProgress + progress = control.oldStartProgress < 0 ? 0:1-control.oldStartProgress var ctx = getContext("2d") diff --git a/resources/qml/components/StateIndicator.qml b/resources/qml/components/StateIndicator.qml new file mode 100644 index 0000000..0df8dcb --- /dev/null +++ b/resources/qml/components/StateIndicator.qml @@ -0,0 +1,212 @@ +import QtQuick 2.0 + +Rectangle { + id: control + + property color successColor: "green" + property color warningColor: "orange" + property color errorColor: "red" + property color unknownColor: "grey" + property color backgroundColor: "white" + + height: app.height * 0.9 + width: height * 0.8 + + color: backgroundColor + + border.width: Math.min(width * 0.1, height * 0.1) + border.color: "green" + radius: border.width * 0.5 + + state: "success" + + + Rectangle { + id: higherRect + + property int totalWidth: Math.abs(Math.sin(rotation * Math.PI / 180) * (height)) + property int totalHeight: Math.abs(Math.cos(rotation * Math.PI / 180) * (height)) + + radius: width * 0.5 + + color: "green" + + } + + Rectangle { + id: lowerRect + + property int totalWidth: Math.abs(Math.sin(rotation * Math.PI / 180) * (height)) + property int totalHeight: Math.abs(Math.cos(rotation * Math.PI / 180) * (height)) + + radius: width * 0.5 + + color: "green" + } + + states: [ + State { + name: "unknown" + PropertyChanges { + target: control + border.color: control.unknownColor + } + + PropertyChanges { + target: higherRect + + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + + width: control.border.width + height: Math.min(parent.width * 0.7, parent.height * 0.7) + + color: control.unknownColor + + rotation: 90 + } + + PropertyChanges { + target: lowerRect + + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + + width: control.border.width + height: Math.min(parent.width * 0.7, parent.height * 0.7) + + color: control.unknownColor + + rotation: -90 + } + }, + + State { + name: "error" + PropertyChanges { + target: control + border.color: control.errorColor + } + + PropertyChanges { + target: higherRect + + x: (parent.width - width) / 2 + y: parent.height * 0.15 + + width: control.border.width + height: parent.height * 0.5 + + color: control.errorColor + } + + PropertyChanges { + target: lowerRect + + x: (parent.width - width) / 2 + y: parent.height - (parent.height * 0.15 + height) + + width: control.border.width * 1.3 + height: width + + color: control.errorColor + } + }, + + State { + name: "warn" + PropertyChanges { + target: control + border.color: control.warningColor + } + + PropertyChanges { + target: higherRect + + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + + width: control.border.width + height: Math.min(parent.width * 0.7, parent.height * 0.7) + + color: control.warningColor + + rotation: 45 + } + + PropertyChanges { + target: lowerRect + + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + + width: control.border.width + height: Math.min(parent.width * 0.7, parent.height * 0.7) + + color: control.warningColor + + rotation: -45 + } + }, + + State { + id: tickState + + property int bottomX: (control.width) / 2 - (higherRect.totalWidth - (lowerRect.totalWidth + higherRect.totalWidth) / 2 ) + property int bottomY: (control.height + higherRect.totalHeight) / 2 - lowerRect.radius + + name: "success" + + PropertyChanges { + target: control + border.color: control.successColor + } + + PropertyChanges { + target: higherRect + + x: tickState.bottomX - width / 2 + (Math.sin(rotation * Math.PI / 180) * (height / 2 - radius)) + y: tickState.bottomY - height / 2 - (Math.cos(rotation * Math.PI / 180) * (height / 2 - radius)) + + width: control.border.width + height: Math.min(parent.width * 0.6, parent.height * 0.6) + + rotation: 40 + + color: control.successColor + } + + PropertyChanges { + target: lowerRect + + x: tickState.bottomX - width / 2 + (Math.sin(rotation * Math.PI / 180) * (height / 2 - radius)) + y: tickState.bottomY - height / 2 - (Math.cos(rotation * Math.PI / 180) *(height / 2 - radius)) + + width: control.border.width + height: Math.min(parent.width * 0.3, parent.height * 0.3) + + rotation: -40 + + color: control.successColor + } + } + ] + + transitions: [ + Transition { + NumberAnimation { + properties: "height,width,rotation,x,y" + duration: 400 + easing.type: Easing.InOutQuad + } + + + ColorAnimation { + properties: "color,border.color" + duration: 400 + easing.type: Easing.InOutQuad + } + } + ] + +} diff --git a/resources/qml/qml.qrc b/resources/qml/qml.qrc index 6c9beb7..657e4b6 100644 --- a/resources/qml/qml.qrc +++ b/resources/qml/qml.qrc @@ -28,5 +28,6 @@ MainPage/CenterContent.qml MainPage/BottomToolBar.qml components/MainActionButton.qml + components/StateIndicator.qml