/*========================================================================= Program: Visualization Toolkit Module: vtkSliderWidget.cxx Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen All rights reserved. See Copyright.txt or http://www.kitware.com/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ #include "vtkSliderWidget.h" #include "vtkSliderRepresentation3D.h" #include "vtkCommand.h" #include "vtkCallbackCommand.h" #include "vtkRenderWindowInteractor.h" #include "vtkObjectFactory.h" #include "vtkRenderer.h" #include "vtkWidgetEventTranslator.h" #include "vtkWidgetCallbackMapper.h" #include "vtkEvent.h" #include "vtkWidgetEvent.h" vtkStandardNewMacro(vtkSliderWidget); //---------------------------------------------------------------------------------- vtkSliderWidget::vtkSliderWidget() { // Set the initial state this->WidgetState = vtkSliderWidget::Start; // Assign initial values this->AnimationMode = vtkSliderWidget::Jump; this->NumberOfAnimationSteps = 24; // Okay, define the events this->CallbackMapper->SetCallbackMethod(vtkCommand::LeftButtonPressEvent, vtkWidgetEvent::Select, this, vtkSliderWidget::SelectAction); this->CallbackMapper->SetCallbackMethod(vtkCommand::MouseMoveEvent, vtkWidgetEvent::Move, this, vtkSliderWidget::MoveAction); this->CallbackMapper->SetCallbackMethod(vtkCommand::LeftButtonReleaseEvent, vtkWidgetEvent::EndSelect, this, vtkSliderWidget::EndSelectAction); } //---------------------------------------------------------------------- void vtkSliderWidget::CreateDefaultRepresentation() { if ( ! this->WidgetRep ) { this->WidgetRep = vtkSliderRepresentation3D::New(); } } //---------------------------------------------------------------------------------- void vtkSliderWidget::SelectAction(vtkAbstractWidget *w) { vtkSliderWidget *self = reinterpret_cast(w); double eventPos[2]; eventPos[0] = self->Interactor->GetEventPosition()[0]; eventPos[1] = self->Interactor->GetEventPosition()[1]; // Okay, make sure that the pick is in the current renderer if (!self->CurrentRenderer || !self->CurrentRenderer->IsInViewport(static_cast(eventPos[0]), static_cast(eventPos[1]))) { self->WidgetState = vtkSliderWidget::Start; return; } // See if the widget has been selected. StartWidgetInteraction records the // starting point of the motion. self->WidgetRep->StartWidgetInteraction(eventPos); int interactionState = self->WidgetRep->GetInteractionState(); if ( interactionState == vtkSliderRepresentation::Outside ) { return; } // We are definitely selected self->GrabFocus(self->EventCallbackCommand); if ( interactionState == vtkSliderRepresentation::Slider ) { self->WidgetState = vtkSliderWidget::Sliding; } else { self->WidgetState = vtkSliderWidget::Animating; } // Highlight as necessary self->WidgetRep->Highlight(1); // start the interaction self->EventCallbackCommand->SetAbortFlag(1); self->StartInteraction(); self->InvokeEvent(vtkCommand::StartInteractionEvent,nullptr); self->Render(); } //---------------------------------------------------------------------------------- void vtkSliderWidget::MoveAction(vtkAbstractWidget *w) { vtkSliderWidget *self = reinterpret_cast(w); // See whether we're active if ( self->WidgetState == vtkSliderWidget::Start || self->WidgetState == vtkSliderWidget::Animating ) { return; } // Definitely moving the slider, get the updated position double eventPos[2]; eventPos[0] = self->Interactor->GetEventPosition()[0]; eventPos[1] = self->Interactor->GetEventPosition()[1]; self->WidgetRep->WidgetInteraction(eventPos); // Interact, if desired self->EventCallbackCommand->SetAbortFlag(1); self->InvokeEvent(vtkCommand::InteractionEvent,nullptr); self->Render(); } //---------------------------------------------------------------------------------- void vtkSliderWidget::EndSelectAction(vtkAbstractWidget *w) { vtkSliderWidget *self = reinterpret_cast(w); if ( self->WidgetState == vtkSliderWidget::Start ) { return; } // If animating we do it and return if ( self->WidgetState == vtkSliderWidget::Animating ) { self->AnimateSlider(self->WidgetRep->GetInteractionState()); } // Highlight if necessary self->WidgetRep->Highlight(0); // The state returns to unselected self->WidgetState = vtkSliderWidget::Start; self->ReleaseFocus(); // Complete interaction self->EventCallbackCommand->SetAbortFlag(1); self->EndInteraction(); self->InvokeEvent(vtkCommand::EndInteractionEvent,nullptr); self->Render(); } //---------------------------------------------------------------------------------- void vtkSliderWidget::AnimateSlider(int selectionState) { // Get the representation and grab some information vtkSliderRepresentation *sliderRep = reinterpret_cast(this->WidgetRep); // If the slider bead has been selected, then nothing happens if ( selectionState == vtkSliderRepresentation::Outside || selectionState == vtkSliderRepresentation::Slider ) { return; } // Depending on animation mode, we'll jump to the pick point or // animate towards it. double minValue=sliderRep->GetMinimumValue(); double maxValue=sliderRep->GetMaximumValue(); double pickedT=sliderRep->GetPickedT(); if ( this->AnimationMode == vtkSliderWidget::Jump ) { if ( selectionState == vtkSliderRepresentation::Tube ) { sliderRep->SetValue(minValue + pickedT*(maxValue-minValue)); } else if ( selectionState == vtkSliderRepresentation::LeftCap ) { sliderRep->SetValue(minValue); } else if ( selectionState == vtkSliderRepresentation::RightCap ) { sliderRep->SetValue(maxValue); } sliderRep->BuildRepresentation(); this->InvokeEvent(vtkCommand::InteractionEvent,nullptr); } else if ( this->AnimationMode == vtkSliderWidget::Animate ) { double targetValue=minValue, originalValue=sliderRep->GetValue(); if ( selectionState == vtkSliderRepresentation::Tube ) { targetValue = minValue + pickedT*(maxValue-minValue); } else if ( selectionState == vtkSliderRepresentation::LeftCap ) { targetValue = minValue; } else if ( selectionState == vtkSliderRepresentation::RightCap ) { targetValue = maxValue; } // Okay, animate the slider double value; for (int i=0; i < this->NumberOfAnimationSteps; i++) { value = originalValue + (static_cast(i+1)/this->NumberOfAnimationSteps)*(targetValue-originalValue); sliderRep->SetValue(value); sliderRep->BuildRepresentation(); this->InvokeEvent(vtkCommand::InteractionEvent,nullptr); this->Render(); } } this->WidgetState = vtkSliderWidget::Start; } //---------------------------------------------------------------------------------- void vtkSliderWidget::PrintSelf(ostream& os, vtkIndent indent) { //Superclass typedef defined in vtkTypeMacro() found in vtkSetGet.h this->Superclass::PrintSelf(os,indent); os << indent << "Animation Mode: "; switch ( this->AnimationMode ) { case vtkSliderWidget::Jump: os << "Jump\n"; break; case vtkSliderWidget::Animate: os << "Animate\n"; break; default: os << "AnimateOff\n"; } os << indent << "Number of Animation Steps: " << this->NumberOfAnimationSteps << "\n"; }