Warning, file /multimedia/amarok/src/widgets/IconButton.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /**************************************************************************************** 0002 * Copyright (c) 2009 Thomas Luebking <thomas.luebking@web.de> * 0003 * * 0004 * This program is free software; you can redistribute it and/or modify it under * 0005 * the terms of the GNU General Public License as published by the Free Software * 0006 * Foundation; either version 2 of the License, or (at your option) any later * 0007 * version. * 0008 * * 0009 * This program is distributed in the hope that it will be useful, but WITHOUT ANY * 0010 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * 0011 * PARTICULAR PURPOSE. See the GNU General Public License for more details. * 0012 * * 0013 * You should have received a copy of the GNU General Public License along with * 0014 * this program. If not, see <http://www.gnu.org/licenses/>. * 0015 ****************************************************************************************/ 0016 0017 #include "IconButton.h" 0018 #include "SvgHandler.h" 0019 0020 #include <QMouseEvent> 0021 #include <QPainter> 0022 #include <QSizePolicy> 0023 #include <QTimerEvent> 0024 #include <QToolBar> 0025 0026 IconButton::IconButton( QWidget *parent ) : QWidget( parent ) 0027 , m_isClick( false ) 0028 { 0029 m_anim.step = 0; 0030 m_anim.timer = 0; 0031 setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ); 0032 0033 // cannot use paletteChanged() from the palette handler directly since the 0034 // svg handler also watches it for retinting. So upon palette change, we are 0035 // called first and the old svg icons will be used. 0036 connect( The::svgHandler(), &SvgHandler::retinted, this, &IconButton::svgRetinted ); 0037 } 0038 0039 void IconButton::setIcon( const QImage &img, int steps ) 0040 { 0041 m_anim.step = 0; 0042 m_anim.steps = steps; 0043 0044 m_icon = img; 0045 m_oldIcon = steps ? m_buffer.image : QImage(); 0046 0047 if ( m_anim.timer ) 0048 killTimer( m_anim.timer ); 0049 if ( steps ) 0050 m_anim.timer = startTimer( 40 ); 0051 else 0052 updateIconBuffer(); 0053 repaint(); 0054 } 0055 0056 0057 void IconButton::mousePressEvent( QMouseEvent *me ) 0058 { 0059 me->accept(); 0060 m_isClick = true; 0061 } 0062 0063 void IconButton::mouseReleaseEvent( QMouseEvent *me ) 0064 { 0065 me->accept(); 0066 if ( m_isClick && rect().contains( me->pos() ) ) 0067 { 0068 m_isClick = false; 0069 Q_EMIT clicked(); 0070 } 0071 } 0072 0073 void IconButton::paintEvent( QPaintEvent * ) 0074 { 0075 QPainter p(this); 0076 p.setRenderHint( QPainter::SmoothPixmapTransform ); 0077 p.drawPixmap( 0, 0, width(), height(), m_buffer.pixmap ); 0078 p.end(); 0079 } 0080 0081 void IconButton::svgRetinted() 0082 { 0083 reloadContent( size() ); 0084 } 0085 0086 void IconButton::resizeEvent( QResizeEvent *re ) 0087 { 0088 if( width() != height() ) 0089 resize( height(), height() ); 0090 else 0091 { 0092 reloadContent( re->size() ); 0093 QWidget::resizeEvent( re ); 0094 } 0095 } 0096 0097 QSize IconButton::sizeHint() const 0098 { 0099 if ( QToolBar *toolBar = qobject_cast<QToolBar*>( parentWidget() ) ) 0100 return toolBar->iconSize(); 0101 0102 return QSize( 32, 32 ); 0103 } 0104 0105 void IconButton::timerEvent( QTimerEvent *te ) 0106 { 0107 if ( te->timerId() != m_anim.timer ) 0108 return; 0109 0110 ++m_anim.step; 0111 updateIconBuffer(); 0112 if ( m_anim.step >= m_anim.steps ) 0113 { 0114 killTimer( m_anim.timer ); 0115 m_anim.timer = 0; 0116 m_oldIcon = QImage(); 0117 } 0118 repaint(); 0119 } 0120 0121 static QImage adjusted( QImage img, const QSize &sz ) 0122 { 0123 QSize doublesz( sz.width()*2, sz.height()*2 ); 0124 if ( img.size() == doublesz ) //double size render to have better looking high-dpi toolbar 0125 return img; 0126 QImage ret( doublesz, QImage::Format_ARGB32_Premultiplied ); 0127 ret.fill( Qt::transparent ); 0128 QPainter p( &ret ); 0129 int xcentershift=(ret.width() - img.width()) /2; 0130 int ycentershift=(ret.height() - img.height()) /2; 0131 if(xcentershift<0) 0132 xcentershift=0; 0133 if(ycentershift<0) 0134 ycentershift=0; 0135 p.drawImage( xcentershift, ycentershift, img ); 0136 p.end(); 0137 return ret; 0138 } 0139 0140 static inline QImage interpolated( const QImage &img1, const QImage &img2, int a1, int a2 ) 0141 { 0142 const int a = a1 + a2; 0143 if (!a) 0144 return img1.copy(); 0145 0146 QImage img( img1.size(), img1.format() ); 0147 0148 const uchar *src[2] = { img1.bits(), img2.bits() }; 0149 uchar *dst = img.bits(); 0150 const int n = img.width()*img.height()*4; 0151 for ( int i = 0; i < n; ++i ) 0152 { 0153 *dst = ((*src[0]*a1 + *src[1]*a2)/a) & 0xff; 0154 ++dst; ++src[0]; ++src[1]; 0155 } 0156 return img; 0157 } 0158 0159 void IconButton::updateIconBuffer() 0160 { 0161 if ( m_anim.step >= m_anim.steps ) 0162 m_buffer.image = adjusted( m_icon, size() ); 0163 else 0164 m_buffer.image = interpolated( adjusted( m_oldIcon, size() ), adjusted( m_icon, size() ), 0165 m_anim.steps - m_anim.step, m_anim.step ); 0166 0167 m_buffer.pixmap = QPixmap::fromImage( m_buffer.image ); 0168 } 0169 0170