1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
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.
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.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the Free
16 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include "gtksignal.h"
24 #define SCROLL_TIMER_LENGTH 20
25 #define SCROLL_INITIAL_DELAY 100
26 #define SCROLL_DELAY_LENGTH 300
28 #define RANGE_CLASS(w) GTK_RANGE_CLASS (GTK_OBJECT (w)->klass)
31 static void gtk_range_class_init (GtkRangeClass *klass);
32 static void gtk_range_init (GtkRange *range);
33 static void gtk_range_destroy (GtkObject *object);
34 static void gtk_range_draw (GtkWidget *widget,
36 static void gtk_range_draw_focus (GtkWidget *widget);
37 static void gtk_range_unrealize (GtkWidget *widget);
38 static gint gtk_range_expose (GtkWidget *widget,
39 GdkEventExpose *event);
40 static gint gtk_range_button_press (GtkWidget *widget,
41 GdkEventButton *event);
42 static gint gtk_range_button_release (GtkWidget *widget,
43 GdkEventButton *event);
44 static gint gtk_range_motion_notify (GtkWidget *widget,
45 GdkEventMotion *event);
46 static gint gtk_range_key_press (GtkWidget *widget,
48 static gint gtk_range_enter_notify (GtkWidget *widget,
49 GdkEventCrossing *event);
50 static gint gtk_range_leave_notify (GtkWidget *widget,
51 GdkEventCrossing *event);
52 static gint gtk_range_focus_in (GtkWidget *widget,
53 GdkEventFocus *event);
54 static gint gtk_range_focus_out (GtkWidget *widget,
55 GdkEventFocus *event);
56 static void gtk_real_range_draw_trough (GtkRange *range);
57 static void gtk_real_range_draw_slider (GtkRange *range);
58 static gint gtk_real_range_timer (GtkRange *range);
59 static gint gtk_range_scroll (GtkRange *range);
61 static void gtk_range_add_timer (GtkRange *range);
62 static void gtk_range_remove_timer (GtkRange *range);
64 static void gtk_range_adjustment_changed (GtkAdjustment *adjustment,
66 static void gtk_range_adjustment_value_changed (GtkAdjustment *adjustment,
69 static void gtk_range_trough_hdims (GtkRange *range,
72 static void gtk_range_trough_vdims (GtkRange *range,
76 static GtkWidgetClass *parent_class = NULL;
82 static guint range_type = 0;
86 GtkTypeInfo range_info =
90 sizeof (GtkRangeClass),
91 (GtkClassInitFunc) gtk_range_class_init,
92 (GtkObjectInitFunc) gtk_range_init,
96 range_type = gtk_type_unique (gtk_widget_get_type (), &range_info);
103 gtk_range_class_init (GtkRangeClass *class)
105 GtkObjectClass *object_class;
106 GtkWidgetClass *widget_class;
108 object_class = (GtkObjectClass*) class;
109 widget_class = (GtkWidgetClass*) class;
111 parent_class = gtk_type_class (gtk_widget_get_type ());
113 object_class->destroy = gtk_range_destroy;
115 widget_class->draw = gtk_range_draw;
116 widget_class->draw_focus = gtk_range_draw_focus;
117 widget_class->unrealize = gtk_range_unrealize;
118 widget_class->expose_event = gtk_range_expose;
119 widget_class->button_press_event = gtk_range_button_press;
120 widget_class->button_release_event = gtk_range_button_release;
121 widget_class->motion_notify_event = gtk_range_motion_notify;
122 widget_class->key_press_event = gtk_range_key_press;
123 widget_class->enter_notify_event = gtk_range_enter_notify;
124 widget_class->leave_notify_event = gtk_range_leave_notify;
125 widget_class->focus_in_event = gtk_range_focus_in;
126 widget_class->focus_out_event = gtk_range_focus_out;
128 class->slider_width = 11;
129 class->stepper_size = 11;
130 class->stepper_slider_spacing = 1;
131 class->min_slider_size = 7;
134 class->step_forw = 3;
135 class->step_back = 4;
136 class->draw_background = NULL;
137 class->draw_trough = gtk_real_range_draw_trough;
138 class->draw_slider = gtk_real_range_draw_slider;
139 class->draw_step_forw = NULL;
140 class->draw_step_back = NULL;
141 class->trough_click = NULL;
142 class->trough_keys = NULL;
143 class->motion = NULL;
144 class->timer = gtk_real_range_timer;
148 gtk_range_init (GtkRange *range)
150 range->trough = NULL;
151 range->slider = NULL;
152 range->step_forw = NULL;
153 range->step_back = NULL;
155 range->x_click_point = 0;
156 range->y_click_point = 0;
159 range->policy = GTK_UPDATE_CONTINUOUS;
160 range->scroll_type = GTK_SCROLL_NONE;
162 range->click_child = 0;
163 range->need_timer = FALSE;
165 range->old_value = 0.0;
166 range->old_lower = 0.0;
167 range->old_upper = 0.0;
168 range->old_page_size = 0.0;
169 range->adjustment = NULL;
173 gtk_range_get_adjustment (GtkRange *range)
175 g_return_val_if_fail (range != NULL, NULL);
176 g_return_val_if_fail (GTK_IS_RANGE (range), NULL);
178 return range->adjustment;
182 gtk_range_set_update_policy (GtkRange *range,
183 GtkUpdateType policy)
185 g_return_if_fail (range != NULL);
186 g_return_if_fail (GTK_IS_RANGE (range));
188 range->policy = policy;
192 gtk_range_set_adjustment (GtkRange *range,
193 GtkAdjustment *adjustment)
195 g_return_if_fail (range != NULL);
196 g_return_if_fail (GTK_IS_RANGE (range));
198 if (range->adjustment)
200 gtk_signal_disconnect_by_data (GTK_OBJECT (range->adjustment), (gpointer) range);
201 gtk_object_unref (GTK_OBJECT (range->adjustment));
204 range->adjustment = adjustment;
205 gtk_object_ref (GTK_OBJECT (range->adjustment));
207 gtk_signal_connect (GTK_OBJECT (adjustment), "changed",
208 (GtkSignalFunc) gtk_range_adjustment_changed,
210 gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed",
211 (GtkSignalFunc) gtk_range_adjustment_value_changed,
214 range->old_value = adjustment->value;
215 range->old_lower = adjustment->lower;
216 range->old_upper = adjustment->upper;
217 range->old_page_size = adjustment->page_size;
219 gtk_range_adjustment_changed (range->adjustment, (gpointer) range);
223 gtk_range_draw_background (GtkRange *range)
225 g_return_if_fail (range != NULL);
226 g_return_if_fail (GTK_IS_RANGE (range));
228 if (range->trough && RANGE_CLASS (range)->draw_background)
229 (* RANGE_CLASS (range)->draw_background) (range);
233 gtk_range_draw_trough (GtkRange *range)
235 g_return_if_fail (range != NULL);
236 g_return_if_fail (GTK_IS_RANGE (range));
238 if (range->trough && RANGE_CLASS (range)->draw_trough)
239 (* RANGE_CLASS (range)->draw_trough) (range);
243 gtk_range_draw_slider (GtkRange *range)
245 g_return_if_fail (range != NULL);
246 g_return_if_fail (GTK_IS_RANGE (range));
248 if (range->slider && RANGE_CLASS (range)->draw_slider)
249 (* RANGE_CLASS (range)->draw_slider) (range);
253 gtk_range_draw_step_forw (GtkRange *range)
255 g_return_if_fail (range != NULL);
256 g_return_if_fail (GTK_IS_RANGE (range));
258 if (range->step_forw && RANGE_CLASS (range)->draw_step_forw)
259 (* RANGE_CLASS (range)->draw_step_forw) (range);
263 gtk_range_draw_step_back (GtkRange *range)
265 g_return_if_fail (range != NULL);
266 g_return_if_fail (GTK_IS_RANGE (range));
268 if (range->step_back && RANGE_CLASS (range)->draw_step_back)
269 (* RANGE_CLASS (range)->draw_step_back) (range);
273 gtk_range_slider_update (GtkRange *range)
275 g_return_if_fail (range != NULL);
276 g_return_if_fail (GTK_IS_RANGE (range));
278 if (RANGE_CLASS (range)->slider_update)
279 (* RANGE_CLASS (range)->slider_update) (range);
283 gtk_range_trough_click (GtkRange *range,
287 g_return_val_if_fail (range != NULL, GTK_TROUGH_NONE);
288 g_return_val_if_fail (GTK_IS_RANGE (range), GTK_TROUGH_NONE);
290 if (RANGE_CLASS (range)->trough_click)
291 return (* RANGE_CLASS (range)->trough_click) (range, x, y);
293 return GTK_TROUGH_NONE;
297 gtk_range_default_hslider_update (GtkRange *range)
303 g_return_if_fail (range != NULL);
304 g_return_if_fail (GTK_IS_RANGE (range));
306 if (GTK_WIDGET_REALIZED (range))
308 gtk_range_trough_hdims (range, &left, &right);
311 if (range->adjustment->value < range->adjustment->lower)
313 range->adjustment->value = range->adjustment->lower;
314 gtk_signal_emit_by_name (GTK_OBJECT (range->adjustment), "value_changed");
316 else if (range->adjustment->value > range->adjustment->upper)
318 range->adjustment->value = range->adjustment->upper;
319 gtk_signal_emit_by_name (GTK_OBJECT (range->adjustment), "value_changed");
322 if (range->adjustment->lower != (range->adjustment->upper - range->adjustment->page_size))
323 x += ((right - left) * (range->adjustment->value - range->adjustment->lower) /
324 (range->adjustment->upper - range->adjustment->lower - range->adjustment->page_size));
331 gdk_window_move (range->slider, x, GTK_WIDGET (range)->style->klass->ythickness);
336 gtk_range_default_vslider_update (GtkRange *range)
342 g_return_if_fail (range != NULL);
343 g_return_if_fail (GTK_IS_RANGE (range));
345 if (GTK_WIDGET_REALIZED (range))
347 gtk_range_trough_vdims (range, &top, &bottom);
350 if (range->adjustment->value < range->adjustment->lower)
352 range->adjustment->value = range->adjustment->lower;
353 gtk_signal_emit_by_name (GTK_OBJECT (range->adjustment), "value_changed");
355 else if (range->adjustment->value > range->adjustment->upper)
357 range->adjustment->value = range->adjustment->upper;
358 gtk_signal_emit_by_name (GTK_OBJECT (range->adjustment), "value_changed");
361 if (range->adjustment->lower != (range->adjustment->upper - range->adjustment->page_size))
362 y += ((bottom - top) * (range->adjustment->value - range->adjustment->lower) /
363 (range->adjustment->upper - range->adjustment->lower - range->adjustment->page_size));
370 gdk_window_move (range->slider, GTK_WIDGET (range)->style->klass->ythickness, y);
375 gtk_range_default_htrough_click (GtkRange *range,
385 g_return_val_if_fail (range != NULL, GTK_TROUGH_NONE);
386 g_return_val_if_fail (GTK_IS_RANGE (range), GTK_TROUGH_NONE);
388 xthickness = GTK_WIDGET (range)->style->klass->xthickness;
389 ythickness = GTK_WIDGET (range)->style->klass->ythickness;
391 if ((x > xthickness) && (y > ythickness))
393 gdk_window_get_size (range->trough, &trough_width, &trough_height);
395 if ((x < (trough_width - xthickness) && (y < (trough_height - ythickness))))
397 gdk_window_get_position (range->slider, &slider_x, NULL);
400 return GTK_TROUGH_START;
402 return GTK_TROUGH_END;
406 return GTK_TROUGH_NONE;
410 gtk_range_default_vtrough_click (GtkRange *range,
420 g_return_val_if_fail (range != NULL, GTK_TROUGH_NONE);
421 g_return_val_if_fail (GTK_IS_RANGE (range), GTK_TROUGH_NONE);
423 xthickness = GTK_WIDGET (range)->style->klass->xthickness;
424 ythickness = GTK_WIDGET (range)->style->klass->ythickness;
426 if ((x > xthickness) && (y > ythickness))
428 gdk_window_get_size (range->trough, &trough_width, &trough_height);
430 if ((x < (trough_width - xthickness) && (y < (trough_height - ythickness))))
432 gdk_window_get_position (range->slider, NULL, &slider_y);
435 return GTK_TROUGH_START;
437 return GTK_TROUGH_END;
441 return GTK_TROUGH_NONE;
445 gtk_range_default_hmotion (GtkRange *range,
451 gint slider_x, slider_y;
454 g_return_if_fail (range != NULL);
455 g_return_if_fail (GTK_IS_RANGE (range));
457 range = GTK_RANGE (range);
459 gdk_window_get_position (range->slider, &slider_x, &slider_y);
460 gtk_range_trough_hdims (range, &left, &right);
465 new_pos = slider_x + xdelta;
469 else if (new_pos > right)
472 old_value = range->adjustment->value;
473 range->adjustment->value = ((range->adjustment->upper -
474 range->adjustment->lower -
475 range->adjustment->page_size) *
476 (new_pos - left) / (right - left) +
477 range->adjustment->lower);
479 if (range->digits >= 0)
483 sprintf (buffer, "%0.*f", range->digits, range->adjustment->value);
484 sscanf (buffer, "%f", &range->adjustment->value);
487 if (old_value != range->adjustment->value)
489 if (range->policy == GTK_UPDATE_CONTINUOUS)
491 gtk_signal_emit_by_name (GTK_OBJECT (range->adjustment), "value_changed");
495 gtk_range_slider_update (range);
496 gtk_range_draw_background (range);
498 if (range->policy == GTK_UPDATE_DELAYED)
500 gtk_range_remove_timer (range);
501 range->timer = gtk_timeout_add (SCROLL_DELAY_LENGTH,
502 (GtkFunction) RANGE_CLASS (range)->timer,
510 gtk_range_default_vmotion (GtkRange *range,
516 gint slider_x, slider_y;
519 g_return_if_fail (range != NULL);
520 g_return_if_fail (GTK_IS_RANGE (range));
522 range = GTK_RANGE (range);
524 gdk_window_get_position (range->slider, &slider_x, &slider_y);
525 gtk_range_trough_vdims (range, &top, &bottom);
530 new_pos = slider_y + ydelta;
534 else if (new_pos > bottom)
537 old_value = range->adjustment->value;
538 range->adjustment->value = ((range->adjustment->upper -
539 range->adjustment->lower -
540 range->adjustment->page_size) *
541 (new_pos - top) / (bottom - top) +
542 range->adjustment->lower);
544 if (range->digits >= 0)
548 sprintf (buffer, "%0.*f", range->digits, range->adjustment->value);
549 sscanf (buffer, "%f", &range->adjustment->value);
552 if (old_value != range->adjustment->value)
554 if (range->policy == GTK_UPDATE_CONTINUOUS)
556 gtk_signal_emit_by_name (GTK_OBJECT (range->adjustment), "value_changed");
560 gtk_range_slider_update (range);
561 gtk_range_draw_background (range);
563 if (range->policy == GTK_UPDATE_DELAYED)
565 gtk_range_remove_timer (range);
566 range->timer = gtk_timeout_add (SCROLL_DELAY_LENGTH,
567 (GtkFunction) RANGE_CLASS (range)->timer,
575 gtk_range_calc_value (GtkRange *range,
583 gtk_range_destroy (GtkObject *object)
587 g_return_if_fail (object != NULL);
588 g_return_if_fail (GTK_IS_RANGE (object));
590 range = GTK_RANGE (object);
592 if (range->adjustment)
593 gtk_object_unref (GTK_OBJECT (range->adjustment));
595 if (GTK_OBJECT_CLASS (parent_class)->destroy)
596 (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
600 gtk_range_draw (GtkWidget *widget,
605 g_return_if_fail (widget != NULL);
606 g_return_if_fail (GTK_IS_RANGE (widget));
607 g_return_if_fail (area != NULL);
609 if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_MAPPED (widget))
611 range = GTK_RANGE (widget);
613 gtk_range_draw_background (range);
614 gtk_range_draw_trough (range);
615 gtk_range_draw_slider (range);
616 gtk_range_draw_step_forw (range);
617 gtk_range_draw_step_back (range);
622 gtk_range_draw_focus (GtkWidget *widget)
624 g_return_if_fail (widget != NULL);
625 g_return_if_fail (GTK_IS_RANGE (widget));
627 if (GTK_WIDGET_DRAWABLE (widget))
628 gtk_range_draw_trough (GTK_RANGE (widget));
632 gtk_range_unrealize (GtkWidget *widget)
636 g_return_if_fail (widget != NULL);
637 g_return_if_fail (GTK_IS_RANGE (widget));
639 GTK_WIDGET_UNSET_FLAGS (widget, GTK_REALIZED);
640 range = GTK_RANGE (widget);
642 gtk_style_detach (widget->style);
645 gdk_window_destroy (range->slider);
647 gdk_window_destroy (range->trough);
648 if (range->step_forw)
649 gdk_window_destroy (range->step_forw);
650 if (range->step_back)
651 gdk_window_destroy (range->step_back);
653 gdk_window_destroy (widget->window);
655 range->slider = NULL;
656 range->trough = NULL;
657 range->step_forw = NULL;
658 range->step_back = NULL;
659 widget->window = NULL;
663 gtk_range_expose (GtkWidget *widget,
664 GdkEventExpose *event)
668 g_return_val_if_fail (widget != NULL, FALSE);
669 g_return_val_if_fail (GTK_IS_RANGE (widget), FALSE);
670 g_return_val_if_fail (event != NULL, FALSE);
672 range = GTK_RANGE (widget);
674 if (event->window == range->trough)
676 gtk_range_draw_trough (range);
678 else if (event->window == widget->window)
680 gtk_range_draw_background (range);
682 else if (event->window == range->slider)
684 gtk_range_draw_slider (range);
686 else if (event->window == range->step_forw)
688 gtk_range_draw_step_forw (range);
690 else if (event->window == range->step_back)
692 gtk_range_draw_step_back (range);
698 gtk_range_button_press (GtkWidget *widget,
699 GdkEventButton *event)
704 g_return_val_if_fail (widget != NULL, FALSE);
705 g_return_val_if_fail (GTK_IS_RANGE (widget), FALSE);
706 g_return_val_if_fail (event != NULL, FALSE);
708 if (!GTK_WIDGET_HAS_FOCUS (widget))
709 gtk_widget_grab_focus (widget);
711 range = GTK_RANGE (widget);
714 gtk_grab_add (widget);
716 range->button = event->button;
717 range->x_click_point = event->x;
718 range->y_click_point = event->y;
720 if (event->window == range->trough)
722 range->click_child = RANGE_CLASS (range)->trough;
724 trough_part = gtk_range_trough_click (range, event->x, event->y);
726 range->scroll_type = GTK_SCROLL_NONE;
727 if (trough_part == GTK_TROUGH_START)
728 range->scroll_type = GTK_SCROLL_PAGE_BACKWARD;
729 else if (trough_part == GTK_TROUGH_END)
730 range->scroll_type = GTK_SCROLL_PAGE_FORWARD;
732 if (range->scroll_type != GTK_SCROLL_NONE)
734 gtk_range_scroll (range);
735 gtk_range_add_timer (range);
738 else if (event->window == range->slider)
740 range->click_child = RANGE_CLASS (range)->slider;
741 range->scroll_type = GTK_SCROLL_NONE;
743 else if (event->window == range->step_forw)
745 range->click_child = RANGE_CLASS (range)->step_forw;
746 range->scroll_type = GTK_SCROLL_STEP_FORWARD;
748 gtk_range_scroll (range);
749 gtk_range_add_timer (range);
750 gtk_range_draw_step_forw (range);
752 else if (event->window == range->step_back)
754 range->click_child = RANGE_CLASS (range)->step_back;
755 range->scroll_type = GTK_SCROLL_STEP_BACKWARD;
757 gtk_range_scroll (range);
758 gtk_range_add_timer (range);
759 gtk_range_draw_step_back (range);
767 gtk_range_button_release (GtkWidget *widget,
768 GdkEventButton *event)
772 g_return_val_if_fail (widget != NULL, FALSE);
773 g_return_val_if_fail (GTK_IS_RANGE (widget), FALSE);
774 g_return_val_if_fail (event != NULL, FALSE);
776 range = GTK_RANGE (widget);
778 if (range->button == event->button)
780 gtk_grab_remove (widget);
783 range->x_click_point = -1;
784 range->y_click_point = -1;
786 if (range->click_child == RANGE_CLASS (range)->slider)
788 if (range->policy == GTK_UPDATE_DELAYED)
789 gtk_range_remove_timer (range);
791 if ((range->policy != GTK_UPDATE_CONTINUOUS) &&
792 (range->old_value != range->adjustment->value))
793 gtk_signal_emit_by_name (GTK_OBJECT (range->adjustment), "value_changed");
795 else if ((range->click_child == RANGE_CLASS (range)->trough) ||
796 (range->click_child == RANGE_CLASS (range)->step_forw) ||
797 (range->click_child == RANGE_CLASS (range)->step_back))
799 gtk_range_remove_timer (range);
801 if ((range->policy != GTK_UPDATE_CONTINUOUS) &&
802 (range->old_value != range->adjustment->value))
803 gtk_signal_emit_by_name (GTK_OBJECT (range->adjustment), "value_changed");
805 if (range->click_child == RANGE_CLASS (range)->step_forw)
807 range->click_child = 0;
808 gtk_range_draw_step_forw (range);
810 else if (range->click_child == RANGE_CLASS (range)->step_back)
812 range->click_child = 0;
813 gtk_range_draw_step_back (range);
817 range->click_child = 0;
824 gtk_range_motion_notify (GtkWidget *widget,
825 GdkEventMotion *event)
828 GdkModifierType mods;
831 g_return_val_if_fail (widget != NULL, FALSE);
832 g_return_val_if_fail (GTK_IS_RANGE (widget), FALSE);
833 g_return_val_if_fail (event != NULL, FALSE);
835 range = GTK_RANGE (widget);
837 if (range->click_child == RANGE_CLASS (range)->slider)
842 if (event->is_hint || (event->window != range->slider))
843 gdk_window_get_pointer (range->slider, &x, &y, &mods);
845 switch (range->button)
848 mask = GDK_BUTTON1_MASK;
851 mask = GDK_BUTTON2_MASK;
854 mask = GDK_BUTTON3_MASK;
863 if (RANGE_CLASS (range)->motion)
864 (* RANGE_CLASS (range)->motion) (range, x - range->x_click_point, y - range->y_click_point);
872 gtk_range_key_press (GtkWidget *widget,
877 GtkScrollType scroll = GTK_SCROLL_NONE;
878 GtkTroughType pos = GTK_TROUGH_NONE;
880 g_return_val_if_fail (widget != NULL, FALSE);
881 g_return_val_if_fail (GTK_IS_RANGE (widget), FALSE);
882 g_return_val_if_fail (event != NULL, FALSE);
884 range = GTK_RANGE (widget);
887 if (RANGE_CLASS (range)->trough_keys)
888 return_val = (* RANGE_CLASS (range)->trough_keys) (range, event, &scroll, &pos);
892 if (scroll != GTK_SCROLL_NONE)
894 range->scroll_type = scroll;
895 gtk_range_scroll (range);
896 if (range->old_value != range->adjustment->value)
898 gtk_signal_emit_by_name (GTK_OBJECT (range->adjustment), "value_changed");
899 switch (range->scroll_type)
901 case GTK_SCROLL_STEP_BACKWARD:
902 gtk_range_draw_step_back (range);
904 case GTK_SCROLL_STEP_FORWARD:
905 gtk_range_draw_step_forw (range);
910 if (pos != GTK_TROUGH_NONE)
912 if (pos == GTK_TROUGH_START)
913 range->adjustment->value = range->adjustment->lower;
915 range->adjustment->value =
916 range->adjustment->upper - range->adjustment->page_size;
918 if (range->old_value != range->adjustment->value)
920 gtk_signal_emit_by_name (GTK_OBJECT (range->adjustment),
923 gtk_range_slider_update (range);
924 gtk_range_draw_background (range);
932 gtk_range_enter_notify (GtkWidget *widget,
933 GdkEventCrossing *event)
937 g_return_val_if_fail (widget != NULL, FALSE);
938 g_return_val_if_fail (GTK_IS_RANGE (widget), FALSE);
939 g_return_val_if_fail (event != NULL, FALSE);
941 range = GTK_RANGE (widget);
943 if (event->window == range->trough)
945 range->in_child = RANGE_CLASS (range)->trough;
947 else if (event->window == range->slider)
949 range->in_child = RANGE_CLASS (range)->slider;
951 if ((range->click_child == 0) ||
952 (range->click_child == RANGE_CLASS (range)->trough))
953 gtk_range_draw_slider (range);
955 else if (event->window == range->step_forw)
957 range->in_child = RANGE_CLASS (range)->step_forw;
959 if ((range->click_child == 0) ||
960 (range->click_child == RANGE_CLASS (range)->trough))
961 gtk_range_draw_step_forw (range);
963 else if (event->window == range->step_back)
965 range->in_child = RANGE_CLASS (range)->step_back;
967 if ((range->click_child == 0) ||
968 (range->click_child == RANGE_CLASS (range)->trough))
969 gtk_range_draw_step_back (range);
976 gtk_range_leave_notify (GtkWidget *widget,
977 GdkEventCrossing *event)
981 g_return_val_if_fail (widget != NULL, FALSE);
982 g_return_val_if_fail (GTK_IS_RANGE (widget), FALSE);
983 g_return_val_if_fail (event != NULL, FALSE);
985 range = GTK_RANGE (widget);
989 if (event->window == range->trough)
992 else if (event->window == range->slider)
994 if ((range->click_child == 0) ||
995 (range->click_child == RANGE_CLASS (range)->trough))
996 gtk_range_draw_slider (range);
998 else if (event->window == range->step_forw)
1000 if ((range->click_child == 0) ||
1001 (range->click_child == RANGE_CLASS (range)->trough))
1002 gtk_range_draw_step_forw (range);
1004 else if (event->window == range->step_back)
1006 if ((range->click_child == 0) ||
1007 (range->click_child == RANGE_CLASS (range)->trough))
1008 gtk_range_draw_step_back (range);
1015 gtk_range_focus_in (GtkWidget *widget,
1016 GdkEventFocus *event)
1018 g_return_val_if_fail (widget != NULL, FALSE);
1019 g_return_val_if_fail (GTK_IS_RANGE (widget), FALSE);
1020 g_return_val_if_fail (event != NULL, FALSE);
1022 GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS);
1023 gtk_widget_draw_focus (widget);
1029 gtk_range_focus_out (GtkWidget *widget,
1030 GdkEventFocus *event)
1032 g_return_val_if_fail (widget != NULL, FALSE);
1033 g_return_val_if_fail (GTK_IS_RANGE (widget), FALSE);
1034 g_return_val_if_fail (event != NULL, FALSE);
1036 GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS);
1037 gtk_widget_draw_focus (widget);
1043 gtk_real_range_draw_trough (GtkRange *range)
1045 g_return_if_fail (range != NULL);
1046 g_return_if_fail (GTK_IS_RANGE (range));
1050 gtk_draw_shadow (GTK_WIDGET (range)->style, range->trough,
1051 GTK_STATE_NORMAL, GTK_SHADOW_IN,
1054 if (GTK_WIDGET_HAS_FOCUS (range))
1055 gdk_draw_rectangle (GTK_WIDGET (range)->window,
1056 GTK_WIDGET (range)->style->black_gc,
1058 GTK_WIDGET (range)->allocation.width - 1,
1059 GTK_WIDGET (range)->allocation.height - 1);
1060 else if (range->trough != GTK_WIDGET (range)->window)
1061 gdk_draw_rectangle (GTK_WIDGET (range)->window,
1062 GTK_WIDGET (range)->style->bg_gc[GTK_STATE_NORMAL],
1064 GTK_WIDGET (range)->allocation.width - 1,
1065 GTK_WIDGET (range)->allocation.height - 1);
1070 gtk_real_range_draw_slider (GtkRange *range)
1072 GtkStateType state_type;
1074 g_return_if_fail (range != NULL);
1075 g_return_if_fail (GTK_IS_RANGE (range));
1079 if ((range->in_child == RANGE_CLASS (range)->slider) ||
1080 (range->click_child == RANGE_CLASS (range)->slider))
1081 state_type = GTK_STATE_PRELIGHT;
1083 state_type = GTK_STATE_NORMAL;
1085 gtk_style_set_background (GTK_WIDGET (range)->style, range->slider, state_type);
1086 gdk_window_clear (range->slider);
1088 gtk_draw_shadow (GTK_WIDGET (range)->style, range->slider,
1089 state_type, GTK_SHADOW_OUT,
1095 gtk_real_range_timer (GtkRange *range)
1099 g_return_val_if_fail (range != NULL, FALSE);
1100 g_return_val_if_fail (GTK_IS_RANGE (range), FALSE);
1103 if (range->click_child == RANGE_CLASS (range)->slider)
1105 if (range->policy == GTK_UPDATE_DELAYED)
1106 gtk_signal_emit_by_name (GTK_OBJECT (range->adjustment), "value_changed");
1114 if (range->need_timer)
1115 range->timer = gtk_timeout_add (SCROLL_TIMER_LENGTH,
1116 (GtkFunction) RANGE_CLASS (range)->timer,
1120 range->need_timer = FALSE;
1123 if (gtk_range_scroll (range))
1131 gtk_range_scroll (GtkRange *range)
1136 g_return_val_if_fail (range != NULL, FALSE);
1137 g_return_val_if_fail (GTK_IS_RANGE (range), FALSE);
1139 new_value = range->adjustment->value;
1142 switch (range->scroll_type)
1144 case GTK_SCROLL_NONE:
1147 case GTK_SCROLL_STEP_BACKWARD:
1148 new_value -= range->adjustment->step_increment;
1149 if (new_value <= range->adjustment->lower)
1151 new_value = range->adjustment->lower;
1157 case GTK_SCROLL_STEP_FORWARD:
1158 new_value += range->adjustment->step_increment;
1159 if (new_value >= (range->adjustment->upper - range->adjustment->page_size))
1161 new_value = range->adjustment->upper - range->adjustment->page_size;
1167 case GTK_SCROLL_PAGE_BACKWARD:
1168 new_value -= range->adjustment->page_increment;
1169 if (new_value <= range->adjustment->lower)
1171 new_value = range->adjustment->lower;
1177 case GTK_SCROLL_PAGE_FORWARD:
1178 new_value += range->adjustment->page_increment;
1179 if (new_value >= (range->adjustment->upper - range->adjustment->page_size))
1181 new_value = range->adjustment->upper - range->adjustment->page_size;
1188 if (new_value != range->adjustment->value)
1190 range->adjustment->value = new_value;
1192 if ((range->policy == GTK_UPDATE_CONTINUOUS) ||
1193 (!return_val && (range->policy == GTK_UPDATE_DELAYED)))
1195 gtk_signal_emit_by_name (GTK_OBJECT (range->adjustment), "value_changed");
1199 gtk_range_slider_update (range);
1200 gtk_range_draw_background (range);
1209 gtk_range_add_timer (GtkRange *range)
1211 g_return_if_fail (range != NULL);
1212 g_return_if_fail (GTK_IS_RANGE (range));
1216 range->need_timer = TRUE;
1217 range->timer = gtk_timeout_add (SCROLL_INITIAL_DELAY,
1218 (GtkFunction) RANGE_CLASS (range)->timer,
1224 gtk_range_remove_timer (GtkRange *range)
1226 g_return_if_fail (range != NULL);
1227 g_return_if_fail (GTK_IS_RANGE (range));
1231 gtk_timeout_remove (range->timer);
1234 range->need_timer = FALSE;
1238 gtk_range_adjustment_changed (GtkAdjustment *adjustment,
1243 g_return_if_fail (adjustment != NULL);
1244 g_return_if_fail (data != NULL);
1246 range = GTK_RANGE (data);
1248 if (((range->old_lower != adjustment->lower) ||
1249 (range->old_upper != adjustment->upper) ||
1250 (range->old_page_size != adjustment->page_size)) &&
1251 (range->old_value == adjustment->value))
1253 if ((adjustment->lower == adjustment->upper) ||
1254 (range->old_lower == (range->old_upper - range->old_page_size)))
1256 adjustment->value = adjustment->lower;
1257 gtk_signal_emit_by_name (GTK_OBJECT (adjustment), "value_changed");
1261 if ((range->old_value != adjustment->value) ||
1262 (range->old_lower != adjustment->lower) ||
1263 (range->old_upper != adjustment->upper) ||
1264 (range->old_page_size != adjustment->page_size))
1266 gtk_range_slider_update (range);
1267 gtk_range_draw_background (range);
1269 range->old_value = adjustment->value;
1270 range->old_lower = adjustment->lower;
1271 range->old_upper = adjustment->upper;
1272 range->old_page_size = adjustment->page_size;
1277 gtk_range_adjustment_value_changed (GtkAdjustment *adjustment,
1282 g_return_if_fail (adjustment != NULL);
1283 g_return_if_fail (data != NULL);
1285 range = GTK_RANGE (data);
1287 if (range->old_value != adjustment->value)
1289 gtk_range_slider_update (range);
1290 gtk_range_draw_background (range);
1292 range->old_value = adjustment->value;
1298 gtk_range_trough_hdims (GtkRange *range,
1308 g_return_if_fail (range != NULL);
1310 gdk_window_get_size (range->trough, &trough_width, NULL);
1311 gdk_window_get_size (range->slider, &slider_length, NULL);
1313 tleft = GTK_WIDGET (range)->style->klass->xthickness;
1314 tright = trough_width - slider_length - GTK_WIDGET (range)->style->klass->xthickness;
1316 if (range->step_back)
1318 gdk_window_get_size (range->step_back, &tmp_width, NULL);
1319 tleft += (tmp_width + RANGE_CLASS (range)->stepper_slider_spacing);
1322 if (range->step_forw)
1324 gdk_window_get_size (range->step_forw, &tmp_width, NULL);
1325 tright -= (tmp_width + RANGE_CLASS (range)->stepper_slider_spacing);
1335 gtk_range_trough_vdims (GtkRange *range,
1345 g_return_if_fail (range != NULL);
1347 gdk_window_get_size (range->trough, NULL, &trough_height);
1348 gdk_window_get_size (range->slider, NULL, &slider_length);
1350 ttop = GTK_WIDGET (range)->style->klass->xthickness;
1351 tbottom = trough_height - slider_length - GTK_WIDGET (range)->style->klass->ythickness;
1353 if (range->step_back)
1355 gdk_window_get_size (range->step_back, NULL, &tmp_height);
1356 ttop += (tmp_height + RANGE_CLASS (range)->stepper_slider_spacing);
1359 if (range->step_forw)
1361 gdk_window_get_size (range->step_forw, NULL, &tmp_height);
1362 tbottom -= (tmp_height + RANGE_CLASS (range)->stepper_slider_spacing);