mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-08-13 17:43:59 +02:00
some more work on the stations
This commit is contained in:
@@ -40,6 +40,11 @@ Item {
|
|||||||
DoubleSlider {
|
DoubleSlider {
|
||||||
width: 500
|
width: 500
|
||||||
height: tempoText.height
|
height: tempoText.height
|
||||||
|
min: 0
|
||||||
|
max: 500
|
||||||
|
lowerSliderPos: echonestStation.minTempo
|
||||||
|
upperSliderPos: echonestStation.maxTempo
|
||||||
|
onValueChanged: echonestStation.setTempo( lowerSliderPos, upperSliderPos )
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
@@ -50,6 +55,14 @@ Item {
|
|||||||
DoubleSlider {
|
DoubleSlider {
|
||||||
width: 500
|
width: 500
|
||||||
height: hotnessText.height
|
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 )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -19,7 +19,7 @@ Item {
|
|||||||
//highlightMoveDuration: 500
|
//highlightMoveDuration: 500
|
||||||
|
|
||||||
model: dynamicModel
|
model: dynamicModel
|
||||||
currentIndex: currentlyPlayedIndex >= 0 ? currentlyPlayedIndex : 0
|
currentIndex: currentlyPlayedIndex
|
||||||
|
|
||||||
property int pathStartX: width / 2
|
property int pathStartX: width / 2
|
||||||
property int pathStartY: height / 2
|
property int pathStartY: height / 2
|
||||||
@@ -155,21 +155,21 @@ Item {
|
|||||||
font.pointSize: 16
|
font.pointSize: 16
|
||||||
width: parent.width
|
width: parent.width
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
text: coverView.model.itemFromIndex( currentlyPlayedIndex ).name
|
text: currentlyPlayedIndex > -1 ? coverView.model.itemFromIndex( currentlyPlayedIndex ).name : ""
|
||||||
}
|
}
|
||||||
Text {
|
Text {
|
||||||
color: "white"
|
color: "white"
|
||||||
font.pointSize: 14
|
font.pointSize: 14
|
||||||
width: parent.width
|
width: parent.width
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
text: coverView.model.itemFromIndex( currentlyPlayedIndex ).artistName
|
text: currentlyPlayedIndex > -1 ? coverView.model.itemFromIndex( currentlyPlayedIndex ).artistName : ""
|
||||||
}
|
}
|
||||||
Text {
|
Text {
|
||||||
color: "white"
|
color: "white"
|
||||||
font.pointSize: 14
|
font.pointSize: 14
|
||||||
width: parent.width
|
width: parent.width
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
text: coverView.model.itemFromIndex( currentlyPlayedIndex ).albumName
|
text: currentlyPlayedIndex > -1 ? coverView.model.itemFromIndex( currentlyPlayedIndex ).albumName : ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -8,16 +8,27 @@ Item {
|
|||||||
property int min: 0
|
property int min: 0
|
||||||
property int max: 100
|
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 lowerSliderPos: 25
|
||||||
property int upperSliderPos: 75
|
property int upperSliderPos: 75
|
||||||
|
|
||||||
|
signal valueChanged()
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
spacing: 10
|
spacing: 10
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
id: minText
|
id: minText
|
||||||
text: min
|
text: root.minLabel.length > 0 ? root.minLabel : min
|
||||||
color: "white"
|
color: "white"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,7 +71,7 @@ Item {
|
|||||||
color: "white"
|
color: "white"
|
||||||
anchors.bottom: lowerSlider.top
|
anchors.bottom: lowerSlider.top
|
||||||
anchors.bottomMargin: 10
|
anchors.bottomMargin: 10
|
||||||
visible: lowerSliderMouseArea.pressed
|
visible: root.showFloatingLabel && lowerSliderMouseArea.pressed
|
||||||
width: lowerFloatingText.width * 1.2
|
width: lowerFloatingText.width * 1.2
|
||||||
height: lowerFloatingText.height + height * 1.2
|
height: lowerFloatingText.height + height * 1.2
|
||||||
x: -(width - lowerSlider.width) / 2
|
x: -(width - lowerSlider.width) / 2
|
||||||
@@ -80,6 +91,10 @@ Item {
|
|||||||
drag.axis: "XAxis"
|
drag.axis: "XAxis"
|
||||||
drag.minimumX: 0
|
drag.minimumX: 0
|
||||||
drag.maximumX: upperSlider.x - lowerSlider.width
|
drag.maximumX: upperSlider.x - lowerSlider.width
|
||||||
|
onReleased: {
|
||||||
|
root.lowerSliderPos = sliderRect.sliderPosToValue( lowerSlider.x );
|
||||||
|
root.valueChanged();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
@@ -96,7 +111,7 @@ Item {
|
|||||||
color: "white"
|
color: "white"
|
||||||
anchors.bottom: upperSlider.top
|
anchors.bottom: upperSlider.top
|
||||||
anchors.bottomMargin: 10
|
anchors.bottomMargin: 10
|
||||||
visible: upperSliderMouseArea.pressed
|
visible: root.showFloatingLabel && upperSliderMouseArea.pressed
|
||||||
width: upperFloatingText.width * 1.2
|
width: upperFloatingText.width * 1.2
|
||||||
height: upperFloatingText.height + height * 1.2
|
height: upperFloatingText.height + height * 1.2
|
||||||
radius: height / 4
|
radius: height / 4
|
||||||
@@ -118,13 +133,18 @@ Item {
|
|||||||
drag.axis: "XAxis"
|
drag.axis: "XAxis"
|
||||||
drag.minimumX: lowerSlider.x + lowerSlider.width
|
drag.minimumX: lowerSlider.x + lowerSlider.width
|
||||||
drag.maximumX: parent.width - upperSlider.width
|
drag.maximumX: parent.width - upperSlider.width
|
||||||
|
onReleased: {
|
||||||
|
root.upperSliderPos = sliderRect.sliderPosToValue( upperSlider.x );
|
||||||
|
root.valueChanged();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
id: maxText
|
id: maxText
|
||||||
text: max
|
text: root.maxLabel.length > 0 ? root.maxLabel : max
|
||||||
color: "white"
|
color: "white"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -587,7 +587,7 @@ PlayableProxyModel::setFilter( const QString& pattern )
|
|||||||
PlayableItem*
|
PlayableItem*
|
||||||
PlayableProxyModel::itemFromIndex(int itemIndex) const
|
PlayableProxyModel::itemFromIndex(int itemIndex) const
|
||||||
{
|
{
|
||||||
qDebug() << "returning item" << sourceModel()->itemFromIndex( itemIndex )->name();
|
// qDebug() << "returning item" << sourceModel()->itemFromIndex( itemIndex )->name();
|
||||||
QModelIndex modelIndex = index( itemIndex, 0 );
|
QModelIndex modelIndex = index( itemIndex, 0 );
|
||||||
return sourceModel()->itemFromIndex( mapToSource( modelIndex ) );
|
return sourceModel()->itemFromIndex( mapToSource( modelIndex ) );
|
||||||
}
|
}
|
||||||
|
@@ -337,6 +337,8 @@ EchonestGenerator::getParams() throw( std::runtime_error )
|
|||||||
} else {
|
} else {
|
||||||
emit paramsGenerated( params );
|
emit paramsGenerated( params );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qDebug() << "ParamsGenerated" << params;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -4,6 +4,8 @@
|
|||||||
#include "PlayableItem.h"
|
#include "PlayableItem.h"
|
||||||
#include "audio/AudioEngine.h"
|
#include "audio/AudioEngine.h"
|
||||||
|
|
||||||
|
#include <echonest/Playlist.h>
|
||||||
|
|
||||||
namespace Tomahawk
|
namespace Tomahawk
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -42,6 +44,18 @@ bool EchonestStation::configured()
|
|||||||
return mainControl() != 0;
|
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)
|
void EchonestStation::playItem(int row)
|
||||||
{
|
{
|
||||||
QModelIndex index( m_model->index( row, 0) );
|
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();
|
qDebug() << "created control" << control->type() << control->selectedType() << control->match();
|
||||||
m_playlist->generator()->generate(20);
|
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -10,8 +10,10 @@ class EchonestStation: public QObject
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY( QString name READ name WRITE setName NOTIFY nameChanged )
|
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( Tomahawk::DynamicControl* mainControl READ mainControl )
|
||||||
|
Q_PROPERTY( int minTempo READ minTempo NOTIFY configurationChanged )
|
||||||
|
Q_PROPERTY( int maxTempo READ maxTempo NOTIFY configurationChanged )
|
||||||
|
|
||||||
public:
|
public:
|
||||||
EchonestStation( PlayableProxyModel *model, dynplaylist_ptr playlist, QObject *parent = 0);
|
EchonestStation( PlayableProxyModel *model, dynplaylist_ptr playlist, QObject *parent = 0);
|
||||||
@@ -22,14 +24,21 @@ public:
|
|||||||
Tomahawk::DynamicControl* mainControl();
|
Tomahawk::DynamicControl* mainControl();
|
||||||
bool configured();
|
bool configured();
|
||||||
|
|
||||||
|
int minTempo() const;
|
||||||
|
int maxTempo() const;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void playItem( int row );
|
void playItem( int row );
|
||||||
|
|
||||||
void setMainControl(const QString &type);
|
void setMainControl(const QString &type);
|
||||||
|
void setTempo( int min, int max );
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void nameChanged();
|
void nameChanged();
|
||||||
void configuredChanged();
|
void configurationChanged();
|
||||||
|
|
||||||
|
private:
|
||||||
|
dyncontrol_ptr findControl( const QString &selectedType, const QString &match ) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString m_name;
|
QString m_name;
|
||||||
|
@@ -42,11 +42,8 @@ DynamicQmlWidget::DynamicQmlWidget( const dynplaylist_ptr& playlist, QWidget* pa
|
|||||||
engine()->addImageProvider( "albumart", new DeclarativeCoverArtProvider( m_proxyModel ) );
|
engine()->addImageProvider( "albumart", new DeclarativeCoverArtProvider( m_proxyModel ) );
|
||||||
|
|
||||||
m_model->loadPlaylist( m_playlist );
|
m_model->loadPlaylist( m_playlist );
|
||||||
// m_model->changeStation();
|
|
||||||
// m_model->startOnDemand();
|
|
||||||
|
|
||||||
// Initially seed the playlist
|
// Initially seed the playlist
|
||||||
// playlist->generator()->fetchNext();
|
|
||||||
m_playlist->generator()->generate( 20 );
|
m_playlist->generator()->generate( 20 );
|
||||||
|
|
||||||
qDebug() << "###got" << m_playlist->generator()->controls().size() << "controls";
|
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
|
// TODO: In case QML is used in more places, this should probably be moved to some generic place
|
||||||
qmlRegisterType<PlayableItem>("tomahawk", 1, 0, "PlayableItem");
|
qmlRegisterType<PlayableItem>("tomahawk", 1, 0, "PlayableItem");
|
||||||
// qmlRegisterUncreatableType<Tomahawk::DynamicControl>("tomahawk", 1, 0, "DynamicControl", "use generator.createControl() isntead");
|
|
||||||
// qmlRegisterUncreatableType<Tomahawk::EchonestControl>("tomahawk", 1, 0, "EchonestControl", "use Generator.createControl() instead");
|
|
||||||
qmlRegisterUncreatableType<DynamicControl>("tomahawk", 1, 0, "DynamicControl", "use generator.createControl() isntead");
|
|
||||||
qmlRegisterUncreatableType<EchonestControl>("tomahawk", 1, 0, "EchonestControl", "use Generator.createControl() instead");
|
|
||||||
qmlRegisterUncreatableType<GeneratorInterface>("tomahawk", 1, 0, "Generator", "you cannot create it on your own - should be set in context");
|
qmlRegisterUncreatableType<GeneratorInterface>("tomahawk", 1, 0, "Generator", "you cannot create it on your own - should be set in context");
|
||||||
qmlRegisterUncreatableType<PlayableItem>("tomahawk", 1, 0, "PlayableItem", "you cannot create it on your own - they will appear in the model");
|
qmlRegisterUncreatableType<PlayableItem>("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);
|
EchonestStation *station = new EchonestStation( m_proxyModel, m_playlist, this);
|
||||||
rootContext()->setContextProperty( "echonestStation", station);
|
rootContext()->setContextProperty( "echonestStation", station);
|
||||||
rootContext()->setContextProperty( "controlModel", controls );
|
|
||||||
rootContext()->setContextProperty( "dynamicModel", m_proxyModel );
|
rootContext()->setContextProperty( "dynamicModel", m_proxyModel );
|
||||||
rootContext()->setContextProperty( "generator", m_playlist->generator().data() );
|
rootContext()->setContextProperty( "generator", m_playlist->generator().data() );
|
||||||
currentItemChanged( m_model->currentItem() );
|
currentItemChanged( m_model->currentItem() );
|
||||||
|
Reference in New Issue
Block a user