Salome HOME
PR: merge from tag mergeto_trunk_17Jan05
[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     
88     QString theContext;
89     QString theParent("Viewer");
90     QString theObject;
91     
92     Desktop->definePopup( theContext, theParent, theObject );
93     Desktop->createPopup( myPopup, theContext, theParent, theObject);
94     Desktop->customPopup( myPopup, theContext, theParent, theObject );
95
96 //    if (Sel->IObjectCount() == 0 && myPopup->count()<1) {
97     if ( myPopup->count() > 0 )
98       myIDs.append ( myPopup->insertSeparator() );      
99     int id;
100     myIDs.append ( id = myPopup->insertItem (tr ("MEN_VP3D_CHANGEBGR")) );      
101     QAD_ASSERT ( myPopup->connectItem ( id, this, SLOT(onChangeBackgroundColor())) );
102 //    }
103   }
104 }
105
106 /*!
107     Sets new CASCADE view on viewport.
108     Returns the previous view or null if the view hasn't been set.
109 */
110 Handle (V3d_View) OCCViewer_ViewPort3d::setView( const Handle (V3d_View)& view )
111 {       
112   Handle (V3d_View) oldView = myActiveView;
113   myActiveView = view;
114   if ( hasWindow() ) setWindow();
115   return oldView;
116 }
117
118 /*!
119     Returns CasCade 3D view
120 */
121 Handle(V3d_View) OCCViewer_ViewPort3d::getView() const
122 {
123   return myActiveView;
124 }
125
126 /*!
127     Returns CasCade 3D viewer
128 */
129 Handle (V3d_Viewer) OCCViewer_ViewPort3d::getViewer() const
130 {
131   Handle (V3d_Viewer) viewer;
132   if ( !myActiveView.IsNull() )
133     viewer = myActiveView->Viewer();
134   return viewer;
135 }
136
137 /*!
138     Passed the handle of native window of the component to CASCADE view
139     (sets window handle for V3d_View class instance).
140 */
141 bool OCCViewer_ViewPort3d::setWindow()
142 {
143   if ( !myActiveView.IsNull() )
144     {
145       int windowHandle = (int) winId();
146       if ( windowHandle == 0 )
147         return false;
148       
149       short hi, lo;
150       lo = (short) windowHandle;
151       hi = (short) (windowHandle >> 16);
152       
153       OCCViewer_ViewPort* preView = getOriginalView();
154       if ( preView )
155         {
156           /* Create new window ( 'magnify' operation ) 
157            */
158           Handle (V3d_View) view;
159           QRect rect = getMagnifyRect();                        
160           if ( preView->inherits("OCCViewer_ViewPort3d") )      
161             {   
162               view = ((OCCViewer_ViewPort3d*)preView)->getView();
163             }                   
164           if ( !view.IsNull() && !rect.isEmpty() )
165             {
166               OCCViewer_VService::SetMagnify(myActiveView, (int)hi, (int) lo, view,
167                                              rect.x(), rect.y(), 
168                                              rect.x() + rect.width(), rect.y() + rect.height(),
169                                              Xw_WQ_SAMEQUALITY);
170               return true;
171             }
172         }
173       
174       /* CasCade will use our widget as the drawing window */
175       OCCViewer_VService::SetWindow( myActiveView, (int) hi, (int) lo, Xw_WQ_SAMEQUALITY);
176       return true;
177     }
178   return false;
179 }
180
181 /*!
182   Forces the CASCADE view to resize window   
183 */
184 void OCCViewer_ViewPort3d::windowResize()
185 {
186   QApplication::syncX();
187   if ( !myActiveView.IsNull() )
188     myActiveView->MustBeResized();
189 }
190
191 /*!
192   Called at 'window fit' transformation
193 */
194 void OCCViewer_ViewPort3d::fitWindow(const QRect& rect)
195 {
196   if ( !myActiveView.IsNull() )
197     {
198       myActiveView->WindowFit( rect.x(), rect.y(), rect.x() + rect.width(), 
199                                rect.y() + rect.height());
200     }
201 }
202
203 /*!
204     Called at 'zoom' transformation
205 */
206 void OCCViewer_ViewPort3d::zoom(int x0, int y0, int x, int y)
207 {
208   if ( !myActiveView.IsNull() )
209     myActiveView->Zoom(x0, y0, x, y);
210 }
211
212 /*!
213   Centers the viewport 
214 */
215 void OCCViewer_ViewPort3d::setCenter(int x, int y)
216 {
217   if ( !myActiveView.IsNull() )
218     {
219       myActiveView->Place(x, y, myCurScale);
220     }
221 }
222
223 /*!
224   Called at 'pan' transformation
225 */
226 void OCCViewer_ViewPort3d::pan(int dx, int dy)
227 {
228   if ( !myActiveView.IsNull() )
229     {
230       myActiveView->Pan(dx, dy, 1.0);
231     }
232 }
233
234 /*!
235     Inits 'rotation' transformation
236 */
237 void OCCViewer_ViewPort3d::startRotation(int x0, int y0)
238 {
239   if ( !myActiveView.IsNull() )
240     {
241       myDegenerated = myActiveView->DegenerateModeIsOn();
242       myActiveView->SetDegenerateModeOn();
243       myActiveView->StartRotation(x0, y0);
244     }
245 }
246
247 /*!
248     Rotates the viewport
249 */
250 void OCCViewer_ViewPort3d::rotate(int x, int y)
251 {
252   if ( !myActiveView.IsNull() )
253     {
254       myActiveView->Rotation(x, y);
255     }
256 }
257
258 /*!
259     Resets the viewport after 'rotation' 
260 */
261 void OCCViewer_ViewPort3d::endRotation()
262 {
263   if ( !myActiveView.IsNull() ) 
264     {
265       if ( !myDegenerated )
266         myActiveView->SetDegenerateModeOff();
267     }
268 }
269
270 /*!
271     Called to update the background color
272 */
273 QColor OCCViewer_ViewPort3d::backgroundColor() const
274 {
275   if ( !myActiveView.IsNull() ) 
276     {   
277       Standard_Real aRed, aGreen, aBlue;
278       myActiveView->BackgroundColor(Quantity_TOC_RGB, aRed, aGreen, aBlue);
279       int red = (int) (aRed * 255);
280       int green = (int) (aGreen * 255);
281       int blue = (int) (aBlue * 255);
282       return QColor(red, green, blue);
283     }
284   return OCCViewer_ViewPort::backgroundColor();
285 }
286
287 /*!
288     Sets the background color    
289 */
290 void OCCViewer_ViewPort3d::setBackgroundColor( const QColor& color)
291 {
292   if ( !myActiveView.IsNull() ) 
293     {           
294       myActiveView->SetBackgroundColor( Quantity_TOC_RGB, color.red()/255., 
295                                         color.green()/255., color.blue()/255.);
296
297       /* VSR : PAL5420 ---------------------------------------------------
298       QAD_CONFIG->addSetting( "OCCViewer:BackgroundColorRed",   color.red() );
299       QAD_CONFIG->addSetting( "OCCViewer:BackgroundColorGreen", color.green() );
300       QAD_CONFIG->addSetting( "OCCViewer:BackgroundColorBlue",  color.blue() );
301       VSR : PAL5420 --------------------------------------------------- */
302       myActiveView->Update();
303     }
304 }
305
306 /*!
307     Sets the background color with color selection dialog
308 */
309 void OCCViewer_ViewPort3d::onChangeBackgroundColor()
310 {
311   if ( !myActiveView.IsNull() ) 
312     {   
313       QColor selColor = QColorDialog::getColor ( backgroundColor(), this );     
314       if ( selColor.isValid() )
315         {       
316           setBackgroundColor( selColor );
317         }
318     }           
319 }
320
321 /*!
322     Repaints the viewport
323 */
324 void OCCViewer_ViewPort3d::paintEvent (QPaintEvent* e )
325 {
326   if ( myActiveView.IsNull() )
327     {
328       QPainter thePainter (this);
329       thePainter.drawText(50, 50, QObject::tr("ERR_VP_NOVIEW"), 7);
330     }
331   else
332     {
333       QApplication::syncX();    
334       if ( !myHasWindow )
335         {
336           myHasWindow = setWindow();
337           if ( myHasWindow ) fitAll();
338         }       
339       if ( myHasWindow ) 
340         {       
341           QRect visibleRect = e->rect();
342           if ( (!myDrawRect) && (!myPaintersRedrawing) )
343             {
344               myActiveView->Redraw ( visibleRect.x(), visibleRect.y(), visibleRect.width(), 
345                                      visibleRect.height());
346             }
347         } 
348     } 
349   OCCViewer_ViewPort::paintEvent( e );
350 }
351
352 /*!
353     Called at 'global panning' transformation    
354 */
355 void OCCViewer_ViewPort3d::activateGlobalPanning()
356 {
357   if ( !myActiveView.IsNull() )
358     {
359       myCurScale = myActiveView->Scale();
360       myActiveView->FitAll(0.01, false);
361     }
362   OCCViewer_ViewPort::activateGlobalPanning();
363 }
364
365 /*!
366     Fits all objects in view
367 */
368 void OCCViewer_ViewPort3d::fitAll( bool withZ )
369 {
370   if ( !myActiveView.IsNull() )
371     {
372       myActiveView->FitAll(0.01, true);
373       if ( withZ ) myActiveView->ZFitAll(0.0);
374     }
375 }
376
377 /*!
378     Resets the view 
379 */
380 void OCCViewer_ViewPort3d::reset() 
381 {
382   if ( !myActiveView.IsNull() )
383     {
384       myActiveView->Reset();
385     }
386 }
387
388 /*!
389   Incremental panning
390 */
391 void OCCViewer_ViewPort3d::incrementalPan( const int incrX, const int incrY )
392 {
393   this->pan( incrX, incrY );
394 }
395
396 /*!
397   Incremental zooming
398 */
399 void OCCViewer_ViewPort3d::incrementalZoom( const int incr )
400 {
401   int cx = width()  / 2;
402   int cy = height() / 2;
403   this->zoom( cx, cy, cx + incr, cy + incr );
404 }
405
406 /*!
407   Incremental rotating
408 */
409 void OCCViewer_ViewPort3d::incrementalRotate( const int incrX, const int incrY )
410 {
411   int cx = width()  / 2;
412   int cy = height() / 2;
413   this->startRotation( cx, cy );
414   this->rotate( cx + incrX, cy + incrY );
415   this->endRotation();
416 }
417
418