This commit is contained in:
Thomas Perl 2014-02-07 17:23:56 +01:00
parent 3d7128a421
commit 99cf0780c1
43 changed files with 239 additions and 182 deletions

View file

@ -27,10 +27,20 @@ var layout = {
var colors = {
download: '#8ae234', /* download green */
select: '#7f5785', /* gpodder dark purple */
fresh: '#cf65de', /* gpodder purple */
fresh: '#815c86', /* gpodder purple */
playback: '#729fcf', /* playback blue */
text: '#333333', /* text color */
placeholder: '#666666',
highlight: '#433b67',
secondaryHighlight: '#605885',
background: '#948db3',
area: '#cccccc',
secondaryBackground: '#d0cce1',
};
var font = 'Source Sans Pro';
var state = {
normal: 0,
downloaded: 1,

View file

@ -20,14 +20,18 @@
import QtQuick 2.0
import 'common/constants.js' as Constants
MouseArea {
id: mouseArea
property bool transparent: false
property bool canHighlight: true
Rectangle {
id: background
anchors.fill: parent
color: (mouseArea.pressed && mouseArea.canHighlight)?'#33ffffff':(mouseArea.transparent?'#00000000':'#88000000')
visible: parent.enabled
color: Constants.colors.area
opacity: (mouseArea.pressed && mouseArea.canHighlight) ? 1 : .5
visible: parent.enabled && ((mouseArea.canHighlight && mouseArea.pressed) || !mouseArea.transparent)
}
}

View file

@ -21,6 +21,8 @@
import QtQuick 2.0
import 'common/constants.js' as Constants
Item {
id: coverArt
@ -42,15 +44,15 @@ Item {
}
Rectangle {
opacity: 1 - cover.opacity
opacity: 0.3 * (1 - cover.opacity)
anchors.fill: cover
clip: true
color: '#11ffffff'
color: Constants.colors.background
PLabel {
text: coverArt.text[0]
color: '#55ffffff'
color: Constants.colors.highlight
anchors.centerIn: parent
font.pixelSize: parent.height * .8
}

View file

@ -27,6 +27,8 @@ SlidePage {
ListView {
anchors.fill: parent
boundsBehavior: Flickable.StopAtBounds
PScrollDecorator {}
model: GPodderDirectorySearchModel { id: directorySearchModel }

View file

@ -36,6 +36,7 @@ SlidePage {
Flickable {
id: flickable
anchors.fill: parent
boundsBehavior: Flickable.StopAtBounds
contentWidth: detailColumn.width
contentHeight: detailColumn.height + detailColumn.spacing

View file

@ -22,6 +22,7 @@ import QtQuick 2.0
import 'common/constants.js' as Constants
import 'common/util.js' as Util
import 'icons/icons.js' as Icons
Item {
id: episodeItem
@ -32,7 +33,7 @@ Item {
height: (opened ? 160 : 80) * pgst.scalef
Behavior on height { PropertyAnimation { duration: 100 } }
Rectangle {
Item {
clip: true
anchors {
left: parent.left
@ -40,7 +41,6 @@ Item {
bottom: parent.bottom
}
height: parent.height - 80 * pgst.scalef
color: '#66000000'
IconContextMenu {
height: parent.height
@ -48,7 +48,8 @@ Item {
IconMenuItem {
text: episodeItem.isPlaying ? 'Pause' : 'Play'
iconSource: 'icons/' + (episodeItem.isPlaying ? 'pause_24x32.png' : 'play_24x32.png')
color: titleLabel.color
icon: episodeItem.isPlaying ? Icons.pause : Icons.play
onClicked: {
if (episodeItem.isPlaying) {
player.pause();
@ -60,7 +61,8 @@ Item {
IconMenuItem {
text: 'Download'
iconSource: 'icons/cloud_download_32x32.png'
color: titleLabel.color
icon: Icons.cloud_download
visible: downloadState != Constants.state.downloaded
onClicked: {
episodeList.selectedIndex = -1;
@ -70,21 +72,24 @@ Item {
IconMenuItem {
text: 'Delete'
iconSource: 'icons/trash_stroke_32x32.png'
color: titleLabel.color
icon: Icons.trash
visible: downloadState != Constants.state.deleted
onClicked: py.call('main.delete_episode', [id]);
}
IconMenuItem {
id: toggleNew
color: titleLabel.color
text: 'Toggle New'
iconSource: 'icons/star_32x32.png'
icon: Icons.star
onClicked: Util.disableUntilReturn(toggleNew, py, 'main.toggle_new', [id]);
}
IconMenuItem {
text: 'Shownotes'
iconSource: 'icons/document_alt_stroke_24x32.png'
color: titleLabel.color
icon: Icons.article
onClicked: pgst.loadPage('EpisodeDetail.qml', {episode_id: id, title: title});
}
}
@ -93,8 +98,8 @@ Item {
ButtonArea {
id: episodeItemArea
opacity: canHighlight ? 1 : 0.2
canHighlight: (episodeList.selectedIndex == index) || (episodeList.selectedIndex == -1)
opacity: (canHighlight || episodeList.selectedIndex == index) ? 1 : 0.2
canHighlight: (episodeList.selectedIndex == -1)
onClicked: {
if (episodeList.selectedIndex == index) {
@ -109,7 +114,7 @@ Item {
Rectangle {
anchors.fill: parent
color: titleLabel.color
visible: (progress > 0) || isPlaying
visible: (progress > 0) || isPlaying || episodeItem.opened
opacity: 0.1
}
@ -133,7 +138,7 @@ Item {
height: parent.height * .2
width: parent.width * playbackProgress
color: Constants.colors.playback
color: titleLabel.color
opacity: episodeItem.isPlaying ? .6 : .2
}
@ -163,10 +168,12 @@ Item {
return Constants.colors.playback;
} else if (progress > 0) {
return Constants.colors.download;
} else if (episodeItem.opened) {
return Constants.colors.highlight;
} else if (isNew && downloadState != Constants.state.downloaded) {
return Constants.colors.fresh;
} else {
return 'white';
return Constants.colors.text;
}
}
@ -179,8 +186,9 @@ Item {
}
}
Image {
PIcon {
id: downloadedIcon
color: titleLabel.color
anchors {
right: parent.right
@ -189,7 +197,7 @@ Item {
}
visible: downloadState == Constants.state.downloaded
source: 'icons/cd_32x32.png'
icon: Icons.cd
}
}
}

View file

@ -22,6 +22,7 @@ import QtQuick 2.0
import 'common'
import 'common/util.js' as Util
import 'icons/icons.js' as Icons
SlidePage {
id: episodesPage
@ -38,7 +39,8 @@ SlidePage {
PullMenu {
PullMenuItem {
source: 'icons/play_24x32.png'
text: 'Now Playing'
icon: Icons.play
onClicked: {
pgst.loadPage('PlayerPage.qml');
episodesPage.unPull();
@ -46,7 +48,8 @@ SlidePage {
}
PullMenuItem {
source: 'icons/trash_stroke_32x32.png'
text: 'Unsubscribe'
icon: Icons.trash
onClicked: {
py.call('main.unsubscribe', [episodesPage.podcast_id]);
episodesPage.closePage();

View file

@ -20,13 +20,11 @@
import QtQuick 2.0
Rectangle {
Item {
id: contextMenu
default property alias children: contextMenuRow.children
height: 80 * pgst.scalef
color: '#33000000'
Row {
id: contextMenuRow
anchors.centerIn: parent

View file

@ -20,26 +20,34 @@
import QtQuick 2.0
import 'common/constants.js' as Constants
ButtonArea {
id: iconMenuItem
property alias text: label.text
property alias iconSource: icon.source
property color color: Constants.colors.secondaryHighlight
property alias icon: icon.icon
property bool alwaysShowText: false
transparent: true
canHighlight: false
height: 80 * pgst.scalef
width: height
Image {
PIcon {
id: icon
anchors.centerIn: parent
opacity: iconMenuItem.enabled ? 1 : .2
color: label.color
}
PLabel {
id: label
font.pixelSize: 15 * pgst.scalef
visible: parent.pressed
visible: parent.pressed || parent.alwaysShowText
color: parent.pressed ? Qt.darker(iconMenuItem.color, 1.1) : iconMenuItem.color
anchors {
bottom: icon.top

View file

@ -43,6 +43,7 @@ Item {
}
children[index-1].opacity = x / width;
//children[index-1].pushPhase = x / width;
}
property bool loadPageInProgress: false

View file

@ -20,31 +20,23 @@
import QtQuick 2.0
import 'icons/icons.js' as Icons
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'
PIcon {
anchors.centerIn: parent
icon: Icons.aperture
rotation: 180 * parent.phase
}
property real phase: 0
PropertyAnimation on phase {
loops: Animation.Infinite
duration: 2000
duration: 5000
running: parent.visible
from: 0
to: 2*Math.PI

36
touch/PIcon.qml Normal file
View file

@ -0,0 +1,36 @@
/**
*
* gPodder QML UI Reference Implementation
* Copyright (c) 2013, 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/constants.js' as Constants
import 'icons/icons.js' as Icons
PLabel {
id: picon
property int size: 48 * pgst.scalef
property string icon
text: icon
font.pixelSize: picon.size
font.family: Icons.font
}

View file

@ -20,8 +20,11 @@
import QtQuick 2.0
import 'common/constants.js' as Constants
Text {
font.pixelSize: 30 * pgst.scalef
color: 'white'
font.family: Constants.font
color: Constants.colors.text
}

View file

@ -26,7 +26,9 @@ ListView {
anchors.fill: parent
property string title
property real pushPhase: 0
boundsBehavior: Flickable.StopAtBounds
header: SlidePageHeader { title: pListView.title }
PScrollDecorator { flickable: pListView }

View file

@ -20,6 +20,8 @@
import QtQuick 2.0
import 'common/constants.js' as Constants
Rectangle {
property var flickable
@ -28,7 +30,7 @@ Rectangle {
width: 5 * pgst.scalef
height: flickable.visibleArea.heightRatio * flickable.height
visible: flickable.visibleArea.heightRatio < 1
color: '#ffffff'
opacity: flickable.moving ? .2 : 0
color: Constants.colors.background
opacity: flickable.moving ? 1 : 0
Behavior on opacity { PropertyAnimation { duration: 100 } }
}

View file

@ -20,13 +20,15 @@
import QtQuick 2.0
Rectangle {
import 'common/constants.js' as Constants
Item {
id: slider
property real value
property real min: 0.0
property real max: 1.0
property color fillColor: '#333333'
property color color: Constants.colors.highlight
property real displayedValue: mouseArea.pressed ? temporaryValue : value
property real temporaryValue
@ -34,7 +36,6 @@ Rectangle {
signal valueChangeRequested(real newValue)
clip: true
color: '#000000'
height: 50 * pgst.scalef
@ -51,28 +52,20 @@ Rectangle {
preventStealing: true
}
Rectangle {
anchors.fill: parent
color: slider.color
opacity: .3
}
Rectangle {
id: fillBackground
color: slider.fillColor
height: parent.height * 0.8
color: slider.color
height: parent.height
width: parent.width * (parent.displayedValue - parent.min) / (parent.max - parent.min)
anchors {
verticalCenter: parent.verticalCenter
}
}
Rectangle {
height: parent.height * 0.9
width: height
radius: width / 2
color: Qt.lighter(slider.fillColor, 1.5)
anchors {
verticalCenter: parent.verticalCenter
left: fillBackground.right
leftMargin: -(width / 2)
}
}
}

View file

@ -20,32 +20,34 @@
import QtQuick 2.0
Rectangle {
import 'common/constants.js' as Constants
Item {
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'
color: Constants.colors.text
selectionColor: Constants.colors.background
id: textInput
font.pixelSize: height
font.family: placeholder.font.family
}
Text {
PLabel {
id: placeholder
anchors.fill: textInput
visible: !textInput.focus && (textInput.text == '')
text: textField.placeholderText
color: '#aaa'
color: Constants.colors.placeholder
font.pixelSize: textInput.font.pixelSize
}
}

View file

@ -22,6 +22,7 @@ import QtQuick 2.0
import 'common/util.js' as Util
import 'common/constants.js' as Constants
import 'icons/icons.js' as Icons
SlidePage {
id: playerPage
@ -29,6 +30,7 @@ SlidePage {
Flickable {
id: flickable
anchors.fill: parent
boundsBehavior: Flickable.StopAtBounds
contentWidth: column.width
contentHeight: column.height + column.spacing
@ -41,6 +43,7 @@ SlidePage {
SlidePageHeader {
title: 'Now playing'
color: Constants.colors.playback
}
Column {
@ -61,46 +64,6 @@ SlidePage {
}
}
IconContextMenu {
width: parent.width
IconMenuItem {
text: player.isPlaying ? 'Pause' : 'Play'
iconSource: 'icons/' + (player.isPlaying ? 'pause_24x32.png' : 'play_24x32.png')
onClicked: {
if (player.isPlaying) {
player.pause();
} else {
player.play();
}
}
}
IconMenuItem {
text: '-1m'
iconSource: 'icons/first_32x32.png'
onClicked: player.seekAndSync(player.position - 60 * 1000);
}
IconMenuItem {
text: '-10s'
iconSource: 'icons/arrow_left_32x32.png'
onClicked: player.seekAndSync(player.position - 10 * 1000);
}
IconMenuItem {
text: '+10s'
iconSource: 'icons/arrow_right_32x32.png'
onClicked: player.seekAndSync(player.position + 10 * 1000);
}
IconMenuItem {
text: '+1m'
iconSource: 'icons/last_32x32.png'
onClicked: player.seekAndSync(player.position + 60 * 1000);
}
}
PLabel {
anchors.horizontalCenter: parent.horizontalCenter
text: Util.formatPosition(slider.displayedValue/1000, player.duration/1000)
@ -112,11 +75,56 @@ SlidePage {
value: player.position
min: 0
max: player.duration
fillColor: Constants.colors.playback
color: Constants.colors.playback
onValueChangeRequested: {
player.seekAndSync(newValue);
}
}
IconContextMenu {
width: parent.width
IconMenuItem {
text: player.isPlaying ? 'Pause' : 'Play'
color: Constants.colors.playback
icon: player.isPlaying ? Icons.pause : Icons.play
onClicked: {
if (player.isPlaying) {
player.pause();
} else {
player.play();
}
}
}
IconMenuItem {
text: '-1m'
color: Constants.colors.playback
icon: Icons.first
onClicked: player.seekAndSync(player.position - 60 * 1000);
}
IconMenuItem {
text: '-10s'
color: Constants.colors.playback
icon: Icons.arrow_left
onClicked: player.seekAndSync(player.position - 10 * 1000);
}
IconMenuItem {
text: '+10s'
color: Constants.colors.playback
icon: Icons.arrow_right
onClicked: player.seekAndSync(player.position + 10 * 1000);
}
IconMenuItem {
text: '+1m'
color: Constants.colors.playback
icon: Icons.last
onClicked: player.seekAndSync(player.position + 60 * 1000);
}
}
}
}

View file

@ -22,6 +22,7 @@ import QtQuick 2.0
import 'common'
import 'common/util.js' as Util
import 'icons/icons.js' as Icons
SlidePage {
id: podcastsPage
@ -29,7 +30,8 @@ SlidePage {
PullMenu {
PullMenuItem {
source: 'icons/play_24x32.png'
text: 'Now Playing'
icon: Icons.play
onClicked: {
pgst.loadPage('PlayerPage.qml');
podcastsPage.unPull();
@ -37,7 +39,8 @@ SlidePage {
}
PullMenuItem {
source: 'icons/reload_24x28.png'
text: 'Refresh feeds'
icon: Icons.reload
onClicked: {
podcastsPage.unPull();
py.call('main.check_for_episodes');
@ -45,7 +48,8 @@ SlidePage {
}
PullMenuItem {
source: 'icons/plus_32x32.png'
text: 'Subscribe'
icon: Icons.plus
onClicked: {
pgst.loadPage('Subscribe.qml');
podcastsPage.unPull();

View file

@ -20,6 +20,8 @@
import QtQuick 2.0
import 'common/constants.js' as Constants
MouseArea {
id: pullMenu
default property alias items: pullMenuColumn.children
@ -31,10 +33,6 @@ MouseArea {
Column {
id: pullMenuColumn
anchors.fill: parent
spacing: (width - 72 * pgst.scalef) / 2
Item { width: 1; height: 1 }
}
}

View file

@ -20,17 +20,14 @@
import QtQuick 2.0
ButtonArea {
import 'common/constants.js' as Constants
IconMenuItem {
id: pullMenuItem
property alias source: img.source
alwaysShowText: true
width: 72 * pgst.scalef
height: 72 * pgst.scalef
Image {
id: img
anchors.centerIn: parent
}
width: parent.width
height: width
anchors.horizontalCenter: parent.horizontalCenter
}

View file

@ -20,6 +20,8 @@
import QtQuick 2.0
import 'common/constants.js' as Constants
Item {
property alias text: pLabel.text
@ -33,7 +35,7 @@ Item {
margins: 10 * pgst.scalef
}
color: '#aaa'
color: Constants.colors.secondaryHighlight
}
}

View file

@ -23,10 +23,8 @@ import QtQuick 2.0
SlidePage {
SlidePageHeader { title: 'Settings' }
Text {
PLabel {
anchors.centerIn: parent
color: 'white'
font.pixelSize: 50 * pgst.scalef
text: 'TODO'
}
}

View file

@ -22,7 +22,7 @@ import QtQuick 2.0
Rectangle {
id: page
color: '#88000000'
color: 'white'
default property alias children: dragging.children
property alias hasPull: dragging.hasPull
@ -52,10 +52,10 @@ Rectangle {
}
Rectangle {
color: 'black'
color: '#ffffff'
anchors.fill: parent
opacity: page.pullPhase * 0.8
opacity: page.pullPhase * 0.9
MouseArea {
enabled: parent.opacity > 0
@ -72,19 +72,6 @@ Rectangle {
}
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
opacity: .1
}
}

View file

@ -24,24 +24,14 @@ import 'common/constants.js' as Constants
Item {
id: slidePageHeader
property string title
property alias title: label.text
property alias color: label.color
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 {
PLabel {
id: label
anchors {
left: parent.left
right: parent.right
@ -50,11 +40,10 @@ Item {
verticalCenter: parent.verticalCenter
}
color: 'white'
color: Constants.colors.highlight
horizontalAlignment: Text.AlignRight
font.pixelSize: parent.height * .4
elide: Text.ElideRight
text: parent.title
}
}

View file

@ -20,6 +20,8 @@
import QtQuick 2.0
import 'icons/icons.js' as Icons
SlidePage {
id: startPage
canClose: false
@ -44,6 +46,7 @@ SlidePage {
Flickable {
id: flickable
boundsBehavior: Flickable.StopAtBounds
Connections {
target: py
@ -96,9 +99,9 @@ SlidePage {
width: subscriptions.width + 2*subscriptions.anchors.margins
height: subscriptions.height + 2*subscriptions.anchors.margins
Image {
PIcon {
id: subscriptions
source: 'icons/plus_32x32.png'
icon: Icons.plus
anchors {
bottom: parent.bottom
@ -158,9 +161,9 @@ SlidePage {
width: refresher.width + 2*refresher.anchors.margins
height: refresher.height + 2*refresher.anchors.margins
Image {
PIcon {
id: refresher
source: 'icons/reload_24x28.png'
icon: Icons.reload
anchors {
bottom: parent.bottom

Binary file not shown.

View file

@ -20,21 +20,10 @@
import QtQuick 2.0
Rectangle {
color: '#336688'
color: 'white'
width: 480
height: 800
Image {
anchors.fill: parent
source: 'images/mask.png'
}
Image {
anchors.fill: parent
source: 'images/noise.png'
fillMode: Image.Tile
}
Main {}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 239 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 270 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 394 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 436 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 214 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 271 B

BIN
touch/icons/iconic_fill.ttf Normal file

Binary file not shown.

15
touch/icons/icons.js Normal file
View file

@ -0,0 +1,15 @@
var font = 'Iconic';
var trash = '\ue05a';
var cd = '\ue064';
var play = '\ue047';
var reload = '\ue030';
var plus = '\u2795';
var pause = '\ue049';
var cloud_download = '\ue044';
var star = '\u2605';
var article = '\ue053';
var first = '\ue04c';
var arrow_left = '\u2190';
var arrow_right = '\u2192';
var last = '\ue04d';
var aperture = '\ue026';

Binary file not shown.

Before

Width:  |  Height:  |  Size: 281 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 146 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 217 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 161 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 357 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 378 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 291 B