File indexing completed on 2024-04-28 05:41:41

0001 /*
0002     Copied from Qt 5.6.3 sources, module qttools, directory src/shared/qtgradienteditor
0003     with small modifications to match more modern C++ standards and for no alpha-channel
0004 
0005     This file is part of the tools applications of the Qt Toolkit.
0006 
0007     SPDX-FileCopyrightText: 2015 The Qt Company Ltd. <http://www.qt.io/licensing/>
0008 
0009     SPDX-License-Identifier: LGPL-2.1-only WITH Qt-LGPL-exception-1.1 OR LGPL-3.0-only WITH Qt-LGPL-exception-1.1 OR LicenseRef-Qt-Commercial
0010 */
0011 
0012 #include "qtcolorbutton.h"
0013 #include <QColorDialog>
0014 #include <QPainter>
0015 #include <QMimeData>
0016 #include <QDragEnterEvent>
0017 #include <QDrag>
0018 #include <QApplication>
0019 
0020 QT_BEGIN_NAMESPACE
0021 
0022 class QtColorButtonPrivate
0023 {
0024     QtColorButton *q_ptr;
0025     Q_DECLARE_PUBLIC(QtColorButton)
0026 public:
0027     QColor m_color;
0028 #ifndef QT_NO_DRAGANDDROP
0029     QColor m_dragColor;
0030     QPoint m_dragStart;
0031     bool m_dragging;
0032 #endif
0033     bool m_backgroundCheckered;
0034 
0035     void slotEditColor();
0036     QColor shownColor() const;
0037     QPixmap generatePixmap() const;
0038 };
0039 
0040 void QtColorButtonPrivate::slotEditColor()
0041 {
0042     const QColor newColor = QColorDialog::getColor(m_color, q_ptr);
0043     if (!newColor.isValid() || newColor == q_ptr->color())
0044         return;
0045     q_ptr->setColor(newColor);
0046     emit q_ptr->colorChanged(m_color);
0047 }
0048 
0049 QColor QtColorButtonPrivate::shownColor() const
0050 {
0051 #ifndef QT_NO_DRAGANDDROP
0052     if (m_dragging)
0053         return m_dragColor;
0054 #endif
0055     return m_color;
0056 }
0057 
0058 QPixmap QtColorButtonPrivate::generatePixmap() const
0059 {
0060     QPixmap pix(24, 24);
0061 
0062     int pixSize = 20;
0063     QBrush br(shownColor());
0064 
0065     QPixmap pm(2 * pixSize, 2 * pixSize);
0066     QPainter pmp(&pm);
0067     pmp.fillRect(0, 0, pixSize, pixSize, Qt::lightGray);
0068     pmp.fillRect(pixSize, pixSize, pixSize, pixSize, Qt::lightGray);
0069     pmp.fillRect(0, pixSize, pixSize, pixSize, Qt::darkGray);
0070     pmp.fillRect(pixSize, 0, pixSize, pixSize, Qt::darkGray);
0071     pmp.fillRect(0, 0, 2 * pixSize, 2 * pixSize, shownColor());
0072     br = QBrush(pm);
0073 
0074     QPainter p(&pix);
0075     int corr = 1;
0076     QRect r = pix.rect().adjusted(corr, corr, -corr, -corr);
0077     p.setBrushOrigin((r.width() % pixSize + pixSize) / 2 + corr, (r.height() % pixSize + pixSize) / 2 + corr);
0078     p.fillRect(r, br);
0079 
0080     p.fillRect(r.width() / 4 + corr, r.height() / 4 + corr,
0081                r.width() / 2, r.height() / 2,
0082                QColor(shownColor().rgb()));
0083     p.drawRect(pix.rect().adjusted(0, 0, -1, -1));
0084 
0085     return pix;
0086 }
0087 
0088 ///////////////
0089 
0090 QtColorButton::QtColorButton(QWidget *parent)
0091     : QToolButton(parent), d_ptr(new QtColorButtonPrivate)
0092 {
0093     d_ptr->q_ptr = this;
0094     d_ptr->m_dragging = false;
0095     d_ptr->m_backgroundCheckered = true;
0096 
0097     setAcceptDrops(true);
0098 
0099     connect(this, SIGNAL(clicked()), this, SLOT(slotEditColor()));
0100     setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred));
0101 }
0102 
0103 QtColorButton::~QtColorButton()
0104 {
0105 }
0106 
0107 void QtColorButton::setColor(const QColor &color)
0108 {
0109     if (d_ptr->m_color == color)
0110         return;
0111     d_ptr->m_color = color;
0112     update();
0113 }
0114 
0115 QColor QtColorButton::color() const
0116 {
0117     return d_ptr->m_color;
0118 }
0119 
0120 void QtColorButton::setBackgroundCheckered(bool checkered)
0121 {
0122     if (d_ptr->m_backgroundCheckered == checkered)
0123         return;
0124     d_ptr->m_backgroundCheckered = checkered;
0125     update();
0126 }
0127 
0128 bool QtColorButton::isBackgroundCheckered() const
0129 {
0130     return d_ptr->m_backgroundCheckered;
0131 }
0132 
0133 void QtColorButton::paintEvent(QPaintEvent *event)
0134 {
0135     QToolButton::paintEvent(event);
0136     if (!isEnabled())
0137         return;
0138 
0139     const int pixSize = 10;
0140     QBrush br(d_ptr->shownColor());
0141     if (d_ptr->m_backgroundCheckered) {
0142         QPixmap pm(2 * pixSize, 2 * pixSize);
0143         QPainter pmp(&pm);
0144         pmp.fillRect(0, 0, pixSize, pixSize, Qt::white);
0145         pmp.fillRect(pixSize, pixSize, pixSize, pixSize, Qt::white);
0146         pmp.fillRect(0, pixSize, pixSize, pixSize, Qt::black);
0147         pmp.fillRect(pixSize, 0, pixSize, pixSize, Qt::black);
0148         pmp.fillRect(0, 0, 2 * pixSize, 2 * pixSize, d_ptr->shownColor());
0149         br = QBrush(pm);
0150     }
0151 
0152     QPainter p(this);
0153     const int corr = 4;
0154     QRect r = rect().adjusted(corr, corr, -corr, -corr);
0155     p.setBrushOrigin((r.width() % pixSize + pixSize) / 2 + corr, (r.height() % pixSize + pixSize) / 2 + corr);
0156     p.fillRect(r, br);
0157 
0158     //const int adjX = qRound(r.width() / 4.0);
0159     //const int adjY = qRound(r.height() / 4.0);
0160     //p.fillRect(r.adjusted(adjX, adjY, -adjX, -adjY),
0161     //           QColor(d_ptr->shownColor().rgb()));
0162     /*
0163     p.fillRect(r.adjusted(0, r.height() * 3 / 4, 0, 0),
0164                QColor(d_ptr->shownColor().rgb()));
0165     p.fillRect(r.adjusted(0, 0, 0, -r.height() * 3 / 4),
0166                QColor(d_ptr->shownColor().rgb()));
0167                */
0168     /*
0169     const QColor frameColor0(0, 0, 0, qRound(0.2 * (0xFF - d_ptr->shownColor().alpha())));
0170     p.setPen(frameColor0);
0171     p.drawRect(r.adjusted(adjX, adjY, -adjX - 1, -adjY - 1));
0172     */
0173 
0174     const QColor frameColor1(0, 0, 0, 26);
0175     p.setPen(frameColor1);
0176     p.drawRect(r.adjusted(1, 1, -2, -2));
0177     const QColor frameColor2(0, 0, 0, 51);
0178     p.setPen(frameColor2);
0179     p.drawRect(r.adjusted(0, 0, -1, -1));
0180 }
0181 
0182 void QtColorButton::mousePressEvent(QMouseEvent *event)
0183 {
0184 #ifndef QT_NO_DRAGANDDROP
0185     if (event->button() == Qt::LeftButton)
0186         d_ptr->m_dragStart = event->pos();
0187 #endif
0188     QToolButton::mousePressEvent(event);
0189 }
0190 
0191 void QtColorButton::mouseMoveEvent(QMouseEvent *event)
0192 {
0193 #ifndef QT_NO_DRAGANDDROP
0194     if (event->buttons() & Qt::LeftButton &&
0195         (d_ptr->m_dragStart - event->pos()).manhattanLength() > QApplication::startDragDistance()) {
0196         QMimeData *mime = new QMimeData;
0197         mime->setColorData(color());
0198         QDrag *drg = new QDrag(this);
0199         drg->setMimeData(mime);
0200         drg->setPixmap(d_ptr->generatePixmap());
0201         setDown(false);
0202         event->accept();
0203         drg->exec();
0204         return;
0205     }
0206 #endif
0207     QToolButton::mouseMoveEvent(event);
0208 }
0209 
0210 #ifndef QT_NO_DRAGANDDROP
0211 void QtColorButton::dragEnterEvent(QDragEnterEvent *event)
0212 {
0213     const QMimeData *mime = event->mimeData();
0214     if (!mime->hasColor())
0215         return;
0216 
0217     event->accept();
0218     d_ptr->m_dragColor = qvariant_cast<QColor>(mime->colorData());
0219     d_ptr->m_dragging = true;
0220     update();
0221 }
0222 
0223 void QtColorButton::dragLeaveEvent(QDragLeaveEvent *event)
0224 {
0225     event->accept();
0226     d_ptr->m_dragging = false;
0227     update();
0228 }
0229 
0230 void QtColorButton::dropEvent(QDropEvent *event)
0231 {
0232     event->accept();
0233     d_ptr->m_dragging = false;
0234     if (d_ptr->m_dragColor == color())
0235         return;
0236     setColor(d_ptr->m_dragColor);
0237     emit colorChanged(color());
0238 }
0239 #endif
0240 
0241 QT_END_NAMESPACE
0242 
0243 #include "moc_qtcolorbutton.cpp"