diff --git a/src/qml/PlayListEntry.qml b/src/qml/PlayListEntry.qml --- a/src/qml/PlayListEntry.qml +++ b/src/qml/PlayListEntry.qml @@ -19,7 +19,7 @@ import QtQuick 2.7 import QtQuick.Layouts 1.2 -import QtQuick.Controls 2.2 +import QtQuick.Controls 2.3 import QtQuick.Controls 1.4 as Controls1 import QtQuick.Window 2.2 import QtGraphicalEffects 1.0 @@ -123,105 +123,116 @@ spacing: 0 anchors.fill: parent - anchors.leftMargin: elisaTheme.layoutHorizontalMargin - anchors.rightMargin: elisaTheme.layoutHorizontalMargin - Item { + Loader { Layout.fillWidth: true Layout.preferredHeight: elisaTheme.delegateWithHeaderHeight - elisaTheme.delegateHeight Layout.minimumHeight: elisaTheme.delegateWithHeaderHeight - elisaTheme.delegateHeight Layout.maximumHeight: elisaTheme.delegateWithHeaderHeight - elisaTheme.delegateHeight + Layout.bottomMargin: elisaTheme.layoutVerticalMargin visible: hasAlbumHeader + active: hasAlbumHeader - RowLayout { - id: headerRow + sourceComponent: Item { + anchors.fill: parent - spacing: elisaTheme.layoutHorizontalMargin + RowLayout { + id: headerRow - anchors.fill: parent + spacing: elisaTheme.layoutHorizontalMargin - Image { - id: mainIcon + anchors.fill: parent - source: (isValid ? (dataHelper.hasValidAlbumCover ? dataHelper.albumCover : Qt.resolvedUrl(elisaTheme.defaultAlbumImage)) : Qt.resolvedUrl(elisaTheme.errorIcon)) + Image { + id: mainIcon - Layout.minimumWidth: headerRow.height - 4 - Layout.maximumWidth: headerRow.height - 4 - Layout.preferredWidth: headerRow.height - 4 - Layout.minimumHeight: headerRow.height - 4 - Layout.maximumHeight: headerRow.height - 4 - Layout.preferredHeight: headerRow.height - 4 - Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter + source: (isValid ? (dataHelper.hasValidAlbumCover ? dataHelper.albumCover : Qt.resolvedUrl(elisaTheme.defaultAlbumImage)) : Qt.resolvedUrl(elisaTheme.errorIcon)) - sourceSize.width: headerRow.height - 4 - sourceSize.height: parent.height - 4 + Layout.minimumWidth: headerRow.height - (elisaTheme.layoutHorizontalMargin / 2) + Layout.maximumWidth: headerRow.height - (elisaTheme.layoutHorizontalMargin / 2) + Layout.preferredWidth: headerRow.height - (elisaTheme.layoutHorizontalMargin / 2) + Layout.minimumHeight: headerRow.height - (elisaTheme.layoutHorizontalMargin / 2) + Layout.maximumHeight: headerRow.height - (elisaTheme.layoutHorizontalMargin / 2) + Layout.preferredHeight: headerRow.height - (elisaTheme.layoutHorizontalMargin / 2) + Layout.leftMargin: elisaTheme.layoutHorizontalMargin + Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter - fillMode: Image.PreserveAspectFit - asynchronous: true + sourceSize.width: headerRow.height - (elisaTheme.layoutHorizontalMargin / 2) + sourceSize.height: headerRow.height - (elisaTheme.layoutHorizontalMargin / 2) - visible: isValid - } + fillMode: Image.PreserveAspectFit + asynchronous: true - BrightnessContrast { - source: mainIcon + visible: isValid + } - cached: true + BrightnessContrast { + source: mainIcon - visible: !isValid + cached: true - contrast: -0.9 + visible: !isValid - Layout.minimumWidth: headerRow.height - 4 - Layout.maximumWidth: headerRow.height - 4 - Layout.preferredWidth: headerRow.height - 4 - Layout.minimumHeight: headerRow.height - 4 - Layout.maximumHeight: headerRow.height - 4 - Layout.preferredHeight: headerRow.height - 4 - Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter - } + contrast: -0.9 - ColumnLayout { - Layout.fillWidth: true - Layout.fillHeight: true + Layout.minimumWidth: headerRow.height - 4 + Layout.maximumWidth: headerRow.height - 4 + Layout.preferredWidth: headerRow.height - 4 + Layout.minimumHeight: headerRow.height - 4 + Layout.maximumHeight: headerRow.height - 4 + Layout.preferredHeight: headerRow.height - 4 + Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter + } - spacing: 0 + ColumnLayout { + id: albumHeaderTextColumn - LabelWithToolTip { - id: mainLabel - text: dataHelper.albumName + Layout.fillWidth: true + Layout.fillHeight: true + Layout.leftMargin: mainCompactLabel.x - ( + (elisaTheme.delegateWithHeaderHeight - elisaTheme.delegateHeight) + + (3 * elisaTheme.layoutHorizontalMargin / 2)) - font.weight: Font.Bold - color: myPalette.text + spacing: 0 - horizontalAlignment: Text.AlignHCenter + LabelWithToolTip { + id: mainLabel + text: dataHelper.albumName - Layout.fillWidth: true - Layout.alignment: Qt.AlignCenter - Layout.topMargin: elisaTheme.layoutVerticalMargin + font.weight: Font.Bold + font.pointSize: elisaTheme.defaultFontPointSize * 1.4 + color: myPalette.text - elide: Text.ElideRight - } + horizontalAlignment: Text.AlignLeft - Item { - Layout.fillHeight: true - } + Layout.fillWidth: true + Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft + Layout.topMargin: elisaTheme.layoutVerticalMargin - LabelWithToolTip { - id: authorLabel + elide: Text.ElideRight + } + + Item { + Layout.fillHeight: true + } - text: dataHelper.albumArtist + LabelWithToolTip { + id: authorLabel - font.weight: Font.Light - color: myPalette.text + text: dataHelper.albumArtist - horizontalAlignment: Text.AlignHCenter + font.weight: Font.Light + color: myPalette.text - Layout.fillWidth: true - Layout.alignment: Qt.AlignCenter - Layout.bottomMargin: elisaTheme.layoutVerticalMargin + horizontalAlignment: Text.AlignLeft - elide: Text.ElideRight + Layout.fillWidth: true + Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft + Layout.bottomMargin: elisaTheme.layoutVerticalMargin + + elide: Text.ElideRight + } } } } @@ -236,24 +247,134 @@ anchors.fill: parent - spacing: elisaTheme.layoutHorizontalMargin + 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 + + Image { + id: playIcon + + anchors.fill: parent + + opacity: 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 + } + } + + Item { + id: fakeDiscNumberItem + + visible: isValid && (!dataHelper.hasValidDiscNumber || isSingleDiscAlbum) + + Layout.preferredWidth: fakeDiscNumberSize.width + (elisaTheme.layoutHorizontalMargin / 4) + Layout.minimumWidth: fakeDiscNumberSize.width + (elisaTheme.layoutHorizontalMargin / 4) + Layout.maximumWidth: fakeDiscNumberSize.width + (elisaTheme.layoutHorizontalMargin / 4) + + TextMetrics { + id: fakeDiscNumberSize + + text: '/9' + } + } + + Label { + id: trackNumberLabel + + horizontalAlignment: Text.AlignRight + + text: Number(dataHelper.trackNumber).toLocaleString(Qt.locale(), 'f', 0) + + font.weight: Font.Light + color: myPalette.text + + Layout.alignment: Qt.AlignVCenter | Qt.AlignRight + + visible: isValid + + Layout.preferredWidth: trackNumberSize.width + Layout.minimumWidth: trackNumberSize.width + Layout.maximumWidth: trackNumberSize.width + + Layout.rightMargin: (dataHelper.hasValidDiscNumber && !isSingleDiscAlbum ? + 0 : elisaTheme.layoutHorizontalMargin / 2) + + TextMetrics { + id: trackNumberSize + + text: (99).toLocaleString(Qt.locale(), 'f', 0) + } + } + + Label { + horizontalAlignment: Text.AlignCenter + + text: '/' + + visible: isValid && dataHelper.hasValidDiscNumber && !isSingleDiscAlbum + + font.weight: Font.Light + color: myPalette.text + + Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter + + Layout.preferredWidth: numberSeparatorSize.width + Layout.minimumWidth: numberSeparatorSize.width + Layout.maximumWidth: numberSeparatorSize.width + + TextMetrics { + id: numberSeparatorSize + + text: '/' + } + } + + Label { + horizontalAlignment: Text.AlignRight + + font.weight: Font.Light + color: myPalette.text + + text: Number(dataHelper.discNumber).toLocaleString(Qt.locale(), 'f', 0) + + visible: isValid && dataHelper.hasValidDiscNumber && !isSingleDiscAlbum + + Layout.alignment: Qt.AlignVCenter | Qt.AlignRight + + Layout.preferredWidth: discNumberSize.width + Layout.minimumWidth: discNumberSize.width + Layout.maximumWidth: discNumberSize.width + + Layout.rightMargin: elisaTheme.layoutHorizontalMargin / 2 + + TextMetrics { + id: discNumberSize + + text: (9).toLocaleString(Qt.locale(), 'f', 0) + } + } LabelWithToolTip { id: mainCompactLabel - text: { - if (dataHelper.hasValidTrackNumber) { - if (dataHelper.hasValidDiscNumber && !isSingleDiscAlbum) - return i18nc("%1: disk number. %2: track number. %3: track title", "%1 - %2 - %3", - Number(dataHelper.discNumber).toLocaleString(Qt.locale(), 'f', 0), - Number(dataHelper.trackNumber).toLocaleString(Qt.locale(), 'f', 0), dataHelper.title); - else - return i18nc("%1: track number. %2: track title", "%1 - %2", - Number(dataHelper.trackNumber).toLocaleString(Qt.locale(), 'f', 0), dataHelper.title); - } else { - return dataHelper.title; - } - } + text: dataHelper.title font.weight: (isPlaying ? Font.Bold : Font.Normal) color: myPalette.text @@ -312,6 +433,7 @@ implicitWidth: elisaTheme.smallDelegateToolButtonSize opacity: 0 + scale: LayoutMirroring.enabled ? -1 : 1 // We can mirror the symmetrical pause icon visible: opacity > 0.1 @@ -337,25 +459,6 @@ visible: opacity > 0.1 action: removeFromPlayList } - - Image { - id: playIcon - - anchors.fill: parent - - opacity: 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 - } } RatingStar { @@ -430,7 +533,7 @@ } PropertyChanges { target: playIcon - opacity: 0 + opacity: (isPlaying === MediaPlayList.IsPlaying || isPlaying === MediaPlayList.IsPaused ? 1.0 : 0.0) } PropertyChanges { target: entryBackground