diff --git a/src/qml/BasicPlayListAlbumHeader.qml b/src/qml/BasicPlayListAlbumHeader.qml index bfe4a528..d66263ce 100644 --- a/src/qml/BasicPlayListAlbumHeader.qml +++ b/src/qml/BasicPlayListAlbumHeader.qml @@ -1,124 +1,126 @@ /* * Copyright 2016-2017 Matthieu Gallien * * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.7 import QtQuick.Layouts 1.2 import QtQuick.Controls 2.3 import org.kde.elisa 1.0 import QtQuick 2.0 RowLayout { id: headerRow property var headerData property string album: headerData[0] property string albumArtist: headerData[1] property url imageUrl: headerData[2] property alias textColor: mainLabel.color TextMetrics { id: trackNumberSize text: (99).toLocaleString(Qt.locale(), 'f', 0) } TextMetrics { id: fakeDiscNumberSize text: '/9' } spacing: elisaTheme.layoutHorizontalMargin - Image { - id: mainIcon - - property int layoutMargin: headerRow.height - elisaTheme.smallDelegateToolButtonSize - - (trackNumberSize.boundingRect.width - trackNumberSize.boundingRect.x) - - (fakeDiscNumberSize.boundingRect.width - fakeDiscNumberSize.boundingRect.x) - - (elisaTheme.layoutHorizontalMargin * 5 / 4) + Item { + property int widthToTrackNumber: elisaTheme.playListDelegateHeight + + elisaTheme.layoutHorizontalMargin + + (trackNumberSize.boundingRect.width - trackNumberSize.boundingRect.x) + + (fakeDiscNumberSize.boundingRect.width - fakeDiscNumberSize.boundingRect.x) + + Layout.minimumWidth: widthToTrackNumber + Layout.maximumWidth: widthToTrackNumber + Layout.preferredWidth: widthToTrackNumber + Layout.fillHeight: true - source: (imageUrl != '' ? imageUrl : Qt.resolvedUrl(elisaTheme.defaultAlbumImage)) + Image { + id: mainIcon - Layout.minimumWidth: headerRow.height - layoutMargin - Layout.maximumWidth: headerRow.height - layoutMargin - Layout.preferredWidth: headerRow.height - layoutMargin - Layout.minimumHeight: headerRow.height - layoutMargin - Layout.maximumHeight: headerRow.height - layoutMargin - Layout.preferredHeight: headerRow.height - layoutMargin - Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter + source: (imageUrl != '' ? imageUrl : Qt.resolvedUrl(elisaTheme.defaultAlbumImage)) - sourceSize.width: headerRow.height - layoutMargin - sourceSize.height: headerRow.height - layoutMargin + anchors.right: parent.right + width: headerRow.height + height: headerRow.height + sourceSize.width: headerRow.height + sourceSize.height: headerRow.height - fillMode: Image.PreserveAspectFit - asynchronous: true + fillMode: Image.PreserveAspectFit + asynchronous: true - opacity: 1 + opacity: 1 + } } ColumnLayout { id: albumHeaderTextColumn Layout.fillWidth: true Layout.fillHeight: true Layout.leftMargin: !LayoutMirroring.enabled ? - elisaTheme.layoutHorizontalMargin / 4 : 0 Layout.rightMargin: LayoutMirroring.enabled ? - elisaTheme.layoutHorizontalMargin / 4 : 0 spacing: 0 LabelWithToolTip { id: mainLabel text: album font.weight: Font.Bold font.pointSize: Math.round(elisaTheme.defaultFontPointSize * 1.4) horizontalAlignment: Text.AlignLeft Layout.fillWidth: true Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft Layout.topMargin: elisaTheme.layoutVerticalMargin elide: Text.ElideRight } Item { Layout.fillHeight: true } LabelWithToolTip { id: authorLabel text: albumArtist font.weight: Font.Light color: mainLabel.color horizontalAlignment: Text.AlignLeft Layout.fillWidth: true Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft Layout.bottomMargin: elisaTheme.layoutVerticalMargin elide: Text.ElideRight } } } diff --git a/src/qml/PlayListBasicView.qml b/src/qml/PlayListBasicView.qml index eceb8f58..4c2b244b 100644 --- a/src/qml/PlayListBasicView.qml +++ b/src/qml/PlayListBasicView.qml @@ -1,171 +1,171 @@ /* * Copyright 2016-2018 Matthieu Gallien * * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.10 import QtQuick.Controls 2.2 import QtQml.Models 2.1 import org.kde.elisa 1.0 ListView { id: playListView property alias playListModel: playListModelDelegate.model property string title signal startPlayback() signal pausePlayback() signal displayError(var errorText) focus: true keyNavigationEnabled: true activeFocusOnTab: true currentIndex: -1 Accessible.role: Accessible.List Accessible.name: title section.property: 'albumSection' section.criteria: ViewSection.FullString section.labelPositioning: ViewSection.InlineLabels section.delegate: PlayListAlbumHeader { headerData: JSON.parse(section) width: scrollBar.visible ? (!LayoutMirroring.enabled ? playListView.width - scrollBar.width : playListView.width) : playListView.width height: elisaTheme.playListHeaderHeight } ScrollBar.vertical: ScrollBar { id: scrollBar } boundsBehavior: Flickable.StopAtBounds clip: true ScrollHelper { id: scrollHelper flickable: playListView anchors.fill: playListView } add: Transition { NumberAnimation { property: "opacity"; from: 0; to: 1; duration: 100 } } populate: Transition { NumberAnimation { property: "opacity"; from: 0; to: 1; duration: 100 } } remove: Transition { NumberAnimation { property: "opacity"; from: 1.0; to: 0; duration: 100 } } displaced: Transition { NumberAnimation { properties: "x,y"; duration: 100; easing.type: Easing.InOutQuad} } model: DelegateModel { id: playListModelDelegate groups: [ DelegateModelGroup { name: "selected" } ] delegate: DraggableItem { id: item placeholderHeight: topItem.placeholderHeight focus: true PlayListEntry { id: entry focus: true width: scrollBar.visible ? (!LayoutMirroring.enabled ? playListView.width - scrollBar.width : playListView.width) : playListView.width scrollBarWidth: scrollBar.visible ? scrollBar.width : 0 index: model.index isAlternateColor: item.DelegateModel.itemsIndex % 2 isSelected: playListView.currentIndex === index containsMouse: item.containsMouse - databaseId: (model.databaseId ? model.databaseId : 0) - title: model.title - artist: model.artist - album: model.album - albumArtist: (model.albumArtist ? model.albumArtist : '') - duration: (model.duration ? model.duration : '') - fileName: (model.trackResource ? model.trackResource : '') - imageUrl: model.imageUrl - trackNumber: (model.trackNumber ? model.trackNumber : -1) - discNumber: (model.discNumber ? model.discNumber : -1) - rating: (model.rating ? model.rating : 0) - isSingleDiscAlbum: (model.isSingleDiscAlbum ? model.isSingleDiscAlbum : true) + databaseId: model.databaseId ? model.databaseId : 0 + title: model.title ? model.title : '' + artist: model.artist ? model.artist : '' + album: model.album ? model.album : '' + albumArtist: model.albumArtist ? model.albumArtist : '' + duration: model.duration ? model.duration : '' + fileName: model.trackResource ? model.trackResource : '' + imageUrl: model.imageUrl ? model.imageUrl : '' + trackNumber: model.trackNumber ? model.trackNumber : -1 + discNumber: model.discNumber ? model.discNumber : -1 + rating: model.rating ? model.rating : 0 + isSingleDiscAlbum: model.isSingleDiscAlbum isValid: model.isValid isPlaying: model.isPlaying onStartPlayback: playListView.startPlayback() onPausePlayback: playListView.pausePlayback() onRemoveFromPlaylist: playListView.playListModel.removeRows(trackIndex, 1) onSwitchToTrack: playListView.playListModel.switchTo(trackIndex) onActiveFocusChanged: { if (activeFocus && playListView.currentIndex !== index) { playListView.currentIndex = index } } } draggedItemParent: playListView onClicked: { playListView.currentIndex = index entry.forceActiveFocus() } onDoubleClicked: { if (model.isValid) { playListView.playListModel.switchTo(model.index) playListView.startPlayback() } } onMoveItemRequested: { playListModel.move(from, to, 1); } } } onCountChanged: if (count === 0) { currentIndex = -1; } } diff --git a/src/qml/PlayListEntry.qml b/src/qml/PlayListEntry.qml index b897c6bd..ebf2abf7 100644 --- a/src/qml/PlayListEntry.qml +++ b/src/qml/PlayListEntry.qml @@ -1,560 +1,546 @@ /* * Copyright 2016-2017 Matthieu Gallien * * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.7 import QtQuick.Layouts 1.2 import QtQuick.Controls 2.3 import QtQuick.Window 2.2 import QtGraphicalEffects 1.0 import org.kde.elisa 1.0 FocusScope { id: playListEntry property var index property bool isSingleDiscAlbum property int isPlaying property bool isSelected property bool isValid property bool isAlternateColor property bool containsMouse property int databaseId: 0 property string title property string artist property string album property string albumArtist property string duration property url fileName property url imageUrl property int trackNumber property int discNumber property int rating property bool hasValidDiscNumber: true property int scrollBarWidth property bool noBackground: false signal startPlayback() signal pausePlayback() signal removeFromPlaylist(var trackIndex) signal switchToTrack(var trackIndex) Accessible.role: Accessible.ListItem Accessible.name: title + ' ' + album + ' ' + artist height: elisaTheme.playListDelegateHeight Action { id: removeFromPlayList text: i18nc("Remove current track from play list", "Remove") icon.name: "error" onTriggered: { playListEntry.removeFromPlaylist(playListEntry.index) } } Action { id: playNow text: i18nc("Play now current track from play list", "Play Now") icon.name: "media-playback-start" enabled: !(isPlaying === MediaPlayList.IsPlaying) && isValid onTriggered: { if (isPlaying === MediaPlayList.NotPlaying) { playListEntry.switchToTrack(playListEntry.index) } playListEntry.startPlayback() } } Action { id: pauseNow text: i18nc("Pause current track from play list", "Pause") icon.name: "media-playback-pause" enabled: isPlaying === MediaPlayList.IsPlaying && isValid onTriggered: playListEntry.pausePlayback() } Action { id: showInfo text: i18nc("Show track metadata", "View Details") icon.name: "help-about" enabled: isValid onTriggered: { if (metadataLoader.active === false) { metadataLoader.active = true } else { metadataLoader.item.close(); metadataLoader.active = false } } } Loader { id: metadataLoader active: false onLoaded: item.show() sourceComponent: MediaTrackMetadataView { databaseId: playListEntry.databaseId fileName: playListEntry.fileName onRejected: metadataLoader.active = false; } } Rectangle { id: entryBackground anchors.fill: parent anchors.rightMargin: LayoutMirroring.enabled ? scrollBarWidth : 0 z: 1 color: myPalette.base height: elisaTheme.playListDelegateHeight } - ColumnLayout { - spacing: 0 + RowLayout { + id: trackRow + z: 2 anchors.fill: parent + anchors.leftMargin: elisaTheme.layoutHorizontalMargin anchors.rightMargin: LayoutMirroring.enabled ? scrollBarWidth : 0 - z: 2 - - Item { - Layout.fillWidth: true - Layout.fillHeight: true - RowLayout { - id: trackRow + spacing: elisaTheme.layoutHorizontalMargin / 4 - anchors.fill: parent - anchors.leftMargin: elisaTheme.layoutHorizontalMargin - - spacing: elisaTheme.layoutHorizontalMargin / 4 - - Item { - id: playIconItem + Item { + id: playIconItem - implicitHeight: elisaTheme.smallDelegateToolButtonSize - implicitWidth: elisaTheme.smallDelegateToolButtonSize - Layout.maximumWidth: elisaTheme.smallDelegateToolButtonSize - Layout.maximumHeight: elisaTheme.smallDelegateToolButtonSize - Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter - Layout.leftMargin: !LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin / 2 : 0 - Layout.rightMargin: LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin / 2 : 0 + implicitHeight: elisaTheme.playListDelegateHeight + implicitWidth: elisaTheme.playListDelegateHeight + Layout.maximumWidth: elisaTheme.playListDelegateHeight + Layout.maximumHeight: elisaTheme.playListDelegateHeight + Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter + Layout.leftMargin: !LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin / 2 : 0 + Layout.rightMargin: LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin / 2 : 0 - Image { - id: playIcon + Image { + id: playIcon - anchors.fill: parent + anchors.centerIn: parent - opacity: 0 + opacity: 0 - source: (isPlaying === MediaPlayList.IsPlaying ? - Qt.resolvedUrl(elisaTheme.playingIndicatorIcon) : Qt.resolvedUrl(elisaTheme.pausedIndicatorIcon)) + source: (isPlaying === MediaPlayList.IsPlaying ? + Qt.resolvedUrl(elisaTheme.playingIndicatorIcon) : Qt.resolvedUrl(elisaTheme.pausedIndicatorIcon)) - width: parent.height * 1. - height: parent.height * 1. + width: elisaTheme.smallControlButtonSize + height: elisaTheme.smallControlButtonSize - sourceSize.width: parent.height * 1. - sourceSize.height: parent.height * 1. - fillMode: Image.PreserveAspectFit - mirror: LayoutMirroring.enabled - visible: opacity > 0.0 - } - } + sourceSize.width: elisaTheme.smallControlButtonSize + sourceSize.height: elisaTheme.smallControlButtonSize + fillMode: Image.PreserveAspectFit + mirror: LayoutMirroring.enabled + visible: opacity > 0.0 + } + } - Item { - id: fakeDiscNumberItem + Item { + id: fakeDiscNumberItem - visible: isValid && (!hasValidDiscNumber || isSingleDiscAlbum) + visible: isValid && (!hasValidDiscNumber || isSingleDiscAlbum) - Layout.preferredWidth: (fakeDiscNumberSize.boundingRect.width - fakeDiscNumberSize.boundingRect.x) + (elisaTheme.layoutHorizontalMargin / 4) - Layout.minimumWidth: (fakeDiscNumberSize.boundingRect.width - fakeDiscNumberSize.boundingRect.x) + (elisaTheme.layoutHorizontalMargin / 4) - Layout.maximumWidth: (fakeDiscNumberSize.boundingRect.width - fakeDiscNumberSize.boundingRect.x) + (elisaTheme.layoutHorizontalMargin / 4) + Layout.preferredWidth: (fakeDiscNumberSize.boundingRect.width - fakeDiscNumberSize.boundingRect.x) + (elisaTheme.layoutHorizontalMargin / 4) + Layout.minimumWidth: (fakeDiscNumberSize.boundingRect.width - fakeDiscNumberSize.boundingRect.x) + (elisaTheme.layoutHorizontalMargin / 4) + Layout.maximumWidth: (fakeDiscNumberSize.boundingRect.width - fakeDiscNumberSize.boundingRect.x) + (elisaTheme.layoutHorizontalMargin / 4) - TextMetrics { - id: fakeDiscNumberSize + TextMetrics { + id: fakeDiscNumberSize - text: '/9' - } - } + text: '/9' + } + } - Label { - id: trackNumberLabel + Label { + id: trackNumberLabel - horizontalAlignment: Text.AlignRight + horizontalAlignment: Text.AlignRight - text: trackNumber !== 0 && trackNumber !== -1 ? Number(trackNumber).toLocaleString(Qt.locale(), 'f', 0) : '' + text: trackNumber !== -1 ? Number(trackNumber).toLocaleString(Qt.locale(), 'f', 0) : '' - font.weight: (isPlaying ? Font.Bold : Font.Light) - color: myPalette.text + font.weight: (isPlaying ? Font.Bold : Font.Light) + color: myPalette.text - Layout.alignment: Qt.AlignVCenter | Qt.AlignRight + Layout.alignment: Qt.AlignVCenter | Qt.AlignRight - visible: isValid + visible: isValid - Layout.preferredWidth: ((trackNumberSize.boundingRect.width - trackNumberSize.boundingRect.x) > (realTrackNumberSize.boundingRect.width - realTrackNumberSize.boundingRect.x) ? (trackNumberSize.boundingRect.width - trackNumberSize.boundingRect.x) : (realTrackNumberSize.boundingRect.width - realTrackNumberSize.boundingRect.x)) - Layout.minimumWidth: ((trackNumberSize.boundingRect.width - trackNumberSize.boundingRect.x) > (realTrackNumberSize.boundingRect.width - realTrackNumberSize.boundingRect.x) ? (trackNumberSize.boundingRect.width - trackNumberSize.boundingRect.x) : (realTrackNumberSize.boundingRect.width - realTrackNumberSize.boundingRect.x)) - Layout.maximumWidth: ((trackNumberSize.boundingRect.width - trackNumberSize.boundingRect.x) > (realTrackNumberSize.boundingRect.width - realTrackNumberSize.boundingRect.x) ? (trackNumberSize.boundingRect.width - trackNumberSize.boundingRect.x) : (realTrackNumberSize.boundingRect.width - realTrackNumberSize.boundingRect.x)) + Layout.preferredWidth: ((trackNumberSize.boundingRect.width - trackNumberSize.boundingRect.x) > (realTrackNumberSize.boundingRect.width - realTrackNumberSize.boundingRect.x) ? (trackNumberSize.boundingRect.width - trackNumberSize.boundingRect.x) : (realTrackNumberSize.boundingRect.width - realTrackNumberSize.boundingRect.x)) + Layout.minimumWidth: ((trackNumberSize.boundingRect.width - trackNumberSize.boundingRect.x) > (realTrackNumberSize.boundingRect.width - realTrackNumberSize.boundingRect.x) ? (trackNumberSize.boundingRect.width - trackNumberSize.boundingRect.x) : (realTrackNumberSize.boundingRect.width - realTrackNumberSize.boundingRect.x)) + Layout.maximumWidth: ((trackNumberSize.boundingRect.width - trackNumberSize.boundingRect.x) > (realTrackNumberSize.boundingRect.width - realTrackNumberSize.boundingRect.x) ? (trackNumberSize.boundingRect.width - trackNumberSize.boundingRect.x) : (realTrackNumberSize.boundingRect.width - realTrackNumberSize.boundingRect.x)) - Layout.rightMargin: !LayoutMirroring.enabled ? (discNumber !== 0 && !isSingleDiscAlbum ? - 0 : elisaTheme.layoutHorizontalMargin / 2) : 0 - Layout.leftMargin: LayoutMirroring.enabled ? (discNumber !== 0 && !isSingleDiscAlbum ? - 0 : elisaTheme.layoutHorizontalMargin / 2) : 0 + Layout.rightMargin: !LayoutMirroring.enabled ? (discNumber !== 0 && !isSingleDiscAlbum ? + 0 : elisaTheme.layoutHorizontalMargin / 2) : 0 + Layout.leftMargin: LayoutMirroring.enabled ? (discNumber !== 0 && !isSingleDiscAlbum ? + 0 : elisaTheme.layoutHorizontalMargin / 2) : 0 - TextMetrics { - id: trackNumberSize + TextMetrics { + id: trackNumberSize - text: (99).toLocaleString(Qt.locale(), 'f', 0) - } + text: (99).toLocaleString(Qt.locale(), 'f', 0) + } - TextMetrics { - id: realTrackNumberSize + TextMetrics { + id: realTrackNumberSize - text: Number(trackNumber).toLocaleString(Qt.locale(), 'f', 0) - } - } + text: Number(trackNumber).toLocaleString(Qt.locale(), 'f', 0) + } + } - Label { - horizontalAlignment: Text.AlignCenter + Label { + horizontalAlignment: Text.AlignCenter - text: '/' + text: '/' - visible: isValid && discNumber !== 0 && !isSingleDiscAlbum + visible: isValid && discNumber !== 0 && !isSingleDiscAlbum - font.weight: (isPlaying ? Font.Bold : Font.Light) - color: myPalette.text + font.weight: (isPlaying ? Font.Bold : Font.Light) + color: myPalette.text - Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter + Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter - Layout.preferredWidth: (numberSeparatorSize.boundingRect.width - numberSeparatorSize.boundingRect.x) - Layout.minimumWidth: (numberSeparatorSize.boundingRect.width - numberSeparatorSize.boundingRect.x) - Layout.maximumWidth: (numberSeparatorSize.boundingRect.width - numberSeparatorSize.boundingRect.x) + Layout.preferredWidth: (numberSeparatorSize.boundingRect.width - numberSeparatorSize.boundingRect.x) + Layout.minimumWidth: (numberSeparatorSize.boundingRect.width - numberSeparatorSize.boundingRect.x) + Layout.maximumWidth: (numberSeparatorSize.boundingRect.width - numberSeparatorSize.boundingRect.x) - TextMetrics { - id: numberSeparatorSize + TextMetrics { + id: numberSeparatorSize - text: '/' - } - } + text: '/' + } + } - Label { - horizontalAlignment: Text.AlignRight + Label { + horizontalAlignment: Text.AlignRight - font.weight: (isPlaying ? Font.Bold : Font.Light) - color: myPalette.text + font.weight: (isPlaying ? Font.Bold : Font.Light) + color: myPalette.text - text: Number(discNumber).toLocaleString(Qt.locale(), 'f', 0) + text: Number(discNumber).toLocaleString(Qt.locale(), 'f', 0) - visible: isValid && discNumber !== 0 && !isSingleDiscAlbum + visible: isValid && discNumber !== 0 && !isSingleDiscAlbum - Layout.alignment: Qt.AlignVCenter | Qt.AlignRight + Layout.alignment: Qt.AlignVCenter | Qt.AlignRight - Layout.preferredWidth: ((discNumberSize.boundingRect.width - discNumberSize.boundingRect.x) > (realDiscNumberSize.boundingRect.width - realDiscNumberSize.boundingRect.x) ? - (discNumberSize.boundingRect.width - discNumberSize.boundingRect.x) : - (realDiscNumberSize.boundingRect.width - realDiscNumberSize.boundingRect.x)) - Layout.minimumWidth: ((discNumberSize.boundingRect.width - discNumberSize.boundingRect.x) > (realDiscNumberSize.boundingRect.width - realDiscNumberSize.boundingRect.x) ? - (discNumberSize.boundingRect.width - discNumberSize.boundingRect.x) : - (realDiscNumberSize.boundingRect.width - realDiscNumberSize.boundingRect.x)) - Layout.maximumWidth: ((discNumberSize.boundingRect.width - discNumberSize.boundingRect.x) > (realDiscNumberSize.boundingRect.width - realDiscNumberSize.boundingRect.x) ? - (discNumberSize.boundingRect.width - discNumberSize.boundingRect.x) : - (realDiscNumberSize.boundingRect.width - realDiscNumberSize.boundingRect.x)) + Layout.preferredWidth: ((discNumberSize.boundingRect.width - discNumberSize.boundingRect.x) > (realDiscNumberSize.boundingRect.width - realDiscNumberSize.boundingRect.x) ? + (discNumberSize.boundingRect.width - discNumberSize.boundingRect.x) : + (realDiscNumberSize.boundingRect.width - realDiscNumberSize.boundingRect.x)) + Layout.minimumWidth: ((discNumberSize.boundingRect.width - discNumberSize.boundingRect.x) > (realDiscNumberSize.boundingRect.width - realDiscNumberSize.boundingRect.x) ? + (discNumberSize.boundingRect.width - discNumberSize.boundingRect.x) : + (realDiscNumberSize.boundingRect.width - realDiscNumberSize.boundingRect.x)) + Layout.maximumWidth: ((discNumberSize.boundingRect.width - discNumberSize.boundingRect.x) > (realDiscNumberSize.boundingRect.width - realDiscNumberSize.boundingRect.x) ? + (discNumberSize.boundingRect.width - discNumberSize.boundingRect.x) : + (realDiscNumberSize.boundingRect.width - realDiscNumberSize.boundingRect.x)) - Layout.rightMargin: !LayoutMirroring.enabled ? (elisaTheme.layoutHorizontalMargin / 2) : 0 - Layout.leftMargin: LayoutMirroring.enabled ? (elisaTheme.layoutHorizontalMargin / 2) : 0 + Layout.rightMargin: !LayoutMirroring.enabled ? (elisaTheme.layoutHorizontalMargin / 2) : 0 + Layout.leftMargin: LayoutMirroring.enabled ? (elisaTheme.layoutHorizontalMargin / 2) : 0 - TextMetrics { - id: discNumberSize + TextMetrics { + id: discNumberSize - text: '9' - } + text: '9' + } - TextMetrics { - id: realDiscNumberSize + TextMetrics { + id: realDiscNumberSize - text: Number(discNumber).toLocaleString(Qt.locale(), 'f', 0) - } - } + text: Number(discNumber).toLocaleString(Qt.locale(), 'f', 0) + } + } - LabelWithToolTip { - id: mainCompactLabel + LabelWithToolTip { + id: mainCompactLabel - text: title + text: title - font.weight: (isPlaying ? Font.Bold : Font.Normal) - color: myPalette.text + font.weight: (isPlaying ? Font.Bold : Font.Normal) + color: myPalette.text - Layout.maximumWidth: mainCompactLabel.implicitWidth + 1 - Layout.fillWidth: true - Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft + Layout.maximumWidth: mainCompactLabel.implicitWidth + 1 + Layout.fillWidth: true + Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft - visible: isValid + visible: isValid - elide: Text.ElideRight - horizontalAlignment: Text.AlignLeft - } + elide: Text.ElideRight + horizontalAlignment: Text.AlignLeft + } - LabelWithToolTip { - id: mainInvalidCompactLabel + LabelWithToolTip { + id: mainInvalidCompactLabel - text: title + text: title - font.weight: Font.Normal - color: myPalette.text + font.weight: Font.Normal + color: myPalette.text - Layout.fillWidth: true - Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft + Layout.fillWidth: true + Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft - visible: !isValid + visible: !isValid - elide: Text.ElideRight - } + elide: Text.ElideRight + } - Item { - Layout.fillWidth: true - Layout.preferredWidth: 0 - } + Item { + Layout.fillWidth: true + Layout.preferredWidth: 0 + } - FlatButtonWithToolTip { - id: infoButton - objectName: 'infoButton' + FlatButtonWithToolTip { + id: infoButton + objectName: 'infoButton' - implicitHeight: elisaTheme.smallDelegateToolButtonSize - implicitWidth: elisaTheme.smallDelegateToolButtonSize - icon.height: elisaTheme.smallControlButtonSize - icon.width: elisaTheme.smallControlButtonSize + implicitHeight: elisaTheme.playListDelegateHeight + implicitWidth: elisaTheme.playListDelegateHeight + icon.height: elisaTheme.smallControlButtonSize + icon.width: elisaTheme.smallControlButtonSize - opacity: 0 + opacity: 0 - visible: opacity > 0.1 + visible: opacity > 0.1 - action: showInfo - Accessible.onPressAction: action.trigger() + action: showInfo - Layout.alignment: Qt.AlignVCenter | Qt.AlignRight - } + Layout.alignment: Qt.AlignVCenter | Qt.AlignRight + } - FlatButtonWithToolTip { - id: playPauseButton - objectName: 'playPauseButton' + FlatButtonWithToolTip { + id: playPauseButton + objectName: 'playPauseButton' - implicitHeight: elisaTheme.smallDelegateToolButtonSize - implicitWidth: elisaTheme.smallDelegateToolButtonSize - icon.height: elisaTheme.smallControlButtonSize - icon.width: elisaTheme.smallControlButtonSize + implicitHeight: elisaTheme.playListDelegateHeight + implicitWidth: elisaTheme.playListDelegateHeight + icon.height: elisaTheme.smallControlButtonSize + icon.width: elisaTheme.smallControlButtonSize - opacity: 0 + opacity: 0 - scale: LayoutMirroring.enabled ? -1 : 1 // We can mirror the symmetrical pause icon + scale: LayoutMirroring.enabled ? -1 : 1 // We can mirror the symmetrical pause icon - visible: opacity > 0.1 - action: !(isPlaying === MediaPlayList.IsPlaying) ? playNow : pauseNow - Accessible.onPressAction: action.trigger() + visible: opacity > 0.1 + action: !(isPlaying === MediaPlayList.IsPlaying) ? playNow : pauseNow - Layout.alignment: Qt.AlignVCenter | Qt.AlignRight - } + Layout.alignment: Qt.AlignVCenter | Qt.AlignRight + } - FlatButtonWithToolTip { - id: removeButton - objectName: 'removeButton' + FlatButtonWithToolTip { + id: removeButton + objectName: 'removeButton' - opacity: 0 + opacity: 0 - visible: opacity > 0.1 - action: removeFromPlayList - Accessible.onPressAction: action.trigger() + visible: opacity > 0.1 + action: removeFromPlayList - implicitHeight: elisaTheme.smallDelegateToolButtonSize - implicitWidth: elisaTheme.smallDelegateToolButtonSize - icon.height: elisaTheme.smallControlButtonSize - icon.width: elisaTheme.smallControlButtonSize - } + implicitHeight: elisaTheme.playListDelegateHeight + implicitWidth: elisaTheme.playListDelegateHeight + icon.height: elisaTheme.smallControlButtonSize + icon.width: elisaTheme.smallControlButtonSize + } - RatingStar { - id: ratingWidget + RatingStar { + id: ratingWidget - starRating: rating + starRating: rating - starSize: elisaTheme.ratingStarSize + starSize: elisaTheme.ratingStarSize - visible: rating > 0 - } + visible: rating > 0 + } - LabelWithToolTip { - id: durationLabel + LabelWithToolTip { + id: durationLabel - text: duration + text: duration - font.weight: (isPlaying ? Font.Bold : Font.Normal) - color: myPalette.text + font.weight: (isPlaying ? Font.Bold : Font.Normal) + color: myPalette.text - Layout.alignment: Qt.AlignVCenter | Qt.AlignRight - Layout.leftMargin: elisaTheme.layoutHorizontalMargin - Layout.rightMargin: elisaTheme.layoutHorizontalMargin + Layout.alignment: Qt.AlignVCenter | Qt.AlignRight + Layout.leftMargin: elisaTheme.layoutHorizontalMargin + Layout.rightMargin: elisaTheme.layoutHorizontalMargin - horizontalAlignment: Text.AlignRight - } - } + horizontalAlignment: Text.AlignRight } } states: [ State { name: 'notSelected' when: !containsMouse && !isSelected && !playListEntry.activeFocus PropertyChanges { target: removeButton opacity: 0 } PropertyChanges { target: infoButton opacity: 0 } PropertyChanges { target: playPauseButton opacity: 0 } PropertyChanges { target: playIcon opacity: (isPlaying === MediaPlayList.IsPlaying || isPlaying === MediaPlayList.IsPaused ? 1.0 : 0.0) } PropertyChanges { target: entryBackground color: (isAlternateColor ? myPalette.alternateBase : myPalette.base) } PropertyChanges { target: entryBackground opacity: 1. } PropertyChanges { target: ratingWidget hoverWidgetOpacity: 0.0 } }, State { name: 'hovered' when: containsMouse && !playListEntry.activeFocus PropertyChanges { target: removeButton opacity: 1 } PropertyChanges { target: playPauseButton opacity: 1 } PropertyChanges { target: infoButton opacity: 1 } PropertyChanges { target: playIcon opacity: (isPlaying === MediaPlayList.IsPlaying || isPlaying === MediaPlayList.IsPaused ? 1.0 : 0.0) } PropertyChanges { target: entryBackground color: myPalette.highlight } PropertyChanges { target: entryBackground opacity: 0.2 } PropertyChanges { target: ratingWidget hoverWidgetOpacity: 1.0 } }, State { name: 'selected' when: !playListEntry.activeFocus && isSelected PropertyChanges { target: removeButton opacity: 0 } PropertyChanges { target: playPauseButton opacity: 0 } PropertyChanges { target: infoButton opacity: 0 } PropertyChanges { target: playIcon opacity: (isPlaying === MediaPlayList.IsPlaying || isPlaying === MediaPlayList.IsPaused ? 1.0 : 0.0) } PropertyChanges { target: entryBackground color: myPalette.mid } PropertyChanges { target: entryBackground opacity: 1. } PropertyChanges { target: ratingWidget hoverWidgetOpacity: 1.0 } }, State { name: 'focused' when: playListEntry.activeFocus PropertyChanges { target: removeButton opacity: 1 } PropertyChanges { target: playPauseButton opacity: 1 } PropertyChanges { target: infoButton opacity: 1 } PropertyChanges { target: playIcon opacity: (isPlaying === MediaPlayList.IsPlaying || isPlaying === MediaPlayList.IsPaused ? 1.0 : 0.0) } PropertyChanges { target: entryBackground color: myPalette.highlight } PropertyChanges { target: entryBackground opacity: 0.6 } PropertyChanges { target: ratingWidget hoverWidgetOpacity: 1.0 } } ] transitions: Transition { ParallelAnimation { NumberAnimation { properties: "opacity, hoverWidgetOpacity" easing.type: Easing.InOutQuad duration: 250 } ColorAnimation { properties: "color" duration: 250 } } } } diff --git a/src/qml/SimplePlayListEntry.qml b/src/qml/SimplePlayListEntry.qml index 85235a19..2dcb59ac 100644 --- a/src/qml/SimplePlayListEntry.qml +++ b/src/qml/SimplePlayListEntry.qml @@ -1,434 +1,306 @@ /* * Copyright 2016-2017 Matthieu Gallien * * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.7 import QtQuick.Layouts 1.2 import QtQuick.Controls 2.3 import QtQuick.Window 2.2 import QtGraphicalEffects 1.0 import org.kde.elisa 1.0 FocusScope { id: playListEntry property var index property bool isSingleDiscAlbum property int isPlaying property bool isValid property int databaseId: 0 property string title property string artist property string album property string albumArtist property string duration property url fileName property url imageUrl property int trackNumber property int discNumber property int rating - property bool hasAlbumHeader - property bool hasValidDiscNumber: true + property bool hasValidDiscNumber: true property int scrollBarWidth signal switchToTrack(var trackIndex) - height: (hasAlbumHeader ? elisaTheme.playListDelegateWithHeaderHeight : elisaTheme.playListDelegateHeight) + Accessible.role: Accessible.ListItem + Accessible.name: title + ' ' + album + ' ' + artist + + height: elisaTheme.playListDelegateHeight Action { id: playNow text: i18nc("Play now current track from play list", "Play Now") icon.name: "media-playback-start" enabled: !(isPlaying === MediaPlayList.IsPlaying) && isValid onTriggered: { playListEntry.switchToTrack(playListEntry.index) } } - Item { - id: entryBackground - - anchors.fill: parent - anchors.rightMargin: LayoutMirroring.enabled ? scrollBarWidth : 0 - - height: (hasAlbumHeader ? elisaTheme.playListDelegateWithHeaderHeight : elisaTheme.playListDelegateHeight) - - focus: true - - ColumnLayout { - spacing: 0 - + MouseArea { anchors.fill: parent - Loader { - Layout.fillWidth: true - Layout.preferredHeight: elisaTheme.playListDelegateWithHeaderHeight - elisaTheme.playListDelegateHeight - Layout.minimumHeight: elisaTheme.playListDelegateWithHeaderHeight - elisaTheme.playListDelegateHeight - Layout.maximumHeight: elisaTheme.playListDelegateWithHeaderHeight - elisaTheme.playListDelegateHeight - - visible: hasAlbumHeader - active: hasAlbumHeader - - sourceComponent: Item { - anchors.fill: parent - - RowLayout { - id: headerRow - - spacing: elisaTheme.layoutHorizontalMargin - - anchors.fill: parent - anchors.topMargin: elisaTheme.layoutVerticalMargin * 1.5 - anchors.bottomMargin: elisaTheme.layoutVerticalMargin * 1.5 - - Image { - id: mainIcon - - source: (isValid ? (imageUrl != '' ? imageUrl : Qt.resolvedUrl(elisaTheme.defaultAlbumImage)) : Qt.resolvedUrl(elisaTheme.errorIcon)) - - Layout.minimumWidth: headerRow.height - Layout.maximumWidth: headerRow.height - Layout.preferredWidth: headerRow.height - Layout.minimumHeight: headerRow.height - Layout.maximumHeight: headerRow.height - Layout.preferredHeight: headerRow.height - Layout.leftMargin: !LayoutMirroring.enabled ? - (elisaTheme.smallDelegateToolButtonSize + - (trackNumberSize.boundingRect.width - trackNumberSize.boundingRect.x) + - (fakeDiscNumberSize.boundingRect.width - fakeDiscNumberSize.boundingRect.x) + - (elisaTheme.layoutHorizontalMargin * 5 / 4) - - headerRow.height) : - 0 - Layout.rightMargin: LayoutMirroring.enabled ? - (elisaTheme.smallDelegateToolButtonSize + - (trackNumberSize.boundingRect.width - trackNumberSize.boundingRect.x) + - (fakeDiscNumberSize.boundingRect.width - fakeDiscNumberSize.boundingRect.x) + - (elisaTheme.layoutHorizontalMargin * 5 / 4) - - headerRow.height) : - 0 - Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter - - sourceSize.width: headerRow.height - sourceSize.height: headerRow.height - - fillMode: Image.PreserveAspectFit - asynchronous: true - - opacity: isValid ? 1 : 0.5 - } - - ColumnLayout { - id: albumHeaderTextColumn - - Layout.fillWidth: true - Layout.fillHeight: true - Layout.leftMargin: !LayoutMirroring.enabled ? - elisaTheme.layoutHorizontalMargin / 4 : 0 - Layout.rightMargin: LayoutMirroring.enabled ? - elisaTheme.layoutHorizontalMargin / 4 : 0 + onClicked: playNow.trigger(this) + } - spacing: 0 + RowLayout { + id: trackRow - LabelWithToolTip { - id: mainLabel + anchors.fill: parent - text: album + spacing: elisaTheme.layoutHorizontalMargin / 4 - font.weight: Font.Bold - font.pointSize: Math.round(elisaTheme.defaultFontPointSize * 1.4) - color: myPalette.highlightedText + Item { + id: playIconItem - horizontalAlignment: Text.AlignLeft + implicitHeight: elisaTheme.playListDelegateHeight + implicitWidth: elisaTheme.playListDelegateHeight + Layout.maximumWidth: elisaTheme.playListDelegateHeight + Layout.maximumHeight: elisaTheme.playListDelegateHeight + Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter + Layout.leftMargin: !LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin / 2 : 0 + Layout.rightMargin: LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin / 2 : 0 - Layout.fillWidth: true - Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft - Layout.topMargin: elisaTheme.layoutVerticalMargin + Image { + id: playIcon - elide: Text.ElideRight - } + anchors.centerIn: parent - Item { - Layout.fillHeight: true - } + opacity: ((isPlaying === MediaPlayList.IsPlaying || isPlaying === MediaPlayList.IsPaused) ? 1.0 : 0.0) - LabelWithToolTip { - id: authorLabel + source: (isPlaying === MediaPlayList.IsPlaying ? + Qt.resolvedUrl(elisaTheme.playingIndicatorIcon) : Qt.resolvedUrl(elisaTheme.pausedIndicatorIcon)) - text: albumArtist + width: elisaTheme.smallControlButtonSize + height: elisaTheme.smallControlButtonSize - font.weight: Font.Light - color: myPalette.highlightedText + sourceSize.width: elisaTheme.smallControlButtonSize + sourceSize.height: elisaTheme.smallControlButtonSize + fillMode: Image.PreserveAspectFit + mirror: LayoutMirroring.enabled + visible: opacity > 0.0 - horizontalAlignment: Text.AlignLeft + layer.enabled: true + layer.effect: ColorOverlay { + cached: true - Layout.fillWidth: true - Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft - Layout.bottomMargin: elisaTheme.layoutVerticalMargin + color: myPalette.highlightedText + } - elide: Text.ElideRight - } - } + Behavior on opacity { + NumberAnimation { + easing.type: Easing.InOutQuad + duration: 250 } } } + } - Item { - Layout.fillWidth: true - Layout.fillHeight: true - - RowLayout { - id: trackRow - - anchors.fill: parent - - spacing: elisaTheme.layoutHorizontalMargin / 4 - - Item { - id: playIconItem - - implicitHeight: elisaTheme.smallDelegateToolButtonSize - implicitWidth: elisaTheme.smallDelegateToolButtonSize - Layout.maximumWidth: elisaTheme.smallDelegateToolButtonSize - Layout.maximumHeight: elisaTheme.smallDelegateToolButtonSize - Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter - Layout.leftMargin: !LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin / 2 : 0 - Layout.rightMargin: LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin / 2 : 0 - - Image { - id: playIcon - - anchors.fill: parent - - opacity: ((isPlaying === MediaPlayList.IsPlaying || isPlaying === MediaPlayList.IsPaused) ? 1.0 : 0.0) - - source: (isPlaying === MediaPlayList.IsPlaying ? - Qt.resolvedUrl(elisaTheme.playingIndicatorIcon) : Qt.resolvedUrl(elisaTheme.pausedIndicatorIcon)) - - width: parent.height * 1. - height: parent.height * 1. - - sourceSize.width: parent.height * 1. - sourceSize.height: parent.height * 1. - fillMode: Image.PreserveAspectFit - mirror: LayoutMirroring.enabled - visible: opacity > 0.0 - - layer.enabled: true - layer.effect: ColorOverlay { - cached: true - - color: myPalette.highlightedText - } - - Behavior on opacity { - NumberAnimation { - easing.type: Easing.InOutQuad - duration: 250 - } - } - } - } - - Item { - id: fakeDiscNumberItem + Item { + id: fakeDiscNumberItem - visible: isValid && (!hasValidDiscNumber || isSingleDiscAlbum) + visible: isValid && (!hasValidDiscNumber || isSingleDiscAlbum) - Layout.preferredWidth: (fakeDiscNumberSize.boundingRect.width - fakeDiscNumberSize.boundingRect.x) + (elisaTheme.layoutHorizontalMargin / 4) - Layout.minimumWidth: (fakeDiscNumberSize.boundingRect.width - fakeDiscNumberSize.boundingRect.x) + (elisaTheme.layoutHorizontalMargin / 4) - Layout.maximumWidth: (fakeDiscNumberSize.boundingRect.width - fakeDiscNumberSize.boundingRect.x) + (elisaTheme.layoutHorizontalMargin / 4) + Layout.preferredWidth: (fakeDiscNumberSize.boundingRect.width - fakeDiscNumberSize.boundingRect.x) + (elisaTheme.layoutHorizontalMargin / 4) + Layout.minimumWidth: (fakeDiscNumberSize.boundingRect.width - fakeDiscNumberSize.boundingRect.x) + (elisaTheme.layoutHorizontalMargin / 4) + Layout.maximumWidth: (fakeDiscNumberSize.boundingRect.width - fakeDiscNumberSize.boundingRect.x) + (elisaTheme.layoutHorizontalMargin / 4) - TextMetrics { - id: fakeDiscNumberSize + TextMetrics { + id: fakeDiscNumberSize - text: '/9' - } - } + text: '/9' + } + } - Label { - id: trackNumberLabel + Label { + id: trackNumberLabel - horizontalAlignment: Text.AlignRight + horizontalAlignment: Text.AlignRight - text: trackNumber !== 0 ? Number(trackNumber).toLocaleString(Qt.locale(), 'f', 0) : '' + text: trackNumber !== -1 ? Number(trackNumber).toLocaleString(Qt.locale(), 'f', 0) : '' - font.weight: (isPlaying ? Font.Bold : Font.Light) - color: myPalette.highlightedText + font.weight: (isPlaying ? Font.Bold : Font.Light) + color: myPalette.highlightedText - Layout.alignment: Qt.AlignVCenter | Qt.AlignRight + Layout.alignment: Qt.AlignVCenter | Qt.AlignRight - visible: isValid + visible: isValid - Layout.preferredWidth: ((trackNumberSize.boundingRect.width - trackNumberSize.boundingRect.x) > (realTrackNumberSize.boundingRect.width - realTrackNumberSize.boundingRect.x) ? - (trackNumberSize.boundingRect.width - trackNumberSize.boundingRect.x) : - (realTrackNumberSize.boundingRect.width - realTrackNumberSize.boundingRect.x)) - Layout.minimumWidth: ((trackNumberSize.boundingRect.width - trackNumberSize.boundingRect.x) > (realTrackNumberSize.boundingRect.width - realTrackNumberSize.boundingRect.x) ? - (trackNumberSize.boundingRect.width - trackNumberSize.boundingRect.x) : - (realTrackNumberSize.boundingRect.width - realTrackNumberSize.boundingRect.x)) - Layout.maximumWidth: ((trackNumberSize.boundingRect.width - trackNumberSize.boundingRect.x) > (realTrackNumberSize.boundingRect.width - realTrackNumberSize.boundingRect.x) ? - (trackNumberSize.boundingRect.width - trackNumberSize.boundingRect.x) : - (realTrackNumberSize.boundingRect.width - realTrackNumberSize.boundingRect.x)) + Layout.preferredWidth: ((trackNumberSize.boundingRect.width - trackNumberSize.boundingRect.x) > (realTrackNumberSize.boundingRect.width - realTrackNumberSize.boundingRect.x) ? + (trackNumberSize.boundingRect.width - trackNumberSize.boundingRect.x) : + (realTrackNumberSize.boundingRect.width - realTrackNumberSize.boundingRect.x)) + Layout.minimumWidth: ((trackNumberSize.boundingRect.width - trackNumberSize.boundingRect.x) > (realTrackNumberSize.boundingRect.width - realTrackNumberSize.boundingRect.x) ? + (trackNumberSize.boundingRect.width - trackNumberSize.boundingRect.x) : + (realTrackNumberSize.boundingRect.width - realTrackNumberSize.boundingRect.x)) + Layout.maximumWidth: ((trackNumberSize.boundingRect.width - trackNumberSize.boundingRect.x) > (realTrackNumberSize.boundingRect.width - realTrackNumberSize.boundingRect.x) ? + (trackNumberSize.boundingRect.width - trackNumberSize.boundingRect.x) : + (realTrackNumberSize.boundingRect.width - realTrackNumberSize.boundingRect.x)) - Layout.rightMargin: !LayoutMirroring.enabled ? (discNumber !== 0 && !isSingleDiscAlbum ? - 0 : elisaTheme.layoutHorizontalMargin / 2) : 0 - Layout.leftMargin: LayoutMirroring.enabled ? (discNumber !== 0 && !isSingleDiscAlbum ? - 0 : elisaTheme.layoutHorizontalMargin / 2) : 0 + Layout.rightMargin: !LayoutMirroring.enabled ? (discNumber !== 0 && !isSingleDiscAlbum ? + 0 : elisaTheme.layoutHorizontalMargin / 2) : 0 + Layout.leftMargin: LayoutMirroring.enabled ? (discNumber !== 0 && !isSingleDiscAlbum ? + 0 : elisaTheme.layoutHorizontalMargin / 2) : 0 - TextMetrics { - id: trackNumberSize + TextMetrics { + id: trackNumberSize - text: (99).toLocaleString(Qt.locale(), 'f', 0) - } + text: (99).toLocaleString(Qt.locale(), 'f', 0) + } - TextMetrics { - id: realTrackNumberSize + TextMetrics { + id: realTrackNumberSize - text: Number(trackNumber).toLocaleString(Qt.locale(), 'f', 0) - } - } + text: Number(trackNumber).toLocaleString(Qt.locale(), 'f', 0) + } + } - Label { - horizontalAlignment: Text.AlignCenter + Label { + horizontalAlignment: Text.AlignCenter - text: '/' + text: '/' - visible: isValid && discNumber !== 0 && !isSingleDiscAlbum + visible: isValid && discNumber !== 0 && !isSingleDiscAlbum - font.weight: (isPlaying ? Font.Bold : Font.Light) - color: myPalette.highlightedText + font.weight: (isPlaying ? Font.Bold : Font.Light) + color: myPalette.highlightedText - Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter + Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter - Layout.preferredWidth: (numberSeparatorSize.boundingRect.width - numberSeparatorSize.boundingRect.x) - Layout.minimumWidth: (numberSeparatorSize.boundingRect.width - numberSeparatorSize.boundingRect.x) - Layout.maximumWidth: (numberSeparatorSize.boundingRect.width - numberSeparatorSize.boundingRect.x) + Layout.preferredWidth: (numberSeparatorSize.boundingRect.width - numberSeparatorSize.boundingRect.x) + Layout.minimumWidth: (numberSeparatorSize.boundingRect.width - numberSeparatorSize.boundingRect.x) + Layout.maximumWidth: (numberSeparatorSize.boundingRect.width - numberSeparatorSize.boundingRect.x) - TextMetrics { - id: numberSeparatorSize + TextMetrics { + id: numberSeparatorSize - text: '/' - } - } + text: '/' + } + } - Label { - horizontalAlignment: Text.AlignRight + Label { + horizontalAlignment: Text.AlignRight - font.weight: (isPlaying ? Font.Bold : Font.Light) - color: myPalette.highlightedText + font.weight: (isPlaying ? Font.Bold : Font.Light) + color: myPalette.highlightedText - text: Number(discNumber).toLocaleString(Qt.locale(), 'f', 0) + text: Number(discNumber).toLocaleString(Qt.locale(), 'f', 0) - visible: isValid && discNumber !== 0 && !isSingleDiscAlbum + visible: isValid && discNumber !== 0 && !isSingleDiscAlbum - Layout.alignment: Qt.AlignVCenter | Qt.AlignRight + Layout.alignment: Qt.AlignVCenter | Qt.AlignRight - Layout.preferredWidth: ((discNumberSize.boundingRect.width - discNumberSize.boundingRect.x) > (realDiscNumberSize.boundingRect.width - realDiscNumberSize.boundingRect.x) ? - (discNumberSize.boundingRect.width - discNumberSize.boundingRect.x) : - (realDiscNumberSize.boundingRect.width - realDiscNumberSize.boundingRect.x)) - Layout.minimumWidth: ((discNumberSize.boundingRect.width - discNumberSize.boundingRect.x) > (realDiscNumberSize.boundingRect.width - realDiscNumberSize.boundingRect.x) ? - (discNumberSize.boundingRect.width - discNumberSize.boundingRect.x) : - (realDiscNumberSize.boundingRect.width - realDiscNumberSize.boundingRect.x)) - Layout.maximumWidth: ((discNumberSize.boundingRect.width - discNumberSize.boundingRect.x) > (realDiscNumberSize.boundingRect.width - realDiscNumberSize.boundingRect.x) ? - (discNumberSize.boundingRect.width - discNumberSize.boundingRect.x) : - (realDiscNumberSize.boundingRect.width - realDiscNumberSize.boundingRect.x)) + Layout.preferredWidth: ((discNumberSize.boundingRect.width - discNumberSize.boundingRect.x) > (realDiscNumberSize.boundingRect.width - realDiscNumberSize.boundingRect.x) ? + (discNumberSize.boundingRect.width - discNumberSize.boundingRect.x) : + (realDiscNumberSize.boundingRect.width - realDiscNumberSize.boundingRect.x)) + Layout.minimumWidth: ((discNumberSize.boundingRect.width - discNumberSize.boundingRect.x) > (realDiscNumberSize.boundingRect.width - realDiscNumberSize.boundingRect.x) ? + (discNumberSize.boundingRect.width - discNumberSize.boundingRect.x) : + (realDiscNumberSize.boundingRect.width - realDiscNumberSize.boundingRect.x)) + Layout.maximumWidth: ((discNumberSize.boundingRect.width - discNumberSize.boundingRect.x) > (realDiscNumberSize.boundingRect.width - realDiscNumberSize.boundingRect.x) ? + (discNumberSize.boundingRect.width - discNumberSize.boundingRect.x) : + (realDiscNumberSize.boundingRect.width - realDiscNumberSize.boundingRect.x)) - Layout.rightMargin: !LayoutMirroring.enabled ? (elisaTheme.layoutHorizontalMargin / 2) : 0 - Layout.leftMargin: LayoutMirroring.enabled ? (elisaTheme.layoutHorizontalMargin / 2) : 0 + Layout.rightMargin: !LayoutMirroring.enabled ? (elisaTheme.layoutHorizontalMargin / 2) : 0 + Layout.leftMargin: LayoutMirroring.enabled ? (elisaTheme.layoutHorizontalMargin / 2) : 0 - TextMetrics { - id: discNumberSize + TextMetrics { + id: discNumberSize - text: '9' - } + text: '9' + } - TextMetrics { - id: realDiscNumberSize + TextMetrics { + id: realDiscNumberSize - text: Number(discNumber).toLocaleString(Qt.locale(), 'f', 0) - } - } + text: Number(discNumber).toLocaleString(Qt.locale(), 'f', 0) + } + } - LabelWithToolTip { - id: mainCompactLabel + LabelWithToolTip { + id: mainCompactLabel - text: title + text: title - font.weight: (isPlaying ? Font.Bold : Font.Normal) - color: myPalette.highlightedText + font.weight: (isPlaying ? Font.Bold : Font.Normal) + color: myPalette.highlightedText - Layout.maximumWidth: mainCompactLabel.implicitWidth + 1 - Layout.fillWidth: true - Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft + Layout.maximumWidth: mainCompactLabel.implicitWidth + 1 + Layout.fillWidth: true + Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft - visible: isValid + visible: isValid - elide: Text.ElideRight - horizontalAlignment: Text.AlignLeft - } + elide: Text.ElideRight + horizontalAlignment: Text.AlignLeft + } - LabelWithToolTip { - id: mainInvalidCompactLabel + LabelWithToolTip { + id: mainInvalidCompactLabel - text: title + text: title - font.weight: Font.Normal - color: myPalette.highlightedText + font.weight: Font.Normal + color: myPalette.highlightedText - Layout.fillWidth: true - Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft + Layout.fillWidth: true + Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft - visible: !isValid + visible: !isValid - elide: Text.ElideRight - } + elide: Text.ElideRight + } - Item { - Layout.fillWidth: true - Layout.preferredWidth: 0 - } + Item { + Layout.fillWidth: true + Layout.preferredWidth: 0 + } - RatingStar { - id: ratingWidget + RatingStar { + id: ratingWidget - starRating: rating + starRating: rating - starSize: elisaTheme.ratingStarSize - } + starSize: elisaTheme.ratingStarSize + } - LabelWithToolTip { - id: durationLabel + LabelWithToolTip { + id: durationLabel - text: duration + text: duration - font.weight: (isPlaying ? Font.Bold : Font.Normal) - color: myPalette.highlightedText + font.weight: (isPlaying ? Font.Bold : Font.Normal) + color: myPalette.highlightedText - Layout.alignment: Qt.AlignVCenter | Qt.AlignRight - Layout.leftMargin: elisaTheme.layoutHorizontalMargin / 2 - Layout.rightMargin: elisaTheme.layoutHorizontalMargin / 2 + Layout.alignment: Qt.AlignVCenter | Qt.AlignRight + Layout.leftMargin: elisaTheme.layoutHorizontalMargin / 2 + Layout.rightMargin: elisaTheme.layoutHorizontalMargin / 2 - horizontalAlignment: Text.AlignRight - } - } - } + horizontalAlignment: Text.AlignRight } } - MouseArea { - anchors.fill: entryBackground - onClicked: playNow.trigger(this) - } } diff --git a/src/qml/SimplePlayListView.qml b/src/qml/SimplePlayListView.qml index 4e1d71c9..659a1842 100644 --- a/src/qml/SimplePlayListView.qml +++ b/src/qml/SimplePlayListView.qml @@ -1,120 +1,119 @@ /* * Copyright 2016-2018 Matthieu Gallien * * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.10 import QtQuick.Controls 2.2 import QtQml.Models 2.1 import org.kde.elisa 1.0 ListView { id: playListView property alias playListModel: playListModelDelegate.model signal startPlayback() signal pausePlayback() signal displayError(var errorText) focus: true activeFocusOnTab: true keyNavigationEnabled: true section.property: 'albumSection' section.criteria: ViewSection.FullString section.labelPositioning: ViewSection.InlineLabels section.delegate: BasicPlayListAlbumHeader { headerData: JSON.parse(section) width: scrollBar.visible ? (!LayoutMirroring.enabled ? playListView.width - scrollBar.width : playListView.width) : playListView.width height: elisaTheme.playListHeaderHeight - 3 * elisaTheme.layoutVerticalMargin textColor: myPalette.highlightedText } ScrollBar.vertical: ScrollBar { id: scrollBar } boundsBehavior: Flickable.StopAtBounds clip: true add: Transition { NumberAnimation { property: "opacity"; from: 0; to: 1; duration: 100 } } populate: Transition { NumberAnimation { property: "opacity"; from: 0; to: 1; duration: 100 } } remove: Transition { NumberAnimation { property: "opacity"; from: 1.0; to: 0; duration: 100 } } displaced: Transition { NumberAnimation { properties: "x,y"; duration: 100; easing.type: Easing.InOutQuad} } model: DelegateModel { id: playListModelDelegate groups: [ DelegateModelGroup { name: "selected" } ] delegate: SimplePlayListEntry { id: entry focus: true width: scrollBar.visible ? (!LayoutMirroring.enabled ? playListView.width - scrollBar.width : playListView.width) : playListView.width scrollBarWidth: scrollBar.visible ? scrollBar.width : 0 index: model.index - databaseId: model.databaseId - title: model.title - artist: model.artist - album: model.album - albumArtist: model.albumArtist - duration: model.duration - fileName: model.trackResource - imageUrl: model.imageUrl - trackNumber: model.trackNumber - discNumber: model.discNumber - rating: model.rating - hasAlbumHeader: model.hasAlbumHeader + databaseId: model.databaseId ? model.databaseId : 0 + title: model.title ? model.title : '' + artist: model.artist ? model.artist : '' + album: model.album ? model.album : '' + albumArtist: model.albumArtist ? model.albumArtist : '' + duration: model.duration ? model.duration : '' + fileName: model.trackResource ? model.trackResource : '' + imageUrl: model.imageUrl ? model.imageUrl : '' + trackNumber: model.trackNumber ? model.trackNumber : -1 + discNumber: model.discNumber ? model.discNumber : -1 + rating: model.rating ? model.rating : 0 isSingleDiscAlbum: model.isSingleDiscAlbum isValid: model.isValid isPlaying: model.isPlaying onSwitchToTrack: playListView.playListModel.switchTo(trackIndex) } } }