diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -372,6 +372,7 @@
qml/ContextViewLyrics.qml
qml/ContentView.qml
qml/ViewSelector.qml
+ qml/ViewSelectorDelegate.qml
qml/DataGridView.qml
qml/TracksView.qml
qml/AlbumView.qml
diff --git a/src/qml/AlbumView.qml b/src/qml/AlbumView.qml
--- a/src/qml/AlbumView.qml
+++ b/src/qml/AlbumView.qml
@@ -45,7 +45,6 @@
id: albumGridView
focus: true
- activeFocusOnTab: true
anchors.fill: parent
@@ -75,6 +74,7 @@
rating: model.rating
isFirstTrackOfDisc: true
isSingleDiscAlbum: true
+ isSelected: albumGridView.currentIndex === index
isAlternateColor: (index % 2) === 1
mediaTrack.onEnqueue: elisa.mediaPlayList.enqueue(databaseId, name, ElisaUtils.Track,
@@ -87,6 +87,12 @@
mediaTrack.onClicked: albumGridView.currentIndex = index
+
+ onActiveFocusChanged: {
+ if (activeFocus && albumGridView.currentIndex !== index) {
+ albumGridView.currentIndex = index
+ }
+ }
}
allowArtistNavigation: true
diff --git a/src/qml/ContentView.qml b/src/qml/ContentView.qml
--- a/src/qml/ContentView.qml
+++ b/src/qml/ContentView.qml
@@ -260,11 +260,6 @@
}
Rectangle {
- border {
- color: (mainContentView.activeFocus ? myPalette.highlight : myPalette.base)
- width: 1
- }
-
radius: 3
color: myPalette.base
diff --git a/src/qml/FileBrowserDelegate.qml b/src/qml/FileBrowserDelegate.qml
--- a/src/qml/FileBrowserDelegate.qml
+++ b/src/qml/FileBrowserDelegate.qml
@@ -23,14 +23,15 @@
import org.kde.elisa 1.0
FocusScope {
- id: fileDelegate
+ id: gridEntry
property var fileName
property var fileUrl
property var imageUrl
property var contentModel
property bool isDirectory
property bool isPlayList
+ property bool isSelected
signal enqueue(var data)
signal replaceAndPlay(var data)
@@ -44,16 +45,29 @@
onLoaded: item.show()
sourceComponent: MediaTrackMetadataView {
- fileName: fileDelegate.fileUrl
+ fileName: gridEntry.fileUrl
onRejected: metadataLoader.active = false;
}
}
- Keys.onReturnPressed: fileDelegate.enqueue(fileUrl)
- Keys.onEnterPressed: fileDelegate.enqueue(fileUrl)
+ Keys.onReturnPressed: gridEntry.enqueue(fileUrl)
+ Keys.onEnterPressed: gridEntry.enqueue(fileUrl)
+
+ Rectangle {
+ id: stateIndicator
+
+ anchors.fill: parent
+ z: 1
+
+ color: "transparent"
+ opacity: 0.4
+
+ radius: 3
+ }
ColumnLayout {
anchors.fill: parent
+ z: 2
spacing: 0
@@ -63,13 +77,13 @@
hoverEnabled: true
acceptedButtons: Qt.LeftButton
- Layout.preferredHeight: fileDelegate.width * 0.85 + elisaTheme.layoutVerticalMargin * 0.5 +
+ Layout.preferredHeight: gridEntry.width * 0.85 + elisaTheme.layoutVerticalMargin * 0.5 +
(mainLabelSize.boundingRect.height - mainLabelSize.boundingRect.y)
Layout.fillWidth: true
- onClicked: fileDelegate.selected()
+ onClicked: gridEntry.selected()
- onDoubleClicked: fileDelegate.open(fileUrl)
+ onDoubleClicked: gridEntry.open(fileUrl)
TextMetrics {
id: mainLabelSize
@@ -84,8 +98,8 @@
anchors.fill: parent
Item {
- Layout.preferredHeight: fileDelegate.width * 0.85
- Layout.preferredWidth: fileDelegate.width * 0.85
+ Layout.preferredHeight: gridEntry.width * 0.85
+ Layout.preferredWidth: gridEntry.width * 0.85
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
@@ -197,7 +211,7 @@
horizontalAlignment: Text.AlignHCenter
Layout.topMargin: elisaTheme.layoutVerticalMargin * 0.5
- Layout.maximumWidth: fileDelegate.width * 0.9
+ Layout.maximumWidth: gridEntry.width * 0.9
Layout.minimumWidth: Layout.maximumWidth
Layout.maximumHeight: (mainLabelSize.boundingRect.height - mainLabelSize.boundingRect.y) * 2
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
@@ -221,7 +235,15 @@
states: [
State {
name: 'notSelected'
- when: !fileDelegate.activeFocus && !hoverArea.containsMouse
+ when: !gridEntry.activeFocus && !hoverHandle.containsMouse && !gridEntry.isSelected
+ PropertyChanges {
+ target: stateIndicator
+ color: 'transparent'
+ }
+ PropertyChanges {
+ target: stateIndicator
+ opacity: 1.0
+ }
PropertyChanges {
target: hoverLoader
active: false
@@ -231,9 +253,57 @@
opacity: 0.0
}
},
+ State {
+ name: 'hovered'
+ when: hoverHandle.containsMouse && !gridEntry.activeFocus
+ PropertyChanges {
+ target: stateIndicator
+ color: myPalette.highlight
+ }
+ PropertyChanges {
+ target: stateIndicator
+ opacity: 0.2
+ }
+ PropertyChanges {
+ target: hoverLoader
+ active: true
+ }
+ PropertyChanges {
+ target: hoverLoader
+ opacity: 1.0
+ }
+ },
+ State {
+ name: 'selected'
+ when: gridEntry.isSelected && !gridEntry.activeFocus
+ PropertyChanges {
+ target: stateIndicator
+ color: myPalette.mid
+ }
+ PropertyChanges {
+ target: stateIndicator
+ opacity: 0.6
+ }
+ PropertyChanges {
+ target: hoverLoader
+ active: false
+ }
+ PropertyChanges {
+ target: hoverLoader
+ opacity: 0.
+ }
+ },
State {
name: 'hoveredOrSelected'
- when: fileDelegate.activeFocus || hoverArea.containsMouse
+ when: gridEntry.activeFocus
+ PropertyChanges {
+ target: stateIndicator
+ color: myPalette.highlight
+ }
+ PropertyChanges {
+ target: stateIndicator
+ opacity: 0.6
+ }
PropertyChanges {
target: hoverLoader
active: true
@@ -247,28 +317,21 @@
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"
+ ParallelAnimation {
+ NumberAnimation {
+ properties: "opacity"
+ easing.type: Easing.InOutQuad
+ duration: 300
+ }
+ ColorAnimation {
+ properties: "color"
+ easing.type: Easing.InOutQuad
+ duration: 300
+ }
}
}
}
diff --git a/src/qml/FileBrowserView.qml b/src/qml/FileBrowserView.qml
--- a/src/qml/FileBrowserView.qml
+++ b/src/qml/FileBrowserView.qml
@@ -104,13 +104,16 @@
anchors.topMargin: 20
anchors.fill: parent
- focus: true
+ activeFocusOnTab: true
+ keyNavigationEnabled: true
ScrollBar.vertical: ScrollBar {
id: scrollBar
}
boundsBehavior: Flickable.StopAtBounds
+ currentIndex: -1
+
model: proxyModel
ScrollHelper {
@@ -143,8 +146,11 @@
delegate: FileBrowserDelegate {
width: contentDirectoryView.cellWidth
height: contentDirectoryView.cellHeight
+
focus: true
+ isSelected: contentDirectoryView.currentIndex === index
+
isDirectory: model.directory
isPlayList: model.isPlaylist
fileName: model.name
@@ -158,6 +164,13 @@
forceActiveFocus()
contentDirectoryView.currentIndex = model.index
}
+
+ onActiveFocusChanged: {
+ if (activeFocus && contentDirectoryView.currentIndex !== model.index) {
+ contentDirectoryView.currentIndex = model.index
+ }
+ }
+
onOpen: loadFolderAndClear(data)
}
}
diff --git a/src/qml/FrequentlyPlayedTracks.qml b/src/qml/FrequentlyPlayedTracks.qml
--- a/src/qml/FrequentlyPlayedTracks.qml
+++ b/src/qml/FrequentlyPlayedTracks.qml
@@ -47,7 +47,6 @@
id: listView
focus: true
- activeFocusOnTab: true
anchors.fill: parent
@@ -65,14 +64,16 @@
title: model.title
artist: model.artist
album: (model.album !== undefined && model.album !== '' ? model.album : '')
- albumArtist: model.albumArtist
+ albumArtist: (model.albumArtist !== undefined && model.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
+ isSelected: listView.currentIndex === index
+ isAlternateColor: (index % 2) === 1
onEnqueue: elisa.mediaPlayList.enqueue(databaseId, name, modelType,
ElisaUtils.AppendPlayList,
@@ -82,7 +83,10 @@
ElisaUtils.ReplacePlayList,
ElisaUtils.TriggerPlay)
- onClicked: contentDirectoryView.currentIndex = index
+ onClicked: {
+ listView.currentIndex = index
+ entry.forceActiveFocus()
+ }
}
Loader {
diff --git a/src/qml/GridBrowserDelegate.qml b/src/qml/GridBrowserDelegate.qml
--- a/src/qml/GridBrowserDelegate.qml
+++ b/src/qml/GridBrowserDelegate.qml
@@ -33,6 +33,7 @@
property var databaseId
property bool delegateDisplaySecondaryText: true
property bool isPartial
+ property bool isSelected
signal enqueue(var databaseId, var name)
signal replaceAndPlay(var databaseId, var name)
@@ -42,8 +43,21 @@
Keys.onReturnPressed: open()
Keys.onEnterPressed: open()
+ Rectangle {
+ id: stateIndicator
+
+ anchors.fill: parent
+ z: 1
+
+ color: "transparent"
+ opacity: 0.4
+
+ radius: 3
+ }
+
ColumnLayout {
anchors.fill: parent
+ z: 2
spacing: 0
@@ -231,6 +245,7 @@
Layout.maximumWidth: gridEntry.width * 0.9
Layout.minimumWidth: Layout.maximumWidth
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
+ Layout.bottomMargin: delegateDisplaySecondaryText ? 0 : elisaTheme.layoutVerticalMargin
elide: Text.ElideRight
}
@@ -246,6 +261,7 @@
// See https://bugreports.qt.io/browse/QTBUG-49646
horizontalAlignment: Text.AlignHCenter
+ Layout.bottomMargin: elisaTheme.layoutVerticalMargin
Layout.maximumWidth: gridEntry.width * 0.9
Layout.minimumWidth: Layout.maximumWidth
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
@@ -265,7 +281,15 @@
states: [
State {
name: 'notSelected'
- when: !gridEntry.activeFocus && !hoverHandle.containsMouse
+ when: !gridEntry.activeFocus && !hoverHandle.containsMouse && !gridEntry.isSelected
+ PropertyChanges {
+ target: stateIndicator
+ color: 'transparent'
+ }
+ PropertyChanges {
+ target: stateIndicator
+ opacity: 1.0
+ }
PropertyChanges {
target: hoverLoader
active: false
@@ -275,9 +299,57 @@
opacity: 0.0
}
},
+ State {
+ name: 'hovered'
+ when: hoverHandle.containsMouse && !gridEntry.activeFocus
+ PropertyChanges {
+ target: stateIndicator
+ color: myPalette.highlight
+ }
+ PropertyChanges {
+ target: stateIndicator
+ opacity: 0.2
+ }
+ PropertyChanges {
+ target: hoverLoader
+ active: true
+ }
+ PropertyChanges {
+ target: hoverLoader
+ opacity: 1.0
+ }
+ },
+ State {
+ name: 'selected'
+ when: gridEntry.isSelected && !gridEntry.activeFocus
+ PropertyChanges {
+ target: stateIndicator
+ color: myPalette.mid
+ }
+ PropertyChanges {
+ target: stateIndicator
+ opacity: 0.6
+ }
+ PropertyChanges {
+ target: hoverLoader
+ active: false
+ }
+ PropertyChanges {
+ target: hoverLoader
+ opacity: 0.
+ }
+ },
State {
name: 'hoveredOrSelected'
- when: gridEntry.activeFocus || hoverHandle.containsMouse
+ when: gridEntry.activeFocus
+ PropertyChanges {
+ target: stateIndicator
+ color: myPalette.highlight
+ }
+ PropertyChanges {
+ target: stateIndicator
+ opacity: 0.6
+ }
PropertyChanges {
target: hoverLoader
active: true
@@ -291,28 +363,21 @@
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"
+ ParallelAnimation {
+ NumberAnimation {
+ properties: "opacity"
+ easing.type: Easing.InOutQuad
+ duration: 300
+ }
+ ColorAnimation {
+ properties: "color"
+ easing.type: Easing.InOutQuad
+ duration: 300
+ }
}
}
}
diff --git a/src/qml/GridBrowserView.qml b/src/qml/GridBrowserView.qml
--- a/src/qml/GridBrowserView.qml
+++ b/src/qml/GridBrowserView.qml
@@ -102,7 +102,6 @@
id: contentDirectoryView
anchors.topMargin: 20
- focus: true
activeFocusOnTab: true
keyNavigationEnabled: true
@@ -113,6 +112,8 @@
}
boundsBehavior: Flickable.StopAtBounds
+ currentIndex: -1
+
TextMetrics {
id: secondaryLabelSize
text: 'example'
@@ -135,6 +136,8 @@
focus: true
+ isSelected: contentDirectoryView.currentIndex === index
+
isPartial: false
mainText: model.display
@@ -153,6 +156,12 @@
forceActiveFocus()
contentDirectoryView.currentIndex = model.index
}
+
+ onActiveFocusChanged: {
+ if (activeFocus && contentDirectoryView.currentIndex !== model.index) {
+ contentDirectoryView.currentIndex = model.index
+ }
+ }
}
}
}
diff --git a/src/qml/ListBrowserView.qml b/src/qml/ListBrowserView.qml
--- a/src/qml/ListBrowserView.qml
+++ b/src/qml/ListBrowserView.qml
@@ -98,16 +98,18 @@
Layout.fillHeight: true
Layout.fillWidth: true
+ Layout.margins: 2
ListView {
id: contentDirectoryView
anchors.topMargin: 20
anchors.fill: parent
- focus: true
activeFocusOnTab: true
keyNavigationEnabled: true
+ currentIndex: -1
+
ScrollBar.vertical: ScrollBar {
id: scrollBar
}
@@ -119,6 +121,10 @@
flickable: contentDirectoryView
anchors.fill: contentDirectoryView
}
+
+ onCountChanged: if (count === 0) {
+ currentIndex = -1;
+ }
}
}
}
diff --git a/src/qml/MediaAlbumTrackDelegate.qml b/src/qml/MediaAlbumTrackDelegate.qml
--- a/src/qml/MediaAlbumTrackDelegate.qml
+++ b/src/qml/MediaAlbumTrackDelegate.qml
@@ -35,6 +35,7 @@
property alias rating: mediaTrack.rating
property alias isFirstTrackOfDisc: mediaTrack.isFirstTrackOfDisc
property alias isSingleDiscAlbum: mediaTrack.isSingleDiscAlbum
+ property alias isSelected: mediaTrack.isSelected
property alias isAlternateColor: mediaTrack.isAlternateColor
ColumnLayout {
diff --git a/src/qml/MediaTrackDelegate.qml b/src/qml/MediaTrackDelegate.qml
--- a/src/qml/MediaTrackDelegate.qml
+++ b/src/qml/MediaTrackDelegate.qml
@@ -39,6 +39,7 @@
property int rating
property bool isFirstTrackOfDisc
property bool isSingleDiscAlbum
+ property bool isSelected
property bool isAlternateColor
property bool detailedView: true
@@ -93,264 +94,264 @@
id: rowRoot
anchors.fill: parent
+ z: 1
color: (isAlternateColor ? myPalette.alternateBase : myPalette.base)
+ }
- MouseArea {
- id: hoverArea
+ MouseArea {
+ id: hoverArea
- anchors.fill: parent
+ anchors.fill: parent
+ z: 2
- hoverEnabled: true
- focus: true
- acceptedButtons: Qt.LeftButton
+ hoverEnabled: true
+ acceptedButtons: Qt.LeftButton
- onClicked: {
- hoverArea.forceActiveFocus()
- mediaTrack.clicked()
- }
+ onClicked: {
+ mediaTrack.clicked()
+ }
- onDoubleClicked: enqueue(databaseId, title)
+ onDoubleClicked: enqueue(databaseId, title)
- RowLayout {
- anchors.fill: parent
- spacing: 0
+ RowLayout {
+ anchors.fill: parent
+ spacing: 0
- LabelWithToolTip {
- id: mainLabel
+ LabelWithToolTip {
+ id: mainLabel
- visible: !detailedView
+ 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);
- }
+ 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
+ elide: Text.ElideRight
+ horizontalAlignment: Text.AlignLeft
- color: myPalette.text
+ 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
- }
+ 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
+ Item {
+ Layout.preferredHeight: mediaTrack.height * 0.9
+ Layout.preferredWidth: mediaTrack.height * 0.9
- Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
+ Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
- visible: detailedView
+ visible: detailedView
- Image {
- id: coverImageElement
+ Image {
+ id: coverImageElement
- anchors.fill: parent
+ anchors.fill: parent
- sourceSize.width: mediaTrack.height * 0.9
- sourceSize.height: mediaTrack.height * 0.9
- fillMode: Image.PreserveAspectFit
- smooth: true
+ sourceSize.width: mediaTrack.height * 0.9
+ sourceSize.height: mediaTrack.height * 0.9
+ fillMode: Image.PreserveAspectFit
+ smooth: true
- source: (imageUrl != '' ? imageUrl : Qt.resolvedUrl(elisaTheme.defaultAlbumImage))
+ source: (imageUrl != '' ? imageUrl : Qt.resolvedUrl(elisaTheme.defaultAlbumImage))
- asynchronous: true
+ asynchronous: true
- layer.enabled: imageUrl != ''
+ layer.enabled: imageUrl != ''
- layer.effect: DropShadow {
- source: coverImageElement
+ layer.effect: DropShadow {
+ source: coverImageElement
- radius: 10
- spread: 0.1
- samples: 21
+ radius: 10
+ spread: 0.1
+ samples: 21
- color: myPalette.shadow
- }
+ color: myPalette.shadow
}
}
+ }
- ColumnLayout {
- visible: detailedView
+ ColumnLayout {
+ visible: detailedView
- Layout.fillWidth: true
- Layout.fillHeight: true
- Layout.alignment: Qt.AlignLeft
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ Layout.alignment: Qt.AlignLeft
- spacing: 0
+ spacing: 0
- LabelWithToolTip {
- id: mainLabelDetailed
+ 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;
- }
+ 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
+ horizontalAlignment: Text.AlignLeft
- font.weight: Font.Bold
- color: myPalette.text
+ 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
+ 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
- }
+ elide: Text.ElideRight
+ }
- Item {
- Layout.fillHeight: true
- }
+ Item {
+ Layout.fillHeight: true
+ }
- LabelWithToolTip {
- id: artistLabel
+ LabelWithToolTip {
+ id: artistLabel
- text: {
- var labelText = ""
- if (artist) {
- labelText += artist
- }
- if (album !== '') {
- labelText += ' - ' + album
- if (!isSingleDiscAlbum) {
- labelText += ' - CD ' + discNumber
- }
+ text: {
+ var labelText = ""
+ if (artist) {
+ labelText += artist
+ }
+ if (album !== '') {
+ labelText += ' - ' + album
+ if (!isSingleDiscAlbum) {
+ labelText += ' - CD ' + discNumber
}
- return labelText;
}
- horizontalAlignment: Text.AlignLeft
+ return labelText;
+ }
+ horizontalAlignment: Text.AlignLeft
- font.weight: Font.Light
- font.italic: true
- color: myPalette.text
+ 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
+ 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
- }
+ elide: Text.ElideRight
}
+ }
- Loader {
- id: hoverLoader
- active: false
+ Loader {
+ id: hoverLoader
+ active: false
- Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
- Layout.rightMargin: 10
+ Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
+ Layout.rightMargin: 10
- z: 1
- opacity: 0
+ z: 1
+ opacity: 0
- sourceComponent: Row {
- anchors.centerIn: parent
+ sourceComponent: Row {
+ anchors.centerIn: parent
- Controls1.ToolButton {
- id: detailsButton
+ Controls1.ToolButton {
+ id: detailsButton
- height: elisaTheme.delegateHeight
- width: elisaTheme.delegateHeight
+ height: elisaTheme.delegateHeight
+ width: elisaTheme.delegateHeight
- action: viewDetailsAction
- }
+ action: viewDetailsAction
+ }
- Controls1.ToolButton {
- id: enqueueButton
+ Controls1.ToolButton {
+ id: enqueueButton
- height: elisaTheme.delegateHeight
- width: elisaTheme.delegateHeight
+ height: elisaTheme.delegateHeight
+ width: elisaTheme.delegateHeight
- action: enqueueAction
- }
+ action: enqueueAction
+ }
- Controls1.ToolButton {
- id: clearAndEnqueueButton
+ Controls1.ToolButton {
+ id: clearAndEnqueueButton
- scale: LayoutMirroring.enabled ? -1 : 1
+ scale: LayoutMirroring.enabled ? -1 : 1
- height: elisaTheme.delegateHeight
- width: elisaTheme.delegateHeight
+ height: elisaTheme.delegateHeight
+ width: elisaTheme.delegateHeight
- action: replaceAndPlayAction
- }
+ action: replaceAndPlayAction
}
}
+ }
- RatingStar {
- id: ratingWidget
+ RatingStar {
+ id: ratingWidget
- starSize: elisaTheme.ratingStarSize
+ starSize: elisaTheme.ratingStarSize
- starRating: rating
+ starRating: rating
- 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
+ }
- LabelWithToolTip {
- id: durationLabel
+ LabelWithToolTip {
+ id: durationLabel
- text: duration
+ text: duration
- font.weight: Font.Light
- color: myPalette.text
+ font.weight: Font.Light
+ color: myPalette.text
- horizontalAlignment: Text.AlignRight
+ horizontalAlignment: Text.AlignRight
- Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
- Layout.rightMargin: !LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin : 0
- Layout.leftMargin: LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin : 0
- }
+ Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
+ Layout.rightMargin: !LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin : 0
+ Layout.leftMargin: LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin : 0
}
}
}
states: [
State {
name: 'notSelected'
- when: !hoverArea.containsMouse && !mediaTrack.activeFocus
+ when: !mediaTrack.activeFocus && !hoverArea.containsMouse && !mediaTrack.isSelected
PropertyChanges {
target: hoverLoader
active: false
@@ -367,10 +368,14 @@
target: rowRoot
color: (isAlternateColor ? myPalette.alternateBase : myPalette.base)
}
+ PropertyChanges {
+ target: rowRoot
+ opacity: 1
+ }
},
State {
- name: 'hoveredOrSelected'
- when: hoverArea.containsMouse || mediaTrack.activeFocus
+ name: 'hovered'
+ when: !mediaTrack.activeFocus && hoverArea.containsMouse
PropertyChanges {
target: hoverLoader
active: true
@@ -383,51 +388,83 @@
target: ratingWidget
hoverWidgetOpacity: 1.0
}
+ PropertyChanges {
+ target: rowRoot
+ color: myPalette.highlight
+ }
+ PropertyChanges {
+ target: rowRoot
+ opacity: 0.2
+ }
+ },
+ State {
+ name: 'selected'
+ when: !mediaTrack.activeFocus && mediaTrack.isSelected
+ PropertyChanges {
+ target: hoverLoader
+ active: false
+ }
+ PropertyChanges {
+ target: hoverLoader
+ opacity: 0.0
+ }
+ PropertyChanges {
+ target: ratingWidget
+ hoverWidgetOpacity: 1.0
+ }
PropertyChanges {
target: rowRoot
color: myPalette.mid
}
+ PropertyChanges {
+ target: rowRoot
+ opacity: 1.
+ }
+ },
+ State {
+ name: 'focused'
+ when: mediaTrack.activeFocus
+ PropertyChanges {
+ target: hoverLoader
+ active: true
+ }
+ PropertyChanges {
+ target: hoverLoader
+ opacity: 1.0
+ }
+ PropertyChanges {
+ target: ratingWidget
+ hoverWidgetOpacity: 1.0
+ }
+ PropertyChanges {
+ target: rowRoot
+ color: myPalette.highlight
+ }
+ PropertyChanges {
+ target: rowRoot
+ opacity: 0.6
+ }
}
]
transitions: [
Transition {
- to: 'hoveredOrSelected'
SequentialAnimation {
PropertyAction {
properties: "active"
}
ParallelAnimation {
NumberAnimation {
properties: "opacity, hoverWidgetOpacity"
easing.type: Easing.InOutQuad
- duration: 250
+ duration: 200
}
ColorAnimation {
properties: "color"
- duration: 250
+ duration: 350
}
}
}
- },
- 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/NavigationActionBar.qml b/src/qml/NavigationActionBar.qml
--- a/src/qml/NavigationActionBar.qml
+++ b/src/qml/NavigationActionBar.qml
@@ -21,9 +21,14 @@
import QtQuick.Controls 2.2
import QtQuick.Controls 1.4 as Controls1
-FocusScope {
+ColumnLayout {
id: navigationBar
+ spacing: 0
+
+ anchors.topMargin: elisaTheme.layoutVerticalMargin
+ anchors.bottomMargin: elisaTheme.layoutVerticalMargin
+
property string mainTitle
property string secondaryTitle
property url image
@@ -73,290 +78,296 @@
onTriggered: sortOrder ? sort(Qt.DescendingOrder) : sort(Qt.AscendingOrder)
}
- ColumnLayout {
- anchors.fill: parent
+ RowLayout {
spacing: 0
+ Layout.alignment: Qt.AlignTop
+ Layout.preferredHeight: elisaTheme.navigationBarHeight
+ Layout.minimumHeight: elisaTheme.navigationBarHeight
+ Layout.maximumHeight: elisaTheme.navigationBarHeight
- anchors.topMargin: elisaTheme.layoutVerticalMargin
- anchors.bottomMargin: elisaTheme.layoutVerticalMargin
+ Controls1.ToolButton {
+ action: goPreviousAction
+ objectName: 'goPreviousButton'
- RowLayout {
- spacing: 0
- Layout.alignment: Qt.AlignTop
- Layout.preferredHeight: elisaTheme.navigationBarHeight
- Layout.minimumHeight: elisaTheme.navigationBarHeight
- Layout.maximumHeight: elisaTheme.navigationBarHeight
+ Keys.onReturnPressed: action.trigger()
- Controls1.ToolButton {
- action: goPreviousAction
- objectName: 'goPreviousButton'
+ activeFocusOnTab: true
+ focus: enableGoBack
+
+ Layout.leftMargin: !LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin : 0
+ Layout.rightMargin: LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin : 0
+ visible: enableGoBack
+ }
- Keys.onReturnPressed: action.trigger()
+ Image {
+ id: mainIcon
+ source: image
- Layout.leftMargin: !LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin : 0
- Layout.rightMargin: LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin : 0
- visible: enableGoBack
- }
+ asynchronous: true
- Image {
- id: mainIcon
- source: image
+ sourceSize.height: elisaTheme.coverImageSize / 2
+ sourceSize.width: elisaTheme.coverImageSize / 2
- asynchronous: true
+ fillMode: Image.PreserveAspectFit
- sourceSize.height: elisaTheme.coverImageSize / 2
- sourceSize.width: elisaTheme.coverImageSize / 2
+ Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft
- fillMode: Image.PreserveAspectFit
+ Layout.preferredHeight: elisaTheme.coverImageSize / 2
+ Layout.minimumHeight: elisaTheme.coverImageSize / 2
+ Layout.maximumHeight: elisaTheme.coverImageSize / 2
+ Layout.preferredWidth: elisaTheme.coverImageSize / 2
+ Layout.minimumWidth: elisaTheme.coverImageSize / 2
+ Layout.maximumWidth: elisaTheme.coverImageSize / 2
+ Layout.leftMargin: !LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin : 0
+ Layout.rightMargin: LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin : 0
+ }
- Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft
+ ColumnLayout {
+ Layout.preferredHeight: elisaTheme.coverImageSize / 1.9
+ Layout.minimumHeight: elisaTheme.coverImageSize / 1.9
+ Layout.maximumHeight: elisaTheme.coverImageSize / 1.9
- Layout.preferredHeight: elisaTheme.coverImageSize / 2
- Layout.minimumHeight: elisaTheme.coverImageSize / 2
- Layout.maximumHeight: elisaTheme.coverImageSize / 2
- Layout.preferredWidth: elisaTheme.coverImageSize / 2
- Layout.minimumWidth: elisaTheme.coverImageSize / 2
- Layout.maximumWidth: elisaTheme.coverImageSize / 2
- Layout.leftMargin: !LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin : 0
- Layout.rightMargin: LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin : 0
- }
+ spacing: 0
- ColumnLayout {
- Layout.preferredHeight: elisaTheme.coverImageSize / 1.9
- Layout.minimumHeight: elisaTheme.coverImageSize / 1.9
- Layout.maximumHeight: elisaTheme.coverImageSize / 1.9
+ Layout.fillWidth: true
+ Layout.leftMargin: !LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin : 0
+ Layout.rightMargin: LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin : 0
- spacing: 0
+ LabelWithToolTip {
+ id: albumLabel
+
+ text: mainTitle
Layout.fillWidth: true
- Layout.leftMargin: !LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin : 0
- Layout.rightMargin: LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin : 0
+ Layout.alignment: Qt.AlignTop | Qt.AlignLeft
+ Layout.topMargin: secondaryTitle !== "" ? 0 : 9
- LabelWithToolTip {
- id: albumLabel
+ elide: Text.ElideRight
+ fontSizeMode: Text.Fit
- text: mainTitle
+ Layout.preferredHeight: elisaTheme.coverImageSize / 5
+ Layout.minimumHeight: elisaTheme.coverImageSize / 5
+ Layout.maximumHeight: elisaTheme.coverImageSize / 5
- Layout.fillWidth: true
- Layout.alignment: Qt.AlignTop | Qt.AlignLeft
- Layout.topMargin: secondaryTitle !== "" ? 0 : 9
+ color: myPalette.text
+
+ font {
+ pointSize: elisaTheme.defaultFontPointSize * 2
+ }
+ }
- elide: Text.ElideRight
- fontSizeMode: Text.Fit
+ LabelWithToolTip {
+ id: authorLabel
- Layout.preferredHeight: elisaTheme.coverImageSize / 5
- Layout.minimumHeight: elisaTheme.coverImageSize / 5
- Layout.maximumHeight: elisaTheme.coverImageSize / 5
+ text: secondaryTitle
- color: myPalette.text
+ color: myPalette.text
- font {
- pointSize: elisaTheme.defaultFontPointSize * 2
- }
+ Layout.fillWidth: true
+ Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
+
+ font {
+ pointSize: elisaTheme.defaultFontPointSize
}
- LabelWithToolTip {
- id: authorLabel
+ elide: Text.ElideRight
- text: secondaryTitle
+ visible: secondaryTitle !== ""
+ }
- color: myPalette.text
+ RowLayout {
+ Layout.fillWidth: true
+ spacing: 0
+ Layout.bottomMargin: secondaryTitle !== "" ? 0 : 14
- Layout.fillWidth: true
- Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
+ Controls1.Button {
+ objectName: 'enqueueButton'
+ text: i18nc("Add current list to playlist", "Enqueue")
+ iconName: "media-track-add-amarok"
- font {
- pointSize: elisaTheme.defaultFontPointSize
- }
+ activeFocusOnTab: true
+ focus: true
- elide: Text.ElideRight
+ onClicked: enqueue()
+ Keys.onReturnPressed: enqueue()
- visible: secondaryTitle !== ""
+ Layout.leftMargin: 0
+ Layout.rightMargin: 0
}
- RowLayout {
- Layout.fillWidth: true
- spacing: 0
- Layout.bottomMargin: secondaryTitle !== "" ? 0 : 14
-
- Controls1.Button {
- objectName: 'enqueueButton'
- text: i18nc("Add current list to playlist", "Enqueue")
- iconName: "media-track-add-amarok"
+ Controls1.Button {
+ objectName: 'replaceAndPlayButton'
+ text: i18nc("Clear playlist and play", "Replace and Play")
+ tooltip: i18nc("Clear playlist and add current list to it", "Replace PlayList and Play Now")
+ iconName: "media-playback-start"
- onClicked: enqueue()
- Keys.onReturnPressed: enqueue()
+ activeFocusOnTab: true
- Layout.leftMargin: 0
- Layout.rightMargin: 0
- }
+ onClicked: replaceAndPlay()
+ Keys.onReturnPressed: replaceAndPlay()
- Controls1.Button {
- objectName: 'replaceAndPlayButton'
- text: i18nc("Clear playlist and play", "Replace and Play")
- tooltip: i18nc("Clear playlist and add current list to it", "Replace PlayList and Play Now")
- iconName: "media-playback-start"
+ Layout.leftMargin: !LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin : 0
+ Layout.rightMargin: LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin : 0
+ }
- onClicked: replaceAndPlay()
- Keys.onReturnPressed: replaceAndPlay()
+ Controls1.Button {
+ objectName: 'showArtistButton'
+ id: showArtistButton
- Layout.leftMargin: !LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin : 0
- Layout.rightMargin: LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin : 0
- }
+ visible: allowArtistNavigation
+ text: i18nc("Button to navigate to the artist of the album", "Display Artist")
+ iconName: "view-media-artist"
- Controls1.Button {
- objectName: 'showArtistButton'
- id: showArtistButton
+ activeFocusOnTab: true
- visible: allowArtistNavigation
- text: i18nc("Button to navigate to the artist of the album", "Display Artist")
- iconName: "view-media-artist"
+ onClicked: showArtist()
+ Keys.onReturnPressed: showArtist()
- onClicked: showArtist()
- Keys.onReturnPressed: showArtist()
+ Layout.leftMargin: !LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin : 0
+ Layout.rightMargin: LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin : 0
+ }
- Layout.leftMargin: !LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin : 0
- Layout.rightMargin: LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin : 0
- }
+ Item {
+ Layout.fillWidth: true
+ }
- Item {
- Layout.fillWidth: true
- }
+ Controls1.ToolButton {
+ action: showFilterAction
+ objectName: 'showFilterButton'
- Controls1.ToolButton {
- action: showFilterAction
- objectName: 'showFilterButton'
+ activeFocusOnTab: true
- Keys.onReturnPressed: action.trigger()
+ Keys.onReturnPressed: action.trigger()
- Layout.alignment: Qt.AlignRight
- Layout.leftMargin: !LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin : 0
- Layout.rightMargin: LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin : 0
- }
+ Layout.alignment: Qt.AlignRight
+ Layout.leftMargin: !LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin : 0
+ Layout.rightMargin: LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin : 0
}
}
}
+ }
- RowLayout {
- id: filterRow
+ RowLayout {
+ id: filterRow
- spacing: 0
+ spacing: 0
- visible: opacity > 0.0
+ visible: opacity > 0.0
- opacity: 0
+ opacity: 0
- Layout.preferredHeight: elisaTheme.navigationBarFilterHeight
- Layout.minimumHeight: elisaTheme.navigationBarFilterHeight
- Layout.maximumHeight: elisaTheme.navigationBarFilterHeight
- Layout.fillWidth: true
- Layout.topMargin: elisaTheme.layoutVerticalMargin * 2
- Layout.leftMargin: !LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin : 0
- Layout.rightMargin: LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin : 0
- Layout.alignment: Qt.AlignTop
+ Layout.preferredHeight: elisaTheme.navigationBarFilterHeight
+ Layout.minimumHeight: elisaTheme.navigationBarFilterHeight
+ Layout.maximumHeight: elisaTheme.navigationBarFilterHeight
+ Layout.fillWidth: true
+ Layout.topMargin: elisaTheme.layoutVerticalMargin * 2
+ Layout.leftMargin: !LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin : 0
+ Layout.rightMargin: LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin : 0
+ Layout.alignment: Qt.AlignTop
- LabelWithToolTip {
- text: i18nc("before the TextField input of the filter", "Search: ")
+ LabelWithToolTip {
+ text: i18nc("before the TextField input of the filter", "Search: ")
- font.bold: true
+ font.bold: true
- Layout.bottomMargin: 0
+ Layout.bottomMargin: 0
- color: myPalette.text
- }
+ color: myPalette.text
+ }
- TextField {
- id: filterTextInput
- objectName: 'filterTextInput'
+ TextField {
+ id: filterTextInput
+ objectName: 'filterTextInput'
- horizontalAlignment: TextInput.AlignLeft
+ horizontalAlignment: TextInput.AlignLeft
- placeholderText: i18nc("Placeholder text in the filter text box", "Album name, artist, etc.")
+ placeholderText: i18nc("Placeholder text in the filter text box", "Album name, artist, etc.")
- Layout.bottomMargin: 0
- Layout.fillWidth: true
- Layout.minimumWidth: (placeHolderTextWidth.boundingRect.width - placeHolderTextWidth.boundingRect.x) * 1.2
- implicitWidth: (placeHolderTextWidth.boundingRect.width - placeHolderTextWidth.boundingRect.x) * 1.2
+ Layout.bottomMargin: 0
+ Layout.fillWidth: true
+ Layout.minimumWidth: (placeHolderTextWidth.boundingRect.width - placeHolderTextWidth.boundingRect.x) * 1.2
+ implicitWidth: (placeHolderTextWidth.boundingRect.width - placeHolderTextWidth.boundingRect.x) * 1.2
- TextMetrics {
- id: placeHolderTextWidth
- text: filterTextInput.placeholderText
- }
+ TextMetrics {
+ id: placeHolderTextWidth
+ text: filterTextInput.placeholderText
+ }
- Image {
- anchors.top: parent.top
- anchors.bottom: parent.bottom
- anchors.right: parent.right
- anchors.margins: elisaTheme.filterClearButtonMargin
- id: clearText
- fillMode: Image.PreserveAspectFit
- smooth: true
- visible: parent.text
- source: Qt.resolvedUrl(elisaTheme.clearIcon)
- height: parent.height
- width: parent.height
- sourceSize.width: parent.height
- sourceSize.height: parent.height
- mirror: LayoutMirroring.enabled
-
- MouseArea {
- id: clear
- anchors { horizontalCenter: parent.horizontalCenter; verticalCenter: parent.verticalCenter }
- height: parent.parent.height
- width: parent.parent.height
- onClicked: {
- parent.parent.text = ""
- parent.parent.forceActiveFocus()
- }
+ Image {
+ anchors.top: parent.top
+ anchors.bottom: parent.bottom
+ anchors.right: parent.right
+ anchors.margins: elisaTheme.filterClearButtonMargin
+ id: clearText
+ fillMode: Image.PreserveAspectFit
+ smooth: true
+ visible: parent.text
+ source: Qt.resolvedUrl(elisaTheme.clearIcon)
+ height: parent.height
+ width: parent.height
+ sourceSize.width: parent.height
+ sourceSize.height: parent.height
+ mirror: LayoutMirroring.enabled
+
+ MouseArea {
+ id: clear
+ anchors { horizontalCenter: parent.horizontalCenter; verticalCenter: parent.verticalCenter }
+ height: parent.parent.height
+ width: parent.parent.height
+ onClicked: {
+ parent.parent.text = ""
+ parent.parent.forceActiveFocus()
}
}
}
+ }
- LabelWithToolTip {
- text: i18nc("before the Rating widget input of the filter", "Rating: ")
+ LabelWithToolTip {
+ text: i18nc("before the Rating widget input of the filter", "Rating: ")
- visible: showRating
+ visible: showRating
- font.bold: true
+ font.bold: true
- color: myPalette.text
+ color: myPalette.text
- Layout.bottomMargin: 0
- Layout.leftMargin: !LayoutMirroring.enabled ? (elisaTheme.layoutHorizontalMargin * 2) : 0
- Layout.rightMargin: LayoutMirroring.enabled ? (elisaTheme.layoutHorizontalMargin * 2) : 0
- }
+ Layout.bottomMargin: 0
+ Layout.leftMargin: !LayoutMirroring.enabled ? (elisaTheme.layoutHorizontalMargin * 2) : 0
+ Layout.rightMargin: LayoutMirroring.enabled ? (elisaTheme.layoutHorizontalMargin * 2) : 0
+ }
- RatingStar {
- id: ratingFilter
- objectName: 'ratingFilter'
+ RatingStar {
+ id: ratingFilter
+ objectName: 'ratingFilter'
- visible: showRating
- hoverWidgetOpacity: 1
+ visible: showRating
+ hoverWidgetOpacity: 1
- readOnly: false
+ readOnly: false
- starSize: elisaTheme.ratingStarSize
+ starSize: elisaTheme.ratingStarSize
- Layout.bottomMargin: 0
- }
+ Layout.bottomMargin: 0
+ }
- Item {
- Layout.fillWidth: true
- implicitWidth: elisaTheme.layoutHorizontalMargin * 4
- }
+ Item {
+ Layout.fillWidth: true
+ implicitWidth: elisaTheme.layoutHorizontalMargin * 4
+ }
- Controls1.ToolButton {
- action: sortAction
- objectName: 'sortAscendingButton'
+ Controls1.ToolButton {
+ action: sortAction
+ objectName: 'sortAscendingButton'
- Keys.onReturnPressed: action.trigger()
+ activeFocusOnTab: true
- Layout.alignment: Qt.AlignRight
- Layout.leftMargin: !LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin : 0
- Layout.rightMargin: LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin : 0
- visible: enableSorting
- }
+ Keys.onReturnPressed: action.trigger()
+
+ Layout.alignment: Qt.AlignRight
+ Layout.leftMargin: !LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin : 0
+ Layout.rightMargin: LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin : 0
+ visible: enableSorting
}
}
diff --git a/src/qml/PlayListBasicView.qml b/src/qml/PlayListBasicView.qml
--- a/src/qml/PlayListBasicView.qml
+++ b/src/qml/PlayListBasicView.qml
@@ -31,8 +31,10 @@
signal displayError(var errorText)
focus: true
- activeFocusOnTab: true
keyNavigationEnabled: true
+ activeFocusOnTab: true
+
+ currentIndex: -1
section.property: 'albumSection'
section.criteria: ViewSection.FullString
@@ -131,6 +133,12 @@
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
@@ -152,4 +160,8 @@
}
}
}
+
+ onCountChanged: if (count === 0) {
+ currentIndex = -1;
+ }
}
diff --git a/src/qml/PlayListEntry.qml b/src/qml/PlayListEntry.qml
--- a/src/qml/PlayListEntry.qml
+++ b/src/qml/PlayListEntry.qml
@@ -118,297 +118,298 @@
anchors.fill: parent
anchors.rightMargin: LayoutMirroring.enabled ? scrollBarWidth : 0
+ z: 1
- color: (isAlternateColor ? myPalette.alternateBase : myPalette.base)
+ color: myPalette.base
height: elisaTheme.playListDelegateHeight
+ }
- focus: true
-
- ColumnLayout {
- spacing: 0
+ ColumnLayout {
+ spacing: 0
- anchors.fill: parent
+ anchors.fill: parent
+ anchors.rightMargin: LayoutMirroring.enabled ? scrollBarWidth : 0
+ z: 2
- Item {
- Layout.fillWidth: true
- Layout.fillHeight: true
+ Item {
+ Layout.fillWidth: true
+ Layout.fillHeight: true
- RowLayout {
- id: trackRow
+ RowLayout {
+ id: trackRow
- anchors.fill: parent
+ anchors.fill: parent
- spacing: elisaTheme.layoutHorizontalMargin / 4
+ 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.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
+ Image {
+ id: playIcon
- anchors.fill: parent
+ anchors.fill: 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: 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
- }
+ sourceSize.width: parent.height * 1.
+ sourceSize.height: parent.height * 1.
+ 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 !== 0 && 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
+ }
- Controls1.ToolButton {
- id: infoButton
- objectName: 'infoButton'
+ Controls1.ToolButton {
+ id: infoButton
+ objectName: 'infoButton'
- implicitHeight: elisaTheme.smallDelegateToolButtonSize
- implicitWidth: elisaTheme.smallDelegateToolButtonSize
+ implicitHeight: elisaTheme.smallDelegateToolButtonSize
+ implicitWidth: elisaTheme.smallDelegateToolButtonSize
- opacity: 0
+ opacity: 0
- visible: opacity > 0.1
+ visible: opacity > 0.1
- action: showInfo
- Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
- }
+ action: showInfo
+ Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
+ }
- Controls1.ToolButton {
- id: playPauseButton
- objectName: 'playPauseButton'
+ Controls1.ToolButton {
+ id: playPauseButton
+ objectName: 'playPauseButton'
- implicitHeight: elisaTheme.smallDelegateToolButtonSize
- implicitWidth: elisaTheme.smallDelegateToolButtonSize
+ implicitHeight: elisaTheme.smallDelegateToolButtonSize
+ implicitWidth: elisaTheme.smallDelegateToolButtonSize
- 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
- Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
- }
+ visible: opacity > 0.1
+ action: !(isPlaying === MediaPlayList.IsPlaying) ? playNow : pauseNow
+ Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
+ }
- Item {
- implicitHeight: elisaTheme.smallDelegateToolButtonSize
- implicitWidth: elisaTheme.smallDelegateToolButtonSize
- Layout.maximumWidth: elisaTheme.smallDelegateToolButtonSize
- Layout.maximumHeight: elisaTheme.smallDelegateToolButtonSize
- Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
+ Item {
+ implicitHeight: elisaTheme.smallDelegateToolButtonSize
+ implicitWidth: elisaTheme.smallDelegateToolButtonSize
+ Layout.maximumWidth: elisaTheme.smallDelegateToolButtonSize
+ Layout.maximumHeight: elisaTheme.smallDelegateToolButtonSize
+ Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
- Controls1.ToolButton {
- id: removeButton
- objectName: 'removeButton'
+ Controls1.ToolButton {
+ id: removeButton
+ objectName: 'removeButton'
- anchors.fill: parent
+ anchors.fill: parent
- opacity: 0
+ opacity: 0
- visible: opacity > 0.1
- action: removeFromPlayList
- }
+ visible: opacity > 0.1
+ action: removeFromPlayList
}
+ }
- 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 / 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
}
}
}
}
states: [
State {
name: 'notSelected'
- when: !containsMouse && (!playListEntry.activeFocus || !isSelected)
+ when: !containsMouse && !isSelected && !playListEntry.activeFocus
PropertyChanges {
target: removeButton
opacity: 0
@@ -429,14 +430,18 @@
target: entryBackground
color: (isAlternateColor ? myPalette.alternateBase : myPalette.base)
}
+ PropertyChanges {
+ target: entryBackground
+ opacity: 1.
+ }
PropertyChanges {
target: ratingWidget
hoverWidgetOpacity: 0.0
}
},
State {
- name: 'hoveredOrSelected'
- when: containsMouse || (playListEntry.activeFocus && isSelected)
+ name: 'hovered'
+ when: containsMouse && !playListEntry.activeFocus
PropertyChanges {
target: removeButton
opacity: 1
@@ -453,10 +458,78 @@
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
diff --git a/src/qml/RecentlyPlayedTracks.qml b/src/qml/RecentlyPlayedTracks.qml
--- a/src/qml/RecentlyPlayedTracks.qml
+++ b/src/qml/RecentlyPlayedTracks.qml
@@ -47,7 +47,6 @@
id: listView
focus: true
- activeFocusOnTab: true
anchors.fill: parent
@@ -65,14 +64,16 @@
title: model.title
artist: model.artist
album: (model.album !== undefined && model.album !== '' ? model.album : '')
- albumArtist: model.albumArtist
+ albumArtist: (model.albumArtist !== undefined && model.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
+ isSelected: listView.currentIndex === index
+ isAlternateColor: (index % 2) === 1
onEnqueue: elisa.mediaPlayList.enqueue(databaseId, name, modelType,
ElisaUtils.AppendPlayList,
@@ -82,7 +83,10 @@
ElisaUtils.ReplacePlayList,
ElisaUtils.TriggerPlay)
- onClicked: contentDirectoryView.currentIndex = index
+ onClicked: {
+ listView.currentIndex = index
+ entry.forceActiveFocus()
+ }
}
Loader {
diff --git a/src/qml/TracksView.qml b/src/qml/TracksView.qml
--- a/src/qml/TracksView.qml
+++ b/src/qml/TracksView.qml
@@ -47,7 +47,6 @@
id: listView
focus: true
- activeFocusOnTab: true
anchors.fill: parent
@@ -65,14 +64,16 @@
title: model.title
artist: model.artist
album: (model.album !== undefined && model.album !== '' ? model.album : '')
- albumArtist: model.albumArtist
+ albumArtist: (model.albumArtist !== undefined && model.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
+ isSelected: listView.currentIndex === index
+ isAlternateColor: (index % 2) === 1
onEnqueue: elisa.mediaPlayList.enqueue(databaseId, name, modelType,
ElisaUtils.AppendPlayList,
@@ -82,7 +83,10 @@
ElisaUtils.ReplacePlayList,
ElisaUtils.TriggerPlay)
- onClicked: contentDirectoryView.currentIndex = index
+ onClicked: {
+ listView.currentIndex = index
+ entry.forceActiveFocus()
+ }
}
Loader {
diff --git a/src/qml/ViewSelector.qml b/src/qml/ViewSelector.qml
--- a/src/qml/ViewSelector.qml
+++ b/src/qml/ViewSelector.qml
@@ -42,174 +42,72 @@
Rectangle {
anchors.fill: parent
+ z: 1
- color: myPalette.base
- border {
- color: (rootFocusScope.activeFocus ? myPalette.highlight : "transparent")
- width: 1
- }
-
- ScrollView {
- focus: true
-
- anchors.fill: parent
-
- clip: true
- ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
-
-
- ListView {
- id: viewModeView
-
- focus: true
- activeFocusOnTab: true
- keyNavigationEnabled: true
-
- property bool ignoreCurrentItemChanges: false
-
- z: 2
-
- anchors.topMargin: elisaTheme.layoutHorizontalMargin * 2
-
- model: DelegateModel {
- id: pageDelegateModel
-
- delegate: MouseArea {
- id: itemMouseArea
-
- property var viewType: model.type
-
- height: elisaTheme.viewSelectorDelegateHeight * 1.4
- width: viewModeView.width
-
- hoverEnabled: true
- acceptedButtons: Qt.LeftButton
-
- Loader {
- anchors.fill: parent
- active: itemMouseArea && itemMouseArea.containsMouse && !nameLabel.visible
-
- sourceComponent: ToolTip {
- delay: Qt.styleHints.mousePressAndHoldInterval
- text: model.display
- visible: itemMouseArea && itemMouseArea.containsMouse && !nameLabel.visible
-
- contentItem: Label {
- text: model.display
- color: myPalette.highlightedText
- }
-
- enter: Transition { NumberAnimation { properties: "opacity"; easing.type: Easing.InOutQuad; from: 0.0; to: 1.0; duration: 300; } }
- exit: Transition { NumberAnimation { properties: "opacity"; easing.type: Easing.InOutQuad; from: 1.0; to: 0.0; duration: 300; } }
-
- background: Rectangle {
- color: myPalette.shadow
- radius: elisaTheme.tooltipRadius
-
- layer.enabled: true
- layer.effect: DropShadow {
- horizontalOffset: elisaTheme.shadowOffset
- verticalOffset: elisaTheme.shadowOffset
- radius: 8
- samples: 17
- color: myPalette.shadow
- }
- }
- }
- }
+ border.color: myPalette.base
- Image {
- id: viewIcon
-
- z: 2
-
- anchors {
- verticalCenter: parent.verticalCenter
- leftMargin: elisaTheme.layoutHorizontalMargin
- left: parent.left
- }
-
- height: elisaTheme.viewSelectorDelegateHeight
- width: elisaTheme.viewSelectorDelegateHeight
+ Behavior on border.color {
+ ColorAnimation {
+ duration: 300
+ }
+ }
+ }
- sourceSize {
- width: elisaTheme.viewSelectorDelegateHeight
- height: elisaTheme.viewSelectorDelegateHeight
- }
+ ScrollView {
+ focus: true
- source: model.image
+ anchors.fill: parent
+ z: 2
- layer.effect: ColorOverlay {
+ clip: true
+ ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
- color: (index === viewModeView.currentIndex || itemMouseArea.containsMouse ? myPalette.highlight : "transparent")
+ ListView {
+ id: viewModeView
- Behavior on color {
- ColorAnimation {
- duration: 300
- }
- }
- }
- }
+ focus: true
+ activeFocusOnTab: true
+ keyNavigationEnabled: true
- LabelWithToolTip {
- id: nameLabel
+ property bool ignoreCurrentItemChanges: false
- z: 2
+ z: 2
- anchors.verticalCenter: parent.verticalCenter
- anchors.leftMargin: elisaTheme.layoutHorizontalMargin
- anchors.left: viewIcon.right
- anchors.right: parent.right
- anchors.rightMargin: elisaTheme.layoutHorizontalMargin
- verticalAlignment: "AlignVCenter"
+ anchors.topMargin: elisaTheme.layoutHorizontalMargin * 2
- font.pointSize: Math.round(elisaTheme.defaultFontPointSize * 1.1)
+ model: DelegateModel {
+ id: pageDelegateModel
- text: model.display
- elide: Text.ElideRight
+ delegate: ViewSelectorDelegate {
+ id: entry
- opacity: textOpacity
- visible: opacity > 0
+ height: Math.round(elisaTheme.viewSelectorDelegateHeight * 1.4)
+ width: viewModeView.width
- Behavior on opacity {
- NumberAnimation {
- duration: 150
- }
- }
+ focus: true
- color: (viewModeView.currentIndex === index || itemMouseArea.containsMouse ? myPalette.highlight : myPalette.text)
+ isSelected: viewModeView.currentIndex === index
- Behavior on color {
- ColorAnimation {
- duration: 300
- }
- }
- }
-
- onClicked: viewModeView.currentIndex = index
+ onClicked: {
+ viewModeView.currentIndex = index
+ entry.forceActiveFocus()
}
}
+ }
- footer: MouseArea {
- width: viewModeView.width
- height: viewModeView.height - y
+ footer: MouseArea {
+ width: viewModeView.width
+ height: viewModeView.height - y
- acceptedButtons: Qt.LeftButton
+ acceptedButtons: Qt.LeftButton
- onClicked:
- {
- rootFocusScope.focus = true
- }
+ onClicked:
+ {
+ rootFocusScope.focus = true
}
-
- onCurrentItemChanged: if (!ignoreCurrentItemChanges) switchView(currentItem.viewType)
}
- }
- Behavior on border.color {
- ColorAnimation {
- duration: 300
- }
+ onCurrentItemChanged: if (!ignoreCurrentItemChanges) switchView(currentItem.viewType)
}
}
diff --git a/src/qml/ViewSelectorDelegate.qml b/src/qml/ViewSelectorDelegate.qml
new file mode 100644
--- /dev/null
+++ b/src/qml/ViewSelectorDelegate.qml
@@ -0,0 +1,252 @@
+/*
+ * Copyright 2016-2019 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 QtGraphicalEffects 1.0
+
+FocusScope {
+ id: rootItem
+
+ property var viewType: model.type
+ property bool isSelected
+
+ signal clicked()
+
+ Rectangle {
+ id: backgroundHighlight
+
+ anchors.fill: parent
+ z: 1
+
+ color: "transparent"
+ }
+
+ MouseArea {
+ id: hoverArea
+
+ anchors.fill: parent
+ z: 2
+
+ hoverEnabled: true
+ acceptedButtons: Qt.LeftButton
+
+ onClicked: {
+ rootItem.clicked()
+ }
+
+ Loader {
+ id: hoverLoader
+
+ anchors.fill: parent
+ active: false
+
+ sourceComponent: ToolTip {
+ delay: Qt.styleHints.mousePressAndHoldInterval
+ text: model.display
+ visible: hoverArea && hoverArea.containsMouse && !nameLabel.visible
+
+ contentItem: Label {
+ text: model.display
+ color: myPalette.highlightedText
+ }
+
+ enter: Transition { NumberAnimation { properties: "opacity"; easing.type: Easing.InOutQuad; from: 0.0; to: 1.0; duration: 300; } }
+ exit: Transition { NumberAnimation { properties: "opacity"; easing.type: Easing.InOutQuad; from: 1.0; to: 0.0; duration: 300; } }
+
+ background: Rectangle {
+ color: myPalette.shadow
+ radius: elisaTheme.tooltipRadius
+
+ layer.enabled: true
+ layer.effect: DropShadow {
+ horizontalOffset: elisaTheme.shadowOffset
+ verticalOffset: elisaTheme.shadowOffset
+ radius: 8
+ samples: 17
+ color: myPalette.shadow
+ }
+ }
+ }
+ }
+
+ Image {
+ id: viewIcon
+
+ z: 2
+
+ anchors {
+ verticalCenter: parent.verticalCenter
+ leftMargin: elisaTheme.layoutHorizontalMargin
+ left: parent.left
+ }
+
+ height: elisaTheme.viewSelectorDelegateHeight
+ width: elisaTheme.viewSelectorDelegateHeight
+
+ sourceSize {
+ width: elisaTheme.viewSelectorDelegateHeight
+ height: elisaTheme.viewSelectorDelegateHeight
+ }
+
+ source: model.image
+
+ layer.enabled: true
+ layer.effect: ColorOverlay {
+ color: nameLabel.color
+ }
+ }
+
+ LabelWithToolTip {
+ id: nameLabel
+
+ z: 2
+
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.leftMargin: elisaTheme.layoutHorizontalMargin
+ anchors.left: viewIcon.right
+ anchors.right: parent.right
+ anchors.rightMargin: elisaTheme.layoutHorizontalMargin
+ verticalAlignment: "AlignVCenter"
+
+ font.pointSize: Math.round(elisaTheme.defaultFontPointSize * 1.1)
+
+ text: model.display
+ elide: Text.ElideRight
+
+ opacity: textOpacity
+ visible: opacity > 0
+
+ color: (viewModeView.currentIndex === index || hoverArea.containsMouse ? myPalette.highlight : myPalette.text)
+ }
+ }
+
+ states: [
+ State {
+ name: 'notSelected'
+ when: !rootItem.activeFocus && !hoverArea.containsMouse && !rootItem.isSelected
+ PropertyChanges {
+ target: hoverLoader
+ active: false
+ }
+ PropertyChanges {
+ target: hoverLoader
+ opacity: 0.0
+ }
+ PropertyChanges {
+ target: viewIcon
+ opacity: 1
+ }
+ PropertyChanges {
+ target: nameLabel
+ color: myPalette.buttonText
+ }
+ PropertyChanges {
+ target: backgroundHighlight
+ color: 'transparent'
+ }
+ },
+ State {
+ name: 'hovered'
+ when: !rootItem.activeFocus && hoverArea.containsMouse
+ PropertyChanges {
+ target: hoverLoader
+ active: true
+ }
+ PropertyChanges {
+ target: hoverLoader
+ opacity: 1.0
+ }
+ PropertyChanges {
+ target: viewIcon
+ opacity: 0.4
+ }
+ PropertyChanges {
+ target: nameLabel
+ color: myPalette.buttonText
+ }
+ PropertyChanges {
+ target: backgroundHighlight
+ color: Qt.rgba(myPalette.highlight.r, myPalette.highlight.g, myPalette.highlight.b, 0.2)
+ }
+ },
+ State {
+ name: 'selected'
+ when: !rootItem.activeFocus && rootItem.isSelected
+ PropertyChanges {
+ target: hoverLoader
+ active: false
+ }
+ PropertyChanges {
+ target: hoverLoader
+ opacity: 0.0
+ }
+ PropertyChanges {
+ target: viewIcon
+ opacity: 1
+ }
+ PropertyChanges {
+ target: nameLabel
+ color: myPalette.buttonText
+ }
+ PropertyChanges {
+ target: backgroundHighlight
+ color: myPalette.mid
+ }
+ },
+ State {
+ name: 'focused'
+ when: rootItem.activeFocus
+ PropertyChanges {
+ target: hoverLoader
+ active: false
+ }
+ PropertyChanges {
+ target: hoverLoader
+ opacity: 0.0
+ }
+ PropertyChanges {
+ target: viewIcon
+ opacity: 1.
+ }
+ PropertyChanges {
+ target: nameLabel
+ color: myPalette.highlightedText
+ }
+ PropertyChanges {
+ target: backgroundHighlight
+ color: myPalette.highlight
+ }
+ }
+ ]
+
+ transitions: [
+ Transition {
+ ParallelAnimation {
+ NumberAnimation {
+ properties: "opacity"
+ easing.type: Easing.InOutQuad
+ duration: 200
+ }
+ ColorAnimation {
+ properties: "color"
+ duration: 250
+ }
+ }
+ }
+ ]
+}
diff --git a/src/resources.qrc b/src/resources.qrc
--- a/src/resources.qrc
+++ b/src/resources.qrc
@@ -44,6 +44,7 @@
qml/BasicPlayListAlbumHeader.qml
qml/MetaDataDelegate.qml
qml/ContextViewLyrics.qml
+ qml/ViewSelectorDelegate.qml
windows/WindowsTheme.qml