1
1
/*
2
- * Copyright 2019 University of Toronto
2
+ * Copyright 2019-2022 University of Toronto
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
13
13
* See the License for the specific language governing permissions and
14
14
* limitations under the License.
15
15
*
16
- * Authors: Mario Badr, Sameh Attia and Tanner Young-Schultz
16
+ * Authors: Mario Badr, Sameh Attia, Tanner Young-Schultz and Vaughn Betz
17
17
*/
18
18
19
19
#include " ezgl/callback.hpp"
20
20
21
21
namespace ezgl {
22
22
23
23
/* *
24
- * Provides file wide variables to support mouse panning
24
+ * Provides file wide variables to support mouse panning. We store some
25
+ * state about mouse panning so we can determine when click & drag mouse
26
+ * panning (handled by ezgl) is happening vs. simple mouse clicks (sent to
27
+ * user mouse click callback).
25
28
*/
26
29
struct mouse_pan {
27
30
/* *
@@ -33,10 +36,15 @@ struct mouse_pan {
33
36
*/
34
37
int last_panning_event_time = 0 ;
35
38
/* *
36
- * The old x and y positions of the mouse pointer
39
+ * The old x and y positions of the mouse pointer, in the previous pan
40
+ * event.
37
41
*/
38
42
double prev_x = 0 ;
39
43
double prev_y = 0 ;
44
+
45
+ /* Has any panning happened since the mouse button was held down?
46
+ */
47
+ bool has_panned = false ;
40
48
} g_mouse_pan;
41
49
42
50
gboolean press_key (GtkWidget *, GdkEventKey *event, gpointer data)
@@ -64,11 +72,12 @@ gboolean press_mouse(GtkWidget *, GdkEventButton *event, gpointer data)
64
72
65
73
if (event->type == GDK_BUTTON_PRESS) {
66
74
67
- // Check for mouse press to support dragging
75
+ // Check for mouse press to support dragging.
68
76
if (event->button == PANNING_MOUSE_BUTTON) {
69
77
g_mouse_pan.panning_mouse_button_pressed = true ;
70
78
g_mouse_pan.prev_x = event->x ;
71
79
g_mouse_pan.prev_y = event->y ;
80
+ g_mouse_pan.has_panned = false ; /* Haven't shifted the view yet */
72
81
}
73
82
// Call the user-defined mouse press callback if defined
74
83
// The user-defined callback is called for mouse buttons other than
@@ -97,8 +106,10 @@ gboolean release_mouse(GtkWidget *, GdkEventButton *event, gpointer data)
97
106
if (event->button == PANNING_MOUSE_BUTTON) {
98
107
g_mouse_pan.panning_mouse_button_pressed = false ;
99
108
100
- // Call the user-defined mouse press callback for the PANNING_MOUSE_BUTTON button only if no panning occurs
101
- if (event->x == g_mouse_pan.prev_x && event->y == g_mouse_pan.prev_y && application->mouse_press_callback != nullptr ) {
109
+ // Call the user-defined mouse press callback for the PANNING_MOUSE_BUTTON button only if no panning occurs.
110
+ // This lets the user use one mouse button for both click-and-drag
111
+ // panning and simple clicking.
112
+ if (!g_mouse_pan.has_panned && application->mouse_press_callback != nullptr ) {
102
113
ezgl::point2d const widget_coordinates (event->x , event->y );
103
114
104
115
std::string main_canvas_id = application->get_main_canvas_id ();
@@ -107,6 +118,7 @@ gboolean release_mouse(GtkWidget *, GdkEventButton *event, gpointer data)
107
118
ezgl::point2d const world = canvas->get_camera ().widget_to_world (widget_coordinates);
108
119
application->mouse_press_callback (application, event, world.x , world.y );
109
120
}
121
+ g_mouse_pan.has_panned = false ; /* Done pan; reset for next time */
110
122
}
111
123
}
112
124
@@ -121,9 +133,15 @@ gboolean move_mouse(GtkWidget *, GdkEventButton *event, gpointer data)
121
133
122
134
// Check if the mouse button is pressed to support dragging
123
135
if (g_mouse_pan.panning_mouse_button_pressed ) {
124
- // drop this panning event if we have just served another one
125
- if (gtk_get_current_event_time () - g_mouse_pan.last_panning_event_time < 100 )
126
- return true ;
136
+ // Code below drops a panning event if we served anothe one
137
+ // less than 100 ms. I believe it was intended to avoid having panning
138
+ // fall behind and queue up many events if redraws were slow. However,
139
+ // it is not necessary on the UG machines (debian) in person, or over
140
+ // VNC or on a VM and it has the bad effect of limiting refresh to 10 Hz.
141
+ // Commenting it out for now and will delete if there
142
+ // are no reported issues. - VB
143
+ // if(gtk_get_current_event_time() - g_mouse_pan.last_panning_event_time < 100)
144
+ // return true;
127
145
128
146
g_mouse_pan.last_panning_event_time = gtk_get_current_event_time ();
129
147
@@ -143,6 +161,7 @@ gboolean move_mouse(GtkWidget *, GdkEventButton *event, gpointer data)
143
161
144
162
// Flip the delta x to avoid inverted dragging
145
163
translate (canvas, -dx, -dy);
164
+ g_mouse_pan.has_panned = true ;
146
165
}
147
166
// Else call the user-defined mouse move callback if defined
148
167
else if (application->mouse_move_callback != nullptr ) {
@@ -283,4 +302,4 @@ gboolean press_proceed(GtkWidget *, gpointer data)
283
302
284
303
return TRUE ;
285
304
}
286
- }
305
+ }
0 commit comments