]> Pileus Git - ~andy/gtk/blob - gtk/gtkrange.c
Merge from themes-2. See the ChangeLog for a somewhat detailed
[~andy/gtk] / gtk / gtkrange.c
1 /* GTK - The GIMP Toolkit
2  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19 #include <stdio.h>
20 #include "gtkmain.h"
21 #include "gtkrange.h"
22 #include "gtksignal.h"
23
24
25 #define SCROLL_TIMER_LENGTH  20
26 #define SCROLL_INITIAL_DELAY 100
27 #define SCROLL_DELAY_LENGTH  300
28
29 #define RANGE_CLASS(w)  GTK_RANGE_CLASS (GTK_OBJECT (w)->klass)
30
31
32 static void gtk_range_class_init               (GtkRangeClass    *klass);
33 static void gtk_range_init                     (GtkRange         *range);
34 static void gtk_range_finalize                 (GtkObject        *object);
35 static void gtk_range_draw                     (GtkWidget        *widget,
36                                                 GdkRectangle     *area);
37 static void gtk_range_draw_focus               (GtkWidget        *widget);
38 static void gtk_range_unrealize                (GtkWidget        *widget);
39 static gint gtk_range_expose                   (GtkWidget        *widget,
40                                                 GdkEventExpose   *event);
41 static gint gtk_range_button_press             (GtkWidget        *widget,
42                                                 GdkEventButton   *event);
43 static gint gtk_range_button_release           (GtkWidget        *widget,
44                                                 GdkEventButton   *event);
45 static gint gtk_range_motion_notify            (GtkWidget        *widget,
46                                                 GdkEventMotion   *event);
47 static gint gtk_range_key_press                (GtkWidget         *widget,
48                                                 GdkEventKey       *event);
49 static gint gtk_range_enter_notify             (GtkWidget        *widget,
50                                                 GdkEventCrossing *event);
51 static gint gtk_range_leave_notify             (GtkWidget        *widget,
52                                                 GdkEventCrossing *event);
53 static gint gtk_range_focus_in                 (GtkWidget        *widget,
54                                                 GdkEventFocus    *event);
55 static gint gtk_range_focus_out                (GtkWidget        *widget,
56                                                 GdkEventFocus    *event);
57 static void gtk_range_style_set                 (GtkWidget       *widget,
58                                                  GtkStyle        *previous_style);
59
60 static void gtk_real_range_draw_trough         (GtkRange         *range);
61 static void gtk_real_range_draw_slider         (GtkRange         *range);
62 static gint gtk_real_range_timer               (GtkRange         *range);
63 static gint gtk_range_scroll                   (GtkRange         *range,
64                                                 gfloat            jump_perc);
65
66 static void gtk_range_add_timer                (GtkRange         *range);
67 static void gtk_range_remove_timer             (GtkRange         *range);
68
69 static void gtk_range_adjustment_changed       (GtkAdjustment    *adjustment,
70                                                 gpointer          data);
71 static void gtk_range_adjustment_value_changed (GtkAdjustment    *adjustment,
72                                                 gpointer          data);
73
74 static void gtk_range_trough_hdims             (GtkRange         *range,
75                                                 gint             *left,
76                                                 gint             *right);
77 static void gtk_range_trough_vdims             (GtkRange         *range,
78                                                 gint             *top,
79                                                 gint             *bottom);
80
81 static GtkWidgetClass *parent_class = NULL;
82
83
84 guint
85 gtk_range_get_type (void)
86 {
87   static guint range_type = 0;
88
89   if (!range_type)
90     {
91       GtkTypeInfo range_info =
92       {
93         "GtkRange",
94         sizeof (GtkRange),
95         sizeof (GtkRangeClass),
96         (GtkClassInitFunc) gtk_range_class_init,
97         (GtkObjectInitFunc) gtk_range_init,
98         /* reserved_1 */ NULL,
99         /* reserved_2 */ NULL,
100         (GtkClassInitFunc) NULL,
101       };
102
103       range_type = gtk_type_unique (gtk_widget_get_type (), &range_info);
104     }
105
106   return range_type;
107 }
108
109 static void
110 gtk_range_class_init (GtkRangeClass *class)
111 {
112   GtkObjectClass *object_class;
113   GtkWidgetClass *widget_class;
114
115   object_class = (GtkObjectClass*) class;
116   widget_class = (GtkWidgetClass*) class;
117
118   parent_class = gtk_type_class (gtk_widget_get_type ());
119
120   object_class->finalize = gtk_range_finalize;
121
122   widget_class->draw = gtk_range_draw;
123   widget_class->draw_focus = gtk_range_draw_focus;
124   widget_class->unrealize = gtk_range_unrealize;
125   widget_class->expose_event = gtk_range_expose;
126   widget_class->button_press_event = gtk_range_button_press;
127   widget_class->button_release_event = gtk_range_button_release;
128   widget_class->motion_notify_event = gtk_range_motion_notify;
129   widget_class->key_press_event = gtk_range_key_press;
130   widget_class->enter_notify_event = gtk_range_enter_notify;
131   widget_class->leave_notify_event = gtk_range_leave_notify;
132   widget_class->focus_in_event = gtk_range_focus_in;
133   widget_class->focus_out_event = gtk_range_focus_out;
134   widget_class->style_set = gtk_range_style_set;
135
136   class->slider_width = 11;
137   class->stepper_size = 11;
138   class->stepper_slider_spacing = 1;
139   class->min_slider_size = 7;
140   class->trough = 1;
141   class->slider = 2;
142   class->step_forw = 3;
143   class->step_back = 4;
144   class->draw_background = NULL;
145   class->clear_background = NULL;
146   class->draw_trough = gtk_real_range_draw_trough;
147   class->draw_slider = gtk_real_range_draw_slider;
148   class->draw_step_forw = NULL;
149   class->draw_step_back = NULL;
150   class->trough_click = NULL;
151   class->trough_keys = NULL;
152   class->motion = NULL;
153   class->timer = gtk_real_range_timer;
154 }
155
156 static void
157 gtk_range_init (GtkRange *range)
158 {
159   range->trough = NULL;
160   range->slider = NULL;
161   range->step_forw = NULL;
162   range->step_back = NULL;
163
164   range->x_click_point = 0;
165   range->y_click_point = 0;
166   range->button = 0;
167   range->digits = -1;
168   range->policy = GTK_UPDATE_CONTINUOUS;
169   range->scroll_type = GTK_SCROLL_NONE;
170   range->in_child = 0;
171   range->click_child = 0;
172   range->need_timer = FALSE;
173   range->timer = 0;
174   range->old_value = 0.0;
175   range->old_lower = 0.0;
176   range->old_upper = 0.0;
177   range->old_page_size = 0.0;
178   range->adjustment = NULL;
179 }
180
181 GtkAdjustment*
182 gtk_range_get_adjustment (GtkRange *range)
183 {
184   g_return_val_if_fail (range != NULL, NULL);
185   g_return_val_if_fail (GTK_IS_RANGE (range), NULL);
186
187   return range->adjustment;
188 }
189
190 void
191 gtk_range_set_update_policy (GtkRange      *range,
192                              GtkUpdateType  policy)
193 {
194   g_return_if_fail (range != NULL);
195   g_return_if_fail (GTK_IS_RANGE (range));
196
197   range->policy = policy;
198 }
199
200 void
201 gtk_range_set_adjustment (GtkRange      *range,
202                           GtkAdjustment *adjustment)
203 {
204   g_return_if_fail (range != NULL);
205   g_return_if_fail (GTK_IS_RANGE (range));
206
207   if (range->adjustment != adjustment)
208     {
209       if (range->adjustment)
210         {
211           gtk_signal_disconnect_by_data (GTK_OBJECT (range->adjustment),
212                                          (gpointer) range);
213           gtk_object_unref (GTK_OBJECT (range->adjustment));
214         }
215       range->adjustment = adjustment;
216       if (adjustment)
217         {
218           gtk_object_ref (GTK_OBJECT (adjustment));
219           gtk_object_sink (GTK_OBJECT (adjustment));
220
221           gtk_signal_connect (GTK_OBJECT (adjustment), "changed",
222                               (GtkSignalFunc) gtk_range_adjustment_changed,
223                               (gpointer) range);
224           gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed",
225                               (GtkSignalFunc) gtk_range_adjustment_value_changed,
226                               (gpointer) range);
227
228           range->old_value = adjustment->value;
229           range->old_lower = adjustment->lower;
230           range->old_upper = adjustment->upper;
231           range->old_page_size = adjustment->page_size;
232           
233           gtk_range_adjustment_changed (adjustment, (gpointer) range);
234         }
235     }
236 }
237
238 void
239 gtk_range_draw_background (GtkRange *range)
240 {
241   g_return_if_fail (range != NULL);
242   g_return_if_fail (GTK_IS_RANGE (range));
243
244   if (range->trough && RANGE_CLASS (range)->draw_background)
245     (* RANGE_CLASS (range)->draw_background) (range);
246 }
247
248 void
249 gtk_range_clear_background (GtkRange *range)
250 {
251   g_return_if_fail (range != NULL);
252   g_return_if_fail (GTK_IS_RANGE (range));
253
254   if (range->trough && RANGE_CLASS (range)->clear_background)
255     (* RANGE_CLASS (range)->clear_background) (range);
256 }
257
258 void
259 gtk_range_draw_trough (GtkRange *range)
260 {
261   g_return_if_fail (range != NULL);
262   g_return_if_fail (GTK_IS_RANGE (range));
263
264   if (range->trough && RANGE_CLASS (range)->draw_trough)
265     (* RANGE_CLASS (range)->draw_trough) (range);
266 }
267
268 void
269 gtk_range_draw_slider (GtkRange *range)
270 {
271   g_return_if_fail (range != NULL);
272   g_return_if_fail (GTK_IS_RANGE (range));
273
274   if (range->slider && RANGE_CLASS (range)->draw_slider)
275     (* RANGE_CLASS (range)->draw_slider) (range);
276 }
277
278 void
279 gtk_range_draw_step_forw (GtkRange *range)
280 {
281   g_return_if_fail (range != NULL);
282   g_return_if_fail (GTK_IS_RANGE (range));
283
284   if (range->step_forw && RANGE_CLASS (range)->draw_step_forw)
285     (* RANGE_CLASS (range)->draw_step_forw) (range);
286 }
287
288 void
289 gtk_range_draw_step_back (GtkRange *range)
290 {
291   g_return_if_fail (range != NULL);
292   g_return_if_fail (GTK_IS_RANGE (range));
293
294   if (range->step_back && RANGE_CLASS (range)->draw_step_back)
295     (* RANGE_CLASS (range)->draw_step_back) (range);
296 }
297
298 void
299 gtk_range_slider_update (GtkRange *range)
300 {
301   g_return_if_fail (range != NULL);
302   g_return_if_fail (GTK_IS_RANGE (range));
303
304   if (RANGE_CLASS (range)->slider_update)
305     (* RANGE_CLASS (range)->slider_update) (range);
306 }
307
308 gint
309 gtk_range_trough_click (GtkRange *range,
310                         gint      x,
311                         gint      y,
312                         gfloat   *jump_perc)
313 {
314   g_return_val_if_fail (range != NULL, GTK_TROUGH_NONE);
315   g_return_val_if_fail (GTK_IS_RANGE (range), GTK_TROUGH_NONE);
316
317   if (RANGE_CLASS (range)->trough_click)
318     return (* RANGE_CLASS (range)->trough_click) (range, x, y, jump_perc);
319
320   return GTK_TROUGH_NONE;
321 }
322
323 void
324 gtk_range_default_hslider_update (GtkRange *range)
325 {
326   gint left;
327   gint right;
328   gint x;
329
330   g_return_if_fail (range != NULL);
331   g_return_if_fail (GTK_IS_RANGE (range));
332
333   if (GTK_WIDGET_REALIZED (range))
334     {
335       gtk_range_trough_hdims (range, &left, &right);
336       x = left;
337
338       if (range->adjustment->value < range->adjustment->lower)
339         {
340           range->adjustment->value = range->adjustment->lower;
341           gtk_signal_emit_by_name (GTK_OBJECT (range->adjustment), "value_changed");
342         }
343       else if (range->adjustment->value > range->adjustment->upper)
344         {
345           range->adjustment->value = range->adjustment->upper;
346           gtk_signal_emit_by_name (GTK_OBJECT (range->adjustment), "value_changed");
347         }
348
349       if (range->adjustment->lower != (range->adjustment->upper - range->adjustment->page_size))
350         x += ((right - left) * (range->adjustment->value - range->adjustment->lower) /
351               (range->adjustment->upper - range->adjustment->lower - range->adjustment->page_size));
352
353       if (x < left)
354         x = left;
355       else if (x > right)
356         x = right;
357
358       gdk_window_move (range->slider, x, GTK_WIDGET (range)->style->klass->ythickness);
359     }
360 }
361
362 void
363 gtk_range_default_vslider_update (GtkRange *range)
364 {
365   gint top;
366   gint bottom;
367   gint y;
368
369   g_return_if_fail (range != NULL);
370   g_return_if_fail (GTK_IS_RANGE (range));
371
372   if (GTK_WIDGET_REALIZED (range))
373     {
374       gtk_range_trough_vdims (range, &top, &bottom);
375       y = top;
376
377       if (range->adjustment->value < range->adjustment->lower)
378         {
379           range->adjustment->value = range->adjustment->lower;
380           gtk_signal_emit_by_name (GTK_OBJECT (range->adjustment), "value_changed");
381         }
382       else if (range->adjustment->value > range->adjustment->upper)
383         {
384           range->adjustment->value = range->adjustment->upper;
385           gtk_signal_emit_by_name (GTK_OBJECT (range->adjustment), "value_changed");
386         }
387
388       if (range->adjustment->lower != (range->adjustment->upper - range->adjustment->page_size))
389         y += ((bottom - top) * (range->adjustment->value - range->adjustment->lower) /
390               (range->adjustment->upper - range->adjustment->lower - range->adjustment->page_size));
391
392       if (y < top)
393         y = top;
394       else if (y > bottom)
395         y = bottom;
396
397       gdk_window_move (range->slider, GTK_WIDGET (range)->style->klass->xthickness, y);
398     }
399 }
400
401 gint
402 gtk_range_default_htrough_click (GtkRange *range,
403                                  gint      x,
404                                  gint      y,
405                                  gfloat   *jump_perc)
406 {
407   gint ythickness;
408   gint trough_width;
409   gint trough_height;
410   gint slider_x;
411   gint slider_length;
412   gint left, right;
413
414   g_return_val_if_fail (range != NULL, GTK_TROUGH_NONE);
415   g_return_val_if_fail (GTK_IS_RANGE (range), GTK_TROUGH_NONE);
416
417   ythickness = GTK_WIDGET (range)->style->klass->ythickness;
418
419   gtk_range_trough_hdims (range, &left, &right);
420   gdk_window_get_size (range->slider, &slider_length, NULL);
421   right += slider_length;
422               
423   if ((x > left) && (y > ythickness))
424     {
425       gdk_window_get_size (range->trough, &trough_width, &trough_height);
426
427       if ((x < right) && (y < (trough_height - ythickness)))
428         {
429           if (jump_perc)
430             {
431               *jump_perc = ((gdouble) (x - left)) / ((gdouble) (right - left));
432               return GTK_TROUGH_JUMP;
433             }
434           
435           gdk_window_get_position (range->slider, &slider_x, NULL);
436           
437           if (x < slider_x)
438             return GTK_TROUGH_START;
439           else
440             return GTK_TROUGH_END;
441         }
442     }
443
444   return GTK_TROUGH_NONE;
445 }
446
447 gint
448 gtk_range_default_vtrough_click (GtkRange *range,
449                                  gint      x,
450                                  gint      y,
451                                  gfloat   *jump_perc)
452 {
453   gint xthickness;
454   gint trough_width;
455   gint trough_height;
456   gint slider_y;
457   gint top, bottom;
458   gint slider_length;
459
460   g_return_val_if_fail (range != NULL, GTK_TROUGH_NONE);
461   g_return_val_if_fail (GTK_IS_RANGE (range), GTK_TROUGH_NONE);
462
463   xthickness = GTK_WIDGET (range)->style->klass->xthickness;
464
465   gtk_range_trough_vdims (range, &top, &bottom);
466   gdk_window_get_size (range->slider, NULL, &slider_length);
467   bottom += slider_length;
468               
469   if ((x > xthickness) && (y > top))
470     {
471       gdk_window_get_size (range->trough, &trough_width, &trough_height);
472
473       if ((x < (trough_width - xthickness) && (y < bottom)))
474         {
475           if (jump_perc)
476             {
477               *jump_perc = ((gdouble) (y - top)) / ((gdouble) (bottom - top));
478
479               return GTK_TROUGH_JUMP;
480             }
481           
482           gdk_window_get_position (range->slider, NULL, &slider_y);
483           
484           if (y < slider_y)
485             return GTK_TROUGH_START;
486           else
487             return GTK_TROUGH_END;
488         }
489     }
490
491   return GTK_TROUGH_NONE;
492 }
493
494 void
495 gtk_range_default_hmotion (GtkRange *range,
496                            gint      xdelta,
497                            gint      ydelta)
498 {
499   gdouble old_value;
500   gint left, right;
501   gint slider_x, slider_y;
502   gint new_pos;
503
504   g_return_if_fail (range != NULL);
505   g_return_if_fail (GTK_IS_RANGE (range));
506
507   range = GTK_RANGE (range);
508
509   gdk_window_get_position (range->slider, &slider_x, &slider_y);
510   gtk_range_trough_hdims (range, &left, &right);
511
512   if (left == right)
513     return;
514
515   new_pos = slider_x + xdelta;
516
517   if (new_pos < left)
518     new_pos = left;
519   else if (new_pos > right)
520     new_pos = right;
521
522   old_value = range->adjustment->value;
523   range->adjustment->value = ((range->adjustment->upper -
524                                range->adjustment->lower -
525                                range->adjustment->page_size) *
526                               (new_pos - left) / (right - left) +
527                               range->adjustment->lower);
528
529   if (range->digits >= 0)
530     {
531       char buffer[64];
532
533       sprintf (buffer, "%0.*f", range->digits, range->adjustment->value);
534       sscanf (buffer, "%f", &range->adjustment->value);
535     }
536
537   if (old_value != range->adjustment->value)
538     {
539       if (range->policy == GTK_UPDATE_CONTINUOUS)
540         {
541           gtk_signal_emit_by_name (GTK_OBJECT (range->adjustment), "value_changed");
542         }
543       else
544         {
545           gtk_range_slider_update (range);
546           gtk_range_clear_background (range);
547
548           if (range->policy == GTK_UPDATE_DELAYED)
549             {
550               gtk_range_remove_timer (range);
551               range->timer = gtk_timeout_add (SCROLL_DELAY_LENGTH,
552                                               (GtkFunction) RANGE_CLASS (range)->timer,
553                                               (gpointer) range);
554             }
555         }
556     }
557 }
558
559 void
560 gtk_range_default_vmotion (GtkRange *range,
561                            gint      xdelta,
562                            gint      ydelta)
563 {
564   gdouble old_value;
565   gint top, bottom;
566   gint slider_x, slider_y;
567   gint new_pos;
568
569   g_return_if_fail (range != NULL);
570   g_return_if_fail (GTK_IS_RANGE (range));
571
572   range = GTK_RANGE (range);
573
574   gdk_window_get_position (range->slider, &slider_x, &slider_y);
575   gtk_range_trough_vdims (range, &top, &bottom);
576
577   if (bottom == top)
578     return;
579
580   new_pos = slider_y + ydelta;
581
582   if (new_pos < top)
583     new_pos = top;
584   else if (new_pos > bottom)
585     new_pos = bottom;
586
587   old_value = range->adjustment->value;
588   range->adjustment->value = ((range->adjustment->upper -
589                                range->adjustment->lower -
590                                range->adjustment->page_size) *
591                               (new_pos - top) / (bottom - top) +
592                               range->adjustment->lower);
593
594   if (range->digits >= 0)
595     {
596       char buffer[64];
597
598       sprintf (buffer, "%0.*f", range->digits, range->adjustment->value);
599       sscanf (buffer, "%f", &range->adjustment->value);
600     }
601
602   if (old_value != range->adjustment->value)
603     {
604       if (range->policy == GTK_UPDATE_CONTINUOUS)
605         {
606           gtk_signal_emit_by_name (GTK_OBJECT (range->adjustment), "value_changed");
607         }
608       else
609         {
610           gtk_range_slider_update (range);
611           gtk_range_clear_background (range);
612
613           if (range->policy == GTK_UPDATE_DELAYED)
614             {
615               gtk_range_remove_timer (range);
616               range->timer = gtk_timeout_add (SCROLL_DELAY_LENGTH,
617                                               (GtkFunction) RANGE_CLASS (range)->timer,
618                                               (gpointer) range);
619             }
620         }
621     }
622 }
623
624
625 static void
626 gtk_range_finalize (GtkObject *object)
627 {
628   GtkRange *range;
629
630   g_return_if_fail (object != NULL);
631   g_return_if_fail (GTK_IS_RANGE (object));
632
633   range = GTK_RANGE (object);
634
635   if (range->adjustment)
636     gtk_object_unref (GTK_OBJECT (range->adjustment));
637
638   (* GTK_OBJECT_CLASS (parent_class)->finalize) (object);
639 }
640
641 static void
642 gtk_range_draw (GtkWidget    *widget,
643                 GdkRectangle *area)
644 {
645   GtkRange *range;
646
647   g_return_if_fail (widget != NULL);
648   g_return_if_fail (GTK_IS_RANGE (widget));
649   g_return_if_fail (area != NULL);
650
651   if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_MAPPED (widget))
652     {
653       range = GTK_RANGE (widget);
654
655       gtk_range_draw_background (range);
656       gtk_range_draw_trough (range);
657       gtk_range_draw_slider (range);
658       gtk_range_draw_step_forw (range);
659       gtk_range_draw_step_back (range);
660     }
661 }
662
663 static void
664 gtk_range_draw_focus (GtkWidget *widget)
665 {
666   g_return_if_fail (widget != NULL);
667   g_return_if_fail (GTK_IS_RANGE (widget));
668
669   if (GTK_WIDGET_DRAWABLE (widget))
670     gtk_range_draw_trough (GTK_RANGE (widget));
671 }
672
673 static void
674 gtk_range_unrealize (GtkWidget *widget)
675 {
676   GtkRange *range;
677
678   g_return_if_fail (widget != NULL);
679   g_return_if_fail (GTK_IS_RANGE (widget));
680
681   range = GTK_RANGE (widget);
682
683   if (range->slider)
684     {
685       gdk_window_set_user_data (range->slider, NULL);
686       gdk_window_destroy (range->slider);
687       range->slider = NULL;
688     }
689   if (range->trough)
690     {
691       gdk_window_set_user_data (range->trough, NULL);
692       gdk_window_destroy (range->trough);
693       range->trough = NULL;
694     }
695   if (range->step_forw)
696     {
697       gdk_window_set_user_data (range->step_forw, NULL);
698       gdk_window_destroy (range->step_forw);
699       range->step_forw = NULL;
700     }
701   if (range->step_back)
702     {
703       gdk_window_set_user_data (range->step_back, NULL);
704       gdk_window_destroy (range->step_back);
705       range->step_back = NULL;
706     }
707
708   if (GTK_WIDGET_CLASS (parent_class)->unrealize)
709     (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
710 }
711
712 static gint
713 gtk_range_expose (GtkWidget      *widget,
714                   GdkEventExpose *event)
715 {
716   GtkRange *range;
717
718   g_return_val_if_fail (widget != NULL, FALSE);
719   g_return_val_if_fail (GTK_IS_RANGE (widget), FALSE);
720   g_return_val_if_fail (event != NULL, FALSE);
721
722   range = GTK_RANGE (widget);
723
724   if (event->window == range->trough)
725     {
726       /* Don't redraw if we are only exposing the literal trough region.
727        * this may not work correctly if someone overrides the default
728        * trough-drawing handler. (Probably should really pass another
729        * argument - the redrawn area to all the drawing functions)
730        */
731       gint xt = widget->style->klass->xthickness;
732       gint yt = widget->style->klass->ythickness;
733       
734       if (!((event->area.x >= xt) &&
735             (event->area.y >= yt) &&
736             (event->area.x + event->area.width <= 
737              widget->allocation.width - xt) &&
738             (event->area.y + event->area.height <= 
739              widget->allocation.height - xt)))
740         gtk_range_draw_trough (range);
741     }
742   else if (event->window == widget->window)
743     {
744       gtk_range_draw_background (range);
745     }
746   else if (event->window == range->slider)
747     {
748       gtk_range_draw_slider (range);
749     }
750   else if (event->window == range->step_forw)
751     {
752       gtk_range_draw_step_forw (range);
753     }
754   else if (event->window == range->step_back)
755     {
756       gtk_range_draw_step_back (range);
757     }
758   return FALSE;
759 }
760
761 static gint
762 gtk_range_button_press (GtkWidget      *widget,
763                         GdkEventButton *event)
764 {
765   GtkRange *range;
766   gint trough_part;
767   gfloat jump_perc;
768
769   g_return_val_if_fail (widget != NULL, FALSE);
770   g_return_val_if_fail (GTK_IS_RANGE (widget), FALSE);
771   g_return_val_if_fail (event != NULL, FALSE);
772
773   if (!GTK_WIDGET_HAS_FOCUS (widget))
774     gtk_widget_grab_focus (widget);
775
776   jump_perc = -1;
777   range = GTK_RANGE (widget);
778   if (range->button == 0)
779     {
780       gtk_grab_add (widget);
781
782       range->button = event->button;
783       range->x_click_point = event->x;
784       range->y_click_point = event->y;
785
786       if (event->window == range->trough)
787         {
788           range->click_child = RANGE_CLASS (range)->trough;
789           
790           if (range->button == 2)
791             trough_part = gtk_range_trough_click (range, event->x, event->y, &jump_perc);
792           else
793             trough_part = gtk_range_trough_click (range, event->x, event->y, NULL);
794           
795           range->scroll_type = GTK_SCROLL_NONE;
796           if (trough_part == GTK_TROUGH_START)
797             range->scroll_type = GTK_SCROLL_PAGE_BACKWARD;
798           else if (trough_part == GTK_TROUGH_END)
799             range->scroll_type = GTK_SCROLL_PAGE_FORWARD;
800           else if (trough_part == GTK_TROUGH_JUMP &&
801                    jump_perc >= 0 && jump_perc <= 1)
802             range->scroll_type = GTK_SCROLL_JUMP;
803           
804           if (range->scroll_type != GTK_SCROLL_NONE)
805             {
806               gtk_range_scroll (range, jump_perc);
807               gtk_range_add_timer (range);
808             }
809         }
810       else if (event->window == range->slider)
811         {
812           range->click_child = RANGE_CLASS (range)->slider;
813           range->scroll_type = GTK_SCROLL_NONE;
814         }
815       else if (event->window == range->step_forw)
816         {
817           range->click_child = RANGE_CLASS (range)->step_forw;
818           range->scroll_type = GTK_SCROLL_STEP_FORWARD;
819
820           gtk_range_scroll (range, -1);
821           gtk_range_add_timer (range);
822           gtk_range_draw_step_forw (range);
823         }
824       else if (event->window == range->step_back)
825         {
826           range->click_child = RANGE_CLASS (range)->step_back;
827           range->scroll_type = GTK_SCROLL_STEP_BACKWARD;
828
829           gtk_range_scroll (range, -1);
830           gtk_range_add_timer (range);
831           gtk_range_draw_step_back (range);
832         }
833     }
834
835   return FALSE;
836 }
837
838 static gint
839 gtk_range_button_release (GtkWidget      *widget,
840                           GdkEventButton *event)
841 {
842   GtkRange *range;
843
844   g_return_val_if_fail (widget != NULL, FALSE);
845   g_return_val_if_fail (GTK_IS_RANGE (widget), FALSE);
846   g_return_val_if_fail (event != NULL, FALSE);
847
848   range = GTK_RANGE (widget);
849
850   if (range->button == event->button)
851     {
852       gtk_grab_remove (widget);
853
854       range->button = 0;
855       range->x_click_point = -1;
856       range->y_click_point = -1;
857
858       if (range->click_child == RANGE_CLASS (range)->slider)
859         {
860           if (range->policy == GTK_UPDATE_DELAYED)
861             gtk_range_remove_timer (range);
862
863           if ((range->policy != GTK_UPDATE_CONTINUOUS) &&
864               (range->old_value != range->adjustment->value))
865             gtk_signal_emit_by_name (GTK_OBJECT (range->adjustment), "value_changed");
866         }
867       else if ((range->click_child == RANGE_CLASS (range)->trough) ||
868                (range->click_child == RANGE_CLASS (range)->step_forw) ||
869                (range->click_child == RANGE_CLASS (range)->step_back))
870         {
871           gtk_range_remove_timer (range);
872
873           if ((range->policy != GTK_UPDATE_CONTINUOUS) &&
874               (range->old_value != range->adjustment->value))
875             gtk_signal_emit_by_name (GTK_OBJECT (range->adjustment), "value_changed");
876
877           if (range->click_child == RANGE_CLASS (range)->step_forw)
878             {
879               range->click_child = 0;
880               gtk_range_draw_step_forw (range);
881             }
882           else if (range->click_child == RANGE_CLASS (range)->step_back)
883             {
884               range->click_child = 0;
885               gtk_range_draw_step_back (range);
886             }
887         }
888
889       range->click_child = 0;
890     }
891
892   return FALSE;
893 }
894
895 static gint
896 gtk_range_motion_notify (GtkWidget      *widget,
897                          GdkEventMotion *event)
898 {
899   GtkRange *range;
900   GdkModifierType mods;
901   gint x, y, mask;
902
903   g_return_val_if_fail (widget != NULL, FALSE);
904   g_return_val_if_fail (GTK_IS_RANGE (widget), FALSE);
905   g_return_val_if_fail (event != NULL, FALSE);
906
907   range = GTK_RANGE (widget);
908
909   if (range->click_child == RANGE_CLASS (range)->slider)
910     {
911       x = event->x;
912       y = event->y;
913
914       if (event->is_hint || (event->window != range->slider))
915         gdk_window_get_pointer (range->slider, &x, &y, &mods);
916
917       switch (range->button)
918         {
919         case 1:
920           mask = GDK_BUTTON1_MASK;
921           break;
922         case 2:
923           mask = GDK_BUTTON2_MASK;
924           break;
925         case 3:
926           mask = GDK_BUTTON3_MASK;
927           break;
928         default:
929           mask = 0;
930           break;
931         }
932
933       if (mods & mask)
934         {
935           if (RANGE_CLASS (range)->motion)
936             (* RANGE_CLASS (range)->motion) (range, x - range->x_click_point, y - range->y_click_point);
937         }
938     }
939
940   return FALSE;
941 }
942
943 static gint
944 gtk_range_key_press (GtkWidget   *widget,
945                      GdkEventKey *event)
946 {
947   GtkRange *range;
948   gint return_val;
949   GtkScrollType scroll = GTK_SCROLL_NONE;
950   GtkTroughType pos = GTK_TROUGH_NONE;
951
952   g_return_val_if_fail (widget != NULL, FALSE);
953   g_return_val_if_fail (GTK_IS_RANGE (widget), FALSE);
954   g_return_val_if_fail (event != NULL, FALSE);
955
956   range = GTK_RANGE (widget);
957   return_val = FALSE;
958
959   if (RANGE_CLASS (range)->trough_keys)
960     return_val = (* RANGE_CLASS (range)->trough_keys) (range, event, &scroll, &pos);
961
962   if (return_val)
963     {
964       if (scroll != GTK_SCROLL_NONE)
965         {
966           range->scroll_type = scroll;
967           gtk_range_scroll (range, -1);
968           if (range->old_value != range->adjustment->value)
969             {
970               gtk_signal_emit_by_name (GTK_OBJECT (range->adjustment), "value_changed");
971               switch (range->scroll_type)
972                 {
973                 case GTK_SCROLL_STEP_BACKWARD:
974                   gtk_range_draw_step_back (range);
975                   break;
976                 case GTK_SCROLL_STEP_FORWARD:
977                   gtk_range_draw_step_forw (range);
978                   break;
979                 }
980             }
981         }
982       if (pos != GTK_TROUGH_NONE)
983         {
984           if (pos == GTK_TROUGH_START)
985             range->adjustment->value = range->adjustment->lower;
986           else if (pos == GTK_TROUGH_END)
987             range->adjustment->value =
988               range->adjustment->upper - range->adjustment->page_size;
989
990           if (range->old_value != range->adjustment->value)
991             {
992               gtk_signal_emit_by_name (GTK_OBJECT (range->adjustment),
993                                        "value_changed");
994
995               gtk_range_slider_update (range);
996               gtk_range_clear_background (range);
997             }
998         }
999     }
1000   return return_val;
1001 }
1002
1003 static gint
1004 gtk_range_enter_notify (GtkWidget        *widget,
1005                         GdkEventCrossing *event)
1006 {
1007   GtkRange *range;
1008
1009   g_return_val_if_fail (widget != NULL, FALSE);
1010   g_return_val_if_fail (GTK_IS_RANGE (widget), FALSE);
1011   g_return_val_if_fail (event != NULL, FALSE);
1012
1013   range = GTK_RANGE (widget);
1014
1015   if (event->window == range->trough)
1016     {
1017       range->in_child = RANGE_CLASS (range)->trough;
1018     }
1019   else if (event->window == range->slider)
1020     {
1021       range->in_child = RANGE_CLASS (range)->slider;
1022
1023       if ((range->click_child == 0) ||
1024           (range->click_child == RANGE_CLASS (range)->trough))
1025         gtk_range_draw_slider (range);
1026     }
1027   else if (event->window == range->step_forw)
1028     {
1029       range->in_child = RANGE_CLASS (range)->step_forw;
1030
1031       if ((range->click_child == 0) ||
1032           (range->click_child == RANGE_CLASS (range)->trough))
1033         gtk_range_draw_step_forw (range);
1034     }
1035   else if (event->window == range->step_back)
1036     {
1037       range->in_child = RANGE_CLASS (range)->step_back;
1038
1039       if ((range->click_child == 0) ||
1040           (range->click_child == RANGE_CLASS (range)->trough))
1041         gtk_range_draw_step_back (range);
1042     }
1043
1044   return FALSE;
1045 }
1046
1047 static gint
1048 gtk_range_leave_notify (GtkWidget        *widget,
1049                         GdkEventCrossing *event)
1050 {
1051   GtkRange *range;
1052
1053   g_return_val_if_fail (widget != NULL, FALSE);
1054   g_return_val_if_fail (GTK_IS_RANGE (widget), FALSE);
1055   g_return_val_if_fail (event != NULL, FALSE);
1056
1057   range = GTK_RANGE (widget);
1058
1059   range->in_child = 0;
1060
1061   if (event->window == range->trough)
1062     {
1063     }
1064   else if (event->window == range->slider)
1065     {
1066       if ((range->click_child == 0) ||
1067           (range->click_child == RANGE_CLASS (range)->trough))
1068         gtk_range_draw_slider (range);
1069     }
1070   else if (event->window == range->step_forw)
1071     {
1072       if ((range->click_child == 0) ||
1073           (range->click_child == RANGE_CLASS (range)->trough))
1074         gtk_range_draw_step_forw (range);
1075     }
1076   else if (event->window == range->step_back)
1077     {
1078       if ((range->click_child == 0) ||
1079           (range->click_child == RANGE_CLASS (range)->trough))
1080         gtk_range_draw_step_back (range);
1081     }
1082
1083   return FALSE;
1084 }
1085
1086 static gint
1087 gtk_range_focus_in (GtkWidget     *widget,
1088                     GdkEventFocus *event)
1089 {
1090   g_return_val_if_fail (widget != NULL, FALSE);
1091   g_return_val_if_fail (GTK_IS_RANGE (widget), FALSE);
1092   g_return_val_if_fail (event != NULL, FALSE);
1093
1094   GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS);
1095   gtk_widget_draw_focus (widget);
1096
1097   return FALSE;
1098 }
1099
1100 static gint
1101 gtk_range_focus_out (GtkWidget     *widget,
1102                      GdkEventFocus *event)
1103 {
1104   g_return_val_if_fail (widget != NULL, FALSE);
1105   g_return_val_if_fail (GTK_IS_RANGE (widget), FALSE);
1106   g_return_val_if_fail (event != NULL, FALSE);
1107
1108   GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS);
1109   gtk_widget_draw_focus (widget);
1110
1111   return FALSE;
1112 }
1113
1114 static void
1115 gtk_real_range_draw_trough (GtkRange *range)
1116 {
1117   g_return_if_fail (range != NULL);
1118   g_return_if_fail (GTK_IS_RANGE (range));
1119
1120   if (range->trough)
1121      {
1122         gtk_paint_box (GTK_WIDGET (range)->style, range->trough,
1123                        GTK_STATE_ACTIVE, GTK_SHADOW_IN,
1124                        NULL, GTK_WIDGET(range), "trough",
1125                        0, 0, -1, -1);
1126         if (GTK_WIDGET_HAS_FOCUS (range))
1127           gtk_paint_focus (GTK_WIDGET (range)->style,
1128                           range->trough,
1129                            NULL, GTK_WIDGET(range), "trough",
1130                           0, 0, -1, -1);
1131     }
1132 }
1133
1134 static void
1135 gtk_real_range_draw_slider (GtkRange *range)
1136 {
1137   GtkStateType state_type;
1138    
1139   g_return_if_fail (range != NULL);
1140   g_return_if_fail (GTK_IS_RANGE (range));
1141    
1142   if (range->slider)
1143     {
1144       if ((range->in_child == RANGE_CLASS (range)->slider) ||
1145           (range->click_child == RANGE_CLASS (range)->slider))
1146         state_type = GTK_STATE_PRELIGHT;
1147       else
1148         state_type = GTK_STATE_NORMAL;
1149       gtk_paint_box (GTK_WIDGET (range)->style, range->slider,
1150                      state_type, GTK_SHADOW_OUT,
1151                      NULL, GTK_WIDGET (range), "slider",
1152                      0, 0, -1, -1);
1153     }
1154 }
1155
1156 static gint
1157 gtk_real_range_timer (GtkRange *range)
1158 {
1159   gint return_val;
1160
1161   g_return_val_if_fail (range != NULL, FALSE);
1162   g_return_val_if_fail (GTK_IS_RANGE (range), FALSE);
1163
1164   return_val = TRUE;
1165   if (range->click_child == RANGE_CLASS (range)->slider)
1166     {
1167       if (range->policy == GTK_UPDATE_DELAYED)
1168         gtk_signal_emit_by_name (GTK_OBJECT (range->adjustment), "value_changed");
1169       return_val = FALSE;
1170     }
1171   else
1172     {
1173       GdkModifierType mods, mask;
1174
1175       if (!range->timer)
1176         {
1177           return_val = FALSE;
1178           if (range->need_timer)
1179             range->timer = gtk_timeout_add (SCROLL_TIMER_LENGTH,
1180                                             (GtkFunction) RANGE_CLASS (range)->timer,
1181                                             (gpointer) range);
1182           else
1183             return FALSE;
1184           range->need_timer = FALSE;
1185         }
1186
1187       switch (range->button)
1188         {
1189         case 1:
1190           mask = GDK_BUTTON1_MASK;
1191           break;
1192         case 2:
1193           mask = GDK_BUTTON2_MASK;
1194           break;
1195         case 3:
1196           mask = GDK_BUTTON3_MASK;
1197           break;
1198         default:
1199           mask = 0;
1200           break;
1201         }
1202
1203       gdk_window_get_pointer (range->slider, NULL, NULL, &mods);
1204
1205       if (mods & mask)
1206         return_val = gtk_range_scroll (range, -1);
1207     }
1208
1209   return return_val;
1210 }
1211
1212 static gint
1213 gtk_range_scroll (GtkRange *range,
1214                   gfloat    jump_perc)
1215 {
1216   gfloat new_value;
1217   gint return_val;
1218
1219   g_return_val_if_fail (range != NULL, FALSE);
1220   g_return_val_if_fail (GTK_IS_RANGE (range), FALSE);
1221
1222   new_value = range->adjustment->value;
1223   return_val = TRUE;
1224
1225   switch (range->scroll_type)
1226     {
1227     case GTK_SCROLL_NONE:
1228       break;
1229       
1230     case GTK_SCROLL_JUMP:
1231       if (jump_perc >= 0 && jump_perc <= 1)
1232         {
1233           new_value = (range->adjustment->lower +
1234                        (range->adjustment->upper - range->adjustment->page_size -
1235                         range->adjustment->lower) * jump_perc);
1236         }
1237       break;
1238       
1239     case GTK_SCROLL_STEP_BACKWARD:
1240       new_value -= range->adjustment->step_increment;
1241       if (new_value <= range->adjustment->lower)
1242         {
1243           new_value = range->adjustment->lower;
1244           return_val = FALSE;
1245           range->timer = 0;
1246         }
1247       break;
1248
1249     case GTK_SCROLL_STEP_FORWARD:
1250       new_value += range->adjustment->step_increment;
1251       if (new_value >= (range->adjustment->upper - range->adjustment->page_size))
1252         {
1253           new_value = range->adjustment->upper - range->adjustment->page_size;
1254           return_val = FALSE;
1255           range->timer = 0;
1256         }
1257       break;
1258
1259     case GTK_SCROLL_PAGE_BACKWARD:
1260       new_value -= range->adjustment->page_increment;
1261       if (new_value <= range->adjustment->lower)
1262         {
1263           new_value = range->adjustment->lower;
1264           return_val = FALSE;
1265           range->timer = 0;
1266         }
1267       break;
1268
1269     case GTK_SCROLL_PAGE_FORWARD:
1270       new_value += range->adjustment->page_increment;
1271       if (new_value >= (range->adjustment->upper - range->adjustment->page_size))
1272         {
1273           new_value = range->adjustment->upper - range->adjustment->page_size;
1274           return_val = FALSE;
1275           range->timer = 0;
1276         }
1277       break;
1278     }
1279
1280   if (new_value != range->adjustment->value)
1281     {
1282       range->adjustment->value = new_value;
1283
1284       if ((range->policy == GTK_UPDATE_CONTINUOUS) ||
1285           (!return_val && (range->policy == GTK_UPDATE_DELAYED)))
1286         {
1287           gtk_signal_emit_by_name (GTK_OBJECT (range->adjustment), "value_changed");
1288         }
1289       else
1290         {
1291           gtk_range_slider_update (range);
1292           gtk_range_clear_background (range);
1293         }
1294     }
1295
1296   return return_val;
1297 }
1298
1299
1300 static void
1301 gtk_range_add_timer (GtkRange *range)
1302 {
1303   g_return_if_fail (range != NULL);
1304   g_return_if_fail (GTK_IS_RANGE (range));
1305
1306   if (!range->timer)
1307     {
1308       range->need_timer = TRUE;
1309       range->timer = gtk_timeout_add (SCROLL_INITIAL_DELAY,
1310                                       (GtkFunction) RANGE_CLASS (range)->timer,
1311                                       (gpointer) range);
1312     }
1313 }
1314
1315 static void
1316 gtk_range_remove_timer (GtkRange *range)
1317 {
1318   g_return_if_fail (range != NULL);
1319   g_return_if_fail (GTK_IS_RANGE (range));
1320
1321   if (range->timer)
1322     {
1323       gtk_timeout_remove (range->timer);
1324       range->timer = 0;
1325     }
1326   range->need_timer = FALSE;
1327 }
1328
1329 static void
1330 gtk_range_adjustment_changed (GtkAdjustment *adjustment,
1331                               gpointer       data)
1332 {
1333   GtkRange *range;
1334
1335   g_return_if_fail (adjustment != NULL);
1336   g_return_if_fail (data != NULL);
1337
1338   range = GTK_RANGE (data);
1339
1340   if (((range->old_lower != adjustment->lower) ||
1341        (range->old_upper != adjustment->upper) ||
1342        (range->old_page_size != adjustment->page_size)) &&
1343       (range->old_value == adjustment->value))
1344     {
1345       if ((adjustment->lower == adjustment->upper) ||
1346           (range->old_lower == (range->old_upper - range->old_page_size)))
1347         {
1348           adjustment->value = adjustment->lower;
1349           gtk_signal_emit_by_name (GTK_OBJECT (adjustment), "value_changed");
1350         }
1351     }
1352
1353   if ((range->old_value != adjustment->value) ||
1354       (range->old_lower != adjustment->lower) ||
1355       (range->old_upper != adjustment->upper) ||
1356       (range->old_page_size != adjustment->page_size))
1357     {
1358       gtk_range_slider_update (range);
1359       gtk_range_clear_background (range);
1360
1361       range->old_value = adjustment->value;
1362       range->old_lower = adjustment->lower;
1363       range->old_upper = adjustment->upper;
1364       range->old_page_size = adjustment->page_size;
1365     }
1366 }
1367
1368 static void
1369 gtk_range_adjustment_value_changed (GtkAdjustment *adjustment,
1370                                     gpointer       data)
1371 {
1372   GtkRange *range;
1373
1374   g_return_if_fail (adjustment != NULL);
1375   g_return_if_fail (data != NULL);
1376
1377   range = GTK_RANGE (data);
1378
1379   if (range->old_value != adjustment->value)
1380     {
1381       gtk_range_slider_update (range);
1382       gtk_range_clear_background (range);
1383
1384       range->old_value = adjustment->value;
1385     }
1386 }
1387
1388
1389 static void
1390 gtk_range_trough_hdims (GtkRange *range,
1391                         gint     *left,
1392                         gint     *right)
1393 {
1394   gint trough_width;
1395   gint slider_length;
1396   gint tmp_width;
1397   gint tleft;
1398   gint tright;
1399
1400   g_return_if_fail (range != NULL);
1401
1402   gdk_window_get_size (range->trough, &trough_width, NULL);
1403   gdk_window_get_size (range->slider, &slider_length, NULL);
1404
1405   tleft = GTK_WIDGET (range)->style->klass->xthickness;
1406   tright = trough_width - slider_length - GTK_WIDGET (range)->style->klass->xthickness;
1407
1408   if (range->step_back)
1409     {
1410       gdk_window_get_size (range->step_back, &tmp_width, NULL);
1411       tleft += (tmp_width + RANGE_CLASS (range)->stepper_slider_spacing);
1412     }
1413
1414   if (range->step_forw)
1415     {
1416       gdk_window_get_size (range->step_forw, &tmp_width, NULL);
1417       tright -= (tmp_width + RANGE_CLASS (range)->stepper_slider_spacing);
1418     }
1419
1420   if (left)
1421     *left = tleft;
1422   if (right)
1423     *right = tright;
1424 }
1425
1426 static void
1427 gtk_range_trough_vdims (GtkRange *range,
1428                         gint     *top,
1429                         gint     *bottom)
1430 {
1431   gint trough_height;
1432   gint slider_length;
1433   gint tmp_height;
1434   gint ttop;
1435   gint tbottom;
1436
1437   g_return_if_fail (range != NULL);
1438
1439   gdk_window_get_size (range->trough, NULL, &trough_height);
1440   gdk_window_get_size (range->slider, NULL, &slider_length);
1441
1442   ttop = GTK_WIDGET (range)->style->klass->ythickness;
1443   tbottom = trough_height - slider_length - GTK_WIDGET (range)->style->klass->ythickness;
1444
1445   if (range->step_back)
1446     {
1447       gdk_window_get_size (range->step_back, NULL, &tmp_height);
1448       ttop += (tmp_height + RANGE_CLASS (range)->stepper_slider_spacing);
1449     }
1450
1451   if (range->step_forw)
1452     {
1453       gdk_window_get_size (range->step_forw, NULL, &tmp_height);
1454       tbottom -= (tmp_height + RANGE_CLASS (range)->stepper_slider_spacing);
1455     }
1456
1457   if (top)
1458     *top = ttop;
1459   if (bottom)
1460     *bottom = tbottom;
1461 }
1462
1463 static void
1464 gtk_range_style_set (GtkWidget *widget,
1465                       GtkStyle  *previous_style)
1466 {
1467   GtkRange *range;
1468
1469   g_return_if_fail (widget != NULL);
1470   g_return_if_fail (GTK_IS_RANGE (widget));
1471
1472   range = GTK_RANGE (widget);
1473
1474   if (GTK_WIDGET_REALIZED (widget) &&
1475       !GTK_WIDGET_NO_WINDOW (widget))
1476     {
1477        if (range->trough)
1478         {
1479           gtk_style_set_background (widget->style, range->trough, GTK_STATE_ACTIVE);
1480           if (GTK_WIDGET_DRAWABLE (widget))
1481             gdk_window_clear (range->trough);
1482         }
1483       /* The draw will take care of the slider */
1484
1485       if (range->step_forw)
1486         {
1487           gtk_style_set_background (widget->style, range->step_forw, GTK_STATE_ACTIVE);
1488           if (GTK_WIDGET_DRAWABLE (widget))
1489             gdk_window_clear (range->step_forw);
1490         }
1491       if (range->step_back)
1492         {
1493           gtk_style_set_background (widget->style, range->step_back, GTK_STATE_ACTIVE);
1494           if (GTK_WIDGET_DRAWABLE (widget))
1495             gdk_window_clear (range->step_back);
1496         }
1497        gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
1498     }
1499 }