]> Pileus Git - ~andy/gtk/blob - gtk/gtkadjustment.c
Add properties to GtkAdjustment. (#64601, Murray Cumming)
[~andy/gtk] / gtk / gtkadjustment.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 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.
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  * Lesser General Public License for more details.
13  *
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.
18  */
19
20 /*
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/. 
25  */
26
27 #include "gtkadjustment.h"
28 #include "gtkintl.h"
29 #include "gtkmarshalers.h"
30
31 enum
32 {
33   PROP_0,
34   PROP_VALUE,
35   PROP_LOWER,
36   PROP_UPPER,
37   PROP_STEP_INCREMENT,
38   PROP_PAGE_INCREMENT,
39   PROP_PAGE_SIZE
40 };
41
42 enum {
43   CHANGED,
44   VALUE_CHANGED,
45   LAST_SIGNAL
46 };
47
48
49 static void gtk_adjustment_class_init (GtkAdjustmentClass *klass);
50 static void gtk_adjustment_init       (GtkAdjustment      *adjustment);
51
52 static void gtk_adjustment_get_property (GObject      *object,
53                                          guint         prop_id,
54                                          GValue       *value,
55                                          GParamSpec   *pspec);
56 static void gtk_adjustment_set_property (GObject      *object,
57                                          guint         prop_id,
58                                          const GValue *value,
59                                          GParamSpec   *pspec);
60
61 static guint adjustment_signals[LAST_SIGNAL] = { 0 };
62
63
64 GType
65 gtk_adjustment_get_type (void)
66 {
67   static GType adjustment_type = 0;
68
69   if (!adjustment_type)
70     {
71       static const GTypeInfo adjustment_info =
72       {
73         sizeof (GtkAdjustmentClass),
74         NULL,           /* base_init */
75         NULL,           /* base_finalize */
76         (GClassInitFunc) gtk_adjustment_class_init,
77         NULL,           /* class_finalize */
78         NULL,           /* class_data */
79         sizeof (GtkAdjustment),
80         0,              /* n_preallocs */
81         (GInstanceInitFunc) gtk_adjustment_init,
82       };
83
84       adjustment_type =
85         g_type_register_static (GTK_TYPE_OBJECT, "GtkAdjustment",
86                                 &adjustment_info, 0);
87     }
88
89   return adjustment_type;
90 }
91
92 static void
93 gtk_adjustment_class_init (GtkAdjustmentClass *class)
94 {
95   GObjectClass *gobject_class = G_OBJECT_CLASS (class);
96
97   gobject_class->set_property = gtk_adjustment_set_property;
98   gobject_class->get_property = gtk_adjustment_get_property;
99
100   class->changed = NULL;
101   class->value_changed = NULL;
102
103   g_object_class_install_property (gobject_class,
104                                    PROP_VALUE,
105                                    g_param_spec_double ("value",
106                                                         P_("Value"),
107                                                         P_("The value of the adjustment"),
108                                                         -G_MAXDOUBLE, 
109                                                         G_MAXDOUBLE, 
110                                                         0.0, 
111                                                         G_PARAM_READWRITE));
112   
113   g_object_class_install_property (gobject_class,
114                                    PROP_LOWER,
115                                    g_param_spec_double ("lower",
116                                                         P_("Minimum Value"),
117                                                         P_("The minimum value of the adjustment"),
118                                                         -G_MAXDOUBLE, 
119                                                         G_MAXDOUBLE, 
120                                                         0.0,
121                                                         G_PARAM_READWRITE));
122   
123   g_object_class_install_property (gobject_class,
124                                    PROP_UPPER,
125                                    g_param_spec_double ("upper",
126                                                         P_("Maximum Value"),
127                                                         P_("The maximum value of the adjustment"),
128                                                         -G_MAXDOUBLE, 
129                                                         G_MAXDOUBLE, 
130                                                         0.0, 
131                                                         G_PARAM_READWRITE));
132   
133   g_object_class_install_property (gobject_class,
134                                    PROP_STEP_INCREMENT,
135                                    g_param_spec_double ("step-increment",
136                                                         P_("Step Increment"),
137                                                         P_("The step increment of the adjustment"),
138                                                         -G_MAXDOUBLE, 
139                                                         G_MAXDOUBLE, 
140                                                         0.0, 
141                                                         G_PARAM_READWRITE));
142   
143   g_object_class_install_property (gobject_class,
144                                    PROP_PAGE_INCREMENT,
145                                    g_param_spec_double ("page-increment",
146                                                         P_("Page Increment"),
147                                                         P_("The page increment of the adjustment"),
148                                                         -G_MAXDOUBLE, 
149                                                         G_MAXDOUBLE, 
150                                                         0.0, 
151                                                         G_PARAM_READWRITE));
152   
153   g_object_class_install_property (gobject_class,
154                                    PROP_PAGE_SIZE,
155                                    g_param_spec_double ("page-size",
156                                                         P_("Page Size"),
157                                                         P_("The page size of the adjustment"),
158                                                         -G_MAXDOUBLE, 
159                                                         G_MAXDOUBLE, 
160                                                         0.0, 
161                                                         G_PARAM_READWRITE));
162   
163
164   adjustment_signals[CHANGED] =
165     g_signal_new ("changed",
166                   G_OBJECT_CLASS_TYPE (class),
167                   G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
168                   G_STRUCT_OFFSET (GtkAdjustmentClass, changed),
169                   NULL, NULL,
170                   _gtk_marshal_VOID__VOID,
171                   G_TYPE_NONE, 0);
172   adjustment_signals[VALUE_CHANGED] =
173     g_signal_new ("value_changed",
174                   G_OBJECT_CLASS_TYPE (class),
175                   G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
176                   G_STRUCT_OFFSET (GtkAdjustmentClass, value_changed),
177                   NULL, NULL,
178                   _gtk_marshal_VOID__VOID,
179                   G_TYPE_NONE, 0);
180 }
181
182 static void
183 gtk_adjustment_init (GtkAdjustment *adjustment)
184 {
185   adjustment->value = 0.0;
186   adjustment->lower = 0.0;
187   adjustment->upper = 0.0;
188   adjustment->step_increment = 0.0;
189   adjustment->page_increment = 0.0;
190   adjustment->page_size = 0.0;
191 }
192
193 static void
194 gtk_adjustment_get_property (GObject *object, guint prop_id, GValue *value, 
195                              GParamSpec *pspec)
196 {
197   GtkAdjustment *adjustment = GTK_ADJUSTMENT (object);
198
199   switch (prop_id)
200     {
201     case PROP_VALUE:
202       g_value_set_double (value, adjustment->value);
203       break;
204     case PROP_LOWER:
205       g_value_set_double (value, adjustment->lower);
206       break;
207     case PROP_UPPER:
208       g_value_set_double (value, adjustment->upper);
209       break;
210     case PROP_STEP_INCREMENT:
211       g_value_set_double (value, adjustment->step_increment);
212       break;
213     case PROP_PAGE_INCREMENT:
214       g_value_set_double (value, adjustment->page_increment);
215       break;
216     case PROP_PAGE_SIZE:
217       g_value_set_double (value, adjustment->page_size);
218       break;
219     default:
220       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
221       break;
222     }
223 }
224
225 static void
226 gtk_adjustment_set_property (GObject * object, guint prop_id, 
227                              const GValue * value, GParamSpec * pspec)
228 {
229   GtkAdjustment *adjustment = GTK_ADJUSTMENT (object);
230   gdouble double_value = g_value_get_double (value);
231
232   switch (prop_id)
233     {
234     case PROP_VALUE:
235       gtk_adjustment_set_value (GTK_ADJUSTMENT (object), double_value);
236       break;
237     case PROP_LOWER:
238       if (adjustment->lower != double_value)
239         {
240           adjustment->lower = double_value;
241           g_object_notify (G_OBJECT (adjustment), "lower");
242         }
243       break;
244     case PROP_UPPER:
245       if (adjustment->upper != double_value)
246         {
247           adjustment->upper = double_value;
248           g_object_notify (G_OBJECT (adjustment), "upper");
249         }
250       break;
251     case PROP_STEP_INCREMENT:
252       if (adjustment->step_increment != double_value)
253         {
254           adjustment->step_increment = double_value;
255           g_object_notify (G_OBJECT (adjustment), "step-increment");
256         }
257       break;
258     case PROP_PAGE_INCREMENT:
259       if (adjustment->page_increment != double_value)
260         {
261           adjustment->page_increment = double_value;
262           g_object_notify (G_OBJECT (adjustment), "page-increment");
263         }
264       break;
265     case PROP_PAGE_SIZE:
266       if (adjustment->page_size != double_value)
267         {
268           adjustment->page_size = double_value;
269           g_object_notify (G_OBJECT (adjustment), "page-size");
270         }
271       break;
272     default:
273       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
274       break;
275     }
276 }
277
278 GtkObject*
279 gtk_adjustment_new (gdouble value,
280                     gdouble lower,
281                     gdouble upper,
282                     gdouble step_increment,
283                     gdouble page_increment,
284                     gdouble page_size)
285 {
286   return g_object_new (GTK_TYPE_ADJUSTMENT, 
287                        "value", value,
288                        "lower", lower,
289                        "upper", upper,
290                        "step-increment", step_increment,
291                        "page-increment", page_increment,
292                        "page_size", page_size,
293                        NULL);
294 }
295
296 /**
297  * gtk_adjustment_get_value:
298  * @adjustment: a #GtkAdjustment
299  *
300  * Gets the current value of the adjustment. See
301  * gtk_adjustment_set_value ().
302  *
303  * Return value: The current value of the adjustment.
304  **/
305 gdouble
306 gtk_adjustment_get_value (GtkAdjustment *adjustment)
307 {
308   g_return_val_if_fail (GTK_IS_ADJUSTMENT (adjustment), 0.);
309
310   return adjustment->value;
311 }
312
313 void
314 gtk_adjustment_set_value (GtkAdjustment        *adjustment,
315                           gdouble               value)
316 {
317   g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment));
318
319   value = CLAMP (value, adjustment->lower, adjustment->upper);
320
321   if (value != adjustment->value)
322     {
323       adjustment->value = value;
324
325       gtk_adjustment_value_changed (adjustment);
326     }
327 }
328
329 void
330 gtk_adjustment_changed (GtkAdjustment        *adjustment)
331 {
332   g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment));
333
334   g_signal_emit (adjustment, adjustment_signals[CHANGED], 0);
335 }
336
337 void
338 gtk_adjustment_value_changed (GtkAdjustment        *adjustment)
339 {
340   g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment));
341
342   g_signal_emit (adjustment, adjustment_signals[VALUE_CHANGED], 0);
343   g_object_notify (G_OBJECT (adjustment), "value");
344 }
345
346 void
347 gtk_adjustment_clamp_page (GtkAdjustment *adjustment,
348                            gdouble        lower,
349                            gdouble        upper)
350 {
351   gboolean need_emission;
352
353   g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment));
354
355   lower = CLAMP (lower, adjustment->lower, adjustment->upper);
356   upper = CLAMP (upper, adjustment->lower, adjustment->upper);
357
358   need_emission = FALSE;
359
360   if (adjustment->value + adjustment->page_size < upper)
361     {
362       adjustment->value = upper - adjustment->page_size;
363       need_emission = TRUE;
364     }
365   if (adjustment->value > lower)
366     {
367       adjustment->value = lower;
368       need_emission = TRUE;
369     }
370
371   if (need_emission)
372     gtk_adjustment_value_changed (adjustment);
373 }