KoDualColorButton.cpp 11 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/* This file is part of the KDE libraries
   Copyright (C) 1999 Daniel M. Duley <mosfet@kde.org>

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public
   License version 2 as published by the Free Software Foundation.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public License
   along with this library; see the file COPYING.LIB.  If not, write to
   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
   Boston, MA 02110-1301, USA.
*/

#include "KoDualColorButton.h"
#include "KoColor.h"
21
#include "KoColorDisplayRendererInterface.h"
Boudewijn Rempt's avatar
Boudewijn Rempt committed
22
#include <kcolormimedata.h>
23 24 25 26

#include "dcolorarrow.xbm"
#include "dcolorreset.xpm"

27
#include <QColorDialog>
28
#include "dialogs/kis_internal_color_selector.h"
29

30
#include <QBrush>
Stephen Kelly's avatar
Stephen Kelly committed
31
#include <QDrag>
32 33
#include <QDragEnterEvent>
#include <QPainter>
Boudewijn Rempt's avatar
Boudewijn Rempt committed
34
#include <qdrawutil.h>
35
#include <QApplication>
36

37
class Q_DECL_HIDDEN KoDualColorButton::Private
38 39
{
  public:
40 41 42 43 44
    Private(const KoColor &fgColor, const KoColor &bgColor,
            QWidget *_dialogParent,
            const KoColorDisplayRendererInterface *_displayRenderer)
        : dialogParent(_dialogParent)
        , dragFlag( false )
45 46 47
        , miniCtlFlag( false )
        , foregroundColor(fgColor)
        , backgroundColor(bgColor)
48 49

        , displayRenderer(_displayRenderer)
50
    {
51
        updateArrows();
52 53 54 55 56
        resetPixmap = QPixmap( (const char **)dcolorreset_xpm );

        popDialog = true;
    }

57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
    void updateArrows() {
        arrowBitmap = QPixmap(12,12);
        arrowBitmap.fill(Qt::transparent);

        QPainter p(&arrowBitmap);
        p.setPen(dialogParent->palette().foreground().color());

        // arrow pointing left
        p.drawLine(0, 3, 7, 3);
        p.drawLine(1, 2, 1, 4);
        p.drawLine(2, 1, 2, 5);
        p.drawLine(3, 0, 3, 6);

        // arrow pointing down
        p.drawLine(8, 4, 8, 11);
        p.drawLine(5, 8, 11, 8);
        p.drawLine(6, 9, 10, 9);
        p.drawLine(7, 10, 9, 10);
    }

77 78
    QWidget* dialogParent;

79
    QPixmap arrowBitmap;
80 81 82 83
    QPixmap resetPixmap;
    bool dragFlag, miniCtlFlag;
    KoColor foregroundColor;
    KoColor backgroundColor;
84
    KisInternalColorSelector *colorSelectorDialog;
85 86 87
    QPoint dragPosition;
    Selection tmpSelection;
    bool popDialog;
88 89 90
    const KoColorDisplayRendererInterface *displayRenderer;

    void init(KoDualColorButton *q);
91 92
};

93
void KoDualColorButton::Private::init(KoDualColorButton *q)
94
{
95 96
    if ( q->sizeHint().isValid() )
        q->setMinimumSize( q->sizeHint() );
97

98
    q->setAcceptDrops( true );
99 100
    QString caption = i18n("Select a color");
    colorSelectorDialog = new KisInternalColorSelector(q, foregroundColor, false, caption, displayRenderer);
101 102
    connect(colorSelectorDialog, SIGNAL(signalForegroundColorChosen(KoColor)), q, SLOT(slotSetForeGroundColorFromDialog(KoColor)));
    connect(q, SIGNAL(foregroundColorChanged(KoColor)), colorSelectorDialog, SLOT(slotColorUpdated(KoColor)));
103
}
104

105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
KoDualColorButton::KoDualColorButton(const KoColor &foregroundColor, const KoColor &backgroundColor, QWidget *parent, QWidget* dialogParent )
    : QWidget( parent ),
      d( new Private(foregroundColor, backgroundColor,
                     dialogParent,
                     KoDumbColorDisplayRenderer::instance()) )
{
    d->init(this);
}

KoDualColorButton::KoDualColorButton(const KoColor &foregroundColor, const KoColor &backgroundColor,
                                     const KoColorDisplayRendererInterface *displayRenderer,
                                     QWidget *parent, QWidget* dialogParent)
    : QWidget( parent ),
      d( new Private(foregroundColor, backgroundColor,
                     dialogParent,
                     displayRenderer) )
{
    d->init(this);
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
}

KoDualColorButton::~KoDualColorButton()
{
  delete d;
}

KoColor KoDualColorButton::foregroundColor() const
{
  return d->foregroundColor;
}

KoColor KoDualColorButton::backgroundColor() const
{
  return d->backgroundColor;
}

bool KoDualColorButton::popDialog() const
{
  return d->popDialog;
}

QSize KoDualColorButton::sizeHint() const
{
  return QSize( 34, 34 );
}

void KoDualColorButton::setForegroundColor( const KoColor &color )
{
  d->foregroundColor = color;
153
  d->colorSelectorDialog->slotColorUpdated(color);
154 155 156 157 158 159 160 161 162
  repaint();
}

void KoDualColorButton::setBackgroundColor( const KoColor &color )
{
  d->backgroundColor = color;
  repaint();
}

163 164 165 166 167 168 169 170
void KoDualColorButton::setDisplayRenderer(const KoColorDisplayRendererInterface *displayRenderer)
{
    if (displayRenderer) {
        d->displayRenderer = displayRenderer;
        d->colorSelectorDialog->setDisplayRenderer(displayRenderer);
    }
}

171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
void KoDualColorButton::setPopDialog( bool popDialog )
{
  d->popDialog = popDialog;
}

void KoDualColorButton::metrics( QRect &foregroundRect, QRect &backgroundRect )
{
  foregroundRect = QRect( 0, 0, width() - 14, height() - 14 );
  backgroundRect = QRect( 14, 14, width() - 14, height() - 14 );
}

void KoDualColorButton::paintEvent(QPaintEvent *)
{
  QRect foregroundRect;
  QRect backgroundRect;

  QPainter painter( this );

  metrics( foregroundRect, backgroundRect );

  QBrush defBrush = palette().brush( QPalette::Button );
192 193
  QBrush foregroundBrush( d->displayRenderer->toQColor(d->foregroundColor), Qt::SolidPattern );
  QBrush backgroundBrush( d->displayRenderer->toQColor(d->backgroundColor), Qt::SolidPattern );
194

195
  qDrawShadeRect( &painter, backgroundRect, palette(), false, 1, 0,
196 197
                  isEnabled() ? &backgroundBrush : &defBrush );

198
  qDrawShadeRect( &painter, foregroundRect, palette(), false, 1, 0,
199 200 201 202
                  isEnabled() ? &foregroundBrush : &defBrush );

  painter.setPen( palette().color( QPalette::Shadow ) );

203 204
  painter.drawPixmap( foregroundRect.right() + 2, 1, d->arrowBitmap );
  painter.drawPixmap( 1, foregroundRect.bottom() + 2, d->resetPixmap );
205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230
}

void KoDualColorButton::dragEnterEvent( QDragEnterEvent *event )
{
  event->setAccepted( isEnabled() && KColorMimeData::canDecode( event->mimeData() ) );
}

void KoDualColorButton::dropEvent( QDropEvent *event )
{
    Q_UNUSED(event);
/*  QColor color = KColorMimeData::fromMimeData( event->mimeData() );

  if ( color.isValid() ) {
    if ( d->selection == Foreground ) {
      d->foregroundColor = color;
      emit foregroundColorChanged( color );
    } else {
      d->backgroundColor = color;
      emit backgroundColorChanged( color );
    }

    repaint();
  }
*/
}

231 232 233 234 235 236 237 238
void KoDualColorButton::slotSetForeGroundColorFromDialog(const KoColor color)
{
    d->foregroundColor = color;
    repaint();
    qDebug()<<"Color as sent by the dual color button: "<<KoColor::toQString(color);
    emit foregroundColorChanged(d->foregroundColor);
}

239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264
void KoDualColorButton::mousePressEvent( QMouseEvent *event )
{
  QRect foregroundRect;
  QRect backgroundRect;

  metrics( foregroundRect, backgroundRect );

  d->dragPosition = event->pos();

  d->dragFlag = false;

  if ( foregroundRect.contains( d->dragPosition ) ) {
    d->tmpSelection = Foreground;
    d->miniCtlFlag = false;
  } else if( backgroundRect.contains( d->dragPosition ) ) {
    d->tmpSelection = Background;
    d->miniCtlFlag = false;
  } else if ( event->pos().x() > foregroundRect.width() ) {
    // We handle the swap and reset controls as soon as the mouse is
    // is pressed and ignore further events on this click (mosfet).

    KoColor tmp = d->foregroundColor;
    d->foregroundColor = d->backgroundColor;
    d->backgroundColor = tmp;

    emit backgroundColorChanged( d->backgroundColor );
265
    emit foregroundColorChanged( d->foregroundColor );
266

267 268
    d->miniCtlFlag = true;
  } else if ( event->pos().x() < backgroundRect.x() ) {
269 270
    d->foregroundColor = d->displayRenderer->approximateFromRenderedQColor(Qt::black);
    d->backgroundColor = d->displayRenderer->approximateFromRenderedQColor(Qt::white);
271 272

    emit backgroundColorChanged( d->backgroundColor );
273
    emit foregroundColorChanged( d->foregroundColor );
274

275 276 277 278 279 280 281 282 283
    d->miniCtlFlag = true;
  }
  repaint();
}


void KoDualColorButton::mouseMoveEvent( QMouseEvent *event )
{
  if ( !d->miniCtlFlag ) {
284
    int delay = QApplication::startDragDistance();
285 286 287 288

    if ( event->x() >= d->dragPosition.x() + delay || event->x() <= d->dragPosition.x() - delay ||
         event->y() >= d->dragPosition.y() + delay || event->y() <= d->dragPosition.y() - delay ) {
      KColorMimeData::createDrag( d->tmpSelection == Foreground ?
289 290
                                  d->displayRenderer->toQColor(d->foregroundColor) :
                                  d->displayRenderer->toQColor(d->backgroundColor),
291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312
                                  this )->start();
      d->dragFlag = true;
    }
  }
}

void KoDualColorButton::mouseReleaseEvent( QMouseEvent *event )
{
    d->dragFlag = false;

    if ( d->miniCtlFlag )
        return;

    d->miniCtlFlag = false;

    QRect foregroundRect;
    QRect backgroundRect;
    metrics( foregroundRect, backgroundRect );

    if ( foregroundRect.contains( event->pos() )) {
        if(d->tmpSelection == Foreground ) {
            if( d->popDialog) {
313
                d->colorSelectorDialog->show();
314

315 316
                //QColor c = d->displayRenderer->toQColor(d->foregroundColor);
                //c = QColorDialog::getColor(c, this) ;
317

318 319 320 321
                //if (c.isValid()) {
                //    d->foregroundColor = d->displayRenderer->approximateFromRenderedQColor(c);
                //    emit foregroundColorChanged(d->foregroundColor);
                //}
322 323 324 325 326 327 328 329 330 331 332
            }
            else
                emit pleasePopDialog( d->foregroundColor);
        }
        else {
            d->foregroundColor = d->backgroundColor;
            emit foregroundColorChanged( d->foregroundColor );
        }
    } else if ( backgroundRect.contains( event->pos() )) {
        if(d->tmpSelection == Background ) {
            if( d->popDialog) {
333 334 335 336 337
                KoColor c = d->backgroundColor;
                c = KisInternalColorSelector::getModalColorDialog(c, false, this);
                d->backgroundColor = c;
                emit backgroundColorChanged(d->backgroundColor);
                /*QColor c = d->displayRenderer->toQColor(d->backgroundColor);
338 339
                c = QColorDialog::getColor(c, this);
                if (c.isValid()) {
340
                    d->backgroundColor = d->displayRenderer->approximateFromRenderedQColor(c);
341
                    emit backgroundColorChanged(d->backgroundColor);
342
                }*/
343 344 345 346 347 348 349 350 351 352 353
            }
            else
                emit pleasePopDialog( d->backgroundColor);
        } else {
            d->backgroundColor = d->foregroundColor;
            emit backgroundColorChanged( d->backgroundColor );
        }
    }

    repaint();
}
354 355 356 357 358 359 360 361 362 363 364 365 366

void KoDualColorButton::changeEvent(QEvent *event)
{
    QWidget::changeEvent(event);

    switch (event->type()) {
    case QEvent::StyleChange:
    case QEvent::PaletteChange:
        d->updateArrows();
    default:
        break;
    }
}