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