1 /*
2  * KDE. Krita Project.
3  *
4  * Copyright (c) 2020 Deif Lou <ginoba@gmail.com>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  */
20 
21 #include <generator/kis_generator.h>
22 #include <generator/kis_generator_registry.h>
23 #include <KoColor.h>
24 #include <filter/kis_filter_configuration.h>
25 #include <kis_config_widget.h>
26 #include <kis_signals_blocker.h>
27 
28 #include <QStringList>
29 #include <QScrollBar>
30 #include <QResizeEvent>
31 
32 #include "KisHalftoneConfigPageWidget.h"
33 
KisHalftoneConfigPageWidget(QWidget * parent,const KisPaintDeviceSP dev)34 KisHalftoneConfigPageWidget::KisHalftoneConfigPageWidget(QWidget *parent, const KisPaintDeviceSP dev)
35     : QWidget(parent)
36     , m_paintDevice(dev)
37     , m_generatorWidget(nullptr)
38     , m_view(nullptr)
39 {
40     Q_ASSERT(m_paintDevice);
41 
42     ui()->setupUi(this);
43 
44     m_generatorIds = KisGeneratorRegistry::instance()->keys();
45     m_generatorIds.sort();
46 
47     ui()->comboBoxGenerator->addItem(i18n("None"));
48     for (const QString &generatorId : m_generatorIds) {
49         KisGeneratorSP generator = KisGeneratorRegistry::instance()->get(generatorId);
50         ui()->comboBoxGenerator->addItem(generator->name());
51     }
52 
53     QVBoxLayout *generatorContainerLayout = new QVBoxLayout(ui()->widgetGeneratorContainer);
54     generatorContainerLayout->setContentsMargins(0, 0, 0, 0);
55 
56     ui()->sliderHardness->setRange(0.0, 100.0, 2);
57     ui()->sliderHardness->setSingleStep(1.0);
58     ui()->sliderHardness->setSuffix(i18n("%"));
59 
60     ui()->sliderForegroundOpacity->setRange(0, 100);
61     ui()->sliderForegroundOpacity->setPrefix(i18n("Opacity: "));
62     ui()->sliderForegroundOpacity->setSuffix(i18n("%"));
63     ui()->sliderBackgroundOpacity->setRange(0, 100);
64     ui()->sliderBackgroundOpacity->setPrefix(i18n("Opacity: "));
65     ui()->sliderBackgroundOpacity->setSuffix(i18n("%"));
66 
67     connect(ui()->comboBoxGenerator, SIGNAL(currentIndexChanged(int)), this, SLOT(slot_comboBoxGenerator_currentIndexChanged(int)));
68     connect(ui()->sliderHardness, SIGNAL(valueChanged(qreal)), this, SIGNAL(signal_configurationUpdated()));
69     connect(ui()->checkBoxInvert, SIGNAL(toggled(bool)), this, SIGNAL(signal_configurationUpdated()));
70     connect(ui()->buttonForegroundColor, SIGNAL(changed(const KoColor&)), this, SIGNAL(signal_configurationUpdated()));
71     connect(ui()->sliderForegroundOpacity, SIGNAL(valueChanged(int)), this, SIGNAL(signal_configurationUpdated()));
72     connect(ui()->buttonBackgroundColor, SIGNAL(changed(const KoColor&)), this, SIGNAL(signal_configurationUpdated()));
73     connect(ui()->sliderBackgroundOpacity, SIGNAL(valueChanged(int)), this, SIGNAL(signal_configurationUpdated()));
74 }
75 
~KisHalftoneConfigPageWidget()76 KisHalftoneConfigPageWidget::~KisHalftoneConfigPageWidget()
77 {}
78 
ui() const79 const Ui_HalftoneConfigPageWidget * KisHalftoneConfigPageWidget::ui() const
80 {
81     return &m_ui;
82 }
83 
ui()84 Ui_HalftoneConfigPageWidget * KisHalftoneConfigPageWidget::ui()
85 {
86     return &m_ui;
87 }
88 
showColors()89 void KisHalftoneConfigPageWidget::showColors()
90 {
91     setColorsVisible(true);
92 }
93 
hideColors()94 void KisHalftoneConfigPageWidget::hideColors()
95 {
96     setColorsVisible(false);
97 }
98 
setColorsVisible(bool show)99 void KisHalftoneConfigPageWidget::setColorsVisible(bool show)
100 {
101     ui()->labelForeground->setVisible(show);
102     ui()->buttonForegroundColor->setVisible(show);
103     ui()->sliderForegroundOpacity->setVisible(show);
104     ui()->labelBackground->setVisible(show);
105     ui()->buttonBackgroundColor->setVisible(show);
106     ui()->sliderBackgroundOpacity->setVisible(show);
107 }
108 
setConfiguration(const KisHalftoneFilterConfigurationSP config,const QString & prefix)109 void KisHalftoneConfigPageWidget::setConfiguration(const KisHalftoneFilterConfigurationSP config, const QString & prefix)
110 {
111     {
112         KisSignalsBlocker signalsBlocker(this, ui()->comboBoxGenerator);
113 
114         QString generatorId = config->generatorId(prefix);
115         int generatorIndex = m_generatorIds.indexOf(generatorId);
116         if (generatorIndex == -1) {
117             ui()->comboBoxGenerator->setCurrentIndex(0);
118             setGenerator("", nullptr);
119         } else {
120             ui()->comboBoxGenerator->setCurrentIndex(generatorIndex + 1);
121             KisFilterConfigurationSP generatorConfiguration = config->generatorConfiguration(prefix);
122             setGenerator(generatorId, generatorConfiguration);
123         }
124 
125         ui()->sliderHardness->setValue(config->hardness(prefix));
126         ui()->checkBoxInvert->setChecked(config->invert(prefix));
127         ui()->buttonForegroundColor->setColor(config->foregroundColor(prefix));
128         ui()->sliderForegroundOpacity->setValue(config->foregroundOpacity(prefix));
129         ui()->buttonBackgroundColor->setColor(config->backgroundColor(prefix));
130         ui()->sliderBackgroundOpacity->setValue(config->backgroundOpacity(prefix));
131     }
132     emit signal_configurationUpdated();
133 }
134 
configuration(KisHalftoneFilterConfigurationSP config,const QString & prefix) const135 void KisHalftoneConfigPageWidget::configuration(KisHalftoneFilterConfigurationSP config, const QString & prefix) const
136 {
137     if (ui()->comboBoxGenerator->currentIndex() == 0) {
138         config->setGeneratorId(prefix, "");
139     } else {
140         QString generatorId = m_generatorIds.at(ui()->comboBoxGenerator->currentIndex() - 1);
141         config->setGeneratorId(prefix, generatorId);
142         if (m_generatorWidget) {
143             config->setGeneratorConfiguration(
144                 prefix, dynamic_cast<KisFilterConfiguration*>(m_generatorWidget->configuration().data())
145             );
146         }
147     }
148 
149     config->setHardness(prefix, ui()->sliderHardness->value());
150     config->setInvert(prefix, ui()->checkBoxInvert->isChecked());
151     config->setForegroundColor(prefix, ui()->buttonForegroundColor->color());
152     config->setForegroundOpacity(prefix, ui()->sliderForegroundOpacity->value());
153     config->setBackgroundColor(prefix, ui()->buttonBackgroundColor->color());
154     config->setBackgroundOpacity(prefix, ui()->sliderBackgroundOpacity->value());
155 }
156 
setGenerator(const QString & generatorId,KisFilterConfigurationSP config)157 void KisHalftoneConfigPageWidget::setGenerator(const QString & generatorId, KisFilterConfigurationSP config)
158 {
159     if (m_generatorWidget) {
160         ui()->widgetGeneratorContainer->layout()->removeWidget(m_generatorWidget);
161         delete m_generatorWidget;
162         m_generatorWidget = nullptr;
163     }
164 
165     KisGeneratorSP generator = KisGeneratorRegistry::instance()->get(generatorId);
166     if (generator) {
167         KisConfigWidget *generatorWidget = generator->createConfigurationWidget(this, m_paintDevice, false);
168         if (generatorWidget) {
169             ui()->widgetGeneratorContainer->layout()->addWidget(generatorWidget);
170             generatorWidget->setView(m_view);
171             if (config) {
172                 generatorWidget->setConfiguration(config);
173             } else {
174                 KisFilterConfigurationSP generatorConfig =
175                     generator->defaultConfiguration();
176                 generatorWidget->setConfiguration(generatorConfig);
177             }
178             m_generatorWidget = generatorWidget;
179             connect(generatorWidget, SIGNAL(sigConfigurationUpdated()), this, SIGNAL(signal_configurationUpdated()));
180         }
181     }
182 }
183 
setView(KisViewManager * view)184 void KisHalftoneConfigPageWidget::setView(KisViewManager *view)
185 {
186     m_view = view;
187     if (m_generatorWidget) {
188         m_generatorWidget->setView(m_view);
189     }
190 }
191 
slot_comboBoxGenerator_currentIndexChanged(int index)192 void KisHalftoneConfigPageWidget::slot_comboBoxGenerator_currentIndexChanged(int index)
193 {
194     if (index < 0 || index > m_generatorIds.size()) {
195         return;
196     }
197 
198     if (index == 0) {
199         setGenerator("", nullptr);
200     } else {
201         QString generatorId = m_generatorIds.at(index - 1);
202         setGenerator(generatorId, nullptr);
203     }
204 
205     emit signal_configurationUpdated();
206 }
207