Warning, file /office/calligra/libs/widgets/KoDualColorButton.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /* This file is part of the KDE libraries
0002    Copyright (C) 1999 Daniel M. Duley <mosfet@kde.org>
0003 
0004    This library is free software; you can redistribute it and/or
0005    modify it under the terms of the GNU Library General Public
0006    License version 2 as published by the Free Software Foundation.
0007 
0008    This library is distributed in the hope that it will be useful,
0009    but WITHOUT ANY WARRANTY; without even the implied warranty of
0010    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0011    Library General Public License for more details.
0012 
0013    You should have received a copy of the GNU Library General Public License
0014    along with this library; see the file COPYING.LIB.  If not, write to
0015    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0016    Boston, MA 02110-1301, USA.
0017 */
0018 
0019 #include "KoDualColorButton.h"
0020 #include "KoColor.h"
0021 #include "KoColorDisplayRendererInterface.h"
0022 #include <kcolormimedata.h>
0023 
0024 #include "dcolorarrow.xbm"
0025 #include "dcolorreset.xpm"
0026 
0027 #include <QColorDialog>
0028 
0029 #include <QBrush>
0030 #include <QDrag>
0031 #include <QDragEnterEvent>
0032 #include <QPainter>
0033 #include <qdrawutil.h>
0034 #include <QApplication>
0035 
0036 class Q_DECL_HIDDEN KoDualColorButton::Private
0037 {
0038   public:
0039     Private(const KoColor &fgColor, const KoColor &bgColor,
0040             QWidget *_dialogParent,
0041             const KoColorDisplayRendererInterface *_displayRenderer)
0042         : dialogParent(_dialogParent)
0043         , dragFlag( false )
0044         , miniCtlFlag( false )
0045         , foregroundColor(fgColor)
0046         , backgroundColor(bgColor)
0047 
0048         , displayRenderer(_displayRenderer)
0049     {
0050         updateArrows();
0051         resetPixmap = QPixmap( (const char **)dcolorreset_xpm );
0052 
0053         popDialog = true;
0054     }
0055 
0056     void updateArrows() {
0057         arrowBitmap = QPixmap(12,12);
0058         arrowBitmap.fill(Qt::transparent);
0059 
0060         QPainter p(&arrowBitmap);
0061         p.setPen(QPen(dialogParent->palette().foreground().color(), 0));
0062 
0063         // arrow pointing left
0064         p.drawLine(0, 3, 7, 3);
0065         p.drawLine(1, 2, 1, 4);
0066         p.drawLine(2, 1, 2, 5);
0067         p.drawLine(3, 0, 3, 6);
0068 
0069         // arrow pointing down
0070         p.drawLine(8, 4, 8, 11);
0071         p.drawLine(5, 8, 11, 8);
0072         p.drawLine(6, 9, 10, 9);
0073         p.drawLine(7, 10, 9, 10);
0074     }
0075 
0076     QWidget* dialogParent;
0077 
0078     QPixmap arrowBitmap;
0079     QPixmap resetPixmap;
0080     bool dragFlag, miniCtlFlag;
0081     KoColor foregroundColor;
0082     KoColor backgroundColor;
0083     QPoint dragPosition;
0084     Selection tmpSelection;
0085     bool popDialog;
0086     const KoColorDisplayRendererInterface *displayRenderer;
0087 
0088     void init(KoDualColorButton *q);
0089 };
0090 
0091 void KoDualColorButton::Private::init(KoDualColorButton *q)
0092 {
0093     if ( q->sizeHint().isValid() )
0094         q->setMinimumSize( q->sizeHint() );
0095 
0096     q->setAcceptDrops( true );
0097 }
0098 
0099 KoDualColorButton::KoDualColorButton(const KoColor &foregroundColor, const KoColor &backgroundColor, QWidget *parent, QWidget* dialogParent )
0100     : QWidget( parent ),
0101       d( new Private(foregroundColor, backgroundColor,
0102                      dialogParent,
0103                      KoDumbColorDisplayRenderer::instance()) )
0104 {
0105     d->init(this);
0106 }
0107 
0108 KoDualColorButton::KoDualColorButton(const KoColor &foregroundColor, const KoColor &backgroundColor,
0109                                      const KoColorDisplayRendererInterface *displayRenderer,
0110                                      QWidget *parent, QWidget* dialogParent)
0111     : QWidget( parent ),
0112       d( new Private(foregroundColor, backgroundColor,
0113                      dialogParent,
0114                      displayRenderer) )
0115 {
0116     d->init(this);
0117 }
0118 
0119 KoDualColorButton::~KoDualColorButton()
0120 {
0121   delete d;
0122 }
0123 
0124 KoColor KoDualColorButton::foregroundColor() const
0125 {
0126   return d->foregroundColor;
0127 }
0128 
0129 KoColor KoDualColorButton::backgroundColor() const
0130 {
0131   return d->backgroundColor;
0132 }
0133 
0134 bool KoDualColorButton::popDialog() const
0135 {
0136   return d->popDialog;
0137 }
0138 
0139 QSize KoDualColorButton::sizeHint() const
0140 {
0141   return QSize( 34, 34 );
0142 }
0143 
0144 void KoDualColorButton::setForegroundColor( const KoColor &color )
0145 {
0146   d->foregroundColor = color;
0147   repaint();
0148 }
0149 
0150 void KoDualColorButton::setBackgroundColor( const KoColor &color )
0151 {
0152   d->backgroundColor = color;
0153   repaint();
0154 }
0155 
0156 void KoDualColorButton::setPopDialog( bool popDialog )
0157 {
0158   d->popDialog = popDialog;
0159 }
0160 
0161 void KoDualColorButton::metrics( QRect &foregroundRect, QRect &backgroundRect )
0162 {
0163   foregroundRect = QRect( 0, 0, width() - 14, height() - 14 );
0164   backgroundRect = QRect( 14, 14, width() - 14, height() - 14 );
0165 }
0166 
0167 void KoDualColorButton::paintEvent(QPaintEvent *)
0168 {
0169   QRect foregroundRect;
0170   QRect backgroundRect;
0171 
0172   QPainter painter( this );
0173 
0174   metrics( foregroundRect, backgroundRect );
0175 
0176   QBrush defBrush = palette().brush( QPalette::Button );
0177   QBrush foregroundBrush( d->displayRenderer->toQColor(d->foregroundColor), Qt::SolidPattern );
0178   QBrush backgroundBrush( d->displayRenderer->toQColor(d->backgroundColor), Qt::SolidPattern );
0179 
0180   qDrawShadeRect( &painter, backgroundRect, palette(), false, 1, 0,
0181                   isEnabled() ? &backgroundBrush : &defBrush );
0182 
0183   qDrawShadeRect( &painter, foregroundRect, palette(), false, 1, 0,
0184                   isEnabled() ? &foregroundBrush : &defBrush );
0185 
0186   painter.setPen( palette().color( QPalette::Shadow ) );
0187 
0188   painter.drawPixmap( foregroundRect.right() + 2, 1, d->arrowBitmap );
0189   painter.drawPixmap( 1, foregroundRect.bottom() + 2, d->resetPixmap );
0190 }
0191 
0192 void KoDualColorButton::dragEnterEvent( QDragEnterEvent *event )
0193 {
0194   event->setAccepted( isEnabled() && KColorMimeData::canDecode( event->mimeData() ) );
0195 }
0196 
0197 void KoDualColorButton::dropEvent( QDropEvent *event )
0198 {
0199     Q_UNUSED(event);
0200 /*  QColor color = KColorMimeData::fromMimeData( event->mimeData() );
0201 
0202   if ( color.isValid() ) {
0203     if ( d->selection == Foreground ) {
0204       d->foregroundColor = color;
0205       emit foregroundColorChanged( color );
0206     } else {
0207       d->backgroundColor = color;
0208       emit backgroundColorChanged( color );
0209     }
0210 
0211     repaint();
0212   }
0213 */
0214 }
0215 
0216 void KoDualColorButton::mousePressEvent( QMouseEvent *event )
0217 {
0218   QRect foregroundRect;
0219   QRect backgroundRect;
0220 
0221   metrics( foregroundRect, backgroundRect );
0222 
0223   d->dragPosition = event->pos();
0224 
0225   d->dragFlag = false;
0226 
0227   if ( foregroundRect.contains( d->dragPosition ) ) {
0228     d->tmpSelection = Foreground;
0229     d->miniCtlFlag = false;
0230   } else if( backgroundRect.contains( d->dragPosition ) ) {
0231     d->tmpSelection = Background;
0232     d->miniCtlFlag = false;
0233   } else if ( event->pos().x() > foregroundRect.width() ) {
0234     // We handle the swap and reset controls as soon as the mouse is
0235     // is pressed and ignore further events on this click (mosfet).
0236 
0237     KoColor tmp = d->foregroundColor;
0238     d->foregroundColor = d->backgroundColor;
0239     d->backgroundColor = tmp;
0240 
0241     emit backgroundColorChanged( d->backgroundColor );
0242     emit foregroundColorChanged( d->foregroundColor );
0243 
0244     d->miniCtlFlag = true;
0245   } else if ( event->pos().x() < backgroundRect.x() ) {
0246     d->foregroundColor = d->displayRenderer->approximateFromRenderedQColor(Qt::black);
0247     d->backgroundColor = d->displayRenderer->approximateFromRenderedQColor(Qt::white);
0248 
0249     emit backgroundColorChanged( d->backgroundColor );
0250     emit foregroundColorChanged( d->foregroundColor );
0251 
0252     d->miniCtlFlag = true;
0253   }
0254   repaint();
0255 }
0256 
0257 
0258 void KoDualColorButton::mouseMoveEvent( QMouseEvent *event )
0259 {
0260   if ( !d->miniCtlFlag ) {
0261     int delay = QApplication::startDragDistance();
0262 
0263     if ( event->x() >= d->dragPosition.x() + delay || event->x() <= d->dragPosition.x() - delay ||
0264          event->y() >= d->dragPosition.y() + delay || event->y() <= d->dragPosition.y() - delay ) {
0265       KColorMimeData::createDrag( d->tmpSelection == Foreground ?
0266                                   d->displayRenderer->toQColor(d->foregroundColor) :
0267                                   d->displayRenderer->toQColor(d->backgroundColor),
0268                                   this )->start();
0269       d->dragFlag = true;
0270     }
0271   }
0272 }
0273 
0274 void KoDualColorButton::mouseReleaseEvent( QMouseEvent *event )
0275 {
0276     d->dragFlag = false;
0277 
0278     if ( d->miniCtlFlag )
0279         return;
0280 
0281     d->miniCtlFlag = false;
0282 
0283     QRect foregroundRect;
0284     QRect backgroundRect;
0285     metrics( foregroundRect, backgroundRect );
0286 
0287     if ( foregroundRect.contains( event->pos() )) {
0288         if(d->tmpSelection == Foreground ) {
0289             if( d->popDialog) {
0290                 QColor c = d->displayRenderer->toQColor(d->foregroundColor);
0291                 c = QColorDialog::getColor(c, this) ;
0292                 if (c.isValid()) {
0293                     d->foregroundColor = d->displayRenderer->approximateFromRenderedQColor(c);
0294                     emit foregroundColorChanged(d->foregroundColor);
0295                 }
0296             }
0297             else
0298                 emit pleasePopDialog( d->foregroundColor);
0299         }
0300         else {
0301             d->foregroundColor = d->backgroundColor;
0302             emit foregroundColorChanged( d->foregroundColor );
0303         }
0304     } else if ( backgroundRect.contains( event->pos() )) {
0305         if(d->tmpSelection == Background ) {
0306             if( d->popDialog) {
0307                 QColor c = d->displayRenderer->toQColor(d->backgroundColor);
0308                 c = QColorDialog::getColor(c, this);
0309                 if (c.isValid()) {
0310                     d->backgroundColor = d->displayRenderer->approximateFromRenderedQColor(c);
0311                     emit backgroundColorChanged(d->backgroundColor);
0312                 }
0313             }
0314             else
0315                 emit pleasePopDialog( d->backgroundColor);
0316         } else {
0317             d->backgroundColor = d->foregroundColor;
0318             emit backgroundColorChanged( d->backgroundColor );
0319         }
0320     }
0321 
0322     repaint();
0323 }
0324 
0325 void KoDualColorButton::changeEvent(QEvent *event)
0326 {
0327     QWidget::changeEvent(event);
0328 
0329     switch (event->type()) {
0330     case QEvent::StyleChange:
0331     case QEvent::PaletteChange:
0332         d->updateArrows();
0333     default:
0334         break;
0335     }
0336 }