mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-14 00:07:35 -04:00
[FEATURE] Data-defined size and rotation for single symbol renderer in symbology-ng. (ticket #2585)
Developed by for Faunalia (http://www.faunalia.it) with funding from Regione Toscana - Sistema Informativo per la Gestione del Territorio e dell' Ambiente [RT-SIGTA]". For the project: "Sviluppo di prodotti software GIS open-source basati sui prodotti QuantumGIS e Postgis (CIG 037728516E) git-svn-id: http://svn.osgeo.org/qgis/trunk@13389 c8812cc2-4d05-0410-92ff-de0c093fc19c
This commit is contained in:
parent
aa18abc3c6
commit
02df126b90
@ -133,6 +133,12 @@ public:
|
||||
QgsSymbolV2* symbol() const;
|
||||
void setSymbol(QgsSymbolV2* s /Transfer/);
|
||||
|
||||
void setRotationField(QString fieldName);
|
||||
QString rotationField() const;
|
||||
|
||||
void setSizeScaleField(QString fieldName);
|
||||
QString sizeScaleField() const;
|
||||
|
||||
virtual QString dump();
|
||||
|
||||
virtual QgsFeatureRendererV2* clone() /Factory/;
|
||||
@ -453,7 +459,7 @@ class QgsSymbolV2RenderContext
|
||||
%End
|
||||
|
||||
public:
|
||||
QgsSymbolV2RenderContext( QgsRenderContext& c, QgsSymbolV2::OutputUnit u , qreal alpha = 1.0, bool selected = false );
|
||||
QgsSymbolV2RenderContext( QgsRenderContext& c, QgsSymbolV2::OutputUnit u , qreal alpha = 1.0, bool selected = false, int renderHints = 0 );
|
||||
~QgsSymbolV2RenderContext();
|
||||
|
||||
QgsRenderContext& renderContext();
|
||||
@ -468,6 +474,11 @@ class QgsSymbolV2RenderContext
|
||||
bool selected() const;
|
||||
void setSelected( bool selected ) const;
|
||||
|
||||
int renderHints() const;
|
||||
void setRenderHints( int hints );
|
||||
|
||||
// Colour used for selections
|
||||
|
||||
static QColor selectionColor();
|
||||
|
||||
double outputLineWidth(double width) const;
|
||||
@ -510,6 +521,12 @@ public:
|
||||
Fill
|
||||
};
|
||||
|
||||
enum RenderHint
|
||||
{
|
||||
DataDefinedSizeScale = 1,
|
||||
DataDefinedRotation = 2
|
||||
};
|
||||
|
||||
virtual ~QgsSymbolV2();
|
||||
|
||||
//! return new default symbol for specified geometry type
|
||||
@ -556,6 +573,12 @@ public:
|
||||
OutputUnit outputUnit() const;
|
||||
void setOutputUnit( OutputUnit u );
|
||||
|
||||
qreal alpha() const;
|
||||
void setAlpha( qreal alpha );
|
||||
|
||||
int renderHints() const;
|
||||
void setRenderHints( int hints );
|
||||
|
||||
protected:
|
||||
QgsSymbolV2(SymbolType type, QgsSymbolLayerV2List layers /Transfer/); // can't be instantiated
|
||||
|
||||
|
@ -68,102 +68,72 @@ void QgsSimpleMarkerSymbolLayerV2::startRender( QgsSymbolV2RenderContext& contex
|
||||
mBrush = QBrush( mColor );
|
||||
mPen = QPen( mBorderColor );
|
||||
mPen.setWidthF( context.outputLineWidth( mPen.widthF() ) );
|
||||
|
||||
QColor selColor = context.selectionColor();
|
||||
mSelBrush = QBrush( selColor );
|
||||
mSelPen = QPen( selColor == mColor ? selColor : mBorderColor );
|
||||
mSelPen.setWidthF( mPen.widthF() );
|
||||
|
||||
mPolygon.clear();
|
||||
bool hasDataDefinedRotation = context.renderHints() & QgsSymbolV2::DataDefinedRotation;
|
||||
bool hasDataDefinedSize = context.renderHints() & QgsSymbolV2::DataDefinedSizeScale;
|
||||
|
||||
double scaledSize = context.outputPixelSize( mSize );
|
||||
double half = scaledSize / 2.0;
|
||||
// use either QPolygonF or QPainterPath for drawing
|
||||
// TODO: find out whether drawing directly doesn't bring overhead - if not, use it for all shapes
|
||||
if ( !prepareShape() ) // drawing as a polygon
|
||||
{
|
||||
if ( preparePath() ) // drawing as a painter path
|
||||
{
|
||||
// some markers can't be drawn as a polygon (circle, cross)
|
||||
// For these set the selected border color to the selected color
|
||||
|
||||
if ( mName == "rectangle" )
|
||||
{
|
||||
mPolygon = QPolygonF( QRectF( QPointF( -half, -half ), QPointF( half, half ) ) );
|
||||
if ( mName != "circle" )
|
||||
mSelPen.setColor( selColor );
|
||||
}
|
||||
else
|
||||
{
|
||||
QgsDebugMsg( "unknown symbol" );
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if ( mName == "diamond" )
|
||||
{
|
||||
mPolygon << QPointF( -half, 0 ) << QPointF( 0, half )
|
||||
<< QPointF( half, 0 ) << QPointF( 0, -half );
|
||||
}
|
||||
else if ( mName == "pentagon" )
|
||||
{
|
||||
mPolygon << QPointF( half * sin( DEG2RAD( 288.0 ) ), - half * cos( DEG2RAD( 288.0 ) ) )
|
||||
<< QPointF( half * sin( DEG2RAD( 216.0 ) ), - half * cos( DEG2RAD( 216.0 ) ) )
|
||||
<< QPointF( half * sin( DEG2RAD( 144.0 ) ), - half * cos( DEG2RAD( 144.0 ) ) )
|
||||
<< QPointF( half * sin( DEG2RAD( 72.0 ) ), - half * cos( DEG2RAD( 72.0 ) ) )
|
||||
<< QPointF( 0, - half );
|
||||
}
|
||||
else if ( mName == "triangle" )
|
||||
{
|
||||
mPolygon << QPointF( -half, half ) << QPointF( half, half ) << QPointF( 0, -half );
|
||||
}
|
||||
else if ( mName == "equilateral_triangle" )
|
||||
{
|
||||
mPolygon << QPointF( half * sin( DEG2RAD( 240.0 ) ), - half * cos( DEG2RAD( 240.0 ) ) )
|
||||
<< QPointF( half * sin( DEG2RAD( 120.0 ) ), - half * cos( DEG2RAD( 120.0 ) ) )
|
||||
<< QPointF( 0, -half );
|
||||
}
|
||||
else if ( mName == "star" )
|
||||
{
|
||||
double sixth = half / 6;
|
||||
|
||||
mPolygon << QPointF( 0, -half )
|
||||
<< QPointF( -sixth, -sixth )
|
||||
<< QPointF( -half, -sixth )
|
||||
<< QPointF( -sixth, 0 )
|
||||
<< QPointF( -half, half )
|
||||
<< QPointF( 0, + sixth )
|
||||
<< QPointF( half, half )
|
||||
<< QPointF( + sixth, 0 )
|
||||
<< QPointF( half, -sixth )
|
||||
<< QPointF( + sixth, -sixth );
|
||||
}
|
||||
else if ( mName == "regular_star" )
|
||||
{
|
||||
double r = half;
|
||||
double inner_r = r * cos( DEG2RAD( 72.0 ) ) / cos( DEG2RAD( 36.0 ) );
|
||||
QMatrix transform;
|
||||
|
||||
mPolygon << QPointF( inner_r * sin( DEG2RAD( 324.0 ) ), - inner_r * cos( DEG2RAD( 324.0 ) ) ) // 324
|
||||
<< QPointF( r * sin( DEG2RAD( 288.0 ) ) , - r * cos( DEG2RAD( 288 ) ) ) // 288
|
||||
<< QPointF( inner_r * sin( DEG2RAD( 252.0 ) ), - inner_r * cos( DEG2RAD( 252.0 ) ) ) // 252
|
||||
<< QPointF( r * sin( DEG2RAD( 216.0 ) ) , - r * cos( DEG2RAD( 216.0 ) ) ) // 216
|
||||
<< QPointF( 0, inner_r ) // 180
|
||||
<< QPointF( r * sin( DEG2RAD( 144.0 ) ) , - r * cos( DEG2RAD( 144.0 ) ) ) // 144
|
||||
<< QPointF( inner_r * sin( DEG2RAD( 108.0 ) ), - inner_r * cos( DEG2RAD( 108.0 ) ) ) // 108
|
||||
<< QPointF( r * sin( DEG2RAD( 72.0 ) ) , - r * cos( DEG2RAD( 72.0 ) ) ) // 72
|
||||
<< QPointF( inner_r * sin( DEG2RAD( 36.0 ) ), - inner_r * cos( DEG2RAD( 36.0 ) ) ) // 36
|
||||
<< QPointF( 0, -half ); // 0
|
||||
}
|
||||
else if ( mName == "arrow" )
|
||||
// scale the shape (if the size is not going to be modified)
|
||||
if ( !hasDataDefinedSize )
|
||||
{
|
||||
double eight = half / 4;
|
||||
double quarter = half / 2;
|
||||
double scaledSize = context.outputPixelSize( mSize );
|
||||
double half = scaledSize / 2.0;
|
||||
transform.scale( half, half );
|
||||
}
|
||||
|
||||
mPolygon << QPointF( 0, -half )
|
||||
<< QPointF( quarter, -quarter )
|
||||
<< QPointF( eight, -quarter )
|
||||
<< QPointF( eight, half )
|
||||
<< QPointF( -eight, half )
|
||||
<< QPointF( -eight, -quarter )
|
||||
<< QPointF( -quarter, -quarter );
|
||||
// rotate if the rotation is not going to be changed during the rendering
|
||||
if ( !hasDataDefinedRotation && mAngle != 0 )
|
||||
{
|
||||
transform.rotate( mAngle );
|
||||
}
|
||||
|
||||
if ( !mPolygon.isEmpty() )
|
||||
mPolygon = transform.map( mPolygon );
|
||||
else
|
||||
mPath = transform.map( mPath );
|
||||
|
||||
if ( !hasDataDefinedRotation && !hasDataDefinedSize )
|
||||
{
|
||||
// we can use the cached marker
|
||||
// TODO: use caching only when drawing to screen (not printer)
|
||||
prepareCache( context );
|
||||
}
|
||||
else
|
||||
{
|
||||
// some markers can't be drawn as a polygon (circle, cross)
|
||||
// For these set the selected border color to the selected color
|
||||
|
||||
if ( mName != "circle" ) mSelPen.setColor( selColor );
|
||||
mCache = QImage();
|
||||
mSelCache = QImage();
|
||||
}
|
||||
}
|
||||
|
||||
// rotate if needed
|
||||
if ( mAngle != 0 )
|
||||
mPolygon = QMatrix().rotate( mAngle ).map( mPolygon );
|
||||
|
||||
// cache the marker
|
||||
// TODO: use caching only when drawing to screen (not printer)
|
||||
// TODO: decide whether to use QImage or QPixmap - based on the render context
|
||||
void QgsSimpleMarkerSymbolLayerV2::prepareCache( QgsSymbolV2RenderContext& context )
|
||||
{
|
||||
double scaledSize = context.outputPixelSize( mSize );
|
||||
|
||||
// calculate necessary image size for the cache
|
||||
double pw = (( mPen.widthF() == 0 ? 1 : mPen.widthF() ) + 1 ) / 2 * 2; // make even (round up); handle cosmetic pen
|
||||
@ -185,6 +155,8 @@ void QgsSimpleMarkerSymbolLayerV2::startRender( QgsSymbolV2RenderContext& contex
|
||||
|
||||
// Construct the selected version of the Cache
|
||||
|
||||
QColor selColor = context.selectionColor();
|
||||
|
||||
mSelCache = QImage( QSize( imageSize, imageSize ), QImage::Format_ARGB32_Premultiplied );
|
||||
mSelCache.fill( 0 );
|
||||
|
||||
@ -224,6 +196,127 @@ void QgsSimpleMarkerSymbolLayerV2::stopRender( QgsSymbolV2RenderContext& context
|
||||
{
|
||||
}
|
||||
|
||||
bool QgsSimpleMarkerSymbolLayerV2::prepareShape()
|
||||
{
|
||||
mPolygon.clear();
|
||||
|
||||
if ( mName == "rectangle" )
|
||||
{
|
||||
mPolygon = QPolygonF( QRectF( QPointF( -1, -1 ), QPointF( 1, 1 ) ) );
|
||||
return true;
|
||||
}
|
||||
else if ( mName == "diamond" )
|
||||
{
|
||||
mPolygon << QPointF( -1, 0 ) << QPointF( 0, 1 )
|
||||
<< QPointF( 1, 0 ) << QPointF( 0, -1 );
|
||||
return true;
|
||||
}
|
||||
else if ( mName == "pentagon" )
|
||||
{
|
||||
mPolygon << QPointF( sin( DEG2RAD( 288.0 ) ), - cos( DEG2RAD( 288.0 ) ) )
|
||||
<< QPointF( sin( DEG2RAD( 216.0 ) ), - cos( DEG2RAD( 216.0 ) ) )
|
||||
<< QPointF( sin( DEG2RAD( 144.0 ) ), - cos( DEG2RAD( 144.0 ) ) )
|
||||
<< QPointF( sin( DEG2RAD( 72.0 ) ), - cos( DEG2RAD( 72.0 ) ) )
|
||||
<< QPointF( 0, -1 );
|
||||
return true;
|
||||
}
|
||||
else if ( mName == "triangle" )
|
||||
{
|
||||
mPolygon << QPointF( -1, 1 ) << QPointF( 1, 1 ) << QPointF( 0, -1 );
|
||||
return true;
|
||||
}
|
||||
else if ( mName == "equilateral_triangle" )
|
||||
{
|
||||
mPolygon << QPointF( sin( DEG2RAD( 240.0 ) ), - cos( DEG2RAD( 240.0 ) ) )
|
||||
<< QPointF( sin( DEG2RAD( 120.0 ) ), - cos( DEG2RAD( 120.0 ) ) )
|
||||
<< QPointF( 0, -1 );
|
||||
return true;
|
||||
}
|
||||
else if ( mName == "star" )
|
||||
{
|
||||
double sixth = 1.0 / 3;
|
||||
|
||||
mPolygon << QPointF( 0, -1 )
|
||||
<< QPointF( -sixth, -sixth )
|
||||
<< QPointF( -1, -sixth )
|
||||
<< QPointF( -sixth, 0 )
|
||||
<< QPointF( -1, 1 )
|
||||
<< QPointF( 0, + sixth )
|
||||
<< QPointF( 1, 1 )
|
||||
<< QPointF( + sixth, 0 )
|
||||
<< QPointF( 1, -sixth )
|
||||
<< QPointF( + sixth, -sixth );
|
||||
return true;
|
||||
}
|
||||
else if ( mName == "regular_star" )
|
||||
{
|
||||
double inner_r = cos( DEG2RAD( 72.0 ) ) / cos( DEG2RAD( 36.0 ) );
|
||||
|
||||
mPolygon << QPointF( inner_r * sin( DEG2RAD( 324.0 ) ), - inner_r * cos( DEG2RAD( 324.0 ) ) ) // 324
|
||||
<< QPointF( sin( DEG2RAD( 288.0 ) ) , - cos( DEG2RAD( 288 ) ) ) // 288
|
||||
<< QPointF( inner_r * sin( DEG2RAD( 252.0 ) ), - inner_r * cos( DEG2RAD( 252.0 ) ) ) // 252
|
||||
<< QPointF( sin( DEG2RAD( 216.0 ) ) , - cos( DEG2RAD( 216.0 ) ) ) // 216
|
||||
<< QPointF( 0, inner_r ) // 180
|
||||
<< QPointF( sin( DEG2RAD( 144.0 ) ) , - cos( DEG2RAD( 144.0 ) ) ) // 144
|
||||
<< QPointF( inner_r * sin( DEG2RAD( 108.0 ) ), - inner_r * cos( DEG2RAD( 108.0 ) ) ) // 108
|
||||
<< QPointF( sin( DEG2RAD( 72.0 ) ) , - cos( DEG2RAD( 72.0 ) ) ) // 72
|
||||
<< QPointF( inner_r * sin( DEG2RAD( 36.0 ) ), - inner_r * cos( DEG2RAD( 36.0 ) ) ) // 36
|
||||
<< QPointF( 0, -1 ); // 0
|
||||
return true;
|
||||
}
|
||||
else if ( mName == "arrow" )
|
||||
{
|
||||
double eight = 1.0 / 4;
|
||||
double quarter = 1.0 / 2;
|
||||
|
||||
mPolygon << QPointF( 0, -1 )
|
||||
<< QPointF( 0.5, -0.5 )
|
||||
<< QPointF( 0.25, -0.25 )
|
||||
<< QPointF( 0.25, 1 )
|
||||
<< QPointF( -0.25, 1 )
|
||||
<< QPointF( -0.25, -0.5 )
|
||||
<< QPointF( -0.5, -0.5 );
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool QgsSimpleMarkerSymbolLayerV2::preparePath()
|
||||
{
|
||||
mPath = QPainterPath();
|
||||
|
||||
if ( mName == "circle" )
|
||||
{
|
||||
mPath.addEllipse( QRectF( -1, -1, 2, 2 ) ); // x,y,w,h
|
||||
return true;
|
||||
}
|
||||
else if ( mName == "cross" )
|
||||
{
|
||||
mPath.moveTo( -1, 0 );
|
||||
mPath.lineTo( 1, 0 ); // horizontal
|
||||
mPath.moveTo( 0, -1 );
|
||||
mPath.lineTo( 0, 1 ); // vertical
|
||||
return true;
|
||||
}
|
||||
else if ( mName == "cross2" )
|
||||
{
|
||||
mPath.moveTo( -1, -1 );
|
||||
mPath.lineTo( 1, 1 );
|
||||
mPath.moveTo( 1, -1 );
|
||||
mPath.lineTo( -1, 1 );
|
||||
return true;
|
||||
}
|
||||
else if ( mName == "line" )
|
||||
{
|
||||
mPath.moveTo( 0, -1 );
|
||||
mPath.lineTo( 0, 1 ); // vertical line
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void QgsSimpleMarkerSymbolLayerV2::renderPoint( const QPointF& point, QgsSymbolV2RenderContext& context )
|
||||
{
|
||||
QgsRenderContext& rc = context.renderContext();
|
||||
@ -233,11 +326,48 @@ void QgsSimpleMarkerSymbolLayerV2::renderPoint( const QPointF& point, QgsSymbolV
|
||||
return;
|
||||
}
|
||||
|
||||
QImage &img = context.selected() ? mSelCache : mCache;
|
||||
double s = img.width() / context.renderContext().rasterScaleFactor();
|
||||
p->drawImage( QRectF( point.x() - s / 2.0 + context.outputLineWidth( mOffset.x() ),
|
||||
point.y() - s / 2.0 + context.outputLineWidth( mOffset.y() ),
|
||||
s, s ), img );
|
||||
bool hasDataDefinedRotation = context.renderHints() & QgsSymbolV2::DataDefinedRotation;
|
||||
bool hasDataDefinedSize = context.renderHints() & QgsSymbolV2::DataDefinedSizeScale;
|
||||
|
||||
if ( !hasDataDefinedRotation && !hasDataDefinedSize )
|
||||
{
|
||||
// we will use cached image
|
||||
QImage &img = context.selected() ? mSelCache : mCache;
|
||||
double s = img.width() / context.renderContext().rasterScaleFactor();
|
||||
p->drawImage( QRectF( point.x() - s / 2.0 + context.outputLineWidth( mOffset.x() ),
|
||||
point.y() - s / 2.0 + context.outputLineWidth( mOffset.y() ),
|
||||
s, s ), img );
|
||||
}
|
||||
else
|
||||
{
|
||||
QMatrix transform;
|
||||
|
||||
// move to the desired position
|
||||
transform.translate( point.x() + context.outputLineWidth( mOffset.x() ),
|
||||
point.y() + context.outputLineWidth( mOffset.y() ) );
|
||||
|
||||
// resize if necessary
|
||||
if ( hasDataDefinedSize )
|
||||
{
|
||||
double scaledSize = context.outputPixelSize( mSize );
|
||||
double half = scaledSize / 2.0;
|
||||
transform.scale( half, half );
|
||||
}
|
||||
|
||||
// rotate if necessary
|
||||
if ( mAngle != 0 )
|
||||
{
|
||||
transform.rotate( mAngle );
|
||||
}
|
||||
|
||||
p->setBrush( context.selected() ? mSelBrush : mBrush );
|
||||
p->setPen( context.selected() ? mSelPen : mPen );
|
||||
|
||||
if ( !mPolygon.isEmpty() )
|
||||
p->drawPolygon( transform.map( mPolygon ) );
|
||||
else
|
||||
p->drawPath( transform.map( mPath ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -268,37 +398,8 @@ void QgsSimpleMarkerSymbolLayerV2::drawMarker( QPainter* p, QgsSymbolV2RenderCon
|
||||
}
|
||||
else
|
||||
{
|
||||
double scaledSize = context.outputPixelSize( mSize );
|
||||
double half = scaledSize / 2.0;
|
||||
if ( mAngle != 0 )
|
||||
{
|
||||
p->save();
|
||||
p->rotate( mAngle );
|
||||
}
|
||||
|
||||
if ( mName == "circle" )
|
||||
{
|
||||
p->drawEllipse( QRectF( -half, -half, half*2, half*2 ) ); // x,y,w,h
|
||||
}
|
||||
else if ( mName == "cross" )
|
||||
{
|
||||
p->drawLine( QPointF( -half, 0 ), QPointF( half, 0 ) ); // horizontal
|
||||
p->drawLine( QPointF( 0, -half ), QPointF( 0, half ) ); // vertical
|
||||
}
|
||||
else if ( mName == "cross2" )
|
||||
{
|
||||
p->drawLine( QPointF( -half, -half ), QPointF( half, half ) );
|
||||
p->drawLine( QPointF( -half, half ), QPointF( half, -half ) );
|
||||
}
|
||||
else if ( mName == "line" )
|
||||
{
|
||||
p->drawLine( QPointF( 0, -half ), QPointF( 0, half ) ); // vertical line
|
||||
}
|
||||
|
||||
if ( mAngle != 0 )
|
||||
p->restore();
|
||||
p->drawPath( mPath );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -363,6 +464,8 @@ void QgsSvgMarkerSymbolLayerV2::startRender( QgsSymbolV2RenderContext& context )
|
||||
selPainter.setPen( Qt::NoPen );
|
||||
selPainter.drawEllipse( QPointF( 0, 0 ), pictureSize*0.6, pictureSize*0.6 );
|
||||
renderer.render( &selPainter, rect );
|
||||
|
||||
mOrigSize = mSize; // save in case the size would be data defined
|
||||
}
|
||||
|
||||
void QgsSvgMarkerSymbolLayerV2::stopRender( QgsSymbolV2RenderContext& context )
|
||||
@ -382,15 +485,18 @@ void QgsSvgMarkerSymbolLayerV2::renderPoint( const QPointF& point, QgsSymbolV2Re
|
||||
QPointF outputOffset = QPointF( context.outputLineWidth( mOffset.x() ), context.outputLineWidth( mOffset.y() ) );
|
||||
p->translate( point + outputOffset );
|
||||
|
||||
if ( context.renderHints() & QgsSymbolV2::DataDefinedSizeScale )
|
||||
{
|
||||
double s = mSize / mOrigSize;
|
||||
p->scale( s, s );
|
||||
}
|
||||
|
||||
if ( mAngle != 0 )
|
||||
p->rotate( mAngle );
|
||||
|
||||
QPicture &pct = context.selected() ? mSelPicture : mPicture;
|
||||
p->drawPicture( 0, 0, pct );
|
||||
|
||||
if ( mAngle != 0 )
|
||||
p->rotate( -mAngle );
|
||||
|
||||
p->restore();
|
||||
}
|
||||
|
||||
@ -555,7 +661,7 @@ void QgsFontMarkerSymbolLayerV2::startRender( QgsSymbolV2RenderContext& context
|
||||
QFontMetrics fm( mFont );
|
||||
mChrOffset = QPointF( fm.width( mChr ) / 2, -fm.ascent() / 2 );
|
||||
|
||||
|
||||
mOrigSize = mSize; // save in case the size would be data defined
|
||||
}
|
||||
|
||||
void QgsFontMarkerSymbolLayerV2::stopRender( QgsSymbolV2RenderContext& context )
|
||||
@ -572,6 +678,13 @@ void QgsFontMarkerSymbolLayerV2::renderPoint( const QPointF& point, QgsSymbolV2R
|
||||
|
||||
p->save();
|
||||
p->translate( point );
|
||||
|
||||
if ( context.renderHints() & QgsSymbolV2::DataDefinedSizeScale )
|
||||
{
|
||||
double s = mSize / mOrigSize;
|
||||
p->scale( s, s );
|
||||
}
|
||||
|
||||
if ( mAngle != 0 )
|
||||
p->rotate( mAngle );
|
||||
|
||||
|
@ -53,10 +53,16 @@ class CORE_EXPORT QgsSimpleMarkerSymbolLayerV2 : public QgsMarkerSymbolLayerV2
|
||||
|
||||
void drawMarker( QPainter* p, QgsSymbolV2RenderContext& context );
|
||||
|
||||
bool prepareShape();
|
||||
bool preparePath();
|
||||
|
||||
void prepareCache( QgsSymbolV2RenderContext& context );
|
||||
|
||||
QColor mBorderColor;
|
||||
QPen mPen;
|
||||
QBrush mBrush;
|
||||
QPolygonF mPolygon;
|
||||
QPainterPath mPath;
|
||||
QString mName;
|
||||
QImage mCache;
|
||||
QPen mSelPen;
|
||||
@ -114,6 +120,7 @@ class CORE_EXPORT QgsSvgMarkerSymbolLayerV2 : public QgsMarkerSymbolLayerV2
|
||||
QString mPath;
|
||||
QPicture mPicture;
|
||||
QPicture mSelPicture;
|
||||
double mOrigSize;
|
||||
};
|
||||
|
||||
|
||||
@ -170,6 +177,7 @@ class CORE_EXPORT QgsFontMarkerSymbolLayerV2 : public QgsMarkerSymbolLayerV2
|
||||
|
||||
QPointF mChrOffset;
|
||||
QFont mFont;
|
||||
double mOrigSize;
|
||||
};
|
||||
|
||||
|
||||
|
@ -4,11 +4,16 @@
|
||||
#include "qgssymbolv2.h"
|
||||
#include "qgssymbollayerv2utils.h"
|
||||
|
||||
#include "qgslogger.h"
|
||||
#include "qgsfeature.h"
|
||||
#include "qgsvectorlayer.h"
|
||||
|
||||
#include <QDomDocument>
|
||||
#include <QDomElement>
|
||||
|
||||
QgsSingleSymbolRendererV2::QgsSingleSymbolRendererV2( QgsSymbolV2* symbol )
|
||||
: QgsFeatureRendererV2( "singleSymbol" )
|
||||
: QgsFeatureRendererV2( "singleSymbol" ),
|
||||
mTempSymbol( NULL )
|
||||
{
|
||||
mSymbol = symbol;
|
||||
}
|
||||
@ -20,22 +25,93 @@ QgsSingleSymbolRendererV2::~QgsSingleSymbolRendererV2()
|
||||
|
||||
QgsSymbolV2* QgsSingleSymbolRendererV2::symbolForFeature( QgsFeature& feature )
|
||||
{
|
||||
return mSymbol;
|
||||
if ( mRotationFieldIdx == -1 && mSizeScaleFieldIdx == -1 )
|
||||
return mSymbol;
|
||||
|
||||
double rotation = 0;
|
||||
double sizeScale = 1;
|
||||
if ( mRotationFieldIdx != -1 )
|
||||
{
|
||||
rotation = feature.attributeMap()[mRotationFieldIdx].toDouble();
|
||||
}
|
||||
if ( mSizeScaleFieldIdx != -1 )
|
||||
{
|
||||
sizeScale = feature.attributeMap()[mSizeScaleFieldIdx].toDouble();
|
||||
}
|
||||
|
||||
if ( mTempSymbol->type() == QgsSymbolV2::Marker )
|
||||
{
|
||||
QgsMarkerSymbolV2* markerSymbol = static_cast<QgsMarkerSymbolV2*>( mTempSymbol );
|
||||
if ( mRotationFieldIdx != -1 )
|
||||
markerSymbol->setAngle( rotation );
|
||||
if ( mSizeScaleFieldIdx != -1 )
|
||||
markerSymbol->setSize( sizeScale * mOrigSize );
|
||||
}
|
||||
else if ( mTempSymbol->type() == QgsSymbolV2::Line )
|
||||
{
|
||||
QgsLineSymbolV2* lineSymbol = static_cast<QgsLineSymbolV2*>( mTempSymbol );
|
||||
if ( mSizeScaleFieldIdx != -1 )
|
||||
lineSymbol->setWidth( sizeScale * mOrigSize );
|
||||
}
|
||||
|
||||
return mTempSymbol;
|
||||
}
|
||||
|
||||
void QgsSingleSymbolRendererV2::startRender( QgsRenderContext& context, const QgsVectorLayer *vlayer )
|
||||
{
|
||||
mRotationFieldIdx = ( mRotationField.isEmpty() ? -1 : vlayer->fieldNameIndex( mRotationField ) );
|
||||
mSizeScaleFieldIdx = ( mSizeScaleField.isEmpty() ? -1 : vlayer->fieldNameIndex( mSizeScaleField ) );
|
||||
|
||||
mSymbol->startRender( context );
|
||||
|
||||
if ( mRotationFieldIdx != -1 || mSizeScaleFieldIdx != -1 )
|
||||
{
|
||||
// we are going to need a temporary symbol
|
||||
mTempSymbol = mSymbol->clone();
|
||||
|
||||
int hints = 0;
|
||||
if ( mRotationFieldIdx != -1 ) hints |= QgsSymbolV2::DataDefinedRotation;
|
||||
if ( mSizeScaleFieldIdx != -1 ) hints |= QgsSymbolV2::DataDefinedSizeScale;
|
||||
mTempSymbol->setRenderHints( hints );
|
||||
|
||||
mTempSymbol->startRender( context );
|
||||
|
||||
if ( mSymbol->type() == QgsSymbolV2::Marker )
|
||||
{
|
||||
mOrigSize = static_cast<QgsMarkerSymbolV2*>( mSymbol )->size();
|
||||
}
|
||||
else if ( mSymbol->type() == QgsSymbolV2::Line )
|
||||
{
|
||||
mOrigSize = static_cast<QgsLineSymbolV2*>( mSymbol )->width();
|
||||
}
|
||||
else
|
||||
{
|
||||
mOrigSize = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QgsSingleSymbolRendererV2::stopRender( QgsRenderContext& context )
|
||||
{
|
||||
mSymbol->stopRender( context );
|
||||
|
||||
if ( mRotationFieldIdx != -1 || mSizeScaleFieldIdx != -1 )
|
||||
{
|
||||
// we are going to need a temporary symbol
|
||||
mTempSymbol->stopRender( context );
|
||||
delete mTempSymbol;
|
||||
mTempSymbol = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
QList<QString> QgsSingleSymbolRendererV2::usedAttributes()
|
||||
{
|
||||
return QList<QString>();
|
||||
QList<QString> lst;
|
||||
if ( !mRotationField.isEmpty() )
|
||||
lst.append( mRotationField );
|
||||
if ( !mSizeScaleField.isEmpty() )
|
||||
lst.append( mSizeScaleField );
|
||||
return lst;
|
||||
}
|
||||
|
||||
QgsSymbolV2* QgsSingleSymbolRendererV2::symbol() const
|
||||
@ -58,6 +134,8 @@ QgsFeatureRendererV2* QgsSingleSymbolRendererV2::clone()
|
||||
{
|
||||
QgsSingleSymbolRendererV2* r = new QgsSingleSymbolRendererV2( mSymbol->clone() );
|
||||
r->setUsingSymbolLevels( usingSymbolLevels() );
|
||||
r->setRotationField( rotationField() );
|
||||
r->setSizeScaleField( sizeScaleField() );
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -84,6 +162,14 @@ QgsFeatureRendererV2* QgsSingleSymbolRendererV2::create( QDomElement& element )
|
||||
// delete symbols if there are any more
|
||||
QgsSymbolLayerV2Utils::clearSymbolMap( symbolMap );
|
||||
|
||||
QDomElement rotationElem = element.firstChildElement( "rotation" );
|
||||
if ( !rotationElem.isNull() )
|
||||
r->setRotationField( rotationElem.attribute( "field" ) );
|
||||
|
||||
QDomElement sizeScaleElem = element.firstChildElement( "sizescale" );
|
||||
if ( !sizeScaleElem.isNull() )
|
||||
r->setSizeScaleField( sizeScaleElem.attribute( "field" ) );
|
||||
|
||||
// TODO: symbol levels
|
||||
return r;
|
||||
}
|
||||
@ -99,6 +185,14 @@ QDomElement QgsSingleSymbolRendererV2::save( QDomDocument& doc )
|
||||
QDomElement symbolsElem = QgsSymbolLayerV2Utils::saveSymbols( symbols, "symbols", doc );
|
||||
rendererElem.appendChild( symbolsElem );
|
||||
|
||||
QDomElement rotationElem = doc.createElement( "rotation" );
|
||||
rotationElem.setAttribute( "field", mRotationField );
|
||||
rendererElem.appendChild( rotationElem );
|
||||
|
||||
QDomElement sizeScaleElem = doc.createElement( "sizescale" );
|
||||
sizeScaleElem.setAttribute( "field", mSizeScaleField );
|
||||
rendererElem.appendChild( sizeScaleElem );
|
||||
|
||||
return rendererElem;
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,12 @@ class CORE_EXPORT QgsSingleSymbolRendererV2 : public QgsFeatureRendererV2
|
||||
QgsSymbolV2* symbol() const;
|
||||
void setSymbol( QgsSymbolV2* s );
|
||||
|
||||
void setRotationField( QString fieldName ) { mRotationField = fieldName; }
|
||||
QString rotationField() const { return mRotationField; }
|
||||
|
||||
void setSizeScaleField( QString fieldName ) { mSizeScaleField = fieldName; }
|
||||
QString sizeScaleField() const { return mSizeScaleField; }
|
||||
|
||||
virtual QString dump();
|
||||
|
||||
virtual QgsFeatureRendererV2* clone();
|
||||
@ -43,6 +49,13 @@ class CORE_EXPORT QgsSingleSymbolRendererV2 : public QgsFeatureRendererV2
|
||||
|
||||
protected:
|
||||
QgsSymbolV2* mSymbol;
|
||||
QString mRotationField;
|
||||
QString mSizeScaleField;
|
||||
|
||||
// temporary stuff for rendering
|
||||
int mRotationFieldIdx, mSizeScaleFieldIdx;
|
||||
QgsSymbolV2* mTempSymbol;
|
||||
double mOrigSize;
|
||||
};
|
||||
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
#include <cmath>
|
||||
|
||||
QgsSymbolV2::QgsSymbolV2( SymbolType type, QgsSymbolLayerV2List layers )
|
||||
: mType( type ), mLayers( layers ), mOutputUnit( MM ), mAlpha( 1.0 )
|
||||
: mType( type ), mLayers( layers ), mOutputUnit( MM ), mAlpha( 1.0 ), mRenderHints( 0 )
|
||||
{
|
||||
|
||||
// check they're all correct symbol layers
|
||||
@ -127,14 +127,14 @@ bool QgsSymbolV2::changeSymbolLayer( int index, QgsSymbolLayerV2* layer )
|
||||
|
||||
void QgsSymbolV2::startRender( QgsRenderContext& context )
|
||||
{
|
||||
QgsSymbolV2RenderContext symbolContext( context, mOutputUnit, mAlpha );
|
||||
QgsSymbolV2RenderContext symbolContext( context, mOutputUnit, mAlpha, false, mRenderHints );
|
||||
for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
|
||||
( *it )->startRender( symbolContext );
|
||||
}
|
||||
|
||||
void QgsSymbolV2::stopRender( QgsRenderContext& context )
|
||||
{
|
||||
QgsSymbolV2RenderContext symbolContext( context, mOutputUnit, mAlpha );
|
||||
QgsSymbolV2RenderContext symbolContext( context, mOutputUnit, mAlpha, false, mRenderHints );
|
||||
for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
|
||||
( *it )->stopRender( symbolContext );
|
||||
}
|
||||
@ -245,8 +245,8 @@ QgsSymbolLayerV2List QgsSymbolV2::cloneLayers() const
|
||||
|
||||
////////////////////
|
||||
|
||||
QgsSymbolV2RenderContext::QgsSymbolV2RenderContext( QgsRenderContext& c, QgsSymbolV2::OutputUnit u, qreal alpha, bool selected )
|
||||
: mRenderContext( c ), mOutputUnit( u ), mAlpha( alpha ), mSelected( selected )
|
||||
QgsSymbolV2RenderContext::QgsSymbolV2RenderContext( QgsRenderContext& c, QgsSymbolV2::OutputUnit u, qreal alpha, bool selected, int renderHints )
|
||||
: mRenderContext( c ), mOutputUnit( u ), mAlpha( alpha ), mSelected( selected ), mRenderHints( renderHints )
|
||||
{
|
||||
|
||||
}
|
||||
@ -347,7 +347,7 @@ double QgsMarkerSymbolV2::size()
|
||||
|
||||
void QgsMarkerSymbolV2::renderPoint( const QPointF& point, QgsRenderContext& context, int layer, bool selected )
|
||||
{
|
||||
QgsSymbolV2RenderContext symbolContext( context, mOutputUnit, mAlpha, selected );
|
||||
QgsSymbolV2RenderContext symbolContext( context, mOutputUnit, mAlpha, selected, mRenderHints );
|
||||
if ( layer != -1 )
|
||||
{
|
||||
if ( layer >= 0 && layer < mLayers.count() )
|
||||
@ -416,7 +416,7 @@ double QgsLineSymbolV2::width()
|
||||
|
||||
void QgsLineSymbolV2::renderPolyline( const QPolygonF& points, QgsRenderContext& context, int layer, bool selected )
|
||||
{
|
||||
QgsSymbolV2RenderContext symbolContext( context, mOutputUnit, mAlpha, selected );
|
||||
QgsSymbolV2RenderContext symbolContext( context, mOutputUnit, mAlpha, selected, mRenderHints );
|
||||
if ( layer != -1 )
|
||||
{
|
||||
if ( layer >= 0 && layer < mLayers.count() )
|
||||
@ -452,7 +452,7 @@ QgsFillSymbolV2::QgsFillSymbolV2( QgsSymbolLayerV2List layers )
|
||||
|
||||
void QgsFillSymbolV2::renderPolygon( const QPolygonF& points, QList<QPolygonF>* rings, QgsRenderContext& context, int layer, bool selected )
|
||||
{
|
||||
QgsSymbolV2RenderContext symbolContext( context, mOutputUnit, mAlpha, selected );
|
||||
QgsSymbolV2RenderContext symbolContext( context, mOutputUnit, mAlpha, selected, mRenderHints );
|
||||
if ( layer != -1 )
|
||||
{
|
||||
if ( layer >= 0 && layer < mLayers.count() )
|
||||
|
@ -35,6 +35,12 @@ class CORE_EXPORT QgsSymbolV2
|
||||
Fill
|
||||
};
|
||||
|
||||
enum RenderHint
|
||||
{
|
||||
DataDefinedSizeScale = 1,
|
||||
DataDefinedRotation = 2
|
||||
};
|
||||
|
||||
virtual ~QgsSymbolV2();
|
||||
|
||||
//! return new default symbol for specified geometry type
|
||||
@ -84,6 +90,9 @@ class CORE_EXPORT QgsSymbolV2
|
||||
qreal alpha() const { return mAlpha; }
|
||||
void setAlpha( qreal alpha ) { mAlpha = alpha; }
|
||||
|
||||
void setRenderHints( int hints ) { mRenderHints = hints; }
|
||||
int renderHints() { return mRenderHints; }
|
||||
|
||||
protected:
|
||||
QgsSymbolV2( SymbolType type, QgsSymbolLayerV2List layers ); // can't be instantiated
|
||||
|
||||
@ -96,6 +105,8 @@ class CORE_EXPORT QgsSymbolV2
|
||||
|
||||
/**Symbol opacity (in the range 0 - 1)*/
|
||||
qreal mAlpha;
|
||||
|
||||
int mRenderHints;
|
||||
};
|
||||
|
||||
///////////////////////
|
||||
@ -103,7 +114,7 @@ class CORE_EXPORT QgsSymbolV2
|
||||
class CORE_EXPORT QgsSymbolV2RenderContext
|
||||
{
|
||||
public:
|
||||
QgsSymbolV2RenderContext( QgsRenderContext& c, QgsSymbolV2::OutputUnit u , qreal alpha = 1.0, bool selected = false );
|
||||
QgsSymbolV2RenderContext( QgsRenderContext& c, QgsSymbolV2::OutputUnit u , qreal alpha = 1.0, bool selected = false, int renderHints = 0 );
|
||||
~QgsSymbolV2RenderContext();
|
||||
|
||||
QgsRenderContext& renderContext() { return mRenderContext; }
|
||||
@ -118,6 +129,9 @@ class CORE_EXPORT QgsSymbolV2RenderContext
|
||||
bool selected() const { return mSelected; }
|
||||
void setSelected( bool selected ) { mSelected = selected; }
|
||||
|
||||
int renderHints() const { return mRenderHints; }
|
||||
void setRenderHints( int hints ) { mRenderHints = hints; }
|
||||
|
||||
// Colour used for selections
|
||||
|
||||
static QColor selectionColor();
|
||||
@ -133,6 +147,7 @@ class CORE_EXPORT QgsSymbolV2RenderContext
|
||||
QgsSymbolV2::OutputUnit mOutputUnit;
|
||||
qreal mAlpha;
|
||||
bool mSelected;
|
||||
int mRenderHints;
|
||||
};
|
||||
|
||||
|
||||
|
@ -3,10 +3,13 @@
|
||||
#include "qgssinglesymbolrendererv2.h"
|
||||
#include "qgssymbolv2.h"
|
||||
|
||||
#include "qgslogger.h"
|
||||
#include "qgsvectorlayer.h"
|
||||
|
||||
#include "qgssymbolv2selectordialog.h"
|
||||
|
||||
#include <QMenu>
|
||||
|
||||
QgsRendererV2Widget* QgsSingleSymbolRendererV2Widget::create( QgsVectorLayer* layer, QgsStyleV2* style, QgsFeatureRendererV2* renderer )
|
||||
{
|
||||
return new QgsSingleSymbolRendererV2Widget( layer, style, renderer );
|
||||
@ -43,6 +46,44 @@ QgsSingleSymbolRendererV2Widget::QgsSingleSymbolRendererV2Widget( QgsVectorLayer
|
||||
layout->addWidget( mSelector );
|
||||
setLayout( layout );
|
||||
|
||||
// advanced actions - data defined rendering
|
||||
QMenu* advMenu = mSelector->advancedMenu();
|
||||
|
||||
mRotationMenu = new QMenu( tr( "Rotation field" ) );
|
||||
mSizeScaleMenu = new QMenu( tr( "Size scale field" ) );
|
||||
|
||||
populateMenu( mRotationMenu, SLOT( rotationFieldSelected() ), mRenderer->rotationField() );
|
||||
populateMenu( mSizeScaleMenu, SLOT( sizeScaleFieldSelected() ), mRenderer->sizeScaleField() );
|
||||
|
||||
advMenu->addMenu( mRotationMenu );
|
||||
advMenu->addMenu( mSizeScaleMenu );
|
||||
}
|
||||
|
||||
void QgsSingleSymbolRendererV2Widget::populateMenu( QMenu* menu, const char* slot, QString fieldName )
|
||||
{
|
||||
QAction* aNo = menu->addAction( tr( "- no field -" ), this, slot );
|
||||
aNo->setCheckable( true );
|
||||
menu->addSeparator();
|
||||
|
||||
bool hasField = false;
|
||||
const QgsFieldMap& flds = mLayer->pendingFields();
|
||||
for ( QgsFieldMap::const_iterator it = flds.begin(); it != flds.end(); ++it )
|
||||
{
|
||||
const QgsField& fld = it.value();
|
||||
if ( fld.type() == QVariant::Int || fld.type() == QVariant::Double )
|
||||
{
|
||||
QAction* a = menu->addAction( fld.name(), this, slot );
|
||||
a->setCheckable( true );
|
||||
if ( fieldName == fld.name() )
|
||||
{
|
||||
a->setChecked( true );
|
||||
hasField = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !hasField )
|
||||
aNo->setChecked( true );
|
||||
}
|
||||
|
||||
QgsSingleSymbolRendererV2Widget::~QgsSingleSymbolRendererV2Widget()
|
||||
@ -66,3 +107,50 @@ void QgsSingleSymbolRendererV2Widget::changeSingleSymbol()
|
||||
mRenderer->setSymbol( mSingleSymbol->clone() );
|
||||
}
|
||||
|
||||
void QgsSingleSymbolRendererV2Widget::rotationFieldSelected()
|
||||
{
|
||||
QObject* s = sender();
|
||||
if ( s == NULL )
|
||||
return;
|
||||
|
||||
QAction* a = qobject_cast<QAction*>( s );
|
||||
if ( a == NULL )
|
||||
return;
|
||||
|
||||
QString fldName = a->text();
|
||||
|
||||
updateMenu( mRotationMenu, fldName );
|
||||
|
||||
if ( fldName == tr( "- no field -" ) )
|
||||
fldName = QString();
|
||||
|
||||
mRenderer->setRotationField( fldName );
|
||||
}
|
||||
|
||||
void QgsSingleSymbolRendererV2Widget::sizeScaleFieldSelected()
|
||||
{
|
||||
QObject* s = sender();
|
||||
if ( s == NULL )
|
||||
return;
|
||||
|
||||
QAction* a = qobject_cast<QAction*>( s );
|
||||
if ( a == NULL )
|
||||
return;
|
||||
|
||||
QString fldName = a->text();
|
||||
|
||||
updateMenu( mSizeScaleMenu, fldName );
|
||||
|
||||
if ( fldName == tr( "- no field -" ) )
|
||||
fldName = QString();
|
||||
|
||||
mRenderer->setSizeScaleField( fldName );
|
||||
}
|
||||
|
||||
void QgsSingleSymbolRendererV2Widget::updateMenu( QMenu* menu, QString fieldName )
|
||||
{
|
||||
foreach( QAction* a, menu->actions() )
|
||||
{
|
||||
a->setChecked( a->text() == fieldName );
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,8 @@
|
||||
class QgsSingleSymbolRendererV2;
|
||||
class QgsSymbolV2SelectorDialog;
|
||||
|
||||
class QMenu;
|
||||
|
||||
class GUI_EXPORT QgsSingleSymbolRendererV2Widget : public QgsRendererV2Widget
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -22,10 +24,20 @@ class GUI_EXPORT QgsSingleSymbolRendererV2Widget : public QgsRendererV2Widget
|
||||
public slots:
|
||||
void changeSingleSymbol();
|
||||
|
||||
void rotationFieldSelected();
|
||||
void sizeScaleFieldSelected();
|
||||
|
||||
protected:
|
||||
|
||||
void populateMenu( QMenu* menu, const char* slot, QString fieldName );
|
||||
void updateMenu( QMenu* menu, QString fieldName );
|
||||
|
||||
QgsSingleSymbolRendererV2* mRenderer;
|
||||
QgsSymbolV2SelectorDialog* mSelector;
|
||||
QgsSymbolV2* mSingleSymbol;
|
||||
|
||||
QMenu* mRotationMenu;
|
||||
QMenu* mSizeScaleMenu;
|
||||
};
|
||||
|
||||
|
||||
|
@ -14,15 +14,18 @@
|
||||
#include <QStandardItemModel>
|
||||
#include <QInputDialog>
|
||||
#include <QKeyEvent>
|
||||
#include <QMenu>
|
||||
|
||||
QgsSymbolV2SelectorDialog::QgsSymbolV2SelectorDialog( QgsSymbolV2* symbol, QgsStyleV2* style, QWidget* parent, bool embedded )
|
||||
: QDialog( parent )
|
||||
: QDialog( parent ), mAdvancedMenu( NULL )
|
||||
{
|
||||
mStyle = style;
|
||||
mSymbol = symbol;
|
||||
|
||||
setupUi( this );
|
||||
|
||||
btnAdvanced->hide(); // advanced button is hidden by default
|
||||
|
||||
// can be embedded in renderer properties dialog
|
||||
if ( embedded )
|
||||
{
|
||||
@ -262,3 +265,14 @@ void QgsSymbolV2SelectorDialog::displayTransparency( double alpha )
|
||||
double transparencyPercent = ( 1 - alpha ) * 100;
|
||||
mTransparencyLabel->setText( tr( "Transparency: %1%" ).arg(( int ) transparencyPercent ) );
|
||||
}
|
||||
|
||||
QMenu* QgsSymbolV2SelectorDialog::advancedMenu()
|
||||
{
|
||||
if ( mAdvancedMenu == NULL )
|
||||
{
|
||||
mAdvancedMenu = new QMenu;
|
||||
btnAdvanced->setMenu( mAdvancedMenu );
|
||||
btnAdvanced->show();
|
||||
}
|
||||
return mAdvancedMenu;
|
||||
}
|
||||
|
@ -9,6 +9,8 @@
|
||||
class QgsStyleV2;
|
||||
class QgsSymbolV2;
|
||||
|
||||
class QMenu;
|
||||
|
||||
class GUI_EXPORT QgsSymbolV2SelectorDialog : public QDialog, private Ui::QgsSymbolV2SelectorDialogBase
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -16,6 +18,9 @@ class GUI_EXPORT QgsSymbolV2SelectorDialog : public QDialog, private Ui::QgsSymb
|
||||
public:
|
||||
QgsSymbolV2SelectorDialog( QgsSymbolV2* symbol, QgsStyleV2* style, QWidget* parent = NULL, bool embedded = false );
|
||||
|
||||
//! return menu for "advanced" button - create it if doesn't exist and show the advanced button
|
||||
QMenu* advancedMenu();
|
||||
|
||||
protected:
|
||||
void populateSymbolView();
|
||||
void updateSymbolPreview();
|
||||
@ -46,6 +51,7 @@ class GUI_EXPORT QgsSymbolV2SelectorDialog : public QDialog, private Ui::QgsSymb
|
||||
protected:
|
||||
QgsStyleV2* mStyle;
|
||||
QgsSymbolV2* mSymbol;
|
||||
QMenu* mAdvancedMenu;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -29,7 +29,7 @@
|
||||
</size>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Box</enum>
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Sunken</enum>
|
||||
@ -221,6 +221,13 @@
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnAdvanced">
|
||||
<property name="text">
|
||||
<string>Advanced</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnAddToStyle">
|
||||
<property name="text">
|
||||
|
Loading…
x
Reference in New Issue
Block a user