File indexing completed on 2024-05-26 04:32:31

0001 /*
0002  *  SPDX-FileCopyrightText: 2009 Cyrille Berger <cberger@cberger.net>
0003  *  SPDX-FileCopyrightText: 2022 Bourumir Wyngs <bourumir.wyngs@gmail.com>
0004  *
0005  *  SPDX-License-Identifier: LGPL-2.0-or-later
0006  */
0007 
0008 #include "digitalmixer_dock.h"
0009 
0010 #include <QGridLayout>
0011 #include <QToolButton>
0012 #include <KisSignalMapper.h>
0013 
0014 #include <klocalizedstring.h>
0015 #include "kis_icon_utils.h"
0016 
0017 #include <KoColorPatch.h>
0018 #include <KoColorSlider.h>
0019 #include <KoColorPopupAction.h>
0020 #include <KoColorSpaceRegistry.h>
0021 #include <KoCanvasResourceProvider.h>
0022 #include <KoCanvasBase.h>
0023 
0024 #include <kis_color_button.h>
0025 #include <kis_properties_configuration.h>
0026 
0027 class DigitalMixerPatch : public KoColorPatch {
0028     public:
0029         DigitalMixerPatch(QWidget* parent) : KoColorPatch(parent) {}
0030         QSize sizeHint() const override
0031         {
0032             return QSize(24,24);
0033         }
0034 };
0035 
0036 DigitalMixerDock::DigitalMixerDock( )
0037     : QDockWidget(i18n("Digital Colors Mixer")), m_canvas(0)
0038     , m_tellCanvas(true)
0039 {
0040     const KoColorSpace *sRGB = KoColorSpaceRegistry::instance()->rgb8();
0041     KoColor initColors[6] = { KoColor(Qt::black, sRGB),
0042                               KoColor(Qt::white, sRGB),
0043                               KoColor(Qt::red, sRGB),
0044                               KoColor(Qt::green, sRGB),
0045                               KoColor(Qt::blue, sRGB),
0046                               KoColor(Qt::yellow, sRGB) };
0047 
0048     QWidget* widget = new QWidget(this);
0049     QGridLayout* layout = new QGridLayout( widget );
0050 
0051     // Current Color
0052     m_currentColorPatch = new KoColorPatch(this);
0053     m_currentColorPatch->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
0054     m_currentColorPatch->setMinimumWidth(48);
0055     layout->addWidget(m_currentColorPatch, 0, 0,3,1);
0056 
0057     // Create the sliders
0058 
0059     KisSignalMapper* signalMapperSelectColor = new KisSignalMapper(this);
0060     connect(signalMapperSelectColor, SIGNAL(mapped(int)), SLOT(popupColorChanged(int)));
0061 
0062     KisSignalMapper* signalMapperColorSlider = new KisSignalMapper(this);
0063     connect(signalMapperColorSlider, SIGNAL(mapped(int)), SLOT(colorSliderChanged(int)));
0064 
0065     KisSignalMapper* signalMapperTargetColor = new KisSignalMapper(this);
0066     connect(signalMapperTargetColor, SIGNAL(mapped(int)), SLOT(targetColorChanged(int)));
0067 
0068     for(int i = 0; i < 6; ++i)
0069     {
0070         Mixer mixer;
0071         mixer.targetColor = new DigitalMixerPatch(this);
0072         mixer.targetColor->setFixedSize(32, 22);
0073         layout->addWidget(mixer.targetColor, 0, i + 1);
0074         mixer.targetSlider = new KoColorSlider(Qt::Vertical, this);
0075         mixer.targetSlider->setFixedWidth(22);
0076         mixer.targetSlider->setMinimumHeight(66);
0077         layout->addWidget(mixer.targetSlider, 1, i + 1);
0078         mixer.actionColor = new KisColorButton( this );
0079         mixer.actionColor->setFixedWidth(22);
0080         layout->addWidget(mixer.actionColor, 2, i + 1);
0081 
0082         m_mixers.push_back(mixer);
0083 
0084         connect(mixer.actionColor, SIGNAL(changed(KoColor)), signalMapperSelectColor, SLOT(map()));
0085         signalMapperSelectColor->setMapping(mixer.actionColor, i);
0086 
0087         connect(mixer.targetSlider, SIGNAL(valueChanged(int)), signalMapperColorSlider, SLOT(map()));
0088         signalMapperColorSlider->setMapping(mixer.targetSlider, i);
0089         mixer.targetSlider->setValue(125);
0090 
0091         connect(mixer.targetColor, SIGNAL(triggered(KoColorPatch*)), signalMapperTargetColor, SLOT(map()));
0092         signalMapperTargetColor->setMapping(mixer.targetColor, i);
0093     }
0094 
0095     //Gradient Mixer
0096     KisSignalMapper* signalMapperGradientStartColor = new KisSignalMapper(this);
0097     connect(signalMapperGradientStartColor, SIGNAL(mapped(int)), SLOT(gradientStartColorChanged(int)));
0098 
0099     KisSignalMapper* signalMapperGradientColorSlider = new KisSignalMapper(this);
0100     connect(signalMapperGradientColorSlider, SIGNAL(mapped(int)), SLOT(gradientColorSliderChanged(int)));
0101 
0102     KisSignalMapper* signalMapperGradientEndColor = new KisSignalMapper(this);
0103     connect(signalMapperGradientEndColor, SIGNAL(mapped(int)), SLOT(gradientEndColorChanged(int)));
0104 
0105     KisSignalMapper* signalMapperGradientTargetColor = new KisSignalMapper(this);
0106     connect(signalMapperGradientTargetColor, SIGNAL(mapped(int)), SLOT(gradientTargetColorChanged(int)));
0107 
0108 
0109     m_gradientMixer.targetColor = new DigitalMixerPatch(this);
0110     m_gradientMixer.targetColor->setFixedSize(32,32);
0111     layout->addWidget(m_gradientMixer.targetColor, 3, 0);
0112 
0113     m_gradientMixer.startColor = new KisColorButton(this);
0114     m_gradientMixer.startColor->setFixedWidth(22);
0115     layout->addWidget(m_gradientMixer.startColor, 3, 1);
0116 
0117     m_gradientMixer.targetSlider = new KoColorSlider(Qt::Horizontal, this);
0118     m_gradientMixer.targetSlider->setFixedHeight(22);
0119     // m_gradientMixer.targetSlider->setMinimumWidth(20);
0120     // m_gradientMixer.targetSlider->setMaximumWidth(120);
0121     // m_gradientMixer.targetSlider->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
0122     layout->addWidget(m_gradientMixer.targetSlider, 3, 2, 1, 4);
0123 
0124     m_gradientMixer.endColor = new KisColorButton(this);
0125     m_gradientMixer.endColor->setFixedWidth(22);
0126     layout->addWidget(m_gradientMixer.endColor, 3, 6);
0127 
0128     connect(m_gradientMixer.startColor, SIGNAL(changed(KoColor)), signalMapperGradientStartColor, SLOT(map()));
0129     signalMapperGradientStartColor->setMapping(m_gradientMixer.startColor, 6);
0130 
0131     connect(m_gradientMixer.targetSlider, SIGNAL(valueChanged(int)), signalMapperGradientColorSlider, SLOT(map()));
0132     signalMapperGradientColorSlider->setMapping(m_gradientMixer.targetSlider, 6);
0133     m_gradientMixer.targetSlider->setValue(125);
0134 
0135     connect(m_gradientMixer.endColor, SIGNAL(changed(KoColor)), signalMapperGradientEndColor, SLOT(map()));
0136     signalMapperGradientEndColor->setMapping(m_gradientMixer.endColor, 6);
0137 
0138     connect(m_gradientMixer.targetColor, SIGNAL(triggered(KoColorPatch*)), signalMapperGradientTargetColor, SLOT(map()));
0139     signalMapperGradientTargetColor->setMapping(m_gradientMixer.targetColor, 6);
0140 
0141     m_reset_button = new QPushButton(KisIconUtils::loadIcon("reload-preset-16"),i18n("Reset"));
0142     m_reset_button->setToolTip(i18n("Return to default settings"));
0143     layout->addWidget(m_reset_button, 0, 0, Qt::AlignLeft);
0144     connect(m_reset_button, SIGNAL(clicked()), SLOT(resetMixer()));
0145 
0146     resetMixer(); // reset colors to default
0147     setWidget( widget );
0148 }
0149 
0150 void DigitalMixerDock::setCanvas(KoCanvasBase * canvas)
0151 {
0152     setEnabled(canvas != 0);
0153 
0154     if (m_canvas) {
0155         m_canvas->disconnectCanvasObserver(this);
0156     }
0157 
0158     m_canvas = canvas;
0159 
0160     if (m_canvas) {
0161         connect(m_canvas->resourceManager(), SIGNAL(canvasResourceChanged(int,QVariant)),
0162                 this, SLOT(canvasResourceChanged(int,QVariant)));
0163 
0164         m_tellCanvas=false;
0165         setCurrentColor(m_canvas->resourceManager()->foregroundColor());
0166         m_tellCanvas=true;
0167     }
0168 }
0169 
0170 
0171 void DigitalMixerDock::gradientStartColorChanged(int id)
0172 {
0173     KoColor color = m_gradientMixer.startColor->color();
0174     KoColor end_color = m_gradientMixer.endColor->color();
0175     color.convertTo(end_color.colorSpace());
0176     m_gradientMixer.targetSlider->setColors(color, end_color);
0177 
0178     gradientColorSliderChanged(id);
0179 }
0180 
0181 void DigitalMixerDock::gradientColorSliderChanged(int /*id*/)
0182 {
0183     m_gradientMixer.targetColor->setColor(m_gradientMixer.targetSlider->currentColor());
0184 }
0185 
0186 void DigitalMixerDock::gradientEndColorChanged(int id)
0187 {
0188     KoColor color = m_gradientMixer.endColor->color();
0189     KoColor start_color = m_gradientMixer.startColor->color();
0190     color.convertTo(start_color.colorSpace());
0191     m_gradientMixer.targetSlider->setColors(start_color, color);
0192 
0193     gradientColorSliderChanged(id);
0194 }
0195 
0196 void DigitalMixerDock::gradientTargetColorChanged(int /*id*/)
0197 {
0198     setCurrentColor(m_gradientMixer.targetColor->color());
0199 }
0200 
0201 void DigitalMixerDock::popupColorChanged(int i)
0202 {
0203     KoColor color = m_mixers[i].actionColor->color();
0204     color.convertTo(m_currentColor.colorSpace());
0205     m_mixers[i].targetSlider->setColors( color, m_currentColor);
0206     colorSliderChanged(i);
0207 }
0208 
0209 void DigitalMixerDock::colorSliderChanged(int i)
0210 {
0211     m_mixers[i].targetColor->setColor(m_mixers[i].targetSlider->currentColor());
0212 }
0213 
0214 void DigitalMixerDock::targetColorChanged(int i)
0215 {
0216     setCurrentColor(m_mixers[i].targetColor->color());
0217 }
0218 
0219 void DigitalMixerDock::resetMixer()
0220 {
0221   const KoColorSpace *sRGB = KoColorSpaceRegistry::instance()->rgb8();
0222 
0223   KoColor initColors[6] = { KoColor(Qt::black, sRGB),
0224                             KoColor(Qt::white, sRGB),
0225                             KoColor(Qt::red, sRGB),
0226                             KoColor(Qt::green, sRGB),
0227                             KoColor(Qt::blue, sRGB),
0228                             KoColor(Qt::yellow, sRGB) };
0229 
0230   for(int i = 0; i < m_mixers.size(); ++i)
0231   {
0232     m_mixers[i].actionColor->setColor(initColors[i]);
0233   }
0234 
0235   setCurrentColor(KoColor(Qt::black, sRGB));
0236 
0237   m_gradientMixer.startColor->setColor(KoColor(Qt::black, sRGB));
0238   m_gradientMixer.endColor->setColor(KoColor(Qt::white, sRGB));
0239 }
0240 
0241 void DigitalMixerDock::setCurrentColor(const KoColor& color)
0242 {
0243     m_currentColor = color;
0244     m_currentColorPatch->setColor(color);
0245     for(int i = 0; i < m_mixers.size(); ++i)
0246     {
0247         popupColorChanged(i);
0248         colorSliderChanged(i);
0249     }
0250     if (m_canvas && m_tellCanvas)
0251     {
0252         m_canvas->resourceManager()->setForegroundColor(m_currentColor);
0253     }
0254 }
0255 
0256 void DigitalMixerDock::canvasResourceChanged(int key, const QVariant& v)
0257 {
0258     m_tellCanvas = false;
0259     if (key == KoCanvasResource::ForegroundColor)
0260         setCurrentColor(v.value<KoColor>());
0261     m_tellCanvas = true;
0262 }
0263 
0264 void DigitalMixerDock::setViewManager(KisViewManager* kisview)
0265 {
0266   KisCanvasResourceProvider *provider = kisview->canvasResourceProvider();
0267   connect(provider, SIGNAL(sigSavingWorkspace(KisWorkspaceResourceSP)),
0268           SLOT(saveToWorkspace(KisWorkspaceResourceSP)));
0269   connect(provider, SIGNAL(sigLoadingWorkspace(KisWorkspaceResourceSP)),
0270           SLOT(loadFromWorkspace(KisWorkspaceResourceSP)));
0271 }
0272 
0273 void DigitalMixerDock::saveToWorkspace(KisWorkspaceResourceSP workspace)
0274 {
0275   KisPropertiesConfiguration configuration;
0276 
0277   configuration.setProperty("gradient_from",
0278                             QVariant::fromValue(m_gradientMixer.startColor->color()));
0279   configuration.setProperty("gradient_to",
0280                             QVariant::fromValue(m_gradientMixer.endColor->color()));
0281 
0282   for(int i = 0; i < m_mixers.size(); ++i)
0283   {
0284     configuration.setProperty("mixer_" + QString::number(i),
0285      QVariant::fromValue(m_mixers[i].actionColor->color()));
0286   }
0287   workspace->setPrefixedProperties("digital-mixer", &configuration);
0288 }
0289 
0290 static void useColor(const KisPropertiesConfiguration &conf, KisColorButton* colorButton, const QString &color)
0291 {
0292   // Do not change if undefined
0293   KoColor koColor = conf.getColor(color, colorButton->color());
0294   colorButton->setColor(koColor);
0295 }
0296 
0297 void DigitalMixerDock::loadFromWorkspace(KisWorkspaceResourceSP workspace)
0298 {
0299   KisPropertiesConfiguration configuration;
0300   workspace->getPrefixedProperties("digital-mixer", &configuration);
0301 
0302   useColor(configuration, m_gradientMixer.startColor, "gradient_from");
0303   useColor(configuration, m_gradientMixer.endColor, "gradient_to");
0304 
0305   for (int i = 0; i < m_mixers.size(); ++i) {
0306     useColor(configuration, m_mixers[i].actionColor, "mixer_" + QString::number(i));
0307   }
0308 }