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