1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-02-26 12:53:41 +01:00

add a steering widget to GeneratorInterface

isn't completely done or hooked up yet, but a good start
This commit is contained in:
Leo Franchi 2011-02-02 23:01:08 -05:00
parent 1443e1a591
commit 50a3c51bfa
8 changed files with 281 additions and 5 deletions

View File

@ -103,6 +103,7 @@ set( libSources
playlist/dynamic/DynamicView.cpp
playlist/dynamic/echonest/EchonestGenerator.cpp
playlist/dynamic/echonest/EchonestControl.cpp
playlist/dynamic/echonest/EchonestSteerer.cpp
playlist/dynamic/widgets/DynamicWidget.cpp
playlist/dynamic/widgets/DynamicControlWrapper.cpp
playlist/dynamic/widgets/DynamicControlList.cpp
@ -242,6 +243,7 @@ set( libHeaders
playlist/dynamic/DynamicView.h
playlist/dynamic/echonest/EchonestGenerator.h
playlist/dynamic/echonest/EchonestControl.h
playlist/dynamic/echonest/EchonestSteerer.h
playlist/dynamic/widgets/DynamicWidget.h
playlist/dynamic/widgets/DynamicControlWrapper.h
playlist/dynamic/widgets/DynamicControlList.h

View File

@ -1,5 +1,5 @@
/****************************************************************************************
* Copyright (c) 2010 Leo Franchi <lfranchi@kde.org> *
* Copyright (c) 2010-2011 Leo Franchi <lfranchi@kde.org> *
* *
* This program is free software; you can redistribute it and/or modify it under *
* the terms of the GNU General Public License as published by the Free Software *
@ -85,6 +85,21 @@ public:
*/
virtual QString sentenceSummary() { return QString(); }
/**
* If an OnDemand playlist can be steered, this returns true.
* If so, the generator should also provide a steering widget
* in steeringWidget()
*/
virtual bool onDemandSteerable() const { return false; }
/**
* Returns a widget used to steer the OnDemand dynamic playlist.
* If this generator doesn't support this (and returns false for
* \c onDemandSteerable) this will be null. The generator is responsible
* for reacting to changes in the widget.
*/
virtual QWidget* steeringWidget() { return 0; }
/// The type of this generator
QString type() const { return m_type; }

View File

@ -1,5 +1,5 @@
/****************************************************************************************
* Copyright (c) 2010 Leo Franchi <lfranchi@kde.org> *
* Copyright (c) 2010-2011 Leo Franchi <lfranchi@kde.org> *
* *
* This program is free software; you can redistribute it and/or modify it under *
* the terms of the GNU General Public License as published by the Free Software *
@ -16,6 +16,7 @@
#include "dynamic/echonest/EchonestGenerator.h"
#include "dynamic/echonest/EchonestControl.h"
#include "dynamic/echonest/EchonestSteerer.h"
#include "query.h"
#include "tomahawk/tomahawkapp.h"
@ -47,6 +48,8 @@ EchonestFactory::typeSelectors() const
EchonestGenerator::EchonestGenerator ( QObject* parent )
: GeneratorInterface ( parent )
, m_dynPlaylist( new Echonest::DynamicPlaylist() )
, m_steerer( 0 )
, m_steeredSinceLastTrack( false )
{
m_type = "echonest";
m_mode = OnDemand;
@ -118,7 +121,14 @@ EchonestGenerator::fetchNext( int rating )
return;
}
QNetworkReply* reply = m_dynPlaylist->fetchNextSong( rating );
QNetworkReply* reply;
if( m_steeredSinceLastTrack ) {
qDebug() << "Steering dynamic playlist!" << m_steerData.first << m_steerData.second;
reply = m_dynPlaylist->fetchNextSong( Echonest::DynamicPlaylist::DynamicControls() << m_steerData );
m_steeredSinceLastTrack = false;
} else {
reply = m_dynPlaylist->fetchNextSong( rating );
}
qDebug() << "getting next song from echonest" << reply->url().toString();
connect( reply, SIGNAL( finished() ), this, SLOT( dynamicFetched() ) );
}
@ -198,6 +208,23 @@ EchonestGenerator::dynamicFetched()
}
}
void
EchonestGenerator::steerDescription( const QString& desc )
{
m_steeredSinceLastTrack = true;
m_steerData.first = Echonest::DynamicPlaylist::SteerDescription;
m_steerData.second = desc;
}
void
EchonestGenerator::steerField( const QString& field )
{
m_steeredSinceLastTrack = true;
m_steerData.first = Echonest::DynamicPlaylist::Steer;
m_steerData.second = field;
}
bool
EchonestGenerator::onlyThisArtistType( Echonest::DynamicPlaylist::ArtistTypeEnum type ) const throw( std::runtime_error )
{
@ -252,6 +279,16 @@ EchonestGenerator::queryFromSong(const Echonest::Song& song)
return query_ptr( new Query( track ) );
}
QWidget*
EchonestGenerator::steeringWidget()
{
if( !m_steerer )
m_steerer = new EchonestSteerer();
return m_steerer;
}
QString
EchonestGenerator::sentenceSummary()
{

View File

@ -1,5 +1,5 @@
/****************************************************************************************
* Copyright (c) 2010 Leo Franchi <lfranchi@kde.org> *
* Copyright (c) 2010-2011 Leo Franchi <lfranchi@kde.org> *
* *
* This program is free software; you can redistribute it and/or modify it under *
* the terms of the GNU General Public License as published by the Free Software *
@ -27,6 +27,8 @@
namespace Tomahawk
{
class EchonestSteerer;
class EchonestFactory : public GeneratorFactoryInterface
{
public:
@ -50,12 +52,18 @@ public:
virtual void startOnDemand();
virtual void fetchNext( int rating = -1 );
virtual QString sentenceSummary();
virtual bool onDemandSteerable() const { return true; }
virtual QWidget* steeringWidget();
private slots:
void staticFinished();
void dynamicStarted();
void dynamicFetched();
// steering controls
void steerField( const QString& field );
void steerDescription( const QString& desc );
private:
Echonest::DynamicPlaylist::PlaylistParams getParams() const throw( std::runtime_error );
query_ptr queryFromSong( const Echonest::Song& song );
@ -64,6 +72,10 @@ private:
Echonest::DynamicPlaylist* m_dynPlaylist;
QPixmap m_logo;
EchonestSteerer* m_steerer;
bool m_steeredSinceLastTrack;
Echonest::DynamicPlaylist::DynamicControl m_steerData;
};
};

View File

@ -0,0 +1,115 @@
/****************************************************************************************
* Copyright (c) 2011 Leo Franchi <lfranchi@kde.org> *
* *
* This program is free software; you can redistribute it and/or modify it under *
* the terms of the GNU General Public License as published by the Free Software *
* Foundation; either version 2 of the License, or (at your option) any later *
* version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT ANY *
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A *
* PARTICULAR PURPOSE. See the GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
****************************************************************************************/
#include "dynamic/echonest/EchonestSteerer.h"
#include <QPaintEvent>
#include <QHBoxLayout>
#include <QLineEdit>
#include <QComboBox>
#include <QLabel>
#include <Playlist.h>
#include <QPainter>
using namespace Tomahawk;
EchonestSteerer::EchonestSteerer( QWidget* parent )
: QWidget( parent )
, m_layout( new QHBoxLayout )
, m_steerTop( 0 )
, m_steerBottom( 0 )
, m_amplifier( 0 )
, m_field( 0 )
, m_description( 0 )
, m_textL( new QVBoxLayout )
{
m_layout->setContentsMargins( 8, 8, 8, 8 );
m_textL->setSpacing( 0 );
m_steerTop = new QLabel( tr( "Steer this station:" ), this );
QFont f = m_steerTop->font();
f.setPointSize( f.pointSize() + 2 );
f.setBold( true );
m_steerTop->setFont( f );
m_textL->addWidget( m_steerTop );
m_steerBottom = new QLabel( tr( "Takes effect on track change" ), this );
f.setPointSize( f.pointSize() - 3 );
m_steerBottom->setFont( f );
m_textL->addWidget( m_steerBottom );
m_layout->addLayout( m_textL, 1 );
m_amplifier = new QComboBox( this );
m_amplifier->addItem( tr( "Much less" ), "^.5" );
m_amplifier->addItem( tr( "Less" ), "^.75" );
m_amplifier->addItem( tr( "More" ), "^1.25" );
m_amplifier->addItem( tr( "Much more" ), "^1.5" );
m_amplifier->addItem( tr( "Much more" ), "^1.5" );
m_field = new QComboBox( this );
m_field->addItem( tr( "Tempo" ), "tempo");
m_field->addItem( tr( "Loudness" ), "loudness");
m_field->addItem( tr( "Danceability" ), "danceability");
m_field->addItem( tr( "Energy" ), "energy");
m_field->addItem( tr( "Song Hotttnesss" ), "tempo");
m_field->addItem( tr( "Artist Hotttnesss" ), "artist_hotttnesss");
m_field->addItem( tr( "Artist Familiarity" ), "artist_familiarity");
m_field->addItem( tr( "By Description" ), "desc");
m_layout->addWidget( m_amplifier );
m_layout->addWidget( m_field );
connect( m_amplifier, SIGNAL( currentIndexChanged( int ) ), this, SLOT( changed() ) );
connect( m_field, SIGNAL( currentIndexChanged( int ) ), this, SLOT( changed() ) );
m_description = new QLineEdit( this );
m_description->hide();
setLayout( m_layout );
setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
resize( sizeHint() );
}
void
EchonestSteerer::paintEvent( QPaintEvent* )
{
QPainter p( this );
QRect r = contentsRect();
p.setBackgroundMode( Qt::TransparentMode );
p.setRenderHint( QPainter::Antialiasing );
p.setOpacity( 0.7 );
QPen pen( palette().dark().color(), .5 );
p.setPen( pen );
p.setBrush( palette().highlight() );
p.drawRoundedRect( r, 10, 10 );
p.setOpacity( .95 );
p.setBrush( QBrush() );
p.setPen( pen );
p.drawRoundedRect( r, 10, 10 );
}
void
EchonestSteerer::changed()
{
if( m_field->itemData( m_field->currentIndex() ).toString() != "desc" ) {
QString steer = m_field->itemData( m_field->currentIndex() ).toString() + m_amplifier->itemData( m_amplifier->currentIndex() ).toString();
emit steerField( steer );
} else {
}
}

View File

@ -0,0 +1,62 @@
/****************************************************************************************
* Copyright (c) 2011 Leo Franchi <lfranchi@kde.org> *
* *
* This program is free software; you can redistribute it and/or modify it under *
* the terms of the GNU General Public License as published by the Free Software *
* Foundation; either version 2 of the License, or (at your option) any later *
* version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT ANY *
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A *
* PARTICULAR PURPOSE. See the GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
****************************************************************************************/
#ifndef ECHONEST_STEERER_H
#define ECHONEST_STEERER_H
#include <QWidget>
class QLabel;
class QComboBox;
class QVBoxLayout;
class QLineEdit;
class QHBoxLayout;
namespace Tomahawk
{
class EchonestSteerer : public QWidget
{
Q_OBJECT
public:
EchonestSteerer( QWidget* parent = 0 );
virtual void paintEvent(QPaintEvent* );
signals:
void steerField( const QString& field );
void steerDescription( const QString& desc );
private slots:
void changed();
private:
QHBoxLayout* m_layout;
QLabel* m_steerTop;
QLabel* m_steerBottom;
QComboBox* m_amplifier;
QComboBox* m_field;
QLineEdit* m_description;
QVBoxLayout* m_textL;
};
};
#endif

View File

@ -45,6 +45,7 @@ DynamicWidget::DynamicWidget( const Tomahawk::dynplaylist_ptr& playlist, QWidget
, m_runningOnDemand( false )
, m_startOnResolved( false )
, m_songsSinceLastResolved( 0 )
, m_steering( 0 )
, m_headerText( 0 )
, m_headerLayout( 0 )
, m_generatorCombo( 0 )
@ -187,6 +188,19 @@ DynamicWidget::sizeHint() const
// to avoid having to calculate it which is slow
return QSize( 5000, 5000 );
}
void
DynamicWidget::resizeEvent(QResizeEvent* )
{
if( m_runningOnDemand && m_steering ) {
int x = ( width() / 2 ) - ( m_steering->size().width() / 2 );
int y = height() - m_steering->size().height() - 40; // padding
m_steering->move( x, y );
}
}
void
DynamicWidget::generateOrStart()
{
@ -201,9 +215,25 @@ DynamicWidget::generateOrStart()
m_playlist->generator()->startOnDemand();
m_generateButton->setText( tr( "Stop" ) );
// show the steering controls
if( m_playlist->generator()->onDemandSteerable() ) {
// position it horizontally centered, above the botton.
m_steering = m_playlist->generator()->steeringWidget();
Q_ASSERT( m_steering );
int x = ( width() / 2 ) - ( m_steering->size().width() / 2 );
int y = height() - m_steering->size().height() - 40; // padding
m_steering->setParent( this );
m_steering->move( x, y );
m_steering->show();
}
} else { // stop
m_runningOnDemand = false;
m_startOnResolved = false;
m_steering = 0;
m_generateButton->setText( tr( "Start" ) );
}
}

View File

@ -59,6 +59,8 @@ public:
PlaylistInterface* playlistInterface() const;
virtual QSize sizeHint() const;
virtual void resizeEvent( QResizeEvent* );
public slots:
void onRevisionLoaded( const Tomahawk::DynamicPlaylistRevision& rev );
@ -88,6 +90,7 @@ private:
bool m_runningOnDemand;
bool m_startOnResolved;
int m_songsSinceLastResolved;
QWidget* m_steering;
// layout and stuff
QLabel* m_headerText;