From: ouv Date: Thu, 27 Jun 2013 15:50:32 +0000 (+0000) Subject: Raw development for ImageViewer. X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=e11264e5369b055c9c3fcde92748af60c07d21b7;p=modules%2Fgui.git Raw development for ImageViewer. --- diff --git a/src/GraphicsView/GraphicsView_Object.cxx b/src/GraphicsView/GraphicsView_Object.cxx index 859608fca..47d3959ae 100644 --- a/src/GraphicsView/GraphicsView_Object.cxx +++ b/src/GraphicsView/GraphicsView_Object.cxx @@ -23,6 +23,7 @@ #include "GraphicsView_Object.h" #include "GraphicsView_Scene.h" +#include "GraphicsView_ViewPort.h" //======================================================================= // Name : GraphicsView_Object @@ -33,8 +34,10 @@ GraphicsView_Object::GraphicsView_Object( QGraphicsItem* theParent ) myPriority( 0 ), myIsOnTop( false ), myIsHighlighted( false ), - myIsSelected( false ) + myIsSelected( false ), + myIsMoving( false ) { + myHighlightCursor = new QCursor( Qt::OpenHandCursor ); } //======================================================================= @@ -43,6 +46,31 @@ GraphicsView_Object::GraphicsView_Object( QGraphicsItem* theParent ) //======================================================================= GraphicsView_Object::~GraphicsView_Object() { + if( myHighlightCursor ) + { + delete myHighlightCursor; + myHighlightCursor = 0; + } +} + +//================================================================ +// Function : addTo +// Purpose : +//================================================================ +void GraphicsView_Object::addTo( GraphicsView_ViewPort* theViewPort ) +{ + if( QGraphicsScene* aScene = theViewPort->scene() ) + aScene->addItem( this ); +} + +//================================================================ +// Function : removeFrom +// Purpose : +//================================================================ +void GraphicsView_Object::removeFrom( GraphicsView_ViewPort* theViewPort ) +{ + if( QGraphicsScene* aScene = theViewPort->scene() ) + aScene->removeItem( this ); } //================================================================ @@ -67,9 +95,9 @@ QRectF GraphicsView_Object::getRect() const // Function : checkHighlight // Purpose : //================================================================ -bool GraphicsView_Object::checkHighlight( double theX, double theY ) const +bool GraphicsView_Object::checkHighlight( double theX, double theY, QCursor& theCursor ) const { - return getRect().contains( theX, theY ); + return !getRect().isNull() && getRect().contains( theX, theY ); } //================================================================ @@ -78,8 +106,9 @@ bool GraphicsView_Object::checkHighlight( double theX, double theY ) const //================================================================ bool GraphicsView_Object::highlight( double theX, double theY ) { + QCursor aCursor; if( myIsHighlighted = isVisible() ) - myIsHighlighted = checkHighlight( theX, theY ); + myIsHighlighted = checkHighlight( theX, theY, aCursor ); return myIsHighlighted; } @@ -98,12 +127,13 @@ void GraphicsView_Object::unhighlight() //================================================================ bool GraphicsView_Object::select( double theX, double theY, const QRectF& theRect ) { + QCursor aCursor; if( myIsSelected = isVisible() ) { if( !theRect.isNull() ) myIsSelected = theRect.contains( getRect() ); else - myIsSelected = checkHighlight( theX, theY ); + myIsSelected = checkHighlight( theX, theY, aCursor ); } return myIsSelected; } @@ -123,9 +153,14 @@ void GraphicsView_Object::unselect() //================================================================ void GraphicsView_Object::move( double theDX, double theDY, bool theIsAtOnce ) { - moveBy( theDX, theDY ); if( theIsAtOnce ) + { finishMove(); + return; + } + + myIsMoving = true; + moveBy( theDX, theDY ); } //================================================================ @@ -134,7 +169,51 @@ void GraphicsView_Object::move( double theDX, double theDY, bool theIsAtOnce ) //================================================================ bool GraphicsView_Object::finishMove() { + myIsMoving = false; if( GraphicsView_Scene* aScene = dynamic_cast( scene() ) ) aScene->processRectChanged(); return true; } + +//================================================================ +// Function : centerPoint +// Purpose : +//================================================================ +QPointF GraphicsView_Object::centerPoint() +{ + QRectF aRect = getRect(); + double aCenterX = aRect.width() / 2.; + double aCenterY = aRect.height() / 2.; + return QPointF( aCenterX, aCenterY ); +} + +//================================================================ +// Function : setRotationAroundCenter +// Purpose : +//================================================================ +void GraphicsView_Object::setRotationAroundCenter( QGraphicsItem* theItem, double theAngle ) +{ + if( !theItem ) + return; + + QRectF aRect = theItem->boundingRect(); + double aCenterX = aRect.width() / 2.; + double aCenterY = aRect.height() / 2.; + if( GraphicsView_Object* anObject = dynamic_cast( theItem ) ) + { + aCenterX = anObject->centerPoint().x(); + aCenterY = anObject->centerPoint().y(); + } + else if( QGraphicsPixmapItem* aPixmapItem = dynamic_cast( theItem ) ) + { + QPoint aPoint = aPixmapItem->pixmap().rect().center(); + aCenterX = aPoint.x(); + aCenterY = aPoint.y(); + } + + QTransform aTransform; + aTransform.translate( aCenterX, aCenterY ); + aTransform.rotate( theAngle ); + aTransform.translate( -aCenterX, -aCenterY ); + theItem->setTransform( aTransform, false ); +} diff --git a/src/GraphicsView/GraphicsView_Object.h b/src/GraphicsView/GraphicsView_Object.h index dba481138..3208ba3b6 100644 --- a/src/GraphicsView/GraphicsView_Object.h +++ b/src/GraphicsView/GraphicsView_Object.h @@ -27,6 +27,8 @@ #include +class GraphicsView_ViewPort; + /* Class : GraphicsView_Object Description : Base class for all objects displayed at the scene @@ -39,6 +41,9 @@ public: virtual void compute() = 0; + virtual void addTo( GraphicsView_ViewPort* theViewPort ); + virtual void removeFrom( GraphicsView_ViewPort* theViewPort ); + const QString& getName() const { return myName; } virtual void setName( const QString& theName ); @@ -52,6 +57,8 @@ public: virtual QRectF getRect() const; + virtual bool checkHighlight( double theX, double theY, QCursor& theCursor ) const; + virtual bool highlight( double theX, double theY ); virtual void unhighlight(); virtual bool isHighlighted() const { return myIsHighlighted; } @@ -63,6 +70,7 @@ public: virtual void move( double theDX, double theDY, bool theIsAtOnce = false ); virtual bool finishMove(); + virtual bool isMoving() const { return myIsMoving; } virtual bool isMovingByXAllowed( double theDX ) { return true; } virtual bool isMovingByYAllowed( double theDY ) { return true; } @@ -79,8 +87,13 @@ public: virtual bool handleMouseMove( QGraphicsSceneMouseEvent* ) { return false; } virtual bool handleMouseRelease( QGraphicsSceneMouseEvent* ) { return false; } + virtual QPointF centerPoint(); + +public: + static void setRotationAroundCenter( QGraphicsItem* theItem, double theAngle ); + protected: - virtual bool checkHighlight( double theX, double theY ) const; + QCursor* getHighlightCursor() const { return myHighlightCursor; } protected: QString myName; @@ -90,6 +103,11 @@ protected: bool myIsHighlighted; bool myIsSelected; + + bool myIsMoving; + +private: + QCursor* myHighlightCursor; }; #endif diff --git a/src/GraphicsView/GraphicsView_PrsImage.cxx b/src/GraphicsView/GraphicsView_PrsImage.cxx new file mode 100644 index 000000000..75475f75e --- /dev/null +++ b/src/GraphicsView/GraphicsView_PrsImage.cxx @@ -0,0 +1,544 @@ +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "GraphicsView_PrsImage.h" + +#include "GraphicsView_PrsImageFrame.h" +#include "GraphicsView_ViewPort.h" + +#include +#include +#include +#include + +#include + +#include + +#define PI 3.14159265359 + +//======================================================================= +// name : GraphicsView_PrsImage +// Purpose : Constructor +//======================================================================= +GraphicsView_PrsImage::GraphicsView_PrsImage() +: GraphicsView_Object(), + myPixmapItem( 0 ), + myPreviewPixmapItem( 0 ), + myImageFrame( 0 ), + myScaleX( 1.0 ), + myScaleY( 1.0 ), + myRotationAngle( 0.0 ), + myPreviewRotationAngle( 0.0 ) +{ +} + +//======================================================================= +// name : GraphicsView_PrsImage +// Purpose : Destructor +//======================================================================= +GraphicsView_PrsImage::~GraphicsView_PrsImage() +{ + if( myPreviewPixmapItem ) + { + delete myPreviewPixmapItem; + myPreviewPixmapItem = 0; + } + + if( myImageFrame ) + { + delete myImageFrame; + myImageFrame = 0; + } + + QListIterator aChildIter( children() ); + while( aChildIter.hasNext() ) + { + if( QGraphicsItem* aChild = aChildIter.next() ) + { + removeFromGroup( aChild ); + if( QGraphicsScene* aScene = aChild->scene() ) + aScene->removeItem( aChild ); + delete aChild; + aChild = 0; + } + } +} + +//================================================================ +// Function : setImage +// Purpose : +//================================================================ +void GraphicsView_PrsImage::setImage( const QImage& theImage ) +{ + myPixmap = QPixmap::fromImage( theImage ); +} + +//================================================================ +// Function : getImage +// Purpose : +//================================================================ +QImage GraphicsView_PrsImage::getImage() const +{ + QImage anImage = myPixmap.toImage(); + return anImage; +} + +//================================================================ +// Function : getTransformation +// Purpose : +//================================================================ +QTransform GraphicsView_PrsImage::getTransform() const +{ + double aPosX, aPosY, aScaleX, aScaleY, aRotationAngle; + getPosition( aPosX, aPosY ); + getScaling( aScaleX, aScaleY ); + getRotationAngle( aRotationAngle ); + + QTransform aTransform; + aTransform.translate( aPosX, aPosY ); + aTransform.scale( aScaleX, aScaleY ); + aTransform.rotate( aRotationAngle ); + return aTransform; +} + +//================================================================ +// Function : setPosition +// Purpose : +//================================================================ +void GraphicsView_PrsImage::setPosition( const double thePosX, const double thePosY ) +{ + setPos( thePosX, thePosY ); +} + +//================================================================ +// Function : getPosition +// Purpose : +//================================================================ +void GraphicsView_PrsImage::getPosition( double& thePosX, double& thePosY ) const +{ + thePosX = pos().x(); + thePosY = pos().y(); +} + +//================================================================ +// Function : setScaling +// Purpose : +//================================================================ +void GraphicsView_PrsImage::setScaling( const double theScaleX, const double theScaleY ) +{ + myScaleX = theScaleX; + myScaleY = theScaleY; +} + +//================================================================ +// Function : getScaling +// Purpose : +//================================================================ +void GraphicsView_PrsImage::getScaling( double& theScaleX, double& theScaleY ) const +{ + theScaleX = myScaleX; + theScaleY = myScaleY; +} + +//================================================================ +// Function : setRotationAngle +// Purpose : +//================================================================ +void GraphicsView_PrsImage::setRotationAngle( const double theRotationAngle ) +{ + myRotationAngle = theRotationAngle; +} + +//================================================================ +// Function : getRotationAngle +// Purpose : +//================================================================ +void GraphicsView_PrsImage::getRotationAngle( double& theRotationAngle ) const +{ + theRotationAngle = myRotationAngle; +} + +//================================================================ +// Function : boundingRect +// Purpose : +//================================================================ +QRectF GraphicsView_PrsImage::boundingRect() const +{ + return myPixmapItem->boundingRect(); +} + +//================================================================ +// Function : compute +// Purpose : +//================================================================ +void GraphicsView_PrsImage::compute() +{ + if( !myPixmapItem ) + { + myPixmapItem = new QGraphicsPixmapItem( this ); + addToGroup( myPixmapItem ); + } + if( !myPreviewPixmapItem ) + { + myPreviewPixmapItem = new QGraphicsPixmapItem(); + //addToGroup( myPreviewPixmapItem ); // don't add + } + if( !myImageFrame ) + { + myImageFrame = new GraphicsView_PrsImageFrame(); + myImageFrame->setPrsImage( this ); + } + + setZValue( 0 ); + + QSize aSourceSize = myPixmap.size(); + QSize aScaledSize( aSourceSize.width() * myScaleX, + aSourceSize.height() * myScaleY ); + + QPixmap aPixmap = myPixmap.scaled( aScaledSize ); + myPixmapItem->setPixmap( aPixmap ); + + myPreviewPixmapItem->setPixmap( aPixmap ); + myPreviewPixmapItem->setVisible( false ); + + setRotationAroundCenter( this, myRotationAngle ); + + myImageFrame->compute(); +} + +//================================================================ +// Function : addTo +// Purpose : +//================================================================ +void GraphicsView_PrsImage::addTo( GraphicsView_ViewPort* theViewPort ) +{ + GraphicsView_Object::addTo( theViewPort ); + theViewPort->addItem( myImageFrame ); + theViewPort->addItem( myPreviewPixmapItem ); +} + +//================================================================ +// Function : removeFrom +// Purpose : +//================================================================ +void GraphicsView_PrsImage::removeFrom( GraphicsView_ViewPort* theViewPort ) +{ + GraphicsView_Object::removeFrom( theViewPort ); + theViewPort->removeItem( myImageFrame ); + theViewPort->removeItem( myPreviewPixmapItem ); +} + +//================================================================ +// Function : checkHighlight +// Purpose : +//================================================================ +bool GraphicsView_PrsImage::checkHighlight( double theX, double theY, QCursor& theCursor ) const +{ + QRect aRect = myPixmapItem->boundingRect().toRect(); + QPolygon aPolygon = sceneTransform().mapToPolygon( aRect ); + if( aPolygon.containsPoint( QPoint( theX, theY ), Qt::OddEvenFill ) ) + { + theCursor = *getHighlightCursor(); + return true; + } + return false; +} + +//================================================================ +// Function : highlight +// Purpose : +//================================================================ +bool GraphicsView_PrsImage::highlight( double theX, double theY ) +{ + bool anIsHighlighted = GraphicsView_Object::highlight( theX, theY ); + return anIsHighlighted; +} + +//================================================================ +// Function : unhighlight +// Purpose : +//================================================================ +void GraphicsView_PrsImage::unhighlight() +{ + GraphicsView_Object::unhighlight(); +} + +//================================================================ +// Function : select +// Purpose : +//================================================================ +bool GraphicsView_PrsImage::select( double theX, double theY, const QRectF& theRect ) +{ + bool anIsSelected = GraphicsView_Object::select( theX, theY, theRect ); + myImageFrame->updateAnchorItems(); + return anIsSelected; +} + +//================================================================ +// Function : unselect +// Purpose : +//================================================================ +void GraphicsView_PrsImage::unselect() +{ + GraphicsView_Object::unselect(); + myImageFrame->updateAnchorItems(); +} + +//================================================================ +// Function : setSelected +// Purpose : +//================================================================ +void GraphicsView_PrsImage::setSelected( bool theState ) +{ + GraphicsView_Object::setSelected( theState ); + myImageFrame->updateAnchorItems(); +} + +//================================================================ +// Function : move +// Purpose : +//================================================================ +void GraphicsView_PrsImage::move( double theDX, double theDY, bool theIsAtOnce ) +{ + if( theIsAtOnce ) + { + finishMove(); + return; + } + + if( !myIsMoving ) + enablePreview( true ); + + myIsMoving = true; + myPreviewPixmapItem->moveBy( theDX, theDY ); +} + +//================================================================ +// Function : finishMove +// Purpose : +//================================================================ +bool GraphicsView_PrsImage::finishMove() +{ + if( myIsMoving ) + { + setPos( myPreviewPixmapItem->pos() ); + myImageFrame->setPos( pos() ); + + enablePreview( false ); + } + return GraphicsView_Object::finishMove(); +} + +//================================================================ +// Function : centerPoint +// Purpose : +//================================================================ +QPointF GraphicsView_PrsImage::centerPoint() +{ + QPointF aPoint = myPixmapItem->boundingRect().center(); + return aPoint; +} + +//================================================================ +// Function : processResize +// Purpose : +//================================================================ +void GraphicsView_PrsImage::processResize( const int theAnchor, + const QPointF& thePoint1, + const QPointF& thePoint2 ) +{ + if( thePoint1 == thePoint2 ) + return; + + if( !myPreviewPixmapItem->isVisible() ) + enablePreview( true ); + + QPixmap aCurrentPixmap = myPixmapItem->pixmap(); + int aWidth = aCurrentPixmap.width(); + int aHeight = aCurrentPixmap.height(); + + double aDX = thePoint2.x() - thePoint1.x(); + double aDY = thePoint2.y() - thePoint1.y(); + + double anAngle = -1 * myRotationAngle * PI / 180.; + + gp_Pnt2d aPnt1( thePoint1.x(), thePoint1.y() ); + gp_Pnt2d aPnt2( thePoint2.x(), thePoint2.y() ); + gp_Vec2d aVec( aPnt1, aPnt2 ); + gp_Vec2d aVecHor( 10, 0 ); + + double aDist = aPnt1.Distance( aPnt2 ); + double anAngle1 = aVec.Angle( aVecHor ); + double anAngle2 = anAngle1 - anAngle; + + double aSizeDX = aDist * cos( anAngle2 ); + double aSizeDY = -aDist * sin( anAngle2 ); + + QPointF aPosShift; + QPointF aSizeShift; + switch( theAnchor ) + { + case GraphicsView_PrsImageFrame::Top: + aPosShift = QPointF( aSizeDY * sin( anAngle ), aSizeDY * cos( anAngle ) ); + aSizeShift = QPointF( 0, -aSizeDY ); + break; + case GraphicsView_PrsImageFrame::Bottom: + aPosShift = QPointF( 0, 0 ); + aSizeShift = QPointF( 0, aSizeDY ); + break; + case GraphicsView_PrsImageFrame::Left: + aPosShift = QPointF( aSizeDX * cos( anAngle ), -aSizeDX * sin( anAngle ) ); + aSizeShift = QPointF( -aSizeDX, 0 ); + break; + case GraphicsView_PrsImageFrame::Right: + aPosShift = QPointF( 0, 0 ); + aSizeShift = QPointF( aSizeDX, 0 ); + break; + case GraphicsView_PrsImageFrame::TopLeft: + aPosShift = QPointF( aDX, aDY ); + aSizeShift = QPointF( -aSizeDX, -aSizeDY ); + break; + case GraphicsView_PrsImageFrame::TopRight: + aPosShift = QPointF( aSizeDY * sin( anAngle ), aSizeDY * cos( anAngle ) ); + aSizeShift = QPointF( aSizeDX, -aSizeDY ); + break; + case GraphicsView_PrsImageFrame::BottomLeft: + aPosShift = QPointF( aSizeDX * cos( anAngle ), -aSizeDX * sin( anAngle ) ); + aSizeShift = QPointF( -aSizeDX, aSizeDY ); + break; + case GraphicsView_PrsImageFrame::BottomRight: + aPosShift = QPointF( 0, 0 ); + aSizeShift = QPointF( aSizeDX, aSizeDY ); + break; + } + + aWidth += (int)aSizeShift.x(); + aHeight += (int)aSizeShift.y(); + if( aWidth < 10 || aHeight < 10 ) // tmp + return; + + QPixmap aPixmap = myPixmap.scaled( aWidth, aHeight ); + myPreviewPixmapItem->setPixmap( aPixmap ); + + myPreviewPixmapItem->setPos( pos() + aPosShift ); +} + +//================================================================ +// Function : finishResize +// Purpose : +//================================================================ +void GraphicsView_PrsImage::finishResize() +{ + QSize aSourceSize = myPixmap.size(); + QSize aScaledSize = myPreviewPixmapItem->pixmap().size(); + + myScaleX = ( (double)aScaledSize.width() ) / ( (double)aSourceSize.width() ); + myScaleY = ( (double)aScaledSize.height() ) / ( (double)aSourceSize.height() ); + + QPointF aSceneCenter = myPixmapItem->sceneBoundingRect().center(); + QPointF aPreviewSceneCenter = myPreviewPixmapItem->sceneBoundingRect().center(); + + QPointF aCenter = myPixmapItem->pixmap().rect().center(); + QPointF aPreviewCenter = myPreviewPixmapItem->pixmap().rect().center(); + + QPointF aCenterShift = aSceneCenter - aCenter; + QPointF aPreviewCenterShift = aPreviewSceneCenter - aPreviewCenter; + + QPointF aPosShift = myPreviewPixmapItem->pos() - pos(); + QPointF aShift = aPreviewCenterShift - aCenterShift - aPosShift; + + myPixmapItem->setPixmap( myPreviewPixmapItem->pixmap() ); + myImageFrame->computeAnchorItems(); + + setPos( myPreviewPixmapItem->pos() + aShift ); + setRotationAroundCenter( this, myRotationAngle ); + + myImageFrame->setPos( myPreviewPixmapItem->pos() + aShift ); + setRotationAroundCenter( myImageFrame, myRotationAngle ); + + enablePreview( false ); +} + +//================================================================ +// Function : processRotate +// Purpose : +//================================================================ +void GraphicsView_PrsImage::processRotate( const QPointF& thePoint1, + const QPointF& thePoint2 ) +{ + if( thePoint1 == thePoint2 ) + return; + + if( !myPreviewPixmapItem->isVisible() ) + enablePreview( true ); + + QRectF aRect = getRect(); + QPointF aCenter = aRect.center(); + + gp_Pnt2d aPnt0( aCenter.x(), aCenter.y() ); + gp_Pnt2d aPnt1( thePoint1.x(), thePoint1.y() ); + gp_Pnt2d aPnt2( thePoint2.x(), thePoint2.y() ); + + gp_Vec2d aVec1( aPnt0, aPnt1 ); + gp_Vec2d aVec2( aPnt0, aPnt2 ); + + double anAngle = aVec1.Angle( aVec2 ); + double anAngleDeg = anAngle / PI * 180.; + + myPreviewRotationAngle = myRotationAngle + anAngleDeg; + setRotationAroundCenter( myPreviewPixmapItem, myPreviewRotationAngle ); +} + +//================================================================ +// Function : finishRotate +// Purpose : +//================================================================ +void GraphicsView_PrsImage::finishRotate() +{ + myRotationAngle = myPreviewRotationAngle; + setRotationAroundCenter( this, myRotationAngle ); + setRotationAroundCenter( myImageFrame, myRotationAngle ); + + enablePreview( false ); +} + +//================================================================ +// Function : enablePreview +// Purpose : +//================================================================ +void GraphicsView_PrsImage::enablePreview( const bool theState ) +{ + if( theState ) + { + myPreviewPixmapItem->setZValue( 100 ); + myPreviewPixmapItem->setOpacity( opacity() / 2. ); + + myPreviewPixmapItem->setPos( pos() ); + setRotationAroundCenter( myPreviewPixmapItem, myRotationAngle ); + myPreviewRotationAngle = myRotationAngle; + + myPreviewPixmapItem->setVisible( true ); + } + else + myPreviewPixmapItem->setVisible( false ); +} diff --git a/src/GraphicsView/GraphicsView_PrsImage.h b/src/GraphicsView/GraphicsView_PrsImage.h new file mode 100644 index 000000000..735179266 --- /dev/null +++ b/src/GraphicsView/GraphicsView_PrsImage.h @@ -0,0 +1,112 @@ +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef GRAPHICSVIEW_PRSIMAGE_H +#define GRAPHICSVIEW_PRSIMAGE_H + +#include "GraphicsView.h" + +#include "GraphicsView_Object.h" + +class GraphicsView_PrsImageFrame; + +/* + Class : GraphicsView_PrsImage + Description : Presentation for image object +*/ +class GRAPHICSVIEW_API GraphicsView_PrsImage : public GraphicsView_Object +{ +public: + GraphicsView_PrsImage(); + virtual ~GraphicsView_PrsImage(); + +public: + void setImage( const QImage& theImage ); + QImage getImage() const; + + QTransform getTransform() const; + + void setPosition( const double thePosX, const double thePosY ); + void getPosition( double& thePosX, double& thePosY ) const; + + void setScaling( const double theScaleX, const double theScaleY ); + void getScaling( double& theScaleX, double& theScaleY ) const; + + void setRotationAngle( const double theRotationAngle ); + void getRotationAngle( double& theRotationAngle ) const; + +public: + // from QGraphicsItem + virtual QRectF boundingRect() const; + + // from GraphicsView_Object + virtual void compute(); + + virtual void addTo( GraphicsView_ViewPort* theViewPort ); + virtual void removeFrom( GraphicsView_ViewPort* theViewPort ); + + virtual bool checkHighlight( double theX, double theY, QCursor& theCursor ) const; + + virtual bool highlight( double theX, double theY ); + virtual void unhighlight(); + + virtual bool select( double theX, double theY, const QRectF& theRect ); + virtual void unselect(); + virtual void setSelected( bool theState ); + + virtual void move( double theDX, double theDY, bool theIsAtOnce = false ); + virtual bool finishMove(); + + virtual QPointF centerPoint(); + +protected: + void processResize( const int theAnchor, + const QPointF& thePoint1, + const QPointF& thePoint2 ); + void finishResize(); + + void processRotate( const QPointF& thePoint1, + const QPointF& thePoint2 ); + void finishRotate(); + +protected: + void enablePreview( const bool theState ); + +protected: + QPixmap myPixmap; + + QGraphicsPixmapItem* myPixmapItem; + QGraphicsPixmapItem* myPreviewPixmapItem; + + GraphicsView_PrsImageFrame* myImageFrame; + + double myScaleX; + double myScaleY; + + double myRotationAngle; + double myPreviewRotationAngle; + +private: + friend class GraphicsView_PrsImageFrame; +}; + +#endif diff --git a/src/GraphicsView/GraphicsView_PrsImageFrame.cxx b/src/GraphicsView/GraphicsView_PrsImageFrame.cxx new file mode 100644 index 000000000..b14dba132 --- /dev/null +++ b/src/GraphicsView/GraphicsView_PrsImageFrame.cxx @@ -0,0 +1,418 @@ +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "GraphicsView_PrsImageFrame.h" + +#include "GraphicsView_PrsImage.h" + +#include +#include + +#include +#include + +#define ANCHOR_RADIUS 10 + +//======================================================================= +// name : GraphicsView_PrsImageFrame +// Purpose : Constructor +//======================================================================= +GraphicsView_PrsImageFrame::GraphicsView_PrsImageFrame() +: GraphicsView_Object(), + myPrsImage( 0 ), + myIsPulling( false ), + myPullingAnchor( Undefined ) +{ + myVerCursor = new QCursor( Qt::SizeVerCursor ); + myHorCursor = new QCursor( Qt::SizeHorCursor ); + myBDiagCursor = new QCursor( Qt::SizeBDiagCursor ); + myFDiagCursor = new QCursor( Qt::SizeFDiagCursor ); + + SUIT_ResourceMgr* rmgr = SUIT_Session::session()->resourceMgr(); + myRotateCursor = new QCursor( rmgr->loadPixmap( "GraphicsView", QObject::tr( "ICON_GV_ROTATE" ) ) ); +} + +//======================================================================= +// name : GraphicsView_PrsImageFrame +// Purpose : Destructor +//======================================================================= +GraphicsView_PrsImageFrame::~GraphicsView_PrsImageFrame() +{ + if( myVerCursor ) + { + delete myVerCursor; + myVerCursor = 0; + } + if( myHorCursor ) + { + delete myHorCursor; + myHorCursor = 0; + } + if( myBDiagCursor ) + { + delete myBDiagCursor; + myBDiagCursor = 0; + } + if( myFDiagCursor ) + { + delete myFDiagCursor; + myFDiagCursor = 0; + } + if( myRotateCursor ) + { + delete myRotateCursor; + myRotateCursor = 0; + } +} + +//================================================================ +// Function : boundingRect +// Purpose : +//================================================================ +QRectF GraphicsView_PrsImageFrame::boundingRect() const +{ + QRectF aRect; + AnchorMapIterator anIter( myAnchorMap ); + while( anIter.hasNext() ) + { + if( QGraphicsEllipseItem* anAnchorItem = anIter.next().value() ) + { + QRectF anAnchorRect = anAnchorItem->boundingRect(); + if( !anAnchorRect.isNull() ) + { + if( aRect.isNull() ) + aRect = anAnchorRect; + else + aRect |= anAnchorRect; + } + } + } + return aRect; +} + +//================================================================ +// Function : compute +// Purpose : +//================================================================ +void GraphicsView_PrsImageFrame::compute() +{ + if( myAnchorMap.isEmpty() ) + { + for( int aType = Top; aType <= TopMost; aType++ ) + { + UnscaledGraphicsEllipseItem* anAnchorItem = new UnscaledGraphicsEllipseItem( this ); + //anAnchorItem->setFlag( QGraphicsItem::ItemIgnoresTransformations, true ); + + Qt::GlobalColor aColor = Qt::white; + if( aType == TopMost ) + aColor = Qt::green; + anAnchorItem->setBrush( QBrush( aColor ) ); + + myAnchorMap.insert( aType, anAnchorItem ); + + addToGroup( anAnchorItem ); + } + } + + setZValue( 1000 ); + + computeAnchorItems(); + updateAnchorItems(); +} + +//================================================================ +// Function : checkHighlight +// Purpose : +//================================================================ +bool GraphicsView_PrsImageFrame::checkHighlight( double theX, double theY, QCursor& theCursor ) const +{ + AnchorMapIterator anIter( myAnchorMap ); + while( anIter.hasNext() ) + { + int aType = anIter.next().key(); + if( QGraphicsEllipseItem* anAnchorItem = anIter.value() ) + { + QRectF aRect = anAnchorItem->sceneBoundingRect(); + if( aRect.contains( QPointF( theX, theY ) ) ) + { + if( aType >= Top && aType <= BottomRight ) + { + if( QCursor* aCursor = getResizeCursor( aType ) ) + theCursor = *aCursor; + } + else if( aType == TopMost ) + theCursor = *getRotateCursor(); + return true; + } + } + } + return false; +} + +//================================================================ +// Function : getPullingRect +// Purpose : +//================================================================ +QRectF GraphicsView_PrsImageFrame::getPullingRect() const +{ + return getRect(); +} + +//================================================================ +// Function : startPulling +// Purpose : +//================================================================ +bool GraphicsView_PrsImageFrame::startPulling( const QPointF& thePoint ) +{ + if( !isVisible() ) + return false; + + AnchorMapIterator anIter( myAnchorMap ); + while( anIter.hasNext() ) + { + int aType = anIter.next().key(); + if( UnscaledGraphicsEllipseItem* anAnchorItem = anIter.value() ) + { + QRectF aRect = anAnchorItem->sceneBoundingRect(); + if( aRect.contains( thePoint ) ) + { + myPullingAnchor = aType; + myPullingPoint = sceneTransform().map( anAnchorItem->getBasePoint() ); + return true; + } + } + } + return false; +} + +//================================================================ +// Function : pull +// Purpose : +//================================================================ +void GraphicsView_PrsImageFrame::pull( const QPointF& thePoint, GraphicsView_Object* ) +{ + if( !myPrsImage ) + return; + + if( myPullingAnchor >= Top && myPullingAnchor <= BottomRight ) + myPrsImage->processResize( myPullingAnchor, myPullingPoint, thePoint ); + else if( myPullingAnchor == TopMost ) + myPrsImage->processRotate( myPullingPoint, thePoint ); +} + +//================================================================ +// Function : finishPulling +// Purpose : +//================================================================ +void GraphicsView_PrsImageFrame::finishPulling() +{ + if( !myPrsImage ) + return; + + if( myPullingAnchor >= Top && myPullingAnchor <= BottomRight ) + myPrsImage->finishResize(); + else if( myPullingAnchor == TopMost ) + myPrsImage->finishRotate(); +} + +//================================================================ +// Function : centerPoint +// Purpose : +//================================================================ +QPointF GraphicsView_PrsImageFrame::centerPoint() +{ + QPointF aPoint1 = myAnchorMap[ Top ]->getBasePoint(); + QPointF aPoint2 = myAnchorMap[ Bottom ]->getBasePoint(); + QPointF aPoint3 = myAnchorMap[ Left ]->getBasePoint(); + QPointF aPoint4 = myAnchorMap[ Right ]->getBasePoint(); + return ( aPoint1 + aPoint2 + aPoint3 + aPoint4 ) /4.; +} + +//================================================================ +// Function : setPrsImage +// Purpose : +//================================================================ +void GraphicsView_PrsImageFrame::setPrsImage( GraphicsView_PrsImage* thePrsImage ) +{ + myPrsImage = thePrsImage; +} + +//================================================================ +// Function : computeAnchorItems +// Purpose : +//================================================================ +void GraphicsView_PrsImageFrame::computeAnchorItems() +{ + if( !myPrsImage ) + return; + + QRectF aRect = myPrsImage->boundingRect(); + + QMap anAnchorPointMap; + anAnchorPointMap[ Top ] = ( aRect.topLeft() + aRect.topRight() ) / 2; + anAnchorPointMap[ Bottom ] = ( aRect.bottomLeft() + aRect.bottomRight() ) / 2; + anAnchorPointMap[ Left ] = ( aRect.topLeft() + aRect.bottomLeft() ) / 2; + anAnchorPointMap[ Right ] = ( aRect.topRight() + aRect.bottomRight() ) / 2; + anAnchorPointMap[ TopLeft ] = aRect.topLeft(); + anAnchorPointMap[ TopRight ] = aRect.topRight(); + anAnchorPointMap[ BottomLeft ] = aRect.bottomLeft(); + anAnchorPointMap[ BottomRight ] = aRect.bottomRight(); + + // tmp + anAnchorPointMap[ TopMost ] = ( aRect.topLeft() + aRect.topRight() ) / 2 - + QPointF( 0, 4 * ANCHOR_RADIUS ); + + qreal ar = ANCHOR_RADIUS; + QMapIterator anIter( anAnchorPointMap ); + while( anIter.hasNext() ) + { + int anAnchorType = anIter.next().key(); + const QPointF& anAnchorPoint = anIter.value(); + + QRectF anAnchorRect( anAnchorPoint - QPointF( ar, ar ), QSizeF( ar * 2, ar * 2 ) ); + myAnchorMap[ anAnchorType ]->setRect( anAnchorRect ); + myAnchorMap[ anAnchorType ]->setBasePoint( anAnchorPoint ); + } +} + +//================================================================ +// Function : updateAnchorItems +// Purpose : +//================================================================ +void GraphicsView_PrsImageFrame::updateAnchorItems() +{ + if( !myPrsImage ) + return; + + bool anIsSelected = myPrsImage->isSelected(); + if( anIsSelected ) + { + double aPosX, aPosY, aRotationAngle; + myPrsImage->getPosition( aPosX, aPosY ); + myPrsImage->getRotationAngle( aRotationAngle ); + + setPos( aPosX, aPosY ); + setRotationAroundCenter( this, aRotationAngle ); + } + setVisible( anIsSelected ); +} + +//================================================================ +// Function : getResizeCursor +// Purpose : +//================================================================ +QCursor* GraphicsView_PrsImageFrame::getResizeCursor( const int theAnchor ) const +{ + if( !myPrsImage ) + return 0; + + double aRotationAngle = 0; + myPrsImage->getRotationAngle( aRotationAngle ); + + int anAngle = (int)aRotationAngle; + anAngle = anAngle % 360; + anAngle += 360; // to avoid negative values + anAngle = anAngle % 360; // 0 <= anAngle <= 359 + + int aShift = 0; + switch( theAnchor ) + { + case Top: aShift = 0; break; + case TopRight: aShift = 45; break; + case Right: aShift = 90; break; + case BottomRight: aShift = 135; break; + case Bottom: aShift = 180; break; + case BottomLeft: aShift = 225; break; + case Left: aShift = 270; break; + case TopLeft: aShift = 315; break; + } + anAngle += aShift; + anAngle = anAngle % 360; + + // 360 = 8 sectors of 45 degrees + if( anAngle <= 22 || anAngle >= 338 ) + return getVerCursor(); + if( anAngle >= 23 && anAngle <= 67 ) + return getBDiagCursor(); + if( anAngle >= 68 && anAngle <= 112 ) + return getHorCursor(); + if( anAngle >= 113 && anAngle <= 157 ) + return getFDiagCursor(); + if( anAngle >= 158 && anAngle <= 202 ) + return getVerCursor(); + if( anAngle >= 203 && anAngle <= 247 ) + return getBDiagCursor(); + if( anAngle >= 248 && anAngle <= 292 ) + return getHorCursor(); + if( anAngle >= 293 && anAngle <= 337 ) + return getFDiagCursor(); + return 0; +} + +//======================================================================= +// name : GraphicsView_PrsImageFrame::UnscaledGraphicsEllipseItem +// Purpose : Constructor +//======================================================================= +GraphicsView_PrsImageFrame::UnscaledGraphicsEllipseItem::UnscaledGraphicsEllipseItem( QGraphicsItem* theParent ) +: QGraphicsEllipseItem( theParent ) +{ +} + +//======================================================================= +// name : GraphicsView_PrsImageFrame::UnscaledGraphicsEllipseItem +// Purpose : Destructor +//======================================================================= +GraphicsView_PrsImageFrame::UnscaledGraphicsEllipseItem::~UnscaledGraphicsEllipseItem() +{ +} + +//================================================================ +// Function : GenerateTranslationOnlyTransform +// Purpose : +//================================================================ +static QTransform GenerateTranslationOnlyTransform( const QTransform &theOriginalTransform, + const QPointF &theTargetPoint ) +{ + qreal dx = theOriginalTransform.m11() * theTargetPoint.x() - theTargetPoint.x() + + theOriginalTransform.m21() * theTargetPoint.y() + + theOriginalTransform.m31(); + qreal dy = theOriginalTransform.m22() * theTargetPoint.y() - theTargetPoint.y() + + theOriginalTransform.m12() * theTargetPoint.x() + + theOriginalTransform.m32(); + return QTransform::fromTranslate( dx, dy ); +} + +//================================================================ +// Function : paint +// Purpose : +//================================================================ +void GraphicsView_PrsImageFrame::UnscaledGraphicsEllipseItem::paint( + QPainter* thePainter, + const QStyleOptionGraphicsItem* theOption, + QWidget* theWidget ) +{ + //thePainter->save(); + //thePainter->setTransform( GenerateTranslationOnlyTransform( thePainter->transform(), + // myBasePoint ) ); + QGraphicsEllipseItem::paint( thePainter, theOption, theWidget ); + //thePainter->restore(); +} diff --git a/src/GraphicsView/GraphicsView_PrsImageFrame.h b/src/GraphicsView/GraphicsView_PrsImageFrame.h new file mode 100644 index 000000000..f71771ef0 --- /dev/null +++ b/src/GraphicsView/GraphicsView_PrsImageFrame.h @@ -0,0 +1,127 @@ +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef GRAPHICSVIEW_PRSIMAGEFRAME_H +#define GRAPHICSVIEW_PRSIMAGEFRAME_H + +#include "GraphicsView.h" + +#include "GraphicsView_Object.h" + +#include + +class GraphicsView_PrsImage; + +/* + Class : GraphicsView_PrsImageFrame + Description : Presentation for image frame object +*/ +class GRAPHICSVIEW_API GraphicsView_PrsImageFrame : public GraphicsView_Object +{ +public: + class UnscaledGraphicsEllipseItem; + + enum AnchorType { Undefined = 0, Top, Bottom, Left, Right, + TopLeft, TopRight, BottomLeft, BottomRight, + TopMost }; + + typedef QMap AnchorMap; + typedef QMapIterator AnchorMapIterator; + +public: + GraphicsView_PrsImageFrame(); + virtual ~GraphicsView_PrsImageFrame(); + +public: + // from QGraphicsItem + virtual QRectF boundingRect() const; + + // from GraphicsView_Object + virtual void compute(); + + virtual bool isMovable() const { return false; } + + virtual bool checkHighlight( double theX, double theY, QCursor& theCursor ) const; + + virtual QRectF getPullingRect() const; + virtual bool portContains( const QPointF& ) { return false; } // useless + virtual bool startPulling( const QPointF& ); + virtual void pull( const QPointF&, GraphicsView_Object* ); + virtual void finishPulling(); + virtual bool isPulling() { return myIsPulling; } + + virtual QPointF centerPoint(); + +public: + void setPrsImage( GraphicsView_PrsImage* ); + + void computeAnchorItems(); + void updateAnchorItems(); + +protected: + QCursor* getVerCursor() const { return myVerCursor; } + QCursor* getHorCursor() const { return myHorCursor; } + QCursor* getBDiagCursor() const { return myBDiagCursor; } + QCursor* getFDiagCursor() const { return myFDiagCursor; } + QCursor* getRotateCursor() const { return myRotateCursor; } + + QCursor* getResizeCursor( const int theAnchor ) const; + +protected: + GraphicsView_PrsImage* myPrsImage; + + bool myIsPulling; + int myPullingAnchor; + QPointF myPullingPoint; + + AnchorMap myAnchorMap; + +private: + QCursor* myVerCursor; + QCursor* myHorCursor; + QCursor* myBDiagCursor; + QCursor* myFDiagCursor; + QCursor* myRotateCursor; +}; + +/* + Class : UnscaledGraphicsEllipseItem + Description : Class for unscaled ellipse item +*/ +class GraphicsView_PrsImageFrame::UnscaledGraphicsEllipseItem : public QGraphicsEllipseItem +{ +public: + UnscaledGraphicsEllipseItem( QGraphicsItem* ); + virtual ~UnscaledGraphicsEllipseItem(); + +public: + void setBasePoint( const QPointF& thePoint ) { myBasePoint = thePoint; } + const QPointF& getBasePoint() const { return myBasePoint; } + +public: + virtual void paint( QPainter*, const QStyleOptionGraphicsItem*, QWidget* ); + +private: + QPointF myBasePoint; +}; + +#endif diff --git a/src/GraphicsView/GraphicsView_PrsPropDlg.cxx b/src/GraphicsView/GraphicsView_PrsPropDlg.cxx new file mode 100644 index 000000000..d134f5ff3 --- /dev/null +++ b/src/GraphicsView/GraphicsView_PrsPropDlg.cxx @@ -0,0 +1,124 @@ +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "GraphicsView_PrsPropDlg.h" + +#include + +#include +#include +#include + +//================================================================ +// Function : GraphicsView_PrsPropDlg +// Purpose : +//================================================================ +GraphicsView_PrsPropDlg::GraphicsView_PrsPropDlg( QWidget* theParent ) +: QtxDialog( theParent, true, true, QtxDialog::OKCancel ) +{ + setWindowTitle( tr( "PROPERTIES" ) ); + + QFrame* aMainFrame = mainFrame(); + + QGroupBox* aPropGroup = new QGroupBox( aMainFrame ); + + QLabel* aPositionXLabel = new QLabel( tr( "POSITION_X" ), aPropGroup ); + myPositionX = new QtxDoubleSpinBox( -1e6, 1e6, 1, aPropGroup ); + + QLabel* aPositionYLabel = new QLabel( tr( "POSITION_Y" ), aPropGroup ); + myPositionY = new QtxDoubleSpinBox( -1e6, 1e6, 1, aPropGroup ); + + QLabel* aScalingXLabel = new QLabel( tr( "SCALING_X" ), aPropGroup ); + myScalingX = new QtxDoubleSpinBox( 1e-6, 1e6, 1, aPropGroup ); + + QLabel* aScalingYLabel = new QLabel( tr( "SCALING_Y" ), aPropGroup ); + myScalingY = new QtxDoubleSpinBox( 1e-6, 1e6, 1, aPropGroup ); + + QLabel* aRotationAngleLabel = new QLabel( tr( "ROTATION_ANGLE" ), aPropGroup ); + myRotationAngle = new QtxDoubleSpinBox( -1e6, 1e6, 1, aPropGroup ); + + QGridLayout* aPropLayout = new QGridLayout( aPropGroup ); + aPropLayout->setMargin( 5 ); + aPropLayout->setSpacing( 5 ); + aPropLayout->addWidget( aPositionXLabel, 0, 0 ); + aPropLayout->addWidget( myPositionX, 0, 1 ); + aPropLayout->addWidget( aPositionYLabel, 1, 0 ); + aPropLayout->addWidget( myPositionY, 1, 1 ); + aPropLayout->addWidget( aScalingXLabel, 2, 0 ); + aPropLayout->addWidget( myScalingX, 2, 1 ); + aPropLayout->addWidget( aScalingYLabel, 3, 0 ); + aPropLayout->addWidget( myScalingY, 3, 1 ); + aPropLayout->addWidget( aRotationAngleLabel, 4, 0 ); + aPropLayout->addWidget( myRotationAngle, 4, 1 ); + aPropLayout->setColumnStretch( 1, 1 ); + + QVBoxLayout* aMainLayout = new QVBoxLayout( aMainFrame ); + aMainLayout->setMargin( 5 ); + aMainLayout->setSpacing( 5 ); + aMainLayout->addWidget( aPropGroup ); + + setButtonPosition( Center, OK ); + setButtonPosition( Center, Cancel ); + setMinimumWidth( 300 ); +} + +//================================================================ +// Function : ~GraphicsView_PrsPropDlg +// Purpose : +//================================================================ +GraphicsView_PrsPropDlg::~GraphicsView_PrsPropDlg() +{ +} + +//============================================================================= +// Function : setData +// Purpose : +//============================================================================= +void GraphicsView_PrsPropDlg::setData( const double thePositionX, + const double thePositionY, + const double theScalingX, + const double theScalingY, + const double theRotationAngle ) +{ + myPositionX->setValue( thePositionX ); + myPositionY->setValue( thePositionY ); + myScalingX->setValue( theScalingX ); + myScalingY->setValue( theScalingY ); + myRotationAngle->setValue( theRotationAngle ); +} + +//============================================================================= +// Function : getData +// Purpose : +//============================================================================= +void GraphicsView_PrsPropDlg::getData( double& thePositionX, + double& thePositionY, + double& theScalingX, + double& theScalingY, + double& theRotationAngle ) const +{ + thePositionX = myPositionX->value(); + thePositionY = myPositionY->value(); + theScalingX = myScalingX->value(); + theScalingY = myScalingY->value(); + theRotationAngle = myRotationAngle->value(); +} diff --git a/src/GraphicsView/GraphicsView_PrsPropDlg.h b/src/GraphicsView/GraphicsView_PrsPropDlg.h new file mode 100644 index 000000000..52b07a8ad --- /dev/null +++ b/src/GraphicsView/GraphicsView_PrsPropDlg.h @@ -0,0 +1,65 @@ +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef GRAPHICSVIEW_PRSPROPDLG_H +#define GRAPHICSVIEW_PRSPROPDLG_H + +#include "GraphicsView.h" + +#include + +class QtxDoubleSpinBox; + +/* + Class : GraphicsView_PrsPropDlg + Description : Dialog for managing presentation properties +*/ +class GRAPHICSVIEW_API GraphicsView_PrsPropDlg : public QtxDialog +{ + Q_OBJECT + +public: + GraphicsView_PrsPropDlg( QWidget* = 0 ); + virtual ~GraphicsView_PrsPropDlg(); + +public: + void setData( const double thePositionX, + const double thePositionY, + const double theScalingX, + const double theScalingY, + const double theRotationAngle ); + + void getData( double& thePositionX, + double& thePositionY, + double& theScalingX, + double& theScalingY, + double& theRotationAngle ) const; + +private: + QtxDoubleSpinBox* myPositionX; + QtxDoubleSpinBox* myPositionY; + QtxDoubleSpinBox* myScalingX; + QtxDoubleSpinBox* myScalingY; + QtxDoubleSpinBox* myRotationAngle; +}; + +#endif diff --git a/src/GraphicsView/GraphicsView_Scene.cxx b/src/GraphicsView/GraphicsView_Scene.cxx index 41c11a385..d2fc4af67 100644 --- a/src/GraphicsView/GraphicsView_Scene.cxx +++ b/src/GraphicsView/GraphicsView_Scene.cxx @@ -25,7 +25,7 @@ #include #include -//#define VIEWER_DEBUG +#define VIEWER_DEBUG // testing ImageViewer //======================================================================= // Name : GraphicsView_Scene @@ -42,7 +42,13 @@ GraphicsView_Scene::GraphicsView_Scene( QObject* theParent ) connect( this, SIGNAL( sceneRectChanged( const QRectF& ) ), this, SLOT( onSceneRectChanged( const QRectF& ) ) ); + + QGraphicsEllipseItem* aCenterItem = new QGraphicsEllipseItem( 0, 0, 5, 5 ); + aCenterItem->setBrush( QBrush( Qt::red ) ); + addItem( aCenterItem ); #endif + + setSceneRect( -500, -500, 3000, 3000 ); // testing ImageViewer } //======================================================================= diff --git a/src/GraphicsView/GraphicsView_ViewPort.cxx b/src/GraphicsView/GraphicsView_ViewPort.cxx index 4fbcd8b42..e323de9b2 100644 --- a/src/GraphicsView/GraphicsView_ViewPort.cxx +++ b/src/GraphicsView/GraphicsView_ViewPort.cxx @@ -135,7 +135,8 @@ GraphicsView_ViewPort::GraphicsView_ViewPort( QWidget* theParent ) myIsDragging( false ), myIsDragPositionInitialized( false ), myIsPulling( false ), - myPullingObject( 0 ) + myPullingObject( 0 ), + myStoredCursor( Qt::ArrowCursor ) { // scene myScene = new GraphicsView_Scene( this ); @@ -143,7 +144,7 @@ GraphicsView_ViewPort::GraphicsView_ViewPort( QWidget* theParent ) mySceneGap = 20; myFitAllGap = 40; - myIsTraceBoundingRectEnabled = true; + myIsTraceBoundingRectEnabled = false; // testing ImageViewer // interaction flags myInteractionFlags = AllFlags; @@ -247,8 +248,10 @@ void GraphicsView_ViewPort::addItem( QGraphicsItem* theItem ) } } myObjects.insert( anIter, anObject ); + anObject->addTo( this ); } - myScene->addItem( theItem ); + else + myScene->addItem( theItem ); onBoundingRectChanged(); } @@ -264,8 +267,10 @@ void GraphicsView_ViewPort::removeItem( QGraphicsItem* theItem ) myHighlightedObject = 0; mySelectedObjects.removeAll( anObject ); myObjects.removeAll( anObject ); + anObject->removeFrom( this ); } - myScene->removeItem( theItem ); + else + myScene->removeItem( theItem ); onBoundingRectChanged(); } @@ -886,7 +891,9 @@ void GraphicsView_ViewPort::highlight( double theX, double theY ) GraphicsView_Object* aPreviousHighlightedObject = myHighlightedObject; GraphicsView_Object* aHighlightedObject = 0; - GraphicsView_ObjectList aList = getObjects( true ); + QCursor aCursor; + + GraphicsView_ObjectList aList = getObjects( false ); GraphicsView_ObjectListIterator anIter( aList ); anIter.toBack(); // objects with higher priority have to be checked earlier while( anIter.hasPrevious() ) @@ -895,8 +902,7 @@ void GraphicsView_ViewPort::highlight( double theX, double theY ) { if( anObject->isVisible() && anObject->isSelectable() ) { - QRectF aRect = anObject->getRect(); - if( !aRect.isNull() && aRect.contains( theX, theY ) ) + if( anObject->checkHighlight( theX, theY, aCursor ) ) { anIsOnObject = true; anIsHighlighted = anObject->highlight( theX, theY ); @@ -911,6 +917,8 @@ void GraphicsView_ViewPort::highlight( double theX, double theY ) } } + setCursor( aCursor ); + if( !anIsOnObject ) { anIter = aList; @@ -1320,7 +1328,7 @@ bool GraphicsView_ViewPort::startPulling( const QPointF& thePoint ) { myIsPulling = true; myPullingObject = anObject; - setCursor( *getHandCursor() ); + //setCursor( *getHandCursor() ); // testing ImageViewer return true; } } @@ -1414,7 +1422,11 @@ void GraphicsView_ViewPort::onMouseEvent( QGraphicsSceneMouseEvent* e ) getHighlightedObject()->isMovable() && !( anAccel || e->button() == Qt::RightButton ) ) || ( nbSelected() && !anAccel && e->button() == Qt::MidButton ) ) - myIsDragging = true; + { + myIsDragging = true; + myStoredCursor = cursor(); + setCursor( Qt::ClosedHandCursor ); + } } break; } @@ -1450,6 +1462,7 @@ void GraphicsView_ViewPort::onMouseEvent( QGraphicsSceneMouseEvent* e ) myIsDragging = false; myDragPosition = QPointF(); + setCursor( myStoredCursor ); emit vpObjectAfterMoving( anIsMoved ); } diff --git a/src/GraphicsView/GraphicsView_ViewPort.h b/src/GraphicsView/GraphicsView_ViewPort.h index 09f2bb32c..e3420e07c 100644 --- a/src/GraphicsView/GraphicsView_ViewPort.h +++ b/src/GraphicsView/GraphicsView_ViewPort.h @@ -290,6 +290,9 @@ private: // pulling bool myIsPulling; GraphicsView_Object* myPullingObject; + + // cursor + QCursor myStoredCursor; }; #endif diff --git a/src/GraphicsView/GraphicsView_Viewer.cxx b/src/GraphicsView/GraphicsView_Viewer.cxx index 7363cae70..360433f1b 100644 --- a/src/GraphicsView/GraphicsView_Viewer.cxx +++ b/src/GraphicsView/GraphicsView_Viewer.cxx @@ -38,6 +38,11 @@ #include #include +// testing ImageViewer +#include "GraphicsView_PrsImage.h" +#include "GraphicsView_PrsPropDlg.h" +#include + //======================================================================= // Name : GraphicsView_Viewer // Purpose : Constructor @@ -98,6 +103,32 @@ void GraphicsView_Viewer::contextMenuPopup( QMenu* thePopup ) if( thePopup->actions().count() > 0 ) thePopup->addSeparator(); + // testing ImageViewer + if( GraphicsView_ViewPort* aViewPort = getActiveViewPort() ) + { + int aNbSelected = aViewPort->nbSelected(); + if( aNbSelected == 0 ) + { + thePopup->addAction( tr( "ADD_IMAGE" ), this, SLOT( onAddImage() ) ); + thePopup->addSeparator(); + + thePopup->addAction( tr( "TEST_IMAGE_COMPOSITION" ), this, SLOT( onTestImageComposition() ) ); + } + else + { + if( aNbSelected == 1 ) + { + thePopup->addAction( tr( "BRING_FORWARD" ), this, SLOT( onBringForward() ) ); + thePopup->addAction( tr( "SEND_BACKWARD" ), this, SLOT( onSendBackward() ) ); + thePopup->addSeparator(); + thePopup->addAction( tr( "PROPERTIES" ), this, SLOT( onPrsProperties() ) ); + thePopup->addSeparator(); + } + thePopup->addAction( tr( "REMOVE_IMAGES" ), this, SLOT( onRemoveImages() ) ); + } + thePopup->addSeparator(); + } + thePopup->addAction( tr( "CHANGE_BGCOLOR" ), this, SLOT( onChangeBgColor() ) ); } @@ -502,3 +533,125 @@ void GraphicsView_Viewer::onSelectionCancel() { emit selectionChanged( GVSCS_Invalid ); } + +//================================================================ +// Function : onAddImage +// Purpose : +//================================================================ +void GraphicsView_Viewer::onAddImage() +{ + if( GraphicsView_ViewPort* aViewPort = getActiveViewPort() ) + { + QString aFileName = QFileDialog::getOpenFileName(); + if( aFileName.isEmpty() ) + return; + + GraphicsView_PrsImage* aPrs = new GraphicsView_PrsImage(); + + QImage anImage( aFileName ); + aPrs->setImage( anImage ); + + aPrs->compute(); + + aViewPort->addItem( aPrs ); + aViewPort->fitAll(); + } +} + +//================================================================ +// Function : onRemoveImages +// Purpose : +//================================================================ +void GraphicsView_Viewer::onRemoveImages() +{ + if( GraphicsView_ViewPort* aViewPort = getActiveViewPort() ) + { + for( aViewPort->initSelected(); aViewPort->moreSelected(); aViewPort->nextSelected() ) + { + if( GraphicsView_Object* anObject = aViewPort->selectedObject() ) + { + if( GraphicsView_PrsImage* aPrs = dynamic_cast( anObject ) ) + { + aViewPort->removeItem( aPrs ); + delete aPrs; + } + } + } + } +} + +//================================================================ +// Function : onBringForward +// Purpose : +//================================================================ +void GraphicsView_Viewer::onBringForward() +{ + // to do +} + +//================================================================ +// Function : onSendBackward +// Purpose : +//================================================================ +void GraphicsView_Viewer::onSendBackward() +{ + // to do +} + +//================================================================ +// Function : onPrsProperties +// Purpose : +//================================================================ +void GraphicsView_Viewer::onPrsProperties() +{ + if( GraphicsView_ViewPort* aViewPort = getActiveViewPort() ) + { + aViewPort->initSelected(); + if( GraphicsView_Object* anObject = aViewPort->selectedObject() ) + { + if( GraphicsView_PrsImage* aPrs = dynamic_cast( anObject ) ) + { + double aPosX, aPosY, aScaleX, aScaleY, aRotationAngle; + aPrs->getPosition( aPosX, aPosY ); + aPrs->getScaling( aScaleX, aScaleY ); + aPrs->getRotationAngle( aRotationAngle ); + + GraphicsView_PrsPropDlg aDlg( aViewPort ); + aDlg.setData( aPosX, aPosY, aScaleX, aScaleY, aRotationAngle ); + if( aDlg.exec() ) + { + aDlg.getData( aPosX, aPosY, aScaleX, aScaleY, aRotationAngle ); + aPrs->setPosition( aPosX, aPosY ); + aPrs->setScaling( aScaleX, aScaleY ); + aPrs->setRotationAngle( aRotationAngle ); + aPrs->compute(); + } + } + } + } +} + +//================================================================ +// Function : onTestImageComposition +// Purpose : +//================================================================ +void GraphicsView_Viewer::onTestImageComposition() +{ + if( GraphicsView_ViewPort* aViewPort = getActiveViewPort() ) + { + GraphicsView_ObjectList aList = aViewPort->getObjects(); + GraphicsView_ObjectListIterator anIter( aList ); + while( anIter.hasNext() ) + { + if( GraphicsView_Object* anObject = anIter.next() ) + { + if( GraphicsView_PrsImage* aPrs = dynamic_cast( anObject ) ) + { + QImage anImage = aPrs->getImage(); + QTransform aTransform = aPrs->getTransform(); + // ... + } + } + } + } +} diff --git a/src/GraphicsView/GraphicsView_Viewer.h b/src/GraphicsView/GraphicsView_Viewer.h index 1664282a8..a9aac5e54 100644 --- a/src/GraphicsView/GraphicsView_Viewer.h +++ b/src/GraphicsView/GraphicsView_Viewer.h @@ -99,6 +99,14 @@ protected slots: virtual void onChangeBgColor(); + // testing ImageViewer + void onAddImage(); + void onRemoveImages(); + void onBringForward(); + void onSendBackward(); + void onPrsProperties(); + void onTestImageComposition(); + private: void handleKeyPress( QKeyEvent* ); void handleKeyRelease( QKeyEvent* ); diff --git a/src/GraphicsView/Makefile.am b/src/GraphicsView/Makefile.am index c8a5d805c..3d9a61301 100644 --- a/src/GraphicsView/Makefile.am +++ b/src/GraphicsView/Makefile.am @@ -27,7 +27,6 @@ lib_LTLIBRARIES = libGraphicsView.la salomeinclude_HEADERS = \ GraphicsView_Defs.h \ -GraphicsView_Geom.h \ GraphicsView.h \ GraphicsView_Object.h \ GraphicsView_Scene.h \ @@ -36,7 +35,10 @@ GraphicsView_Viewer.h \ GraphicsView_ViewFrame.h \ GraphicsView_ViewManager.h \ GraphicsView_ViewPort.h \ -GraphicsView_ViewTransformer.h +GraphicsView_ViewTransformer.h \ +GraphicsView_PrsImage.h \ +GraphicsView_PrsImageFrame.h \ +GraphicsView_PrsPropDlg.h dist_libGraphicsView_la_SOURCES = \ GraphicsView_Object.cxx \ @@ -46,7 +48,10 @@ GraphicsView_Viewer.cxx \ GraphicsView_ViewFrame.cxx \ GraphicsView_ViewManager.cxx \ GraphicsView_ViewPort.cxx \ -GraphicsView_ViewTransformer.cxx +GraphicsView_ViewTransformer.cxx \ +GraphicsView_PrsImage.cxx \ +GraphicsView_PrsImageFrame.cxx \ +GraphicsView_PrsPropDlg.cxx MOC_FILES = \ GraphicsView_ViewManager_moc.cxx \ @@ -54,7 +59,8 @@ GraphicsView_Viewer_moc.cxx \ GraphicsView_ViewFrame_moc.cxx \ GraphicsView_Selector_moc.cxx \ GraphicsView_ViewPort_moc.cxx \ -GraphicsView_Scene_moc.cxx +GraphicsView_Scene_moc.cxx \ +GraphicsView_PrsPropDlg_moc.cxx nodist_libGraphicsView_la_SOURCES = $(MOC_FILES) @@ -67,6 +73,7 @@ resources/graphics_view_fitselect.png \ resources/graphics_view_glpan.png \ resources/graphics_view_pan.png \ resources/graphics_view_reset.png \ +resources/graphics_view_rotate.png \ resources/graphics_view_zoom.png nodist_salomeres_DATA = \ @@ -74,6 +81,6 @@ nodist_salomeres_DATA = \ GraphicsView_msg_en.qm \ GraphicsView_msg_fr.qm -libGraphicsView_la_CPPFLAGS = $(QT_INCLUDES) -I$(srcdir)/../SUIT -I$(srcdir)/../Qtx -libGraphicsView_la_LDFLAGS = $(QT_MT_LIBS) +libGraphicsView_la_CPPFLAGS = $(QT_INCLUDES) $(CAS_CPPFLAGS) -I$(srcdir)/../SUIT -I$(srcdir)/../Qtx +libGraphicsView_la_LDFLAGS = $(QT_MT_LIBS) $(CAS_KERNEL) libGraphicsView_la_LIBADD = ../SUIT/libsuit.la diff --git a/src/GraphicsView/resources/GraphicsView_images.ts b/src/GraphicsView/resources/GraphicsView_images.ts index 9de9cd021..ca607b209 100644 --- a/src/GraphicsView/resources/GraphicsView_images.ts +++ b/src/GraphicsView/resources/GraphicsView_images.ts @@ -37,5 +37,9 @@ ICON_GV_FITAREA graphics_view_fitarea.png + + ICON_GV_ROTATE + graphics_view_rotate.png + diff --git a/src/GraphicsView/resources/GraphicsView_msg_en.ts b/src/GraphicsView/resources/GraphicsView_msg_en.ts index a6f2fe92f..6c0eaae65 100644 --- a/src/GraphicsView/resources/GraphicsView_msg_en.ts +++ b/src/GraphicsView/resources/GraphicsView_msg_en.ts @@ -77,6 +77,30 @@ CHANGE_BGCOLOR Change background... + + ADD_IMAGE + Add image + + + REMOVE_IMAGES + Remove image(s) + + + BRING_FORWARD + Bring forward + + + SEND_BACKWARD + Send backward + + + PROPERTIES + Properties + + + TEST_IMAGE_COMPOSITION + Test image composition + GraphicsView_ViewManager @@ -85,4 +109,31 @@ Graphics scene:%M - viewer:%V + + GraphicsView_PrsPropDlg + + PROPERTIES + Properties + + + POSITION_X + Position X + + + POSITION_Y + Position Y + + + SCALING_X + Scaling X + + + SCALING_Y + Scaling Y + + + ROTATION_ANGLE + Rotation angle + + diff --git a/src/GraphicsView/resources/graphics_view_rotate.png b/src/GraphicsView/resources/graphics_view_rotate.png new file mode 100755 index 000000000..3f180b40c Binary files /dev/null and b/src/GraphicsView/resources/graphics_view_rotate.png differ