2008-10-09 Alejandro Pinheiro <apinheiro@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 (a #HildonDialog)
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, HILDON_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
86 /* private functions */
87 static gboolean requires_done_button (HildonPickerDialog * dialog);
88
89 static void
90 _select_on_selector_changed_cb (HildonTouchSelector * dialog,
91                                 gint column, gpointer data);
92
93 static gboolean
94 _hildon_picker_dialog_set_selector (HildonPickerDialog * dialog,
95                                     HildonTouchSelector * selector);
96
97 static void
98 _update_title_on_selector_changed_cb (HildonTouchSelector * selector,
99                                       gint column, gpointer data);
100
101 static void
102 hildon_picker_dialog_class_init (HildonPickerDialogClass * class)
103 {
104   GObjectClass *gobject_class;
105   GtkObjectClass *object_class;
106   GtkWidgetClass *widget_class;
107   GtkContainerClass *container_class;
108
109   gobject_class = (GObjectClass *) class;
110   object_class = (GtkObjectClass *) class;
111   widget_class = (GtkWidgetClass *) class;
112   container_class = (GtkContainerClass *) class;
113
114   /* GObject */
115   gobject_class->set_property = hildon_picker_dialog_set_property;
116   gobject_class->get_property = hildon_picker_dialog_get_property;
117
118   /* GtkWidget */
119
120   /* HildonPickerDialog */
121   class->set_selector = _hildon_picker_dialog_set_selector;
122
123   /* signals */
124
125   /* properties */
126   /**
127    * HildonPickerDialog
128    *
129    * Button label
130    */
131   g_object_class_install_property (gobject_class,
132                                    PROP_DONE_BUTTON_TEXT,
133                                    g_param_spec_string ("done-button-text",
134                                                         "Done Button Label",
135                                                         "Done Button Label",
136                                                         DEFAULT_DONE_BUTTON_TEXT,
137                                                         G_PARAM_READABLE |
138                                                         G_PARAM_WRITABLE |
139                                                         G_PARAM_CONSTRUCT));
140
141   g_type_class_add_private (object_class, sizeof (HildonPickerDialogPrivate));
142 }
143
144
145 static void
146 hildon_picker_dialog_init (HildonPickerDialog * dialog)
147 {
148   GtkWidget *separator = NULL;
149
150   dialog->priv = HILDON_PICKER_DIALOG_GET_PRIVATE (dialog);
151
152   dialog->priv->selector = NULL;
153   dialog->priv->button =
154     hildon_dialog_add_button (HILDON_DIALOG (dialog), "", GTK_RESPONSE_OK);
155   gtk_widget_grab_default (dialog->priv->button);
156
157   dialog->priv->title_label = gtk_label_new ("default value");
158   gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
159                       dialog->priv->title_label, FALSE, FALSE, 0);
160   separator = gtk_hseparator_new ();
161   gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
162                       separator, FALSE, FALSE, 0);
163
164   dialog->priv->signal_id = 0;
165
166 /*   gtk_widget_show (dialog->priv->title_label); */
167 /*   gtk_widget_show (separator); */
168 }
169
170
171 static void
172 hildon_picker_dialog_set_property (GObject * object,
173                                    guint param_id,
174                                    const GValue * value, GParamSpec * pspec)
175 {
176   switch (param_id) {
177   case PROP_DONE_BUTTON_TEXT:
178     hildon_picker_dialog_set_done_label (HILDON_PICKER_DIALOG (object),
179                                          g_value_get_string (value));
180     break;
181   default:
182     G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
183     break;
184   }
185 }
186
187 static void
188 hildon_picker_dialog_get_property (GObject * object,
189                                    guint param_id,
190                                    GValue * value, GParamSpec * pspec)
191 {
192   HildonPickerDialog *dialog;
193
194   dialog = HILDON_PICKER_DIALOG (object);
195
196   switch (param_id) {
197   case PROP_DONE_BUTTON_TEXT:
198     g_value_set_string (value, hildon_picker_dialog_get_done_label (dialog));
199     break;
200   default:
201     G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
202     break;
203   }
204 }
205
206 /* ------------------------------ PRIVATE METHODS ---------------------------- */
207 static void
208 _select_on_selector_changed_cb (HildonTouchSelector * selector,
209                                 gint column, gpointer data)
210 {
211   HildonPickerDialog *dialog = NULL;
212
213   g_return_if_fail (HILDON_IS_PICKER_DIALOG (data));
214
215   dialog = HILDON_PICKER_DIALOG (data);
216
217   gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
218 }
219
220 static void
221 _update_title_on_selector_changed_cb (HildonTouchSelector * selector,
222                                       gint column, gpointer data)
223 {
224   HildonPickerDialog *dialog = NULL;
225   gchar *new_title = NULL;
226
227   g_return_if_fail (HILDON_IS_PICKER_DIALOG (data));
228
229   dialog = HILDON_PICKER_DIALOG (data);
230
231   new_title = hildon_touch_selector_get_current_text (selector);
232
233   if (dialog->priv->title_label != NULL) {
234 /*       gtk_label_set_text (GTK_LABEL(selector->priv->title_label), new_title); */
235   }
236   gtk_window_set_title (GTK_WINDOW (dialog), new_title);
237
238   g_free (new_title);
239 }
240
241
242 void
243 hildon_picker_dialog_set_done_label (HildonPickerDialog * dialog,
244                                      const gchar * label)
245 {
246   HildonPickerDialogPrivate *priv;
247
248   g_return_if_fail (HILDON_IS_PICKER_DIALOG (dialog));
249   g_return_if_fail (label != NULL);
250
251   priv = HILDON_PICKER_DIALOG_GET_PRIVATE (dialog);
252
253   gtk_button_set_label (GTK_BUTTON (priv->button), label);
254 }
255
256 const gchar *
257 hildon_picker_dialog_get_done_label (HildonPickerDialog * dialog)
258 {
259   HildonPickerDialogPrivate *priv;
260
261   g_return_val_if_fail (HILDON_IS_PICKER_DIALOG (dialog), NULL);
262
263   priv = HILDON_PICKER_DIALOG_GET_PRIVATE (dialog);
264
265   return gtk_button_get_label (GTK_BUTTON (priv->button));
266 }
267
268 static gboolean
269 requires_done_button (HildonPickerDialog * dialog)
270 {
271   return hildon_touch_selector_has_multiple_selection
272     (HILDON_TOUCH_SELECTOR (dialog->priv->selector));
273 }
274
275 /* ------------------------------ PUBLIC METHODS ---------------------------- */
276
277 /**
278  * hildon_picker_dialog_new:
279  * @parent: the parent window
280  *
281  * Creates a new #HildonPickerDialog
282  *
283  * Returns: a new #HildonPickerDialog
284  **/
285 GtkWidget *
286 hildon_picker_dialog_new (GtkWindow * parent)
287 {
288   GtkDialog *dialog = NULL;
289
290   dialog = g_object_new (HILDON_TYPE_PICKER_DIALOG, NULL);
291
292   if (parent) {
293     gtk_window_set_transient_for (GTK_WINDOW (dialog), parent);
294   }
295
296   return GTK_WIDGET (dialog);
297 }
298
299
300 static gboolean
301 _hildon_picker_dialog_set_selector (HildonPickerDialog * dialog,
302                                     HildonTouchSelector * selector)
303 {
304   if (dialog->priv->selector != NULL) {
305     gtk_container_remove (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox),
306                           dialog->priv->selector);
307     g_object_unref (dialog->priv->selector);
308     dialog->priv->selector = NULL;
309   }
310
311   dialog->priv->selector = GTK_WIDGET (selector);
312
313   if (dialog->priv->selector != NULL) {
314     gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
315                         dialog->priv->selector, TRUE, TRUE, 0);
316     gtk_widget_show (dialog->priv->selector);
317     g_object_ref (dialog->priv->selector);
318   }
319
320   if (dialog->priv->signal_id) {
321     g_signal_handler_disconnect (dialog->priv->selector,
322                                  dialog->priv->signal_id);
323   }
324
325   if (requires_done_button (dialog)) {
326     gtk_dialog_set_has_separator (GTK_DIALOG (dialog), TRUE);
327     gtk_widget_show (GTK_DIALOG (dialog)->action_area);
328     /* update the title */
329     dialog->priv->signal_id =
330       g_signal_connect (G_OBJECT (dialog->priv->selector), "changed",
331                         G_CALLBACK (_update_title_on_selector_changed_cb),
332                         dialog);
333   } else {
334     gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
335     gtk_widget_hide (GTK_DIALOG (dialog)->action_area);
336     dialog->priv->signal_id =
337       g_signal_connect (G_OBJECT (dialog->priv->selector), "changed",
338                         G_CALLBACK (_select_on_selector_changed_cb), dialog);
339   }
340
341   return TRUE;
342 }
343
344 gboolean
345 hildon_picker_dialog_set_selector (HildonPickerDialog * dialog,
346                                    HildonTouchSelector * selector)
347 {
348   g_return_val_if_fail (HILDON_IS_PICKER_DIALOG (dialog), FALSE);
349   g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR (selector), FALSE);
350
351   return HILDON_PICKER_DIALOG_GET_CLASS (dialog)->set_selector (dialog, selector);
352 }
353
354 HildonTouchSelector *
355 hildon_picker_dialog_get_selector (HildonPickerDialog * dialog)
356 {
357   g_return_val_if_fail (HILDON_IS_PICKER_DIALOG (dialog), NULL);
358
359   return HILDON_TOUCH_SELECTOR (dialog->priv->selector);
360 }