X-Git-Url: https://vcs.maemo.org/git/?a=blobdiff_plain;f=src%2Fhildon-check-button.c;h=b647c1c43e611bdee89f6c8c91d0d42e09584db6;hb=3e01c35cb8fc31655d51ac915f7739e3bd2381f6;hp=fa1c3d70e92f1b7dd0e556ce750fbf5b82756264;hpb=bfbff07d8cad9fd3f3315d926d710a33e3311858;p=hildon diff --git a/src/hildon-check-button.c b/src/hildon-check-button.c index fa1c3d7..b647c1c 100644 --- a/src/hildon-check-button.c +++ b/src/hildon-check-button.c @@ -18,15 +18,27 @@ * SECTION:hildon-check-button * @short_description: Button with a check box inside * - * This is a standard GtkButton which contains a check box and a - * label. Functions are provided to get and set the values of both the - * check box and the label. Standard GtkButton methods must not be - * used for that. + * #HildonCheckButton is a button containing a label and a check box + * which will remain 'pressed-in' when clicked. Clicking again will + * make the check box toggle its state. + * + * The state of a #HildonCheckButton can be set using + * hildon_check_button_set_active(), and retrieved using + * hildon_check_button_get_active(). The label can be set using + * gtk_button_set_label() and retrieved using gtk_button_get_label(). + * + * + * + * #HildonCheckButton does NOT support an image, so don't use + * gtk_button_set_image(). + * + * * * + * Using a Hildon check button * * void - * button_clicked (GtkButton *button, gpointer user_data) + * button_toggled (HildonCheckButton *button, gpointer user_data) * { * gboolean active; * @@ -43,151 +55,207 @@ * GtkWidget *button; * * button = hildon_check_button_new (HILDON_SIZE_AUTO); - * hildon_check_button_set_label (GTK_BUTTON (button), "Click me"); + * gtk_button_set_label (GTK_BUTTON (button), "Click me"); * - * g_signal_connect (button, "clicked", G_CALLBACK (button_clicked), NULL); + * g_signal_connect (button, "toggled", G_CALLBACK (button_toggled), NULL); * * return button; * } * * - */ #include "hildon-check-button.h" -static void -check_button_clicked (GtkButton *button, - GtkCellRendererToggle *renderer) -{ - gboolean current = gtk_cell_renderer_toggle_get_active (renderer); - gtk_cell_renderer_toggle_set_active (renderer, !current); -} +enum { + TOGGLED, + LAST_SIGNAL +}; -/** - * hildon_check_button_set_label: - * @button: A #GtkButton created with hildon_check_button_new() - * @label: New text for the label. - * - * Sets the text of the button label to @label. - **/ -void -hildon_check_button_set_label (GtkButton *button, - const gchar *label) -{ - GtkCellRendererText *text_renderer; +static guint signals[LAST_SIGNAL] = { 0 }; - g_return_if_fail (GTK_IS_BUTTON (button)); - text_renderer = GTK_CELL_RENDERER_TEXT (g_object_get_data (G_OBJECT (button), "text-renderer")); - g_return_if_fail (GTK_IS_CELL_RENDERER_TEXT (text_renderer)); +G_DEFINE_TYPE (HildonCheckButton, hildon_check_button, GTK_TYPE_BUTTON); - g_object_set (text_renderer, "text", label, NULL); -} +#define HILDON_CHECK_BUTTON_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \ + HILDON_TYPE_CHECK_BUTTON, HildonCheckButtonPrivate)); + +struct _HildonCheckButtonPrivate +{ + GtkCellRendererToggle *toggle_renderer; +}; /** - * hildon_check_button_get_label: - * @button: A #GtkButton created with hildon_check_button_new() + * hildon_check_button_toggled: + * @button: A #HildonCheckButton * - * Gets the text of the label inside the button. + * Emits the #HildonCheckButton::toggled signal on the #HildonCheckButton. + * There is no good reason for an application ever to call this function. * - * Return value: the text of the label. This string is owned by the - * button and must not be modified or freed. - **/ -const gchar * -hildon_check_button_get_label (GtkButton *button) + * Since: 2.2 + */ +void +hildon_check_button_toggled (HildonCheckButton *button) { - GtkCellRendererText *text_renderer; - const gchar *text; - - g_return_val_if_fail (GTK_IS_BUTTON (button), NULL); - text_renderer = GTK_CELL_RENDERER_TEXT (g_object_get_data (G_OBJECT (button), "text-renderer")); - g_return_val_if_fail (GTK_IS_CELL_RENDERER_TEXT (text_renderer), NULL); - - g_object_get (text_renderer, "text", &text, NULL); + g_return_if_fail (HILDON_IS_CHECK_BUTTON (button)); - return text; + g_signal_emit (button, signals[TOGGLED], 0); } /** * hildon_check_button_set_active: - * @button: A #GtkButton created with hildon_check_button_new() - * @is_active: new state for the check box + * @button: A #HildonCheckButton + * @is_active: new state for the button * - * Sets the state of the check box. + * Sets the status of a #HildonCheckButton. Set to %TRUE if you want + * @button to be 'pressed-in', and %FALSE to raise it. This action + * causes the #HildonCheckButton::toggled signal to be emitted. + * + * Since: 2.2 **/ void -hildon_check_button_set_active (GtkButton *button, - gboolean is_active) +hildon_check_button_set_active (HildonCheckButton *button, + gboolean is_active) { - GtkCellRendererToggle *toggle_renderer; + gboolean prev_is_active; - g_return_if_fail (GTK_IS_BUTTON (button)); - toggle_renderer = GTK_CELL_RENDERER_TOGGLE (g_object_get_data (G_OBJECT (button), "toggle-renderer")); - g_return_if_fail (GTK_IS_CELL_RENDERER_TOGGLE (toggle_renderer)); + g_return_if_fail (HILDON_IS_CHECK_BUTTON (button)); - gtk_cell_renderer_toggle_set_active (toggle_renderer, is_active); + prev_is_active = hildon_check_button_get_active (button); + + if (prev_is_active != is_active) { + gtk_button_clicked (GTK_BUTTON (button)); + gtk_widget_queue_draw (GTK_WIDGET (button)); + } } /** * hildon_check_button_get_active: - * @button: A #GtkButton created with hildon_check_button_new() + * @button: A #HildonCheckButton + * + * Gets the current state of @button. * - * Gets the state of the check box. + * Return value: %TRUE if @button is active, %FALSE otherwise. * - * Return value: %TRUE if the check box is active, %FALSE otherwise. + * Since: 2.2 **/ gboolean -hildon_check_button_get_active (GtkButton *button) +hildon_check_button_get_active (HildonCheckButton *button) { - GtkCellRendererToggle *toggle_renderer; - - g_return_val_if_fail (GTK_IS_BUTTON (button), FALSE); - toggle_renderer = GTK_CELL_RENDERER_TOGGLE (g_object_get_data (G_OBJECT (button), "toggle-renderer")); - g_return_val_if_fail (GTK_IS_CELL_RENDERER_TOGGLE (toggle_renderer), FALSE); + g_return_val_if_fail (HILDON_IS_CHECK_BUTTON (button), FALSE); - return gtk_cell_renderer_toggle_get_active (toggle_renderer); + return gtk_cell_renderer_toggle_get_active (button->priv->toggle_renderer); } /** * hildon_check_button_new: * @size: Flags indicating the size of the new button * - * This function creates a #GtkButton containing a label and a check - * box. + * Creates a new #HildonCheckButton. * - * This button has specific functions to get and set the values of the - * label and the check box. You must not use the standard #GtkButton - * methods for that. + * Return value: A newly created #HildonCheckButton * - * To set the alignment you can use gtk_button_set_alignment() - * - * Return value: A newly created #GtkButton widget. + * Since: 2.2 **/ GtkWidget * hildon_check_button_new (HildonSizeType size) { - GtkWidget *button = gtk_button_new (); + GtkWidget *button = g_object_new (HILDON_TYPE_CHECK_BUTTON, "xalign", 0.0, NULL); + hildon_gtk_widget_set_theme_size (button, size); + return button; +} + +static void +hildon_check_button_clicked (GtkButton *button) +{ + HildonCheckButton *checkbutton = HILDON_CHECK_BUTTON (button); + gboolean current = hildon_check_button_get_active (checkbutton); + + gtk_cell_renderer_toggle_set_active (checkbutton->priv->toggle_renderer, !current); + + hildon_check_button_toggled (checkbutton); +} + +static void +hildon_check_button_apply_style (GtkWidget *widget) +{ + guint checkbox_size; + HildonCheckButtonPrivate *priv = HILDON_CHECK_BUTTON (widget)->priv; + + gtk_widget_style_get (widget, "checkbox-size", &checkbox_size, NULL); + + g_object_set (priv->toggle_renderer, "indicator-size", checkbox_size, NULL); +} + +static void +hildon_check_button_style_set (GtkWidget *widget, + GtkStyle *previous_style) +{ + if (GTK_WIDGET_CLASS (hildon_check_button_parent_class)->style_set) + GTK_WIDGET_CLASS (hildon_check_button_parent_class)->style_set (widget, previous_style); + + hildon_check_button_apply_style (widget); +} + +static void +hildon_check_button_class_init (HildonCheckButtonClass *klass) +{ + GObjectClass *gobject_class = (GObjectClass*) klass; + GtkWidgetClass *widget_class = (GtkWidgetClass*) klass; + GtkButtonClass *button_class = (GtkButtonClass*) klass; + + widget_class->style_set = hildon_check_button_style_set; + button_class->clicked = hildon_check_button_clicked; + + klass->toggled = NULL; + + /** + * HildonCheckButton::toggled + * + * Emitted when the #HildonCheckButton's state is changed. + * + * Since: 2.2 + */ + signals[TOGGLED] = + g_signal_new ("toggled", + G_OBJECT_CLASS_TYPE (gobject_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (HildonCheckButtonClass, toggled), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + gtk_widget_class_install_style_property ( + widget_class, + g_param_spec_uint ( + "checkbox-size", + "Size of the check box", + "Size of the check box", + 0, G_MAXUINT, 26, + G_PARAM_READABLE)); + + g_type_class_add_private (klass, sizeof (HildonCheckButtonPrivate)); +} + +static void +hildon_check_button_init (HildonCheckButton *button) +{ + HildonCheckButtonPrivate *priv = HILDON_CHECK_BUTTON_GET_PRIVATE (button); GtkWidget *cell_view = gtk_cell_view_new (); - GtkCellRenderer *toggle_renderer = gtk_cell_renderer_toggle_new (); - GtkCellRenderer *text_renderer = gtk_cell_renderer_text_new (); - GtkWidget *alignment = gtk_alignment_new (0.5, 0.5, 0.0, 0.0); - /* Set the size of the button */ - hildon_gtk_widget_set_theme_size (button, size); + /* Store private part */ + button->priv = priv; - /* Pack everything */ - gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (cell_view), toggle_renderer, FALSE); - gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (cell_view), text_renderer, FALSE); - gtk_container_add (GTK_CONTAINER (alignment), cell_view); - gtk_container_add (GTK_CONTAINER (button), alignment); - gtk_widget_show_all (GTK_WIDGET (alignment)); + /* Make sure that the check box is always shown, no matter the value of gtk-button-images */ + g_signal_connect (cell_view, "notify::visible", G_CALLBACK (gtk_widget_show), NULL); - /* Toggle the check box when the button is clicked */ - g_signal_connect (button, "clicked", G_CALLBACK (check_button_clicked), toggle_renderer); + /* Create toggle renderer and pack it into the cell view */ + priv->toggle_renderer = GTK_CELL_RENDERER_TOGGLE (gtk_cell_renderer_toggle_new ()); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (cell_view), + GTK_CELL_RENDERER (priv->toggle_renderer), FALSE); - /* Set the data */ - g_object_set_data (G_OBJECT (button), "toggle-renderer", toggle_renderer); - g_object_set_data (G_OBJECT (button), "text-renderer", text_renderer); + /* Add cell view to the image */ + gtk_button_set_image (GTK_BUTTON (button), cell_view); - return button; + hildon_check_button_apply_style (GTK_WIDGET (button)); }