diff --git a/README b/README index d40b265..bf1a596 100644 --- a/README +++ b/README @@ -14,3 +14,5 @@ Qt Multimedia 5.0.2 http://qt-project.org/ Python 3.3.0 http://python.org/ PyOtherSide 1.0.0 http://thp.io/2011/pyotherside/ gPodder 4.0.0 http://gpodder.org/ + +On the Desktop: Qt Quick Controls 5.1 diff --git a/common/GPodderCore.qml b/common/GPodderCore.qml new file mode 100644 index 0000000..6692829 --- /dev/null +++ b/common/GPodderCore.qml @@ -0,0 +1,59 @@ + +/** + * + * gPodder QML UI Reference Implementation + * Copyright (c) 2013, 2014, 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 + + +Python { + id: py + + property bool ready: false + signal downloading(int episode_id) + signal downloadProgress(int episode_id, real progress) + signal downloaded(int episode_id) + + Component.onCompleted: { + setHandler('hello', function (version, copyright) { + console.log('gPodder version ' + version + ' starting up'); + console.log('Copyright: ' + copyright); + }); + + setHandler('downloading', py.downloading); + setHandler('download-progress', py.downloadProgress); + setHandler('downloaded', py.downloaded); + + var path = Qt.resolvedUrl('../..').substr('file://'.length); + addImportPath(path); + + // Load the Python side of things + importModule('main', function() { + py.ready = true; + }); + } + + onReceived: { + console.log('unhandled message: ' + data); + } + + onError: { + console.log('Python failure: ' + traceback); + } +} diff --git a/qml/util.js b/common/util.js similarity index 100% rename from qml/util.js rename to common/util.js diff --git a/desktop/common b/desktop/common new file mode 120000 index 0000000..60d3b0a --- /dev/null +++ b/desktop/common @@ -0,0 +1 @@ +../common \ No newline at end of file diff --git a/desktop/gpodder.qml b/desktop/gpodder.qml new file mode 100644 index 0000000..cac92ac --- /dev/null +++ b/desktop/gpodder.qml @@ -0,0 +1,88 @@ +import QtQuick 2.0 +import QtQuick.Controls 1.0 +import QtQuick.Layouts 1.0 + +import 'common' +import 'common/util.js' as Util + +ApplicationWindow { + width: 500 + height: 400 + + title: 'gPodder' + + GPodderCore { + id: py + + onReadyChanged: { + if (ready) { + py.call('main.load_podcasts', [], function (podcasts) { + Util.updateModelFrom(podcastListModel, podcasts); + }); + } + } + } + + menuBar: MenuBar { + Menu { title: 'File'; MenuItem { text: 'Quit' } } + } + + SplitView { + anchors.fill: parent + + TableView { + width: 200 + model: ListModel { id: podcastListModel } + headerVisible: false + alternatingRowColors: false + + rowDelegate: Rectangle { + height: 60 + color: styleData.selected ? '#eee' : '#fff' + } + + TableViewColumn { + role: 'coverart' + title: 'Image' + delegate: Item { + height: 60 + width: 60 + Image { + source: styleData.value + width: 50 + height: 50 + anchors.centerIn: parent + } + } + + width: 60 + } + + TableViewColumn { + role: 'title' + title: 'Podcast' + delegate: Item { + height: 60 + Text { + text: styleData.value + anchors.verticalCenter: parent.verticalCenter + } + } + } + + onCurrentRowChanged: { + var id = podcastListModel.get(currentRow).id; + py.call('main.load_episodes', [id], function (episodes) { + Util.updateModelFrom(episodeListModel, episodes); + }); + } + } + + TableView { + Layout.fillWidth: true + model: ListModel { id: episodeListModel } + + TableViewColumn { role: 'title'; title: 'Title' } + } + } +} diff --git a/main.py b/main.py index 4e9c204..9edc98f 100644 --- a/main.py +++ b/main.py @@ -19,7 +19,7 @@ import sys import os -sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'gpodder', 'src')) +sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'gpodder-core', 'src')) import pyotherside import gpodder diff --git a/qml/ButtonArea.qml b/touch/ButtonArea.qml similarity index 100% rename from qml/ButtonArea.qml rename to touch/ButtonArea.qml diff --git a/qml/ButtonRow.qml b/touch/ButtonRow.qml similarity index 100% rename from qml/ButtonRow.qml rename to touch/ButtonRow.qml diff --git a/qml/Dragging.qml b/touch/Dragging.qml similarity index 100% rename from qml/Dragging.qml rename to touch/Dragging.qml diff --git a/qml/EpisodeDetail.qml b/touch/EpisodeDetail.qml similarity index 100% rename from qml/EpisodeDetail.qml rename to touch/EpisodeDetail.qml diff --git a/qml/EpisodeItem.qml b/touch/EpisodeItem.qml similarity index 100% rename from qml/EpisodeItem.qml rename to touch/EpisodeItem.qml diff --git a/qml/EpisodesPage.qml b/touch/EpisodesPage.qml similarity index 97% rename from qml/EpisodesPage.qml rename to touch/EpisodesPage.qml index 47810ad..7e0f128 100644 --- a/qml/EpisodesPage.qml +++ b/touch/EpisodesPage.qml @@ -19,9 +19,8 @@ */ import QtQuick 2.0 -import io.thp.pyotherside 1.0 -import 'util.js' as Util +import 'common/util.js' as Util SlidePage { id: episodesPage diff --git a/qml/FreshEpisodes.qml b/touch/FreshEpisodes.qml similarity index 97% rename from qml/FreshEpisodes.qml rename to touch/FreshEpisodes.qml index f090fe8..997c170 100644 --- a/qml/FreshEpisodes.qml +++ b/touch/FreshEpisodes.qml @@ -20,7 +20,7 @@ import QtQuick 2.0 -import 'util.js' as Util +import 'common/util.js' as Util SlidePage { id: freshEpisodes @@ -51,7 +51,7 @@ SlidePage { onClicked: py.call('main.download_episode', [id]); Connections { - target: pgst + target: py onDownloadProgress: { if (episode_id == id) { freshEpisodesListModel.setProperty(index, 'progress', progress); diff --git a/qml/Main.qml b/touch/Main.qml similarity index 60% rename from qml/Main.qml rename to touch/Main.qml index d78c00e..5699460 100644 --- a/qml/Main.qml +++ b/touch/Main.qml @@ -19,11 +19,12 @@ */ import QtQuick 2.0 -import io.thp.pyotherside 1.0 +import 'common' Item { id: pgst - property bool ready: false + + GPodderCore { id: py } property real scalef: width / 480 @@ -41,10 +42,6 @@ Item { children[index-1].opacity = x / width; } - signal downloading(int episode_id) - signal downloadProgress(int episode_id, real progress) - signal downloaded(int episode_id) - function loadPage(filename, properties) { var component = Qt.createComponent(filename); if (component.status != Component.Ready) { @@ -58,50 +55,17 @@ Item { } } - Python { - id: py - - Component.onCompleted: { - addImportPath('.'); - - setHandler('hello', function (version, copyright) { - console.log('gPodder version ' + version + ' starting up'); - console.log('Copyright: ' + copyright); - }); - - setHandler('downloading', pgst.downloading); - setHandler('download-progress', pgst.downloadProgress); - setHandler('downloaded', pgst.downloaded); - - var path = Qt.resolvedUrl('..').substr('file://'.length); - addImportPath(path); - - // Load the Python side of things - importModule('main', function() { - pgst.ready = true; - }); - } - - onReceived: { - console.log('unhandled message: ' + data); - } - - onError: { - console.log('Python failure: ' + traceback); - } - } - Player { id: player } PBusyIndicator { anchors.centerIn: parent - visible: !pgst.ready + visible: !py.ready } StartPage { id: startPage - visible: pgst.ready + visible: py.ready } } diff --git a/qml/PBusyIndicator.qml b/touch/PBusyIndicator.qml similarity index 100% rename from qml/PBusyIndicator.qml rename to touch/PBusyIndicator.qml diff --git a/qml/PLabel.qml b/touch/PLabel.qml similarity index 100% rename from qml/PLabel.qml rename to touch/PLabel.qml diff --git a/qml/PListView.qml b/touch/PListView.qml similarity index 100% rename from qml/PListView.qml rename to touch/PListView.qml diff --git a/qml/PSlider.qml b/touch/PSlider.qml similarity index 100% rename from qml/PSlider.qml rename to touch/PSlider.qml diff --git a/qml/PTextField.qml b/touch/PTextField.qml similarity index 100% rename from qml/PTextField.qml rename to touch/PTextField.qml diff --git a/qml/Player.qml b/touch/Player.qml similarity index 100% rename from qml/Player.qml rename to touch/Player.qml diff --git a/qml/PlayerPage.qml b/touch/PlayerPage.qml similarity index 100% rename from qml/PlayerPage.qml rename to touch/PlayerPage.qml diff --git a/qml/PodcastItem.qml b/touch/PodcastItem.qml similarity index 100% rename from qml/PodcastItem.qml rename to touch/PodcastItem.qml diff --git a/qml/PodcastsPage.qml b/touch/PodcastsPage.qml similarity index 99% rename from qml/PodcastsPage.qml rename to touch/PodcastsPage.qml index d64bb8d..adbdfa3 100644 --- a/qml/PodcastsPage.qml +++ b/touch/PodcastsPage.qml @@ -20,7 +20,7 @@ import QtQuick 2.0 -import 'util.js' as Util +import 'common/util.js' as Util SlidePage { id: podcastsPage diff --git a/qml/PullMenu.qml b/touch/PullMenu.qml similarity index 100% rename from qml/PullMenu.qml rename to touch/PullMenu.qml diff --git a/qml/PullMenuItem.qml b/touch/PullMenuItem.qml similarity index 100% rename from qml/PullMenuItem.qml rename to touch/PullMenuItem.qml diff --git a/qml/SectionHeader.qml b/touch/SectionHeader.qml similarity index 100% rename from qml/SectionHeader.qml rename to touch/SectionHeader.qml diff --git a/qml/Settings.qml b/touch/Settings.qml similarity index 100% rename from qml/Settings.qml rename to touch/Settings.qml diff --git a/qml/SlidePage.qml b/touch/SlidePage.qml similarity index 100% rename from qml/SlidePage.qml rename to touch/SlidePage.qml diff --git a/qml/SlidePageHeader.qml b/touch/SlidePageHeader.qml similarity index 100% rename from qml/SlidePageHeader.qml rename to touch/SlidePageHeader.qml diff --git a/qml/Stacking.qml b/touch/Stacking.qml similarity index 100% rename from qml/Stacking.qml rename to touch/Stacking.qml diff --git a/qml/StartPage.qml b/touch/StartPage.qml similarity index 98% rename from qml/StartPage.qml rename to touch/StartPage.qml index c5d2979..e7344f8 100644 --- a/qml/StartPage.qml +++ b/touch/StartPage.qml @@ -44,9 +44,9 @@ SlidePage { Flickable { Connections { - target: pgst + target: py onReadyChanged: { - if (pgst.ready) { + if (py.ready) { startPage.update_stats(); } } @@ -229,9 +229,9 @@ SlidePage { spacing: 20 * pgst.scalef Connections { - target: pgst + target: py onReadyChanged: { - if (pgst.ready) { + if (py.ready) { py.call('main.load_podcasts', [], function (podcasts) { recommendationsRepeater.model = podcasts.splice(0, 4); }); diff --git a/qml/StartPageButton.qml b/touch/StartPageButton.qml similarity index 100% rename from qml/StartPageButton.qml rename to touch/StartPageButton.qml diff --git a/qml/Subscribe.qml b/touch/Subscribe.qml similarity index 100% rename from qml/Subscribe.qml rename to touch/Subscribe.qml diff --git a/touch/common b/touch/common new file mode 120000 index 0000000..60d3b0a --- /dev/null +++ b/touch/common @@ -0,0 +1 @@ +../common \ No newline at end of file diff --git a/qml/constants.js b/touch/constants.js similarity index 100% rename from qml/constants.js rename to touch/constants.js diff --git a/index.qml b/touch/gpodder.qml similarity index 92% rename from index.qml rename to touch/gpodder.qml index c2303aa..5c3ba70 100644 --- a/index.qml +++ b/touch/gpodder.qml @@ -18,7 +18,6 @@ */ import QtQuick 2.0 -import 'qml' Rectangle { color: '#336688' @@ -28,12 +27,12 @@ Rectangle { Image { anchors.fill: parent - source: 'qml/images/mask.png' + source: 'images/mask.png' } Image { anchors.fill: parent - source: 'qml/images/noise.png' + source: 'images/noise.png' fillMode: Image.Tile } diff --git a/qml/images/delete.png b/touch/images/delete.png similarity index 100% rename from qml/images/delete.png rename to touch/images/delete.png diff --git a/qml/images/gpodder.png b/touch/images/gpodder.png similarity index 100% rename from qml/images/gpodder.png rename to touch/images/gpodder.png diff --git a/qml/images/mask.png b/touch/images/mask.png similarity index 100% rename from qml/images/mask.png rename to touch/images/mask.png diff --git a/qml/images/noise.png b/touch/images/noise.png similarity index 100% rename from qml/images/noise.png rename to touch/images/noise.png diff --git a/qml/images/pageshadow.png b/touch/images/pageshadow.png similarity index 100% rename from qml/images/pageshadow.png rename to touch/images/pageshadow.png diff --git a/qml/images/play.png b/touch/images/play.png similarity index 100% rename from qml/images/play.png rename to touch/images/play.png diff --git a/qml/images/search.png b/touch/images/search.png similarity index 100% rename from qml/images/search.png rename to touch/images/search.png diff --git a/qml/images/subscriptions.png b/touch/images/subscriptions.png similarity index 100% rename from qml/images/subscriptions.png rename to touch/images/subscriptions.png