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