Warning, /system/mycroft-gui/import/qml/StatusIndicator.qml is written in an unsupported language. File is not indexed.
0001 /*
0002 * Copyright 2018 by Marco Martin <mart@kde.org>
0003 * Copyright 2018 David Edmundson <davidedmundson@kde.org>
0004 *
0005 * Licensed under the Apache License, Version 2.0 (the "License");
0006 * you may not use this file except in compliance with the License.
0007 * You may obtain a copy of the License at
0008 *
0009 * http://www.apache.org/licenses/LICENSE-2.0
0010 *
0011 * Unless required by applicable law or agreed to in writing, software
0012 * distributed under the License is distributed on an "AS IS" BASIS,
0013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014 * See the License for the specific language governing permissions and
0015 * limitations under the License.
0016 *
0017 */
0018
0019 import QtQuick 2.15
0020 import org.kde.kirigami 2.19 as Kirigami
0021 import Mycroft 1.0 as Mycroft
0022 import Qt5Compat.GraphicalEffects
0023
0024 Item {
0025 id: root
0026 implicitWidth: Kirigami.Units.gridUnit * 5
0027 implicitHeight: width
0028
0029 property bool hasShadow: true
0030
0031 state: "idle"
0032 states: [
0033 State {
0034 name: "idle"
0035 PropertyChanges {
0036 target: innerCircle
0037 graphicsColor: "white"
0038 backgroundColor: "deepskyblue"
0039 }
0040 PropertyChanges {
0041 target: root
0042 opacity: 0
0043 }
0044 StateChangeScript {
0045 script: {
0046 innerCircleRotation.running = false;
0047 innerCircleRotation.to = 0;
0048 innerCircleRotation.loops = 1;
0049 innerCircleRotation.running = true;
0050
0051 outerCircleRotation.loops = 1;
0052 outerCircleRotation.restart();
0053
0054 fadeTimer.running = false;
0055 }
0056 }
0057 },
0058 State {
0059 name: "waiting"
0060 PropertyChanges {
0061 target: innerCircle
0062 graphicsColor: "white"
0063 backgroundColor: "deepskyblue"
0064 }
0065 PropertyChanges {
0066 target: root
0067 opacity: 1
0068 }
0069 StateChangeScript {
0070 script: {
0071 innerCircleRotation.running = false;
0072 innerCircleRotation.to = -360;
0073 innerCircleRotation.loops = 1;
0074 innerCircleRotation.running = true;
0075
0076 outerCircleRotation.loops = 1;
0077 outerCircleRotation.restart();
0078
0079 fadeTimer.running = false;
0080 }
0081 }
0082 },
0083 State {
0084 name: "loading"
0085 PropertyChanges {
0086 target: innerCircle
0087 targetRotation: 0
0088 graphicsColor: "white"
0089 backgroundColor: "deepskyblue"
0090 }
0091 PropertyChanges {
0092 target: root
0093 opacity: 1
0094 }
0095
0096 StateChangeScript {
0097 script: {
0098 innerCircleRotation.running = false;
0099 innerCircleRotation.to = innerCircle.rotation - 360;
0100 innerCircleRotation.loops = Animation.Infinite;
0101 innerCircleRotation.running = true;
0102
0103 outerCircleRotation.loops = Animation.Infinite;
0104 outerCircleRotation.restart();
0105
0106 fadeTimer.running = false;
0107 }
0108 }
0109 },
0110 State {
0111 name: "ok"
0112 PropertyChanges {
0113 target: innerCircle
0114 explicit: true
0115 targetRotation: -90
0116 graphicsColor: Kirigami.Theme.positiveTextColor
0117 backgroundColor: Qt.tint(Kirigami.Theme.backgroundColor, Qt.rgba(Kirigami.Theme.positiveTextColor.r, Kirigami.Theme.positiveTextColor.g, Kirigami.Theme.positiveTextColor.b, 0.4))
0118 }
0119 PropertyChanges {
0120 target: root
0121 opacity: 1
0122 }
0123 StateChangeScript {
0124 script: {
0125 innerCircleRotation.running = false;
0126 innerCircleRotation.to = -90;
0127 innerCircleRotation.loops = 1;
0128 innerCircleRotation.running = true;
0129
0130 outerCircleRotation.loops = 1;
0131 outerCircleRotation.restart();
0132
0133 fadeTimer.restart();
0134 }
0135 }
0136 },
0137 State {
0138 name: "error"
0139 PropertyChanges {
0140 target: innerCircle
0141 explicit: true
0142 graphicsColor: Kirigami.Theme.negativeTextColor
0143 backgroundColor: Qt.tint(Kirigami.Theme.backgroundColor, Qt.rgba(Kirigami.Theme.negativeTextColor.r, Kirigami.Theme.negativeTextColor.g, Kirigami.Theme.negativeTextColor.b, 0.4))
0144 }
0145 PropertyChanges {
0146 target: root
0147 opacity: 1
0148 }
0149 StateChangeScript {
0150 script: {
0151 innerCircleRotation.running = false;
0152 innerCircleRotation.to = 90;
0153 innerCircleRotation.loops = 1;
0154 innerCircleRotation.running = true;
0155
0156 outerCircleRotation.loops = 1;
0157 outerCircleRotation.restart();
0158
0159 fadeTimer.restart();
0160 }
0161 }
0162 }
0163 ]
0164
0165 Connections {
0166 target: Mycroft.MycroftController
0167 function onListeningChanged() {
0168 if (Mycroft.MycroftController.listening) {
0169 root.state = "waiting";
0170 } else {
0171 fadeTimer.restart();
0172 }
0173 }
0174 function onNotUnderstood() {
0175 root.state = "idle"
0176 root.state = "error";
0177 }
0178 function onFallbackTextRecieved(skill, data){
0179 if (skill.length > 0) {
0180 root.state = "ok";
0181 }
0182 }
0183 function onServerReadyChanged() {
0184 if (Mycroft.MycroftController.serverReady) {
0185 root.state = "ok";
0186 }
0187 }
0188 function onStatusChanged(status) {
0189 switch (Mycroft.MycroftController.status) {
0190 case Mycroft.MycroftController.Open:
0191 root.state = Mycroft.MycroftController.serverReady ? "ok" : "loading";
0192 break;
0193 case Mycroft.MycroftController.Connecting:
0194 root.state = "loading";
0195 break;
0196 case Mycroft.MycroftController.Error:
0197 default:
0198 root.state = "error";
0199 break;
0200 }
0201 }
0202 function onCurrentIntentChanged() {
0203 if (Mycroft.MycroftController.currentIntent.length == 0) {
0204 if (root.state == "loading") {
0205 root.state = "idle";
0206 }
0207 } else {
0208 root.state = "loading";
0209 }
0210 }
0211 }
0212
0213 Rectangle {
0214 id: background
0215 anchors.centerIn: parent
0216 width: Math.min(parent.width, parent.height)
0217 height: width
0218 color: innerCircle.backgroundColor
0219 radius: height
0220 layer.enabled: hasShadow
0221 layer.effect: DropShadow {
0222 cached: true
0223 transparentBorder: true
0224 horizontalOffset: 0
0225 verticalOffset: 2
0226 }
0227 }
0228 Behavior on opacity {
0229 OpacityAnimator {
0230 duration: innerCircle.animationLength
0231 easing.type: Easing.InOutCubic
0232 }
0233 }
0234
0235 Rectangle {
0236 id: innerCircleGraphics
0237 anchors {
0238 fill: outerCircle
0239 margins: innerCircle.unit * 5
0240 }
0241 visible: false
0242
0243 color: innerCircle.graphicsColor
0244 radius: width
0245 }
0246 Item {
0247 id: innerCircleMask
0248 visible: false
0249 anchors.fill: innerCircleGraphics
0250
0251 Rectangle {
0252 anchors {
0253 left: parent.left
0254 right: parent.horizontalCenter
0255 top: parent.top
0256 bottom: parent.bottom
0257 }
0258 color: "white"
0259 }
0260 }
0261 OpacityMask {
0262 id: innerCircle
0263 property int unit: Math.max(1, background.width/20)
0264 property color graphicsColor
0265 property color backgroundColor
0266 property int animationLength: 1000
0267 property int targetRotation: 0
0268 Behavior on graphicsColor {
0269 ColorAnimation {
0270 duration: innerCircle.animationLength
0271 easing.type: Easing.InOutCubic
0272 }
0273 }
0274 Behavior on backgroundColor {
0275 ColorAnimation {
0276 duration: innerCircle.animationLength
0277 easing.type: Easing.InOutCubic
0278 }
0279 }
0280 anchors.fill: innerCircleGraphics
0281 source: innerCircleGraphics
0282 maskSource: innerCircleMask
0283
0284 RotationAnimator {
0285 id: innerCircleRotation
0286 target: innerCircle
0287 from: innerCircle.rotation
0288 to: 0
0289 direction: RotationAnimator.Counterclockwise
0290 duration: innerCircle.animationLength
0291 easing.type: Easing.InOutCubic
0292 }
0293 }
0294
0295 Item {
0296 id: outerCircle
0297
0298 anchors {
0299 fill: background
0300 margins: innerCircle.unit * 3
0301 }
0302
0303 // the little dot
0304 Rectangle {
0305 width: innerCircle.unit * 2
0306 height: width
0307 radius: width
0308 color: innerCircle.graphicsColor
0309 anchors.horizontalCenter : parent.horizontalCenter
0310 }
0311 //the circle
0312 Rectangle {
0313 anchors {
0314 fill: parent
0315 margins: innerCircle.unit * 3
0316 }
0317 radius: width
0318 color: "transparent"
0319 border.width: innerCircle.unit
0320 border.color: innerCircle.graphicsColor
0321 }
0322 RotationAnimator {
0323 id: outerCircleRotation
0324 target: outerCircle
0325 from: outerCircle.rotation
0326 to: outerCircle.rotation + 360 - (outerCircle.rotation + 360) % 360
0327 direction: RotationAnimator.Clockwise
0328 duration: innerCircle.animationLength
0329 easing.type: Easing.InOutCubic
0330 }
0331 }
0332 Timer {
0333 id: fadeTimer
0334 interval: 3000
0335 repeat: false
0336 onTriggered: root.state = "idle"
0337 }
0338 }