Salome HOME
8b2c8a0ebcd3ec42a13d634a5f73a7ef450a84a1
[modules/hydro.git] / src / HYDROGUI / HYDROGUI_PrsImage.cxx
1 // Copyright (C) 2007-2013  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 #include "HYDROGUI_PrsImage.h"
24
25 #include "HYDROGUI_PrsImageFrame.h"
26
27 #include <GraphicsView_ViewPort.h>
28
29 #include <QCursor>
30 #include <QApplication>
31
32 //=======================================================================
33 // name    : HYDROGUI_PrsImage
34 // Purpose : Constructor
35 //=======================================================================
36 HYDROGUI_PrsImage::HYDROGUI_PrsImage( const Handle(HYDROData_Entity)& theObject )
37 : HYDROGUI_Prs( theObject ),
38   myPixmapItem( 0 ),
39   myCaptionItem( 0 ),
40   myPrsImageFrame( 0 ),
41   myIsTransformationPointPreview( false ),
42   myIsByTwoPoints( true ),
43   myTransformationPointType( None )
44 {
45   myTransformationPointCursor = new QCursor( Qt::CrossCursor );
46 }
47
48 //=======================================================================
49 // name    : HYDROGUI_PrsImage
50 // Purpose : Destructor
51 //=======================================================================
52 HYDROGUI_PrsImage::~HYDROGUI_PrsImage()
53 {
54   if( myTransformationPointCursor )
55   {
56     delete myTransformationPointCursor;
57     myTransformationPointCursor = 0;
58   }
59 }
60
61 //================================================================
62 // Function : setImage
63 // Purpose  : 
64 //================================================================
65 void HYDROGUI_PrsImage::setImage( const QImage& theImage )
66 {
67   myImage = theImage;
68 }
69
70 //================================================================
71 // Function : getImage
72 // Purpose  : 
73 //================================================================
74 QImage HYDROGUI_PrsImage::getImage() const
75 {
76   return myImage;
77 }
78
79 //================================================================
80 // Function : setCaption
81 // Purpose  : 
82 //================================================================
83 void HYDROGUI_PrsImage::setCaption( const QString& theCaption )
84 {
85   if( myCaptionItem )
86   {
87     myCaptionItem->setText( theCaption );
88     myCaptionItem->setVisible( !theCaption.isEmpty() );
89   }
90 }
91
92 //================================================================
93 // Function : getCaption
94 // Purpose  : 
95 //================================================================
96 QString HYDROGUI_PrsImage::getCaption() const
97 {
98   if( myCaptionItem )
99     return myCaptionItem->text();
100   return QString();
101 }
102
103 //================================================================
104 // Function : setIsTransformationPointPreview
105 // Purpose  : 
106 //================================================================
107 void HYDROGUI_PrsImage::setIsTransformationPointPreview( const bool theState )
108 {
109   myIsTransformationPointPreview = theState;
110 }
111
112 //================================================================
113 // Function : getIsTransformationPointPreview
114 // Purpose  : 
115 //================================================================
116 bool HYDROGUI_PrsImage::getIsTransformationPointPreview() const
117 {
118   return myIsTransformationPointPreview;
119 }
120
121 //================================================================
122 // Function : setTransformationPointType
123 // Purpose  : 
124 //================================================================
125 void HYDROGUI_PrsImage::setTransformationPointType( const int thePointType )
126 {
127   myTransformationPointType = thePointType;
128   if( thePointType != None )
129     computeTransformationPoints();
130 }
131
132 //================================================================
133 // Function : setTransformationPointMap
134 // Purpose  : 
135 //================================================================
136 void HYDROGUI_PrsImage::setTransformationPointMap( const TransformationPointMap& theMap )
137 {
138   myTransformationPointMap = theMap;
139   if( !theMap.isEmpty() )
140     computeTransformationPoints();
141 }
142
143 //================================================================
144 // Function : updateTransformationPoint
145 // Purpose  : 
146 //================================================================
147 void HYDROGUI_PrsImage::updateTransformationPoint( const int thePointType,
148                                                    const bool theIsY,
149                                                    const int theValue )
150 {
151   if( myTransformationPointMap.find( thePointType ) != myTransformationPointMap.end() )
152   {
153     TransformationPoint& aTransformationPoint = myTransformationPointMap[ thePointType ];
154     QPoint& aPoint = aTransformationPoint.Point;
155     theIsY ? aPoint.setY( theValue ) : aPoint.setX( theValue );
156     computeTransformationPoints();
157   }
158 }
159
160 //================================================================
161 // Function : boundingRect
162 // Purpose  : 
163 //================================================================
164 QRectF HYDROGUI_PrsImage::boundingRect() const
165 {
166   return myPixmapItem->boundingRect();
167 }
168
169 //================================================================
170 // Function : compute
171 // Purpose  : 
172 //================================================================
173 void HYDROGUI_PrsImage::compute()
174 {
175   if( !myPixmapItem )
176   {
177     myPixmapItem = new QGraphicsPixmapItem( this );
178     addToGroup( myPixmapItem );
179   }
180   if( !myCaptionItem )
181   {
182     myCaptionItem = new QGraphicsSimpleTextItem( this );
183
184     QFont aFont = myCaptionItem->font();
185     aFont.setPointSize( 14 );
186     myCaptionItem->setFont( aFont );
187
188     addToGroup( myCaptionItem );
189   }
190   if( !myPrsImageFrame )
191   {
192     myPrsImageFrame = new HYDROGUI_PrsImageFrame( this );
193     addToGroup( myPrsImageFrame );
194   }
195
196   myPixmapItem->setPixmap( QPixmap::fromImage( myImage ) );
197
198   myCaptionItem->setPos( 0, -30 );
199   myCaptionItem->setVisible( false );
200
201   myPrsImageFrame->compute();
202 }
203
204 //================================================================
205 // Function : addTo
206 // Purpose  : 
207 //================================================================
208 void HYDROGUI_PrsImage::addTo( GraphicsView_ViewPort* theViewPort )
209 {
210   HYDROGUI_Prs::addTo( theViewPort );
211   theViewPort->addItem( myPrsImageFrame );
212 }
213
214 //================================================================
215 // Function : removeFrom
216 // Purpose  : 
217 //================================================================
218 void HYDROGUI_PrsImage::removeFrom( GraphicsView_ViewPort* theViewPort )
219 {
220   HYDROGUI_Prs::removeFrom( theViewPort );
221   theViewPort->removeItem( myPrsImageFrame );
222 }
223
224 //================================================================
225 // Function : checkHighlight
226 // Purpose  : 
227 //================================================================
228 bool HYDROGUI_PrsImage::checkHighlight( double theX, double theY, QCursor& theCursor ) const
229 {
230   QRect aRect = myPixmapItem->boundingRect().toRect();
231   QPolygon aPolygon = sceneTransform().mapToPolygon( aRect );
232   if( aPolygon.containsPoint( QPoint( theX, theY ), Qt::OddEvenFill ) )
233   {
234     if( myIsTransformationPointPreview )
235     {
236       if( myTransformationPointType != None )
237         theCursor = *getTransformationPointCursor();
238     }
239     else
240       theCursor = *getHighlightCursor();
241     return true;
242   }
243   return false;
244 }
245
246 //================================================================
247 // Function : select
248 // Purpose  : 
249 //================================================================
250 bool HYDROGUI_PrsImage::select( double theX, double theY, const QRectF& theRect )
251 {
252   if( myIsTransformationPointPreview )
253   {
254     if( myTransformationPointType == None || !theRect.isEmpty() )
255       return false;
256
257     QPoint aPos = pos().toPoint();
258
259     TransformationPoint& aTransformationPoint = myTransformationPointMap[ myTransformationPointType ];
260     aTransformationPoint.Point = QPoint( (int)theX, (int)theY ) - aPos;
261     computeTransformationPoints();
262     return true;
263   }
264
265   bool anIsSelected = HYDROGUI_Prs::select( theX, theY, theRect );
266   myPrsImageFrame->updateVisibility();
267   return anIsSelected;
268 }
269
270 //================================================================
271 // Function : unselect
272 // Purpose  : 
273 //================================================================
274 void HYDROGUI_PrsImage::unselect()
275 {
276   HYDROGUI_Prs::unselect();
277   if( !myIsTransformationPointPreview )
278     myPrsImageFrame->updateVisibility();
279 }
280
281 //================================================================
282 // Function : setSelected
283 // Purpose  : 
284 //================================================================
285 void HYDROGUI_PrsImage::setSelected( bool theState )
286 {
287   HYDROGUI_Prs::setSelected( theState );
288   if( !myIsTransformationPointPreview )
289     myPrsImageFrame->updateVisibility();
290 }
291
292 //================================================================
293 // Function : computeTransformationPoints
294 // Purpose  : 
295 //================================================================
296 void HYDROGUI_PrsImage::computeTransformationPoints()
297 {
298   if( myTransformationPointMap.isEmpty() )
299   {
300     int aWidth = myImage.width();
301     int aHeight = myImage.height();
302
303     // Create presentations for transformation points A, B and C
304     for( int aPointType = PointA; aPointType <= PointC; aPointType++ )
305     {
306       TransformationPoint aTransformationPoint;
307
308       QPoint aPoint;
309       QString aCaption;
310       QColor aColor = Qt::black;
311       switch( aPointType )
312       {
313         case PointA:
314           aPoint = QPoint( 0, 0 );
315           aCaption = "A";
316           aColor = Qt::darkRed;
317           break;
318         case PointB:
319           aPoint = QPoint( aWidth, 0 );
320           aCaption = "B";
321           aColor = Qt::darkGreen;
322           break;
323         case PointC:
324           aPoint = QPoint( 0, aHeight );
325           aCaption = "C";
326           aColor = Qt::darkBlue;
327           break;
328       }
329       
330       aTransformationPoint.Point = aPoint;
331       aTransformationPoint.Caption = aCaption;
332
333       QGraphicsEllipseItem* aPointItem = new QGraphicsEllipseItem( this );
334       aPointItem->setPen( QPen( aColor ) );
335       aPointItem->setBrush( QBrush( aColor ) );
336
337       double aRadius = 3;
338       QRectF aRect( -QPointF( aRadius, aRadius ), QSizeF( aRadius * 2 + 1, aRadius * 2 + 1 ) );
339       aPointItem->setRect( aRect );
340       aPointItem->setPos( QPointF( 0, 0 ) );
341
342       QGraphicsSimpleTextItem* aCaptionItem = aCaptionItem = new QGraphicsSimpleTextItem( aCaption, this );
343       aCaptionItem->setPen( QPen( aColor ) );
344       aCaptionItem->setBrush( QBrush( aColor ) );
345       QFont aFont = aCaptionItem->font();
346       aFont.setPointSize( qApp->font().pointSize() );
347       aCaptionItem->setFont( aFont );
348       aCaptionItem->setPos( QPointF( -aRadius * 2, aRadius * 2 ) );
349
350       aTransformationPoint.GroupItem = new QGraphicsItemGroup( this );
351       aTransformationPoint.GroupItem->addToGroup( aPointItem );
352       aTransformationPoint.GroupItem->addToGroup( aCaptionItem );
353       aTransformationPoint.GroupItem->setVisible( false );
354       aTransformationPoint.GroupItem->setFlag( QGraphicsItem::ItemIgnoresTransformations );
355       aTransformationPoint.GroupItem->setPos( aPoint );
356
357       myTransformationPointMap[ aPointType ] = aTransformationPoint;
358     }
359   }
360
361   for( int aPointType = PointA; aPointType <= PointC; aPointType++ )
362   {
363     // Show/hide the point if necessary
364     updateTrsfPoint( aPointType );
365   }
366 }
367
368 //================================================================
369 // Function : updateTrsfPoint
370 // Purpose  : 
371 //================================================================
372 void HYDROGUI_PrsImage::updateTrsfPoint( const int thePointType )
373 {
374   // If image is transformed only by two points then the point C is invisible
375   bool anIsPointVisible = myIsTransformationPointPreview && ( 
376     ( !myIsByTwoPoints ) || ( myIsByTwoPoints && ( thePointType != PointC ) ) );
377
378   TransformationPoint& aTransformationPoint = myTransformationPointMap[ thePointType ];
379
380   const QPointF& aPoint = aTransformationPoint.Point;
381   aTransformationPoint.GroupItem->setPos( aPoint );
382   aTransformationPoint.GroupItem->setVisible( anIsPointVisible );
383 }
384
385 //================================================================
386 // Function : getIsByTwoPoints
387 // Purpose  : 
388 //================================================================
389 bool HYDROGUI_PrsImage::getIsByTwoPoints() const
390 {
391   return myIsByTwoPoints;
392 }
393
394 //================================================================
395 // Function : setIsByTwoPoints
396 // Purpose  : 
397 //================================================================
398 void HYDROGUI_PrsImage::setIsByTwoPoints( const bool theIsByTwoPoints )
399 {
400   myIsByTwoPoints = theIsByTwoPoints;
401   if ( myTransformationPointMap.contains( PointC ) )
402   {
403     // Show/hide the point C if necessary
404     updateTrsfPoint( PointC );
405   }
406 }