Skip to content

Commit

Permalink
Fix ColorPickerItem to work with QQuickView-based GLWidget.
Browse files Browse the repository at this point in the history
  • Loading branch information
ddennedy committed Aug 26, 2014
1 parent 52519d3 commit aa55abe
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 65 deletions.
124 changes: 80 additions & 44 deletions src/qmltypes/colorpickeritem.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
/*
* Copyright (c) 2014 Meltytech, LLC
* Author: Brian Matherly <pez4brian@yahoo.com>
* Author: Dan Dennedy <dan@dennedy.org>
* Inspiration: KDENLIVE colorpickerwidget.cpp by Till Theato (root@ttill.de)
* Inspiration: QColorDialog.cpp
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand All @@ -26,11 +28,42 @@
#include <QDesktopWidget>
#include <QImage>
#include <QScreen>
#include "mainwindow.h"

class EventFilter : public QObject
{
public:
explicit EventFilter(ScreenSelector *selector, QObject *parent = 0)
: QObject(parent)
, m_selector(selector)
{}

bool eventFilter(QObject *, QEvent *event)
{
switch (event->type()) {
case QEvent::MouseButtonPress:
return m_selector->onMousePressEvent(static_cast<QMouseEvent *>(event));
case QEvent::MouseMove:
return m_selector->onMouseMoveEvent(static_cast<QMouseEvent *>(event));
case QEvent::MouseButtonRelease:
return m_selector->onMouseReleaseEvent(static_cast<QMouseEvent *>(event));
case QEvent::KeyPress:
return m_selector->onKeyPressEvent(static_cast<QKeyEvent *>(event));
default:
break;
}
return false;
}

private:
ScreenSelector *m_selector;
};

ScreenSelector::ScreenSelector(QWidget* parent)
: QFrame(parent)
, m_selectionInProgress(false)
, m_SelectionRect()
, m_selectionRect()
, m_eventFilter(0)
{
setFrameStyle(QFrame::Box | QFrame::Plain);
setWindowOpacity(0.5);
Expand All @@ -41,83 +74,79 @@ ScreenSelector::ScreenSelector(QWidget* parent)
void ScreenSelector::startSelection()
{
m_selectionInProgress = false;
grabMouse(QCursor(QIcon::fromTheme("color-picker", QIcon(":/icons/oxygen/32x32/actions/color-picker.png")).pixmap(22, 22), 0, 21));
if (!m_eventFilter)
m_eventFilter = new EventFilter(this);
QApplication::instance()->installEventFilter(m_eventFilter);
grabMouse();
grabKeyboard();
MAIN.setCursor(Qt::CrossCursor);
}

void ScreenSelector::mousePressEvent(QMouseEvent *event)
bool ScreenSelector::onMousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton && !m_selectionInProgress) {
m_selectionInProgress = true;
show();
m_SelectionRect = QRect(event->globalPos(), QSize(1,1));
setGeometry(m_SelectionRect);
m_selectionRect = QRect(event->globalPos(), QSize(1,1));
setGeometry(m_selectionRect);
}
QFrame::mousePressEvent(event);
return true;
}

void ScreenSelector::mouseMoveEvent(QMouseEvent *event)
bool ScreenSelector::onMouseMoveEvent(QMouseEvent *event)
{
if (m_selectionInProgress) {
m_SelectionRect.setWidth(event->globalX() - m_SelectionRect.x());
m_SelectionRect.setHeight(event->globalY() - m_SelectionRect.y());
m_selectionRect.setWidth(event->globalX() - m_selectionRect.x());
m_selectionRect.setHeight(event->globalY() - m_selectionRect.y());

if (m_SelectionRect.width() == 0) {
m_SelectionRect.setWidth(1);
if (m_selectionRect.width() == 0) {
m_selectionRect.setWidth(1);
}
if (m_SelectionRect.height() == 0) {
m_SelectionRect.setHeight(1);
if (m_selectionRect.height() == 0) {
m_selectionRect.setHeight(1);
}
setGeometry(m_SelectionRect.normalized());
setGeometry(m_selectionRect.normalized());
}
QFrame::mouseMoveEvent(event);
return true;
}

void ScreenSelector::mouseReleaseEvent(QMouseEvent *event)
bool ScreenSelector::onMouseReleaseEvent(QMouseEvent *event)
{
if(event->button() == Qt::LeftButton && m_selectionInProgress == true ) {
releaseMouse();
releaseKeyboard();
m_selectionInProgress = false;
hide();
release();
// Give the frame buffer time to clear the selector window before
// signaling the selection.
QTimer::singleShot(100, this, SLOT(screenRefreshed()));
QTimer::singleShot(100, this, SLOT(grabColor()));
}
QFrame::mouseReleaseEvent(event);
}

void ScreenSelector::screenRefreshed()
{
emit screenSelected(m_SelectionRect);
}

ColorPickerItem::ColorPickerItem(QObject* parent)
: QObject(parent)
, m_selector(NULL)
{
m_selector = new ScreenSelector(0);
connect(m_selector, SIGNAL(screenSelected(QRect)), this, SLOT(slotScreenSelected(QRect)));
return true;
}

ColorPickerItem::~ColorPickerItem()
bool ScreenSelector::onKeyPressEvent(QKeyEvent* event)
{
delete m_selector;
if (event->key() == Qt::Key_Escape)
release();
event->accept();
return true;
}

void ColorPickerItem::pickColor()
void ScreenSelector::release()
{
m_selector->startSelection();
QApplication::instance()->removeEventFilter(m_eventFilter);
releaseMouse();
releaseKeyboard();
MAIN.setCursor(Qt::ArrowCursor);
m_selectionInProgress = false;
hide();
}

void ColorPickerItem::slotScreenSelected(QRect pickerRect)
void ScreenSelector::grabColor()
{
pickerRect = pickerRect.normalized();

m_selectionRect = m_selectionRect.normalized();
QDesktopWidget* desktop = QApplication::desktop();
int screenNum = desktop->screenNumber(pickerRect.topLeft());
int screenNum = desktop->screenNumber(m_selectionRect.topLeft());
QScreen* screen = QGuiApplication::screens()[screenNum];
QPixmap screenGrab = screen->grabWindow(desktop->winId(), pickerRect.x(), pickerRect.y(), pickerRect.width(), pickerRect.height());
QPixmap screenGrab = screen->grabWindow(desktop->winId(),
m_selectionRect.x(), m_selectionRect.y(), m_selectionRect.width(), m_selectionRect.height());
QImage image = screenGrab.toImage();
int numPixel = image.width() * image.height();
int sumR = 0;
Expand All @@ -136,3 +165,10 @@ void ColorPickerItem::slotScreenSelected(QRect pickerRect)
QColor avgColor(sumR / numPixel, sumG / numPixel, sumB / numPixel);
emit colorPicked(avgColor);
}

ColorPickerItem::ColorPickerItem(QObject* parent)
: QObject(parent)
{
connect(this, SIGNAL(pickColor()), &m_selector, SLOT(startSelection()));
connect(&m_selector, SIGNAL(colorPicked(QColor)), SIGNAL(colorPicked(QColor)));
}
46 changes: 25 additions & 21 deletions src/qmltypes/colorpickeritem.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/*
* Copyright (c) 2014 Meltytech, LLC
* Author: Brian Matherly <pez4brian@yahoo.com>
* Author: Dan Dennedy <dan@dennedy.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand All @@ -23,47 +24,50 @@
#include <QColor>
#include <QFrame>

class ScreenSelector;
class EventFilter;

class ColorPickerItem : public QObject
class ScreenSelector : public QFrame
{
Q_OBJECT
public:
explicit ColorPickerItem(QObject* parent = 0);
virtual ~ColorPickerItem();
Q_INVOKABLE void pickColor();
ScreenSelector(QWidget* parent = 0);

public slots:
void startSelection();

signals:
void screenSelected(QRect);
void colorPicked(const QColor &color);

public:
bool onMousePressEvent(QMouseEvent *event);
bool onMouseMoveEvent(QMouseEvent *event);
bool onMouseReleaseEvent(QMouseEvent *event);
bool onKeyPressEvent(QKeyEvent *event);

private:
ScreenSelector* m_selector;
bool m_selectionInProgress;
QRect m_selectionRect;
EventFilter* m_eventFilter;

void release();

private slots:
void slotScreenSelected(QRect);
void grabColor();
};

class ScreenSelector : public QFrame
class ColorPickerItem : public QObject
{
Q_OBJECT
public:
ScreenSelector(QWidget* parent = 0);
void startSelection();
explicit ColorPickerItem(QObject* parent = 0);

signals:
void screenSelected(QRect);

protected:
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
void pickColor();
void colorPicked(const QColor &color);

private:
bool m_selectionInProgress;
QRect m_SelectionRect;

private slots:
void screenRefreshed();
ScreenSelector m_selector;
};

#endif // COLORPICKERITEM_H

0 comments on commit aa55abe

Please sign in to comment.