File indexing completed on 2024-06-16 04:10:09

0001 /*
0002    Copyright (c) 2003-2007 Clarence Dang <dang@kde.org>
0003    All rights reserved.
0004 
0005    Redistribution and use in source and binary forms, with or without
0006    modification, are permitted provided that the following conditions
0007    are met:
0008 
0009    1. Redistributions of source code must retain the above copyright
0010       notice, this list of conditions and the following disclaimer.
0011    2. Redistributions in binary form must reproduce the above copyright
0012       notice, this list of conditions and the following disclaimer in the
0013       documentation and/or other materials provided with the distribution.
0014 
0015    THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
0016    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0017    OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
0018    IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
0019    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
0020    NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0021    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0022    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0023    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
0024    THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0025 */
0026 
0027 
0028 #define DEBUG_KP_EFFECT_BALANCE 0
0029 
0030 
0031 #include "kpEffectBalanceWidget.h"
0032 
0033 #include "imagelib/effects/kpEffectBalance.h"
0034 #include "commands/imagelib/effects/kpEffectBalanceCommand.h"
0035 #include "pixmapfx/kpPixmapFX.h"
0036 
0037 #include "kpLogCategories.h"
0038 #include <KLocalizedString>
0039 #include "kpNumInput.h"
0040 
0041 #include <cmath>
0042 
0043 #include <QComboBox>
0044 #include <QGridLayout>
0045 #include <QLabel>
0046 #include <QPushButton>
0047 
0048 #if DEBUG_KP_EFFECT_BALANCE
0049     #include <qdatetime.h>
0050 #endif
0051 
0052 
0053 kpEffectBalanceWidget::kpEffectBalanceWidget (bool actOnSelection,
0054                                               QWidget *parent)
0055     : kpEffectWidgetBase (actOnSelection, parent)
0056 {
0057     auto *lay = new QGridLayout (this);
0058     lay->setContentsMargins(0, 0, 0, 0);
0059 
0060     auto *brightnessLabel = new QLabel (i18n ("&Brightness:"), this);
0061     m_brightnessInput = new kpIntNumInput (0/*value*/, this);
0062     m_brightnessInput->setRange (-50, 50);
0063     auto *brightnessResetPushButton = new QPushButton (i18n ("Re&set"), this);
0064 
0065     auto *contrastLabel = new QLabel (i18n ("Co&ntrast:"), this);
0066     m_contrastInput = new kpIntNumInput (0/*value*/, this);
0067     m_contrastInput->setRange (-50, 50);
0068      auto *contrastResetPushButton = new QPushButton (i18n ("&Reset"), this);
0069 
0070     auto *gammaLabel = new QLabel (i18n ("&Gamma:"), this);
0071     m_gammaInput = new kpIntNumInput (0/*value*/, this);
0072     m_gammaInput->setRange (-50, 50);
0073     // TODO: This is what should be shown in the m_gammaInput spinbox
0074     m_gammaLabel = new QLabel (this);
0075     // TODO: This doesn't seem to be wide enough with some fonts so the
0076     //       whole layout moves when we drag the gamma slider.
0077     m_gammaLabel->setMinimumWidth(m_gammaLabel->fontMetrics().horizontalAdvance(QLatin1String(" 10.00 ")));
0078     m_gammaLabel->setAlignment (m_gammaLabel->alignment () | Qt::AlignRight);
0079     auto *gammaResetPushButton = new QPushButton (i18n ("Rese&t"), this);
0080 
0081 
0082     auto *spaceWidget = new QLabel (this);
0083     spaceWidget->setFixedSize (1, fontMetrics ().height () / 4);
0084 
0085 
0086     auto *channelLabel = new QLabel (i18n ("C&hannels:"), this);
0087     m_channelsComboBox = new QComboBox (this);
0088     m_channelsComboBox->addItem (i18n ("All"));
0089     m_channelsComboBox->addItem (i18n ("Red"));
0090     m_channelsComboBox->addItem (i18n ("Green"));
0091     m_channelsComboBox->addItem (i18n ("Blue"));
0092 
0093 
0094     auto *resetPushButton = new QPushButton (i18n ("Reset &All Values"), this);
0095 
0096 
0097     brightnessLabel->setBuddy (m_brightnessInput);
0098     contrastLabel->setBuddy (m_contrastInput);
0099     gammaLabel->setBuddy (m_gammaInput);
0100 
0101     channelLabel->setBuddy (m_channelsComboBox);
0102 
0103 
0104     lay->addWidget (brightnessLabel, 0, 0);
0105     lay->addWidget (m_brightnessInput, 0, 1, 1, 2);
0106     lay->addWidget (brightnessResetPushButton, 0, 4);
0107 
0108     lay->addWidget (contrastLabel, 1, 0);
0109     lay->addWidget (m_contrastInput, 1, 1, 1, 2);
0110     lay->addWidget (contrastResetPushButton, 1, 4);
0111 
0112     lay->addWidget (gammaLabel, 2, 0);
0113     lay->addWidget (m_gammaInput, 2, 1, 1, 2);
0114     lay->addWidget (m_gammaLabel, 2, 3);
0115     lay->addWidget (gammaResetPushButton, 2, 4);
0116 
0117     lay->addWidget (spaceWidget, 3, 0, 1, 5);
0118     lay->addWidget (resetPushButton, 4, 2, 1, 3, Qt::AlignRight);
0119 
0120     lay->addWidget (channelLabel, 4, 0);
0121     lay->addWidget (m_channelsComboBox, 4, 1, Qt::AlignLeft);
0122     //lay->addWidget (resetPushButton, 4, 2, Qt::AlignRight);
0123 
0124     lay->setColumnStretch (1, 1);
0125 
0126 
0127     // (no need for settingsChangedDelayed() since BCG effect is so fast :))
0128     connect (m_brightnessInput, &kpIntNumInput::valueChanged,
0129              this, &kpEffectBalanceWidget::settingsChangedNoWaitCursor);
0130     connect (m_contrastInput, &kpIntNumInput::valueChanged,
0131              this, &kpEffectBalanceWidget::settingsChangedNoWaitCursor);
0132 
0133     connect (m_gammaInput, &kpIntNumInput::valueChanged,
0134              this, &kpEffectBalanceWidget::recalculateGammaLabel);
0135     connect (m_gammaInput, &kpIntNumInput::valueChanged,
0136              this, &kpEffectBalanceWidget::settingsChangedNoWaitCursor);
0137 
0138     connect (m_channelsComboBox,
0139              static_cast<void (QComboBox::*)(int)>(&QComboBox::activated),
0140              this, &kpEffectBalanceWidget::settingsChanged);
0141 
0142     connect (brightnessResetPushButton, &QPushButton::clicked,
0143              this, &kpEffectBalanceWidget::resetBrightness);
0144     connect (contrastResetPushButton, &QPushButton::clicked,
0145              this, &kpEffectBalanceWidget::resetContrast);
0146     connect (gammaResetPushButton, &QPushButton::clicked,
0147              this, &kpEffectBalanceWidget::resetGamma);
0148 
0149     connect (resetPushButton, &QPushButton::clicked,
0150              this, &kpEffectBalanceWidget::resetAll);
0151 
0152     recalculateGammaLabel ();
0153 }
0154 
0155 kpEffectBalanceWidget::~kpEffectBalanceWidget () = default;
0156 
0157 
0158 // public virtual [base kpEffectWidgetBase]
0159 QString kpEffectBalanceWidget::caption () const
0160 {
0161     return i18n ("Settings");
0162 }
0163 
0164 
0165 // public virtual [base kpEffectWidgetBase]
0166 bool kpEffectBalanceWidget::isNoOp () const
0167 {
0168     return (brightness () == 0 && contrast () == 0 && gamma () == 0);
0169 }
0170 
0171 // public virtual [base kpEffectWidgetBase]
0172 kpImage kpEffectBalanceWidget::applyEffect (const kpImage &image)
0173 {
0174     return kpEffectBalance::applyEffect (image,
0175         channels (), brightness (), contrast (), gamma ());
0176 }
0177 
0178 // public virtual [base kpEffectWidgetBase]
0179 kpEffectCommandBase *kpEffectBalanceWidget::createCommand (
0180         kpCommandEnvironment *cmdEnviron) const
0181 {
0182     return new kpEffectBalanceCommand (channels (),
0183                                        brightness (), contrast (), gamma (),
0184                                        m_actOnSelection,
0185                                        cmdEnviron);
0186 }
0187 
0188 
0189 // protected
0190 int kpEffectBalanceWidget::channels () const
0191 {
0192     switch (m_channelsComboBox->currentIndex ())
0193     {
0194     default:
0195     case 0:
0196         return kpEffectBalance::RGB;
0197 
0198     case 1:
0199         return kpEffectBalance::Red;
0200 
0201     case 2:
0202         return kpEffectBalance::Green;
0203 
0204     case 3:
0205         return kpEffectBalance::Blue;
0206     }
0207 }
0208 
0209 
0210 // protected
0211 int kpEffectBalanceWidget::brightness () const
0212 {
0213     return m_brightnessInput->value ();
0214 }
0215 
0216 // protected
0217 int kpEffectBalanceWidget::contrast () const
0218 {
0219     return m_contrastInput->value ();
0220 }
0221 
0222 // protected
0223 int kpEffectBalanceWidget::gamma () const
0224 {
0225     return m_gammaInput->value ();
0226 }
0227 
0228 
0229 // protected slot
0230 void kpEffectBalanceWidget::recalculateGammaLabel ()
0231 {
0232     m_gammaLabel->setText (
0233         QLatin1String (" ") +
0234         QString::number (std::pow (10, gamma () / 50.0),
0235                          'f'/*[-]9.9*/,
0236                          2/*precision*/) +
0237         QLatin1String (" "));
0238     m_gammaLabel->repaint ();
0239 }
0240 
0241 
0242 // protected slot
0243 void kpEffectBalanceWidget::resetBrightness ()
0244 {
0245     if (brightness () == 0) {
0246         return;
0247     }
0248 
0249     bool sb = signalsBlocked ();
0250 
0251     if (!sb) {
0252         blockSignals (true);
0253     }
0254     m_brightnessInput->setValue (0);
0255     if (!sb) {
0256         blockSignals (false);
0257     }
0258 
0259     // Immediate update (if signals aren't blocked)
0260     Q_EMIT settingsChanged ();
0261 }
0262 
0263 // protected slot
0264 void kpEffectBalanceWidget::resetContrast ()
0265 {
0266     if (contrast () == 0) {
0267         return;
0268     }
0269 
0270     bool sb = signalsBlocked ();
0271 
0272     if (!sb) {
0273         blockSignals (true);
0274     }
0275     m_contrastInput->setValue (0);
0276     if (!sb) {
0277         blockSignals (false);
0278     }
0279 
0280     // Immediate update (if signals aren't blocked)
0281     Q_EMIT settingsChanged ();
0282 }
0283 
0284 // protected slot
0285 void kpEffectBalanceWidget::resetGamma ()
0286 {
0287     if (gamma () == 0) {
0288         return;
0289     }
0290 
0291     bool sb = signalsBlocked ();
0292 
0293     if (!sb) {
0294         blockSignals (true);
0295     }
0296     m_gammaInput->setValue (0);
0297     recalculateGammaLabel ();
0298     if (!sb) {
0299         blockSignals (false);
0300     }
0301 
0302     // Immediate update (if signals aren't blocked)
0303     Q_EMIT settingsChanged ();
0304 }
0305 
0306 
0307 // protected slot
0308 void kpEffectBalanceWidget::resetAll ()
0309 {
0310     if (isNoOp ()) {
0311         return;
0312     }
0313 
0314     // Prevent multiple settingsChanged() which would normally result in
0315     // redundant, expensive preview repaints
0316     blockSignals (true);
0317 
0318     resetBrightness ();
0319     resetContrast ();
0320     resetGamma ();
0321 
0322     recalculateGammaLabel ();
0323 
0324     blockSignals (false);
0325 
0326     Q_EMIT settingsChanged ();
0327 }
0328 
0329 #include "moc_kpEffectBalanceWidget.cpp"