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