Desktop UI: Port pill for podcast list
This commit is contained in:
parent
f3fb2585dc
commit
1386245b50
3 changed files with 381 additions and 63 deletions
|
@ -1,4 +1,4 @@
|
|||
import QtQuick 2.0
|
||||
import QtQuick 2.3
|
||||
import QtQuick.Controls 1.0
|
||||
import QtQuick.Layouts 1.0
|
||||
import QtQuick.Dialogs 1.2
|
||||
|
@ -7,6 +7,7 @@ import 'dialogs'
|
|||
|
||||
import 'common'
|
||||
import 'common/util.js' as Util
|
||||
import 'common/constants.js' as Constants
|
||||
|
||||
ApplicationWindow {
|
||||
id: appWindow
|
||||
|
@ -63,87 +64,282 @@ ApplicationWindow {
|
|||
SplitView {
|
||||
anchors.fill: parent
|
||||
|
||||
TableView {
|
||||
id: podcastListView
|
||||
ColumnLayout {
|
||||
TableView {
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
|
||||
width: 200
|
||||
model: GPodderPodcastListModel { id: podcastListModel }
|
||||
GPodderPodcastListModelConnections {}
|
||||
headerVisible: false
|
||||
alternatingRowColors: false
|
||||
id: podcastListView
|
||||
|
||||
Menu {
|
||||
id: podcastContextMenu
|
||||
MenuItem {
|
||||
text: 'Unsubscribe'
|
||||
onTriggered: {
|
||||
var podcast_id = podcastListModel.get(podcastListView.currentRow).id;
|
||||
py.call('main.unsubscribe', [podcast_id]);
|
||||
model: GPodderPodcastListModel { id: podcastListModel }
|
||||
GPodderPodcastListModelConnections {}
|
||||
headerVisible: false
|
||||
alternatingRowColors: false
|
||||
horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff
|
||||
|
||||
Menu {
|
||||
id: podcastContextMenu
|
||||
|
||||
MenuItem {
|
||||
text: 'Unsubscribe'
|
||||
onTriggered: {
|
||||
var podcast_id = podcastListModel.get(podcastListView.currentRow).id;
|
||||
py.call('main.unsubscribe', [podcast_id]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rowDelegate: Rectangle {
|
||||
height: 40
|
||||
color: styleData.selected ? '#eee' : '#fff'
|
||||
|
||||
MouseArea {
|
||||
acceptedButtons: Qt.RightButton
|
||||
anchors.fill: parent
|
||||
onClicked: podcastContextMenu.popup()
|
||||
}
|
||||
}
|
||||
|
||||
TableViewColumn {
|
||||
role: 'coverart'
|
||||
title: 'Image'
|
||||
delegate: Item {
|
||||
height: 32
|
||||
width: 32
|
||||
Image {
|
||||
source: styleData.value
|
||||
width: 32
|
||||
height: 32
|
||||
anchors.centerIn: parent
|
||||
MenuItem {
|
||||
text: 'Mark episodes as old'
|
||||
onTriggered: {
|
||||
var podcast_id = podcastListModel.get(podcastListView.currentRow).id;
|
||||
py.call('main.mark_episodes_as_old', [podcast_id]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
width: 40
|
||||
}
|
||||
|
||||
TableViewColumn {
|
||||
role: 'title'
|
||||
title: 'Podcast'
|
||||
delegate: Item {
|
||||
rowDelegate: Rectangle {
|
||||
height: 40
|
||||
Text {
|
||||
text: styleData.value
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
color: styleData.selected ? Constants.colors.select : 'transparent'
|
||||
|
||||
MouseArea {
|
||||
acceptedButtons: Qt.RightButton
|
||||
anchors.fill: parent
|
||||
onClicked: podcastContextMenu.popup()
|
||||
}
|
||||
}
|
||||
|
||||
TableViewColumn {
|
||||
id: coverartColumn
|
||||
width: 40
|
||||
|
||||
role: 'coverart'
|
||||
title: 'Image'
|
||||
delegate: Item {
|
||||
height: 32
|
||||
width: 32
|
||||
Image {
|
||||
mipmap: true
|
||||
source: styleData.value
|
||||
width: 32
|
||||
height: 32
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TableViewColumn {
|
||||
role: 'title'
|
||||
title: 'Podcast'
|
||||
width: podcastListView.width - coverartColumn.width - indicatorColumn.width - 2 * 5
|
||||
|
||||
delegate: Item {
|
||||
property var row: podcastListModel.get(styleData.row)
|
||||
|
||||
width: parent.width
|
||||
height: 40
|
||||
|
||||
Column {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
spacing: -5
|
||||
|
||||
Text {
|
||||
width: parent.width
|
||||
color: styleData.selected ? 'white' : 'black'
|
||||
|
||||
font.bold: row.newEpisodes
|
||||
text: styleData.value
|
||||
elide: styleData.elideMode
|
||||
}
|
||||
|
||||
Text {
|
||||
width: parent.width
|
||||
font.pointSize: 10
|
||||
color: styleData.selected ? 'white' : 'black'
|
||||
|
||||
text: row.description
|
||||
elide: styleData.elideMode
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TableViewColumn {
|
||||
id: indicatorColumn
|
||||
width: 50
|
||||
|
||||
role: 'indicator'
|
||||
title: 'Indicator'
|
||||
|
||||
delegate: Item {
|
||||
height: 32
|
||||
width: 50
|
||||
property var row: podcastListModel.get(styleData.row)
|
||||
|
||||
Rectangle {
|
||||
anchors.centerIn: parent
|
||||
visible: row.updating
|
||||
|
||||
color: styleData.selected ? '#ffffff' : '#000000'
|
||||
|
||||
property real phase: 0
|
||||
|
||||
width: 15 + 3 * Math.sin(phase)
|
||||
height: width
|
||||
|
||||
PropertyAnimation on phase {
|
||||
loops: Animation.Infinite
|
||||
duration: 2000
|
||||
running: parent.visible
|
||||
from: 0
|
||||
to: 2*Math.PI
|
||||
}
|
||||
}
|
||||
|
||||
Pill {
|
||||
anchors.centerIn: parent
|
||||
|
||||
visible: !row.updating
|
||||
|
||||
leftCount: row.unplayed
|
||||
rightCount: row.downloaded
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onCurrentRowChanged: {
|
||||
var id = podcastListModel.get(currentRow).id;
|
||||
episodeListModel.loadEpisodes(id);
|
||||
}
|
||||
}
|
||||
|
||||
onCurrentRowChanged: {
|
||||
var id = podcastListModel.get(currentRow).id;
|
||||
episodeListModel.loadEpisodes(id);
|
||||
|
||||
Button {
|
||||
Layout.fillWidth: true
|
||||
Layout.margins: 3
|
||||
text: 'Check for new episodes'
|
||||
onClicked: py.call('main.check_for_episodes');
|
||||
enabled: !py.refreshing
|
||||
}
|
||||
}
|
||||
|
||||
TableView {
|
||||
Layout.fillWidth: true
|
||||
model: GPodderEpisodeListModel { id: episodeListModel }
|
||||
GPodderEpisodeListModelConnections {}
|
||||
SplitView {
|
||||
orientation: Orientation.Vertical
|
||||
|
||||
TableViewColumn { role: 'title'; title: 'Title' }
|
||||
TableView {
|
||||
id: episodeListView
|
||||
|
||||
onActivated: {
|
||||
var episode_id = episodeListModel.get(currentRow).id;
|
||||
Layout.fillWidth: true
|
||||
model: GPodderEpisodeListModel { id: episodeListModel }
|
||||
GPodderEpisodeListModelConnections {}
|
||||
selectionMode: SelectionMode.MultiSelection
|
||||
|
||||
openDialog('dialogs/EpisodeDetailsDialog.qml', function (dialog) {
|
||||
py.call('main.show_episode', [episode_id], function (episode) {
|
||||
dialog.episode = episode;
|
||||
function forEachSelectedEpisode(callback) {
|
||||
episodeListView.selection.forEach(function(rowIndex) {
|
||||
var episode_id = episodeListModel.get(rowIndex).id;
|
||||
callback(episode_id);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Menu {
|
||||
id: episodeContextMenu
|
||||
|
||||
MenuItem {
|
||||
text: 'Toggle new'
|
||||
onTriggered: {
|
||||
episodeListView.forEachSelectedEpisode(function (episode_id) {
|
||||
py.call('main.toggle_new', [episode_id]);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
text: 'Download'
|
||||
onTriggered: {
|
||||
episodeListView.forEachSelectedEpisode(function (episode_id) {
|
||||
py.call('main.download_episode', [episode_id]);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
text: 'Delete'
|
||||
onTriggered: {
|
||||
episodeListView.forEachSelectedEpisode(function (episode_id) {
|
||||
py.call('main.delete_episode', [episode_id]);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rowDelegate: Rectangle {
|
||||
height: 40
|
||||
color: styleData.selected ? Constants.colors.select : 'transparent'
|
||||
|
||||
MouseArea {
|
||||
acceptedButtons: Qt.RightButton
|
||||
anchors.fill: parent
|
||||
onClicked: episodeContextMenu.popup()
|
||||
}
|
||||
}
|
||||
|
||||
TableViewColumn {
|
||||
role: 'title'
|
||||
title: 'Episode'
|
||||
|
||||
delegate: Row {
|
||||
property var row: episodeListModel.get(styleData.row)
|
||||
height: 32
|
||||
|
||||
Item {
|
||||
width: 32
|
||||
height: 32
|
||||
|
||||
Rectangle {
|
||||
anchors.centerIn: parent
|
||||
width: 10
|
||||
height: 10
|
||||
color: episodeTitle.color
|
||||
}
|
||||
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
opacity: row.downloadState === Constants.state.downloaded
|
||||
}
|
||||
|
||||
Column {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: -5
|
||||
|
||||
Text {
|
||||
id: episodeTitle
|
||||
text: styleData.value
|
||||
elide: styleData.elideMode
|
||||
color: styleData.selected ? 'white' : 'black'
|
||||
font.bold: row.isNew
|
||||
}
|
||||
|
||||
Text {
|
||||
text: row.progress ? ('Downloading: ' + parseInt(100*row.progress) + '%') : row.subtitle
|
||||
elide: styleData.elideMode
|
||||
color: styleData.selected ? 'white' : 'black'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onActivated: {
|
||||
var episode_id = episodeListModel.get(currentRow).id;
|
||||
|
||||
openDialog('dialogs/EpisodeDetailsDialog.qml', function (dialog) {
|
||||
py.call('main.show_episode', [episode_id], function (episode) {
|
||||
dialog.episode = episode;
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Label {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue