From 8ac762e5e191df19b2155f13830953abaeac34a8 Mon Sep 17 00:00:00 2001 From: Mathieu Pellerin Date: Mon, 4 Feb 2019 16:43:04 +0700 Subject: [PATCH] [ui] Fix tiny vertex marker on hidpi --- .../core/auto_generated/qgsvectorlayer.sip.in | 4 +++- .../symbology/qgsrenderer.sip.in | 2 +- .../auto_generated/symbology/qgssymbol.sip.in | 4 ++-- .../symbology/qgssymbollayerutils.sip.in | 14 +++++++++++++ src/app/qgsoptions.cpp | 4 ++-- src/core/qgsvectorlayer.h | 7 +++++-- src/core/qgsvectorlayerrenderer.cpp | 9 ++++---- src/core/qgsvectorlayerrenderer.h | 3 ++- src/core/symbology/qgsrenderer.cpp | 11 +++++----- src/core/symbology/qgsrenderer.h | 4 ++-- src/core/symbology/qgssymbol.cpp | 7 ++++--- src/core/symbology/qgssymbol.h | 4 ++-- src/core/symbology/qgssymbollayerutils.cpp | 21 +++++++++++++++++++ src/core/symbology/qgssymbollayerutils.h | 14 +++++++++++++ src/ui/qgsoptionsbase.ui | 8 +++---- 15 files changed, 87 insertions(+), 29 deletions(-) diff --git a/python/core/auto_generated/qgsvectorlayer.sip.in b/python/core/auto_generated/qgsvectorlayer.sip.in index ffbb33d2e75..bc3b7e6742a 100644 --- a/python/core/auto_generated/qgsvectorlayer.sip.in +++ b/python/core/auto_generated/qgsvectorlayer.sip.in @@ -1842,9 +1842,11 @@ Destroy active command and reverts all changes in it NoMarker }; - static void drawVertexMarker( double x, double y, QPainter &p, QgsVectorLayer::VertexMarkerType type, int vertexSize ); + static void drawVertexMarker( double x, double y, QPainter &p, QgsVectorLayer::VertexMarkerType type, int vertexSize ); %Docstring Draws a vertex symbol at (screen) coordinates x, y. (Useful to assist vertex editing.) + +.. deprecated:: Use the equivalent QgsSymbolLayerUtils.drawVertexMarker function instead %End void updateFields(); diff --git a/python/core/auto_generated/symbology/qgsrenderer.sip.in b/python/core/auto_generated/symbology/qgsrenderer.sip.in index 8a275722eb2..05a6bddaf25 100644 --- a/python/core/auto_generated/symbology/qgsrenderer.sip.in +++ b/python/core/auto_generated/symbology/qgsrenderer.sip.in @@ -315,7 +315,7 @@ If supported by the renderer, return classification attribute for the use in leg .. versionadded:: 2.6 %End - void setVertexMarkerAppearance( int type, int size ); + void setVertexMarkerAppearance( int type, double size ); %Docstring Sets type and size of editing vertex markers for subsequent rendering %End diff --git a/python/core/auto_generated/symbology/qgssymbol.sip.in b/python/core/auto_generated/symbology/qgssymbol.sip.in index fdd9a17be10..b07810e4ee1 100644 --- a/python/core/auto_generated/symbology/qgssymbol.sip.in +++ b/python/core/auto_generated/symbology/qgssymbol.sip.in @@ -428,7 +428,7 @@ Returns whether the symbol utilizes any data defined properties. .. deprecated:: Will be removed in QGIS 4.0 %End - void renderFeature( const QgsFeature &feature, QgsRenderContext &context, int layer = -1, bool selected = false, bool drawVertexMarker = false, int currentVertexMarkerType = 0, int currentVertexMarkerSize = 0 ); + void renderFeature( const QgsFeature &feature, QgsRenderContext &context, int layer = -1, bool selected = false, bool drawVertexMarker = false, int currentVertexMarkerType = 0, double currentVertexMarkerSize = 0.0 ); %Docstring Render a feature. Before calling this the startRender() method should be called to initialize the rendering process. After rendering all features stopRender() must be called. @@ -487,7 +487,7 @@ This is required for layers that generate their own geometry from other information in the rendering context. %End - void renderVertexMarker( QPointF pt, QgsRenderContext &context, int currentVertexMarkerType, int currentVertexMarkerSize ); + void renderVertexMarker( QPointF pt, QgsRenderContext &context, int currentVertexMarkerType, double currentVertexMarkerSize ); %Docstring Render editing vertex marker at specified point diff --git a/python/core/auto_generated/symbology/qgssymbollayerutils.sip.in b/python/core/auto_generated/symbology/qgssymbollayerutils.sip.in index da9df994d2c..16ec8223ac2 100644 --- a/python/core/auto_generated/symbology/qgssymbollayerutils.sip.in +++ b/python/core/auto_generated/symbology/qgssymbollayerutils.sip.in @@ -22,6 +22,13 @@ class QgsSymbolLayerUtils %End public: + enum VertexMarkerType + { + SemiTransparentCircle, + Cross, + NoMarker + }; + static QString encodeColor( const QColor &color ); static QColor decodeColor( const QString &str ); @@ -240,6 +247,13 @@ Returns a pixmap preview for a color ramp. static void drawStippledBackground( QPainter *painter, QRect rect ); + static void drawVertexMarker( double x, double y, QPainter &p, QgsSymbolLayerUtils::VertexMarkerType type, int markerSize ); +%Docstring +Draws a vertex symbol at (painter) coordinates x, y. (Useful to assist vertex editing.) + +.. versionadded:: 3.4.5 +%End + static double estimateMaxSymbolBleed( QgsSymbol *symbol, const QgsRenderContext &context ); %Docstring Returns the maximum estimated bleed for the symbol diff --git a/src/app/qgsoptions.cpp b/src/app/qgsoptions.cpp index 82f4e76543b..8aeb97b7d1d 100644 --- a/src/app/qgsoptions.cpp +++ b/src/app/qgsoptions.cpp @@ -1035,7 +1035,7 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WindowFlags fl, const QListsetCurrentIndex( mMarkerStyleComboBox->findText( tr( "None" ) ) ); } - mMarkerSizeSpinBox->setValue( mSettings->value( QStringLiteral( "/qgis/digitizing/marker_size" ), 3 ).toInt() ); + mMarkerSizeSpinBox->setValue( mSettings->value( QStringLiteral( "/qgis/digitizing/marker_size_mm" ), 2.0 ).toDouble() ); chkReuseLastValues->setChecked( mSettings->value( QStringLiteral( "/qgis/digitizing/reuseLastValues" ), false ).toBool() ); chkDisableAttributeValuesDlg->setChecked( mSettings->value( QStringLiteral( "/qgis/digitizing/disable_enter_attribute_values_dialog" ), false ).toBool() ); @@ -1622,7 +1622,7 @@ void QgsOptions::saveOptions() { mSettings->setValue( QStringLiteral( "/qgis/digitizing/marker_style" ), "None" ); } - mSettings->setValue( QStringLiteral( "/qgis/digitizing/marker_size" ), ( mMarkerSizeSpinBox->value() ) ); + mSettings->setValue( QStringLiteral( "/qgis/digitizing/marker_size_mm" ), ( mMarkerSizeSpinBox->value() ) ); mSettings->setValue( QStringLiteral( "/qgis/digitizing/reuseLastValues" ), chkReuseLastValues->isChecked() ); mSettings->setValue( QStringLiteral( "/qgis/digitizing/disable_enter_attribute_values_dialog" ), chkDisableAttributeValuesDlg->isChecked() ); diff --git a/src/core/qgsvectorlayer.h b/src/core/qgsvectorlayer.h index 78ecb374717..e1b0fae3749 100644 --- a/src/core/qgsvectorlayer.h +++ b/src/core/qgsvectorlayer.h @@ -1690,8 +1690,11 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte NoMarker }; - //! Draws a vertex symbol at (screen) coordinates x, y. (Useful to assist vertex editing.) - static void drawVertexMarker( double x, double y, QPainter &p, QgsVectorLayer::VertexMarkerType type, int vertexSize ); + /** + * Draws a vertex symbol at (screen) coordinates x, y. (Useful to assist vertex editing.) + * \deprecated Use the equivalent QgsSymbolLayerUtils::drawVertexMarker function instead + */ + Q_DECL_DEPRECATED static void drawVertexMarker( double x, double y, QPainter &p, QgsVectorLayer::VertexMarkerType type, int vertexSize ); /** * Will regenerate the `fields` property of this layer by obtaining all fields diff --git a/src/core/qgsvectorlayerrenderer.cpp b/src/core/qgsvectorlayerrenderer.cpp index e6d83ad76cd..c38ba499087 100644 --- a/src/core/qgsvectorlayerrenderer.cpp +++ b/src/core/qgsvectorlayerrenderer.cpp @@ -24,6 +24,7 @@ #include "qgsrendercontext.h" #include "qgssinglesymbolrenderer.h" #include "qgssymbollayer.h" +#include "qgssymbollayerutils.h" #include "qgssymbol.h" #include "qgsvectorlayer.h" #include "qgsvectorlayerdiagramprovider.h" @@ -67,18 +68,18 @@ QgsVectorLayerRenderer::QgsVectorLayerRenderer( QgsVectorLayer *layer, QgsRender QString markerTypeString = settings.value( QStringLiteral( "qgis/digitizing/marker_style" ), "Cross" ).toString(); if ( markerTypeString == QLatin1String( "Cross" ) ) { - mVertexMarkerStyle = QgsVectorLayer::Cross; + mVertexMarkerStyle = QgsSymbolLayerUtils::Cross; } else if ( markerTypeString == QLatin1String( "SemiTransparentCircle" ) ) { - mVertexMarkerStyle = QgsVectorLayer::SemiTransparentCircle; + mVertexMarkerStyle = QgsSymbolLayerUtils::SemiTransparentCircle; } else { - mVertexMarkerStyle = QgsVectorLayer::NoMarker; + mVertexMarkerStyle = QgsSymbolLayerUtils::NoMarker; } - mVertexMarkerSize = settings.value( QStringLiteral( "qgis/digitizing/marker_size" ), 3 ).toInt(); + mVertexMarkerSize = settings.value( QStringLiteral( "qgis/digitizing/marker_size_mm" ), 2.0 ).toDouble(); if ( !mRenderer ) return; diff --git a/src/core/qgsvectorlayerrenderer.h b/src/core/qgsvectorlayerrenderer.h index c94f1005998..a782090118d 100644 --- a/src/core/qgsvectorlayerrenderer.h +++ b/src/core/qgsvectorlayerrenderer.h @@ -123,7 +123,8 @@ class QgsVectorLayerRenderer : public QgsMapLayerRenderer bool mDrawVertexMarkers; bool mVertexMarkerOnlyForSelection; - int mVertexMarkerStyle, mVertexMarkerSize; + int mVertexMarkerStyle = 0; + double mVertexMarkerSize = 2.0; QgsWkbTypes::GeometryType mGeometryType; diff --git a/src/core/symbology/qgsrenderer.cpp b/src/core/symbology/qgsrenderer.cpp index 63fa24318bb..67ece3d70cb 100644 --- a/src/core/symbology/qgsrenderer.cpp +++ b/src/core/symbology/qgsrenderer.cpp @@ -60,7 +60,7 @@ QgsFeatureRenderer::QgsFeatureRenderer( const QString &type ) : mType( type ) , mUsingSymbolLevels( false ) , mCurrentVertexMarkerType( QgsVectorLayer::Cross ) - , mCurrentVertexMarkerSize( 3 ) + , mCurrentVertexMarkerSize( 2 ) , mForceRaster( false ) , mOrderByEnabled( false ) { @@ -337,7 +337,7 @@ QgsLegendSymbolList QgsFeatureRenderer::legendSymbolItems() const return QgsLegendSymbolList(); } -void QgsFeatureRenderer::setVertexMarkerAppearance( int type, int size ) +void QgsFeatureRenderer::setVertexMarkerAppearance( int type, double size ) { mCurrentVertexMarkerType = type; mCurrentVertexMarkerSize = size; @@ -350,9 +350,10 @@ bool QgsFeatureRenderer::willRenderFeature( const QgsFeature &feature, QgsRender void QgsFeatureRenderer::renderVertexMarker( QPointF pt, QgsRenderContext &context ) { - QgsVectorLayer::drawVertexMarker( pt.x(), pt.y(), *context.painter(), - static_cast< QgsVectorLayer::VertexMarkerType >( mCurrentVertexMarkerType ), - mCurrentVertexMarkerSize ); + int markerSize = context.convertToPainterUnits( mCurrentVertexMarkerSize, QgsUnitTypes::RenderMillimeters ); + QgsSymbolLayerUtils::drawVertexMarker( pt.x(), pt.y(), *context.painter(), + static_cast< QgsSymbolLayerUtils::VertexMarkerType >( mCurrentVertexMarkerType ), + markerSize ); } void QgsFeatureRenderer::renderVertexMarkerPolyline( QPolygonF &pts, QgsRenderContext &context ) diff --git a/src/core/symbology/qgsrenderer.h b/src/core/symbology/qgsrenderer.h index c6048bef585..977e295a35c 100644 --- a/src/core/symbology/qgsrenderer.h +++ b/src/core/symbology/qgsrenderer.h @@ -342,7 +342,7 @@ class CORE_EXPORT QgsFeatureRenderer virtual QString legendClassificationAttribute() const { return QString(); } //! Sets type and size of editing vertex markers for subsequent rendering - void setVertexMarkerAppearance( int type, int size ); + void setVertexMarkerAppearance( int type, double size ); /** * Returns whether the renderer will render a feature or not. @@ -505,7 +505,7 @@ class CORE_EXPORT QgsFeatureRenderer //! The current type of editing marker int mCurrentVertexMarkerType; //! The current size of editing marker - int mCurrentVertexMarkerSize; + double mCurrentVertexMarkerSize; QgsPaintEffect *mPaintEffect = nullptr; diff --git a/src/core/symbology/qgssymbol.cpp b/src/core/symbology/qgssymbol.cpp index 93813fb13f5..1b9ef8e4463 100644 --- a/src/core/symbology/qgssymbol.cpp +++ b/src/core/symbology/qgssymbol.cpp @@ -740,7 +740,7 @@ class GeometryRestorer }; ///@endcond PRIVATE -void QgsSymbol::renderFeature( const QgsFeature &feature, QgsRenderContext &context, int layer, bool selected, bool drawVertexMarker, int currentVertexMarkerType, int currentVertexMarkerSize ) +void QgsSymbol::renderFeature( const QgsFeature &feature, QgsRenderContext &context, int layer, bool selected, bool drawVertexMarker, int currentVertexMarkerType, double currentVertexMarkerSize ) { const QgsGeometry geom = feature.geometry(); if ( geom.isNull() ) @@ -1062,9 +1062,10 @@ QgsSymbolRenderContext *QgsSymbol::symbolRenderContext() return mSymbolRenderContext.get(); } -void QgsSymbol::renderVertexMarker( QPointF pt, QgsRenderContext &context, int currentVertexMarkerType, int currentVertexMarkerSize ) +void QgsSymbol::renderVertexMarker( QPointF pt, QgsRenderContext &context, int currentVertexMarkerType, double currentVertexMarkerSize ) { - QgsVectorLayer::drawVertexMarker( pt.x(), pt.y(), *context.painter(), static_cast< QgsVectorLayer::VertexMarkerType >( currentVertexMarkerType ), currentVertexMarkerSize ); + int markerSize = context.convertToPainterUnits( currentVertexMarkerSize, QgsUnitTypes::RenderMillimeters ); + QgsSymbolLayerUtils::drawVertexMarker( pt.x(), pt.y(), *context.painter(), static_cast< QgsSymbolLayerUtils::VertexMarkerType >( currentVertexMarkerType ), markerSize ); } //////////////////// diff --git a/src/core/symbology/qgssymbol.h b/src/core/symbology/qgssymbol.h index 6187dd95fff..ba5adbca698 100644 --- a/src/core/symbology/qgssymbol.h +++ b/src/core/symbology/qgssymbol.h @@ -429,7 +429,7 @@ class CORE_EXPORT QgsSymbol * Render a feature. Before calling this the startRender() method should be called to initialize * the rendering process. After rendering all features stopRender() must be called. */ - void renderFeature( const QgsFeature &feature, QgsRenderContext &context, int layer = -1, bool selected = false, bool drawVertexMarker = false, int currentVertexMarkerType = 0, int currentVertexMarkerSize = 0 ); + void renderFeature( const QgsFeature &feature, QgsRenderContext &context, int layer = -1, bool selected = false, bool drawVertexMarker = false, int currentVertexMarkerType = 0, double currentVertexMarkerSize = 0.0 ); /** * Returns the symbol render context. Only valid between startRender and stopRender calls. @@ -506,7 +506,7 @@ class CORE_EXPORT QgsSymbol * Render editing vertex marker at specified point * \since QGIS 2.16 */ - void renderVertexMarker( QPointF pt, QgsRenderContext &context, int currentVertexMarkerType, int currentVertexMarkerSize ); + void renderVertexMarker( QPointF pt, QgsRenderContext &context, int currentVertexMarkerType, double currentVertexMarkerSize ); SymbolType mType; QgsSymbolLayerList mLayers; diff --git a/src/core/symbology/qgssymbollayerutils.cpp b/src/core/symbology/qgssymbollayerutils.cpp index eccdedb3198..49cff32e5bf 100644 --- a/src/core/symbology/qgssymbollayerutils.cpp +++ b/src/core/symbology/qgssymbollayerutils.cpp @@ -797,6 +797,27 @@ void QgsSymbolLayerUtils::drawStippledBackground( QPainter *painter, QRect rect painter->fillRect( rect, brush ); } +void QgsSymbolLayerUtils::drawVertexMarker( double x, double y, QPainter &p, QgsSymbolLayerUtils::VertexMarkerType type, int markerSize ) +{ + qreal s = ( markerSize - 1 ) / 2.0; + + switch ( type ) + { + case QgsSymbolLayerUtils::SemiTransparentCircle: + p.setPen( QColor( 50, 100, 120, 200 ) ); + p.setBrush( QColor( 200, 200, 210, 120 ) ); + p.drawEllipse( x - s, y - s, s * 2, s * 2 ); + break; + case QgsSymbolLayerUtils::Cross: + p.setPen( QColor( 255, 0, 0 ) ); + p.drawLine( x - s, y + s, x + s, y - s ); + p.drawLine( x - s, y - s, x + s, y + s ); + break; + case QgsSymbolLayerUtils::NoMarker: + break; + } +} + #include #include diff --git a/src/core/symbology/qgssymbollayerutils.h b/src/core/symbology/qgssymbollayerutils.h index f349212a29b..05edb44135d 100644 --- a/src/core/symbology/qgssymbollayerutils.h +++ b/src/core/symbology/qgssymbollayerutils.h @@ -55,6 +55,14 @@ class CORE_EXPORT QgsSymbolLayerUtils { public: + //! Editing vertex markers + enum VertexMarkerType + { + SemiTransparentCircle, + Cross, + NoMarker + }; + static QString encodeColor( const QColor &color ); static QColor decodeColor( const QString &str ); @@ -234,6 +242,12 @@ class CORE_EXPORT QgsSymbolLayerUtils static void drawStippledBackground( QPainter *painter, QRect rect ); + /** + * Draws a vertex symbol at (painter) coordinates x, y. (Useful to assist vertex editing.) + * \since QGIS 3.4.5 + */ + static void drawVertexMarker( double x, double y, QPainter &p, QgsSymbolLayerUtils::VertexMarkerType type, int markerSize ); + //! Returns the maximum estimated bleed for the symbol static double estimateMaxSymbolBleed( QgsSymbol *symbol, const QgsRenderContext &context ); diff --git a/src/ui/qgsoptionsbase.ui b/src/ui/qgsoptionsbase.ui index 87a1f959a60..ef4dfbb94c2 100644 --- a/src/ui/qgsoptionsbase.ui +++ b/src/ui/qgsoptionsbase.ui @@ -4259,22 +4259,22 @@ The bigger the number, the faster zooming with the mouse wheel will be. - + Qt::LeftToRight - 3 + 0.4 - 1 + 0.2 - Marker size + Marker size (in millimeter)