summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Gil <davidgiloliva@gmail.com>2013-04-18 01:05:41 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-04-28 03:27:49 +0200
commitd928dbbc919f5f39af9ce5c69eb8e9ffa9da71d3 (patch)
tree336ae10f82e711a9b4e9354567c8eb1a75c1cf71
parent67d7651212bd9485f475a8e079f17b5606168245 (diff)
Add a screen color picker button to QColorDialog
Add a new button with which any color present on the screen can be picked up. This feature is very useful in any image processing application. Notice: --I have setMouseTracking to true because I consider that it makes much easier to grab the desired color. --I have set the cursor manually because for some unknown reason the cursor wouldn't change with grabMouse(Qt::CrossCursor). Task-number: QTBUG-14332 Change-Id: I39e3543d3ed55276f43d569a2f03087bbf89b27a Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com> Reviewed-by: Kevin Ottens <kevin.ottens@kdab.com> Reviewed-by: Lars Knoll <lars.knoll@digia.com>
-rw-r--r--src/widgets/dialogs/qcolordialog.cpp120
-rw-r--r--src/widgets/dialogs/qcolordialog.h4
-rw-r--r--src/widgets/dialogs/qcolordialog_p.h7
3 files changed, 130 insertions, 1 deletions
diff --git a/src/widgets/dialogs/qcolordialog.cpp b/src/widgets/dialogs/qcolordialog.cpp
index d6254076c5..5edf883e5a 100644
--- a/src/widgets/dialogs/qcolordialog.cpp
+++ b/src/widgets/dialogs/qcolordialog.cpp
@@ -63,6 +63,8 @@
#include "qmimedata.h"
#include "qspinbox.h"
#include "qdialogbuttonbox.h"
+#include "qscreen.h"
+#include "qcursor.h"
QT_BEGIN_NAMESPACE
@@ -1417,6 +1419,15 @@ bool QColorDialogPrivate::selectColor(const QColor &col)
return false;
}
+QColor QColorDialogPrivate::grabScreenColor(const QPoint &p)
+{
+ const QDesktopWidget *desktop = QApplication::desktop();
+ const QPixmap pixmap = QGuiApplication::screens().at(desktop->screenNumber())->grabWindow(desktop->winId(),
+ p.x(), p.y(), 1, 1);
+ QImage i = pixmap.toImage();
+ return i.pixel(0, 0);
+}
+
//sets all widgets except cs to display rgb
void QColorDialogPrivate::_q_newColorTypedIn(QRgb rgb)
{
@@ -1442,6 +1453,48 @@ void QColorDialogPrivate::_q_newStandard(int r, int c)
custom->setSelected(-1,-1);
}
+void QColorDialogPrivate::_q_pickScreenColor()
+{
+ Q_Q(QColorDialog);
+ screenColorPicking = true;
+ // If user pushes Escape, the last color before picking will be restored.
+ beforeScreenColorPicking = cs->currentColor();
+ /*For some reason, q->grabMouse(Qt::CrossCursor) doesn't change
+ * the cursor, and therefore I have to change it manually.
+ */
+ q->grabMouse();
+ q->setCursor(Qt::CrossCursor);
+ q->grabKeyboard();
+ /* With setMouseTracking(true) the desired color can be more precisedly picked up,
+ * and continuously pushing the mouse button is not necessary.
+ */
+ q->setMouseTracking(true);
+
+ addCusBt->setDisabled(true);
+ buttons->setDisabled(true);
+ screenColorPickerButton->setDisabled(true);
+
+ q->setCurrentColor(grabScreenColor(QCursor::pos()));
+ lblScreenColorInfo->setText(QColorDialog::tr("Cursor at %1, %2, color: %3\nPress ESC to cancel")
+ .arg(QCursor::pos().x())
+ .arg(QCursor::pos().y())
+ .arg(q->currentColor().name()));
+}
+
+void QColorDialogPrivate::releaseColorPicking()
+{
+ Q_Q(QColorDialog);
+ screenColorPicking = false;
+ q->releaseMouse();
+ q->releaseKeyboard();
+ q->setCursor(Qt::ArrowCursor);
+ q->setMouseTracking(false);
+ lblScreenColorInfo->setText(QLatin1String("\n"));
+ addCusBt->setDisabled(false);
+ buttons->setDisabled(false);
+ screenColorPickerButton->setDisabled(false);
+}
+
void QColorDialogPrivate::init(const QColor &initial)
{
Q_Q(QColorDialog);
@@ -1450,7 +1503,7 @@ void QColorDialogPrivate::init(const QColor &initial)
q->setWindowTitle(QColorDialog::tr("Select Color"));
nativeDialogInUse = (platformColorDialogHelper() != 0);
-
+ screenColorPicking = false;
nextCust = 0;
QVBoxLayout *mainLay = new QVBoxLayout(q);
// there's nothing in this dialog that benefits from sizing up
@@ -1486,6 +1539,15 @@ void QColorDialogPrivate::init(const QColor &initial)
leftLay->addWidget(lblBasicColors);
leftLay->addWidget(standard);
+#if !defined(Q_OS_WINCE) && !defined(QT_SMALL_COLORDIALOG)
+ // The screen color picker button
+ screenColorPickerButton = new QPushButton(QColorDialog::tr("Pick Screen Color"));
+ leftLay->addWidget(screenColorPickerButton);
+ lblScreenColorInfo = new QLabel(QLatin1String("\n"));
+ leftLay->addWidget(lblScreenColorInfo);
+ q->connect(screenColorPickerButton, SIGNAL(clicked()), SLOT(_q_pickScreenColor()));
+#endif
+
#if !defined(Q_OS_WINCE)
leftLay->addStretch();
#endif
@@ -1658,6 +1720,11 @@ static const Qt::WindowFlags DefaultWindowFlags =
during the execution of the program. Use setCustomColor() to set
the custom colors, and use customColor() to get them.
+ When pressing the "Pick Screen Color" button, the cursor changes to a haircross
+ and the colors on the screen are scanned. The user can pick up one by clicking
+ the mouse or the Enter button. Pressing Escape restores the last color selected
+ before entering this mode.
+
The \l{dialogs/standarddialogs}{Standard Dialogs} example shows
how to use QColorDialog as well as other built-in Qt dialogs.
@@ -1972,6 +2039,57 @@ void QColorDialog::changeEvent(QEvent *e)
}
/*!
+ \reimp
+*/
+void QColorDialog::mouseMoveEvent(QMouseEvent *e)
+{
+ Q_D(QColorDialog);
+ if (d->screenColorPicking) {
+ setCurrentColor(d->grabScreenColor(e->globalPos()));
+ d->lblScreenColorInfo->setText(QColorDialog::tr("Cursor at %1, %2, color: %3\nPress ESC to cancel")
+ .arg(e->globalPos().x())
+ .arg(e->globalPos().y())
+ .arg(currentColor().name()));
+ return;
+ }
+ QDialog::mouseMoveEvent(e);
+}
+
+/*!
+ \reimp
+*/
+void QColorDialog::mouseReleaseEvent(QMouseEvent *e)
+{
+ Q_D(QColorDialog);
+ if (d->screenColorPicking) {
+ setCurrentColor(d->grabScreenColor(e->globalPos()));
+ d->releaseColorPicking();
+ return;
+ }
+ QDialog::mouseReleaseEvent(e);
+}
+
+/*!
+ \reimp
+*/
+void QColorDialog::keyPressEvent(QKeyEvent *e)
+{
+ Q_D(QColorDialog);
+ if (d->screenColorPicking) {
+ if (e->key() == Qt::Key_Escape) {
+ d->releaseColorPicking();
+ d->setCurrentColor(d->beforeScreenColorPicking);
+ } else if (e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter) {
+ setCurrentColor(d->grabScreenColor(QCursor::pos()));
+ d->releaseColorPicking();
+ }
+ e->accept();
+ return;
+ }
+ QDialog::keyPressEvent(e);
+}
+
+/*!
Closes the dialog and sets its result code to \a result. If this dialog
is shown with exec(), done() causes the local event loop to finish,
and exec() to return \a result.
diff --git a/src/widgets/dialogs/qcolordialog.h b/src/widgets/dialogs/qcolordialog.h
index 80a31c4268..e76a120c3a 100644
--- a/src/widgets/dialogs/qcolordialog.h
+++ b/src/widgets/dialogs/qcolordialog.h
@@ -112,6 +112,9 @@ Q_SIGNALS:
protected:
void changeEvent(QEvent *event);
+ virtual void mouseMoveEvent(QMouseEvent *);
+ virtual void mouseReleaseEvent(QMouseEvent *);
+ virtual void keyPressEvent(QKeyEvent *);
void done(int result);
private:
@@ -122,6 +125,7 @@ private:
Q_PRIVATE_SLOT(d_func(), void _q_newColorTypedIn(QRgb rgb))
Q_PRIVATE_SLOT(d_func(), void _q_newCustom(int, int))
Q_PRIVATE_SLOT(d_func(), void _q_newStandard(int, int))
+ Q_PRIVATE_SLOT(d_func(), void _q_pickScreenColor())
friend class QColorShower;
};
diff --git a/src/widgets/dialogs/qcolordialog_p.h b/src/widgets/dialogs/qcolordialog_p.h
index 900b38fc61..bb24992512 100644
--- a/src/widgets/dialogs/qcolordialog_p.h
+++ b/src/widgets/dialogs/qcolordialog_p.h
@@ -87,6 +87,7 @@ public:
void setCurrentColor(QRgb rgb);
void setCurrentQColor(const QColor &color);
bool selectColor(const QColor &color);
+ QColor grabScreenColor(const QPoint &p);
int currentAlpha() const;
void setCurrentAlpha(int a);
@@ -100,6 +101,8 @@ public:
void _q_newColorTypedIn(QRgb rgb);
void _q_newCustom(int, int);
void _q_newStandard(int, int);
+ void _q_pickScreenColor();
+ void releaseColorPicking();
QWellArray *custom;
QWellArray *standard;
@@ -111,12 +114,16 @@ public:
QColorShower *cs;
QLabel *lblBasicColors;
QLabel *lblCustomColors;
+ QLabel *lblScreenColorInfo;
QPushButton *ok;
QPushButton *cancel;
QPushButton *addCusBt;
+ QPushButton *screenColorPickerButton;
QColor selectedQColor;
int nextCust;
bool smallDisplay;
+ bool screenColorPicking;
+ QRgb beforeScreenColorPicking;
QSharedPointer<QColorDialogOptions> options;
QPointer<QObject> receiverToDisconnectOnClose;