Commit 96577556 authored by Julien Finet's avatar Julien Finet
Browse files

Emit interaction events when moving control points

Add unit test to ensure correct events are fired.

Change-Id: I1ee45a26d2007f311e36d8c3a4b05c23fe423a58
parent 44fdb1a4
......@@ -6,6 +6,7 @@ IF(VTK_USE_RENDERING AND VTK_USE_VIEWS)
SET(MyTests
TestContextScene.cxx
TestControlPointsItem.cxx
TestControlPointsItemEvents.cxx
TestVector.cxx
)
......
/*=========================================================================
Program: Visualization Toolkit
Module: TestVector.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.
=========================================================================*/
// Charts includes
#include "vtkContextInteractorStyle.h"
#include "vtkContextScene.h"
#include "vtkControlPointsItem.h"
#include "vtkColorTransferControlPointsItem.h"
#include "vtkColorTransferFunction.h"
// Common includes"
#include "vtkIdTypeArray.h"
#include "vtkInteractorEventRecorder.h"
#include "vtkNew.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkSmartPointer.h"
// STD includes
#include <iostream>
#include <map>
//----------------------------------------------------------------------------
class vtkTFCallback : public vtkCommand
{
public:
static vtkTFCallback *New()
{
return new vtkTFCallback;
}
vtkTFCallback()
{
}
void Execute( vtkObject *caller, unsigned long event,
void *vtkNotUsed(callData) )
{
vtkColorTransferFunction* self =
reinterpret_cast< vtkColorTransferFunction* >( caller );
if (!self)
{
return;
}
if (this->EventSpy.count(event) == 0)
{
this->EventSpy[event] = 0;
}
++this->EventSpy[event];
std::cout << "InvokedEvent: " << event << this->EventSpy[event] << std::endl;
}
std::map<unsigned long, int> EventSpy;
};
//----------------------------------------------------------------------------
int TestControlPointsItemEvents(int, char*[])
{
vtkNew<vtkColorTransferFunction> transferFunction;
transferFunction->AddHSVSegment(50.,0.,1.,1.,85.,0.3333,1.,1.);
transferFunction->AddHSVSegment(85.,0.3333,1.,1.,170.,0.6666,1.,1.);
transferFunction->AddHSVSegment(170.,0.6666,1.,1.,200.,0.,1.,1.);
vtkNew<vtkTFCallback> cbk;
transferFunction->AddObserver( vtkCommand::StartEvent, cbk.GetPointer() );
transferFunction->AddObserver( vtkCommand::ModifiedEvent, cbk.GetPointer() );
transferFunction->AddObserver( vtkCommand::EndEvent, cbk.GetPointer() );
transferFunction->AddObserver( vtkCommand::StartInteractionEvent, cbk.GetPointer() );
transferFunction->AddObserver( vtkCommand::InteractionEvent, cbk.GetPointer() );
transferFunction->AddObserver( vtkCommand::EndInteractionEvent, cbk.GetPointer() );
vtkNew<vtkColorTransferControlPointsItem> controlPoints;
controlPoints->SetColorTransferFunction(transferFunction.GetPointer());
// vtkNew<vtkChartXY> chart;
// chart->AddPlot(controlPoints.GetPointer());
vtkNew<vtkContextScene> scene;
scene->AddItem(controlPoints.GetPointer());
vtkNew<vtkContextInteractorStyle> interactorStyle;
interactorStyle->SetScene(scene.GetPointer());
vtkNew<vtkRenderWindowInteractor> iren;
iren->SetInteractorStyle(interactorStyle.GetPointer());
vtkNew<vtkInteractorEventRecorder> recorder;
recorder->SetInteractor(iren.GetPointer());
recorder->ReadFromInputStringOn();
// Add a point at (60, 0.5) and move it to (62, 0.5)
const char addAndDragEvents[] =
"# StreamVersion 1\n"
"LeftButtonPressEvent 60 1 0 0 0 0 0\n"
"MouseMoveEvent 62 1 0 0 0 0 0\n"
"LeftButtonReleaseEvent 62 1 0 0 0 0 0\n"
;
recorder->SetInputString(addAndDragEvents);
recorder->Play();
// 1 ModifiedEvent for adding a point
// 1 ModifiedEvent for moving the point
if (cbk->EventSpy[vtkCommand::ModifiedEvent] != 2 ||
cbk->EventSpy[vtkCommand::StartInteractionEvent] != 1 ||
cbk->EventSpy[vtkCommand::InteractionEvent] != 1 ||
cbk->EventSpy[vtkCommand::EndInteractionEvent] != 1 ||
cbk->EventSpy[vtkCommand::StartEvent] != 0 ||
cbk->EventSpy[vtkCommand::EndEvent] != 0)
{
std::cerr << "Wrong number of fired events : "
<< cbk->EventSpy[vtkCommand::ModifiedEvent] << " "
<< cbk->EventSpy[vtkCommand::StartInteractionEvent] << " "
<< cbk->EventSpy[vtkCommand::InteractionEvent] << " "
<< cbk->EventSpy[vtkCommand::EndInteractionEvent] << " "
<< cbk->EventSpy[vtkCommand::StartEvent] << " "
<< cbk->EventSpy[vtkCommand::EndEvent] << std::endl;
return EXIT_FAILURE;
}
cbk->EventSpy.clear();
// Move all the points to the right.
controlPoints->MovePoints(vtkVector2f(5, 0.));
// One ModifiedEvent for each moved point
if (cbk->EventSpy[vtkCommand::ModifiedEvent] > controlPoints->GetNumberOfPoints() ||
cbk->EventSpy[vtkCommand::StartInteractionEvent] != 0 ||
cbk->EventSpy[vtkCommand::InteractionEvent] != 0 ||
cbk->EventSpy[vtkCommand::EndInteractionEvent] != 0 ||
cbk->EventSpy[vtkCommand::StartEvent] != 1 ||
cbk->EventSpy[vtkCommand::EndEvent] != 1)
{
std::cerr << "Wrong number of fired events : "
<< cbk->EventSpy[vtkCommand::ModifiedEvent] << " "
<< cbk->EventSpy[vtkCommand::StartInteractionEvent] << " "
<< cbk->EventSpy[vtkCommand::InteractionEvent] << " "
<< cbk->EventSpy[vtkCommand::EndInteractionEvent] << " "
<< cbk->EventSpy[vtkCommand::StartEvent] << " "
<< cbk->EventSpy[vtkCommand::EndEvent] << std::endl;
return EXIT_FAILURE;
}
cbk->EventSpy.clear();
const char dblClickEvents[] =
"# StreamVersion 1\n"
"MouseMoveEvent 56 1 0 0 0 0 0\n" // shouldn't move the point
"LeftButtonPressEvent 55 1 0 0 0 0 0\n" // select the first point
"LeftButtonReleaseEvent 55 1 0 0 0 0 0\n"
"LeftButtonPressEvent 55 1 0 0 0 1 0\n" // dbl click
"MouseMoveEvent 56 1 0 0 0 0 0\n" // shouldn't move the point
;
recorder->SetInputString(dblClickEvents);
recorder->Play();
if (cbk->EventSpy[vtkCommand::ModifiedEvent] != 0 ||
cbk->EventSpy[vtkCommand::StartInteractionEvent] != 0 ||
cbk->EventSpy[vtkCommand::InteractionEvent] != 0 ||
cbk->EventSpy[vtkCommand::EndInteractionEvent] != 0 ||
cbk->EventSpy[vtkCommand::StartEvent] != 0 ||
cbk->EventSpy[vtkCommand::EndEvent] != 0)
{
std::cerr << "Wrong number of fired events : "
<< cbk->EventSpy[vtkCommand::ModifiedEvent] << " "
<< cbk->EventSpy[vtkCommand::StartInteractionEvent] << " "
<< cbk->EventSpy[vtkCommand::InteractionEvent] << " "
<< cbk->EventSpy[vtkCommand::EndInteractionEvent] << " "
<< cbk->EventSpy[vtkCommand::StartEvent] << " "
<< cbk->EventSpy[vtkCommand::EndEvent] << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
......@@ -68,20 +68,11 @@ void vtkColorTransferControlPointsItem::PrintSelf(ostream &os, vtkIndent indent)
}
//-----------------------------------------------------------------------------
void vtkColorTransferControlPointsItem::StartChanges()
void vtkColorTransferControlPointsItem::emitEvent(unsigned long event, void* params)
{
if (this->ColorTransferFunction)
{
this->ColorTransferFunction->InvokeEvent(vtkCommand::StartEvent);
}
}
//-----------------------------------------------------------------------------
void vtkColorTransferControlPointsItem::EndChanges()
{
if (this->ColorTransferFunction)
{
this->ColorTransferFunction->InvokeEvent(vtkCommand::EndEvent);
this->ColorTransferFunction->InvokeEvent(event, params);
}
}
......
......@@ -85,8 +85,7 @@ protected:
vtkColorTransferControlPointsItem();
virtual ~vtkColorTransferControlPointsItem();
virtual void StartChanges();
virtual void EndChanges();
virtual void emitEvent(unsigned long event, void* params);
virtual unsigned long int GetControlPointsMTime();
......
......@@ -70,23 +70,13 @@ void vtkCompositeControlPointsItem::PrintSelf(ostream &os, vtkIndent indent)
}
//-----------------------------------------------------------------------------
void vtkCompositeControlPointsItem::StartChanges()
void vtkCompositeControlPointsItem::emitEvent(unsigned long event, void* params)
{
if (this->OpacityFunction)
{
this->OpacityFunction->InvokeEvent(vtkCommand::StartEvent);
this->OpacityFunction->InvokeEvent(event, params);
}
this->Superclass::StartChanges();
}
//-----------------------------------------------------------------------------
void vtkCompositeControlPointsItem::EndChanges()
{
if (this->OpacityFunction)
{
this->OpacityFunction->InvokeEvent(vtkCommand::EndEvent);
}
this->Superclass::EndChanges();
this->Superclass::emitEvent(event, params);
}
//-----------------------------------------------------------------------------
......
......@@ -85,8 +85,7 @@ protected:
vtkCompositeControlPointsItem();
virtual ~vtkCompositeControlPointsItem();
virtual void StartChanges();
virtual void EndChanges();
virtual void emitEvent(unsigned long event, void* params);
virtual unsigned long int GetControlPointsMTime();
......
......@@ -52,6 +52,7 @@ vtkControlPointsItem::vtkControlPointsItem()
this->CurrentPoint = -1;
this->BlockUpdates = 0;
this->StartedInteractions = 0;
this->Callback = vtkCallbackCommand::New();
this->Callback->SetClientData(this);
......@@ -210,6 +211,58 @@ bool vtkControlPointsItem::Paint(vtkContext2D* painter)
return true;
}
//-----------------------------------------------------------------------------
void vtkControlPointsItem::StartChanges()
{
this->emitEvent(vtkCommand::StartEvent);
}
//-----------------------------------------------------------------------------
void vtkControlPointsItem::EndChanges()
{
this->emitEvent(vtkCommand::EndEvent);
}
//-----------------------------------------------------------------------------
void vtkControlPointsItem::StartInteraction()
{
++this->StartedInteractions;
this->emitEvent(vtkCommand::StartInteractionEvent);
}
//-----------------------------------------------------------------------------
void vtkControlPointsItem::StartInteractionIfNotStarted()
{
if (this->GetInteractionsCount() == 0)
{
this->StartInteraction();
}
}
//-----------------------------------------------------------------------------
void vtkControlPointsItem::Interaction()
{
assert(this->StartedInteractions > 0);
this->emitEvent(vtkCommand::InteractionEvent);
}
//-----------------------------------------------------------------------------
void vtkControlPointsItem::EndInteraction()
{
--this->StartedInteractions;
assert(this->StartedInteractions >= 0);
this->emitEvent(vtkCommand::EndInteractionEvent);
}
//-----------------------------------------------------------------------------
int vtkControlPointsItem::GetInteractionsCount()const
{
return this->StartedInteractions;
}
//-----------------------------------------------------------------------------
//void vtkControlPointsItem::emitEvent(unsigned long event, void* params);
//-----------------------------------------------------------------------------
void vtkControlPointsItem::CallComputePoints(
vtkObject* vtkNotUsed(sender), unsigned long event,
......@@ -873,20 +926,32 @@ bool vtkControlPointsItem::MouseMoveEvent(const vtkContextMouseEvent &mouse)
{
if (this->StrokeMode)
{
this->StartInteractionIfNotStarted();
this->Stroke(mouse.Pos);
this->Interaction();
}
else if (this->CurrentPoint == -1 && this->Selection->GetNumberOfTuples() > 1)
{
this->StartInteractionIfNotStarted();
vtkIdTypeArray* points = this->GetSelection();
points->Register(this);// must stay valid after each individual point move
this->MovePoints(
vtkVector2f(mouse.Pos[0] - mouse.LastPos[0], mouse.Pos[1] - mouse.LastPos[1]),
points);
points->UnRegister(this);
this->Interaction();
}
else if (this->CurrentPoint != -1)
{
this->StartInteractionIfNotStarted();
this->SetCurrentPointPos(mouse.Pos);
this->Interaction();
}
}
if (mouse.Button == vtkContextMouseEvent::RIGHT_BUTTON)
......@@ -1287,6 +1352,10 @@ void vtkControlPointsItem::EditPoint(float vtkNotUsed(tX), float vtkNotUsed(tY))
//-----------------------------------------------------------------------------
bool vtkControlPointsItem::MouseButtonReleaseEvent(const vtkContextMouseEvent &mouse)
{
if (this->GetInteractionsCount())
{
this->EndInteraction();
}
if (mouse.Button == vtkContextMouseEvent::LEFT_BUTTON)
{
return true;
......@@ -1427,29 +1496,45 @@ bool vtkControlPointsItem::KeyPressEvent(const vtkContextKeyEvent &key)
translate.SetY( translate.GetY() * (bounds[3] - bounds[2]) * step);
if (this->GetNumberOfSelectedPoints())
{
this->StartInteractionIfNotStarted();
vtkIdTypeArray* points = this->GetSelection();
points->Register(this); // must stay valid after each individual move
this->MovePoints(translate, points);
points->UnRegister(this);
this->Interaction();
}
else
{
this->StartInteractionIfNotStarted();
this->MoveCurrentPoint(translate);
this->Interaction();
}
}
else if (key.GetInteractor()->GetKeySym() == std::string("plus"))
{
this->StartInteractionIfNotStarted();
vtkIdTypeArray* pointIds = this->GetSelection();
pointIds->Register(this); // must stay valid after each individual move
this->SpreadPoints(1., pointIds);
pointIds->UnRegister(this);
this->Interaction();
}
else if (key.GetInteractor()->GetKeySym() == std::string("minus"))
{
this->StartInteractionIfNotStarted();
vtkIdTypeArray* pointIds = this->GetSelection();
pointIds->Register(this); // must stay valid after each individual move
this->SpreadPoints(-1., pointIds);
pointIds->UnRegister(this);
this->Interaction();
}
}
else if (control)
......
......@@ -253,8 +253,14 @@ protected:
vtkControlPointsItem();
virtual ~vtkControlPointsItem();
virtual void StartChanges()=0;
virtual void EndChanges()=0;
void StartChanges();
void EndChanges();
void StartInteraction();
void StartInteractionIfNotStarted();
void Interaction();
void EndInteraction();
int GetInteractionsCount()const;
virtual void emitEvent(unsigned long event, void* params = 0) = 0;
static void CallComputePoints(vtkObject* sender, unsigned long event, void* receiver, void* params);
......@@ -301,6 +307,7 @@ protected:
vtkPen* SelectedPointPen;
vtkBrush* SelectedPointBrush;
int BlockUpdates;
int StartedInteractions;
vtkIdType CurrentPoint;
double Bounds[4];
......
......@@ -67,20 +67,11 @@ void vtkPiecewiseControlPointsItem::PrintSelf(ostream &os, vtkIndent indent)
}
//-----------------------------------------------------------------------------
void vtkPiecewiseControlPointsItem::StartChanges()
void vtkPiecewiseControlPointsItem::emitEvent(unsigned long event, void* params)
{
if (this->PiecewiseFunction)
{
this->PiecewiseFunction->InvokeEvent(vtkCommand::StartEvent);
}
}
//-----------------------------------------------------------------------------
void vtkPiecewiseControlPointsItem::EndChanges()
{
if (this->PiecewiseFunction)
{
this->PiecewiseFunction->InvokeEvent(vtkCommand::EndEvent);
this->PiecewiseFunction->InvokeEvent(event, params);
}
}
......
......@@ -68,8 +68,7 @@ protected:
vtkPiecewiseControlPointsItem();
virtual ~vtkPiecewiseControlPointsItem();
virtual void StartChanges();
virtual void EndChanges();
virtual void emitEvent(unsigned long event, void* params = 0);
virtual unsigned long int GetControlPointsMTime();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment