You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
927 lines
28 KiB
C++
927 lines
28 KiB
C++
/*=========================================================================
|
|
|
|
Program: Visualization Toolkit
|
|
Module: vtkRenderWindowInteractor.h
|
|
|
|
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.
|
|
|
|
=========================================================================*/
|
|
/**
|
|
* @class vtkRenderWindowInteractor
|
|
* @brief platform-independent render window
|
|
* interaction including picking and frame rate control.
|
|
*
|
|
*
|
|
* vtkRenderWindowInteractor provides a platform-independent interaction
|
|
* mechanism for mouse/key/time events. It serves as a base class for
|
|
* platform-dependent implementations that handle routing of mouse/key/timer
|
|
* messages to vtkInteractorObserver and its subclasses. vtkRenderWindowInteractor
|
|
* also provides controls for picking, rendering frame rate, and headlights.
|
|
*
|
|
* vtkRenderWindowInteractor has changed from previous implementations and
|
|
* now serves only as a shell to hold user preferences and route messages to
|
|
* vtkInteractorStyle. Callbacks are available for many events. Platform
|
|
* specific subclasses should provide methods for manipulating timers,
|
|
* TerminateApp, and an event loop if required via
|
|
* Initialize/Start/Enable/Disable.
|
|
*
|
|
* @warning
|
|
* vtkRenderWindowInteractor routes events through VTK's command/observer
|
|
* design pattern. That is, when vtkRenderWindowInteractor (actually, one of
|
|
* its subclasses) sees a platform-dependent event, it translates this into
|
|
* a VTK event using the InvokeEvent() method. Then any vtkInteractorObservers
|
|
* registered for that event are expected to respond as appropriate.
|
|
*
|
|
* @sa
|
|
* vtkInteractorObserver
|
|
*/
|
|
|
|
#ifndef vtkRenderWindowInteractor_h
|
|
#define vtkRenderWindowInteractor_h
|
|
|
|
#include "vtkCommand.h" // for method sig
|
|
#include "vtkObject.h"
|
|
#include "vtkRenderingCoreModule.h" // For export macro
|
|
|
|
class vtkTimerIdMap;
|
|
|
|
// Timer flags for win32/X compatibility
|
|
#define VTKI_TIMER_FIRST 0
|
|
#define VTKI_TIMER_UPDATE 1
|
|
|
|
// maximum pointers active at once
|
|
// for example in multitouch
|
|
#define VTKI_MAX_POINTERS 5
|
|
|
|
class vtkAbstractPicker;
|
|
class vtkAbstractPropPicker;
|
|
class vtkAssemblyPath;
|
|
class vtkHardwareWindow;
|
|
class vtkInteractorObserver;
|
|
class vtkRenderWindow;
|
|
class vtkRenderer;
|
|
class vtkObserverMediator;
|
|
class vtkInteractorEventRecorder;
|
|
class vtkPickingManager;
|
|
|
|
class VTKRENDERINGCORE_EXPORT vtkRenderWindowInteractor : public vtkObject
|
|
{
|
|
|
|
friend class vtkInteractorEventRecorder;
|
|
|
|
public:
|
|
static vtkRenderWindowInteractor* New();
|
|
vtkTypeMacro(vtkRenderWindowInteractor, vtkObject);
|
|
void PrintSelf(ostream& os, vtkIndent indent) override;
|
|
|
|
//@{
|
|
/**
|
|
* Prepare for handling events and set the Enabled flag to true.
|
|
* This will be called automatically by Start() if the interactor
|
|
* is not initialized, but it can be called manually if you need
|
|
* to perform any operations between initialization and the start
|
|
* of the event loop.
|
|
*/
|
|
virtual void Initialize();
|
|
void ReInitialize()
|
|
{
|
|
this->Initialized = 0;
|
|
this->Enabled = 0;
|
|
this->Initialize();
|
|
}
|
|
//@}
|
|
|
|
/**
|
|
* This Method detects loops of RenderWindow-Interactor,
|
|
* so objects are freed properly.
|
|
*/
|
|
void UnRegister(vtkObjectBase* o) override;
|
|
|
|
/**
|
|
* Start the event loop. This is provided so that you do not have to
|
|
* implement your own event loop. You still can use your own
|
|
* event loop if you want.
|
|
*/
|
|
virtual void Start();
|
|
|
|
/**
|
|
* Run the event loop and return. This is provided so that you can
|
|
* implement your own event loop but yet use the vtk event handling as
|
|
* well.
|
|
*/
|
|
virtual void ProcessEvents() {}
|
|
|
|
/**
|
|
* Is the interactor loop done
|
|
*/
|
|
vtkGetMacro(Done, bool);
|
|
vtkSetMacro(Done, bool);
|
|
|
|
/**
|
|
* Enable/Disable interactions. By default interactors are enabled when
|
|
* initialized. Initialize() must be called prior to enabling/disabling
|
|
* interaction. These methods are used when a window/widget is being
|
|
* shared by multiple renderers and interactors. This allows a "modal"
|
|
* display where one interactor is active when its data is to be displayed
|
|
* and all other interactors associated with the widget are disabled
|
|
* when their data is not displayed.
|
|
*/
|
|
virtual void Enable()
|
|
{
|
|
this->Enabled = 1;
|
|
this->Modified();
|
|
}
|
|
virtual void Disable()
|
|
{
|
|
this->Enabled = 0;
|
|
this->Modified();
|
|
}
|
|
vtkGetMacro(Enabled, int);
|
|
|
|
//@{
|
|
/**
|
|
* Enable/Disable whether vtkRenderWindowInteractor::Render() calls
|
|
* this->RenderWindow->Render().
|
|
*/
|
|
vtkBooleanMacro(EnableRender, bool);
|
|
vtkSetMacro(EnableRender, bool);
|
|
vtkGetMacro(EnableRender, bool);
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Set/Get the rendering window being controlled by this object.
|
|
*/
|
|
void SetRenderWindow(vtkRenderWindow* aren);
|
|
vtkGetObjectMacro(RenderWindow, vtkRenderWindow);
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Set/Get the hardware window being controlled by this object.
|
|
* For opengl the hardware window is not used as the opengl
|
|
* subclasses of RenderWindow provide the functionality.
|
|
*/
|
|
void SetHardwareWindow(vtkHardwareWindow* aren);
|
|
vtkGetObjectMacro(HardwareWindow, vtkHardwareWindow);
|
|
//@}
|
|
|
|
/**
|
|
* Event loop notification member for window size change.
|
|
* Window size is measured in pixels.
|
|
*
|
|
* If the size has changed, this method will fire
|
|
* vtkCommand::WindowResizeEvent.
|
|
*/
|
|
virtual void UpdateSize(int x, int y);
|
|
|
|
/**
|
|
* This class provides two groups of methods for manipulating timers. The
|
|
* first group (CreateTimer(timerType) and DestroyTimer()) implicitly use
|
|
* an internal timer id (and are present for backward compatibility). The
|
|
* second group (CreateRepeatingTimer(long),CreateOneShotTimer(long),
|
|
* ResetTimer(int),DestroyTimer(int)) use timer ids so multiple timers can
|
|
* be independently managed. In the first group, the CreateTimer() method
|
|
* takes an argument indicating whether the timer is created the first time
|
|
* (timerType==VTKI_TIMER_FIRST) or whether it is being reset
|
|
* (timerType==VTKI_TIMER_UPDATE). (In initial implementations of VTK this
|
|
* was how one shot and repeating timers were managed.) In the second
|
|
* group, the create methods take a timer duration argument (in
|
|
* milliseconds) and return a timer id. Thus the ResetTimer(timerId) and
|
|
* DestroyTimer(timerId) methods take this timer id and operate on the
|
|
* timer as appropriate. Methods are also available for determining
|
|
*/
|
|
virtual int CreateTimer(int timerType); // first group, for backward compatibility
|
|
virtual int DestroyTimer(); // first group, for backward compatibility
|
|
|
|
/**
|
|
* Create a repeating timer, with the specified duration (in milliseconds).
|
|
* \return the timer id.
|
|
*/
|
|
int CreateRepeatingTimer(unsigned long duration);
|
|
|
|
/**
|
|
* Create a one shot timer, with the specified duration (in milliseconds).
|
|
* \return the timer id.
|
|
*/
|
|
int CreateOneShotTimer(unsigned long duration);
|
|
|
|
/**
|
|
* Query whether the specified timerId is a one shot timer.
|
|
* \return 1 if the timer is a one shot timer.
|
|
*/
|
|
int IsOneShotTimer(int timerId);
|
|
|
|
/**
|
|
* Get the duration (in milliseconds) for the specified timerId.
|
|
*/
|
|
unsigned long GetTimerDuration(int timerId);
|
|
|
|
/**
|
|
* Reset the specified timer.
|
|
*/
|
|
int ResetTimer(int timerId);
|
|
|
|
/**
|
|
* Destroy the timer specified by timerId.
|
|
* \return 1 if the timer was destroyed.
|
|
*/
|
|
int DestroyTimer(int timerId);
|
|
|
|
/**
|
|
* Get the VTK timer ID that corresponds to the supplied platform ID.
|
|
*/
|
|
virtual int GetVTKTimerId(int platformTimerId);
|
|
|
|
// Moved into the public section of the class so that classless timer procs
|
|
// can access these enum members without being "friends"...
|
|
enum
|
|
{
|
|
OneShotTimer = 1,
|
|
RepeatingTimer
|
|
};
|
|
|
|
//@{
|
|
/**
|
|
* Specify the default timer interval (in milliseconds). (This is used in
|
|
* conjunction with the timer methods described previously, e.g.,
|
|
* CreateTimer() uses this value; and CreateRepeatingTimer(duration) and
|
|
* CreateOneShotTimer(duration) use the default value if the parameter
|
|
* "duration" is less than or equal to zero.) Care must be taken when
|
|
* adjusting the timer interval from the default value of 10
|
|
* milliseconds--it may adversely affect the interactors.
|
|
*/
|
|
vtkSetClampMacro(TimerDuration, unsigned long, 1, 100000);
|
|
vtkGetMacro(TimerDuration, unsigned long);
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* These methods are used to communicate information about the currently
|
|
* firing CreateTimerEvent or DestroyTimerEvent. The caller of
|
|
* CreateTimerEvent sets up TimerEventId, TimerEventType and
|
|
* TimerEventDuration. The observer of CreateTimerEvent should set up an
|
|
* appropriate platform specific timer based on those values and set the
|
|
* TimerEventPlatformId before returning. The caller of DestroyTimerEvent
|
|
* sets up TimerEventPlatformId. The observer of DestroyTimerEvent should
|
|
* simply destroy the platform specific timer created by CreateTimerEvent.
|
|
* See vtkGenericRenderWindowInteractor's InternalCreateTimer and
|
|
* InternalDestroyTimer for an example.
|
|
*/
|
|
vtkSetMacro(TimerEventId, int);
|
|
vtkGetMacro(TimerEventId, int);
|
|
vtkSetMacro(TimerEventType, int);
|
|
vtkGetMacro(TimerEventType, int);
|
|
vtkSetMacro(TimerEventDuration, int);
|
|
vtkGetMacro(TimerEventDuration, int);
|
|
vtkSetMacro(TimerEventPlatformId, int);
|
|
vtkGetMacro(TimerEventPlatformId, int);
|
|
//@}
|
|
|
|
/**
|
|
* This function is called on 'q','e' keypress if exitmethod is not
|
|
* specified and should be overridden by platform dependent subclasses
|
|
* to provide a termination procedure if one is required.
|
|
*/
|
|
virtual void TerminateApp(void) { this->Done = true; }
|
|
|
|
//@{
|
|
/**
|
|
* External switching between joystick/trackball/new? modes. Initial value
|
|
* is a vtkInteractorStyleSwitch object.
|
|
*/
|
|
virtual void SetInteractorStyle(vtkInteractorObserver*);
|
|
vtkGetObjectMacro(InteractorStyle, vtkInteractorObserver);
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Turn on/off the automatic repositioning of lights as the camera moves.
|
|
* Default is On.
|
|
*/
|
|
vtkSetMacro(LightFollowCamera, vtkTypeBool);
|
|
vtkGetMacro(LightFollowCamera, vtkTypeBool);
|
|
vtkBooleanMacro(LightFollowCamera, vtkTypeBool);
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Set/Get the desired update rate. This is used by vtkLODActor's to tell
|
|
* them how quickly they need to render. This update is in effect only
|
|
* when the camera is being rotated, or zoomed. When the interactor is
|
|
* still, the StillUpdateRate is used instead.
|
|
* The default is 15.
|
|
*/
|
|
vtkSetClampMacro(DesiredUpdateRate, double, 0.0001, VTK_FLOAT_MAX);
|
|
vtkGetMacro(DesiredUpdateRate, double);
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Set/Get the desired update rate when movement has stopped.
|
|
* For the non-still update rate, see the SetDesiredUpdateRate method.
|
|
* The default is 0.0001
|
|
*/
|
|
vtkSetClampMacro(StillUpdateRate, double, 0.0001, VTK_FLOAT_MAX);
|
|
vtkGetMacro(StillUpdateRate, double);
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* See whether interactor has been initialized yet.
|
|
* Default is 0.
|
|
*/
|
|
vtkGetMacro(Initialized, int);
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Set/Get the object used to perform pick operations. In order to
|
|
* pick instances of vtkProp, the picker must be a subclass of
|
|
* vtkAbstractPropPicker, meaning that it can identify a particular
|
|
* instance of vtkProp.
|
|
*/
|
|
virtual void SetPicker(vtkAbstractPicker*);
|
|
vtkGetObjectMacro(Picker, vtkAbstractPicker);
|
|
//@}
|
|
|
|
/**
|
|
* Create default picker. Used to create one when none is specified.
|
|
* Default is an instance of vtkPropPicker.
|
|
*/
|
|
virtual vtkAbstractPropPicker* CreateDefaultPicker();
|
|
|
|
//@{
|
|
/**
|
|
* Set the picking manager.
|
|
* Set/Get the object used to perform operations through the interactor
|
|
* By default, a valid but disabled picking manager is instantiated.
|
|
*/
|
|
virtual void SetPickingManager(vtkPickingManager*);
|
|
vtkGetObjectMacro(PickingManager, vtkPickingManager);
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* These methods correspond to the Exit, User and Pick
|
|
* callbacks. They allow for the Style to invoke them.
|
|
*/
|
|
virtual void ExitCallback();
|
|
virtual void UserCallback();
|
|
virtual void StartPickCallback();
|
|
virtual void EndPickCallback();
|
|
//@}
|
|
|
|
/**
|
|
* Get the current position of the mouse.
|
|
*/
|
|
virtual void GetMousePosition(int* x, int* y)
|
|
{
|
|
*x = 0;
|
|
*y = 0;
|
|
}
|
|
|
|
//@{
|
|
/**
|
|
* Hide or show the mouse cursor, it is nice to be able to hide the
|
|
* default cursor if you want VTK to display a 3D cursor instead.
|
|
*/
|
|
void HideCursor();
|
|
void ShowCursor();
|
|
//@}
|
|
|
|
/**
|
|
* Render the scene. Just pass the render call on to the
|
|
* associated vtkRenderWindow.
|
|
*/
|
|
virtual void Render();
|
|
|
|
//@{
|
|
/**
|
|
* Given a position x, move the current camera's focal point to x.
|
|
* The movement is animated over the number of frames specified in
|
|
* NumberOfFlyFrames. The LOD desired frame rate is used.
|
|
*/
|
|
void FlyTo(vtkRenderer* ren, double x, double y, double z);
|
|
void FlyTo(vtkRenderer* ren, double* x) { this->FlyTo(ren, x[0], x[1], x[2]); }
|
|
void FlyToImage(vtkRenderer* ren, double x, double y);
|
|
void FlyToImage(vtkRenderer* ren, double* x) { this->FlyToImage(ren, x[0], x[1]); }
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Set the number of frames to fly to when FlyTo is invoked.
|
|
*/
|
|
vtkSetClampMacro(NumberOfFlyFrames, int, 1, VTK_INT_MAX);
|
|
vtkGetMacro(NumberOfFlyFrames, int);
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Set the total Dolly value to use when flying to (FlyTo()) a
|
|
* specified point. Negative values fly away from the point.
|
|
*/
|
|
vtkSetMacro(Dolly, double);
|
|
vtkGetMacro(Dolly, double);
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Set/Get information about the current event.
|
|
* The current x,y position is in the EventPosition, and the previous
|
|
* event position is in LastEventPosition, updated automatically each
|
|
* time EventPosition is set using its Set() method. Mouse positions
|
|
* are measured in pixels.
|
|
* The other information is about key board input.
|
|
*/
|
|
vtkGetVector2Macro(EventPosition, int);
|
|
vtkGetVector2Macro(LastEventPosition, int);
|
|
vtkSetVector2Macro(LastEventPosition, int);
|
|
virtual void SetEventPosition(int x, int y)
|
|
{
|
|
vtkDebugMacro(<< this->GetClassName() << " (" << this << "): setting EventPosition to (" << x
|
|
<< "," << y << ")");
|
|
if (this->EventPosition[0] != x || this->EventPosition[1] != y ||
|
|
this->LastEventPosition[0] != x || this->LastEventPosition[1] != y)
|
|
{
|
|
this->LastEventPosition[0] = this->EventPosition[0];
|
|
this->LastEventPosition[1] = this->EventPosition[1];
|
|
this->EventPosition[0] = x;
|
|
this->EventPosition[1] = y;
|
|
this->Modified();
|
|
}
|
|
}
|
|
virtual void SetEventPosition(int pos[2]) { this->SetEventPosition(pos[0], pos[1]); }
|
|
virtual void SetEventPositionFlipY(int x, int y)
|
|
{
|
|
this->SetEventPosition(x, this->Size[1] - y - 1);
|
|
}
|
|
virtual void SetEventPositionFlipY(int pos[2]) { this->SetEventPositionFlipY(pos[0], pos[1]); }
|
|
//@}
|
|
|
|
virtual int* GetEventPositions(int pointerIndex)
|
|
{
|
|
if (pointerIndex >= VTKI_MAX_POINTERS)
|
|
{
|
|
return nullptr;
|
|
}
|
|
return this->EventPositions[pointerIndex];
|
|
}
|
|
virtual int* GetLastEventPositions(int pointerIndex)
|
|
{
|
|
if (pointerIndex >= VTKI_MAX_POINTERS)
|
|
{
|
|
return nullptr;
|
|
}
|
|
return this->LastEventPositions[pointerIndex];
|
|
}
|
|
virtual void SetEventPosition(int x, int y, int pointerIndex)
|
|
{
|
|
if (pointerIndex < 0 || pointerIndex >= VTKI_MAX_POINTERS)
|
|
{
|
|
return;
|
|
}
|
|
if (pointerIndex == 0)
|
|
{
|
|
this->LastEventPosition[0] = this->EventPosition[0];
|
|
this->LastEventPosition[1] = this->EventPosition[1];
|
|
this->EventPosition[0] = x;
|
|
this->EventPosition[1] = y;
|
|
}
|
|
vtkDebugMacro(<< this->GetClassName() << " (" << this << "): setting EventPosition to (" << x
|
|
<< "," << y << ") for pointerIndex number " << pointerIndex);
|
|
if (this->EventPositions[pointerIndex][0] != x || this->EventPositions[pointerIndex][1] != y ||
|
|
this->LastEventPositions[pointerIndex][0] != x ||
|
|
this->LastEventPositions[pointerIndex][1] != y)
|
|
{
|
|
this->LastEventPositions[pointerIndex][0] = this->EventPositions[pointerIndex][0];
|
|
this->LastEventPositions[pointerIndex][1] = this->EventPositions[pointerIndex][1];
|
|
this->EventPositions[pointerIndex][0] = x;
|
|
this->EventPositions[pointerIndex][1] = y;
|
|
this->Modified();
|
|
}
|
|
}
|
|
virtual void SetEventPosition(int pos[2], int pointerIndex)
|
|
{
|
|
this->SetEventPosition(pos[0], pos[1], pointerIndex);
|
|
}
|
|
virtual void SetEventPositionFlipY(int x, int y, int pointerIndex)
|
|
{
|
|
this->SetEventPosition(x, this->Size[1] - y - 1, pointerIndex);
|
|
}
|
|
virtual void SetEventPositionFlipY(int pos[2], int pointerIndex)
|
|
{
|
|
this->SetEventPositionFlipY(pos[0], pos[1], pointerIndex);
|
|
}
|
|
|
|
//@{
|
|
/**
|
|
* Set/get whether alt modifier key was pressed.
|
|
*/
|
|
vtkSetMacro(AltKey, int);
|
|
vtkGetMacro(AltKey, int);
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Set/get whether control modifier key was pressed.
|
|
*/
|
|
vtkSetMacro(ControlKey, int);
|
|
vtkGetMacro(ControlKey, int);
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Set/get whether shift modifier key was pressed.
|
|
*/
|
|
vtkSetMacro(ShiftKey, int);
|
|
vtkGetMacro(ShiftKey, int);
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Set/get the key code for the key that was pressed.
|
|
*/
|
|
vtkSetMacro(KeyCode, char);
|
|
vtkGetMacro(KeyCode, char);
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Set/get the repear count for the key or mouse event. This specifies how
|
|
* many times a key has been pressed.
|
|
*/
|
|
vtkSetMacro(RepeatCount, int);
|
|
vtkGetMacro(RepeatCount, int);
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Set/get the key symbol for the key that was pressed. This is the key
|
|
* symbol as defined by the relevant X headers. On X based platforms this
|
|
* corresponds to the installed X server, whereas on other platforms the
|
|
* native key codes are translated into a string representation.
|
|
*/
|
|
vtkSetStringMacro(KeySym);
|
|
vtkGetStringMacro(KeySym);
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Set/get the index of the most recent pointer to have an event
|
|
*/
|
|
vtkSetMacro(PointerIndex, int);
|
|
vtkGetMacro(PointerIndex, int);
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Set/get the rotation for the gesture in degrees, update LastRotation
|
|
*/
|
|
void SetRotation(double val);
|
|
vtkGetMacro(Rotation, double);
|
|
vtkGetMacro(LastRotation, double);
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Set/get the scale for the gesture, updates LastScale
|
|
*/
|
|
void SetScale(double val);
|
|
vtkGetMacro(Scale, double);
|
|
vtkGetMacro(LastScale, double);
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Set/get the translation for pan/swipe gestures, update LastTranslation
|
|
*/
|
|
void SetTranslation(double val[2]);
|
|
vtkGetVector2Macro(Translation, double);
|
|
vtkGetVector2Macro(LastTranslation, double);
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Set all the event information in one call.
|
|
*/
|
|
void SetEventInformation(int x, int y, int ctrl, int shift, char keycode, int repeatcount,
|
|
const char* keysym, int pointerIndex)
|
|
{
|
|
this->SetEventPosition(x, y, pointerIndex);
|
|
this->ControlKey = ctrl;
|
|
this->ShiftKey = shift;
|
|
this->KeyCode = keycode;
|
|
this->RepeatCount = repeatcount;
|
|
this->PointerIndex = pointerIndex;
|
|
if (keysym)
|
|
{
|
|
this->SetKeySym(keysym);
|
|
}
|
|
this->Modified();
|
|
}
|
|
void SetEventInformation(int x, int y, int ctrl = 0, int shift = 0, char keycode = 0,
|
|
int repeatcount = 0, const char* keysym = nullptr)
|
|
{
|
|
this->SetEventInformation(x, y, ctrl, shift, keycode, repeatcount, keysym, 0);
|
|
}
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Calls SetEventInformation, but flips the Y based on the current Size[1]
|
|
* value (i.e. y = this->Size[1] - y - 1).
|
|
*/
|
|
void SetEventInformationFlipY(int x, int y, int ctrl, int shift, char keycode, int repeatcount,
|
|
const char* keysym, int pointerIndex)
|
|
{
|
|
this->SetEventInformation(
|
|
x, this->Size[1] - y - 1, ctrl, shift, keycode, repeatcount, keysym, pointerIndex);
|
|
}
|
|
void SetEventInformationFlipY(int x, int y, int ctrl = 0, int shift = 0, char keycode = 0,
|
|
int repeatcount = 0, const char* keysym = nullptr)
|
|
{
|
|
this->SetEventInformationFlipY(x, y, ctrl, shift, keycode, repeatcount, keysym, 0);
|
|
}
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Set all the keyboard-related event information in one call.
|
|
*/
|
|
void SetKeyEventInformation(int ctrl = 0, int shift = 0, char keycode = 0, int repeatcount = 0,
|
|
const char* keysym = nullptr)
|
|
{
|
|
this->ControlKey = ctrl;
|
|
this->ShiftKey = shift;
|
|
this->KeyCode = keycode;
|
|
this->RepeatCount = repeatcount;
|
|
if (keysym)
|
|
{
|
|
this->SetKeySym(keysym);
|
|
}
|
|
this->Modified();
|
|
}
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* This methods sets the Size ivar of the interactor without
|
|
* actually changing the size of the window. Normally
|
|
* application programmers would use UpdateSize if anything.
|
|
* This is useful for letting someone else change the size of
|
|
* the rendering window and just letting the interactor
|
|
* know about the change.
|
|
* The current event width/height (if any) is in EventSize
|
|
* (Expose event, for example).
|
|
* Window size is measured in pixels.
|
|
*/
|
|
vtkSetVector2Macro(Size, int);
|
|
vtkGetVector2Macro(Size, int);
|
|
vtkSetVector2Macro(EventSize, int);
|
|
vtkGetVector2Macro(EventSize, int);
|
|
//@}
|
|
|
|
/**
|
|
* When an event occurs, we must determine which Renderer the event
|
|
* occurred within, since one RenderWindow may contain multiple
|
|
* renderers.
|
|
*/
|
|
virtual vtkRenderer* FindPokedRenderer(int, int);
|
|
|
|
/**
|
|
* Return the object used to mediate between vtkInteractorObservers
|
|
* contending for resources. Multiple interactor observers will often
|
|
* request different resources (e.g., cursor shape); the mediator uses a
|
|
* strategy to provide the resource based on priority of the observer plus
|
|
* the particular request (default versus non-default cursor shape).
|
|
*/
|
|
vtkObserverMediator* GetObserverMediator();
|
|
|
|
//@{
|
|
/**
|
|
* Use a 3DConnexion device. Initial value is false.
|
|
* If VTK is not build with the TDx option, this is no-op.
|
|
* If VTK is build with the TDx option, and a device is not connected,
|
|
* a warning is emitted.
|
|
* It is must be called before the first Render to be effective, otherwise
|
|
* it is ignored.
|
|
*/
|
|
vtkSetMacro(UseTDx, bool);
|
|
vtkGetMacro(UseTDx, bool);
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Fire various events. SetEventInformation should be called just prior
|
|
* to calling any of these methods. These methods will Invoke the
|
|
* corresponding vtk event.
|
|
*/
|
|
virtual void MouseMoveEvent();
|
|
virtual void RightButtonPressEvent();
|
|
virtual void RightButtonReleaseEvent();
|
|
virtual void LeftButtonPressEvent();
|
|
virtual void LeftButtonReleaseEvent();
|
|
virtual void MiddleButtonPressEvent();
|
|
virtual void MiddleButtonReleaseEvent();
|
|
virtual void MouseWheelForwardEvent();
|
|
virtual void MouseWheelBackwardEvent();
|
|
virtual void ExposeEvent();
|
|
virtual void ConfigureEvent();
|
|
virtual void EnterEvent();
|
|
virtual void LeaveEvent();
|
|
virtual void KeyPressEvent();
|
|
virtual void KeyReleaseEvent();
|
|
virtual void CharEvent();
|
|
virtual void ExitEvent();
|
|
virtual void FourthButtonPressEvent();
|
|
virtual void FourthButtonReleaseEvent();
|
|
virtual void FifthButtonPressEvent();
|
|
virtual void FifthButtonReleaseEvent();
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Fire various gesture based events. These methods will Invoke the
|
|
* corresponding vtk event.
|
|
*/
|
|
virtual void StartPinchEvent();
|
|
virtual void PinchEvent();
|
|
virtual void EndPinchEvent();
|
|
virtual void StartRotateEvent();
|
|
virtual void RotateEvent();
|
|
virtual void EndRotateEvent();
|
|
virtual void StartPanEvent();
|
|
virtual void PanEvent();
|
|
virtual void EndPanEvent();
|
|
virtual void TapEvent();
|
|
virtual void LongTapEvent();
|
|
virtual void SwipeEvent();
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Convert multitouch events into gestures. When this is on
|
|
* (its default) multitouch events received by this interactor
|
|
* will be converted into gestures by VTK. If turned off the
|
|
* raw multitouch events will be passed down.
|
|
*/
|
|
vtkSetMacro(RecognizeGestures, bool);
|
|
vtkGetMacro(RecognizeGestures, bool);
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* When handling gestures you can query this value to
|
|
* determine how many pointers are down for the gesture
|
|
* this is useful for pan gestures for example
|
|
*/
|
|
vtkGetMacro(PointersDownCount, int);
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Most multitouch systems use persistent contact/pointer ids to
|
|
* track events/motion during multitouch events. We keep an array
|
|
* that maps these system dependent contact ids to our pointer index
|
|
* These functions return -1 if the ID is not found or if there
|
|
* is no more room for contacts
|
|
*/
|
|
void ClearContact(size_t contactID);
|
|
int GetPointerIndexForContact(size_t contactID);
|
|
int GetPointerIndexForExistingContact(size_t contactID);
|
|
bool IsPointerIndexSet(int i);
|
|
void ClearPointerIndex(int i);
|
|
//@}
|
|
|
|
protected:
|
|
vtkRenderWindowInteractor();
|
|
~vtkRenderWindowInteractor() override;
|
|
|
|
vtkRenderWindow* RenderWindow;
|
|
vtkHardwareWindow* HardwareWindow;
|
|
vtkInteractorObserver* InteractorStyle;
|
|
|
|
// Used as a helper object to pick instances of vtkProp
|
|
vtkAbstractPicker* Picker;
|
|
vtkPickingManager* PickingManager;
|
|
|
|
bool Done; // is the event loop done running
|
|
|
|
/**
|
|
* Create default pickingManager. Used to create one when none is specified.
|
|
* Default is an instance of vtkPickingManager.
|
|
*/
|
|
virtual vtkPickingManager* CreateDefaultPickingManager();
|
|
|
|
int Initialized;
|
|
int Enabled;
|
|
bool EnableRender;
|
|
int Style;
|
|
vtkTypeBool LightFollowCamera;
|
|
int ActorMode;
|
|
double DesiredUpdateRate;
|
|
double StillUpdateRate;
|
|
|
|
// Event information
|
|
int AltKey;
|
|
int ControlKey;
|
|
int ShiftKey;
|
|
char KeyCode;
|
|
double Rotation;
|
|
double LastRotation;
|
|
double Scale;
|
|
double LastScale;
|
|
double Translation[2];
|
|
double LastTranslation[2];
|
|
int RepeatCount;
|
|
char* KeySym;
|
|
int EventPosition[2];
|
|
int LastEventPosition[2];
|
|
int EventSize[2];
|
|
int Size[2];
|
|
int TimerEventId;
|
|
int TimerEventType;
|
|
int TimerEventDuration;
|
|
int TimerEventPlatformId;
|
|
|
|
int EventPositions[VTKI_MAX_POINTERS][2];
|
|
int LastEventPositions[VTKI_MAX_POINTERS][2];
|
|
int PointerIndex;
|
|
|
|
size_t PointerIndexLookup[VTKI_MAX_POINTERS];
|
|
|
|
// control the fly to
|
|
int NumberOfFlyFrames;
|
|
double Dolly;
|
|
|
|
/**
|
|
* These methods allow the interactor to control which events are
|
|
* processed. When the GrabFocus() method is called, then only events that
|
|
* the supplied vtkCommands have registered are invoked. (This method is
|
|
* typically used by widgets, i.e., subclasses of vtkInteractorObserver, to
|
|
* grab events once an event sequence begins.) Note that the friend
|
|
* declaration is done here to avoid doing so in the superclass vtkObject.
|
|
*/
|
|
friend class vtkInteractorObserver;
|
|
void GrabFocus(vtkCommand* mouseEvents, vtkCommand* keypressEvents = nullptr)
|
|
{
|
|
this->Superclass::InternalGrabFocus(mouseEvents, keypressEvents);
|
|
}
|
|
void ReleaseFocus() { this->Superclass::InternalReleaseFocus(); }
|
|
|
|
/**
|
|
* Widget mediators are used to resolve contention for cursors and other resources.
|
|
*/
|
|
vtkObserverMediator* ObserverMediator;
|
|
|
|
// Timer related members
|
|
friend struct vtkTimerStruct;
|
|
vtkTimerIdMap* TimerMap; // An internal, PIMPLd map of timers and associated attributes
|
|
unsigned long TimerDuration; // in milliseconds
|
|
//@{
|
|
/**
|
|
* Internal methods for creating and destroying timers that must be
|
|
* implemented by subclasses. InternalCreateTimer() returns a
|
|
* platform-specific timerId and InternalDestroyTimer() returns
|
|
* non-zero value on success.
|
|
*/
|
|
virtual int InternalCreateTimer(int timerId, int timerType, unsigned long duration);
|
|
virtual int InternalDestroyTimer(int platformTimerId);
|
|
int GetCurrentTimerId();
|
|
//@}
|
|
|
|
// Force the interactor to handle the Start() event loop, ignoring any
|
|
// overrides. (Overrides are registered by observing StartEvent on the
|
|
// interactor.)
|
|
int HandleEventLoop;
|
|
|
|
/**
|
|
* Run the event loop (does not return until TerminateApp is called).
|
|
*/
|
|
virtual void StartEventLoop() {}
|
|
|
|
bool UseTDx; // 3DConnexion device.
|
|
|
|
// when recognizing gestures VTK will take multitouch events
|
|
// if it receives them and convert them to gestures
|
|
bool RecognizeGestures;
|
|
int PointersDownCount;
|
|
int PointersDown[VTKI_MAX_POINTERS];
|
|
virtual void RecognizeGesture(vtkCommand::EventIds);
|
|
int StartingEventPositions[VTKI_MAX_POINTERS][2];
|
|
vtkCommand::EventIds CurrentGesture;
|
|
|
|
private:
|
|
vtkRenderWindowInteractor(const vtkRenderWindowInteractor&) = delete;
|
|
void operator=(const vtkRenderWindowInteractor&) = delete;
|
|
};
|
|
|
|
#endif
|