@@ -26,6 +26,8 @@ QgsComposerArrow::QgsComposerArrow( QgsComposition* c )
26
26
: QgsComposerItem( c )
27
27
, mStartPoint( 0 , 0 )
28
28
, mStopPoint( 0 , 0 )
29
+ , mStartXIdx( 0 )
30
+ , mStartYIdx( 0 )
29
31
, mMarkerMode( DefaultMarker )
30
32
, mArrowColor( QColor( 0 , 0 , 0 ) )
31
33
{
@@ -39,6 +41,8 @@ QgsComposerArrow::QgsComposerArrow( const QPointF& startPoint, const QPointF& st
39
41
, mMarkerMode( DefaultMarker )
40
42
, mArrowColor( QColor( 0 , 0 , 0 ) )
41
43
{
44
+ mStartXIdx = mStopPoint .x () < mStartPoint .x ();
45
+ mStartYIdx = mStopPoint .y () < mStartPoint .y ();
42
46
initGraphicsSettings ();
43
47
adaptItemSceneRect ();
44
48
}
@@ -97,18 +101,31 @@ void QgsComposerArrow::paint( QPainter* painter, const QStyleOptionGraphicsItem
97
101
98
102
void QgsComposerArrow::setSceneRect ( const QRectF& rectangle )
99
103
{
100
- // maintain the relative position of start and stop point in the rectangle
101
- double startPointXPos = ( mStartPoint .x () - pos ().x () ) / rect ().width ();
102
- double startPointYPos = ( mStartPoint .y () - pos ().y () ) / rect ().height ();
103
- double stopPointXPos = ( mStopPoint .x () - pos ().x () ) / rect ().width ();
104
- double stopPointYPos = ( mStopPoint .y () - pos ().y () ) / rect ().height ();
104
+ if ( rectangle.width () < 0 )
105
+ {
106
+ mStartXIdx = 1 - mStartXIdx ;
107
+ }
108
+ if ( rectangle.height () < 0 )
109
+ {
110
+ mStartYIdx = 1 - mStartYIdx ;
111
+ }
105
112
106
- mStartPoint .setX ( rectangle.left () + startPointXPos * rectangle.width () );
107
- mStartPoint .setY ( rectangle.top () + startPointYPos * rectangle.height () );
108
- mStopPoint .setX ( rectangle.left () + stopPointXPos * rectangle.width () );
109
- mStopPoint .setY ( rectangle.top () + stopPointYPos * rectangle.height () );
113
+ double margin = computeMarkerMargin ();
110
114
111
- adaptItemSceneRect ();
115
+ // Ensure the rectangle is at least as large as needed to include the markers
116
+ QRectF rect = rectangle.unite ( QRectF ( rectangle.x (), rectangle.y (), 2 . * margin, 2 . * margin ) );
117
+
118
+ // Compute new start and stop positions
119
+ double x[2 ] = {rect.x (), rect.x () + rect.width ()};
120
+ double y[2 ] = {rect.y (), rect.y () + rect.height ()};
121
+
122
+ double xsign = x[mStartXIdx ] < x[1 - mStartXIdx ] ? 1.0 : -1.0 ;
123
+ double ysign = y[mStartYIdx ] < y[1 - mStartYIdx ] ? 1.0 : -1.0 ;
124
+
125
+ mStartPoint = QPointF ( x[mStartXIdx ] + xsign * margin, y[mStartYIdx ] + ysign * margin );
126
+ mStopPoint = QPointF ( x[1 - mStartXIdx ] - xsign * margin, y[1 - mStartYIdx ] - ysign * margin );
127
+
128
+ QgsComposerItem::setSceneRect ( rect );
112
129
}
113
130
114
131
void QgsComposerArrow::drawHardcodedMarker ( QPainter *p, MarkerType type )
@@ -258,30 +275,41 @@ void QgsComposerArrow::setArrowHeadWidth( double width )
258
275
adaptItemSceneRect ();
259
276
}
260
277
261
- void QgsComposerArrow::adaptItemSceneRect ()
278
+ double QgsComposerArrow::computeMarkerMargin () const
262
279
{
263
- // rectangle containing start and end point
264
- QRectF rect = QRectF ( qMin ( mStartPoint .x (), mStopPoint .x () ), qMin ( mStartPoint .y (), mStopPoint .y () ),
265
- qAbs ( mStopPoint .x () - mStartPoint .x () ), qAbs ( mStopPoint .y () - mStartPoint .y () ) );
266
- double enlarge = 0 ;
280
+ double margin = 0 ;
267
281
if ( mMarkerMode == DefaultMarker )
268
282
{
269
- enlarge = mPen .widthF () / 2.0 + mArrowHeadWidth / 2.0 ;
283
+ margin = mPen .widthF () / 2.0 + mArrowHeadWidth / 2.0 ;
270
284
}
271
285
else if ( mMarkerMode == NoMarker )
272
286
{
273
- enlarge = mPen .widthF () / 2.0 ;
287
+ margin = mPen .widthF () / 2.0 ;
274
288
}
275
289
else if ( mMarkerMode == SVGMarker )
276
290
{
277
291
double maxArrowHeight = qMax ( mStartArrowHeadHeight , mStopArrowHeadHeight );
278
- enlarge = mPen .widthF () / 2 + qMax ( mArrowHeadWidth / 2.0 , maxArrowHeight / 2.0 );
292
+ margin = mPen .widthF () / 2 + qMax ( mArrowHeadWidth / 2.0 , maxArrowHeight / 2.0 );
279
293
}
294
+ return margin;
295
+ }
280
296
297
+ void QgsComposerArrow::adaptItemSceneRect ()
298
+ {
299
+ // rectangle containing start and end point
300
+ QRectF rect = QRectF ( qMin ( mStartPoint .x (), mStopPoint .x () ), qMin ( mStartPoint .y (), mStopPoint .y () ),
301
+ qAbs ( mStopPoint .x () - mStartPoint .x () ), qAbs ( mStopPoint .y () - mStartPoint .y () ) );
302
+ double enlarge = computeMarkerMargin ();
281
303
rect.adjust ( -enlarge, -enlarge, enlarge, enlarge );
282
304
QgsComposerItem::setSceneRect ( rect );
283
305
}
284
306
307
+ void QgsComposerArrow::setMarkerMode ( MarkerMode mode )
308
+ {
309
+ mMarkerMode = mode;
310
+ adaptItemSceneRect ();
311
+ }
312
+
285
313
bool QgsComposerArrow::writeXML ( QDomElement& elem, QDomDocument & doc ) const
286
314
{
287
315
QDomElement composerArrowElem = doc.createElement ( " ComposerArrow" );
@@ -362,7 +390,12 @@ bool QgsComposerArrow::readXML( const QDomElement& itemElem, const QDomDocument&
362
390
mStopPoint .setY ( stopPointElem.attribute ( " y" , " 0.0" ).toDouble () );
363
391
}
364
392
393
+ mStartXIdx = mStopPoint .x () < mStartPoint .x ();
394
+ mStartYIdx = mStopPoint .y () < mStartPoint .y ();
395
+
365
396
adaptItemSceneRect ();
366
397
emit itemChanged ();
367
398
return true ;
368
399
}
400
+
401
+
0 commit comments