PageRenderTime 322ms CodeModel.GetById 110ms app.highlight 97ms RepoModel.GetById 105ms app.codeStats 0ms

/src/libtomahawk/widgets/Breadcrumb.cpp

http://github.com/tomahawk-player/tomahawk
C++ | 174 lines | 108 code | 31 blank | 35 comment | 8 complexity | c544d1aa70dd10c65deff3ad3de860b1 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 "Breadcrumb.h"
 20
 21#include "BreadcrumbButton.h"
 22#include "utils/TomahawkStyle.h"
 23#include "utils/TomahawkUtilsGui.h"
 24#include "utils/Logger.h"
 25
 26#include <QStylePainter>
 27#include <QPushButton>
 28#include <QHBoxLayout>
 29#include <QPropertyAnimation>
 30#include <QDebug>
 31
 32using namespace Tomahawk;
 33
 34Breadcrumb::Breadcrumb( QWidget* parent, Qt::WindowFlags f )
 35    : QWidget( parent, f )
 36    , m_model( 0 )
 37    , m_buttonlayout( new QHBoxLayout( this ) )
 38{
 39    TomahawkUtils::unmarginLayout( m_buttonlayout );
 40    m_buttonlayout->setAlignment( Qt::AlignLeft );
 41
 42    setAutoFillBackground( true );
 43    setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
 44
 45    setLayoutDirection( Qt::LeftToRight );
 46    setLayout( m_buttonlayout );
 47    show();
 48}
 49
 50
 51Breadcrumb::~Breadcrumb()
 52{
 53}
 54
 55
 56void
 57Breadcrumb::setModel( QAbstractItemModel* model )
 58{
 59    foreach ( BreadcrumbButton* b, m_buttons )
 60        b->deleteLater();;
 61    m_buttons.clear();
 62
 63    m_model = model;
 64    updateButtons( QModelIndex() );
 65}
 66
 67
 68void
 69Breadcrumb::setRootIcon( const QPixmap& pm )
 70{
 71    m_rootIcon = TomahawkUtils::tinted( pm, Qt::white );
 72
 73    QPushButton* button = new QPushButton( QIcon( m_rootIcon ), "", this );
 74    button->setFlat( true );
 75    button->setStyleSheet( "QPushButton{ background-color: transparent; border: none; width:36px; height:36px; }" );
 76    m_buttonlayout->insertWidget( 0, button );
 77    m_buttonlayout->insertSpacing( 0, 5 );
 78    m_buttonlayout->insertSpacing( 2, 5 );
 79}
 80
 81
 82void
 83Breadcrumb::paintEvent( QPaintEvent* )
 84{
 85    QStylePainter p( this );
 86    TomahawkStyle::horizontalHeader( &p, rect() );
 87}
 88
 89
 90// updateFrom is the item that has changed---all children must be recomputed
 91// if invalid, redo the whole breadcrumb
 92void
 93Breadcrumb::updateButtons( const QModelIndex& updateFrom )
 94{
 95//     qDebug() << "Updating buttons:" << updateFrom.data();
 96    int cur = 0;
 97    QModelIndex idx = updateFrom;
 98    for ( int i = 0; i < m_buttons.count(); i++ )
 99    {
100//         qDebug() << "Checking if this breadcrumb item changed:" << m_buttons[ i ]->currentIndex().data() << updateFrom.data() << ( m_buttons[ i ]->currentIndex() != updateFrom);
101        if ( m_buttons[ i ]->currentIndex() == updateFrom )
102        {
103            cur = i;
104            break;
105        }
106    }
107
108    // We set the parent index, so go up one
109    idx = idx.parent();
110
111    // Ok, changed all indices that are at cur or past it. lets update them
112    // When we get to the "end" of the tree, the leaf node is the chart itself
113//     qDebug() << "DONE and beginning iteration:" << idx.data();
114    while ( m_model->rowCount( idx ) > 0 )
115    {
116//         qDebug() << "CHANGED AND iterating:" << idx.data();
117        BreadcrumbButton* btn = 0;
118        if ( m_buttons.size() <= cur )
119        {
120            // We have to create a new button, doesn't exist yet
121            btn = new BreadcrumbButton( this, m_model );
122            connect( btn, SIGNAL( currentIndexChanged( QModelIndex ) ), this, SLOT( breadcrumbComboChanged( QModelIndex ) ) );
123
124            m_buttonlayout->addWidget( btn );
125            btn->show();
126
127            // Animate all buttons except the first
128            if ( !m_buttons.isEmpty() && isVisible() )
129            {
130                QPropertyAnimation* animation = new QPropertyAnimation( btn, "pos" );
131                animation->setDuration( 300 );
132                animation->setStartValue( m_buttons.last()->pos() );
133                animation->setEndValue( btn->pos() );
134                animation->start( QAbstractAnimation::DeleteWhenStopped );
135            }
136
137            m_buttons.append( btn );
138        }
139        else
140        {
141            // Got a button already, we just want to change the contents
142            btn = m_buttons[ cur ];
143        }
144
145        // The children of idx are what populates this combobox.
146        // It takes care of setting the default/user-populated value.
147        btn->setParentIndex( idx );
148
149        // Repeat with children
150        idx = btn->currentIndex();
151
152        cur++;
153    }
154
155    // extra buttons to delete! (cur is 0-indexed)
156    while ( m_buttons.size() > cur )
157    {
158        BreadcrumbButton* b = m_buttons.takeLast();
159        m_buttonlayout->removeWidget( b );
160        b->deleteLater();
161    }
162
163    // Now we're at the leaf, lets activate the chart
164    emit activateIndex( idx );
165}
166
167
168void
169Breadcrumb::breadcrumbComboChanged( const QModelIndex& childSelected )
170{
171    // Some breadcrumb buttons' combobox changed. lets update the child breadcrumbs
172    tDebug() << "Combo changed:" << childSelected.data();
173    updateButtons( childSelected );
174}