File indexing completed on 2024-05-12 16:34:28

0001 /* This file is part of the KDE project
0002  * Copyright (c) 2009 Jan Hambrecht <jaham@gmx.net>
0003  *
0004  * This library is free software; you can redistribute it and/or
0005  * modify it under the terms of the GNU Lesser General Public
0006  * License as published by the Free Software Foundation; either
0007  * version 2.1 of the License, or (at your option) any later version.
0008  *
0009  * This library is distributed in the hope that it will be useful,
0010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0012  * Library General Public License for more details.
0013  *
0014  * You should have received a copy of the GNU Lesser General Public License
0015  * along with this library; see the file COPYING.LIB.  If not, write to
0016  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0017  * Boston, MA 02110-1301, USA.
0018  */
0019 
0020 #include "ComponentTransferEffectConfigWidget.h"
0021 #include "KoFilterEffect.h"
0022 
0023 #include <QSpinBox>
0024 #include <kcombobox.h>
0025 #include <klineedit.h>
0026 #include <klocalizedstring.h>
0027 
0028 #include <QGridLayout>
0029 #include <QLabel>
0030 #include <QStackedWidget>
0031 #include <QRadioButton>
0032 #include <QButtonGroup>
0033 
0034 const qreal ValueStep = 0.1;
0035 
0036 ComponentTransferEffectConfigWidget::ComponentTransferEffectConfigWidget(QWidget *parent)
0037         : KoFilterEffectConfigWidgetBase(parent), m_effect(0)
0038         , m_currentChannel(ComponentTransferEffect::ChannelR)
0039 {
0040     QGridLayout * g = new QGridLayout(this);
0041 
0042     QButtonGroup * group = new QButtonGroup(this);
0043 
0044     QRadioButton * butR = new QRadioButton("R", this);
0045     QRadioButton * butG = new QRadioButton("G", this);
0046     QRadioButton * butB = new QRadioButton("B", this);
0047     QRadioButton * butA = new QRadioButton("A", this);
0048     g->addWidget(butR, 0, 0);
0049     g->addWidget(butG, 0, 1);
0050     g->addWidget(butB, 0, 2);
0051     g->addWidget(butA, 0, 3);
0052     group->addButton(butR, ComponentTransferEffect::ChannelR);
0053     group->addButton(butG, ComponentTransferEffect::ChannelG);
0054     group->addButton(butB, ComponentTransferEffect::ChannelB);
0055     group->addButton(butA, ComponentTransferEffect::ChannelA);
0056     butR->setChecked(true);
0057 
0058     g->addWidget(new QLabel(i18n("Function"), this), 1, 0, 1, 2);
0059     m_function = new KComboBox(this);
0060     m_function->addItem(i18n("Identity"));
0061     m_function->addItem(i18n("Table"));
0062     m_function->addItem(i18n("Discrete"));
0063     m_function->addItem(i18n("Linear"));
0064     m_function->addItem(i18n("Gamma"));
0065     g->addWidget(m_function, 1, 2, 1, 2);
0066 
0067     m_stack = new QStackedWidget(this);
0068     m_stack->setContentsMargins(0, 0, 0, 0);
0069     g->addWidget(m_stack, 2, 0, 1, 4);
0070 
0071     // Identity widget
0072     m_stack->addWidget(new QWidget(this));
0073 
0074     // Table widget
0075     QWidget * tableWidget = new QWidget(m_stack);
0076     QGridLayout * tableLayout = new QGridLayout(tableWidget);
0077     tableLayout->addWidget(new QLabel(i18n("Values"), tableWidget), 0, 0);
0078     m_tableValues = new KLineEdit(tableWidget);
0079     tableLayout->addWidget(m_tableValues, 0, 1);
0080     tableLayout->setContentsMargins(0, 0, 0, 0);
0081     tableLayout->addItem(new QSpacerItem(0, 1, QSizePolicy::Minimum, QSizePolicy::MinimumExpanding), 1, 0);
0082     m_stack->addWidget(tableWidget);
0083 
0084     // Discrete widget
0085     QWidget * discreteWidget = new QWidget(m_stack);
0086     QGridLayout * discreteLayout = new QGridLayout(discreteWidget);
0087     discreteLayout->addWidget(new QLabel(i18n("Values"), discreteWidget), 0, 0);
0088     m_discreteValues = new KLineEdit(discreteWidget);
0089     discreteLayout->addWidget(m_discreteValues, 0, 1);
0090     discreteLayout->setContentsMargins(0, 0, 0, 0);
0091     discreteLayout->addItem(new QSpacerItem(0, 1, QSizePolicy::Minimum, QSizePolicy::MinimumExpanding), 1, 0);
0092     m_stack->addWidget(discreteWidget);
0093 
0094     // Linear widget
0095     QWidget * linearWidget = new QWidget(m_stack);
0096     QGridLayout * linearLayout = new QGridLayout(linearWidget);
0097     linearLayout->addWidget(new QLabel(i18n("Slope"), linearWidget), 0, 0);
0098     m_slope = new QDoubleSpinBox(linearWidget);
0099     m_slope->setRange(m_slope->minimum(), m_slope->maximum());
0100     m_slope->setSingleStep(ValueStep);
0101     linearLayout->addWidget(m_slope, 0, 1);
0102     linearLayout->addWidget(new QLabel(i18n("Intercept")), 1, 0);
0103     m_intercept = new QDoubleSpinBox(linearWidget);
0104     m_intercept->setRange(m_intercept->minimum(), m_intercept->maximum());
0105     m_intercept->setSingleStep(ValueStep);
0106     linearLayout->addWidget(m_intercept, 1, 1);
0107     linearLayout->addItem(new QSpacerItem(0, 1, QSizePolicy::Minimum, QSizePolicy::MinimumExpanding), 2, 0);
0108     linearLayout->setContentsMargins(0, 0, 0, 0);
0109     linearWidget->setLayout(linearLayout);
0110     m_stack->addWidget(linearWidget);
0111 
0112     QWidget * gammaWidget = new QWidget(m_stack);
0113     QGridLayout * gammaLayout = new QGridLayout(gammaWidget);
0114     gammaLayout->addWidget(new QLabel(i18n("Amplitude"), gammaWidget), 0, 0);
0115     m_amplitude = new QDoubleSpinBox(gammaWidget);
0116     m_amplitude->setRange(m_amplitude->minimum(), m_amplitude->maximum());
0117     m_amplitude->setSingleStep(ValueStep);
0118     gammaLayout->addWidget(m_amplitude, 0, 1);
0119     gammaLayout->addWidget(new QLabel(i18n("Exponent"), gammaWidget), 1, 0);
0120     m_exponent = new QDoubleSpinBox(gammaWidget);
0121     m_exponent->setRange(m_exponent->minimum(), m_exponent->maximum());
0122     m_exponent->setSingleStep(ValueStep);
0123     gammaLayout->addWidget(m_exponent, 1, 1);
0124     gammaLayout->addWidget(new QLabel(i18n("Offset"), gammaWidget), 2, 0);
0125     m_offset = new QDoubleSpinBox(gammaWidget);
0126     m_offset->setRange(m_offset->minimum(), m_offset->maximum());
0127     m_offset->setSingleStep(ValueStep);
0128     gammaLayout->addWidget(m_offset, 2, 1);
0129     gammaLayout->addItem(new QSpacerItem(0, 1, QSizePolicy::Minimum, QSizePolicy::MinimumExpanding), 3, 0);
0130     gammaLayout->setContentsMargins(0, 0, 0, 0);
0131     gammaWidget->setLayout(gammaLayout);
0132     m_stack->addWidget(gammaWidget);
0133 
0134     setLayout(g);
0135 
0136     connect(m_function, SIGNAL(currentIndexChanged(int)), m_stack, SLOT(setCurrentIndex(int)));
0137     connect(m_function, SIGNAL(currentIndexChanged(int)), this, SLOT(functionChanged(int)));
0138     connect(m_tableValues, SIGNAL(editingFinished()), this, SLOT(tableValuesChanged()));
0139     connect(m_discreteValues, SIGNAL(editingFinished()), this, SLOT(discreteValuesChanged()));
0140     connect(m_slope, SIGNAL(valueChanged(double)), this, SLOT(slopeChanged(double)));
0141     connect(m_intercept, SIGNAL(valueChanged(double)), this, SLOT(interceptChanged(double)));
0142     connect(m_amplitude, SIGNAL(valueChanged(double)), this, SLOT(amplitudeChanged(double)));
0143     connect(m_exponent, SIGNAL(valueChanged(double)), this, SLOT(exponentChanged(double)));
0144     connect(m_offset, SIGNAL(valueChanged(double)), this, SLOT(offsetChanged(double)));
0145     connect(group, SIGNAL(buttonClicked(int)), this, SLOT(channelSelected(int)));
0146 }
0147 
0148 void ComponentTransferEffectConfigWidget::updateControls()
0149 {
0150     m_function->blockSignals(true);
0151 
0152     QString values;
0153 
0154     switch (m_effect->function(m_currentChannel)) {
0155     case ComponentTransferEffect::Identity:
0156         m_function->setCurrentIndex(0);
0157         break;
0158     case ComponentTransferEffect::Table:
0159         m_function->setCurrentIndex(1);
0160         m_tableValues->blockSignals(true);
0161         foreach(qreal v, m_effect->tableValues(m_currentChannel)) {
0162             values += QString("%1;").arg(v);
0163         }
0164         m_tableValues->setText(values);
0165         m_tableValues->blockSignals(false);
0166         break;
0167     case ComponentTransferEffect::Discrete:
0168         m_function->setCurrentIndex(2);
0169         m_discreteValues->blockSignals(true);
0170         foreach(qreal v, m_effect->tableValues(m_currentChannel)) {
0171             values += QString("%1;").arg(v);
0172         }
0173         m_discreteValues->setText(values);
0174         m_discreteValues->blockSignals(false);
0175         break;
0176     case ComponentTransferEffect::Linear:
0177         m_function->setCurrentIndex(3);
0178         m_slope->blockSignals(true);
0179         m_slope->setValue(m_effect->slope(m_currentChannel));
0180         m_slope->blockSignals(false);
0181         m_intercept->blockSignals(true);
0182         m_intercept->setValue(m_effect->intercept(m_currentChannel));
0183         m_intercept->blockSignals(false);
0184         break;
0185     case ComponentTransferEffect::Gamma:
0186         m_function->setCurrentIndex(4);
0187         m_amplitude->blockSignals(true);
0188         m_amplitude->setValue(m_effect->amplitude(m_currentChannel));
0189         m_amplitude->blockSignals(false);
0190         m_exponent->blockSignals(true);
0191         m_exponent->setValue(m_effect->exponent(m_currentChannel));
0192         m_exponent->blockSignals(false);
0193         m_offset->blockSignals(true);
0194         m_offset->setValue(m_effect->offset(m_currentChannel));
0195         m_offset->blockSignals(false);
0196         break;
0197     }
0198 
0199     m_function->blockSignals(false);
0200     m_stack->setCurrentIndex(m_function->currentIndex());
0201 }
0202 
0203 bool ComponentTransferEffectConfigWidget::editFilterEffect(KoFilterEffect * filterEffect)
0204 {
0205     m_effect = dynamic_cast<ComponentTransferEffect*>(filterEffect);
0206     if (!m_effect)
0207         return false;
0208 
0209     updateControls();
0210 
0211     return true;
0212 }
0213 
0214 void ComponentTransferEffectConfigWidget::slopeChanged(double slope)
0215 {
0216     if (!m_effect)
0217         return;
0218 
0219     m_effect->setSlope(m_currentChannel, slope);
0220     emit filterChanged();
0221 }
0222 
0223 void ComponentTransferEffectConfigWidget::interceptChanged(double intercept)
0224 {
0225     if (!m_effect)
0226         return;
0227 
0228     m_effect->setIntercept(m_currentChannel, intercept);
0229     emit filterChanged();
0230 }
0231 
0232 void ComponentTransferEffectConfigWidget::amplitudeChanged(double amplitude)
0233 {
0234     if (!m_effect)
0235         return;
0236 
0237     m_effect->setAmplitude(m_currentChannel, amplitude);
0238     emit filterChanged();
0239 }
0240 
0241 void ComponentTransferEffectConfigWidget::exponentChanged(double exponent)
0242 {
0243     if (!m_effect)
0244         return;
0245 
0246     m_effect->setExponent(m_currentChannel, exponent);
0247     emit filterChanged();
0248 }
0249 
0250 void ComponentTransferEffectConfigWidget::offsetChanged(double offset)
0251 {
0252     if (!m_effect)
0253         return;
0254 
0255     m_effect->setOffset(m_currentChannel, offset);
0256     emit filterChanged();
0257 }
0258 
0259 void ComponentTransferEffectConfigWidget::tableValuesChanged()
0260 {
0261     QStringList values = m_tableValues->text().split(';', QString::SkipEmptyParts);
0262     QList<qreal> tableValues;
0263     foreach(const QString &v, values) {
0264         tableValues.append(v.toDouble());
0265     }
0266     m_effect->setTableValues(m_currentChannel, tableValues);
0267     emit filterChanged();
0268 }
0269 
0270 void ComponentTransferEffectConfigWidget::discreteValuesChanged()
0271 {
0272     QStringList values = m_discreteValues->text().split(';', QString::SkipEmptyParts);
0273     QList<qreal> tableValues;
0274     foreach(const QString &v, values) {
0275         tableValues.append(v.toDouble());
0276     }
0277     m_effect->setTableValues(m_currentChannel, tableValues);
0278     emit filterChanged();
0279 }
0280 
0281 void ComponentTransferEffectConfigWidget::functionChanged(int index)
0282 {
0283     if (!m_effect)
0284         return;
0285 
0286     m_effect->setFunction(m_currentChannel, static_cast<ComponentTransferEffect::Function>(index));
0287 
0288     emit filterChanged();
0289 }
0290 
0291 void ComponentTransferEffectConfigWidget::channelSelected(int channel)
0292 {
0293     m_currentChannel = static_cast<ComponentTransferEffect::Channel>(channel);
0294     updateControls();
0295 }