/src/libtomahawk/context/ContextWidget.cpp

http://github.com/tomahawk-player/tomahawk · C++ · 363 lines · 272 code · 72 blank · 19 comment · 26 complexity · a96d33ffc0cde82fcdde46a7f56bb391 MD5 · raw file

  1. /* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
  2. *
  3. * Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.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 "ContextWidget.h"
  19. #include "ui_ContextWidget.h"
  20. #include <QGraphicsProxyWidget>
  21. #include <QGraphicsScene>
  22. #include <QPropertyAnimation>
  23. #include <QTimeLine>
  24. #include "context/ContextPage.h"
  25. #include "context/pages/RelatedArtistsContext.h"
  26. #include "context/pages/TopTracksContext.h"
  27. #include "context/pages/WikipediaContext.h"
  28. #include "Source.h"
  29. #include "utils/StyleHelper.h"
  30. #include "utils/TomahawkUtilsGui.h"
  31. #define ANIMATION_TIME 450
  32. #define SLIDE_TIME 350
  33. using namespace Tomahawk;
  34. ContextWidget::ContextWidget( QWidget* parent )
  35. : QWidget( parent )
  36. , ui( new Ui::ContextWidget )
  37. , m_currentView( 0 )
  38. , m_visible( false )
  39. {
  40. ui->setupUi( this );
  41. TomahawkUtils::unmarginLayout( layout() );
  42. setContentsMargins( 0, 0, 0, 0 );
  43. m_scene = new QGraphicsScene( this );
  44. TopTracksContext* ttc = new TopTracksContext();
  45. RelatedArtistsContext* rac = new RelatedArtistsContext();
  46. WebContext* wiki = new WikipediaContext();
  47. /*WebContext* lastfm = new LastfmContext();*/
  48. m_views << ttc;
  49. m_views << rac;
  50. m_views << wiki;
  51. /* m_views << lastfm;*/
  52. foreach ( ContextPage* view, m_views )
  53. {
  54. ContextProxyPage* page = new ContextProxyPage();
  55. page->setPage( view );
  56. m_scene->addItem( page );
  57. connect( page, SIGNAL( focused() ), SLOT( onPageFocused() ) );
  58. m_pages << page;
  59. }
  60. ui->contextView->setScene( m_scene );
  61. ui->contextView->setFrameShape( QFrame::NoFrame );
  62. ui->contextView->setStyleSheet( "QGraphicsView { background: transparent; }" );
  63. ui->contextView->setAttribute( Qt::WA_MacShowFocusRect, 0 );
  64. ui->contextView->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
  65. ui->contextView->hide();
  66. QPalette whitePal = ui->toggleButton->palette();
  67. whitePal.setColor( QPalette::Foreground, Qt::white );
  68. ui->toggleButton->setPalette( whitePal );
  69. ui->toggleButton->setCursor( Qt::PointingHandCursor );
  70. m_minHeight = TomahawkUtils::defaultFontHeight() * 1.4;
  71. ui->toggleButton->setMinimumHeight( m_minHeight );
  72. setAutoFillBackground( true );
  73. setFixedHeight( m_minHeight );
  74. ensurePolished();
  75. QPalette pal = palette();
  76. pal.setBrush( QPalette::Window, QColor( "#454e59" ) );
  77. setPalette( pal );
  78. connect( ui->toggleButton, SIGNAL( clicked() ), SLOT( toggleSize() ) );
  79. m_timeLine = new QTimeLine( ANIMATION_TIME, this );
  80. m_timeLine->setUpdateInterval( 20 );
  81. m_timeLine->setEasingCurve( QEasingCurve::OutCubic );
  82. connect( m_timeLine, SIGNAL( frameChanged( int ) ), SLOT( onAnimationStep( int ) ) );
  83. connect( m_timeLine, SIGNAL( finished() ), SLOT( onAnimationFinished() ) );
  84. }
  85. ContextWidget::~ContextWidget()
  86. {
  87. }
  88. void
  89. ContextWidget::changeEvent( QEvent* e )
  90. {
  91. QWidget::changeEvent( e );
  92. switch ( e->type() )
  93. {
  94. case QEvent::LanguageChange:
  95. ui->retranslateUi( this );
  96. break;
  97. default:
  98. break;
  99. }
  100. }
  101. void
  102. ContextWidget::layoutViews( bool animate )
  103. {
  104. int smallViewWidth = 120;
  105. float smallViewOpacity = 0.6;
  106. int margin = 6;
  107. int maxVisible = 2;
  108. int itemSize = ( m_scene->sceneRect().width() - smallViewWidth * 2 ) / maxVisible;
  109. int firstPos = margin;
  110. float opacity;
  111. if ( m_currentView > 0 )
  112. firstPos = smallViewWidth;
  113. if ( m_currentView + maxVisible >= m_pages.count() )
  114. {
  115. int delta = m_pages.count() - m_currentView;
  116. firstPos = m_scene->sceneRect().width() - ( delta * itemSize ) + 1;
  117. }
  118. for ( int i = 0; i < m_pages.count(); i++ )
  119. {
  120. QGraphicsWidget* view = m_pages.at( i );
  121. int x = firstPos - ( ( m_currentView - i ) * itemSize );
  122. if ( ( x < smallViewWidth && x < firstPos ) || i > m_currentView + maxVisible - 1 )
  123. {
  124. opacity = smallViewOpacity;
  125. }
  126. else
  127. {
  128. opacity = 1.0;
  129. }
  130. {
  131. QPropertyAnimation* animation = new QPropertyAnimation( view, "opacity" );
  132. animation->setDuration( SLIDE_TIME );
  133. animation->setEndValue( opacity );
  134. animation->start();
  135. }
  136. QRect rect( x, margin, itemSize - margin * 2, m_scene->sceneRect().height() - margin * 2 );
  137. if ( animate )
  138. {
  139. {
  140. QPropertyAnimation* animation = new QPropertyAnimation( view, "geometry" );
  141. animation->setDuration( SLIDE_TIME );
  142. animation->setEndValue( rect );
  143. animation->start();
  144. }
  145. }
  146. else
  147. {
  148. view->setGeometry( rect );
  149. }
  150. }
  151. }
  152. void
  153. ContextWidget::onPageFocused()
  154. {
  155. ContextProxyPage* widget = qobject_cast< ContextProxyPage* >( sender() );
  156. int i = 0;
  157. foreach ( ContextProxyPage* view, m_pages )
  158. {
  159. if ( view == widget )
  160. {
  161. m_currentView = i;
  162. layoutViews( true );
  163. return;
  164. }
  165. i++;
  166. }
  167. }
  168. void
  169. ContextWidget::fadeOut( bool animate )
  170. {
  171. foreach ( QGraphicsWidget* view, m_pages )
  172. {
  173. if ( animate )
  174. {
  175. QPropertyAnimation* animation = new QPropertyAnimation( view, "opacity" );
  176. animation->setDuration( SLIDE_TIME );
  177. animation->setEndValue( 0.0 );
  178. animation->start();
  179. }
  180. else
  181. view->setOpacity( 0.0 );
  182. }
  183. }
  184. void
  185. ContextWidget::setArtist( const Tomahawk::artist_ptr& artist )
  186. {
  187. if ( artist.isNull() )
  188. return;
  189. m_artist = artist;
  190. if ( height() > m_minHeight )
  191. {
  192. foreach ( ContextProxyPage* proxy, m_pages )
  193. {
  194. proxy->page()->setArtist( artist );
  195. }
  196. layoutViews( true );
  197. }
  198. }
  199. void
  200. ContextWidget::setAlbum( const Tomahawk::album_ptr& album )
  201. {
  202. if ( album.isNull() )
  203. return;
  204. m_album = album;
  205. if ( height() > m_minHeight )
  206. {
  207. foreach ( ContextProxyPage* proxy, m_pages )
  208. {
  209. proxy->page()->setAlbum( album );
  210. }
  211. layoutViews( true );
  212. }
  213. }
  214. void
  215. ContextWidget::setQuery( const Tomahawk::query_ptr& query, bool force )
  216. {
  217. if ( query.isNull() )
  218. return;
  219. if ( !force && !m_query.isNull() && query->artist() == m_query->artist() )
  220. return;
  221. m_query = query;
  222. if ( height() > m_minHeight )
  223. {
  224. foreach ( ContextProxyPage* proxy, m_pages )
  225. {
  226. proxy->page()->setQuery( query );
  227. }
  228. layoutViews( true );
  229. }
  230. }
  231. void
  232. ContextWidget::toggleSize()
  233. {
  234. m_maxHeight = TomahawkUtils::tomahawkWindow()->height() * 0.3;
  235. if ( height() == m_minHeight )
  236. {
  237. m_timeLine->setFrameRange( height(), m_maxHeight );
  238. m_timeLine->setDirection( QTimeLine::Forward );
  239. m_timeLine->start();
  240. }
  241. else
  242. {
  243. m_visible = false;
  244. ui->contextView->hide();
  245. m_timeLine->setFrameRange( m_minHeight, height() );
  246. m_timeLine->setDirection( QTimeLine::Backward );
  247. m_timeLine->start();
  248. }
  249. }
  250. void
  251. ContextWidget::onAnimationStep( int frame )
  252. {
  253. setFixedHeight( frame );
  254. }
  255. void
  256. ContextWidget::onAnimationFinished()
  257. {
  258. if ( m_timeLine->direction() == QTimeLine::Forward )
  259. {
  260. setFixedHeight( m_maxHeight );
  261. m_visible = true;
  262. ui->contextView->show();
  263. fadeOut( false );
  264. m_scene->setSceneRect( ui->contextView->viewport()->rect() );
  265. layoutViews( false );
  266. setArtist( m_artist );
  267. setAlbum( m_album );
  268. setQuery( m_query, true );
  269. ui->toggleButton->setText( tr( "Hide Footnotes" ) );
  270. }
  271. else
  272. {
  273. setFixedHeight( m_minHeight );
  274. ui->toggleButton->setText( tr( "Show Footnotes" ) );
  275. }
  276. }
  277. void
  278. ContextWidget::paintEvent( QPaintEvent* e )
  279. {
  280. QWidget::paintEvent( e );
  281. }
  282. void
  283. ContextWidget::resizeEvent( QResizeEvent* e )
  284. {
  285. QWidget::resizeEvent( e );
  286. if ( m_visible )
  287. {
  288. m_scene->setSceneRect( ui->contextView->viewport()->rect() );
  289. layoutViews( false );
  290. }
  291. }