File indexing completed on 2024-05-12 16:02:07
0001 /* This file is part of the KDE project 0002 SPDX-FileCopyrightText: 2006 Sven Langkamp <sven.langkamp@gmail.com> 0003 SPDX-FileCopyrightText: 2009 Cyrille Berger <cberger@cberger.net> 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 #include "KoColorSlider.h" 0008 #include "KoColorSpace.h" 0009 0010 #include <KoColor.h> 0011 #include <KoMixColorsOp.h> 0012 0013 #include <QPainter> 0014 #include <QTimer> 0015 #include <QStyleOption> 0016 #include <QPointer> 0017 0018 #define ARROWSIZE 8 0019 0020 struct Q_DECL_HIDDEN KoColorSlider::Private 0021 { 0022 Private() : upToDate(false), displayRenderer(0) {} 0023 KoColor minColor; 0024 KoColor maxColor; 0025 QPixmap pixmap; 0026 bool upToDate; 0027 QPointer<KoColorDisplayRendererInterface> displayRenderer; 0028 }; 0029 0030 KoColorSlider::KoColorSlider(QWidget* parent, KoColorDisplayRendererInterface *displayRenderer) 0031 : KSelector(parent) 0032 , d(new Private) 0033 { 0034 setMaximum(255); 0035 d->displayRenderer = displayRenderer; 0036 connect(d->displayRenderer, SIGNAL(displayConfigurationChanged()), SLOT(update()), Qt::UniqueConnection); 0037 } 0038 0039 KoColorSlider::KoColorSlider(Qt::Orientation o, QWidget *parent, KoColorDisplayRendererInterface *displayRenderer) 0040 : KSelector(o, parent), d(new Private) 0041 { 0042 setMaximum(255); 0043 d->displayRenderer = displayRenderer; 0044 connect(d->displayRenderer, SIGNAL(displayConfigurationChanged()), SLOT(update()), Qt::UniqueConnection); 0045 } 0046 0047 KoColorSlider::~KoColorSlider() 0048 { 0049 delete d; 0050 } 0051 0052 void KoColorSlider::setColors(const KoColor& mincolor, const KoColor& maxcolor) 0053 { 0054 d->minColor = mincolor; 0055 d->maxColor = maxcolor; 0056 d->upToDate = false; 0057 QTimer::singleShot(1, this, SLOT(update())); 0058 } 0059 0060 void KoColorSlider::drawContents( QPainter *painter ) 0061 { 0062 QPixmap checker(8, 8); 0063 QPainter p(&checker); 0064 p.fillRect(0, 0, 4, 4, Qt::lightGray); 0065 p.fillRect(4, 0, 4, 4, Qt::darkGray); 0066 p.fillRect(0, 4, 4, 4, Qt::darkGray); 0067 p.fillRect(4, 4, 4, 4, Qt::lightGray); 0068 p.end(); 0069 QRect contentsRect_(contentsRect()); 0070 painter->fillRect(contentsRect_, QBrush(checker)); 0071 0072 if( !d->upToDate || d->pixmap.isNull() || d->pixmap.width() != contentsRect_.width() 0073 || d->pixmap.height() != contentsRect_.height() ) 0074 { 0075 KoColor c = d->minColor; // smart way to fetch colorspace 0076 QColor color; 0077 0078 const quint8 *colors[2]; 0079 colors[0] = d->minColor.data(); 0080 colors[1] = d->maxColor.data(); 0081 0082 KoMixColorsOp * mixOp = c.colorSpace()->mixColorsOp(); 0083 Q_ASSERT(mixOp); 0084 QImage image(contentsRect_.width(), contentsRect_.height(), QImage::Format_ARGB32 ); 0085 0086 if( orientation() == Qt::Horizontal ) { 0087 for (int x = 0; x < contentsRect_.width(); x++) { 0088 0089 qreal t = static_cast<qreal>(x) / (contentsRect_.width() - 1); 0090 0091 qint16 colorWeights[2]; 0092 colorWeights[0] = static_cast<quint8>((1.0 - t) * 255 + 0.5); 0093 colorWeights[1] = 255 - colorWeights[0]; 0094 0095 mixOp->mixColors(colors, colorWeights, 2, c.data()); 0096 0097 if (d->displayRenderer) { 0098 color = d->displayRenderer->toQColor(c); 0099 } 0100 else { 0101 color = c.toQColor(); 0102 } 0103 0104 for (int y = 0; y < contentsRect_.height(); y++) 0105 image.setPixel(x, y, color.rgba()); 0106 } 0107 } 0108 else { 0109 for (int y = 0; y < contentsRect_.height(); y++) { 0110 0111 qreal t = static_cast<qreal>(y) / (contentsRect_.height() - 1); 0112 0113 qint16 colorWeights[2]; 0114 colorWeights[0] = static_cast<quint8>((t) * 255 + 0.5); 0115 colorWeights[1] = 255 - colorWeights[0]; 0116 0117 mixOp->mixColors(colors, colorWeights, 2, c.data()); 0118 0119 if (d->displayRenderer) { 0120 color = d->displayRenderer->toQColor(c); 0121 } 0122 else { 0123 color = c.toQColor(); 0124 } 0125 0126 for (int x = 0; x < contentsRect_.width(); x++) 0127 image.setPixel(x, y, color.rgba()); 0128 } 0129 } 0130 d->pixmap = QPixmap::fromImage(image); 0131 d->upToDate = true; 0132 } 0133 painter->drawPixmap( contentsRect_, d->pixmap, QRect( 0, 0, d->pixmap.width(), d->pixmap.height()) ); 0134 } 0135 0136 KoColor KoColorSlider::currentColor() const 0137 { 0138 const quint8 *colors[2]; 0139 colors[0] = d->minColor.data(); 0140 colors[1] = d->maxColor.data(); 0141 KoMixColorsOp * mixOp = d->minColor.colorSpace()->mixColorsOp(); 0142 KoColor c(d->minColor.colorSpace()); 0143 qint16 weights[2]; 0144 weights[1] = (value() - minimum()) / qreal(maximum() - minimum()) * 255; 0145 weights[0] = 255 - weights[1]; 0146 mixOp->mixColors(colors, weights, 2, c.data()); 0147 return c; 0148 } 0149 0150 void KoColorSlider::drawArrow(QPainter *painter, const QPoint &pos) 0151 { 0152 painter->setPen(QPen(palette().text().color(), 0)); 0153 painter->setBrush(palette().text()); 0154 0155 QStyleOption o; 0156 o.initFrom(this); 0157 o.state &= ~QStyle::State_MouseOver; 0158 0159 if ( orientation() == Qt::Vertical ) { 0160 o.rect = QRect( pos.x(), pos.y() - ARROWSIZE / 2, 0161 ARROWSIZE, ARROWSIZE ); 0162 } else { 0163 o.rect = QRect( pos.x() - ARROWSIZE / 2, pos.y(), 0164 ARROWSIZE, ARROWSIZE ); 0165 } 0166 0167 QStyle::PrimitiveElement arrowPE; 0168 switch (arrowDirection()) { 0169 case Qt::UpArrow: 0170 arrowPE = QStyle::PE_IndicatorArrowUp; 0171 break; 0172 case Qt::DownArrow: 0173 arrowPE = QStyle::PE_IndicatorArrowDown; 0174 break; 0175 case Qt::RightArrow: 0176 arrowPE = QStyle::PE_IndicatorArrowRight; 0177 break; 0178 case Qt::LeftArrow: 0179 default: 0180 arrowPE = QStyle::PE_IndicatorArrowLeft; 0181 break; 0182 } 0183 0184 style()->drawPrimitive(arrowPE, &o, painter, this); 0185 0186 }