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 }