PageRenderTime 374ms CodeModel.GetById 60ms app.highlight 224ms RepoModel.GetById 79ms app.codeStats 1ms

/src/libtomahawk/widgets/OverlayWidget.cpp

http://github.com/tomahawk-player/tomahawk
C++ | 241 lines | 163 code | 54 blank | 24 comment | 24 complexity | 453e6a65d668969986fcdab468969210 MD5 | raw file
  1/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
  2 *
  3 *   Copyright 2010-2014, Christian Muehlhaeuser <muesli@tomahawk-player.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
 20#include "OverlayWidget.h"
 21
 22#include "playlist/PlayableProxyModel.h"
 23#include "utils/TomahawkUtilsGui.h"
 24#include "utils/Logger.h"
 25
 26#include <QPainter>
 27#include <QPropertyAnimation>
 28
 29
 30#define CORNER_ROUNDNESS 8.0
 31#define FADING_DURATION 500
 32#define OPACITY 0.70
 33
 34
 35OverlayWidget::OverlayWidget( QWidget* parent )
 36    : QWidget( parent ) // this is on purpose!
 37    , m_parent( parent )
 38    , m_itemView( 0 )
 39{
 40    init();
 41}
 42
 43
 44OverlayWidget::OverlayWidget( QAbstractItemView* parent )
 45    : QWidget( parent ) // this is on purpose!
 46    , m_parent( parent )
 47    , m_itemView( parent )
 48{
 49    init();
 50
 51    onViewModelChanged();
 52    connect( m_itemView, SIGNAL( modelChanged() ), SLOT( onViewModelChanged() ) );
 53}
 54
 55
 56OverlayWidget::~OverlayWidget()
 57{
 58}
 59
 60
 61void
 62OverlayWidget::init()
 63{
 64    installEventFilter( m_parent );
 65    setAcceptDrops( true );
 66
 67    setAttribute( Qt::WA_TranslucentBackground, true );
 68    m_opacity = 0.00;
 69    setOpacity( m_opacity );
 70
 71    m_timer.setSingleShot( true );
 72    connect( &m_timer, SIGNAL( timeout() ), this, SLOT( hide() ) );
 73}
 74
 75
 76void
 77OverlayWidget::setOpacity( qreal opacity )
 78{
 79    m_opacity = opacity;
 80
 81    if ( m_opacity == 0.00 && !isHidden() )
 82    {
 83        QWidget::hide();
 84    }
 85    else if ( m_opacity > 0.00 && isHidden() )
 86    {
 87        QWidget::show();
 88    }
 89
 90    repaint();
 91}
 92
 93
 94void
 95OverlayWidget::setText( const QString& text )
 96{
 97    m_text = text;
 98    onViewChanged();
 99}
100
101
102void
103OverlayWidget::show( int timeoutSecs )
104{
105    if ( !isEnabled() )
106        return;
107
108    QPropertyAnimation* animation = new QPropertyAnimation( this, "opacity" );
109    animation->setDuration( FADING_DURATION );
110    animation->setEndValue( 1.0 );
111    animation->start();
112
113    if ( timeoutSecs > 0 )
114        m_timer.start( timeoutSecs * 1000 );
115}
116
117
118void
119OverlayWidget::hide()
120{
121    if ( !isEnabled() )
122        return;
123
124    QPropertyAnimation* animation = new QPropertyAnimation( this, "opacity" );
125    animation->setDuration( FADING_DURATION );
126    animation->setEndValue( 0.00 );
127    animation->start();
128}
129
130
131bool
132OverlayWidget::shown() const
133{
134    if ( !isEnabled() )
135        return false;
136
137    return m_opacity == OPACITY;
138}
139
140
141void
142OverlayWidget::onViewChanged()
143{
144    if ( !m_itemView )
145        return;
146
147    PlayableProxyModel* model = qobject_cast<PlayableProxyModel*>( m_itemView->model() );
148    if ( !model )
149        return;
150
151    if ( m_text.isEmpty() || model->rowCount( QModelIndex() ) || model->isLoading() )
152    {
153        hide();
154    }
155    else
156    {
157        show();
158    }
159}
160
161
162void
163OverlayWidget::onViewModelChanged()
164{
165    if ( !m_itemView )
166        return;
167
168    if ( m_itemView->model() )
169    {
170        connect( m_itemView->model(), SIGNAL( rowsInserted( QModelIndex, int, int ) ), SLOT( onViewChanged() ), Qt::UniqueConnection );
171        connect( m_itemView->model(), SIGNAL( rowsRemoved( QModelIndex, int, int ) ), SLOT( onViewChanged() ), Qt::UniqueConnection );
172        connect( m_itemView->model(), SIGNAL( loadingStarted() ), SLOT( onViewChanged() ), Qt::UniqueConnection );
173        connect( m_itemView->model(), SIGNAL( loadingFinished() ), SLOT( onViewChanged() ), Qt::UniqueConnection );
174
175        onViewChanged();
176    }
177}
178
179
180void
181OverlayWidget::paintEvent( QPaintEvent* event )
182{
183    Q_UNUSED( event );
184
185    {
186        QSize maxiSize = QSize( (double)m_parent->width() * 0.70, (double)m_parent->height() * 0.70 );
187        QSize prefSize = QSize( 380, 128 );
188        int width = qMin( maxiSize.width(), prefSize.width() );
189        int height = qMin( maxiSize.height(), prefSize.height() );
190        QSize newSize = QSize( width, height );
191
192        if ( newSize != size() )
193            resize( newSize );
194    }
195
196    QPoint center( ( m_parent->width() - width() ) / 2, ( m_parent->height() - height() ) / 2 );
197    if ( center != pos() )
198    {
199        move( center );
200    }
201
202    QPainter p( this );
203    QRect r = contentsRect();
204
205    p.setBackgroundMode( Qt::TransparentMode );
206    p.setRenderHint( QPainter::Antialiasing );
207    p.setOpacity( m_opacity );
208
209/*    QPen pen( palette().dark().color(), .5 );
210    p.setPen( pen );
211    //FIXME const color
212    p.setBrush( QColor( 30, 30, 30, 255.0 * OPACITY ) );
213    p.drawRoundedRect( r, CORNER_ROUNDNESS, CORNER_ROUNDNESS );*/
214
215    QTextOption to( Qt::AlignCenter );
216    to.setWrapMode( QTextOption::WrapAtWordBoundaryOrAnywhere );
217
218    // shrink to fit if needed
219    QFont f( font() );
220    f.setPointSize( TomahawkUtils::defaultFontSize() + 7 );
221    f.setBold( true );
222
223    QRectF textRect = r.adjusted( 8, 8, -8, -8 );
224    qreal availHeight = textRect.height();
225
226    QFontMetricsF fm( f );
227    qreal textHeight = fm.boundingRect( textRect, Qt::AlignCenter | Qt::TextWordWrap, text() ).height();
228    while ( textHeight > availHeight )
229    {
230        if ( f.pointSize() <= 4 ) // don't try harder
231            break;
232
233        f.setPointSize( f.pointSize() - 1 );
234        fm = QFontMetricsF( f );
235        textHeight = fm.boundingRect( textRect, Qt::AlignCenter | Qt::TextWordWrap, text() ).height();
236    }
237
238    p.setFont( f );
239    p.setPen( Qt::gray );
240    p.drawText( r.adjusted( 8, 8, -8, -8 ), text(), to );
241}