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