Skip to content

Commit 61ecac3

Browse files
author
mhugent
committed
Move code to draw arrow head from composer arrow to composer item
git-svn-id: http://svn.osgeo.org/qgis/trunk@13328 c8812cc2-4d05-0410-92ff-de0c093fc19c
1 parent 63ef719 commit 61ecac3

File tree

5 files changed

+71
-48
lines changed

5 files changed

+71
-48
lines changed

python/core/qgscomposeritem.sip

+6
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,12 @@ class QgsComposerItem: QObject, QGraphicsRectItem
181181
/**Draw background*/
182182
virtual void drawBackground( QPainter* p );
183183

184+
/**Draws arrowhead*/
185+
void drawArrowHead( QPainter* p, double x, double y, double angle, double arrowHeadWidth ) const;
186+
187+
/**Returns angle of the line from p1 to p2 (clockwise, starting at N)*/
188+
double angle( const QPointF& p1, const QPointF& p2 ) const;
189+
184190
/**Returns the current (zoom level dependent) tolerance to decide if mouse position is close enough to the \
185191
item border for resizing*/
186192
double rectHandlerBorderTolerance() const;

src/core/composer/qgscomposerarrow.cpp

+4-46
Original file line numberDiff line numberDiff line change
@@ -105,43 +105,15 @@ void QgsComposerArrow::setSceneRect( const QRectF& rectangle )
105105

106106
void QgsComposerArrow::drawHardcodedMarker( QPainter* p, MarkerType type )
107107
{
108-
double angle = arrowAngle();
109-
//qWarning(QString::number(angle).toLocal8Bit().data());
110-
double angleRad = angle / 180.0 * M_PI;
111-
QPointF middlePoint = QPointF( mStopPoint.x() - transform().dx(), mStopPoint.y() - transform().dy() );
112-
113-
//rotate both arrow points
114-
QPointF p1 = QPointF( -mArrowHeadWidth / 2.0, mArrowHeadWidth );
115-
QPointF p2 = QPointF( mArrowHeadWidth / 2.0, mArrowHeadWidth );
116-
117-
QPointF p1Rotated, p2Rotated;
118-
p1Rotated.setX( p1.x() * cos( angleRad ) + p1.y() * -sin( angleRad ) );
119-
p1Rotated.setY( p1.x() * sin( angleRad ) + p1.y() * cos( angleRad ) );
120-
p2Rotated.setX( p2.x() * cos( angleRad ) + p2.y() * -sin( angleRad ) );
121-
p2Rotated.setY( p2.x() * sin( angleRad ) + p2.y() * cos( angleRad ) );
122-
123-
QPolygonF arrowHeadPoly;
124-
arrowHeadPoly << middlePoint;
125-
arrowHeadPoly << QPointF( middlePoint.x() + p1Rotated.x(), middlePoint.y() + p1Rotated.y() );
126-
arrowHeadPoly << QPointF( middlePoint.x() + p2Rotated.x(), middlePoint.y() + p2Rotated.y() );
127-
128-
p->save();
129-
130-
QPen arrowPen = p->pen();
131-
arrowPen.setJoinStyle( Qt::RoundJoin );
132108
QBrush arrowBrush = p->brush();
133109
arrowBrush.setColor( mArrowColor );
134-
arrowBrush.setStyle( Qt::SolidPattern );
135-
p->setPen( arrowPen );
136110
p->setBrush( arrowBrush );
137-
p->drawPolygon( arrowHeadPoly );
138-
139-
p->restore();
111+
drawArrowHead( p, mStopPoint.x() - transform().dx(), mStopPoint.y() - transform().dy(), angle( mStartPoint, mStopPoint ), mArrowHeadWidth );
140112
}
141113

142114
void QgsComposerArrow::drawSVGMarker( QPainter* p, MarkerType type, const QString& markerPath )
143115
{
144-
double angle = arrowAngle();
116+
double ang = angle( mStartPoint, mStopPoint );
145117

146118
double arrowHeadHeight;
147119
if ( type == StartMarker )
@@ -211,7 +183,7 @@ void QgsComposerArrow::drawSVGMarker( QPainter* p, MarkerType type, const QStrin
211183
fixPoint.setX( 0 ); fixPoint.setY( -arrowHeadHeight / 2.0 );
212184
}
213185
QPointF rotatedFixPoint;
214-
double angleRad = angle / 180 * M_PI;
186+
double angleRad = ang / 180 * M_PI;
215187
rotatedFixPoint.setX( fixPoint.x() * cos( angleRad ) + fixPoint.y() * -sin( angleRad ) );
216188
rotatedFixPoint.setY( fixPoint.x() * sin( angleRad ) + fixPoint.y() * cos( angleRad ) );
217189

@@ -221,7 +193,7 @@ void QgsComposerArrow::drawSVGMarker( QPainter* p, MarkerType type, const QStrin
221193

222194
p->save();
223195
p->translate( canvasPoint.x() - rotatedFixPoint.x() , canvasPoint.y() - rotatedFixPoint.y() );
224-
p->rotate( angle );
196+
p->rotate( ang );
225197
p->translate( -mArrowHeadWidth / 2.0, -arrowHeadHeight / 2.0 );
226198

227199
p->drawImage( QRectF( 0, 0, mArrowHeadWidth, arrowHeadHeight ), markerImage, QRectF( 0, 0, imageWidth, imageHeight ) );
@@ -230,20 +202,6 @@ void QgsComposerArrow::drawSVGMarker( QPainter* p, MarkerType type, const QStrin
230202
return;
231203
}
232204

233-
double QgsComposerArrow::arrowAngle() const
234-
{
235-
double xDiff = mStopPoint.x() - mStartPoint.x();
236-
double yDiff = mStopPoint.y() - mStartPoint.y();
237-
double length = sqrt( xDiff * xDiff + yDiff * yDiff );
238-
239-
double angle = acos(( -yDiff * length ) / ( length * length ) ) * 180 / M_PI;
240-
if ( xDiff < 0 )
241-
{
242-
return ( 360 - angle );
243-
}
244-
return angle;
245-
}
246-
247205
void QgsComposerArrow::setStartMarker( const QString& svgPath )
248206
{
249207
QSvgRenderer r;

src/core/composer/qgscomposerarrow.h

-2
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,6 @@ class CORE_EXPORT QgsComposerArrow: public QgsComposerItem
108108
void drawHardcodedMarker( QPainter* p, MarkerType type );
109109
/**Draws a user-defined marker (must be an svg file)*/
110110
void drawSVGMarker( QPainter* p, MarkerType type, const QString& markerPath );
111-
/**Calculates arrow angle (for marker rotation)*/
112-
double arrowAngle() const;
113111
/**Apply default graphics settings*/
114112
void initGraphicsSettings();
115113
};

src/core/composer/qgscomposeritem.cpp

+55
Original file line numberDiff line numberDiff line change
@@ -721,6 +721,43 @@ void QgsComposerItem::drawText( QPainter* p, const QRectF& rect, const QString&
721721
p->restore();
722722
}
723723

724+
void QgsComposerItem::drawArrowHead( QPainter* p, double x, double y, double angle, double arrowHeadWidth ) const
725+
{
726+
if ( !p )
727+
{
728+
return;
729+
}
730+
double angleRad = angle / 180.0 * M_PI;
731+
QPointF middlePoint( x, y );
732+
//rotate both arrow points
733+
QPointF p1 = QPointF( -arrowHeadWidth / 2.0, arrowHeadWidth );
734+
QPointF p2 = QPointF( arrowHeadWidth / 2.0, arrowHeadWidth );
735+
736+
QPointF p1Rotated, p2Rotated;
737+
p1Rotated.setX( p1.x() * cos( angleRad ) + p1.y() * -sin( angleRad ) );
738+
p1Rotated.setY( p1.x() * sin( angleRad ) + p1.y() * cos( angleRad ) );
739+
p2Rotated.setX( p2.x() * cos( angleRad ) + p2.y() * -sin( angleRad ) );
740+
p2Rotated.setY( p2.x() * sin( angleRad ) + p2.y() * cos( angleRad ) );
741+
742+
QPolygonF arrowHeadPoly;
743+
arrowHeadPoly << middlePoint;
744+
arrowHeadPoly << QPointF( middlePoint.x() + p1Rotated.x(), middlePoint.y() + p1Rotated.y() );
745+
arrowHeadPoly << QPointF( middlePoint.x() + p2Rotated.x(), middlePoint.y() + p2Rotated.y() );
746+
747+
p->save();
748+
749+
QPen arrowPen = p->pen();
750+
arrowPen.setJoinStyle( Qt::RoundJoin );
751+
QBrush arrowBrush = p->brush();
752+
arrowBrush.setStyle( Qt::SolidPattern );
753+
p->setPen( arrowPen );
754+
p->setBrush( arrowBrush );
755+
arrowBrush.setStyle( Qt::SolidPattern );
756+
p->drawPolygon( arrowHeadPoly );
757+
758+
p->restore();
759+
}
760+
724761
double QgsComposerItem::textWidthMillimeters( const QFont& font, const QString& text ) const
725762
{
726763
QFont metricsFont = scaledFontPixelSize( font );
@@ -748,6 +785,24 @@ QFont QgsComposerItem::scaledFontPixelSize( const QFont& font ) const
748785
return scaledFont;
749786
}
750787

788+
double QgsComposerItem::angle( const QPointF& p1, const QPointF& p2 ) const
789+
{
790+
double xDiff = p2.x() - p1.x();
791+
double yDiff = p2.y() - p1.y();
792+
double length = sqrt( xDiff * xDiff + yDiff * yDiff );
793+
if ( length <= 0 )
794+
{
795+
return 0;
796+
}
797+
798+
double angle = acos(( -yDiff * length ) / ( length * length ) ) * 180 / M_PI;
799+
if ( xDiff < 0 )
800+
{
801+
return ( 360 - angle );
802+
}
803+
return angle;
804+
}
805+
751806
double QgsComposerItem::horizontalViewScaleFactor() const
752807
{
753808
double result = -1;

src/core/composer/qgscomposeritem.h

+6
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,12 @@ class CORE_EXPORT QgsComposerItem: public QObject, public QGraphicsRectItem
233233
/**Draw background*/
234234
virtual void drawBackground( QPainter* p );
235235

236+
/**Draws arrowhead*/
237+
void drawArrowHead( QPainter* p, double x, double y, double angle, double arrowHeadWidth ) const;
238+
239+
/**Returns angle of the line from p1 to p2 (clockwise, starting at N)*/
240+
double angle( const QPointF& p1, const QPointF& p2 ) const;
241+
236242
/**Returns the current (zoom level dependent) tolerance to decide if mouse position is close enough to the \
237243
item border for resizing*/
238244
double rectHandlerBorderTolerance() const;

0 commit comments

Comments
 (0)