diff --git a/qml/ButtonArea.qml b/qml/ButtonArea.qml new file mode 100644 index 0000000..0f07557 --- /dev/null +++ b/qml/ButtonArea.qml @@ -0,0 +1,37 @@ + +/** + * + * gPodder QML UI Reference Implementation + * Copyright (c) 2013, Thomas Perl + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + */ + +import QtQuick 2.0 + +Rectangle { + id: buttonArea + + signal clicked + + property bool transparent: false + color: mouseArea.pressed?'#33ffffff':(transparent?'#00000000':'#88000000') + + MouseArea { + id: mouseArea + anchors.fill: parent + onClicked: buttonArea.clicked(); + } +} + diff --git a/qml/ButtonRow.qml b/qml/ButtonRow.qml new file mode 100644 index 0000000..a65fd80 --- /dev/null +++ b/qml/ButtonRow.qml @@ -0,0 +1,45 @@ + +/** + * + * gPodder QML UI Reference Implementation + * Copyright (c) 2013, Thomas Perl + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + */ + +import QtQuick 2.0 + +Row { + id: buttonRow + property var model + + height: 100 * pgst.scalef + + Repeater { + id: repeater + model: buttonRow.model + + delegate: ButtonArea { + height: buttonRow.height + width: buttonRow.width / repeater.count + onClicked: buttonRow.model[index].clicked() + + PLabel { + anchors.centerIn: parent + text: modelData.label + } + } + } +} + diff --git a/qml/Dragging.qml b/qml/Dragging.qml new file mode 100644 index 0000000..7c94ebd --- /dev/null +++ b/qml/Dragging.qml @@ -0,0 +1,57 @@ + +/** + * + * gPodder QML UI Reference Implementation + * Copyright (c) 2013, Thomas Perl + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + */ + +import QtQuick 2.0 + +MouseArea { + id: dragging + + property Item stacking + property bool hasPull: false + property bool canClose: true + signal pulled + + anchors.fill: parent + + drag { + target: parent + axis: Drag.XAxis + minimumX: dragging.hasPull ? (-parent.width/4) : 0 + maximumX: canClose ? parent.width : 0 + filterChildren: true + } + + onPressedChanged: { + if (pressed) { + dragging.stacking.stopAllAnimations(); + } else { + if (hasPull && parent.x < -parent.width / 4 + 10) { + pulled(); + parent.x = -parent.width / 4; + //dragging.stacking.fadeInAgain(); + } else if (parent.x > parent.width / 3) { + dragging.stacking.startFadeOut(); + } else { + dragging.stacking.fadeInAgain(); + } + } + } +} + diff --git a/qml/EpisodeDetail.qml b/qml/EpisodeDetail.qml new file mode 100644 index 0000000..a58e9cd --- /dev/null +++ b/qml/EpisodeDetail.qml @@ -0,0 +1,76 @@ + +/** + * + * gPodder QML UI Reference Implementation + * Copyright (c) 2013, Thomas Perl + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + */ + +import QtQuick 2.0 + +import 'constants.js' as Constants + +SlidePage { + id: detailPage + + property int episode_id + property string title + + Component.onCompleted: { + label.text = 'Loading...'; + py.call('main.show_episode', [episode_id], function (episode) { + label.text = episode.description; + }); + } + + Flickable { + id: flickable + anchors.fill: parent + + contentWidth: detailColumn.width + contentHeight: detailColumn.height + detailColumn.spacing + + Column { + id: detailColumn + + width: detailPage.width + spacing: 10 * pgst.scalef + + SlidePageHeader { + title: detailPage.title + } + + ButtonArea { + width: detailPage.width + height: 100 * pgst.scalef + onClicked: player.playbackEpisode(detailPage.episode_id) + + PLabel { + anchors.centerIn: parent + text: 'Play' + } + } + + PLabel { + id: label + width: parent.width * .8 + font.pixelSize: 30 * pgst.scalef + anchors.horizontalCenter: parent.horizontalCenter + wrapMode: Text.WordWrap + } + } + } +} + diff --git a/qml/EpisodeItem.qml b/qml/EpisodeItem.qml new file mode 100644 index 0000000..e0354b6 --- /dev/null +++ b/qml/EpisodeItem.qml @@ -0,0 +1,77 @@ + +/** + * + * gPodder QML UI Reference Implementation + * Copyright (c) 2013, Thomas Perl + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + */ + +import QtQuick 2.0 + +import 'constants.js' as Constants + +ButtonArea { + id: podcastItem + + Rectangle { + anchors { + top: parent.top + bottom: parent.bottom + left: parent.left + } + width: parent.width * progress + color: Constants.colors.download + opacity: .4 + } + + transparent: true + height: 80 * pgst.scalef + + anchors { + left: parent.left + right: parent.right + } + + PLabel { + anchors { + left: parent.left + right: downloadStatusIcon.left + verticalCenter: parent.verticalCenter + margins: 30 * pgst.scalef + } + + elide: Text.ElideRight + text: title + } + + Image { + id: downloadStatusIcon + + anchors { + right: parent.right + verticalCenter: parent.verticalCenter + margins: 30 * pgst.scalef + } + + source: { + switch (downloadState) { + case Constants.state.normal: return ''; + case Constants.state.downloaded: return 'images/play.png'; + case Constants.state.deleted: return 'images/delete.png'; + } + } + } +} + diff --git a/qml/EpisodesPage.qml b/qml/EpisodesPage.qml new file mode 100644 index 0000000..47810ad --- /dev/null +++ b/qml/EpisodesPage.qml @@ -0,0 +1,71 @@ + +/** + * + * gPodder QML UI Reference Implementation + * Copyright (c) 2013, Thomas Perl + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + */ + +import QtQuick 2.0 +import io.thp.pyotherside 1.0 + +import 'util.js' as Util + +SlidePage { + id: episodesPage + + hasPull: true + + property int podcast_id + property string title + + width: parent.width + height: parent.height + + Component.onCompleted: { + py.call('main.load_episodes', [podcast_id], function (episodes) { + Util.updateModelFrom(episodeListModel, episodes); + }); + } + + PullMenu { + PullMenuItem { + source: 'images/play.png' + onClicked: { + pgst.loadPage('PlayerPage.qml'); + episodesPage.unPull(); + } + } + + PullMenuItem { + source: 'images/delete.png' + onClicked: { + py.call('main.unsubscribe', [episodesPage.podcast_id]); + episodesPage.closePage(); + } + } + } + + PListView { + id: episodeList + title: episodesPage.title + model: ListModel { id: episodeListModel } + + delegate: EpisodeItem { + onClicked: pgst.loadPage('EpisodeDetail.qml', {episode_id: id, title: title}); + } + } +} + diff --git a/qml/FreshEpisodes.qml b/qml/FreshEpisodes.qml new file mode 100644 index 0000000..f090fe8 --- /dev/null +++ b/qml/FreshEpisodes.qml @@ -0,0 +1,71 @@ + +/** + * + * gPodder QML UI Reference Implementation + * Copyright (c) 2013, Thomas Perl + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + */ + +import QtQuick 2.0 + +import 'util.js' as Util + +SlidePage { + id: freshEpisodes + property bool ready: false + + Component.onCompleted: { + py.call('main.get_fresh_episodes', [], function (episodes) { + Util.updateModelFrom(freshEpisodesListModel, episodes); + freshEpisodes.ready = true; + }); + } + + PBusyIndicator { + visible: !freshEpisodes.ready + anchors.centerIn: parent + } + + PListView { + id: freshEpisodesList + title: 'Fresh episodes' + + model: ListModel { id: freshEpisodesListModel } + + section.property: 'published' + section.delegate: SectionHeader { text: section } + + delegate: EpisodeItem { + onClicked: py.call('main.download_episode', [id]); + + Connections { + target: pgst + onDownloadProgress: { + if (episode_id == id) { + freshEpisodesListModel.setProperty(index, 'progress', progress); + } + } + onDownloaded: { + if (id == episode_id) { + freshEpisodesListModel.remove(index); + } + } + } + + //pgst.loadPage('EpisodeDetail.qml', {episode_id: id, title: title}); + } + } +} + diff --git a/qml/Main.qml b/qml/Main.qml new file mode 100644 index 0000000..d78c00e --- /dev/null +++ b/qml/Main.qml @@ -0,0 +1,107 @@ + +/** + * + * gPodder QML UI Reference Implementation + * Copyright (c) 2013, Thomas Perl + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + */ + +import QtQuick 2.0 +import io.thp.pyotherside 1.0 + +Item { + id: pgst + property bool ready: false + + property real scalef: width / 480 + + anchors.fill: parent + + function update(page, x) { + var index = -1; + for (var i=0; i + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + */ + +import QtQuick 2.0 + +Item { + height: 64 * pgst.scalef + width: 64 * pgst.scalef + + Image { + anchors { + horizontalCenter: parent.horizontalCenter + bottom: parent.bottom + bottomMargin: 30*Math.abs(Math.sin(phase)) * pgst.scalef + } + + transform: Scale { + origin.x: 32 * pgst.scalef + origin.y: 32 * pgst.scalef + xScale: 1.0 - 0.3 * (1.0 - Math.abs(Math.sin(phase))) + } + + source: 'images/gpodder.png' + } + + property real phase: 0 + + PropertyAnimation on phase { + loops: Animation.Infinite + duration: 2000 + running: parent.visible + from: 0 + to: 2*Math.PI + } +} + diff --git a/qml/PLabel.qml b/qml/PLabel.qml new file mode 100644 index 0000000..580cfe7 --- /dev/null +++ b/qml/PLabel.qml @@ -0,0 +1,27 @@ + +/** + * + * gPodder QML UI Reference Implementation + * Copyright (c) 2013, Thomas Perl + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + */ + +import QtQuick 2.0 + +Text { + font.pixelSize: 30 * pgst.scalef + color: 'white' +} + diff --git a/qml/PListView.qml b/qml/PListView.qml new file mode 100644 index 0000000..b53e9c7 --- /dev/null +++ b/qml/PListView.qml @@ -0,0 +1,34 @@ + +/** + * + * gPodder QML UI Reference Implementation + * Copyright (c) 2013, Thomas Perl + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + */ + +import QtQuick 2.0 + +import 'constants.js' as Constants + +ListView { + id: pListView + + anchors.fill: parent + + property string title + + header: SlidePageHeader { title: pListView.title } +} + diff --git a/qml/PSlider.qml b/qml/PSlider.qml new file mode 100644 index 0000000..a4144d4 --- /dev/null +++ b/qml/PSlider.qml @@ -0,0 +1,53 @@ + +/** + * + * gPodder QML UI Reference Implementation + * Copyright (c) 2013, Thomas Perl + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + */ + +import QtQuick 2.0 + +Rectangle { + id: slider + + property real value + property real min: 0.0 + property real max: 1.0 + + signal valueChangeRequested(real newValue) + + color: '#aa000000' + + height: 50 * pgst.scalef + + MouseArea { + anchors.fill: parent + onClicked: slider.valueChangeRequested(min + (max - min) * (mouse.x / width)) + } + + Rectangle { + height: parent.height * 0.9 + width: height + + color: '#aaffffff' + + anchors { + verticalCenter: parent.verticalCenter + left: parent.left + leftMargin: parent.width * (parent.value - parent.min) / (parent.max - parent.min) + } + } +} diff --git a/qml/PTextField.qml b/qml/PTextField.qml new file mode 100644 index 0000000..91a7a03 --- /dev/null +++ b/qml/PTextField.qml @@ -0,0 +1,51 @@ + +/** + * + * gPodder QML UI Reference Implementation + * Copyright (c) 2013, Thomas Perl + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + */ + +import QtQuick 2.0 + +Rectangle { + id: textField + + property alias text: textInput.text + property string placeholderText: '' + + radius: 10 * pgst.scalef + height: 50 * pgst.scalef + color: 'white' + + TextInput { + anchors { + fill: parent + margins: 5 * pgst.scalef + } + color: 'black' + id: textInput + font.pixelSize: height + } + + Text { + anchors.fill: textInput + visible: !textInput.focus && (textInput.text == '') + text: textField.placeholderText + color: '#aaa' + font.pixelSize: textInput.font.pixelSize + } +} + diff --git a/qml/Player.qml b/qml/Player.qml new file mode 100644 index 0000000..cc7c3b7 --- /dev/null +++ b/qml/Player.qml @@ -0,0 +1,37 @@ + +/** + * + * gPodder QML UI Reference Implementation + * Copyright (c) 2013, Thomas Perl + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + */ + +import QtQuick 2.0 +import QtMultimedia 5.0 + +MediaPlayer { + id: player + + property int episode + property var queue: ([]) + + function playbackEpisode(episode_id) { + player.episode = episode_id; + py.call('main.play_episode', [episode_id], function (episode) { + player.source = episode.source; + player.play(); + }); + } +} diff --git a/qml/PlayerPage.qml b/qml/PlayerPage.qml new file mode 100644 index 0000000..8928099 --- /dev/null +++ b/qml/PlayerPage.qml @@ -0,0 +1,83 @@ + +/** + * + * gPodder QML UI Reference Implementation + * Copyright (c) 2013, Thomas Perl + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + */ + +import QtQuick 2.0 + +import 'constants.js' as Constants + +SlidePage { + id: playerPage + + property string episodeTitle + + Component.onCompleted: { + py.call('main.show_episode', [player.episode], function (episode) { + playerPage.episodeTitle = episode.title; + }); + } + + Flickable { + id: flickable + anchors.fill: parent + + contentWidth: column.width + contentHeight: column.height + column.spacing + + Column { + id: column + + width: playerPage.width + spacing: 10 * pgst.scalef + + SlidePageHeader { + title: 'Now playing' + } + + ButtonRow { + width: playerPage.width + model: [ + { label: 'Play', clicked: function() { + player.play(); + }}, + { label: 'Pause', clicked: function() { + player.pause(); + }}, + { label: 'Details', clicked: function() { + pgst.loadPage('EpisodeDetail.qml', { + episode_id: player.episode, + title: playerPage.episodeTitle + }); + }} + ] + } + + PSlider { + width: playerPage.width + value: player.playbackRate + min: 0.5 + max: 3.0 + onValueChangeRequested: { + player.playbackRate = newValue + value = player.playbackRate + } + } + } + } +} diff --git a/qml/PodcastItem.qml b/qml/PodcastItem.qml new file mode 100644 index 0000000..8b1442e --- /dev/null +++ b/qml/PodcastItem.qml @@ -0,0 +1,71 @@ + +/** + * + * gPodder QML UI Reference Implementation + * Copyright (c) 2013, Thomas Perl + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + */ + +import QtQuick 2.0 + +ButtonArea { + id: podcastItem + + transparent: true + + height: 100 * pgst.scalef + anchors { + left: parent.left + right: parent.right + } + + Image { + id: cover + visible: !updating + + anchors { + left: parent.left + leftMargin: 10 * pgst.scalef + verticalCenter: parent.verticalCenter + } + + sourceSize.width: width + sourceSize.height: height + + width: 80 * pgst.scalef + height: 80 * pgst.scalef + + source: coverart + } + + PBusyIndicator { + anchors.centerIn: cover + visible: updating + } + + PLabel { + anchors { + left: cover.right + leftMargin: 10 * pgst.scalef + rightMargin: 10 * pgst.scalef + right: parent.right + verticalCenter: parent.verticalCenter + } + + elide: Text.ElideRight + text: title + } +} + diff --git a/qml/PodcastsPage.qml b/qml/PodcastsPage.qml new file mode 100644 index 0000000..d64bb8d --- /dev/null +++ b/qml/PodcastsPage.qml @@ -0,0 +1,114 @@ + +/** + * + * gPodder QML UI Reference Implementation + * Copyright (c) 2013, Thomas Perl + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + */ + +import QtQuick 2.0 + +import 'util.js' as Util + +SlidePage { + id: podcastsPage + hasPull: true + + function reload() { + loading.visible = true; + py.call('main.load_podcasts', [], function (podcasts) { + Util.updateModelFrom(podcastListModel, podcasts); + loading.visible = false; + }); + } + + Component.onCompleted: { + reload(); + + py.setHandler('podcast-list-changed', podcastsPage.reload); + + py.setHandler('updating-podcast', function (podcast_id) { + for (var i=0; i + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + */ + +import QtQuick 2.0 + +Column { + id: pullMenu + + width: parent.width / 4 + height: parent.height + anchors.top: parent.top + anchors.left: parent.right + + Item { width: 1; height: 1 } + + spacing: (width - 72 * pgst.scalef) / 2 +} + diff --git a/qml/PullMenuItem.qml b/qml/PullMenuItem.qml new file mode 100644 index 0000000..f63f76e --- /dev/null +++ b/qml/PullMenuItem.qml @@ -0,0 +1,38 @@ + +/** + * + * gPodder QML UI Reference Implementation + * Copyright (c) 2013, Thomas Perl + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + */ + +import QtQuick 2.0 + +Image { + id: pullMenuItem + + signal clicked + + width: 72 * pgst.scalef + height: 72 * pgst.scalef + + anchors.horizontalCenter: parent.horizontalCenter + + MouseArea { + anchors.fill: parent + onClicked: pullMenuItem.clicked(); + } +} + diff --git a/qml/SectionHeader.qml b/qml/SectionHeader.qml new file mode 100644 index 0000000..621f83e --- /dev/null +++ b/qml/SectionHeader.qml @@ -0,0 +1,39 @@ + +/** + * + * gPodder QML UI Reference Implementation + * Copyright (c) 2013, Thomas Perl + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + */ + +import QtQuick 2.0 + +Item { + property alias text: pLabel.text + + height: 70 * pgst.scalef + + PLabel { + id: pLabel + anchors { + left: parent.left + bottom: parent.bottom + margins: 10 * pgst.scalef + } + + color: '#aaa' + } +} + diff --git a/qml/Settings.qml b/qml/Settings.qml new file mode 100644 index 0000000..3b6a18f --- /dev/null +++ b/qml/Settings.qml @@ -0,0 +1,33 @@ + +/** + * + * gPodder QML UI Reference Implementation + * Copyright (c) 2013, Thomas Perl + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + */ + +import QtQuick 2.0 + +SlidePage { + SlidePageHeader { title: 'Settings' } + + Text { + anchors.centerIn: parent + color: 'white' + font.pixelSize: 50 * pgst.scalef + text: 'TODO' + } +} + diff --git a/qml/SlidePage.qml b/qml/SlidePage.qml new file mode 100644 index 0000000..2d1435d --- /dev/null +++ b/qml/SlidePage.qml @@ -0,0 +1,92 @@ + +/** + * + * gPodder QML UI Reference Implementation + * Copyright (c) 2013, Thomas Perl + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + */ + +import QtQuick 2.0 + +import 'constants.js' as Constants + +Rectangle { + id: page + color: '#88000000' + + default property alias children: dragging.children + property alias hasPull: dragging.hasPull + property alias canClose: dragging.canClose + property real pullPhase: (x >= 0) ? 0 : (-x / (width / 4)) + + function unPull() { + stacking.fadeInAgain(); + } + + function closePage() { + stacking.startFadeOut(); + } + + onXChanged: pgst.update(page, x) + + width: parent.width + height: parent.height + + Stacking { id: stacking } + + Dragging { + id: dragging + stacking: stacking + + onPulled: console.log('have pulled it!') + } + + Rectangle { + color: 'black' + anchors.fill: parent + + opacity: page.pullPhase * 0.8 + + MouseArea { + enabled: parent.opacity > 0 + anchors.fill: parent + onClicked: page.unPull(); + } + } + + Image { + anchors { + right: parent.left + top: parent.top + bottom: parent.bottom + } + width: 10 * pgst.scalef + source: 'images/pageshadow.png' + opacity: .2 + } + + Image { + anchors { + left: parent.right + top: parent.top + bottom: parent.bottom + } + mirror: true + width: 10 * pgst.scalef + source: 'images/pageshadow.png' + opacity: .2 + } +} + diff --git a/qml/SlidePageHeader.qml b/qml/SlidePageHeader.qml new file mode 100644 index 0000000..0435ba0 --- /dev/null +++ b/qml/SlidePageHeader.qml @@ -0,0 +1,60 @@ + +/** + * + * gPodder QML UI Reference Implementation + * Copyright (c) 2013, Thomas Perl + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + */ + +import QtQuick 2.0 + +import 'constants.js' as Constants + +Item { + id: slidePageHeader + property string title + + width: parent.width + height: Constants.layout.header.height * pgst.scalef + + Rectangle { + anchors { + left: parent.left + right: parent.right + top: parent.top + topMargin: slidePageHeader.height * 0.15 + } + + height: slidePageHeader.height * 0.7 + color: '#33000000' + } + + Text { + anchors { + left: parent.left + right: parent.right + rightMargin: 20 * pgst.scalef + leftMargin: 70 * pgst.scalef + verticalCenter: parent.verticalCenter + } + + color: 'white' + horizontalAlignment: Text.AlignRight + font.pixelSize: parent.height * .4 * pgst.scalef + elide: Text.ElideRight + text: parent.title + } +} + diff --git a/qml/Stacking.qml b/qml/Stacking.qml new file mode 100644 index 0000000..ce856c3 --- /dev/null +++ b/qml/Stacking.qml @@ -0,0 +1,63 @@ + +/** + * + * gPodder QML UI Reference Implementation + * Copyright (c) 2013, Thomas Perl + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + */ + +import QtQuick 2.0 + +Item { + id: stacking + property variant page: parent + + PropertyAnimation { + id: fadeIn + target: stacking.page + property: 'x' + to: 0 + duration: 500 + easing.type: Easing.OutCubic + } + + PropertyAnimation { + id: fadeOut + target: stacking.page + property: 'x' + to: stacking.page.width + duration: 500 + easing.type: Easing.OutCubic + } + + function startFadeOut() { + fadeOut.start(); + page.destroy(500); + } + + function fadeInAgain() { + fadeIn.start(); + } + + function stopAllAnimations() { + fadeIn.stop(); + } + + Component.onCompleted: { + page.x = page.width; + fadeIn.start(); + } +} + diff --git a/qml/StartPage.qml b/qml/StartPage.qml new file mode 100644 index 0000000..c5d2979 --- /dev/null +++ b/qml/StartPage.qml @@ -0,0 +1,251 @@ + +/** + * + * gPodder QML UI Reference Implementation + * Copyright (c) 2013, Thomas Perl + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + */ + +import QtQuick 2.0 + +SlidePage { + id: startPage + canClose: false + + function update_stats() { + py.call('main.get_stats', [], function (result) { + stats.text = result; + }); + + py.call('main.get_fresh_episodes_summary', [3], function (episodes) { + freshEpisodesRepeater.model = episodes; + }); + } + + Component.onCompleted: { + py.setHandler('update-stats', startPage.update_stats); + } + + Component.onDestruction: { + py.setHandler('update-stats', undefined); + } + + Flickable { + Connections { + target: pgst + onReadyChanged: { + if (pgst.ready) { + startPage.update_stats(); + } + } + } + + anchors.fill: parent + + contentWidth: startPageColumn.width + contentHeight: startPageColumn.height + startPageColumn.spacing + + Column { + id: startPageColumn + + width: startPage.width + spacing: 20 * pgst.scalef + + SlidePageHeader { + title: 'gPodder' + } + + StartPageButton { + id: subscriptionsPane + + title: 'Subscriptions' + onClicked: pgst.loadPage('PodcastsPage.qml'); + + PLabel { + id: stats + + anchors { + verticalCenter: parent.verticalCenter + left: parent.left + margins: 20 * pgst.scalef + } + } + + ButtonArea { + anchors { + bottom: parent.bottom + right: parent.right + } + + transparent: true + onClicked: pgst.loadPage('Subscribe.qml'); + width: subscriptions.width + 2*subscriptions.anchors.margins + height: subscriptions.height + 2*subscriptions.anchors.margins + + Image { + id: subscriptions + source: 'images/subscriptions.png' + + anchors { + bottom: parent.bottom + right: parent.right + margins: 20 * pgst.scalef + } + } + } + } + + StartPageButton { + id: freshEpisodesPage + + title: 'Fresh episodes' + onClicked: pgst.loadPage('FreshEpisodes.qml'); + + Component.onCompleted: { + py.setHandler('refreshing', function (is_refreshing) { + refresherButtonArea.visible = !is_refreshing; + if (!is_refreshing) { + freshEpisodesPage.title = 'Fresh episodes'; + } + }); + + py.setHandler('refresh-progress', function (pos, total) { + freshEpisodesPage.title = 'Refreshing feeds (' + pos + '/' + total + ')'; + }); + } + + Row { + anchors.bottom: parent.bottom + anchors.bottomMargin: 50 * pgst.scalef + anchors.leftMargin: 20 * pgst.scalef + anchors.left: parent.left + spacing: 10 * pgst.scalef + + Repeater { + id: freshEpisodesRepeater + + Image { + source: modelData.coverart + sourceSize { width: 80 * pgst.scalef; height: 80 * pgst.scalef } + width: 80 * pgst.scalef + height: 80 * pgst.scalef + + PLabel { + anchors { + horizontalCenter: parent.horizontalCenter + top: parent.bottom + margins: 5 * pgst.scalef + } + + text: modelData.newEpisodes + } + } + } + } + + ButtonArea { + id: refresherButtonArea + + anchors { + bottom: parent.bottom + right: parent.right + } + + transparent: true + onClicked: py.call('main.check_for_episodes'); + width: refresher.width + 2*refresher.anchors.margins + height: refresher.height + 2*refresher.anchors.margins + + Image { + id: refresher + source: 'images/search.png' + + anchors { + bottom: parent.bottom + right: parent.right + margins: 20 * pgst.scalef + } + } + } + } + + ButtonArea { + onClicked: pgst.loadPage('PlayerPage.qml'); + + anchors { + left: recommendationsPane.left + right: recommendationsPane.right + } + + height: 100 * pgst.scalef + + PLabel { + anchors.centerIn: parent + text: 'Now playing' + } + } + + ButtonArea { + onClicked: pgst.loadPage('Settings.qml'); + + anchors { + left: recommendationsPane.left + right: recommendationsPane.right + } + + height: 100 * pgst.scalef + + PLabel { + anchors.centerIn: parent + text: 'Settings' + } + } + + StartPageButton { + id: recommendationsPane + + title: 'Recommendations' + onClicked: pgst.loadPage('Settings.qml'); + + Row { + anchors { + horizontalCenter: parent.horizontalCenter + bottom: parent.bottom + margins: 40 * pgst.scalef + } + + spacing: 20 * pgst.scalef + + Connections { + target: pgst + onReadyChanged: { + if (pgst.ready) { + py.call('main.load_podcasts', [], function (podcasts) { + recommendationsRepeater.model = podcasts.splice(0, 4); + }); + } + } + } + + Repeater { + id: recommendationsRepeater + Image { source: modelData.coverart; sourceSize { width: 80 * pgst.scalef; height: 80 * pgst.scalef } } + } + } + } + } + } +} + diff --git a/qml/StartPageButton.qml b/qml/StartPageButton.qml new file mode 100644 index 0000000..7c4917e --- /dev/null +++ b/qml/StartPageButton.qml @@ -0,0 +1,42 @@ + +/** + * + * gPodder QML UI Reference Implementation + * Copyright (c) 2013, Thomas Perl + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + */ + +import QtQuick 2.0 + +ButtonArea { + id: startPageButton + + property string title + + anchors.horizontalCenter: parent.horizontalCenter + width: parent.width * .9 + height: 200 * pgst.scalef + + PLabel { + anchors { + right: parent.right + top: parent.top + margins: 20 * pgst.scalef + } + + text: startPageButton.title + } +} + diff --git a/qml/Subscribe.qml b/qml/Subscribe.qml new file mode 100644 index 0000000..1736ec9 --- /dev/null +++ b/qml/Subscribe.qml @@ -0,0 +1,64 @@ + +/** + * + * gPodder QML UI Reference Implementation + * Copyright (c) 2013, Thomas Perl + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + */ + +import QtQuick 2.0 + +SlidePage { + id: subscribe + + SlidePageHeader { title: 'Add subscription' } + + Column { + anchors.centerIn: parent + spacing: 30 * pgst.scalef + + PTextField { + id: input + width: subscribe.width *.8 + placeholderText: 'Feed URL' + } + + ButtonArea { + id: button + width: input.width + height: input.height + + PLabel { + anchors.centerIn: parent + text: 'Subscribe' + } + + onClicked: { + loading.visible = true; + button.visible = false; + input.visible = false; + py.call('main.subscribe', [input.text], function () { + subscribe.closePage(); + }); + } + } + + PBusyIndicator { + id: loading + visible: false + anchors.horizontalCenter: parent.horizontalCenter + } + } +} diff --git a/qml/constants.js b/qml/constants.js new file mode 100644 index 0000000..28e3076 --- /dev/null +++ b/qml/constants.js @@ -0,0 +1,39 @@ + +/** + * + * gPodder QML UI Reference Implementation + * Copyright (c) 2013, Thomas Perl + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + */ + +var layout = { + header: { + height: 100, /* page header height */ + }, +}; + +var colors = { + download: '#8ae234', /* download green */ + select: '#7f5785', /* gpodder dark purple */ + fresh: '#cf65de', /* gpodder purple */ + playback: '#729fcf', /* playback blue */ +}; + +var state = { + normal: 0, + downloaded: 1, + deleted: 2, +}; + diff --git a/qml/util.js b/qml/util.js new file mode 100644 index 0000000..ec5acb4 --- /dev/null +++ b/qml/util.js @@ -0,0 +1,33 @@ + +/** + * + * gPodder QML UI Reference Implementation + * Copyright (c) 2013, Thomas Perl + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + */ + +function updateModelFrom(model, data) { + for (var i=0; i data.length) { + model.remove(model.count-1); + } +} diff --git a/rpm/org.gpodder.sailfish.spec b/rpm/org.gpodder.sailfish.spec index f8cca45..d8260d7 100644 --- a/rpm/org.gpodder.sailfish.spec +++ b/rpm/org.gpodder.sailfish.spec @@ -30,7 +30,8 @@ TARGET=%{buildroot}/%{_datadir}/%{name}/qml mkdir -p $TARGET cp -rpv gpodder-core/src/* $TARGET/ cp -rpv podcastparser/podcastparser.py $TARGET/ -cp -rpv gpodder-ui-qml/main.py gpodder-ui-qml/qml $TARGET/ +cp -rpv gpodder-ui-qml/main.py $TARGET/ +cp -rpv qml $TARGET/ cp -rpv %{name}.qml $TARGET/ TARGET=%{buildroot}/%{_datadir}/applications @@ -43,7 +44,6 @@ cp -rpv %{name}.png $TARGET/ %files %defattr(-,root,root,-) -%doc gpodder-core/README gpodder-core/LICENSE.GPLv3 gpodder-core/LICENSE.ISC %{_datadir}/%{name} %{_datadir}/applications/%{name}.desktop %{_datadir}/icons/hicolor/*/apps/%{name}.png