diff --git a/src/qml/AlbumsView.qml b/src/qml/AlbumsView.qml index 2821b80a..3dfc0f69 100644 --- a/src/qml/AlbumsView.qml +++ b/src/qml/AlbumsView.qml @@ -1,53 +1,59 @@ /* * Copyright 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.3 import org.kde.elisa 1.0 MediaBrowser { id: allAlbums focus: true anchors { fill: parent leftMargin: elisaTheme.layoutHorizontalMargin rightMargin: elisaTheme.layoutHorizontalMargin } firstPage: GridBrowserView { id: allAlbumsView focus: true defaultIcon: elisaTheme.albumCoverIcon contentModel: elisa.allAlbumsProxyModel image: elisaTheme.albumIcon mainTitle: i18nc("Title of the view of all albums", "Albums") - onEnqueue: elisa.mediaPlayList.enqueue(data, elisa.mediaPlayList.Album) - onReplaceAndPlay: elisa.mediaPlayList.replaceAndPlay(data, elisa.mediaPlayList.Album) + onEnqueue: elisa.mediaPlayList.enqueue(databaseId, name, ElisaUtils.Album, + ElisaUtils.AppendPlayList, + ElisaUtils.DoNotTriggerPlay) + + onReplaceAndPlay: elisa.mediaPlayList.enqueue(databaseId, name, ElisaUtils.Album, + ElisaUtils.ReplacePlayList, + ElisaUtils.TriggerPlay) + onOpen: viewManager.openOneAlbum(allAlbums.stackView, innerMainTitle, innerSecondaryTitle, innerImage, databaseId) onGoBack: viewManager.goBack() } } diff --git a/src/qml/ArtistsView.qml b/src/qml/ArtistsView.qml index 996623af..dd5971c9 100644 --- a/src/qml/ArtistsView.qml +++ b/src/qml/ArtistsView.qml @@ -1,55 +1,61 @@ /* * Copyright 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.3 import org.kde.elisa 1.0 MediaBrowser { id: allArtists focus: true anchors { fill: parent leftMargin: elisaTheme.layoutHorizontalMargin rightMargin: elisaTheme.layoutHorizontalMargin } firstPage: GridBrowserView { id: allArtistsView focus: true showRating: false delegateDisplaySecondaryText: false defaultIcon: elisaTheme.artistIcon contentModel: elisa.allArtistsProxyModel image: elisaTheme.artistIcon mainTitle: i18nc("Title of the view of all artists", "Artists") - onEnqueue: elisa.mediaPlayList.enqueue(data, elisa.mediaPlayList.Artist) - onReplaceAndPlay: elisa.mediaPlayList.replaceAndPlay(data, elisa.mediaPlayList.Artist) + onEnqueue: elisa.mediaPlayList.enqueue(databaseId, name, ElisaUtils.Artist, + ElisaUtils.AppendPlayList, + ElisaUtils.DoNotTriggerPlay) + + onReplaceAndPlay: elisa.mediaPlayList.enqueue(databaseId, name, ElisaUtils.Artist, + ElisaUtils.ReplacePlayList, + ElisaUtils.TriggerPlay) + onOpen: viewManager.openOneArtist(allArtists.stackView, innerMainTitle, innerImage, 0) onGoBack: viewManager.goBack() } } diff --git a/src/qml/GenresView.qml b/src/qml/GenresView.qml index 9f38a49f..e5e367df 100644 --- a/src/qml/GenresView.qml +++ b/src/qml/GenresView.qml @@ -1,53 +1,59 @@ /* * Copyright 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.3 import org.kde.elisa 1.0 MediaBrowser { id: localGenres focus: true anchors { fill: parent leftMargin: elisaTheme.layoutHorizontalMargin rightMargin: elisaTheme.layoutHorizontalMargin } firstPage: GridBrowserView { id: allGenresView focus: true showRating: false delegateDisplaySecondaryText: false defaultIcon: elisaTheme.genresIcon contentModel: elisa.allGenresProxyModel image: elisaTheme.genresIcon mainTitle: i18nc("Title of the view of all genres", "Genres") - onEnqueue: elisa.mediaPlayList.enqueue(data, elisa.mediaPlayList.Genre) - onReplaceAndPlay: elisa.mediaPlayList.replaceAndPlay(data, elisa.mediaPlayList.Genre) + onEnqueue: elisa.mediaPlayList.enqueue(databaseId, name, ElisaUtils.Genre, + ElisaUtils.AppendPlayList, + ElisaUtils.DoNotTriggerPlay) + + onReplaceAndPlay: elisa.mediaPlayList.enqueue(databaseId, name, ElisaUtils.Genre, + ElisaUtils.ReplacePlayList, + ElisaUtils.TriggerPlay) + onOpen: viewManager.openAllArtistsFromGenre(localGenres.stackView, innerMainTitle) onGoBack: viewManager.goBack() } } diff --git a/src/qml/GridBrowserDelegate.qml b/src/qml/GridBrowserDelegate.qml index 19974f4b..4a8e8c58 100644 --- a/src/qml/GridBrowserDelegate.qml +++ b/src/qml/GridBrowserDelegate.qml @@ -1,313 +1,313 @@ /* * 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.Controls 2.2 import QtQuick.Controls 1.4 as Controls1 import QtQuick.Window 2.2 import QtQml.Models 2.1 import QtQuick.Layouts 1.2 import QtGraphicalEffects 1.0 FocusScope { id: gridEntry property var imageUrl property bool shadowForImage property alias mainText: mainLabel.text property alias secondaryText: secondaryLabel.text property var databaseId property bool delegateDisplaySecondaryText: true property bool isPartial - signal enqueue(var data) - signal replaceAndPlay(var data) + signal enqueue(var databaseId, var name) + signal replaceAndPlay(var databaseId, var name) signal open() signal selected() Controls1.Action { id: enqueueAction text: i18nc("Add whole container to play list", "Enqueue") iconName: 'media-track-add-amarok' - onTriggered: enqueue(databaseId) + onTriggered: enqueue(databaseId, mainText) enabled: databaseId !== undefined } Controls1.Action { id: openAction text: i18nc("Open view of the container", "Open") iconName: 'document-open-folder' onTriggered: open() } Controls1.Action { id: replaceAndPlayAction text: i18nc("Clear play list and add whole container to play list", "Play Now and Replace Play List") iconName: 'media-playback-start' - onTriggered: replaceAndPlay(databaseId) + onTriggered: replaceAndPlay(databaseId, mainText) enabled: databaseId !== undefined } Keys.onReturnPressed: openAction.trigger(this) Keys.onEnterPressed: openAction.trigger(this) ColumnLayout { anchors.fill: parent spacing: 0 MouseArea { id: hoverHandle hoverEnabled: true acceptedButtons: Qt.LeftButton Layout.preferredHeight: gridEntry.width * 0.85 + elisaTheme.layoutVerticalMargin * 0.5 + mainLabelSize.height + secondaryLabelSize.height Layout.fillWidth: true onClicked: { gridEntry.selected() } onDoubleClicked: openAction.trigger(this) TextMetrics { id: mainLabelSize font: mainLabel.font text: mainLabel.text } TextMetrics { id: secondaryLabelSize font: secondaryLabel.font text: secondaryLabel.text } ColumnLayout { id: mainData spacing: 0 anchors.fill: parent Item { Layout.preferredHeight: gridEntry.width * 0.85 Layout.preferredWidth: gridEntry.width * 0.85 Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter Loader { id: hoverLoader active: false anchors.centerIn: parent z: 1 opacity: 0 sourceComponent: Row { Controls1.ToolButton { id: enqueueButton objectName: 'enqueueButton' action: enqueueAction visible: enqueueAction.enabled width: elisaTheme.delegateToolButtonSize height: elisaTheme.delegateToolButtonSize } Controls1.ToolButton { id: openButton objectName: 'openButton' action: openAction width: elisaTheme.delegateToolButtonSize height: elisaTheme.delegateToolButtonSize } Controls1.ToolButton { id: replaceAndPlayButton objectName: 'replaceAndPlayButton' scale: LayoutMirroring.enabled ? -1 : 1 action: replaceAndPlayAction visible: replaceAndPlayAction.enabled width: elisaTheme.delegateToolButtonSize height: elisaTheme.delegateToolButtonSize } } } Loader { id: coverImageLoader active: !isPartial anchors.fill: parent sourceComponent: Image { id: coverImage anchors.fill: parent sourceSize.width: parent.width sourceSize.height: parent.height fillMode: Image.PreserveAspectFit smooth: true source: (gridEntry.imageUrl !== undefined ? gridEntry.imageUrl : "") asynchronous: true layer.enabled: shadowForImage layer.effect: DropShadow { source: coverImage radius: 10 spread: 0.1 samples: 21 color: myPalette.shadow } } } Loader { active: isPartial anchors.fill: parent sourceComponent: BusyIndicator { anchors.fill: parent running: true } } } LabelWithToolTip { id: mainLabel font.weight: Font.Bold color: myPalette.text horizontalAlignment: Text.AlignLeft Layout.topMargin: elisaTheme.layoutVerticalMargin * 0.5 Layout.preferredWidth: gridEntry.width * 0.85 Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom elide: Text.ElideRight } LabelWithToolTip { id: secondaryLabel font.weight: Font.Light color: myPalette.text horizontalAlignment: Text.AlignLeft Layout.preferredWidth: gridEntry.width * 0.85 Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom visible: delegateDisplaySecondaryText elide: Text.ElideRight } } } Item { Layout.fillHeight: true } } states: [ State { name: 'notSelected' when: !gridEntry.activeFocus && !hoverHandle.containsMouse PropertyChanges { target: hoverLoader active: false } PropertyChanges { target: hoverLoader opacity: 0.0 } PropertyChanges { target: coverImageLoader opacity: 1 } }, State { name: 'hoveredOrSelected' when: gridEntry.activeFocus || hoverHandle.containsMouse PropertyChanges { target: hoverLoader active: true } PropertyChanges { target: hoverLoader opacity: 1.0 } PropertyChanges { target: coverImageLoader opacity: 0.2 } } ] transitions: [ Transition { to: 'hoveredOrSelected' SequentialAnimation { PropertyAction { properties: "active" } NumberAnimation { properties: "opacity" easing.type: Easing.InOutQuad duration: 100 } } }, Transition { to: 'notSelected' SequentialAnimation { NumberAnimation { properties: "opacity" easing.type: Easing.InOutQuad duration: 100 } PropertyAction { properties: "active" } } } ] } diff --git a/src/qml/GridBrowserView.qml b/src/qml/GridBrowserView.qml index 4e763e6f..a90fc507 100644 --- a/src/qml/GridBrowserView.qml +++ b/src/qml/GridBrowserView.qml @@ -1,165 +1,165 @@ /* * 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.Controls 2.2 import QtQuick.Window 2.2 import QtQml.Models 2.1 import QtQuick.Layouts 1.2 import QtGraphicalEffects 1.0 import org.kde.elisa 1.0 FocusScope { id: gridView property bool isSubPage: false property string mainTitle property string secondaryTitle property url image property alias contentModel: contentDirectoryView.model property alias showRating: navigationBar.showRating property bool delegateDisplaySecondaryText: true property alias expandedFilterView: navigationBar.expandedFilterView property var stackView property url defaultIcon - signal enqueue(var data) - signal replaceAndPlay(var data) + signal enqueue(var databaseId, var name) + signal replaceAndPlay(var databaseId, var name) signal open(var innerMainTitle, var innerSecondaryTitle, var innerImage, var databaseId) signal goBack() SystemPalette { id: myPalette colorGroup: SystemPalette.Active } Theme { id: elisaTheme } ColumnLayout { anchors.fill: parent spacing: 0 NavigationActionBar { id: navigationBar mainTitle: gridView.mainTitle secondaryTitle: gridView.secondaryTitle image: gridView.image enableGoBack: isSubPage sortOrder: if (contentModel) {contentModel.sortedAscending} else true height: elisaTheme.navigationBarHeight Layout.preferredHeight: height Layout.minimumHeight: height Layout.maximumHeight: height Layout.fillWidth: true Loader { active: contentModel !== undefined sourceComponent: Binding { target: contentModel property: 'filterText' value: navigationBar.filterText } } Loader { active: contentModel sourceComponent: Binding { target: contentModel property: 'filterRating' value: navigationBar.filterRating } } onEnqueue: contentModel.enqueueToPlayList() onReplaceAndPlay:contentModel.replaceAndPlayOfPlayList() onGoBack: gridView.goBack() onSort: contentModel.sortModel(order) } Rectangle { color: myPalette.base Layout.fillHeight: true Layout.fillWidth: true clip: true GridView { id: contentDirectoryView anchors.topMargin: 20 focus: true anchors.fill: parent ScrollBar.vertical: ScrollBar { id: scrollBar } boundsBehavior: Flickable.StopAtBounds TextMetrics { id: secondaryLabelSize text: 'example' } ScrollHelper { id: scrollHelper flickable: contentDirectoryView anchors.fill: contentDirectoryView } cellWidth: elisaTheme.gridDelegateWidth cellHeight: (delegateDisplaySecondaryText ? elisaTheme.gridDelegateHeight : elisaTheme.gridDelegateHeight - secondaryLabelSize.height) delegate: GridBrowserDelegate { width: contentDirectoryView.cellWidth height: contentDirectoryView.cellHeight focus: true isPartial: false mainText: model.display secondaryText: if (gridView.delegateDisplaySecondaryText) {model.secondaryText} else {""} imageUrl: (model && model.imageUrl && model.imageUrl.toString() !== "" ? model.imageUrl : defaultIcon) shadowForImage: (model && model.imageUrl && model.imageUrl.toString() !== "" ? true : false) databaseId: model.databaseId delegateDisplaySecondaryText: gridView.delegateDisplaySecondaryText - onEnqueue: gridView.enqueue(data) - onReplaceAndPlay: gridView.replaceAndPlay(data) + onEnqueue: gridView.enqueue(databaseId, name) + onReplaceAndPlay: gridView.replaceAndPlay(databaseId, name) onOpen: gridView.open(model.display, model.secondaryText, (model && model.imageUrl && model.imageUrl.toString() !== "" ? model.imageUrl : defaultIcon), model.databaseId) onSelected: { forceActiveFocus() contentDirectoryView.currentIndex = model.index } } } } } } diff --git a/src/qml/MediaTrackDelegate.qml b/src/qml/MediaTrackDelegate.qml index 38bfc905..2065486a 100644 --- a/src/qml/MediaTrackDelegate.qml +++ b/src/qml/MediaTrackDelegate.qml @@ -1,444 +1,444 @@ /* * Copyright 2016-2017 Matthieu Gallien * Copyright 2017 Alexander Stippich * * 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.2 import QtQuick.Controls 1.4 as Controls1 import QtQuick.Window 2.2 import QtGraphicalEffects 1.0 import org.kde.elisa 1.0 FocusScope { id: mediaTrack property var databaseId property string title property string artist property string album property string albumArtist property string duration property url imageUrl property int trackNumber property int discNumber property int rating property bool isFirstTrackOfDisc property bool isSingleDiscAlbum property bool isAlternateColor property bool detailedView: true signal clicked() - signal enqueue(var data) - signal replaceAndPlay(var data) - - Controls1.Action { - id: replaceAndPlayAction - text: i18nc("Clear play list and enqueue current track", "Play Now and Replace Play List") - iconName: "media-playback-start" - onTriggered: replaceAndPlay(databaseId) - } + signal enqueue(var databaseId, var name) + signal replaceAndPlay(var databaseId, var name) Controls1.Action { id: enqueueAction text: i18nc("Enqueue current track", "Enqueue") iconName: "media-track-add-amarok" - onTriggered: enqueue(databaseId) + onTriggered: enqueue(databaseId, title) } Controls1.Action { id: viewDetailsAction text: i18nc("Show track metadata", "View Details") iconName: "help-about" onTriggered: { if (metadataLoader.active === false) { metadataLoader.active = true } else { metadataLoader.item.close(); metadataLoader.active = false } } } + Controls1.Action { + id: replaceAndPlayAction + text: i18nc("Clear play list and enqueue current track", "Play Now and Replace Play List") + iconName: "media-playback-start" + onTriggered: replaceAndPlay(databaseId, title) + } + TrackDataHelper { id: dataHelper } Keys.onReturnPressed: enqueueToPlaylist(trackData) Keys.onEnterPressed: enqueueToPlaylist(trackData) Loader { id: metadataLoader active: false onLoaded: item.show() sourceComponent: MediaTrackMetadataView { trackDataHelper: dataHelper onRejected: metadataLoader.active = false; } } Rectangle { id: rowRoot anchors.fill: parent color: (isAlternateColor ? myPalette.alternateBase : myPalette.base) MouseArea { id: hoverArea anchors.fill: parent hoverEnabled: true focus: true acceptedButtons: Qt.LeftButton onClicked: { hoverArea.forceActiveFocus() mediaTrack.clicked() } onDoubleClicked: enqueue(trackData) RowLayout { anchors.fill: parent spacing: 0 LabelWithToolTip { id: mainLabel visible: !detailedView text: { if (trackNumber !== 0) { if (artist !== albumArtist) return i18nc("%1: track number. %2: track title. %3: artist name", "%1 - %2 - %3", trackNumber.toLocaleString(Qt.locale(), 'f', 0), title, artist); else return i18nc("%1: track number. %2: track title.", "%1 - %2", trackNumber.toLocaleString(Qt.locale(), 'f', 0), title); } else { if (artist !== albumArtist) return i18nc("%1: track title. %2: artist name", "%1 - %2", title, artist); else return i18nc("%1: track title", "%1", title); } } elide: Text.ElideRight horizontalAlignment: Text.AlignLeft color: myPalette.text Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter Layout.fillWidth: true Layout.leftMargin: { if (!LayoutMirroring.enabled) return (!isSingleDiscAlbum ? elisaTheme.layoutHorizontalMargin * 4 : elisaTheme.layoutHorizontalMargin) else return 0 } Layout.rightMargin: { if (LayoutMirroring.enabled) return (!isSingleDiscAlbum ? elisaTheme.layoutHorizontalMargin * 4 : elisaTheme.layoutHorizontalMargin) else return 0 } } Item { Layout.preferredHeight: mediaTrack.height * 0.9 Layout.preferredWidth: mediaTrack.height * 0.9 Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter visible: detailedView Image { id: coverImageElement anchors.fill: parent sourceSize.width: mediaTrack.height * 0.9 sourceSize.height: mediaTrack.height * 0.9 fillMode: Image.PreserveAspectFit smooth: true source: (imageUrl != '' ? imageUrl : Qt.resolvedUrl(elisaTheme.defaultAlbumImage)) asynchronous: true layer.enabled: imageUrl != '' layer.effect: DropShadow { source: coverImageElement radius: 10 spread: 0.1 samples: 21 color: myPalette.shadow } } } ColumnLayout { visible: detailedView Layout.fillWidth: true Layout.fillHeight: true Layout.alignment: Qt.AlignLeft spacing: 0 LabelWithToolTip { id: mainLabelDetailed text: { if (trackNumber !== 0) { return i18nc("%1: track number. %2: track title", "%1 - %2", trackNumber.toLocaleString(Qt.locale(), 'f', 0), title); } else { return title; } } horizontalAlignment: Text.AlignLeft font.weight: Font.Bold color: myPalette.text Layout.alignment: Qt.AlignLeft | Qt.AlignTop Layout.leftMargin: !LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin : 0 Layout.rightMargin: LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin : 0 Layout.fillWidth: true Layout.topMargin: elisaTheme.layoutVerticalMargin / 2 elide: Text.ElideRight } Item { Layout.fillHeight: true } LabelWithToolTip { id: artistLabel text: { var labelText = "" if (artist) { labelText += artist } if (album !== '') { labelText += ' - ' + album if (!isSingleDiscAlbum) { labelText += ' - CD ' + discNumber } } return labelText; } horizontalAlignment: Text.AlignLeft font.weight: Font.Light font.italic: true color: myPalette.text Layout.alignment: Qt.AlignLeft | Qt.AlignBottom Layout.leftMargin: !LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin : 0 Layout.rightMargin: LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin : 0 Layout.fillWidth: true Layout.bottomMargin: elisaTheme.layoutVerticalMargin / 2 elide: Text.ElideRight } } Loader { id: hoverLoader active: false Layout.alignment: Qt.AlignVCenter | Qt.AlignRight Layout.rightMargin: 10 z: 1 opacity: 0 sourceComponent: Row { anchors.centerIn: parent Controls1.ToolButton { id: detailsButton height: elisaTheme.delegateHeight width: elisaTheme.delegateHeight action: viewDetailsAction } Controls1.ToolButton { id: enqueueButton height: elisaTheme.delegateHeight width: elisaTheme.delegateHeight action: enqueueAction } Controls1.ToolButton { id: clearAndEnqueueButton scale: LayoutMirroring.enabled ? -1 : 1 height: elisaTheme.delegateHeight width: elisaTheme.delegateHeight action: replaceAndPlayAction } } } RatingStar { id: ratingWidget starSize: elisaTheme.ratingStarSize starRating: rating Layout.alignment: Qt.AlignVCenter | Qt.AlignRight Layout.leftMargin: elisaTheme.layoutHorizontalMargin Layout.rightMargin: elisaTheme.layoutHorizontalMargin } TextMetrics { id: durationTextMetrics text: i18nc("This is used to preserve a fixed width for the duration text.", "00:00") } LabelWithToolTip { id: durationLabel text: duration font.weight: Font.Light color: myPalette.text horizontalAlignment: Text.AlignRight Layout.alignment: Qt.AlignVCenter | Qt.AlignRight Layout.rightMargin: !LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin : 0 Layout.leftMargin: LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin : 0 Layout.preferredWidth: durationTextMetrics.width + 1 } } } } states: [ State { name: 'notSelected' when: !hoverArea.containsMouse && !mediaTrack.activeFocus PropertyChanges { target: hoverLoader active: false } PropertyChanges { target: hoverLoader opacity: 0.0 } PropertyChanges { target: ratingWidget hoverWidgetOpacity: 0.0 } PropertyChanges { target: rowRoot color: (isAlternateColor ? myPalette.alternateBase : myPalette.base) } }, State { name: 'hoveredOrSelected' when: hoverArea.containsMouse || mediaTrack.activeFocus PropertyChanges { target: hoverLoader active: true } PropertyChanges { target: hoverLoader opacity: 1.0 } PropertyChanges { target: ratingWidget hoverWidgetOpacity: 1.0 } PropertyChanges { target: rowRoot color: myPalette.mid } } ] transitions: [ Transition { to: 'hoveredOrSelected' SequentialAnimation { PropertyAction { properties: "active" } ParallelAnimation { NumberAnimation { properties: "opacity, hoverWidgetOpacity" easing.type: Easing.InOutQuad duration: 250 } ColorAnimation { properties: "color" duration: 250 } } } }, Transition { to: 'notSelected' SequentialAnimation { ParallelAnimation { NumberAnimation { properties: "opacity, hoverWidgetOpacity" easing.type: Easing.InOutQuad duration: 250 } ColorAnimation { properties: "color" duration: 250 } } PropertyAction { properties: "active" } } } ] } diff --git a/src/qml/TracksView.qml b/src/qml/TracksView.qml index e1c24597..1e153c5d 100644 --- a/src/qml/TracksView.qml +++ b/src/qml/TracksView.qml @@ -1,71 +1,75 @@ /* * Copyright 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.3 import org.kde.elisa 1.0 MediaBrowser { id: localTracks focus: true anchors { fill: parent leftMargin: elisaTheme.layoutHorizontalMargin rightMargin: elisaTheme.layoutHorizontalMargin } firstPage: ListBrowserView { id: allTracksView focus: true contentModel: elisa.allTracksProxyModel delegate: MediaTrackDelegate { id: entry width: allTracksView.delegateWidth height: elisaTheme.trackDelegateHeight focus: true databaseId: model.databaseId title: model.title artist: model.artist album: (model.album !== undefined && model.album !== '' ? model.album : '') albumArtist: model.albumArtist duration: model.duration imageUrl: (model.imageUrl !== undefined && model.imageUrl !== '' ? model.imageUrl : '') trackNumber: model.trackNumber discNumber: model.discNumber rating: model.rating isFirstTrackOfDisc: false isSingleDiscAlbum: model.isSingleDiscAlbum - onEnqueue: elisa.mediaPlayList.enqueue(data) + onEnqueue: elisa.mediaPlayList.enqueue(databaseId, name, ElisaUtils.Track, + ElisaUtils.AppendPlayList, + ElisaUtils.DoNotTriggerPlay) - onReplaceAndPlay: elisa.mediaPlayList.replaceAndPlay(data) + onReplaceAndPlay: elisa.mediaPlayList.enqueue(databaseId, name, ElisaUtils.Track, + ElisaUtils.ReplacePlayList, + ElisaUtils.TriggerPlay) onClicked: contentDirectoryView.currentIndex = index } image: elisaTheme.tracksIcon mainTitle: i18nc("Title of the view of all tracks", "Tracks") } }