File indexing completed on 2024-12-22 04:13:06
0001 /* 0002 * SPDX-FileCopyrightText: 2021 Deif Lou <ginoba@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include <QToolButton> 0008 #include <QCheckBox> 0009 #include <QHBoxLayout> 0010 0011 #include <kis_slider_spin_box.h> 0012 #include <kis_color_button.h> 0013 #include <kis_icon_utils.h> 0014 #include <KisSpinBoxI18nHelper.h> 0015 0016 #include "KisGradientColorEditor.h" 0017 0018 class Q_DECL_HIDDEN KisGradientColorEditor::Private 0019 { 0020 public: 0021 KisDoubleSliderSpinBox *positionSlider{nullptr}; 0022 QToolButton *colorTypeForegroundButton{nullptr}; 0023 QToolButton *colorTypeBackgroundButton{nullptr}; 0024 QToolButton *colorTypeCustomButton{nullptr}; 0025 QCheckBox *transparentCheckBox{nullptr}; 0026 KisColorButton *colorButton{nullptr}; 0027 KisDoubleSliderSpinBox *opacitySlider{nullptr}; 0028 }; 0029 0030 KisGradientColorEditor::KisGradientColorEditor(QWidget *parent) 0031 : QWidget(parent) 0032 , m_d(new Private) 0033 { 0034 m_d->colorTypeForegroundButton = new QToolButton; 0035 m_d->colorTypeForegroundButton->setCheckable(true); 0036 m_d->colorTypeForegroundButton->setChecked(true); 0037 m_d->colorTypeForegroundButton->setAutoExclusive(true); 0038 m_d->colorTypeForegroundButton->setAutoRaise(true); 0039 m_d->colorTypeForegroundButton->setIcon(KisIconUtils::loadIcon("object-order-lower-calligra")); 0040 m_d->colorTypeForegroundButton->setToolTip(i18nc("Button to change the gradient stop type to foreground", "Foreground color")); 0041 connect(m_d->colorTypeForegroundButton, &QToolButton::toggled, 0042 [this](bool toggled) 0043 { 0044 if (toggled) { 0045 setColorType(KisGradientWidgetsUtils::Foreground); 0046 } 0047 emit colorTypeChanged(KisGradientWidgetsUtils::Foreground); 0048 }); 0049 0050 m_d->colorTypeBackgroundButton = new QToolButton; 0051 m_d->colorTypeBackgroundButton->setCheckable(true); 0052 m_d->colorTypeBackgroundButton->setAutoExclusive(true); 0053 m_d->colorTypeBackgroundButton->setAutoRaise(true); 0054 m_d->colorTypeBackgroundButton->setIcon(KisIconUtils::loadIcon("object-order-raise-calligra")); 0055 m_d->colorTypeBackgroundButton->setToolTip(i18nc("Button to change the gradient stop type to background", "Background color")); 0056 connect(m_d->colorTypeBackgroundButton, &QToolButton::toggled, 0057 [this](bool toggled) 0058 { 0059 if (toggled) { 0060 setColorType(KisGradientWidgetsUtils::Background); 0061 } 0062 emit colorTypeChanged(KisGradientWidgetsUtils::Background); 0063 }); 0064 0065 m_d->colorTypeCustomButton = new QToolButton; 0066 m_d->colorTypeCustomButton->setCheckable(true); 0067 m_d->colorTypeCustomButton->setAutoExclusive(true); 0068 m_d->colorTypeCustomButton->setAutoRaise(true); 0069 m_d->colorTypeCustomButton->setIcon(KisIconUtils::loadIcon("wheel-sectors")); 0070 m_d->colorTypeCustomButton->setToolTip(i18nc("Button to change the gradient stop type to custom color", "Custom color")); 0071 connect(m_d->colorTypeCustomButton, &QToolButton::toggled, 0072 [this](bool toggled) 0073 { 0074 if (toggled) { 0075 setColorType(KisGradientWidgetsUtils::Custom); 0076 } 0077 emit colorTypeChanged(KisGradientWidgetsUtils::Custom); 0078 }); 0079 0080 QWidget *colorTypeButtonsContainer = new QWidget; 0081 0082 m_d->transparentCheckBox = new QCheckBox; 0083 m_d->transparentCheckBox->setText(i18n("Transparent")); 0084 m_d->transparentCheckBox->setProperty("isBeingUsed", true); 0085 connect(m_d->transparentCheckBox, SIGNAL(toggled(bool)), this, SIGNAL(transparentToggled(bool))); 0086 0087 m_d->colorButton = new KisColorButton; 0088 m_d->colorButton->setVisible(false); 0089 connect(m_d->colorButton, SIGNAL(changed(KoColor)), this, SIGNAL(colorChanged(KoColor))); 0090 0091 m_d->opacitySlider = new KisDoubleSliderSpinBox; 0092 m_d->opacitySlider->setRange(0, 100, 2); 0093 KisSpinBoxI18nHelper::setText(m_d->opacitySlider, 0094 i18nc("{n} is the number value, % is the percent sign", "Opacity: {n}%")); 0095 m_d->opacitySlider->setVisible(false); 0096 connect(m_d->opacitySlider, SIGNAL(valueChanged(double)), this, SIGNAL(opacityChanged(qreal))); 0097 0098 m_d->positionSlider = new KisDoubleSliderSpinBox; 0099 m_d->positionSlider->setRange(0, 100, 2); 0100 KisSpinBoxI18nHelper::setText(m_d->positionSlider, 0101 i18nc("{n} is the number value, % is the percent sign", "Position: {n}%")); 0102 connect(m_d->positionSlider, SIGNAL(valueChanged(double)), this, SIGNAL(positionChanged(qreal))); 0103 0104 QHBoxLayout *colorTypeButtonsLayout = new QHBoxLayout; 0105 colorTypeButtonsLayout->setMargin(0); 0106 colorTypeButtonsLayout->setSpacing(0); 0107 colorTypeButtonsLayout->addWidget(m_d->colorTypeForegroundButton); 0108 colorTypeButtonsLayout->addWidget(m_d->colorTypeBackgroundButton); 0109 colorTypeButtonsLayout->addWidget(m_d->colorTypeCustomButton); 0110 colorTypeButtonsContainer->setLayout(colorTypeButtonsLayout); 0111 0112 QHBoxLayout *mainLayout = new QHBoxLayout; 0113 mainLayout->setMargin(0); 0114 mainLayout->setSpacing(5); 0115 mainLayout->addWidget(colorTypeButtonsContainer); 0116 mainLayout->addWidget(m_d->transparentCheckBox); 0117 mainLayout->addWidget(m_d->colorButton); 0118 mainLayout->addWidget(m_d->opacitySlider); 0119 mainLayout->addStretch(); 0120 mainLayout->addWidget(m_d->positionSlider); 0121 setLayout(mainLayout); 0122 0123 setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); 0124 } 0125 0126 KisGradientColorEditor::KisGradientColorEditor(const KisGradientColorEditor &other) 0127 : QWidget() 0128 { 0129 setPosition(other.position()); 0130 setColorType(other.colorType()); 0131 setTransparent(other.transparent()); 0132 setColor(other.color()); 0133 setOpacity(other.opacity()); 0134 } 0135 0136 KisGradientColorEditor::~KisGradientColorEditor() 0137 {} 0138 0139 qreal KisGradientColorEditor::position() const 0140 { 0141 return m_d->positionSlider->value(); 0142 } 0143 0144 KisGradientWidgetsUtils::ColorType KisGradientColorEditor::colorType() const 0145 { 0146 if (m_d->colorTypeForegroundButton->isChecked()) { 0147 return KisGradientWidgetsUtils::Foreground; 0148 } else if (m_d->colorTypeBackgroundButton->isChecked()) { 0149 return KisGradientWidgetsUtils::Background; 0150 } else { 0151 return KisGradientWidgetsUtils::Custom; 0152 } 0153 } 0154 0155 KoColor KisGradientColorEditor::color() const 0156 { 0157 return m_d->colorButton->color(); 0158 } 0159 0160 bool KisGradientColorEditor::transparent() const 0161 { 0162 return m_d->transparentCheckBox->isChecked(); 0163 } 0164 0165 qreal KisGradientColorEditor::opacity() const 0166 { 0167 return m_d->opacitySlider->value(); 0168 } 0169 0170 void KisGradientColorEditor::setPosition(qreal position) 0171 { 0172 m_d->positionSlider->setValue(position); 0173 } 0174 0175 void KisGradientColorEditor::setColorType(KisGradientWidgetsUtils::ColorType type) 0176 { 0177 if (type == KisGradientWidgetsUtils::Foreground) { 0178 m_d->colorTypeForegroundButton->setChecked(true); 0179 } else if (type == KisGradientWidgetsUtils::Background) { 0180 m_d->colorTypeBackgroundButton->setChecked(true); 0181 } else { 0182 m_d->colorTypeCustomButton->setChecked(true); 0183 } 0184 0185 // "if" to avoid flickering. setUpdatesEnabled doesn't seems to work here? 0186 if (type == KisGradientWidgetsUtils::Custom) { 0187 m_d->transparentCheckBox->setVisible(false); 0188 m_d->colorButton->setVisible(true); 0189 m_d->opacitySlider->setVisible(true); 0190 } else { 0191 m_d->colorButton->setVisible(false); 0192 m_d->opacitySlider->setVisible(false); 0193 m_d->transparentCheckBox->setVisible(m_d->transparentCheckBox->property("isBeingUsed").toBool()); 0194 } 0195 0196 if (type != colorType()) { 0197 emit colorTypeChanged(type); 0198 } 0199 } 0200 0201 void KisGradientColorEditor::setTransparent(bool checked) 0202 { 0203 m_d->transparentCheckBox->setChecked(checked); 0204 } 0205 0206 void KisGradientColorEditor::setColor(KoColor color) 0207 { 0208 color.setOpacity(1.0); 0209 if (color == m_d->colorButton->color()) { 0210 return; 0211 } 0212 m_d->colorButton->setColor(color); 0213 } 0214 0215 void KisGradientColorEditor::setOpacity(qreal opacity) 0216 { 0217 m_d->opacitySlider->setValue(opacity); 0218 } 0219 0220 void KisGradientColorEditor::setUseTransParentCheckBox(bool use) 0221 { 0222 m_d->transparentCheckBox->setProperty("isBeingUsed", use); 0223 if (colorType() != KisGradientWidgetsUtils::Custom) { 0224 m_d->transparentCheckBox->setVisible(use); 0225 } 0226 } 0227 0228 void KisGradientColorEditor::setUsePositionSlider(bool use) 0229 { 0230 m_d->positionSlider->setVisible(use); 0231 } 0232 0233 void KisGradientColorEditor::setPositionSliderEnabled(bool enabled) 0234 { 0235 m_d->positionSlider->setEnabled(enabled); 0236 } 0237 0238 QSize KisGradientColorEditor::sizeHint() const 0239 { 0240 return QSize( 0241 m_d->colorTypeForegroundButton->sizeHint().width() + 0242 m_d->colorTypeBackgroundButton->sizeHint().width() + 0243 m_d->colorTypeCustomButton->sizeHint().width() + 0244 qMax( 0245 m_d->transparentCheckBox->sizeHint().width(), 0246 m_d->colorButton->sizeHint().width() + 0247 m_d->opacitySlider->sizeHint().width() 0248 ) + 0249 (m_d->positionSlider->isVisible() ? m_d->positionSlider->sizeHint().width() : 0) + 0250 15, // spacing 0251 0252 qMax( 0253 m_d->colorTypeForegroundButton->sizeHint().height(), 0254 qMax( 0255 m_d->transparentCheckBox->sizeHint().height(), 0256 qMax( 0257 m_d->colorButton->sizeHint().height(), 0258 m_d->opacitySlider->sizeHint().height() 0259 ) 0260 ) 0261 ) 0262 ); 0263 } 0264 0265 QSize KisGradientColorEditor::minimumSizeHint() const 0266 { 0267 return QSize( 0268 m_d->colorTypeForegroundButton->minimumSizeHint().width() + 0269 m_d->colorTypeBackgroundButton->minimumSizeHint().width() + 0270 m_d->colorTypeCustomButton->minimumSizeHint().width() + 0271 qMax( 0272 m_d->transparentCheckBox->minimumSizeHint().width(), 0273 m_d->colorButton->minimumSizeHint().width() + 0274 m_d->opacitySlider->minimumSizeHint().width() 0275 ) + 0276 (m_d->positionSlider->isVisible() ? m_d->positionSlider->minimumSizeHint().width() : 0) + 0277 15, // spacing 0278 0279 qMax( 0280 m_d->colorTypeForegroundButton->minimumSizeHint().height(), 0281 qMax( 0282 m_d->transparentCheckBox->minimumSizeHint().height(), 0283 qMax( 0284 m_d->colorButton->minimumSizeHint().height(), 0285 m_d->opacitySlider->minimumSizeHint().height() 0286 ) 0287 ) 0288 ) 0289 ); 0290 }