Salome HOME
Merge from OCC_development_generic_2006
[modules/gui.git] / src / SVTK / SVTK_RenderWindowInteractor.cxx
1 //  SALOME VTKViewer : build VTK 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   : 
25 //  Author : 
26 //  Module : SALOME
27 //  $Header$
28
29 #include "SVTK_RenderWindowInteractor.h"
30 #include "SVTK_GenericRenderWindowInteractor.h"
31
32 #include "SVTK_InteractorStyle.h"
33 #include "SVTK_Renderer.h"
34 #include "SVTK_Functor.h"
35 #include "SALOME_Actor.h"
36
37 #include "SVTK_SpaceMouse.h" 
38 #include "SVTK_Event.h" 
39
40 #include "VTKViewer_Algorithm.h"
41
42 // VTK Includes
43 #include <vtkObjectFactory.h>
44 #include <vtkRendererCollection.h>
45 #include <vtkRenderWindow.h>
46 #include <vtkGenericRenderWindowInteractor.h>
47 #include <vtkCallbackCommand.h>
48 #include <vtkCommand.h>
49 #include <vtkPicker.h>
50 #include <vtkCamera.h>
51
52 // QT Includes
53 #include <qtimer.h>
54 #include <qapplication.h>
55 #include <qcolordialog.h>
56 #include <qpaintdevice.h>
57
58 using namespace std;
59
60 static bool GENERATE_SUIT_EVENTS = false;
61 static bool FOCUS_UNDER_MOUSE = false;
62
63
64 //----------------------------------------------------------------------------
65 QVTK_RenderWindowInteractor
66 ::QVTK_RenderWindowInteractor(QWidget* theParent, 
67                               const char* theName):
68   QWidget(theParent,theName,Qt::WNoAutoErase),
69   myRenderWindow(vtkRenderWindow::New())
70 {
71   setMouseTracking(true);
72
73   myRenderWindow->Delete();
74   myRenderWindow->DoubleBufferOn();
75
76 #ifndef WNT
77   myRenderWindow->SetDisplayId((void*)x11Display());
78 #endif
79   myRenderWindow->SetWindowId((void*)winId());
80 }
81
82
83 void 
84 QVTK_RenderWindowInteractor
85 ::Initialize(vtkGenericRenderWindowInteractor* theDevice)
86 {
87   if(GetDevice())
88     myDevice->SetRenderWindow(NULL);
89
90   myDevice = theDevice;
91
92   if(theDevice)
93     theDevice->SetRenderWindow(getRenderWindow());
94 }
95
96 //----------------------------------------------------------------------------
97 QVTK_RenderWindowInteractor
98 ::~QVTK_RenderWindowInteractor() 
99 {
100   if(SVTK_SpaceMouse* aSpaceMouse = SVTK_SpaceMouse::getInstance())
101     if(aSpaceMouse->isSpaceMouseOn())
102       aSpaceMouse->close(x11Display());
103 }
104
105
106 //----------------------------------------------------------------------------
107 vtkGenericRenderWindowInteractor* 
108 QVTK_RenderWindowInteractor
109 ::GetDevice()
110 {
111   return myDevice.GetPointer();
112 }
113
114 //----------------------------------------------------------------------------
115 vtkRenderWindow*
116 QVTK_RenderWindowInteractor
117 ::getRenderWindow()
118 {
119   return myRenderWindow.GetPointer();
120 }
121
122 //----------------------------------------------------------------------------
123 void
124 QVTK_RenderWindowInteractor
125 ::InvokeEvent(unsigned long theEvent, void* theCallData)
126 {
127   GetDevice()->InvokeEvent(theEvent,theCallData);
128 }
129
130 //----------------------------------------------------------------------------
131 void
132 QVTK_RenderWindowInteractor
133 ::show()
134 {
135   QWidget::show();
136   update(); // needed for initial contents display on Win32
137 }
138
139 //----------------------------------------------------------------------------
140 void
141 QVTK_RenderWindowInteractor
142 ::polish()
143 {
144   // Final initialization just before the widget is displayed
145   GetDevice()->SetSize(width(),height());
146   if(!GetDevice()->GetInitialized()){
147     GetDevice()->Initialize();
148     GetDevice()->ConfigureEvent();
149   }
150 }
151
152 //----------------------------------------------------------------------------
153 void
154 QVTK_RenderWindowInteractor
155 ::resize(int w, int h) 
156 {
157   GetDevice()->UpdateSize(w,h);
158 }
159
160 //----------------------------------------------------------------------------
161 void
162 QVTK_RenderWindowInteractor
163 ::paintEvent( QPaintEvent* theEvent ) 
164 {
165   GetDevice()->Render();
166 }
167
168
169 //----------------------------------------------------------------------------
170 void
171 QVTK_RenderWindowInteractor
172 ::resizeEvent( QResizeEvent* theEvent )
173 {
174   int* aSize = getRenderWindow()->GetSize();
175   int aWidth = aSize[0];
176   int aHeight = aSize[1];
177
178   GetDevice()->UpdateSize(width(),height());
179
180   if(isVisible() && aWidth && aHeight){
181     if( aWidth != width() || aHeight != height() ) {
182       vtkRendererCollection * aRenderers = getRenderWindow()->GetRenderers();
183       aRenderers->InitTraversal();
184       double aCoeff = 1.0;
185       if(vtkRenderer *aRenderer = aRenderers->GetNextItem()) {
186         vtkCamera *aCamera = aRenderer->GetActiveCamera();
187         double aScale = aCamera->GetParallelScale();
188         if((aWidth - width())*(aHeight - height()) > 0)
189           aCoeff = sqrt(double(aWidth)/double(width())*double(height())/double(aHeight));
190         else
191           aCoeff = double(aWidth)/double(width());
192         aCamera->SetParallelScale(aScale*aCoeff);
193       }
194     }
195   }
196
197   update(); 
198 }
199
200
201 //----------------------------------------------------------------------------
202 void
203 QVTK_RenderWindowInteractor
204 ::contextMenuEvent( QContextMenuEvent* event )
205 {}
206
207
208 //----------------------------------------------------------------------------
209 void
210 QVTK_RenderWindowInteractor
211 ::mouseMoveEvent( QMouseEvent* event ) 
212 {
213   GetDevice()->SetEventInformationFlipY(event->x(), 
214                                         event->y(),
215                                         event->state() & ControlButton,
216                                         event->state() & ShiftButton);
217   GetDevice()->MouseMoveEvent();
218 }
219
220
221 //----------------------------------------------------------------------------
222 void
223 QVTK_RenderWindowInteractor
224 ::mousePressEvent( QMouseEvent* event ) 
225 {
226   GetDevice()->SetEventInformationFlipY(event->x(), 
227                                         event->y(),
228                                         event->state() & ControlButton,
229                                         event->state() & ShiftButton);
230   if( event->button() & LeftButton )
231     GetDevice()->LeftButtonPressEvent();
232   else if( event->button() & MidButton )
233     GetDevice()->MiddleButtonPressEvent();
234   else if( event->button() & RightButton )
235     GetDevice()->RightButtonPressEvent();
236 }
237
238
239 //----------------------------------------------------------------------------
240 void
241 QVTK_RenderWindowInteractor
242 ::mouseReleaseEvent( QMouseEvent *event )
243 {
244   GetDevice()->SetEventInformationFlipY(event->x(), 
245                                         event->y(),
246                                         event->state() & ControlButton,
247                                         event->state() & ShiftButton);
248
249   if( event->button() & LeftButton )
250     GetDevice()->LeftButtonReleaseEvent();
251   else if( event->button() & MidButton )
252     GetDevice()->MiddleButtonReleaseEvent();
253   else if( event->button() & RightButton )
254     GetDevice()->RightButtonReleaseEvent();
255 }
256
257
258 //----------------------------------------------------------------------------
259 void
260 QVTK_RenderWindowInteractor
261 ::mouseDoubleClickEvent( QMouseEvent* event )
262 {}
263
264
265 //----------------------------------------------------------------------------
266 void
267 QVTK_RenderWindowInteractor
268 ::wheelEvent( QWheelEvent* event )
269 {
270   setActiveWindow();
271   setFocus();
272 }
273
274
275 //----------------------------------------------------------------------------
276 void
277 QVTK_RenderWindowInteractor
278 ::keyPressEvent( QKeyEvent* event ) 
279 {
280   GetDevice()->SetKeyEventInformation(event->state() & ControlButton,
281                                       event->state() & ShiftButton,
282                                       event->key());
283   GetDevice()->KeyPressEvent();
284   GetDevice()->CharEvent();
285 }
286
287 //----------------------------------------------------------------------------
288 void
289 QVTK_RenderWindowInteractor
290 ::keyReleaseEvent( QKeyEvent * event ) 
291 {
292   GetDevice()->SetKeyEventInformation(event->state() & ControlButton,
293                                       event->state() & ShiftButton,
294                                       event->key());
295   GetDevice()->KeyReleaseEvent();
296 }
297
298
299 //----------------------------------------------------------------------------
300 void  
301 QVTK_RenderWindowInteractor
302 ::enterEvent( QEvent* event )
303 {
304   if(FOCUS_UNDER_MOUSE){
305     setActiveWindow();
306     setFocus();
307   }
308   GetDevice()->EnterEvent();
309 }
310
311 //----------------------------------------------------------------------------
312 void  
313 QVTK_RenderWindowInteractor
314 ::leaveEvent( QEvent * )
315 {
316   GetDevice()->LeaveEvent();
317 }
318
319
320 //----------------------------------------------------------------------------
321 void  
322 QVTK_RenderWindowInteractor
323 ::focusInEvent( QFocusEvent* event )
324 {
325   QWidget::focusInEvent( event );
326
327   // register set space mouse events receiver
328   if(SVTK_SpaceMouse* aSpaceMouse = SVTK_SpaceMouse::getInstance()){
329     if(!aSpaceMouse->isSpaceMouseOn()) {// initialize 3D space mouse driver 
330       aSpaceMouse->initialize(x11Display(),winId());
331     }else{
332       aSpaceMouse->setWindow(x11Display(),winId());
333     }
334   }
335 }
336
337 //----------------------------------------------------------------------------
338 void  
339 QVTK_RenderWindowInteractor
340 ::focusOutEvent ( QFocusEvent* event )
341 {
342   QWidget::focusOutEvent( event );
343
344   // unregister set space mouse events receiver
345   if(SVTK_SpaceMouse* aSpaceMouse = SVTK_SpaceMouse::getInstance()){
346     if(aSpaceMouse->isSpaceMouseOn())
347       aSpaceMouse->setWindow(x11Display(),0);
348   }
349 }
350
351
352 //----------------------------------------------------------------------------
353 bool 
354 QVTK_RenderWindowInteractor
355 ::x11Event( XEvent *xEvent )
356 {
357   // handle 3d space mouse events
358   if(SVTK_SpaceMouse* aSpaceMouse = SVTK_SpaceMouse::getInstance()){
359     if(aSpaceMouse->isSpaceMouseOn() && xEvent->type == ClientMessage){
360       SVTK_SpaceMouse::MoveEvent anEvent;
361       int type = aSpaceMouse->translateEvent( x11Display(), xEvent, &anEvent, 1.0, 1.0 );
362       switch( type ){
363       case SVTK_SpaceMouse::SpaceMouseMove : 
364         GetDevice()->InvokeEvent(SVTK::SpaceMouseMoveEvent, anEvent.data );
365         break;
366       case SVTK_SpaceMouse::SpaceButtonPress :
367         GetDevice()->InvokeEvent( SVTK::SpaceMouseButtonEvent, &anEvent.button );
368         break;
369       case SVTK_SpaceMouse::SpaceButtonRelease :
370         break;
371       }
372       return true; // stop handling the event
373     }
374   }
375
376   return QWidget::x11Event( xEvent );
377 }
378
379
380 //----------------------------------------------------------------------------
381 SVTK_RenderWindowInteractor
382 ::SVTK_RenderWindowInteractor(QWidget* theParent, 
383                                const char* theName):
384   QVTK_RenderWindowInteractor(theParent,theName),
385   myEventCallbackCommand(vtkCallbackCommand::New())
386 {
387   myEventCallbackCommand->Delete();
388
389   myEventCallbackCommand->SetClientData(this); 
390   myPriority = 0.0;
391
392   myEventCallbackCommand->SetCallback(SVTK_RenderWindowInteractor::ProcessEvents);
393 }
394
395 void
396 SVTK_RenderWindowInteractor
397 ::Initialize(vtkGenericRenderWindowInteractor* theDevice,
398              SVTK_Renderer* theRenderer,
399              SVTK_Selector* theSelector)
400 {
401   QVTK_RenderWindowInteractor::Initialize(theDevice);
402   SetRenderer(theRenderer);
403   SetSelector(theSelector);
404 }
405
406 //----------------------------------------------------------------------------
407 SVTK_RenderWindowInteractor
408 ::~SVTK_RenderWindowInteractor() 
409 {
410   // Sequence of the destruction call are fixed and should be changed.
411   // vtkRenderWindow instance should be destroyed after all vtkRenderer's
412   GetDevice()->SetInteractorStyle(NULL); 
413   while(!myInteractorStyles.empty()){
414     const PInteractorStyle& aStyle = myInteractorStyles.top();
415     aStyle->SetInteractor(NULL);
416     myInteractorStyles.pop();
417   }
418
419   SetRenderer(NULL);
420
421   GetDevice()->SetRenderWindow(NULL);
422 }
423
424 //----------------------------------------------------------------------------
425 SVTK_Renderer* 
426 SVTK_RenderWindowInteractor
427 ::GetRenderer()
428 {
429   return myRenderer.GetPointer();
430 }
431
432 vtkRenderer* 
433 SVTK_RenderWindowInteractor
434 ::getRenderer()
435 {
436   return GetRenderer()->GetDevice();
437 }
438
439 void
440 SVTK_RenderWindowInteractor
441 ::SetRenderer(SVTK_Renderer* theRenderer)
442 {
443   if(theRenderer == myRenderer.GetPointer())
444     return;
445
446   if(GetRenderer())
447     myRenderWindow->RemoveRenderer(getRenderer());
448
449   myRenderer = theRenderer;
450
451   if(GetRenderer())
452     myRenderWindow->AddRenderer(getRenderer());
453 }
454
455
456 //----------------------------------------------------------------------------
457 void
458 SVTK_RenderWindowInteractor
459 ::InitInteractorStyle(vtkInteractorStyle* theStyle)
460 {
461   GetDevice()->SetInteractorStyle(theStyle); 
462 }
463
464
465 //----------------------------------------------------------------------------
466 void
467 SVTK_RenderWindowInteractor
468 ::PushInteractorStyle(vtkInteractorStyle* theStyle)
469 {
470   myInteractorStyles.push(PInteractorStyle(theStyle));
471   InitInteractorStyle(theStyle);
472 }
473
474
475 //----------------------------------------------------------------------------
476 void
477 SVTK_RenderWindowInteractor
478 ::PopInteractorStyle()
479 {
480   if(GetInteractorStyle())
481     myInteractorStyles.pop();
482   
483   if(GetInteractorStyle()) 
484     InitInteractorStyle(GetInteractorStyle());
485 }
486
487
488 //----------------------------------------------------------------------------
489 vtkInteractorStyle* 
490 SVTK_RenderWindowInteractor
491 ::GetInteractorStyle()
492 {
493   return myInteractorStyles.empty() ? 0 : myInteractorStyles.top().GetPointer();
494 }
495
496
497 //----------------------------------------------------------------------------
498 SVTK_Selector* 
499 SVTK_RenderWindowInteractor
500 ::GetSelector() 
501
502   return mySelector.GetPointer(); 
503 }
504
505
506 void
507 SVTK_RenderWindowInteractor
508 ::SetSelector(SVTK_Selector* theSelector)
509
510   if(mySelector.GetPointer())
511     mySelector->RemoveObserver(myEventCallbackCommand.GetPointer());
512
513   mySelector = theSelector; 
514
515   if(mySelector.GetPointer())
516     mySelector->AddObserver(vtkCommand::EndPickEvent, 
517                             myEventCallbackCommand.GetPointer(), 
518                             myPriority);
519 }
520
521
522 //----------------------------------------------------------------------------
523 void 
524 SVTK_RenderWindowInteractor
525 ::ProcessEvents(vtkObject* vtkNotUsed(theObject), 
526                 unsigned long theEvent,
527                 void* theClientData, 
528                 void* vtkNotUsed(theCallData))
529 {
530   SVTK_RenderWindowInteractor* self = reinterpret_cast<SVTK_RenderWindowInteractor*>(theClientData);
531
532   switch(theEvent){
533   case vtkCommand::EndPickEvent:
534     self->onEmitSelectionChanged();
535     break;
536   }
537 }
538
539
540 //----------------------------------------------------------------
541 void
542 SVTK_RenderWindowInteractor
543 ::SetSelectionMode(Selection_Mode theMode)
544 {
545   mySelector->SetSelectionMode(theMode);
546 }
547
548
549 //----------------------------------------------------------------
550 Selection_Mode
551 SVTK_RenderWindowInteractor
552 ::SelectionMode() const
553 {
554   return mySelector->SelectionMode();
555 }
556
557
558 //----------------------------------------------------------------
559 void
560 SVTK_RenderWindowInteractor
561 ::onEmitSelectionChanged()
562 {
563   return emit selectionChanged();
564 }
565
566
567 //----------------------------------------------------------------------------
568 void
569 SVTK_RenderWindowInteractor
570 ::mouseMoveEvent( QMouseEvent* event ) 
571 {
572   QVTK_RenderWindowInteractor::mouseMoveEvent(event);
573
574   if(GENERATE_SUIT_EVENTS)
575     emit MouseMove( event );
576 }
577
578
579 //----------------------------------------------------------------------------
580 void
581 SVTK_RenderWindowInteractor
582 ::mousePressEvent( QMouseEvent* event ) 
583 {
584   QVTK_RenderWindowInteractor::mousePressEvent(event);
585
586   if(GENERATE_SUIT_EVENTS)
587     emit MouseButtonPressed( event );
588 }
589
590
591 //----------------------------------------------------------------------------
592 void
593 SVTK_RenderWindowInteractor
594 ::mouseReleaseEvent( QMouseEvent *event )
595 {
596   QVTK_RenderWindowInteractor::mouseReleaseEvent(event);
597
598   if(GENERATE_SUIT_EVENTS)
599     emit MouseButtonReleased( event );
600 }
601
602
603 //----------------------------------------------------------------------------
604 void
605 SVTK_RenderWindowInteractor
606 ::mouseDoubleClickEvent( QMouseEvent* event )
607 {
608   QVTK_RenderWindowInteractor::mouseDoubleClickEvent(event);
609
610   if(GENERATE_SUIT_EVENTS)
611     emit MouseDoubleClicked( event );
612 }
613
614
615 //----------------------------------------------------------------------------
616 void
617 SVTK_RenderWindowInteractor
618 ::wheelEvent( QWheelEvent* event )
619 {
620   QVTK_RenderWindowInteractor::wheelEvent(event);
621
622   if(event->delta() > 0)
623     GetDevice()->InvokeEvent(SVTK::ZoomInEvent,NULL);
624   else
625     GetDevice()->InvokeEvent(SVTK::ZoomOutEvent,NULL);
626
627   if(GENERATE_SUIT_EVENTS)
628     emit WheelMoved( event );
629 }
630
631
632 //----------------------------------------------------------------------------
633 void
634 SVTK_RenderWindowInteractor
635 ::keyPressEvent( QKeyEvent* event ) 
636 {
637   QVTK_RenderWindowInteractor::keyPressEvent(event);
638
639   if(GENERATE_SUIT_EVENTS)
640     emit KeyPressed( event );
641 }
642
643 //----------------------------------------------------------------------------
644 void
645 SVTK_RenderWindowInteractor
646 ::keyReleaseEvent( QKeyEvent * event ) 
647 {
648   QVTK_RenderWindowInteractor::keyReleaseEvent(event);
649
650   if(GENERATE_SUIT_EVENTS)
651     emit KeyReleased( event );
652 }
653
654 //----------------------------------------------------------------------------
655 void
656 SVTK_RenderWindowInteractor
657 ::contextMenuEvent( QContextMenuEvent* event )
658 {
659   if( !( event->state() & KeyButtonMask ) )
660     emit contextMenuRequested( event );
661 }