1 // SALOME VTKViewer : build VTK viewer into Salome desktop
3 // Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
20 // See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
29 #include "SVTK_RenderWindowInteractor.h"
30 #include "SVTK_GenericRenderWindowInteractor.h"
32 #include "SVTK_InteractorStyle.h"
33 #include "SVTK_Renderer.h"
34 #include "SVTK_Functor.h"
35 #include "SALOME_Actor.h"
37 #include "SVTK_SpaceMouse.h"
38 #include "SVTK_Event.h"
40 #include "VTKViewer_Algorithm.h"
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>
54 #include <qapplication.h>
55 #include <qcolordialog.h>
56 #include <qpaintdevice.h>
60 static bool GENERATE_SUIT_EVENTS = false;
61 static bool FOCUS_UNDER_MOUSE = false;
64 //----------------------------------------------------------------------------
65 QVTK_RenderWindowInteractor
66 ::QVTK_RenderWindowInteractor(QWidget* theParent,
68 QWidget(theParent,theName,Qt::WNoAutoErase),
69 myRenderWindow(vtkRenderWindow::New())
71 setMouseTracking(true);
73 myRenderWindow->Delete();
74 myRenderWindow->DoubleBufferOn();
77 myRenderWindow->SetDisplayId((void*)x11Display());
79 myRenderWindow->SetWindowId((void*)winId());
84 QVTK_RenderWindowInteractor
85 ::Initialize(vtkGenericRenderWindowInteractor* theDevice)
88 myDevice->SetRenderWindow(NULL);
93 theDevice->SetRenderWindow(getRenderWindow());
96 //----------------------------------------------------------------------------
97 QVTK_RenderWindowInteractor
98 ::~QVTK_RenderWindowInteractor()
100 if(SVTK_SpaceMouse* aSpaceMouse = SVTK_SpaceMouse::getInstance())
101 if(aSpaceMouse->isSpaceMouseOn())
102 aSpaceMouse->close(x11Display());
106 //----------------------------------------------------------------------------
107 vtkGenericRenderWindowInteractor*
108 QVTK_RenderWindowInteractor
111 return myDevice.GetPointer();
114 //----------------------------------------------------------------------------
116 QVTK_RenderWindowInteractor
119 return myRenderWindow.GetPointer();
122 //----------------------------------------------------------------------------
124 QVTK_RenderWindowInteractor
125 ::InvokeEvent(unsigned long theEvent, void* theCallData)
127 GetDevice()->InvokeEvent(theEvent,theCallData);
130 //----------------------------------------------------------------------------
132 QVTK_RenderWindowInteractor
136 update(); // needed for initial contents display on Win32
139 //----------------------------------------------------------------------------
141 QVTK_RenderWindowInteractor
144 // Final initialization just before the widget is displayed
145 GetDevice()->SetSize(width(),height());
146 if(!GetDevice()->GetInitialized()){
147 GetDevice()->Initialize();
148 GetDevice()->ConfigureEvent();
152 //----------------------------------------------------------------------------
154 QVTK_RenderWindowInteractor
155 ::resize(int w, int h)
157 GetDevice()->UpdateSize(w,h);
160 //----------------------------------------------------------------------------
162 QVTK_RenderWindowInteractor
163 ::paintEvent( QPaintEvent* theEvent )
165 GetDevice()->CreateTimer(VTKI_TIMER_FIRST);
169 //----------------------------------------------------------------------------
171 QVTK_RenderWindowInteractor
172 ::resizeEvent( QResizeEvent* theEvent )
174 int* aSize = getRenderWindow()->GetSize();
175 int aWidth = aSize[0];
176 int aHeight = aSize[1];
178 GetDevice()->UpdateSize(width(),height());
180 if(isVisible() && aWidth && aHeight){
181 if( aWidth != width() || aHeight != height() ) {
182 vtkRendererCollection * aRenderers = getRenderWindow()->GetRenderers();
183 aRenderers->InitTraversal();
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));
191 aCoeff = double(aWidth)/double(width());
192 aCamera->SetParallelScale(aScale*aCoeff);
201 //----------------------------------------------------------------------------
203 QVTK_RenderWindowInteractor
204 ::contextMenuEvent( QContextMenuEvent* event )
208 //----------------------------------------------------------------------------
210 QVTK_RenderWindowInteractor
211 ::mouseMoveEvent( QMouseEvent* event )
213 GetDevice()->SetEventInformationFlipY(event->x(),
215 event->state() & ControlButton,
216 event->state() & ShiftButton);
217 GetDevice()->MouseMoveEvent();
221 //----------------------------------------------------------------------------
223 QVTK_RenderWindowInteractor
224 ::mousePressEvent( QMouseEvent* event )
226 GetDevice()->SetEventInformationFlipY(event->x(),
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();
239 //----------------------------------------------------------------------------
241 QVTK_RenderWindowInteractor
242 ::mouseReleaseEvent( QMouseEvent *event )
244 GetDevice()->SetEventInformationFlipY(event->x(),
246 event->state() & ControlButton,
247 event->state() & ShiftButton);
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();
258 //----------------------------------------------------------------------------
260 QVTK_RenderWindowInteractor
261 ::mouseDoubleClickEvent( QMouseEvent* event )
265 //----------------------------------------------------------------------------
267 QVTK_RenderWindowInteractor
268 ::wheelEvent( QWheelEvent* event )
275 //----------------------------------------------------------------------------
277 QVTK_RenderWindowInteractor
278 ::keyPressEvent( QKeyEvent* event )
280 GetDevice()->SetKeyEventInformation(event->state() & ControlButton,
281 event->state() & ShiftButton,
283 GetDevice()->KeyPressEvent();
284 GetDevice()->CharEvent();
287 //----------------------------------------------------------------------------
289 QVTK_RenderWindowInteractor
290 ::keyReleaseEvent( QKeyEvent * event )
292 GetDevice()->SetKeyEventInformation(event->state() & ControlButton,
293 event->state() & ShiftButton,
295 GetDevice()->KeyReleaseEvent();
299 //----------------------------------------------------------------------------
301 QVTK_RenderWindowInteractor
302 ::enterEvent( QEvent* event )
304 if(FOCUS_UNDER_MOUSE){
308 GetDevice()->EnterEvent();
311 //----------------------------------------------------------------------------
313 QVTK_RenderWindowInteractor
314 ::leaveEvent( QEvent * )
316 GetDevice()->LeaveEvent();
320 //----------------------------------------------------------------------------
322 QVTK_RenderWindowInteractor
323 ::focusInEvent( QFocusEvent* event )
325 QWidget::focusInEvent( event );
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());
332 aSpaceMouse->setWindow(x11Display(),winId());
337 //----------------------------------------------------------------------------
339 QVTK_RenderWindowInteractor
340 ::focusOutEvent ( QFocusEvent* event )
342 QWidget::focusOutEvent( event );
344 // unregister set space mouse events receiver
345 if(SVTK_SpaceMouse* aSpaceMouse = SVTK_SpaceMouse::getInstance()){
346 if(aSpaceMouse->isSpaceMouseOn())
347 aSpaceMouse->setWindow(x11Display(),0);
352 //----------------------------------------------------------------------------
354 QVTK_RenderWindowInteractor
355 ::x11Event( XEvent *xEvent )
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 );
363 case SVTK_SpaceMouse::SpaceMouseMove :
364 GetDevice()->InvokeEvent(SVTK::SpaceMouseMoveEvent, anEvent.data );
366 case SVTK_SpaceMouse::SpaceButtonPress :
367 GetDevice()->InvokeEvent( SVTK::SpaceMouseButtonEvent, &anEvent.button );
369 case SVTK_SpaceMouse::SpaceButtonRelease :
372 return true; // stop handling the event
376 return QWidget::x11Event( xEvent );
380 //----------------------------------------------------------------------------
381 SVTK_RenderWindowInteractor
382 ::SVTK_RenderWindowInteractor(QWidget* theParent,
383 const char* theName):
384 QVTK_RenderWindowInteractor(theParent,theName),
385 myEventCallbackCommand(vtkCallbackCommand::New())
387 myEventCallbackCommand->Delete();
389 myEventCallbackCommand->SetClientData(this);
392 myEventCallbackCommand->SetCallback(SVTK_RenderWindowInteractor::ProcessEvents);
396 SVTK_RenderWindowInteractor
397 ::Initialize(vtkGenericRenderWindowInteractor* theDevice,
398 SVTK_Renderer* theRenderer,
399 SVTK_Selector* theSelector)
401 QVTK_RenderWindowInteractor::Initialize(theDevice);
402 SetRenderer(theRenderer);
403 SetSelector(theSelector);
406 //----------------------------------------------------------------------------
407 SVTK_RenderWindowInteractor
408 ::~SVTK_RenderWindowInteractor()
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();
421 GetDevice()->SetRenderWindow(NULL);
424 //----------------------------------------------------------------------------
426 SVTK_RenderWindowInteractor
429 return myRenderer.GetPointer();
433 SVTK_RenderWindowInteractor
436 return GetRenderer()->GetDevice();
440 SVTK_RenderWindowInteractor
441 ::SetRenderer(SVTK_Renderer* theRenderer)
443 if(theRenderer == myRenderer.GetPointer())
447 myRenderWindow->RemoveRenderer(getRenderer());
449 myRenderer = theRenderer;
452 myRenderWindow->AddRenderer(getRenderer());
456 //----------------------------------------------------------------------------
458 SVTK_RenderWindowInteractor
459 ::InitInteractorStyle(vtkInteractorStyle* theStyle)
461 GetDevice()->SetInteractorStyle(theStyle);
465 //----------------------------------------------------------------------------
467 SVTK_RenderWindowInteractor
468 ::PushInteractorStyle(vtkInteractorStyle* theStyle)
470 myInteractorStyles.push(PInteractorStyle(theStyle));
471 InitInteractorStyle(theStyle);
475 //----------------------------------------------------------------------------
477 SVTK_RenderWindowInteractor
478 ::PopInteractorStyle()
480 if(GetInteractorStyle())
481 myInteractorStyles.pop();
483 if(GetInteractorStyle())
484 InitInteractorStyle(GetInteractorStyle());
488 //----------------------------------------------------------------------------
490 SVTK_RenderWindowInteractor
491 ::GetInteractorStyle()
493 return myInteractorStyles.empty() ? 0 : myInteractorStyles.top().GetPointer();
497 //----------------------------------------------------------------------------
499 SVTK_RenderWindowInteractor
502 return mySelector.GetPointer();
507 SVTK_RenderWindowInteractor
508 ::SetSelector(SVTK_Selector* theSelector)
510 if(mySelector.GetPointer())
511 mySelector->RemoveObserver(myEventCallbackCommand.GetPointer());
513 mySelector = theSelector;
515 if(mySelector.GetPointer())
516 mySelector->AddObserver(vtkCommand::EndPickEvent,
517 myEventCallbackCommand.GetPointer(),
522 //----------------------------------------------------------------------------
524 SVTK_RenderWindowInteractor
525 ::ProcessEvents(vtkObject* vtkNotUsed(theObject),
526 unsigned long theEvent,
528 void* vtkNotUsed(theCallData))
530 SVTK_RenderWindowInteractor* self = reinterpret_cast<SVTK_RenderWindowInteractor*>(theClientData);
533 case vtkCommand::EndPickEvent:
534 self->onEmitSelectionChanged();
540 //----------------------------------------------------------------
542 SVTK_RenderWindowInteractor
543 ::SetSelectionMode(Selection_Mode theMode)
545 mySelector->SetSelectionMode(theMode);
549 //----------------------------------------------------------------
551 SVTK_RenderWindowInteractor
552 ::SelectionMode() const
554 return mySelector->SelectionMode();
558 //----------------------------------------------------------------
560 SVTK_RenderWindowInteractor
561 ::onEmitSelectionChanged()
563 return emit selectionChanged();
567 //----------------------------------------------------------------------------
569 SVTK_RenderWindowInteractor
570 ::mouseMoveEvent( QMouseEvent* event )
572 QVTK_RenderWindowInteractor::mouseMoveEvent(event);
574 if(GENERATE_SUIT_EVENTS)
575 emit MouseMove( event );
579 //----------------------------------------------------------------------------
581 SVTK_RenderWindowInteractor
582 ::mousePressEvent( QMouseEvent* event )
584 QVTK_RenderWindowInteractor::mousePressEvent(event);
586 if(GENERATE_SUIT_EVENTS)
587 emit MouseButtonPressed( event );
591 //----------------------------------------------------------------------------
593 SVTK_RenderWindowInteractor
594 ::mouseReleaseEvent( QMouseEvent *event )
596 QVTK_RenderWindowInteractor::mouseReleaseEvent(event);
598 if(GENERATE_SUIT_EVENTS)
599 emit MouseButtonReleased( event );
603 //----------------------------------------------------------------------------
605 SVTK_RenderWindowInteractor
606 ::mouseDoubleClickEvent( QMouseEvent* event )
608 QVTK_RenderWindowInteractor::mouseDoubleClickEvent(event);
610 if(GENERATE_SUIT_EVENTS)
611 emit MouseDoubleClicked( event );
615 //----------------------------------------------------------------------------
617 SVTK_RenderWindowInteractor
618 ::wheelEvent( QWheelEvent* event )
620 QVTK_RenderWindowInteractor::wheelEvent(event);
622 if(event->delta() > 0)
623 GetDevice()->InvokeEvent(SVTK::ZoomInEvent,NULL);
625 GetDevice()->InvokeEvent(SVTK::ZoomOutEvent,NULL);
627 if(GENERATE_SUIT_EVENTS)
628 emit WheelMoved( event );
632 //----------------------------------------------------------------------------
634 SVTK_RenderWindowInteractor
635 ::keyPressEvent( QKeyEvent* event )
637 QVTK_RenderWindowInteractor::keyPressEvent(event);
639 if(GENERATE_SUIT_EVENTS)
640 emit KeyPressed( event );
643 //----------------------------------------------------------------------------
645 SVTK_RenderWindowInteractor
646 ::keyReleaseEvent( QKeyEvent * event )
648 QVTK_RenderWindowInteractor::keyReleaseEvent(event);
650 if(GENERATE_SUIT_EVENTS)
651 emit KeyReleased( event );
654 //----------------------------------------------------------------------------
656 SVTK_RenderWindowInteractor
657 ::contextMenuEvent( QContextMenuEvent* event )
659 if( !( event->state() & KeyButtonMask ) )
660 emit contextMenuRequested( event );