/src/libtomahawk/playlist/dynamic/widgets/CollapsibleControls.cpp

http://github.com/tomahawk-player/tomahawk · C++ · 217 lines · 154 code · 42 blank · 21 comment · 11 complexity · 67e33b2e7c3fa1b1da8b003aea02c1f0 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. * Copyright 2010-2011, Jeff Mitchell <jeff@tomahawk-player.org>
  5. *
  6. * Tomahawk is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Tomahawk is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include "CollapsibleControls.h"
  20. #include "DynamicControlList.h"
  21. #include "DynamicControlWrapper.h"
  22. #include "playlist/dynamic/GeneratorInterface.h"
  23. #include "playlist/dynamic/DynamicControl.h"
  24. #include "utils/ImageRegistry.h"
  25. #include "utils/TomahawkUtils.h"
  26. #include "widgets/ElidedLabel.h"
  27. #include "Source.h"
  28. #include <QLabel>
  29. #include <QStackedLayout>
  30. #include <QToolButton>
  31. #include <QEasingCurve>
  32. #include <QTimeLine>
  33. #include <QPaintEvent>
  34. #include <QPainter>
  35. #include "utils/Logger.h"
  36. using namespace Tomahawk;
  37. CollapsibleControls::CollapsibleControls( QWidget* parent )
  38. : QWidget( parent )
  39. , m_isLocal( true )
  40. {
  41. init();
  42. }
  43. CollapsibleControls::CollapsibleControls( const dynplaylist_ptr& playlist, bool isLocal, QWidget* parent )
  44. : QWidget( parent )
  45. , m_dynplaylist( playlist )
  46. , m_isLocal( isLocal )
  47. {
  48. init();
  49. setControls( m_dynplaylist, m_isLocal );
  50. }
  51. Tomahawk::CollapsibleControls::~CollapsibleControls()
  52. {
  53. }
  54. void
  55. CollapsibleControls::init()
  56. {
  57. m_timeline = new QTimeLine( 250, this );
  58. m_timeline->setUpdateInterval( 5 );
  59. m_animHeight = -1;
  60. m_collapseAnimation = false;
  61. connect( m_timeline, SIGNAL( frameChanged( int ) ), this, SLOT( onAnimationStep( int ) ) );
  62. connect( m_timeline, SIGNAL( finished() ), this, SLOT( onAnimationFinished() ) );
  63. m_layout = new QStackedLayout;
  64. setContentsMargins( 0, 0, 0, 0 );
  65. m_layout->setContentsMargins( 0, 0, 0, 0 );
  66. m_layout->setSpacing( 0 );
  67. m_controls = new Tomahawk::DynamicControlList( this );
  68. m_layout->addWidget( m_controls );
  69. connect( m_controls, SIGNAL( toggleCollapse() ), this, SLOT( toggleCollapse() ) );
  70. m_summaryWidget = new QWidget( this );
  71. m_summaryWidget->setMinimumHeight( 24 );
  72. m_summaryWidget->setMaximumHeight( 24 );
  73. m_summaryWidget->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
  74. m_summaryLayout = new QHBoxLayout;
  75. m_summaryWidget->setLayout( m_summaryLayout );
  76. m_summaryLayout->setMargin( 0 );
  77. m_summaryWidget->setContentsMargins( 3, 0, 0, 0 );
  78. m_summary = new ElidedLabel( m_summaryWidget );
  79. QFont f = m_summary->font();
  80. f.setPointSize( f.pointSize() + 1 );
  81. f.setBold( true );
  82. m_summary->setFont( f );
  83. m_summaryLayout->addWidget( m_summary, 1 );
  84. m_summaryExpand = DynamicControlWrapper::initButton( this );
  85. m_summaryExpand->setIcon( ImageRegistry::instance()->icon( RESPATH "images/arrow-down-double.svg" ) );
  86. m_expandL = new QStackedLayout;
  87. m_expandL->setContentsMargins( 0, 0, 0, 0 );
  88. m_expandL->setMargin( 0 );
  89. m_expandL->addWidget( m_summaryExpand );
  90. m_expandL->addWidget( DynamicControlWrapper::createDummy( m_summaryExpand, this ) );
  91. m_summaryLayout->addLayout( m_expandL );
  92. if( m_isLocal )
  93. m_expandL->setCurrentIndex( 0 );
  94. else
  95. m_expandL->setCurrentIndex( 1 );
  96. m_layout->addWidget( m_summaryWidget );
  97. connect( m_summaryExpand, SIGNAL( clicked( bool ) ), this, SLOT( toggleCollapse() ) );
  98. if( m_isLocal )
  99. m_layout->setCurrentWidget( m_controls );
  100. else
  101. m_layout->setCurrentWidget( m_summary );
  102. connect( m_controls, SIGNAL( controlChanged( Tomahawk::dyncontrol_ptr ) ), SIGNAL( controlChanged( Tomahawk::dyncontrol_ptr ) ) );
  103. connect( m_controls, SIGNAL( controlsChanged( bool ) ), SIGNAL( controlsChanged( bool ) ) );
  104. setLayout( m_layout );
  105. setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
  106. }
  107. QList< DynamicControlWrapper* >
  108. Tomahawk::CollapsibleControls::controls() const
  109. {
  110. return m_controls->controls();
  111. }
  112. void
  113. CollapsibleControls::setControls( const dynplaylist_ptr& playlist, bool isLocal )
  114. {
  115. m_dynplaylist = playlist;
  116. m_isLocal = isLocal;
  117. m_controls->setControls( m_dynplaylist->generator(), m_dynplaylist->generator()->controls() );
  118. if( !m_isLocal ) {
  119. m_expandL->setCurrentIndex( 1 );
  120. m_summary->setText( m_dynplaylist->generator()->sentenceSummary() );
  121. m_layout->setCurrentWidget( m_summaryWidget );
  122. setMaximumHeight( m_summaryWidget->sizeHint().height() );
  123. } else {
  124. m_expandL->setCurrentIndex( 0 );
  125. }
  126. }
  127. void
  128. CollapsibleControls::toggleCollapse()
  129. {
  130. // qDebug() << "TOGGLING SIZEHINTS:" << m_controls->height() << m_summaryWidget->sizeHint();
  131. m_timeline->setEasingCurve( QEasingCurve::OutBack );
  132. m_timeline->setFrameRange( m_summaryWidget->sizeHint().height(), m_controls->height() );
  133. if( m_layout->currentWidget() == m_controls ) {
  134. m_summary->setText( m_dynplaylist->generator()->sentenceSummary() );
  135. m_controls->setSizePolicy( QSizePolicy::Ignored, QSizePolicy::Ignored );
  136. m_timeline->setDirection( QTimeLine::Backward );
  137. m_timeline->start();
  138. m_collapseAnimation = true;
  139. } else {
  140. m_summaryWidget->setSizePolicy( QSizePolicy::Ignored, QSizePolicy::Ignored );
  141. m_layout->setCurrentWidget( m_controls );
  142. m_timeline->setDirection( QTimeLine::Forward );
  143. m_timeline->start();
  144. m_collapseAnimation = false;
  145. }
  146. }
  147. void
  148. CollapsibleControls::onAnimationStep( int step )
  149. {
  150. // qDebug() << "ANIMATION STEP:" << step;
  151. resize( width(), step );
  152. m_animHeight = step;
  153. setMaximumHeight( m_animHeight );
  154. }
  155. void
  156. CollapsibleControls::onAnimationFinished()
  157. {
  158. // qDebug() << "ANIMATION DONE:" << m_animHeight;
  159. setMaximumHeight( m_animHeight );
  160. m_animHeight = -1;
  161. if( m_collapseAnimation ) {
  162. m_layout->setCurrentWidget( m_summaryWidget );
  163. } else {
  164. setMaximumHeight( QWIDGETSIZE_MAX );
  165. }
  166. }
  167. QSize
  168. CollapsibleControls::sizeHint() const
  169. {
  170. if( m_animHeight >= 0 ) {
  171. return QSize( QWidget::sizeHint().width(), m_animHeight );
  172. } else {
  173. return QWidget::sizeHint();
  174. }
  175. }