Android UI customizations
This commit is contained in:
parent
c7fd930219
commit
9610c51c30
18 changed files with 260 additions and 48 deletions
33
common/GPodderPlatform.qml
Normal file
33
common/GPodderPlatform.qml
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
|
||||||
|
Item {
|
||||||
|
property bool emulatingAndroid: false
|
||||||
|
|
||||||
|
property bool android: (typeof(gpodderAndroid) !== 'undefined') || emulatingAndroid
|
||||||
|
|
||||||
|
property bool needsBackButton: !android
|
||||||
|
property bool toolbarOnTop: android
|
||||||
|
property bool invertedToolbar: toolbarOnTop
|
||||||
|
property bool titleInToolbar: toolbarOnTop
|
||||||
|
property bool floatingPlayButton: android
|
||||||
|
}
|
|
@ -41,7 +41,7 @@ MediaPlayer {
|
||||||
property int playedFrom: 0
|
property int playedFrom: 0
|
||||||
|
|
||||||
property var androidConnections: Connections {
|
property var androidConnections: Connections {
|
||||||
target: (typeof(gpodderAndroid) === 'undefined') ? null : gpodderAndroid
|
target: platform.android ? gpodderAndroid : null
|
||||||
|
|
||||||
onAudioBecomingNoisy: {
|
onAudioBecomingNoisy: {
|
||||||
if (playbackState === MediaPlayer.PlayingState) {
|
if (playbackState === MediaPlayer.PlayingState) {
|
||||||
|
|
|
@ -36,8 +36,17 @@ var colors = {
|
||||||
playback: '#729fcf', /* playback blue */
|
playback: '#729fcf', /* playback blue */
|
||||||
destructive: '#cf424f', /* destructive actions */
|
destructive: '#cf424f', /* destructive actions */
|
||||||
|
|
||||||
page: '#dddddd',
|
|
||||||
toolbar: '#d0d0d0',
|
toolbar: '#d0d0d0',
|
||||||
|
toolbarText: '#333333',
|
||||||
|
toolbarDisabled: '#666666',
|
||||||
|
|
||||||
|
inverted: {
|
||||||
|
toolbar: '#815c86',
|
||||||
|
toolbarText: '#ffffff',
|
||||||
|
toolbarDisabled: '#aaffffff',
|
||||||
|
},
|
||||||
|
|
||||||
|
page: '#dddddd',
|
||||||
dialog: '#dddddd',
|
dialog: '#dddddd',
|
||||||
dialogBackground: '#aa000000',
|
dialogBackground: '#aa000000',
|
||||||
text: '#333333', /* text color */
|
text: '#333333', /* text color */
|
||||||
|
|
|
@ -23,7 +23,7 @@ import QtQuick 2.0
|
||||||
import 'common/constants.js' as Constants
|
import 'common/constants.js' as Constants
|
||||||
|
|
||||||
SlidePage {
|
SlidePage {
|
||||||
id: aboutPage
|
id: page
|
||||||
|
|
||||||
Flickable {
|
Flickable {
|
||||||
id: flickable
|
id: flickable
|
||||||
|
@ -36,7 +36,7 @@ SlidePage {
|
||||||
Column {
|
Column {
|
||||||
id: detailColumn
|
id: detailColumn
|
||||||
|
|
||||||
width: aboutPage.width
|
width: page.width
|
||||||
spacing: 15 * pgst.scalef
|
spacing: 15 * pgst.scalef
|
||||||
|
|
||||||
SlidePageHeader {
|
SlidePageHeader {
|
||||||
|
@ -46,6 +46,8 @@ SlidePage {
|
||||||
Column {
|
Column {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
|
|
||||||
|
Item { height: 10 * pgst.scalef; width: 1 }
|
||||||
|
|
||||||
PLabel {
|
PLabel {
|
||||||
width: parent.width * .95
|
width: parent.width * .95
|
||||||
font.pixelSize: 30 * pgst.scalef
|
font.pixelSize: 30 * pgst.scalef
|
||||||
|
|
|
@ -75,11 +75,10 @@ SlidePage {
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
spacing: Constants.layout.padding * pgst.scalef
|
spacing: Constants.layout.padding * pgst.scalef
|
||||||
|
|
||||||
PLabel {
|
SlidePageHeader {
|
||||||
text: detailPage.title
|
title: detailPage.title
|
||||||
width: parent.width
|
width: parent.width
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
font.pixelSize: 35 * pgst.scalef
|
|
||||||
color: Constants.colors.highlight
|
color: Constants.colors.highlight
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ import 'common/constants.js' as Constants
|
||||||
import 'icons/icons.js' as Icons
|
import 'icons/icons.js' as Icons
|
||||||
|
|
||||||
SlidePage {
|
SlidePage {
|
||||||
id: allEpisodesPage
|
id: page
|
||||||
|
|
||||||
hasMenuButton: true
|
hasMenuButton: true
|
||||||
menuButtonIcon: Icons.magnifying_glass
|
menuButtonIcon: Icons.magnifying_glass
|
||||||
|
|
|
@ -26,7 +26,7 @@ import 'common/constants.js' as Constants
|
||||||
import 'icons/icons.js' as Icons
|
import 'icons/icons.js' as Icons
|
||||||
|
|
||||||
SlidePage {
|
SlidePage {
|
||||||
id: episodesPage
|
id: page
|
||||||
|
|
||||||
property int podcast_id
|
property int podcast_id
|
||||||
property string title
|
property string title
|
||||||
|
@ -44,7 +44,7 @@ SlidePage {
|
||||||
{
|
{
|
||||||
label: 'Mark episodes as old',
|
label: 'Mark episodes as old',
|
||||||
callback: function () {
|
callback: function () {
|
||||||
py.call('main.mark_episodes_as_old', [episodesPage.podcast_id]);
|
py.call('main.mark_episodes_as_old', [page.podcast_id]);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -56,7 +56,7 @@ SlidePage {
|
||||||
{
|
{
|
||||||
label: 'Unsubscribe',
|
label: 'Unsubscribe',
|
||||||
callback: function () {
|
callback: function () {
|
||||||
var ctx = { py: py, id: episodesPage.podcast_id, page: episodesPage };
|
var ctx = { py: py, id: page.podcast_id, page: page };
|
||||||
pgst.showConfirmation(title, 'Unsubscribe', 'Cancel', 'Remove this podcast and all downloaded episodes?', Icons.trash, function () {
|
pgst.showConfirmation(title, 'Unsubscribe', 'Cancel', 'Remove this podcast and all downloaded episodes?', Icons.trash, function () {
|
||||||
ctx.py.call('main.unsubscribe', [ctx.id]);
|
ctx.py.call('main.unsubscribe', [ctx.id]);
|
||||||
ctx.page.closePage();
|
ctx.page.closePage();
|
||||||
|
@ -80,6 +80,6 @@ SlidePage {
|
||||||
|
|
||||||
EpisodeListView {
|
EpisodeListView {
|
||||||
id: episodeList
|
id: episodeList
|
||||||
title: episodesPage.title
|
title: page.title
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,8 @@ ButtonArea {
|
||||||
|
|
||||||
property alias text: label.text
|
property alias text: label.text
|
||||||
property color color: Constants.colors.secondaryHighlight
|
property color color: Constants.colors.secondaryHighlight
|
||||||
property color _real_color: enabled ? color : Constants.colors.placeholder
|
property color colorDisabled: Constants.colors.placeholder
|
||||||
|
property color _real_color: enabled ? color : colorDisabled
|
||||||
property alias icon: icon.icon
|
property alias icon: icon.icon
|
||||||
property alias size: icon.size
|
property alias size: icon.size
|
||||||
property bool alwaysShowText: false
|
property bool alwaysShowText: false
|
||||||
|
|
|
@ -30,6 +30,7 @@ Item {
|
||||||
|
|
||||||
GPodderCore { id: py }
|
GPodderCore { id: py }
|
||||||
GPodderPlayback { id: player }
|
GPodderPlayback { id: player }
|
||||||
|
GPodderPlatform { id: platform }
|
||||||
|
|
||||||
GPodderPodcastListModel { id: podcastListModel }
|
GPodderPodcastListModel { id: podcastListModel }
|
||||||
GPodderPodcastListModelConnections {}
|
GPodderPodcastListModelConnections {}
|
||||||
|
@ -98,6 +99,7 @@ Item {
|
||||||
property bool hasMenuButton: false
|
property bool hasMenuButton: false
|
||||||
property string menuButtonLabel: ''
|
property string menuButtonLabel: ''
|
||||||
property string menuButtonIcon: ''
|
property string menuButtonIcon: ''
|
||||||
|
property string windowTitle: 'gPodder'
|
||||||
|
|
||||||
function topOfStackChanged(offset) {
|
function topOfStackChanged(offset) {
|
||||||
if (offset === undefined) {
|
if (offset === undefined) {
|
||||||
|
@ -107,9 +109,13 @@ Item {
|
||||||
var page = children[children.length+offset-1];
|
var page = children[children.length+offset-1];
|
||||||
|
|
||||||
pgst.hasBackButton = Qt.binding(function () { return page.isDialog || page.canClose; });
|
pgst.hasBackButton = Qt.binding(function () { return page.isDialog || page.canClose; });
|
||||||
pgst.hasMenuButton = Qt.binding(function () { return page.hasMenuButton; });
|
pgst.hasMenuButton = Qt.binding(function () { return !page.isDialog && page.hasMenuButton; });
|
||||||
pgst.menuButtonLabel = Qt.binding(function () { return pgst.hasMenuButton ? page.menuButtonLabel : 'Menu'; });
|
pgst.menuButtonLabel = Qt.binding(function () { return (!page.isDialog && pgst.hasMenuButton) ? page.menuButtonLabel : 'Menu'; });
|
||||||
pgst.menuButtonIcon = Qt.binding(function () { return pgst.hasMenuButton ? page.menuButtonIcon : Icons.vellipsis; });
|
pgst.menuButtonIcon = Qt.binding(function () { return (!page.isDialog && pgst.hasMenuButton) ? page.menuButtonIcon : Icons.vellipsis; });
|
||||||
|
|
||||||
|
if (!page.isDialog) {
|
||||||
|
pgst.windowTitle = page.title || 'gPodder';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function showConfirmation(title, affirmative, negative, description, icon, callback) {
|
function showConfirmation(title, affirmative, negative, description, icon, callback) {
|
||||||
|
@ -170,10 +176,11 @@ Item {
|
||||||
anchors {
|
anchors {
|
||||||
left: parent.left
|
left: parent.left
|
||||||
right: parent.right
|
right: parent.right
|
||||||
bottom: toolbar.top
|
top: platform.toolbarOnTop ? toolbar.bottom : undefined
|
||||||
|
bottom: platform.toolbarOnTop ? undefined : toolbar.top
|
||||||
}
|
}
|
||||||
|
|
||||||
source: 'images/toolbarshadow.png'
|
source: platform.toolbarOnTop ? 'images/toolbarshadow-top.png' : 'images/toolbarshadow.png'
|
||||||
opacity: .1
|
opacity: .1
|
||||||
height: 10 * pgst.scalef
|
height: 10 * pgst.scalef
|
||||||
visible: toolbar.showing
|
visible: toolbar.showing
|
||||||
|
@ -183,7 +190,14 @@ Item {
|
||||||
id: toolbar
|
id: toolbar
|
||||||
z: 102
|
z: 102
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
top: platform.toolbarOnTop ? parent.top : undefined
|
||||||
|
bottom: platform.toolbarOnTop ? undefined : parent.bottom
|
||||||
|
}
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
|
id: toolbarButtonsLeft
|
||||||
|
|
||||||
anchors {
|
anchors {
|
||||||
verticalCenter: parent.verticalCenter
|
verticalCenter: parent.verticalCenter
|
||||||
left: parent.left
|
left: parent.left
|
||||||
|
@ -195,9 +209,7 @@ Item {
|
||||||
text: 'Back'
|
text: 'Back'
|
||||||
icon: Icons.arrow_left
|
icon: Icons.arrow_left
|
||||||
|
|
||||||
// Don't show back button on Android (Android has its own)
|
visible: platform.needsBackButton
|
||||||
visible: (typeof(gpodderAndroid) === 'undefined')
|
|
||||||
|
|
||||||
enabled: pgst.hasBackButton
|
enabled: pgst.hasBackButton
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
|
@ -207,7 +219,22 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PToolbarLabel {
|
||||||
|
visible: platform.titleInToolbar
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
verticalCenter: parent.verticalCenter
|
||||||
|
left: toolbarButtonsLeft.right
|
||||||
|
right: toolbarButtonsRight.left
|
||||||
|
margins: Constants.layout.padding * pgst.scalef
|
||||||
|
}
|
||||||
|
|
||||||
|
text: pgst.windowTitle
|
||||||
|
}
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
|
id: toolbarButtonsRight
|
||||||
|
|
||||||
anchors {
|
anchors {
|
||||||
verticalCenter: parent.verticalCenter
|
verticalCenter: parent.verticalCenter
|
||||||
right: parent.right
|
right: parent.right
|
||||||
|
@ -218,6 +245,7 @@ Item {
|
||||||
|
|
||||||
text: 'Now Playing'
|
text: 'Now Playing'
|
||||||
icon: Icons.play
|
icon: Icons.play
|
||||||
|
visible: !platform.floatingPlayButton
|
||||||
|
|
||||||
enabled: player.episode != 0
|
enabled: player.episode != 0
|
||||||
onClicked: loadPage('PlayerPage.qml');
|
onClicked: loadPage('PlayerPage.qml');
|
||||||
|
@ -265,6 +293,45 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
z: 190
|
||||||
|
color: Constants.colors.playback
|
||||||
|
visible: platform.floatingPlayButton
|
||||||
|
|
||||||
|
Behavior on opacity { NumberAnimation { } }
|
||||||
|
opacity: (player.episode != 0) ? (player.isPlaying ? 1 : .5) : 0
|
||||||
|
|
||||||
|
width: Constants.layout.item.height * 1.1 * pgst.scalef
|
||||||
|
height: width
|
||||||
|
radius: height / 2
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
right: parent.right
|
||||||
|
margins: Constants.layout.padding * 2 * pgst.scalef
|
||||||
|
}
|
||||||
|
|
||||||
|
y: pgst.height - height - anchors.margins
|
||||||
|
|
||||||
|
PIcon {
|
||||||
|
id: icon
|
||||||
|
anchors.centerIn: parent
|
||||||
|
icon: Icons.headphones
|
||||||
|
size: 60
|
||||||
|
color: Constants.colors.inverted.toolbarText
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: loadPage('PlayerPage.qml');
|
||||||
|
drag {
|
||||||
|
target: parent
|
||||||
|
axis: Drag.YAxis
|
||||||
|
minimumY: pgst.bottomSpacing + parent.anchors.margins
|
||||||
|
maximumY: pgst.height - parent.height - parent.anchors.margins
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
PodcastsPage {
|
PodcastsPage {
|
||||||
visible: py.ready
|
visible: py.ready
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ Rectangle {
|
||||||
id: toolbar
|
id: toolbar
|
||||||
property bool showing: true
|
property bool showing: true
|
||||||
|
|
||||||
color: Constants.colors.toolbar
|
color: platform.invertedToolbar ? Constants.colors.inverted.toolbar : Constants.colors.toolbar
|
||||||
|
|
||||||
height: 80 * pgst.scalef
|
height: 80 * pgst.scalef
|
||||||
|
|
||||||
|
@ -40,9 +40,10 @@ Rectangle {
|
||||||
anchors {
|
anchors {
|
||||||
left: parent.left
|
left: parent.left
|
||||||
right: parent.right
|
right: parent.right
|
||||||
bottom: parent.bottom
|
topMargin: toolbar.showing ? 0 : -toolbar.height
|
||||||
bottomMargin: toolbar.showing ? 0 : -height
|
bottomMargin: toolbar.showing ? 0 : -toolbar.height
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on anchors.bottomMargin { PropertyAnimation { duration: 100 } }
|
Behavior on anchors.bottomMargin { PropertyAnimation { duration: 100 } }
|
||||||
|
Behavior on anchors.topMargin { PropertyAnimation { duration: 100 } }
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,7 @@ Rectangle {
|
||||||
|
|
||||||
width: iconMenuItem.width
|
width: iconMenuItem.width
|
||||||
height: iconMenuItem.height
|
height: iconMenuItem.height
|
||||||
color: iconMenuItem.pressed ? Constants.colors.toolbarArea : 'transparent'
|
color: iconMenuItem.pressed ? (platform.invertedToolbar ? Constants.colors.toolbarArea : Constants.colors.inverted.toolbarArea) : 'transparent'
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
height: 5 * pgst.scalef
|
height: 5 * pgst.scalef
|
||||||
|
@ -51,7 +51,8 @@ Rectangle {
|
||||||
|
|
||||||
IconMenuItem {
|
IconMenuItem {
|
||||||
id: iconMenuItem
|
id: iconMenuItem
|
||||||
color: Constants.colors.text
|
color: platform.invertedToolbar ? Constants.colors.inverted.toolbarText : Constants.colors.toolbarText
|
||||||
|
colorDisabled: platform.invertedToolbar ? Constants.colors.inverted.toolbarDisabled : Constants.colors.toolbarDisabled
|
||||||
transparent: true
|
transparent: true
|
||||||
enabled: parent.enabled
|
enabled: parent.enabled
|
||||||
onClicked: toolbarButton.clicked()
|
onClicked: toolbarButton.clicked()
|
||||||
|
|
84
touch/PToolbarLabel.qml
Normal file
84
touch/PToolbarLabel.qml
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: toolbarLabel
|
||||||
|
|
||||||
|
property string text: ''
|
||||||
|
property bool firstLable: false
|
||||||
|
|
||||||
|
onTextChanged: {
|
||||||
|
state = (state === 'a') ? 'b': 'a';
|
||||||
|
if (state === 'a') {
|
||||||
|
a.text = text;
|
||||||
|
} else {
|
||||||
|
b.text = text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
states: [
|
||||||
|
State {
|
||||||
|
name: 'a'
|
||||||
|
PropertyChanges { target: a; opacity: 1; anchors.leftMargin: 0 }
|
||||||
|
PropertyChanges { target: b; opacity: 0; anchors.leftMargin: 10 * pgst.scalef }
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: 'b'
|
||||||
|
PropertyChanges { target: a; opacity: 0; anchors.leftMargin: -10 * pgst.scalef }
|
||||||
|
PropertyChanges { target: b; opacity: 1; anchors.leftMargin: 0 }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
PLabel {
|
||||||
|
id: a
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
left: parent.left
|
||||||
|
right: parent.right
|
||||||
|
verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
color: platform.invertedToolbar ? Constants.colors.inverted.toolbarText : Constants.colors.toolbarText
|
||||||
|
elide: Text.ElideRight
|
||||||
|
|
||||||
|
Behavior on anchors.leftMargin { NumberAnimation { } }
|
||||||
|
Behavior on opacity { NumberAnimation { } }
|
||||||
|
}
|
||||||
|
|
||||||
|
PLabel {
|
||||||
|
id: b
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
left: parent.left
|
||||||
|
right: parent.right
|
||||||
|
verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
color: platform.invertedToolbar ? Constants.colors.inverted.toolbarText : Constants.colors.toolbarText
|
||||||
|
elide: Text.ElideRight
|
||||||
|
|
||||||
|
Behavior on anchors.leftMargin { NumberAnimation { } }
|
||||||
|
Behavior on opacity { NumberAnimation { } }
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,7 +25,7 @@ import 'common/util.js' as Util
|
||||||
import 'icons/icons.js' as Icons
|
import 'icons/icons.js' as Icons
|
||||||
|
|
||||||
SlidePage {
|
SlidePage {
|
||||||
id: podcastDetail
|
id: page
|
||||||
|
|
||||||
property int podcast_id
|
property int podcast_id
|
||||||
property string title
|
property string title
|
||||||
|
@ -43,7 +43,7 @@ SlidePage {
|
||||||
{
|
{
|
||||||
label: 'Visit website',
|
label: 'Visit website',
|
||||||
callback: function () {
|
callback: function () {
|
||||||
Qt.openUrlExternally(podcastDetail.link);
|
Qt.openUrlExternally(page.link);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -51,14 +51,14 @@ SlidePage {
|
||||||
callback: function () {
|
callback: function () {
|
||||||
pgst.loadPage('TextInputDialog.qml', {
|
pgst.loadPage('TextInputDialog.qml', {
|
||||||
placeholderText: 'Feed URL',
|
placeholderText: 'Feed URL',
|
||||||
text: podcastDetail.url,
|
text: page.url,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Change section',
|
label: 'Change section',
|
||||||
callback: function () {
|
callback: function () {
|
||||||
var ctx = { py: py, id: podcastDetail.podcast_id };
|
var ctx = { py: py, id: page.podcast_id };
|
||||||
pgst.loadPage('TextInputDialog.qml', {
|
pgst.loadPage('TextInputDialog.qml', {
|
||||||
buttonText: 'Change section',
|
buttonText: 'Change section',
|
||||||
placeholderText: 'New section',
|
placeholderText: 'New section',
|
||||||
|
@ -74,18 +74,18 @@ SlidePage {
|
||||||
|
|
||||||
PBusyIndicator {
|
PBusyIndicator {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
visible: !podcastDetail.ready
|
visible: !page.ready
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
py.call('main.show_podcast', [podcast_id], function (podcast) {
|
py.call('main.show_podcast', [podcast_id], function (podcast) {
|
||||||
podcastDetail.title = podcast.title;
|
page.title = podcast.title;
|
||||||
podcastDetail.description = podcast.description;
|
page.description = podcast.description;
|
||||||
podcastDetail.link = podcast.link;
|
page.link = podcast.link;
|
||||||
podcastDetail.section = podcast.section;
|
page.section = podcast.section;
|
||||||
podcastDetail.coverart = podcast.coverart;
|
page.coverart = podcast.coverart;
|
||||||
podcastDetail.url = podcast.url;
|
page.url = podcast.url;
|
||||||
podcastDetail.ready = true;
|
page.ready = true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,7 +100,7 @@ SlidePage {
|
||||||
Column {
|
Column {
|
||||||
id: detailColumn
|
id: detailColumn
|
||||||
|
|
||||||
width: podcastDetail.width
|
width: page.width
|
||||||
spacing: Constants.layout.padding * pgst.scalef
|
spacing: Constants.layout.padding * pgst.scalef
|
||||||
|
|
||||||
Item { height: Constants.layout.padding * pgst.scalef; width: parent.width }
|
Item { height: Constants.layout.padding * pgst.scalef; width: parent.width }
|
||||||
|
@ -116,23 +116,22 @@ SlidePage {
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
id: coverImage
|
id: coverImage
|
||||||
source: podcastDetail.coverart
|
source: page.coverart
|
||||||
fillMode: Image.PreserveAspectFit
|
fillMode: Image.PreserveAspectFit
|
||||||
width: parent.width
|
width: parent.width
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PLabel {
|
SlidePageHeader {
|
||||||
text: podcastDetail.title
|
title: page.title
|
||||||
width: parent.width
|
width: parent.width
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
font.pixelSize: 35 * pgst.scalef
|
|
||||||
color: Constants.colors.highlight
|
color: Constants.colors.highlight
|
||||||
}
|
}
|
||||||
|
|
||||||
PLabel {
|
PLabel {
|
||||||
visible: text !== ''
|
visible: text !== ''
|
||||||
text: podcastDetail.link
|
text: page.link
|
||||||
width: parent.width
|
width: parent.width
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
font.pixelSize: 20 * pgst.scalef
|
font.pixelSize: 20 * pgst.scalef
|
||||||
|
@ -140,7 +139,7 @@ SlidePage {
|
||||||
}
|
}
|
||||||
|
|
||||||
PLabel {
|
PLabel {
|
||||||
text: 'Section: ' + podcastDetail.section
|
text: 'Section: ' + page.section
|
||||||
width: parent.width
|
width: parent.width
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
font.pixelSize: 20 * pgst.scalef
|
font.pixelSize: 20 * pgst.scalef
|
||||||
|
@ -148,7 +147,7 @@ SlidePage {
|
||||||
}
|
}
|
||||||
|
|
||||||
PLabel {
|
PLabel {
|
||||||
text: podcastDetail.description
|
text: page.description
|
||||||
width: parent.width
|
width: parent.width
|
||||||
font.pixelSize: 30 * pgst.scalef
|
font.pixelSize: 30 * pgst.scalef
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
|
|
|
@ -26,7 +26,8 @@ import 'icons/icons.js' as Icons
|
||||||
import 'common/constants.js' as Constants
|
import 'common/constants.js' as Constants
|
||||||
|
|
||||||
SlidePage {
|
SlidePage {
|
||||||
id: podcastsPage
|
id: page
|
||||||
|
|
||||||
canClose: false
|
canClose: false
|
||||||
|
|
||||||
hasMenuButton: true
|
hasMenuButton: true
|
||||||
|
|
|
@ -33,6 +33,7 @@ Rectangle {
|
||||||
property alias canClose: dragging.canClose
|
property alias canClose: dragging.canClose
|
||||||
property bool isDialog: false
|
property bool isDialog: false
|
||||||
|
|
||||||
|
property string title: ''
|
||||||
property bool hasMenuButton: false
|
property bool hasMenuButton: false
|
||||||
property string menuButtonLabel: 'Menu'
|
property string menuButtonLabel: 'Menu'
|
||||||
property string menuButtonIcon: Icons.vellipsis
|
property string menuButtonIcon: Icons.vellipsis
|
||||||
|
@ -49,6 +50,8 @@ Rectangle {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: parent.height - parent.bottomSpacing
|
height: parent.height - parent.bottomSpacing
|
||||||
|
|
||||||
|
y: platform.toolbarOnTop ? parent.bottomSpacing : 0
|
||||||
|
|
||||||
Stacking { id: stacking }
|
Stacking { id: stacking }
|
||||||
|
|
||||||
Dragging {
|
Dragging {
|
||||||
|
|
|
@ -27,9 +27,20 @@ Item {
|
||||||
id: slidePageHeader
|
id: slidePageHeader
|
||||||
property alias title: label.text
|
property alias title: label.text
|
||||||
property alias color: label.color
|
property alias color: label.color
|
||||||
|
property alias wrapMode: label.wrapMode
|
||||||
|
property bool isOnSlidePage: (typeof(page) !== 'undefined') ? page : null
|
||||||
|
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: Constants.layout.header.height * pgst.scalef
|
|
||||||
|
visible: !platform.titleInToolbar || !isOnSlidePage
|
||||||
|
height: visible ? (Constants.layout.header.height * pgst.scalef) : 0
|
||||||
|
|
||||||
|
Binding {
|
||||||
|
target: isOnSlidePage ? page : null
|
||||||
|
property: 'title'
|
||||||
|
value: slidePageHeader.title
|
||||||
|
when: platform.titleInToolbar
|
||||||
|
}
|
||||||
|
|
||||||
PLabel {
|
PLabel {
|
||||||
id: label
|
id: label
|
||||||
|
|
|
@ -22,3 +22,4 @@ var link = '\ue077';
|
||||||
var vellipsis = '\u22ee';
|
var vellipsis = '\u22ee';
|
||||||
var paperclip = '\ue08a';
|
var paperclip = '\ue08a';
|
||||||
var tag_fill = '\ue02b';
|
var tag_fill = '\ue02b';
|
||||||
|
var headphones = '\ue061';
|
||||||
|
|
BIN
touch/images/toolbarshadow-top.png
Normal file
BIN
touch/images/toolbarshadow-top.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 295 B |
Loading…
Add table
Add a link
Reference in a new issue