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