Salome HOME
Merge branch 'BR_H2018_3' into BR_2018_V8_5
[modules/hydro.git] / src / HYDROGUI / HYDROGUI_PrsImage.cxx
1 // Copyright (C) 2014-2015  EDF-R&D
2 // This library is free software; you can redistribute it and/or
3 // modify it under the terms of the GNU Lesser General Public
4 // License as published by the Free Software Foundation; either
5 // version 2.1 of the License, or (at your option) any later version.
6 //
7 // This library is distributed in the hope that it will be useful,
8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
10 // Lesser General Public License for more details.
11 //
12 // You should have received a copy of the GNU Lesser General Public
13 // License along with this library; if not, write to the Free Software
14 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
15 //
16 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
17 //
18
19 #include "HYDROGUI_PrsImage.h"
20
21 #include "HYDROGUI_PrsImageFrame.h"
22
23 #include <GraphicsView_ViewPort.h>
24
25 #include <QCursor>
26 #include <QApplication>
27
28 //=======================================================================
29 // name    : HYDROGUI_PrsImage
30 // Purpose : Constructor
31 //=======================================================================
32 HYDROGUI_PrsImage::HYDROGUI_PrsImage( const Handle(HYDROData_Entity)& theObject )
33 : HYDROGUI_Prs( theObject ),
34   myPixmapItem( 0 ),
35   myCaptionItem( 0 ),
36   myPrsImageFrame( 0 ),
37   myIsTransformationPointPreview( false ),
38   myIsByTwoPoints( true ),
39   myTransformationPointType( None )
40 {
41   myTransformationPointCursor = new QCursor( Qt::CrossCursor );
42 }
43
44 //=======================================================================
45 // name    : HYDROGUI_PrsImage
46 // Purpose : Destructor
47 //=======================================================================
48 HYDROGUI_PrsImage::~HYDROGUI_PrsImage()
49 {
50   if( myTransformationPointCursor )
51   {
52     delete myTransformationPointCursor;
53     myTransformationPointCursor = 0;
54   }
55 }
56
57 //================================================================
58 // Function : setImage
59 // Purpose  : 
60 //================================================================
61 void HYDROGUI_PrsImage::setImage( const QImage& theImage, const bool theCompute )
62 {
63   myImage = theImage;
64   if ( theCompute ) {
65     compute();
66     computeTransformationPoints( true );
67   }
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 : setTransformationPointCursorShape
162 // Purpose  : 
163 //================================================================
164 void HYDROGUI_PrsImage::setTransformationPointCursorShape(Qt::CursorShape theCursorShape)
165 {
166   if ( myTransformationPointCursor )
167     myTransformationPointCursor->setShape(theCursorShape);
168 }
169
170 //================================================================
171 // Function : boundingRect
172 // Purpose  : 
173 //================================================================
174 QRectF HYDROGUI_PrsImage::boundingRect() const
175 {
176   return myPixmapItem->boundingRect();
177 }
178
179 //================================================================
180 // Function : compute
181 // Purpose  : 
182 //================================================================
183 void HYDROGUI_PrsImage::compute()
184 {
185   if( !myPixmapItem )
186   {
187     myPixmapItem = new QGraphicsPixmapItem( this );
188     addToGroup( myPixmapItem );
189   }
190   if( !myCaptionItem )
191   {
192     myCaptionItem = new QGraphicsSimpleTextItem( this );
193
194     QFont aFont = myCaptionItem->font();
195     aFont.setPointSize( 14 );
196     myCaptionItem->setFont( aFont );
197
198     addToGroup( myCaptionItem );
199   }
200   if( !myPrsImageFrame )
201   {
202     myPrsImageFrame = new HYDROGUI_PrsImageFrame( this );
203     addToGroup( myPrsImageFrame );
204   }
205
206   myPixmapItem->setPixmap( QPixmap::fromImage( myImage ) );
207
208   myCaptionItem->setPos( 0, -30 );
209   myCaptionItem->setVisible( false );
210
211   myPrsImageFrame->compute();
212 }
213
214 //================================================================
215 // Function : addTo
216 // Purpose  : 
217 //================================================================
218 void HYDROGUI_PrsImage::addTo( GraphicsView_ViewPort* theViewPort )
219 {
220   HYDROGUI_Prs::addTo( theViewPort );
221   theViewPort->addItem( myPrsImageFrame );
222 }
223
224 //================================================================
225 // Function : removeFrom
226 // Purpose  : 
227 //================================================================
228 void HYDROGUI_PrsImage::removeFrom( GraphicsView_ViewPort* theViewPort )
229 {
230   HYDROGUI_Prs::removeFrom( theViewPort );
231   theViewPort->removeItem( myPrsImageFrame );
232 }
233
234 //================================================================
235 // Function : checkHighlight
236 // Purpose  : 
237 //================================================================
238 bool HYDROGUI_PrsImage::checkHighlight( double theX, double theY, QCursor& theCursor ) const
239 {
240   QRect aRect = myPixmapItem->boundingRect().toRect();
241   QPolygon aPolygon = sceneTransform().mapToPolygon( aRect );
242   if( aPolygon.containsPoint( QPoint( theX, theY ), Qt::OddEvenFill ) )
243   {
244     if( myIsTransformationPointPreview )
245     {
246       if( myTransformationPointType != None )
247         theCursor = *getTransformationPointCursor();
248     }
249     else
250       theCursor = *getHighlightCursor();
251     return true;
252   }
253   return false;
254 }
255
256 //================================================================
257 // Function : select
258 // Purpose  : 
259 //================================================================
260 bool HYDROGUI_PrsImage::select( double theX, double theY, const QRectF& theRect )
261 {
262   if( myIsTransformationPointPreview )
263   {
264     if( myTransformationPointType == None || !theRect.isEmpty() )
265       return false;
266
267     QPoint aPos = pos().toPoint();
268
269     TransformationPoint& aTransformationPoint = myTransformationPointMap[ myTransformationPointType ];
270     aTransformationPoint.Point = QPoint( (int)theX, (int)theY ) - aPos;
271     computeTransformationPoints();
272     return true;
273   }
274
275   bool anIsSelected = HYDROGUI_Prs::select( theX, theY, theRect );
276   myPrsImageFrame->updateVisibility();
277   return anIsSelected;
278 }
279
280 //================================================================
281 // Function : unselect
282 // Purpose  : 
283 //================================================================
284 void HYDROGUI_PrsImage::unselect()
285 {
286   HYDROGUI_Prs::unselect();
287   if( !myIsTransformationPointPreview )
288     myPrsImageFrame->updateVisibility();
289 }
290
291 //================================================================
292 // Function : setSelected
293 // Purpose  : 
294 //================================================================
295 void HYDROGUI_PrsImage::setSelected( bool theState )
296 {
297   HYDROGUI_Prs::setSelected( theState );
298   if( !myIsTransformationPointPreview )
299     myPrsImageFrame->updateVisibility();
300 }
301
302 //================================================================
303 // Function : computeTransformationPoints
304 // Purpose  : 
305 //================================================================
306 void HYDROGUI_PrsImage::computeTransformationPoints( const bool theObligatoryInit )
307 {
308   {
309     for( int aPointType = PointA; aPointType <= PointC; aPointType++ )
310     {
311       if( myTransformationPointMap.isEmpty() || theObligatoryInit )
312         initTrsfPoints( aPointType );
313       // Show/hide the point if necessary
314       updateTrsfPoint( aPointType );
315
316     }
317   }
318 }
319
320 QGraphicsItemGroup* HYDROGUI_PrsImage::createPointItem( const QString& theCaption,
321                                                         const QColor& theColor )
322 {
323   QGraphicsEllipseItem* aPointItem = new QGraphicsEllipseItem( this );
324   aPointItem->setPen( QPen( theColor ) );
325   aPointItem->setBrush( QBrush( theColor ) );
326
327   double aRadius = 3;
328   QRectF aRect( -QPointF( aRadius, aRadius ), QSizeF( aRadius * 2 + 1, aRadius * 2 + 1 ) );
329   aPointItem->setRect( aRect );
330   aPointItem->setPos( QPointF( 0, 0 ) );
331
332   QGraphicsSimpleTextItem* aCaptionItem = aCaptionItem = new QGraphicsSimpleTextItem( theCaption, this );
333   aCaptionItem->setPen( QPen( theColor ) );
334   aCaptionItem->setBrush( QBrush( theColor ) );
335   QFont aFont = aCaptionItem->font();
336   aFont.setPointSize( qApp->font().pointSize() );
337   aCaptionItem->setFont( aFont );
338   aCaptionItem->setPos( QPointF( -aRadius * 2, aRadius * 2 ) );
339
340   QGraphicsItemGroup* aGroupItem = new QGraphicsItemGroup( this );
341   aGroupItem->addToGroup( aPointItem );
342   aGroupItem->addToGroup( aCaptionItem );
343   aGroupItem->setVisible( false );
344   aGroupItem->setFlag( QGraphicsItem::ItemIgnoresTransformations );
345
346   return aGroupItem;
347 }
348
349 //================================================================
350 // Function : initTrsfPoints
351 // Purpose  : 
352 //================================================================
353 void HYDROGUI_PrsImage::initTrsfPoints( const int thePointType )
354 {
355   QPoint aPoint;
356   QString aCaption;
357   QColor aColor = Qt::black;
358
359   int aWidth = myImage.width();
360   int aHeight = myImage.height();
361   switch( thePointType )
362   {
363     case PointA:
364       aPoint = QPoint( 0, 0 );
365       aCaption = "A";
366       aColor = Qt::darkRed;
367       break;
368     case PointB:
369       aPoint = QPoint( aWidth, 0 );
370       aCaption = "B";
371       aColor = Qt::darkGreen;
372       break;
373     case PointC:
374       aPoint = QPoint( 0, aHeight );
375       aCaption = "C";
376       aColor = Qt::darkBlue;
377       break;
378   }
379
380   TransformationPoint aTransformationPoint;
381   if ( myTransformationPointMap.contains( thePointType ) )
382     aTransformationPoint = myTransformationPointMap[thePointType];
383
384   aTransformationPoint.Point = aPoint;
385   aTransformationPoint.Caption = aCaption;
386   if ( !aTransformationPoint.GroupItem )
387     aTransformationPoint.GroupItem = createPointItem( aCaption, aColor );
388   aTransformationPoint.GroupItem->setPos( aPoint );
389
390   myTransformationPointMap[ thePointType ] = aTransformationPoint;
391 }
392
393 //================================================================
394 // Function : updateTrsfPoint
395 // Purpose  : 
396 //================================================================
397 void HYDROGUI_PrsImage::updateTrsfPoint( const int thePointType )
398 {
399   // If image is transformed only by two points then the point C is invisible
400   bool anIsPointVisible = myIsTransformationPointPreview && ( 
401     ( !myIsByTwoPoints ) || ( myIsByTwoPoints && ( thePointType != PointC ) ) );
402
403   TransformationPoint& aTransformationPoint = myTransformationPointMap[ thePointType ];
404
405   const QPointF& aPoint = aTransformationPoint.Point;
406   aTransformationPoint.GroupItem->setPos( aPoint );
407   aTransformationPoint.GroupItem->setVisible( anIsPointVisible );
408 }
409
410 //================================================================
411 // Function : getIsByTwoPoints
412 // Purpose  : 
413 //================================================================
414 bool HYDROGUI_PrsImage::getIsByTwoPoints() const
415 {
416   return myIsByTwoPoints;
417 }
418
419 //================================================================
420 // Function : setIsByTwoPoints
421 // Purpose  : 
422 //================================================================
423 void HYDROGUI_PrsImage::setIsByTwoPoints( const bool theIsByTwoPoints )
424 {
425   myIsByTwoPoints = theIsByTwoPoints;
426   if ( myTransformationPointMap.contains( PointC ) )
427   {
428     // Show/hide the point C if necessary
429     updateTrsfPoint( PointC );
430   }
431 }