1 // Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File: QtxColorButton.cxx
23 // Author: Sergey TELKOV
25 #include "QtxColorButton.h"
32 #include <QPaintEvent>
33 #include <QColorDialog>
34 #include <QStyleOptionToolButton>
38 \brief The QtxColorButton class implements a widget for color
39 preference items editing.
41 The color preference item is represented as the colored button with
42 assocoiated popup menu whihc is called when the user presses the small
43 arrow button near it. The popup menu allows selecting of the color
44 from the predefined set. In addition it contains the button which
45 invokes standard "Select color" dialog box.
47 Initial color value can be set with setColor() method. Chosen color
48 can be retrieved with the color() method.
53 \param parent parent widget
55 QtxColorButton::QtxColorButton( QWidget* parent )
56 : QToolButton( parent )
58 setCheckable( false );
59 setPopupMode( MenuButtonPopup );
61 QMenu* pm = new QMenu( this );
62 QGridLayout* grid = new QGridLayout( pm );
64 grid->setSpacing( 0 );
66 QList<QColor> cList = colorsList();
68 int h = cList.count() / w;
70 for ( int y = 0; y < h; y++ )
72 for ( int x = 0; x < w; x++ )
74 QColor c = cList.at( x * h + y ).toRgb();
75 QToolButton* btn = new QToolButton( pm );
76 btn->setAutoRaise( true );
77 btn->setCheckable( true );
78 myColors.insert( btn, c );
79 grid->addWidget( btn, y + 1, x );
81 btn->installEventFilter( this );
83 connect( btn, SIGNAL( clicked( bool ) ), this, SLOT( onToggled( bool ) ) );
89 myAutoButton = new QToolButton( pm );
90 myAutoButton->setText( tr( "Auto" ) );
91 myAutoButton->setAutoRaise( true );
92 myAutoButton->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
93 grid->addWidget( myAutoButton, 0, 0, 1, grid->columnCount() );
94 connect( myAutoButton, SIGNAL( clicked( bool ) ), this, SLOT( onAutoClicked( bool ) ) );
96 QToolButton* other = new QToolButton( pm );
97 other->setText( tr( "Other colors..." ) );
98 other->setAutoRaise( true );
99 other->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
100 grid->addWidget( other, grid->rowCount(), 0, 1, grid->columnCount() );
101 connect( other, SIGNAL( clicked( bool ) ), this, SLOT( onDialogClicked( bool ) ) );
103 other->installEventFilter( this );
107 connect( this, SIGNAL( clicked( bool ) ), this, SLOT( onClicked( bool ) ) );
108 connect( pm, SIGNAL( aboutToShow() ), this, SLOT( onAboutToShow() ) );
110 myAutoButton->setVisible( false );
116 QtxColorButton::~QtxColorButton()
121 \brief Get currently selected color.
123 Returns null QColor if no color is selected.
125 \return selected color
128 QColor QtxColorButton::color() const
130 return myColors.contains( this ) ? myColors[this] : QColor();
135 \param c color to be set as current
138 void QtxColorButton::setColor( const QColor& c )
140 myColors.insert( this, c );
143 updateButton( this );
147 \brief Returns the status of "auto" color button in popup widget.
148 \return \c true if the "auto" button is enabled
150 bool QtxColorButton::isAutoEnabled() const
152 return myAutoButton->isVisibleTo( myAutoButton->parentWidget() );
156 \brief Enable/disable the "auto" color button in popup widget.
157 \param on enable/disable state
159 void QtxColorButton::setAutoEnabled( bool on )
161 myAutoButton->setVisible( on );
165 \brief Returns text of the "auto" color button in popup widget.
167 QString QtxColorButton::autoText() const
169 return myAutoButton->text();
173 \brief Sets text of the "auto" color button in popup widget.
174 \param txt new button text
176 void QtxColorButton::setAutoText( const QString& txt )
178 myAutoButton->setText( txt );
182 \brief Filter events for the child widgets.
183 \param o event receiver object
185 \return \c true if the event should be filtered
187 bool QtxColorButton::eventFilter( QObject* o, QEvent* e )
189 if ( e->type() == QEvent::Leave )
190 updateButton( ::qobject_cast<QToolButton*>( o ) );
191 return QToolButton::eventFilter( o, e );
195 \brief Called when the popup menu is about to show.
197 Updates the menu and child widgets state.
199 void QtxColorButton::onAboutToShow()
205 \brief Called when the button is clicked by the user.
207 Emits the signal clicked( QColor ).
209 \param on button state (not used)
211 void QtxColorButton::onClicked( bool )
213 emit clicked( color() );
217 \brief Called when any color selection button from popup menu
220 Changes the currently selected color and emits the signal
223 \param on button state
225 void QtxColorButton::onToggled( bool on )
227 const QToolButton* tb = ::qobject_cast<QToolButton*>( sender() );
231 QColor old = color();
233 if ( on && myColors.contains( tb ) )
235 myColors.insert( this, myColors[tb] );
236 updateButton( this );
244 if ( old != color() )
245 emit changed( color() );
249 \brief Called the "Auto" child button from popup menu
252 Sets the undefined (auto) color as current.
256 void QtxColorButton::onAutoClicked( bool )
261 setColor( QColor() );
265 \brief Called the "Other colors" child button from popup menu
268 Invokes standard "Select color" dialog box allowing user to select
269 custom color. If the current color is changed by the user, emits
270 the signal changed( QColor ).
274 void QtxColorButton::onDialogClicked( bool )
276 QColor c = QColorDialog::getColor( color(), this );
280 QColor old = color();
284 if ( old != color() )
285 emit changed( color() );
289 \brief Customize paint event for the widget.
292 void QtxColorButton::paintEvent( QPaintEvent* e )
294 QToolButton::paintEvent( e );
296 QStyleOptionToolButton opt;
297 opt.initFrom( this );
300 opt.features = QStyleOptionToolButton::Menu;
302 QRect r = style()->subControlRect( QStyle::CC_ToolButton, &opt, QStyle::SC_ToolButton );
303 r.setTopLeft( r.topLeft() + QPoint( 2, 2 ) );
304 r.setBottomRight( r.bottomRight() - QPoint( 2, 2 ) );
306 QPixmap pix( r.size() );
307 pix.fill( palette().color( backgroundRole() ) );
309 if ( color().isValid() )
310 drawColor( &pix, color() );
312 QPainter pixp( &pix );
313 pixp.drawRect( 2, 2, pix.width() - 4, pix.height() - 4 );
314 pixp.fillRect( 3, 3, pix.width() - 6, pix.height() - 6, QBrush( Qt::BDiagPattern ) );
319 p.drawPixmap( r, pix );
324 \brief Update widget state.
326 void QtxColorButton::updateState()
328 QList<QToolButton*> bList = qFindChildren<QToolButton*>( menu() );
329 for ( QList<QToolButton*>::iterator cit = bList.begin(); cit != bList.end(); ++cit )
330 updateButton( *cit );
334 \brief Update child button state.
335 \param btn child button
337 void QtxColorButton::updateButton( QToolButton* btn )
339 QColor c = color().toRgb();
340 bool block = btn->signalsBlocked();
341 btn->blockSignals( true );
342 btn->setChecked( false );
343 if ( myColors.contains( btn ) ) {
344 btn->setIcon( buttonIcon( myColors[btn] ) );
345 btn->setChecked( myColors[btn].toRgb() == c );
347 btn->setDown( false );
348 btn->blockSignals( block );
352 \brief Generate (if necessary) or get the icon for the button.
353 \param c color to be used for the icon
354 \return icon pixmap for the button
356 QPixmap QtxColorButton::buttonIcon( const QColor& c ) const
358 static QMap<int, QPixmap> pixMap;
360 if ( pixMap.contains( c.rgb() ) )
361 return pixMap[c.rgb()];
363 QPixmap pix( 16, 16 );
365 QColor bg = Qt::white;
370 drawColor( &pix, c );
372 pix.setMask( pix.createHeuristicMask() );
374 pixMap.insert( c.rgb(), pix );
381 \param pd paint device
385 void QtxColorButton::drawColor( QPaintDevice* pd, const QColor& c, const int m ) const
391 p.setPen( Qt::black );
392 p.fillRect( m, m, pd->width() - 2 * m - 1, pd->height() - 2 * m - 1, QBrush( c ) );
393 p.drawRect( m, m, pd->width() - 2 * m - 1, pd->height() - 2 * m - 1 );
398 \brief Get predefined list of colors to be used in the popup menu.
399 \return list of colors
401 QList<QColor> QtxColorButton::colorsList() const
405 for ( int g = 0; g < 4; g++ )
407 for ( int r = 0; r < 4; r++ )
409 for ( int b = 0; b < 3; b++ )
410 lst.append( QColor( qRgb( r * 255 / 3, g * 255 / 3, b * 255 / 2 ) ) );
417 \fn void QtxColorButton::clicked( QColor color );
418 \brief This signal is emitted when the widget button is clicked by
420 \param color current color
424 \fn void QtxColorButton::changed( QColor color );
425 \brief This signal is emitted when the current color is changed.
426 \param color new current color