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 }