]> git.ipfire.org Git - thirdparty/bacula.git/commitdiff
BEE Backport bacula/src/qt-console/tray-monitor/PulseLoader.qml
authorHenrique <henrique.faria@baculasystems.com>
Sat, 16 May 2020 09:41:52 +0000 (11:41 +0200)
committerEric Bollengier <eric@baculasystems.com>
Thu, 29 Apr 2021 08:44:19 +0000 (10:44 +0200)
This commit is the result of the squash of the following main commits:

Author: Henrique <henrique.faria@baculasystems.com>
Date:   Tue Oct 22 21:47:39 2019 -0300

    android: added custom loading animation

bacula/src/qt-console/tray-monitor/PulseLoader.qml [new file with mode: 0644]

diff --git a/bacula/src/qt-console/tray-monitor/PulseLoader.qml b/bacula/src/qt-console/tray-monitor/PulseLoader.qml
new file mode 100644 (file)
index 0000000..356be8b
--- /dev/null
@@ -0,0 +1,151 @@
+import QtQuick 2.10
+
+Item {
+
+    // ----- Public Properties ----- //
+
+    property int radius: 25
+    property bool useDouble: false
+    property bool running: true
+
+    property color color: "white"
+
+    // ----- Private Properties ----- //
+
+    property int _innerRadius: radius * 0.7
+    property int _circleRadius: (radius - _innerRadius) * 0.5
+
+    id: root
+    width: radius * 2
+    height: radius * 2
+    onRunningChanged: {
+        if (running === false) {
+            for (var i = 0; i < repeater.model; i++) {
+                if (repeater.itemAt(i)) {
+                    repeater.itemAt(i).stopAnimation();
+                }
+            }
+        }
+        else {
+            for (var i = 0; i < repeater.model; i++) {
+                if (repeater.itemAt(i)) {
+                    repeater.itemAt(i).playAnimation();
+                }
+            }
+        }
+    }
+
+    Repeater {
+        id: repeater
+        model: root.useDouble ? 10 : 4
+        delegate: Component {
+            Rectangle {
+                // ----- Private Properties ----- //
+                property int _currentAngle: _getStartAngle()
+
+                id: rect
+                width: _getWidth()
+                height: width
+                radius: width
+                color: root.color
+                transformOrigin: Item.Center
+                x: root._getPosOnCircle(_currentAngle).x
+                y: root._getPosOnCircle(_currentAngle).y
+                antialiasing: true
+
+                SequentialAnimation {
+                    id: anim
+                    loops: Animation.Infinite
+
+                    NumberAnimation {
+                        target: rect
+                        property: "_currentAngle"
+                        duration: root.useDouble ? 1800 : 1000
+                        from: rect._getStartAngle()
+                        to: 360 + rect._getStartAngle()
+                        easing.type: Easing.OutQuad
+                    }
+
+                    PauseAnimation { duration: 500 }
+                }
+
+                // ----- Public Functions ----- //
+
+                function playAnimation() {
+                    if (anim.running == false) {
+                        anim.start();
+                    }
+                    else if (anim.paused) {
+                        anim.resume();
+                    }
+                }
+
+                function stopAnimation() {
+                    if (anim.running) {
+                        anim.pause();
+                    }
+                }
+
+                // ----- Private Functions ----- //
+
+                function _getStartAngle() {
+                    var ang = 90;
+                    if (root.useDouble) {
+                        ang = index < 5 ? 90 : 270;
+                    }
+
+                    return ang;
+                }
+
+                function _getWidth() {
+                    var w = (root._circleRadius) * 0.5 * (repeater.model - index);
+                    if (root.useDouble) {
+                        w = (root._circleRadius) * 0.5 * ((repeater.model / 2) - Math.abs(repeater.model / 2 - index))
+                    }
+
+                    return w;
+                }
+            }
+        }
+    }
+
+    Timer {
+        // ----- Private Properties ----- //
+        property int _circleIndex: 0
+
+        id: timer
+        interval: 100
+        repeat: true
+        running: true
+        onTriggered: {
+            var maxIndex = root.useDouble ? repeater.model / 2 : repeater.model;
+            if (_circleIndex === maxIndex) {
+                stop();
+                _circleIndex = 0;
+            }
+            else {
+                repeater.itemAt(_circleIndex).playAnimation();
+                if (root.useDouble) {
+                    repeater.itemAt(repeater.model - _circleIndex - 1).playAnimation();
+                }
+
+                _circleIndex++;
+            }
+        }
+    }
+
+    // ----- Private Functions ----- //
+
+    function _toRadian(degree) {
+        return (degree * 3.14159265) / 180.0;
+    }
+
+    function _getPosOnCircle(angleInDegree) {
+        var centerX = root.width / 2, centerY = root.height / 2;
+        var posX = 0, posY = 0;
+
+        posX = centerX + root._innerRadius * Math.cos(_toRadian(angleInDegree));
+        posY = centerY - root._innerRadius * Math.sin(_toRadian(angleInDegree));
+        return Qt.point(posX, posY);
+    }
+}