PageRenderTime 73ms CodeModel.GetById 20ms app.highlight 31ms RepoModel.GetById 19ms app.codeStats 0ms

/src/libtomahawk/widgets/BreadcrumbButton.cpp

http://github.com/tomahawk-player/tomahawk
C++ | 197 lines | 134 code | 39 blank | 24 comment | 13 complexity | 2c0fd87dfc89a213367cc3a1f996639c MD5 | raw file
  1/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
  2 *
  3 *   Copyright 2011, Casey Link <unnamedrambler@gmail.com>
  4 *   Copyright 2010-2011, Leo Franchi <lfranchi@kde.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
 20#include "BreadcrumbButton.h"
 21
 22#include "Breadcrumb.h"
 23#include "ComboBox.h"
 24#include "utils/TomahawkStyle.h"
 25#include "utils/TomahawkUtilsGui.h"
 26#include "utils/Logger.h"
 27
 28#include <QPaintEvent>
 29#include <QPainter>
 30#include <QHBoxLayout>
 31
 32using namespace Tomahawk;
 33
 34class BreadcrumbArrow : public QWidget
 35{
 36public:
 37    BreadcrumbArrow( QWidget* parent )
 38        : QWidget(parent)
 39    {
 40        setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
 41    }
 42
 43protected:
 44    virtual void paintEvent( QPaintEvent* ) {
 45        QPainter p( this );
 46        QStyleOption opt;
 47        opt.initFrom( this );
 48        QRect r = rect();
 49
 50        const bool reverse = opt.direction == Qt::RightToLeft;
 51        const int menuButtonWidth = 12;
 52        const int rightSpacing = 10;
 53        const int right = !reverse ? r.right() - rightSpacing : r.left() + menuButtonWidth;
 54        const int height = r.height();
 55
 56        QLine l1( 1, 0, right, height / 2 );
 57        QLine l2( 1, height, right, height / 2 );
 58
 59        p.setRenderHint( QPainter::Antialiasing, true );
 60
 61        // Draw the shadow
 62        QColor shadow( 0, 0, 0, 100 );
 63        p.translate( 0, 1 );
 64        p.setPen( shadow );
 65        p.drawLine( l1 );
 66        p.drawLine( l2 );
 67
 68        // Draw the main arrow
 69        QColor foreGround( "#747474" );
 70        p.translate( 0, -1 );
 71        p.setPen( foreGround );
 72        p.drawLine( l1 );
 73        p.drawLine( l2 );
 74    }
 75
 76    virtual QSize sizeHint() const
 77    {
 78        return QSize( 20, TomahawkUtils::defaultFontHeight() + 8 );
 79    }
 80
 81};
 82
 83BreadcrumbButton::BreadcrumbButton( Breadcrumb* parent, QAbstractItemModel* model )
 84    : QWidget( parent )
 85    , m_breadcrumb( parent )
 86    , m_model( model )
 87    , m_combo( new ComboBox( this ) )
 88    , m_arrow( new BreadcrumbArrow( this ) )
 89{
 90    setLayout( new QHBoxLayout );
 91
 92    TomahawkUtils::unmarginLayout( layout() );
 93    layout()->addWidget( m_combo );
 94    layout()->addWidget( m_arrow );
 95
 96    setFixedHeight( TomahawkUtils::defaultFontHeight() + 8 );
 97    m_combo->setSizeAdjustPolicy( QComboBox::AdjustToContents );
 98
 99    setSizePolicy( QSizePolicy::Maximum, QSizePolicy::Expanding );
100
101    connect( m_combo, SIGNAL( activated( int ) ), SLOT( comboboxActivated( int ) ) );
102}
103
104
105void
106BreadcrumbButton::paintEvent( QPaintEvent* )
107{
108    QPainter p( this );
109
110    TomahawkStyle::horizontalHeader( &p, rect() ); // draw the background
111    m_arrow->setVisible( hasChildren() );
112}
113
114
115QSize
116BreadcrumbButton::sizeHint() const
117{
118    // our width = width of combo + 20px for right-arrow and spacing
119    const int padding = hasChildren() ? 20 : 8;
120    return m_combo->sizeHint() + QSize( padding, 0 );
121}
122
123
124void
125BreadcrumbButton::setParentIndex( const QModelIndex& idx )
126{
127    m_parentIndex = idx;
128    // Populate listview with list of children.
129    // Then try to find a default
130    QStringList list;
131    int count = m_model->rowCount( m_parentIndex );
132    int defaultIndex = -1, userSelected = -1;
133    for ( int i = 0; i < count; ++i )
134    {
135        QModelIndex idx = m_model->index( i, 0, m_parentIndex );
136        if ( idx.isValid() )
137        {
138            list << idx.data().toString();
139            if ( idx.data( Breadcrumb::DefaultRole ).toBool() )
140                defaultIndex = i;
141            if ( idx.data( Breadcrumb::UserSelectedRole ).toBool() )
142                userSelected = i;
143        }
144    }
145
146    if ( m_combo->count() && !list.isEmpty() )
147    {
148        // Check if it's the same, Don't change if it is, as it'll cause flickering
149        QStringList old;
150        for ( int i = 0; i < m_combo->count(); i++ )
151            old << m_combo->itemText( i );
152
153        if ( list == old )
154            return;
155    }
156
157    m_combo->hide();
158    m_combo->clear();
159    m_combo->addItems( list );
160
161    if ( userSelected > -1 )
162        m_combo->setCurrentIndex( userSelected );
163    else if ( defaultIndex > -1 )
164        m_combo->setCurrentIndex( defaultIndex );
165
166    m_curIndex = m_model->index( m_combo->currentIndex(), 0, m_parentIndex );
167
168    m_combo->show();
169    m_combo->adjustSize();
170}
171
172
173void
174BreadcrumbButton::comboboxActivated( int idx )
175{
176    m_model->setData( m_curIndex, false, Breadcrumb::UserSelectedRole );
177
178    QModelIndex selected = m_model->index( idx, 0, m_parentIndex );
179    m_curIndex = selected;
180    m_model->setData( selected, true, Breadcrumb::UserSelectedRole );
181
182    emit currentIndexChanged( selected );
183}
184
185
186bool
187BreadcrumbButton::hasChildren() const
188{
189    return m_model->rowCount( m_model->index( m_combo->currentIndex(), 0, m_parentIndex ) ) > 0;
190}
191
192
193QModelIndex
194BreadcrumbButton::currentIndex() const
195{
196    return m_model->index( m_combo->currentIndex(), 0, m_parentIndex );
197}