2008-09-15 Alberto Garcia <agarcia@igalia.com>
[hildon] / src / hildon-picker-dialog.c
1 /*
2  * This file is a part of hildon
3  *
4  * Copyright (C) 2005, 2008 Nokia Corporation.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version. or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free
18  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  */
20
21 /**
22  * SECTION:hildon-picker-dialog
23  * @short_description: A utility widget that shows a #HildonTouchSelector widget
24  *
25  * HildonPickerDialog is a utility widget that shows a #HildonTouchSelector widget in
26  * a new dialog (see #GtkDialog for more information about this issue)
27  *
28  */
29
30 #ifdef HAVE_CONFIG_H
31 #include <config.h>
32 #endif
33
34 #include <string.h>
35 #include <stdlib.h>
36 #include <libintl.h>
37
38 #include "hildon-touch-selector.h"
39 #include "hildon-picker-dialog.h"
40
41 #define _(String)  dgettext("hildon-libs", String)
42
43 #define HILDON_PICKER_DIALOG_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), HILDON_TYPE_PICKER_DIALOG, HildonPickerDialogPrivate))
44
45 G_DEFINE_TYPE (HildonPickerDialog, hildon_picker_dialog, GTK_TYPE_DIALOG)
46
47 struct _HildonPickerDialogPrivate
48 {
49   GtkWidget *selector;
50   GtkWidget *separator;
51   GtkWidget *button;
52
53   GtkWidget *title_label;
54
55   gulong signal_id;
56 };
57
58 /* properties */
59 enum
60 {
61   PROP_0,
62   PROP_DONE_BUTTON_TEXT,
63   PROP_LAST
64 };
65
66 enum
67 {
68   RESPONSE,
69   LAST_SIGNAL
70 };
71
72 #define DEFAULT_DONE_BUTTON_TEXT        "Done"
73
74 static void
75 hildon_picker_dialog_set_property (GObject * object,
76                                    guint prop_id,
77                                    const GValue * value,
78                                    GParamSpec * pspec);
79
80 static void
81 hildon_picker_dialog_get_property (GObject * object,
82                                    guint prop_id,
83                                    GValue * value, GParamSpec * pspec);
84 /* gtkwidget */
85 static void hildon_picker_dialog_realize (GtkWidget * widget);
86
87 /* private functions */
88 static gboolean requires_done_button (HildonPickerDialog * dialog);
89
90 static void
91 _select_on_selector_changed_cb (HildonTouchSelector * dialog,
92                                 gint column, gpointer data);
93
94 static gboolean
95 _hildon_picker_dialog_set_selector (HildonPickerDialog * dialog,
96                                     HildonTouchSelector * selector);
97
98 static void
99 _update_title_on_selector_changed_cb (HildonTouchSelector * selector,
100                                       gint column, gpointer data);
101
102 static void
103 hildon_picker_dialog_class_init (HildonPickerDialogClass * class)
104 {
105   GObjectClass *gobject_class;
106   GtkObjectClass *object_class;
107   GtkWidgetClass *widget_class;
108   GtkContainerClass *container_class;
109
110   gobject_class = (GObjectClass *) class;
111   object_class = (GtkObjectClass *) class;
112   widget_class = (GtkWidgetClass *) class;
113   container_class = (GtkContainerClass *) class;
114
115   /* GObject */
116   gobject_class->set_property = hildon_picker_dialog_set_property;
117   gobject_class->get_property = hildon_picker_dialog_get_property;
118
119   /* GtkWidget */
120   widget_class->realize = hildon_picker_dialog_realize;
121
122   /* HildonPickerDialog */
123   class->set_selector = _hildon_picker_dialog_set_selector;
124
125   /* signals */
126
127   /* properties */
128   /**
129    * HildonPickerDialog
130    *
131    * Button label
132    */
133   g_object_class_install_property (gobject_class,
134                                    PROP_DONE_BUTTON_TEXT,
135                                    g_param_spec_string ("done-button-text",
136                                                         "Done Button Label",
137                                                         "Done Button Label",
138                                                         DEFAULT_DONE_BUTTON_TEXT,
139                                                         G_PARAM_READABLE |
140                                                         G_PARAM_WRITABLE |
141                                                         G_PARAM_CONSTRUCT));
142
143   g_type_class_add_private (object_class, sizeof (HildonPickerDialogPrivate));
144 }
145
146
147 static void
148 hildon_picker_dialog_init (HildonPickerDialog * dialog)
149 {
150   GtkWidget *separator = NULL;
151
152   dialog->priv = HILDON_PICKER_DIALOG_GET_PRIVATE (dialog);
153
154   dialog->priv->selector = NULL;
155   dialog->priv->button =
156     gtk_dialog_add_button (GTK_DIALOG (dialog), "", GTK_RESPONSE_OK);
157   gtk_widget_grab_default (dialog->priv->button);
158
159   dialog->priv->title_label = gtk_label_new ("default value");
160   gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
161                       dialog->priv->title_label, FALSE, FALSE, 0);
162   separator = gtk_hseparator_new ();
163   gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
164                       separator, FALSE, FALSE, 0);
165
166   dialog->priv->signal_id = 0;
167
168 /*   gtk_widget_show (dialog->priv->title_label); */
169 /*   gtk_widget_show (separator); */
170 }
171
172
173 static void
174 hildon_picker_dialog_set_property (GObject * object,
175                                    guint param_id,
176                                    const GValue * value, GParamSpec * pspec)
177 {
178   switch (param_id) {
179   case PROP_DONE_BUTTON_TEXT:
180     hildon_picker_dialog_set_done_label (HILDON_PICKER_DIALOG (object),
181                                          g_value_get_string (value));
182     break;
183   default:
184     G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
185     break;
186   }
187 }
188
189 static void
190 hildon_picker_dialog_get_property (GObject * object,
191                                    guint param_id,
192                                    GValue * value, GParamSpec * pspec)
193 {
194   HildonPickerDialog *dialog;
195
196   dialog = HILDON_PICKER_DIALOG (object);
197
198   switch (param_id) {
199   case PROP_DONE_BUTTON_TEXT:
200     g_value_set_string (value, hildon_picker_dialog_get_done_label (dialog));
201     break;
202   default:
203     G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
204     break;
205   }
206 }
207
208
209 static void
210 hildon_picker_dialog_realize (GtkWidget * widget)
211 {
212   GTK_WIDGET_CLASS (hildon_picker_dialog_parent_class)->realize (widget);
213
214 /*   gdk_window_set_decorations (widget->window, GDK_DECOR_BORDER); */
215 }
216
217 /* ------------------------------ PRIVATE METHODS ---------------------------- */
218 static void
219 _select_on_selector_changed_cb (HildonTouchSelector * selector,
220                                 gint column, gpointer data)
221 {
222   HildonPickerDialog *dialog = NULL;
223
224   g_return_if_fail (HILDON_IS_PICKER_DIALOG (data));
225
226   dialog = HILDON_PICKER_DIALOG (data);
227
228   gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
229 }
230
231 static void
232 _update_title_on_selector_changed_cb (HildonTouchSelector * selector,
233                                       gint column, gpointer data)
234 {
235   HildonPickerDialog *dialog = NULL;
236   gchar *new_title = NULL;
237
238   g_return_if_fail (HILDON_IS_PICKER_DIALOG (data));
239
240   dialog = HILDON_PICKER_DIALOG (data);
241
242   new_title = hildon_touch_selector_get_current_text (selector);
243
244   if (dialog->priv->title_label != NULL) {
245 /*       gtk_label_set_text (GTK_LABEL(selector->priv->title_label), new_title); */
246   }
247   gtk_window_set_title (GTK_WINDOW (dialog), new_title);
248
249   g_free (new_title);
250 }
251
252
253 void
254 hildon_picker_dialog_set_done_label (HildonPickerDialog * dialog,
255                                      const gchar * label)
256 {
257   HildonPickerDialogPrivate *priv;
258
259   g_return_if_fail (HILDON_IS_PICKER_DIALOG (dialog));
260   g_return_if_fail (label != NULL);
261
262   priv = HILDON_PICKER_DIALOG_GET_PRIVATE (dialog);
263
264   gtk_button_set_label (GTK_BUTTON (priv->button), label);
265 }
266
267 const gchar *
268 hildon_picker_dialog_get_done_label (HildonPickerDialog * dialog)
269 {
270   HildonPickerDialogPrivate *priv;
271
272   g_return_val_if_fail (HILDON_IS_PICKER_DIALOG (dialog), NULL);
273
274   priv = HILDON_PICKER_DIALOG_GET_PRIVATE (dialog);
275
276   return gtk_button_get_label (GTK_BUTTON (priv->button));
277 }
278
279 static gboolean
280 requires_done_button (HildonPickerDialog * dialog)
281 {
282   return hildon_touch_selector_has_multiple_selection
283     (HILDON_TOUCH_SELECTOR (dialog->priv->selector));
284 }
285
286 /* ------------------------------ PUBLIC METHODS ---------------------------- */
287
288 /**
289  * hildon_picker_dialog_new:
290  * @parent: the parent window
291  *
292  * Creates a new #HildonPickerDialog
293  *
294  * Returns: a new #HildonPickerDialog
295  **/
296 GtkWidget *
297 hildon_picker_dialog_new (GtkWindow * parent)
298 {
299   GtkDialog *dialog = NULL;
300
301   dialog = g_object_new (HILDON_TYPE_PICKER_DIALOG, NULL);
302
303   if (parent) {
304     gtk_window_set_transient_for (GTK_WINDOW (dialog), parent);
305   }
306
307   return GTK_WIDGET (dialog);
308 }
309
310
311 static gboolean
312 _hildon_picker_dialog_set_selector (HildonPickerDialog * dialog,
313                                     HildonTouchSelector * selector)
314 {
315   if (dialog->priv->selector != NULL) {
316     gtk_container_remove (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox),
317                           dialog->priv->selector);
318     g_object_unref (dialog->priv->selector);
319     dialog->priv->selector = NULL;
320   }
321
322   dialog->priv->selector = GTK_WIDGET (selector);
323
324   if (dialog->priv->selector != NULL) {
325     gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
326                         dialog->priv->selector, TRUE, TRUE, 0);
327     gtk_widget_show (dialog->priv->selector);
328     g_object_ref (dialog->priv->selector);
329   }
330
331   if (dialog->priv->signal_id) {
332     g_signal_handler_disconnect (dialog->priv->selector,
333                                  dialog->priv->signal_id);
334   }
335
336   if (requires_done_button (dialog)) {
337     gtk_dialog_set_has_separator (GTK_DIALOG (dialog), TRUE);
338     gtk_widget_show (GTK_DIALOG (dialog)->action_area);
339     /* update the title */
340     dialog->priv->signal_id =
341       g_signal_connect (G_OBJECT (dialog->priv->selector), "changed",
342                         G_CALLBACK (_update_title_on_selector_changed_cb),
343                         dialog);
344   } else {
345     gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
346     gtk_widget_hide (GTK_DIALOG (dialog)->action_area);
347     dialog->priv->signal_id =
348       g_signal_connect (G_OBJECT (dialog->priv->selector), "changed",
349                         G_CALLBACK (_select_on_selector_changed_cb), dialog);
350   }
351
352   return TRUE;
353 }
354
355 gboolean
356 hildon_picker_dialog_set_selector (HildonPickerDialog * dialog,
357                                    HildonTouchSelector * selector)
358 {
359   g_return_val_if_fail (HILDON_IS_PICKER_DIALOG (dialog), FALSE);
360   g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR (selector), FALSE);
361
362   return HILDON_PICKER_DIALOG_GET_CLASS (dialog)->set_selector (dialog, selector);
363 }
364
365 HildonTouchSelector *
366 hildon_picker_dialog_get_selector (HildonPickerDialog * dialog)
367 {
368   g_return_val_if_fail (HILDON_IS_PICKER_DIALOG (dialog), NULL);
369
370   return HILDON_TOUCH_SELECTOR (dialog->priv->selector);
371 }