From e1e666fa3d99c54279a0957e5fb555baefde8852 Mon Sep 17 00:00:00 2001 From: Jim Evins Date: Sat, 11 Jan 2014 00:30:52 -0500 Subject: [PATCH] Implement region select capability in View. --- app/LabelRegion.cpp | 24 +++++++ app/LabelRegion.h | 9 +++ app/View.cpp | 156 +++++++++++++++++++++++++++++++++++++++----- app/View.h | 24 +++++-- 4 files changed, 192 insertions(+), 21 deletions(-) diff --git a/app/LabelRegion.cpp b/app/LabelRegion.cpp index e8125fd..3b73281 100644 --- a/app/LabelRegion.cpp +++ b/app/LabelRegion.cpp @@ -19,3 +19,27 @@ */ #include "LabelRegion.h" + +#include +#include + + +namespace glabels +{ + + QRectF LabelRegion::rect() const + { + using std::min; + using std::fabs; + + QRectF r; + + r.setX( min( mX1, mX2 ) ); + r.setY( min( mY1, mY2 ) ); + r.setWidth( fabs( mX2 - mX1 ) ); + r.setHeight( fabs( mY2 - mY1 ) ); + + return r; + } + +} diff --git a/app/LabelRegion.h b/app/LabelRegion.h index b10fbfc..6864365 100644 --- a/app/LabelRegion.h +++ b/app/LabelRegion.h @@ -21,6 +21,8 @@ #ifndef glabels_LabelRegion_h #define glabels_LabelRegion_h +#include + namespace glabels { @@ -64,6 +66,13 @@ namespace glabels inline void setY2( double value ); + ///////////////////////////////// + // Methods + ///////////////////////////////// + public: + QRectF rect() const; + + ///////////////////////////////// // Private Data ///////////////////////////////// diff --git a/app/View.cpp b/app/View.cpp index 7c6188a..8b6cda4 100644 --- a/app/View.cpp +++ b/app/View.cpp @@ -63,6 +63,10 @@ namespace const QColor markupLineColor( 240, 99, 99 ); const double markupLineWidthPixels = 1; + + const QColor selectRegionFillColor( 192, 192, 255, 128 ); + const QColor selectRegionOutlineColor( 0, 0, 255, 128 ); + const double selectRegionOutlineWidthPixels = 3; } @@ -74,6 +78,8 @@ namespace glabels /// View::View( QWidget *parent ) : QGraphicsView(parent) { + mState = IdleState; + setZoomReal( 1, false ); mModel = 0; @@ -85,11 +91,14 @@ namespace glabels mScene = new QGraphicsScene(); setScene( mScene ); - mScene->addItem( mLabelLayer = new QGraphicsItemGroup() ); - mScene->addItem( mGridLayer = new QGraphicsItemGroup() ); - mScene->addItem( mMarkupLayer = new QGraphicsItemGroup() ); - mScene->addItem( mObjectLayer = new QGraphicsItemGroup() ); - mScene->addItem( mForegroundLayer = new QGraphicsItemGroup() ); + mScene->addItem( mLabelLayer = new QGraphicsItemGroup() ); + mScene->addItem( mGridLayer = new QGraphicsItemGroup() ); + mScene->addItem( mMarkupLayer = new QGraphicsItemGroup() ); + mScene->addItem( mObjectLayer = new QGraphicsItemGroup() ); + mScene->addItem( mForegroundLayer = new QGraphicsItemGroup() ); + mScene->addItem( mSelectRegionLayer = new QGraphicsItemGroup() ); + + initSelectRegionLayer(); } @@ -100,16 +109,18 @@ namespace glabels { mModel = model; - createLabelLayer(); - createGridLayer(); - createMarkupLayer(); + mScene->setSceneRect( 0, 0, model->w(), model->h() ); + + initLabelLayer(); + initGridLayer(); + initMarkupLayer(); foreach (LabelModelObject* object, model->objectList() ) { addObjectToObjectLayer( object ); } - createForegroundLayer(); + initForegroundLayer(); } @@ -268,6 +279,25 @@ namespace glabels { QPointF pointer = mapToScene( event->x(), event->y() ); emit pointerMoved( pointer.x(), pointer.y() ); + + switch (mState) + { + + case IdleState: + break; + + case ArrowSelectRegionState: + mSelectRegion.setX2( pointer.x() ); + mSelectRegion.setY2( pointer.y() ); + + mSelectRegionItem->setRect( mSelectRegion.rect() ); + break; + + default: + // Should not happen! + break; + + } } @@ -280,6 +310,76 @@ namespace glabels } + /// + /// Mouse Button Press Event Handler + /// + void View::mousePressEvent( QMouseEvent* event ) + { + QPointF pointer = mapToScene( event->x(), event->y() ); + + if ( event->button() & Qt::LeftButton ) + { + // Select Region + if ( !(event->modifiers() & Qt::ControlModifier) ) + { + mModel->unselectAll(); + } + + mSelectRegion.setX1( pointer.x() ); + mSelectRegion.setY1( pointer.y() ); + mSelectRegion.setX2( pointer.x() ); + mSelectRegion.setY2( pointer.y() ); + + mSelectRegionItem->setRect( mSelectRegion.rect() ); + mSelectRegionLayer->setVisible( true ); + + mState = ArrowSelectRegionState; + } + else + { + } + } + + + /// + /// Mouse Button Release Event Handler + /// + void View::mouseReleaseEvent( QMouseEvent* event ) + { + QPointF pointer = mapToScene( event->x(), event->y() ); + + if ( event->button() & Qt::LeftButton ) + { + switch (mState) + { + + case IdleState: + break; + + case ArrowSelectRegionState: + mSelectRegion.setX2( pointer.x() ); + mSelectRegion.setY2( pointer.y() ); + + mSelectRegionItem->setRect( 0, 0, 0, 0 ); + mSelectRegionLayer->setVisible( false ); + + mModel->selectRegion( mSelectRegion ); + + mState = IdleState; + break; + + default: + // Should not happen! + break; + + } + } + else + { + } + } + + /// /// Clear Layer (Item Group) of All Child Items /// @@ -293,9 +393,9 @@ namespace glabels /// - /// Create Label Layer + /// Initialize Label Layer /// - void View::createLabelLayer() + void View::initLabelLayer() { clearLayer( mLabelLayer ); @@ -315,9 +415,9 @@ namespace glabels /// - /// Create Grid Layer + /// Initialize Grid Layer /// - void View::createGridLayer() + void View::initGridLayer() { clearLayer( mGridLayer ); @@ -361,9 +461,9 @@ namespace glabels /// - /// Create Markup Layer + /// Initialize Markup Layer /// - void View::createMarkupLayer() + void View::initMarkupLayer() { clearLayer( mMarkupLayer ); @@ -393,9 +493,9 @@ namespace glabels /// - /// Create Foreground Layer + /// Initialize Foreground Layer /// - void View::createForegroundLayer() + void View::initForegroundLayer() { clearLayer( mForegroundLayer ); @@ -410,4 +510,26 @@ namespace glabels mForegroundLayer->addToGroup( outlineItem ); } + + /// + /// Initialize Select Region Layer + /// + void View::initSelectRegionLayer() + { + clearLayer( mSelectRegionLayer ); + + mSelectRegionItem = new QGraphicsRectItem(); + + QBrush brush( selectRegionFillColor ); + mSelectRegionItem->setBrush( brush ); + + QPen pen( selectRegionOutlineColor ); + pen.setJoinStyle( Qt::MiterJoin ); + pen.setCosmetic( true ); + pen.setWidthF( selectRegionOutlineWidthPixels ); + mSelectRegionItem->setPen( pen ); + + mSelectRegionLayer->addToGroup( mSelectRegionItem ); + } + } diff --git a/app/View.h b/app/View.h index 368bc86..310eb94 100644 --- a/app/View.h +++ b/app/View.h @@ -23,6 +23,8 @@ #include +#include "LabelRegion.h" + class QGraphicsScene; class QGraphicsItemGroup; @@ -99,6 +101,8 @@ namespace glabels protected: void resizeEvent( QResizeEvent* event ); void mouseMoveEvent( QMouseEvent* event ); + void mousePressEvent( QMouseEvent* event ); + void mouseReleaseEvent( QMouseEvent* event ); void leaveEvent( QEvent* event ); @@ -107,17 +111,25 @@ namespace glabels ///////////////////////////////////// private: void clearLayer( QGraphicsItemGroup* layer ); - void createLabelLayer(); - void createGridLayer(); - void createMarkupLayer(); + void initLabelLayer(); + void initGridLayer(); + void initMarkupLayer(); void addObjectToObjectLayer( LabelModelObject* object ); - void createForegroundLayer(); + void initForegroundLayer(); + void initSelectRegionLayer(); ///////////////////////////////////// // Private data ///////////////////////////////////// private: + enum State { + IdleState, + ArrowSelectRegionState + }; + + State mState; + QGraphicsScene* mScene; QGraphicsItemGroup* mLabelLayer; @@ -125,6 +137,10 @@ namespace glabels QGraphicsItemGroup* mMarkupLayer; QGraphicsItemGroup* mObjectLayer; QGraphicsItemGroup* mForegroundLayer; + QGraphicsItemGroup* mSelectRegionLayer; + + QGraphicsRectItem* mSelectRegionItem; + LabelRegion mSelectRegion; double mZoom; bool mZoomToFitFlag;