/*========================================================================= medInria Copyright (c) INRIA 2013 - 2018. All rights reserved. See LICENSE.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. =========================================================================*/ #include "vtkInteractorStyleImageView2D.h" #include "vtkCallbackCommand.h" #include "vtkAbstractPropPicker.h" #include "vtkAssemblyPath.h" #include "vtkMath.h" #include "vtkObjectFactory.h" #include "vtkRenderWindowInteractor.h" #include #include #include #include #include "vtkCommand.h" #include vtkStandardNewMacro (vtkInteractorStyleImageView2D); vtkInteractorStyleImageView2D::vtkInteractorStyleImageView2D() : vtkInteractorStyleImage() { this->SliceStep = 0; this->RequestedPosition[0] = this->RequestedPosition[1] = 0; this->LeftButtonInteraction = InteractionTypeWindowLevel; this->RightButtonInteraction = InteractionTypeZoom; this->MiddleButtonInteraction = InteractionTypePan; this->WheelButtonInteraction = InteractionTypeSlice; this->KeyboardInteraction = InteractionTypeSlice; } vtkInteractorStyleImageView2D::~vtkInteractorStyleImageView2D() { } //---------------------------------------------------------------------------- void vtkInteractorStyleImageView2D::OnMouseMove() { int x = this->Interactor->GetEventPosition()[0]; int y = this->Interactor->GetEventPosition()[1]; this->FindPokedRenderer(x, y); switch (this->State) { case VTKIS_SLICE_MOVE: this->SliceMove(); this->InvokeEvent(vtkImageView2DCommand::SliceMoveEvent, this); break; case VTKIS_TIME_CHANGE: this->TimeChange(); this->InvokeEvent(vtkImageView2DCommand::TimeChangeEvent, this); break; case VTKIS_DOLLY: case VTKIS_ZOOM: this->Superclass::OnMouseMove(); this->InvokeEvent(vtkImageView2DCommand::CameraZoomEvent, this); this->InvokeEvent(vtkImageView2DCommand::CameraMoveEvent, this); break; case VTKIS_PAN: this->Superclass::OnMouseMove(); this->InvokeEvent(vtkImageView2DCommand::CameraPanEvent, this); this->InvokeEvent(vtkImageView2DCommand::CameraMoveEvent, this); break; case VTKIS_SPIN: case VTKIS_ROTATE: case VTKIS_FORWARDFLY: case VTKIS_REVERSEFLY: this->Superclass::OnMouseMove(); this->InvokeEvent(vtkImageView2DCommand::CameraMoveEvent, this); break; case VTKIS_NONE: this->RequestedPosition[0] = x; this->RequestedPosition[1] = y; this->InvokeEvent (vtkImageView2DCommand::RequestedCursorInformationEvent, this); break; default: this->Superclass::OnMouseMove(); break; } } //---------------------------------------------------------------------------- void vtkInteractorStyleImageView2D::OnLeftButtonDown() { int x = this->Interactor->GetEventPosition()[0]; int y = this->Interactor->GetEventPosition()[1]; this->FindPokedRenderer(x, y); if (this->Interactor->GetRepeatCount()) { this->RequestedPosition[0] = x; this->RequestedPosition[1] = y; this->InvokeEvent (vtkImageView2DCommand::RequestedPositionEvent, this); return; } this->GrabFocus(this->EventCallbackCommand); if (this->Interactor->GetShiftKey() || this->Interactor->GetControlKey()) { if (this->GetLeftButtonInteraction() == InteractionTypeWindowLevel) this->StartSliceMove(); } else { switch(this->GetLeftButtonInteraction()) { case InteractionTypeSlice: this->RequestedPosition[0] = x; this->RequestedPosition[1] = y; this->InvokeEvent (vtkImageView2DCommand::RequestedPositionEvent, this); this->StartSliceMove(); break; case InteractionTypeTime: this->RequestedPosition[0] = x; this->RequestedPosition[1] = y; // this->InvokeEvent (vtkImageView2DCommand::RequestedPositionEvent, this); this->StartTimeChange(); break; case InteractionTypeWindowLevel: this->Superclass::OnLeftButtonDown(); break; case InteractionTypeZoom: this->Superclass::OnRightButtonDown(); break; case InteractionTypePan: this->Superclass::OnMiddleButtonDown(); break; default: break; } } } //---------------------------------------------------------------------------- void vtkInteractorStyleImageView2D::OnLeftButtonUp() { switch (this->State) { case VTKIS_SLICE_MOVE: this->EndSliceMove(); if ( this->Interactor ) { this->ReleaseFocus(); } break; case VTKIS_TIME_CHANGE: this->EndTimeChange(); if ( this->Interactor ) { this->ReleaseFocus(); } break; default: break; } switch (this->LeftButtonInteraction) { case InteractionTypeSlice : break; case InteractionTypeTime : break; case InteractionTypeZoom : this->Superclass::OnRightButtonUp(); break; case InteractionTypePan : this->Superclass::OnMiddleButtonUp(); break; case InteractionTypeWindowLevel : default: this->Superclass::OnLeftButtonUp(); break; } } //---------------------------------------------------------------------------- void vtkInteractorStyleImageView2D::OnMiddleButtonDown() { int x = this->Interactor->GetEventPosition()[0]; int y = this->Interactor->GetEventPosition()[1]; this->FindPokedRenderer(x, y); if ( !this->CurrentRenderer ) return; this->GrabFocus(this->EventCallbackCommand); switch(this->GetMiddleButtonInteraction()) { case InteractionTypeSlice: this->StartSliceMove(); break; case InteractionTypeTime: this->StartTimeChange(); break; case InteractionTypeWindowLevel: this->Superclass::OnLeftButtonDown(); break; case InteractionTypeZoom: this->Superclass::OnRightButtonDown(); break; case InteractionTypePan: this->Superclass::OnMiddleButtonDown(); break; default: break; } } //---------------------------------------------------------------------------- void vtkInteractorStyleImageView2D::OnMiddleButtonUp() { switch (this->State) { case VTKIS_SLICE_MOVE: this->EndSliceMove(); if ( this->Interactor ) { this->ReleaseFocus(); } break; case VTKIS_TIME_CHANGE: this->EndTimeChange(); if ( this->Interactor ) { this->ReleaseFocus(); } break; default: break; } switch (this->MiddleButtonInteraction) { case InteractionTypeSlice : break; case InteractionTypeTime : break; case InteractionTypeZoom : this->Superclass::OnRightButtonUp(); break; case InteractionTypeWindowLevel : this->Superclass::OnLeftButtonUp(); break; case InteractionTypePan : default: this->Superclass::OnMiddleButtonUp(); break; } } //---------------------------------------------------------------------------- void vtkInteractorStyleImageView2D::OnRightButtonDown() { int x = this->Interactor->GetEventPosition()[0]; int y = this->Interactor->GetEventPosition()[1]; this->FindPokedRenderer(x, y); if ( !this->CurrentRenderer ) return; this->GrabFocus(this->EventCallbackCommand); switch(this->GetRightButtonInteraction()) { case InteractionTypeSlice: this->StartSliceMove(); break; case InteractionTypeTime: this->StartTimeChange(); break; case InteractionTypeWindowLevel: this->Superclass::OnLeftButtonDown(); break; case InteractionTypeZoom: this->Superclass::OnRightButtonDown(); break; case InteractionTypePan: this->Superclass::OnMiddleButtonDown(); break; default: break; } } //---------------------------------------------------------------------------- void vtkInteractorStyleImageView2D::OnRightButtonUp() { switch (this->State) { case VTKIS_SLICE_MOVE: this->EndSliceMove(); if ( this->Interactor ) { this->ReleaseFocus(); } break; case VTKIS_TIME_CHANGE: this->EndTimeChange(); if ( this->Interactor ) { this->ReleaseFocus(); } break; default: break; } switch (this->RightButtonInteraction) { case InteractionTypeSlice : break; case InteractionTypeTime : break; case InteractionTypePan : this->Superclass::OnMiddleButtonUp(); break; case InteractionTypeWindowLevel : this->Superclass::OnLeftButtonUp(); break; case InteractionTypeZoom : default: this->Superclass::OnRightButtonUp(); break; } } //---------------------------------------------------------------------------- void vtkInteractorStyleImageView2D::OnMouseWheelForward() { int x = this->Interactor->GetEventPosition()[0]; int y = this->Interactor->GetEventPosition()[1]; this->FindPokedRenderer(x, y); if ( !this->CurrentRenderer ) return; switch(this->GetWheelButtonInteraction()) { case InteractionTypeSlice: this->SliceStep = 1; this->InvokeEvent (vtkImageView2DCommand::SliceMoveEvent, this); break; case InteractionTypeTime: this->SliceStep = 1; this->InvokeEvent (vtkImageView2DCommand::TimeChangeEvent, this); break; case InteractionTypeWindowLevel: this->Superclass::OnMouseWheelForward(); break; case InteractionTypeZoom: this->Superclass::OnMouseWheelForward(); break; case InteractionTypePan: this->Superclass::OnMouseWheelForward(); break; default: break; } } //---------------------------------------------------------------------------- void vtkInteractorStyleImageView2D::OnMouseWheelBackward() { int x = this->Interactor->GetEventPosition()[0]; int y = this->Interactor->GetEventPosition()[1]; this->FindPokedRenderer(x, y); if ( !this->CurrentRenderer ) return; switch(this->GetWheelButtonInteraction()) { case InteractionTypeSlice: this->SliceStep = -1; this->InvokeEvent (vtkImageView2DCommand::SliceMoveEvent, this); break; case InteractionTypeTime: this->SliceStep = -1; this->InvokeEvent (vtkImageView2DCommand::TimeChangeEvent, this); break; case InteractionTypeWindowLevel: this->Superclass::OnMouseWheelBackward(); break; case InteractionTypeZoom: this->Superclass::OnMouseWheelBackward(); break; case InteractionTypePan: this->Superclass::OnMouseWheelBackward(); break; default: break; } } //---------------------------------------------------------------------------- void vtkInteractorStyleImageView2D::OnChar() { vtkRenderWindowInteractor *rwi = this->Interactor; if (strcmp (rwi->GetKeySym(),"Up")==0 || strcmp (rwi->GetKeySym(),"Down")==0) { if (strcmp (rwi->GetKeySym(),"Up")==0) this->SliceStep = 1; else this->SliceStep = -1; switch (this->KeyboardInteraction) { case InteractionTypeSlice: this->InvokeEvent (vtkImageView2DCommand::SliceMoveEvent, this); break; case InteractionTypeTime: this->InvokeEvent (vtkImageView2DCommand::TimeChangeEvent, this); break; default: break; /* case InteractionTypeWindowLevel: //this->InvokeEvent (vtkImageView2DCommand::InteractionTypeWindowLevel, this); break; case InteractionTypeZoom: this->InvokeEvent (vtkImageView2DCommand::CameraZoomEvent, this); break; case InteractionTypePan: this->InvokeEvent (vtkImageView2DCommand::CameraPanEvent, this); break; */ } } else if ((rwi->GetKeyCode() == 'r') || (rwi->GetKeyCode() == 'R')) { this->InvokeEvent(vtkImageView2DCommand::ResetViewerEvent, this); } } //---------------------------------------------------------------------------- void vtkInteractorStyleImageView2D::OnKeyDown() { // Apparently there is a problem here. // The event vtkCommand::CharEvent and vtkCommand::KeyPressEvent seem // to mix between each other. // tackled by calling the charevent // (supposed to be called at any keyboard event) this->OnChar(); this->Superclass::OnKeyDown(); } //---------------------------------------------------------------------------- void vtkInteractorStyleImageView2D::OnKeyUp() { this->Superclass::OnKeyUp(); } //---------------------------------------------------------------------------- void vtkInteractorStyleImageView2D::StartSliceMove() { if ((this->State != VTKIS_NONE) && (this->State != VTKIS_PICK)) { return; } this->StartState(VTKIS_SLICE_MOVE); this->InvokeEvent(vtkImageView2DCommand::StartSliceMoveEvent, this); } //---------------------------------------------------------------------------- void vtkInteractorStyleImageView2D::EndSliceMove() { if (this->State != VTKIS_SLICE_MOVE) { return; } this->StopState(); this->InvokeEvent(vtkImageView2DCommand::EndSliceMoveEvent, this); } //---------------------------------------------------------------------------- void vtkInteractorStyleImageView2D::SliceMove() { vtkRenderWindowInteractor *rwi = this->Interactor; int dy = rwi->GetEventPosition()[1] - rwi->GetLastEventPosition()[1]; this->SliceStep = dy; } //---------------------------------------------------------------------------- void vtkInteractorStyleImageView2D::StartTimeChange() { if ((this->State != VTKIS_NONE) && (this->State != VTKIS_PICK)) { return; } this->StartState(VTKIS_TIME_CHANGE); this->InvokeEvent(vtkImageView2DCommand::StartTimeChangeEvent, this); } //---------------------------------------------------------------------------- void vtkInteractorStyleImageView2D::EndTimeChange() { if (this->State != VTKIS_TIME_CHANGE) { return; } this->StopState(); this->InvokeEvent(vtkImageView2DCommand::EndTimeChangeEvent, this); } //---------------------------------------------------------------------------- void vtkInteractorStyleImageView2D::TimeChange() { vtkRenderWindowInteractor *rwi = this->Interactor; int dy = rwi->GetEventPosition()[1] - rwi->GetLastEventPosition()[1]; this->SliceStep = dy; } //---------------------------------------------------------------------------- void vtkInteractorStyleImageView2D::DefaultMoveAction() { this->InvokeEvent (vtkImageView2DCommand::DefaultMoveEvent ,this); }