/*========================================================================= 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