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 }