Toolbar with back button, menu and play throbber
This commit is contained in:
parent
532a99edea
commit
7bdf6b783a
19 changed files with 298 additions and 129 deletions
|
@ -32,11 +32,17 @@ var colors = {
|
||||||
destructive: '#cf424f', /* destructive actions */
|
destructive: '#cf424f', /* destructive actions */
|
||||||
|
|
||||||
page: '#dddddd',
|
page: '#dddddd',
|
||||||
|
toolbar: '#d0d0d0',
|
||||||
|
dialog: '#dddddd',
|
||||||
dialogBackground: '#aa000000',
|
dialogBackground: '#aa000000',
|
||||||
text: '#333333', /* text color */
|
text: '#333333', /* text color */
|
||||||
|
dialogText: '#333333',
|
||||||
highlight: '#433b67',
|
highlight: '#433b67',
|
||||||
|
dialogHighlight: '#433b67',
|
||||||
secondaryHighlight: '#605885',
|
secondaryHighlight: '#605885',
|
||||||
area: '#cccccc',
|
area: '#cccccc',
|
||||||
|
dialogArea: '#d0d0d0',
|
||||||
|
toolbarArea: '#bbbbbb',
|
||||||
placeholder: '#666666',
|
placeholder: '#666666',
|
||||||
|
|
||||||
//page: '#000000',
|
//page: '#000000',
|
||||||
|
|
|
@ -26,6 +26,7 @@ MouseArea {
|
||||||
id: mouseArea
|
id: mouseArea
|
||||||
property bool transparent: false
|
property bool transparent: false
|
||||||
property bool canHighlight: true
|
property bool canHighlight: true
|
||||||
|
property alias color: background.color
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: background
|
id: background
|
||||||
|
|
|
@ -24,6 +24,8 @@ import 'common/constants.js' as Constants
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: page
|
id: page
|
||||||
|
z: 200
|
||||||
|
|
||||||
color: Constants.colors.dialogBackground
|
color: Constants.colors.dialogBackground
|
||||||
|
|
||||||
Component.onCompleted: pgst.dialogsVisible = pgst.dialogsVisible + 1;
|
Component.onCompleted: pgst.dialogsVisible = pgst.dialogsVisible + 1;
|
||||||
|
@ -57,7 +59,7 @@ Rectangle {
|
||||||
property int maxHeight: parent.height - 4 * border
|
property int maxHeight: parent.height - 4 * border
|
||||||
height: ((page.contentHeight > 0 && page.contentHeight < maxHeight) ? page.contentHeight : maxHeight) * parent.opacity
|
height: ((page.contentHeight > 0 && page.contentHeight < maxHeight) ? page.contentHeight : maxHeight) * parent.opacity
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
color: Constants.colors.page
|
color: Constants.colors.dialog
|
||||||
clip: true
|
clip: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,11 @@ SlidePage {
|
||||||
property string link
|
property string link
|
||||||
property bool ready: false
|
property bool ready: false
|
||||||
|
|
||||||
|
hasMenuButton: detailPage.link != ''
|
||||||
|
menuButtonIcon: Icons.link
|
||||||
|
menuButtonLabel: 'Website'
|
||||||
|
onMenuButtonClicked: Qt.openUrlExternally(detailPage.link)
|
||||||
|
|
||||||
PBusyIndicator {
|
PBusyIndicator {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
visible: !detailPage.ready
|
visible: !detailPage.ready
|
||||||
|
@ -59,12 +64,7 @@ SlidePage {
|
||||||
width: detailPage.width
|
width: detailPage.width
|
||||||
spacing: 10 * pgst.scalef
|
spacing: 10 * pgst.scalef
|
||||||
|
|
||||||
SlidePageHeader {
|
Item { height: 20 * pgst.scalef; width: parent.width }
|
||||||
title: 'Shownotes'
|
|
||||||
icon: (detailPage.link != '') ? Icons.link : ''
|
|
||||||
iconText: 'Website'
|
|
||||||
onIconClicked: Qt.openUrlExternally(detailPage.link);
|
|
||||||
}
|
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
width: parent.width - 2 * 30 * pgst.scalef
|
width: parent.width - 2 * 30 * pgst.scalef
|
||||||
|
|
|
@ -28,6 +28,11 @@ import 'icons/icons.js' as Icons
|
||||||
SlidePage {
|
SlidePage {
|
||||||
id: allEpisodesPage
|
id: allEpisodesPage
|
||||||
|
|
||||||
|
hasMenuButton: true
|
||||||
|
menuButtonIcon: Icons.magnifying_glass
|
||||||
|
menuButtonLabel: 'Filter'
|
||||||
|
onMenuButtonClicked: queryControl.showSelectionDialog()
|
||||||
|
|
||||||
EpisodeQueryControl {
|
EpisodeQueryControl {
|
||||||
id: queryControl
|
id: queryControl
|
||||||
model: episodesListModel
|
model: episodesListModel
|
||||||
|
@ -48,9 +53,6 @@ SlidePage {
|
||||||
id: episodeList
|
id: episodeList
|
||||||
property int selectedIndex: -1
|
property int selectedIndex: -1
|
||||||
title: 'Episodes'
|
title: 'Episodes'
|
||||||
headerIcon: Icons.magnifying_glass
|
|
||||||
headerIconText: 'Filter'
|
|
||||||
onHeaderIconClicked: queryControl.showSelectionDialog();
|
|
||||||
|
|
||||||
PPlaceholder {
|
PPlaceholder {
|
||||||
text: 'No episodes found'
|
text: 'No episodes found'
|
||||||
|
|
|
@ -34,6 +34,36 @@ SlidePage {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: parent.height
|
height: parent.height
|
||||||
|
|
||||||
|
hasMenuButton: true
|
||||||
|
menuButtonLabel: 'Settings'
|
||||||
|
onMenuButtonClicked: {
|
||||||
|
pgst.showSelection([
|
||||||
|
{
|
||||||
|
label: 'Filter list (' + queryControl.currentFilter + ')',
|
||||||
|
callback: function () {
|
||||||
|
queryControl.showSelectionDialog();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Mark episodes as old',
|
||||||
|
callback: function () {
|
||||||
|
py.call('main.mark_episodes_as_old', [episodesPage.podcast_id]);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Unsubscribe',
|
||||||
|
callback: function () {
|
||||||
|
var ctx = { py: py, id: episodesPage.podcast_id, page: episodesPage };
|
||||||
|
pgst.showConfirmation('Unsubscribe', Icons.trash, function () {
|
||||||
|
ctx.py.call('main.unsubscribe', [ctx.id]);
|
||||||
|
ctx.page.closePage();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
episodeListModel.podcast_id = podcast_id;
|
episodeListModel.podcast_id = podcast_id;
|
||||||
episodeListModel.setQuery(episodeListModel.queries.All);
|
episodeListModel.setQuery(episodeListModel.queries.All);
|
||||||
|
@ -52,35 +82,6 @@ SlidePage {
|
||||||
title: episodesPage.title
|
title: episodesPage.title
|
||||||
model: GPodderEpisodeListModel { id: episodeListModel }
|
model: GPodderEpisodeListModel { id: episodeListModel }
|
||||||
|
|
||||||
headerIcon: Icons.cog
|
|
||||||
headerIconText: 'Settings'
|
|
||||||
onHeaderIconClicked: {
|
|
||||||
pgst.showSelection([
|
|
||||||
{
|
|
||||||
label: 'Filter list (' + queryControl.currentFilter + ')',
|
|
||||||
callback: function () {
|
|
||||||
queryControl.showSelectionDialog();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Mark episodes as old',
|
|
||||||
callback: function () {
|
|
||||||
py.call('main.mark_episodes_as_old', [episodesPage.podcast_id]);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Unsubscribe',
|
|
||||||
callback: function () {
|
|
||||||
var ctx = { py: py, id: episodesPage.podcast_id, page: episodesPage };
|
|
||||||
pgst.showConfirmation('Unsubscribe', Icons.trash, function () {
|
|
||||||
ctx.py.call('main.unsubscribe', [ctx.id]);
|
|
||||||
ctx.page.closePage();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
PPlaceholder {
|
PPlaceholder {
|
||||||
text: 'No episodes'
|
text: 'No episodes'
|
||||||
visible: episodeList.count === 0
|
visible: episodeList.count === 0
|
||||||
|
|
|
@ -32,6 +32,8 @@ ButtonArea {
|
||||||
property alias size: icon.size
|
property alias size: icon.size
|
||||||
property bool alwaysShowText: false
|
property bool alwaysShowText: false
|
||||||
|
|
||||||
|
Behavior on _real_color { ColorAnimation { duration: 100 } }
|
||||||
|
|
||||||
transparent: true
|
transparent: true
|
||||||
canHighlight: false
|
canHighlight: false
|
||||||
|
|
||||||
|
|
|
@ -51,10 +51,36 @@ Item {
|
||||||
} else {
|
} else {
|
||||||
children[index-1].opacity = x / width;
|
children[index-1].opacity = x / width;
|
||||||
}
|
}
|
||||||
|
|
||||||
//children[index-1].pushPhase = x / width;
|
//children[index-1].pushPhase = x / width;
|
||||||
}
|
}
|
||||||
|
|
||||||
property bool loadPageInProgress: false
|
property bool loadPageInProgress: false
|
||||||
|
property bool hasBackButton: false
|
||||||
|
property int bottomSpacing: toolbar.showing ? toolbar.height+toolbar.anchors.bottomMargin : 0
|
||||||
|
|
||||||
|
property bool hasMenuButton: false
|
||||||
|
property string menuButtonLabel: ''
|
||||||
|
property string menuButtonIcon: ''
|
||||||
|
|
||||||
|
function topOfStackChanged(offset) {
|
||||||
|
if (offset === undefined) {
|
||||||
|
offset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
var page = children[children.length+offset-1];
|
||||||
|
|
||||||
|
// TODO: Maybe make these property bindings instead
|
||||||
|
pgst.hasBackButton = (!page.isDialog && page.canClose);
|
||||||
|
pgst.hasMenuButton = page.hasMenuButton;
|
||||||
|
if (pgst.hasMenuButton) {
|
||||||
|
pgst.menuButtonLabel = page.menuButtonLabel;
|
||||||
|
pgst.menuButtonIcon = page.menuButtonIcon;
|
||||||
|
} else {
|
||||||
|
pgst.menuButtonLabel = 'Menu';
|
||||||
|
pgst.menuButtonIcon = Icons.vellipsis;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function showConfirmation(title, icon, callback) {
|
function showConfirmation(title, icon, callback) {
|
||||||
loadPage('Confirmation.qml', {
|
loadPage('Confirmation.qml', {
|
||||||
|
@ -106,29 +132,67 @@ Item {
|
||||||
visible: !py.ready
|
visible: !py.ready
|
||||||
}
|
}
|
||||||
|
|
||||||
IconMenuItem {
|
Image {
|
||||||
id: throbber
|
z: 101
|
||||||
|
|
||||||
z: 100
|
|
||||||
|
|
||||||
anchors {
|
anchors {
|
||||||
|
left: parent.left
|
||||||
right: parent.right
|
right: parent.right
|
||||||
rightMargin: (opacity-1) * width
|
bottom: toolbar.top
|
||||||
top: parent.top
|
|
||||||
topMargin: (Constants.layout.header.height * pgst.scalef - height) / 2
|
|
||||||
}
|
}
|
||||||
|
|
||||||
text: 'Now Playing'
|
source: 'images/toolbarshadow.png'
|
||||||
color: Constants.colors.playback
|
opacity: .1
|
||||||
icon: Icons.play
|
height: 10 * pgst.scalef
|
||||||
|
visible: toolbar.showing
|
||||||
|
}
|
||||||
|
|
||||||
transparent: false
|
PToolbar {
|
||||||
enabled: opacity
|
id: toolbar
|
||||||
|
z: 102
|
||||||
|
|
||||||
opacity: player.episode != 0 && !pgst.dialogsVisible
|
Row {
|
||||||
Behavior on opacity { PropertyAnimation { duration: 200 } }
|
anchors {
|
||||||
|
verticalCenter: parent.verticalCenter
|
||||||
|
left: parent.left
|
||||||
|
}
|
||||||
|
|
||||||
onClicked: loadPage('PlayerPage.qml');
|
PToolbarButton {
|
||||||
|
id: backButton
|
||||||
|
|
||||||
|
text: 'Back'
|
||||||
|
icon: Icons.arrow_left
|
||||||
|
|
||||||
|
enabled: pgst.hasBackButton
|
||||||
|
onClicked: pgst.children[pgst.children.length-1].closePage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
anchors {
|
||||||
|
verticalCenter: parent.verticalCenter
|
||||||
|
right: parent.right
|
||||||
|
}
|
||||||
|
|
||||||
|
PToolbarButton {
|
||||||
|
id: throbber
|
||||||
|
|
||||||
|
text: 'Now Playing'
|
||||||
|
icon: Icons.play
|
||||||
|
|
||||||
|
enabled: player.episode != 0
|
||||||
|
onClicked: loadPage('PlayerPage.qml');
|
||||||
|
}
|
||||||
|
|
||||||
|
PToolbarButton {
|
||||||
|
id: menuButton
|
||||||
|
|
||||||
|
text: pgst.menuButtonLabel
|
||||||
|
icon: pgst.menuButtonIcon
|
||||||
|
|
||||||
|
enabled: pgst.hasMenuButton
|
||||||
|
onClicked: pgst.children[pgst.children.length-1].menuButtonClicked()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PodcastsPage {
|
PodcastsPage {
|
||||||
|
|
|
@ -27,19 +27,12 @@ ListView {
|
||||||
|
|
||||||
property string title
|
property string title
|
||||||
property real pushPhase: 0
|
property real pushPhase: 0
|
||||||
property string headerIcon
|
|
||||||
property string headerIconText
|
|
||||||
|
|
||||||
signal headerIconClicked()
|
|
||||||
|
|
||||||
boundsBehavior: Flickable.StopAtBounds
|
boundsBehavior: Flickable.StopAtBounds
|
||||||
|
|
||||||
header: SlidePageHeader {
|
header: SlidePageHeader {
|
||||||
id: header
|
id: header
|
||||||
title: pListView.title
|
title: pListView.title
|
||||||
icon: pListView.headerIcon
|
|
||||||
iconText: pListView.headerIconText
|
|
||||||
onIconClicked: pListView.headerIconClicked()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PScrollDecorator { flickable: pListView }
|
PScrollDecorator { flickable: pListView }
|
||||||
|
|
48
touch/PToolbar.qml
Normal file
48
touch/PToolbar.qml
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* gPodder QML UI Reference Implementation
|
||||||
|
* Copyright (c) 2014, Thomas Perl <m@thp.io>
|
||||||
|
*
|
||||||
|
* 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 'common'
|
||||||
|
|
||||||
|
import 'common/constants.js' as Constants
|
||||||
|
import 'icons/icons.js' as Icons
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: toolbar
|
||||||
|
property bool showing: true
|
||||||
|
|
||||||
|
color: Constants.colors.toolbar
|
||||||
|
|
||||||
|
height: 80 * pgst.scalef
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
// Capture all touch events
|
||||||
|
anchors.fill: parent
|
||||||
|
}
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
left: parent.left
|
||||||
|
right: parent.right
|
||||||
|
bottom: parent.bottom
|
||||||
|
bottomMargin: toolbar.showing ? 0 : -height
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on anchors.bottomMargin { PropertyAnimation { duration: 100 } }
|
||||||
|
}
|
59
touch/PToolbarButton.qml
Normal file
59
touch/PToolbarButton.qml
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* gPodder QML UI Reference Implementation
|
||||||
|
* Copyright (c) 2014, Thomas Perl <m@thp.io>
|
||||||
|
*
|
||||||
|
* 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 'common'
|
||||||
|
|
||||||
|
import 'common/constants.js' as Constants
|
||||||
|
import 'icons/icons.js' as Icons
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: toolbarButton
|
||||||
|
|
||||||
|
//property alias color: iconMenuItem.color
|
||||||
|
//property alias text: iconMenuItem.text
|
||||||
|
property string text: ''
|
||||||
|
property alias icon: iconMenuItem.icon
|
||||||
|
|
||||||
|
signal clicked()
|
||||||
|
|
||||||
|
width: iconMenuItem.width
|
||||||
|
height: iconMenuItem.height
|
||||||
|
color: iconMenuItem.pressed ? Constants.colors.toolbarArea : 'transparent'
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
height: 5 * pgst.scalef
|
||||||
|
color: iconMenuItem.pressed ? Constants.colors.secondaryHighlight : 'transparent'
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
left: parent.left
|
||||||
|
right: parent.right
|
||||||
|
top: parent.top
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IconMenuItem {
|
||||||
|
id: iconMenuItem
|
||||||
|
color: Constants.colors.text
|
||||||
|
transparent: true
|
||||||
|
enabled: parent.enabled
|
||||||
|
onClicked: toolbarButton.clicked()
|
||||||
|
}
|
||||||
|
}
|
|
@ -63,6 +63,7 @@ Dialog {
|
||||||
}
|
}
|
||||||
text: player.episode_title
|
text: player.episode_title
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
|
color: Constants.colors.dialogText
|
||||||
}
|
}
|
||||||
|
|
||||||
PLabel {
|
PLabel {
|
||||||
|
@ -72,12 +73,14 @@ Dialog {
|
||||||
}
|
}
|
||||||
text: player.podcast_title
|
text: player.podcast_title
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
|
color: Constants.colors.dialogText
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PLabel {
|
PLabel {
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
text: Util.formatPosition(slider.displayedValue/1000, player.duration/1000)
|
text: Util.formatPosition(slider.displayedValue/1000, player.duration/1000)
|
||||||
|
color: Constants.colors.dialogText
|
||||||
}
|
}
|
||||||
|
|
||||||
PSlider {
|
PSlider {
|
||||||
|
|
|
@ -29,6 +29,43 @@ SlidePage {
|
||||||
id: podcastsPage
|
id: podcastsPage
|
||||||
canClose: false
|
canClose: false
|
||||||
|
|
||||||
|
hasMenuButton: true
|
||||||
|
menuButtonLabel: 'Settings'
|
||||||
|
onMenuButtonClicked: {
|
||||||
|
pgst.showSelection([
|
||||||
|
{
|
||||||
|
label: 'Check for new episodes',
|
||||||
|
callback: function () {
|
||||||
|
py.call('main.check_for_episodes');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Filter episodes',
|
||||||
|
callback: function () {
|
||||||
|
pgst.loadPage('EpisodeQueryPage.qml');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'About',
|
||||||
|
callback: function () {
|
||||||
|
pgst.loadPage('AboutPage.qml');
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Add new podcast',
|
||||||
|
callback: function () {
|
||||||
|
pgst.loadPage('Subscribe.qml');
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Search gpodder.net',
|
||||||
|
callback: function () {
|
||||||
|
pgst.loadPage('Directory.qml');
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
PListView {
|
PListView {
|
||||||
id: podcastList
|
id: podcastList
|
||||||
title: 'Subscriptions'
|
title: 'Subscriptions'
|
||||||
|
@ -36,43 +73,6 @@ SlidePage {
|
||||||
section.property: 'section'
|
section.property: 'section'
|
||||||
section.delegate: SectionHeader { text: section }
|
section.delegate: SectionHeader { text: section }
|
||||||
|
|
||||||
headerIcon: Icons.cog
|
|
||||||
headerIconText: 'Settings'
|
|
||||||
onHeaderIconClicked: {
|
|
||||||
pgst.showSelection([
|
|
||||||
{
|
|
||||||
label: 'Check for new episodes',
|
|
||||||
callback: function () {
|
|
||||||
py.call('main.check_for_episodes');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Filter episodes',
|
|
||||||
callback: function () {
|
|
||||||
pgst.loadPage('EpisodeQueryPage.qml');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'About',
|
|
||||||
callback: function () {
|
|
||||||
pgst.loadPage('AboutPage.qml');
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Add new podcast',
|
|
||||||
callback: function () {
|
|
||||||
pgst.loadPage('Subscribe.qml');
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Search gpodder.net',
|
|
||||||
callback: function () {
|
|
||||||
pgst.loadPage('Directory.qml');
|
|
||||||
},
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
PPlaceholder {
|
PPlaceholder {
|
||||||
text: 'No podcasts'
|
text: 'No podcasts'
|
||||||
visible: podcastList.count === 0
|
visible: podcastList.count === 0
|
||||||
|
|
|
@ -46,7 +46,7 @@ Dialog {
|
||||||
SlidePageHeader {
|
SlidePageHeader {
|
||||||
id: header
|
id: header
|
||||||
visible: title != ''
|
visible: title != ''
|
||||||
color: Constants.colors.highlight
|
color: Constants.colors.dialogHighlight
|
||||||
title: selectionDialog.title
|
title: selectionDialog.title
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,8 +56,9 @@ Dialog {
|
||||||
delegate: ButtonArea {
|
delegate: ButtonArea {
|
||||||
id: buttonArea
|
id: buttonArea
|
||||||
|
|
||||||
|
color: Constants.colors.dialogArea
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: 60 * pgst.scalef
|
height: 70 * pgst.scalef
|
||||||
|
|
||||||
transparent: (index != selectionDialog.selectedIndex)
|
transparent: (index != selectionDialog.selectedIndex)
|
||||||
|
|
||||||
|
@ -69,7 +70,8 @@ Dialog {
|
||||||
}
|
}
|
||||||
|
|
||||||
text: modelData
|
text: modelData
|
||||||
color: (index == selectionDialog.selectedIndex || buttonArea.pressed) ? Constants.colors.highlight : Constants.colors.text
|
color: (index == selectionDialog.selectedIndex || buttonArea.pressed) ? Constants.colors.dialogHighlight : Constants.colors.dialogText
|
||||||
|
font.pixelSize: 30 * pgst.scalef
|
||||||
}
|
}
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
|
|
|
@ -21,15 +21,23 @@
|
||||||
import QtQuick 2.0
|
import QtQuick 2.0
|
||||||
|
|
||||||
import 'common/constants.js' as Constants
|
import 'common/constants.js' as Constants
|
||||||
|
import 'icons/icons.js' as Icons
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: page
|
id: page
|
||||||
color: Constants.colors.page
|
color: Constants.colors.page
|
||||||
|
|
||||||
|
Component.onCompleted: pgst.topOfStackChanged();
|
||||||
|
|
||||||
default property alias children: dragging.children
|
default property alias children: dragging.children
|
||||||
property alias canClose: dragging.canClose
|
property alias canClose: dragging.canClose
|
||||||
property bool isDialog: false
|
property bool isDialog: false
|
||||||
|
|
||||||
|
property bool hasMenuButton: false
|
||||||
|
property string menuButtonLabel: 'Menu'
|
||||||
|
property string menuButtonIcon: Icons.vellipsis
|
||||||
|
signal menuButtonClicked()
|
||||||
|
|
||||||
function closePage() {
|
function closePage() {
|
||||||
stacking.startFadeOut();
|
stacking.startFadeOut();
|
||||||
}
|
}
|
||||||
|
@ -37,7 +45,7 @@ Rectangle {
|
||||||
onXChanged: pgst.update(page, x)
|
onXChanged: pgst.update(page, x)
|
||||||
|
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: parent.height
|
height: parent.height - parent.bottomSpacing
|
||||||
|
|
||||||
Stacking { id: stacking }
|
Stacking { id: stacking }
|
||||||
|
|
||||||
|
|
|
@ -28,45 +28,21 @@ Item {
|
||||||
property alias title: label.text
|
property alias title: label.text
|
||||||
property alias color: label.color
|
property alias color: label.color
|
||||||
|
|
||||||
property alias iconText: icon.text
|
|
||||||
property alias icon: icon.icon
|
|
||||||
signal iconClicked()
|
|
||||||
|
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: Constants.layout.header.height * pgst.scalef
|
height: Constants.layout.header.height * pgst.scalef
|
||||||
|
|
||||||
IconMenuItem {
|
|
||||||
id: icon
|
|
||||||
|
|
||||||
visible: icon != '' && icon != undefined
|
|
||||||
enabled: visible
|
|
||||||
|
|
||||||
text: 'Search'
|
|
||||||
icon: ''
|
|
||||||
color: label.color
|
|
||||||
|
|
||||||
anchors {
|
|
||||||
left: parent.left
|
|
||||||
verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
onClicked: slidePageHeader.iconClicked()
|
|
||||||
}
|
|
||||||
|
|
||||||
PLabel {
|
PLabel {
|
||||||
id: label
|
id: label
|
||||||
anchors {
|
anchors {
|
||||||
left: icon.visible ? icon.right : parent.left
|
left: parent.left
|
||||||
right: parent.right
|
right: parent.right
|
||||||
rightMargin: 20 * pgst.scalef + (throbber.width * throbber.opacity)
|
rightMargin: 20 * pgst.scalef
|
||||||
leftMargin: 20 * pgst.scalef
|
leftMargin: 20 * pgst.scalef
|
||||||
verticalCenter: parent.verticalCenter
|
verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
color: Constants.colors.highlight
|
color: Constants.colors.highlight
|
||||||
horizontalAlignment: Text.AlignRight
|
|
||||||
font.pixelSize: parent.height * .4
|
font.pixelSize: parent.height * .4
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,7 @@ Item {
|
||||||
|
|
||||||
function startFadeOut() {
|
function startFadeOut() {
|
||||||
fadeOut.start();
|
fadeOut.start();
|
||||||
|
pgst.topOfStackChanged(-1);
|
||||||
page.destroy(500);
|
page.destroy(500);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,3 +19,4 @@ var folder = '\ue065';
|
||||||
var magnifying_glass = '\ue074';
|
var magnifying_glass = '\ue074';
|
||||||
var cog = '\u2699';
|
var cog = '\u2699';
|
||||||
var link = '\ue077';
|
var link = '\ue077';
|
||||||
|
var vellipsis = '\u22ee';
|
||||||
|
|
BIN
touch/images/toolbarshadow.png
Normal file
BIN
touch/images/toolbarshadow.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 154 B |
Loading…
Add table
Add a link
Reference in a new issue