]> Creatis software - cpPlugins.git/blob - appli/examples/example_Test_DoubleClick.cxx
double click example updates
[cpPlugins.git] / appli / examples / example_Test_DoubleClick.cxx
1 #include <vtkRenderWindow.h>
2 #include <vtkRenderWindowInteractor.h>
3 #include <vtkRenderer.h>
4 #include <vtkSphereSource.h>
5 #include <vtkPolyDataMapper.h>
6 #include <vtkActor.h>
7 #include <vtkSmartPointer.h>
8 #include <vtkPointPicker.h>
9 #include <vtkCamera.h>
10 #include <vtkInteractorStyleTrackballCamera.h>
11 #include <vtkObjectFactory.h>
12
13 #ifdef WIN32
14 #include <windows.h>
15 #else
16 #endif
17
18 #if __cplusplus > 199711L
19 #include <chrono>
20 #endif
21
22 // Define interaction style
23 class MouseInteractorStyleDoubleClick : public vtkInteractorStyleTrackballCamera
24 {
25 public:
26
27         static MouseInteractorStyleDoubleClick* New();
28         vtkTypeMacro(MouseInteractorStyleDoubleClick, vtkInteractorStyleTrackballCamera);
29
30         MouseInteractorStyleDoubleClick() : NumberOfClicks(0), ResetPixelDistance(5), DoubleClickTolerance(1000)
31         {
32                 this->PreviousPosition[0] = 0;
33                 this->PreviousPosition[1] = 0;
34 #ifdef WIN32
35                 this->DoubleClickTolerance = GetDoubleClickTime();
36 #else
37                 // I dont have any idea if this has an equivalent for linux
38                 //this->DoubleClickTolerance = GetDoubleClickTime();
39 #endif
40         }
41
42         virtual void OnLeftButtonDown()
43         {
44                 //std::cout << "Pressed left mouse button." << std::endl;
45                 this->NumberOfClicks++;
46
47                 if (this->NumberOfClicks > 1)
48                 {
49                         this->LastClickTime = this->CurrentClickTime;
50 #if __cplusplus <= 199711L
51                         this->CurrentClickTime = time(0) * 1000;
52 #else
53                         this->CurrentClickTime = std::chrono::duration_cast<std::chrono::milliseconds>(
54                                 std::chrono::system_clock::now().time_since_epoch()
55                                 );
56 #endif
57
58                 }
59                 else
60                 {
61 #if __cplusplus <= 199711L
62                         this->CurrentClickTime = time(0) * 1000;
63 #else
64                         this->CurrentClickTime = std::chrono::duration_cast<std::chrono::milliseconds>(
65                                 std::chrono::system_clock::now().time_since_epoch()
66                                 );
67
68 #endif
69                 }
70
71                 //std::cout << "NumberOfClicks = " << this->NumberOfClicks << std::endl;
72                 int pickPosition[2];
73                 this->GetInteractor()->GetEventPosition(pickPosition);
74
75                 int xdist = pickPosition[0] - this->PreviousPosition[0];
76                 int ydist = pickPosition[1] - this->PreviousPosition[1];
77
78                 this->PreviousPosition[0] = pickPosition[0];
79                 this->PreviousPosition[1] = pickPosition[1];
80
81                 int moveDistance = (int)sqrt((double)(xdist*xdist + ydist*ydist));
82
83                 // Reset numClicks - If mouse moved further than resetPixelDistance
84                 if (moveDistance > this->ResetPixelDistance)
85                 {
86                         this->NumberOfClicks = 1;
87                 }
88
89
90                 if (this->NumberOfClicks == 2)
91                 {
92                         double  seconds;
93 #if __cplusplus <= 199711L
94                         seconds = difftime(this->CurrentClickTime, this->LastClickTime);
95 #else
96                         seconds = this->CurrentClickTime - this->LastClickTime;
97 #endif
98                         
99                         if (seconds <= this->DoubleClickTolerance)
100                         {
101                                 std::cout << "Double clicked. with " << seconds << " of diference" << std::endl;
102                                 this->NumberOfClicks = 0;
103                         }
104                         else
105                         {
106                                 std::cout << "Too slow to be considered as a double click" << std::endl;
107                                 this->NumberOfClicks = 1;
108                         }
109                 }
110                 // forward events
111                 vtkInteractorStyleTrackballCamera::OnLeftButtonDown();
112         }
113
114
115
116 private:
117         unsigned int NumberOfClicks;
118         int PreviousPosition[2];
119         int ResetPixelDistance;
120         double DoubleClickTolerance; // time in miliseconds
121
122 #if __cplusplus <= 199711L      
123         time_t LastClickTime;
124         time_t CurrentClickTime;
125 #else
126         std::chrono::milliseconds LastClickTime;
127         std::chrono::milliseconds CurrentClickTime;
128 #endif
129 };
130 vtkStandardNewMacro(MouseInteractorStyleDoubleClick);
131
132 int main(int, char *[])
133 {
134         vtkSmartPointer<vtkSphereSource> sphereSource =
135                 vtkSmartPointer<vtkSphereSource>::New();
136         sphereSource->SetCenter(0.0, 0.0, 0.0);
137         sphereSource->SetRadius(5.0);
138         sphereSource->Update();
139
140         vtkSmartPointer<vtkPolyDataMapper> mapper =
141                 vtkSmartPointer<vtkPolyDataMapper>::New();
142         mapper->SetInputConnection(sphereSource->GetOutputPort());
143
144         vtkSmartPointer<vtkActor> actor =
145                 vtkSmartPointer<vtkActor>::New();
146         actor->SetMapper(mapper);
147
148         vtkSmartPointer<vtkRenderer> renderer =
149                 vtkSmartPointer<vtkRenderer>::New();
150         renderer->SetBackground(1, 1, 1); // Background color white
151         renderer->AddActor(actor);
152
153         vtkSmartPointer<vtkRenderWindow> renderWindow =
154                 vtkSmartPointer<vtkRenderWindow>::New();
155         renderWindow->AddRenderer(renderer);
156
157         vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
158                 vtkSmartPointer<vtkRenderWindowInteractor>::New();
159         renderWindowInteractor->SetRenderWindow(renderWindow);
160
161         vtkSmartPointer<MouseInteractorStyleDoubleClick> style =
162                 vtkSmartPointer<MouseInteractorStyleDoubleClick>::New();
163         renderWindowInteractor->SetInteractorStyle(style);
164
165         renderWindowInteractor->Initialize();
166         renderWindowInteractor->Start();
167
168         return EXIT_SUCCESS;
169 }