summary refs log tree commit diff
path: root/resources/qml/ui
diff options
context:
space:
mode:
authorJoseph Donofry <joedonofry@gmail.com>2021-11-09 22:17:00 -0500
committerJoseph Donofry <joedonofry@gmail.com>2021-11-09 22:17:00 -0500
commitc1c9c71b08915a27538e34e422255d53b7bf1fdf (patch)
treee64f9f987461333672e012ea0c52fecb7f2ae77c /resources/qml/ui
parentInitial Refactoring into separate controls (diff)
downloadnheko-c1c9c71b08915a27538e34e422255d53b7bf1fdf.tar.xz
Move rest of controls to separate file
Diffstat (limited to 'resources/qml/ui')
-rw-r--r--resources/qml/ui/media/MediaControls.qml141
-rw-r--r--resources/qml/ui/media/VolumeControl.qml67
-rw-r--r--resources/qml/ui/media/qmldir3
3 files changed, 178 insertions, 33 deletions
diff --git a/resources/qml/ui/media/MediaControls.qml b/resources/qml/ui/media/MediaControls.qml
new file mode 100644
index 00000000..de3e98a7
--- /dev/null
+++ b/resources/qml/ui/media/MediaControls.qml
@@ -0,0 +1,141 @@
+// SPDX-FileCopyrightText: 2021 Nheko Contributors
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+import QtMultimedia 5.15
+import QtQuick 2.15
+import QtQuick.Controls 2.15
+import QtQuick.Layouts 1.2
+import im.nheko 1.0
+
+Item {
+    id: control
+
+    property alias desiredVolume: volumeSlider.desiredVolume
+    property alias muted: volumeSlider.muted
+    property alias volumeOrientation: volumeSlider.orientation
+    property var mediaState
+    property bool mediaLoaded: false
+    property var duration
+    property var positionValue: 0
+    property var position
+    property int controlHeight: 25
+    property bool shouldShowControls: playerMouseArea.shouldShowControls || volumeSlider.controlsVisible
+
+    signal activated(real mouseX, real mouseY)
+
+    function durationToString(duration) {
+        function maybeZeroPrepend(time) {
+            return (time < 10) ? "0" + time.toString() : time.toString();
+        }
+
+        var totalSeconds = Math.floor(duration / 1000);
+        var seconds = totalSeconds % 60;
+        var minutes = (Math.floor(totalSeconds / 60)) % 60;
+        var hours = (Math.floor(totalSeconds / (60 * 24))) % 24;
+        // Always show minutes and don't prepend zero into the leftmost element
+        var ss = maybeZeroPrepend(seconds);
+        var mm = (hours > 0) ? maybeZeroPrepend(minutes) : minutes.toString();
+        var hh = hours.toString();
+        if (hours < 1)
+            return mm + ":" + ss;
+
+        return hh + ":" + mm + ":" + ss;
+    }
+
+    MouseArea {
+        id: playerMouseArea
+
+        property bool shouldShowControls: (containsMouse && controlHideTimer.running) || (control.mediaState != MediaPlayer.PlayingState) || controlRect.contains(mapToItem(controlRect, mouseX, mouseY))
+
+        onClicked: control.activated(mouseX, mouseY)
+        hoverEnabled: true
+        onPositionChanged: controlHideTimer.start()
+        onExited: controlHideTimer.start()
+        onEntered: controlHideTimer.start()
+        anchors.fill: control
+        propagateComposedEvents: true
+    }
+
+    Rectangle {
+        id: controlRect
+
+        // Window color with 128/255 alpha
+        color: {
+            var wc = Nheko.colors.alternateBase;
+            return Qt.rgba(wc.r, wc.g, wc.b, 0.5);
+        }
+        anchors.bottom: control.bottom
+        anchors.left: control.left
+        anchors.right: control.right
+        height: 40
+        opacity: control.shouldShowControls ? 1 : 0
+
+        RowLayout {
+            anchors.fill: parent
+            width: parent.width
+
+            // Play/pause button
+            Image {
+                id: playbackStateImage
+
+                property color controlColor: (playbackStateArea.containsMouse) ? Nheko.colors.highlight : Nheko.colors.text
+
+                fillMode: Image.PreserveAspectFit
+                Layout.preferredHeight: control.controlHeight
+                Layout.alignment: Qt.AlignVCenter
+                source: (control.mediaState == MediaPlayer.PlayingState) ? "image://colorimage/:/icons/icons/ui/pause-symbol.png?" + controlColor : "image://colorimage/:/icons/icons/ui/play-sign.png?" + controlColor
+
+                MouseArea {
+                    id: playbackStateArea
+
+                    anchors.fill: parent
+                    hoverEnabled: true
+                    onClicked: control.activated(mouseX, mouseY)
+                }
+
+            }
+
+            Label {
+                text: (!control.mediaLoaded) ? "-/-" : (durationToString(control.positionValue) + "/" + durationToString(control.duration))
+                color: Nheko.colors.text
+            }
+
+            Slider {
+                Layout.fillWidth: true
+                Layout.minimumWidth: 50
+                height: control.controlHeight
+                value: control.positionValue
+                onMoved: control.position = value
+                from: 0
+                to: control.duration
+            }
+
+            VolumeControl {
+                id: volumeSlider
+
+                Layout.rightMargin: 5
+                Layout.preferredHeight: control.controlHeight
+            }
+
+        }
+
+        // Fade controls in/out
+        Behavior on opacity {
+            OpacityAnimator {
+                duration: 100
+            }
+
+        }
+
+    }
+
+    // For hiding controls on stationary cursor
+    Timer {
+        id: controlHideTimer
+
+        interval: 1500 //ms
+        repeat: false
+    }
+
+}
diff --git a/resources/qml/ui/media/VolumeControl.qml b/resources/qml/ui/media/VolumeControl.qml
index b826dfc6..cd844ed5 100644
--- a/resources/qml/ui/media/VolumeControl.qml
+++ b/resources/qml/ui/media/VolumeControl.qml
@@ -5,101 +5,104 @@
 import QtMultimedia 5.15
 import QtQuick 2.15
 import QtQuick.Controls 2.15
-
 import im.nheko 1.0
 
 // Volume slider activator
 Image {
+    // TODO: add icons for different volume levels
+    id: volumeImage
+
     property alias desiredVolume: volumeSlider.desiredVolume
     property alias orientation: volumeSlider.orientation
     property alias controlsVisible: volumeSliderRect.visible
     property bool muted: false
-    property color controlColor: (volumeImageArea.containsMouse) ?
-    Nheko.colors.highlight : Nheko.colors.text
-
-    // TODO: add icons for different volume levels
-    id: volumeImage
-    source: (desiredVolume > 0 && !muted) ?
-    "image://colorimage/:/icons/icons/ui/volume-up.png?"+ controlColor :
-    "image://colorimage/:/icons/icons/ui/volume-off-indicator.png?"+ controlColor
+    property color controlColor: (volumeImageArea.containsMouse) ? Nheko.colors.highlight : Nheko.colors.text
 
+    source: (desiredVolume > 0 && !muted) ? "image://colorimage/:/icons/icons/ui/volume-up.png?" + controlColor : "image://colorimage/:/icons/icons/ui/volume-off-indicator.png?" + controlColor
     fillMode: Image.PreserveAspectFit
 
     MouseArea {
-        id: volumeImageArea	
+        id: volumeImageArea
+
         anchors.fill: parent
         hoverEnabled: true
         onExited: volumeSliderHideTimer.start()
         onPositionChanged: volumeSliderHideTimer.start()
         onClicked: volumeImage.muted = !volumeImage.muted
+
         // For hiding volume slider after a while
         Timer {
             id: volumeSliderHideTimer
+
             interval: 1500
             repeat: false
             running: false
         }
+
     }
+
     Rectangle {
         id: volumeSliderRect
+
         opacity: (visible) ? 1 : 0
-        Behavior on opacity {
-            OpacityAnimator {
-                duration: 100
-            }
-        }
-        // TODO: figure out a better way to put the slider popup above controlRect
         anchors.bottom: volumeImage.top
         anchors.bottomMargin: 10
         anchors.horizontalCenter: volumeImage.horizontalCenter
         color: {
-            var wc = Nheko.colors.window
-            return Qt.rgba(wc.r, wc.g, wc.b, 0.5)
+            var wc = Nheko.colors.window;
+            return Qt.rgba(wc.r, wc.g, wc.b, 0.5);
         }
         /* TODO: base width on the slider width (some issue with it not having a geometry
         when using the width here?) */
         width: volumeImage.width * 0.7
         radius: volumeSlider.width / 2
         height: controlRect.height * 2 //100
-        visible: volumeImageArea.containsMouse ||
-        volumeSliderHideTimer.running ||
-        volumeSliderRectMouseArea.containsMouse
+        visible: volumeImageArea.containsMouse || volumeSliderHideTimer.running || volumeSliderRectMouseArea.containsMouse
+
         Slider {
             // TODO: the slider is slightly off-center on the left for some reason...
             id: volumeSlider
 
-            value: 1.0
             // Desired value to avoid loop onMoved -> media.volume -> value -> onMoved...
-            property real desiredVolume: QtMultimedia.convertVolume(volumeSlider.value,
-            QtMultimedia.LogarithmicVolumeScale,
-            QtMultimedia.LinearVolumeScale)
+            property real desiredVolume: QtMultimedia.convertVolume(volumeSlider.value, QtMultimedia.LogarithmicVolumeScale, QtMultimedia.LinearVolumeScale)
 
-            anchors.fill: parent
+            value: 1
+            anchors.fill: volumeSliderRect
             anchors.bottomMargin: volumeSliderRect.height * 0.1
             anchors.topMargin: volumeSliderRect.height * 0.1
             anchors.horizontalCenter: volumeSliderRect.horizontalCenter
             orientation: Qt.Vertical
             onDesiredVolumeChanged: {
-                volumeImage.muted = !(desiredVolume > 0.0)
+                volumeImage.muted = !(desiredVolume > 0);
             }
-
         }
         // Used for resetting the timer on mouse moves on volumeSliderRect
+
         MouseArea {
             id: volumeSliderRectMouseArea
+
             anchors.fill: parent
             hoverEnabled: true
             propagateComposedEvents: true
             onExited: volumeSliderHideTimer.start()
-
             onClicked: mouse.accepted = false
             onPressed: mouse.accepted = false
             onReleased: mouse.accepted = false
             onPressAndHold: mouse.accepted = false
             onPositionChanged: {
-                mouse.accepted = false
-                volumeSliderHideTimer.start()
+                mouse.accepted = false;
+                volumeSliderHideTimer.start();
             }
         }
+
+        Behavior on opacity {
+            OpacityAnimator {
+                duration: 100
+            }
+
+        }
+        // TODO: figure out a better way to put the slider popup above controlRect
+
     }
-}
\ No newline at end of file
+
+}
diff --git a/resources/qml/ui/media/qmldir b/resources/qml/ui/media/qmldir
index 14df35df..143b603d 100644
--- a/resources/qml/ui/media/qmldir
+++ b/resources/qml/ui/media/qmldir
@@ -1,2 +1,3 @@
 module im.nheko.UI.Media
-VolumeSlider 1.0 VolumeSlider.qml
\ No newline at end of file
+VolumeSlider 1.0 VolumeSlider.qml
+MediaControls 1.0 MediaControls.qml
\ No newline at end of file