Commit d02e03b4 authored by Will Schroeder's avatar Will Schroeder
Browse files

ENH:Added the ability to record and playback events

parent 3a738d50
......@@ -27,6 +27,7 @@ vtkImageViewer.cxx
vtkImageViewer2.cxx
vtkImagingFactory.cxx
vtkImporter.cxx
vtkInteractorEventRecorder.cxx
vtkInteractorObserver.cxx
vtkInteractorStyle.cxx
vtkInteractorStyleFlight.cxx
......
/*=========================================================================
Program: Visualization Toolkit
Module: vtkInteractorEventRecorder.cxx
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) 1993-2002 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 "vtkInteractorEventRecorder.h"
#include "vtkCallbackCommand.h"
#include "vtkObjectFactory.h"
#include "vtkRenderWindowInteractor.h"
vtkCxxRevisionMacro(vtkInteractorEventRecorder, "1.1");
vtkStandardNewMacro(vtkInteractorEventRecorder);
vtkInteractorEventRecorder::vtkInteractorEventRecorder()
{
// take over the processing of delete and keypress events from the superclass
this->KeyPressCallbackCommand->SetCallback(
vtkInteractorEventRecorder::ProcessCharEvent);
this->Priority = VTK_LARGE_FLOAT; //get events first
this->EventCallbackCommand->SetCallback(
vtkInteractorEventRecorder::ProcessEvents);
this->FileName = 0;
this->State = vtkInteractorEventRecorder::Start;
this->InputStream = NULL;
this->OutputStream = NULL;
}
vtkInteractorEventRecorder::~vtkInteractorEventRecorder()
{
if ( this->FileName )
{
delete [] this->FileName;
}
if ( this->InputStream )
{
delete this->InputStream;
this->InputStream = NULL;
}
if ( this->OutputStream )
{
delete this->OutputStream;
this->OutputStream = NULL;
}
}
void vtkInteractorEventRecorder::SetEnabled(int enabling)
{
if ( ! this->Interactor )
{
vtkErrorMacro(<<"The interactor must be set prior to enabling/disabling widget");
return;
}
if ( enabling ) //----------------------------------------------------------
{
vtkDebugMacro(<<"Enabling widget");
if ( this->Enabled ) //already enabled, just return
{
return;
}
this->Enabled = 1;
// listen to any event
vtkRenderWindowInteractor *i = this->Interactor;
i->AddObserver(vtkCommand::AnyEvent, this->EventCallbackCommand,
this->Priority);
this->InvokeEvent(vtkCommand::EnableEvent,NULL);
}
else //disabling-----------------------------------------------------------
{
vtkDebugMacro(<<"Disabling widget");
if ( ! this->Enabled ) //already disabled, just return
{
return;
}
this->Enabled = 0;
// don't listen for events any more
this->Interactor->RemoveObserver(this->EventCallbackCommand);
this->InvokeEvent(vtkCommand::DisableEvent,NULL);
}
}
void vtkInteractorEventRecorder::Record()
{
if ( this->State == vtkInteractorEventRecorder::Start )
{
if ( ! this->OutputStream ) //need to open file
{
this->OutputStream = new ofstream(this->FileName, ios::out);
if (this->OutputStream->fail())
{
vtkErrorMacro(<< "Unable to open file: "<< this->FileName);
delete this->OutputStream;
return;
}
}
this->State = vtkInteractorEventRecorder::Recording;
}
}
void vtkInteractorEventRecorder::Play()
{
if ( this->State == vtkInteractorEventRecorder::Start )
{
if ( ! this->InputStream ) //need to open file
{
this->InputStream = new ifstream(this->FileName, ios::in);
if (this->InputStream->fail())
{
vtkErrorMacro(<< "Unable to open file: "<< this->FileName);
delete this->InputStream;
return;
}
}
vtkDebugMacro(<<"Playing");
this->State = vtkInteractorEventRecorder::Playing;
// Read events and invoke them on the object in question
char event[128], keySym[64];
int pos[2], ctrlKey, shiftKey, keyCode, repeatCount;
while ( ! this->InputStream->eof() )
{
this->InputStream->width(256);
*this->InputStream >> event;
*this->InputStream >> pos[0];
*this->InputStream >> pos[1];
*this->InputStream >> ctrlKey;
*this->InputStream >> shiftKey;
*this->InputStream >> keyCode;
*this->InputStream >> repeatCount;
*this->InputStream >> keySym;
this->Interactor->SetEventPosition(pos);
this->Interactor->SetControlKey(ctrlKey);
this->Interactor->SetShiftKey(shiftKey);
this->Interactor->SetKeyCode(keyCode);
this->Interactor->SetRepeatCount(repeatCount);
this->Interactor->SetKeySym(keySym);
unsigned long ievent = vtkCommand::GetEventIdFromString(event);
this->Interactor->InvokeEvent(ievent, NULL);
}
}
this->State = vtkInteractorEventRecorder::Start;
}
void vtkInteractorEventRecorder::Stop()
{
this->State = vtkInteractorEventRecorder::Start;
this->Modified();
}
void vtkInteractorEventRecorder::Rewind()
{
if ( ! this->InputStream ) //need to already have an open file
{
vtkGenericWarningMacro(<<"No input file opened to rewind...");
}
this->InputStream->clear();
this->InputStream->seekg(0);
}
// This adds the keypress event observer and the delete event observer
void vtkInteractorEventRecorder::SetInteractor(vtkRenderWindowInteractor* i)
{
if (i == this->Interactor)
{
return;
}
// if we already have an Interactor then stop observing it
if (this->Interactor)
{
this->SetEnabled(0); //disable the old interactor
this->Interactor->RemoveObserver(this->KeyPressCallbackCommand);
}
this->Interactor = i;
// add observers for each of the events handled in ProcessEvents
if (i)
{
i->AddObserver(vtkCommand::CharEvent,
this->KeyPressCallbackCommand, this->Priority);
i->AddObserver(vtkCommand::DeleteEvent,
this->KeyPressCallbackCommand, this->Priority);
}
this->Modified();
}
void vtkInteractorEventRecorder::ProcessCharEvent(vtkObject* object,
unsigned long event,
void* clientData,
void* vtkNotUsed(callData))
{
vtkInteractorEventRecorder* self =
reinterpret_cast<vtkInteractorEventRecorder *>( clientData );
vtkRenderWindowInteractor* rwi =
static_cast<vtkRenderWindowInteractor *>( object );
switch(event)
{
case vtkCommand::DeleteEvent:
self->Interactor = NULL; //its going bye bye
self->Enabled = 0;
break;
case vtkCommand::CharEvent:
if ( self->KeyPressActivation )
{
if (rwi->GetKeyCode() == self->KeyPressActivationValue )
{
if ( !self->Enabled )
{
self->On();
}
else
{
self->Off();
}
}//event not aborted
}//if activation enabled
}
}
void vtkInteractorEventRecorder::ProcessEvents(vtkObject* object,
unsigned long event,
void* clientData,
void* vtkNotUsed(callData))
{
vtkInteractorEventRecorder* self =
reinterpret_cast<vtkInteractorEventRecorder *>( clientData );
vtkRenderWindowInteractor* rwi =
static_cast<vtkRenderWindowInteractor *>( object );
// all events are processed
if ( self->State == vtkInteractorEventRecorder::Recording )
{
switch(event)
{
case vtkCommand::ModifiedEvent: //dont want these
break;
default:
self->WriteEvent(vtkCommand::GetStringFromEventId(event),
rwi->GetEventPosition(), rwi->GetControlKey(),
rwi->GetShiftKey(), rwi->GetKeyCode(),
rwi->GetRepeatCount(), rwi->GetKeySym());
}
self->OutputStream->flush();
}
}
void vtkInteractorEventRecorder::WriteEvent(const char* event, int pos[2],
int ctrlKey, int shiftKey,
int keyCode, int repeatCount,
char* keySym)
{
*this->OutputStream << event << " " << pos[0] << " " << pos[1] << " "
<< ctrlKey << " " << shiftKey << " "
<< keyCode << " " << repeatCount << " "
<< keySym << "\n";
}
void vtkInteractorEventRecorder::ReadEvent()
{
}
void vtkInteractorEventRecorder::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os,indent);
if (this->FileName)
{
os << indent << "File Name: " << this->FileName << "\n";
}
}
/*=========================================================================
Program: Visualization Toolkit
Module: vtkInteractorEventRecorder.h
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) 1993-2002 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.
=========================================================================*/
// .NAME vtkInteractorEventRecorder - record VTK events to a file; play them back to an object
// .SECTION Description
// vtkInteractorEventRecorder records all VTK events invoked from a
// vtkRenderWindowInteractor. The events are recorded to a
// file. vtkInteractorEventRecorder can also be used to play those events
// back and invoke them on an vtkRenderWindowInteractor.
// .SECTION See Also
// vtkInteractorObserver vtkCallback
#ifndef __vtkInteractorEventRecorder_h
#define __vtkInteractorEventRecorder_h
#include "vtkInteractorObserver.h"
// The superclass that all commands should be subclasses of
class VTK_RENDERING_EXPORT vtkInteractorEventRecorder : public vtkInteractorObserver
{
public:
static vtkInteractorEventRecorder *New();
vtkTypeRevisionMacro(vtkInteractorEventRecorder,vtkInteractorObserver);
void PrintSelf(ostream& os, vtkIndent indent);
// Satisfy the superclass API. Enable/disable listening for events.
virtual void SetEnabled(int);
virtual void SetInteractor(vtkRenderWindowInteractor* iren);
// Description:
// Set/Get the name of a file events should be written to/from.
vtkSetStringMacro(FileName);
vtkGetStringMacro(FileName);
// Description:
// Invoke this method to begin recording events. The events will be
// recorded to the filename indicated.
void Record();
// Description:
// Invoke this method to begin playing events from the current position.
// The events will be played back from the filename indicated.
void Play();
// Description:
// Invoke this method to stop recording/playing events.
// played back from the filename indicated.
void Stop();
// Description:
// Rewind to the beginning of the file.
void Rewind();
protected:
vtkInteractorEventRecorder();
~vtkInteractorEventRecorder();
// file to read/write from
char *FileName;
// for reading and writing
istream *InputStream;
ostream *OutputStream;
//methods for processing events
static void ProcessCharEvent(vtkObject* object, unsigned long event,
void* clientdata, void* calldata);
static void ProcessEvents(vtkObject* object, unsigned long event,
void* clientdata, void* calldata);
virtual void WriteEvent(const char* event, int pos[2], int ctrlKey,
int shiftKey, int keyCode, int repeatCount,
char* keySym);
virtual void ReadEvent();
//BTX - manage the state of the recorder
int State;
enum WidgetState
{
Start=0,
Playing,
Recording
};
//ETX
private:
vtkInteractorEventRecorder(const vtkInteractorEventRecorder&); // Not implemented.
void operator=(const vtkInteractorEventRecorder&); // Not implemented.
};
#endif /* __vtkInteractorEventRecorder_h */
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