reset line to avoid duplicating last item
[rugen] / src / gtkenhancedscale.c
1 /* GtkEnhancedScale - A gtk(h)scale with multiple sliders
2 * Copyright (C) 2001 - Ronald Bultje
3 * Modified look-and-feel by Dan Dennedy
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
18 * USA.
19 */
20
21 /* Some code used was taken from GtkScale and GtkRange, all part
22 * of the Gimp Toolkit (Gtk+), http://www.gtk.org/
23 */
24
25 #ifdef HAVE_CONFIG_H
26 #include <config.h>
27 #endif
28
29 #include <gtk/gtkmain.h>
30 #include <gtk/gtksignal.h>
31 #include <gdk/gdkkeysyms.h>
32 #include <gtk/gtkadjustment.h>
33 #include "gtkenhancedscale.h"
34 #include <string.h>
35 #include <stdio.h>
36 #include <malloc.h>
37 #include <math.h>
38
39 #define ENHANCED_SCALE_CLASS(w) GTK_ENHANCED_SCALE_CLASS ( G_OBJECT_GET_CLASS( G_OBJECT( w ) ) )
40 /* #define DEBUG */
41
42 static void gtk_enhanced_scale_class_init (GtkEnhancedScaleClass *klass);
43 static void gtk_enhanced_scale_init (GtkEnhancedScale *enhanced_scale);
44 static void gtk_enhanced_scale_destroy (GtkObject *object);
45 static void gtk_enhanced_scale_realize (GtkWidget *widget);
46 static void gtk_enhanced_scale_unrealize (GtkWidget *widget);
47 static void gtk_enhanced_scale_size_request (GtkWidget *widget, GtkRequisition *requisition);
48 static void gtk_enhanced_scale_size_allocate (GtkWidget *widget, GtkAllocation *allocation);
49 static gint gtk_enhanced_scale_expose (GtkWidget *widget, GdkEventExpose *event);
50 static void gtk_enhanced_scale_pos_trough (GtkEnhancedScale *enhanced_scale, gint *x, gint *y, gint *w, gint *h);
51 static void gtk_enhanced_scale_draw (GtkWidget *widget, GdkRectangle *area);
52 static void gtk_enhanced_scale_draw_slider (GtkEnhancedScale *enhanced_scale, gint i);
53 static void gtk_enhanced_scale_draw_trough (GtkEnhancedScale *enhanced_scale);
54 static void gtk_enhanced_scale_slider_update (GtkEnhancedScale *enhanced_scale, gint i);
55 static void gtk_enhanced_scale_trough_hdims (GtkEnhancedScale *enhanced_scale, gint *left, gint *right, gint i);
56 static void gtk_enhanced_scale_get_slider_position(GtkEnhancedScale *enhanced_scale,gint *x, gint *y, gint i);
57 static gint gtk_enhanced_scale_get_stepper_spacing(GtkWidget *widget);
58 static gint gtk_enhanced_scale_get_trough_border(GtkWidget *widget);
59 /*static gint gtk_enhanced_scale_get_stepper_size(GtkWidget *widget);*/
60 static gint gtk_enhanced_scale_get_slider_width(GtkWidget *widget);
61 static gint gtk_enhanced_scale_button_press(GtkWidget *widget, GdkEventButton *event);
62 static gint gtk_enhanced_scale_button_release(GtkWidget *widget, GdkEventButton *event);
63 static gint gtk_enhanced_scale_motion_notify(GtkWidget *widget, GdkEventMotion *event);
64 static void gtk_enhanced_scale_motion_x(GtkEnhancedScale *enhanced_scale, gint x, gint i);
65 static gint gtk_enhanced_scale_key_press(GtkWidget *widget, GdkEventKey *event);
66 static gint gtk_enhanced_scale_enter_notify(GtkWidget *widget, GdkEventCrossing *event);
67 static gint gtk_enhanced_scale_leave_notify(GtkWidget *widget, GdkEventCrossing *event);
68 static gint gtk_enhanced_scale_focus_in(GtkWidget *widget, GdkEventFocus *event);
69 static gint gtk_enhanced_scale_focus_out(GtkWidget *widget, GdkEventFocus *event);
70 static void gtk_enhanced_scale_style_set(GtkWidget *widget, GtkStyle *style);
71 static void gtk_enhanced_scale_adjustment_value_changed(GtkAdjustment *adjustment, gpointer data);
72
73 static GtkWidgetClass *parent_class = NULL;
74
75 /* ================================================================= */
76
77 guint gtk_enhanced_scale_get_type ()
78 {
79 static guint enhanced_scale_type = 0;
80
81 if (!enhanced_scale_type)
82 {
83 GtkTypeInfo enhanced_scale_info =
84 {
85 "GtkEnhancedScale",
86 sizeof (GtkEnhancedScale),
87 sizeof (GtkEnhancedScaleClass),
88 (GtkClassInitFunc) gtk_enhanced_scale_class_init,
89 (GtkObjectInitFunc) gtk_enhanced_scale_init,
90 NULL,
91 NULL,
92 };
93 enhanced_scale_type = gtk_type_unique (gtk_widget_get_type (),
94 &enhanced_scale_info);
95 }
96 return enhanced_scale_type;
97 }
98
99 static void gtk_enhanced_scale_class_init (GtkEnhancedScaleClass *class)
100 {
101 GtkObjectClass *object_class;
102 GtkWidgetClass *widget_class;
103
104 object_class = (GtkObjectClass*) class;
105 widget_class = (GtkWidgetClass*) class;
106 parent_class = gtk_type_class (gtk_widget_get_type ());
107
108 object_class->destroy = gtk_enhanced_scale_destroy;
109
110 widget_class->realize = gtk_enhanced_scale_realize;
111 widget_class->unrealize = gtk_enhanced_scale_unrealize;
112 widget_class->expose_event = gtk_enhanced_scale_expose;
113 widget_class->size_request = gtk_enhanced_scale_size_request;
114 widget_class->size_allocate = gtk_enhanced_scale_size_allocate;
115
116 /* Events and their corresponding reaction-functions */
117 widget_class->button_press_event = gtk_enhanced_scale_button_press;
118 widget_class->button_release_event = gtk_enhanced_scale_button_release;
119 widget_class->motion_notify_event = gtk_enhanced_scale_motion_notify;
120 widget_class->key_press_event = gtk_enhanced_scale_key_press;
121 widget_class->enter_notify_event = gtk_enhanced_scale_enter_notify;
122 widget_class->leave_notify_event = gtk_enhanced_scale_leave_notify;
123 widget_class->focus_in_event = gtk_enhanced_scale_focus_in;
124 widget_class->focus_out_event = gtk_enhanced_scale_focus_out;
125 widget_class->style_set = gtk_enhanced_scale_style_set;
126
127 class->slider_width = 32;
128 class->trough_width = 10;
129 class->stepper_size = 11;
130 class->stepper_slider_spacing = 1;
131 class->trough = 1;
132 class->slider = 2;
133 class->arrow_width = 20;
134 class->arrow_height = 10;
135 }
136
137 static void gtk_enhanced_scale_init (GtkEnhancedScale *enhanced_scale)
138 {
139 enhanced_scale->in_child = 0;
140 enhanced_scale->click_child = 0;
141 enhanced_scale->active_slider = 0; /* default */
142 enhanced_scale->clicked_slider = -1; /* none */
143 enhanced_scale->x_click_point = 0;
144 enhanced_scale->breaks = NULL;
145
146 GTK_WIDGET_SET_FLAGS (GTK_WIDGET(enhanced_scale), GTK_CAN_FOCUS);
147 }
148
149 GtkWidget* gtk_enhanced_scale_new (GtkObject *adjustment[],
150 gint num_adjustments)
151 {
152 GtkEnhancedScale *enhanced_scale;
153 int i;
154
155 for(i=0;i<num_adjustments;i++)
156 {
157 if (adjustment[i] == NULL) return NULL;
158 }
159
160 enhanced_scale = gtk_type_new (gtk_enhanced_scale_get_type ());
161 enhanced_scale->adjustment = adjustment;
162 enhanced_scale->num_adjustments = num_adjustments;
163
164 enhanced_scale->handler_id = malloc(num_adjustments);
165
166 for (i=0;i<num_adjustments;i++)
167 {
168 enhanced_scale->handler_id[i] = gtk_signal_connect (adjustment[i], "value_changed",
169 (GtkSignalFunc) gtk_enhanced_scale_adjustment_value_changed,
170 (gpointer) enhanced_scale);
171 }
172
173 return GTK_WIDGET (enhanced_scale);
174 }
175
176 static void gtk_enhanced_scale_destroy (GtkObject *object)
177 {
178 GtkEnhancedScale *enhanced_scale;
179 gint i;
180
181 g_return_if_fail (object != NULL);
182 g_return_if_fail (GTK_IS_ENHANCED_SCALE (object));
183
184 enhanced_scale = GTK_ENHANCED_SCALE (object);
185 #ifdef DEBUG
186 printf("Received destroy signal, let's disappear!\n");
187 #endif
188 for(i=0;i<enhanced_scale->num_adjustments;i++)
189 gtk_signal_disconnect(enhanced_scale->adjustment[i], enhanced_scale->handler_id[i]);
190
191 if ( enhanced_scale->breaks != NULL )
192 g_array_free( enhanced_scale->breaks, TRUE );
193
194 if (GTK_OBJECT_CLASS (parent_class)->destroy)
195 (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
196 #ifdef DEBUG
197 printf("Finished destroy signal\n");
198 #endif
199 }
200
201 static void gtk_enhanced_scale_realize (GtkWidget *widget)
202 {
203 GdkWindowAttr attributes;
204 GtkEnhancedScale *enhanced_scale;
205 gint attributes_mask;
206 gint x=0, y=0, w=0, h=0;
207 gint slider_width;
208 gint i;
209
210 g_return_if_fail (widget != NULL);
211 g_return_if_fail (GTK_IS_ENHANCED_SCALE (widget));
212
213 slider_width = gtk_enhanced_scale_get_slider_width(widget);
214
215 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
216 enhanced_scale = GTK_ENHANCED_SCALE (widget);
217
218 attributes.x = widget->allocation.x;
219 attributes.y = widget->allocation.y;
220 attributes.width = widget->allocation.width;
221 attributes.height = widget->allocation.height;
222 attributes.wclass = GDK_INPUT_OUTPUT;
223 attributes.window_type = GDK_WINDOW_CHILD;
224 attributes.event_mask = gtk_widget_get_events (widget) |
225 GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK |
226 GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK |
227 GDK_POINTER_MOTION_HINT_MASK;
228 attributes.visual = gtk_widget_get_visual (widget);
229 attributes.colormap = gtk_widget_get_colormap (widget);
230 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
231 widget->window = gdk_window_new (widget->parent->window, &attributes, attributes_mask);
232
233 gtk_enhanced_scale_pos_trough (enhanced_scale, &x, &y, &w, &h);
234 attributes.x = x;
235 attributes.y = y;
236 attributes.width = w;
237 attributes.height = h;
238 attributes.wclass = GDK_INPUT_OUTPUT;
239 attributes.window_type = GDK_WINDOW_CHILD;
240 attributes.event_mask = gtk_widget_get_events (widget) |
241 (GDK_EXPOSURE_MASK |
242 GDK_BUTTON_PRESS_MASK |
243 GDK_BUTTON_RELEASE_MASK |
244 GDK_ENTER_NOTIFY_MASK |
245 GDK_LEAVE_NOTIFY_MASK);
246 attributes.visual = gtk_widget_get_visual (widget);
247 attributes.colormap = gtk_widget_get_colormap (widget);
248 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
249 #ifdef DEBUG
250 printf("Scale trough properties - x: %d, y: %d, w: %d, h: %d\n",x,y,w,h);
251 #endif
252 enhanced_scale->trough = gdk_window_new (widget->window, &attributes, attributes_mask);
253
254 enhanced_scale->slider = malloc(enhanced_scale->num_adjustments);
255 attributes.width = ENHANCED_SCALE_CLASS (enhanced_scale)->arrow_width;
256 attributes.height = ENHANCED_SCALE_CLASS (enhanced_scale)->arrow_height;
257 attributes.event_mask |= (GDK_BUTTON_MOTION_MASK |
258 GDK_POINTER_MOTION_HINT_MASK);
259 enhanced_scale->slider[0] = gdk_window_new (enhanced_scale->trough,
260 &attributes, attributes_mask);
261 attributes.y += ENHANCED_SCALE_CLASS (enhanced_scale)->arrow_height + ENHANCED_SCALE_CLASS (enhanced_scale)->trough_width;
262 attributes.width = ENHANCED_SCALE_CLASS (enhanced_scale)->arrow_width/2;
263 for(i=1;i<enhanced_scale->num_adjustments;i++)
264 enhanced_scale->slider[i] = gdk_window_new (enhanced_scale->trough,
265 &attributes, attributes_mask);
266
267 widget->style = gtk_style_attach (widget->style, widget->window);
268
269
270 for(i=0;i<enhanced_scale->num_adjustments;i++)
271 gdk_window_set_user_data (enhanced_scale->slider[i], widget);
272 gdk_window_set_user_data (enhanced_scale->trough, widget);
273 gdk_window_set_user_data (widget->window, widget);
274
275 for(i=0;i<enhanced_scale->num_adjustments;i++)
276 gtk_style_set_background (widget->style, enhanced_scale->slider[i], GTK_STATE_NORMAL);
277 gtk_style_set_background (widget->style, enhanced_scale->trough, GTK_STATE_NORMAL);
278 gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
279
280 for (i=0;i<enhanced_scale->num_adjustments;i++)
281 {
282 gtk_enhanced_scale_slider_update (GTK_ENHANCED_SCALE (widget), i);
283 gdk_window_show (enhanced_scale->slider[i]);
284 }
285 gdk_window_show (enhanced_scale->trough);
286 }
287
288 static void gtk_enhanced_scale_unrealize (GtkWidget *widget)
289 {
290 GtkEnhancedScale *enhanced_scale;
291 int i;
292
293 g_return_if_fail (widget != NULL);
294 g_return_if_fail (GTK_IS_ENHANCED_SCALE (widget));
295
296 enhanced_scale = GTK_ENHANCED_SCALE (widget);
297
298 for (i=0;i<enhanced_scale->num_adjustments;i++)
299 {
300 if (enhanced_scale->slider[i])
301 {
302 gdk_window_set_user_data (enhanced_scale->slider[i], NULL);
303 gdk_window_destroy (enhanced_scale->slider[i]);
304 enhanced_scale->slider[i] = NULL;
305 }
306 }
307 if (enhanced_scale->trough)
308 {
309 gdk_window_set_user_data (enhanced_scale->trough, NULL);
310 gdk_window_destroy (enhanced_scale->trough);
311 enhanced_scale->trough = NULL;
312 }
313
314 gdk_window_set_user_data (widget->window, NULL);
315 #ifdef DEBUG
316 printf("Received unrealize signal, let's disappear!\n");
317 #endif
318 if (GTK_WIDGET_CLASS (parent_class)->unrealize)
319 (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
320 }
321
322 static void gtk_enhanced_scale_size_request (GtkWidget *widget,
323 GtkRequisition *requisition)
324 {
325 GtkEnhancedScale *enhanced_scale;
326 gint trough_border, slider_width;
327
328 enhanced_scale = GTK_ENHANCED_SCALE (widget);
329
330 #ifdef DEBUG
331 printf("Received size_request signal\n");
332 #endif
333
334 trough_border = gtk_enhanced_scale_get_trough_border(GTK_WIDGET(enhanced_scale));
335 slider_width = gtk_enhanced_scale_get_slider_width(GTK_WIDGET(enhanced_scale));
336
337 requisition->width = (ENHANCED_SCALE_CLASS(enhanced_scale)->arrow_width + trough_border) * 4;
338 requisition->height = (slider_width + trough_border * 2);
339
340 }
341
342 static void gtk_enhanced_scale_size_allocate (GtkWidget *widget,
343 GtkAllocation *allocation)
344 {
345 GtkEnhancedScale *enhanced_scale;
346
347 g_return_if_fail (widget != NULL);
348 g_return_if_fail (GTK_IS_ENHANCED_SCALE (widget));
349 g_return_if_fail (allocation != NULL);
350
351 widget->allocation = *allocation;
352 enhanced_scale = GTK_ENHANCED_SCALE (widget);
353
354 #ifdef DEBUG
355 printf("Received size allocate signal: %d\n", allocation->width);
356 #endif
357
358 if (GTK_WIDGET_REALIZED (widget))
359 {
360 gint i, x, y, width, height;
361
362 gdk_window_move_resize (widget->window,
363 allocation->x, allocation->y,
364 allocation->width, allocation->height);
365
366 x = allocation->x;
367 y = allocation->y;
368 width = allocation->width;
369 height = allocation->height;
370 gtk_enhanced_scale_pos_trough( enhanced_scale, &x, &y, &width, &height);
371 gdk_window_move_resize (enhanced_scale->trough, x, y, width, height);
372
373 for ( i = 0; i<enhanced_scale->num_adjustments; i++ )
374 gtk_enhanced_scale_slider_update( enhanced_scale, i );
375
376 }
377
378 }
379
380 static gint gtk_enhanced_scale_expose (GtkWidget *widget, GdkEventExpose *event)
381 {
382 GtkEnhancedScale *enhanced_scale;
383 GdkRectangle area;
384
385 g_return_val_if_fail (widget != NULL, FALSE);
386 g_return_val_if_fail (GTK_IS_ENHANCED_SCALE (widget), FALSE);
387 g_return_val_if_fail (event != NULL, FALSE);
388
389 if (event->count > 0)
390 return FALSE;
391
392 enhanced_scale = GTK_ENHANCED_SCALE (widget);
393
394 gdk_window_clear_area (widget->window, 0, 0,
395 widget->allocation.width, widget->allocation.height);
396
397 /* This would be the place to draw it */
398 area.x = 0;
399 area.y = 0;
400 area.width = widget->allocation.width;
401 area.height = widget->allocation.height;
402 gtk_enhanced_scale_draw (widget, &area);
403
404 return FALSE;
405 }
406
407 /* =========================================================================
408 * Paint functions
409 * Some were directly taken from GtkScale, GtkHScale and GtkRange
410 */
411
412 static void gtk_enhanced_scale_draw (GtkWidget *widget, GdkRectangle *area)
413 {
414 GtkEnhancedScale *enhanced_scale;
415 GdkRectangle tmp_area;
416 gint x=0, y=0, w=0, h=0;
417
418 g_return_if_fail (widget != NULL);
419 g_return_if_fail (GTK_IS_ENHANCED_SCALE (widget));
420 #ifdef DEBUG
421 printf("Trying to draw enhanced_scale\n");
422 #endif
423 if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_MAPPED (widget))
424 {
425 gint i;
426 #ifdef DEBUG
427 printf("Drawing enhanced_scale\n");
428 #endif
429 enhanced_scale = GTK_ENHANCED_SCALE (widget);
430
431 gtk_enhanced_scale_pos_trough (GTK_ENHANCED_SCALE (widget), &x, &y, &w, &h);
432
433 tmp_area.x = x;
434 tmp_area.y = y;
435 tmp_area.width = w;
436 tmp_area.height = h;
437
438 #ifdef DEBUG
439 printf("Drawing enhanced_scale with size = %d\n", w);
440 #endif
441 //if (gdk_rectangle_intersect (area, &tmp_area, area))
442 {
443 for(i=0;i<enhanced_scale->num_adjustments;i++) {
444 gtk_enhanced_scale_slider_update (enhanced_scale, i);
445 gtk_enhanced_scale_draw_slider (enhanced_scale, i);
446 }
447 gtk_enhanced_scale_draw_trough (enhanced_scale);
448 }
449 }
450 }
451
452 static void gtk_enhanced_scale_draw_trough (GtkEnhancedScale *enhanced_scale)
453 {
454 g_return_if_fail (enhanced_scale != NULL);
455 g_return_if_fail (GTK_IS_ENHANCED_SCALE(enhanced_scale));
456
457 if (enhanced_scale->trough)
458 {
459 gint x, x2, y, b;
460 gint left, right;
461
462 #ifdef DEBUG
463 printf("Drawing trough: %d\n", GTK_WIDGET(enhanced_scale)->allocation.width-2);
464 #endif
465
466 if ( enhanced_scale->num_adjustments > 1 )
467 {
468 /* trough */
469 b = gtk_enhanced_scale_get_trough_border(GTK_WIDGET(enhanced_scale));
470 gtk_enhanced_scale_trough_hdims (enhanced_scale, &left, &right, 0);
471
472 gdk_draw_rectangle( enhanced_scale->trough, GTK_WIDGET (enhanced_scale)->style->mid_gc[GTK_STATE_NORMAL],
473 TRUE, ENHANCED_SCALE_CLASS (enhanced_scale)->arrow_width/2 + 1,
474 ENHANCED_SCALE_CLASS (enhanced_scale)->arrow_height + b + 1,
475 right-left,
476 ENHANCED_SCALE_CLASS (enhanced_scale)->trough_width - 2
477 );
478
479 /* selected area */
480 gtk_enhanced_scale_get_slider_position( enhanced_scale, &x, &y, 1);
481 gtk_enhanced_scale_get_slider_position( enhanced_scale, &x2, &y, 2);
482 if (x2 - x - ENHANCED_SCALE_CLASS (enhanced_scale)->arrow_width/2 > 0)
483 {
484 gdk_draw_rectangle( enhanced_scale->trough,
485 GTK_WIDGET (enhanced_scale)->style->mid_gc[GTK_STATE_SELECTED],
486 TRUE,
487 x + ENHANCED_SCALE_CLASS (enhanced_scale)->arrow_width/2 + 1,
488 ENHANCED_SCALE_CLASS (enhanced_scale)->arrow_height + b + 1,
489 x2 - x - ENHANCED_SCALE_CLASS (enhanced_scale)->arrow_width/2,
490 ENHANCED_SCALE_CLASS (enhanced_scale)->trough_width - 2
491 );
492 }
493 }
494 else
495 {
496 /* trough */
497 b = gtk_enhanced_scale_get_trough_border(GTK_WIDGET(enhanced_scale));
498 gtk_enhanced_scale_trough_hdims (enhanced_scale, &left, &right, 0);
499 gdk_draw_rectangle( enhanced_scale->trough, GTK_WIDGET (enhanced_scale)->style->mid_gc[GTK_STATE_NORMAL],
500 TRUE, ENHANCED_SCALE_CLASS (enhanced_scale)->arrow_width/2 + 1,
501 ENHANCED_SCALE_CLASS (enhanced_scale)->arrow_height + b + 1,
502 right-left,
503 ENHANCED_SCALE_CLASS (enhanced_scale)->trough_width - 2
504 );
505 }
506
507 /* scene breaks */
508 if ( enhanced_scale->breaks != NULL )
509 if ( enhanced_scale->breaks->len > 1 )
510 for ( x2 = 0; x2 < (enhanced_scale->breaks->len - 1); x2++ )
511 {
512 gint left, right;
513
514 gtk_enhanced_scale_trough_hdims (enhanced_scale, &left, &right, 0);
515 x = left + ENHANCED_SCALE_CLASS (enhanced_scale)->arrow_width/2;
516 x += ((right - left) * ( g_array_index( enhanced_scale->breaks, gint, x2 ) -
517 GTK_ADJUSTMENT(enhanced_scale->adjustment[0])->lower) /
518 (GTK_ADJUSTMENT(enhanced_scale->adjustment[0])->upper -
519 GTK_ADJUSTMENT(enhanced_scale->adjustment[0])->lower -
520 GTK_ADJUSTMENT(enhanced_scale->adjustment[0])->page_size));
521 gdk_draw_line (enhanced_scale->trough, GTK_WIDGET (enhanced_scale)->style->light_gc[GTK_STATE_NORMAL],
522 x,
523 ENHANCED_SCALE_CLASS (enhanced_scale)->arrow_height + b,
524 x,
525 ENHANCED_SCALE_CLASS (enhanced_scale)->arrow_height + b + ENHANCED_SCALE_CLASS (enhanced_scale)->trough_width -1
526 );
527
528 }
529
530 /* frame position */
531 gtk_enhanced_scale_get_slider_position( enhanced_scale, &x, &y, 0);
532 }
533 }
534
535 static void gtk_enhanced_scale_draw_slider (GtkEnhancedScale *enhanced_scale, gint i)
536 {
537 GtkStateType state_type;
538 GdkPoint points[3];
539
540 g_return_if_fail (enhanced_scale != NULL);
541 g_return_if_fail (GTK_IS_ENHANCED_SCALE (enhanced_scale));
542 g_return_if_fail (i>=0);
543 g_return_if_fail (i<enhanced_scale->num_adjustments);
544
545 if (enhanced_scale->slider[i])
546 {
547 #ifdef DEBUG
548 printf("Drawing slider %d\n", i);
549 #endif
550 if ((enhanced_scale->in_child == ENHANCED_SCALE_CLASS (enhanced_scale)->slider) ||
551 (enhanced_scale->click_child == ENHANCED_SCALE_CLASS (enhanced_scale)->slider))
552 state_type = GTK_STATE_SELECTED;
553 else
554 state_type = GTK_STATE_SELECTED;
555
556 switch ( i )
557 {
558 case 0:
559 gdk_draw_line (enhanced_scale->slider[i], GTK_WIDGET (enhanced_scale)->style->dark_gc[GTK_STATE_NORMAL],
560 ENHANCED_SCALE_CLASS (enhanced_scale)->arrow_width,
561 0,
562 ENHANCED_SCALE_CLASS (enhanced_scale)->arrow_width/2 + 1,
563 ENHANCED_SCALE_CLASS (enhanced_scale)->arrow_height - 1
564 );
565 gdk_draw_line (enhanced_scale->slider[i], GTK_WIDGET (enhanced_scale)->style->dark_gc[GTK_STATE_NORMAL],
566 ENHANCED_SCALE_CLASS (enhanced_scale)->arrow_width+1,
567 1,
568 ENHANCED_SCALE_CLASS (enhanced_scale)->arrow_width/2 + 2,
569 ENHANCED_SCALE_CLASS (enhanced_scale)->arrow_height
570 );
571 points[0].x = ENHANCED_SCALE_CLASS (enhanced_scale)->arrow_width;
572 points[0].y = 0;
573 points[1].x = 0;
574 points[1].y = 0;
575 points[2].x = ENHANCED_SCALE_CLASS (enhanced_scale)->arrow_width/2;
576 points[2].y = ENHANCED_SCALE_CLASS (enhanced_scale)->arrow_height;
577 break;
578 case 1:
579 gdk_draw_line (enhanced_scale->slider[i], GTK_WIDGET (enhanced_scale)->style->dark_gc[GTK_STATE_NORMAL],
580 ENHANCED_SCALE_CLASS (enhanced_scale)->arrow_width/2 - 1,
581 2,
582 ENHANCED_SCALE_CLASS (enhanced_scale)->arrow_width/2 - 1,
583 ENHANCED_SCALE_CLASS (enhanced_scale)->arrow_height - 1
584 );
585 gdk_draw_line (enhanced_scale->slider[i], GTK_WIDGET (enhanced_scale)->style->dark_gc[GTK_STATE_NORMAL],
586 ENHANCED_SCALE_CLASS (enhanced_scale)->arrow_width/2 - 1,
587 ENHANCED_SCALE_CLASS (enhanced_scale)->arrow_height - 1,
588 2,
589 ENHANCED_SCALE_CLASS (enhanced_scale)->arrow_height - 1
590 );
591 points[0].x = ENHANCED_SCALE_CLASS (enhanced_scale)->arrow_width/2 - 1;
592 points[0].y = 0;
593 points[1].x = 0;
594 points[1].y = ENHANCED_SCALE_CLASS (enhanced_scale)->arrow_height - 1;
595 points[2].x = ENHANCED_SCALE_CLASS (enhanced_scale)->arrow_width/2 - 1;
596 points[2].y = ENHANCED_SCALE_CLASS (enhanced_scale)->arrow_height - 1;
597 break;
598 case 2:
599 gdk_draw_line (enhanced_scale->slider[i], GTK_WIDGET (enhanced_scale)->style->dark_gc[GTK_STATE_NORMAL],
600 2,
601 2,
602 ENHANCED_SCALE_CLASS (enhanced_scale)->arrow_width/2 - 1,
603 ENHANCED_SCALE_CLASS (enhanced_scale)->arrow_height - 1
604 );
605 gdk_draw_line (enhanced_scale->slider[i], GTK_WIDGET (enhanced_scale)->style->dark_gc[GTK_STATE_NORMAL],
606 1,
607 ENHANCED_SCALE_CLASS (enhanced_scale)->arrow_height - 1,
608 ENHANCED_SCALE_CLASS (enhanced_scale)->arrow_width/2,
609 ENHANCED_SCALE_CLASS (enhanced_scale)->arrow_height - 1
610 );
611 points[0].x = 0;
612 points[0].y = 0;
613 points[1].x = 0;
614 points[1].y = ENHANCED_SCALE_CLASS (enhanced_scale)->arrow_height - 1;
615 points[2].x = ENHANCED_SCALE_CLASS (enhanced_scale)->arrow_width/2 - 1;
616 points[2].y = ENHANCED_SCALE_CLASS (enhanced_scale)->arrow_height - 1;
617 break;
618 default:
619 return;
620 }
621 gdk_draw_polygon( enhanced_scale->slider[i],
622 GTK_WIDGET(enhanced_scale)->style->bg_gc[state_type], TRUE, points, 3 );
623 /*
624 gtk_paint_polygon( GTK_WIDGET(enhanced_scale)->style, enhanced_scale->slider[i],
625 state_type, GTK_SHADOW_NONE, NULL, GTK_WIDGET(enhanced_scale), NULL,
626 points, 3, TRUE );
627 gtk_paint_arrow( GTK_WIDGET(enhanced_scale)->style, enhanced_scale->slider[i],
628 state_type,
629 (enhanced_scale->clicked_slider == i ? GTK_SHADOW_IN : GTK_SHADOW_OUT),
630 NULL, GTK_WIDGET(enhanced_scale), NULL,
631 (i==0)? GTK_ARROW_DOWN : GTK_ARROW_UP, TRUE, 0, 0,
632 ENHANCED_SCALE_CLASS (enhanced_scale)->arrow_width,
633 ENHANCED_SCALE_CLASS (enhanced_scale)->arrow_height
634 );
635 */
636 }
637 }
638
639 /* =========================================================================
640 * Functions to make life easier
641 * positioning functions etc, mostly directly taken from GtkScale, GtkHScale
642 * and GtkRange
643 */
644
645 static void gtk_enhanced_scale_pos_trough (GtkEnhancedScale *enhanced_scale,
646 gint *x, gint *y, gint *w, gint *h)
647 {
648 GtkWidget *widget;
649 gint trough_border, slider_width;
650
651 g_return_if_fail (enhanced_scale != NULL);
652 g_return_if_fail (GTK_IS_ENHANCED_SCALE (enhanced_scale));
653 g_return_if_fail ((x != NULL) && (y != NULL) && (w != NULL) && (h != NULL));
654
655 widget = GTK_WIDGET (enhanced_scale);
656 trough_border = gtk_enhanced_scale_get_trough_border(GTK_WIDGET(enhanced_scale));
657 slider_width = gtk_enhanced_scale_get_slider_width(GTK_WIDGET(enhanced_scale));
658
659 *w = widget->allocation.width - 2;
660 *h = (slider_width + trough_border * 2);
661 *x = 1;
662 *y = (widget->allocation.height - *h) / 2;
663 }
664
665 static void gtk_enhanced_scale_slider_update (GtkEnhancedScale *enhanced_scale, gint i)
666 {
667 /* i is the number of the adjustment */
668 gint left;
669 gint right;
670 gint x;
671 gint trough_border;
672
673 g_return_if_fail (enhanced_scale != NULL);
674 g_return_if_fail (GTK_IS_ENHANCED_SCALE (enhanced_scale));
675 g_return_if_fail (i >= 0);
676 g_return_if_fail (i < enhanced_scale->num_adjustments);
677
678 trough_border = gtk_enhanced_scale_get_trough_border(GTK_WIDGET(enhanced_scale));
679
680 if (GTK_WIDGET_REALIZED (enhanced_scale))
681 {
682 gtk_enhanced_scale_trough_hdims (enhanced_scale, &left, &right, i);
683 x = left;
684 #ifdef DEBUG
685 printf("Updating slider %d\n",i);
686 #endif
687 if (GTK_ADJUSTMENT(enhanced_scale->adjustment[i])->value <
688 GTK_ADJUSTMENT(enhanced_scale->adjustment[i])->lower)
689 {
690 GTK_ADJUSTMENT(enhanced_scale->adjustment[i])->value =
691 GTK_ADJUSTMENT(enhanced_scale->adjustment[i])->lower;
692 gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(enhanced_scale->adjustment[i])),
693 "value_changed");
694 }
695 else if (GTK_ADJUSTMENT(enhanced_scale->adjustment[i])->value >
696 GTK_ADJUSTMENT(enhanced_scale->adjustment[i])->upper)
697 {
698 GTK_ADJUSTMENT(enhanced_scale->adjustment[i])->value =
699 GTK_ADJUSTMENT(enhanced_scale->adjustment[i])->upper;
700 gtk_signal_emit_by_name(GTK_OBJECT (GTK_ADJUSTMENT(enhanced_scale->adjustment[i])),
701 "value_changed");
702 }
703 if (GTK_ADJUSTMENT(enhanced_scale->adjustment[i])->lower !=
704 (GTK_ADJUSTMENT(enhanced_scale->adjustment[i])->upper -
705 GTK_ADJUSTMENT(enhanced_scale->adjustment[i])->page_size))
706 {
707 x += ((right - left) * (GTK_ADJUSTMENT(enhanced_scale->adjustment[i])->value -
708 GTK_ADJUSTMENT(enhanced_scale->adjustment[i])->lower) /
709 (GTK_ADJUSTMENT(enhanced_scale->adjustment[i])->upper -
710 GTK_ADJUSTMENT(enhanced_scale->adjustment[i])->lower -
711 GTK_ADJUSTMENT(enhanced_scale->adjustment[i])->page_size));
712 }
713 /*
714 if (GTK_ADJUSTMENT(enhanced_scale->adjustment[i])->lower !=
715 (GTK_ADJUSTMENT(enhanced_scale->adjustment[i])->upper))
716 {
717 x += ((right - left) * (GTK_ADJUSTMENT(enhanced_scale->adjustment[i])->value -
718 GTK_ADJUSTMENT(enhanced_scale->adjustment[i])->lower) /
719 (GTK_ADJUSTMENT(enhanced_scale->adjustment[i])->upper -
720 GTK_ADJUSTMENT(enhanced_scale->adjustment[i])->lower));
721 }
722 */
723 if (x < left)
724 x = left;
725 else if (x > right)
726 x = right;
727
728 gdk_window_move (enhanced_scale->slider[i], x,
729 trough_border + (i>0 ? ENHANCED_SCALE_CLASS(enhanced_scale)->arrow_height+ENHANCED_SCALE_CLASS(enhanced_scale)->trough_width : 0) );
730 }
731 }
732
733 static void gtk_enhanced_scale_trough_hdims (GtkEnhancedScale *enhanced_scale, gint *left, gint *right, gint i)
734 {
735 gint trough_width;
736 gint slider_length;
737 gint tleft;
738 gint tright;
739 gint stepper_spacing;
740 gint trough_border;
741
742 g_return_if_fail (enhanced_scale != NULL);
743
744 gdk_window_get_size (enhanced_scale->trough, &trough_width, NULL);
745 gdk_window_get_size (enhanced_scale->slider[0], &slider_length, NULL);
746
747 trough_border = gtk_enhanced_scale_get_trough_border(GTK_WIDGET(enhanced_scale));
748 stepper_spacing = gtk_enhanced_scale_get_stepper_spacing(GTK_WIDGET(enhanced_scale));
749
750 tleft = trough_border;
751 tright = trough_width - slider_length + trough_border;
752 if ( i == 2 )
753 {
754 tleft += slider_length/2;
755 tright += slider_length/2;
756 }
757
758 if (left)
759 *left = tleft;
760 if (right)
761 *right = tright;
762 }
763
764 static void gtk_enhanced_scale_get_slider_position(GtkEnhancedScale *enhanced_scale, gint *x, gint *y, gint i)
765 {
766 g_return_if_fail (enhanced_scale != NULL);
767 g_return_if_fail (GTK_IS_ENHANCED_SCALE (enhanced_scale));
768 g_return_if_fail (i >= 0);
769 g_return_if_fail (i < enhanced_scale->num_adjustments);
770
771 gdk_window_get_position(enhanced_scale->slider[i], x, y);
772 }
773
774 static gint gtk_enhanced_scale_get_stepper_spacing(GtkWidget *widget)
775 {
776 /*return gtk_style_get_prop_experimental (widget->style,
777 "GtkEnhancedScale::stepper_spacing",
778 ENHANCED_SCALE_CLASS (widget)->stepper_slider_spacing);*/
779 return ENHANCED_SCALE_CLASS (widget)->stepper_slider_spacing;
780 }
781
782 static gint gtk_enhanced_scale_get_trough_border(GtkWidget *widget)
783 {
784 /*return gtk_style_get_prop_experimental (widget->style,
785 "GtkEnhancedScale::trough_border",
786 widget->style->klass->xthickness);*/
787 return widget->style->ythickness;
788 }
789
790 /*static gint gtk_enhanced_scale_get_stepper_size(GtkWidget *widget)
791 {
792 return gtk_style_get_prop_experimental (widget->style,
793 "GtkEnhancedScale::stepper_size",
794 ENHANCED_SCALE_CLASS (widget)->stepper_size);
795 }*/
796
797 static gint gtk_enhanced_scale_get_slider_width(GtkWidget *widget)
798 {
799 /*return gtk_style_get_prop_experimental (widget->style,
800 "GtkEnhancedScale::slider_width",
801 ENHANCED_SCALE_CLASS (widget)->slider_width);*/
802 return ENHANCED_SCALE_CLASS (widget)->slider_width;
803 }
804
805 /* =========================================================================
806 * Signal handlers/Callbacks for motion, buttons, keys, focus etc.
807 * Partly helped by code from GtkScale/GtkRange
808 */
809
810 static gint gtk_enhanced_scale_button_press(GtkWidget *widget, GdkEventButton *event)
811 {
812 GtkEnhancedScale *enhanced_scale;
813 int i;
814
815 g_return_val_if_fail (widget != NULL, FALSE);
816 g_return_val_if_fail (GTK_IS_ENHANCED_SCALE (widget), FALSE);
817 g_return_val_if_fail (event != NULL, FALSE);
818
819 if (!GTK_WIDGET_HAS_FOCUS (widget))
820 gtk_widget_grab_focus (widget);
821 #ifdef DEBUG
822 printf("Received press event, button %d\n", event->button);
823 #endif
824 enhanced_scale = GTK_ENHANCED_SCALE (widget);
825 enhanced_scale->x_click_point = event->x;
826
827 if (event->window == enhanced_scale->trough)
828 {
829 gint x,y,n,left,right;
830 gtk_enhanced_scale_get_slider_position(enhanced_scale, &x,&y,enhanced_scale->active_slider);
831 #ifdef DEBUG
832 printf("Source: trough. Active slider: %d (pos: %d,%d). Click position: %d,%d.\n",
833 enhanced_scale->active_slider, x,y,(int)(event->x), (int)(event->y));
834 #endif
835 gtk_enhanced_scale_trough_hdims (enhanced_scale, &left, &right,
836 enhanced_scale->active_slider);
837 n = (GTK_ADJUSTMENT(enhanced_scale->adjustment[enhanced_scale->active_slider])->page_increment)
838 *(right-left)
839 /(GTK_ADJUSTMENT(enhanced_scale->adjustment[enhanced_scale->active_slider])->upper-
840 GTK_ADJUSTMENT(enhanced_scale->adjustment[enhanced_scale->active_slider])->lower);
841
842 if (event->x > x + gtk_enhanced_scale_get_slider_width(widget)) /* Click at right of slider */
843 {
844 gtk_enhanced_scale_motion_x(enhanced_scale, n, enhanced_scale->active_slider);
845 }
846 else if (event->x < x) /* click at left of active slider */
847 {
848 gtk_enhanced_scale_motion_x(enhanced_scale, -n, enhanced_scale->active_slider);
849 }
850 }
851 else for (i=0;i<enhanced_scale->num_adjustments;i++)
852 {
853 gint x,y;
854 gtk_enhanced_scale_get_slider_position(enhanced_scale, &x,&y,i);
855 if (event->window == enhanced_scale->slider[i])
856 {
857 enhanced_scale->active_slider = i;
858 #ifdef DEBUG
859 printf("Source: slider %d (pos: %d,%d)\n",i,x,y);
860 #endif
861 enhanced_scale->clicked_slider = i;
862 }
863 }
864 return TRUE;
865 }
866
867 static gint gtk_enhanced_scale_button_release(GtkWidget *widget, GdkEventButton *event)
868 {
869 GtkEnhancedScale *enhanced_scale;
870
871 g_return_val_if_fail (widget != NULL, FALSE);
872 g_return_val_if_fail (GTK_IS_ENHANCED_SCALE (widget), FALSE);
873 g_return_val_if_fail (event != NULL, FALSE);
874
875 enhanced_scale = GTK_ENHANCED_SCALE (widget);
876
877 enhanced_scale->x_click_point = 0;
878 #ifdef DEBUG
879 printf("Button released");
880 if (enhanced_scale->clicked_slider != -1) printf(" - slider %d unselected", enhanced_scale->clicked_slider);
881 printf("\n");
882 #endif
883 enhanced_scale->clicked_slider = -1;
884 gtk_widget_queue_draw (widget);
885 return TRUE;
886 }
887
888 static gint gtk_enhanced_scale_motion_notify(GtkWidget *widget, GdkEventMotion *event)
889 {
890 GtkEnhancedScale *enhanced_scale;
891 int x,y;
892 GdkModifierType mods;
893
894 g_return_val_if_fail (widget != NULL, FALSE);
895 g_return_val_if_fail (GTK_IS_ENHANCED_SCALE (widget), FALSE);
896 g_return_val_if_fail (event != NULL, FALSE);
897
898 enhanced_scale = GTK_ENHANCED_SCALE (widget);
899
900 if (enhanced_scale->clicked_slider != -1)
901 {
902 gdk_window_get_pointer (enhanced_scale->slider[enhanced_scale->clicked_slider], &x, &y, &mods);
903 #ifdef DEBUG
904 printf("Motion notify\n");
905 #endif
906 if (mods & GDK_BUTTON1_MASK)
907 gtk_enhanced_scale_motion_x(enhanced_scale, x - enhanced_scale->x_click_point,
908 enhanced_scale->clicked_slider);
909 }
910
911 return TRUE;
912 }
913
914 static void gtk_enhanced_scale_motion_x(GtkEnhancedScale *enhanced_scale, gint delta_x, gint i)
915 {
916 gdouble old_value;
917 gint left, right;
918 gint slider_x, slider_y;
919 gint new_pos;
920
921 g_return_if_fail (enhanced_scale != NULL);
922 g_return_if_fail (GTK_IS_ENHANCED_SCALE (enhanced_scale));
923 g_return_if_fail (i>=0);
924 g_return_if_fail (i<enhanced_scale->num_adjustments);
925
926 gdk_window_get_position (enhanced_scale->slider[i], &slider_x, &slider_y);
927 gtk_enhanced_scale_trough_hdims (enhanced_scale, &left, &right,i);
928 #ifdef DEBUG
929 printf("motion_x called: delta_x = %d, slider_x = %d, l/r=%d/%d\n", delta_x, slider_x, left, right);
930 #endif
931 if (left == right)
932 return;
933
934 new_pos = slider_x + delta_x;
935
936 if (new_pos < left)
937 new_pos = left;
938 else if (new_pos > right)
939 new_pos = right;
940
941 old_value = GTK_ADJUSTMENT(enhanced_scale->adjustment[i])->value;
942 GTK_ADJUSTMENT(enhanced_scale->adjustment[i])->value = (gint)
943 ((GTK_ADJUSTMENT(enhanced_scale->adjustment[i])->upper -
944 GTK_ADJUSTMENT(enhanced_scale->adjustment[i])->lower -
945 GTK_ADJUSTMENT(enhanced_scale->adjustment[i])->page_size) *
946 (new_pos - left) / (right - left) +
947 GTK_ADJUSTMENT(enhanced_scale->adjustment[i])->lower);
948 if ( (int) old_value != (int) GTK_ADJUSTMENT(enhanced_scale->adjustment[i])->value)
949 {
950 gtk_signal_emit_by_name (GTK_OBJECT (enhanced_scale->adjustment[i]), "value_changed");
951 }
952 }
953
954 static gint gtk_enhanced_scale_key_press(GtkWidget *widget, GdkEventKey *event)
955 {
956 GtkEnhancedScale *enhanced_scale;
957 #ifdef DEBUG
958 char *key;
959 #endif
960 g_return_val_if_fail (widget != NULL, FALSE);
961 g_return_val_if_fail (GTK_IS_ENHANCED_SCALE (widget), FALSE);
962 g_return_val_if_fail (event != NULL, FALSE);
963 #ifdef DEBUG
964 key = "unkown";
965 #endif
966 enhanced_scale = GTK_ENHANCED_SCALE (widget);
967
968 if(enhanced_scale->active_slider >= 0 && enhanced_scale->active_slider < enhanced_scale->num_adjustments)
969 {
970 gint n1,n2,left,right;
971
972 gtk_enhanced_scale_trough_hdims (enhanced_scale, &left, &right,
973 enhanced_scale->active_slider);
974 n1 = (GTK_ADJUSTMENT(enhanced_scale->adjustment[enhanced_scale->active_slider])->
975 page_increment)*(right-left)/
976 (GTK_ADJUSTMENT(enhanced_scale->adjustment[enhanced_scale->active_slider])->upper-
977 GTK_ADJUSTMENT(enhanced_scale->adjustment[enhanced_scale->active_slider])->lower);
978 n2 = (GTK_ADJUSTMENT(enhanced_scale->adjustment[enhanced_scale->active_slider])->
979 step_increment)*(right-left)/
980 (GTK_ADJUSTMENT(enhanced_scale->adjustment[enhanced_scale->active_slider])->upper-
981 GTK_ADJUSTMENT(enhanced_scale->adjustment[enhanced_scale->active_slider])->lower);
982
983 switch (event->keyval)
984 {
985 case GDK_Left:
986 if (event->state & GDK_CONTROL_MASK)
987 gtk_enhanced_scale_motion_x(enhanced_scale,
988 -n1, enhanced_scale->active_slider);
989 else
990 gtk_enhanced_scale_motion_x(enhanced_scale,
991 -n2, enhanced_scale->active_slider);
992 #ifdef DEBUG
993 key = "left_arrow";
994 #endif
995 break;
996 case GDK_Right:
997 if (event->state & GDK_CONTROL_MASK)
998 gtk_enhanced_scale_motion_x(enhanced_scale,
999 n1, enhanced_scale->active_slider);
1000 else
1001 gtk_enhanced_scale_motion_x(enhanced_scale,
1002 n2, enhanced_scale->active_slider);
1003 #ifdef DEBUG
1004 key = "right_arrow";
1005 #endif
1006 break;
1007 case GDK_Home:
1008 /* Clumsy, but the check in gtk_enhanced_scale_motion_x() will take care */
1009 gtk_enhanced_scale_motion_x(enhanced_scale,
1010 0 - GTK_ADJUSTMENT(enhanced_scale->adjustment[enhanced_scale->active_slider])->upper,
1011 enhanced_scale->active_slider);
1012 #ifdef DEBUG
1013 key = "home";
1014 #endif
1015 break;
1016 case GDK_End:
1017 /* Clumsy, but the check in gtk_enhanced_scale_motion_x() will take care */
1018 gtk_enhanced_scale_motion_x(enhanced_scale,
1019 GTK_ADJUSTMENT(enhanced_scale->adjustment[enhanced_scale->active_slider])->upper,
1020 enhanced_scale->active_slider);
1021 #ifdef DEBUG
1022 key = "end";
1023 #endif
1024 break;
1025 }
1026 }
1027 #ifdef DEBUG
1028 printf("Key pressed: %s\n", key);
1029 #endif
1030 return TRUE;
1031 }
1032
1033 static gint gtk_enhanced_scale_enter_notify(GtkWidget *widget, GdkEventCrossing *event)
1034 {
1035 GtkEnhancedScale *enhanced_scale;
1036 gint i;
1037
1038 g_return_val_if_fail (widget != NULL, FALSE);
1039 g_return_val_if_fail (GTK_IS_ENHANCED_SCALE (widget), FALSE);
1040 g_return_val_if_fail (event != NULL, FALSE);
1041
1042 enhanced_scale = GTK_ENHANCED_SCALE (widget);
1043
1044 if (event->window == enhanced_scale->trough)
1045 {
1046 enhanced_scale->in_child = ENHANCED_SCALE_CLASS (enhanced_scale)->trough;
1047 }
1048 else for (i=0;i<enhanced_scale->num_adjustments;i++)
1049 if (event->window == enhanced_scale->slider[i])
1050 {
1051 enhanced_scale->in_child = ENHANCED_SCALE_CLASS (enhanced_scale)->slider;
1052 if ((enhanced_scale->click_child == 0) ||
1053 (enhanced_scale->click_child == ENHANCED_SCALE_CLASS (enhanced_scale)->trough))
1054 gtk_enhanced_scale_draw_slider (enhanced_scale,i);
1055 }
1056
1057 return TRUE;
1058 }
1059
1060 static gint gtk_enhanced_scale_leave_notify(GtkWidget *widget, GdkEventCrossing *event)
1061 {
1062 GtkEnhancedScale *enhanced_scale;
1063 gint i;
1064
1065 g_return_val_if_fail (widget != NULL, FALSE);
1066 g_return_val_if_fail (GTK_IS_ENHANCED_SCALE (widget), FALSE);
1067 g_return_val_if_fail (event != NULL, FALSE);
1068
1069 enhanced_scale = GTK_ENHANCED_SCALE (widget);
1070
1071 enhanced_scale->in_child = 0;
1072
1073 if (event->window == enhanced_scale->trough)
1074 {
1075 }
1076 else for (i=0;i<enhanced_scale->num_adjustments;i++)
1077 if (event->window == enhanced_scale->slider[i])
1078 {
1079 if ((enhanced_scale->click_child == 0) ||
1080 (enhanced_scale->click_child == ENHANCED_SCALE_CLASS (enhanced_scale)->trough))
1081 gtk_enhanced_scale_draw_slider (enhanced_scale, i);
1082 }
1083
1084 return TRUE;
1085 }
1086
1087 static gint gtk_enhanced_scale_focus_in(GtkWidget *widget, GdkEventFocus *event)
1088 {
1089 g_return_val_if_fail (widget != NULL, FALSE);
1090 g_return_val_if_fail (GTK_IS_ENHANCED_SCALE (widget), FALSE);
1091 g_return_val_if_fail (event != NULL, FALSE);
1092
1093 GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS);
1094 gtk_widget_queue_draw (widget);
1095 #ifdef DEBUG
1096 printf("focus_in\n");
1097 #endif
1098 gtk_widget_queue_draw (widget);
1099 return FALSE;
1100 }
1101
1102 static gint gtk_enhanced_scale_focus_out(GtkWidget *widget, GdkEventFocus *event)
1103 {
1104 g_return_val_if_fail (widget != NULL, FALSE);
1105 g_return_val_if_fail (GTK_IS_ENHANCED_SCALE (widget), FALSE);
1106 g_return_val_if_fail (event != NULL, FALSE);
1107
1108 GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS);
1109 gtk_widget_queue_draw (widget);
1110 #ifdef DEBUG
1111 printf("focus_out\n");
1112 #endif
1113 gtk_widget_queue_draw (widget);
1114 return FALSE;
1115 }
1116
1117 static void gtk_enhanced_scale_style_set(GtkWidget *widget, GtkStyle *style)
1118 {
1119 GtkEnhancedScale *enhanced_scale;
1120 int i;
1121
1122 g_return_if_fail (widget != NULL);
1123 g_return_if_fail (GTK_IS_ENHANCED_SCALE (widget));
1124
1125 enhanced_scale = GTK_ENHANCED_SCALE (widget);
1126
1127 if (GTK_WIDGET_REALIZED (widget))
1128 {
1129 if (enhanced_scale->trough)
1130 gtk_style_set_background (widget->style, enhanced_scale->trough, GTK_STATE_NORMAL);
1131
1132 for(i=0;i<enhanced_scale->num_adjustments;i++)
1133 if (enhanced_scale->slider[i])
1134 gtk_style_set_background (widget->style, enhanced_scale->slider[i],
1135 GTK_STATE_NORMAL);
1136 }
1137 }
1138
1139 static void gtk_enhanced_scale_adjustment_value_changed(GtkAdjustment *adjustment, gpointer data)
1140 {
1141 GtkEnhancedScale *enhanced_scale;
1142 gint i;
1143
1144 g_return_if_fail (adjustment != NULL);
1145 g_return_if_fail (data != NULL);
1146
1147 enhanced_scale = GTK_ENHANCED_SCALE(data);
1148
1149 for (i=0;i<enhanced_scale->num_adjustments;i++)
1150 {
1151 //if(adjustment == GTK_ADJUSTMENT(enhanced_scale->adjustment[i]))
1152 gtk_enhanced_scale_slider_update (enhanced_scale,i);
1153 }
1154 gtk_enhanced_scale_draw (GTK_WIDGET( enhanced_scale ), NULL );
1155 }
1156
1157 void gtk_enhanced_scale_set_breaks( GtkWidget *widget, GArray *breaks )
1158 {
1159 GtkEnhancedScale *enhanced_scale;
1160 GdkRectangle area;
1161
1162 g_return_if_fail( widget != NULL );
1163 g_return_if_fail( breaks != NULL );
1164 enhanced_scale = GTK_ENHANCED_SCALE( widget );
1165 enhanced_scale->breaks = breaks;
1166
1167 gdk_window_clear_area (widget->window, 0, 0,
1168 widget->allocation.width, widget->allocation.height);
1169
1170 /* This would be the place to draw it */
1171 area.x = 0;
1172 area.y = 0;
1173 area.width = widget->allocation.width;
1174 area.height = widget->allocation.height;
1175 gtk_enhanced_scale_draw (widget, &area);
1176 }