diff --git a/libs/ui/dialogs/kis_internal_color_selector.cpp b/libs/ui/dialogs/kis_internal_color_selector.cpp index ec331a8210..0f75d1448a 100644 --- a/libs/ui/dialogs/kis_internal_color_selector.cpp +++ b/libs/ui/dialogs/kis_internal_color_selector.cpp @@ -1,166 +1,206 @@ /* * 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 +#include +#include #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" +#include "kis_config.h" struct KisInternalColorSelector::Private { bool allowUpdates = true; KoColor currentColor; + KoColor previousColor; const KoColorSpace *currentColorSpace; bool chooseAlpha = false; KisSignalCompressor *compressColorChanges; const 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...? + KisConfig cfg; + QString paletteName = cfg.readEntry("internal_selector_active_color_set", QString()); + KoResourceServer* rServer = KoResourceServerProvider::instance()->paletteServer(false); + KoColorSet *savedPal = rServer->resourceByName(paletteName); + if (savedPal) { + m_ui->paletteBox->setColorSet(savedPal); + } else { + savedPal = rServer->resources().first(); + if (savedPal) { + m_ui->paletteBox->setColorSet(savedPal); + } + } + connect(m_ui->paletteBox, SIGNAL(colorChanged(KoColor,bool)), this, SLOT(slotColorUpdated(KoColor))); + + m_ui->currentColor->setColor(m_d->currentColor); + m_ui->previousColor->setColor(m_d->currentColor); + connect(this, SIGNAL(accepted()), this, SLOT(setPreviousColor())); 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); } void KisInternalColorSelector::setDisplayRenderer(const KoColorDisplayRendererInterface *displayRenderer) { if (displayRenderer) { m_d->displayRenderer = displayRenderer; m_ui->visualSelector->setDisplayRenderer(displayRenderer); } else { m_d->displayRenderer = KoDumbColorDisplayRenderer::instance(); } } 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::setPreviousColor() +{ + m_d->previousColor = m_d->currentColor; + KisConfig cfg; + if (m_ui->paletteBox->colorSet()) { + cfg.writeEntry("internal_selector_active_color_set", m_ui->paletteBox->colorSet()->name()); + } +} + 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); } + m_ui->previousColor->setColor(m_d->previousColor); + + m_ui->currentColor->setColor(m_d->currentColor); + if (source != this->parent()) { emit(signalForegroundColorChosen(m_d->currentColor)); m_d->compressColorChanges->start(); } } void KisInternalColorSelector::endUpdateWithNewColor() { m_d->allowUpdates = true; } + +void KisInternalColorSelector::leaveEvent(QEvent *) +{ + setPreviousColor(); + +} diff --git a/libs/ui/dialogs/kis_internal_color_selector.h b/libs/ui/dialogs/kis_internal_color_selector.h index eb9b835d31..f5c5e202e8 100644 --- a/libs/ui/dialogs/kis_internal_color_selector.h +++ b/libs/ui/dialogs/kis_internal_color_selector.h @@ -1,123 +1,131 @@ /* * 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, 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 setDisplayRenderer * Set the display renderer. This is necessary for HDR color manage support. * @param displayRenderer */ void setDisplayRenderer(const KoColorDisplayRendererInterface *displayRenderer); /** * @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(); + /** + * @brief setPreviousColor + * triggered when the dialog is either accepted or hidden. + */ + void setPreviousColor(); + 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); + + virtual void leaveEvent(QEvent *); }; #endif // KISINTERNALCOLORSELECTOR_H diff --git a/libs/ui/forms/wdgdlginternalcolorselector.ui b/libs/ui/forms/wdgdlginternalcolorselector.ui index c9c03744c1..43954a0bb4 100644 --- a/libs/ui/forms/wdgdlginternalcolorselector.ui +++ b/libs/ui/forms/wdgdlginternalcolorselector.ui @@ -1,113 +1,215 @@ WdgDlgInternalColorSelector 0 0 - 418 + 430 483 Dialog - - - - 0 - 0 - - - - - 250 - 250 - - - - - - - - - 0 - 0 - - - - - - + + + + + + + + 0 + 0 + + + + + 250 + 250 + + + + + + + + + 0 + 0 + + + + + + + + + + + + + 0 + 0 + + + + + 220 + 50 + + + + + + + + + 0 + 0 + + + + + 50 + 50 + + + + + + + + + + + 0 + 0 + + + + + 50 + 50 + + + + + + + + + 0 + 0 + + + + + 50 + 50 + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok KisSpinboxColorSelector QWidget
kis_spinbox_color_selector.h
1
KisScreenColorPicker QWidget
kis_screen_color_picker.h
1
KisVisualColorSelector QWidget
kis_visual_color_selector.h
1
+ + KoColorPatch + QWidget +
KoColorPatch.h
+ 1 +
+ + KoColorSetWidget + QFrame +
KoColorSetWidget.h
+ 1 +
buttonBox accepted() WdgDlgInternalColorSelector accept() 248 254 157 274 buttonBox rejected() WdgDlgInternalColorSelector reject() 316 260 286 274
diff --git a/libs/ui/widgets/kis_visual_color_selector.cpp b/libs/ui/widgets/kis_visual_color_selector.cpp index 4b491dee4a..32265576dd 100644 --- a/libs/ui/widgets/kis_visual_color_selector.cpp +++ b/libs/ui/widgets/kis_visual_color_selector.cpp @@ -1,715 +1,715 @@ /* * 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 "KoChannelInfo.h" #include #include "kis_signal_compressor.h" struct KisVisualColorSelector::Private { KoColor currentcolor; const KoColorSpace *currentCS; QList widgetlist; bool updateSelf = false; 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::HSV, - cs, 2, 2, + KisVisualColorSelectorShape::HSL, + cs, 0, 0, m_d->displayRenderer); KisVisualRectangleSelectorShape *block = new KisVisualRectangleSelectorShape(this, KisVisualRectangleSelectorShape::twodimensional, - KisVisualColorSelectorShape::HSV, - cs, 0, 1, + 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 (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; const KoColorDisplayRendererInterface *displayRenderer = 0; qreal hue = 0.0; qreal sat = 0.0; }; KisVisualColorSelectorShape::KisVisualColorSelectorShape(QWidget *parent, KisVisualColorSelectorShape::Dimensions dimension, KisVisualColorSelectorShape::ColorModel model, const KoColorSpace *cs, int channel1, int channel2, const KoColorDisplayRendererInterface *displayRenderer): QWidget(parent), m_d(new Private) { 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); setDisplayRenderer(displayRenderer); } 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(); convertShapeCoordinateToKoColor(getCursorPosition(), true); 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 (const KoColorDisplayRendererInterface *displayRenderer) { if (displayRenderer) { if (m_d->displayRenderer) { m_d->displayRenderer->disconnect(this); } m_d->displayRenderer = displayRenderer; } else { m_d->displayRenderer = KoDumbColorDisplayRenderer::instance(); } connect(m_d->displayRenderer, SIGNAL(displayConfigurationChanged()), SLOT(updateFromChangedDisplayRenderer()), Qt::UniqueConnection); } void KisVisualColorSelectorShape::updateFromChangedDisplayRenderer() { qDebug()<<"update from changed display renderer"; m_d->pixmapsNeedUpdate = true; updateCursor(); //m_d->currentColor = convertShapeCoordinateToKoColor(getCursorPosition()); update(); } QColor KisVisualColorSelectorShape::getColorFromConverter(KoColor c){ QColor col; if (m_d->displayRenderer && m_d->displayRenderer->getPaintingColorSpace()==m_d->cs) { 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, bool cursor) { KoColor c = m_d->currentColor; QVector channelValues (c.colorSpace()->channelCount()); channelValues.fill(1.0); c.colorSpace()->normalisedChannelsValue(c.data(), channelValues); QVector maxvalue(c.colorSpace()->channelCount()); maxvalue.fill(1.0); if (m_d->displayRenderer && m_d->displayRenderer->getPaintingColorSpace()==m_d->cs && m_d->cs->colorDepthId().id().contains("f")) { for (int ch = 0; chcs->channels()[ch]; maxvalue[ch] = m_d->displayRenderer->maxVisibleFloatValue(channel); channelValues[ch] = channelValues[ch]/(maxvalue[ch]); } } 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") { if (m_d->model == ColorModel::HSV){ /* * RGBToHSV has a undefined hue possibility. This means that hue will be -1. * This can be annoying for dealing with a selector, but I understand it is being * used for the KoColorSelector... For now implement a qMax here. */ QVector inbetween(3); RGBToHSV(channelValues[2],channelValues[1], channelValues[0], &inbetween[0], &inbetween[1], &inbetween[2]); inbetween = convertvectorqrealTofloat(getHSX(convertvectorfloatToqreal(inbetween))); inbetween[m_d->channel1] = coordinates.x()*huedivider; if (m_d->dimension == Dimensions::twodimensional) { inbetween[m_d->channel2] = coordinates.y()*huedivider2; } if (cursor==true){setHSX(convertvectorfloatToqreal(inbetween));} HSVToRGB(qMax(inbetween[0],(float)0.0), inbetween[1], inbetween[2], &channelValues[2], &channelValues[1], &channelValues[0]); } else if (m_d->model == ColorModel::HSL) { /* * HSLToRGB can give negative values on the grey. I fixed the fromNormalisedChannel function to clamp, * but you might want to manually clamp for floating point values. */ QVector inbetween(3); RGBToHSL(channelValues[2],channelValues[1], channelValues[0], &inbetween[0], &inbetween[1], &inbetween[2]); inbetween = convertvectorqrealTofloat(getHSX(convertvectorfloatToqreal(inbetween))); inbetween[m_d->channel1] = coordinates.x()*huedivider; if (m_d->dimension == Dimensions::twodimensional) { inbetween[m_d->channel2] = coordinates.y()*huedivider2; } if (cursor==true){setHSX(convertvectorfloatToqreal(inbetween));} HSLToRGB(inbetween[0], inbetween[1], inbetween[2],&channelValues[2],&channelValues[1], &channelValues[0]); } else if (m_d->model == ColorModel::HSI) { /* * HSI is a modified HSY function. */ QVector chan2 = convertvectorfloatToqreal(channelValues); QVector inbetween(3); RGBToHSI(chan2[2],chan2[1], chan2[0], &inbetween[0], &inbetween[1], &inbetween[2]); inbetween = getHSX(inbetween); inbetween[m_d->channel1] = coordinates.x(); if (m_d->dimension == Dimensions::twodimensional) { inbetween[m_d->channel2] = coordinates.y(); } if (cursor==true){setHSX(inbetween);} HSIToRGB(inbetween[0], inbetween[1], inbetween[2],&chan2[2],&chan2[1], &chan2[0]); channelValues = convertvectorqrealTofloat(chan2); } else /*if (m_d->model == ColorModel::HSY)*/ { /* * HSY is pretty slow to render due being a pretty over-the-top function. * Might be worth investigating whether HCY can be used instead, but I have had * some weird results with that. */ QVector luma= m_d->cs->lumaCoefficients(); QVector chan2 = convertvectorfloatToqreal(channelValues); QVector inbetween(3); RGBToHSY(chan2[2],chan2[1], chan2[0], &inbetween[0], &inbetween[1], &inbetween[2], luma[0], luma[1], luma[2]); inbetween = getHSX(inbetween); inbetween[m_d->channel1] = coordinates.x(); if (m_d->dimension == Dimensions::twodimensional) { inbetween[m_d->channel2] = coordinates.y(); } if (cursor==true){setHSX(inbetween);} HSYToRGB(inbetween[0], inbetween[1], inbetween[2],&chan2[2],&chan2[1], &chan2[0], luma[0], luma[1], luma[2]); channelValues = convertvectorqrealTofloat(chan2); } } } else { channelValues[m_d->channel1] = coordinates.x(); if (m_d->dimension == Dimensions::twodimensional) { channelValues[m_d->channel2] = coordinates.y(); } } for (int i=0; ifromNormalisedChannelsValue(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); QVector maxvalue(c.colorSpace()->channelCount()); maxvalue.fill(1.0); if (m_d->displayRenderer && m_d->displayRenderer->getPaintingColorSpace()==m_d->cs && m_d->cs->colorDepthId().id().contains("f")) { for (int ch = 0; chcs->channels()[ch]; maxvalue[ch] = m_d->displayRenderer->maxVisibleFloatValue(channel); channelValues[ch] = channelValues[ch]/(maxvalue[ch]); } } 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") { if (m_d->model == ColorModel::HSV){ QVector inbetween(3); RGBToHSV(channelValues[2],channelValues[1], channelValues[0], &inbetween[0], &inbetween[1], &inbetween[2]); inbetween = convertvectorqrealTofloat(getHSX(convertvectorfloatToqreal(inbetween))); coordinates.setX(inbetween[m_d->channel1]/huedivider); if (m_d->dimension == Dimensions::twodimensional) { coordinates.setY(inbetween[m_d->channel2]/huedivider2); } } else if (m_d->model == ColorModel::HSL) { QVector inbetween(3); RGBToHSL(channelValues[2],channelValues[1], channelValues[0], &inbetween[0], &inbetween[1], &inbetween[2]); inbetween = convertvectorqrealTofloat(getHSX(convertvectorfloatToqreal(inbetween))); coordinates.setX(inbetween[m_d->channel1]/huedivider); if (m_d->dimension == Dimensions::twodimensional) { coordinates.setY(inbetween[m_d->channel2]/huedivider2); } } else if (m_d->model == ColorModel::HSI) { QVector chan2 = convertvectorfloatToqreal(channelValues); QVector inbetween(3); RGBToHSI(chan2[2],chan2[1], chan2[0], &inbetween[0], &inbetween[1], &inbetween[2]); inbetween = getHSX(inbetween); coordinates.setX(inbetween[m_d->channel1]); if (m_d->dimension == Dimensions::twodimensional) { coordinates.setY(inbetween[m_d->channel2]); } } else /*if (m_d->model == ColorModel::HSY)*/ { QVector luma = m_d->cs->lumaCoefficients(); QVector chan2 = convertvectorfloatToqreal(channelValues); QVector inbetween(3); RGBToHSY(chan2[2],chan2[1], chan2[0], &inbetween[0], &inbetween[1], &inbetween[2], luma[0], luma[1], luma[2]); inbetween = getHSX(inbetween); coordinates.setX(inbetween[m_d->channel1]); if (m_d->dimension == Dimensions::twodimensional) { coordinates.setY(inbetween[m_d->channel2]); } } } } else { coordinates.setX(channelValues[m_d->channel1]); if (m_d->dimension == Dimensions::twodimensional) { coordinates.setY(channelValues[m_d->channel2]); } } return coordinates; } QVector KisVisualColorSelectorShape::convertvectorqrealTofloat(QVector real) { QVector vloat(real.size()); for (int i=0; i KisVisualColorSelectorShape::convertvectorfloatToqreal(QVector vloat) { QVector real(vloat.size()); for (int i=0; imousePressActive = 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); //check if old and new colors differ. if (m_d->pixmapsNeedUpdate) { 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; } QVector KisVisualColorSelectorShape::getHSX(QVector hsx) { if ((hsx[2]<=0.0 || hsx[2]>=1.0) && m_d->channel1!=2 && m_d->channel2!=2) { hsx[1] = m_d->sat; hsx[0]=m_d->hue; } else if (hsx[1]<=0.0 && m_d->channel1!=1 && m_d->channel2!=1){ hsx[0]=m_d->hue; } return hsx; } void KisVisualColorSelectorShape::setHSX(QVector hsx) { if (hsx[2]>0.0 && hsx[2<1.0]){ m_d->sat = hsx[1]; } if (hsx[1]>0.0) { m_d->hue = hsx[0]; } } /*-----------Rectangle Shape------------*/ KisVisualRectangleSelectorShape::KisVisualRectangleSelectorShape(QWidget *parent, Dimensions dimension, ColorModel model, const KoColorSpace *cs, int channel1, int channel2, 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); }