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