1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkHoverWidget.cxx
5 
6   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7   All rights reserved.
8   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10      This software is distributed WITHOUT ANY WARRANTY; without even
11      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12      PURPOSE.  See the above copyright notice for more information.
13 
14 =========================================================================*/
15 #include "vtkHoverWidget.h"
16 #include "vtkRenderWindowInteractor.h"
17 #include "vtkWidgetCallbackMapper.h"
18 #include "vtkWidgetEvent.h"
19 #include "vtkWidgetEventTranslator.h"
20 #include "vtkObjectFactory.h"
21 #include "vtkCallbackCommand.h"
22 #include "vtkEvent.h"
23 
24 vtkStandardNewMacro(vtkHoverWidget);
25 
26 //-------------------------------------------------------------------------
vtkHoverWidget()27 vtkHoverWidget::vtkHoverWidget()
28 {
29   this->WidgetState = Start;
30   this->TimerDuration = 250;
31 
32   // Okay, define the events for this widget. Note that we look for extra events
33   // (like button press) because without it the hover widget thinks nothing has changed
34   // and doesn't begin retiming.
35   this->CallbackMapper->SetCallbackMethod(vtkCommand::LeftButtonPressEvent,
36                                           vtkWidgetEvent::Move,
37                                           this, vtkHoverWidget::MoveAction);
38   this->CallbackMapper->SetCallbackMethod(vtkCommand::MiddleButtonPressEvent,
39                                           vtkWidgetEvent::Move,
40                                           this, vtkHoverWidget::MoveAction);
41   this->CallbackMapper->SetCallbackMethod(vtkCommand::RightButtonPressEvent,
42                                           vtkWidgetEvent::Move,
43                                           this, vtkHoverWidget::MoveAction);
44   this->CallbackMapper->SetCallbackMethod(vtkCommand::MouseWheelForwardEvent,
45                                           vtkWidgetEvent::Move,
46                                           this, vtkHoverWidget::MoveAction);
47   this->CallbackMapper->SetCallbackMethod(vtkCommand::MouseWheelBackwardEvent,
48                                           vtkWidgetEvent::Move,
49                                           this, vtkHoverWidget::MoveAction);
50   this->CallbackMapper->SetCallbackMethod(vtkCommand::MouseMoveEvent,
51                                           vtkWidgetEvent::Move,
52                                           this, vtkHoverWidget::MoveAction);
53   this->CallbackMapper->SetCallbackMethod(vtkCommand::TimerEvent,
54                                           vtkWidgetEvent::TimedOut,
55                                           this, vtkHoverWidget::HoverAction);
56   this->CallbackMapper->SetCallbackMethod(vtkCommand::KeyPressEvent,
57                                           vtkEvent::AnyModifier, 13, 1, "Return",
58                                           vtkWidgetEvent::Select,
59                                           this, vtkHoverWidget::SelectAction);
60 }
61 
62 //-------------------------------------------------------------------------
63 vtkHoverWidget::~vtkHoverWidget() = default;
64 
65 //----------------------------------------------------------------------
SetEnabled(int enabling)66 void vtkHoverWidget::SetEnabled(int enabling)
67 {
68   if ( enabling ) //----------------
69   {
70     vtkDebugMacro(<<"Enabling widget");
71 
72     if ( this->Enabled ) //already enabled, just return
73     {
74       return;
75     }
76 
77     if ( ! this->Interactor )
78     {
79       vtkErrorMacro(<<"The interactor must be set prior to enabling the widget");
80       return;
81     }
82 
83     // We're ready to enable
84     this->Enabled = 1;
85 
86     // listen for the events found in the EventTranslator
87     this->EventTranslator->AddEventsToInteractor(this->Interactor,
88                                                  this->EventCallbackCommand,this->Priority);
89 
90     // Start off the timer
91     this->TimerId = this->Interactor->CreateRepeatingTimer(this->TimerDuration);
92     this->WidgetState = vtkHoverWidget::Timing;
93 
94     this->InvokeEvent(vtkCommand::EnableEvent,nullptr);
95   }
96 
97   else //disabling------------------
98   {
99     vtkDebugMacro(<<"Disabling widget");
100 
101     if ( ! this->Enabled ) //already disabled, just return
102     {
103       return;
104     }
105 
106     this->Enabled = 0;
107     this->Interactor->RemoveObserver(this->EventCallbackCommand);
108     this->InvokeEvent(vtkCommand::DisableEvent,nullptr);
109   }
110 }
111 
112 //-------------------------------------------------------------------------
MoveAction(vtkAbstractWidget * w)113 void vtkHoverWidget::MoveAction(vtkAbstractWidget *w)
114 {
115   vtkHoverWidget *self = reinterpret_cast<vtkHoverWidget*>(w);
116   if ( self->WidgetState == vtkHoverWidget::Timing )
117   {
118     self->Interactor->DestroyTimer(self->TimerId);
119   }
120   else //we have already timed out, on this move we begin retiming
121   {
122     self->WidgetState = vtkHoverWidget::Timing;
123     self->SubclassEndHoverAction();
124     self->InvokeEvent(vtkCommand::EndInteractionEvent,nullptr);
125   }
126   self->TimerId = self->Interactor->CreateRepeatingTimer(self->TimerDuration);
127 }
128 
129 //-------------------------------------------------------------------------
HoverAction(vtkAbstractWidget * w)130 void vtkHoverWidget::HoverAction(vtkAbstractWidget *w)
131 {
132   vtkHoverWidget *self = reinterpret_cast<vtkHoverWidget*>(w);
133   int timerId = *(reinterpret_cast<int*>(self->CallData));
134 
135   // If this is the timer event we are waiting for...
136   if ( timerId == self->TimerId && self->WidgetState == vtkHoverWidget::Timing )
137   {
138     self->Interactor->DestroyTimer(self->TimerId);
139     self->WidgetState = vtkHoverWidget::TimedOut;
140     self->SubclassHoverAction();
141     self->InvokeEvent(vtkCommand::TimerEvent,nullptr);
142     self->EventCallbackCommand->SetAbortFlag(1); //no one else gets this timer
143   }
144 }
145 
146 //-------------------------------------------------------------------------
SelectAction(vtkAbstractWidget * w)147 void vtkHoverWidget::SelectAction(vtkAbstractWidget *w)
148 {
149   vtkHoverWidget *self = reinterpret_cast<vtkHoverWidget*>(w);
150 
151   // If widget is hovering we grab the selection event
152   if ( self->WidgetState == vtkHoverWidget::TimedOut )
153   {
154     self->SubclassSelectAction();
155     self->InvokeEvent(vtkCommand::WidgetActivateEvent,nullptr);
156     self->EventCallbackCommand->SetAbortFlag(1); //no one else gets this event
157   }
158 }
159 
160 //-------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)161 void vtkHoverWidget::PrintSelf(ostream& os, vtkIndent indent)
162 {
163   this->Superclass::PrintSelf(os,indent);
164 
165   os << indent << "Timer Duration: " << this->TimerDuration << "\n";
166 }
167