mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-14 00:07:35 -04:00
[FEATURE] Allow the line symbol layers to be used for outline of polygon (fill) symbols
git-svn-id: http://svn.osgeo.org/qgis/trunk@14855 c8812cc2-4d05-0410-92ff-de0c093fc19c
This commit is contained in:
parent
8af3dd1273
commit
7e5d546f13
@ -565,6 +565,9 @@ class QgsLineSymbolLayerV2 : QgsSymbolLayerV2
|
||||
public:
|
||||
virtual void renderPolyline(const QPolygonF& points, QgsSymbolV2RenderContext& context) = 0;
|
||||
|
||||
//! @note added in v1.7
|
||||
virtual void renderPolygonOutline( const QPolygonF& points, QList<QPolygonF>* rings, QgsSymbolV2RenderContext& context );
|
||||
|
||||
void setWidth(double width);
|
||||
double width() const;
|
||||
|
||||
|
@ -45,6 +45,17 @@ void QgsLineSymbolLayerV2::drawPreviewIcon( QgsSymbolV2RenderContext& context, Q
|
||||
stopRender( context );
|
||||
}
|
||||
|
||||
void QgsLineSymbolLayerV2::renderPolygonOutline( const QPolygonF& points, QList<QPolygonF>* rings, QgsSymbolV2RenderContext& context )
|
||||
{
|
||||
renderPolyline( points, context );
|
||||
if ( rings )
|
||||
{
|
||||
foreach( const QPolygonF& ring, *rings )
|
||||
renderPolyline( ring, context );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void QgsFillSymbolLayerV2::drawPreviewIcon( QgsSymbolV2RenderContext& context, QSize size )
|
||||
{
|
||||
QPolygonF poly = QRectF( QPointF( 0, 0 ), QPointF( size.width() - 1, size.height() - 1 ) );
|
||||
|
@ -99,6 +99,9 @@ class CORE_EXPORT QgsLineSymbolLayerV2 : public QgsSymbolLayerV2
|
||||
public:
|
||||
virtual void renderPolyline( const QPolygonF& points, QgsSymbolV2RenderContext& context ) = 0;
|
||||
|
||||
//! @note added in v1.7
|
||||
virtual void renderPolygonOutline( const QPolygonF& points, QList<QPolygonF>* rings, QgsSymbolV2RenderContext& context );
|
||||
|
||||
virtual void setWidth( double width ) { mWidth = width; }
|
||||
virtual double width() const { return mWidth; }
|
||||
|
||||
|
@ -28,7 +28,7 @@ QgsSymbolV2::QgsSymbolV2( SymbolType type, QgsSymbolLayerV2List layers )
|
||||
{
|
||||
mLayers.removeAt( i-- );
|
||||
}
|
||||
else if ( mLayers[i]->type() != mType )
|
||||
else if ( !isSymbolLayerCompatible( mLayers[i]->type() ) )
|
||||
{
|
||||
delete mLayers[i];
|
||||
mLayers.removeAt( i-- );
|
||||
@ -69,12 +69,21 @@ QgsSymbolLayerV2* QgsSymbolV2::symbolLayer( int layer )
|
||||
}
|
||||
|
||||
|
||||
bool QgsSymbolV2::isSymbolLayerCompatible( SymbolType t )
|
||||
{
|
||||
// fill symbol can contain also line symbol layers for drawing of outlines
|
||||
if ( mType == Fill && t == Line )
|
||||
return true;
|
||||
|
||||
return mType == t;
|
||||
}
|
||||
|
||||
|
||||
bool QgsSymbolV2::insertSymbolLayer( int index, QgsSymbolLayerV2* layer )
|
||||
{
|
||||
if ( index < 0 || index > mLayers.count() ) // can be added also after the last index
|
||||
return false;
|
||||
if ( layer == NULL || layer->type() != mType )
|
||||
if ( layer == NULL || !isSymbolLayerCompatible( layer->type() ) )
|
||||
return false;
|
||||
|
||||
mLayers.insert( index, layer );
|
||||
@ -84,7 +93,7 @@ bool QgsSymbolV2::insertSymbolLayer( int index, QgsSymbolLayerV2* layer )
|
||||
|
||||
bool QgsSymbolV2::appendSymbolLayer( QgsSymbolLayerV2* layer )
|
||||
{
|
||||
if ( layer == NULL || layer->type() != mType )
|
||||
if ( layer == NULL || !isSymbolLayerCompatible( layer->type() ) )
|
||||
return false;
|
||||
|
||||
mLayers.append( layer );
|
||||
@ -116,7 +125,7 @@ bool QgsSymbolV2::changeSymbolLayer( int index, QgsSymbolLayerV2* layer )
|
||||
{
|
||||
if ( index < 0 || index >= mLayers.count() )
|
||||
return false;
|
||||
if ( layer == NULL || layer->type() != mType )
|
||||
if ( layer == NULL || !isSymbolLayerCompatible( layer->type() ) )
|
||||
return false;
|
||||
|
||||
delete mLayers[index]; // first delete the original layer
|
||||
@ -165,7 +174,20 @@ void QgsSymbolV2::drawPreviewIcon( QPainter* painter, QSize size )
|
||||
QgsSymbolV2RenderContext symbolContext( context, mOutputUnit, mAlpha, false, mRenderHints );
|
||||
for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
|
||||
{
|
||||
( *it )->drawPreviewIcon( symbolContext, size );
|
||||
if ( mType == Fill && ( *it )->type() == Line )
|
||||
{
|
||||
// line symbol layer would normally draw just a line
|
||||
// so we override this case to force it to draw a polygon outline
|
||||
QgsLineSymbolLayerV2* lsl = ( QgsLineSymbolLayerV2* ) * it;
|
||||
|
||||
// from QgsFillSymbolLayerV2::drawPreviewIcon()
|
||||
QPolygonF poly = QRectF( QPointF( 0, 0 ), QPointF( size.width() - 1, size.height() - 1 ) );
|
||||
lsl->startRender( symbolContext );
|
||||
lsl->renderPolygonOutline( poly, NULL, symbolContext );
|
||||
lsl->stopRender( symbolContext );
|
||||
}
|
||||
else
|
||||
( *it )->drawPreviewIcon( symbolContext, size );
|
||||
}
|
||||
}
|
||||
|
||||
@ -456,14 +478,29 @@ void QgsFillSymbolV2::renderPolygon( const QPolygonF& points, QList<QPolygonF>*
|
||||
if ( layer != -1 )
|
||||
{
|
||||
if ( layer >= 0 && layer < mLayers.count() )
|
||||
(( QgsFillSymbolLayerV2* ) mLayers[layer] )->renderPolygon( points, rings, symbolContext );
|
||||
{
|
||||
QgsSymbolV2::SymbolType layertype = mLayers.at( layer )->type();
|
||||
if ( layertype == QgsSymbolV2::Fill )
|
||||
(( QgsFillSymbolLayerV2* ) mLayers[layer] )->renderPolygon( points, rings, symbolContext );
|
||||
else if ( layertype == QgsSymbolV2::Line )
|
||||
(( QgsLineSymbolLayerV2* ) mLayers[layer] )->renderPolygonOutline( points, rings, symbolContext );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
|
||||
{
|
||||
QgsFillSymbolLayerV2* layer = ( QgsFillSymbolLayerV2* ) * it;
|
||||
layer->renderPolygon( points, rings, symbolContext );
|
||||
QgsSymbolV2::SymbolType layertype = ( *it )->type();
|
||||
if ( layertype == QgsSymbolV2::Fill )
|
||||
{
|
||||
QgsFillSymbolLayerV2* layer = ( QgsFillSymbolLayerV2* ) * it;
|
||||
layer->renderPolygon( points, rings, symbolContext );
|
||||
}
|
||||
else if ( layertype == QgsSymbolV2::Line )
|
||||
{
|
||||
QgsLineSymbolLayerV2* layer = ( QgsLineSymbolLayerV2* ) * it;
|
||||
layer->renderPolygonOutline( points, rings, symbolContext );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -101,6 +101,11 @@ class CORE_EXPORT QgsSymbolV2
|
||||
|
||||
QgsSymbolLayerV2List cloneLayers() const;
|
||||
|
||||
//! check whether a symbol layer type can be used within the symbol
|
||||
//! (marker-marker, line-line, fill-fill/line)
|
||||
//! @note added in 1.7
|
||||
bool isSymbolLayerCompatible( SymbolType t );
|
||||
|
||||
SymbolType mType;
|
||||
QgsSymbolLayerV2List mLayers;
|
||||
|
||||
|
@ -164,6 +164,17 @@ void QgsSymbolV2PropertiesDialog::populateLayerTypes()
|
||||
cboLayerType->clear();
|
||||
for ( int i = 0; i < types.count(); i++ )
|
||||
cboLayerType->addItem( QgsSymbolLayerV2Registry::instance()->symbolLayerMetadata( types[i] )->visibleName(), types[i] );
|
||||
|
||||
if ( mSymbol->type() == QgsSymbolV2::Fill )
|
||||
{
|
||||
QStringList typesLine = QgsSymbolLayerV2Registry::instance()->symbolLayersForType( QgsSymbolV2::Line );
|
||||
for ( int i = 0; i < typesLine.count(); i++ )
|
||||
{
|
||||
QString visibleName = QgsSymbolLayerV2Registry::instance()->symbolLayerMetadata( typesLine[i] )->visibleName();
|
||||
QString name = QString( tr( "Outline: %1" ) ).arg( visibleName );
|
||||
cboLayerType->addItem( name, typesLine[i] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -223,6 +234,10 @@ void QgsSymbolV2PropertiesDialog::loadPropertyWidgets()
|
||||
|
||||
QStringList layerTypes = pReg->symbolLayersForType( mSymbol->type() );
|
||||
|
||||
// also load line symbol layers for fill symbols
|
||||
if ( mSymbol->type() == QgsSymbolV2::Fill )
|
||||
layerTypes += pReg->symbolLayersForType( QgsSymbolV2::Line );
|
||||
|
||||
for ( int i = 0; i < layerTypes.count(); i++ )
|
||||
{
|
||||
QString layerType = layerTypes[i];
|
||||
|
Loading…
x
Reference in New Issue
Block a user