mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-08-31 09:32:03 +02:00
some more work on stations
This commit is contained in:
82
data/qml/CoverFlip.qml
Normal file
82
data/qml/CoverFlip.qml
Normal file
@@ -0,0 +1,82 @@
|
||||
import QtQuick 1.1
|
||||
import tomahawk 1.0
|
||||
import "tomahawkimports"
|
||||
|
||||
PathView {
|
||||
id: coverView
|
||||
|
||||
// The start coordinates for the covers
|
||||
// Default is left, centered in height
|
||||
property int pathStartX: coverSize
|
||||
property int pathStartY: height / 2
|
||||
|
||||
// The size of the covers in the path
|
||||
property int coverSize: 100
|
||||
|
||||
// emitted when a cover is clicked
|
||||
signal itemClicked(int index)
|
||||
|
||||
// emitted when a cover is clicked
|
||||
signal itemPlayPauseClicked(int index)
|
||||
|
||||
preferredHighlightBegin: 0.2 // scene.width / 11000
|
||||
preferredHighlightEnd: preferredHighlightBegin
|
||||
pathItemCount: 5
|
||||
//highlightMoveDuration: 500
|
||||
|
||||
delegate: CoverImage {
|
||||
height: root.coverSize
|
||||
width: root.coverSize
|
||||
|
||||
showLabels: true
|
||||
showMirror: true
|
||||
artistName: model.artistName
|
||||
trackName: model.trackName
|
||||
artworkId: model.coverID
|
||||
showPlayButton: true
|
||||
currentyPlayed: mode.itemFromIndex(index).isPlaying
|
||||
|
||||
scale: PathView.itemScale
|
||||
itemBrightness: PathView.itemBrightness
|
||||
opacity: PathView.itemOpacity
|
||||
z: -x
|
||||
|
||||
onPlayClicked: {
|
||||
coverView.itemPlayPauseClicked(index)
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
coverView.itemClicked(index)
|
||||
}
|
||||
}
|
||||
|
||||
path: Path {
|
||||
startX: coverView.pathStartX
|
||||
startY: coverView.pathStartY
|
||||
|
||||
PathAttribute { name: "itemOpacity"; value: 1 }
|
||||
PathAttribute { name: "itemBrightness"; value: 1 }
|
||||
PathAttribute { name: "itemScale"; value: 1 }
|
||||
// PathLine { x: coverView.pathStartX * 0.9 ; y: coverView.pathStartY * 0.9 }
|
||||
// PathPercent { value: .2 }
|
||||
// PathAttribute { name: "itemOpacity"; value: 1 }
|
||||
// PathAttribute { name: "itemBrightness"; value: 1 }
|
||||
// PathAttribute { name: "itemScale"; value: 1 }
|
||||
// PathLine { x: coverView.pathStartX * .5; y: coverView.pathStartY * .5}
|
||||
// PathPercent { value: .3 }
|
||||
// PathAttribute { name: "itemOpacity"; value: 1 }
|
||||
// PathAttribute { name: "itemBrightness"; value: 1 }
|
||||
// PathAttribute { name: "itemScale"; value: 0.5 }
|
||||
// // PathLine { x: coverView.pathStartX * .25 ; y: coverView.pathStartY * .25 }
|
||||
// // PathPercent { value: .75 }
|
||||
// // PathAttribute { name: "itemOpacity"; value: 1 }
|
||||
// // PathAttribute { name: "itemBrightness"; value: .5 }
|
||||
// // PathAttribute { name: "itemScale"; value: 0.4 }
|
||||
PathLine { x: root.width; y: 0 }
|
||||
PathPercent { value: 1 }
|
||||
PathAttribute { name: "itemOpacity"; value: 1 }
|
||||
PathAttribute { name: "itemBrightness"; value: 0 }
|
||||
PathAttribute { name: "itemScale"; value: 0.1 }
|
||||
}
|
||||
|
||||
}
|
@@ -5,8 +5,13 @@ Item {
|
||||
|
||||
// Should the artist + track labels be painted
|
||||
property bool showLabels: true
|
||||
|
||||
// Should the play button be painted on mouse hover?
|
||||
property bool showPlayButton: false
|
||||
|
||||
// if this is true, the play button will be swapped by a pause button
|
||||
property bool currentyPlayed: false
|
||||
|
||||
// Should the mirror be painted?
|
||||
property bool showMirror: false
|
||||
|
||||
@@ -57,31 +62,35 @@ Item {
|
||||
source: "image://albumart/" + artworkId
|
||||
}
|
||||
|
||||
|
||||
Rectangle {
|
||||
id: textBackground
|
||||
anchors { left: parent.left; right: parent.right; bottom: parent.bottom }
|
||||
height: 32
|
||||
anchors.margins: 5
|
||||
color: "black"
|
||||
opacity: showLabels ? 0.5 : 0
|
||||
height: (artistText.height + trackText.height) * 2
|
||||
opacity: 1// showLabels ? 1 : 0
|
||||
radius: 3
|
||||
gradient: Gradient {
|
||||
GradientStop { position: 0.0; color: "#00000000" }
|
||||
GradientStop { position: 0.5; color: "black" }
|
||||
GradientStop { position: 1.0; color: "black" }
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
id: trackText
|
||||
color: "white"
|
||||
font.bold: true
|
||||
text: trackName
|
||||
anchors { left: textBackground.left; right: textBackground.right; top: textBackground.top }
|
||||
anchors { left: parent.left; right: parent.right; bottom: artistText.top }
|
||||
anchors.margins: 2
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
elide: Text.ElideRight
|
||||
opacity: showLabels ? 1 : 0
|
||||
}
|
||||
Text {
|
||||
id: artistText
|
||||
color: "white"
|
||||
text: artistName
|
||||
anchors { left: textBackground.left; right: textBackground.right; bottom: textBackground.bottom }
|
||||
anchors { left: parent.left; right: parent.right; bottom: parent.bottom }
|
||||
anchors.margins: 2
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
elide: Text.ElideRight
|
||||
@@ -144,7 +153,7 @@ Item {
|
||||
Image {
|
||||
id: playButton
|
||||
visible: showPlayButton ? mouseArea.containsMouse : false
|
||||
source: "../images/play-rest.png"
|
||||
source: currentyPlayed ? "../images/pause-rest.png" : "../images/play-rest.png"
|
||||
anchors.centerIn: parent
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
|
@@ -6,7 +6,7 @@ Rectangle {
|
||||
id: scene
|
||||
color: "black"
|
||||
anchors.fill: parent
|
||||
state: echonestStation.configured ? "list" : "configure"
|
||||
state: "list"
|
||||
|
||||
ListModel {
|
||||
id: styleModel
|
||||
@@ -48,79 +48,79 @@ Rectangle {
|
||||
id: stationVisualModel
|
||||
|
||||
|
||||
Column {
|
||||
height: scene.height
|
||||
width: scene.width
|
||||
// Column {
|
||||
// height: scene.height
|
||||
// width: scene.width
|
||||
|
||||
Row {
|
||||
height: scene.height / 2
|
||||
width: scene.width
|
||||
spacing: width * .1
|
||||
// Row {
|
||||
// height: scene.height / 2
|
||||
// width: scene.width
|
||||
// spacing: width * .1
|
||||
|
||||
Item {
|
||||
height: parent.height
|
||||
width: (parent.width - orText.width - parent.spacing * 2 ) * 2 / 3
|
||||
GridView {
|
||||
id: gridView
|
||||
anchors.fill: parent
|
||||
anchors.margins: cellWidth / 2
|
||||
model: dummyArtistModel
|
||||
// Item {
|
||||
// height: parent.height
|
||||
// width: (parent.width - orText.width - parent.spacing * 2 ) * 2 / 3
|
||||
// GridView {
|
||||
// id: gridView
|
||||
// anchors.fill: parent
|
||||
// anchors.margins: cellWidth / 2
|
||||
// model: dummyArtistModel
|
||||
|
||||
cellWidth: gridView.width / 4 - 1 // -1 to make sure there is space for 4 items even with rounding error
|
||||
cellHeight: cellWidth
|
||||
// cellWidth: gridView.width / 4 - 1 // -1 to make sure there is space for 4 items even with rounding error
|
||||
// cellHeight: cellWidth
|
||||
|
||||
delegate: Item {
|
||||
height: gridView.cellHeight * .9
|
||||
width: height
|
||||
// delegate: Item {
|
||||
// height: gridView.cellHeight * .9
|
||||
// width: height
|
||||
|
||||
CoverImage {
|
||||
artistName: modelData
|
||||
anchors.fill: parent
|
||||
// CoverImage {
|
||||
// artistName: modelData
|
||||
// anchors.fill: parent
|
||||
|
||||
onClicked: {
|
||||
echonestStation.setMainControl( EchonestStation.StationTypeArtist, modelData );
|
||||
stationListView.incrementCurrentIndex();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// onClicked: {
|
||||
// echonestStation.setMainControl( EchonestStation.StationTypeArtist, modelData );
|
||||
// stationListView.incrementCurrentIndex();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
// }
|
||||
|
||||
Row {
|
||||
height: scene.height / 2
|
||||
width: scene.width * .9
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
spacing: width * .1
|
||||
// Row {
|
||||
// height: scene.height / 2
|
||||
// width: scene.width * .9
|
||||
// anchors.horizontalCenter: parent.horizontalCenter
|
||||
// spacing: width * .1
|
||||
|
||||
TagCloud {
|
||||
height: parent.height
|
||||
width: (parent.width - orText.width - parent.spacing * 2 ) * 2 / 3
|
||||
model: styleModel//generator.styles()
|
||||
opacity: echonestStation.configured ? 0 : 1
|
||||
// TagCloud {
|
||||
// height: parent.height
|
||||
// width: (parent.width - orText.width - parent.spacing * 2 ) * 2 / 3
|
||||
// model: styleModel//generator.styles()
|
||||
// opacity: echonestStation.configured ? 0 : 1
|
||||
|
||||
onTagClicked: {
|
||||
echonestStation.setMainControl( EchonestStation.StationTypeStyle, item );
|
||||
stationListView.incrementCurrentIndex();
|
||||
}
|
||||
// onTagClicked: {
|
||||
// echonestStation.setMainControl( EchonestStation.StationTypeStyle, item );
|
||||
// stationListView.incrementCurrentIndex();
|
||||
// }
|
||||
|
||||
Behavior on opacity {
|
||||
NumberAnimation { duration: 300 }
|
||||
}
|
||||
}
|
||||
Text {
|
||||
id: orText
|
||||
text: "or"
|
||||
color: "white"
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
InputField {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: (parent.width - orText.width - parent.spacing * 2 ) * 1 / 3
|
||||
}
|
||||
}
|
||||
}
|
||||
// Behavior on opacity {
|
||||
// NumberAnimation { duration: 300 }
|
||||
// }
|
||||
// }
|
||||
// Text {
|
||||
// id: orText
|
||||
// text: "or"
|
||||
// color: "white"
|
||||
// anchors.verticalCenter: parent.verticalCenter
|
||||
// }
|
||||
// InputField {
|
||||
// anchors.verticalCenter: parent.verticalCenter
|
||||
// width: (parent.width - orText.width - parent.spacing * 2 ) * 1 / 3
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
StationView {
|
||||
coverSize: Math.min(scene.height, scene.width) / 2
|
||||
@@ -147,12 +147,12 @@ Rectangle {
|
||||
orientation: ListView.Horizontal
|
||||
model: stationVisualModel
|
||||
interactive: false
|
||||
highlightMoveDuration: 400
|
||||
//highlightMoveDuration: 400
|
||||
|
||||
Component.onCompleted: {
|
||||
if ( echonestStation.configured ) {
|
||||
currentIndex = 1
|
||||
}
|
||||
}
|
||||
// currentIndex: 1
|
||||
|
||||
// Component.onCompleted: {
|
||||
// currentIndex = 1
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
@@ -8,79 +8,24 @@ Item {
|
||||
|
||||
signal configure()
|
||||
|
||||
PathView {
|
||||
|
||||
CoverFlip {
|
||||
id: coverView
|
||||
anchors.fill: parent
|
||||
anchors.rightMargin: parent.width / 3
|
||||
|
||||
preferredHighlightBegin: 0.2 // scene.width / 11000
|
||||
preferredHighlightEnd: preferredHighlightBegin
|
||||
pathItemCount: 5
|
||||
//highlightMoveDuration: 500
|
||||
anchors.leftMargin: parent.width / 2
|
||||
|
||||
model: dynamicModel
|
||||
currentIndex: currentlyPlayedIndex
|
||||
|
||||
property int pathStartX: width / 2
|
||||
property int pathStartY: height / 2
|
||||
|
||||
delegate: CoverImage {
|
||||
height: root.coverSize
|
||||
width: root.coverSize
|
||||
|
||||
showLabels: false
|
||||
showMirror: true
|
||||
//artistName: model.artistName
|
||||
//trackName: model.trackName
|
||||
artworkId: model.coverID
|
||||
|
||||
scale: PathView.itemScale
|
||||
itemBrightness: PathView.itemBrightness
|
||||
opacity: PathView.itemOpacity
|
||||
z: x
|
||||
|
||||
onClicked: {
|
||||
if ( currentlyPlayedIndex !==-1 ) {
|
||||
echonestStation.playItem( index )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
path: Path {
|
||||
startX: coverView.pathStartX
|
||||
startY: coverView.pathStartY
|
||||
|
||||
PathAttribute { name: "itemOpacity"; value: 0 }
|
||||
PathAttribute { name: "itemBrightness"; value: 0 }
|
||||
PathAttribute { name: "itemScale"; value: 1.5 }
|
||||
PathLine { x: coverView.pathStartX * 0.9 ; y: coverView.pathStartY * 0.9 }
|
||||
PathPercent { value: .2 }
|
||||
PathAttribute { name: "itemOpacity"; value: 1 }
|
||||
PathAttribute { name: "itemBrightness"; value: 1 }
|
||||
PathAttribute { name: "itemScale"; value: 1 }
|
||||
PathLine { x: coverView.pathStartX * .5; y: coverView.pathStartY * .5}
|
||||
PathPercent { value: .3 }
|
||||
PathAttribute { name: "itemOpacity"; value: 1 }
|
||||
PathAttribute { name: "itemBrightness"; value: 1 }
|
||||
PathAttribute { name: "itemScale"; value: 0.5 }
|
||||
// PathLine { x: coverView.pathStartX * .25 ; y: coverView.pathStartY * .25 }
|
||||
// PathPercent { value: .75 }
|
||||
// PathAttribute { name: "itemOpacity"; value: 1 }
|
||||
// PathAttribute { name: "itemBrightness"; value: .5 }
|
||||
// PathAttribute { name: "itemScale"; value: 0.4 }
|
||||
PathLine { x: 0; y: 0 }
|
||||
PathPercent { value: 1 }
|
||||
PathAttribute { name: "itemOpacity"; value: 1 }
|
||||
PathAttribute { name: "itemBrightness"; value: 0 }
|
||||
PathAttribute { name: "itemScale"; value: 0.1 }
|
||||
onItemPlayPauseClicked: {
|
||||
rootView.playItem(index)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Item {
|
||||
anchors { top: parent.top; right: parent.right; bottom: parent.bottom }
|
||||
anchors { top: parent.top; left: parent.left; bottom: parent.bottom }
|
||||
anchors.margins: 50
|
||||
width: scene.width / 3
|
||||
width: scene.width / 2
|
||||
|
||||
Column {
|
||||
anchors { left: parent.left; top: parent.top; right: parent.right }
|
||||
|
@@ -171,5 +171,6 @@
|
||||
<file>data/qml/tomahawkimports/InputField.qml</file>
|
||||
<file>data/qml/tomahawkimports/Button.qml</file>
|
||||
<file>data/qml/tomahawkimports/DoubleSlider.qml</file>
|
||||
<file>data/qml/CoverFlip.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
@@ -33,6 +33,7 @@ Q_OBJECT
|
||||
Q_PROPERTY(QString name READ name NOTIFY dataChanged)
|
||||
Q_PROPERTY(QString artistName READ artistName NOTIFY dataChanged)
|
||||
Q_PROPERTY(QString albumName READ albumName NOTIFY dataChanged)
|
||||
Q_PROPERTY(bool isPlaying READ isPlaying NOTIFY dataChanged)
|
||||
public:
|
||||
~PlayableItem();
|
||||
|
||||
|
@@ -167,6 +167,17 @@ EchonestGenerator::generate( int number )
|
||||
// qWarning() << "Got invalid controls!" << e.what();
|
||||
// emit error( "Filters are not valid", e.what() );
|
||||
// }
|
||||
|
||||
|
||||
QList< query_ptr > queries;
|
||||
queries << Query::get("Colour Haze", "All", QString(), uuid(), true);
|
||||
queries << Query::get("Colour Haze", "Sun", QString(), uuid(), true);
|
||||
queries << Query::get("Colour Haze", "Zen", QString(), uuid(), true);
|
||||
queries << Query::get("Colour Haze", "Outside", QString(), uuid(), true);
|
||||
queries << Query::get("Colour Haze", "Dirt", QString(), uuid(), true);
|
||||
|
||||
emit generated( queries );
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@@ -42,8 +42,6 @@ DynamicQmlWidget::DynamicQmlWidget( const dynplaylist_ptr& playlist, QWidget* pa
|
||||
|
||||
m_model->loadPlaylist( m_playlist );
|
||||
|
||||
// Initially seed the playlist
|
||||
m_playlist->generator()->generate( 20 );
|
||||
|
||||
qDebug() << "###got" << m_playlist->generator()->controls().size() << "controls";
|
||||
|
||||
@@ -55,6 +53,7 @@ DynamicQmlWidget::DynamicQmlWidget( const dynplaylist_ptr& playlist, QWidget* pa
|
||||
|
||||
rootContext()->setContextProperty( "dynamicModel", m_proxyModel );
|
||||
rootContext()->setContextProperty( "generator", m_playlist->generator().data() );
|
||||
rootContext()->setContextProperty( "rootView", this );
|
||||
|
||||
setSource( QUrl( "qrc" RESPATH "qml/StationScene.qml" ) );
|
||||
|
||||
@@ -67,6 +66,9 @@ DynamicQmlWidget::DynamicQmlWidget( const dynplaylist_ptr& playlist, QWidget* pa
|
||||
connect( AudioEngine::instance(), SIGNAL( started( Tomahawk::result_ptr ) ), this, SLOT( trackStarted() ) );
|
||||
connect( AudioEngine::instance(), SIGNAL( playlistChanged( Tomahawk::playlistinterface_ptr ) ), this, SLOT( playlistChanged( Tomahawk::playlistinterface_ptr ) ) );
|
||||
|
||||
// Initially seed the playlist
|
||||
m_playlist->generator()->generate( 20 );
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -114,6 +116,17 @@ playlist_ptr DynamicQmlWidget::playlist() const
|
||||
return m_model->playlist();
|
||||
}
|
||||
|
||||
void DynamicQmlWidget::playItem(int index)
|
||||
{
|
||||
qDebug() << "playItem called for cover" << index;
|
||||
AudioEngine::instance()->playItem( m_proxyModel->playlistInterface(), m_proxyModel->itemFromIndex( index )->result() );
|
||||
}
|
||||
|
||||
void DynamicQmlWidget::pause()
|
||||
{
|
||||
AudioEngine::instance()->pause();
|
||||
}
|
||||
|
||||
void DynamicQmlWidget::currentItemChanged( const QPersistentModelIndex ¤tIndex )
|
||||
{
|
||||
rootContext()->setContextProperty( "currentlyPlayedIndex", m_proxyModel->mapFromSource( currentIndex ).row() );
|
||||
|
@@ -54,6 +54,10 @@ public:
|
||||
|
||||
playlist_ptr playlist() const;
|
||||
|
||||
public slots:
|
||||
void playItem(int index);
|
||||
void pause();
|
||||
|
||||
private slots:
|
||||
void currentItemChanged( const QPersistentModelIndex ¤tIndex );
|
||||
void tracksGenerated( const QList< Tomahawk::query_ptr>& queries );
|
||||
|
Reference in New Issue
Block a user