Salome HOME
Harmonisation of GUI.
[modules/hydro.git] / src / HYDROGUI / HYDROGUI_PrsImageFrame.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_PrsImageFrame.h"
24
25 #include "HYDROGUI_PrsImage.h"
26
27 #include <QPainter>
28
29 #define FRAME_Z_VALUE   1000
30 #define ANCHOR_RADIUS   3
31 #define EPSILON         1e-6
32
33 //=======================================================================
34 // name    : HYDROGUI_PrsImageFrame
35 // Purpose : Constructor
36 //=======================================================================
37 HYDROGUI_PrsImageFrame::HYDROGUI_PrsImageFrame( HYDROGUI_PrsImage* thePrsImage )
38 : GraphicsView_Object( thePrsImage ),
39   myPrsImage( thePrsImage )
40 {
41 }
42
43 //=======================================================================
44 // name    : HYDROGUI_PrsImageFrame
45 // Purpose : Destructor
46 //=======================================================================
47 HYDROGUI_PrsImageFrame::~HYDROGUI_PrsImageFrame()
48 {
49 }
50
51 //================================================================
52 // Function : boundingRect
53 // Purpose  : 
54 //================================================================
55 QRectF HYDROGUI_PrsImageFrame::boundingRect() const
56 {
57   QRectF aRect;
58   AnchorMapIterator anIter( myAnchorMap );
59   while( anIter.hasNext() )
60   {
61     if( QGraphicsEllipseItem* anAnchorItem = anIter.next().value() )
62     {
63       QRectF anAnchorRect = anAnchorItem->boundingRect();
64       if( !anAnchorRect.isNull() )
65       {
66         if( aRect.isNull() )
67           aRect = anAnchorRect;
68         else
69           aRect |= anAnchorRect;
70       }
71     }
72   }
73   return aRect;
74 }
75
76 //================================================================
77 // Function : compute
78 // Purpose  : 
79 //================================================================
80 void HYDROGUI_PrsImageFrame::compute()
81 {
82   if( myAnchorMap.isEmpty() )
83   {
84     for( int aType = TopLeft; aType <= BottomRight; aType++ )
85     {
86       UnscaledGraphicsEllipseItem* anAnchorItem = new UnscaledGraphicsEllipseItem( this );
87       anAnchorItem->setBrush( QBrush( Qt::white ) );
88       myAnchorMap.insert( aType, anAnchorItem );
89       addToGroup( anAnchorItem );
90     }
91   }
92
93   setZValue( FRAME_Z_VALUE );
94
95   computeAnchorItems();
96   updateVisibility();
97 }
98
99 //================================================================
100 // Function : computeAnchorItems
101 // Purpose  : 
102 //================================================================
103 void HYDROGUI_PrsImageFrame::computeAnchorItems()
104 {
105   if( !myPrsImage )
106     return;
107
108   QRectF aRect = myPrsImage->boundingRect();
109
110   QMap<int, QPointF> anAnchorPointMap;
111   anAnchorPointMap[ TopLeft ] = aRect.topLeft();
112   anAnchorPointMap[ TopRight ] = aRect.topRight();
113   anAnchorPointMap[ BottomLeft ] = aRect.bottomLeft();
114   anAnchorPointMap[ BottomRight ] = aRect.bottomRight();
115
116   qreal ar = ANCHOR_RADIUS;
117   QMapIterator<int, QPointF> anIter( anAnchorPointMap );
118   while( anIter.hasNext() )
119   {
120     int anAnchorType = anIter.next().key();
121     const QPointF& anAnchorPoint = anIter.value();
122
123     QRectF anAnchorRect( anAnchorPoint - QPointF( ar, ar ), QSizeF( ar * 2, ar * 2 ) );
124     myAnchorMap[ anAnchorType ]->setRect( anAnchorRect );
125     myAnchorMap[ anAnchorType ]->setBasePoint( anAnchorPoint );
126   }
127 }
128
129 //================================================================
130 // Function : updateVisibility
131 // Purpose  : 
132 //================================================================
133 void HYDROGUI_PrsImageFrame::updateVisibility()
134 {
135   setVisible( myPrsImage && myPrsImage->isSelected() );
136 }
137
138 //=======================================================================
139 // name    : HYDROGUI_PrsImageFrame::UnscaledGraphicsEllipseItem
140 // Purpose : Constructor
141 //=======================================================================
142 HYDROGUI_PrsImageFrame::UnscaledGraphicsEllipseItem::UnscaledGraphicsEllipseItem( QGraphicsItem* theParent )
143 : QGraphicsEllipseItem( theParent )
144 {
145 }
146
147 //=======================================================================
148 // name    : HYDROGUI_PrsImageFrame::UnscaledGraphicsEllipseItem
149 // Purpose : Destructor
150 //=======================================================================
151 HYDROGUI_PrsImageFrame::UnscaledGraphicsEllipseItem::~UnscaledGraphicsEllipseItem()
152 {
153 }
154
155 //================================================================
156 // Function : boundingRect
157 // Purpose  : 
158 //================================================================
159 QRectF HYDROGUI_PrsImageFrame::UnscaledGraphicsEllipseItem::boundingRect() const
160 {
161   QRectF aRect = QGraphicsEllipseItem::boundingRect();
162
163   GraphicsView_Object* aParent = dynamic_cast<GraphicsView_Object*>( parentItem() );
164   if( !aParent )
165     return aRect;
166
167   // take into account a transformation of the base image item
168   double aXScale = 1.0;
169   double aYScale = 1.0;
170   if( QGraphicsItem* aGrandParent = aParent->parentItem() )
171   {
172     QTransform aTransform = aGrandParent->transform();
173     QLineF aLine( 0, 0, 1, 1 );
174     aLine = aTransform.map( aLine );
175     aXScale = aLine.dx();
176     aYScale = aLine.dy();
177   }
178
179   QTransform aViewTransform = aParent->getViewTransform();
180   double aScale = aViewTransform.m11(); // same as m22(), viewer specific
181   if( fabs( aScale ) < EPSILON || fabs( aXScale ) < EPSILON || fabs( aYScale ) < EPSILON)
182     return aRect;
183
184   QPointF aCenter = aRect.center();
185   double aWidth = aRect.width() / aScale / aXScale;
186   double aHeight = aRect.height() / aScale / aYScale;
187
188   aRect = QRectF( aCenter.x() - aWidth / 2, aCenter.y() - aHeight / 2, aWidth, aHeight );
189   return aRect;
190 }
191
192 //================================================================
193 // Function : GenerateTranslationOnlyTransform
194 // Purpose  : 
195 //================================================================
196 static QTransform GenerateTranslationOnlyTransform( const QTransform &theOriginalTransform,
197                                                     const QPointF &theTargetPoint )
198 {
199   qreal dx = theOriginalTransform.m11() * theTargetPoint.x() - theTargetPoint.x() +
200              theOriginalTransform.m21() * theTargetPoint.y() +
201              theOriginalTransform.m31();
202   qreal dy = theOriginalTransform.m22() * theTargetPoint.y() - theTargetPoint.y() +
203              theOriginalTransform.m12() * theTargetPoint.x() +
204              theOriginalTransform.m32();
205   return QTransform::fromTranslate( dx, dy );
206 }
207
208 //================================================================
209 // Function : paint
210 // Purpose  : 
211 //================================================================
212 void HYDROGUI_PrsImageFrame::UnscaledGraphicsEllipseItem::paint(
213   QPainter* thePainter,
214   const QStyleOptionGraphicsItem* theOption,
215   QWidget* theWidget )
216 {
217   thePainter->save();
218   thePainter->setTransform( GenerateTranslationOnlyTransform( thePainter->transform(),
219                                                               myBasePoint ) );
220   QGraphicsEllipseItem::paint( thePainter, theOption, theWidget );
221   thePainter->restore();
222 }