PageRenderTime 185ms CodeModel.GetById 60ms app.highlight 70ms RepoModel.GetById 51ms app.codeStats 0ms

/src/libtomahawk/playlist/dynamic/echonest/EchonestSteerer.cpp

http://github.com/tomahawk-player/tomahawk
C++ | 272 lines | 197 code | 51 blank | 24 comment | 12 complexity | 87259f8e414c996a52bbeda8c470210d MD5 | raw file
  1/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
  2 *
  3 *   Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
  4 *
  5 *   Tomahawk is free software: you can redistribute it and/or modify
  6 *   it under the terms of the GNU General Public License as published by
  7 *   the Free Software Foundation, either version 3 of the License, or
  8 *   (at your option) any later version.
  9 *
 10 *   Tomahawk is distributed in the hope that it will be useful,
 11 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 12 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 13 *   GNU General Public License for more details.
 14 *
 15 *   You should have received a copy of the GNU General Public License
 16 *   along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
 17 */
 18
 19#include "playlist/dynamic/echonest/EchonestSteerer.h"
 20
 21#include "Source.h"
 22#include "playlist/dynamic/widgets/DynamicWidget.h"
 23#include "utils/ImageRegistry.h"
 24#include "utils/TomahawkUtils.h"
 25#include "utils/Logger.h"
 26
 27#include <echonest5/Playlist.h>
 28
 29#include <QPaintEvent>
 30#include <QHBoxLayout>
 31#include <QLineEdit>
 32#include <QComboBox>
 33#include <QLabel>
 34#include <QPainter>
 35#include <QToolButton>
 36#include <QPropertyAnimation>
 37
 38using namespace Tomahawk;
 39
 40#define ANIM_DURATION 300
 41
 42
 43EchonestSteerer::EchonestSteerer( QWidget* parent )
 44    : QWidget( parent )
 45    , m_layout( new QHBoxLayout )
 46    , m_amplifier( 0 )
 47    , m_field( 0 )
 48    , m_description( 0 )
 49    , m_textL( new QVBoxLayout )
 50    , m_steerTop( 0 )
 51    , m_steerBottom( 0 )
 52    , m_reset( 0 )
 53    , m_expanding( true )
 54
 55{
 56    m_layout->setContentsMargins( 8, 8, 8, 8 );
 57
 58    m_textL->setSpacing( 0 );
 59    m_steerTop = new QLabel( tr( "Steer this station:" ), this );
 60    QFont f = m_steerTop->font();
 61    f.setPointSize( f.pointSize() + 2 );
 62    f.setBold( true );
 63    m_steerTop->setFont( f );
 64    m_textL->addWidget( m_steerTop );
 65//    m_steerBottom = new QLabel( tr( "Takes effect on track change" ), this );
 66//    f.setPointSize( f.pointSize() - 3 );
 67//    m_steerBottom->setFont( f );
 68//    m_textL->addWidget( m_steerBottom );
 69
 70
 71    QPalette p = m_steerTop->palette();
 72#ifdef Q_OS_MAC
 73    p.setBrush( QPalette::WindowText, Qt::white );
 74#else
 75    p.setBrush( QPalette::WindowText, palette().highlightedText()  );
 76#endif
 77    m_steerTop->setPalette( p );
 78
 79    m_layout->addLayout( m_textL, 1 );
 80
 81    m_amplifier = new QComboBox( this );
 82    m_amplifier->addItem( tr( "Much less" ), "^.1" );
 83    m_amplifier->addItem( tr( "Less" ), "^.5" );
 84    m_amplifier->addItem( tr( "A bit less" ), "^.75" );
 85    m_amplifier->addItem( tr( "Keep at current", "" ) );
 86    m_amplifier->addItem( tr( "A bit more" ), "^1.25" );
 87    m_amplifier->addItem( tr( "More" ), "^1.5" );
 88    m_amplifier->addItem( tr( "Much more" ), "^2" );
 89    m_amplifier->setCurrentIndex( 3 );
 90    m_field = new QComboBox( this );
 91    m_field->addItem( tr( "Tempo" ), "tempo");
 92    m_field->addItem( tr( "Loudness" ), "loudness");
 93    m_field->addItem( tr( "Danceability" ), "danceability");
 94    m_field->addItem( tr( "Energy" ), "energy");
 95    m_field->addItem( tr( "Song Hotttnesss" ), "tempo");
 96    m_field->addItem( tr( "Artist Hotttnesss" ), "artist_hotttnesss");
 97    m_field->addItem( tr( "Artist Familiarity" ), "artist_familiarity");
 98    m_field->addItem( tr( "By Description" ), "desc");
 99    m_layout->addWidget( m_amplifier );
100    m_layout->addWidget( m_field );
101
102    connect( m_amplifier, SIGNAL( currentIndexChanged( int ) ), this, SLOT( changed() ) );
103    connect( m_field, SIGNAL( currentIndexChanged( int ) ), this, SLOT( changed() ) );
104
105    m_description = new QLineEdit( this );
106    m_description->setPlaceholderText( tr( "Enter a description" ) );
107    m_description->hide();
108
109    connect( m_description, SIGNAL( textChanged( QString ) ), this, SLOT( changed() ) );
110
111    m_apply = initButton( this );
112    m_apply->setIcon( ImageRegistry::instance()->icon( RESPATH "images/apply-check.svg" ) );
113    m_apply->setToolTip( tr( "Apply steering command" ) );
114    m_layout->addWidget( m_apply );
115    connect( m_apply, SIGNAL( clicked( bool ) ), this, SLOT( applySteering() ) );
116
117    m_reset = initButton( this );
118    m_reset->setIcon( ImageRegistry::instance()->icon( RESPATH "images/view-refresh.svg" ) );
119    m_reset->setToolTip( tr( "Reset all steering commands" ) );
120    m_layout->addWidget( m_reset );
121
122    connect( m_reset, SIGNAL( clicked( bool ) ), this, SLOT( resetSteering( bool ) ) );
123
124    setLayout( m_layout );
125    setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
126
127    m_resizeAnim.setDuration( ANIM_DURATION );
128    m_resizeAnim.setEasingCurve( QEasingCurve::InOutQuad );
129    m_resizeAnim.setDirection( QTimeLine::Forward );
130    m_resizeAnim.setUpdateInterval( 8 );
131
132    connect( &m_resizeAnim, SIGNAL( frameChanged( int ) ), this, SLOT( resizeFrame( int ) ) );
133
134
135    m_fadeAnim = new QPropertyAnimation( this, "opacity", this );
136    m_fadeAnim->setDuration( ANIM_DURATION );
137    m_fadeAnim->setStartValue( 0 );
138    m_fadeAnim->setEndValue( .7 );
139    resize( sizeHint() );
140}
141
142
143void
144EchonestSteerer::paintEvent( QPaintEvent* )
145{
146    QPainter p( this );
147    QRect r = contentsRect();
148    QPalette pal = palette();
149
150    DynamicWidget::paintRoundedFilledRect( p, pal, r, m_opacity );
151}
152
153
154void
155EchonestSteerer::setOpacity( qreal opacity )
156{
157    m_opacity = opacity;
158    if( m_opacity == 0 )
159        hide();
160    repaint();
161}
162
163
164void
165EchonestSteerer::fadeIn()
166{
167    m_fadeAnim->setDirection( QAbstractAnimation::Forward );
168    m_fadeAnim->start();
169
170    show();
171}
172
173
174void
175EchonestSteerer::fadeOut()
176{
177    m_fadeAnim->setDirection( QAbstractAnimation::Backward );
178    m_fadeAnim->start();
179}
180
181
182void
183EchonestSteerer::changed()
184{
185    if( m_field->itemData( m_field->currentIndex() ).toString() != "desc" ) {
186        // if description was shown, animate to shrink
187        if( m_layout->indexOf( m_description ) > 0 ) {
188            m_expanding = false;
189            int start = width();
190            int end = start - m_layout->spacing() - m_description->sizeHint().width();;
191
192            m_layout->removeWidget( m_description );
193            m_description->hide();
194            m_layout->setStretchFactor(  m_textL, 1 );
195
196            m_resizeAnim.setFrameRange( start, end );
197            m_resizeAnim.start();
198        }
199    } else { // description, so put in the description field
200        if( m_layout->indexOf( m_description ) == -1 ) {
201            // animate to expand
202            m_layout->insertWidget( m_layout->count() - 1, m_description, 1 );
203            m_layout->setStretchFactor( m_textL, 0 );
204            m_description->show();
205
206            m_expanding = true;
207            int start = width();
208            int end = start + m_layout->spacing() + m_description->sizeHint().width();
209            m_resizeAnim.setFrameRange( start, end );
210            m_resizeAnim.start();
211        }
212    }
213}
214
215void
216EchonestSteerer::applySteering()
217{
218    if ( m_field->itemData( m_field->currentIndex() ).toString() != "desc" )
219    {
220        QString steer = m_field->itemData( m_field->currentIndex() ).toString() + m_amplifier->itemData( m_amplifier->currentIndex() ).toString();
221        emit steerField( steer );
222    }
223    else
224    {
225        if ( !m_description->text().isEmpty() )
226        {
227            QString steer = m_description->text() + m_amplifier->itemData( m_amplifier->currentIndex() ).toString();
228            emit steerDescription( steer );
229        }
230    }
231
232    emit steeringChanged();
233
234    resetSteering( true );
235}
236
237
238void
239EchonestSteerer::resizeFrame( int width )
240{
241//     qDebug() << "RESIZING TO:" << width;
242    resize( width, sizeHint().height() );
243    repaint();
244
245    emit resized();
246}
247
248
249void
250EchonestSteerer::resetSteering( bool automatic )
251{
252    m_amplifier->setCurrentIndex( 3 );
253
254    if( !automatic ) {
255        m_description->clear();
256        m_field->setCurrentIndex( 0 );
257        emit reset();
258    }
259}
260
261
262QToolButton*
263EchonestSteerer::initButton( QWidget* parent )
264{
265    QToolButton* btn = new QToolButton( parent );
266    btn->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
267    btn->setIconSize( QSize( 14, 14 ) );
268    btn->setToolButtonStyle( Qt::ToolButtonIconOnly );
269    btn->setAutoRaise( true );
270    btn->setContentsMargins( 0, 0, 0, 0 );
271    return btn;
272}