mirror of
https://github.com/qgis/QGIS.git
synced 2025-10-15 00:02:52 -04:00
Move default legend patch shape handling to QgsStyle
This commit is contained in:
parent
e5be0de36a
commit
ae8e5cfeaa
@ -116,11 +116,6 @@ The default behavior is to respect the geometry()'s aspect ratio.
|
||||
Converts the patch shape to a set of QPolygonF objects representing
|
||||
how the patch should be drawn for a symbol of the given ``type`` at the specified ``size`` (as
|
||||
geometry parts and rings).
|
||||
%End
|
||||
|
||||
static QList< QList< QPolygonF > > defaultPatch( QgsSymbol::SymbolType type, QSizeF size );
|
||||
%Docstring
|
||||
Returns the default patch geometry for the given symbol ``type`` and ``size`` as a set of QPolygonF objects (parts and rings).
|
||||
%End
|
||||
|
||||
void readXml( const QDomElement &element, const QgsReadWriteContext &context );
|
||||
|
@ -552,6 +552,24 @@ Removes label settings from the style.
|
||||
Changes a label setting's name.
|
||||
|
||||
.. versionadded:: 3.10
|
||||
%End
|
||||
|
||||
QgsLegendPatchShape defaultPatch( QgsSymbol::SymbolType type, QSizeF size ) const;
|
||||
%Docstring
|
||||
Returns the default legend patch shape for the given symbol ``type``.
|
||||
|
||||
.. seealso:: :py:func:`defaultPatchAsQPolygonF`
|
||||
|
||||
.. versionadded:: 3.14
|
||||
%End
|
||||
|
||||
QList< QList< QPolygonF > > defaultPatchAsQPolygonF( QgsSymbol::SymbolType type, QSizeF size ) const;
|
||||
%Docstring
|
||||
Returns the default patch geometry for the given symbol ``type`` and ``size`` as a set of QPolygonF objects (parts and rings).
|
||||
|
||||
.. seealso:: :py:func:`defaultPatch`
|
||||
|
||||
.. versionadded:: 3.14
|
||||
%End
|
||||
|
||||
bool createDatabase( const QString &filename );
|
||||
|
@ -19,6 +19,7 @@ email : nyall dot dawson at gmail dot com
|
||||
#include "qgsmultilinestring.h"
|
||||
#include "qgslinestring.h"
|
||||
#include "qgspolygon.h"
|
||||
#include "qgsstyle.h"
|
||||
|
||||
QgsLegendPatchShape::QgsLegendPatchShape( QgsSymbol::SymbolType type, const QgsGeometry &geometry, bool preserveAspectRatio )
|
||||
: mSymbolType( type )
|
||||
@ -83,7 +84,7 @@ QPolygonF curveToPolygonF( const QgsCurve *curve )
|
||||
QList<QList<QPolygonF> > QgsLegendPatchShape::toQPolygonF( QgsSymbol::SymbolType type, QSizeF size ) const
|
||||
{
|
||||
if ( isNull() || type != mSymbolType )
|
||||
return defaultPatch( type, size );
|
||||
return QgsStyle::defaultStyle()->defaultPatchAsQPolygonF( type, size );
|
||||
|
||||
// scale and translate to desired size
|
||||
|
||||
@ -128,7 +129,7 @@ QList<QList<QPolygonF> > QgsLegendPatchShape::toQPolygonF( QgsSymbol::SymbolType
|
||||
}
|
||||
else
|
||||
{
|
||||
points << QPointF( size.width() / 2, size.height() / 2 );
|
||||
points << QPointF( static_cast< int >( size.width() ) / 2, static_cast< int >( size.height() ) / 2 );
|
||||
}
|
||||
return QList< QList<QPolygonF> >() << ( QList< QPolygonF >() << points );
|
||||
}
|
||||
@ -176,29 +177,6 @@ QList<QList<QPolygonF> > QgsLegendPatchShape::toQPolygonF( QgsSymbol::SymbolType
|
||||
return QList< QList<QPolygonF> >();
|
||||
}
|
||||
|
||||
QList<QList<QPolygonF> > QgsLegendPatchShape::defaultPatch( QgsSymbol::SymbolType type, QSizeF size )
|
||||
{
|
||||
switch ( type )
|
||||
{
|
||||
case QgsSymbol::Marker:
|
||||
return QList< QList< QPolygonF > >() << ( QList< QPolygonF >() << ( QPolygonF() << QPointF( static_cast< int >( size.width() ) / 2,
|
||||
static_cast< int >( size.height() ) / 2 ) ) );
|
||||
|
||||
case QgsSymbol::Line:
|
||||
// we're adding 0.5 to get rid of blurred preview:
|
||||
// drawing antialiased lines of width 1 at (x,0)-(x,100) creates 2px line
|
||||
return QList< QList<QPolygonF> >() << ( QList< QPolygonF >() << ( QPolygonF() << QPointF( 0, static_cast< int >( size.height() ) / 2 + 0.5 ) << QPointF( size.width(), static_cast< int >( size.height() ) / 2 + 0.5 ) ) );
|
||||
|
||||
case QgsSymbol::Fill:
|
||||
return QList< QList<QPolygonF> >() << ( QList< QPolygonF> () << ( QRectF( QPointF( 0, 0 ), QPointF( static_cast< int >( size.width() ), static_cast< int >( size.height() ) ) ) ) );
|
||||
|
||||
case QgsSymbol::Hybrid:
|
||||
return QList< QList<QPolygonF> >();
|
||||
}
|
||||
|
||||
return QList< QList<QPolygonF> >();
|
||||
}
|
||||
|
||||
void QgsLegendPatchShape::readXml( const QDomElement &element, const QgsReadWriteContext & )
|
||||
{
|
||||
mGeometry = QgsGeometry::fromWkt( element.attribute( QStringLiteral( "wkt" ) ) );
|
||||
|
@ -126,11 +126,6 @@ class CORE_EXPORT QgsLegendPatchShape
|
||||
*/
|
||||
QList< QList< QPolygonF > > toQPolygonF( QgsSymbol::SymbolType type, QSizeF size ) const;
|
||||
|
||||
/**
|
||||
* Returns the default patch geometry for the given symbol \a type and \a size as a set of QPolygonF objects (parts and rings).
|
||||
*/
|
||||
static QList< QList< QPolygonF > > defaultPatch( QgsSymbol::SymbolType type, QSizeF size );
|
||||
|
||||
/**
|
||||
* Read settings from a DOM \a element.
|
||||
* \see writeXml()
|
||||
|
@ -22,6 +22,9 @@
|
||||
#include "qgslogger.h"
|
||||
#include "qgsreadwritecontext.h"
|
||||
#include "qgssettings.h"
|
||||
#include "qgslegendpatchshape.h"
|
||||
#include "qgslinestring.h"
|
||||
#include "qgspolygon.h"
|
||||
|
||||
#include <QDomDocument>
|
||||
#include <QDomElement>
|
||||
@ -921,6 +924,61 @@ bool QgsStyle::renameLabelSettings( const QString &oldName, const QString &newNa
|
||||
return result;
|
||||
}
|
||||
|
||||
QgsLegendPatchShape QgsStyle::defaultPatch( QgsSymbol::SymbolType type, QSizeF size ) const
|
||||
{
|
||||
if ( type == QgsSymbol::Hybrid )
|
||||
return QgsLegendPatchShape();
|
||||
|
||||
if ( mDefaultPatchCache[ type ].contains( size ) )
|
||||
return mDefaultPatchCache[ type ].value( size );
|
||||
|
||||
QgsGeometry geom;
|
||||
switch ( type )
|
||||
{
|
||||
case QgsSymbol::Marker:
|
||||
geom = QgsGeometry( qgis::make_unique< QgsPoint >( static_cast< int >( size.width() ) / 2, static_cast< int >( size.height() ) / 2 ) );
|
||||
break;
|
||||
|
||||
case QgsSymbol::Line:
|
||||
{
|
||||
// we're adding 0.5 to get rid of blurred preview:
|
||||
// drawing antialiased lines of width 1 at (x,0)-(x,100) creates 2px line
|
||||
double y = static_cast< int >( size.height() ) / 2 + 0.5;
|
||||
geom = QgsGeometry( qgis::make_unique< QgsLineString >( ( QVector< double >() << 0 << size.width() ),
|
||||
( QVector< double >() << y << y ) ) );
|
||||
break;
|
||||
}
|
||||
|
||||
case QgsSymbol::Fill:
|
||||
{
|
||||
geom = QgsGeometry( qgis::make_unique< QgsPolygon >(
|
||||
new QgsLineString( QVector< double >() << 0 << static_cast< int >( size.width() ) << static_cast< int >( size.width() ) << 0 << 0,
|
||||
QVector< double >() << static_cast< int >( size.height() ) << static_cast< int >( size.height() ) << 0 << 0 << static_cast< int >( size.height() ) ) ) );
|
||||
break;
|
||||
}
|
||||
|
||||
case QgsSymbol::Hybrid:
|
||||
break;
|
||||
}
|
||||
|
||||
QgsLegendPatchShape res = QgsLegendPatchShape( type, geom, true );
|
||||
mDefaultPatchCache[ type ][size ] = res;
|
||||
return res;
|
||||
}
|
||||
|
||||
QList<QList<QPolygonF> > QgsStyle::defaultPatchAsQPolygonF( QgsSymbol::SymbolType type, QSizeF size ) const
|
||||
{
|
||||
if ( type == QgsSymbol::Hybrid )
|
||||
return QList<QList<QPolygonF> >();
|
||||
|
||||
if ( mDefaultPatchQPolygonFCache[ type ].contains( size ) )
|
||||
return mDefaultPatchQPolygonFCache[ type ].value( size );
|
||||
|
||||
QList<QList<QPolygonF> > res = defaultPatch( type, size ).toQPolygonF( type, size );
|
||||
mDefaultPatchQPolygonFCache[ type ][size ] = res;
|
||||
return res;
|
||||
}
|
||||
|
||||
QStringList QgsStyle::symbolsOfFavorite( StyleEntity type ) const
|
||||
{
|
||||
if ( !mCurrentDB )
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "qgssymbollayerutils.h" // QgsStringMap
|
||||
#include "qgstextrenderer.h"
|
||||
#include "qgspallabeling.h"
|
||||
#include "layertree/qgslegendpatchshape.h"
|
||||
|
||||
class QgsSymbol;
|
||||
class QgsSymbolLayer;
|
||||
@ -584,6 +585,22 @@ class CORE_EXPORT QgsStyle : public QObject
|
||||
*/
|
||||
bool renameLabelSettings( const QString &oldName, const QString &newName );
|
||||
|
||||
/**
|
||||
* Returns the default legend patch shape for the given symbol \a type.
|
||||
*
|
||||
* \see defaultPatchAsQPolygonF()
|
||||
* \since QGIS 3.14
|
||||
*/
|
||||
QgsLegendPatchShape defaultPatch( QgsSymbol::SymbolType type, QSizeF size ) const;
|
||||
|
||||
/**
|
||||
* Returns the default patch geometry for the given symbol \a type and \a size as a set of QPolygonF objects (parts and rings).
|
||||
*
|
||||
* \see defaultPatch()
|
||||
* \since QGIS 3.14
|
||||
*/
|
||||
QList< QList< QPolygonF > > defaultPatchAsQPolygonF( QgsSymbol::SymbolType type, QSizeF size ) const;
|
||||
|
||||
/**
|
||||
* Creates an on-disk database
|
||||
*
|
||||
@ -911,6 +928,9 @@ class CORE_EXPORT QgsStyle : public QObject
|
||||
|
||||
sqlite3_database_unique_ptr mCurrentDB;
|
||||
|
||||
mutable QHash< QgsSymbol::SymbolType, QHash< QSizeF, QgsLegendPatchShape > > mDefaultPatchCache;
|
||||
mutable QHash< QgsSymbol::SymbolType, QHash< QSizeF, QList< QList< QPolygonF > > > > mDefaultPatchQPolygonFCache;
|
||||
|
||||
static QgsStyle *sDefaultStyle;
|
||||
|
||||
//! Convenience function to open the DB and return a sqlite3 object
|
||||
|
@ -549,7 +549,7 @@ void QgsSymbol::drawPreviewIcon( QPainter *painter, QSize size, QgsRenderContext
|
||||
const QSizeF targetSize = QSizeF( size.width() - 1, size.height() - 1 );
|
||||
|
||||
const QList< QList< QPolygonF > > polys = patchShape ? patchShape->toQPolygonF( QgsSymbol::Fill, targetSize )
|
||||
: QgsLegendPatchShape::defaultPatch( QgsSymbol::Fill, targetSize );
|
||||
: QgsStyle::defaultStyle()->defaultPatchAsQPolygonF( QgsSymbol::Fill, targetSize );
|
||||
|
||||
lsl->startRender( symbolContext );
|
||||
QgsPaintEffect *effect = lsl->paintEffect();
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "qgsapplication.h"
|
||||
#include "qgsmultipoint.h"
|
||||
#include "qgslegendpatchshape.h"
|
||||
#include "qgsstyle.h"
|
||||
|
||||
#include <QSize>
|
||||
#include <QPainter>
|
||||
@ -453,7 +454,7 @@ void QgsMarkerSymbolLayer::drawPreviewIcon( QgsSymbolRenderContext &context, QSi
|
||||
QgsPaintEffect *effect = paintEffect();
|
||||
|
||||
QPolygonF points = context.patchShape() ? context.patchShape()->toQPolygonF( QgsSymbol::Marker, size ).value( 0 ).value( 0 )
|
||||
: QgsLegendPatchShape::defaultPatch( QgsSymbol::Marker, size ).value( 0 ).value( 0 );
|
||||
: QgsStyle::defaultStyle()->defaultPatchAsQPolygonF( QgsSymbol::Marker, size ).value( 0 ).value( 0 );
|
||||
|
||||
std::unique_ptr< QgsEffectPainter > effectPainter;
|
||||
if ( effect && effect->enabled() )
|
||||
@ -640,7 +641,7 @@ QgsMapUnitScale QgsLineSymbolLayer::mapUnitScale() const
|
||||
void QgsLineSymbolLayer::drawPreviewIcon( QgsSymbolRenderContext &context, QSize size )
|
||||
{
|
||||
const QList< QList< QPolygonF > > points = context.patchShape() ? context.patchShape()->toQPolygonF( QgsSymbol::Line, size )
|
||||
: QgsLegendPatchShape::defaultPatch( QgsSymbol::Line, size );
|
||||
: QgsStyle::defaultStyle()->defaultPatchAsQPolygonF( QgsSymbol::Line, size );
|
||||
startRender( context );
|
||||
QgsPaintEffect *effect = paintEffect();
|
||||
|
||||
@ -700,7 +701,7 @@ double QgsLineSymbolLayer::dxfWidth( const QgsDxfExport &e, QgsSymbolRenderConte
|
||||
void QgsFillSymbolLayer::drawPreviewIcon( QgsSymbolRenderContext &context, QSize size )
|
||||
{
|
||||
const QList< QList< QPolygonF > > polys = context.patchShape() ? context.patchShape()->toQPolygonF( QgsSymbol::Fill, size )
|
||||
: QgsLegendPatchShape::defaultPatch( QgsSymbol::Fill, size );
|
||||
: QgsStyle::defaultStyle()->defaultPatchAsQPolygonF( QgsSymbol::Fill, size );
|
||||
|
||||
startRender( context );
|
||||
QgsPaintEffect *effect = paintEffect();
|
||||
|
@ -28,7 +28,8 @@ from qgis.core import (QgsLegendPatchShape,
|
||||
QgsMarkerSymbol,
|
||||
QgsRenderChecker,
|
||||
QgsReadWriteContext,
|
||||
QgsRenderContext
|
||||
QgsRenderContext,
|
||||
QgsStyle
|
||||
)
|
||||
from qgis.PyQt.QtXml import QDomDocument, QDomElement
|
||||
|
||||
@ -83,28 +84,28 @@ class TestQgsLegendPatchShape(unittest.TestCase):
|
||||
self.assertTrue(shape.isNull())
|
||||
|
||||
def testDefault(self):
|
||||
self.assertEqual(QgsLegendPatchShape.defaultPatch(QgsSymbol.Hybrid, QSizeF(1, 1)), [])
|
||||
self.assertEqual(QgsLegendPatchShape.defaultPatch(QgsSymbol.Hybrid, QSizeF(10, 10)), [])
|
||||
self.assertEqual(QgsStyle.defaultStyle().defaultPatchAsQPolygonF(QgsSymbol.Hybrid, QSizeF(1, 1)), [])
|
||||
self.assertEqual(QgsStyle.defaultStyle().defaultPatchAsQPolygonF(QgsSymbol.Hybrid, QSizeF(10, 10)), [])
|
||||
|
||||
# markers
|
||||
self.assertEqual(self.polys_to_list(QgsLegendPatchShape.defaultPatch(QgsSymbol.Marker, QSizeF(1, 1))), [[[[0.0, 0.0]]]])
|
||||
self.assertEqual(self.polys_to_list(QgsLegendPatchShape.defaultPatch(QgsSymbol.Marker, QSizeF(2, 2))),
|
||||
self.assertEqual(self.polys_to_list(QgsStyle.defaultStyle().defaultPatchAsQPolygonF(QgsSymbol.Marker, QSizeF(1, 1))), [[[[0.0, 0.0]]]])
|
||||
self.assertEqual(self.polys_to_list(QgsStyle.defaultStyle().defaultPatchAsQPolygonF(QgsSymbol.Marker, QSizeF(2, 2))),
|
||||
[[[[1.0, 1.0]]]])
|
||||
self.assertEqual(self.polys_to_list(QgsLegendPatchShape.defaultPatch(QgsSymbol.Marker, QSizeF(10, 2))), [[[[5.0, 1.0]]]])
|
||||
self.assertEqual(self.polys_to_list(QgsStyle.defaultStyle().defaultPatchAsQPolygonF(QgsSymbol.Marker, QSizeF(10, 2))), [[[[5.0, 1.0]]]])
|
||||
|
||||
# lines
|
||||
self.assertEqual(self.polys_to_list(QgsLegendPatchShape.defaultPatch(QgsSymbol.Line, QSizeF(1, 1))), [[[[0.0, 0.5], [1.0, 0.5]]]])
|
||||
self.assertEqual(self.polys_to_list(QgsLegendPatchShape.defaultPatch(QgsSymbol.Line, QSizeF(10, 2))), [[[[0.0, 1.5], [10.0, 1.5]]]])
|
||||
self.assertEqual(self.polys_to_list(QgsLegendPatchShape.defaultPatch(QgsSymbol.Line, QSizeF(9, 3))), [[[[0.0, 1.5], [9.0, 1.5]]]])
|
||||
self.assertEqual(self.polys_to_list(QgsStyle.defaultStyle().defaultPatchAsQPolygonF(QgsSymbol.Line, QSizeF(1, 1))), [[[[0.0, 0.5], [1.0, 0.5]]]])
|
||||
self.assertEqual(self.polys_to_list(QgsStyle.defaultStyle().defaultPatchAsQPolygonF(QgsSymbol.Line, QSizeF(10, 2))), [[[[0.0, 1.5], [10.0, 1.5]]]])
|
||||
self.assertEqual(self.polys_to_list(QgsStyle.defaultStyle().defaultPatchAsQPolygonF(QgsSymbol.Line, QSizeF(9, 3))), [[[[0.0, 1.5], [9.0, 1.5]]]])
|
||||
|
||||
# fills
|
||||
self.assertEqual(self.polys_to_list(QgsLegendPatchShape.defaultPatch(QgsSymbol.Fill, QSizeF(1, 1))), [[[[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 1.0], [0.0, 0.0]]]])
|
||||
self.assertEqual(self.polys_to_list(QgsLegendPatchShape.defaultPatch(QgsSymbol.Fill, QSizeF(10, 2))), [[[[0.0, 0.0], [10.0, 0.0], [10.0, 2.0], [0.0, 2.0], [0.0, 0.0]]]])
|
||||
self.assertEqual(self.polys_to_list(QgsStyle.defaultStyle().defaultPatchAsQPolygonF(QgsSymbol.Fill, QSizeF(1, 1))), [[[[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 1.0], [0.0, 0.0]]]])
|
||||
self.assertEqual(self.polys_to_list(QgsStyle.defaultStyle().defaultPatchAsQPolygonF(QgsSymbol.Fill, QSizeF(10, 2))), [[[[0.0, 0.0], [10.0, 0.0], [10.0, 2.0], [0.0, 2.0], [0.0, 0.0]]]])
|
||||
|
||||
def testMarkers(self):
|
||||
# shouldn't matter what a point geometry is, it will always be rendered in center of symbol patch
|
||||
shape = QgsLegendPatchShape(QgsSymbol.Marker, QgsGeometry.fromWkt('Point( 5 5 )'), False)
|
||||
self.assertEqual(self.polys_to_list(shape.toQPolygonF(QgsSymbol.Marker, QSizeF(1, 1))), [[[[0.5, 0.5]]]])
|
||||
self.assertEqual(self.polys_to_list(shape.toQPolygonF(QgsSymbol.Marker, QSizeF(1, 1))), [[[[0, 0]]]])
|
||||
self.assertEqual(self.polys_to_list(shape.toQPolygonF(QgsSymbol.Marker, QSizeF(10, 2))), [[[[5.0, 1.0]]]])
|
||||
|
||||
# requesting different symbol type, should return default
|
||||
|
Loading…
x
Reference in New Issue
Block a user