File indexing completed on 2024-05-12 16:02:00
0001 /* 0002 * SPDX-FileCopyrightText: 2008 Cyrille Berger <cberger@cberger.net> 0003 * SPDX-FileCopyrightText: 2011 Sven Langkamp <sven.langkamp@gmail.com> 0004 * SPDX-FileCopyrightText: 2015 Moritz Molch <kde@moritzmolch.de> 0005 * 0006 * SPDX-License-Identifier: LGPL-2.0-or-later 0007 */ 0008 0009 #include "kis_color_input.h" 0010 0011 #include <KoConfig.h> 0012 #ifdef HAVE_OPENEXR 0013 #include <half.h> 0014 #endif 0015 0016 #include <cmath> 0017 0018 #include <kis_debug.h> 0019 0020 #include <QHBoxLayout> 0021 #include <QLabel> 0022 #include <QLineEdit> 0023 #include <QSpinBox> 0024 #include <QDoubleSpinBox> 0025 0026 #include <klocalizedstring.h> 0027 0028 #include <KoChannelInfo.h> 0029 #include <KoColor.h> 0030 #include <KoColorSlider.h> 0031 #include <KoColorSpace.h> 0032 #include <KisHsvColorSlider.h> 0033 0034 #include "kis_double_parse_spin_box.h" 0035 #include "kis_int_parse_spin_box.h" 0036 #include "kis_signals_blocker.h" 0037 0038 KisColorInput::KisColorInput(QWidget* parent, const KoChannelInfo* channelInfo, KoColor* color, KoColorDisplayRendererInterface *displayRenderer, bool usePercentage) : 0039 QWidget(parent), m_channelInfo(channelInfo), m_color(color), m_displayRenderer(displayRenderer), 0040 m_usePercentage(usePercentage) 0041 { 0042 } 0043 0044 void KisColorInput::init() 0045 { 0046 QHBoxLayout* m_layout = new QHBoxLayout(this); 0047 m_layout->setContentsMargins(0,0,0,0); 0048 m_layout->setSpacing(1); 0049 0050 QLabel* m_label = new QLabel(i18n("%1:", m_channelInfo->name()), this); 0051 m_layout->addWidget(m_label); 0052 0053 m_colorSlider = new KoColorSlider(Qt::Horizontal, this, m_displayRenderer); 0054 m_colorSlider->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); 0055 m_layout->addWidget(m_colorSlider); 0056 0057 QWidget* m_input = createInput(); 0058 m_layout->addWidget(m_input); 0059 } 0060 0061 KisIntegerColorInput::KisIntegerColorInput(QWidget* parent, const KoChannelInfo* channelInfo, KoColor* color, KoColorDisplayRendererInterface *displayRenderer, bool usePercentage) : 0062 KisColorInput(parent, channelInfo, color, displayRenderer, usePercentage) 0063 { 0064 init(); 0065 } 0066 0067 void KisIntegerColorInput::setValue(int v) 0068 { 0069 quint8* data = m_color->data() + m_channelInfo->pos(); 0070 switch (m_channelInfo->channelValueType()) { 0071 case KoChannelInfo::UINT8: 0072 *(reinterpret_cast<quint8*>(data)) = v; 0073 break; 0074 case KoChannelInfo::UINT16: 0075 *(reinterpret_cast<quint16*>(data)) = v; 0076 break; 0077 case KoChannelInfo::UINT32: 0078 *(reinterpret_cast<quint32*>(data)) = v; 0079 break; 0080 default: 0081 Q_ASSERT(false); 0082 } 0083 emit(updated()); 0084 } 0085 0086 void KisIntegerColorInput::update() 0087 { 0088 KoColor min = *m_color; 0089 KoColor max = *m_color; 0090 quint8* data = m_color->data() + m_channelInfo->pos(); 0091 quint8* dataMin = min.data() + m_channelInfo->pos(); 0092 quint8* dataMax = max.data() + m_channelInfo->pos(); 0093 m_intNumInput->blockSignals(true); 0094 m_colorSlider->blockSignals(true); 0095 switch (m_channelInfo->channelValueType()) { 0096 case KoChannelInfo::UINT8: 0097 if (m_usePercentage) { 0098 m_intNumInput->setMaximum(100); 0099 m_intNumInput->setValue(round(*(reinterpret_cast<quint8*>(data))*1.0 / 255.0 * 100.0)); 0100 } else { 0101 m_intNumInput->setMaximum(0xFF); 0102 m_intNumInput->setValue(*(reinterpret_cast<quint8*>(data))); 0103 } 0104 m_colorSlider->setValue(*(reinterpret_cast<quint8*>(data))); 0105 *(reinterpret_cast<quint8*>(dataMin)) = 0x0; 0106 *(reinterpret_cast<quint8*>(dataMax)) = 0xFF; 0107 break; 0108 case KoChannelInfo::UINT16: 0109 if (m_usePercentage) { 0110 m_intNumInput->setMaximum(100); 0111 m_intNumInput->setValue(round(*(reinterpret_cast<quint16*>(data))*1.0 / 65535.0 * 100.0)); 0112 } else { 0113 m_intNumInput->setMaximum(0xFFFF); 0114 m_intNumInput->setValue(*(reinterpret_cast<quint16*>(data))); 0115 } 0116 m_colorSlider->setValue(*(reinterpret_cast<quint16*>(data))); 0117 *(reinterpret_cast<quint16*>(dataMin)) = 0x0; 0118 *(reinterpret_cast<quint16*>(dataMax)) = 0xFFFF; 0119 break; 0120 case KoChannelInfo::UINT32: 0121 if (m_usePercentage) { 0122 m_intNumInput->setMaximum(100); 0123 m_intNumInput->setValue(round(*(reinterpret_cast<quint32*>(data))*1.0 / 4294967295.0 * 100.0)); 0124 } else { 0125 m_intNumInput->setMaximum(0xFFFF); 0126 m_intNumInput->setValue(*(reinterpret_cast<quint32*>(data))); 0127 } 0128 m_colorSlider->setValue(*(reinterpret_cast<quint32*>(data))); 0129 *(reinterpret_cast<quint32*>(dataMin)) = 0x0; 0130 *(reinterpret_cast<quint32*>(dataMax)) = 0xFFFFFFFF; 0131 break; 0132 default: 0133 Q_ASSERT(false); 0134 } 0135 m_colorSlider->setColors(min, max); 0136 m_intNumInput->blockSignals(false); 0137 m_colorSlider->blockSignals(false); 0138 } 0139 0140 QWidget* KisIntegerColorInput::createInput() 0141 { 0142 m_intNumInput = new KisIntParseSpinBox(this); 0143 m_intNumInput->setMinimum(0); 0144 m_colorSlider->setMinimum(0); 0145 0146 if (m_usePercentage) { 0147 m_intNumInput->setSuffix(i18n("%")); 0148 } else { 0149 m_intNumInput->setSuffix(""); 0150 } 0151 0152 switch (m_channelInfo->channelValueType()) { 0153 case KoChannelInfo::UINT8: 0154 if (m_usePercentage) { 0155 m_intNumInput->setMaximum(100); 0156 } else { 0157 m_intNumInput->setMaximum(0xFF); 0158 } 0159 m_colorSlider->setMaximum(0xFF); 0160 break; 0161 case KoChannelInfo::UINT16: 0162 if (m_usePercentage) { 0163 m_intNumInput->setMaximum(100); 0164 } else { 0165 m_intNumInput->setMaximum(0xFFFF); 0166 } 0167 m_colorSlider->setMaximum(0xFFFF); 0168 break; 0169 case KoChannelInfo::UINT32: 0170 if (m_usePercentage) { 0171 m_intNumInput->setMaximum(100); 0172 } else { 0173 m_intNumInput->setMaximum(0xFFFFFFFF); 0174 } 0175 m_colorSlider->setMaximum(0xFFFFFFFF); 0176 break; 0177 default: 0178 Q_ASSERT(false); 0179 } 0180 connect(m_colorSlider, SIGNAL(valueChanged(int)), this, SLOT(onColorSliderChanged(int))); 0181 connect(m_intNumInput, SIGNAL(valueChanged(int)), this, SLOT(onNumInputChanged(int))); 0182 return m_intNumInput; 0183 } 0184 0185 void KisIntegerColorInput::setPercentageWise(bool val) 0186 { 0187 m_usePercentage = val; 0188 0189 if (m_usePercentage) { 0190 m_intNumInput->setSuffix(i18n("%")); 0191 } else { 0192 m_intNumInput->setSuffix(""); 0193 } 0194 } 0195 0196 void KisIntegerColorInput::onColorSliderChanged(int val) 0197 { 0198 m_intNumInput->blockSignals(true); 0199 if (m_usePercentage) { 0200 switch (m_channelInfo->channelValueType()) { 0201 case KoChannelInfo::UINT8: 0202 m_intNumInput->setValue(round((val*1.0) / 255.0 * 100.0)); 0203 break; 0204 case KoChannelInfo::UINT16: 0205 m_intNumInput->setValue(round((val*1.0) / 65535.0 * 100.0)); 0206 break; 0207 case KoChannelInfo::UINT32: 0208 m_intNumInput->setValue(round((val*1.0) / 4294967295.0 * 100.0)); 0209 break; 0210 default: 0211 Q_ASSERT(false); 0212 } 0213 } else { 0214 m_intNumInput->setValue(val); 0215 } 0216 m_intNumInput->blockSignals(false); 0217 setValue(val); 0218 } 0219 0220 void KisIntegerColorInput::onNumInputChanged(int val) 0221 { 0222 m_colorSlider->blockSignals(true); 0223 if (m_usePercentage) { 0224 switch (m_channelInfo->channelValueType()) { 0225 case KoChannelInfo::UINT8: 0226 m_colorSlider->setValue((val*1.0)/100.0 * 255.0); 0227 m_colorSlider->blockSignals(false); 0228 setValue((val*1.0)/100.0 * 255.0); 0229 break; 0230 case KoChannelInfo::UINT16: 0231 m_colorSlider->setValue((val*1.0)/100.0 * 65535.0); 0232 m_colorSlider->blockSignals(false); 0233 setValue((val*1.0)/100.0 * 65535.0); 0234 break; 0235 case KoChannelInfo::UINT32: 0236 m_colorSlider->setValue((val*1.0)/100.0 * 4294967295.0); 0237 m_colorSlider->blockSignals(false); 0238 setValue((val*1.0)/100.0 * 4294967295.0); 0239 break; 0240 default: 0241 Q_ASSERT(false); 0242 } 0243 } else { 0244 m_colorSlider->setValue(val); 0245 m_colorSlider->blockSignals(false); 0246 setValue(val); 0247 } 0248 } 0249 0250 KisFloatColorInput::KisFloatColorInput(QWidget* parent, const KoChannelInfo* channelInfo, KoColor* color, KoColorDisplayRendererInterface *displayRenderer, bool usePercentage) : 0251 KisColorInput(parent, channelInfo, color, displayRenderer, usePercentage) 0252 { 0253 init(); 0254 } 0255 0256 void KisFloatColorInput::setValue(double v) 0257 { 0258 quint8* data = m_color->data() + m_channelInfo->pos(); 0259 switch (m_channelInfo->channelValueType()) { 0260 #ifdef HAVE_OPENEXR 0261 case KoChannelInfo::FLOAT16: 0262 *(reinterpret_cast<half*>(data)) = v; 0263 break; 0264 #endif 0265 case KoChannelInfo::FLOAT32: 0266 *(reinterpret_cast<float*>(data)) = v; 0267 break; 0268 default: 0269 Q_ASSERT(false); 0270 } 0271 emit(updated()); 0272 } 0273 0274 QWidget* KisFloatColorInput::createInput() 0275 { 0276 m_dblNumInput = new KisDoubleParseSpinBox(this); 0277 m_dblNumInput->setMinimum(0); 0278 m_dblNumInput->setMaximum(1.0); 0279 connect(m_colorSlider, SIGNAL(valueChanged(int)), this, SLOT(sliderChanged(int))); 0280 connect(m_dblNumInput, SIGNAL(valueChanged(double)), this, SLOT(setValue(double))); 0281 m_dblNumInput->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Preferred); 0282 m_dblNumInput->setMinimumWidth(60); 0283 m_dblNumInput->setMaximumWidth(60); 0284 0285 quint8* data = m_color->data() + m_channelInfo->pos(); 0286 qreal value = 1.0; 0287 0288 switch (m_channelInfo->channelValueType()) { 0289 #ifdef HAVE_OPENEXR 0290 case KoChannelInfo::FLOAT16: 0291 value = *(reinterpret_cast<half*>(data)); 0292 break; 0293 #endif 0294 case KoChannelInfo::FLOAT32: 0295 value = *(reinterpret_cast<float*>(data)); 0296 break; 0297 default: 0298 Q_ASSERT(false); 0299 } 0300 m_dblNumInput->setValue(value); 0301 0302 return m_dblNumInput; 0303 } 0304 0305 void KisFloatColorInput::sliderChanged(int i) 0306 { 0307 const qreal floatRange = m_maxValue - m_minValue; 0308 m_dblNumInput->setValue(m_minValue + (i / 255.0) * floatRange); 0309 } 0310 0311 void KisFloatColorInput::update() 0312 { 0313 KoColor min = *m_color; 0314 KoColor max = *m_color; 0315 quint8* data = m_color->data() + m_channelInfo->pos(); 0316 quint8* dataMin = min.data() + m_channelInfo->pos(); 0317 quint8* dataMax = max.data() + m_channelInfo->pos(); 0318 0319 qreal value = 1.0; 0320 m_minValue = m_displayRenderer->minVisibleFloatValue(m_channelInfo); 0321 m_maxValue = m_displayRenderer->maxVisibleFloatValue(m_channelInfo); 0322 m_dblNumInput->blockSignals(true); 0323 m_colorSlider->blockSignals(true); 0324 0325 switch (m_channelInfo->channelValueType()) { 0326 #ifdef HAVE_OPENEXR 0327 case KoChannelInfo::FLOAT16: 0328 value = *(reinterpret_cast<half*>(data)); 0329 m_minValue = qMin(value, m_minValue); 0330 m_maxValue = qMax(value, m_maxValue); 0331 *(reinterpret_cast<half*>(dataMin)) = m_minValue; 0332 *(reinterpret_cast<half*>(dataMax)) = m_maxValue; 0333 break; 0334 #endif 0335 case KoChannelInfo::FLOAT32: 0336 value = *(reinterpret_cast<float*>(data)); 0337 m_minValue = qMin(value, m_minValue); 0338 m_maxValue = qMax(value, m_maxValue); 0339 *(reinterpret_cast<float*>(dataMin)) = m_minValue; 0340 *(reinterpret_cast<float*>(dataMax)) = m_maxValue; 0341 break; 0342 default: 0343 Q_ASSERT(false); 0344 } 0345 0346 m_dblNumInput->setMinimum(m_minValue); 0347 m_dblNumInput->setMaximum(m_maxValue); 0348 0349 // ensure at least 3 significant digits are always shown 0350 int newPrecision = 2 + qMax(qreal(0.0), std::ceil(-std::log10(m_maxValue))); 0351 if (newPrecision != m_dblNumInput->decimals()) { 0352 m_dblNumInput->setDecimals(newPrecision); 0353 m_dblNumInput->updateGeometry(); 0354 } 0355 m_dblNumInput->setValue(value); 0356 0357 m_colorSlider->setColors(min, max); 0358 0359 const qreal floatRange = m_maxValue - m_minValue; 0360 m_colorSlider->setValue((value - m_minValue) / floatRange * 255); 0361 m_dblNumInput->blockSignals(false); 0362 m_colorSlider->blockSignals(false); 0363 } 0364 0365 KisHexColorInput::KisHexColorInput(QWidget* parent, KoColor* color, KoColorDisplayRendererInterface *displayRenderer, bool usePercentage, bool usePreview) : 0366 KisColorInput(parent, 0, color, displayRenderer, usePercentage) 0367 { 0368 QHBoxLayout* m_layout = new QHBoxLayout(this); 0369 m_layout->setContentsMargins(0,0,0,0); 0370 m_layout->setSpacing(1); 0371 0372 QLabel* m_label = new QLabel(i18n("Color name:"), this); 0373 m_label->setMinimumWidth(50); 0374 m_layout->addWidget(m_label); 0375 0376 QWidget* m_input = createInput(); 0377 m_input->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Preferred); 0378 0379 if(usePreview) { 0380 m_colorPreview = new QLabel(""); 0381 m_colorPreview->setMinimumWidth(30); 0382 m_layout->addWidget(m_colorPreview); 0383 } 0384 0385 m_layout->addWidget(m_input); 0386 } 0387 0388 void KisHexColorInput::setValue() 0389 { 0390 QString valueString = m_hexInput->text(); 0391 valueString.remove(QChar('#')); 0392 0393 QList<KoChannelInfo*> channels = m_color->colorSpace()->channels(); 0394 channels = KoChannelInfo::displayOrderSorted(channels); 0395 Q_FOREACH (KoChannelInfo* channel, channels) { 0396 if (channel->channelType() == KoChannelInfo::COLOR) { 0397 Q_ASSERT(channel->channelValueType() == KoChannelInfo::UINT8); 0398 quint8* data = m_color->data() + channel->pos(); 0399 0400 int value = valueString.left(2).toInt(0, 16); 0401 *(reinterpret_cast<quint8*>(data)) = value; 0402 valueString.remove(0, 2); 0403 } 0404 } 0405 emit(updated()); 0406 } 0407 0408 void KisHexColorInput::update() 0409 { 0410 QString hexString("#"); 0411 0412 QList<KoChannelInfo*> channels = m_color->colorSpace()->channels(); 0413 channels = KoChannelInfo::displayOrderSorted(channels); 0414 Q_FOREACH (KoChannelInfo* channel, channels) { 0415 if (channel->channelType() == KoChannelInfo::COLOR) { 0416 Q_ASSERT(channel->channelValueType() == KoChannelInfo::UINT8); 0417 quint8* data = m_color->data() + channel->pos(); 0418 hexString.append(QString("%1").arg(*(reinterpret_cast<quint8*>(data)), 2, 16, QChar('0'))); 0419 } 0420 } 0421 m_hexInput->setText(hexString); 0422 if( m_colorPreview) { 0423 m_colorPreview->setStyleSheet(QString("background-color: %1").arg(m_displayRenderer->toQColor(*m_color).name())); 0424 } 0425 } 0426 0427 QWidget* KisHexColorInput::createInput() 0428 { 0429 m_hexInput = new QLineEdit(this); 0430 m_hexInput->setAlignment(Qt::AlignRight); 0431 0432 int digits = 2*m_color->colorSpace()->colorChannelCount(); 0433 QString pattern = QString("#?[a-fA-F0-9]{%1,%2}").arg(digits).arg(digits); 0434 m_hexInput->setValidator(new QRegExpValidator(QRegExp(pattern), this)); 0435 connect(m_hexInput, SIGNAL(editingFinished()), this, SLOT(setValue())); 0436 return m_hexInput; 0437 } 0438 0439 0440 KisHsvColorInput::KisHsvColorInput(QWidget *parent, KoColor *color) 0441 : QWidget(parent) 0442 , m_color(color) 0443 , m_hSlider(nullptr) 0444 , m_sSlider(nullptr) 0445 , m_vSlider(nullptr) 0446 , m_hInput(nullptr) 0447 , m_sInput(nullptr) 0448 , m_vInput(nullptr) 0449 , m_h(0) 0450 , m_s(0) 0451 , m_v(0) 0452 { 0453 0454 QLabel *labels[3]; 0455 KisHsvColorSlider *sliders[3]; 0456 KisDoubleParseSpinBox *inputs[3]; 0457 const char *labelNames[3] = { "H:", "S:", "V:" }; 0458 qreal maxValues[3] = { 360, 100, 100 }; 0459 int labelWidth = 0; 0460 0461 QVBoxLayout *mainLayout = new QVBoxLayout(this); 0462 mainLayout->setContentsMargins(0,0,0,0); 0463 0464 for (int i = 0; i < 3; i++) { 0465 // Slider layout 0466 QHBoxLayout *sliderLayout = new QHBoxLayout(); 0467 sliderLayout->setContentsMargins(0,0,0,0); 0468 sliderLayout->setSpacing(1); 0469 0470 // Label 0471 QLabel *label = new QLabel(i18n(labelNames[i]), this); 0472 sliderLayout->addWidget(label); 0473 0474 // Slider itself 0475 KisHsvColorSlider *slider = new KisHsvColorSlider(Qt::Horizontal, this); 0476 slider->setMinimum(0); 0477 slider->setMaximum(maxValues[i]); 0478 slider->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); 0479 sliderLayout->addWidget(slider); 0480 0481 // Input box 0482 KisDoubleParseSpinBox *input = new KisDoubleParseSpinBox(this); 0483 input->setMinimum(0); 0484 input->setMaximum(maxValues[i]); 0485 0486 input->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Preferred); 0487 input->setMinimumWidth(60); 0488 input->setMaximumWidth(60); 0489 0490 slider->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); 0491 sliderLayout->addWidget(input); 0492 0493 mainLayout->addLayout(sliderLayout); 0494 0495 // Record max label width 0496 labelWidth = qMax(labelWidth, label->sizeHint().width()); 0497 0498 sliders[i] = slider; 0499 inputs[i] = input; 0500 labels[i] = label; 0501 } 0502 0503 // Align the labels 0504 for (int i = 0; i < 3; i++) { 0505 labels[i]->setMinimumWidth(labelWidth); 0506 } 0507 0508 // Connect slots 0509 connect(sliders[0], SIGNAL(valueChanged(int)), this, SLOT(hueSliderChanged(int))); 0510 connect(inputs[0], SIGNAL(valueChanged(double)), this, SLOT(setHue(double))); 0511 connect(sliders[1], SIGNAL(valueChanged(int)), this, SLOT(saturationSliderChanged(int))); 0512 connect(inputs[1], SIGNAL(valueChanged(double)), this, SLOT(setSaturation(double))); 0513 connect(sliders[2], SIGNAL(valueChanged(int)), this, SLOT(valueSliderChanged(int))); 0514 connect(inputs[2], SIGNAL(valueChanged(double)), this, SLOT(setValue(double))); 0515 0516 m_hSlider = sliders[0]; 0517 m_sSlider = sliders[1]; 0518 m_vSlider = sliders[2]; 0519 0520 m_hInput = inputs[0]; 0521 m_sInput = inputs[1]; 0522 m_vInput = inputs[2]; 0523 0524 // Set initial values 0525 QColor c = m_color->toQColor(); 0526 c.getHsvF(&m_h, &m_s, &m_v); 0527 m_hInput->setValue(m_h); 0528 m_sInput->setValue(m_s); 0529 m_vInput->setValue(m_v); 0530 0531 // Update sliders 0532 QColor minC, maxC; 0533 minC.setHsvF(0, 1, 1); 0534 maxC.setHsvF(1, 1, 1); 0535 m_hSlider->setColors(minC, maxC); 0536 m_hSlider->setCircularHue(true); 0537 0538 recolorSliders(); 0539 } 0540 0541 void KisHsvColorInput::sendUpdate() 0542 { 0543 { 0544 KisSignalsBlocker blocker( 0545 m_hSlider, m_sSlider, m_vSlider 0546 ); 0547 m_hSlider->setValue(m_h * 360); 0548 m_sSlider->setValue(m_s * 100); 0549 m_vSlider->setValue(m_v * 100); 0550 } 0551 0552 recolorSliders(); 0553 0554 QColor c; 0555 c.setHsvF(m_h, m_s, m_v); 0556 0557 m_color->fromQColor(c); 0558 emit(updated()); 0559 } 0560 0561 void KisHsvColorInput::setHue(double x) 0562 { 0563 if (x < 0) { 0564 x = 0; 0565 } 0566 0567 if (x > 360) { 0568 x = 360; 0569 } 0570 0571 m_h = x / 360; 0572 sendUpdate(); 0573 } 0574 0575 void KisHsvColorInput::setSaturation(double x) 0576 { 0577 if (x < 0) { 0578 x = 0; 0579 } 0580 0581 if (x > 100) { 0582 x = 100; 0583 } 0584 0585 m_s = x / 100; 0586 sendUpdate(); 0587 } 0588 0589 void KisHsvColorInput::setValue(double x) 0590 { 0591 if (x < 0) { 0592 x = 0; 0593 } 0594 0595 if (x > 100) { 0596 x = 100; 0597 } 0598 0599 m_v = x / 100; 0600 sendUpdate(); 0601 } 0602 0603 void KisHsvColorInput::hueSliderChanged(int i) 0604 { 0605 m_hInput->setValue(i); 0606 } 0607 0608 void KisHsvColorInput::saturationSliderChanged(int i) 0609 { 0610 m_sInput->setValue(i); 0611 } 0612 0613 void KisHsvColorInput::valueSliderChanged(int i) 0614 { 0615 m_vInput->setValue(i); 0616 } 0617 0618 void KisHsvColorInput::recolorSliders() { 0619 // Update sliders 0620 QColor minC, maxC; 0621 minC.setHsvF(m_h, 0, m_v); 0622 maxC.setHsvF(m_h, 1, m_v); 0623 m_sSlider->setColors(minC, maxC); 0624 0625 minC.setHsvF(m_h, m_s, 0); 0626 maxC.setHsvF(m_h, m_s, 1); 0627 m_vSlider->setColors(minC, maxC); 0628 } 0629 0630 void KisHsvColorInput::update() 0631 { 0632 KisSignalsBlocker blocker( 0633 m_hInput, m_sInput, m_vInput, 0634 m_hSlider, m_sSlider, m_vSlider 0635 ); 0636 0637 // Check if it is the same color we have 0638 QColor current; 0639 current.setHsvF(m_h, m_s, m_v); 0640 QColor theirs = m_color->toQColor(); 0641 0642 // Truncate to integer for this check 0643 if (!(current.red() == theirs.red() && current.green() == theirs.green() && current.blue() == theirs.blue())) { 0644 // Apply the update 0645 qreal theirH; 0646 theirs.getHsvF(&theirH, &m_s, &m_v); 0647 0648 // Don't jump the Hue slider around to 0 if it is currently on 360 0649 const qreal EPSILON = 1e-6; 0650 if (!((1.0 - m_h) < EPSILON && (theirH - 0.0) < EPSILON)) { 0651 m_h = theirH; 0652 } 0653 0654 m_hInput->setValue(m_h * 360); 0655 m_sInput->setValue(m_s * 100); 0656 m_vInput->setValue(m_v * 100); 0657 0658 recolorSliders(); 0659 0660 // Update slider positions 0661 m_hSlider->setValue(m_h * 360); 0662 m_sSlider->setValue(m_s * 100); 0663 m_vSlider->setValue(m_v * 100); 0664 } 0665 }