1 // This is for the simulated jog/shuttle control on the main window, but it
2 // can also be controlled by jog/shuttle controllers that exist in the
3 // physical world (which are handled in ADM_jogshuttle.cpp).
4
5 #include <gtk/gtk.h>
6 #include "jogshuttle.h"
7
8 #define JOG_SHUTTLE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), JOG_TYPE_SHUTTLE, JogShuttlePrivate))
9
10 G_DEFINE_TYPE (JogShuttle, jog_shuttle, GTK_TYPE_DRAWING_AREA);
11
12 static gboolean jog_shuttle_expose (GtkWidget *wheel, GdkEventExpose *event);
13 static gboolean jog_shuttle_button_press (GtkWidget *wheel, GdkEventButton *event);
14 static gboolean jog_shuttle_button_release (GtkWidget *wheel, GdkEventButton *event);
15 static gboolean jog_shuttle_motion_notify (GtkWidget *wheel, GdkEventMotion *event);
16
17 typedef struct _JogShuttlePrivate JogShuttlePrivate;
18
19 struct _JogShuttlePrivate
20 {
21 gfloat pos[6];
22 gboolean pressed;
23 gboolean external_control;
24 gfloat start;
25 gfloat offset;
26 gfloat value;
27 };
28
29 enum
30 {
31 VALUE_CHANGED,
32 LAST_SIGNAL
33 };
34
35 static guint jog_shuttle_signals[LAST_SIGNAL] = { 0 };
36
37 static void
jog_shuttle_class_init(JogShuttleClass * class)38 jog_shuttle_class_init (JogShuttleClass *class)
39 {
40 #if 0
41 GObjectClass *obj_class;
42 GtkWidgetClass *widget_class;
43
44 obj_class = G_OBJECT_CLASS (class);
45 widget_class = GTK_WIDGET_CLASS (class);
46
47 widget_class->button_press_event = jog_shuttle_button_press;
48 widget_class->button_release_event = jog_shuttle_button_release;
49 widget_class->motion_notify_event = jog_shuttle_motion_notify;
50 widget_class->expose_event = jog_shuttle_expose;
51
52 jog_shuttle_signals[VALUE_CHANGED] = g_signal_new (
53 "value-changed",
54 G_OBJECT_CLASS_TYPE (obj_class),
55 G_SIGNAL_RUN_FIRST,
56 G_STRUCT_OFFSET (JogShuttleClass, value_changed),
57 NULL, NULL,
58 gtk_marshal_NONE__NONE,
59 G_TYPE_NONE, 0);
60
61 g_type_class_add_private (obj_class, sizeof (JogShuttlePrivate));
62 #endif
63 }
64
65 static void
jog_shuttle_init(JogShuttle * wheel)66 jog_shuttle_init (JogShuttle *wheel)
67 {
68 #if 0
69 JogShuttlePrivate *priv;
70 priv = JOG_SHUTTLE_GET_PRIVATE (wheel);
71
72 priv->pressed = FALSE;
73 priv->external_control = FALSE;
74 priv->offset = 0;
75 priv->value = 0;
76 gtk_widget_add_events (GTK_WIDGET (wheel), GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK);
77 #endif
78 }
79
reset(GtkWidget * wheel)80 static void reset(GtkWidget *wheel)
81 {
82 #if 0
83 JogShuttlePrivate *priv;
84 priv = JOG_SHUTTLE_GET_PRIVATE (wheel);
85 gfloat width = wheel->allocation.width;
86
87 int i;
88 for (i=0; i<6; i++)
89 {
90 priv->pos[i] = width / 6 * i;
91 }
92 #endif
93 }
94
95 static gboolean
jog_shuttle_button_press(GtkWidget * wheel,GdkEventButton * event)96 jog_shuttle_button_press (GtkWidget *wheel, GdkEventButton *event)
97 {
98 #if 0
99 JogShuttlePrivate *priv;
100 priv = JOG_SHUTTLE_GET_PRIVATE (wheel);
101
102 priv->start = event->x;
103 priv->pressed = TRUE;
104 #endif
105 return FALSE;
106 }
107
108 static gboolean
jog_shuttle_button_release(GtkWidget * wheel,GdkEventButton * event)109 jog_shuttle_button_release (GtkWidget *wheel, GdkEventButton *event)
110 {
111 #if 0
112 JogShuttlePrivate *priv;
113 priv = JOG_SHUTTLE_GET_PRIVATE (wheel);
114
115 priv->pressed = FALSE;
116 priv->offset = 0;
117 GtkWidget *widget;
118 GdkRegion *region;
119
120 widget = GTK_WIDGET (wheel);
121
122 if (!widget->window) return;
123
124 region = gdk_drawable_get_clip_region (widget->window);
125 gdk_window_invalidate_region (widget->window, region, TRUE);
126 gdk_window_process_updates (widget->window, TRUE);
127
128 gdk_region_destroy (region);
129 #endif
130
131 return FALSE;
132 }
133
emit_value_changed_signal(JogShuttle * wheel)134 static emit_value_changed_signal (JogShuttle *wheel)
135 {
136 #if 0
137 g_signal_emit (wheel, jog_shuttle_signals[VALUE_CHANGED], 0);
138 #endif
139 }
140
141 static gboolean
jog_shuttle_motion_notify(GtkWidget * wheel,GdkEventMotion * event)142 jog_shuttle_motion_notify (GtkWidget *wheel, GdkEventMotion *event)
143 {
144 #if 0
145 JogShuttlePrivate *priv;
146 priv = JOG_SHUTTLE_GET_PRIVATE (wheel);
147
148 gfloat width = wheel->allocation.width;
149 gfloat height = wheel->allocation.height;
150
151 if (!priv->pressed) return TRUE;
152 GtkWidget *widget;
153 GdkRegion *region;
154
155 widget = GTK_WIDGET (wheel);
156
157 priv->offset = event->x - priv->start;
158 priv->start = event->x;
159
160 if (!widget->window) return;
161
162 if ((priv->offset+priv->pos[3]) > width || (priv->offset+priv->pos[3]) < 0) return;
163
164 region = gdk_drawable_get_clip_region (widget->window);
165 gdk_window_invalidate_region (widget->window, region, TRUE);
166 gdk_window_process_updates (widget->window, TRUE);
167
168 gdk_region_destroy (region);
169 #endif
170 }
171
172 static void
draw_borders(GtkWidget * wheel,cairo_t * cr)173 draw_borders (GtkWidget *wheel, cairo_t *cr)
174 {
175 #if 0
176 gfloat width = wheel->allocation.width;
177 gfloat height = wheel->allocation.height;
178 gfloat middle = width/2.0;
179
180 cairo_set_line_width (cr, 1);
181 cairo_set_source_rgb (cr, 0.53, 0.53, 0.53);
182 cairo_line_to (cr, 1, 0);
183 cairo_line_to (cr, width-1, 0);
184 cairo_stroke (cr);
185 cairo_line_to (cr, 1, height-1);
186 cairo_line_to (cr, width-1, height-1);
187 cairo_stroke (cr);
188 cairo_line_to (cr, 1, 1);
189 cairo_line_to (cr, 1, height-1);
190 cairo_stroke (cr);
191 cairo_line_to (cr, width, 1);
192 cairo_line_to (cr, width, height-1);
193 cairo_stroke (cr);
194
195 cairo_pattern_t *cp1 = cairo_pattern_create_linear (1, 1, middle-6, 1);
196 cairo_pattern_add_color_stop_rgb (cp1, 0, 0.00, 0.00, 0.00);
197 cairo_pattern_add_color_stop_rgb (cp1, 1, 0.98, 0.98, 0.98);
198 cairo_pattern_t *cp2 = cairo_pattern_create_linear (width-1, 1, middle+6, 1);
199 cairo_pattern_add_color_stop_rgb (cp2, 0, 0.00, 0.00, 0.00);
200 cairo_pattern_add_color_stop_rgb (cp2, 1, 0.98, 0.98, 0.98);
201 cairo_pattern_t *cp3 = cairo_pattern_create_linear (1, height-2, middle-6, height-2);
202 cairo_pattern_add_color_stop_rgb (cp3, 1, 0.98, 0.98, 0.98);
203 cairo_pattern_add_color_stop_rgb (cp3, 0, 0.00, 0.00, 0.00);
204 cairo_pattern_t *cp4 = cairo_pattern_create_linear (width-1, height-2, middle+6, height-2);
205 cairo_pattern_add_color_stop_rgb (cp4, 1, 0.98, 0.98, 0.98);
206 cairo_pattern_add_color_stop_rgb (cp4, 0, 0.00, 0.00, 0.00);
207
208 cairo_set_line_width (cr, 1);
209 cairo_set_source (cr, cp1);
210 cairo_line_to (cr, 1, 1);
211 cairo_line_to (cr, middle, 1);
212 cairo_stroke (cr);
213 cairo_set_source (cr, cp3);
214 cairo_line_to (cr, 1, height-2);
215 cairo_line_to (cr, middle, height-2);
216 cairo_stroke (cr);
217 cairo_set_source (cr, cp2);
218 cairo_line_to (cr, middle, 1);
219 cairo_line_to (cr, width-1, 1);
220 cairo_stroke (cr);
221 cairo_set_source (cr, cp4);
222 cairo_line_to (cr, middle, height-2);
223 cairo_line_to (cr, width-1, height-2);
224 cairo_stroke (cr);
225 cairo_pattern_destroy(cp1);
226 cairo_pattern_destroy(cp2);
227 cairo_pattern_destroy(cp3);
228 cairo_pattern_destroy(cp4);
229 #endif
230 }
231
232 static void
draw_background(GtkWidget * wheel,cairo_t * cr)233 draw_background (GtkWidget *wheel, cairo_t *cr)
234 {
235 #if 0
236 gfloat width = wheel->allocation.width;
237 gfloat height = wheel->allocation.height;
238 gfloat middle = width/2.0;
239
240 cairo_set_line_width (cr, 0);
241 cairo_pattern_t *base1 = cairo_pattern_create_linear (1, 1, middle-5, 1);
242 cairo_pattern_add_color_stop_rgb (base1, 0, 0.33, 0.33, 0.33);
243 cairo_pattern_add_color_stop_rgb (base1, 1, 0.88, 0.88, 0.88);
244 cairo_set_source (cr, base1);
245 cairo_rectangle (cr, 1, 0, middle-1, height-1);
246 cairo_fill_preserve (cr);
247 cairo_stroke (cr);
248 cairo_pattern_t *base2 = cairo_pattern_create_linear (width-1, 1, middle+5, 1);
249 cairo_pattern_add_color_stop_rgb (base2, 0, 0.33, 0.33, 0.33);
250 cairo_pattern_add_color_stop_rgb (base2, 1, 0.88, 0.88, 0.88);
251 cairo_set_source (cr, base2);
252 cairo_rectangle (cr, middle, 0, middle-1, height-1);
253 cairo_fill_preserve (cr);
254 cairo_stroke (cr);
255 cairo_pattern_destroy(base1);
256 cairo_pattern_destroy(base2);
257 #endif
258 }
259
260 static void
draw_edges(GtkWidget * wheel,cairo_t * cr)261 draw_edges (GtkWidget *wheel, cairo_t *cr)
262 {
263 #if 0
264 gfloat width = wheel->allocation.width;
265 gfloat height = wheel->allocation.height;
266
267 cairo_set_line_width (cr, 0);
268 cairo_pattern_t *cp5 = cairo_pattern_create_linear (1, 2, 6, 2);
269 cairo_pattern_add_color_stop_rgb (cp5, 0, 0.00, 0.00, 0.00);
270 cairo_pattern_add_color_stop_rgb (cp5, 1, 0.23, 0.23, 0.23);
271 cairo_set_source (cr, cp5);
272 cairo_rectangle (cr, 1, 2, 6, height-4);
273 cairo_fill_preserve (cr);
274 cairo_stroke (cr);
275 cairo_set_line_width (cr, 0);
276 cairo_pattern_t *cp6 = cairo_pattern_create_linear (width-1, 2, width-6, 2);
277 cairo_pattern_add_color_stop_rgb (cp6, 0, 0.00, 0.00, 0.00);
278 cairo_pattern_add_color_stop_rgb (cp6, 1, 0.23, 0.23, 0.23);
279 cairo_set_source (cr, cp6);
280 cairo_rectangle (cr, width-7, 2, 6, height-4);
281 cairo_fill_preserve (cr);
282 cairo_stroke (cr);
283 cairo_pattern_destroy(cp5);
284 cairo_pattern_destroy(cp6);
285 #endif
286 }
287
288 static void
draw_lines(GtkWidget * wheel,cairo_t * cr)289 draw_lines (GtkWidget *wheel, cairo_t *cr)
290 {
291 #if 0
292 JogShuttlePrivate *priv;
293 priv = JOG_SHUTTLE_GET_PRIVATE (wheel);
294
295 gfloat width = wheel->allocation.width;
296 gfloat height = wheel->allocation.height;
297 gfloat middle = width/2.0;
298
299 int i;
300 for (i=0; i<6; i++)
301 {
302 priv->pos[i] += priv->offset;
303 if (priv->pos[i] > width)
304 {
305 priv->pos[i] -= width;
306 }
307 else if (priv->pos[i] < 0)
308 {
309 priv->pos[i] = width + priv->pos[i];
310 }
311
312 gfloat color;
313 if (priv->pos[i] <= middle)
314 {
315 color = priv->pos[i] / middle * 0.85;
316 }
317 else
318 {
319 color = (width-priv->pos[i]) / middle * 0.85;
320 }
321 if (i==3)
322 {
323 cairo_set_source_rgb (cr, color, 0, 0);
324 cairo_set_line_width (cr, 2);
325 }
326 else
327 {
328 cairo_set_source_rgb (cr, color, color, color);
329 cairo_set_line_width (cr, 1);
330 }
331 cairo_line_to (cr, priv->pos[i], 2);
332 cairo_line_to (cr, priv->pos[i], height-2);
333 cairo_stroke (cr);
334 }
335
336 priv->value = (priv->pos[3]-middle) / middle;
337 //printf ("pos[3] = %f\n", priv->pos[3]);
338 emit_value_changed_signal (JOG_SHUTTLE(wheel));
339 #endif
340 }
341
342 static gboolean
jog_shuttle_expose(GtkWidget * wheel,GdkEventExpose * event)343 jog_shuttle_expose (GtkWidget *wheel, GdkEventExpose *event)
344 {
345 #if 0
346 JogShuttlePrivate *priv;
347 priv = JOG_SHUTTLE_GET_PRIVATE (wheel);
348
349 if (!priv->pressed && !priv->external_control)
350 {
351 reset(wheel);
352 }
353
354 cairo_t *cr;
355 cr = gdk_cairo_create (wheel->window);
356
357 cairo_rectangle (cr, event->area.x, event->area.y, event->area.width, event->area.height);
358 cairo_clip (cr);
359 cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
360 draw_background (wheel, cr);
361 draw_lines (wheel, cr);
362 draw_borders (wheel, cr);
363 draw_edges (wheel, cr);
364
365 cairo_destroy (cr);
366 #endif
367 return FALSE;
368 }
369
370 gfloat
jog_shuttle_get_value(GtkWidget * wheel)371 jog_shuttle_get_value (GtkWidget *wheel)
372 {
373 #if 0
374 if (!wheel)
375 return 0;
376 JogShuttlePrivate *priv;
377 priv = JOG_SHUTTLE_GET_PRIVATE (wheel);
378 if (!priv->pressed && !priv->external_control)
379 return 0;
380 return (priv->value);
381 #endif
382 }
383
384 void
jog_shuttle_set_value(GtkWidget * wheel,gfloat value)385 jog_shuttle_set_value (GtkWidget *wheel, gfloat value)
386 {
387 #if 0
388 JogShuttlePrivate *priv;
389 priv = JOG_SHUTTLE_GET_PRIVATE (wheel);
390 priv->external_control = (value < -0.001 || value > 0.001);
391 priv->offset = 0;
392
393 gfloat width = wheel->allocation.width;
394 gfloat offset = value * (width / 2);
395
396 gfloat was = priv->pos[3];
397 int i;
398 for (i=0; i<6; i++)
399 {
400 priv->pos[i] = width / 6 * i + offset;
401 }
402
403 //printf ("value = %f, offset = %f, pos[3] = %f (was %f)\n", value, offset, priv->pos[3], was);
404
405 GtkWidget * widget = GTK_WIDGET (wheel);
406 if (!widget->window)
407 return;
408
409 GdkRegion * region = gdk_drawable_get_clip_region (widget->window);
410 gdk_window_invalidate_region (widget->window, region, TRUE);
411 gdk_window_process_updates (widget->window, TRUE);
412 gdk_region_destroy (region);
413 #endif
414 }
415
416 GtkWidget *
jog_shuttle_new(void)417 jog_shuttle_new (void)
418 {
419 return g_object_new (JOG_TYPE_SHUTTLE, NULL);
420 }
421