From 52d5dbaf4d09a839c26a58b177d96ac44b77b999 Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Wed, 25 Jul 2012 22:05:39 +0200 Subject: [PATCH] some more work on the stations --- data/qml/StationConfig.qml | 13 +++++ data/qml/StationView.qml | 8 +-- data/qml/tomahawkimports/DoubleSlider.qml | 28 ++++++++-- .../playlist/PlayableProxyModel.cpp | 2 +- .../dynamic/echonest/EchonestGenerator.cpp | 2 + .../dynamic/echonest/EchonestStation.cpp | 51 ++++++++++++++++++- .../dynamic/echonest/EchonestStation.h | 13 ++++- .../dynamic/widgets/DynamicQmlWidget.cpp | 16 ------ 8 files changed, 105 insertions(+), 28 deletions(-) diff --git a/data/qml/StationConfig.qml b/data/qml/StationConfig.qml index fd62e333a..d6f0ce11d 100644 --- a/data/qml/StationConfig.qml +++ b/data/qml/StationConfig.qml @@ -40,6 +40,11 @@ Item { DoubleSlider { width: 500 height: tempoText.height + min: 0 + max: 500 + lowerSliderPos: echonestStation.minTempo + upperSliderPos: echonestStation.maxTempo + onValueChanged: echonestStation.setTempo( lowerSliderPos, upperSliderPos ) } Text { @@ -50,6 +55,14 @@ Item { DoubleSlider { width: 500 height: hotnessText.height + min: 0 + max: 100 + minLabel: "Less" + maxLabel: "More" + showFloatingLabel: false + lowerSliderPos: echonestStation.minHotttness * 100 + upperSliderPos: echonestStation.maxHotttness * 100 + onValueChanged: echonestStation.setHotttness( 1.0 * lowerSliderPos / 100, 1.0 * upperSliderPos / 100 ) } } diff --git a/data/qml/StationView.qml b/data/qml/StationView.qml index 5f4677c1d..ee413fc0d 100644 --- a/data/qml/StationView.qml +++ b/data/qml/StationView.qml @@ -19,7 +19,7 @@ Item { //highlightMoveDuration: 500 model: dynamicModel - currentIndex: currentlyPlayedIndex >= 0 ? currentlyPlayedIndex : 0 + currentIndex: currentlyPlayedIndex property int pathStartX: width / 2 property int pathStartY: height / 2 @@ -155,21 +155,21 @@ Item { font.pointSize: 16 width: parent.width elide: Text.ElideRight - text: coverView.model.itemFromIndex( currentlyPlayedIndex ).name + text: currentlyPlayedIndex > -1 ? coverView.model.itemFromIndex( currentlyPlayedIndex ).name : "" } Text { color: "white" font.pointSize: 14 width: parent.width elide: Text.ElideRight - text: coverView.model.itemFromIndex( currentlyPlayedIndex ).artistName + text: currentlyPlayedIndex > -1 ? coverView.model.itemFromIndex( currentlyPlayedIndex ).artistName : "" } Text { color: "white" font.pointSize: 14 width: parent.width elide: Text.ElideRight - text: coverView.model.itemFromIndex( currentlyPlayedIndex ).albumName + text: currentlyPlayedIndex > -1 ? coverView.model.itemFromIndex( currentlyPlayedIndex ).albumName : "" } } } diff --git a/data/qml/tomahawkimports/DoubleSlider.qml b/data/qml/tomahawkimports/DoubleSlider.qml index f03f66898..b1dc522cc 100644 --- a/data/qml/tomahawkimports/DoubleSlider.qml +++ b/data/qml/tomahawkimports/DoubleSlider.qml @@ -8,16 +8,27 @@ Item { property int min: 0 property int max: 100 + /** The labels next to the slider + * if empty, min and max values are used + */ + property string minLabel: "" + property string maxLabel: "" + + /** Should the floating label indicating the current position be shown? */ + property bool showFloatingLabel: true + property int lowerSliderPos: 25 property int upperSliderPos: 75 + signal valueChanged() + Row { anchors.fill: parent spacing: 10 Text { id: minText - text: min + text: root.minLabel.length > 0 ? root.minLabel : min color: "white" } @@ -60,7 +71,7 @@ Item { color: "white" anchors.bottom: lowerSlider.top anchors.bottomMargin: 10 - visible: lowerSliderMouseArea.pressed + visible: root.showFloatingLabel && lowerSliderMouseArea.pressed width: lowerFloatingText.width * 1.2 height: lowerFloatingText.height + height * 1.2 x: -(width - lowerSlider.width) / 2 @@ -80,6 +91,10 @@ Item { drag.axis: "XAxis" drag.minimumX: 0 drag.maximumX: upperSlider.x - lowerSlider.width + onReleased: { + root.lowerSliderPos = sliderRect.sliderPosToValue( lowerSlider.x ); + root.valueChanged(); + } } Rectangle { @@ -96,7 +111,7 @@ Item { color: "white" anchors.bottom: upperSlider.top anchors.bottomMargin: 10 - visible: upperSliderMouseArea.pressed + visible: root.showFloatingLabel && upperSliderMouseArea.pressed width: upperFloatingText.width * 1.2 height: upperFloatingText.height + height * 1.2 radius: height / 4 @@ -118,13 +133,18 @@ Item { drag.axis: "XAxis" drag.minimumX: lowerSlider.x + lowerSlider.width drag.maximumX: parent.width - upperSlider.width + onReleased: { + root.upperSliderPos = sliderRect.sliderPosToValue( upperSlider.x ); + root.valueChanged(); + } + } } Text { id: maxText - text: max + text: root.maxLabel.length > 0 ? root.maxLabel : max color: "white" } } diff --git a/src/libtomahawk/playlist/PlayableProxyModel.cpp b/src/libtomahawk/playlist/PlayableProxyModel.cpp index 9600343e9..5fb8b63fe 100644 --- a/src/libtomahawk/playlist/PlayableProxyModel.cpp +++ b/src/libtomahawk/playlist/PlayableProxyModel.cpp @@ -587,7 +587,7 @@ PlayableProxyModel::setFilter( const QString& pattern ) PlayableItem* PlayableProxyModel::itemFromIndex(int itemIndex) const { - qDebug() << "returning item" << sourceModel()->itemFromIndex( itemIndex )->name(); +// qDebug() << "returning item" << sourceModel()->itemFromIndex( itemIndex )->name(); QModelIndex modelIndex = index( itemIndex, 0 ); return sourceModel()->itemFromIndex( mapToSource( modelIndex ) ); } diff --git a/src/libtomahawk/playlist/dynamic/echonest/EchonestGenerator.cpp b/src/libtomahawk/playlist/dynamic/echonest/EchonestGenerator.cpp index b39793890..f36674a3d 100644 --- a/src/libtomahawk/playlist/dynamic/echonest/EchonestGenerator.cpp +++ b/src/libtomahawk/playlist/dynamic/echonest/EchonestGenerator.cpp @@ -337,6 +337,8 @@ EchonestGenerator::getParams() throw( std::runtime_error ) } else { emit paramsGenerated( params ); } + + qDebug() << "ParamsGenerated" << params; } diff --git a/src/libtomahawk/playlist/dynamic/echonest/EchonestStation.cpp b/src/libtomahawk/playlist/dynamic/echonest/EchonestStation.cpp index 4551e994b..627727b57 100644 --- a/src/libtomahawk/playlist/dynamic/echonest/EchonestStation.cpp +++ b/src/libtomahawk/playlist/dynamic/echonest/EchonestStation.cpp @@ -4,6 +4,8 @@ #include "PlayableItem.h" #include "audio/AudioEngine.h" +#include + namespace Tomahawk { @@ -42,6 +44,18 @@ bool EchonestStation::configured() return mainControl() != 0; } +int EchonestStation::minTempo() const +{ + dyncontrol_ptr minTempoControl = findControl( "Tempo", "min_tempo" ); + return minTempoControl.isNull() ? 0 : minTempoControl->input().toInt(); +} + +int EchonestStation::maxTempo() const +{ + dyncontrol_ptr maxTempoControl = findControl( "Tempo", "max_tempo" ); + return maxTempoControl.isNull() ? 500 : maxTempoControl->input().toInt(); +} + void EchonestStation::playItem(int row) { QModelIndex index( m_model->index( row, 0) ); @@ -64,7 +78,42 @@ void EchonestStation::setMainControl(const QString &type) qDebug() << "created control" << control->type() << control->selectedType() << control->match(); m_playlist->generator()->generate(20); - emit configuredChanged(); + emit configurationChanged(); +} + +void EchonestStation::setTempo(int min, int max) +{ + dyncontrol_ptr tempoMinControl = findControl("Tempo", "min_tempo"); + dyncontrol_ptr tempoMaxControl = findControl("Tempo", "max_tempo"); + + if ( tempoMinControl.isNull() ) { + tempoMinControl = m_playlist->generator()->createControl( "echonest" ); + tempoMinControl->setSelectedType( "Tempo" ); + tempoMinControl->setMatch( "min_tempo" ); + } + + if ( tempoMaxControl.isNull() ) { + tempoMaxControl = m_playlist->generator()->createControl( "echonest" ); + tempoMaxControl->setSelectedType( "Tempo" ); + tempoMaxControl->setMatch( "max_tempo" ); + } + + tempoMinControl->setInput( QString::number( min ) ); + tempoMaxControl->setInput( QString::number( max ) ); + + m_playlist->generator()->generate(20); + + emit configurationChanged(); +} + +dyncontrol_ptr EchonestStation::findControl(const QString &selectedType, const QString &match) const +{ + foreach ( dyncontrol_ptr control, m_playlist->generator()->controls() ) { + if ( control->selectedType() == selectedType && control->match() == match ) { + return control; + } + } + return dyncontrol_ptr(); } } diff --git a/src/libtomahawk/playlist/dynamic/echonest/EchonestStation.h b/src/libtomahawk/playlist/dynamic/echonest/EchonestStation.h index 753972413..a5ab900df 100644 --- a/src/libtomahawk/playlist/dynamic/echonest/EchonestStation.h +++ b/src/libtomahawk/playlist/dynamic/echonest/EchonestStation.h @@ -10,8 +10,10 @@ class EchonestStation: public QObject { Q_OBJECT Q_PROPERTY( QString name READ name WRITE setName NOTIFY nameChanged ) - Q_PROPERTY( bool configured READ configured NOTIFY configuredChanged ) + Q_PROPERTY( bool configured READ configured NOTIFY configurationChanged ) Q_PROPERTY( Tomahawk::DynamicControl* mainControl READ mainControl ) + Q_PROPERTY( int minTempo READ minTempo NOTIFY configurationChanged ) + Q_PROPERTY( int maxTempo READ maxTempo NOTIFY configurationChanged ) public: EchonestStation( PlayableProxyModel *model, dynplaylist_ptr playlist, QObject *parent = 0); @@ -22,14 +24,21 @@ public: Tomahawk::DynamicControl* mainControl(); bool configured(); + int minTempo() const; + int maxTempo() const; + public slots: void playItem( int row ); void setMainControl(const QString &type); + void setTempo( int min, int max ); signals: void nameChanged(); - void configuredChanged(); + void configurationChanged(); + +private: + dyncontrol_ptr findControl( const QString &selectedType, const QString &match ) const; private: QString m_name; diff --git a/src/libtomahawk/playlist/dynamic/widgets/DynamicQmlWidget.cpp b/src/libtomahawk/playlist/dynamic/widgets/DynamicQmlWidget.cpp index 2e7399a0d..f987d5ec7 100644 --- a/src/libtomahawk/playlist/dynamic/widgets/DynamicQmlWidget.cpp +++ b/src/libtomahawk/playlist/dynamic/widgets/DynamicQmlWidget.cpp @@ -42,11 +42,8 @@ DynamicQmlWidget::DynamicQmlWidget( const dynplaylist_ptr& playlist, QWidget* pa engine()->addImageProvider( "albumart", new DeclarativeCoverArtProvider( m_proxyModel ) ); m_model->loadPlaylist( m_playlist ); -// m_model->changeStation(); -// m_model->startOnDemand(); // Initially seed the playlist -// playlist->generator()->fetchNext(); m_playlist->generator()->generate( 20 ); qDebug() << "###got" << m_playlist->generator()->controls().size() << "controls"; @@ -55,25 +52,12 @@ DynamicQmlWidget::DynamicQmlWidget( const dynplaylist_ptr& playlist, QWidget* pa // TODO: In case QML is used in more places, this should probably be moved to some generic place qmlRegisterType("tomahawk", 1, 0, "PlayableItem"); -// qmlRegisterUncreatableType("tomahawk", 1, 0, "DynamicControl", "use generator.createControl() isntead"); -// qmlRegisterUncreatableType("tomahawk", 1, 0, "EchonestControl", "use Generator.createControl() instead"); - qmlRegisterUncreatableType("tomahawk", 1, 0, "DynamicControl", "use generator.createControl() isntead"); - qmlRegisterUncreatableType("tomahawk", 1, 0, "EchonestControl", "use Generator.createControl() instead"); qmlRegisterUncreatableType("tomahawk", 1, 0, "Generator", "you cannot create it on your own - should be set in context"); qmlRegisterUncreatableType("tomahawk", 1, 0, "PlayableItem", "you cannot create it on your own - they will appear in the model"); - QStringList generatorControls; - - foreach(dyncontrol_ptr control, m_playlist->generator()->controls()) { - qDebug() << "**CTRL" << control->summary() << control->input() << control->match() << control->type() << control->selectedType(); - generatorControls << control->summary(); - } - - ControlModel *controls = new ControlModel(m_playlist->generator(), this); EchonestStation *station = new EchonestStation( m_proxyModel, m_playlist, this); rootContext()->setContextProperty( "echonestStation", station); - rootContext()->setContextProperty( "controlModel", controls ); rootContext()->setContextProperty( "dynamicModel", m_proxyModel ); rootContext()->setContextProperty( "generator", m_playlist->generator().data() ); currentItemChanged( m_model->currentItem() );