diff --git a/dialogs/imagelib/transforms/kpTransformResizeScaleDialog.cpp b/dialogs/imagelib/transforms/kpTransformResizeScaleDialog.cpp --- a/dialogs/imagelib/transforms/kpTransformResizeScaleDialog.cpp +++ b/dialogs/imagelib/transforms/kpTransformResizeScaleDialog.cpp @@ -365,17 +365,6 @@ connect (m_newHeightInput, SIGNAL (valueChanged(int)), this, SLOT (slotHeightChanged(int))); - // COMPAT: KDoubleNumInput only fires valueChanged(double) once per - // edit. It should either fire: - // - // 1. At the end of the edit (triggered by clicking or tabbing - // away), like with KDE 3. - // - // OR - // - // 2. Once per keystroke. - // - // Bug in KDoubleNumInput. connect (m_percentWidthInput, SIGNAL (valueChanged(double)), this, SLOT (slotPercentWidthChanged(double))); connect (m_percentHeightInput, SIGNAL (valueChanged(double)), diff --git a/widgets/imagelib/effects/kpEffectHSVWidget.h b/widgets/imagelib/effects/kpEffectHSVWidget.h --- a/widgets/imagelib/effects/kpEffectHSVWidget.h +++ b/widgets/imagelib/effects/kpEffectHSVWidget.h @@ -32,10 +32,6 @@ #include "kpEffectWidgetBase.h" - -class KDoubleNumInput; - - class kpEffectHSVWidget : public kpEffectWidgetBase { Q_OBJECT @@ -53,9 +49,12 @@ kpCommandEnvironment *cmdEnviron) const override; protected: - KDoubleNumInput *m_hueInput; - KDoubleNumInput *m_saturationInput; - KDoubleNumInput *m_valueInput; + KpMultDoubleSpinBox *m_hueInputSB; + KpDoubleSlider *m_hueInputS; + KpMultDoubleSpinBox *m_saturationInputSB; + KpDoubleSlider *m_saturationInputS; + KpMultDoubleSpinBox *m_valueInputSB; + KpDoubleSlider *m_valueInputS; }; diff --git a/widgets/imagelib/effects/kpEffectHSVWidget.cpp b/widgets/imagelib/effects/kpEffectHSVWidget.cpp --- a/widgets/imagelib/effects/kpEffectHSVWidget.cpp +++ b/widgets/imagelib/effects/kpEffectHSVWidget.cpp @@ -28,12 +28,13 @@ #include "kpEffectHSVWidget.h" -#include -#include +#include +#include +#include +#include #include "kpLogCategories.h" #include -#include // kdelibs4support #include "imagelib/effects/kpEffectHSV.h" #include "commands/imagelib/effects/kpEffectHSVCommand.h" @@ -49,39 +50,66 @@ QLabel *saturationLabel = new QLabel (i18n ("&Saturation:"), this); QLabel *valueLabel = new QLabel (i18nc ("The V of HSV", "&Value:"), this); - m_hueInput = new KDoubleNumInput (this); - m_hueInput->setRange (-180, 180, 15/*step*/, true/*slider*/); - - m_saturationInput = new KDoubleNumInput (this); - m_saturationInput->setRange (-1, 1, .1/*step*/, true/*slider*/); - - m_valueInput = new KDoubleNumInput (this); - m_valueInput->setRange (-1, 1, .1/*step*/, true/*slider*/); - - hueLabel->setBuddy (m_hueInput); - saturationLabel->setBuddy (m_saturationInput); - valueLabel->setBuddy (m_valueInput); + m_hueInputSB = new KpMultDoubleSpinBox (this); + m_hueInputSB->setRange (-180, 180); + m_hueInputSB->setSingleStep (15); + m_hueInputS = new KpDoubleSlider (this, -180, 180); + m_hueInputS->setRange (-100, 100); + m_hueInputS->setTickPosition(QSlider::TicksBelow); + + m_saturationInputSB = new KpMultDoubleSpinBox (this); + m_saturationInputSB->setRange (-1, 1); + m_saturationInputSB->setSingleStep (.1); + m_saturationInputS = new KpDoubleSlider (this, -1, 1); + m_saturationInputS->setRange (-100, 100); + m_saturationInputS->setTickPosition(QSlider::TicksBelow); + + m_valueInputSB = new KpMultDoubleSpinBox (this); + m_valueInputSB->setRange (-1, 1); + m_valueInputSB->setSingleStep (.1); + m_valueInputS = new KpDoubleSlider (this, -1, 1); + m_valueInputS->setRange (-100, 100); + m_valueInputS->setTickPosition(QSlider::TicksBelow); + + hueLabel->setBuddy (m_hueInputS); + saturationLabel->setBuddy (m_saturationInputS); + valueLabel->setBuddy (m_valueInputS); lay->addWidget (hueLabel, 0, 0); - lay->addWidget (m_hueInput, 0, 1); + lay->addWidget (m_hueInputS, 0, 1); + lay->addWidget (m_hueInputSB, 0, 2); lay->addWidget (saturationLabel, 1, 0); - lay->addWidget (m_saturationInput, 1, 1); + lay->addWidget (m_saturationInputS, 1, 1); + lay->addWidget (m_saturationInputSB, 1, 2); lay->addWidget (valueLabel, 2, 0); - lay->addWidget (m_valueInput, 2, 1); + lay->addWidget (m_valueInputS, 2, 1); + lay->addWidget (m_valueInputSB, 2, 2); lay->setColumnStretch (1, 1); - connect (m_hueInput, SIGNAL (valueChanged(double)), - this, SIGNAL (settingsChangedDelayed())); - - connect (m_saturationInput, SIGNAL (valueChanged(double)), - this, SIGNAL (settingsChangedDelayed())); - - connect (m_valueInput, SIGNAL (valueChanged(double)), - this, SIGNAL (settingsChangedDelayed())); + connect (m_hueInputSB, QOverload::of(&QDoubleSpinBox::valueChanged), + this, &kpEffectHSVWidget::settingsChangedDelayed); + connect (m_hueInputSB, &KpMultDoubleSpinBox::doubleSBValueChanged, + m_hueInputS, &QSlider::setValue); + connect (m_hueInputS, &KpDoubleSlider::doubleValueChanged, + m_hueInputSB, &QDoubleSpinBox::setValue); + + connect (m_saturationInputSB, QOverload::of(&QDoubleSpinBox::valueChanged), + this, &kpEffectHSVWidget::settingsChangedDelayed); + connect (m_saturationInputSB, &KpMultDoubleSpinBox::doubleSBValueChanged, + m_saturationInputS, &QSlider::setValue); + connect (m_saturationInputS, &KpDoubleSlider::doubleValueChanged, + m_saturationInputSB, &QDoubleSpinBox::setValue); + + connect (m_valueInputSB, QOverload::of(&QDoubleSpinBox::valueChanged), + this, &kpEffectHSVWidget::settingsChangedDelayed); + connect (m_valueInputSB, &KpMultDoubleSpinBox::doubleSBValueChanged, + m_valueInputS, &QSlider::setValue); + connect (m_valueInputS, &KpDoubleSlider::doubleValueChanged, + m_valueInputSB, &QDoubleSpinBox::setValue); } kpEffectHSVWidget::~kpEffectHSVWidget () @@ -100,7 +128,7 @@ // public virtual [base kpEffectWidgetBase] bool kpEffectHSVWidget::isNoOp () const { - if (m_hueInput->value () == 0 && m_saturationInput->value () == 0 && m_valueInput->value () == 0) + if (m_hueInputSB->value () == 0 && m_saturationInputSB->value () == 0 && m_valueInputSB->value () == 0) return true; else return false; @@ -110,7 +138,7 @@ kpImage kpEffectHSVWidget::applyEffect (const kpImage &image) { return kpEffectHSV::applyEffect (image, - m_hueInput->value (), m_saturationInput->value (), m_valueInput->value ()); + m_hueInputSB->value (), m_saturationInputSB->value (), m_valueInputSB->value ()); } // public virtual [base kpEffectWidgetBase] @@ -118,7 +146,7 @@ kpCommandEnvironment *cmdEnviron) const { return new kpEffectHSVCommand ( - m_hueInput->value (), m_saturationInput->value (), m_valueInput->value (), + m_hueInputSB->value (), m_saturationInputSB->value (), m_valueInputSB->value (), m_actOnSelection, cmdEnviron); } diff --git a/widgets/imagelib/effects/kpEffectToneEnhanceWidget.h b/widgets/imagelib/effects/kpEffectToneEnhanceWidget.h --- a/widgets/imagelib/effects/kpEffectToneEnhanceWidget.h +++ b/widgets/imagelib/effects/kpEffectToneEnhanceWidget.h @@ -33,10 +33,6 @@ #include "kpEffectWidgetBase.h" - -class KDoubleNumInput; - - class kpEffectToneEnhanceWidget : public kpEffectWidgetBase { Q_OBJECT @@ -60,9 +56,10 @@ kpCommandEnvironment *cmdEnviron) const override; protected: - KDoubleNumInput *m_granularityInput; - KDoubleNumInput *m_amountInput; + KpMultDoubleSpinBox *m_granularityInputSB; + KpDoubleSlider *m_granularityInputS; + KpMultDoubleSpinBox *m_amountInputSB; + KpDoubleSlider *m_amountInputS; }; - #endif // kpEffectToneEnhanceWidget_H diff --git a/widgets/imagelib/effects/kpEffectToneEnhanceWidget.cpp b/widgets/imagelib/effects/kpEffectToneEnhanceWidget.cpp --- a/widgets/imagelib/effects/kpEffectToneEnhanceWidget.cpp +++ b/widgets/imagelib/effects/kpEffectToneEnhanceWidget.cpp @@ -35,17 +35,20 @@ #include #include +#include +#include #include "kpLogCategories.h" #include -#include // kdelibs4support kpEffectToneEnhanceWidget::kpEffectToneEnhanceWidget (bool actOnSelection, QWidget *parent) : kpEffectWidgetBase (actOnSelection, parent), - m_granularityInput (nullptr), - m_amountInput (nullptr) + m_granularityInputSB (nullptr), + m_granularityInputS (nullptr), + m_amountInputSB (nullptr), + m_amountInputS (nullptr) { QGridLayout *lay = new QGridLayout (this); @@ -58,30 +61,50 @@ QLabel *amountLabel = new QLabel (i18n ("&Amount:"), this); - m_granularityInput = new KDoubleNumInput (this); - m_granularityInput->setRange (0, 1, .1/*step*/, true/*slider*/); + m_granularityInputSB = new KpMultDoubleSpinBox (this); + m_granularityInputSB->setRange (0, 1); + m_granularityInputSB->setSingleStep(0.1); + m_granularityInputS = new KpDoubleSlider (this, 0, 1); + m_granularityInputS->setRange (-100, 100); + m_granularityInputS->setValue (-100); + m_granularityInputS->setTickPosition(QSlider::TicksBelow); - m_amountInput = new KDoubleNumInput (this); - m_amountInput->setRange (0, 1, .1/*step*/, true/*slider*/); + m_amountInputSB = new KpMultDoubleSpinBox (this); + m_amountInputSB->setRange (0, 1); + m_amountInputSB->setSingleStep(0.1); + m_amountInputS = new KpDoubleSlider (this, 0, 1); + m_amountInputS->setRange (-100, 100); + m_amountInputS->setValue (-100); + m_amountInputS->setTickPosition(QSlider::TicksBelow); - granularityLabel->setBuddy (m_granularityInput); - amountLabel->setBuddy (m_amountInput); + granularityLabel->setBuddy (m_granularityInputS); + amountLabel->setBuddy (m_amountInputS); lay->addWidget (granularityLabel, 0, 0); - lay->addWidget (m_granularityInput, 0, 1); + lay->addWidget (m_granularityInputS, 0, 1); + lay->addWidget (m_granularityInputSB, 0, 2); lay->addWidget (amountLabel, 1, 0); - lay->addWidget (m_amountInput, 1, 1); + lay->addWidget (m_amountInputS, 1, 1); + lay->addWidget (m_amountInputSB, 1, 2); lay->setColumnStretch (1, 1); - connect (m_granularityInput, SIGNAL (valueChanged(double)), - this, SIGNAL (settingsChangedDelayed())); + connect (m_granularityInputSB, QOverload::of(&QDoubleSpinBox::valueChanged), + this, &kpEffectToneEnhanceWidget::settingsChangedDelayed); + connect (m_granularityInputSB, &KpMultDoubleSpinBox::doubleSBValueChanged, + m_granularityInputS, &QSlider::setValue); + connect (m_granularityInputS, &KpDoubleSlider::doubleValueChanged, + m_granularityInputSB, &QDoubleSpinBox::setValue); - connect (m_amountInput, SIGNAL (valueChanged(double)), - this, SIGNAL (settingsChangedDelayed())); + connect (m_amountInputSB, QOverload::of(&QDoubleSpinBox::valueChanged), + this, &kpEffectToneEnhanceWidget::settingsChangedDelayed); + connect (m_amountInputSB, &KpMultDoubleSpinBox::doubleSBValueChanged, + m_amountInputS, &QSlider::setValue); + connect (m_amountInputS, &KpDoubleSlider::doubleValueChanged, + m_amountInputSB, &QDoubleSpinBox::setValue); } } @@ -101,13 +124,13 @@ // private double kpEffectToneEnhanceWidget::amount () const { - return m_amountInput ? m_amountInput->value () : 0; + return m_amountInputSB ? m_amountInputSB->value () : 0; } // private double kpEffectToneEnhanceWidget::granularity () const { - return m_granularityInput ? m_granularityInput->value () : 0; + return m_granularityInputSB ? m_granularityInputSB->value () : 0; } diff --git a/widgets/imagelib/effects/kpEffectWidgetBase.h b/widgets/imagelib/effects/kpEffectWidgetBase.h --- a/widgets/imagelib/effects/kpEffectWidgetBase.h +++ b/widgets/imagelib/effects/kpEffectWidgetBase.h @@ -30,14 +30,69 @@ #define kpEffectWidgetBase_H -#include +#include #include "imagelib/kpImage.h" +#include + +#include class kpCommandEnvironment; class kpEffectCommandBase; +class KpMultDoubleSpinBox : public QDoubleSpinBox +{ + Q_OBJECT + +public: + KpMultDoubleSpinBox(QWidget *parent = 0) : QDoubleSpinBox(parent) + { + connect(this, QOverload::of(&QDoubleSpinBox::valueChanged), + this, &KpMultDoubleSpinBox::notifySBValueChanged); + } + +signals: + void doubleSBValueChanged(int value); + +public slots: + void notifySBValueChanged(double value) + { + int scale = 100; + // linear mapping [min, max] -> [-scale, scale] + double multValue = qRound((2 * value - maximum() - minimum()) / (maximum() - minimum()) * scale); + emit doubleSBValueChanged(multValue); + } +}; + +class KpDoubleSlider : public QSlider +{ + Q_OBJECT + +public: + KpDoubleSlider(QWidget *parent = 0, double minimumValue = 0, double maximumValue = 1) : QSlider(Qt::Horizontal, parent) + { + m_minValue = minimumValue; + m_maxValue = maximumValue; + connect(this, &QSlider::valueChanged, + this, &KpDoubleSlider::notifyValueChanged); + } + +signals: + void doubleValueChanged(double value); + +public slots: + void notifyValueChanged(int value) + { + int scale = 100; + // linear mapping [-scale, scale] -> [m_minValue, m_maxValue] + double doubleValue = (value / 2.0 / scale) * (m_maxValue - m_minValue) + (m_maxValue + m_minValue) / 2.0; + emit doubleValueChanged(doubleValue); + } +private: + double m_minValue; + double m_maxValue; +}; class kpEffectWidgetBase : public QWidget {