diff --git a/images/images.qrc b/images/images.qrc index 3786c58088c..6864c5d3cc8 100644 --- a/images/images.qrc +++ b/images/images.qrc @@ -606,6 +606,13 @@ themes/default/mActionResizeSquare.svg themes/default/mSourceFields.svg flags/zh_Hant.svg + themes/default/cursors/mCapturePoint.svg + themes/default/cursors/mCrossHair.svg + themes/default/cursors/mSampler.svg + themes/default/cursors/mSelect.svg + themes/default/cursors/mZoomIn.svg + themes/default/cursors/mZoomOut.svg + themes/default/cursors/mIdentify.svg qgis_tips/symbol_levels.png diff --git a/images/themes/default/cursors/mCapturePoint.svg b/images/themes/default/cursors/mCapturePoint.svg new file mode 100644 index 00000000000..ed149e9382b --- /dev/null +++ b/images/themes/default/cursors/mCapturePoint.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/themes/default/cursors/mCrossHair.svg b/images/themes/default/cursors/mCrossHair.svg new file mode 100644 index 00000000000..71c2f57a428 --- /dev/null +++ b/images/themes/default/cursors/mCrossHair.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/themes/default/cursors/mIdentify.svg b/images/themes/default/cursors/mIdentify.svg new file mode 100644 index 00000000000..d95b9853a3e --- /dev/null +++ b/images/themes/default/cursors/mIdentify.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/themes/default/cursors/mSampler.svg b/images/themes/default/cursors/mSampler.svg new file mode 100644 index 00000000000..61df80602d1 --- /dev/null +++ b/images/themes/default/cursors/mSampler.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/themes/default/cursors/mSelect.svg b/images/themes/default/cursors/mSelect.svg new file mode 100644 index 00000000000..d12d640222c --- /dev/null +++ b/images/themes/default/cursors/mSelect.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/themes/default/cursors/mZoomIn.svg b/images/themes/default/cursors/mZoomIn.svg new file mode 100644 index 00000000000..4b91b55d8cd --- /dev/null +++ b/images/themes/default/cursors/mZoomIn.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/themes/default/cursors/mZoomOut.svg b/images/themes/default/cursors/mZoomOut.svg new file mode 100644 index 00000000000..26af3ec31be --- /dev/null +++ b/images/themes/default/cursors/mZoomOut.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/python/core/qgsapplication.sip b/python/core/qgsapplication.sip index 401aea2a752..03c6d656c33 100644 --- a/python/core/qgsapplication.sip +++ b/python/core/qgsapplication.sip @@ -345,6 +345,26 @@ Returns the path to the default theme directory. :rtype: QIcon %End + enum Cursor + { + ZoomIn, + ZoomOut, + Identify, + CrossHair, + CapturePoint, + Select, + Sampler, + }; + + static QCursor getThemeCursor( const Cursor &cursor ); +%Docstring + Helper to get a theme cursor. It will fall back to the + default theme if the active theme does not have the required icon. + Cursors are automatically scaled to look like a 16px cursor on 96dpi + screens. + :rtype: QCursor +%End + static QPixmap getThemePixmap( const QString &name ); %Docstring Helper to get a theme icon as a pixmap. It will fall back to the diff --git a/src/app/composer/qgscomposer.cpp b/src/app/composer/qgscomposer.cpp index 29c5d9bdc01..0427ee5c995 100644 --- a/src/app/composer/qgscomposer.cpp +++ b/src/app/composer/qgscomposer.cpp @@ -57,7 +57,6 @@ #include "qgsproject.h" #include "qgsmapcanvas.h" #include "qgsmessageviewer.h" -#include "qgscursors.h" #include "qgsmaplayeractionregistry.h" #include "qgsgeometry.h" #include "qgspaperitem.h" diff --git a/src/app/qgisapp.cpp b/src/app/qgisapp.cpp index ef4800290ab..fc49cfccb51 100644 --- a/src/app/qgisapp.cpp +++ b/src/app/qgisapp.cpp @@ -161,7 +161,6 @@ Q_GUI_EXPORT extern int qt_defaultDpiX(); #include "qgscoordinatetransform.h" #include "qgscoordinateutils.h" #include "qgscredentialdialog.h" -#include "qgscursors.h" #include "qgscustomdrophandler.h" #include "qgscustomization.h" #include "qgscustomlayerorderwidget.h" diff --git a/src/app/qgsmaptoolidentifyaction.cpp b/src/app/qgsmaptoolidentifyaction.cpp index e15a5823099..ba498208008 100644 --- a/src/app/qgsmaptoolidentifyaction.cpp +++ b/src/app/qgsmaptoolidentifyaction.cpp @@ -16,7 +16,6 @@ #include "qgsapplication.h" #include "qgisapp.h" #include "qgsattributetabledialog.h" -#include "qgscursors.h" #include "qgsdistancearea.h" #include "qgsfeature.h" #include "qgsfeaturestore.h" @@ -50,14 +49,9 @@ QgsMapToolIdentifyAction::QgsMapToolIdentifyAction( QgsMapCanvas *canvas ) : QgsMapToolIdentify( canvas ) { mToolName = tr( "Identify" ); - // set cursor - QPixmap myIdentifyQPixmap = QPixmap( ( const char ** ) identify_cursor ); - mCursor = QCursor( myIdentifyQPixmap, 1, 1 ); - + setCursor( QgsApplication::getThemeCursor( QgsApplication::Cursor::Identify ) ); connect( this, &QgsMapToolIdentify::changedRasterResults, this, &QgsMapToolIdentifyAction::handleChangedRasterResults ); - mIdentifyMenu->setAllowMultipleReturn( true ); - QgsMapLayerAction *attrTableAction = new QgsMapLayerAction( tr( "Show attribute table" ), mIdentifyMenu, QgsMapLayer::VectorLayer, QgsMapLayerAction::MultipleFeatures ); connect( attrTableAction, &QgsMapLayerAction::triggeredForFeatures, this, &QgsMapToolIdentifyAction::showAttributeTable ); identifyMenu()->addCustomAction( attrTableAction ); diff --git a/src/app/qgsmaptoolselectrectangle.cpp b/src/app/qgsmaptoolselectrectangle.cpp index 31562e72816..687d6577504 100644 --- a/src/app/qgsmaptoolselectrectangle.cpp +++ b/src/app/qgsmaptoolselectrectangle.cpp @@ -20,7 +20,6 @@ #include "qgsmapcanvas.h" #include "qgsmaptopixel.h" #include "qgsvectorlayer.h" -#include "qgscursors.h" #include "qgsgeometry.h" #include "qgspointxy.h" #include "qgis.h" @@ -34,8 +33,7 @@ QgsMapToolSelectFeatures::QgsMapToolSelectFeatures( QgsMapCanvas *canvas ) , mDragging( false ) { mToolName = tr( "Select features" ); - QPixmap mySelectQPixmap = QPixmap( ( const char ** ) select_cursor ); - mCursor = QCursor( mySelectQPixmap, 1, 1 ); + setCursor( QgsApplication::getThemeCursor( QgsApplication::Cursor::Select ) ); mRubberBand = nullptr; mFillColor = QColor( 254, 178, 76, 63 ); mStrokeColor = QColor( 254, 58, 29, 100 ); diff --git a/src/app/qgsmeasuretool.cpp b/src/app/qgsmeasuretool.cpp index 185f2944ff2..1aead8b7b4a 100644 --- a/src/app/qgsmeasuretool.cpp +++ b/src/app/qgsmeasuretool.cpp @@ -24,7 +24,6 @@ #include "qgsexception.h" #include "qgsmeasuredialog.h" #include "qgsmeasuretool.h" -#include "qgscursors.h" #include "qgsmessagelog.h" #include "qgssettings.h" @@ -40,8 +39,7 @@ QgsMeasureTool::QgsMeasureTool( QgsMapCanvas *canvas, bool measureArea ) mRubberBand = new QgsRubberBand( canvas, mMeasureArea ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry ); mRubberBandPoints = new QgsRubberBand( canvas, QgsWkbTypes::PointGeometry ); - QPixmap myCrossHairQPixmap = QPixmap( ( const char ** ) cross_hair_cursor ); - mCursor = QCursor( myCrossHairQPixmap, 8, 8 ); + setCursor( QgsApplication::getThemeCursor( QgsApplication::Cursor::CrossHair ) ); mDone = true; // Append point we will move diff --git a/src/core/qgsapplication.cpp b/src/core/qgsapplication.cpp index 23b27698fd7..d37f4593ef1 100644 --- a/src/core/qgsapplication.cpp +++ b/src/core/qgsapplication.cpp @@ -481,6 +481,70 @@ QIcon QgsApplication::getThemeIcon( const QString &name ) return icon; } +QCursor QgsApplication::getThemeCursor( const Cursor &cursor ) +{ + QgsApplication *app = instance(); + if ( app && app->mCursorCache.contains( cursor ) ) + return app->mCursorCache.value( cursor ); + + // All calculations are done on 32x32 icons + // Defaults to center, individual cursors may override + int activeX = 16; + int activeY = 16; + + QString name; + switch ( cursor ) + { + case ZoomIn: + name = QStringLiteral( "mZoomIn.svg" ); + activeX = 13; + activeY = 13; + break; + case ZoomOut: + name = QStringLiteral( "mZoomOut.svg" ); + activeX = 13; + activeY = 13; + break; + case Identify: + activeX = 3; + activeY = 6; + name = QStringLiteral( "mIdentify.svg" ); + break; + case CrossHair: + name = QStringLiteral( "mCrossHair.svg" ); + break; + case CapturePoint: + name = QStringLiteral( "mCapturePoint.svg" ); + break; + case Select: + name = QStringLiteral( "mSelect.svg" ); + activeX = 6; + activeY = 6; + break; + case Sampler: + activeX = 5; + activeY = 5; + name = QStringLiteral( "mSampler.svg" ); + break; + // No default + } + // It should never get here! + Q_ASSERT( ! name.isEmpty( ) ); + + QIcon icon = getThemeIcon( QStringLiteral( "cursors" ) + QDir::separator() + name ); + QCursor _cursor; + // Check if an icon exists for this cursor (the O.S. default cursor will be used if it does not) + if ( ! icon.isNull( ) ) + { + // Apply scaling + float scale( ( float ) app->fontMetrics().height() / 32 * 1.5 ) ; // Make them bigger to match 24x24 + _cursor = QCursor( icon.pixmap( std::ceil( scale * 32 ), std::ceil( scale * 32 ) ), std::ceil( scale * activeX ), std::ceil( scale * activeY ) ); + } + if ( app ) + app->mCursorCache.insert( cursor, _cursor ); + return _cursor; +} + // TODO: add some caching mechanism ? QPixmap QgsApplication::getThemePixmap( const QString &name ) { diff --git a/src/core/qgsapplication.h b/src/core/qgsapplication.h index 2d5eb311366..36b5fc1986c 100644 --- a/src/core/qgsapplication.h +++ b/src/core/qgsapplication.h @@ -311,6 +311,29 @@ class CORE_EXPORT QgsApplication : public QApplication */ static QIcon getThemeIcon( const QString &name ); + /** + * \brief The Cursor enum defines constants for QGIS custom + * cursors. + */ + enum Cursor + { + ZoomIn, //!< Zoom in + ZoomOut, //!< Zoom out + Identify, //!< Identify: obtain information about the object + CrossHair, //!< Precisely identify a point on the canvas + CapturePoint, //!< Select and capture a point or a feature + Select, //!< Select a rectangle + Sampler, //!< Color/Value picker + }; + + /** + * Helper to get a theme cursor. It will fall back to the + * default theme if the active theme does not have the required icon. + * Cursors are automatically scaled to look like a 16px cursor on 96dpi + * screens. + */ + static QCursor getThemeCursor( const Cursor &cursor ); + /** * Helper to get a theme icon as a pixmap. It will fall back to the * default theme if the active theme does not have the required icon. @@ -747,6 +770,7 @@ class CORE_EXPORT QgsApplication : public QApplication static QString sPlatformName; QMap mIconCache; + QMap mCursorCache; QgsDataItemProviderRegistry *mDataItemProviderRegistry = nullptr; QgsAuthManager *mAuthManager = nullptr; diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index 82055027ed0..aa1b4c80e46 100755 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -229,7 +229,6 @@ SET(QGIS_GUI_SRCS qgscompoundcolorwidget.cpp qgsconfigureshortcutsdialog.cpp qgscredentialdialog.cpp - qgscursors.cpp qgscustomdrophandler.cpp qgscurveeditorwidget.cpp qgsdatumtransformdialog.cpp @@ -718,7 +717,6 @@ SET(QGIS_GUI_HDRS qgsattributeeditorcontext.h qgsattributeforminterface.h qgsattributeformlegacyinterface.h - qgscursors.h qgsdetaileditemdata.h qgsexpressionbuilderdialog.h qgsgeometryrubberband.h diff --git a/src/gui/layout/qgslayoutviewtooladditem.cpp b/src/gui/layout/qgslayoutviewtooladditem.cpp index 40e37bdc54f..6e5f33e889b 100644 --- a/src/gui/layout/qgslayoutviewtooladditem.cpp +++ b/src/gui/layout/qgslayoutviewtooladditem.cpp @@ -15,7 +15,6 @@ #include "qgslayoutviewtooladditem.h" #include "qgsapplication.h" -#include "qgscursors.h" #include "qgslayoutview.h" #include "qgslayout.h" #include "qgslayoutitemregistry.h" @@ -35,8 +34,7 @@ QgsLayoutViewToolAddItem::QgsLayoutViewToolAddItem( QgsLayoutView *view ) : QgsLayoutViewTool( view, tr( "Add item" ) ) { setFlags( QgsLayoutViewTool::FlagSnaps ); - QPixmap crosshairQPixmap = QPixmap( ( const char ** )( cross_hair_cursor ) ); - setCursor( QCursor( crosshairQPixmap, 8, 8 ) ); + setCursor( QgsApplication::getThemeCursor( QgsApplication::Cursor::CrossHair ) ); } void QgsLayoutViewToolAddItem::setItemMetadataId( int metadataId ) diff --git a/src/gui/layout/qgslayoutviewtooladdnodeitem.cpp b/src/gui/layout/qgslayoutviewtooladdnodeitem.cpp index 53538942ea4..20b2f964212 100644 --- a/src/gui/layout/qgslayoutviewtooladdnodeitem.cpp +++ b/src/gui/layout/qgslayoutviewtooladdnodeitem.cpp @@ -15,7 +15,6 @@ #include "qgslayoutviewtooladdnodeitem.h" #include "qgsapplication.h" -#include "qgscursors.h" #include "qgslayoutview.h" #include "qgslayout.h" #include "qgslayoutitemregistry.h" @@ -37,8 +36,7 @@ QgsLayoutViewToolAddNodeItem::QgsLayoutViewToolAddNodeItem( QgsLayoutView *view : QgsLayoutViewTool( view, tr( "Add item" ) ) { setFlags( QgsLayoutViewTool::FlagSnaps ); - QPixmap crosshairQPixmap = QPixmap( ( const char ** )( cross_hair_cursor ) ); - setCursor( QCursor( crosshairQPixmap, 8, 8 ) ); + setCursor( QgsApplication::getThemeCursor( QgsApplication::Cursor::CrossHair ) ); } void QgsLayoutViewToolAddNodeItem::setItemMetadataId( int metadataId ) diff --git a/src/gui/layout/qgslayoutviewtooltemporarykeyzoom.cpp b/src/gui/layout/qgslayoutviewtooltemporarykeyzoom.cpp index 362984f0b44..07b1f8559d6 100644 --- a/src/gui/layout/qgslayoutviewtooltemporarykeyzoom.cpp +++ b/src/gui/layout/qgslayoutviewtooltemporarykeyzoom.cpp @@ -16,7 +16,6 @@ #include "qgslayoutviewtooltemporarykeyzoom.h" #include "qgslayoutviewmouseevent.h" #include "qgslayoutview.h" -#include "qgscursors.h" #include #include @@ -107,7 +106,7 @@ void QgsLayoutViewToolTemporaryKeyZoom::activate() void QgsLayoutViewToolTemporaryKeyZoom::updateCursor( Qt::KeyboardModifiers modifiers ) { - QPixmap zoomQPixmap = QPixmap( ( const char ** )( ( modifiers & Qt::AltModifier ) ? zoom_out : zoom_in ) ); - QCursor zoomCursor = QCursor( zoomQPixmap, 7, 7 ); - view()->viewport()->setCursor( zoomCursor ); + view()->viewport()->setCursor( ( modifiers & Qt::AltModifier ) ? + QgsApplication::getThemeCursor( QgsApplication::Cursor::ZoomOut ) : + QgsApplication::getThemeCursor( QgsApplication::Cursor::ZoomIn ) ); } diff --git a/src/gui/layout/qgslayoutviewtoolzoom.cpp b/src/gui/layout/qgslayoutviewtoolzoom.cpp index 5735bc36cbd..cc70934e076 100644 --- a/src/gui/layout/qgslayoutviewtoolzoom.cpp +++ b/src/gui/layout/qgslayoutviewtoolzoom.cpp @@ -18,15 +18,12 @@ #include "qgslayoutview.h" #include "qgslayoutviewrubberband.h" #include "qgsrectangle.h" -#include "qgscursors.h" #include QgsLayoutViewToolZoom::QgsLayoutViewToolZoom( QgsLayoutView *view ) : QgsLayoutViewTool( view, tr( "Pan" ) ) { - QPixmap zoomQPixmap = QPixmap( ( const char ** )( zoom_in ) ); - setCursor( QCursor( zoomQPixmap, 7, 7 ) ); - + setCursor( QgsApplication::getThemeCursor( QgsApplication::Cursor::ZoomIn ) ); mRubberBand.reset( new QgsLayoutViewRectangularRubberBand( view ) ); mRubberBand->setBrush( QBrush( QColor( 70, 50, 255, 25 ) ) ); mRubberBand->setPen( QPen( QBrush( QColor( 70, 50, 255, 100 ) ), 0 ) ); @@ -110,9 +107,10 @@ void QgsLayoutViewToolZoom::keyPressEvent( QKeyEvent *event ) //respond to changes in the alt key status and update cursor accordingly if ( !event->isAutoRepeat() ) { - QPixmap zoomQPixmap = QPixmap( ( const char ** )( ( event->modifiers() & Qt::AltModifier ) ? zoom_out : zoom_in ) ); - QCursor zoomCursor = QCursor( zoomQPixmap, 7, 7 ); - view()->viewport()->setCursor( zoomCursor ); + + view()->viewport()->setCursor( ( event->modifiers() & Qt::AltModifier ) ? + QgsApplication::getThemeCursor( QgsApplication::Cursor::ZoomOut ) : + QgsApplication::getThemeCursor( QgsApplication::Cursor::ZoomIn ) ); } event->ignore(); } @@ -122,9 +120,10 @@ void QgsLayoutViewToolZoom::keyReleaseEvent( QKeyEvent *event ) //respond to changes in the alt key status and update cursor accordingly if ( !event->isAutoRepeat() ) { - QPixmap zoomQPixmap = QPixmap( ( const char ** )( ( event->modifiers() & Qt::AltModifier ) ? zoom_out : zoom_in ) ); - QCursor zoomCursor = QCursor( zoomQPixmap, 7, 7 ); - view()->viewport()->setCursor( zoomCursor ); + + view()->viewport()->setCursor( ( event->modifiers() & Qt::AltModifier ) ? + QgsApplication::getThemeCursor( QgsApplication::Cursor::ZoomOut ) : + QgsApplication::getThemeCursor( QgsApplication::Cursor::ZoomIn ) ); } event->ignore(); } diff --git a/src/gui/qgscolorbutton.cpp b/src/gui/qgscolorbutton.cpp index 8385f2f13ce..f02f2638784 100644 --- a/src/gui/qgscolorbutton.cpp +++ b/src/gui/qgscolorbutton.cpp @@ -18,7 +18,6 @@ #include "qgsapplication.h" #include "qgslogger.h" #include "qgssymbollayerutils.h" -#include "qgscursors.h" #include "qgscolorswatchgrid.h" #include "qgscolorschemeregistry.h" #include "qgscolorwidgets.h" @@ -34,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -246,10 +246,14 @@ void QgsColorButton::mouseMoveEvent( QMouseEvent *e ) { //if left button depressed, sample color under cursor and temporarily update button color //to give feedback to user - QPixmap snappedPixmap = QPixmap::grabWindow( QApplication::desktop()->winId(), e->globalPos().x(), e->globalPos().y(), 1, 1 ); - QImage snappedImage = snappedPixmap.toImage(); - QColor hoverColor = snappedImage.pixel( 0, 0 ); - setButtonBackground( hoverColor ); + QScreen *screen = findScreenAt( e->globalPos() ); + if ( screen ) + { + QPixmap snappedPixmap = screen->grabWindow( QApplication::desktop()->winId(), e->globalPos().x(), e->globalPos().y(), 1, 1 ); + QImage snappedImage = snappedPixmap.toImage(); + QColor hoverColor = snappedImage.pixel( 0, 0 ); + setButtonBackground( hoverColor ); + } } e->accept(); return; @@ -298,6 +302,7 @@ void QgsColorButton::stopPicking( QPointF eventPos, bool sampleColor ) releaseMouse(); releaseKeyboard(); unsetCursor(); + setMouseTracking( false ); mPickingColor = false; if ( !sampleColor ) @@ -307,7 +312,7 @@ void QgsColorButton::stopPicking( QPointF eventPos, bool sampleColor ) } //grab snapshot of pixel under mouse cursor - QPixmap snappedPixmap = QPixmap::grabWindow( QApplication::desktop()->winId(), eventPos.x(), eventPos.y(), 1, 1 ); + QPixmap snappedPixmap = QApplication::desktop()->screen()->grab( QRect( eventPos.x(), eventPos.y(), 1, 1 ) ); QImage snappedImage = snappedPixmap.toImage(); //extract color from pixel and set color setColor( snappedImage.pixel( 0, 0 ) ); @@ -361,6 +366,18 @@ void QgsColorButton::dropEvent( QDropEvent *e ) } } +QScreen *QgsColorButton::findScreenAt( const QPoint &pos ) +{ + for ( QScreen *screen : QGuiApplication::screens() ) + { + if ( screen->geometry().contains( pos ) ) + { + return screen; + } + } + return nullptr; +} + void QgsColorButton::setValidColor( const QColor &newColor ) { if ( newColor.isValid() ) @@ -672,12 +689,12 @@ void QgsColorButton::pasteColor() void QgsColorButton::activatePicker() { - //pick color - QPixmap samplerPixmap = QPixmap( ( const char ** ) sampler_cursor ); - setCursor( QCursor( samplerPixmap, 0, 0 ) ); + //activate picker color + setCursor( QgsApplication::getThemeCursor( QgsApplication::Cursor::Sampler ) ); grabMouse(); grabKeyboard(); mPickingColor = true; + setMouseTracking( true ); } QColor QgsColorButton::color() const diff --git a/src/gui/qgscolorbutton.h b/src/gui/qgscolorbutton.h index 97d623bd173..1f0652aa122 100644 --- a/src/gui/qgscolorbutton.h +++ b/src/gui/qgscolorbutton.h @@ -415,6 +415,7 @@ class GUI_EXPORT QgsColorButton : public QToolButton private: + static QScreen *findScreenAt( const QPoint &pos ); Behavior mBehavior = QgsColorButton::ShowDialog; QString mColorDialogTitle; QColor mColor; diff --git a/src/gui/qgscolordialog.cpp b/src/gui/qgscolordialog.cpp index 807e2d9ef39..10e53c0ff88 100644 --- a/src/gui/qgscolordialog.cpp +++ b/src/gui/qgscolordialog.cpp @@ -18,7 +18,6 @@ #include "qgscolorscheme.h" #include "qgscolorschemeregistry.h" #include "qgssymbollayerutils.h" -#include "qgscursors.h" #include "qgsapplication.h" #include "qgssettings.h" diff --git a/src/gui/qgscomposerview.cpp b/src/gui/qgscomposerview.cpp index b66754e934d..bae015e6ad2 100644 --- a/src/gui/qgscomposerview.cpp +++ b/src/gui/qgscomposerview.cpp @@ -45,7 +45,6 @@ #include "qgsaddremovemultiframecommand.h" #include "qgspaperitem.h" #include "qgsmapcanvas.h" -#include "qgscursors.h" #include "qgscomposerutils.h" #include "qgssettings.h" @@ -480,11 +479,9 @@ QCursor QgsComposerView::defaultCursorForTool( Tool currentTool ) case Select: return Qt::ArrowCursor; + // Use custom QGIS cursor for ZoomIn case Zoom: - { - QPixmap myZoomQPixmap = QPixmap( ( const char ** )( zoom_in ) ); - return QCursor( myZoomQPixmap, 7, 7 ); - } + return QgsApplication::getThemeCursor( QgsApplication::Cursor::ZoomIn ); case Pan: return Qt::OpenHandCursor; @@ -492,16 +489,15 @@ QCursor QgsComposerView::defaultCursorForTool( Tool currentTool ) case MoveItemContent: return Qt::ArrowCursor; + // Use QGIS custom cursor for the following case EditNodesItem: - return Qt::CrossCursor; - + case AddPolyline: case AddArrow: case AddMap: case AddRectangle: case AddTriangle: case AddEllipse: case AddPolygon: - case AddPolyline: case AddHtml: case AddLabel: case AddScalebar: @@ -509,10 +505,7 @@ QCursor QgsComposerView::defaultCursorForTool( Tool currentTool ) case AddPicture: case AddTable: case AddAttributeTable: - { - QPixmap myCrosshairQPixmap = QPixmap( ( const char ** )( cross_hair_cursor ) ); - return QCursor( myCrosshairQPixmap, 8, 8 ); - } + return QgsApplication::getThemeCursor( QgsApplication::Cursor::CrossHair ); } return Qt::ArrowCursor; } @@ -1688,10 +1681,9 @@ void QgsComposerView::keyPressEvent( QKeyEvent *e ) else { //both control and space pressed - //set cursor to zoom in/out depending on shift key status - QPixmap myZoomQPixmap = QPixmap( ( const char ** )( ( e->modifiers() & Qt::AltModifier ) ? zoom_out : zoom_in ) ); - QCursor zoomCursor = QCursor( myZoomQPixmap, 7, 7 ); - viewport()->setCursor( zoomCursor ); + viewport()->setCursor( ( e->modifiers() & Qt::AltModifier ) ? + QgsApplication::getThemeCursor( QgsApplication::Cursor::ZoomOut ) : + QgsApplication::getThemeCursor( QgsApplication::Cursor::ZoomIn ) ); } return; } @@ -1724,9 +1716,9 @@ void QgsComposerView::keyPressEvent( QKeyEvent *e ) mPreviousTool = mCurrentTool; setCurrentTool( Zoom ); //set cursor to zoom in/out depending on alt key status - QPixmap myZoomQPixmap = QPixmap( ( const char ** )( ( e->modifiers() & Qt::AltModifier ) ? zoom_out : zoom_in ) ); - QCursor zoomCursor = QCursor( myZoomQPixmap, 7, 7 ); - viewport()->setCursor( zoomCursor ); + viewport()->setCursor( ( e->modifiers() & Qt::AltModifier ) ? + QgsApplication::getThemeCursor( QgsApplication::Cursor::ZoomOut ) : + QgsApplication::getThemeCursor( QgsApplication::Cursor::ZoomIn ) ); return; } } @@ -1736,9 +1728,9 @@ void QgsComposerView::keyPressEvent( QKeyEvent *e ) //using the zoom tool, respond to changes in alt key status and update mouse cursor accordingly if ( ! e->isAutoRepeat() ) { - QPixmap myZoomQPixmap = QPixmap( ( const char ** )( ( e->modifiers() & Qt::AltModifier ) ? zoom_out : zoom_in ) ); - QCursor zoomCursor = QCursor( myZoomQPixmap, 7, 7 ); - viewport()->setCursor( zoomCursor ); + viewport()->setCursor( ( e->modifiers() & Qt::AltModifier ) ? + QgsApplication::getThemeCursor( QgsApplication::Cursor::ZoomOut ) : + QgsApplication::getThemeCursor( QgsApplication::Cursor::ZoomIn ) ); } return; } @@ -1925,9 +1917,9 @@ void QgsComposerView::keyReleaseEvent( QKeyEvent *e ) //if zoom tool is active, respond to changes in the alt key status and update cursor accordingly if ( ! e->isAutoRepeat() ) { - QPixmap myZoomQPixmap = QPixmap( ( const char ** )( ( e->modifiers() & Qt::AltModifier ) ? zoom_out : zoom_in ) ); - QCursor zoomCursor = QCursor( myZoomQPixmap, 7, 7 ); - viewport()->setCursor( zoomCursor ); + viewport()->setCursor( ( e->modifiers() & Qt::AltModifier ) ? + QgsApplication::getThemeCursor( QgsApplication::Cursor::ZoomOut ) : + QgsApplication::getThemeCursor( QgsApplication::Cursor::ZoomIn ) ); } return; } diff --git a/src/gui/qgscompoundcolorwidget.cpp b/src/gui/qgscompoundcolorwidget.cpp index 85c1c1b63de..2015567e06d 100644 --- a/src/gui/qgscompoundcolorwidget.cpp +++ b/src/gui/qgscompoundcolorwidget.cpp @@ -17,7 +17,6 @@ #include "qgscolorscheme.h" #include "qgscolorschemeregistry.h" #include "qgssymbollayerutils.h" -#include "qgscursors.h" #include "qgsapplication.h" #include "qgssettings.h" @@ -28,6 +27,7 @@ #include #include #include +#include #include #include @@ -515,8 +515,7 @@ void QgsCompoundColorWidget::mAddCustomColorButton_clicked() void QgsCompoundColorWidget::mSampleButton_clicked() { //activate picker color - QPixmap samplerPixmap = QPixmap( ( const char ** ) sampler_cursor ); - setCursor( QCursor( samplerPixmap, 0, 0 ) ); + setCursor( QgsApplication::getThemeCursor( QgsApplication::Cursor::Sampler ) ); grabMouse(); grabKeyboard(); mPickingColor = true; @@ -544,6 +543,18 @@ void QgsCompoundColorWidget::mActionShowInButtons_toggled( bool state ) } } +QScreen *QgsCompoundColorWidget::findScreenAt( const QPoint &pos ) +{ + for ( QScreen *screen : QGuiApplication::screens() ) + { + if ( screen->geometry().contains( pos ) ) + { + return screen; + } + } + return nullptr; +} + void QgsCompoundColorWidget::saveSettings() { //save changes to scheme @@ -696,8 +707,16 @@ QColor QgsCompoundColorWidget::averageColor( const QImage &image ) const QColor QgsCompoundColorWidget::sampleColor( QPoint point ) const { int sampleRadius = mSpinBoxRadius->value() - 1; - QPixmap snappedPixmap = QPixmap::grabWindow( QApplication::desktop()->winId(), point.x() - sampleRadius, point.y() - sampleRadius, - 1 + sampleRadius * 2, 1 + sampleRadius * 2 ); + QScreen *screen = findScreenAt( point ); + if ( ! screen ) + { + return QColor(); + } + QPixmap snappedPixmap = screen->grabWindow( QApplication::desktop()->winId(), + point.x() - sampleRadius, + point.y() - sampleRadius, + 1 + sampleRadius * 2, + 1 + sampleRadius * 2 ); QImage snappedImage = snappedPixmap.toImage(); //scan all pixels and take average color return averageColor( snappedImage ); diff --git a/src/gui/qgscompoundcolorwidget.h b/src/gui/qgscompoundcolorwidget.h index 523b4bebc67..95fc6150668 100644 --- a/src/gui/qgscompoundcolorwidget.h +++ b/src/gui/qgscompoundcolorwidget.h @@ -137,6 +137,8 @@ class GUI_EXPORT QgsCompoundColorWidget : public QgsPanelWidget, private Ui::Qgs private: + static QScreen *findScreenAt( const QPoint &pos ); + bool mAllowAlpha = true; int mLastCustomColorIndex = 0; diff --git a/src/gui/qgscursors.cpp b/src/gui/qgscursors.cpp deleted file mode 100644 index 8be095c08aa..00000000000 --- a/src/gui/qgscursors.cpp +++ /dev/null @@ -1,191 +0,0 @@ -/*************************************************************************** - qgscursors.cpp - - ------------------- - begin : 2007 - copyright : (C) 2007 by Gary E. Sherman - email : sherman@mrcc.com -***************************************************************************/ - -/*************************************************************************** - * * - * 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 * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - ***************************************************************************/ -#include "qgscursors.h" - -#define SIP_NO_FILE - -// cursors -const char *zoom_in[] = -{ - "16 16 3 1", - ". c None", - "a c #000000", - "# c #ffffff", - ".....#####......", - "...##aaaaa##....", - "..#.a.....a.#...", - ".#.a...a...a.#..", - ".#a....a....a#..", - "#a.....a.....a#.", - "#a.....a.....a#.", - "#a.aaaa#aaaa.a#.", - "#a.....a.....a#.", - "#a.....a.....a#.", - ".#a....a....a#..", - ".#.a...a...aaa#.", - "..#.a.....a#aaa#", - "...##aaaaa###aa#", - ".....#####...###", - "..............#." -}; - -const char *zoom_out[] = -{ - "16 16 4 1", - "b c None", - ". c None", - "a c #000000", - "# c #ffffff", - ".....#####......", - "...##aaaaa##....", - "..#.a.....a.#...", - ".#.a.......a.#..", - ".#a.........a#..", - "#a...........a#.", - "#a...........a#.", - "#a.aaaa#aaaa.a#.", - "#a...........a#.", - "#a...........a#.", - ".#a.........a#..", - ".#.a.......aaa#.", - "..#.a.....a#aaa#", - "...##aaaaa###aa#", - ".....#####...###", - "..............#." -}; - - -const char *capture_point_cursor[] = -{ - "16 16 3 1", - " » c None", - ".» c #000000", - "+» c #FFFFFF", - " ", - " +.+ ", - " ++.++ ", - " +.....+ ", - " +. .+ ", - " +. . .+ ", - " +. . .+ ", - " ++. . .++", - " ... ...+... ...", - " ++. . .++", - " +. . .+ ", - " +. . .+ ", - " ++. .+ ", - " ++.....+ ", - " ++.++ ", - " +.+ " -}; - -const char *select_cursor[] = -{ - "16 16 3 1", - "# c None", - "a c #000000", - ". c #ffffff", - ".###############", - "...#############", - ".aa..###########", - "#.aaa..a.a.a.a.#", - "#.aaaaa..#####a#", - "#a.aaaaaa..###.#", - "#..aaaaaa...##a#", - "#a.aaaaa.#####.#", - "#.#.aaaaa.####a#", - "#a#.aa.aaa.###.#", - "#.##..#..aa.##a#", - "#a##.####.aa.#.#", - "#.########.aa.a#", - "#a#########.aa..", - "#.a.a.a.a.a..a.#", - "#############.##" -}; - -const char *identify_cursor[] = -{ - "16 16 3 1", - "# c None", - "a c #000000", - ". c #ffffff", - ".###########..##", - "...########.aa.#", - ".aa..######.aa.#", - "#.aaa..#####..##", - "#.aaaaa..##.aa.#", - "##.aaaaaa...aa.#", - "##.aaaaaa...aa.#", - "##.aaaaa.##.aa.#", - "###.aaaaa.#.aa.#", - "###.aa.aaa..aa.#", - "####..#..aa.aa.#", - "####.####.aa.a.#", - "##########.aa..#", - "###########.aa..", - "############.a.#", - "#############.##" -}; - -const char *cross_hair_cursor[] = -{ - "16 16 3 1", - " » c None", - ".» c #000000", - "+» c #FFFFFF", - " ", - " +.+ ", - " +.+ ", - " +.+ ", - " +.+ ", - " +.+ ", - " . ", - " +++++ +++++", - " ...... ......", - " +++++ +++++", - " . ", - " +.+ ", - " +.+ ", - " +.+ ", - " +.+ ", - " +.+ " -}; - -const char *sampler_cursor[] = -{ - "16 16 3 1", - " » c None", - ".» c #000000", - "+» c #FFFFFF", - ".. ", - ".+. ", - " .+.. ", - " .++. ", - " .+++. ", - " .+++. ", - " .+++. ", - " .+++... ", - " .++... ", - " ...... ", - " ....... ", - " ........ ", - " .......", - " ......", - " .....", - " ... " -}; diff --git a/src/gui/qgscursors.h b/src/gui/qgscursors.h deleted file mode 100644 index e8210e68ae3..00000000000 --- a/src/gui/qgscursors.h +++ /dev/null @@ -1,38 +0,0 @@ -/*************************************************************************** - qgscursors.h - - ------------------- - begin : 2007 - copyright : (C) 2007 by Gary E. Sherman - email : sherman@mrcc.com -***************************************************************************/ - -/*************************************************************************** - * * - * 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 * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - ***************************************************************************/ -#ifndef QGSCURSORS_H -#define QGSCURSORS_H - -#include "qgis_gui.h" - -#define SIP_NO_FILE - -/** - * \ingroup gui - * Bitmap cursors for map operations. - */ -extern GUI_EXPORT const char *zoom_in[]; -extern GUI_EXPORT const char *zoom_out[]; - -extern GUI_EXPORT const char *capture_point_cursor[]; -extern GUI_EXPORT const char *select_cursor[]; -extern GUI_EXPORT const char *identify_cursor[]; -extern GUI_EXPORT const char *cross_hair_cursor[]; -extern GUI_EXPORT const char *sampler_cursor[]; - -#endif diff --git a/src/gui/qgsmapcanvas.cpp b/src/gui/qgsmapcanvas.cpp index 0012671a14e..ba753d091f6 100644 --- a/src/gui/qgsmapcanvas.cpp +++ b/src/gui/qgsmapcanvas.cpp @@ -63,7 +63,6 @@ email : sherman at mrcc.com #include "qgsproject.h" #include "qgsrubberband.h" #include "qgsvectorlayer.h" -#include "qgscursors.h" #include "qgsmapthemecollection.h" #include @@ -169,8 +168,7 @@ QgsMapCanvas::QgsMapCanvas( QWidget *parent ) mPreviewEffect = new QgsPreviewEffect( this ); viewport()->setGraphicsEffect( mPreviewEffect ); - QPixmap zoomPixmap = QPixmap( ( const char ** )( zoom_in ) ); - mZoomCursor = QCursor( zoomPixmap, 7, 7 ); + mZoomCursor = QgsApplication::getThemeCursor( QgsApplication::Cursor::ZoomIn ); connect( &mAutoRefreshTimer, &QTimer::timeout, this, &QgsMapCanvas::autoRefreshTriggered ); diff --git a/src/gui/qgsmaptoolcapture.cpp b/src/gui/qgsmaptoolcapture.cpp index 20782efdf0a..23c93cd88c2 100644 --- a/src/gui/qgsmaptoolcapture.cpp +++ b/src/gui/qgsmaptoolcapture.cpp @@ -15,7 +15,6 @@ #include "qgsmaptoolcapture.h" -#include "qgscursors.h" #include "qgsexception.h" #include "qgsfeatureiterator.h" #include "qgsgeometryvalidator.h" @@ -51,8 +50,7 @@ QgsMapToolCapture::QgsMapToolCapture( QgsMapCanvas *canvas, QgsAdvancedDigitizin mSnapIndicator.reset( new QgsSnapIndicator( canvas ) ); - QPixmap mySelectQPixmap = QPixmap( ( const char ** ) capture_point_cursor ); - setCursor( QCursor( mySelectQPixmap, 8, 8 ) ); + setCursor( QgsApplication::getThemeCursor( QgsApplication::Cursor::CapturePoint ) ); connect( canvas, &QgsMapCanvas::currentLayerChanged, this, &QgsMapToolCapture::currentLayerChanged ); diff --git a/src/gui/qgsmaptoolidentify.cpp b/src/gui/qgsmaptoolidentify.cpp index c52c91139d3..72b4d6af5a6 100644 --- a/src/gui/qgsmaptoolidentify.cpp +++ b/src/gui/qgsmaptoolidentify.cpp @@ -14,7 +14,6 @@ ***************************************************************************/ #include "qgsapplication.h" -#include "qgscursors.h" #include "qgsdistancearea.h" #include "qgsfeature.h" #include "qgsfeatureiterator.h" @@ -56,9 +55,7 @@ QgsMapToolIdentify::QgsMapToolIdentify( QgsMapCanvas *canvas ) , mLastMapUnitsPerPixel( -1.0 ) , mCoordinatePrecision( 6 ) { - // set cursor - QPixmap myIdentifyQPixmap = QPixmap( ( const char ** ) identify_cursor ); - mCursor = QCursor( myIdentifyQPixmap, 1, 1 ); + setCursor( QgsApplication::getThemeCursor( QgsApplication::Cursor::Identify ) ); } QgsMapToolIdentify::~QgsMapToolIdentify() diff --git a/src/gui/qgsmaptoolidentifyfeature.cpp b/src/gui/qgsmaptoolidentifyfeature.cpp index d6a352e05d4..673c1b35ebd 100644 --- a/src/gui/qgsmaptoolidentifyfeature.cpp +++ b/src/gui/qgsmaptoolidentifyfeature.cpp @@ -15,7 +15,6 @@ #include -#include "qgscursors.h" #include "qgsmaptoolidentifyfeature.h" #include "qgsmapcanvas.h" @@ -27,8 +26,7 @@ QgsMapToolIdentifyFeature::QgsMapToolIdentifyFeature( QgsMapCanvas *canvas, QgsV mToolName = tr( "Identify feature" ); // set cursor - QPixmap cursorPixmap = QPixmap( ( const char ** ) cross_hair_cursor ); - mCursor = QCursor( cursorPixmap, 1, 1 ); + mCursor = QCursor( Qt::CrossCursor ); } void QgsMapToolIdentifyFeature::canvasReleaseEvent( QgsMapMouseEvent *e ) diff --git a/src/gui/qgsmaptoolpan.cpp b/src/gui/qgsmaptoolpan.cpp index dc7a24ea0b3..5c148118379 100644 --- a/src/gui/qgsmaptoolpan.cpp +++ b/src/gui/qgsmaptoolpan.cpp @@ -15,7 +15,6 @@ #include "qgsmaptoolpan.h" #include "qgsmapcanvas.h" -#include "qgscursors.h" #include "qgsmaptopixel.h" #include #include diff --git a/src/gui/qgsmaptoolzoom.cpp b/src/gui/qgsmaptoolzoom.cpp index f0d5cd01968..0ce91535728 100644 --- a/src/gui/qgsmaptoolzoom.cpp +++ b/src/gui/qgsmaptoolzoom.cpp @@ -16,7 +16,6 @@ #include "qgsmaptoolzoom.h" #include "qgsmapcanvas.h" #include "qgsmaptopixel.h" -#include "qgscursors.h" #include "qgsrubberband.h" #include @@ -35,8 +34,8 @@ QgsMapToolZoom::QgsMapToolZoom( QgsMapCanvas *canvas, bool zoomOut ) { mToolName = tr( "Zoom" ); // set the cursor - QPixmap myZoomQPixmap = QPixmap( ( const char ** )( zoomOut ? zoom_out : zoom_in ) ); - mCursor = QCursor( myZoomQPixmap, 7, 7 ); + mCursor = zoomOut ? QgsApplication::getThemeCursor( QgsApplication::Cursor::ZoomOut ) : + QgsApplication::getThemeCursor( QgsApplication::Cursor::ZoomIn ); } QgsMapToolZoom::~QgsMapToolZoom() diff --git a/src/plugins/coordinate_capture/coordinatecapturemaptool.cpp b/src/plugins/coordinate_capture/coordinatecapturemaptool.cpp index 0bd1e90ac08..506d5f51988 100644 --- a/src/plugins/coordinate_capture/coordinatecapturemaptool.cpp +++ b/src/plugins/coordinate_capture/coordinatecapturemaptool.cpp @@ -14,7 +14,6 @@ ***************************************************************************/ #include "coordinatecapturemaptool.h" -#include "qgscursors.h" #include "qgsmapcanvas.h" #include "qgsmaptopixel.h" #include "qgsrubberband.h" @@ -29,9 +28,7 @@ CoordinateCaptureMapTool::CoordinateCaptureMapTool( QgsMapCanvas *thepCanvas ) : QgsMapTool( thepCanvas ) { - // set cursor - QPixmap myCursor = QPixmap( ( const char ** ) capture_point_cursor ); - mCursor = QCursor( myCursor, 8, 8 ); //8,8 is the point in the cursor where clicks register + setCursor( QgsApplication::getThemeCursor( QgsApplication::Cursor::CrossHair ) ); mpMapCanvas = thepCanvas; mpRubberBand = new QgsRubberBand( mpMapCanvas, QgsWkbTypes::PolygonGeometry ); mpRubberBand->setColor( Qt::red ); diff --git a/src/plugins/evis/idtool/eviseventidtool.cpp b/src/plugins/evis/idtool/eviseventidtool.cpp index 9dd594c7453..0e652e434b2 100644 --- a/src/plugins/evis/idtool/eviseventidtool.cpp +++ b/src/plugins/evis/idtool/eviseventidtool.cpp @@ -26,7 +26,6 @@ **/ #include "eviseventidtool.h" -#include "qgscursors.h" #include "qgsmaptopixel.h" #include "qgsmaptool.h" #include "qgsvectorlayer.h" @@ -45,8 +44,7 @@ eVisEventIdTool::eVisEventIdTool( QgsMapCanvas *canvas ) : QgsMapTool( canvas ) { //set cursor - QPixmap myIdentifyQPixmap = QPixmap( ( const char ** ) identify_cursor ); - mCursor = QCursor( myIdentifyQPixmap, 1, 1 ); + setCursor( QgsApplication::getThemeCursor( QgsApplication::Cursor::Identify ) ); //set the current tool to this object if ( mCanvas )