]> Pileus Git - ~andy/gtk/blob - gtk/gtkcellrendererspin.c
Match parameter names with the headers.
[~andy/gtk] / gtk / gtkcellrendererspin.c
1 /* GtkCellRendererSpin
2  * Copyright (C) 2004 Lorenzo Gil Sanchez
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  * Authors: Lorenzo Gil Sanchez    <lgs@sicem.biz>
20  *          Carlos Garnacho Parro  <carlosg@gnome.org>
21  */
22
23 #include <config.h>
24 #include <gdk/gdkkeysyms.h>
25 #include "gtkintl.h"
26 #include "gtkprivate.h"
27 #include "gtkspinbutton.h"
28 #include "gtkcellrendererspin.h"
29 #include "gtkalias.h"
30
31 #define GTK_CELL_RENDERER_SPIN_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_CELL_RENDERER_SPIN, GtkCellRendererSpinPrivate))
32
33 struct _GtkCellRendererSpinPrivate
34 {
35   GtkAdjustment *adjustment;
36   gdouble climb_rate;
37   guint   digits;
38 };
39
40 static void gtk_cell_renderer_spin_class_init (GtkCellRendererSpinClass *klass);
41 static void gtk_cell_renderer_spin_init       (GtkCellRendererSpin      *self);
42 static void gtk_cell_renderer_spin_finalize   (GObject                  *object);
43
44 static void gtk_cell_renderer_spin_get_property (GObject      *object,
45                                                  guint         prop_id,
46                                                  GValue       *value,
47                                                  GParamSpec   *spec);
48 static void gtk_cell_renderer_spin_set_property (GObject      *object,
49                                                  guint         prop_id,
50                                                  const GValue *value,
51                                                  GParamSpec   *spec);
52
53 static GtkCellEditable * gtk_cell_renderer_spin_start_editing (GtkCellRenderer     *cell,
54                                                                GdkEvent            *event,
55                                                                GtkWidget           *widget,
56                                                                const gchar         *path,
57                                                                GdkRectangle        *background_area,
58                                                                GdkRectangle        *cell_area,
59                                                                GtkCellRendererState flags);
60 enum {
61   PROP_0,
62   PROP_ADJUSTMENT,
63   PROP_CLIMB_RATE,
64   PROP_DIGITS
65 };
66
67 #define GTK_CELL_RENDERER_SPIN_PATH "gtk-cell-renderer-spin-path"
68
69 G_DEFINE_TYPE (GtkCellRendererSpin, gtk_cell_renderer_spin, GTK_TYPE_CELL_RENDERER_TEXT);
70
71
72 static void
73 gtk_cell_renderer_spin_class_init (GtkCellRendererSpinClass *klass)
74 {
75   GObjectClass *object_class = G_OBJECT_CLASS (klass);
76   GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS (klass);
77
78   object_class->finalize     = gtk_cell_renderer_spin_finalize;
79   object_class->get_property = gtk_cell_renderer_spin_get_property;
80   object_class->set_property = gtk_cell_renderer_spin_set_property;
81
82   cell_class->start_editing  = gtk_cell_renderer_spin_start_editing;
83
84   /**
85    * GtkCellRendererSpin:adjustment:
86    *
87    * The adjustment that holds the value of the spinbutton. 
88    * This must be non-%NULL for the cell renderer to be editable.
89    *
90    * Since: 2.10
91    */
92   g_object_class_install_property (object_class,
93                                    PROP_ADJUSTMENT,
94                                    g_param_spec_object ("adjustment",
95                                                         P_("Adjustment"),
96                                                         P_("The adjustment that holds the value of the spinbutton."),
97                                                         GTK_TYPE_ADJUSTMENT,
98                                                         GTK_PARAM_READWRITE));
99
100
101   /**
102    * GtkCellRendererSpin:climb-rate:
103    *
104    * The acceleration rate when you hold down a button.
105    *
106    * Since: 2.10
107    */
108   g_object_class_install_property (object_class,
109                                    PROP_CLIMB_RATE,
110                                    g_param_spec_double ("climb-rate",
111                                                         P_("Climb rate"),
112                                                         P_("The acceleration rate when you hold down a button"),
113                                                         0.0, G_MAXDOUBLE, 0.0,
114                                                         GTK_PARAM_READWRITE));  
115   /**
116    * GtkCellRendererSpin:digits:
117    *
118    * The number of decimal places to display.
119    *
120    * Since: 2.10
121    */
122   g_object_class_install_property (object_class,
123                                    PROP_DIGITS,
124                                    g_param_spec_uint ("digits",
125                                                       P_("Digits"),
126                                                       P_("The number of decimal places to display"),
127                                                       0, 20, 0,
128                                                       GTK_PARAM_READWRITE));  
129
130   g_type_class_add_private (object_class, sizeof (GtkCellRendererSpinPrivate));
131 }
132
133 static void
134 gtk_cell_renderer_spin_init (GtkCellRendererSpin *self)
135 {
136   GtkCellRendererSpinPrivate *priv;
137
138   priv = GTK_CELL_RENDERER_SPIN_GET_PRIVATE (self);
139
140   priv->adjustment = NULL;
141   priv->climb_rate = 0.0;
142   priv->digits = 0;
143 }
144
145 static void
146 gtk_cell_renderer_spin_finalize (GObject *object)
147 {
148   GtkCellRendererSpinPrivate *priv;
149
150   priv = GTK_CELL_RENDERER_SPIN_GET_PRIVATE (object);
151
152   if (priv && priv->adjustment)
153     g_object_unref (priv->adjustment);
154
155   if (G_OBJECT_CLASS (gtk_cell_renderer_spin_parent_class)->finalize)
156     (* G_OBJECT_CLASS (gtk_cell_renderer_spin_parent_class)->finalize) (object);
157 }
158
159 static void
160 gtk_cell_renderer_spin_get_property (GObject      *object,
161                                      guint         prop_id,
162                                      GValue       *value,
163                                      GParamSpec   *pspec)
164 {
165   GtkCellRendererSpin *renderer;
166   GtkCellRendererSpinPrivate *priv;
167
168   renderer = GTK_CELL_RENDERER_SPIN (object);
169   priv = GTK_CELL_RENDERER_SPIN_GET_PRIVATE (renderer);
170
171   switch (prop_id)
172     {
173     case PROP_ADJUSTMENT:
174       g_value_set_object (value, priv->adjustment);
175       break;
176     case PROP_CLIMB_RATE:
177       g_value_set_double (value, priv->climb_rate);
178       break;
179     case PROP_DIGITS:
180       g_value_set_uint (value, priv->digits);
181       break;
182     default:
183       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
184       break;
185     }
186 }
187
188 static void
189 gtk_cell_renderer_spin_set_property (GObject      *object,
190                                      guint         prop_id,
191                                      const GValue *value,
192                                      GParamSpec   *pspec)
193 {
194   GtkCellRendererSpin *renderer;
195   GtkCellRendererSpinPrivate *priv;
196   GObject *obj;
197
198   renderer = GTK_CELL_RENDERER_SPIN (object);
199   priv = GTK_CELL_RENDERER_SPIN_GET_PRIVATE (renderer);
200
201   switch (prop_id)
202     {
203     case PROP_ADJUSTMENT:
204       obj = g_value_get_object (value);
205
206       if (priv->adjustment)
207         {
208           g_object_unref (priv->adjustment);
209           priv->adjustment = NULL;
210         }
211
212       if (obj)
213         priv->adjustment = g_object_ref (obj);
214       break;
215     case PROP_CLIMB_RATE:
216       priv->climb_rate = g_value_get_double (value);
217       break;
218     case PROP_DIGITS:
219       priv->digits = g_value_get_uint (value);
220       break;
221     default:
222       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
223       break;
224     }
225 }
226
227 static gboolean
228 gtk_cell_renderer_spin_focus_out_event (GtkWidget *widget,
229                                         GdkEvent  *event,
230                                         gpointer   data)
231 {
232   const gchar *path;
233   const gchar *new_text;
234   gboolean canceled;
235
236   canceled = GTK_ENTRY (widget)->editing_canceled;
237
238   g_signal_handlers_disconnect_by_func (widget,
239                                         gtk_cell_renderer_spin_focus_out_event,
240                                         data);
241
242   gtk_cell_renderer_stop_editing (GTK_CELL_RENDERER (data), canceled);
243
244   if (!canceled)
245     {
246       path = g_object_get_data (G_OBJECT (widget), GTK_CELL_RENDERER_SPIN_PATH);
247
248       new_text = gtk_entry_get_text (GTK_ENTRY (widget));
249       g_signal_emit_by_name (data, "edited", path, new_text);
250     }
251   
252   return FALSE;
253 }
254
255 static gboolean
256 gtk_cell_renderer_spin_key_press_event (GtkWidget   *widget,
257                                         GdkEventKey *event,
258                                         gpointer     data)
259 {
260   if (event->state == 0)
261     {
262       if (event->keyval == GDK_Up)
263         {
264           gtk_spin_button_spin (GTK_SPIN_BUTTON (widget), GTK_SPIN_STEP_FORWARD, 1);
265           return TRUE;
266         }
267       else if (event->keyval == GDK_Down)
268         {
269           gtk_spin_button_spin (GTK_SPIN_BUTTON (widget), GTK_SPIN_STEP_BACKWARD, 1);
270           return TRUE;
271         }
272     }
273
274   return FALSE;
275 }
276
277 static GtkCellEditable *
278 gtk_cell_renderer_spin_start_editing (GtkCellRenderer     *cell,
279                                       GdkEvent            *event,
280                                       GtkWidget           *widget,
281                                       const gchar         *path,
282                                       GdkRectangle        *background_area,
283                                       GdkRectangle        *cell_area,
284                                       GtkCellRendererState flags)
285 {
286   GtkCellRendererSpinPrivate *priv;
287   GtkCellRendererText *cell_text;
288   GtkWidget *spin;
289
290   cell_text = GTK_CELL_RENDERER_TEXT (cell);
291   priv = GTK_CELL_RENDERER_SPIN_GET_PRIVATE (cell);
292
293   if (!cell_text->editable)
294     return NULL;
295
296   if (!priv->adjustment)
297     return NULL;
298
299   spin = gtk_spin_button_new (g_object_ref (priv->adjustment),
300                               priv->climb_rate, priv->digits);
301
302   if (cell_text->text)
303     gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin),
304                                g_ascii_strtod (cell_text->text, NULL));
305
306   g_object_set_data_full (G_OBJECT (spin), GTK_CELL_RENDERER_SPIN_PATH,
307                           g_strdup (path), g_free);
308
309   g_signal_connect (G_OBJECT (spin), "focus_out_event",
310                     G_CALLBACK (gtk_cell_renderer_spin_focus_out_event),
311                     cell);
312   g_signal_connect (G_OBJECT (spin), "key_press_event",
313                     G_CALLBACK (gtk_cell_renderer_spin_key_press_event),
314                     cell);
315
316   gtk_widget_show (spin);
317
318   return GTK_CELL_EDITABLE (spin);
319 }
320
321 /**
322  * gtk_cell_renderer_spin_new:
323  *
324  * Creates a new #GtkCellRendererSpin. 
325  *
326  * Returns: a new #GtkCellRendererSpin
327  *
328  * Since: 2.10
329  */
330 GtkCellRenderer *
331 gtk_cell_renderer_spin_new (void)
332 {
333   return g_object_new (GTK_TYPE_CELL_RENDERER_SPIN, NULL);
334 }
335
336
337 #define __GTK_CELL_RENDERER_SPIN_C__
338 #include  "gtkaliasdef.c"