Salome HOME
68a73d4a5b47cde0a8660cbb9e84de4349643bb7
[modules/kernel.git] / src / OCCViewer / OCCViewer_ViewPort3d.cxx
1 //  SALOME OCCViewer : build OCC Viewer into Salome desktop
2 //
3 //  Copyright (C) 2003  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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
21 //
22 //
23 //
24 //  File   : OCCViewer_ViewPort3d.cxx
25 //  Author : Nicolas REJNERI
26 //  Module : SALOME
27 //  $Header$
28
29 #include "OCCViewer_ViewPort3d.h"
30
31 #include "QAD.h"
32 #include "QAD_Settings.h"
33 #include "QAD_Config.h"
34 #include "QAD_Desktop.h"
35 #include "QAD_Study.h"
36 #include "SALOME_Selection.h"
37
38 // QT Include
39 #include <qcolordialog.h>
40
41 // Open CASCADE Includes
42 #include <V3d_PerspectiveView.hxx>
43 #include <V3d_OrthographicView.hxx>
44
45 #if !defined WNT
46 #include <Xw.hxx>
47 #endif
48
49 using namespace std;
50
51 /*!
52     Constructor
53 */
54 OCCViewer_ViewPort3d::OCCViewer_ViewPort3d( QWidget* parent, const Handle( V3d_Viewer)& viewer,
55                                             V3d_TypeOfView  viewType, OCCViewer_ViewPort* prevView , 
56                                             const QRect* magnify ) : 
57   OCCViewer_ViewPort( parent )
58 {
59   if ( viewType == V3d_ORTHOGRAPHIC )
60     myActiveView = new V3d_OrthographicView( viewer );        
61   else
62     myActiveView = new V3d_PerspectiveView( viewer );        
63   
64   myCurScale = 1.0;
65   myDegenerated = true;    
66
67   myActiveView->SetDegenerateModeOn();
68
69   if ( prevView ) setOriginalView( prevView, *magnify );
70 }
71
72 /*!
73     Destructor
74 */
75 OCCViewer_ViewPort3d::~OCCViewer_ViewPort3d()
76 {
77   myActiveView->Remove();    
78 }
79
80 /*!
81     Creates the popup 
82 */
83 void OCCViewer_ViewPort3d::onCreatePopup() 
84 {
85   if ( myPopup ) {      
86     QAD_Desktop*     Desktop = (QAD_Desktop*) QAD_Application::getDesktop();
87     QAD_Study*   myActiveStudy = Desktop->getActiveStudy();
88     
89     QString theContext;
90     QString theParent("Viewer");
91     QString theObject;
92     
93     Desktop->definePopup( theContext, theParent, theObject );
94     Desktop->createPopup( myPopup, theContext, theParent, theObject);
95     Desktop->customPopup( myPopup, theContext, theParent, theObject );
96
97 //    if (Sel->IObjectCount() == 0 && myPopup->count()<1) {
98     if ( myPopup->count() > 0 )
99       myIDs.append ( myPopup->insertSeparator() );      
100     int id;
101     myIDs.append ( id = myPopup->insertItem (tr ("MEN_VP3D_CHANGEBGR")) );      
102     QAD_ASSERT ( myPopup->connectItem ( id, this, SLOT(onChangeBackgroundColor())) );
103 //    }
104   }
105 }
106
107 /*!
108     Sets new CASCADE view on viewport.
109     Returns the previous view or null if the view hasn't been set.
110 */
111 Handle (V3d_View) OCCViewer_ViewPort3d::setView( const Handle (V3d_View)& view )
112 {       
113   Handle (V3d_View) oldView = myActiveView;
114   myActiveView = view;
115   if ( hasWindow() ) setWindow();
116   return oldView;
117 }
118
119 /*!
120     Returns CasCade 3D view
121 */
122 Handle(V3d_View) OCCViewer_ViewPort3d::getView() const
123 {
124   return myActiveView;
125 }
126
127 /*!
128     Returns CasCade 3D viewer
129 */
130 Handle (V3d_Viewer) OCCViewer_ViewPort3d::getViewer() const
131 {
132   Handle (V3d_Viewer) viewer;
133   if ( !myActiveView.IsNull() )
134     viewer = myActiveView->Viewer();
135   return viewer;
136 }
137
138 /*!
139     Passed the handle of native window of the component to CASCADE view
140     (sets window handle for V3d_View class instance).
141 */
142 bool OCCViewer_ViewPort3d::setWindow()
143 {
144   if ( !myActiveView.IsNull() )
145     {
146       int windowHandle = (int) winId();
147       if ( windowHandle == 0 )
148         return false;
149       
150       short hi, lo;
151       lo = (short) windowHandle;
152       hi = (short) (windowHandle >> 16);
153       
154       OCCViewer_ViewPort* preView = getOriginalView();
155       if ( preView )
156         {
157           /* Create new window ( 'magnify' operation ) 
158            */
159           Handle (V3d_View) view;
160           QRect rect = getMagnifyRect();                        
161           if ( preView->inherits("OCCViewer_ViewPort3d") )      
162             {   
163               view = ((OCCViewer_ViewPort3d*)preView)->getView();
164             }                   
165           if ( !view.IsNull() && !rect.isEmpty() )
166             {
167               OCCViewer_VService::SetMagnify(myActiveView, (int)hi, (int) lo, view,
168                                              rect.x(), rect.y(), 
169                                              rect.x() + rect.width(), rect.y() + rect.height(),
170                                              Xw_WQ_SAMEQUALITY);
171               return true;
172             }
173         }
174       
175       /* CasCade will use our widget as the drawing window */
176       OCCViewer_VService::SetWindow( myActiveView, (int) hi, (int) lo, Xw_WQ_SAMEQUALITY);
177       return true;
178     }
179   return false;
180 }
181
182 /*!
183   Forces the CASCADE view to resize window   
184 */
185 void OCCViewer_ViewPort3d::windowResize()
186 {
187   QApplication::syncX();
188   if ( !myActiveView.IsNull() )
189     myActiveView->MustBeResized();
190 }
191
192 /*!
193   Called at 'window fit' transformation
194 */
195 void OCCViewer_ViewPort3d::fitWindow(const QRect& rect)
196 {
197   if ( !myActiveView.IsNull() )
198     {
199       myActiveView->WindowFit( rect.x(), rect.y(), rect.x() + rect.width(), 
200                                rect.y() + rect.height());
201     }
202 }
203
204 /*!
205     Called at 'zoom' transformation
206 */
207 void OCCViewer_ViewPort3d::zoom(int x0, int y0, int x, int y)
208 {
209   if ( !myActiveView.IsNull() )
210     myActiveView->Zoom(x0, y0, x, y);
211 }
212
213 /*!
214   Centers the viewport 
215 */
216 void OCCViewer_ViewPort3d::setCenter(int x, int y)
217 {
218   if ( !myActiveView.IsNull() )
219     {
220       myActiveView->Place(x, y, myCurScale);
221     }
222 }
223
224 /*!
225   Called at 'pan' transformation
226 */
227 void OCCViewer_ViewPort3d::pan(int dx, int dy)
228 {
229   if ( !myActiveView.IsNull() )
230     {
231       myActiveView->Pan(dx, dy, 1.0);
232     }
233 }
234
235 /*!
236     Inits 'rotation' transformation
237 */
238 void OCCViewer_ViewPort3d::startRotation(int x0, int y0)
239 {
240   if ( !myActiveView.IsNull() )
241     {
242       myDegenerated = myActiveView->DegenerateModeIsOn();
243       myActiveView->SetDegenerateModeOn();
244       myActiveView->StartRotation(x0, y0);
245     }
246 }
247
248 /*!
249     Rotates the viewport
250 */
251 void OCCViewer_ViewPort3d::rotate(int x, int y)
252 {
253   if ( !myActiveView.IsNull() )
254     {
255       myActiveView->Rotation(x, y);
256     }
257 }
258
259 /*!
260     Resets the viewport after 'rotation' 
261 */
262 void OCCViewer_ViewPort3d::endRotation()
263 {
264   if ( !myActiveView.IsNull() ) 
265     {
266       if ( !myDegenerated )
267         myActiveView->SetDegenerateModeOff();
268     }
269 }
270
271 /*!
272     Called to update the background color
273 */
274 QColor OCCViewer_ViewPort3d::backgroundColor() const
275 {
276   if ( !myActiveView.IsNull() ) 
277     {   
278       Standard_Real aRed, aGreen, aBlue;
279       myActiveView->BackgroundColor(Quantity_TOC_RGB, aRed, aGreen, aBlue);
280       int red = (int) (aRed * 255);
281       int green = (int) (aGreen * 255);
282       int blue = (int) (aBlue * 255);
283       return QColor(red, green, blue);
284     }
285   return OCCViewer_ViewPort::backgroundColor();
286 }
287
288 /*!
289     Sets the background color    
290 */
291 void OCCViewer_ViewPort3d::setBackgroundColor( const QColor& color)
292 {
293   if ( !myActiveView.IsNull() ) 
294     {           
295       myActiveView->SetBackgroundColor( Quantity_TOC_RGB, color.red()/255., 
296                                         color.green()/255., color.blue()/255.);
297
298       /* VSR : PAL5420 ---------------------------------------------------
299       QAD_CONFIG->addSetting( "OCCViewer:BackgroundColorRed",   color.red() );
300       QAD_CONFIG->addSetting( "OCCViewer:BackgroundColorGreen", color.green() );
301       QAD_CONFIG->addSetting( "OCCViewer:BackgroundColorBlue",  color.blue() );
302       VSR : PAL5420 --------------------------------------------------- */
303       myActiveView->Update();
304     }
305 }
306
307 /*!
308     Sets the background color with color selection dialog
309 */
310 void OCCViewer_ViewPort3d::onChangeBackgroundColor()
311 {
312   if ( !myActiveView.IsNull() ) 
313     {   
314       QColor selColor = QColorDialog::getColor ( backgroundColor(), this );     
315       if ( selColor.isValid() )
316         {       
317           setBackgroundColor( selColor );
318         }
319     }           
320 }
321
322 /*!
323     Repaints the viewport
324 */
325 void OCCViewer_ViewPort3d::paintEvent (QPaintEvent* e )
326 {
327   if ( myActiveView.IsNull() )
328     {
329       QPainter thePainter (this);
330       thePainter.drawText(50, 50, QObject::tr("ERR_VP_NOVIEW"), 7);
331     }
332   else
333     {
334       QApplication::syncX();    
335       if ( !myHasWindow )
336         {
337           myHasWindow = setWindow();
338           if ( myHasWindow ) fitAll();
339         }       
340       if ( myHasWindow ) 
341         {       
342           QRect visibleRect = e->rect();
343           if ( (!myDrawRect) && (!myPaintersRedrawing) )
344             {
345               myActiveView->Redraw ( visibleRect.x(), visibleRect.y(), visibleRect.width(), 
346                                      visibleRect.height());
347             }
348         } 
349     } 
350   OCCViewer_ViewPort::paintEvent( e );
351 }
352
353 /*!
354     Called at 'global panning' transformation    
355 */
356 void OCCViewer_ViewPort3d::activateGlobalPanning()
357 {
358   if ( !myActiveView.IsNull() )
359     {
360       myCurScale = myActiveView->Scale();
361       myActiveView->FitAll(0.01, false);
362     }
363   OCCViewer_ViewPort::activateGlobalPanning();
364 }
365
366 /*!
367     Fits all objects in view
368 */
369 void OCCViewer_ViewPort3d::fitAll( bool withZ )
370 {
371   if ( !myActiveView.IsNull() )
372     {
373       myActiveView->FitAll(0.01, true);
374       if ( withZ ) myActiveView->ZFitAll(0.0);
375     }
376 }
377
378 /*!
379     Resets the view 
380 */
381 void OCCViewer_ViewPort3d::reset() 
382 {
383   if ( !myActiveView.IsNull() )
384     {
385       myActiveView->Reset();
386     }
387 }