summary refs log tree commit diff
path: root/resources
diff options
context:
space:
mode:
authorJoseph Donofry <joedonofry@gmail.com>2021-01-11 17:50:26 -0500
committerJoseph Donofry <joedonofry@gmail.com>2021-01-11 17:50:26 -0500
commit1bc2db4bdfe93694452e1a7c129f82294dab8c00 (patch)
tree36ae4d01e6e95a9ba4ad5009549ac2930ba7d2d4 /resources
parentMerge branch 'ci-cleanups-and-experiments' into 'master' (diff)
downloadnheko-1bc2db4bdfe93694452e1a7c129f82294dab8c00.tar.xz
Add Ripple effects to qml buttons and avatar
Diffstat (limited to 'resources')
-rw-r--r--resources/qml/Avatar.qml7
-rw-r--r--resources/qml/ImageButton.qml7
-rw-r--r--resources/qml/ui/Ripple.qml177
-rw-r--r--resources/qml/ui/qmldir2
-rw-r--r--resources/res.qrc1
5 files changed, 194 insertions, 0 deletions
diff --git a/resources/qml/Avatar.qml b/resources/qml/Avatar.qml
index aa873ffe..2801bd37 100644
--- a/resources/qml/Avatar.qml
+++ b/resources/qml/Avatar.qml
@@ -1,3 +1,4 @@
+import "./ui"
 import QtGraphicalEffects 1.0
 import QtQuick 2.6
 import QtQuick.Controls 2.3
@@ -43,6 +44,12 @@ Rectangle {
 
             anchors.fill: parent
             onClicked: TimelineManager.openImageOverlay(TimelineManager.timeline.avatarUrl(userid), TimelineManager.timeline.data.id)
+
+            Ripple {
+                rippleTarget: mouseArea
+                color: Qt.rgba(colors.alternateBase.r, colors.alternateBase.g, colors.alternateBase.b, 0.5)
+            }
+
         }
 
         layer.effect: OpacityMask {
diff --git a/resources/qml/ImageButton.qml b/resources/qml/ImageButton.qml
index 4ebda680..b5a34b7b 100644
--- a/resources/qml/ImageButton.qml
+++ b/resources/qml/ImageButton.qml
@@ -1,3 +1,4 @@
+import "./ui"
 import QtQuick 2.3
 import QtQuick.Controls 2.3
 
@@ -28,4 +29,10 @@ AbstractButton {
         cursorShape: Qt.PointingHandCursor
     }
 
+    Ripple {
+        color: Qt.rgba(buttonTextColor.r, buttonTextColor.g, buttonTextColor.b, 0.5)
+        clip: false
+        rippleTarget: button
+    }
+
 }
diff --git a/resources/qml/ui/Ripple.qml b/resources/qml/ui/Ripple.qml
new file mode 100644
index 00000000..9b404a68
--- /dev/null
+++ b/resources/qml/ui/Ripple.qml
@@ -0,0 +1,177 @@
+import QtGraphicalEffects 1.10
+import QtQuick 2.10
+import QtQuick.Controls 2.3
+
+Item {
+    id: ripple
+
+    property alias clip: backgroundLayer.clip
+    property real radius: 0
+    property color color: "#22000000"
+    property real maxRadius: Math.max(width, height)
+    property real radiusAnimationRate: 0.05
+    property real radiusTailAnimationRate: 0.5
+    property real opacityAnimationDuration: 300
+    readonly property real diameter: radius * 2
+    property real centerX
+    property real centerY
+    property var rippleTarget: parent
+
+    function start() {
+        console.log("Starting ripple animation");
+        ripple.state = "ACTIVE";
+    }
+
+    function stop() {
+        console.log("Stopping ripple animation");
+        ripple.state = "NORMAL";
+    }
+
+    anchors.fill: parent
+    state: "NORMAL"
+    states: [
+        State {
+            name: "NORMAL"
+        },
+        State {
+            name: "ACTIVE"
+        }
+    ]
+    transitions: [
+        Transition {
+            from: "NORMAL"
+            to: "ACTIVE"
+
+            SequentialAnimation {
+                ScriptAction {
+                    script: {
+                        ripple.opacity = 1;
+                        ripple.visible = true;
+                    }
+                }
+
+                NumberAnimation {
+                    id: radius_animation
+
+                    target: ripple
+                    properties: "radius"
+                    from: 0
+                    to: ripple.maxRadius
+                    duration: ripple.maxRadius / ripple.radiusAnimationRate
+
+                    easing {
+                        type: Easing.OutQuad
+                    }
+
+                }
+
+            }
+
+        },
+        Transition {
+            from: "ACTIVE"
+            to: "NORMAL"
+
+            SequentialAnimation {
+                ParallelAnimation {
+                    NumberAnimation {
+                        id: radius_tail_animation
+
+                        target: ripple
+                        properties: "radius"
+                        to: ripple.maxRadius
+                        duration: ripple.maxRadius / ripple.radiusTailAnimationRate
+
+                        easing {
+                            type: Easing.Linear
+                        }
+
+                    }
+
+                    NumberAnimation {
+                        id: opacity_animation
+
+                        target: ripple
+                        properties: "opacity"
+                        to: 0
+                        duration: ripple.opacityAnimationDuration
+
+                        easing {
+                            type: Easing.InQuad
+                        }
+
+                    }
+
+                }
+
+                ScriptAction {
+                    script: {
+                        ripple.visible = false;
+                    }
+                }
+
+            }
+
+        }
+    ]
+
+    Connections {
+        function onPressed(mouse) {
+            // Button
+            // Default to center
+
+            // MouseArea
+            if (mouse) {
+                ripple.centerX = mouse.x;
+                ripple.centerY = mouse.y;
+            } else if (rippleTarget.pressX) {
+                ripple.centerX = rippleTarget.pressX;
+                ripple.centerY = rippleTarget.pressY;
+            } else {
+                ripple.centerX = width / 2;
+                ripple.centerY = height / 2;
+            }
+            ripple.start();
+        }
+
+        function onReleased() {
+            ripple.stop();
+        }
+
+        function onExited() {
+            ripple.stop();
+        }
+
+        function onCanceled() {
+            ripple.stop();
+        }
+
+        function onClicked() {
+            ripple.stop();
+        }
+
+        target: rippleTarget
+        ignoreUnknownSignals: true
+    }
+
+    Rectangle {
+        id: backgroundLayer
+
+        anchors.fill: parent
+        color: "transparent"
+        clip: true
+
+        Rectangle {
+            id: circle
+
+            x: ripple.centerX - ripple.radius
+            y: ripple.centerY - ripple.radius
+            height: ripple.diameter
+            width: ripple.diameter
+            radius: ripple.radius
+            color: ripple.color
+        }
+
+    }
+
+}
diff --git a/resources/qml/ui/qmldir b/resources/qml/ui/qmldir
new file mode 100644
index 00000000..a8466a10
--- /dev/null
+++ b/resources/qml/ui/qmldir
@@ -0,0 +1,2 @@
+module im.nheko.UI
+Ripple 1.0 Ripple.qml
\ No newline at end of file
diff --git a/resources/res.qrc b/resources/res.qrc
index a01907ec..9b05575e 100644
--- a/resources/res.qrc
+++ b/resources/res.qrc
@@ -159,6 +159,7 @@
         <file>qml/device-verification/NewVerificationRequest.qml</file>
         <file>qml/device-verification/Failed.qml</file>
         <file>qml/device-verification/Success.qml</file>
+        <file>qml/ui/Ripple.qml</file>
     </qresource>
     <qresource prefix="/media">
         <file>media/ring.ogg</file>