diff options
author | Joseph Donofry <joedonofry@gmail.com> | 2021-11-09 22:17:00 -0500 |
---|---|---|
committer | Joseph Donofry <joedonofry@gmail.com> | 2021-11-09 22:17:00 -0500 |
commit | c1c9c71b08915a27538e34e422255d53b7bf1fdf (patch) | |
tree | e64f9f987461333672e012ea0c52fecb7f2ae77c /resources/qml/ui | |
parent | Initial Refactoring into separate controls (diff) | |
download | nheko-c1c9c71b08915a27538e34e422255d53b7bf1fdf.tar.xz |
Move rest of controls to separate file
Diffstat (limited to 'resources/qml/ui')
-rw-r--r-- | resources/qml/ui/media/MediaControls.qml | 141 | ||||
-rw-r--r-- | resources/qml/ui/media/VolumeControl.qml | 67 | ||||
-rw-r--r-- | resources/qml/ui/media/qmldir | 3 |
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 |