Back to index

salome-gui  6.5.0
QtxColorButton.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // This library is free software; you can redistribute it and/or
00004 // modify it under the terms of the GNU Lesser General Public
00005 // License as published by the Free Software Foundation; either
00006 // version 2.1 of the License.
00007 //
00008 // This library is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011 // Lesser General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU Lesser General Public
00014 // License along with this library; if not, write to the Free Software
00015 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00016 //
00017 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00018 //
00019 
00020 // File:      QtxColorButton.cxx
00021 // Author:    Sergey TELKOV
00022 //
00023 #include "QtxColorButton.h"
00024 
00025 #include <QMenu>
00026 #include <QStyle>
00027 #include <QLayout>
00028 #include <QBitmap>
00029 #include <QPainter>
00030 #include <QPaintEvent>
00031 #include <QColorDialog>
00032 #include <QStyleOptionToolButton>
00033 
00053 QtxColorButton::QtxColorButton( QWidget* parent )
00054 : QToolButton( parent )
00055 {
00056   setCheckable( false );
00057   setPopupMode( MenuButtonPopup ); // VSR 11/10/2010 temporarily roolback from InstantPopup (regressions)
00058 
00059   QMenu* pm = new QMenu( this );
00060   QGridLayout* grid = new QGridLayout( pm );
00061   grid->setMargin( 5 );
00062   grid->setSpacing( 0 );
00063 
00064   QList<QColor> cList = colorsList();
00065   int w = 8;
00066   int h = cList.count() / w;
00067 
00068   for ( int y = 0; y < h; y++ )
00069   {
00070     for ( int x = 0; x < w; x++ )
00071     {
00072       QColor c = cList.at( x * h + y ).toRgb();
00073       QToolButton* btn = new QToolButton( pm );
00074       btn->setAutoRaise( true );
00075       btn->setCheckable( true );
00076       myColors.insert( btn, c );
00077       grid->addWidget( btn, y + 1, x );
00078 
00079       btn->installEventFilter( this );
00080 
00081       connect( btn, SIGNAL( clicked( bool ) ), this, SLOT( onToggled( bool ) ) );
00082 
00083       updateButton( btn );
00084     }
00085   }
00086 
00087   myAutoButton = new QToolButton( pm );
00088   myAutoButton->setText( tr( "Auto" ) );
00089   myAutoButton->setAutoRaise( true );
00090   myAutoButton->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
00091   grid->addWidget( myAutoButton, 0, 0, 1, grid->columnCount() );
00092   connect( myAutoButton, SIGNAL( clicked( bool ) ), this, SLOT( onAutoClicked( bool ) ) );
00093 
00094   QToolButton* other = new QToolButton( pm );
00095   other->setText( tr( "Other colors..." ) );
00096   other->setAutoRaise( true );
00097   other->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
00098   grid->addWidget( other, grid->rowCount(), 0, 1, grid->columnCount() );
00099   connect( other, SIGNAL( clicked( bool ) ), this, SLOT( onDialogClicked( bool ) ) );
00100 
00101   other->installEventFilter( this );
00102 
00103   setMenu( pm );
00104 
00105   connect( this, SIGNAL( clicked( bool ) ), this, SLOT( onClicked( bool ) ) );
00106   connect( pm,   SIGNAL( aboutToShow() ),   this, SLOT( onAboutToShow() ) );
00107 
00108   myAutoButton->setVisible( false );
00109 }
00110 
00114 QtxColorButton::~QtxColorButton()
00115 {
00116 }
00117 
00126 QColor QtxColorButton::color() const
00127 {
00128   return myColors.contains( this ) ? myColors[this] : QColor();
00129 }
00130 
00136 void QtxColorButton::setColor( const QColor& c )
00137 {
00138   myColors.insert( this, c );
00139   updateState();
00140   update();
00141   updateButton( this );
00142 }
00143 
00148 bool QtxColorButton::isAutoEnabled() const
00149 {
00150   return myAutoButton->isVisibleTo( myAutoButton->parentWidget() );
00151 }
00152 
00157 void QtxColorButton::setAutoEnabled( bool on )
00158 {
00159   myAutoButton->setVisible( on );
00160 }
00161 
00165 QString QtxColorButton::autoText() const
00166 {
00167   return myAutoButton->text();
00168 }
00169 
00174 void QtxColorButton::setAutoText( const QString& txt )
00175 {
00176   myAutoButton->setText( txt );
00177 }
00178 
00185 bool QtxColorButton::eventFilter( QObject* o, QEvent* e )
00186 {
00187   if ( e->type() == QEvent::Leave )
00188     updateButton( ::qobject_cast<QToolButton*>( o ) );
00189   return QToolButton::eventFilter( o, e );
00190 }
00191 
00197 void QtxColorButton::onAboutToShow()
00198 {
00199   updateState();
00200 }
00201 
00209 void QtxColorButton::onClicked( bool )
00210 {
00211   emit clicked( color() );
00212 }
00213 
00223 void QtxColorButton::onToggled( bool on )
00224 {
00225   const QToolButton* tb = ::qobject_cast<QToolButton*>( sender() );
00226   if ( !tb )
00227     return;
00228 
00229   QColor old = color();
00230 
00231   if ( on && myColors.contains( tb ) )
00232   {
00233     myColors.insert( this, myColors[tb] );
00234     updateButton( this );
00235   }
00236 
00237   if ( menu() )
00238     menu()->hide();
00239 
00240   updateState();
00241 
00242   if ( old != color() )
00243     emit changed( color() );
00244 }
00245 
00254 void QtxColorButton::onAutoClicked( bool )
00255 {
00256   if ( menu() )
00257     menu()->hide();
00258 
00259   setColor( QColor() );
00260 }
00261 
00272 void QtxColorButton::onDialogClicked( bool )
00273 {
00274   QColor c = QColorDialog::getColor( color(), this );
00275   if ( !c.isValid() )
00276     return;
00277 
00278   QColor old = color();
00279 
00280   setColor( c );
00281 
00282   if ( old != color() )
00283     emit changed( color() );
00284 }
00285 
00290 void QtxColorButton::paintEvent( QPaintEvent* e )
00291 {
00292   QToolButton::paintEvent( e );
00293 
00294   QStyleOptionToolButton opt;
00295   opt.initFrom( this );
00296   opt.text = text();
00297   opt.icon = icon();
00298   opt.features = QStyleOptionToolButton::Menu;
00299 
00300   QRect r = style()->subControlRect( QStyle::CC_ToolButton, &opt, QStyle::SC_ToolButton );
00301   r.setTopLeft( r.topLeft() + QPoint( 2, 2 ) );
00302   r.setBottomRight( r.bottomRight() - QPoint( 2, 2 ) );
00303 
00304   QPixmap pix( r.size() );
00305   pix.fill( palette().color( backgroundRole() ) );
00306 
00307   if ( color().isValid() )
00308     drawColor( &pix, isEnabled() ? color() : palette().mid().color(), isEnabled() ? Qt::black : palette().mid().color() );
00309   else {
00310     QPainter pixp( &pix );
00311     pixp.setPen( palette().color( isEnabled() ? QPalette::WindowText : QPalette::Mid ) );
00312     pixp.drawRect( 2, 2, pix.width() - 4, pix.height() - 4 );
00313     pixp.fillRect( 3, 3, pix.width() - 6, pix.height() - 6, 
00314                  QBrush( palette().color( isEnabled() ? QPalette::WindowText : QPalette::Mid ), Qt::BDiagPattern ) );
00315     pixp.end();
00316   }
00317 
00318   QPainter p( this );
00319   p.drawPixmap( r, pix );
00320   p.end();
00321 }
00322 
00326 void QtxColorButton::updateState()
00327 {
00328   QList<QToolButton*> bList = qFindChildren<QToolButton*>( menu() );
00329   for ( QList<QToolButton*>::iterator cit = bList.begin(); cit != bList.end(); ++cit )
00330     updateButton( *cit );
00331 }
00332 
00337 void QtxColorButton::updateButton( QToolButton* btn )
00338 {
00339   QColor c = color().toRgb();
00340   bool block = btn->signalsBlocked();
00341   btn->blockSignals( true );
00342   btn->setChecked( false );
00343   if ( myColors.contains( btn ) ) {
00344     btn->setIcon( buttonIcon( myColors[btn] ) );
00345     btn->setChecked( myColors[btn].toRgb() == c );
00346   }
00347   btn->setDown( false );
00348   btn->blockSignals( block );
00349 }
00350 
00356 QPixmap QtxColorButton::buttonIcon( const QColor& c ) const
00357 {
00358   static QMap<int, QPixmap> pixMap;
00359 
00360   if ( pixMap.contains( c.rgb() ) )
00361     return pixMap[c.rgb()];
00362 
00363   QPixmap pix( 16, 16 );
00364 
00365   QColor bg = Qt::white;
00366   if ( bg == c )
00367     bg = Qt::gray;
00368   pix.fill( bg );
00369 
00370   drawColor( &pix, c );
00371 
00372   pix.setMask( pix.createHeuristicMask() );
00373 
00374   pixMap.insert( c.rgb(), pix );
00375 
00376   return pix;
00377 }
00378 
00385 void QtxColorButton::drawColor( QPaintDevice* pd, const QColor& c, const QColor& bc, const int m ) const
00386 {
00387   if ( !pd )
00388     return;
00389 
00390   QPainter p( pd );
00391   p.setPen( bc );
00392   p.fillRect( m, m, pd->width() - 2 * m - 1, pd->height() - 2 * m - 1, QBrush( c ) );
00393   p.drawRect( m, m, pd->width() - 2 * m - 1, pd->height() - 2 * m - 1 );
00394   p.end();
00395 }
00396 
00401 QList<QColor> QtxColorButton::colorsList() const
00402 {
00403   QList<QColor> lst;
00404 
00405   for ( int g = 0; g < 4; g++ )
00406   {
00407     for ( int r = 0; r < 4; r++ )
00408     {
00409       for ( int b = 0; b < 3; b++ )
00410         lst.append( QColor( qRgb( r * 255 / 3, g * 255 / 3, b * 255 / 2 ) ) );
00411     }
00412   }
00413   return lst;
00414 }
00415