2008-10-08 Alberto Garcia <agarcia@igalia.com>
[hildon] / src / hildon-check-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 /**
18  * SECTION:hildon-check-button
19  * @short_description: Button with a check box inside
20  *
21  * This is a standard #GtkButton which contains a check box and a
22  * label. Functions are provided to get and set the value of the check
23  * box. Note that this button does NOT support an image, so don't use
24  * gtk_button_set_image()
25  *
26  * <example>
27  * <title>Using a Hildon check button</title>
28  * <programlisting>
29  * void
30  * button_clicked (GtkButton *button, gpointer user_data)
31  * {
32  *     gboolean active;
33  * <!-- -->
34  *     active = hildon_check_button_get_active (button);
35  *     if (active)
36  *        g_debug ("Button is active");
37  *     else
38  *        g_debug ("Button is not active");
39  * }
40  * <!-- -->
41  * GtkWidget *
42  * create_button (void)
43  * {
44  *     GtkWidget *button;
45  * <!-- -->
46  *     button = hildon_check_button_new (HILDON_SIZE_AUTO);
47  *     gtk_button_set_label (GTK_BUTTON (button), "Click me");
48  * <!-- -->
49  *     g_signal_connect (button, "clicked", G_CALLBACK (button_clicked), NULL);
50  * <!-- -->
51  *     return button;
52  * }
53  * </programlisting>
54  * </example>
55
56  */
57
58 #include                                        "hildon-check-button.h"
59
60 static GQuark                                   quark = 0;
61
62 static void
63 check_button_clicked                            (GtkButton             *button,
64                                                  GtkCellRendererToggle *renderer)
65 {
66     gboolean current = gtk_cell_renderer_toggle_get_active (renderer);
67     gtk_cell_renderer_toggle_set_active (renderer, !current);
68 }
69
70 /**
71  * hildon_check_button_set_active:
72  * @button: A #GtkButton created with hildon_check_button_new()
73  * @is_active: new state for the check box
74  *
75  * Sets the state of the check box.
76  **/
77 void
78 hildon_check_button_set_active                  (GtkButton *button,
79                                                  gboolean   is_active)
80 {
81     GtkCellRendererToggle *toggle_renderer;
82     gboolean prev_is_active;
83
84     g_return_if_fail (GTK_IS_BUTTON (button));
85     toggle_renderer = GTK_CELL_RENDERER_TOGGLE (g_object_get_qdata (G_OBJECT (button), quark));
86     g_return_if_fail (GTK_IS_CELL_RENDERER_TOGGLE (toggle_renderer));
87
88     prev_is_active = gtk_cell_renderer_toggle_get_active (toggle_renderer);
89
90     if (prev_is_active != is_active) {
91       gtk_button_clicked (button);
92       gtk_widget_queue_draw (GTK_WIDGET (button));
93     }
94 }
95
96 /**
97  * hildon_check_button_get_active:
98  * @button: A #GtkButton created with hildon_check_button_new()
99  *
100  * Gets the state of the check box.
101  *
102  * Return value: %TRUE if the check box is active, %FALSE otherwise.
103  **/
104 gboolean
105 hildon_check_button_get_active                  (GtkButton *button)
106 {
107     GtkCellRendererToggle *toggle_renderer;
108
109     g_return_val_if_fail (GTK_IS_BUTTON (button), FALSE);
110     toggle_renderer = GTK_CELL_RENDERER_TOGGLE (g_object_get_qdata (G_OBJECT (button), quark));
111     g_return_val_if_fail (GTK_IS_CELL_RENDERER_TOGGLE (toggle_renderer), FALSE);
112
113     return gtk_cell_renderer_toggle_get_active (toggle_renderer);
114 }
115
116 /**
117  * hildon_check_button_new:
118  * @size: Flags indicating the size of the new button
119  *
120  * This function creates a #GtkButton containing a label and a check
121  * box.
122  *
123  * Return value: A newly created #GtkButton widget with a check box.
124  **/
125 GtkWidget *
126 hildon_check_button_new                         (HildonSizeType size)
127 {
128     GtkWidget *button = gtk_button_new ();
129     GtkWidget *cell_view = gtk_cell_view_new ();
130     GtkCellRenderer *toggle_renderer = gtk_cell_renderer_toggle_new ();
131
132     /* Initialize quark */
133     if (G_UNLIKELY (quark == 0)) {
134         quark = g_quark_from_static_string ("toggle-renderer");
135     }
136
137     /* Set the size of the button */
138     hildon_gtk_widget_set_theme_size (button, size);
139
140     /* Toggle the check box when the button is clicked */
141     g_signal_connect (button, "clicked", G_CALLBACK (check_button_clicked), toggle_renderer);
142
143     /* Make sure that the check box is always shown, no matter the value of gtk-button-images */
144     g_signal_connect (cell_view, "notify::visible", G_CALLBACK (gtk_widget_show), NULL);
145
146     /* Store the renderer for later use */
147     g_object_set_qdata (G_OBJECT (button), quark, toggle_renderer);
148
149     /* Pack everything */
150     gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (cell_view), toggle_renderer, FALSE);
151     gtk_button_set_image (GTK_BUTTON (button), cell_view);
152
153     return button;
154 }