From 7d6b7ccc507f6ef6362bf643a219d81b560e6549 Mon Sep 17 00:00:00 2001 From: Sandro Santilli Date: Fri, 6 Feb 2015 17:48:55 +0100 Subject: [PATCH] Show actually visible canvas area in overview (possibly rotated) Fix #11862 --- src/gui/qgsmapoverviewcanvas.cpp | 88 ++++++-------------------------- 1 file changed, 16 insertions(+), 72 deletions(-) diff --git a/src/gui/qgsmapoverviewcanvas.cpp b/src/gui/qgsmapoverviewcanvas.cpp index 45fef9c53fb..654dc5d2055 100644 --- a/src/gui/qgsmapoverviewcanvas.cpp +++ b/src/gui/qgsmapoverviewcanvas.cpp @@ -33,6 +33,8 @@ //! widget that serves as rectangle showing current extent in overview class QgsPanningWidget : public QWidget { + QPolygon mPoly; + public: QgsPanningWidget( QWidget* parent ) : QWidget( parent ) @@ -42,13 +44,12 @@ class QgsPanningWidget : public QWidget setAttribute( Qt::WA_NoSystemBackground ); } - void resizeEvent( QResizeEvent* r ) override + void setPolygon( const QPolygon& p ) { - QSize s = r->size(); - QRegion reg( 0, 0, s.width(), s.height() ); - QRegion reg2( 2, 2, s.width() - 4, s.height() - 4 ); - QRegion reg3 = reg.subtracted( reg2 ); - setMask( reg3 ); + if ( p == mPoly ) return; + mPoly = p; + setGeometry( p.boundingRect() ); + repaint(); } @@ -56,12 +57,11 @@ class QgsPanningWidget : public QWidget { Q_UNUSED( pe ); - QRect r( QPoint( 0, 0 ), size() ); QPainter p; p.begin( this ); p.setPen( Qt::red ); - p.setBrush( Qt::red ); - p.drawRect( r ); + QPolygonF t = mPoly.translated( -mPoly.boundingRect().left(), -mPoly.boundingRect().top() ); + p.drawConvexPolygon( t ); p.end(); } @@ -122,70 +122,14 @@ void QgsMapOverviewCanvas::drawExtentRect() return; } + const QPolygonF& vPoly = mMapCanvas->mapSettings().visiblePolygon(); const QgsMapToPixel& cXf = mSettings.mapToPixel(); - QgsPoint ll( extent.xMinimum(), extent.yMinimum() ); - QgsPoint ur( extent.xMaximum(), extent.yMaximum() ); - - // transform the points before drawing - cXf.transform( &ll ); - cXf.transform( &ur ); - -#if 0 - // test whether panning widget should be drawn - bool show = false; - if ( ur.x() >= 0 && ur.x() < width() ) - show = true; - if ( ll.x() >= 0 && ll.x() < width() ) - show = true; - if ( ur.y() >= 0 && ur.y() < height() ) - show = true; - if ( ll.y() >= 0 && ll.y() < height() ) - show = true; - if ( !show ) - { - QgsDebugMsg( "panning: extent out of overview area" ); - mPanningWidget->hide(); - return; - } -#endif - - // round values - int x1 = static_cast( ur.x() + 0.5 ), x2 = static_cast( ll.x() + 0.5 ); - int y1 = static_cast( ur.y() + 0.5 ), y2 = static_cast( ll.y() + 0.5 ); - - if ( x1 > x2 ) - std::swap( x1, x2 ); - if ( y1 > y2 ) - std::swap( y1, y2 ); - -#ifdef Q_OS_MAC - // setGeometry (Qt 4.2) is causing Mac window corruption (decorations - // are drawn at odd locations) if both coords are at limit. This may - // have something to do with Qt calculating dimensions as x2 - x1 + 1. - // (INT_MAX - INT_MIN + 1 is UINT_MAX + 1) - if ( x1 == INT_MIN && x2 == INT_MAX ) - x1 += 1; // x2 -= 1 works too - if ( y1 == INT_MIN && y2 == INT_MAX ) - y1 += 1; -#endif - - QRect r( x1, y1, x2 - x1 + 1, y2 - y1 + 1 ); - - // allow for 5 pixel minimum widget size - if ( r.width() < 5 && x1 > INT_MIN + 2 ) // make sure no underflow occurs (2 is largest adjustment) - { - r.setX( r.x() - (( 5 - r.width() ) / 2 ) ); // adjust x by 1/2 the difference of calculated and min. width - r.setWidth( 5 ); - } - if ( r.height() < 5 && y1 > INT_MIN + 2 ) - { - r.setY( r.y() - (( 5 - r.height() ) / 2 ) ); // adjust y - r.setHeight( 5 ); - } - - QgsDebugMsg( QString( "panning: extent to widget: [%1,%2] [%3x%4]" ).arg( x1 ).arg( y1 ).arg( r.width() ).arg( r.height() ) ); - - mPanningWidget->setGeometry( r ); + QVector< QPoint > pts; + pts.push_back( cXf.transform( QgsPoint(vPoly[0]) ).toQPointF().toPoint() ); + pts.push_back( cXf.transform( QgsPoint(vPoly[1]) ).toQPointF().toPoint() ); + pts.push_back( cXf.transform( QgsPoint(vPoly[2]) ).toQPointF().toPoint() ); + pts.push_back( cXf.transform( QgsPoint(vPoly[3]) ).toQPointF().toPoint() ); + mPanningWidget->setPolygon( QPolygon(pts) ); mPanningWidget->show(); // show if hidden }