QmlDesigner: Fix ColorPicker EyeDropper

Task-number: QDS-11451
Change-Id: I8889e0475647bec480757652b84a5751642a6a07
Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
Reviewed-by: Qt CI Patch Build Bot <ci_patchbuild_bot@qt.io>
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
Henning Gruendl
2023-11-30 18:36:23 +01:00
committed by Henning Gründl
parent db0e1a62fc
commit 277463bb90
5 changed files with 62 additions and 23 deletions

View File

@@ -183,6 +183,8 @@ SecondColumnLayout {
property QtObject loaderItem: loader.item
property string gradientPropertyName
keepOpen: loader.item?.eyeDropperActive ?? false
width: 260
function commitToGradient() {

View File

@@ -13,6 +13,8 @@ import QtQuickDesignerColorPalette
Column {
id: root
property bool eyeDropperActive: ColorPaletteBackend.eyeDropperActive
property bool supportGradient: false
property bool shapeGradients: false
property alias gradientLine: gradientLine

View File

@@ -32,6 +32,8 @@ QtObject {
property rect __itemGlobal: Qt.rect(0, 0, 100, 100)
property bool keepOpen: false
signal closing(close: var)
function showGlobal() {
@@ -287,6 +289,9 @@ QtObject {
if (!focusWindow)
return
if (root.keepOpen)
return
if (focusWindow !== window && focusWindow.transientParent !== window)
root.close()
}

View File

@@ -3,13 +3,14 @@
#include "colorpalettebackend.h"
#include <QDebug>
#include <QColorDialog>
#include <QTimer>
#include <coreplugin/icore.h>
#include <QApplication>
#include <QScreen>
#include <QColorDialog>
#include <QDebug>
#include <QPainter>
#include <QScreen>
#include <QTimer>
namespace QmlDesigner {
@@ -205,17 +206,22 @@ void ColorPaletteBackend::showDialog(QColor color)
void ColorPaletteBackend::eyeDropper()
{
QWindow *window = QGuiApplication::focusWindow();
if (!window)
QWidget *widget = Core::ICore::mainWindow();
if (!widget)
return;
m_eyeDropperActive = true;
emit eyeDropperActiveChanged();
if (!m_colorPickingEventFilter)
m_colorPickingEventFilter = new QColorPickingEventFilter(this);
window->installEventFilter(m_colorPickingEventFilter);
window->setMouseGrabEnabled(true);
window->setKeyboardGrabEnabled(true);
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);
@@ -224,6 +230,14 @@ void ColorPaletteBackend::eyeDropper()
// 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());
}
@@ -245,7 +259,12 @@ QImage ColorPaletteBackend::grabScreenRect(const QPoint &p)
if (!screen)
screen = QGuiApplication::primaryScreen();
const QPixmap pixmap = screen->grabWindow(0, p.x(), p.y(), g_screenGrabWidth, g_screenGrabHeight);
const QRect screenRect = screen->geometry();
const QPixmap pixmap = screen->grabWindow(0,
p.x() - screenRect.x(),
p.y() - screenRect.y(),
g_screenGrabWidth,
g_screenGrabHeight);
return pixmap.toImage();
}
@@ -273,8 +292,8 @@ void ColorPaletteBackend::updateEyeDropperPosition(const QPoint &globalPos)
void ColorPaletteBackend::updateCursor(const QImage &image)
{
QWindow *window = QGuiApplication::focusWindow();
if (!window)
QWidget *widget = Core::ICore::mainWindow();
if (!widget)
return;
QPixmap pixmap(QSize(g_cursorWidth, g_cursorHeight));
@@ -307,24 +326,28 @@ void ColorPaletteBackend::updateCursor(const QImage &image)
painter.drawRect(centerRect);
painter.end();
QCursor cursor(pixmap);
window->setCursor(cursor);
QGuiApplication::changeOverrideCursor(QCursor(pixmap));
}
void ColorPaletteBackend::releaseEyeDropper()
{
QWindow *window = QGuiApplication::focusWindow();
if (!window)
QWidget *widget = Core::ICore::mainWindow();
if (!widget)
return;
window->removeEventFilter(m_colorPickingEventFilter);
window->setMouseGrabEnabled(false);
m_eyeDropperActive = false;
emit eyeDropperActiveChanged();
widget->removeEventFilter(m_colorPickingEventFilter);
widget->releaseMouse();
#ifdef Q_OS_WIN32
updateTimer->stop();
dummyTransparentWindow.setVisible(false);
#endif
window->setKeyboardGrabEnabled(false);
window->unsetCursor();
widget->releaseKeyboard();
widget->setMouseTracking(false);
QGuiApplication::restoreOverrideCursor();
}
bool ColorPaletteBackend::handleEyeDropperMouseMove(QMouseEvent *e)
@@ -360,4 +383,9 @@ bool ColorPaletteBackend::handleEyeDropperKeyPress(QKeyEvent *e)
return true;
}
bool ColorPaletteBackend::eyeDropperActive() const
{
return m_eyeDropperActive;
}
} // namespace QmlDesigner

View File

@@ -71,6 +71,7 @@ class ColorPaletteBackend : public QObject
Q_PROPERTY(QStringList palettes
READ palettes
NOTIFY palettesChanged)
Q_PROPERTY(bool eyeDropperActive READ eyeDropperActive NOTIFY eyeDropperActiveChanged)
public:
~ColorPaletteBackend();
@@ -82,7 +83,6 @@ public:
void removeColor(int id, const QString &palette);
Q_INVOKABLE void addRecentColor(const QString &color);
Q_INVOKABLE void addFavoriteColor(const QString &color);
Q_INVOKABLE void removeFavoriteColor(int id);
@@ -100,7 +100,6 @@ public:
Q_INVOKABLE void showDialog(QColor color);
Q_INVOKABLE void eyeDropper();
QColor grabScreenColor(const QPoint &p);
@@ -116,6 +115,7 @@ public:
bool handleEyeDropperMouseButtonRelease(QMouseEvent *e);
bool handleEyeDropperKeyPress(QKeyEvent *e);
bool eyeDropperActive() const;
ColorPaletteBackend(const ColorPaletteBackend &) = delete;
void operator=(const ColorPaletteBackend &) = delete;
@@ -129,6 +129,7 @@ signals:
void currentColorChanged(const QColor &color);
void eyeDropperRejected();
void eyeDropperActiveChanged();
private:
ColorPaletteBackend();
@@ -140,6 +141,7 @@ private:
QHash<QString, Palette> m_data;
QColorPickingEventFilter *m_colorPickingEventFilter;
bool m_eyeDropperActive = false;
#ifdef Q_OS_WIN32
QTimer *updateTimer;
QWindow dummyTransparentWindow;