Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[FEATURE] add outline join style settings to simple markers
(fixes #3797)
  • Loading branch information
nirvn committed Apr 3, 2016
1 parent 99d5e42 commit 6ad3537
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 12 deletions.
25 changes: 24 additions & 1 deletion python/core/symbology-ng/qgsmarkersymbollayerv2.sip
Expand Up @@ -5,12 +5,24 @@ class QgsSimpleMarkerSymbolLayerV2 : QgsMarkerSymbolLayerV2
%End

public:
/** Constructor for QgsSimpleMarkerSymbolLayerV2.
* @param name symbol name, should be one of "square", "rectangle", "diamond",
* "pentagon", "triangle", "equilateral_triangle", "star", "regular_star", "arrow",
* "circle", "cross", "cross2", "line", "x", "arrowhead", "filled_arrowhead"
* @param color fill color for symbol
* @param borderColor border color for symbol
* @param size symbol size (in mm)
* @param angle symbol rotation angle
* @param scaleMethod scaling method for data defined scaling
* @param penJoinStyle join style for outline pen
*/
QgsSimpleMarkerSymbolLayerV2( const QString& name = DEFAULT_SIMPLEMARKER_NAME,
const QColor& color = DEFAULT_SIMPLEMARKER_COLOR,
const QColor& borderColor = DEFAULT_SIMPLEMARKER_BORDERCOLOR,
double size = DEFAULT_SIMPLEMARKER_SIZE,
double angle = DEFAULT_SIMPLEMARKER_ANGLE,
QgsSymbolV2::ScaleMethod scaleMethod = DEFAULT_SCALE_METHOD );
QgsSymbolV2::ScaleMethod scaleMethod = DEFAULT_SCALE_METHOD,
Qt::PenJoinStyle penJoinStyle = DEFAULT_SIMPLEFILL_JOINSTYLE );

// static stuff

Expand Down Expand Up @@ -41,9 +53,20 @@ class QgsSimpleMarkerSymbolLayerV2 : QgsMarkerSymbolLayerV2
QColor borderColor() const;
void setBorderColor( const QColor& color );

/** Get outline join style.
* @note added in 2.4 */
Qt::PenStyle outlineStyle() const;
/** Set outline join style.
* @note added in 2.4 */
void setOutlineStyle( Qt::PenStyle outlineStyle );

/** Get outline join style.
* @note added in 2.16 */
Qt::PenJoinStyle penJoinStyle() const;
/** Set outline join style.
* @note added in 2.16 */
void setPenJoinStyle( Qt::PenJoinStyle style );

/** Get outline color.
* @note added in 2.1 */
QColor outlineColor() const;
Expand Down
32 changes: 25 additions & 7 deletions src/core/symbology-ng/qgsmarkersymbollayerv2.cpp
Expand Up @@ -48,8 +48,9 @@ static void _fixQPictureDPI( QPainter* p )

//////

QgsSimpleMarkerSymbolLayerV2::QgsSimpleMarkerSymbolLayerV2( const QString& name, const QColor& color, const QColor& borderColor, double size, double angle, QgsSymbolV2::ScaleMethod scaleMethod )
: mOutlineStyle( Qt::SolidLine ), mOutlineWidth( 0 ), mOutlineWidthUnit( QgsSymbolV2::MM )
QgsSimpleMarkerSymbolLayerV2::QgsSimpleMarkerSymbolLayerV2( const QString& name, const QColor& color, const QColor& borderColor, double size, double angle, QgsSymbolV2::ScaleMethod scaleMethod,
Qt::PenJoinStyle penJoinStyle )
: mOutlineStyle( Qt::SolidLine ), mOutlineWidth( 0 ), mOutlineWidthUnit( QgsSymbolV2::MM ), mPenJoinStyle( penJoinStyle )
{
mName = name;
mColor = color;
Expand All @@ -68,6 +69,7 @@ QgsSymbolLayerV2* QgsSimpleMarkerSymbolLayerV2::create( const QgsStringMap& prop
QString name = DEFAULT_SIMPLEMARKER_NAME;
QColor color = DEFAULT_SIMPLEMARKER_COLOR;
QColor borderColor = DEFAULT_SIMPLEMARKER_BORDERCOLOR;
Qt::PenJoinStyle penJoinStyle = DEFAULT_SIMPLEMARKER_JOINSTYLE;
double size = DEFAULT_SIMPLEMARKER_SIZE;
double angle = DEFAULT_SIMPLEMARKER_ANGLE;
QgsSymbolV2::ScaleMethod scaleMethod = DEFAULT_SCALE_METHOD;
Expand All @@ -89,14 +91,18 @@ QgsSymbolLayerV2* QgsSimpleMarkerSymbolLayerV2::create( const QgsStringMap& prop
{
borderColor = QgsSymbolLayerV2Utils::decodeColor( props["line_color"] );
}
if ( props.contains( "joinstyle" ) )
{
penJoinStyle = QgsSymbolLayerV2Utils::decodePenJoinStyle( props["joinstyle"] );
}
if ( props.contains( "size" ) )
size = props["size"].toDouble();
if ( props.contains( "angle" ) )
angle = props["angle"].toDouble();
if ( props.contains( "scale_method" ) )
scaleMethod = QgsSymbolLayerV2Utils::decodeScaleMethod( props["scale_method"] );

QgsSimpleMarkerSymbolLayerV2* m = new QgsSimpleMarkerSymbolLayerV2( name, color, borderColor, size, angle, scaleMethod );
QgsSimpleMarkerSymbolLayerV2* m = new QgsSimpleMarkerSymbolLayerV2( name, color, borderColor, size, angle, scaleMethod, penJoinStyle );
if ( props.contains( "offset" ) )
m->setOffset( QgsSymbolLayerV2Utils::decodePoint( props["offset"] ) );
if ( props.contains( "offset_unit" ) )
Expand Down Expand Up @@ -168,6 +174,7 @@ void QgsSimpleMarkerSymbolLayerV2::startRender( QgsSymbolV2RenderContext& contex
mBrush = QBrush( brushColor );
mPen = QPen( penColor );
mPen.setStyle( mOutlineStyle );
mPen.setJoinStyle( mPenJoinStyle );
mPen.setWidthF( QgsSymbolLayerV2Utils::convertToPainterUnits( context.renderContext(), mOutlineWidth, mOutlineWidthUnit, mOutlineWidthMapUnitScale ) );

QColor selBrushColor = context.renderContext().selectionColor();
Expand All @@ -190,8 +197,8 @@ void QgsSimpleMarkerSymbolLayerV2::startRender( QgsSymbolV2RenderContext& contex
// - drawing to screen (not printer)
mUsingCache = !hasDataDefinedRotation && !hasDataDefinedSize && !context.renderContext().forceVectorOutput()
&& !hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_NAME ) && !hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_COLOR ) && !hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_COLOR_BORDER )
&& !hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_OUTLINE_WIDTH ) && !hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_OUTLINE_STYLE ) &&
!hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_SIZE );
&& !hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_OUTLINE_WIDTH ) && !hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_OUTLINE_STYLE )
&& !hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_JOIN_STYLE ) && !hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_SIZE );

// use either QPolygonF or QPainterPath for drawing
// TODO: find out whether drawing directly doesn't bring overhead - if not, use it for all shapes
Expand Down Expand Up @@ -259,7 +266,7 @@ bool QgsSimpleMarkerSymbolLayerV2::prepareCache( QgsSymbolV2RenderContext& conte
double scaledSize = QgsSymbolLayerV2Utils::convertToPainterUnits( context.renderContext(), mSize, mSizeUnit, mSizeMapUnitScale );

// calculate necessary image size for the cache
double pw = (( qgsDoubleNear( mPen.widthF(), 0.0 ) ? 1 : mPen.widthF() ) + 1 ) / 2 * 2; // make even (round up); handle cosmetic pen
double pw = qRound((( qgsDoubleNear( mPen.widthF(), 0.0 ) ? 1 : mPen.widthF() * 4 ) + 1 ) ) / 2 * 2; // make even (round up); handle cosmetic pen
int imageSize = ( static_cast< int >( scaledSize ) + pw ) / 2 * 2 + 1; // make image width, height odd; account for pen width
double center = imageSize / 2.0;

Expand Down Expand Up @@ -560,6 +567,16 @@ void QgsSimpleMarkerSymbolLayerV2::renderPoint( QPointF point, QgsSymbolV2Render
mSelPen.setStyle( QgsSymbolLayerV2Utils::decodePenStyle( outlineStyle ) );
}
}
if ( hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_JOIN_STYLE ) )
{
context.setOriginalValueVariable( QgsSymbolLayerV2Utils::encodePenJoinStyle( mPenJoinStyle ) );
QString style = evaluateDataDefinedProperty( QgsSymbolLayerV2::EXPR_JOIN_STYLE, context, QVariant(), &ok ).toString();
if ( ok )
{
mPen.setJoinStyle( QgsSymbolLayerV2Utils::decodePenJoinStyle( style ) );
mSelPen.setJoinStyle( QgsSymbolLayerV2Utils::decodePenJoinStyle( style ) );
}
}

p->setBrush( context.selected() ? mSelBrush : mBrush );
p->setPen( context.selected() ? mSelPen : mPen );
Expand Down Expand Up @@ -664,6 +681,7 @@ QgsStringMap QgsSimpleMarkerSymbolLayerV2::properties() const
map["outline_width"] = QString::number( mOutlineWidth );
map["outline_width_unit"] = QgsSymbolLayerV2Utils::encodeOutputUnit( mOutlineWidthUnit );
map["outline_width_map_unit_scale"] = QgsSymbolLayerV2Utils::encodeMapUnitScale( mOutlineWidthMapUnitScale );
map["joinstyle"] = QgsSymbolLayerV2Utils::encodePenJoinStyle( mPenJoinStyle );
map["horizontal_anchor_point"] = QString::number( mHorizontalAnchorPoint );
map["vertical_anchor_point"] = QString::number( mVerticalAnchorPoint );

Expand All @@ -675,7 +693,7 @@ QgsStringMap QgsSimpleMarkerSymbolLayerV2::properties() const

QgsSimpleMarkerSymbolLayerV2* QgsSimpleMarkerSymbolLayerV2::clone() const
{
QgsSimpleMarkerSymbolLayerV2* m = new QgsSimpleMarkerSymbolLayerV2( mName, mColor, mBorderColor, mSize, mAngle, mScaleMethod );
QgsSimpleMarkerSymbolLayerV2* m = new QgsSimpleMarkerSymbolLayerV2( mName, mColor, mBorderColor, mSize, mAngle, mScaleMethod, mPenJoinStyle );
m->setOffset( mOffset );
m->setSizeUnit( mSizeUnit );
m->setSizeMapUnitScale( mSizeMapUnitScale );
Expand Down
27 changes: 26 additions & 1 deletion src/core/symbology-ng/qgsmarkersymbollayerv2.h
Expand Up @@ -22,6 +22,7 @@
#define DEFAULT_SIMPLEMARKER_NAME "circle"
#define DEFAULT_SIMPLEMARKER_COLOR QColor(255,0,0)
#define DEFAULT_SIMPLEMARKER_BORDERCOLOR QColor(0,0,0)
#define DEFAULT_SIMPLEMARKER_JOINSTYLE Qt::BevelJoin
#define DEFAULT_SIMPLEMARKER_SIZE DEFAULT_POINT_SIZE
#define DEFAULT_SIMPLEMARKER_ANGLE 0

Expand All @@ -34,12 +35,24 @@
class CORE_EXPORT QgsSimpleMarkerSymbolLayerV2 : public QgsMarkerSymbolLayerV2
{
public:
/** Constructor for QgsSimpleMarkerSymbolLayerV2.
* @param name symbol name, should be one of "square", "rectangle", "diamond",
* "pentagon", "triangle", "equilateral_triangle", "star", "regular_star", "arrow",
* "circle", "cross", "cross2", "line", "x", "arrowhead", "filled_arrowhead"
* @param color fill color for symbol
* @param borderColor border color for symbol
* @param size symbol size (in mm)
* @param angle symbol rotation angle
* @param scaleMethod scaling method for data defined scaling
* @param penJoinStyle join style for outline pen
*/
QgsSimpleMarkerSymbolLayerV2( const QString& name = DEFAULT_SIMPLEMARKER_NAME,
const QColor& color = DEFAULT_SIMPLEMARKER_COLOR,
const QColor& borderColor = DEFAULT_SIMPLEMARKER_BORDERCOLOR,
double size = DEFAULT_SIMPLEMARKER_SIZE,
double angle = DEFAULT_SIMPLEMARKER_ANGLE,
QgsSymbolV2::ScaleMethod scaleMethod = DEFAULT_SCALE_METHOD );
QgsSymbolV2::ScaleMethod scaleMethod = DEFAULT_SCALE_METHOD,
Qt::PenJoinStyle penJoinStyle = DEFAULT_SIMPLEMARKER_JOINSTYLE );

// static stuff

Expand Down Expand Up @@ -70,9 +83,20 @@ class CORE_EXPORT QgsSimpleMarkerSymbolLayerV2 : public QgsMarkerSymbolLayerV2
QColor borderColor() const { return mBorderColor; }
void setBorderColor( const QColor& color ) { mBorderColor = color; }

/** Get outline join style.
* @note added in 2.4 */
Qt::PenStyle outlineStyle() const { return mOutlineStyle; }
/** Set outline join style.
* @note added in 2.4 */
void setOutlineStyle( Qt::PenStyle outlineStyle ) { mOutlineStyle = outlineStyle; }

/** Get outline join style.
* @note added in 2.16 */
Qt::PenJoinStyle penJoinStyle() const { return mPenJoinStyle; }
/** Set outline join style.
* @note added in 2.16 */
void setPenJoinStyle( Qt::PenJoinStyle style ) { mPenJoinStyle = style; }

/** Get outline color.
* @note added in 2.1 */
QColor outlineColor() const override { return borderColor(); }
Expand Down Expand Up @@ -122,6 +146,7 @@ class CORE_EXPORT QgsSimpleMarkerSymbolLayerV2 : public QgsMarkerSymbolLayerV2
double mOutlineWidth;
QgsSymbolV2::OutputUnit mOutlineWidthUnit;
QgsMapUnitScale mOutlineWidthMapUnitScale;
Qt::PenJoinStyle mPenJoinStyle;
QPen mPen;
QBrush mBrush;
QPolygonF mPolygon;
Expand Down
11 changes: 11 additions & 0 deletions src/gui/symbology-ng/qgssymbollayerv2widget.cpp
Expand Up @@ -455,6 +455,7 @@ QgsSimpleMarkerSymbolLayerV2Widget::QgsSimpleMarkerSymbolLayerV2Widget( const Qg
connect( lstNames, SIGNAL( currentRowChanged( int ) ), this, SLOT( setName() ) );
connect( btnChangeColorBorder, SIGNAL( colorChanged( const QColor& ) ), this, SLOT( setColorBorder( const QColor& ) ) );
connect( btnChangeColorFill, SIGNAL( colorChanged( const QColor& ) ), this, SLOT( setColorFill( const QColor& ) ) );
connect( cboJoinStyle, SIGNAL( currentIndexChanged( int ) ), this, SLOT( penJoinStyleChanged() ) );
connect( spinSize, SIGNAL( valueChanged( double ) ), this, SLOT( setSize() ) );
connect( spinAngle, SIGNAL( valueChanged( double ) ), this, SLOT( setAngle() ) );
connect( spinOffsetX, SIGNAL( valueChanged( double ) ), this, SLOT( setOffset() ) );
Expand Down Expand Up @@ -503,6 +504,9 @@ void QgsSimpleMarkerSymbolLayerV2Widget::setSymbolLayer( QgsSymbolLayerV2* layer
mOutlineWidthSpinBox->blockSignals( true );
mOutlineWidthSpinBox->setValue( mLayer->outlineWidth() );
mOutlineWidthSpinBox->blockSignals( false );
cboJoinStyle->blockSignals( true );
cboJoinStyle->setPenJoinStyle( mLayer->penJoinStyle() );
cboJoinStyle->blockSignals( false );

// without blocking signals the value gets changed because of slot setOffset()
spinOffsetX->blockSignals( true );
Expand Down Expand Up @@ -542,6 +546,7 @@ void QgsSimpleMarkerSymbolLayerV2Widget::setSymbolLayer( QgsSymbolLayerV2* layer
registerDataDefinedButton( mBorderColorDDBtn, "color_border", QgsDataDefinedButton::String, QgsDataDefinedButton::colorAlphaDesc() );
registerDataDefinedButton( mOutlineWidthDDBtn, "outline_width", QgsDataDefinedButton::Double, QgsDataDefinedButton::doublePosDesc() );
registerDataDefinedButton( mOutlineStyleDDBtn, "outline_style", QgsDataDefinedButton::String, QgsDataDefinedButton::lineStyleDesc() );
registerDataDefinedButton( mJoinStyleDDBtn, "join_style", QgsDataDefinedButton::String, QgsDataDefinedButton::penJoinStyleDesc() );
registerDataDefinedButton( mSizeDDBtn, "size", QgsDataDefinedButton::Double, QgsDataDefinedButton::doublePosDesc() );
registerDataDefinedButton( mAngleDDBtn, "angle", QgsDataDefinedButton::Double, QgsDataDefinedButton::double180RotDesc() );
registerDataDefinedButton( mOffsetDDBtn, "offset", QgsDataDefinedButton::String, QgsDataDefinedButton::doubleXYDesc() );
Expand Down Expand Up @@ -574,6 +579,12 @@ void QgsSimpleMarkerSymbolLayerV2Widget::setColorFill( const QColor& color )
emit changed();
}

void QgsSimpleMarkerSymbolLayerV2Widget::penJoinStyleChanged()
{
mLayer->setPenJoinStyle( cboJoinStyle->penJoinStyle() );
emit changed();
}

void QgsSimpleMarkerSymbolLayerV2Widget::setSize()
{
mLayer->setSize( spinSize->value() );
Expand Down
1 change: 1 addition & 0 deletions src/gui/symbology-ng/qgssymbollayerv2widget.h
Expand Up @@ -201,6 +201,7 @@ class GUI_EXPORT QgsSimpleMarkerSymbolLayerV2Widget : public QgsSymbolLayerV2Wid
private slots:

void updateAssistantSymbol();
void penJoinStyleChanged();

private:

Expand Down
37 changes: 34 additions & 3 deletions src/ui/symbollayer/widget_simplemarker.ui
Expand Up @@ -70,7 +70,7 @@
</item>
</layout>
</item>
<item row="6" column="1">
<item row="7" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QgsDoubleSpinBox" name="mOutlineWidthSpinBox">
Expand Down Expand Up @@ -295,7 +295,7 @@
</property>
</widget>
</item>
<item row="6" column="0">
<item row="7" column="0">
<widget class="QLabel" name="mOutlineWidthLabel">
<property name="text">
<string>Outline width</string>
Expand Down Expand Up @@ -323,6 +323,30 @@
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Join style</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="6" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_7">
<item>
<widget class="QgsPenJoinStyleComboBox" name="cboJoinStyle"/>
</item>
<item>
<widget class="QgsDataDefinedButton" name="mJoinStyleDDBtn">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
Expand Down Expand Up @@ -491,6 +515,11 @@
<header>qgsunitselectionwidget.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>QgsPenJoinStyleComboBox</class>
<extends>QComboBox</extends>
<header>qgspenstylecombobox.h</header>
</customwidget>
<customwidget>
<class>QgsPenStyleComboBox</class>
<extends>QComboBox</extends>
Expand All @@ -507,9 +536,11 @@
<tabstop>mSizeUnitWidget</tabstop>
<tabstop>mOutlineStyleComboBox</tabstop>
<tabstop>mOutlineStyleDDBtn</tabstop>
<tabstop>cboJoinStyle</tabstop>
<tabstop>mJoinStyleDDBtn</tabstop>
<tabstop>mOutlineWidthSpinBox</tabstop>
<tabstop>mOutlineWidthDDBtn</tabstop>
<tabstop>mOutlineWidthUnitWidget</tabstop>
<tabstop>mOutlineWidthUnitWidget</tabstop>
<tabstop>spinAngle</tabstop>
<tabstop>mAngleDDBtn</tabstop>
<tabstop>spinOffsetX</tabstop>
Expand Down

0 comments on commit 6ad3537

Please sign in to comment.