2 * This file is a part of hildon
4 * Copyright (C) 2008 Nokia Corporation, all rights reserved.
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.
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.
18 * SECTION:hildon-picker-button
19 * @short_description: A button that launches a #HildonPickerDialog and displays the
21 * @see_also: #HildonTouchSelector, #HildonPickerDialog
23 * #HildonPickerButton is a widget that lets the user select a particular item from
24 * a list. Visually, it's a button with title and value labels that brings up a
25 * #HildonPickerDialog. The user can then use this dialog to choose an item, which
26 * will be displayed in the value label of the button.
28 * You should create your own #HildonTouchSelector at convenience and set it
29 * to the #HildonPickerButton with hildon_picker_button_set_selector(). For
30 * the common use cases of buttons to select date and time, you can use #HildonDateButton
31 * and #HildonTimeButton.
35 #include "hildon-picker-button.h"
36 #include "hildon-picker-dialog.h"
38 G_DEFINE_TYPE (HildonPickerButton, hildon_picker_button, HILDON_TYPE_BUTTON)
40 #define GET_PRIVATE(o) \
41 (G_TYPE_INSTANCE_GET_PRIVATE ((o), HILDON_TYPE_PICKER_BUTTON, HildonPickerButtonPrivate))
43 typedef struct _HildonPickerButtonPrivate HildonPickerButtonPrivate;
45 struct _HildonPickerButtonPrivate
49 gchar *done_button_text;
65 static guint picker_button_signals[LAST_SIGNAL] = { 0 };
68 _current_selector_empty (HildonPickerButton *button);
70 hildon_picker_button_selector_selection_changed (HildonTouchSelector * selector,
77 hildon_picker_button_get_property (GObject * object, guint property_id,
78 GValue * value, GParamSpec * pspec)
80 switch (property_id) {
82 g_value_set_object (value,
83 hildon_picker_button_get_selector (HILDON_PICKER_BUTTON (object)));
85 case PROP_DONE_BUTTON_TEXT:
86 g_value_set_string (value,
87 hildon_picker_button_get_done_button_text (HILDON_PICKER_BUTTON (object)));
90 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
95 hildon_picker_button_set_property (GObject * object, guint property_id,
96 const GValue * value, GParamSpec * pspec)
98 switch (property_id) {
100 hildon_picker_button_set_selector (HILDON_PICKER_BUTTON (object),
101 g_value_get_object (value));
103 case PROP_DONE_BUTTON_TEXT:
104 hildon_picker_button_set_done_button_text (HILDON_PICKER_BUTTON (object),
105 g_value_get_string (value));
108 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
113 hildon_picker_button_finalize (GObject * object)
115 HildonPickerButtonPrivate *priv;
117 priv = GET_PRIVATE (object);
119 if (priv->selector) {
120 g_signal_handlers_disconnect_by_func (priv->selector,
121 hildon_picker_button_selector_selection_changed,
123 g_object_unref (priv->selector);
124 priv->selector = NULL;
127 gtk_widget_destroy (priv->dialog);
131 G_OBJECT_CLASS (hildon_picker_button_parent_class)->finalize (object);
135 hildon_picker_button_clicked (GtkButton * button)
138 HildonPickerButtonPrivate *priv;
141 priv = GET_PRIVATE (HILDON_PICKER_BUTTON (button));
143 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR (priv->selector));
145 /* Create the dialog if it doesn't exist already. */
147 parent = gtk_widget_get_toplevel (GTK_WIDGET (button));
148 if (GTK_WIDGET_TOPLEVEL (parent)) {
149 priv->dialog = hildon_picker_dialog_new (GTK_WINDOW (parent));
151 priv->dialog = hildon_picker_dialog_new (NULL);
154 hildon_picker_dialog_set_selector (HILDON_PICKER_DIALOG (priv->dialog),
155 HILDON_TOUCH_SELECTOR (priv->selector));
156 if (priv->done_button_text) {
157 hildon_picker_dialog_set_done_label (HILDON_PICKER_DIALOG (priv->dialog),
158 priv->done_button_text);
161 gtk_window_set_modal (GTK_WINDOW (priv->dialog),
162 gtk_window_get_modal (GTK_WINDOW (parent)));
163 gtk_window_set_title (GTK_WINDOW (priv->dialog),
164 hildon_button_get_title (HILDON_BUTTON (button)));
167 if (_current_selector_empty (HILDON_PICKER_BUTTON (button))) {
168 g_warning ("There are no elements to selects!! Not showing the dialog!!");
170 response = gtk_dialog_run (GTK_DIALOG (priv->dialog));
172 case GTK_RESPONSE_OK:
173 hildon_button_set_value (HILDON_BUTTON (button),
174 hildon_touch_selector_get_current_text
175 (HILDON_TOUCH_SELECTOR (priv->selector)));
176 g_signal_emit (HILDON_PICKER_BUTTON (button),
177 picker_button_signals[VALUE_CHANGED], 0);
180 gtk_widget_hide (priv->dialog);
185 hildon_picker_button_selector_selection_changed (HildonTouchSelector * selector,
191 HildonPickerButton *button = HILDON_PICKER_BUTTON (user_data);
192 HildonPickerButtonPrivate *priv = GET_PRIVATE (button);
194 if (!GTK_IS_WINDOW (priv->dialog) ||
195 !gtk_window_is_active (GTK_WINDOW (priv->dialog))) {
196 value = hildon_touch_selector_get_current_text (HILDON_TOUCH_SELECTOR (priv->selector));
198 hildon_button_set_value (HILDON_BUTTON (button), value);
199 g_signal_emit (HILDON_PICKER_BUTTON (button),
200 picker_button_signals[VALUE_CHANGED], 0);
206 hildon_picker_button_class_init (HildonPickerButtonClass * klass)
208 GObjectClass *object_class = G_OBJECT_CLASS (klass);
209 GtkButtonClass *button_class = GTK_BUTTON_CLASS (klass);
211 g_type_class_add_private (klass, sizeof (HildonPickerButtonPrivate));
213 object_class->get_property = hildon_picker_button_get_property;
214 object_class->set_property = hildon_picker_button_set_property;
215 object_class->finalize = hildon_picker_button_finalize;
217 button_class->clicked = hildon_picker_button_clicked;
219 g_object_class_install_property (object_class,
221 g_param_spec_object ("touch-selector",
222 "HildonTouchSelector widget",
223 "HildonTouchSelector widget to be launched on button clicked",
224 HILDON_TYPE_TOUCH_SELECTOR,
226 g_object_class_install_property (object_class,
227 PROP_DONE_BUTTON_TEXT,
228 g_param_spec_string ("done-button-text",
229 "HildonPickerDialog \"done\" button text",
230 "The text for the \"done\" button in the dialog launched",
235 * HildonPickerButton::value-changed:
236 * @widget: the widget that received the signal
238 * The ::value-changed signal is emitted each time the user chooses a different
239 * item from the #HildonTouchSelector related, and the value label gets updated.
241 picker_button_signals[VALUE_CHANGED] =
242 g_signal_new ("value-changed",
243 G_TYPE_FROM_CLASS (klass),
244 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
247 g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0, NULL);
251 hildon_picker_button_init (HildonPickerButton * self)
253 HildonPickerButtonPrivate *priv;
255 priv = GET_PRIVATE (self);
258 priv->selector = NULL;
259 priv->done_button_text = NULL;
263 _current_selector_empty (HildonPickerButton *button)
265 HildonPickerButtonPrivate *priv;
266 HildonTouchSelector *selector = NULL;
267 GtkTreeModel *model = NULL;
271 priv = GET_PRIVATE (button);
272 selector = HILDON_TOUCH_SELECTOR (priv->selector);
274 g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR (selector), TRUE);
276 if (hildon_touch_selector_has_multiple_selection (selector)) {
279 for (i=0; i < hildon_touch_selector_get_num_columns (selector); i++) {
280 model = hildon_touch_selector_get_model (selector, i);
282 if (gtk_tree_model_get_iter_first (model, &iter)) {
291 * hildon_picker_button_new:
292 * @size: One of #HildonSizeType, specifying the size of the new button.
293 * @arrangement: one of #HildonButtonArrangement, specifying the placement of the
296 * Creates a new #HildonPickerButton. See hildon_button_new() for details on the
299 * Returns: a newly created #HildonPickerButton
302 hildon_picker_button_new (HildonSizeType size,
303 HildonButtonArrangement arrangement)
307 button = g_object_new (HILDON_TYPE_PICKER_BUTTON,
308 "arrangement", arrangement, "size", size, NULL);
314 * hildon_picker_button_set_selector:
315 * @button: a #HildonPickerButton
316 * @selector: a #HildonTouchSelector
318 * Sets @selector as the #HildonTouchSelector to be shown in the
319 * #HildonPickerDialog that @button brings up.
322 hildon_picker_button_set_selector (HildonPickerButton * button,
323 HildonTouchSelector * selector)
325 HildonPickerButtonPrivate *priv;
328 g_return_if_fail (HILDON_IS_PICKER_BUTTON (button));
329 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR (selector));
331 priv = GET_PRIVATE (button);
333 if (priv->selector) {
334 g_signal_handlers_disconnect_by_func (priv->selector,
335 hildon_picker_button_selector_selection_changed,
337 g_object_unref (priv->selector);
340 priv->selector = g_object_ref (selector);
342 g_signal_connect (G_OBJECT (selector), "changed",
343 G_CALLBACK (hildon_picker_button_selector_selection_changed),
346 value = hildon_touch_selector_get_current_text (HILDON_TOUCH_SELECTOR (priv->selector));
348 hildon_button_set_value (HILDON_BUTTON (button), value);
349 g_signal_emit (HILDON_PICKER_BUTTON (button),
350 picker_button_signals[VALUE_CHANGED], 0);
355 * hildon_picker_button_get_selector:
356 * @button: a #HildonPickerButton
358 * Retrieves the #HildonTouchSelector associated to @button.
360 * Returns: a #HildonTouchSelector
362 HildonTouchSelector *
363 hildon_picker_button_get_selector (HildonPickerButton * button)
365 HildonPickerButtonPrivate *priv;
367 g_return_val_if_fail (HILDON_IS_PICKER_BUTTON (button), NULL);
369 priv = GET_PRIVATE (button);
371 return HILDON_TOUCH_SELECTOR (priv->selector);
375 * hildon_picker_button_get_active:
376 * @button: a #HildonPickerButton
378 * Returns the index of the currently active item, or -1 if there's no
379 * active item. If the selector has several columns, only the first
382 * Returns: an integer which is the index of the currently active item, or -1 if there's no active item.
385 hildon_picker_button_get_active (HildonPickerButton * button)
387 HildonTouchSelector *sel;
388 g_return_val_if_fail (HILDON_IS_PICKER_BUTTON (button), -1);
390 sel = hildon_picker_button_get_selector (button);
392 return hildon_touch_selector_get_active (sel, 0);
396 * hildon_picker_button_set_active:
397 * @button: a #HildonPickerButton
398 * @index: the index of the item to select, or -1 to have no active item
400 * Sets the active item of the #HildonTouchSelector associated to
401 * @button to @index. If the selector has several columns, only the
405 hildon_picker_button_set_active (HildonPickerButton * button,
408 HildonTouchSelector *sel;
410 g_return_if_fail (HILDON_IS_PICKER_BUTTON (button));
412 sel = hildon_picker_button_get_selector (button);
413 hildon_touch_selector_set_active (sel, 0, index);
415 text = hildon_touch_selector_get_current_text (sel);
416 hildon_button_set_value (HILDON_BUTTON (button), text);
421 * hildon_picker_button_get_done_button_text:
422 * @button: a #HildonPickerButton
424 * Gets the text used in the #HildonPickerDialog that is launched by
425 * @button. If no custom text is set, then %NULL is returned.
427 * Returns: the custom string to be used, or %NULL if the default
428 * #HildonPickerDialog::done-button-text is to be used.
431 hildon_picker_button_get_done_button_text (HildonPickerButton *button)
433 HildonPickerButtonPrivate *priv;
435 g_return_val_if_fail (HILDON_IS_PICKER_BUTTON (button), NULL);
437 priv = GET_PRIVATE (button);
439 return priv->done_button_text;
443 * hildon_picker_button_set_done_button_text:
444 * @button: a #HildonPickerButton
445 * @done_button_text: a string
447 * Sets a custom string to be used in the \"done\" button in the #HildonPickerDialog
448 * launched. If not set, the default HildonPickerButton::done-button-text property
449 * value will be used.
452 hildon_picker_button_set_done_button_text (HildonPickerButton *button,
453 const gchar *done_button_text)
455 HildonPickerButtonPrivate *priv;
457 g_return_if_fail (HILDON_IS_PICKER_BUTTON (button));
458 g_return_if_fail (done_button_text != NULL);
460 priv = GET_PRIVATE (button);
462 g_free (priv->done_button_text);
463 priv->done_button_text = g_strdup (done_button_text);