]> Pileus Git - ~andy/gtk/blob - gtk/gtkscale.c
documented necessary changes for 1.4 transition.
[~andy/gtk] / gtk / gtkscale.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
20 /*
21  * Modified by the GTK+ Team and others 1997-1999.  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/. 
25  */
26
27 #include <math.h>
28 #include "gtkcontainer.h"
29 #include "gtkscale.h"
30
31
32 enum {
33   ARG_0,
34   ARG_DIGITS,
35   ARG_DRAW_VALUE,
36   ARG_VALUE_POS
37 };
38
39
40 static void gtk_scale_class_init      (GtkScaleClass *klass);
41 static void gtk_scale_init            (GtkScale      *scale);
42 static void gtk_scale_set_arg         (GtkObject     *object,
43                                        GtkArg        *arg,
44                                        guint          arg_id);
45 static void gtk_scale_get_arg         (GtkObject     *object,
46                                        GtkArg        *arg,
47                                        guint          arg_id);
48 static void gtk_scale_map             (GtkWidget     *widget);
49 static void gtk_scale_unmap           (GtkWidget     *widget);
50
51 static void gtk_scale_draw_background (GtkRange      *range);
52
53
54 static GtkRangeClass *parent_class = NULL;
55
56
57 GtkType
58 gtk_scale_get_type (void)
59 {
60   static GtkType scale_type = 0;
61
62   if (!scale_type)
63     {
64       static const GtkTypeInfo scale_info =
65       {
66         "GtkScale",
67         sizeof (GtkScale),
68         sizeof (GtkScaleClass),
69         (GtkClassInitFunc) gtk_scale_class_init,
70         (GtkObjectInitFunc) gtk_scale_init,
71         /* reserved_1 */ NULL,
72         /* reserved_2 */ NULL,
73         (GtkClassInitFunc) NULL,
74       };
75
76       scale_type = gtk_type_unique (GTK_TYPE_RANGE, &scale_info);
77     }
78
79   return scale_type;
80 }
81
82 static void
83 gtk_scale_class_init (GtkScaleClass *class)
84 {
85   GtkObjectClass *object_class;
86   GtkWidgetClass *widget_class;
87   GtkRangeClass *range_class;
88
89   object_class = (GtkObjectClass*) class;
90   range_class = (GtkRangeClass*) class;
91   widget_class = (GtkWidgetClass*) class;
92   
93   parent_class = gtk_type_class (GTK_TYPE_RANGE);
94   
95   gtk_object_add_arg_type ("GtkScale::digits",
96                            GTK_TYPE_INT,
97                            GTK_ARG_READWRITE,
98                            ARG_DIGITS);
99   gtk_object_add_arg_type ("GtkScale::draw_value",
100                            GTK_TYPE_BOOL,
101                            GTK_ARG_READWRITE,
102                            ARG_DRAW_VALUE);
103   gtk_object_add_arg_type ("GtkScale::value_pos",
104                            GTK_TYPE_POSITION_TYPE,
105                            GTK_ARG_READWRITE,
106                            ARG_VALUE_POS);
107
108   object_class->set_arg = gtk_scale_set_arg;
109   object_class->get_arg = gtk_scale_get_arg;
110
111   widget_class->map = gtk_scale_map;
112   widget_class->unmap = gtk_scale_unmap;
113   
114   range_class->draw_background = gtk_scale_draw_background;
115
116   class->slider_length = 31;
117   class->value_spacing = 2;
118   class->draw_value = NULL;
119 }
120
121 static void
122 gtk_scale_set_arg (GtkObject      *object,
123                    GtkArg         *arg,
124                    guint           arg_id)
125 {
126   GtkScale *scale;
127
128   scale = GTK_SCALE (object);
129
130   switch (arg_id)
131     {
132     case ARG_DIGITS:
133       gtk_scale_set_digits (scale, GTK_VALUE_INT (*arg));
134       break;
135     case ARG_DRAW_VALUE:
136       gtk_scale_set_draw_value (scale, GTK_VALUE_BOOL (*arg));
137       break;
138     case ARG_VALUE_POS:
139       gtk_scale_set_value_pos (scale, GTK_VALUE_ENUM (*arg));
140       break;
141     default:
142       break;
143     }
144 }
145
146 static void
147 gtk_scale_get_arg (GtkObject      *object,
148                    GtkArg         *arg,
149                    guint           arg_id)
150 {
151   GtkScale *scale;
152
153   scale = GTK_SCALE (object);
154
155   switch (arg_id)
156     {
157     case ARG_DIGITS:
158       GTK_VALUE_INT (*arg) = GTK_RANGE (scale)->digits;
159       break;
160     case ARG_DRAW_VALUE:
161       GTK_VALUE_BOOL (*arg) = scale->draw_value;
162       break;
163     case ARG_VALUE_POS:
164       GTK_VALUE_ENUM (*arg) = scale->value_pos;
165       break;
166     default:
167       arg->type = GTK_TYPE_INVALID;
168       break;
169     }
170 }
171
172 static void
173 gtk_scale_init (GtkScale *scale)
174 {
175   GTK_WIDGET_SET_FLAGS (scale, GTK_CAN_FOCUS);
176   GTK_WIDGET_SET_FLAGS (scale, GTK_NO_WINDOW);
177   GTK_RANGE (scale)->digits = 1;
178   scale->draw_value = TRUE;
179   scale->value_pos = GTK_POS_TOP;
180 }
181
182 static void
183 gtk_scale_map (GtkWidget *widget)
184 {
185   GtkRange *range;
186
187   g_return_if_fail (widget != NULL);
188   g_return_if_fail (GTK_IS_SCALE (widget));
189
190   GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
191   range = GTK_RANGE (widget);
192
193   gdk_window_show (range->trough);
194 }
195
196 static void
197 gtk_scale_unmap (GtkWidget *widget)
198 {
199   GtkRange *range;
200
201   g_return_if_fail (widget != NULL);
202   g_return_if_fail (GTK_IS_SCALE (widget));
203
204   GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
205   range = GTK_RANGE (widget);
206
207   if (GTK_WIDGET_NO_WINDOW (widget))
208      gtk_widget_queue_clear (widget);
209
210   gdk_window_hide (range->trough);
211 }
212
213 void
214 gtk_scale_set_digits (GtkScale *scale,
215                       gint      digits)
216 {
217   g_return_if_fail (scale != NULL);
218   g_return_if_fail (GTK_IS_SCALE (scale));
219
220   digits = CLAMP (digits, -1, 16);
221
222   if (GTK_RANGE (scale)->digits != digits)
223     {
224       GTK_RANGE (scale)->digits = digits;
225
226       gtk_widget_queue_resize (GTK_WIDGET (scale));
227     }
228 }
229
230 void
231 gtk_scale_set_draw_value (GtkScale *scale,
232                           gboolean  draw_value)
233 {
234   g_return_if_fail (scale != NULL);
235   g_return_if_fail (GTK_IS_SCALE (scale));
236
237   draw_value = draw_value != FALSE;
238
239   if (scale->draw_value != draw_value)
240     {
241       scale->draw_value = draw_value;
242
243       gtk_widget_queue_resize (GTK_WIDGET (scale));
244     }
245 }
246
247 void
248 gtk_scale_set_value_pos (GtkScale        *scale,
249                          GtkPositionType  pos)
250 {
251   g_return_if_fail (scale != NULL);
252   g_return_if_fail (GTK_IS_SCALE (scale));
253
254   if (scale->value_pos != pos)
255     {
256       scale->value_pos = pos;
257
258       if (GTK_WIDGET_VISIBLE (scale) && GTK_WIDGET_MAPPED (scale))
259         gtk_widget_queue_resize (GTK_WIDGET (scale));
260     }
261 }
262
263 gint
264 gtk_scale_get_value_width (GtkScale *scale)
265 {
266   GtkRange *range;
267   gchar buffer[128];
268   gfloat value;
269   gint temp;
270   gint return_val;
271   gint digits;
272   gint i, j;
273
274   g_return_val_if_fail (scale != NULL, 0);
275   g_return_val_if_fail (GTK_IS_SCALE (scale), 0);
276
277   return_val = 0;
278   if (scale->draw_value)
279     {
280       range = GTK_RANGE (scale);
281
282       value = ABS (range->adjustment->lower);
283       if (value == 0) value = 1;
284       digits = log10 (value) + 1;
285       if (digits > 13)
286         digits = 13;
287
288       i = 0;
289       if (range->adjustment->lower < 0)
290         buffer[i++] = '-';
291       for (j = 0; j < digits; j++)
292         buffer[i++] = '0';
293       if (GTK_RANGE (scale)->digits)
294         buffer[i++] = '.';
295       for (j = 0; j < GTK_RANGE (scale)->digits; j++)
296         buffer[i++] = '0';
297       buffer[i] = '\0';
298
299       return_val = gdk_string_measure (GTK_WIDGET (scale)->style->font, buffer);
300
301       value = ABS (range->adjustment->upper);
302       if (value == 0) value = 1;
303       digits = log10 (value) + 1;
304       if (digits > 13)
305         digits = 13;
306
307       i = 0;
308       if (range->adjustment->upper < 0)
309         buffer[i++] = '-';
310       for (j = 0; j < digits; j++)
311         buffer[i++] = '0';
312       if (GTK_RANGE (scale)->digits)
313         buffer[i++] = '.';
314       for (j = 0; j < GTK_RANGE (scale)->digits; j++)
315         buffer[i++] = '0';
316       buffer[i] = '\0';
317
318       temp = gdk_string_measure (GTK_WIDGET (scale)->style->font, buffer);
319       return_val = MAX (return_val, temp);
320     }
321
322   return return_val;
323 }
324
325 void
326 gtk_scale_draw_value (GtkScale *scale)
327 {
328   g_return_if_fail (scale != NULL);
329   g_return_if_fail (GTK_IS_SCALE (scale));
330
331   if (GTK_SCALE_GET_CLASS (scale)->draw_value)
332     GTK_SCALE_GET_CLASS (scale)->draw_value (scale);
333 }
334
335
336 static void
337 gtk_scale_draw_background (GtkRange *range)
338 {
339   g_return_if_fail (range != NULL);
340   g_return_if_fail (GTK_IS_SCALE (range));
341
342   gtk_scale_draw_value (GTK_SCALE (range));
343 }