diff --git a/libs/ui/dialogs/kis_internal_color_selector.cpp b/libs/ui/dialogs/kis_internal_color_selector.cpp index 6a9c6a33f4..788962b8b1 100644 --- a/libs/ui/dialogs/kis_internal_color_selector.cpp +++ b/libs/ui/dialogs/kis_internal_color_selector.cpp @@ -1,156 +1,156 @@ /* * Copyright (C) Wolthera van Hovell tot Westerflier , (C) 2016 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include #include #include "KoColorSpaceRegistry.h" #include "kis_signal_compressor.h" #include "KisViewManager.h" #include "KoColorDisplayRendererInterface.h" #include "kis_spinbox_color_selector.h" #include "kis_internal_color_selector.h" #include "ui_wdgdlginternalcolorselector.h" struct KisInternalColorSelector::Private { bool allowUpdates = true; KoColor currentColor; const KoColorSpace *currentColorSpace; bool chooseAlpha = false; KisSignalCompressor *compressColorChanges; - QPointer displayRenderer; + const KoColorDisplayRendererInterface *displayRenderer; }; -KisInternalColorSelector::KisInternalColorSelector(QWidget *parent, KoColor color, bool modal, const QString &caption, KoColorDisplayRendererInterface *displayRenderer) +KisInternalColorSelector::KisInternalColorSelector(QWidget *parent, KoColor color, bool modal, const QString &caption, const KoColorDisplayRendererInterface *displayRenderer) : QDialog(parent) ,m_d(new Private) { setModal(modal); m_ui = new Ui_WdgDlgInternalColorSelector(); m_ui->setupUi(this); if (!modal) { m_ui->buttonBox->hide(); } setWindowTitle(caption); m_d->currentColor = color; m_d->currentColorSpace = m_d->currentColor.colorSpace(); m_d->displayRenderer = displayRenderer; m_ui->spinboxselector->slotSetColor(color); connect(m_ui->spinboxselector, SIGNAL(sigNewColor(KoColor)), this, SLOT(slotColorUpdated(KoColor))); m_ui->visualSelector->slotSetColor(color); m_ui->visualSelector->setDisplayRenderer(displayRenderer); connect(m_ui->visualSelector, SIGNAL(sigNewColor(KoColor)), this, SLOT(slotColorUpdated(KoColor))); connect(m_ui->screenColorPicker, SIGNAL(sigNewColorPicked(KoColor)),this, SLOT(slotColorUpdated(KoColor))); //TODO: Add disable signal as well. Might be not necessary...? connect(this, SIGNAL(signalForegroundColorChosen(KoColor)), this, SLOT(slotLockSelector())); m_d->compressColorChanges = new KisSignalCompressor(100 /* ms */, KisSignalCompressor::POSTPONE, this); connect(m_d->compressColorChanges, SIGNAL(timeout()), this, SLOT(endUpdateWithNewColor())); connect(m_ui->buttonBox, SIGNAL(accepted()), this, SLOT(accept())); connect(m_ui->buttonBox, SIGNAL(rejected()), this, SLOT(reject())); } KisInternalColorSelector::~KisInternalColorSelector() { delete m_ui; //TODO: Does the scoped pointer also need to be deleted??? } void KisInternalColorSelector::slotColorUpdated(KoColor newColor) { //if the update did not come from this selector... if (m_d->allowUpdates || QObject::sender() == this->parent()) { qDebug()<<"Color as received by the internal color selector" << KoColor::toQString(newColor); m_d->currentColor = newColor; updateAllElements(QObject::sender()); } } void KisInternalColorSelector::colorSpaceChanged(const KoColorSpace *cs) { if (cs == m_d->currentColorSpace) { return; } m_d->currentColorSpace = KoColorSpaceRegistry::instance()->colorSpace(cs->colorModelId().id(), cs->colorDepthId().id(), cs->profile()); m_ui->spinboxselector->slotSetColorSpace(m_d->currentColorSpace); } KoColor KisInternalColorSelector::getModalColorDialog(const KoColor color, bool chooseAlpha, QWidget* parent, QString caption) { KisInternalColorSelector dialog(parent, color, true, caption); dialog.chooseAlpha(chooseAlpha); dialog.exec(); return dialog.getCurrentColor(); } KoColor KisInternalColorSelector::getCurrentColor() { return m_d->currentColor; } void KisInternalColorSelector::chooseAlpha(bool chooseAlpha) { m_d->chooseAlpha = chooseAlpha; } void KisInternalColorSelector::slotConfigurationChanged() { //m_d->canvas->displayColorConverter()-> //slotColorSpaceChanged(m_d->canvas->image()->colorSpace()); } void KisInternalColorSelector::slotLockSelector() { m_d->allowUpdates = false; } void KisInternalColorSelector::updateAllElements(QObject *source) { //update everything!!! if (source != m_ui->spinboxselector) { m_ui->spinboxselector->slotSetColor(m_d->currentColor); } if (source != m_ui->visualSelector) { m_ui->visualSelector->slotSetColor(m_d->currentColor); } if (source != this->parent()) { emit(signalForegroundColorChosen(m_d->currentColor)); m_d->compressColorChanges->start(); } } void KisInternalColorSelector::endUpdateWithNewColor() { m_d->allowUpdates = true; } diff --git a/libs/ui/dialogs/kis_internal_color_selector.h b/libs/ui/dialogs/kis_internal_color_selector.h index 883566ee99..259ea116d8 100644 --- a/libs/ui/dialogs/kis_internal_color_selector.h +++ b/libs/ui/dialogs/kis_internal_color_selector.h @@ -1,116 +1,116 @@ /* * Copyright (C) Wolthera van Hovell tot Westerflier , (C) 2016 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KISINTERNALCOLORSELECTOR_H #define KISINTERNALCOLORSELECTOR_H #include "kritaui_export.h" #include "KoColor.h" #include "KoColorSpace.h" #include "KoColorDisplayRendererInterface.h" #include #include "ui_wdgdlginternalcolorselector.h" /** * @brief The KisInternalColorSelector class * * A non-modal color selector dialog that is not a plugin and can thus be used for filters. */ class KRITAUI_EXPORT KisInternalColorSelector : public QDialog { Q_OBJECT public: - KisInternalColorSelector(QWidget* parent, KoColor color, bool modal, const QString &caption, KoColorDisplayRendererInterface *displayRenderer = KoDumbColorDisplayRenderer::instance()); + KisInternalColorSelector(QWidget* parent, KoColor color, bool modal, const QString &caption, const KoColorDisplayRendererInterface *displayRenderer = KoDumbColorDisplayRenderer::instance()); ~KisInternalColorSelector(); /** * @brief slotColorSpaceChanged * Color space has changed, use this dialog to change the colorspace. */ void colorSpaceChanged(const KoColorSpace *cs); /** * @brief getModalColorDialog * Excecute this dialog modally. The function returns * the KoColor you want. * @param color - The current color. Make sure this is in the color space you want your * end color to be in. * @param chooseAlpha - Whether or not the alpha-choosing functionality should be used. */ static KoColor getModalColorDialog(const KoColor color, bool chooseAlpha = false, QWidget* parent = Q_NULLPTR, QString caption = QString()); /** * @brief getCurrentColor * @return gives currently active color; */ KoColor getCurrentColor(); void chooseAlpha(bool chooseAlpha); Q_SIGNALS: /** * @brief signalForegroundColorChosen * The most important signal. This will sent out when a color has been picked from the selector. * There will be a small delay to make sure that the selector causes too many updates. * * Do not connect this to slotColorUpdated. * @param color The new color chosen */ void signalForegroundColorChosen(KoColor color); public Q_SLOTS: /** * @brief slotColorUpdated * Very important slot. Is connected to krita's resources to make sure it has * the currently active color. It's very important that this function is able to understand * when the signal came from itself. * @param newColor This is the new color. */ void slotColorUpdated(KoColor newColor); private Q_SLOTS: /** * @brief slotLockSelector * This slot will prevent the color from being updated. */ void slotLockSelector(); /** * @brief slotConfigurationChanged * Wrapper slot for changes to the colorspace. */ void slotConfigurationChanged(); void endUpdateWithNewColor(); private: Ui_WdgDlgInternalColorSelector *m_ui; //the UI struct Private; //The private struct const QScopedPointer m_d; //the private pointer /** * @brief updateAllElements * Updates each widget with the new element, and if it's responsible for the update sents * a signal out that there's a new color. */ void updateAllElements(QObject *source); }; #endif // KISINTERNALCOLORSELECTOR_H diff --git a/libs/ui/widgets/KoDualColorButton.cpp b/libs/ui/widgets/KoDualColorButton.cpp index 05c8a01455..d9b80bfb43 100644 --- a/libs/ui/widgets/KoDualColorButton.cpp +++ b/libs/ui/widgets/KoDualColorButton.cpp @@ -1,358 +1,358 @@ /* This file is part of the KDE libraries Copyright (C) 1999 Daniel M. Duley 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" #include "KoColorDisplayRendererInterface.h" #include #include "dcolorarrow.xbm" #include "dcolorreset.xpm" #include #include "dialogs/kis_internal_color_selector.h" #include #include #include #include #include #include class Q_DECL_HIDDEN KoDualColorButton::Private { public: Private(const KoColor &fgColor, const KoColor &bgColor, QWidget *_dialogParent, const KoColorDisplayRendererInterface *_displayRenderer) : dialogParent(_dialogParent) , dragFlag( false ) , miniCtlFlag( false ) , foregroundColor(fgColor) , backgroundColor(bgColor) , displayRenderer(_displayRenderer) { updateArrows(); resetPixmap = QPixmap( (const char **)dcolorreset_xpm ); popDialog = true; } 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); } QWidget* dialogParent; QPixmap arrowBitmap; QPixmap resetPixmap; bool dragFlag, miniCtlFlag; KoColor foregroundColor; KoColor backgroundColor; KisInternalColorSelector *colorSelectorDialog; QPoint dragPosition; Selection tmpSelection; bool popDialog; const KoColorDisplayRendererInterface *displayRenderer; void init(KoDualColorButton *q); }; void KoDualColorButton::Private::init(KoDualColorButton *q) { if ( q->sizeHint().isValid() ) q->setMinimumSize( q->sizeHint() ); q->setAcceptDrops( true ); - QString caption = "Select a color"; - colorSelectorDialog = new KisInternalColorSelector(q, foregroundColor, false, caption, KoDumbColorDisplayRenderer::instance()); + QString caption = i18n("Select a color"); + colorSelectorDialog = new KisInternalColorSelector(q, foregroundColor, false, caption, displayRenderer); connect(colorSelectorDialog, SIGNAL(signalForegroundColorChosen(KoColor)), q, SLOT(slotSetForeGroundColorFromDialog(KoColor))); connect(q, SIGNAL(foregroundColorChanged(KoColor)), colorSelectorDialog, SLOT(slotColorUpdated(KoColor))); } 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); } 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; d->colorSelectorDialog->slotColorUpdated(color); repaint(); } void KoDualColorButton::setBackgroundColor( const KoColor &color ) { d->backgroundColor = color; repaint(); } 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 ); QBrush foregroundBrush( d->displayRenderer->toQColor(d->foregroundColor), Qt::SolidPattern ); QBrush backgroundBrush( d->displayRenderer->toQColor(d->backgroundColor), Qt::SolidPattern ); qDrawShadeRect( &painter, backgroundRect, palette(), false, 1, 0, isEnabled() ? &backgroundBrush : &defBrush ); qDrawShadeRect( &painter, foregroundRect, palette(), false, 1, 0, isEnabled() ? &foregroundBrush : &defBrush ); painter.setPen( palette().color( QPalette::Shadow ) ); painter.drawPixmap( foregroundRect.right() + 2, 1, d->arrowBitmap ); painter.drawPixmap( 1, foregroundRect.bottom() + 2, d->resetPixmap ); } 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(); } */ } void KoDualColorButton::slotSetForeGroundColorFromDialog(const KoColor color) { d->foregroundColor = color; repaint(); qDebug()<<"Color as sent by the dual color button: "<foregroundColor); } 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 ); emit foregroundColorChanged( d->foregroundColor ); d->miniCtlFlag = true; } else if ( event->pos().x() < backgroundRect.x() ) { d->foregroundColor = d->displayRenderer->approximateFromRenderedQColor(Qt::black); d->backgroundColor = d->displayRenderer->approximateFromRenderedQColor(Qt::white); emit backgroundColorChanged( d->backgroundColor ); emit foregroundColorChanged( d->foregroundColor ); d->miniCtlFlag = true; } repaint(); } void KoDualColorButton::mouseMoveEvent( QMouseEvent *event ) { if ( !d->miniCtlFlag ) { int delay = QApplication::startDragDistance(); 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 ? d->displayRenderer->toQColor(d->foregroundColor) : d->displayRenderer->toQColor(d->backgroundColor), 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) { d->colorSelectorDialog->show(); //QColor c = d->displayRenderer->toQColor(d->foregroundColor); //c = QColorDialog::getColor(c, this) ; //if (c.isValid()) { // d->foregroundColor = d->displayRenderer->approximateFromRenderedQColor(c); // emit foregroundColorChanged(d->foregroundColor); //} } 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) { KoColor c = d->backgroundColor; c = KisInternalColorSelector::getModalColorDialog(c, false, this); d->backgroundColor = c; emit backgroundColorChanged(d->backgroundColor); /*QColor c = d->displayRenderer->toQColor(d->backgroundColor); c = QColorDialog::getColor(c, this); if (c.isValid()) { d->backgroundColor = d->displayRenderer->approximateFromRenderedQColor(c); emit backgroundColorChanged(d->backgroundColor); }*/ } else emit pleasePopDialog( d->backgroundColor); } else { d->backgroundColor = d->foregroundColor; emit backgroundColorChanged( d->backgroundColor ); } } repaint(); } void KoDualColorButton::changeEvent(QEvent *event) { QWidget::changeEvent(event); switch (event->type()) { case QEvent::StyleChange: case QEvent::PaletteChange: d->updateArrows(); default: break; } } diff --git a/libs/ui/widgets/kis_visual_color_selector.cpp b/libs/ui/widgets/kis_visual_color_selector.cpp index 3824c93e6f..049972d055 100644 --- a/libs/ui/widgets/kis_visual_color_selector.cpp +++ b/libs/ui/widgets/kis_visual_color_selector.cpp @@ -1,545 +1,568 @@ /* * Copyright (C) Wolthera van Hovell tot Westerflier , (C) 2016 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kis_visual_color_selector.h" #include #include #include #include #include #include #include #include #include "KoColorConversions.h" #include "KoColorDisplayRendererInterface.h" #include #include "kis_signal_compressor.h" struct KisVisualColorSelector::Private { KoColor currentcolor; const KoColorSpace *currentCS; QList widgetlist; bool updateSelf = false; - QPointer displayRenderer; + const KoColorDisplayRendererInterface *displayRenderer = 0; //Current coordinates. QVector currentCoordinates; }; KisVisualColorSelector::KisVisualColorSelector(QWidget *parent) : QWidget(parent), m_d(new Private) { QVBoxLayout *layout = new QVBoxLayout; this->setLayout(layout); //m_d->updateSelf = new KisSignalCompressor(100 /* ms */, KisSignalCompressor::POSTPONE, this); } KisVisualColorSelector::~KisVisualColorSelector() { } void KisVisualColorSelector::slotSetColor(KoColor c) { if (m_d->updateSelf==false) { m_d->currentcolor = c; if (m_d->currentCS != c.colorSpace()) { slotsetColorSpace(c.colorSpace()); } } updateSelectorElements(); } void KisVisualColorSelector::slotsetColorSpace(const KoColorSpace *cs) { if (m_d->currentCS != cs) { m_d->currentCS = cs; if (this->layout()) { qDeleteAll(this->children()); } m_d->widgetlist.clear(); QHBoxLayout *layout = new QHBoxLayout; //redraw all the widgets. if (m_d->currentCS->colorChannelCount() == 1) { KisVisualRectangleSelectorShape *bar = new KisVisualRectangleSelectorShape(this, KisVisualRectangleSelectorShape::onedimensional,KisVisualColorSelectorShape::Channel, cs, 0, 0); bar->setMaximumWidth(width()*0.1); bar->setMaximumHeight(height()); connect (bar, SIGNAL(sigNewColor(KoColor)), this, SLOT(updateFromWidgets(KoColor))); layout->addWidget(bar); m_d->widgetlist.append(bar); } else if (m_d->currentCS->colorChannelCount() == 3) { - KisVisualRectangleSelectorShape *bar = new KisVisualRectangleSelectorShape(this, KisVisualRectangleSelectorShape::onedimensional,KisVisualColorSelectorShape::HSL, cs, 0, 0); - KisVisualRectangleSelectorShape *block = new KisVisualRectangleSelectorShape(this, KisVisualRectangleSelectorShape::twodimensional,KisVisualColorSelectorShape::HSL, cs, 1, 2); + KisVisualRectangleSelectorShape *bar = new KisVisualRectangleSelectorShape(this, + KisVisualRectangleSelectorShape::onedimensional, + KisVisualColorSelectorShape::HSL, + cs, 0, 0, + m_d->displayRenderer); + KisVisualRectangleSelectorShape *block = new KisVisualRectangleSelectorShape(this, KisVisualRectangleSelectorShape::twodimensional, + KisVisualColorSelectorShape::HSL, + cs, 1, 2, + m_d->displayRenderer); bar->setMaximumWidth(width()*0.1); bar->setMaximumHeight(height()); block->setMaximumWidth(width()*0.9); block->setMaximumHeight(height()); bar->setColor(m_d->currentcolor); block->setColor(m_d->currentcolor); connect (bar, SIGNAL(sigNewColor(KoColor)), block, SLOT(setColorFromSibling(KoColor))); connect (block, SIGNAL(sigNewColor(KoColor)), SLOT(updateFromWidgets(KoColor))); layout->addWidget(bar); layout->addWidget(block); m_d->widgetlist.append(bar); m_d->widgetlist.append(block); } else if (m_d->currentCS->colorChannelCount() == 4) { KisVisualRectangleSelectorShape *block = new KisVisualRectangleSelectorShape(this, KisVisualRectangleSelectorShape::twodimensional,KisVisualColorSelectorShape::Channel, cs, 0, 1); KisVisualRectangleSelectorShape *block2 = new KisVisualRectangleSelectorShape(this, KisVisualRectangleSelectorShape::twodimensional,KisVisualColorSelectorShape::Channel, cs, 2, 3); block->setMaximumWidth(width()*0.5); block->setMaximumHeight(height()); block2->setMaximumWidth(width()*0.5); block2->setMaximumHeight(height()); block->setColor(m_d->currentcolor); block2->setColor(m_d->currentcolor); connect (block, SIGNAL(sigNewColor(KoColor)), block2, SLOT(setColorFromSibling(KoColor))); connect (block2, SIGNAL(sigNewColor(KoColor)), SLOT(updateFromWidgets(KoColor))); layout->addWidget(block); layout->addWidget(block2); m_d->widgetlist.append(block); m_d->widgetlist.append(block2); } this->setLayout(layout); } } -void KisVisualColorSelector::setDisplayRenderer (KoColorDisplayRendererInterface *displayRenderer) { +void KisVisualColorSelector::setDisplayRenderer (const KoColorDisplayRendererInterface *displayRenderer) { m_d->displayRenderer = displayRenderer; if (m_d->widgetlist.size()>0) { Q_FOREACH (KisVisualColorSelectorShape *shape, m_d->widgetlist) { shape->setDisplayRenderer(displayRenderer); } } } void KisVisualColorSelector::updateSelectorElements() { //first lock all elements from sending updates, then update all elements. Q_FOREACH (KisVisualColorSelectorShape *shape, m_d->widgetlist) { shape->blockSignals(true); } Q_FOREACH (KisVisualColorSelectorShape *shape, m_d->widgetlist) { if (m_d->updateSelf==false) { shape->setColor(m_d->currentcolor); } else { shape->setColorFromSibling(m_d->currentcolor); } } Q_FOREACH (KisVisualColorSelectorShape *shape, m_d->widgetlist) { shape->blockSignals(false); } } void KisVisualColorSelector::updateFromWidgets(KoColor c) { m_d->currentcolor = c; Q_EMIT sigNewColor(c); m_d->updateSelf = true; } void KisVisualColorSelector::leaveEvent(QEvent *) { m_d->updateSelf = false; } /*------------Selector shape------------*/ struct KisVisualColorSelectorShape::Private { QPixmap gradient; QPixmap fullSelector; bool pixmapsNeedUpdate = true; QPointF currentCoordinates; Dimensions dimension; ColorModel model; const KoColorSpace *cs; KoColor currentColor; int channel1; int channel2; KisSignalCompressor *updateTimer; bool mousePressActive = false; - QPointer displayRenderer; + const KoColorDisplayRendererInterface *displayRenderer = 0; }; KisVisualColorSelectorShape::KisVisualColorSelectorShape(QWidget *parent, KisVisualColorSelectorShape::Dimensions dimension, KisVisualColorSelectorShape::ColorModel model, const KoColorSpace *cs, int channel1, int channel2, - KoColorDisplayRendererInterface *displayRenderer): QWidget(parent), m_d(new Private) + const KoColorDisplayRendererInterface *displayRenderer): QWidget(parent), m_d(new Private) { - m_d->displayRenderer = displayRenderer; - connect(m_d->displayRenderer, SIGNAL(displayConfigurationChanged()), SLOT(update())); m_d->dimension = dimension; m_d->model = model; m_d->cs = cs; m_d->currentColor = KoColor(); m_d->currentColor.setOpacity(1.0); m_d->currentColor.convertTo(cs); int maxchannel = m_d->cs->colorChannelCount()-1; m_d->channel1 = qBound(0, channel1, maxchannel); m_d->channel2 = qBound(0, channel2, maxchannel); this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); m_d->updateTimer = new KisSignalCompressor(100 /* ms */, KisSignalCompressor::POSTPONE, this); + if (displayRenderer) { + m_d->displayRenderer = displayRenderer; + connect(m_d->displayRenderer, SIGNAL(displayConfigurationChanged()), this, SLOT(update()), Qt::UniqueConnection); + } else { + KoDumbColorDisplayRenderer::instance(); + } + } KisVisualColorSelectorShape::~KisVisualColorSelectorShape() { } void KisVisualColorSelectorShape::updateCursor() { QPointF point1 = convertKoColorToShapeCoordinate(m_d->currentColor); if (point1 != m_d->currentCoordinates) { m_d->currentCoordinates = point1; } } QPointF KisVisualColorSelectorShape::getCursorPosition() { return m_d->currentCoordinates; } void KisVisualColorSelectorShape::setColor(KoColor c) { if (c.colorSpace() != m_d->cs) { c.convertTo(m_d->cs); } m_d->currentColor = c; updateCursor(); m_d->pixmapsNeedUpdate = true; update(); } void KisVisualColorSelectorShape::setColorFromSibling(KoColor c) { if (c.colorSpace() != m_d->cs) { c.convertTo(m_d->cs); } m_d->currentColor = c; Q_EMIT sigNewColor(c); m_d->pixmapsNeedUpdate = true; update(); } -void KisVisualColorSelectorShape::setDisplayRenderer (KoColorDisplayRendererInterface *displayRenderer) { - m_d->displayRenderer = displayRenderer; +void KisVisualColorSelectorShape::setDisplayRenderer (const KoColorDisplayRendererInterface *displayRenderer) +{ + if (displayRenderer) { + if (m_d->displayRenderer) { + m_d->displayRenderer->disconnect(this); + } + m_d->displayRenderer = displayRenderer; + connect(m_d->displayRenderer, SIGNAL(displayConfigurationChanged()), + SLOT(update()), Qt::UniqueConnection); + } else { + m_d->displayRenderer = KoDumbColorDisplayRenderer::instance(); + } } QColor KisVisualColorSelectorShape::getColorFromConverter(KoColor c){ QColor col; if (m_d->displayRenderer) { col = m_d->displayRenderer->toQColor(c); } else { col = c.toQColor(); } return col; } void KisVisualColorSelectorShape::slotSetActiveChannels(int channel1, int channel2) { int maxchannel = m_d->cs->colorChannelCount()-1; m_d->channel1 = qBound(0, channel1, maxchannel); m_d->channel2 = qBound(0, channel2, maxchannel); m_d->pixmapsNeedUpdate = true; update(); } QPixmap KisVisualColorSelectorShape::getPixmap() { if (m_d->pixmapsNeedUpdate == true) { m_d->pixmapsNeedUpdate = false; m_d->gradient = QPixmap(width(), height()); m_d->gradient.fill(Qt::black); QImage img(width(), height(), QImage::Format_RGB32); img.fill(Qt::black); for (int y = 0; ygradient = QPixmap::fromImage(img, Qt::AvoidDither); } return m_d->gradient; } KoColor KisVisualColorSelectorShape::convertShapeCoordinateToKoColor(QPointF coordinates) { KoColor c = m_d->currentColor; QVector channelValues (c.colorSpace()->channelCount()); channelValues.fill(1.0); c.colorSpace()->normalisedChannelsValue(c.data(), channelValues); qreal huedivider = 1.0; qreal huedivider2 = 1.0; if (m_d->channel1==0) { huedivider = 360.0; } if (m_d->channel2==0) { huedivider2 = 360.0; } if (m_d->model != ColorModel::Channel && c.colorSpace()->colorModelId().id() == "RGBA") { if (c.colorSpace()->colorModelId().id() == "RGBA") { QVector inbetween(3); if (m_d->model == ColorModel::HSV){ RGBToHSV(channelValues[2],channelValues[1], channelValues[0], &inbetween[0], &inbetween[1], &inbetween[2]); inbetween[m_d->channel1] = coordinates.x()*huedivider; if (m_d->dimension == Dimensions::twodimensional) { inbetween[m_d->channel2] = coordinates.y()*huedivider2; } HSVToRGB(inbetween[0], inbetween[1], inbetween[2], &channelValues[2], &channelValues[1], &channelValues[0]); } else /*(m_d->model == KisVisualColorSelectorShape::ColorModel::HSL)*/{ RGBToHSL(channelValues[2],channelValues[1], channelValues[0], &inbetween[0], &inbetween[1], &inbetween[2]); inbetween[m_d->channel1] = coordinates.x()*huedivider; if (m_d->dimension == Dimensions::twodimensional) { inbetween[m_d->channel2] = coordinates.y()*huedivider2; } HSLToRGB(inbetween[0], inbetween[1], inbetween[2],&channelValues[2],&channelValues[1], &channelValues[0]); } } } else { channelValues[m_d->channel1] = coordinates.x(); if (m_d->dimension == Dimensions::twodimensional) { channelValues[m_d->channel2] = coordinates.y(); } } c.colorSpace()->fromNormalisedChannelsValue(c.data(), channelValues); return c; } QPointF KisVisualColorSelectorShape::convertKoColorToShapeCoordinate(KoColor c) { if (c.colorSpace() != m_d->cs) { c.convertTo(m_d->cs); } QVector channelValues (m_d->currentColor.colorSpace()->channelCount()); channelValues.fill(1.0); m_d->cs->normalisedChannelsValue(c.data(), channelValues); QPointF coordinates(0.0,0.0); qreal huedivider = 1.0; qreal huedivider2 = 1.0; if (m_d->channel1==0) { huedivider = 360.0; } if (m_d->channel2==0) { huedivider2 = 360.0; } if (m_d->model != ColorModel::Channel && c.colorSpace()->colorModelId().id() == "RGBA") { if (c.colorSpace()->colorModelId().id() == "RGBA") { QVector inbetween(3); if (m_d->model == ColorModel::HSV){ RGBToHSV(channelValues[2],channelValues[1], channelValues[0], &inbetween[0], &inbetween[1], &inbetween[2]); coordinates.setX(inbetween[m_d->channel1]/huedivider); if (m_d->dimension == Dimensions::twodimensional) { coordinates.setY(inbetween[m_d->channel2]/huedivider2); } } else { RGBToHSL(channelValues[2],channelValues[1], channelValues[0], &inbetween[0], &inbetween[1], &inbetween[2]); coordinates.setX(inbetween[m_d->channel1]/huedivider); if (m_d->dimension == Dimensions::twodimensional) { coordinates.setY(inbetween[m_d->channel2]/huedivider2); } } } } else { coordinates.setX(channelValues[m_d->channel1]); if (m_d->dimension == Dimensions::twodimensional) { coordinates.setY(channelValues[m_d->channel2]); } } return coordinates; } void KisVisualColorSelectorShape::mousePressEvent(QMouseEvent *e) { m_d->mousePressActive = true; } void KisVisualColorSelectorShape::mouseMoveEvent(QMouseEvent *e) { if (m_d->mousePressActive==true && this->mask().contains(e->pos())) { QPointF coordinates = convertWidgetCoordinateToShapeCoordinate(e->pos()); KoColor col = convertShapeCoordinateToKoColor(coordinates); setColor(col); if (!m_d->updateTimer->isActive()) { Q_EMIT sigNewColor(col); m_d->updateTimer->start(); } } else { e->ignore(); } } void KisVisualColorSelectorShape::mouseReleaseEvent(QMouseEvent *) { m_d->mousePressActive = false; } void KisVisualColorSelectorShape::paintEvent(QPaintEvent*) { QPainter painter(this); if (m_d->pixmapsNeedUpdate) { getPixmap(); setMask(getMaskMap()); } drawCursor(); painter.drawPixmap(0,0,m_d->fullSelector); } void KisVisualColorSelectorShape::resizeEvent(QResizeEvent *) { m_d->pixmapsNeedUpdate = true; } KisVisualColorSelectorShape::Dimensions KisVisualColorSelectorShape::getDimensions() { return m_d->dimension; } KisVisualColorSelectorShape::ColorModel KisVisualColorSelectorShape::getColorModel() { return m_d->model; } void KisVisualColorSelectorShape::setFullImage(QPixmap full) { m_d->fullSelector = full; } KoColor KisVisualColorSelectorShape::getCurrentColor() { return m_d->currentColor; } /*-----------Rectangle Shape------------*/ KisVisualRectangleSelectorShape::KisVisualRectangleSelectorShape(QWidget *parent, Dimensions dimension, ColorModel model, const KoColorSpace *cs, int channel1, int channel2, - singelDTypes d, KoColorDisplayRendererInterface *displayRenderer) + const KoColorDisplayRendererInterface *displayRenderer, + singelDTypes d) : KisVisualColorSelectorShape(parent, dimension, model, cs, channel1, channel2, displayRenderer) { m_type = d; } KisVisualRectangleSelectorShape::~KisVisualRectangleSelectorShape() { } QPointF KisVisualRectangleSelectorShape::convertShapeCoordinateToWidgetCoordinate(QPointF coordinate) { qreal x = width()/2; qreal y = height()/2; KisVisualColorSelectorShape::Dimensions dimension = getDimensions(); if (dimension == KisVisualColorSelectorShape::onedimensional && m_type == KisVisualRectangleSelectorShape::vertical) { y = coordinate.x()*height(); } else if (dimension == KisVisualColorSelectorShape::onedimensional && m_type == KisVisualRectangleSelectorShape::horizontal) { x = coordinate.x()*width(); } else { x = coordinate.x()*width(); y = coordinate.y()*height(); } return QPointF(x,y); } QPointF KisVisualRectangleSelectorShape::convertWidgetCoordinateToShapeCoordinate(QPoint coordinate) { //default implementation: qreal x = 0.5; qreal y = 0.5; KisVisualColorSelectorShape::Dimensions dimension = getDimensions(); if (dimension == KisVisualColorSelectorShape::onedimensional && m_type == KisVisualRectangleSelectorShape::vertical) { x = (qreal)coordinate.y()/(qreal)height(); } else if (dimension == KisVisualColorSelectorShape::onedimensional && m_type == KisVisualRectangleSelectorShape::horizontal) { x = (qreal)coordinate.x()/(qreal)width(); } else { x = (qreal)coordinate.x()/(qreal)width(); y = (qreal)coordinate.y()/(qreal)height(); } return QPointF(x, y); } QRegion KisVisualRectangleSelectorShape::getMaskMap() { QRegion mask = QRegion(0,0,width(),height()); return mask; } void KisVisualRectangleSelectorShape::drawCursor() { QPointF cursorPoint = convertShapeCoordinateToWidgetCoordinate(getCursorPosition()); QPixmap fullSelector = getPixmap(); QColor col = getColorFromConverter(getCurrentColor()); QPainter painter; painter.begin(&fullSelector); painter.setRenderHint(QPainter::Antialiasing); //QPainterPath path; QBrush fill; fill.setStyle(Qt::SolidPattern); int cursorwidth = 5; QRect rect(cursorPoint.toPoint().x()-cursorwidth,cursorPoint.toPoint().y()-cursorwidth, cursorwidth*2,cursorwidth*2); if (m_type==KisVisualRectangleSelectorShape::vertical){ int x = ( cursorPoint.x()-(width()/2)+1 ); int y = ( cursorPoint.y()-cursorwidth ); rect.setCoords(x, y, x+width()-2, y+(cursorwidth*2)); } else { int x = cursorPoint.x()-cursorwidth; int y = cursorPoint.y()-(height()/2)+1; rect.setCoords(x, y, x+(cursorwidth*2), y+cursorwidth-2); } if (getDimensions() == KisVisualColorSelectorShape::onedimensional) { painter.setPen(Qt::white); fill.setColor(Qt::white); painter.setBrush(fill); painter.drawRect(rect); //set filter conversion! fill.setColor(col); painter.setPen(Qt::black); painter.setBrush(fill); rect.setCoords(rect.topLeft().x()+1, rect.topLeft().y()+1, rect.topLeft().x()+rect.width()-2, rect.topLeft().y()+rect.height()-2); painter.drawRect(rect); } else { painter.setPen(Qt::white); fill.setColor(Qt::white); painter.setBrush(fill); painter.drawEllipse(cursorPoint, cursorwidth, cursorwidth); fill.setColor(col); painter.setPen(Qt::black); painter.setBrush(fill); painter.drawEllipse(cursorPoint, cursorwidth-1.0, cursorwidth-1.0); } painter.end(); setFullImage(fullSelector); } diff --git a/libs/ui/widgets/kis_visual_color_selector.h b/libs/ui/widgets/kis_visual_color_selector.h index 616c2f6f98..fb6a3cff05 100644 --- a/libs/ui/widgets/kis_visual_color_selector.h +++ b/libs/ui/widgets/kis_visual_color_selector.h @@ -1,169 +1,170 @@ /* * Copyright (C) Wolthera van Hovell tot Westerflier , (C) 2016 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KISVISUALCOLORSELECTOR_H #define KISVISUALCOLORSELECTOR_H #include #include #include #include #include #include #include #include "KoColorDisplayRendererInterface.h" #include "kritaui_export.h" /** * @brief The KisVisualColorSelector class * this gives a color selector box that draws gradients and everything. * Unlike other color selectors, this one draws the full gamut of the given colorspace. */ class KRITAUI_EXPORT KisVisualColorSelector : public QWidget { Q_OBJECT public: explicit KisVisualColorSelector(QWidget *parent = 0); ~KisVisualColorSelector(); Q_SIGNALS: void sigNewColor(KoColor c); public Q_SLOTS: void slotSetColor(KoColor c); void slotsetColorSpace(const KoColorSpace *cs); - void setDisplayRenderer (KoColorDisplayRendererInterface *displayRenderer); + void setDisplayRenderer (const KoColorDisplayRendererInterface *displayRenderer); private Q_SLOTS: void updateFromWidgets(KoColor c); protected: void leaveEvent(QEvent *); private: struct Private; const QScopedPointer m_d; void updateSelectorElements(); void drawGradients(); }; //kis_visual_color_selector_shape class KisVisualColorSelectorShape : public QWidget { Q_OBJECT public: /** * @brief The Dimensions enum * Wether or not the shape is single or two dimensional. * A 2d widget can represent at maximum 2 coordinates. */ enum Dimensions{onedimensional, twodimensional}; enum ColorModel{Channel, HSV, HSL, HSI, HSY, YUV}; explicit KisVisualColorSelectorShape(QWidget *parent, KisVisualColorSelectorShape::Dimensions dimension, KisVisualColorSelectorShape::ColorModel model, const KoColorSpace *cs, int channel1, int channel2, - KoColorDisplayRendererInterface *displayRenderer = KoDumbColorDisplayRenderer::instance()); + const KoColorDisplayRendererInterface *displayRenderer = KoDumbColorDisplayRenderer::instance()); ~KisVisualColorSelectorShape(); QPointF getCursorPosition(); Dimensions getDimensions(); ColorModel getColorModel(); QPixmap getPixmap(); void setFullImage(QPixmap full); KoColor getCurrentColor(); - void setDisplayRenderer (KoColorDisplayRendererInterface *displayRenderer); + void setDisplayRenderer (const KoColorDisplayRendererInterface *displayRenderer); QColor getColorFromConverter(KoColor c); Q_SIGNALS: void sigNewColor(KoColor col); public Q_SLOTS: void setColor(KoColor c); void setColorFromSibling(KoColor c); void slotSetActiveChannels(int channel1, int channel2); protected: void mousePressEvent(QMouseEvent *e); void mouseMoveEvent(QMouseEvent *e); void mouseReleaseEvent(QMouseEvent *e); void paintEvent(QPaintEvent*); void resizeEvent(QResizeEvent *); private: struct Private; const QScopedPointer m_d; /** * @brief convertShapeCoordinateToWidgetCoordinate * @return take the position in the shape and convert it to screen coordinates. */ virtual QPointF convertShapeCoordinateToWidgetCoordinate(QPointF) = 0; /** * @brief convertWidgetCoordinateToShapeCoordinate * Convert a coordinate in the widget's height/width to a shape coordinate. * @param coordinate the position your wish to have the shape coordinates of. */ virtual QPointF convertWidgetCoordinateToShapeCoordinate(QPoint coordinate) = 0; /** * @brief updateCursor * Update the cursor position. */ void updateCursor(); QPointF convertKoColorToShapeCoordinate(KoColor c); KoColor convertShapeCoordinateToKoColor(QPointF coordinates); /** * @brief getPixmap * @return the pixmap of this shape. */ virtual QRegion getMaskMap() = 0; virtual void drawCursor() = 0; }; class KisVisualRectangleSelectorShape : public KisVisualColorSelectorShape { Q_OBJECT public: enum singelDTypes{vertical, horizontal, border}; explicit KisVisualRectangleSelectorShape(QWidget *parent, Dimensions dimension, ColorModel model, const KoColorSpace *cs, int channel1, int channel2, - KisVisualRectangleSelectorShape::singelDTypes d = KisVisualRectangleSelectorShape::vertical, - KoColorDisplayRendererInterface *displayRenderer = KoDumbColorDisplayRenderer::instance()); + const KoColorDisplayRendererInterface *displayRenderer = KoDumbColorDisplayRenderer::instance(), + KisVisualRectangleSelectorShape::singelDTypes d = KisVisualRectangleSelectorShape::vertical + ); ~KisVisualRectangleSelectorShape(); void setBarWidth(); private: virtual QPointF convertShapeCoordinateToWidgetCoordinate(QPointF coordinate); virtual QPointF convertWidgetCoordinateToShapeCoordinate(QPoint coordinate); singelDTypes m_type; virtual QRegion getMaskMap(); virtual void drawCursor(); }; #endif // KISVISUALCOLORSELECTOR_H