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 "vtkCallbackCommand.h"
17 #include "vtkEvent.h"
18 #include "vtkObjectFactory.h"
19 #include "vtkRenderWindowInteractor.h"
20 #include "vtkWidgetCallbackMapper.h"
21 #include "vtkWidgetEvent.h"
22 #include "vtkWidgetEventTranslator.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(
36     vtkCommand::LeftButtonPressEvent, vtkWidgetEvent::Move, this, vtkHoverWidget::MoveAction);
37   this->CallbackMapper->SetCallbackMethod(
38     vtkCommand::MiddleButtonPressEvent, vtkWidgetEvent::Move, this, vtkHoverWidget::MoveAction);
39   this->CallbackMapper->SetCallbackMethod(
40     vtkCommand::RightButtonPressEvent, vtkWidgetEvent::Move, this, vtkHoverWidget::MoveAction);
41   this->CallbackMapper->SetCallbackMethod(
42     vtkCommand::MouseWheelForwardEvent, vtkWidgetEvent::Move, this, vtkHoverWidget::MoveAction);
43   this->CallbackMapper->SetCallbackMethod(
44     vtkCommand::MouseWheelBackwardEvent, vtkWidgetEvent::Move, this, vtkHoverWidget::MoveAction);
45   this->CallbackMapper->SetCallbackMethod(
46     vtkCommand::MouseMoveEvent, vtkWidgetEvent::Move, this, vtkHoverWidget::MoveAction);
47   this->CallbackMapper->SetCallbackMethod(
48     vtkCommand::TimerEvent, vtkWidgetEvent::TimedOut, this, vtkHoverWidget::HoverAction);
49   this->CallbackMapper->SetCallbackMethod(vtkCommand::KeyPressEvent, vtkEvent::AnyModifier, 13, 1,
50     "Return", vtkWidgetEvent::Select, this, vtkHoverWidget::SelectAction);
51 }
52 
53 //------------------------------------------------------------------------------
54 vtkHoverWidget::~vtkHoverWidget() = default;
55 
56 //------------------------------------------------------------------------------
SetEnabled(int enabling)57 void vtkHoverWidget::SetEnabled(int enabling)
58 {
59   if (enabling) //----------------
60   {
61     vtkDebugMacro(<< "Enabling widget");
62 
63     if (this->Enabled) // already enabled, just return
64     {
65       return;
66     }
67 
68     if (!this->Interactor)
69     {
70       vtkErrorMacro(<< "The interactor must be set prior to enabling the widget");
71       return;
72     }
73 
74     // We're ready to enable
75     this->Enabled = 1;
76 
77     // listen for the events found in the EventTranslator
78     this->EventTranslator->AddEventsToInteractor(
79       this->Interactor, this->EventCallbackCommand, this->Priority);
80 
81     // Start off the timer
82     this->TimerId = this->Interactor->CreateRepeatingTimer(this->TimerDuration);
83     this->WidgetState = vtkHoverWidget::Timing;
84 
85     this->InvokeEvent(vtkCommand::EnableEvent, nullptr);
86   }
87 
88   else // disabling------------------
89   {
90     vtkDebugMacro(<< "Disabling widget");
91 
92     if (!this->Enabled) // already disabled, just return
93     {
94       return;
95     }
96 
97     this->Enabled = 0;
98     this->Interactor->RemoveObserver(this->EventCallbackCommand);
99     this->InvokeEvent(vtkCommand::DisableEvent, nullptr);
100   }
101 }
102 
103 //------------------------------------------------------------------------------
MoveAction(vtkAbstractWidget * w)104 void vtkHoverWidget::MoveAction(vtkAbstractWidget* w)
105 {
106   vtkHoverWidget* self = reinterpret_cast<vtkHoverWidget*>(w);
107   if (self->WidgetState == vtkHoverWidget::Timing)
108   {
109     self->Interactor->DestroyTimer(self->TimerId);
110   }
111   else // we have already timed out, on this move we begin retiming
112   {
113     self->WidgetState = vtkHoverWidget::Timing;
114     self->SubclassEndHoverAction();
115     self->InvokeEvent(vtkCommand::EndInteractionEvent, nullptr);
116   }
117   self->TimerId = self->Interactor->CreateRepeatingTimer(self->TimerDuration);
118 }
119 
120 //------------------------------------------------------------------------------
HoverAction(vtkAbstractWidget * w)121 void vtkHoverWidget::HoverAction(vtkAbstractWidget* w)
122 {
123   vtkHoverWidget* self = reinterpret_cast<vtkHoverWidget*>(w);
124   int timerId = *(reinterpret_cast<int*>(self->CallData));
125 
126   // If this is the timer event we are waiting for...
127   if (timerId == self->TimerId && self->WidgetState == vtkHoverWidget::Timing)
128   {
129     self->Interactor->DestroyTimer(self->TimerId);
130     self->WidgetState = vtkHoverWidget::TimedOut;
131     self->SubclassHoverAction();
132     self->InvokeEvent(vtkCommand::TimerEvent, nullptr);
133     self->EventCallbackCommand->SetAbortFlag(1); // no one else gets this timer
134   }
135 }
136 
137 //------------------------------------------------------------------------------
SelectAction(vtkAbstractWidget * w)138 void vtkHoverWidget::SelectAction(vtkAbstractWidget* w)
139 {
140   vtkHoverWidget* self = reinterpret_cast<vtkHoverWidget*>(w);
141 
142   // If widget is hovering we grab the selection event
143   if (self->WidgetState == vtkHoverWidget::TimedOut)
144   {
145     self->SubclassSelectAction();
146     self->InvokeEvent(vtkCommand::WidgetActivateEvent, nullptr);
147     self->EventCallbackCommand->SetAbortFlag(1); // no one else gets this event
148   }
149 }
150 
151 //------------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)152 void vtkHoverWidget::PrintSelf(ostream& os, vtkIndent indent)
153 {
154   this->Superclass::PrintSelf(os, indent);
155 
156   os << indent << "Timer Duration: " << this->TimerDuration << "\n";
157 }
158