2008-07-29 Claudio Saavedra <csaavedra@igalia.com>
[hildon] / src / hildon-picker-button.c
1 /*
2  * This file is a part of hildon
3  *
4  * Copyright (C) 2008 Nokia Corporation, all rights reserved.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser Public License as published by
8  * the Free Software Foundation; version 2 of the license.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU Lesser Public License for more details.
14  *
15  */
16
17 #include "hildon-picker-button.h"
18 #include "hildon-picker-dialog.h"
19
20 G_DEFINE_TYPE (HildonPickerButton, hildon_picker_button, HILDON_TYPE_BUTTON)
21
22 #define GET_PRIVATE(o)                                                  \
23   (G_TYPE_INSTANCE_GET_PRIVATE ((o), HILDON_TYPE_PICKER_BUTTON, HildonPickerButtonPrivate))
24
25 typedef struct _HildonPickerButtonPrivate HildonPickerButtonPrivate;
26
27 struct _HildonPickerButtonPrivate
28 {
29   GtkWidget *picker;
30   GtkWidget *dialog;
31 };
32
33 /* Signals */
34 enum
35 {
36   VALUE_CHANGED,
37   LAST_SIGNAL
38 };
39
40 enum
41 {
42   PROP_PICKER = 1,
43 };
44
45 static guint picker_button_signals[LAST_SIGNAL] = { 0 };
46
47 static void
48 hildon_picker_button_get_property (GObject * object, guint property_id,
49                                    GValue * value, GParamSpec * pspec)
50 {
51   switch (property_id) {
52   case PROP_PICKER:
53     g_value_set_object (value,
54                         hildon_picker_button_get_picker (HILDON_PICKER_BUTTON (object)));
55     break;
56   default:
57     G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
58   }
59 }
60
61 static void
62 hildon_picker_button_set_property (GObject * object, guint property_id,
63                                    const GValue * value, GParamSpec * pspec)
64 {
65   switch (property_id) {
66   case PROP_PICKER:
67     hildon_picker_button_set_picker (HILDON_PICKER_BUTTON (object),
68                                      g_value_get_object (value));
69     break;
70   default:
71     G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
72   }
73 }
74
75 static void
76 hildon_picker_button_clicked (GtkButton * button)
77 {
78   GtkWidget *parent;
79   HildonPickerButtonPrivate *priv;
80   gint response;
81
82   priv = GET_PRIVATE (HILDON_PICKER_BUTTON (button));
83
84   g_return_if_fail (HILDON_IS_TOUCH_PICKER (priv->picker));
85
86   /* Create the dialog if it doesn't exist already.  */
87   if (!priv->dialog) {
88     parent = gtk_widget_get_toplevel (GTK_WIDGET (button));
89     if (GTK_WIDGET_TOPLEVEL (parent)) {
90       priv->dialog = hildon_picker_dialog_new (GTK_WINDOW (parent));
91     } else {
92       priv->dialog = hildon_picker_dialog_new (NULL);
93     }
94
95     hildon_picker_dialog_set_picker (HILDON_PICKER_DIALOG (priv->dialog),
96                                      HILDON_TOUCH_PICKER (priv->picker));
97
98     gtk_window_set_modal (GTK_WINDOW (priv->dialog),
99                           gtk_window_get_modal (GTK_WINDOW (parent)));
100     gtk_window_set_title (GTK_WINDOW (priv->dialog),
101                           hildon_button_get_title (HILDON_BUTTON (button)));
102   }
103
104   response = gtk_dialog_run (GTK_DIALOG (priv->dialog));
105   switch (response) {
106   case GTK_RESPONSE_OK:
107     hildon_button_set_value (HILDON_BUTTON (button),
108                              hildon_touch_picker_get_current_text
109                              (HILDON_TOUCH_PICKER (priv->picker)));
110     g_signal_emit (HILDON_PICKER_BUTTON (button),
111                    picker_button_signals[VALUE_CHANGED], 0);
112     break;
113   }
114   gtk_widget_hide (priv->dialog);
115 }
116
117 static void
118 hildon_picker_button_class_init (HildonPickerButtonClass * klass)
119 {
120   GObjectClass *object_class = G_OBJECT_CLASS (klass);
121   GtkButtonClass *button_class = GTK_BUTTON_CLASS (klass);
122
123   g_type_class_add_private (klass, sizeof (HildonPickerButtonPrivate));
124
125   object_class->get_property = hildon_picker_button_get_property;
126   object_class->set_property = hildon_picker_button_set_property;
127
128   button_class->clicked = hildon_picker_button_clicked;
129
130   g_object_class_install_property (object_class,
131                                    PROP_PICKER,
132                                    g_param_spec_object ("touch-picker",
133                                                         "HildonTouchPicker widget",
134                                                         "HildonTouchPicker widget to be launched on button clicked",
135                                                         HILDON_TYPE_TOUCH_PICKER,
136                                                         G_PARAM_READWRITE));
137
138   picker_button_signals[VALUE_CHANGED] =
139     g_signal_new ("value-changed",
140                   G_TYPE_FROM_CLASS (klass),
141                   G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
142                   0,
143                   NULL, NULL,
144                   g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0, NULL);
145 }
146
147 static void
148 hildon_picker_button_init (HildonPickerButton * self)
149 {
150   HildonPickerButtonPrivate *priv;
151
152   priv = GET_PRIVATE (self);
153
154   priv->dialog = NULL;
155   priv->picker = NULL;
156 }
157
158 GtkWidget *
159 hildon_picker_button_new (HildonButtonFlags flags)
160 {
161   GtkWidget *button;
162
163   button = g_object_new (HILDON_TYPE_PICKER_BUTTON,
164                          "arrangement-flags", flags, NULL);
165
166   return button;
167 }
168
169 GtkWidget *
170 hildon_picker_button_new_text (HildonButtonFlags flags)
171 {
172   GtkWidget *button;
173   GtkWidget *picker;
174   GtkListStore *store;
175
176   button = hildon_picker_button_new (flags);
177
178   picker = hildon_touch_picker_new ();
179   store = gtk_list_store_new (1, G_TYPE_STRING);
180
181   hildon_touch_picker_append_text_column (HILDON_TOUCH_PICKER (picker),
182                                           GTK_TREE_MODEL (store));
183
184   hildon_picker_button_set_picker (HILDON_PICKER_BUTTON (button),
185                                    HILDON_TOUCH_PICKER (picker));
186
187   return button;
188 }
189
190 void
191 hildon_picker_button_append_text (HildonPickerButton * button,
192                                   const gchar * text)
193 {
194   HildonPickerButtonPrivate *priv;
195   GtkTreeIter iter;
196   GtkTreeModel *model;
197
198   g_return_if_fail (HILDON_IS_PICKER_BUTTON (button));
199   g_return_if_fail (text != NULL);
200
201   priv = GET_PRIVATE (button);
202
203   model =
204     hildon_touch_picker_get_model (HILDON_TOUCH_PICKER (priv->picker), 0);
205
206   g_return_if_fail (GTK_IS_LIST_STORE (model));
207
208   gtk_list_store_append (GTK_LIST_STORE (model), &iter);
209   gtk_list_store_set (GTK_LIST_STORE (model), &iter, 0, text, -1);
210 }
211
212 void
213 hildon_picker_button_prepend_text (HildonPickerButton * button,
214                                    const gchar * text)
215 {
216   HildonPickerButtonPrivate *priv;
217   GtkTreeIter iter;
218   GtkTreeModel *model;
219
220   g_return_if_fail (HILDON_IS_PICKER_BUTTON (button));
221   g_return_if_fail (text != NULL);
222
223   priv = GET_PRIVATE (button);
224
225   model =
226     hildon_touch_picker_get_model (HILDON_TOUCH_PICKER (priv->picker), 0);
227
228   g_return_if_fail (GTK_IS_LIST_STORE (model));
229
230   gtk_list_store_prepend (GTK_LIST_STORE (model), &iter);
231   gtk_list_store_set (GTK_LIST_STORE (model), &iter, 0, text, -1);
232 }
233
234 void
235 hildon_picker_button_insert_text (HildonPickerButton * button,
236                                   gint position, const gchar * text)
237 {
238   HildonPickerButtonPrivate *priv;
239   GtkTreeIter iter;
240   GtkTreeModel *model;
241
242   g_return_if_fail (HILDON_IS_PICKER_BUTTON (button));
243   g_return_if_fail (text != NULL);
244   g_return_if_fail (position >= 0);
245
246   priv = GET_PRIVATE (button);
247
248   model =
249     hildon_touch_picker_get_model (HILDON_TOUCH_PICKER (priv->picker), 0);
250
251   g_return_if_fail (GTK_IS_LIST_STORE (model));
252
253   gtk_list_store_insert (GTK_LIST_STORE (model), &iter, position);
254   gtk_list_store_set (GTK_LIST_STORE (model), &iter, 0, text, -1);
255 }
256
257 void
258 hildon_picker_button_set_picker (HildonPickerButton * button,
259                                  HildonTouchPicker * picker)
260 {
261   HildonPickerButtonPrivate *priv;
262
263   g_return_if_fail (HILDON_IS_PICKER_BUTTON (button));
264   g_return_if_fail (HILDON_IS_TOUCH_PICKER (picker));
265
266   priv = GET_PRIVATE (button);
267
268   priv->picker = g_object_ref (picker);
269 }
270
271 HildonTouchPicker *
272 hildon_picker_button_get_picker (HildonPickerButton * button)
273 {
274   HildonPickerButtonPrivate *priv;
275
276   g_return_val_if_fail (HILDON_IS_PICKER_BUTTON (button), NULL);
277
278   priv = GET_PRIVATE (button);
279
280   return HILDON_TOUCH_PICKER (priv->picker);
281 }