|
QGIS API Documentation
master-3f58142
|
00001 /*************************************************************************** 00002 qgscolorbutton.cpp - Button which displays a color 00003 -------------------------------------- 00004 Date : 12-Dec-2006 00005 Copyright : (C) 2006 by Tom Elwertowski 00006 Email : telwertowski at users dot sourceforge dot net 00007 *************************************************************************** 00008 * * 00009 * This program is free software; you can redistribute it and/or modify * 00010 * it under the terms of the GNU General Public License as published by * 00011 * the Free Software Foundation; either version 2 of the License, or * 00012 * (at your option) any later version. * 00013 * * 00014 ***************************************************************************/ 00015 00016 #include "qgscolorbutton.h" 00017 #include "qgscolordialog.h" 00018 #include "qgsapplication.h" 00019 #include "qgslogger.h" 00020 00021 #include <QPainter> 00022 #include <QSettings> 00023 #include <QTemporaryFile> 00024 00041 QgsColorButton::QgsColorButton( QWidget *parent, QString cdt, QColorDialog::ColorDialogOptions cdo ) 00042 : QPushButton( parent ) 00043 , mColorDialogTitle( cdt.isEmpty() ? tr( "Select Color" ) : cdt ) 00044 , mColor( Qt::black ) 00045 , mColorDialogOptions( cdo ) 00046 , mAcceptLiveUpdates( true ) 00047 , mTempPNG( NULL ) 00048 { 00049 connect( this, SIGNAL( clicked() ), this, SLOT( onButtonClicked() ) ); 00050 } 00051 00052 QgsColorButton::~QgsColorButton() 00053 { 00054 if ( mTempPNG.exists() ) 00055 mTempPNG.remove(); 00056 } 00057 00058 const QPixmap& QgsColorButton::transpBkgrd() 00059 { 00060 static QPixmap transpBkgrd; 00061 00062 if ( transpBkgrd.isNull() ) 00063 transpBkgrd = QgsApplication::getThemePixmap( "/transp-background_8x8.png" ); 00064 00065 return transpBkgrd; 00066 } 00067 00068 void QgsColorButton::onButtonClicked() 00069 { 00070 //QgsDebugMsg( "entered" ); 00071 QColor newColor; 00072 #if QT_VERSION >= 0x040500 00073 QSettings settings; 00074 if ( mAcceptLiveUpdates && settings.value( "/qgis/live_color_dialogs", false ).toBool() ) 00075 { 00076 newColor = QgsColorDialog::getLiveColor( 00077 color(), this, SLOT( setValidColor( const QColor& ) ), 00078 this->parentWidget(), mColorDialogTitle, mColorDialogOptions ); 00079 } 00080 else 00081 { 00082 newColor = QColorDialog::getColor( color(), this->parentWidget(), mColorDialogTitle, mColorDialogOptions ); 00083 } 00084 #else 00085 newColor = QColorDialog::getColor( color(), this->parentWidget() ); 00086 #endif 00087 setValidColor( newColor ); 00088 00089 // reactivate button's window 00090 activateWindow(); 00091 } 00092 00093 void QgsColorButton::setValidColor( const QColor& newColor ) 00094 { 00095 if ( newColor.isValid() ) 00096 { 00097 setColor( newColor ); 00098 } 00099 } 00100 00101 void QgsColorButton::changeEvent( QEvent* e ) 00102 { 00103 if ( e->type() == QEvent::EnabledChange ) 00104 { 00105 setButtonBackground(); 00106 } 00107 QPushButton::changeEvent( e ); 00108 } 00109 00110 #if 0 // causes too many cyclical updates, but may be needed on some platforms 00111 void QgsColorButton::paintEvent( QPaintEvent* e ) 00112 { 00113 QPushButton::paintEvent( e ); 00114 00115 if ( !mBackgroundSet ) 00116 { 00117 setButtonBackground(); 00118 } 00119 } 00120 #endif 00121 00122 void QgsColorButton::showEvent( QShowEvent* e ) 00123 { 00124 setButtonBackground(); 00125 QPushButton::showEvent( e ); 00126 } 00127 00128 void QgsColorButton::setColor( const QColor &color ) 00129 { 00130 if ( !color.isValid() ) 00131 { 00132 return; 00133 } 00134 QColor oldColor = mColor; 00135 mColor = color; 00136 00137 if ( oldColor != mColor ) 00138 { 00139 setButtonBackground(); 00140 if ( isEnabled() ) 00141 { 00142 // TODO: May be beneficial to have the option to set color without emitting this signal. 00143 // Now done by blockSignals( bool ) where button is used 00144 emit colorChanged( mColor ); 00145 } 00146 } 00147 } 00148 00149 void QgsColorButton::setButtonBackground() 00150 { 00151 if ( !text().isEmpty() ) 00152 { 00153 // generate icon pixmap for regular pushbutton 00154 setFlat( false ); 00155 00156 QPixmap pixmap; 00157 pixmap = QPixmap( iconSize() ); 00158 pixmap.fill( QColor( 0, 0, 0, 0 ) ); 00159 00160 int iconW = iconSize().width(); 00161 int iconH = iconSize().height(); 00162 QRect rect( 0, 0, iconW, iconH ); 00163 00164 // QPainterPath::addRoundRect has flaws, draw chamfered corners instead 00165 QPainterPath roundRect; 00166 int chamfer = 3; 00167 int inset = 1; 00168 roundRect.moveTo( chamfer, inset ); 00169 roundRect.lineTo( iconW - chamfer, inset ); 00170 roundRect.lineTo( iconW - inset, chamfer ); 00171 roundRect.lineTo( iconW - inset, iconH - chamfer ); 00172 roundRect.lineTo( iconW - chamfer, iconH - inset ); 00173 roundRect.lineTo( chamfer, iconH - inset ); 00174 roundRect.lineTo( inset, iconH - chamfer ); 00175 roundRect.lineTo( inset, chamfer ); 00176 roundRect.closeSubpath(); 00177 00178 QPainter p; 00179 p.begin( &pixmap ); 00180 p.setRenderHint( QPainter::Antialiasing ); 00181 p.setClipPath( roundRect ); 00182 p.setPen( Qt::NoPen ); 00183 if ( mColor.alpha() < 255 ) 00184 { 00185 p.drawTiledPixmap( rect, transpBkgrd() ); 00186 } 00187 p.setBrush( mColor ); 00188 p.drawRect( rect ); 00189 p.end(); 00190 00191 // set this pixmap as icon 00192 setIcon( QIcon( pixmap ) ); 00193 } 00194 else 00195 { 00196 // generate temp background image file with checkerboard canvas to be used via stylesheet 00197 00198 // set flat, or inline spacing (widget margins) needs to be manually calculated and set 00199 setFlat( true ); 00200 00201 bool useAlpha = ( mColorDialogOptions & QColorDialog::ShowAlphaChannel ); 00202 00203 // in case margins need to be adjusted 00204 QString margin = QString( "%1px %2px %3px %4px" ).arg( 0 ).arg( 0 ).arg( 0 ).arg( 0 ); 00205 00206 //QgsDebugMsg( QString( "%1 margin: %2" ).arg( objectName() ).arg( margin ) ); 00207 00208 QString bkgrd = QString( " background-color: rgba(%1,%2,%3,%4);" ) 00209 .arg( mColor.red() ) 00210 .arg( mColor.green() ) 00211 .arg( mColor.blue() ) 00212 .arg( useAlpha ? mColor.alpha() : 255 ); 00213 00214 if ( useAlpha && mColor.alpha() < 255 ) 00215 { 00216 QPixmap pixmap = transpBkgrd(); 00217 QRect rect( 0, 0, pixmap.width(), pixmap.height() ); 00218 00219 QPainter p; 00220 p.begin( &pixmap ); 00221 p.setRenderHint( QPainter::Antialiasing ); 00222 p.setPen( Qt::NoPen ); 00223 p.setBrush( mColor ); 00224 p.drawRect( rect ); 00225 p.end(); 00226 00227 if ( mTempPNG.open() ) 00228 { 00229 mTempPNG.setAutoRemove( false ); 00230 pixmap.save( mTempPNG.fileName(), "PNG" ); 00231 mTempPNG.close(); 00232 } 00233 00234 bkgrd = QString( " background-image: url(%1);" ).arg( mTempPNG.fileName() ); 00235 } 00236 00237 //QgsDebugMsg( QString( "%1" ).arg( bkgrd ) ); 00238 00239 // TODO: get OS-style focus color and switch border to that color when button in focus 00240 setStyleSheet( QString( "QgsColorButton{" 00241 " %1" 00242 " background-position: top left;" 00243 " background-origin: content;" 00244 " background-clip: content;" 00245 " padding: 2px;" 00246 " margin: %2;" 00247 " outline: none;" 00248 " border-style: %4;" 00249 " border-width: 1px;" 00250 " border-color: rgb(%3,%3,%3);" 00251 " border-radius: 3px;} " 00252 "QgsColorButton:pressed{" 00253 " %1" 00254 " background-position: top left;" 00255 " background-origin: content;" 00256 " background-clip: content;" 00257 " padding: 1px;" 00258 " margin: %2;" 00259 " outline: none;" 00260 " border-style: inset;" 00261 " border-width: 2px;" 00262 " border-color: rgb(128,128,128);" 00263 " border-radius: 4px;} " ) 00264 .arg( bkgrd ) 00265 .arg( margin ) 00266 .arg( isEnabled() ? "128" : "110" ) 00267 .arg( isEnabled() ? "outset" : "dotted" ) ); 00268 } 00269 } 00270 00271 QColor QgsColorButton::color() const 00272 { 00273 return mColor; 00274 } 00275 00276 void QgsColorButton::setColorDialogOptions( QColorDialog::ColorDialogOptions cdo ) 00277 { 00278 mColorDialogOptions = cdo; 00279 } 00280 00281 QColorDialog::ColorDialogOptions QgsColorButton::colorDialogOptions() 00282 { 00283 return mColorDialogOptions; 00284 } 00285 00286 void QgsColorButton::setColorDialogTitle( QString cdt ) 00287 { 00288 mColorDialogTitle = cdt; 00289 } 00290 00291 QString QgsColorButton::colorDialogTitle() 00292 { 00293 return mColorDialogTitle; 00294 }