Salome HOME
PR: mergefrom_BSEC_br1_14Mar04
[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 using namespace std;
49
50 /*!
51     Constructor
52 */
53 OCCViewer_ViewPort3d::OCCViewer_ViewPort3d( QWidget* parent, const Handle( V3d_Viewer)& viewer,
54                                             V3d_TypeOfView  viewType, OCCViewer_ViewPort* prevView , 
55                                             const QRect* magnify ) : 
56   OCCViewer_ViewPort( parent )
57 {
58   if ( viewType == V3d_ORTHOGRAPHIC )
59     myActiveView = new V3d_OrthographicView( viewer );        
60   else
61     myActiveView = new V3d_PerspectiveView( viewer );        
62   
63   myCurScale = 1.0;
64   myDegenerated = true;    
65
66   myActiveView->SetDegenerateModeOn();
67
68   if ( prevView ) setOriginalView( prevView, *magnify );
69 }
70
71 /*!
72     Destructor
73 */
74 OCCViewer_ViewPort3d::~OCCViewer_ViewPort3d()
75 {
76   myActiveView->Remove();    
77 }
78
79 /*!
80     Creates the popup 
81 */
82 void OCCViewer_ViewPort3d::onCreatePopup() 
83 {
84   if ( myPopup ) {      
85     QAD_Desktop*     Desktop = (QAD_Desktop*) QAD_Application::getDesktop();
86     QAD_Study*   myActiveStudy = Desktop->getActiveStudy();
87     SALOME_Selection*      Sel = SALOME_Selection::Selection( myActiveStudy->getSelection() );
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       QAD_CONFIG->addSetting( "OCCViewer:BackgroundColorRed",   color.red() );
299       QAD_CONFIG->addSetting( "OCCViewer:BackgroundColorGreen", color.green() );
300       QAD_CONFIG->addSetting( "OCCViewer:BackgroundColorBlue",  color.blue() );
301       
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 }