/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. #include "playlist/dynamic/echonest/EchonestSteerer.h"
  19. #include "Source.h"
  20. #include "playlist/dynamic/widgets/DynamicWidget.h"
  21. #include "utils/ImageRegistry.h"
  22. #include "utils/TomahawkUtils.h"
  23. #include "utils/Logger.h"
  24. #include <echonest5/Playlist.h>
  25. #include <QPaintEvent>
  26. #include <QHBoxLayout>
  27. #include <QLineEdit>
  28. #include <QComboBox>
  29. #include <QLabel>
  30. #include <QPainter>
  31. #include <QToolButton>
  32. #include <QPropertyAnimation>
  33. using namespace Tomahawk;
  34. #define ANIM_DURATION 300
  35. EchonestSteerer::EchonestSteerer( QWidget* parent )
  36. : QWidget( parent )
  37. , m_layout( new QHBoxLayout )
  38. , m_amplifier( 0 )
  39. , m_field( 0 )
  40. , m_description( 0 )
  41. , m_textL( new QVBoxLayout )
  42. , m_steerTop( 0 )
  43. , m_steerBottom( 0 )
  44. , m_reset( 0 )
  45. , m_expanding( true )
  46. {
  47. m_layout->setContentsMargins( 8, 8, 8, 8 );
  48. m_textL->setSpacing( 0 );
  49. m_steerTop = new QLabel( tr( "Steer this station:" ), this );
  50. QFont f = m_steerTop->font();
  51. f.setPointSize( f.pointSize() + 2 );
  52. f.setBold( true );
  53. m_steerTop->setFont( f );
  54. m_textL->addWidget( m_steerTop );
  55. // m_steerBottom = new QLabel( tr( "Takes effect on track change" ), this );
  56. // f.setPointSize( f.pointSize() - 3 );
  57. // m_steerBottom->setFont( f );
  58. // m_textL->addWidget( m_steerBottom );
  59. QPalette p = m_steerTop->palette();
  60. #ifdef Q_OS_MAC
  61. p.setBrush( QPalette::WindowText, Qt::white );
  62. #else
  63. p.setBrush( QPalette::WindowText, palette().highlightedText() );
  64. #endif
  65. m_steerTop->setPalette( p );
  66. m_layout->addLayout( m_textL, 1 );
  67. m_amplifier = new QComboBox( this );
  68. m_amplifier->addItem( tr( "Much less" ), "^.1" );
  69. m_amplifier->addItem( tr( "Less" ), "^.5" );
  70. m_amplifier->addItem( tr( "A bit less" ), "^.75" );
  71. m_amplifier->addItem( tr( "Keep at current", "" ) );
  72. m_amplifier->addItem( tr( "A bit more" ), "^1.25" );
  73. m_amplifier->addItem( tr( "More" ), "^1.5" );
  74. m_amplifier->addItem( tr( "Much more" ), "^2" );
  75. m_amplifier->setCurrentIndex( 3 );
  76. m_field = new QComboBox( this );
  77. m_field->addItem( tr( "Tempo" ), "tempo");
  78. m_field->addItem( tr( "Loudness" ), "loudness");
  79. m_field->addItem( tr( "Danceability" ), "danceability");
  80. m_field->addItem( tr( "Energy" ), "energy");
  81. m_field->addItem( tr( "Song Hotttnesss" ), "tempo");
  82. m_field->addItem( tr( "Artist Hotttnesss" ), "artist_hotttnesss");
  83. m_field->addItem( tr( "Artist Familiarity" ), "artist_familiarity");
  84. m_field->addItem( tr( "By Description" ), "desc");
  85. m_layout->addWidget( m_amplifier );
  86. m_layout->addWidget( m_field );
  87. connect( m_amplifier, SIGNAL( currentIndexChanged( int ) ), this, SLOT( changed() ) );
  88. connect( m_field, SIGNAL( currentIndexChanged( int ) ), this, SLOT( changed() ) );
  89. m_description = new QLineEdit( this );
  90. m_description->setPlaceholderText( tr( "Enter a description" ) );
  91. m_description->hide();
  92. connect( m_description, SIGNAL( textChanged( QString ) ), this, SLOT( changed() ) );
  93. m_apply = initButton( this );
  94. m_apply->setIcon( ImageRegistry::instance()->icon( RESPATH "images/apply-check.svg" ) );
  95. m_apply->setToolTip( tr( "Apply steering command" ) );
  96. m_layout->addWidget( m_apply );
  97. connect( m_apply, SIGNAL( clicked( bool ) ), this, SLOT( applySteering() ) );
  98. m_reset = initButton( this );
  99. m_reset->setIcon( ImageRegistry::instance()->icon( RESPATH "images/view-refresh.svg" ) );
  100. m_reset->setToolTip( tr( "Reset all steering commands" ) );
  101. m_layout->addWidget( m_reset );
  102. connect( m_reset, SIGNAL( clicked( bool ) ), this, SLOT( resetSteering( bool ) ) );
  103. setLayout( m_layout );
  104. setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
  105. m_resizeAnim.setDuration( ANIM_DURATION );
  106. m_resizeAnim.setEasingCurve( QEasingCurve::InOutQuad );
  107. m_resizeAnim.setDirection( QTimeLine::Forward );
  108. m_resizeAnim.setUpdateInterval( 8 );
  109. connect( &m_resizeAnim, SIGNAL( frameChanged( int ) ), this, SLOT( resizeFrame( int ) ) );
  110. m_fadeAnim = new QPropertyAnimation( this, "opacity", this );
  111. m_fadeAnim->setDuration( ANIM_DURATION );
  112. m_fadeAnim->setStartValue( 0 );
  113. m_fadeAnim->setEndValue( .7 );
  114. resize( sizeHint() );
  115. }
  116. void
  117. EchonestSteerer::paintEvent( QPaintEvent* )
  118. {
  119. QPainter p( this );
  120. QRect r = contentsRect();
  121. QPalette pal = palette();
  122. DynamicWidget::paintRoundedFilledRect( p, pal, r, m_opacity );
  123. }
  124. void
  125. EchonestSteerer::setOpacity( qreal opacity )
  126. {
  127. m_opacity = opacity;
  128. if( m_opacity == 0 )
  129. hide();
  130. repaint();
  131. }
  132. void
  133. EchonestSteerer::fadeIn()
  134. {
  135. m_fadeAnim->setDirection( QAbstractAnimation::Forward );
  136. m_fadeAnim->start();
  137. show();
  138. }
  139. void
  140. EchonestSteerer::fadeOut()
  141. {
  142. m_fadeAnim->setDirection( QAbstractAnimation::Backward );
  143. m_fadeAnim->start();
  144. }
  145. void
  146. EchonestSteerer::changed()
  147. {
  148. if( m_field->itemData( m_field->currentIndex() ).toString() != "desc" ) {
  149. // if description was shown, animate to shrink
  150. if( m_layout->indexOf( m_description ) > 0 ) {
  151. m_expanding = false;
  152. int start = width();
  153. int end = start - m_layout->spacing() - m_description->sizeHint().width();;
  154. m_layout->removeWidget( m_description );
  155. m_description->hide();
  156. m_layout->setStretchFactor( m_textL, 1 );
  157. m_resizeAnim.setFrameRange( start, end );
  158. m_resizeAnim.start();
  159. }
  160. } else { // description, so put in the description field
  161. if( m_layout->indexOf( m_description ) == -1 ) {
  162. // animate to expand
  163. m_layout->insertWidget( m_layout->count() - 1, m_description, 1 );
  164. m_layout->setStretchFactor( m_textL, 0 );
  165. m_description->show();
  166. m_expanding = true;
  167. int start = width();
  168. int end = start + m_layout->spacing() + m_description->sizeHint().width();
  169. m_resizeAnim.setFrameRange( start, end );
  170. m_resizeAnim.start();
  171. }
  172. }
  173. }
  174. void
  175. EchonestSteerer::applySteering()
  176. {
  177. if ( m_field->itemData( m_field->currentIndex() ).toString() != "desc" )
  178. {
  179. QString steer = m_field->itemData( m_field->currentIndex() ).toString() + m_amplifier->itemData( m_amplifier->currentIndex() ).toString();
  180. emit steerField( steer );
  181. }
  182. else
  183. {
  184. if ( !m_description->text().isEmpty() )
  185. {
  186. QString steer = m_description->text() + m_amplifier->itemData( m_amplifier->currentIndex() ).toString();
  187. emit steerDescription( steer );
  188. }
  189. }
  190. emit steeringChanged();
  191. resetSteering( true );
  192. }
  193. void
  194. EchonestSteerer::resizeFrame( int width )
  195. {
  196. // qDebug() << "RESIZING TO:" << width;
  197. resize( width, sizeHint().height() );
  198. repaint();
  199. emit resized();
  200. }
  201. void
  202. EchonestSteerer::resetSteering( bool automatic )
  203. {
  204. m_amplifier->setCurrentIndex( 3 );
  205. if( !automatic ) {
  206. m_description->clear();
  207. m_field->setCurrentIndex( 0 );
  208. emit reset();
  209. }
  210. }
  211. QToolButton*
  212. EchonestSteerer::initButton( QWidget* parent )
  213. {
  214. QToolButton* btn = new QToolButton( parent );
  215. btn->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
  216. btn->setIconSize( QSize( 14, 14 ) );
  217. btn->setToolButtonStyle( Qt::ToolButtonIconOnly );
  218. btn->setAutoRaise( true );
  219. btn->setContentsMargins( 0, 0, 0, 0 );
  220. return btn;
  221. }