7 #include "fwRenderVTK/vtk/fwVtkWheelWidget.hpp" 9 #include <fwServices/macros.hpp> 11 #include <glm/geometric.hpp> 12 #include <glm/gtc/vec1.hpp> 13 #include <glm/vec2.hpp> 15 #include <vtkActor2D.h> 16 #include <vtkCallbackCommand.h> 17 #include <vtkObjectFactory.h> 18 #include <vtkRenderer.h> 19 #include <vtkRenderWindow.h> 20 #include <vtkRenderWindowInteractor.h> 21 #include <vtkWidgetCallbackMapper.h> 22 #include <vtkWidgetEvent.h> 28 fwVtkWheelWidget::fwVtkWheelWidget()
31 this->WidgetState = fwVtkWheelWidget::Hovering;
34 this->CallbackMapper->SetCallbackMethod(vtkCommand::LeftButtonPressEvent,
35 vtkWidgetEvent::Select,
36 this, fwVtkWheelWidget::SelectAction);
37 this->CallbackMapper->SetCallbackMethod(vtkCommand::MouseMoveEvent,
39 this, fwVtkWheelWidget::MoveAction);
40 this->CallbackMapper->SetCallbackMethod(vtkCommand::LeftButtonReleaseEvent,
41 vtkWidgetEvent::EndSelect,
42 this, fwVtkWheelWidget::EndSelectAction);
45 m_wheelUpdateCallback = [] (double, double, double)
55 if( !this->WidgetRep )
63 void fwVtkWheelWidget::SetWheelUpdateCallback(std::function<
void (
double,
double,
double)> f)
65 m_wheelUpdateCallback = f;
70 void fwVtkWheelWidget::MoveAction(vtkAbstractWidget* w)
74 int x =
self->Interactor->GetEventPosition()[0];
75 int y =
self->Interactor->GetEventPosition()[1];
78 bool renderRequired =
false;
82 SLM_ASSERT(
"Widget representation is not a wheel.", widgetRep);
84 if ( self->WidgetState == fwVtkWheelWidget::Selecting )
86 const auto& actPos = widgetRep->
GetWheelActor()->GetPosition();
87 const int* viewportSize =
self->GetRepresentation()->GetRenderer()->GetRenderWindow()->GetSize();
89 x = ::glm::clamp(x, 0, viewportSize[0]);
90 y = ::glm::clamp(y, 0, viewportSize[1]);
92 widgetRep->
GetWheelActor()->SetPosition(x - self->m_initMouseX + actPos[0], y - self->m_initMouseY + actPos[1]);
93 self->m_initMouseX = x;
94 self->m_initMouseY = y;
98 self->m_wheelUpdateCallback(center.x, center.y, orientation);
99 self->EventCallbackCommand->SetAbortFlag(1);
101 renderRequired =
true;
103 else if( self->WidgetState == fwVtkWheelWidget::Rotating)
107 const auto v1 = ::glm::normalize(::glm::dvec2(self->m_initMouseX - center.x, self->m_initMouseY - center.y));
108 const auto v2 = ::glm::normalize(::glm::dvec2(x - center.x, y - center.y));
110 const double vectProd = v1.x * v2.y - v1.y * v2.x;
111 const double vectDot = ::glm::dot(v1, v2);
112 const double angleSin = std::asin(vectProd);
113 const double angleCos = std::acos(vectDot);
115 const double angle = ::glm::sign(angleSin) * angleCos;
120 self->m_wheelUpdateCallback(center.x, center.y, orientation);
121 self->EventCallbackCommand->SetAbortFlag(1);
123 renderRequired =
true;
125 else if ( self->WidgetState == fwVtkWheelWidget::Hovering )
128 renderRequired =
true;
139 void fwVtkWheelWidget::SelectAction(vtkAbstractWidget* w)
143 const int x =
self->Interactor->GetEventPosition()[0];
144 const int y =
self->Interactor->GetEventPosition()[1];
148 SLM_ASSERT(
"Widget representation is not a wheel.", widgetRep);
152 self->WidgetState = ::fwVtkWheelWidget::Selecting;
153 self->m_initMouseX = x;
154 self->m_initMouseY = y;
155 self->EventCallbackCommand->SetAbortFlag(1);
159 self->WidgetState = ::fwVtkWheelWidget::Rotating;
160 self->m_initMouseX = x;
161 self->m_initMouseY = y;
163 self->EventCallbackCommand->SetAbortFlag(1);
171 void fwVtkWheelWidget::EndSelectAction(vtkAbstractWidget* w)
175 self->WidgetState = fwVtkWheelWidget::Hovering;
191 this->WidgetRep = rep;
static FWRENDERVTK_API fwVtkWheelRepresentation * New()
Calls the constructor. Initializes wheel geometry and actor.
double GetOrientation() const
Returns the orientation in radians.
#define SLM_WARN(message)
vtkActor2D * GetWheelActor() const
Get the actor holding the wheel.
FWRENDERVTK_API::glm::dvec2 GetCenterInScreenSpace() const
Returns the center in viewport coordinates.
FWRENDERVTK_API void SetOrientation(double orientation)
Set the wheel orientation, expressed in radians.
#define SLM_ASSERT(message, cond)
work like 'assert' from 'cassert', with in addition a message logged by spylog (with FATAL loglevel) ...
#define OSLM_FATAL(message)
FWRENDERVTK_API void SetHovering(bool hover)
Set the wheel hovering.
FWRENDERVTK_API bool isOnWheel(int X, int Y) const
Check if the (X, Y) screen position is on the wheel.
FWRENDERVTK_API bool isInCenter(int X, int Y) const
Check if the (X, Y) screen position is inside the wheel center.
Representation of a wheel widget.