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 QtObject loaderItem: loader.item
property string gradientPropertyName property string gradientPropertyName
keepOpen: loader.item?.eyeDropperActive ?? false
width: 260 width: 260
function commitToGradient() { function commitToGradient() {

View File

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

View File

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

View File

@@ -3,13 +3,14 @@
#include "colorpalettebackend.h" #include "colorpalettebackend.h"
#include <QDebug> #include <coreplugin/icore.h>
#include <QColorDialog>
#include <QTimer>
#include <QApplication> #include <QApplication>
#include <QScreen> #include <QColorDialog>
#include <QDebug>
#include <QPainter> #include <QPainter>
#include <QScreen>
#include <QTimer>
namespace QmlDesigner { namespace QmlDesigner {
@@ -205,17 +206,22 @@ void ColorPaletteBackend::showDialog(QColor color)
void ColorPaletteBackend::eyeDropper() void ColorPaletteBackend::eyeDropper()
{ {
QWindow *window = QGuiApplication::focusWindow(); QWidget *widget = Core::ICore::mainWindow();
if (!window) if (!widget)
return; return;
m_eyeDropperActive = true;
emit eyeDropperActiveChanged();
if (!m_colorPickingEventFilter) if (!m_colorPickingEventFilter)
m_colorPickingEventFilter = new QColorPickingEventFilter(this); m_colorPickingEventFilter = new QColorPickingEventFilter(this);
window->installEventFilter(m_colorPickingEventFilter); widget->installEventFilter(m_colorPickingEventFilter);
window->setMouseGrabEnabled(true); #ifndef QT_NO_CURSOR
window->setKeyboardGrabEnabled(true); widget->grabMouse(/*Qt::CrossCursor*/);
#else
widget->grabMouse();
#endif
#ifdef Q_OS_WIN32 // excludes WinRT #ifdef Q_OS_WIN32 // excludes WinRT
// On Windows mouse tracking doesn't work over other processes's windows // On Windows mouse tracking doesn't work over other processes's windows
updateTimer->start(30); updateTimer->start(30);
@@ -224,6 +230,14 @@ void ColorPaletteBackend::eyeDropper()
// and loose focus. // and loose focus.
dummyTransparentWindow.show(); dummyTransparentWindow.show();
#endif #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()); updateEyeDropperPosition(QCursor::pos());
} }
@@ -245,7 +259,12 @@ QImage ColorPaletteBackend::grabScreenRect(const QPoint &p)
if (!screen) if (!screen)
screen = QGuiApplication::primaryScreen(); 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(); return pixmap.toImage();
} }
@@ -273,8 +292,8 @@ void ColorPaletteBackend::updateEyeDropperPosition(const QPoint &globalPos)
void ColorPaletteBackend::updateCursor(const QImage &image) void ColorPaletteBackend::updateCursor(const QImage &image)
{ {
QWindow *window = QGuiApplication::focusWindow(); QWidget *widget = Core::ICore::mainWindow();
if (!window) if (!widget)
return; return;
QPixmap pixmap(QSize(g_cursorWidth, g_cursorHeight)); QPixmap pixmap(QSize(g_cursorWidth, g_cursorHeight));
@@ -307,24 +326,28 @@ void ColorPaletteBackend::updateCursor(const QImage &image)
painter.drawRect(centerRect); painter.drawRect(centerRect);
painter.end(); painter.end();
QCursor cursor(pixmap); QGuiApplication::changeOverrideCursor(QCursor(pixmap));
window->setCursor(cursor);
} }
void ColorPaletteBackend::releaseEyeDropper() void ColorPaletteBackend::releaseEyeDropper()
{ {
QWindow *window = QGuiApplication::focusWindow(); QWidget *widget = Core::ICore::mainWindow();
if (!window) if (!widget)
return; return;
window->removeEventFilter(m_colorPickingEventFilter); m_eyeDropperActive = false;
window->setMouseGrabEnabled(false); emit eyeDropperActiveChanged();
widget->removeEventFilter(m_colorPickingEventFilter);
widget->releaseMouse();
#ifdef Q_OS_WIN32 #ifdef Q_OS_WIN32
updateTimer->stop(); updateTimer->stop();
dummyTransparentWindow.setVisible(false); dummyTransparentWindow.setVisible(false);
#endif #endif
window->setKeyboardGrabEnabled(false); widget->releaseKeyboard();
window->unsetCursor(); widget->setMouseTracking(false);
QGuiApplication::restoreOverrideCursor();
} }
bool ColorPaletteBackend::handleEyeDropperMouseMove(QMouseEvent *e) bool ColorPaletteBackend::handleEyeDropperMouseMove(QMouseEvent *e)
@@ -360,4 +383,9 @@ bool ColorPaletteBackend::handleEyeDropperKeyPress(QKeyEvent *e)
return true; return true;
} }
bool ColorPaletteBackend::eyeDropperActive() const
{
return m_eyeDropperActive;
}
} // namespace QmlDesigner } // namespace QmlDesigner

View File

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