OpenVoiceOS/buildroot-external/package/mycroft-gui/StatusIndicator.qml

341 lines
10 KiB
QML

/*
* Copyright 2018 by Marco Martin <mart@kde.org>
* Copyright 2018 David Edmundson <davidedmundson@kde.org>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import QtQuick 2.9
import QtGraphicalEffects 1.0
import org.kde.kirigami 2.5 as Kirigami
import Mycroft 1.0 as Mycroft
Item {
id: root
implicitWidth: Kirigami.Units.gridUnit * 5
implicitHeight: width
property var circleBackgroundColor: "#F5F5F5"
property var circleInnerColor: "#CD5C5C"
property bool hasShadow: true
state: "idle"
states: [
State {
name: "idle"
PropertyChanges {
target: innerCircle
graphicsColor: circleInnerColor
backgroundColor: circleBackgroundColor
}
PropertyChanges {
target: root
opacity: 0
}
StateChangeScript {
script: {
innerCircleRotation.running = false;
innerCircleRotation.to = 0;
innerCircleRotation.loops = 1;
innerCircleRotation.running = true;
outerCircleRotation.loops = 1;
outerCircleRotation.restart();
fadeTimer.running = false;
}
}
},
State {
name: "waiting"
PropertyChanges {
target: innerCircle
graphicsColor: circleInnerColor
backgroundColor: circleBackgroundColor
}
PropertyChanges {
target: root
opacity: 1
}
StateChangeScript {
script: {
innerCircleRotation.running = false;
innerCircleRotation.to = -360;
innerCircleRotation.loops = 1;
innerCircleRotation.running = true;
outerCircleRotation.loops = 1;
outerCircleRotation.restart();
fadeTimer.running = false;
}
}
},
State {
name: "loading"
PropertyChanges {
target: innerCircle
targetRotation: 0
graphicsColor: circleInnerColor
backgroundColor: circleBackgroundColor
}
PropertyChanges {
target: root
opacity: 1
}
StateChangeScript {
script: {
innerCircleRotation.running = false;
innerCircleRotation.to = innerCircle.rotation - 360;
innerCircleRotation.loops = Animation.Infinite;
innerCircleRotation.running = true;
outerCircleRotation.loops = Animation.Infinite;
outerCircleRotation.restart();
fadeTimer.running = false;
}
}
},
State {
name: "ok"
PropertyChanges {
target: innerCircle
explicit: true
targetRotation: -90
graphicsColor: Kirigami.Theme.positiveTextColor
backgroundColor: Qt.tint(Kirigami.Theme.backgroundColor, Qt.rgba(Kirigami.Theme.positiveTextColor.r, Kirigami.Theme.positiveTextColor.g, Kirigami.Theme.positiveTextColor.b, 0.4))
}
PropertyChanges {
target: root
opacity: 1
}
StateChangeScript {
script: {
innerCircleRotation.running = false;
innerCircleRotation.to = -90;
innerCircleRotation.loops = 1;
innerCircleRotation.running = true;
outerCircleRotation.loops = 1;
outerCircleRotation.restart();
fadeTimer.restart();
}
}
},
State {
name: "error"
PropertyChanges {
target: innerCircle
explicit: true
graphicsColor: "white"
backgroundColor: Qt.tint(Kirigami.Theme.backgroundColor, Qt.rgba(Kirigami.Theme.negativeTextColor.r, Kirigami.Theme.negativeTextColor.g, Kirigami.Theme.negativeTextColor.b, 0.4))
}
PropertyChanges {
target: root
opacity: 1
}
StateChangeScript {
script: {
innerCircleRotation.running = false;
innerCircleRotation.to = 90;
innerCircleRotation.loops = 1;
innerCircleRotation.running = true;
outerCircleRotation.loops = 1;
outerCircleRotation.restart();
fadeTimer.restart();
}
}
}
]
Connections {
target: Mycroft.MycroftController
onListeningChanged: {
if (Mycroft.MycroftController.listening) {
root.state = "waiting";
} else {
fadeTimer.restart();
}
}
onNotUnderstood: {
root.state = "idle"
root.state = "error";
}
onFallbackTextRecieved: {
if (skill.length > 0) {
root.state = "ok";
}
}
onServerReadyChanged: {
if (Mycroft.MycroftController.serverReady) {
root.state = "ok";
}
}
onStatusChanged: {
switch (Mycroft.MycroftController.status) {
case Mycroft.MycroftController.Open:
root.state = Mycroft.MycroftController.serverReady ? "ok" : "loading";
break;
case Mycroft.MycroftController.Connecting:
root.state = "loading";
break;
case Mycroft.MycroftController.Error:
default:
root.state = "error";
break;
}
}
onCurrentIntentChanged: {
if (Mycroft.MycroftController.currentIntent.length == 0) {
if (root.state == "loading") {
root.state = "idle";
}
} else {
root.state = "loading";
}
}
}
Rectangle {
id: background
anchors.centerIn: parent
width: Math.min(parent.width, parent.height)
height: width
color: innerCircle.backgroundColor
radius: height
layer.enabled: hasShadow
layer.effect: DropShadow {
cached: true
transparentBorder: true
horizontalOffset: 0
verticalOffset: 2
}
}
Behavior on opacity {
OpacityAnimator {
duration: innerCircle.animationLength
easing.type: Easing.InOutCubic
}
}
Rectangle {
id: innerCircleGraphics
anchors {
fill: outerCircle
margins: innerCircle.unit * 5
}
visible: false
color: innerCircle.graphicsColor
radius: width
}
Item {
id: innerCircleMask
visible: false
anchors.fill: innerCircleGraphics
Rectangle {
anchors {
left: parent.left
right: parent.horizontalCenter
top: parent.top
bottom: parent.bottom
}
color: "white"
}
}
OpacityMask {
id: innerCircle
property int unit: Math.max(1, background.width/20)
property color graphicsColor
property color backgroundColor
property int animationLength: 1000
property int targetRotation: 0
Behavior on graphicsColor {
ColorAnimation {
duration: innerCircle.animationLength
easing.type: Easing.InOutCubic
}
}
Behavior on backgroundColor {
ColorAnimation {
duration: innerCircle.animationLength
easing.type: Easing.InOutCubic
}
}
anchors.fill: innerCircleGraphics
source: innerCircleGraphics
maskSource: innerCircleMask
RotationAnimator {
id: innerCircleRotation
target: innerCircle
from: innerCircle.rotation
to: 0
direction: RotationAnimator.Counterclockwise
duration: innerCircle.animationLength
easing.type: Easing.InOutCubic
}
}
Item {
id: outerCircle
anchors {
fill: background
margins: innerCircle.unit * 3
}
// the little dot
Rectangle {
width: innerCircle.unit * 2
height: width
radius: width
color: innerCircle.graphicsColor
anchors.horizontalCenter : parent.horizontalCenter
}
//the circle
Rectangle {
anchors {
fill: parent
margins: innerCircle.unit * 3
}
radius: width
color: "transparent"
border.width: innerCircle.unit
border.color: innerCircle.graphicsColor
}
RotationAnimator {
id: outerCircleRotation
target: outerCircle
from: outerCircle.rotation
to: outerCircle.rotation + 360 - (outerCircle.rotation + 360) % 360
direction: RotationAnimator.Clockwise
duration: innerCircle.animationLength
easing.type: Easing.InOutCubic
}
}
Timer {
id: fadeTimer
interval: 3000
repeat: false
onTriggered: root.state = "idle"
}
}