File indexing completed on 2024-05-05 04:49:30

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 "TrackActionButton.h"
0018 
0019 #include <QAction>
0020 #include <QEvent>
0021 #include <QTimer>
0022 
0023 TrackActionButton::TrackActionButton( QWidget *parent, const QAction *act ) : IconButton( parent )
0024 {
0025     if ( act )
0026         setAction( act );
0027     if ( parent )
0028         parent->installEventFilter( this );
0029     // this is during the labelslide - so we wait a short time with image processing ;-)
0030     QTimer::singleShot( 1200, this, &TrackActionButton::init );
0031 }
0032 
0033 bool TrackActionButton::eventFilter( QObject *o, QEvent *e )
0034 {
0035     if ( o == parentWidget() )
0036     {
0037         if ( e->type() == QEvent::Enter )
0038             setIcon( m_icon.image[1], 3 );
0039         else if ( e->type() == QEvent::Leave )
0040             setIcon( m_icon.image[0], 6 );
0041     }
0042     return false;
0043 }
0044 
0045 void TrackActionButton::enterEvent( QEvent *e )
0046 {
0047     setIcon( m_icon.image[2], 3 );
0048     IconButton::enterEvent( e );
0049 }
0050 
0051 void TrackActionButton::init()
0052 {
0053     reloadContent( size() );
0054 }
0055 
0056 void TrackActionButton::leaveEvent( QEvent *e )
0057 {
0058     setIcon( m_icon.image[1], 6 );
0059     IconButton::leaveEvent( e );
0060 }
0061 
0062 void TrackActionButton::reloadContent( const QSize &sz )
0063 {
0064     if ( sz.isNull() )
0065         return;
0066     int r,g,b;
0067     palette().color(foregroundRole()).getRgb(&r,&g,&b);
0068     //double size render to have better looking high-dpi toolbar
0069     m_icon.image[2] = m_icon.icon.pixmap( QSize( sz.width()*2, sz.height()*2 ) ).toImage();
0070     QImage img = m_icon.image[2].convertToFormat(QImage::Format_ARGB32);
0071     int n = img.width() * img.height();
0072     
0073     const uchar *bits = img.bits();
0074     QRgb *pixel = (QRgb*)(const_cast<uchar*>(bits));
0075 
0076     // this creates a (slightly) translucent monochromactic version of the
0077     // image using the foreground color
0078     // the gray value is turned into the opacity
0079 #define ALPHA qAlpha(pixel[i])
0080 #define GRAY qGray(pixel[i])
0081     if ( qMax( qMax(r,g), b ) > 128 ) // value > 50%, bright foreground
0082         for (int i = 0; i < n; ++i)
0083             pixel[i] = qRgba( r,g,b, ( ALPHA * ( (160*GRAY) / 255 ) ) / 255 );
0084     else // inverse
0085         for (int i = 0; i < n; ++i)
0086             pixel[i] = qRgba( r,g,b, ( ALPHA * ( (160*(255-GRAY)) / 255 ) ) / 255 );
0087 
0088     // premultiplied is much faster on painting / alphablending
0089     m_icon.image[1] = img.convertToFormat(QImage::Format_ARGB32_Premultiplied);
0090 
0091     // and a very translucent variant
0092     for (int i = 0; i < n; ++i)
0093         pixel[i] = qRgba(r,g,b, ALPHA/3);
0094 
0095 #undef ALPHA
0096 #undef GRAY
0097 
0098     m_icon.image[0] = img.convertToFormat(QImage::Format_ARGB32_Premultiplied);
0099 
0100     int i = 0;
0101     if ( underMouse() )
0102         i = 2;
0103     else if ( !parentWidget() || parentWidget()->underMouse() )
0104         i = 1;
0105 
0106     setIcon( m_icon.image[i] );
0107 }
0108 
0109 void TrackActionButton::setAction( const QAction *act )
0110 {
0111     disconnect( this, &TrackActionButton::clicked, nullptr, nullptr );
0112     m_action = act;
0113     if ( act )
0114     {
0115         m_icon.icon = act->icon();
0116         setToolTip( act->toolTip() );
0117         connect ( this, &TrackActionButton::clicked, act, &QAction::trigger );
0118         connect ( act, &QAction::changed, this, &TrackActionButton::updateAction );
0119     }
0120     else
0121     {
0122         m_icon.icon = QIcon();
0123         setToolTip( QString() );
0124     }
0125 }
0126 
0127 QSize TrackActionButton::sizeHint() const
0128 {
0129     return QSize( 24, 24 );
0130 }
0131 
0132 void TrackActionButton::updateAction()
0133 {
0134     if ( QAction *act = qobject_cast<QAction*>(sender()) )
0135     {
0136         if ( act == m_action )
0137         {
0138             m_icon.icon = act->icon();
0139             setToolTip( act->toolTip() );
0140         }
0141         else // old action, stop listening
0142             disconnect ( act, &QAction::changed, this, &TrackActionButton::updateAction );
0143     }
0144 }
0145