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.
36 * create_selector (void)
38 * GtkWidget *selector;
40 * selector = hildon_touch_selector_new_text ();
42 * hildon_touch_selector_append_text (HILDON_TOUCH_SELECTOR (selector), "America");
43 * hildon_touch_selector_append_text (HILDON_TOUCH_SELECTOR (selector), "Europe");
44 * hildon_touch_selector_append_text (HILDON_TOUCH_SELECTOR (selector), "Asia");
45 * hildon_touch_selector_append_text (HILDON_TOUCH_SELECTOR (selector), "Africa");
46 * hildon_touch_selector_append_text (HILDON_TOUCH_SELECTOR (selector), "Australia");
48 * hildon_touch_selector_set_active (HILDON_TOUCH_SELECTOR (selector), 0, 2);
54 * create_button (HildonTouchSelector *selector)
58 * button = hildon_picker_button_new (HILDON_SIZE_AUTO, HILDON_BUTTON_ARRANGEMENT_VERTICAL);
59 * hildon_button_set_title (HILDON_BUTTON (button), "Continent");
61 * hildon_picker_button_set_selector (HILDON_PICKER_BUTTON (button),
62 * HILDON_TOUCH_SELECTOR (selector));
70 #include "hildon-picker-button.h"
71 #include "hildon-picker-dialog.h"
73 G_DEFINE_TYPE (HildonPickerButton, hildon_picker_button, HILDON_TYPE_BUTTON)
75 #define GET_PRIVATE(o) \
76 (G_TYPE_INSTANCE_GET_PRIVATE ((o), HILDON_TYPE_PICKER_BUTTON, HildonPickerButtonPrivate))
78 typedef struct _HildonPickerButtonPrivate HildonPickerButtonPrivate;
80 struct _HildonPickerButtonPrivate
84 gchar *done_button_text;
100 static guint picker_button_signals[LAST_SIGNAL] = { 0 };
103 _current_selector_empty (HildonPickerButton *button);
105 hildon_picker_button_selector_selection_changed (HildonTouchSelector * selector,
112 hildon_picker_button_get_property (GObject * object, guint property_id,
113 GValue * value, GParamSpec * pspec)
115 switch (property_id) {
117 g_value_set_object (value,
118 hildon_picker_button_get_selector (HILDON_PICKER_BUTTON (object)));
120 case PROP_DONE_BUTTON_TEXT:
121 g_value_set_string (value,
122 hildon_picker_button_get_done_button_text (HILDON_PICKER_BUTTON (object)));
125 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
130 hildon_picker_button_set_property (GObject * object, guint property_id,
131 const GValue * value, GParamSpec * pspec)
133 switch (property_id) {
135 hildon_picker_button_set_selector (HILDON_PICKER_BUTTON (object),
136 g_value_get_object (value));
138 case PROP_DONE_BUTTON_TEXT:
139 hildon_picker_button_set_done_button_text (HILDON_PICKER_BUTTON (object),
140 g_value_get_string (value));
143 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
148 hildon_picker_button_finalize (GObject * object)
150 HildonPickerButtonPrivate *priv;
152 priv = GET_PRIVATE (object);
154 if (priv->selector) {
155 g_signal_handlers_disconnect_by_func (priv->selector,
156 hildon_picker_button_selector_selection_changed,
158 g_object_unref (priv->selector);
159 priv->selector = NULL;
162 gtk_widget_destroy (priv->dialog);
166 if (priv->done_button_text) {
167 g_free (priv->done_button_text);
168 priv->done_button_text = NULL;
171 G_OBJECT_CLASS (hildon_picker_button_parent_class)->finalize (object);
175 hildon_picker_button_on_dialog_response (GtkDialog *dialog,
179 HildonPickerButton *button;
180 HildonPickerButtonPrivate *priv;
183 button = HILDON_PICKER_BUTTON (user_data);
184 priv = GET_PRIVATE (button);
187 case GTK_RESPONSE_OK:
188 value = hildon_touch_selector_get_current_text
189 (HILDON_TOUCH_SELECTOR (priv->selector));
190 hildon_button_set_value (HILDON_BUTTON (button), value);
192 g_signal_emit (button, picker_button_signals[VALUE_CHANGED], 0);
195 gtk_widget_hide (priv->dialog);
199 hildon_picker_button_clicked (GtkButton * button)
202 HildonPickerButtonPrivate *priv;
204 priv = GET_PRIVATE (HILDON_PICKER_BUTTON (button));
206 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR (priv->selector));
208 /* Create the dialog if it doesn't exist already. */
210 parent = gtk_widget_get_toplevel (GTK_WIDGET (button));
211 if (GTK_WIDGET_TOPLEVEL (parent)) {
212 priv->dialog = hildon_picker_dialog_new (GTK_WINDOW (parent));
214 priv->dialog = hildon_picker_dialog_new (NULL);
217 hildon_picker_dialog_set_selector (HILDON_PICKER_DIALOG (priv->dialog),
218 HILDON_TOUCH_SELECTOR (priv->selector));
219 if (priv->done_button_text) {
220 hildon_picker_dialog_set_done_label (HILDON_PICKER_DIALOG (priv->dialog),
221 priv->done_button_text);
224 gtk_window_set_modal (GTK_WINDOW (priv->dialog),
225 gtk_window_get_modal (GTK_WINDOW (parent)));
226 gtk_window_set_title (GTK_WINDOW (priv->dialog),
227 hildon_button_get_title (HILDON_BUTTON (button)));
230 if (_current_selector_empty (HILDON_PICKER_BUTTON (button))) {
231 g_warning ("There are no elements in the selector. Nothing to show.");
233 g_signal_connect (priv->dialog, "response",
234 G_CALLBACK (hildon_picker_button_on_dialog_response),
236 g_signal_connect (priv->dialog, "delete-event",
237 G_CALLBACK (gtk_widget_hide_on_delete),
239 gtk_window_present (GTK_WINDOW (priv->dialog));
244 hildon_picker_button_selector_selection_changed (HildonTouchSelector * selector,
250 HildonPickerButton *button = HILDON_PICKER_BUTTON (user_data);
251 HildonPickerButtonPrivate *priv = GET_PRIVATE (button);
253 if (!GTK_IS_WINDOW (priv->dialog) ||
254 !gtk_window_is_active (GTK_WINDOW (priv->dialog))) {
255 value = hildon_touch_selector_get_current_text (HILDON_TOUCH_SELECTOR (priv->selector));
257 hildon_button_set_value (HILDON_BUTTON (button), value);
259 g_signal_emit (HILDON_PICKER_BUTTON (button),
260 picker_button_signals[VALUE_CHANGED], 0);
266 hildon_picker_button_class_init (HildonPickerButtonClass * klass)
268 GObjectClass *object_class = G_OBJECT_CLASS (klass);
269 GtkButtonClass *button_class = GTK_BUTTON_CLASS (klass);
271 g_type_class_add_private (klass, sizeof (HildonPickerButtonPrivate));
273 object_class->get_property = hildon_picker_button_get_property;
274 object_class->set_property = hildon_picker_button_set_property;
275 object_class->finalize = hildon_picker_button_finalize;
277 button_class->clicked = hildon_picker_button_clicked;
279 g_object_class_install_property (object_class,
281 g_param_spec_object ("touch-selector",
282 "HildonTouchSelector widget",
283 "HildonTouchSelector widget to be launched on button clicked",
284 HILDON_TYPE_TOUCH_SELECTOR,
286 g_object_class_install_property (object_class,
287 PROP_DONE_BUTTON_TEXT,
288 g_param_spec_string ("done-button-text",
289 "HildonPickerDialog \"done\" button text",
290 "The text for the \"done\" button in the dialog launched",
295 * HildonPickerButton::value-changed:
296 * @widget: the widget that received the signal
298 * The ::value-changed signal is emitted each time the user chooses a different
299 * item from the #HildonTouchSelector related, and the value label gets updated.
303 picker_button_signals[VALUE_CHANGED] =
304 g_signal_new ("value-changed",
305 G_TYPE_FROM_CLASS (klass),
306 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
309 g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0, NULL);
313 hildon_picker_button_init (HildonPickerButton * self)
315 HildonPickerButtonPrivate *priv;
317 priv = GET_PRIVATE (self);
320 priv->selector = NULL;
321 priv->done_button_text = NULL;
323 hildon_button_set_style (HILDON_BUTTON (self),
324 HILDON_BUTTON_STYLE_PICKER);
328 _current_selector_empty (HildonPickerButton *button)
330 HildonPickerButtonPrivate *priv;
331 HildonTouchSelector *selector = NULL;
332 GtkTreeModel *model = NULL;
336 priv = GET_PRIVATE (button);
337 selector = HILDON_TOUCH_SELECTOR (priv->selector);
339 g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR (selector), TRUE);
341 if (hildon_touch_selector_has_multiple_selection (selector)) {
344 for (i=0; i < hildon_touch_selector_get_num_columns (selector); i++) {
345 model = hildon_touch_selector_get_model (selector, i);
347 if (gtk_tree_model_get_iter_first (model, &iter)) {
356 * hildon_picker_button_new:
357 * @size: One of #HildonSizeType, specifying the size of the new button.
358 * @arrangement: one of #HildonButtonArrangement, specifying the placement of the
361 * Creates a new #HildonPickerButton. See hildon_button_new() for details on the
364 * Returns: a newly created #HildonPickerButton
369 hildon_picker_button_new (HildonSizeType size,
370 HildonButtonArrangement arrangement)
374 button = g_object_new (HILDON_TYPE_PICKER_BUTTON,
375 "arrangement", arrangement, "size", size,
382 * hildon_picker_button_set_selector:
383 * @button: a #HildonPickerButton
384 * @selector: a #HildonTouchSelector
386 * Sets @selector as the #HildonTouchSelector to be shown in the
387 * #HildonPickerDialog that @button brings up.
392 hildon_picker_button_set_selector (HildonPickerButton * button,
393 HildonTouchSelector * selector)
395 HildonPickerButtonPrivate *priv;
398 g_return_if_fail (HILDON_IS_PICKER_BUTTON (button));
399 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR (selector));
401 priv = GET_PRIVATE (button);
403 if (priv->selector) {
404 g_signal_handlers_disconnect_by_func (priv->selector,
405 hildon_picker_button_selector_selection_changed,
407 g_object_unref (priv->selector);
410 priv->selector = g_object_ref (selector);
412 g_signal_connect (G_OBJECT (selector), "changed",
413 G_CALLBACK (hildon_picker_button_selector_selection_changed),
416 value = hildon_touch_selector_get_current_text (HILDON_TOUCH_SELECTOR (priv->selector));
418 hildon_button_set_value (HILDON_BUTTON (button), value);
420 g_signal_emit (HILDON_PICKER_BUTTON (button),
421 picker_button_signals[VALUE_CHANGED], 0);
426 * hildon_picker_button_get_selector:
427 * @button: a #HildonPickerButton
429 * Retrieves the #HildonTouchSelector associated to @button.
431 * Returns: a #HildonTouchSelector
435 HildonTouchSelector *
436 hildon_picker_button_get_selector (HildonPickerButton * button)
438 HildonPickerButtonPrivate *priv;
440 g_return_val_if_fail (HILDON_IS_PICKER_BUTTON (button), NULL);
442 priv = GET_PRIVATE (button);
444 return HILDON_TOUCH_SELECTOR (priv->selector);
448 * hildon_picker_button_get_active:
449 * @button: a #HildonPickerButton
451 * Returns the index of the currently active item, or -1 if there's no
452 * active item. If the selector has several columns, only the first
455 * Returns: an integer which is the index of the currently active item, or -1 if there's no active item.
460 hildon_picker_button_get_active (HildonPickerButton * button)
462 HildonTouchSelector *sel;
463 g_return_val_if_fail (HILDON_IS_PICKER_BUTTON (button), -1);
465 sel = hildon_picker_button_get_selector (button);
467 return hildon_touch_selector_get_active (sel, 0);
471 * hildon_picker_button_set_active:
472 * @button: a #HildonPickerButton
473 * @index: the index of the item to select, or -1 to have no active item
475 * Sets the active item of the #HildonTouchSelector associated to
476 * @button to @index. If the selector has several columns, only the
482 hildon_picker_button_set_active (HildonPickerButton * button,
485 HildonTouchSelector *sel;
487 g_return_if_fail (HILDON_IS_PICKER_BUTTON (button));
489 sel = hildon_picker_button_get_selector (button);
490 hildon_touch_selector_set_active (sel, 0, index);
492 text = hildon_touch_selector_get_current_text (sel);
493 hildon_button_set_value (HILDON_BUTTON (button), text);
498 * hildon_picker_button_get_done_button_text:
499 * @button: a #HildonPickerButton
501 * Gets the text used in the #HildonPickerDialog that is launched by
502 * @button. If no custom text is set, then %NULL is returned.
504 * Returns: the custom string to be used, or %NULL if the default
505 * #HildonPickerDialog::done-button-text is to be used.
510 hildon_picker_button_get_done_button_text (HildonPickerButton *button)
512 HildonPickerButtonPrivate *priv;
514 g_return_val_if_fail (HILDON_IS_PICKER_BUTTON (button), NULL);
516 priv = GET_PRIVATE (button);
518 return priv->done_button_text;
522 * hildon_picker_button_set_done_button_text:
523 * @button: a #HildonPickerButton
524 * @done_button_text: a string
526 * Sets a custom string to be used in the "done" button in #HildonPickerDialog.
527 * If unset, the default HildonPickerButton::done-button-text property
528 * value will be used.
533 hildon_picker_button_set_done_button_text (HildonPickerButton *button,
534 const gchar *done_button_text)
536 HildonPickerButtonPrivate *priv;
538 g_return_if_fail (HILDON_IS_PICKER_BUTTON (button));
539 g_return_if_fail (done_button_text != NULL);
541 priv = GET_PRIVATE (button);
543 g_free (priv->done_button_text);
544 priv->done_button_text = g_strdup (done_button_text);
547 hildon_picker_dialog_set_done_label (HILDON_PICKER_DIALOG (priv->dialog),
548 priv->done_button_text);