File indexing completed on 2024-12-22 04:12:17

0001 /*
0002  *  SPDX-FileCopyrightText: 2016 Dmitry Kazakov <dimula73@gmail.com>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #include "kis_uniform_paintop_property_widget.h"
0008 
0009 #include <QVBoxLayout>
0010 #include <QCheckBox>
0011 #include <QComboBox>
0012 
0013 #include "kis_slider_spin_box.h"
0014 #include <KisAngleSelector.h>
0015 #include "kis_acyclic_signal_connector.h"
0016 #include "kis_slider_based_paintop_property.h"
0017 #include "kis_combo_based_paintop_property.h"
0018 #include "kis_debug.h"
0019 
0020 /****************************************************************/
0021 /*      KisUniformPaintOpPropertyWidget                         */
0022 /****************************************************************/
0023 
0024 struct KisUniformPaintOpPropertyWidget::Private
0025 {
0026     Private(KisUniformPaintOpPropertySP _property)
0027         : property(_property) {}
0028 
0029     typedef KisUniformPaintOpProperty::Type Type;
0030     KisUniformPaintOpPropertySP property;
0031 };
0032 
0033 KisUniformPaintOpPropertyWidget::KisUniformPaintOpPropertyWidget(KisUniformPaintOpPropertySP property, QWidget *parent)
0034     : QWidget(parent),
0035       m_d(new Private(property))
0036 {
0037     KisAcyclicSignalConnector *conn = new KisAcyclicSignalConnector(this);
0038     conn->connectForwardVariant(property.data(), SIGNAL(valueChanged(QVariant)),
0039                                 this, SLOT(setValue(QVariant)));
0040 
0041     conn->connectBackwardVariant(this, SIGNAL(valueChanged(QVariant)),
0042                                  property.data(), SLOT(setValue(QVariant)));
0043 }
0044 
0045 KisUniformPaintOpPropertyWidget::~KisUniformPaintOpPropertyWidget()
0046 {
0047 }
0048 
0049 KisUniformPaintOpPropertySP KisUniformPaintOpPropertyWidget::property() const
0050 {
0051     return m_d->property;
0052 }
0053 
0054 void KisUniformPaintOpPropertyWidget::slotThemeChanged(QPalette pal)
0055 {
0056     for(int i=0; i<this->children().size(); i++) {
0057         QWidget *w = qobject_cast<QWidget*>(this->children().at(i));
0058         if (w) {
0059             w->setPalette(pal);
0060         }
0061     }
0062 }
0063 
0064 /****************************************************************/
0065 /*      KisUniformPaintOpPropertyIntSlider                      */
0066 /****************************************************************/
0067 
0068 KisUniformPaintOpPropertyIntSlider::KisUniformPaintOpPropertyIntSlider(KisUniformPaintOpPropertySP property, QWidget *parent)
0069     : KisUniformPaintOpPropertyWidget(property, parent)
0070 {
0071     const QString prefix = QString("%1: ").arg(property->name());
0072     QVBoxLayout *layout = new QVBoxLayout(this);
0073 
0074     KisIntSliderBasedPaintOpProperty *sliderProperty =
0075         dynamic_cast<KisIntSliderBasedPaintOpProperty*>(property.data());
0076     KIS_ASSERT_RECOVER_RETURN(sliderProperty);
0077 
0078     connect(sliderProperty, &KisIntSliderBasedPaintOpProperty::sigRangeChanged,
0079             this, &KisUniformPaintOpPropertyIntSlider::slotRangeChanged);
0080 
0081     if (property->subType() == KisUniformPaintOpProperty::SubType_Angle) {
0082         KisAngleSelector *slider = new KisAngleSelector(this);
0083         slider->setPrefix(prefix);
0084         slider->setDecimals(0);
0085         slider->setRange(static_cast<qreal>(sliderProperty->min()), static_cast<qreal>(sliderProperty->max()));
0086         slider->setFlipOptionsMode(KisAngleSelector::FlipOptionsMode_MenuButton);
0087 
0088         slider->setAngle(static_cast<qreal>(sliderProperty->value().toInt()));
0089         connect(slider, &KisAngleSelector::angleChanged, this, [this](qreal angle) { slotSliderChanged(static_cast<int>(angle)); });
0090 
0091         m_slider = slider;
0092     } else {
0093         KisSliderSpinBox *slider = new KisSliderSpinBox(this);
0094         slider->setBlockUpdateSignalOnDrag(true);
0095         slider->setRange(sliderProperty->min(), sliderProperty->max());
0096         slider->setSingleStep(sliderProperty->singleStep());
0097         slider->setPageStep(sliderProperty->pageStep());
0098         slider->setPrefix(prefix);
0099         slider->setSuffix(sliderProperty->suffix());
0100         slider->setExponentRatio(sliderProperty->exponentRatio());
0101 
0102         slider->setValue(sliderProperty->value().toInt());
0103         connect(slider, SIGNAL(valueChanged(int)), SLOT(slotSliderChanged(int)));
0104 
0105         m_slider = slider;
0106     }
0107 
0108     layout->addWidget(m_slider);
0109 }
0110 
0111 void KisUniformPaintOpPropertyIntSlider::setValue(const QVariant &value)
0112 {
0113     if (dynamic_cast<KisAngleSelector*>(m_slider)) {
0114         dynamic_cast<KisAngleSelector*>(m_slider)->setAngle(static_cast<qreal>(value.toInt()));
0115     } else {
0116         KIS_SAFE_ASSERT_RECOVER_RETURN(dynamic_cast<KisSliderSpinBox*>(m_slider));
0117         dynamic_cast<KisSliderSpinBox*>(m_slider)->setValue(value.toInt());
0118     }
0119 }
0120 
0121 void KisUniformPaintOpPropertyIntSlider::slotSliderChanged(int value)
0122 {
0123     emit valueChanged(value);
0124 }
0125 
0126 void KisUniformPaintOpPropertyIntSlider::slotRangeChanged()
0127 {
0128     KisIntSliderBasedPaintOpProperty *sliderProperty =
0129         dynamic_cast<KisIntSliderBasedPaintOpProperty*>(property().data());
0130     KIS_ASSERT_RECOVER_RETURN(sliderProperty);
0131 
0132     if (KisAngleSelector *slider = dynamic_cast<KisAngleSelector*>(m_slider)) {
0133         slider->setRange(sliderProperty->min(), sliderProperty->max());
0134     } else if (KisSliderSpinBox *slider = dynamic_cast<KisSliderSpinBox*>(m_slider)) {
0135         slider->setRange(sliderProperty->min(), sliderProperty->max());
0136     }
0137 }
0138 
0139 /****************************************************************/
0140 /*      KisUniformPaintOpPropertyDoubleSlider                   */
0141 /****************************************************************/
0142 
0143 KisUniformPaintOpPropertyDoubleSlider::KisUniformPaintOpPropertyDoubleSlider(KisUniformPaintOpPropertySP property, QWidget *parent)
0144     : KisUniformPaintOpPropertyWidget(property, parent)
0145 {
0146     const QString prefix = QString("%1: ").arg(property->name());
0147     QVBoxLayout *layout = new QVBoxLayout(this);
0148 
0149     KisDoubleSliderBasedPaintOpProperty *sliderProperty =
0150         dynamic_cast<KisDoubleSliderBasedPaintOpProperty*>(property.data());
0151     KIS_ASSERT_RECOVER_RETURN(sliderProperty);
0152 
0153     connect(sliderProperty, &KisDoubleSliderBasedPaintOpProperty::sigRangeChanged,
0154             this, &KisUniformPaintOpPropertyDoubleSlider::slotRangeChanged);
0155 
0156     if (property->subType() == KisUniformPaintOpProperty::SubType_Angle) {
0157         KisAngleSelector *slider = new KisAngleSelector(this);
0158         slider->setPrefix(prefix);
0159         slider->setDecimals(sliderProperty->decimals());
0160         slider->setRange(sliderProperty->min(), sliderProperty->max());
0161         slider->setFlipOptionsMode(KisAngleSelector::FlipOptionsMode_MenuButton);
0162 
0163         slider->setAngle(sliderProperty->value().toReal());
0164         connect(slider, SIGNAL(angleChanged(qreal)), SLOT(slotSliderChanged(qreal)));
0165 
0166         m_slider = slider;
0167     } else {
0168         KisDoubleSliderSpinBox *slider = new KisDoubleSliderSpinBox(this);
0169         slider->setBlockUpdateSignalOnDrag(true);
0170         slider->setRange(sliderProperty->min(), sliderProperty->max(), sliderProperty->decimals());
0171         slider->setSingleStep(sliderProperty->singleStep());
0172         slider->setPrefix(prefix);
0173         slider->setSuffix(sliderProperty->suffix());
0174         slider->setExponentRatio(sliderProperty->exponentRatio());
0175 
0176         slider->setValue(sliderProperty->value().toReal());
0177         connect(slider, SIGNAL(valueChanged(qreal)), SLOT(slotSliderChanged(qreal)));
0178 
0179         m_slider = slider;
0180     }
0181 
0182     layout->addWidget(m_slider);
0183 }
0184 
0185 void KisUniformPaintOpPropertyDoubleSlider::setValue(const QVariant &value)
0186 {
0187     if (dynamic_cast<KisAngleSelector*>(m_slider)) {
0188         dynamic_cast<KisAngleSelector*>(m_slider)->setAngle(value.toInt());
0189     } else {
0190         KIS_SAFE_ASSERT_RECOVER_RETURN(dynamic_cast<KisDoubleSliderSpinBox*>(m_slider));
0191         dynamic_cast<KisDoubleSliderSpinBox*>(m_slider)->setValue(value.toInt());
0192     }
0193 }
0194 
0195 void KisUniformPaintOpPropertyDoubleSlider::slotSliderChanged(qreal value)
0196 {
0197     emit valueChanged(value);
0198 }
0199 
0200 void KisUniformPaintOpPropertyDoubleSlider::slotRangeChanged()
0201 {
0202     KisDoubleSliderBasedPaintOpProperty *sliderProperty =
0203         dynamic_cast<KisDoubleSliderBasedPaintOpProperty*>(property().data());
0204     KIS_ASSERT_RECOVER_RETURN(sliderProperty);
0205 
0206     if (KisAngleSelector *slider = dynamic_cast<KisAngleSelector*>(m_slider)) {
0207         slider->setRange(sliderProperty->min(), sliderProperty->max());
0208     } else if (KisDoubleSliderSpinBox *slider = dynamic_cast<KisDoubleSliderSpinBox*>(m_slider)) {
0209         slider->setRange(sliderProperty->min(), sliderProperty->max());
0210     }
0211 }
0212 
0213 /****************************************************************/
0214 /*      KisUniformPaintOpPropertyCheckBox                       */
0215 /****************************************************************/
0216 
0217 KisUniformPaintOpPropertyCheckBox::KisUniformPaintOpPropertyCheckBox(KisUniformPaintOpPropertySP property, QWidget *parent)
0218     : KisUniformPaintOpPropertyWidget(property, parent)
0219 {
0220     QVBoxLayout *layout = new QVBoxLayout(this);
0221 
0222     m_checkBox = new QCheckBox(property->name(), this);
0223     m_checkBox->setChecked(property->value().toBool());
0224     connect(m_checkBox, SIGNAL(toggled(bool)), SLOT(slotCheckBoxChanged(bool)));
0225 
0226     layout->addWidget(m_checkBox);
0227 }
0228 
0229 void KisUniformPaintOpPropertyCheckBox::setValue(const QVariant &value)
0230 {
0231     m_checkBox->setChecked(value.toBool());
0232 }
0233 
0234 void KisUniformPaintOpPropertyCheckBox::slotCheckBoxChanged(bool value)
0235 {
0236     emit valueChanged(value);
0237 }
0238 
0239 /****************************************************************/
0240 /*      KisUniformPaintOpPropertyComboBox                       */
0241 /****************************************************************/
0242 
0243 KisUniformPaintOpPropertyComboBox::KisUniformPaintOpPropertyComboBox(KisUniformPaintOpPropertySP property, QWidget *parent)
0244     : KisUniformPaintOpPropertyWidget(property, parent)
0245 {
0246     QVBoxLayout *layout = new QVBoxLayout(this);
0247 
0248     KisComboBasedPaintOpProperty *comboProperty =
0249         dynamic_cast<KisComboBasedPaintOpProperty*>(property.data());
0250     KIS_ASSERT_RECOVER_RETURN(comboProperty);
0251 
0252     const QList<QString> items = comboProperty->items();
0253     const QList<QIcon> icons = comboProperty->icons();
0254 
0255     m_comboBox = new QComboBox(this);
0256 
0257     KIS_SAFE_ASSERT_RECOVER_RETURN(icons.isEmpty() ||
0258                                    items.size() == icons.size());
0259 
0260     if (!icons.isEmpty()) {
0261         auto itemIt = items.constBegin();
0262         auto iconIt = icons.constBegin();
0263 
0264         while (itemIt != items.constEnd() &&
0265                iconIt != icons.constEnd()) {
0266 
0267             m_comboBox->addItem(*iconIt, *itemIt);
0268 
0269             ++itemIt;
0270             ++iconIt;
0271         }
0272     } else {
0273         Q_FOREACH (const QString &item, items) {
0274             m_comboBox->addItem(item);
0275         }
0276     }
0277 
0278     m_comboBox->setCurrentIndex(property->value().toInt());
0279     connect(m_comboBox, SIGNAL(currentIndexChanged(int)), SLOT(slotComboBoxChanged(int)));
0280 
0281     layout->addWidget(m_comboBox);
0282 }
0283 
0284 void KisUniformPaintOpPropertyComboBox::setValue(const QVariant &value)
0285 {
0286     m_comboBox->setCurrentIndex(value.toInt());
0287 }
0288 
0289 void KisUniformPaintOpPropertyComboBox::slotComboBoxChanged(int value)
0290 {
0291     emit valueChanged(value);
0292 }