Add moving spin box to enter numeric value for curve offset

This commit is contained in:
Marco Hugentobler 2012-02-18 14:14:45 +01:00
parent 41a3280103
commit 47667dbd55
4 changed files with 104 additions and 24 deletions

View File

@ -202,6 +202,7 @@ SET (QGIS_APP_MOC_HDRS
qgsmaptoolmovefeature.h qgsmaptoolmovefeature.h
qgsmaptoolmovelabel.h qgsmaptoolmovelabel.h
qgsmaptoolmovevertex.h qgsmaptoolmovevertex.h
qgsmaptooloffsetcurve.h
qgsmaptoolreshape.h qgsmaptoolreshape.h
qgsmaptoolrotatelabel.h qgsmaptoolrotatelabel.h
qgsmaptoolrotatepointsymbols.h qgsmaptoolrotatepointsymbols.h

View File

@ -18,15 +18,19 @@
#include "qgsmaplayerregistry.h" #include "qgsmaplayerregistry.h"
#include "qgsrubberband.h" #include "qgsrubberband.h"
#include "qgsvectorlayer.h" #include "qgsvectorlayer.h"
#include <QDoubleSpinBox>
#include <QGraphicsProxyWidget>
#include <QMouseEvent> #include <QMouseEvent>
QgsMapToolOffsetCurve::QgsMapToolOffsetCurve( QgsMapCanvas* canvas ): QgsMapToolEdit( canvas ), mRubberBand( 0 ), mOriginalGeometry( 0 ), mGeometryModified( false ), mDistanceItem( 0 ) QgsMapToolOffsetCurve::QgsMapToolOffsetCurve( QgsMapCanvas* canvas ): QgsMapToolEdit( canvas ), mRubberBand( 0 ),
mOriginalGeometry( 0 ), mGeometryModified( false ), mDistanceItem( 0 ), mDistanceSpinBox( 0 )
{ {
} }
QgsMapToolOffsetCurve::~QgsMapToolOffsetCurve() QgsMapToolOffsetCurve::~QgsMapToolOffsetCurve()
{ {
deleteRubberBandAndGeometry(); deleteRubberBandAndGeometry();
deleteDistanceItem();
} }
void QgsMapToolOffsetCurve::canvasPressEvent( QMouseEvent * e ) void QgsMapToolOffsetCurve::canvasPressEvent( QMouseEvent * e )
@ -57,8 +61,12 @@ void QgsMapToolOffsetCurve::canvasPressEvent( QMouseEvent * e )
{ {
mOriginalGeometry = createOriginGeometry( vl, snapResult, fet ); mOriginalGeometry = createOriginGeometry( vl, snapResult, fet );
mRubberBand = createRubberBand(); mRubberBand = createRubberBand();
if ( mRubberBand )
{
mRubberBand->setToGeometry( mOriginalGeometry, layer ); mRubberBand->setToGeometry( mOriginalGeometry, layer );
}
mModifiedFeature = fet.id(); mModifiedFeature = fet.id();
createDistanceItem();
} }
} }
} }
@ -66,6 +74,7 @@ void QgsMapToolOffsetCurve::canvasPressEvent( QMouseEvent * e )
void QgsMapToolOffsetCurve::canvasReleaseEvent( QMouseEvent * e ) void QgsMapToolOffsetCurve::canvasReleaseEvent( QMouseEvent * e )
{ {
Q_UNUSED( e );
QgsVectorLayer* vlayer = currentVectorLayer(); QgsVectorLayer* vlayer = currentVectorLayer();
if ( !vlayer || !mGeometryModified ) if ( !vlayer || !mGeometryModified )
{ {
@ -96,11 +105,28 @@ void QgsMapToolOffsetCurve::canvasReleaseEvent( QMouseEvent * e )
vlayer->destroyEditCommand(); vlayer->destroyEditCommand();
} }
delete mRubberBand; deleteRubberBandAndGeometry();
mRubberBand = 0; deleteDistanceItem();
mCanvas->refresh(); mCanvas->refresh();
} }
void QgsMapToolOffsetCurve::placeOffsetCurveToValue()
{
if ( mOriginalGeometry && mRubberBand && mRubberBand->numberOfVertices() > 0 )
{
//is rubber band left or right of original geometry
double leftOf = 0;
const QgsPoint* firstPoint = mRubberBand->getPoint( 0 );
if ( firstPoint )
{
QgsPoint minDistPoint;
int beforeVertex;
mOriginalGeometry->closestSegmentWithContext( *firstPoint, minDistPoint, beforeVertex, &leftOf );
}
setOffsetForRubberBand( mDistanceSpinBox->value(), leftOf < 0 );
}
}
void QgsMapToolOffsetCurve::canvasMoveEvent( QMouseEvent * e ) void QgsMapToolOffsetCurve::canvasMoveEvent( QMouseEvent * e )
{ {
if ( !mOriginalGeometry || !mRubberBand ) if ( !mOriginalGeometry || !mRubberBand )
@ -114,6 +140,12 @@ void QgsMapToolOffsetCurve::canvasMoveEvent( QMouseEvent * e )
return; return;
} }
if ( mDistanceItem )
{
mDistanceItem->show();
mDistanceItem->setPos( e->posF() + QPointF( 10, 10 ) );
}
mGeometryModified = true; mGeometryModified = true;
//get offset from current position rectangular to feature //get offset from current position rectangular to feature
@ -122,19 +154,13 @@ void QgsMapToolOffsetCurve::canvasMoveEvent( QMouseEvent * e )
int beforeVertex; int beforeVertex;
double leftOf; double leftOf;
double offset = sqrt( mOriginalGeometry->closestSegmentWithContext( layerCoords, minDistPoint, beforeVertex, &leftOf ) ); double offset = sqrt( mOriginalGeometry->closestSegmentWithContext( layerCoords, minDistPoint, beforeVertex, &leftOf ) );
//qWarning( QString::number( offset ).toLocal8Bit().data() );
//create offset geometry using geos //create offset geometry using geos
QgsGeometry geomCopy( *mOriginalGeometry ); setOffsetForRubberBand( offset, leftOf < 0 );
GEOSGeometry* geosGeom = geomCopy.asGeos();
if ( geosGeom ) if ( mDistanceSpinBox )
{ {
GEOSGeometry* offsetGeom = GEOSSingleSidedBuffer( geosGeom, offset, 8, 1, 1, ( leftOf < 0 ) ? 1 : 0 ); mDistanceSpinBox->setValue( offset );
if ( offsetGeom )
{
mModifiedGeometry.fromGeos( offsetGeom );
mRubberBand->setToGeometry( &mModifiedGeometry, layer );
}
} }
} }
@ -182,19 +208,35 @@ QgsGeometry* QgsMapToolOffsetCurve::createOriginGeometry( QgsVectorLayer* vl, co
} }
} }
QGraphicsProxyWidget* QgsMapToolOffsetCurve::createDistanceItem() void QgsMapToolOffsetCurve::createDistanceItem()
{ {
if ( !mCanvas ) if ( !mCanvas )
{ {
return 0; return;
} }
QGraphicsProxyWidget* pw = new QGraphicsProxyWidget(); deleteDistanceItem();
//Embed double spin box
QDoubleSpinBox* sb = new QDoubleSpinBox();
pw->setWidget( sb );
return pw; mDistanceItem = new QGraphicsProxyWidget();
mDistanceSpinBox = new QDoubleSpinBox();
mDistanceSpinBox->setMaximum( 99999999 );
mDistanceSpinBox->setDecimals( 2 );
mDistanceItem->setWidget( mDistanceSpinBox );
mCanvas->scene()->addItem( mDistanceItem );
mDistanceSpinBox->grabKeyboard();
mDistanceItem->hide();
QObject::connect( mDistanceSpinBox, SIGNAL( editingFinished() ), this, SLOT( placeOffsetCurveToValue() ) );
}
void QgsMapToolOffsetCurve::deleteDistanceItem()
{
if ( mDistanceSpinBox )
{
mDistanceSpinBox->releaseKeyboard();
}
delete mDistanceItem;
mDistanceItem = 0;
mDistanceSpinBox = 0;
} }
void QgsMapToolOffsetCurve::deleteRubberBandAndGeometry() void QgsMapToolOffsetCurve::deleteRubberBandAndGeometry()
@ -204,3 +246,30 @@ void QgsMapToolOffsetCurve::deleteRubberBandAndGeometry()
delete mOriginalGeometry; delete mOriginalGeometry;
mOriginalGeometry = 0; mOriginalGeometry = 0;
} }
void QgsMapToolOffsetCurve::setOffsetForRubberBand( double offset, bool leftSide )
{
if ( !mRubberBand || !mOriginalGeometry )
{
return;
}
QgsVectorLayer* sourceLayer = dynamic_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( mSourceLayerId ) );
if ( !sourceLayer )
{
return;
}
QgsGeometry geomCopy( *mOriginalGeometry );
GEOSGeometry* geosGeom = geomCopy.asGeos();
if ( geosGeom )
{
GEOSGeometry* offsetGeom = GEOSSingleSidedBuffer( geosGeom, offset, 8, 1, 1, leftSide ? 1 : 0 );
if ( offsetGeom )
{
mModifiedGeometry.fromGeos( offsetGeom );
mRubberBand->setToGeometry( &mModifiedGeometry, sourceLayer );
}
}
}

View File

@ -20,10 +20,12 @@
#include "qgsgeometry.h" #include "qgsgeometry.h"
#include "qgssnapper.h" #include "qgssnapper.h"
class QDoubleSpinBox;
class QGraphicsProxyWidget; class QGraphicsProxyWidget;
class QgsMapToolOffsetCurve: public QgsMapToolEdit class QgsMapToolOffsetCurve: public QgsMapToolEdit
{ {
Q_OBJECT
public: public:
QgsMapToolOffsetCurve( QgsMapCanvas* canvas ); QgsMapToolOffsetCurve( QgsMapCanvas* canvas );
~QgsMapToolOffsetCurve(); ~QgsMapToolOffsetCurve();
@ -32,6 +34,10 @@ class QgsMapToolOffsetCurve: public QgsMapToolEdit
void canvasReleaseEvent( QMouseEvent * e ); void canvasReleaseEvent( QMouseEvent * e );
void canvasMoveEvent( QMouseEvent * e ); void canvasMoveEvent( QMouseEvent * e );
private slots:
/**Places curve offset to value entered in the spin box*/
void placeOffsetCurveToValue();
private: private:
/**Rubberband that shows the position of the offset curve*/ /**Rubberband that shows the position of the offset curve*/
@ -46,13 +52,17 @@ class QgsMapToolOffsetCurve: public QgsMapToolEdit
QString mSourceLayerId; QString mSourceLayerId;
/**Internal flag to distinguish move from click*/ /**Internal flag to distinguish move from click*/
bool mGeometryModified; bool mGeometryModified;
/**Shows current distance value and allows numerical editing*/ /**Embedded item widget for distance spinbox*/
QGraphicsProxyWidget* mDistanceItem; QGraphicsProxyWidget* mDistanceItem;
/**Shows current distance value and allows numerical editing*/
QDoubleSpinBox* mDistanceSpinBox;
void deleteRubberBandAndGeometry(); void deleteRubberBandAndGeometry();
QgsGeometry* createOriginGeometry( QgsVectorLayer* vl, const QgsSnappingResult& sr, QgsFeature& snappedFeature ); QgsGeometry* createOriginGeometry( QgsVectorLayer* vl, const QgsSnappingResult& sr, QgsFeature& snappedFeature );
QGraphicsProxyWidget* createDistanceItem(); void createDistanceItem();
void deleteDistanceItem();
void setOffsetForRubberBand( double offset, bool leftSide );
}; };
#endif // QGSMAPTOOLOFFSETCURVE_H #endif // QGSMAPTOOLOFFSETCURVE_H

View File

@ -88,7 +88,7 @@ QgsMapCanvas::QgsMapCanvas( QWidget * parent, const char *name )
if ( viewport() ) if ( viewport() )
{ {
#ifndef ANDROID #ifndef ANDROID
viewport()->setAttribute( Qt::WA_PaintOnScreen, true ); //viewport()->setAttribute( Qt::WA_PaintOnScreen, true );
#endif //ANDROID #endif //ANDROID
} }