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 Lesser 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 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser 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.
21 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
22 * file for a list of people on the GTK+ Team. See the ChangeLog
23 * files for a list of changes. These files are distributed with
24 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
30 #include "gtkmarshal.h"
44 static guint signals[LAST_SIGNAL];
46 static void gtk_scale_class_init (GtkScaleClass *klass);
47 static void gtk_scale_init (GtkScale *scale);
48 static void gtk_scale_set_arg (GtkObject *object,
51 static void gtk_scale_get_arg (GtkObject *object,
54 static void gtk_scale_map (GtkWidget *widget);
55 static void gtk_scale_unmap (GtkWidget *widget);
57 static void gtk_scale_draw_background (GtkRange *range);
60 static GtkRangeClass *parent_class = NULL;
64 gtk_scale_get_type (void)
66 static GtkType scale_type = 0;
70 static const GtkTypeInfo scale_info =
74 sizeof (GtkScaleClass),
75 (GtkClassInitFunc) gtk_scale_class_init,
76 (GtkObjectInitFunc) gtk_scale_init,
77 /* reserved_1 */ NULL,
78 /* reserved_2 */ NULL,
79 (GtkClassInitFunc) NULL,
82 scale_type = gtk_type_unique (GTK_TYPE_RANGE, &scale_info);
89 single_string_accumulator (GSignalInvocationHint *ihint,
91 const GValue *handler_return,
94 gboolean continue_emission;
97 str = g_value_get_string (handler_return);
98 g_value_set_string (return_accu, str);
99 continue_emission = str == NULL;
101 return continue_emission;
105 gtk_scale_class_init (GtkScaleClass *class)
107 GtkObjectClass *object_class;
108 GtkWidgetClass *widget_class;
109 GtkRangeClass *range_class;
111 object_class = (GtkObjectClass*) class;
112 range_class = (GtkRangeClass*) class;
113 widget_class = (GtkWidgetClass*) class;
115 parent_class = gtk_type_class (GTK_TYPE_RANGE);
117 gtk_object_add_arg_type ("GtkScale::digits",
121 gtk_object_add_arg_type ("GtkScale::draw_value",
125 gtk_object_add_arg_type ("GtkScale::value_pos",
126 GTK_TYPE_POSITION_TYPE,
130 signals[FORMAT_VALUE] =
131 g_signal_newc ("format_value",
132 G_TYPE_FROM_CLASS (object_class),
134 G_STRUCT_OFFSET (GtkScaleClass, format_value),
135 single_string_accumulator, NULL,
136 gtk_marshal_STRING__DOUBLE,
140 object_class->set_arg = gtk_scale_set_arg;
141 object_class->get_arg = gtk_scale_get_arg;
143 widget_class->map = gtk_scale_map;
144 widget_class->unmap = gtk_scale_unmap;
146 range_class->draw_background = gtk_scale_draw_background;
148 gtk_widget_class_install_style_property (widget_class,
149 g_param_spec_int ("slider_length",
151 _("Length of scale's slider"),
156 class->value_spacing = 2;
157 class->draw_value = NULL;
161 gtk_scale_set_arg (GtkObject *object,
167 scale = GTK_SCALE (object);
172 gtk_scale_set_digits (scale, GTK_VALUE_INT (*arg));
175 gtk_scale_set_draw_value (scale, GTK_VALUE_BOOL (*arg));
178 gtk_scale_set_value_pos (scale, GTK_VALUE_ENUM (*arg));
186 gtk_scale_get_arg (GtkObject *object,
192 scale = GTK_SCALE (object);
197 GTK_VALUE_INT (*arg) = GTK_RANGE (scale)->digits;
200 GTK_VALUE_BOOL (*arg) = scale->draw_value;
203 GTK_VALUE_ENUM (*arg) = scale->value_pos;
206 arg->type = GTK_TYPE_INVALID;
212 gtk_scale_init (GtkScale *scale)
214 GTK_WIDGET_SET_FLAGS (scale, GTK_CAN_FOCUS);
215 GTK_WIDGET_SET_FLAGS (scale, GTK_NO_WINDOW);
216 GTK_RANGE (scale)->digits = 1;
217 scale->draw_value = TRUE;
218 scale->value_pos = GTK_POS_TOP;
222 gtk_scale_map (GtkWidget *widget)
226 g_return_if_fail (widget != NULL);
227 g_return_if_fail (GTK_IS_SCALE (widget));
229 GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
230 range = GTK_RANGE (widget);
232 gdk_window_show (range->trough);
236 gtk_scale_unmap (GtkWidget *widget)
240 g_return_if_fail (widget != NULL);
241 g_return_if_fail (GTK_IS_SCALE (widget));
243 GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
244 range = GTK_RANGE (widget);
246 if (GTK_WIDGET_NO_WINDOW (widget))
247 gtk_widget_queue_clear (widget);
249 gdk_window_hide (range->trough);
253 gtk_scale_set_digits (GtkScale *scale,
256 g_return_if_fail (scale != NULL);
257 g_return_if_fail (GTK_IS_SCALE (scale));
259 digits = CLAMP (digits, -1, 16);
261 if (GTK_RANGE (scale)->digits != digits)
263 GTK_RANGE (scale)->digits = digits;
265 gtk_widget_queue_resize (GTK_WIDGET (scale));
270 gtk_scale_set_draw_value (GtkScale *scale,
273 g_return_if_fail (scale != NULL);
274 g_return_if_fail (GTK_IS_SCALE (scale));
276 draw_value = draw_value != FALSE;
278 if (scale->draw_value != draw_value)
280 scale->draw_value = draw_value;
282 gtk_widget_queue_resize (GTK_WIDGET (scale));
287 gtk_scale_set_value_pos (GtkScale *scale,
290 g_return_if_fail (scale != NULL);
291 g_return_if_fail (GTK_IS_SCALE (scale));
293 if (scale->value_pos != pos)
295 scale->value_pos = pos;
297 if (GTK_WIDGET_VISIBLE (scale) && GTK_WIDGET_MAPPED (scale))
298 gtk_widget_queue_resize (GTK_WIDGET (scale));
303 gtk_scale_get_value_size (GtkScale *scale,
309 g_return_if_fail (scale != NULL);
310 g_return_if_fail (GTK_IS_SCALE (scale));
312 if (scale->draw_value)
315 PangoRectangle logical_rect;
318 range = GTK_RANGE (scale);
320 layout = gtk_widget_create_pango_layout (GTK_WIDGET (scale), NULL);
322 txt = _gtk_scale_format_value (scale, range->adjustment->lower);
323 pango_layout_set_text (layout, txt, -1);
326 pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
329 *width = logical_rect.width;
331 *height = logical_rect.height;
333 txt = _gtk_scale_format_value (scale, range->adjustment->upper);
334 pango_layout_set_text (layout, txt, -1);
337 pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
340 *width = MAX (*width, logical_rect.width);
342 *height = MAX (*height, logical_rect.height);
344 g_object_unref (G_OBJECT (layout));
357 gtk_scale_get_value_width (GtkScale *scale)
361 g_return_val_if_fail (scale != NULL, 0);
362 g_return_val_if_fail (GTK_IS_SCALE (scale), 0);
364 gtk_scale_get_value_size (scale, &width, NULL);
370 gtk_scale_draw_value (GtkScale *scale)
372 g_return_if_fail (scale != NULL);
373 g_return_if_fail (GTK_IS_SCALE (scale));
375 if (GTK_SCALE_GET_CLASS (scale)->draw_value)
376 GTK_SCALE_GET_CLASS (scale)->draw_value (scale);
381 gtk_scale_draw_background (GtkRange *range)
383 g_return_if_fail (range != NULL);
384 g_return_if_fail (GTK_IS_SCALE (range));
386 gtk_scale_draw_value (GTK_SCALE (range));
390 * _gtk_scale_format_value:
391 * @scale: a #GtkScale
392 * @value: adjustment value
394 * Emits "format_value" signal to format the value, if no user
395 * signal handlers, falls back to a default format.
397 * Return value: formatted value
400 _gtk_scale_format_value (GtkScale *scale,
405 g_signal_emit (G_OBJECT (scale),
406 signals[FORMAT_VALUE],
414 return g_strdup_printf ("%0.*f", GTK_RANGE (scale)->digits,