Salome HOME
Merge branch 'BR_IMPROVEMENTS' of ssh://git.salome-platform.org/modules/hydro into...
[modules/hydro.git] / src / HYDROGUI / HYDROGUI_PrsImage.cxx
1 // Copyright (C) 2007-2015  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, or (at your option) any later version.
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, const bool theCompute )
66 {
67   myImage = theImage;
68   if ( theCompute ) {
69     compute();
70     computeTransformationPoints( true );
71   }
72 }
73
74 //================================================================
75 // Function : getImage
76 // Purpose  : 
77 //================================================================
78 QImage HYDROGUI_PrsImage::getImage() const
79 {
80   return myImage;
81 }
82
83 //================================================================
84 // Function : setCaption
85 // Purpose  : 
86 //================================================================
87 void HYDROGUI_PrsImage::setCaption( const QString& theCaption )
88 {
89   if( myCaptionItem )
90   {
91     myCaptionItem->setText( theCaption );
92     myCaptionItem->setVisible( !theCaption.isEmpty() );
93   }
94 }
95
96 //================================================================
97 // Function : getCaption
98 // Purpose  : 
99 //================================================================
100 QString HYDROGUI_PrsImage::getCaption() const
101 {
102   if( myCaptionItem )
103     return myCaptionItem->text();
104   return QString();
105 }
106
107 //================================================================
108 // Function : setIsTransformationPointPreview
109 // Purpose  : 
110 //================================================================
111 void HYDROGUI_PrsImage::setIsTransformationPointPreview( const bool theState )
112 {
113   myIsTransformationPointPreview = theState;
114 }
115
116 //================================================================
117 // Function : getIsTransformationPointPreview
118 // Purpose  : 
119 //================================================================
120 bool HYDROGUI_PrsImage::getIsTransformationPointPreview() const
121 {
122   return myIsTransformationPointPreview;
123 }
124
125 //================================================================
126 // Function : setTransformationPointType
127 // Purpose  : 
128 //================================================================
129 void HYDROGUI_PrsImage::setTransformationPointType( const int thePointType )
130 {
131   myTransformationPointType = thePointType;
132   if( thePointType != None )
133     computeTransformationPoints();
134 }
135
136 //================================================================
137 // Function : setTransformationPointMap
138 // Purpose  : 
139 //================================================================
140 void HYDROGUI_PrsImage::setTransformationPointMap( const TransformationPointMap& theMap )
141 {
142   myTransformationPointMap = theMap;
143   if( !theMap.isEmpty() )
144     computeTransformationPoints();
145 }
146
147 //================================================================
148 // Function : updateTransformationPoint
149 // Purpose  : 
150 //================================================================
151 void HYDROGUI_PrsImage::updateTransformationPoint( const int thePointType,
152                                                    const bool theIsY,
153                                                    const int theValue )
154 {
155   if( myTransformationPointMap.find( thePointType ) != myTransformationPointMap.end() )
156   {
157     TransformationPoint& aTransformationPoint = myTransformationPointMap[ thePointType ];
158     QPoint& aPoint = aTransformationPoint.Point;
159     theIsY ? aPoint.setY( theValue ) : aPoint.setX( theValue );
160     computeTransformationPoints();
161   }
162 }
163
164 //================================================================
165 // Function : setTransformationPointCursorShape
166 // Purpose  : 
167 //================================================================
168 void HYDROGUI_PrsImage::setTransformationPointCursorShape(Qt::CursorShape theCursorShape)
169 {
170   if ( myTransformationPointCursor )
171     myTransformationPointCursor->setShape(theCursorShape);
172 }
173
174 //================================================================
175 // Function : boundingRect
176 // Purpose  : 
177 //================================================================
178 QRectF HYDROGUI_PrsImage::boundingRect() const
179 {
180   return myPixmapItem->boundingRect();
181 }
182
183 //================================================================
184 // Function : compute
185 // Purpose  : 
186 //================================================================
187 void HYDROGUI_PrsImage::compute()
188 {
189   if( !myPixmapItem )
190   {
191     myPixmapItem = new QGraphicsPixmapItem( this );
192     addToGroup( myPixmapItem );
193   }
194   if( !myCaptionItem )
195   {
196     myCaptionItem = new QGraphicsSimpleTextItem( this );
197
198     QFont aFont = myCaptionItem->font();
199     aFont.setPointSize( 14 );
200     myCaptionItem->setFont( aFont );
201
202     addToGroup( myCaptionItem );
203   }
204   if( !myPrsImageFrame )
205   {
206     myPrsImageFrame = new HYDROGUI_PrsImageFrame( this );
207     addToGroup( myPrsImageFrame );
208   }
209
210   myPixmapItem->setPixmap( QPixmap::fromImage( myImage ) );
211
212   myCaptionItem->setPos( 0, -30 );
213   myCaptionItem->setVisible( false );
214
215   myPrsImageFrame->compute();
216 }
217
218 //================================================================
219 // Function : addTo
220 // Purpose  : 
221 //================================================================
222 void HYDROGUI_PrsImage::addTo( GraphicsView_ViewPort* theViewPort )
223 {
224   HYDROGUI_Prs::addTo( theViewPort );
225   theViewPort->addItem( myPrsImageFrame );
226 }
227
228 //================================================================
229 // Function : removeFrom
230 // Purpose  : 
231 //================================================================
232 void HYDROGUI_PrsImage::removeFrom( GraphicsView_ViewPort* theViewPort )
233 {
234   HYDROGUI_Prs::removeFrom( theViewPort );
235   theViewPort->removeItem( myPrsImageFrame );
236 }
237
238 //================================================================
239 // Function : checkHighlight
240 // Purpose  : 
241 //================================================================
242 bool HYDROGUI_PrsImage::checkHighlight( double theX, double theY, QCursor& theCursor ) const
243 {
244   QRect aRect = myPixmapItem->boundingRect().toRect();
245   QPolygon aPolygon = sceneTransform().mapToPolygon( aRect );
246   if( aPolygon.containsPoint( QPoint( theX, theY ), Qt::OddEvenFill ) )
247   {
248     if( myIsTransformationPointPreview )
249     {
250       if( myTransformationPointType != None )
251         theCursor = *getTransformationPointCursor();
252     }
253     else
254       theCursor = *getHighlightCursor();
255     return true;
256   }
257   return false;
258 }
259
260 //================================================================
261 // Function : select
262 // Purpose  : 
263 //================================================================
264 bool HYDROGUI_PrsImage::select( double theX, double theY, const QRectF& theRect )
265 {
266   if( myIsTransformationPointPreview )
267   {
268     if( myTransformationPointType == None || !theRect.isEmpty() )
269       return false;
270
271     QPoint aPos = pos().toPoint();
272
273     TransformationPoint& aTransformationPoint = myTransformationPointMap[ myTransformationPointType ];
274     aTransformationPoint.Point = QPoint( (int)theX, (int)theY ) - aPos;
275     computeTransformationPoints();
276     return true;
277   }
278
279   bool anIsSelected = HYDROGUI_Prs::select( theX, theY, theRect );
280   myPrsImageFrame->updateVisibility();
281   return anIsSelected;
282 }
283
284 //================================================================
285 // Function : unselect
286 // Purpose  : 
287 //================================================================
288 void HYDROGUI_PrsImage::unselect()
289 {
290   HYDROGUI_Prs::unselect();
291   if( !myIsTransformationPointPreview )
292     myPrsImageFrame->updateVisibility();
293 }
294
295 //================================================================
296 // Function : setSelected
297 // Purpose  : 
298 //================================================================
299 void HYDROGUI_PrsImage::setSelected( bool theState )
300 {
301   HYDROGUI_Prs::setSelected( theState );
302   if( !myIsTransformationPointPreview )
303     myPrsImageFrame->updateVisibility();
304 }
305
306 //================================================================
307 // Function : computeTransformationPoints
308 // Purpose  : 
309 //================================================================
310 void HYDROGUI_PrsImage::computeTransformationPoints( const bool theObligatoryInit )
311 {
312   {
313     for( int aPointType = PointA; aPointType <= PointC; aPointType++ )
314     {
315       if( myTransformationPointMap.isEmpty() || theObligatoryInit )
316         initTrsfPoints( aPointType );
317       // Show/hide the point if necessary
318       updateTrsfPoint( aPointType );
319
320     }
321   }
322 }
323
324 QGraphicsItemGroup* HYDROGUI_PrsImage::createPointItem( const QString& theCaption,
325                                                         const QColor& theColor )
326 {
327   QGraphicsEllipseItem* aPointItem = new QGraphicsEllipseItem( this );
328   aPointItem->setPen( QPen( theColor ) );
329   aPointItem->setBrush( QBrush( theColor ) );
330
331   double aRadius = 3;
332   QRectF aRect( -QPointF( aRadius, aRadius ), QSizeF( aRadius * 2 + 1, aRadius * 2 + 1 ) );
333   aPointItem->setRect( aRect );
334   aPointItem->setPos( QPointF( 0, 0 ) );
335
336   QGraphicsSimpleTextItem* aCaptionItem = aCaptionItem = new QGraphicsSimpleTextItem( theCaption, this );
337   aCaptionItem->setPen( QPen( theColor ) );
338   aCaptionItem->setBrush( QBrush( theColor ) );
339   QFont aFont = aCaptionItem->font();
340   aFont.setPointSize( qApp->font().pointSize() );
341   aCaptionItem->setFont( aFont );
342   aCaptionItem->setPos( QPointF( -aRadius * 2, aRadius * 2 ) );
343
344   QGraphicsItemGroup* aGroupItem = new QGraphicsItemGroup( this );
345   aGroupItem->addToGroup( aPointItem );
346   aGroupItem->addToGroup( aCaptionItem );
347   aGroupItem->setVisible( false );
348   aGroupItem->setFlag( QGraphicsItem::ItemIgnoresTransformations );
349
350   return aGroupItem;
351 }
352
353 //================================================================
354 // Function : initTrsfPoints
355 // Purpose  : 
356 //================================================================
357 void HYDROGUI_PrsImage::initTrsfPoints( const int thePointType )
358 {
359   QPoint aPoint;
360   QString aCaption;
361   QColor aColor = Qt::black;
362
363   int aWidth = myImage.width();
364   int aHeight = myImage.height();
365   switch( thePointType )
366   {
367     case PointA:
368       aPoint = QPoint( 0, 0 );
369       aCaption = "A";
370       aColor = Qt::darkRed;
371       break;
372     case PointB:
373       aPoint = QPoint( aWidth, 0 );
374       aCaption = "B";
375       aColor = Qt::darkGreen;
376       break;
377     case PointC:
378       aPoint = QPoint( 0, aHeight );
379       aCaption = "C";
380       aColor = Qt::darkBlue;
381       break;
382   }
383
384   TransformationPoint aTransformationPoint;
385   if ( myTransformationPointMap.contains( thePointType ) )
386     aTransformationPoint = myTransformationPointMap[thePointType];
387
388   aTransformationPoint.Point = aPoint;
389   aTransformationPoint.Caption = aCaption;
390   if ( !aTransformationPoint.GroupItem )
391     aTransformationPoint.GroupItem = createPointItem( aCaption, aColor );
392   aTransformationPoint.GroupItem->setPos( aPoint );
393
394   myTransformationPointMap[ thePointType ] = aTransformationPoint;
395 }
396
397 //================================================================
398 // Function : updateTrsfPoint
399 // Purpose  : 
400 //================================================================
401 void HYDROGUI_PrsImage::updateTrsfPoint( const int thePointType )
402 {
403   // If image is transformed only by two points then the point C is invisible
404   bool anIsPointVisible = myIsTransformationPointPreview && ( 
405     ( !myIsByTwoPoints ) || ( myIsByTwoPoints && ( thePointType != PointC ) ) );
406
407   TransformationPoint& aTransformationPoint = myTransformationPointMap[ thePointType ];
408
409   const QPointF& aPoint = aTransformationPoint.Point;
410   aTransformationPoint.GroupItem->setPos( aPoint );
411   aTransformationPoint.GroupItem->setVisible( anIsPointVisible );
412 }
413
414 //================================================================
415 // Function : getIsByTwoPoints
416 // Purpose  : 
417 //================================================================
418 bool HYDROGUI_PrsImage::getIsByTwoPoints() const
419 {
420   return myIsByTwoPoints;
421 }
422
423 //================================================================
424 // Function : setIsByTwoPoints
425 // Purpose  : 
426 //================================================================
427 void HYDROGUI_PrsImage::setIsByTwoPoints( const bool theIsByTwoPoints )
428 {
429   myIsByTwoPoints = theIsByTwoPoints;
430   if ( myTransformationPointMap.contains( PointC ) )
431   {
432     // Show/hide the point C if necessary
433     updateTrsfPoint( PointC );
434   }
435 }