diff --git a/src/qml/HeaderBar.qml b/src/qml/HeaderBar.qml new file mode 100644 index 00000000..5e5a4e7d --- /dev/null +++ b/src/qml/HeaderBar.qml @@ -0,0 +1,133 @@ +import QtQuick 2.14 +import QtQuick.Controls 2.14 +import QtQuick.Layouts 1.14 +import QtMultimedia 5.15 +import QtGraphicalEffects 1.15 + +import org.kde.kirigami 2.14 as Kirigami + +import org.kde.kasts 1.0 + +Rectangle { + id: headerBar + anchors.fill: parent + color: Kirigami.Theme.backgroundColor + RowLayout { + anchors.left: parent.left + anchors.right: parent.right + spacing: Kirigami.Units.largeSpacing + anchors.verticalCenter: parent.verticalCenter + ImageWithFallback { + id: mainImage + imageSource: AudioManager.entry ? AudioManager.entry.cachedImage : "no-image" + height: controlsLayout.height + width: height + absoluteRadius: 5 + Layout.leftMargin: Kirigami.Units.largeSpacing + } + ColumnLayout { + id: controlsLayout + Layout.fillWidth: true + Layout.fillHeight: true + RowLayout { + Layout.rightMargin: Kirigami.Units.largeSpacing + ColumnLayout { + Kirigami.Heading { + text: AudioManager.entry ? AudioManager.entry.title : "No track title" + Layout.fillWidth: true + elide: Text.ElideRight + horizontalAlignment: Text.AlignLeft + level: 2 + wrapMode: Text.Wrap + font.bold: true + } + Label { + text: AudioManager.entry ? AudioManager.entry.feed.name : "No feed" + elide: Text.ElideRight + wrapMode: Text.Wrap + opacity: 0.6 + Layout.bottomMargin: 10 + } + } + Item { + Layout.fillWidth: true + } + RowLayout { + property int iconSize: Kirigami.Units.gridUnit + property int buttonSize: playButton.implicitWidth + Button { + contentItem: Label { + text: AudioManager.playbackRate + "x" + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + onClicked: { + if(AudioManager.playbackRate === 2.5) + AudioManager.playbackRate = 1 + else + AudioManager.playbackRate = AudioManager.playbackRate + 0.25 + } + flat: true + Layout.alignment: Qt.AlignHCenter + padding: 0 + implicitWidth: playButton.width * 2 + implicitHeight: playButton.height + } + Button { + icon.name: "media-seek-backward" + icon.height: parent.iconSize + icon.width: parent.iconSize + flat: true + Layout.alignment: Qt.AlignHCenter + Layout.preferredWidth: parent.buttonSize + onClicked: AudioManager.skipBackward() + enabled: AudioManager.canSkipBackward + } + Button { + id: playButton + icon.name: AudioManager.playbackState === Audio.PlayingState ? "media-playback-pause" : "media-playback-start" + icon.height: parent.iconSize + icon.width: parent.iconSize + flat: true + Layout.alignment: Qt.AlignHCenter + Layout.preferredWidth: parent.buttonSize + onClicked: AudioManager.playbackState === Audio.PlayingState ? AudioManager.pause() : AudioManager.play() + enabled: AudioManager.canPlay + } + Button { + icon.name: "media-seek-forward" + icon.height: parent.iconSize + icon.width: parent.iconSize + flat: true + Layout.alignment: Qt.AlignHCenter + Layout.preferredWidth: parent.buttonSize + onClicked: AudioManager.skipForward() + enabled: AudioManager.canSkipForward + } + Button { + icon.name: "media-skip-forward" + icon.height: parent.iconSize + icon.width: parent.iconSize + flat: true + Layout.alignment: Qt.AlignHCenter + Layout.preferredWidth: parent.buttonSize + onClicked: AudioManager.next() + enabled: AudioManager.canGoNext + } + } + } + Slider { + id: durationSlider + enabled: AudioManager.entry + Layout.fillWidth: true + Layout.fillHeight: true + Layout.rightMargin: Kirigami.Units.largeSpacing + padding: 0 + from: 0 + to: AudioManager.duration + value: AudioManager.position + onMoved: AudioManager.seek(value) + } + } + } +} diff --git a/src/qml/main.qml b/src/qml/main.qml index f9750b13..1c47df8b 100644 --- a/src/qml/main.qml +++ b/src/qml/main.qml @@ -19,7 +19,7 @@ Kirigami.ApplicationWindow { property var miniplayerSize: Kirigami.Units.gridUnit * 3 + Kirigami.Units.gridUnit / 6 property int tabBarHeight: Kirigami.Units.gridUnit * 2 - property int bottomMessageSpacing: Kirigami.Units.largeSpacing * 9 + ( AudioManager.entry ? ( footerLoader.item.contentY == 0 ? miniplayerSize : 0 ) : 0 ) + tabBarActive * tabBarHeight + property int bottomMessageSpacing: Kirigami.Units.largeSpacing * 9 + ( ( AudioManager.entry && Kirigami.Settings.isMobile ) ? ( footerLoader.item.contentY == 0 ? miniplayerSize : 0 ) : 0 ) + tabBarActive * tabBarHeight property int tabBarActive: 0 Kirigami.PagePool { @@ -49,8 +49,8 @@ Kirigami.ApplicationWindow { visible: !Kirigami.Settings.isMobile } // make room at the bottom for miniplayer - handle.anchors.bottomMargin: (AudioManager.entry ? (footerLoader.item.contentY == 0 ? miniplayerSize : 0) : 0) + Kirigami.Units.smallSpacing + tabBarActive * tabBarHeight - handleVisible: !AudioManager.entry || footerLoader.item.contentY === 0 + handle.anchors.bottomMargin: (( AudioManager.entry && Kirigami.Settings.isMobile ) ? (footerLoader.item.contentY == 0 ? miniplayerSize : 0) : 0) + Kirigami.Units.smallSpacing + tabBarActive * tabBarHeight + handleVisible: !(AudioManager.entry && Kirigami.Settings.isMobile) || footerLoader.item.contentY === 0 actions: [ Kirigami.PagePoolAction { text: i18n("Queue") @@ -118,8 +118,8 @@ Kirigami.ApplicationWindow { contextDrawer: Kirigami.ContextDrawer { id: contextDrawer // make room at the bottom for miniplayer - handle.anchors.bottomMargin: ( AudioManager.entry ? ( footerLoader.item.contentY == 0 ? miniplayerSize : 0 ) : 0 ) + Kirigami.Units.smallSpacing + tabBarActive * tabBarHeight - handleVisible: !AudioManager.entry || footerLoader.item.contentY == 0 + handle.anchors.bottomMargin: ( (AudioManager.entry && Kirigami.Settings.isMobile) ? ( footerLoader.item.contentY == 0 ? miniplayerSize : 0 ) : 0 ) + Kirigami.Units.smallSpacing + tabBarActive * tabBarHeight + handleVisible: !( AudioManager.entry && Kirigami.Settings.isMobile) || footerLoader.item.contentY == 0 } Mpris2 { @@ -137,15 +137,26 @@ Kirigami.ApplicationWindow { } } + header: Loader { + id: headerLoader + height: root.height * 0.12 + Kirigami.Units.gridUnit + active: !Kirigami.Settings.isMobile + visible: active + Layout.fillWidth: true + sourceComponent: HeaderBar { + focus: true + } + } + // create space at the bottom to show miniplayer without it hiding stuff // underneath - pageStack.anchors.bottomMargin: (AudioManager.entry) ? miniplayerSize : 0 + pageStack.anchors.bottomMargin: (AudioManager.entry && Kirigami.Settings.isMobile) ? miniplayerSize : 0 Loader { id: footerLoader anchors.fill: parent - active: AudioManager.entry + active: AudioManager.entry && Kirigami.Settings.isMobile visible: active z: (!item || item.contentY === 0) ? -1 : 999 sourceComponent: FooterBar { diff --git a/src/resources.qrc b/src/resources.qrc index c8f72881..d1550011 100755 --- a/src/resources.qrc +++ b/src/resources.qrc @@ -23,6 +23,7 @@ qml/GenericEntryDelegate.qml qml/ImageWithFallback.qml qml/UpdateNotification.qml + qml/HeaderBar.qml qtquickcontrols2.conf