forked from qt-creator/qt-creator
QmlDesigner: EyeDropper use platform service
Task-number: QDS-12517 Change-Id: I1fdbdf3aa0992826d109d0e24e92d15c7576fb93 Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
This commit is contained in:
committed by
Tim Jenssen
parent
04155ac5a1
commit
989eae1667
@@ -39,7 +39,7 @@ SecondColumnLayout {
|
||||
|
||||
property bool shapeGradients: false
|
||||
|
||||
//for now, gradients on MCUs are limited to Basic and Shape Linear Gradient:
|
||||
// Gradients on MCUs are limited to Basic and Shape Linear Gradient.
|
||||
property bool mcuGradients: false
|
||||
|
||||
property color originalColor
|
||||
@@ -91,8 +91,8 @@ SecondColumnLayout {
|
||||
|
||||
if (colorEditor.backendValue !== undefined) {
|
||||
if (colorEditor.isVector3D)
|
||||
colorEditor.backendValue.value = Qt.vector3d(
|
||||
colorEditor.color.r, colorEditor.color.g,
|
||||
colorEditor.backendValue.value = Qt.vector3d(colorEditor.color.r,
|
||||
colorEditor.color.g,
|
||||
colorEditor.color.b)
|
||||
else
|
||||
colorEditor.backendValue.value = colorEditor.color
|
||||
@@ -223,10 +223,8 @@ SecondColumnLayout {
|
||||
|
||||
function open() {
|
||||
popupDialog.ensureLoader()
|
||||
|
||||
popupDialog.show(preview)
|
||||
|
||||
popupDialog.loaderItem.aboutToBeShown() //need it for now
|
||||
popupDialog.loaderItem.aboutToBeShown() // need it for now
|
||||
}
|
||||
|
||||
function determineActiveColorMode() {
|
||||
|
@@ -12,10 +12,9 @@ import QtQuickDesignerColorPalette
|
||||
Column {
|
||||
id: root
|
||||
|
||||
// There seems to be an issue on Windows and MacOS with ColorPickers
|
||||
// Canvases not being painted on initialization
|
||||
// because ColorEditorPopup is invisible at init time,
|
||||
// so we use this signal to explicitly pass visibility status
|
||||
// There seems to be an issue on Windows and macOS with ColorPickers canvas not being painted
|
||||
// on initialization, because ColorEditorPopup is invisible at init time, so we use this signal
|
||||
// to explicitly pass visibility status.
|
||||
signal aboutToBeShown
|
||||
|
||||
property bool eyeDropperActive: ColorPaletteBackend.eyeDropperActive
|
||||
@@ -23,7 +22,7 @@ Column {
|
||||
property bool supportGradient: false
|
||||
property bool shapeGradients: false
|
||||
|
||||
//for now, gradients on MCUs are limited to Basic and Shape Linear Gradient:
|
||||
// Gradients on MCUs are limited to Basic and Shape Linear Gradient.
|
||||
property bool mcuGradients: false
|
||||
|
||||
property alias gradientLine: gradientLine
|
||||
@@ -188,7 +187,7 @@ Column {
|
||||
icon: StudioTheme.Constants.eyeDropper
|
||||
pixelSize: StudioTheme.Values.myIconFontSize * 1.4
|
||||
tooltip: qsTr("Eye Dropper")
|
||||
onClicked: ColorPaletteBackend.eyeDropper()
|
||||
onClicked: ColorPaletteBackend.invokeEyeDropper()
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -69,6 +69,8 @@ Item {
|
||||
|
||||
property QtObject loaderItem: loader.item
|
||||
|
||||
keepOpen: loader.item?.eyeDropperActive ?? false
|
||||
|
||||
width: 260
|
||||
|
||||
function ensureLoader() {
|
||||
@@ -91,6 +93,7 @@ Item {
|
||||
id: popup
|
||||
width: popupDialog.contentWidth
|
||||
visible: popupDialog.visible
|
||||
parentWindow: popupDialog.window
|
||||
|
||||
onActivateColor: function(color) {
|
||||
colorBackend.activateColor(color)
|
||||
|
@@ -12,9 +12,13 @@ import QtQuickDesignerColorPalette
|
||||
Column {
|
||||
id: root
|
||||
|
||||
property bool eyeDropperActive: ColorPaletteBackend.eyeDropperActive
|
||||
|
||||
property color color
|
||||
property color originalColor
|
||||
|
||||
property Window parentWindow: null
|
||||
|
||||
readonly property real twoColumnWidth: (colorColumn.width - StudioTheme.Values.controlGap) * 0.5
|
||||
readonly property real fourColumnWidth: (colorColumn.width - (3 * StudioTheme.Values.controlGap)) * 0.25
|
||||
|
||||
@@ -42,7 +46,7 @@ Column {
|
||||
icon: StudioTheme.Constants.eyeDropper
|
||||
pixelSize: StudioTheme.Values.myIconFontSize * 1.4
|
||||
toolTip: qsTr("Eye Dropper")
|
||||
onClicked: ColorPaletteBackend.eyeDropper()
|
||||
onClicked: ColorPaletteBackend.invokeEyeDropper()
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -53,7 +53,7 @@ add_qtc_plugin(QmlDesigner
|
||||
PLUGIN_MANUAL_DEPENDS LicenseChecker ${IDE_VERSION} optional
|
||||
DEPENDS
|
||||
QmlJS LanguageUtils QmlEditorWidgets AdvancedDockingSystem
|
||||
Qt::QuickWidgets Qt::CorePrivate Qt::Xml Qt::Svg Sqlite Zip
|
||||
Qt::QuickWidgets Qt::CorePrivate Qt::Xml Qt::Svg Sqlite Zip Qt::GuiPrivate
|
||||
PUBLIC_DEPENDS
|
||||
QmlDesignerUtils QmlPuppetCommunication QmlDesignerCore
|
||||
DEFINES
|
||||
|
@@ -9,9 +9,14 @@
|
||||
#include <QColorDialog>
|
||||
#include <QDebug>
|
||||
#include <QPainter>
|
||||
#include <QPainterPath>
|
||||
#include <QScreen>
|
||||
#include <QTimer>
|
||||
|
||||
#include <private/qguiapplication_p.h>
|
||||
#include <qpa/qplatformintegration.h>
|
||||
#include <qpa/qplatformservices.h>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
QPointer<ColorPaletteBackend> ColorPaletteBackend::m_instance = nullptr;
|
||||
@@ -19,7 +24,7 @@ QPointer<ColorPaletteBackend> ColorPaletteBackend::m_instance = nullptr;
|
||||
ColorPaletteBackend::ColorPaletteBackend()
|
||||
: m_currentPalette()
|
||||
, m_data()
|
||||
, m_colorPickingEventFilter(nullptr)
|
||||
, m_eyeDropperEventFilter(nullptr)
|
||||
#ifdef Q_OS_WIN32
|
||||
, updateTimer(0)
|
||||
#endif
|
||||
@@ -43,6 +48,8 @@ ColorPaletteBackend::ColorPaletteBackend()
|
||||
ColorPaletteBackend::~ColorPaletteBackend()
|
||||
{
|
||||
//writePalettes(); // TODO crash on QtDS close
|
||||
if (m_eyeDropperActive)
|
||||
eyeDropperLeave(QCursor::pos(), EyeDropperEventFilter::LeaveReason::Default);
|
||||
}
|
||||
|
||||
void ColorPaletteBackend::readPalettes()
|
||||
@@ -204,67 +211,129 @@ void ColorPaletteBackend::showDialog(QColor color)
|
||||
QTimer::singleShot(0, [colorDialog](){ colorDialog->exec(); });
|
||||
}
|
||||
|
||||
void ColorPaletteBackend::eyeDropper()
|
||||
void ColorPaletteBackend::invokeEyeDropper()
|
||||
{
|
||||
QWidget *widget = Core::ICore::mainWindow();
|
||||
if (!widget)
|
||||
return;
|
||||
|
||||
m_eyeDropperActive = true;
|
||||
emit eyeDropperActiveChanged();
|
||||
|
||||
if (!m_colorPickingEventFilter)
|
||||
m_colorPickingEventFilter = new QColorPickingEventFilter(this);
|
||||
|
||||
widget->installEventFilter(m_colorPickingEventFilter);
|
||||
#ifndef QT_NO_CURSOR
|
||||
widget->grabMouse(/*Qt::CrossCursor*/);
|
||||
#else
|
||||
widget->grabMouse();
|
||||
#endif
|
||||
#ifdef Q_OS_WIN32 // excludes WinRT
|
||||
// On Windows mouse tracking doesn't work over other processes's windows
|
||||
updateTimer->start(30);
|
||||
// HACK: Because mouse grabbing doesn't work across processes, we have to have a dummy,
|
||||
// invisible window to catch the mouse click, otherwise we will click whatever we clicked
|
||||
// and loose focus.
|
||||
dummyTransparentWindow.show();
|
||||
#endif
|
||||
widget->grabKeyboard();
|
||||
/* With setMouseTracking(true) the desired color can be more precisely picked up,
|
||||
* and continuously pushing the mouse button is not necessary.
|
||||
*/
|
||||
widget->setMouseTracking(true);
|
||||
|
||||
QGuiApplication::setOverrideCursor(QCursor());
|
||||
|
||||
updateEyeDropperPosition(QCursor::pos());
|
||||
eyeDropperEnter();
|
||||
}
|
||||
|
||||
const int g_cursorWidth = 64;
|
||||
const int g_cursorHeight = 64;
|
||||
const int g_screenGrabWidth = 7;
|
||||
const int g_screenGrabHeight = 7;
|
||||
const int g_pixelX = 3;
|
||||
const int g_pixelY = 3;
|
||||
void ColorPaletteBackend::eyeDropperEnter()
|
||||
{
|
||||
if (m_eyeDropperActive)
|
||||
return;
|
||||
|
||||
QPointer<QWindow> window = Core::ICore::mainWindow()->windowHandle();
|
||||
|
||||
if (m_eyeDropperWindow.isNull()) {
|
||||
if (window.isNull()) {
|
||||
qWarning() << "No window found, cannot enter eyeDropperMode.";
|
||||
return;
|
||||
}
|
||||
|
||||
m_eyeDropperWindow = window;
|
||||
}
|
||||
|
||||
if (auto *platformServices = QGuiApplicationPrivate::platformIntegration()->services();
|
||||
platformServices
|
||||
&& platformServices->hasCapability(QPlatformServices::Capability::ColorPicking)) {
|
||||
if (auto *colorPickerService = platformServices->colorPicker(m_eyeDropperWindow)) {
|
||||
connect(colorPickerService,
|
||||
&QPlatformServiceColorPicker::colorPicked,
|
||||
this,
|
||||
[this, colorPickerService](const QColor &color) {
|
||||
colorPickerService->deleteLater();
|
||||
// When the service was canceled by pressing escape the color returned will
|
||||
// be QColor(ARGB, 0, 0, 0, 0), so we test for alpha to avoid setting the color.
|
||||
// https://codereview.qt-project.org/c/qt/qtbase/+/589113
|
||||
if (color.alpha() != 0 || !color.isValid())
|
||||
emit currentColorChanged(color);
|
||||
m_eyeDropperActive = false;
|
||||
emit eyeDropperActiveChanged();
|
||||
});
|
||||
m_eyeDropperActive = true;
|
||||
emit eyeDropperActiveChanged();
|
||||
colorPickerService->pickColor();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
m_eyeDropperPreviousColor = m_eyeDropperCurrentColor;
|
||||
|
||||
if (!bool(m_eyeDropperEventFilter))
|
||||
m_eyeDropperEventFilter.reset(new EyeDropperEventFilter(
|
||||
[this](QPoint pos, EyeDropperEventFilter::LeaveReason c) { eyeDropperLeave(pos, c); },
|
||||
[this](QPoint pos) { eyeDropperPointerMoved(pos); }));
|
||||
|
||||
if (m_eyeDropperWindow->setMouseGrabEnabled(true)
|
||||
&& m_eyeDropperWindow->setKeyboardGrabEnabled(true)) {
|
||||
#if QT_CONFIG(cursor)
|
||||
QGuiApplication::setOverrideCursor(QCursor());
|
||||
updateEyeDropperPosition(QCursor::pos());
|
||||
#endif
|
||||
m_eyeDropperWindow->installEventFilter(m_eyeDropperEventFilter.get());
|
||||
m_eyeDropperActive = true;
|
||||
emit eyeDropperActiveChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void ColorPaletteBackend::eyeDropperLeave(const QPoint &pos,
|
||||
EyeDropperEventFilter::LeaveReason actionOnLeave)
|
||||
{
|
||||
if (!m_eyeDropperActive)
|
||||
return;
|
||||
|
||||
if (!m_eyeDropperWindow) {
|
||||
qWarning() << "Window not set, cannot leave eyeDropperMode.";
|
||||
return;
|
||||
}
|
||||
|
||||
if (actionOnLeave != EyeDropperEventFilter::LeaveReason::Cancel) {
|
||||
m_eyeDropperCurrentColor = grabScreenColor(pos);
|
||||
|
||||
emit currentColorChanged(m_eyeDropperCurrentColor);
|
||||
}
|
||||
|
||||
m_eyeDropperWindow->removeEventFilter(m_eyeDropperEventFilter.get());
|
||||
m_eyeDropperWindow->setMouseGrabEnabled(false);
|
||||
m_eyeDropperWindow->setKeyboardGrabEnabled(false);
|
||||
#if QT_CONFIG(cursor)
|
||||
QGuiApplication::restoreOverrideCursor();
|
||||
#endif
|
||||
|
||||
m_eyeDropperActive = false;
|
||||
emit eyeDropperActiveChanged();
|
||||
m_eyeDropperWindow.clear();
|
||||
}
|
||||
|
||||
void ColorPaletteBackend::eyeDropperPointerMoved(const QPoint &pos)
|
||||
{
|
||||
m_eyeDropperCurrentColor = grabScreenColor(pos);
|
||||
updateEyeDropperPosition(pos);
|
||||
}
|
||||
|
||||
const QSize g_cursorSize(64, 64);
|
||||
const QSize g_halfCursorSize = g_cursorSize / 2;
|
||||
const QSize g_screenGrabSize(11, 11);
|
||||
const QSize g_previewSize(12, 12);
|
||||
const QSize g_halfPreviewSize = g_previewSize / 2;
|
||||
|
||||
QColor ColorPaletteBackend::grabScreenColor(const QPoint &p)
|
||||
{
|
||||
return grabScreenRect(p).pixel(g_pixelX, g_pixelY);
|
||||
return grabScreenRect(QRect(p, QSize(1, 1))).pixel(0, 0);
|
||||
}
|
||||
|
||||
QImage ColorPaletteBackend::grabScreenRect(const QPoint &p)
|
||||
QImage ColorPaletteBackend::grabScreenRect(const QRect &r)
|
||||
{
|
||||
QScreen *screen = QGuiApplication::screenAt(p);
|
||||
QScreen *screen = QGuiApplication::screenAt(r.topLeft());
|
||||
if (!screen)
|
||||
screen = QGuiApplication::primaryScreen();
|
||||
|
||||
const QRect screenRect = screen->geometry();
|
||||
const QPixmap pixmap = screen->grabWindow(0,
|
||||
p.x() - screenRect.x(),
|
||||
p.y() - screenRect.y(),
|
||||
g_screenGrabWidth,
|
||||
g_screenGrabHeight);
|
||||
r.x() - screenRect.x(),
|
||||
r.y() - screenRect.y(),
|
||||
r.width(),
|
||||
r.height());
|
||||
|
||||
return pixmap.toImage();
|
||||
}
|
||||
|
||||
@@ -272,7 +341,7 @@ void ColorPaletteBackend::updateEyeDropper()
|
||||
{
|
||||
#ifndef QT_NO_CURSOR
|
||||
static QPoint lastGlobalPos;
|
||||
QPoint newGlobalPos = QCursor::pos();
|
||||
const QPoint newGlobalPos = QCursor::pos();
|
||||
if (lastGlobalPos == newGlobalPos)
|
||||
return;
|
||||
|
||||
@@ -287,102 +356,70 @@ void ColorPaletteBackend::updateEyeDropper()
|
||||
|
||||
void ColorPaletteBackend::updateEyeDropperPosition(const QPoint &globalPos)
|
||||
{
|
||||
updateCursor(grabScreenRect(globalPos));
|
||||
#if QT_CONFIG(cursor)
|
||||
QPoint topLeft = globalPos - QPoint(g_halfCursorSize.width(), g_halfCursorSize.height());
|
||||
updateCursor(grabScreenRect(QRect(topLeft, g_cursorSize)));
|
||||
#endif
|
||||
}
|
||||
|
||||
void ColorPaletteBackend::updateCursor(const QImage &image)
|
||||
{
|
||||
QWidget *widget = Core::ICore::mainWindow();
|
||||
if (!widget)
|
||||
QWindow *window = Core::ICore::mainWindow()->windowHandle();
|
||||
if (!window)
|
||||
return;
|
||||
|
||||
QPixmap pixmap(QSize(g_cursorWidth, g_cursorHeight));
|
||||
QPixmap pixmap(g_cursorSize);
|
||||
pixmap.fill(Qt::transparent);
|
||||
|
||||
QPainter painter(&pixmap);
|
||||
painter.setRenderHint(QPainter::Antialiasing);
|
||||
|
||||
QPainterPath clipPath;
|
||||
clipPath.addEllipse(QRect(QPoint(0, 0), g_cursorSize).adjusted(1, 1, -1, -1));
|
||||
|
||||
painter.setClipPath(clipPath, Qt::IntersectClip);
|
||||
|
||||
const QPoint topLeft = QPoint(g_halfCursorSize.width(), g_halfCursorSize.height())
|
||||
- QPoint(qFloor(g_screenGrabSize.width() / 2),
|
||||
qFloor(g_screenGrabSize.height() / 2));
|
||||
|
||||
const QColor topCenter = image.pixelColor(g_halfCursorSize.width(), 0);
|
||||
const QColor bottomCenter = image.pixelColor(g_halfCursorSize.width(), g_cursorSize.height() - 1);
|
||||
const QColor leftCenter = image.pixelColor(0, g_halfCursorSize.height());
|
||||
const QColor rightCenter = image.pixelColor(g_cursorSize.width() - 1, g_halfCursorSize.height());
|
||||
|
||||
// Find the mean gray value of top, bottom, left and right center
|
||||
int borderGray = (qGray(topCenter.rgb()) + qGray(bottomCenter.rgb()) + qGray(leftCenter.rgb())
|
||||
+ qGray(rightCenter.rgb()))
|
||||
/ 4;
|
||||
|
||||
// Draw the magnified image/screen grab
|
||||
QRect r(QPoint(), pixmap.size());
|
||||
painter.drawImage(r, image, QRect(0, 0, g_screenGrabWidth, g_screenGrabHeight));
|
||||
const QRect r(QPoint(), pixmap.size());
|
||||
painter.drawImage(r, image, QRect(topLeft, g_screenGrabSize));
|
||||
|
||||
const int pixelWidth = (g_cursorWidth - 1) / g_screenGrabWidth;
|
||||
const int pixelHeight = (g_cursorHeight - 1) / g_screenGrabHeight;
|
||||
// Draw the pixel lines
|
||||
painter.setPen(QPen(QColor(192, 192, 192, 150), 1.0, Qt::SolidLine));
|
||||
for (int i = 1; i != g_screenGrabWidth; ++i) {
|
||||
int x = pixelWidth * i;
|
||||
painter.drawLine(x, 0, x, g_cursorHeight);
|
||||
}
|
||||
painter.setClipping(false);
|
||||
|
||||
for (int i = 1; i != g_screenGrabHeight; ++i) {
|
||||
int y = pixelHeight * i;
|
||||
painter.drawLine(0, y, g_cursorWidth, y);
|
||||
}
|
||||
// Draw the sorounding border
|
||||
painter.setPen(QPen(Qt::black, 1.0, Qt::SolidLine));
|
||||
painter.drawRect(r.adjusted(0, 0, -1, -1));
|
||||
QPen pen(borderGray < 128 ? Qt::white : Qt::black, 2.0, Qt::SolidLine);
|
||||
|
||||
const QColor color = image.pixel(g_pixelX, g_pixelY);
|
||||
QRect centerRect = QRect(2 * pixelWidth, 2 * pixelHeight, 3 * pixelWidth, 3 * pixelHeight);
|
||||
// Draw the center rectangle with the current eye dropper color
|
||||
painter.setBrush(QBrush(color, Qt::SolidPattern));
|
||||
painter.drawRect(centerRect);
|
||||
// Draw the surrounding border
|
||||
painter.setPen(pen);
|
||||
painter.drawPath(clipPath);
|
||||
|
||||
pen.setWidth(1);
|
||||
painter.setPen(pen);
|
||||
|
||||
const QRect previewRect(QPoint(g_halfCursorSize.width() - g_halfPreviewSize.width(),
|
||||
g_halfCursorSize.height() - g_halfPreviewSize.height()),
|
||||
g_previewSize);
|
||||
|
||||
painter.fillRect(previewRect, m_eyeDropperCurrentColor);
|
||||
painter.drawRect(previewRect);
|
||||
|
||||
painter.end();
|
||||
|
||||
QGuiApplication::changeOverrideCursor(QCursor(pixmap));
|
||||
}
|
||||
|
||||
void ColorPaletteBackend::releaseEyeDropper()
|
||||
{
|
||||
QWidget *widget = Core::ICore::mainWindow();
|
||||
if (!widget)
|
||||
return;
|
||||
|
||||
m_eyeDropperActive = false;
|
||||
emit eyeDropperActiveChanged();
|
||||
|
||||
widget->removeEventFilter(m_colorPickingEventFilter);
|
||||
widget->releaseMouse();
|
||||
#ifdef Q_OS_WIN32
|
||||
updateTimer->stop();
|
||||
dummyTransparentWindow.setVisible(false);
|
||||
#endif
|
||||
widget->releaseKeyboard();
|
||||
widget->setMouseTracking(false);
|
||||
|
||||
QGuiApplication::restoreOverrideCursor();
|
||||
}
|
||||
|
||||
bool ColorPaletteBackend::handleEyeDropperMouseMove(QMouseEvent *e)
|
||||
{
|
||||
updateEyeDropperPosition(e->globalPosition().toPoint());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ColorPaletteBackend::handleEyeDropperMouseButtonRelease(QMouseEvent *e)
|
||||
{
|
||||
if (e->button() == Qt::LeftButton)
|
||||
emit currentColorChanged(grabScreenColor(e->globalPosition().toPoint()));
|
||||
else
|
||||
emit eyeDropperRejected();
|
||||
|
||||
releaseEyeDropper();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ColorPaletteBackend::handleEyeDropperKeyPress(QKeyEvent *e)
|
||||
{
|
||||
#if QT_CONFIG(shortcut)
|
||||
if (e->matches(QKeySequence::Cancel)) {
|
||||
emit eyeDropperRejected();
|
||||
releaseEyeDropper();
|
||||
} //else
|
||||
#endif
|
||||
//if (e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter) {
|
||||
// emit currentColorChanged(grabScreenColor(e->globalPosition().toPoint()));
|
||||
// releaseEyeDropper();
|
||||
//}
|
||||
e->accept();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ColorPaletteBackend::eyeDropperActive() const
|
||||
{
|
||||
return m_eyeDropperActive;
|
||||
|
@@ -18,12 +18,62 @@
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
class QColorPickingEventFilter;
|
||||
|
||||
const int g_maxPaletteSize = 8;
|
||||
const QString g_recent = "Recent";
|
||||
const QString g_favorite = "Favorite";
|
||||
|
||||
class EyeDropperEventFilter : public QObject
|
||||
{
|
||||
public:
|
||||
enum class LeaveReason { Default, Cancel };
|
||||
|
||||
explicit EyeDropperEventFilter(std::function<void(QPoint, LeaveReason)> callOnLeave,
|
||||
std::function<void(QPoint)> callOnUpdate)
|
||||
: m_leave(callOnLeave)
|
||||
, m_update(callOnUpdate)
|
||||
{}
|
||||
|
||||
bool eventFilter(QObject *obj, QEvent *event) override
|
||||
{
|
||||
switch (event->type()) {
|
||||
case QEvent::MouseMove: {
|
||||
m_lastPosition = static_cast<QMouseEvent *>(event)->globalPosition().toPoint();
|
||||
m_update(m_lastPosition);
|
||||
return true;
|
||||
}
|
||||
case QEvent::MouseButtonRelease: {
|
||||
m_lastPosition = static_cast<QMouseEvent *>(event)->globalPosition().toPoint();
|
||||
m_leave(m_lastPosition, EyeDropperEventFilter::LeaveReason::Default);
|
||||
return true;
|
||||
}
|
||||
case QEvent::MouseButtonPress:
|
||||
return true;
|
||||
case QEvent::KeyPress: {
|
||||
auto keyEvent = static_cast<QKeyEvent *>(event);
|
||||
#if QT_CONFIG(shortcut)
|
||||
if (keyEvent->matches(QKeySequence::Cancel))
|
||||
m_leave(m_lastPosition, EyeDropperEventFilter::LeaveReason::Cancel);
|
||||
else
|
||||
#endif
|
||||
if (keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter) {
|
||||
m_leave(m_lastPosition, EyeDropperEventFilter::LeaveReason::Default);
|
||||
} else if (keyEvent->key() == Qt::Key_Escape) {
|
||||
m_leave(m_lastPosition, EyeDropperEventFilter::LeaveReason::Cancel);
|
||||
}
|
||||
keyEvent->accept();
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
return QObject::eventFilter(obj, event);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::function<void(QPoint, LeaveReason)> m_leave;
|
||||
std::function<void(QPoint)> m_update;
|
||||
QPoint m_lastPosition;
|
||||
};
|
||||
|
||||
struct Palette
|
||||
{
|
||||
Palette()
|
||||
@@ -100,20 +150,22 @@ public:
|
||||
|
||||
Q_INVOKABLE void showDialog(QColor color);
|
||||
|
||||
Q_INVOKABLE void eyeDropper();
|
||||
//Q_INVOKABLE void eyeDropper();
|
||||
|
||||
Q_INVOKABLE void invokeEyeDropper();
|
||||
|
||||
QColor grabScreenColor(const QPoint &p);
|
||||
QImage grabScreenRect(const QPoint &p);
|
||||
QImage grabScreenRect(const QRect &r);
|
||||
void updateEyeDropper();
|
||||
void updateEyeDropperPosition(const QPoint &globalPos);
|
||||
|
||||
void updateCursor(const QImage &image);
|
||||
|
||||
void releaseEyeDropper();
|
||||
|
||||
bool handleEyeDropperMouseMove(QMouseEvent *e);
|
||||
bool handleEyeDropperMouseButtonRelease(QMouseEvent *e);
|
||||
bool handleEyeDropperKeyPress(QKeyEvent *e);
|
||||
//void releaseEyeDropper();
|
||||
//
|
||||
//bool handleEyeDropperMouseMove(QMouseEvent *e);
|
||||
//bool handleEyeDropperMouseButtonRelease(QMouseEvent *e);
|
||||
//bool handleEyeDropperKeyPress(QKeyEvent *e);
|
||||
|
||||
bool eyeDropperActive() const;
|
||||
|
||||
@@ -134,13 +186,20 @@ signals:
|
||||
private:
|
||||
ColorPaletteBackend();
|
||||
|
||||
void eyeDropperEnter();
|
||||
void eyeDropperLeave(const QPoint &pos, EyeDropperEventFilter::LeaveReason actionOnLeave);
|
||||
void eyeDropperPointerMoved(const QPoint &pos);
|
||||
|
||||
private:
|
||||
static QPointer<ColorPaletteBackend> m_instance;
|
||||
QString m_currentPalette;
|
||||
QStringList m_currentPaletteColors;
|
||||
QHash<QString, Palette> m_data;
|
||||
|
||||
QColorPickingEventFilter *m_colorPickingEventFilter;
|
||||
std::unique_ptr<EyeDropperEventFilter> m_eyeDropperEventFilter;
|
||||
QPointer<QWindow> m_eyeDropperWindow;
|
||||
QColor m_eyeDropperCurrentColor;
|
||||
QColor m_eyeDropperPreviousColor;
|
||||
bool m_eyeDropperActive = false;
|
||||
#ifdef Q_OS_WIN32
|
||||
QTimer *updateTimer;
|
||||
@@ -148,35 +207,6 @@ private:
|
||||
#endif
|
||||
};
|
||||
|
||||
class QColorPickingEventFilter : public QObject {
|
||||
public:
|
||||
explicit QColorPickingEventFilter(ColorPaletteBackend *colorPalette)
|
||||
: QObject(colorPalette)
|
||||
, m_colorPalette(colorPalette)
|
||||
{}
|
||||
|
||||
bool eventFilter(QObject *, QEvent *event) override
|
||||
{
|
||||
switch (event->type()) {
|
||||
case QEvent::MouseMove:
|
||||
return m_colorPalette->handleEyeDropperMouseMove(
|
||||
static_cast<QMouseEvent *>(event));
|
||||
case QEvent::MouseButtonRelease:
|
||||
return m_colorPalette->handleEyeDropperMouseButtonRelease(
|
||||
static_cast<QMouseEvent *>(event));
|
||||
case QEvent::KeyPress:
|
||||
return m_colorPalette->handleEyeDropperKeyPress(
|
||||
static_cast<QKeyEvent *>(event));
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
ColorPaletteBackend *m_colorPalette;
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner
|
||||
|
||||
QML_DECLARE_TYPE(QmlDesigner::ColorPaletteBackend)
|
||||
|
Reference in New Issue
Block a user