]> Pileus Git - ~andy/gtk/blob - gtk/gtkrange.c
call the base class init fucntions from all parent types upon class
[~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         /* reversed_1 */ NULL,
99         /* reversed_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->draw_trough = gtk_real_range_draw_trough;
146   class->draw_slider = gtk_real_range_draw_slider;
147   class->draw_step_forw = NULL;
148   class->draw_step_back = NULL;
149   class->trough_click = NULL;
150   class->trough_keys = NULL;
151   class->motion = NULL;
152   class->timer = gtk_real_range_timer;
153 }
154
155 static void
156 gtk_range_init (GtkRange *range)
157 {
158   range->trough = NULL;
159   range->slider = NULL;
160   range->step_forw = NULL;
161   range->step_back = NULL;
162
163   range->x_click_point = 0;
164   range->y_click_point = 0;
165   range->button = 0;
166   range->digits = -1;
167   range->policy = GTK_UPDATE_CONTINUOUS;
168   range->scroll_type = GTK_SCROLL_NONE;
169   range->in_child = 0;
170   range->click_child = 0;
171   range->need_timer = FALSE;
172   range->timer = 0;
173   range->old_value = 0.0;
174   range->old_lower = 0.0;
175   range->old_upper = 0.0;
176   range->old_page_size = 0.0;
177   range->adjustment = NULL;
178 }
179
180 GtkAdjustment*
181 gtk_range_get_adjustment (GtkRange *range)
182 {
183   g_return_val_if_fail (range != NULL, NULL);
184   g_return_val_if_fail (GTK_IS_RANGE (range), NULL);
185
186   return range->adjustment;
187 }
188
189 void
190 gtk_range_set_update_policy (GtkRange      *range,
191                              GtkUpdateType  policy)
192 {
193   g_return_if_fail (range != NULL);
194   g_return_if_fail (GTK_IS_RANGE (range));
195
196   range->policy = policy;
197 }
198
199 void
200 gtk_range_set_adjustment (GtkRange      *range,
201                           GtkAdjustment *adjustment)
202 {
203   g_return_if_fail (range != NULL);
204   g_return_if_fail (GTK_IS_RANGE (range));
205
206   if (range->adjustment != adjustment)
207     {
208       if (range->adjustment)
209         {
210           gtk_signal_disconnect_by_data (GTK_OBJECT (range->adjustment),
211                                          (gpointer) range);
212           gtk_object_unref (GTK_OBJECT (range->adjustment));
213         }
214       range->adjustment = adjustment;
215       if (adjustment)
216         {
217           gtk_object_ref (GTK_OBJECT (adjustment));
218           gtk_object_sink (GTK_OBJECT (adjustment));
219
220           gtk_signal_connect (GTK_OBJECT (adjustment), "changed",
221                               (GtkSignalFunc) gtk_range_adjustment_changed,
222                               (gpointer) range);
223           gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed",
224                               (GtkSignalFunc) gtk_range_adjustment_value_changed,
225                               (gpointer) range);
226
227           range->old_value = adjustment->value;
228           range->old_lower = adjustment->lower;
229           range->old_upper = adjustment->upper;
230           range->old_page_size = adjustment->page_size;
231           
232           gtk_range_adjustment_changed (adjustment, (gpointer) range);
233         }
234     }
235 }
236
237 void
238 gtk_range_draw_background (GtkRange *range)
239 {
240   g_return_if_fail (range != NULL);
241   g_return_if_fail (GTK_IS_RANGE (range));
242
243   if (range->trough && RANGE_CLASS (range)->draw_background)
244     (* RANGE_CLASS (range)->draw_background) (range);
245 }
246
247 void
248 gtk_range_draw_trough (GtkRange *range)
249 {
250   g_return_if_fail (range != NULL);
251   g_return_if_fail (GTK_IS_RANGE (range));
252
253   if (range->trough && RANGE_CLASS (range)->draw_trough)
254     (* RANGE_CLASS (range)->draw_trough) (range);
255 }
256
257 void
258 gtk_range_draw_slider (GtkRange *range)
259 {
260   g_return_if_fail (range != NULL);
261   g_return_if_fail (GTK_IS_RANGE (range));
262
263   if (range->slider && RANGE_CLASS (range)->draw_slider)
264     (* RANGE_CLASS (range)->draw_slider) (range);
265 }
266
267 void
268 gtk_range_draw_step_forw (GtkRange *range)
269 {
270   g_return_if_fail (range != NULL);
271   g_return_if_fail (GTK_IS_RANGE (range));
272
273   if (range->step_forw && RANGE_CLASS (range)->draw_step_forw)
274     (* RANGE_CLASS (range)->draw_step_forw) (range);
275 }
276
277 void
278 gtk_range_draw_step_back (GtkRange *range)
279 {
280   g_return_if_fail (range != NULL);
281   g_return_if_fail (GTK_IS_RANGE (range));
282
283   if (range->step_back && RANGE_CLASS (range)->draw_step_back)
284     (* RANGE_CLASS (range)->draw_step_back) (range);
285 }
286
287 void
288 gtk_range_slider_update (GtkRange *range)
289 {
290   g_return_if_fail (range != NULL);
291   g_return_if_fail (GTK_IS_RANGE (range));
292
293   if (RANGE_CLASS (range)->slider_update)
294     (* RANGE_CLASS (range)->slider_update) (range);
295 }
296
297 gint
298 gtk_range_trough_click (GtkRange *range,
299                         gint      x,
300                         gint      y,
301                         gfloat   *jump_perc)
302 {
303   g_return_val_if_fail (range != NULL, GTK_TROUGH_NONE);
304   g_return_val_if_fail (GTK_IS_RANGE (range), GTK_TROUGH_NONE);
305
306   if (RANGE_CLASS (range)->trough_click)
307     return (* RANGE_CLASS (range)->trough_click) (range, x, y, jump_perc);
308
309   return GTK_TROUGH_NONE;
310 }
311
312 void
313 gtk_range_default_hslider_update (GtkRange *range)
314 {
315   gint left;
316   gint right;
317   gint x;
318
319   g_return_if_fail (range != NULL);
320   g_return_if_fail (GTK_IS_RANGE (range));
321
322   if (GTK_WIDGET_REALIZED (range))
323     {
324       gtk_range_trough_hdims (range, &left, &right);
325       x = left;
326
327       if (range->adjustment->value < range->adjustment->lower)
328         {
329           range->adjustment->value = range->adjustment->lower;
330           gtk_signal_emit_by_name (GTK_OBJECT (range->adjustment), "value_changed");
331         }
332       else if (range->adjustment->value > range->adjustment->upper)
333         {
334           range->adjustment->value = range->adjustment->upper;
335           gtk_signal_emit_by_name (GTK_OBJECT (range->adjustment), "value_changed");
336         }
337
338       if (range->adjustment->lower != (range->adjustment->upper - range->adjustment->page_size))
339         x += ((right - left) * (range->adjustment->value - range->adjustment->lower) /
340               (range->adjustment->upper - range->adjustment->lower - range->adjustment->page_size));
341
342       if (x < left)
343         x = left;
344       else if (x > right)
345         x = right;
346
347       gdk_window_move (range->slider, x, GTK_WIDGET (range)->style->klass->ythickness);
348     }
349 }
350
351 void
352 gtk_range_default_vslider_update (GtkRange *range)
353 {
354   gint top;
355   gint bottom;
356   gint y;
357
358   g_return_if_fail (range != NULL);
359   g_return_if_fail (GTK_IS_RANGE (range));
360
361   if (GTK_WIDGET_REALIZED (range))
362     {
363       gtk_range_trough_vdims (range, &top, &bottom);
364       y = top;
365
366       if (range->adjustment->value < range->adjustment->lower)
367         {
368           range->adjustment->value = range->adjustment->lower;
369           gtk_signal_emit_by_name (GTK_OBJECT (range->adjustment), "value_changed");
370         }
371       else if (range->adjustment->value > range->adjustment->upper)
372         {
373           range->adjustment->value = range->adjustment->upper;
374           gtk_signal_emit_by_name (GTK_OBJECT (range->adjustment), "value_changed");
375         }
376
377       if (range->adjustment->lower != (range->adjustment->upper - range->adjustment->page_size))
378         y += ((bottom - top) * (range->adjustment->value - range->adjustment->lower) /
379               (range->adjustment->upper - range->adjustment->lower - range->adjustment->page_size));
380
381       if (y < top)
382         y = top;
383       else if (y > bottom)
384         y = bottom;
385
386       gdk_window_move (range->slider, GTK_WIDGET (range)->style->klass->xthickness, y);
387     }
388 }
389
390 gint
391 gtk_range_default_htrough_click (GtkRange *range,
392                                  gint      x,
393                                  gint      y,
394                                  gfloat   *jump_perc)
395 {
396   gint ythickness;
397   gint trough_width;
398   gint trough_height;
399   gint slider_x;
400   gint slider_length;
401   gint left, right;
402
403   g_return_val_if_fail (range != NULL, GTK_TROUGH_NONE);
404   g_return_val_if_fail (GTK_IS_RANGE (range), GTK_TROUGH_NONE);
405
406   ythickness = GTK_WIDGET (range)->style->klass->ythickness;
407
408   gtk_range_trough_hdims (range, &left, &right);
409   gdk_window_get_size (range->slider, &slider_length, NULL);
410   right += slider_length;
411               
412   if ((x > left) && (y > ythickness))
413     {
414       gdk_window_get_size (range->trough, &trough_width, &trough_height);
415
416       if ((x < right) && (y < (trough_height - ythickness)))
417         {
418           if (jump_perc)
419             {
420               *jump_perc = ((gdouble) (x - left)) / ((gdouble) (right - left));
421               return GTK_TROUGH_JUMP;
422             }
423           
424           gdk_window_get_position (range->slider, &slider_x, NULL);
425           
426           if (x < slider_x)
427             return GTK_TROUGH_START;
428           else
429             return GTK_TROUGH_END;
430         }
431     }
432
433   return GTK_TROUGH_NONE;
434 }
435
436 gint
437 gtk_range_default_vtrough_click (GtkRange *range,
438                                  gint      x,
439                                  gint      y,
440                                  gfloat   *jump_perc)
441 {
442   gint xthickness;
443   gint trough_width;
444   gint trough_height;
445   gint slider_y;
446   gint top, bottom;
447   gint slider_length;
448
449   g_return_val_if_fail (range != NULL, GTK_TROUGH_NONE);
450   g_return_val_if_fail (GTK_IS_RANGE (range), GTK_TROUGH_NONE);
451
452   xthickness = GTK_WIDGET (range)->style->klass->xthickness;
453
454   gtk_range_trough_vdims (range, &top, &bottom);
455   gdk_window_get_size (range->slider, NULL, &slider_length);
456   bottom += slider_length;
457               
458   if ((x > xthickness) && (y > top))
459     {
460       gdk_window_get_size (range->trough, &trough_width, &trough_height);
461
462       if ((x < (trough_width - xthickness) && (y < bottom)))
463         {
464           if (jump_perc)
465             {
466               *jump_perc = ((gdouble) (y - top)) / ((gdouble) (bottom - top));
467
468               return GTK_TROUGH_JUMP;
469             }
470           
471           gdk_window_get_position (range->slider, NULL, &slider_y);
472           
473           if (y < slider_y)
474             return GTK_TROUGH_START;
475           else
476             return GTK_TROUGH_END;
477         }
478     }
479
480   return GTK_TROUGH_NONE;
481 }
482
483 void
484 gtk_range_default_hmotion (GtkRange *range,
485                            gint      xdelta,
486                            gint      ydelta)
487 {
488   gdouble old_value;
489   gint left, right;
490   gint slider_x, slider_y;
491   gint new_pos;
492
493   g_return_if_fail (range != NULL);
494   g_return_if_fail (GTK_IS_RANGE (range));
495
496   range = GTK_RANGE (range);
497
498   gdk_window_get_position (range->slider, &slider_x, &slider_y);
499   gtk_range_trough_hdims (range, &left, &right);
500
501   if (left == right)
502     return;
503
504   new_pos = slider_x + xdelta;
505
506   if (new_pos < left)
507     new_pos = left;
508   else if (new_pos > right)
509     new_pos = right;
510
511   old_value = range->adjustment->value;
512   range->adjustment->value = ((range->adjustment->upper -
513                                range->adjustment->lower -
514                                range->adjustment->page_size) *
515                               (new_pos - left) / (right - left) +
516                               range->adjustment->lower);
517
518   if (range->digits >= 0)
519     {
520       char buffer[64];
521
522       sprintf (buffer, "%0.*f", range->digits, range->adjustment->value);
523       sscanf (buffer, "%f", &range->adjustment->value);
524     }
525
526   if (old_value != range->adjustment->value)
527     {
528       if (range->policy == GTK_UPDATE_CONTINUOUS)
529         {
530           gtk_signal_emit_by_name (GTK_OBJECT (range->adjustment), "value_changed");
531         }
532       else
533         {
534           gtk_range_slider_update (range);
535           gtk_range_draw_background (range);
536
537           if (range->policy == GTK_UPDATE_DELAYED)
538             {
539               gtk_range_remove_timer (range);
540               range->timer = gtk_timeout_add (SCROLL_DELAY_LENGTH,
541                                               (GtkFunction) RANGE_CLASS (range)->timer,
542                                               (gpointer) range);
543             }
544         }
545     }
546 }
547
548 void
549 gtk_range_default_vmotion (GtkRange *range,
550                            gint      xdelta,
551                            gint      ydelta)
552 {
553   gdouble old_value;
554   gint top, bottom;
555   gint slider_x, slider_y;
556   gint new_pos;
557
558   g_return_if_fail (range != NULL);
559   g_return_if_fail (GTK_IS_RANGE (range));
560
561   range = GTK_RANGE (range);
562
563   gdk_window_get_position (range->slider, &slider_x, &slider_y);
564   gtk_range_trough_vdims (range, &top, &bottom);
565
566   if (bottom == top)
567     return;
568
569   new_pos = slider_y + ydelta;
570
571   if (new_pos < top)
572     new_pos = top;
573   else if (new_pos > bottom)
574     new_pos = bottom;
575
576   old_value = range->adjustment->value;
577   range->adjustment->value = ((range->adjustment->upper -
578                                range->adjustment->lower -
579                                range->adjustment->page_size) *
580                               (new_pos - top) / (bottom - top) +
581                               range->adjustment->lower);
582
583   if (range->digits >= 0)
584     {
585       char buffer[64];
586
587       sprintf (buffer, "%0.*f", range->digits, range->adjustment->value);
588       sscanf (buffer, "%f", &range->adjustment->value);
589     }
590
591   if (old_value != range->adjustment->value)
592     {
593       if (range->policy == GTK_UPDATE_CONTINUOUS)
594         {
595           gtk_signal_emit_by_name (GTK_OBJECT (range->adjustment), "value_changed");
596         }
597       else
598         {
599           gtk_range_slider_update (range);
600           gtk_range_draw_background (range);
601
602           if (range->policy == GTK_UPDATE_DELAYED)
603             {
604               gtk_range_remove_timer (range);
605               range->timer = gtk_timeout_add (SCROLL_DELAY_LENGTH,
606                                               (GtkFunction) RANGE_CLASS (range)->timer,
607                                               (gpointer) range);
608             }
609         }
610     }
611 }
612
613
614 static void
615 gtk_range_finalize (GtkObject *object)
616 {
617   GtkRange *range;
618
619   g_return_if_fail (object != NULL);
620   g_return_if_fail (GTK_IS_RANGE (object));
621
622   range = GTK_RANGE (object);
623
624   if (range->adjustment)
625     gtk_object_unref (GTK_OBJECT (range->adjustment));
626
627   (* GTK_OBJECT_CLASS (parent_class)->finalize) (object);
628 }
629
630 static void
631 gtk_range_draw (GtkWidget    *widget,
632                 GdkRectangle *area)
633 {
634   GtkRange *range;
635
636   g_return_if_fail (widget != NULL);
637   g_return_if_fail (GTK_IS_RANGE (widget));
638   g_return_if_fail (area != NULL);
639
640   if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_MAPPED (widget))
641     {
642       range = GTK_RANGE (widget);
643
644       gtk_range_draw_background (range);
645       gtk_range_draw_trough (range);
646       gtk_range_draw_slider (range);
647       gtk_range_draw_step_forw (range);
648       gtk_range_draw_step_back (range);
649     }
650 }
651
652 static void
653 gtk_range_draw_focus (GtkWidget *widget)
654 {
655   g_return_if_fail (widget != NULL);
656   g_return_if_fail (GTK_IS_RANGE (widget));
657
658   if (GTK_WIDGET_DRAWABLE (widget))
659     gtk_range_draw_trough (GTK_RANGE (widget));
660 }
661
662 static void
663 gtk_range_unrealize (GtkWidget *widget)
664 {
665   GtkRange *range;
666
667   g_return_if_fail (widget != NULL);
668   g_return_if_fail (GTK_IS_RANGE (widget));
669
670   range = GTK_RANGE (widget);
671
672   if (range->slider)
673     {
674       gdk_window_set_user_data (range->slider, NULL);
675       gdk_window_destroy (range->slider);
676       range->slider = NULL;
677     }
678   if (range->trough)
679     {
680       gdk_window_set_user_data (range->trough, NULL);
681       gdk_window_destroy (range->trough);
682       range->trough = NULL;
683     }
684   if (range->step_forw)
685     {
686       gdk_window_set_user_data (range->step_forw, NULL);
687       gdk_window_destroy (range->step_forw);
688       range->step_forw = NULL;
689     }
690   if (range->step_back)
691     {
692       gdk_window_set_user_data (range->step_back, NULL);
693       gdk_window_destroy (range->step_back);
694       range->step_back = NULL;
695     }
696
697   if (GTK_WIDGET_CLASS (parent_class)->unrealize)
698     (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
699 }
700
701 static gint
702 gtk_range_expose (GtkWidget      *widget,
703                   GdkEventExpose *event)
704 {
705   GtkRange *range;
706
707   g_return_val_if_fail (widget != NULL, FALSE);
708   g_return_val_if_fail (GTK_IS_RANGE (widget), FALSE);
709   g_return_val_if_fail (event != NULL, FALSE);
710
711   range = GTK_RANGE (widget);
712
713   if (event->window == range->trough)
714     {
715       /* Don't redraw if we are only exposing the literal trough region.
716        * this may not work correctly if someone overrides the default
717        * trough-drawing handler. (Probably should really pass another
718        * argument - the redrawn area to all the drawing functions)
719        */
720
721       gint xt = widget->style->klass->xthickness;
722       gint yt = widget->style->klass->ythickness;
723       
724       if (!((event->area.x >= xt) &&
725             (event->area.y >= yt) &&
726             (event->area.x + event->area.width <= 
727              widget->allocation.width - xt) &&
728             (event->area.y + event->area.height <= 
729              widget->allocation.height - xt)))
730         gtk_range_draw_trough (range);
731     }
732   else if (event->window == widget->window)
733     {
734       gtk_range_draw_background (range);
735     }
736   else if (event->window == range->slider)
737     {
738       gtk_range_draw_slider (range);
739     }
740   else if (event->window == range->step_forw)
741     {
742       gtk_range_draw_step_forw (range);
743     }
744   else if (event->window == range->step_back)
745     {
746       gtk_range_draw_step_back (range);
747     }
748   return FALSE;
749 }
750
751 static gint
752 gtk_range_button_press (GtkWidget      *widget,
753                         GdkEventButton *event)
754 {
755   GtkRange *range;
756   gint trough_part;
757   gfloat jump_perc;
758
759   g_return_val_if_fail (widget != NULL, FALSE);
760   g_return_val_if_fail (GTK_IS_RANGE (widget), FALSE);
761   g_return_val_if_fail (event != NULL, FALSE);
762
763   if (!GTK_WIDGET_HAS_FOCUS (widget))
764     gtk_widget_grab_focus (widget);
765
766   jump_perc = -1;
767   range = GTK_RANGE (widget);
768   if (range->button == 0)
769     {
770       gtk_grab_add (widget);
771
772       range->button = event->button;
773       range->x_click_point = event->x;
774       range->y_click_point = event->y;
775
776       if (event->window == range->trough)
777         {
778           range->click_child = RANGE_CLASS (range)->trough;
779           
780           if (range->button == 2)
781             trough_part = gtk_range_trough_click (range, event->x, event->y, &jump_perc);
782           else
783             trough_part = gtk_range_trough_click (range, event->x, event->y, NULL);
784           
785           range->scroll_type = GTK_SCROLL_NONE;
786           if (trough_part == GTK_TROUGH_START)
787             range->scroll_type = GTK_SCROLL_PAGE_BACKWARD;
788           else if (trough_part == GTK_TROUGH_END)
789             range->scroll_type = GTK_SCROLL_PAGE_FORWARD;
790           else if (trough_part == GTK_TROUGH_JUMP &&
791                    jump_perc >= 0 && jump_perc <= 1)
792             range->scroll_type = GTK_SCROLL_JUMP;
793           
794           if (range->scroll_type != GTK_SCROLL_NONE)
795             {
796               gtk_range_scroll (range, jump_perc);
797               gtk_range_add_timer (range);
798             }
799         }
800       else if (event->window == range->slider)
801         {
802           range->click_child = RANGE_CLASS (range)->slider;
803           range->scroll_type = GTK_SCROLL_NONE;
804         }
805       else if (event->window == range->step_forw)
806         {
807           range->click_child = RANGE_CLASS (range)->step_forw;
808           range->scroll_type = GTK_SCROLL_STEP_FORWARD;
809
810           gtk_range_scroll (range, -1);
811           gtk_range_add_timer (range);
812           gtk_range_draw_step_forw (range);
813         }
814       else if (event->window == range->step_back)
815         {
816           range->click_child = RANGE_CLASS (range)->step_back;
817           range->scroll_type = GTK_SCROLL_STEP_BACKWARD;
818
819           gtk_range_scroll (range, -1);
820           gtk_range_add_timer (range);
821           gtk_range_draw_step_back (range);
822         }
823     }
824
825   return FALSE;
826 }
827
828 static gint
829 gtk_range_button_release (GtkWidget      *widget,
830                           GdkEventButton *event)
831 {
832   GtkRange *range;
833
834   g_return_val_if_fail (widget != NULL, FALSE);
835   g_return_val_if_fail (GTK_IS_RANGE (widget), FALSE);
836   g_return_val_if_fail (event != NULL, FALSE);
837
838   range = GTK_RANGE (widget);
839
840   if (range->button == event->button)
841     {
842       gtk_grab_remove (widget);
843
844       range->button = 0;
845       range->x_click_point = -1;
846       range->y_click_point = -1;
847
848       if (range->click_child == RANGE_CLASS (range)->slider)
849         {
850           if (range->policy == GTK_UPDATE_DELAYED)
851             gtk_range_remove_timer (range);
852
853           if ((range->policy != GTK_UPDATE_CONTINUOUS) &&
854               (range->old_value != range->adjustment->value))
855             gtk_signal_emit_by_name (GTK_OBJECT (range->adjustment), "value_changed");
856         }
857       else if ((range->click_child == RANGE_CLASS (range)->trough) ||
858                (range->click_child == RANGE_CLASS (range)->step_forw) ||
859                (range->click_child == RANGE_CLASS (range)->step_back))
860         {
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           if (range->click_child == RANGE_CLASS (range)->step_forw)
868             {
869               range->click_child = 0;
870               gtk_range_draw_step_forw (range);
871             }
872           else if (range->click_child == RANGE_CLASS (range)->step_back)
873             {
874               range->click_child = 0;
875               gtk_range_draw_step_back (range);
876             }
877         }
878
879       range->click_child = 0;
880     }
881
882   return FALSE;
883 }
884
885 static gint
886 gtk_range_motion_notify (GtkWidget      *widget,
887                          GdkEventMotion *event)
888 {
889   GtkRange *range;
890   GdkModifierType mods;
891   gint x, y, mask;
892
893   g_return_val_if_fail (widget != NULL, FALSE);
894   g_return_val_if_fail (GTK_IS_RANGE (widget), FALSE);
895   g_return_val_if_fail (event != NULL, FALSE);
896
897   range = GTK_RANGE (widget);
898
899   if (range->click_child == RANGE_CLASS (range)->slider)
900     {
901       x = event->x;
902       y = event->y;
903
904       if (event->is_hint || (event->window != range->slider))
905         gdk_window_get_pointer (range->slider, &x, &y, &mods);
906
907       switch (range->button)
908         {
909         case 1:
910           mask = GDK_BUTTON1_MASK;
911           break;
912         case 2:
913           mask = GDK_BUTTON2_MASK;
914           break;
915         case 3:
916           mask = GDK_BUTTON3_MASK;
917           break;
918         default:
919           mask = 0;
920           break;
921         }
922
923       if (mods & mask)
924         {
925           if (RANGE_CLASS (range)->motion)
926             (* RANGE_CLASS (range)->motion) (range, x - range->x_click_point, y - range->y_click_point);
927         }
928     }
929
930   return FALSE;
931 }
932
933 static gint
934 gtk_range_key_press (GtkWidget   *widget,
935                      GdkEventKey *event)
936 {
937   GtkRange *range;
938   gint return_val;
939   GtkScrollType scroll = GTK_SCROLL_NONE;
940   GtkTroughType pos = GTK_TROUGH_NONE;
941
942   g_return_val_if_fail (widget != NULL, FALSE);
943   g_return_val_if_fail (GTK_IS_RANGE (widget), FALSE);
944   g_return_val_if_fail (event != NULL, FALSE);
945
946   range = GTK_RANGE (widget);
947   return_val = FALSE;
948
949   if (RANGE_CLASS (range)->trough_keys)
950     return_val = (* RANGE_CLASS (range)->trough_keys) (range, event, &scroll, &pos);
951
952   if (return_val)
953     {
954       if (scroll != GTK_SCROLL_NONE)
955         {
956           range->scroll_type = scroll;
957           gtk_range_scroll (range, -1);
958           if (range->old_value != range->adjustment->value)
959             {
960               gtk_signal_emit_by_name (GTK_OBJECT (range->adjustment), "value_changed");
961               switch (range->scroll_type)
962                 {
963                 case GTK_SCROLL_STEP_BACKWARD:
964                   gtk_range_draw_step_back (range);
965                   break;
966                 case GTK_SCROLL_STEP_FORWARD:
967                   gtk_range_draw_step_forw (range);
968                   break;
969                 }
970             }
971         }
972       if (pos != GTK_TROUGH_NONE)
973         {
974           if (pos == GTK_TROUGH_START)
975             range->adjustment->value = range->adjustment->lower;
976           else if (pos == GTK_TROUGH_END)
977             range->adjustment->value =
978               range->adjustment->upper - range->adjustment->page_size;
979
980           if (range->old_value != range->adjustment->value)
981             {
982               gtk_signal_emit_by_name (GTK_OBJECT (range->adjustment),
983                                        "value_changed");
984
985               gtk_range_slider_update (range);
986               gtk_range_draw_background (range);
987             }
988         }
989     }
990   return return_val;
991 }
992
993 static gint
994 gtk_range_enter_notify (GtkWidget        *widget,
995                         GdkEventCrossing *event)
996 {
997   GtkRange *range;
998
999   g_return_val_if_fail (widget != NULL, FALSE);
1000   g_return_val_if_fail (GTK_IS_RANGE (widget), FALSE);
1001   g_return_val_if_fail (event != NULL, FALSE);
1002
1003   range = GTK_RANGE (widget);
1004
1005   if (event->window == range->trough)
1006     {
1007       range->in_child = RANGE_CLASS (range)->trough;
1008     }
1009   else if (event->window == range->slider)
1010     {
1011       range->in_child = RANGE_CLASS (range)->slider;
1012
1013       if ((range->click_child == 0) ||
1014           (range->click_child == RANGE_CLASS (range)->trough))
1015         gtk_range_draw_slider (range);
1016     }
1017   else if (event->window == range->step_forw)
1018     {
1019       range->in_child = RANGE_CLASS (range)->step_forw;
1020
1021       if ((range->click_child == 0) ||
1022           (range->click_child == RANGE_CLASS (range)->trough))
1023         gtk_range_draw_step_forw (range);
1024     }
1025   else if (event->window == range->step_back)
1026     {
1027       range->in_child = RANGE_CLASS (range)->step_back;
1028
1029       if ((range->click_child == 0) ||
1030           (range->click_child == RANGE_CLASS (range)->trough))
1031         gtk_range_draw_step_back (range);
1032     }
1033
1034   return FALSE;
1035 }
1036
1037 static gint
1038 gtk_range_leave_notify (GtkWidget        *widget,
1039                         GdkEventCrossing *event)
1040 {
1041   GtkRange *range;
1042
1043   g_return_val_if_fail (widget != NULL, FALSE);
1044   g_return_val_if_fail (GTK_IS_RANGE (widget), FALSE);
1045   g_return_val_if_fail (event != NULL, FALSE);
1046
1047   range = GTK_RANGE (widget);
1048
1049   range->in_child = 0;
1050
1051   if (event->window == range->trough)
1052     {
1053     }
1054   else if (event->window == range->slider)
1055     {
1056       if ((range->click_child == 0) ||
1057           (range->click_child == RANGE_CLASS (range)->trough))
1058         gtk_range_draw_slider (range);
1059     }
1060   else if (event->window == range->step_forw)
1061     {
1062       if ((range->click_child == 0) ||
1063           (range->click_child == RANGE_CLASS (range)->trough))
1064         gtk_range_draw_step_forw (range);
1065     }
1066   else if (event->window == range->step_back)
1067     {
1068       if ((range->click_child == 0) ||
1069           (range->click_child == RANGE_CLASS (range)->trough))
1070         gtk_range_draw_step_back (range);
1071     }
1072
1073   return FALSE;
1074 }
1075
1076 static gint
1077 gtk_range_focus_in (GtkWidget     *widget,
1078                     GdkEventFocus *event)
1079 {
1080   g_return_val_if_fail (widget != NULL, FALSE);
1081   g_return_val_if_fail (GTK_IS_RANGE (widget), FALSE);
1082   g_return_val_if_fail (event != NULL, FALSE);
1083
1084   GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS);
1085   gtk_widget_draw_focus (widget);
1086
1087   return FALSE;
1088 }
1089
1090 static gint
1091 gtk_range_focus_out (GtkWidget     *widget,
1092                      GdkEventFocus *event)
1093 {
1094   g_return_val_if_fail (widget != NULL, FALSE);
1095   g_return_val_if_fail (GTK_IS_RANGE (widget), FALSE);
1096   g_return_val_if_fail (event != NULL, FALSE);
1097
1098   GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS);
1099   gtk_widget_draw_focus (widget);
1100
1101   return FALSE;
1102 }
1103
1104 static void
1105 gtk_real_range_draw_trough (GtkRange *range)
1106 {
1107   g_return_if_fail (range != NULL);
1108   g_return_if_fail (GTK_IS_RANGE (range));
1109
1110   if (range->trough)
1111     {
1112       gtk_draw_shadow (GTK_WIDGET (range)->style, range->trough,
1113                        GTK_STATE_NORMAL, GTK_SHADOW_IN,
1114                        0, 0, -1, -1);
1115
1116       if (GTK_WIDGET_HAS_FOCUS (range))
1117         gdk_draw_rectangle (GTK_WIDGET (range)->window,
1118                             GTK_WIDGET (range)->style->black_gc,
1119                             FALSE, 0, 0,
1120                             GTK_WIDGET (range)->allocation.width - 1,
1121                             GTK_WIDGET (range)->allocation.height - 1);
1122       else if (range->trough != GTK_WIDGET (range)->window)
1123         gdk_draw_rectangle (GTK_WIDGET (range)->window,
1124                             GTK_WIDGET (range)->style->bg_gc[GTK_STATE_NORMAL],
1125                             FALSE, 0, 0,
1126                             GTK_WIDGET (range)->allocation.width - 1,
1127                             GTK_WIDGET (range)->allocation.height - 1);
1128     }
1129 }
1130
1131 static void
1132 gtk_real_range_draw_slider (GtkRange *range)
1133 {
1134   GtkStateType state_type;
1135
1136   g_return_if_fail (range != NULL);
1137   g_return_if_fail (GTK_IS_RANGE (range));
1138
1139   if (range->slider)
1140     {
1141       if ((range->in_child == RANGE_CLASS (range)->slider) ||
1142           (range->click_child == RANGE_CLASS (range)->slider))
1143         state_type = GTK_STATE_PRELIGHT;
1144       else
1145         state_type = GTK_STATE_NORMAL;
1146
1147       gtk_style_set_background (GTK_WIDGET (range)->style, range->slider, state_type);
1148       gdk_window_clear (range->slider);
1149
1150       gtk_draw_shadow (GTK_WIDGET (range)->style, range->slider,
1151                        state_type, GTK_SHADOW_OUT,
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_draw_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_draw_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_draw_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     }
1498 }