mirror of
https://github.com/qgis/QGIS.git
synced 2025-02-28 00:17:30 -05:00
Merge pull request #1300 from manisandro/fix_composer_arrow_bbox
Improve print composer arrow bounding box logic
This commit is contained in:
commit
241e2f7fbd
@ -26,6 +26,8 @@ QgsComposerArrow::QgsComposerArrow( QgsComposition* c )
|
|||||||
: QgsComposerItem( c )
|
: QgsComposerItem( c )
|
||||||
, mStartPoint( 0, 0 )
|
, mStartPoint( 0, 0 )
|
||||||
, mStopPoint( 0, 0 )
|
, mStopPoint( 0, 0 )
|
||||||
|
, mStartXIdx( 0 )
|
||||||
|
, mStartYIdx( 0 )
|
||||||
, mMarkerMode( DefaultMarker )
|
, mMarkerMode( DefaultMarker )
|
||||||
, mArrowColor( QColor( 0, 0, 0 ) )
|
, mArrowColor( QColor( 0, 0, 0 ) )
|
||||||
{
|
{
|
||||||
@ -39,6 +41,8 @@ QgsComposerArrow::QgsComposerArrow( const QPointF& startPoint, const QPointF& st
|
|||||||
, mMarkerMode( DefaultMarker )
|
, mMarkerMode( DefaultMarker )
|
||||||
, mArrowColor( QColor( 0, 0, 0 ) )
|
, mArrowColor( QColor( 0, 0, 0 ) )
|
||||||
{
|
{
|
||||||
|
mStartXIdx = mStopPoint.x() < mStartPoint.x();
|
||||||
|
mStartYIdx = mStopPoint.y() < mStartPoint.y();
|
||||||
initGraphicsSettings();
|
initGraphicsSettings();
|
||||||
adaptItemSceneRect();
|
adaptItemSceneRect();
|
||||||
}
|
}
|
||||||
@ -97,18 +101,31 @@ void QgsComposerArrow::paint( QPainter* painter, const QStyleOptionGraphicsItem
|
|||||||
|
|
||||||
void QgsComposerArrow::setSceneRect( const QRectF& rectangle )
|
void QgsComposerArrow::setSceneRect( const QRectF& rectangle )
|
||||||
{
|
{
|
||||||
//maintain the relative position of start and stop point in the rectangle
|
if ( rectangle.width() < 0 )
|
||||||
double startPointXPos = ( mStartPoint.x() - pos().x() ) / rect().width();
|
{
|
||||||
double startPointYPos = ( mStartPoint.y() - pos().y() ) / rect().height();
|
mStartXIdx = 1 - mStartXIdx;
|
||||||
double stopPointXPos = ( mStopPoint.x() - pos().x() ) / rect().width();
|
}
|
||||||
double stopPointYPos = ( mStopPoint.y() - pos().y() ) / rect().height();
|
if ( rectangle.height() < 0 )
|
||||||
|
{
|
||||||
|
mStartYIdx = 1 - mStartYIdx;
|
||||||
|
}
|
||||||
|
|
||||||
mStartPoint.setX( rectangle.left() + startPointXPos * rectangle.width() );
|
double margin = computeMarkerMargin();
|
||||||
mStartPoint.setY( rectangle.top() + startPointYPos * rectangle.height() );
|
|
||||||
mStopPoint.setX( rectangle.left() + stopPointXPos * rectangle.width() );
|
|
||||||
mStopPoint.setY( rectangle.top() + stopPointYPos * rectangle.height() );
|
|
||||||
|
|
||||||
adaptItemSceneRect();
|
// Ensure the rectangle is at least as large as needed to include the markers
|
||||||
|
QRectF rect = rectangle.unite( QRectF( rectangle.x(), rectangle.y(), 2. * margin, 2. * margin ) );
|
||||||
|
|
||||||
|
// Compute new start and stop positions
|
||||||
|
double x[2] = {rect.x(), rect.x() + rect.width()};
|
||||||
|
double y[2] = {rect.y(), rect.y() + rect.height()};
|
||||||
|
|
||||||
|
double xsign = x[mStartXIdx] < x[1 - mStartXIdx] ? 1.0 : -1.0;
|
||||||
|
double ysign = y[mStartYIdx] < y[1 - mStartYIdx] ? 1.0 : -1.0;
|
||||||
|
|
||||||
|
mStartPoint = QPointF( x[mStartXIdx] + xsign * margin, y[mStartYIdx] + ysign * margin );
|
||||||
|
mStopPoint = QPointF( x[1 - mStartXIdx] - xsign * margin, y[1 - mStartYIdx] - ysign * margin );
|
||||||
|
|
||||||
|
QgsComposerItem::setSceneRect( rect );
|
||||||
}
|
}
|
||||||
|
|
||||||
void QgsComposerArrow::drawHardcodedMarker( QPainter *p, MarkerType type )
|
void QgsComposerArrow::drawHardcodedMarker( QPainter *p, MarkerType type )
|
||||||
@ -258,30 +275,41 @@ void QgsComposerArrow::setArrowHeadWidth( double width )
|
|||||||
adaptItemSceneRect();
|
adaptItemSceneRect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double QgsComposerArrow::computeMarkerMargin() const
|
||||||
|
{
|
||||||
|
double margin = 0;
|
||||||
|
if ( mMarkerMode == DefaultMarker )
|
||||||
|
{
|
||||||
|
margin = mPen.widthF() / 2.0 + mArrowHeadWidth / 2.0;
|
||||||
|
}
|
||||||
|
else if ( mMarkerMode == NoMarker )
|
||||||
|
{
|
||||||
|
margin = mPen.widthF() / 2.0;
|
||||||
|
}
|
||||||
|
else if ( mMarkerMode == SVGMarker )
|
||||||
|
{
|
||||||
|
double maxArrowHeight = qMax( mStartArrowHeadHeight, mStopArrowHeadHeight );
|
||||||
|
margin = mPen.widthF() / 2 + qMax( mArrowHeadWidth / 2.0, maxArrowHeight / 2.0 );
|
||||||
|
}
|
||||||
|
return margin;
|
||||||
|
}
|
||||||
|
|
||||||
void QgsComposerArrow::adaptItemSceneRect()
|
void QgsComposerArrow::adaptItemSceneRect()
|
||||||
{
|
{
|
||||||
//rectangle containing start and end point
|
//rectangle containing start and end point
|
||||||
QRectF rect = QRectF( qMin( mStartPoint.x(), mStopPoint.x() ), qMin( mStartPoint.y(), mStopPoint.y() ),
|
QRectF rect = QRectF( qMin( mStartPoint.x(), mStopPoint.x() ), qMin( mStartPoint.y(), mStopPoint.y() ),
|
||||||
qAbs( mStopPoint.x() - mStartPoint.x() ), qAbs( mStopPoint.y() - mStartPoint.y() ) );
|
qAbs( mStopPoint.x() - mStartPoint.x() ), qAbs( mStopPoint.y() - mStartPoint.y() ) );
|
||||||
double enlarge = 0;
|
double enlarge = computeMarkerMargin();
|
||||||
if ( mMarkerMode == DefaultMarker )
|
|
||||||
{
|
|
||||||
enlarge = mPen.widthF() / 2.0 + mArrowHeadWidth / 2.0;
|
|
||||||
}
|
|
||||||
else if ( mMarkerMode == NoMarker )
|
|
||||||
{
|
|
||||||
enlarge = mPen.widthF() / 2.0;
|
|
||||||
}
|
|
||||||
else if ( mMarkerMode == SVGMarker )
|
|
||||||
{
|
|
||||||
double maxArrowHeight = qMax( mStartArrowHeadHeight, mStopArrowHeadHeight );
|
|
||||||
enlarge = mPen.widthF() / 2 + qMax( mArrowHeadWidth / 2.0, maxArrowHeight / 2.0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
rect.adjust( -enlarge, -enlarge, enlarge, enlarge );
|
rect.adjust( -enlarge, -enlarge, enlarge, enlarge );
|
||||||
QgsComposerItem::setSceneRect( rect );
|
QgsComposerItem::setSceneRect( rect );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QgsComposerArrow::setMarkerMode( MarkerMode mode )
|
||||||
|
{
|
||||||
|
mMarkerMode = mode;
|
||||||
|
adaptItemSceneRect();
|
||||||
|
}
|
||||||
|
|
||||||
bool QgsComposerArrow::writeXML( QDomElement& elem, QDomDocument & doc ) const
|
bool QgsComposerArrow::writeXML( QDomElement& elem, QDomDocument & doc ) const
|
||||||
{
|
{
|
||||||
QDomElement composerArrowElem = doc.createElement( "ComposerArrow" );
|
QDomElement composerArrowElem = doc.createElement( "ComposerArrow" );
|
||||||
@ -362,7 +390,12 @@ bool QgsComposerArrow::readXML( const QDomElement& itemElem, const QDomDocument&
|
|||||||
mStopPoint.setY( stopPointElem.attribute( "y", "0.0" ).toDouble() );
|
mStopPoint.setY( stopPointElem.attribute( "y", "0.0" ).toDouble() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mStartXIdx = mStopPoint.x() < mStartPoint.x();
|
||||||
|
mStartYIdx = mStopPoint.y() < mStartPoint.y();
|
||||||
|
|
||||||
adaptItemSceneRect();
|
adaptItemSceneRect();
|
||||||
emit itemChanged();
|
emit itemChanged();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ class CORE_EXPORT QgsComposerArrow: public QgsComposerItem
|
|||||||
void setArrowColor( const QColor& c ) { mArrowColor = c; }
|
void setArrowColor( const QColor& c ) { mArrowColor = c; }
|
||||||
|
|
||||||
MarkerMode markerMode() const { return mMarkerMode;}
|
MarkerMode markerMode() const { return mMarkerMode;}
|
||||||
void setMarkerMode( MarkerMode mode ) {mMarkerMode = mode;}
|
void setMarkerMode( MarkerMode mode );
|
||||||
|
|
||||||
/** stores state in Dom element
|
/** stores state in Dom element
|
||||||
* @param elem is Dom element corresponding to 'Composer' tag
|
* @param elem is Dom element corresponding to 'Composer' tag
|
||||||
@ -88,6 +88,12 @@ class CORE_EXPORT QgsComposerArrow: public QgsComposerItem
|
|||||||
QPointF mStartPoint;
|
QPointF mStartPoint;
|
||||||
QPointF mStopPoint;
|
QPointF mStopPoint;
|
||||||
|
|
||||||
|
/**Considering the rectangle as spanning [x[0], x[1]] x [y[0], y[1]], these
|
||||||
|
* indices specify which index {0, 1} corresponds to the start point
|
||||||
|
* coordinate of the respective dimension*/
|
||||||
|
int mStartXIdx;
|
||||||
|
int mStartYIdx;
|
||||||
|
|
||||||
QPen mPen;
|
QPen mPen;
|
||||||
QBrush mBrush;
|
QBrush mBrush;
|
||||||
|
|
||||||
@ -110,6 +116,8 @@ class CORE_EXPORT QgsComposerArrow: public QgsComposerItem
|
|||||||
/**Adapts the item scene rect to contain the start point, the stop point including the arrow marker and the outline.
|
/**Adapts the item scene rect to contain the start point, the stop point including the arrow marker and the outline.
|
||||||
Needs to be called whenever the arrow width/height, the outline with or the endpoints are changed*/
|
Needs to be called whenever the arrow width/height, the outline with or the endpoints are changed*/
|
||||||
void adaptItemSceneRect();
|
void adaptItemSceneRect();
|
||||||
|
/**Computes the margin around the line necessary to include the markers */
|
||||||
|
double computeMarkerMargin() const;
|
||||||
/**Draws the default marker at the line end*/
|
/**Draws the default marker at the line end*/
|
||||||
void drawHardcodedMarker( QPainter* p, MarkerType type );
|
void drawHardcodedMarker( QPainter* p, MarkerType type );
|
||||||
/**Draws a user-defined marker (must be an svg file)*/
|
/**Draws a user-defined marker (must be an svg file)*/
|
||||||
@ -119,3 +127,5 @@ class CORE_EXPORT QgsComposerArrow: public QgsComposerItem
|
|||||||
};
|
};
|
||||||
|
|
||||||
#endif // QGSCOMPOSERARROW_H
|
#endif // QGSCOMPOSERARROW_H
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user