2 * This file is part of hildon-libs
4 * Copyright (C) 2005 Nokia Corporation.
6 * Contact: Luc Pionchon <luc.pionchon@nokia.com>
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
26 * SECTION:hildon-caption
27 * @short_description: A single-child container widget that precedes the
28 * contained widget with a field label and an optional icon
30 * #HildonCaption is a single-child container widget that precedes the
31 * contained widget with a field label and an optional icon. It allows
32 * grouping of several controls together. When a captioned widget has focus,
33 * both widget and caption label are displayed with active focus.
36 #include <gtk/gtkhbox.h>
37 #include <gtk/gtklabel.h>
38 #include <gtk/gtkimage.h>
39 #include <gtk/gtkentry.h>
40 #include <gtk/gtkcombo.h>
41 #include <gtk/gtkcombobox.h>
42 #include <gtk/gtkcomboboxentry.h>
43 #include <gtk/gtkoptionmenu.h>
44 #include <gtk/gtkmarshal.h>
45 #include <gtk/gtkalignment.h>
48 #include "hildon-caption.h"
49 #include "hildon-defines.h"
55 #define _(String) dgettext(PACKAGE, String)
57 #define HILDON_CAPTION_MANDATORY_ICON "qgn_list_gene_mandat_field"
58 #define HILDON_CAPTION_SPACING 6
60 #define HILDON_CAPTION_GET_PRIVATE(obj) \
61 (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
62 HILDON_TYPE_CAPTION, HildonCaptionPrivate));
65 static GtkEventBox *parent_class = NULL;
67 typedef struct _HildonCaptionPrivate HildonCaptionPrivate;
85 static void hildon_caption_class_init ( HildonCaptionClass *caption_class );
86 static void hildon_caption_init ( HildonCaption *caption );
87 static void hildon_caption_size_request ( GtkWidget *widget, GtkRequisition *requisition );
88 static void hildon_caption_size_allocate( GtkWidget *widget, GtkAllocation *allocation );
90 static void hildon_caption_forall( GtkContainer *container,
91 gboolean include_internals,
92 GtkCallback callback, gpointer data );
93 static void hildon_caption_hierarchy_changed( GtkWidget *widget,
94 GtkWidget *previous_toplevel);
95 static void hildon_caption_set_focus( GtkWindow *window, GtkWidget *widget,
97 static void hildon_caption_activate( GtkWidget *widget );
99 static void hildon_caption_set_property( GObject *object, guint param_id,
100 const GValue *value, GParamSpec *pspec );
101 static void hildon_caption_get_property( GObject *object, guint param_id,
102 GValue *value, GParamSpec *pspec );
103 static gboolean hildon_caption_expose( GtkWidget *widget,
104 GdkEventExpose *event );
105 static void hildon_caption_destroy( GtkObject *self );
106 static gboolean hildon_caption_button_press( GtkWidget *widget, GdkEventButton *event );
109 hildon_caption_set_label_text( HildonCaptionPrivate *priv );
111 static void hildon_caption_set_child_property (GtkContainer *container,
116 static void hildon_caption_get_child_property (GtkContainer *container,
122 struct _HildonCaptionPrivate
124 GtkWidget *caption_area;
125 GtkWidget *mandatory_icon;
128 GtkWidget *icon_align; /* Arbitrary icon widgets do not support alignment */
132 guint is_focused : 1;
134 HildonCaptionStatus status;
137 /* Register optional/mandatory type enumeration */
139 hildon_caption_status_get_type (void)
141 static GType etype = 0;
143 static const GEnumValue values[] = {
144 { HILDON_CAPTION_OPTIONAL, "HILDON_CAPTION_OPTIONAL", "optional" },
145 { HILDON_CAPTION_MANDATORY, "HILDON_CAPTION_MANDATORY", "mandatory" },
148 etype = g_enum_register_static ("HildonCaptionStatus", values);
154 * hildon_caption_get_type:
156 * Initialises, and returns the type of a hildon caption.
158 * @Returns: GType of #HildonCaption
160 GType hildon_caption_get_type (void)
162 static GType caption_type = 0;
166 static const GTypeInfo caption_info = {
167 sizeof(HildonCaptionClass),
168 NULL, /* base_init */
169 NULL, /* base_finalize */
170 (GClassInitFunc) hildon_caption_class_init,
171 NULL, /* class_finalize */
172 NULL, /* class_data */
173 sizeof(HildonCaption),
175 (GInstanceInitFunc) hildon_caption_init,
177 caption_type = g_type_register_static( GTK_TYPE_EVENT_BOX,
178 "HildonCaption", &caption_info, 0 );
184 * Initialises the caption class.
186 static void hildon_caption_class_init( HildonCaptionClass *caption_class )
188 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(caption_class);
189 GObjectClass *gobject_class = G_OBJECT_CLASS(caption_class);
190 GtkContainerClass *container_class = GTK_CONTAINER_CLASS(caption_class);
192 parent_class = g_type_class_peek_parent( caption_class );
194 g_type_class_add_private( caption_class, sizeof(HildonCaptionPrivate) );
196 /* Override virtual functions */
197 gobject_class->get_property = hildon_caption_get_property;
198 gobject_class->set_property = hildon_caption_set_property;
200 caption_class->activate = hildon_caption_activate;
202 GTK_OBJECT_CLASS(caption_class)->destroy = hildon_caption_destroy;
204 container_class->forall = hildon_caption_forall;
205 container_class->set_child_property = hildon_caption_set_child_property;
206 container_class->get_child_property = hildon_caption_get_child_property;
208 widget_class->expose_event = hildon_caption_expose;
209 widget_class->hierarchy_changed = hildon_caption_hierarchy_changed;
210 widget_class->size_request = hildon_caption_size_request;
211 widget_class->size_allocate = hildon_caption_size_allocate;
212 widget_class->button_press_event = hildon_caption_button_press;
214 /* Create new signals and properties */
215 widget_class->activate_signal = g_signal_new( "activate",
220 G_STRUCT_OFFSET( HildonCaptionClass,
221 activate), NULL, NULL,
222 gtk_marshal_VOID__VOID,
226 * HildonCaption:label:
230 g_object_class_install_property( gobject_class, PROP_LABEL,
231 g_param_spec_string("label",
232 "Current label", "Caption label",
233 NULL, G_PARAM_READABLE | G_PARAM_WRITABLE) );
236 * HildonCaption:icon:
238 * The icon shown on the caption area.
240 g_object_class_install_property( gobject_class, PROP_ICON,
241 g_param_spec_object("icon",
243 "The icon shown on the caption area",
244 GTK_TYPE_WIDGET, G_PARAM_READABLE |
247 * HildonCaption:status:
249 * Mandatory or optional status.
251 g_object_class_install_property( gobject_class, PROP_STATUS,
252 g_param_spec_enum("status",
254 "Mandatory or optional status",
255 HILDON_TYPE_CAPTION_STATUS,
256 HILDON_CAPTION_OPTIONAL,
257 G_PARAM_READABLE | G_PARAM_WRITABLE) );
259 * HildonCaption:size_group:
261 * Current size group the caption is in.
263 g_object_class_install_property( gobject_class, PROP_SIZE_GROUP,
264 g_param_spec_object("size_group",
265 "Current size group",
266 "Current size group the caption is in",
267 GTK_TYPE_SIZE_GROUP, G_PARAM_READABLE |
271 * HildonCaption:separator:
273 * The current separator.
275 g_object_class_install_property( gobject_class, PROP_SEPARATOR,
276 g_param_spec_string("separator",
277 "Current separator", "Current separator",
278 _("Ecdg_ti_caption_separator"),
279 G_PARAM_READABLE | G_PARAM_WRITABLE) );
281 /* Create child properties. These are related to
282 child <-> parent relationship, not to either of objects itself */
283 gtk_container_class_install_child_property (container_class,
285 g_param_spec_boolean ("expand",
286 "Same as GtkBox expand.",
287 "Same as GtkBox expand. Wheter the child should be expanded or not.",
292 /* Destroy can be called multiple times, remember to set pointers to NULL */
293 static void hildon_caption_destroy( GtkObject *self )
295 HildonCaptionPrivate *priv = HILDON_CAPTION_GET_PRIVATE(self);
297 /* Free our internal child */
298 if( priv->caption_area )
300 gtk_widget_unparent( priv->caption_area );
301 priv->caption_area = NULL;
304 /* Free user provided strings */
307 g_free( priv->text );
310 if( priv->separator )
312 g_free( priv->separator );
313 priv->separator = NULL;
316 /* Parent classes destroy takes care of user packed contents */
317 if( GTK_OBJECT_CLASS(parent_class)->destroy )
318 GTK_OBJECT_CLASS(parent_class)->destroy( self );
321 /* Parent, eventbox will run allocate also for the child which may be
322 * owning a window too. This window is then moved and resized
323 * and we do not want to do that (it causes flickering).
325 static gboolean hildon_caption_expose( GtkWidget *widget,
326 GdkEventExpose *event )
328 HildonCaptionPrivate *priv = NULL;
333 g_assert( HILDON_IS_CAPTION(widget) );
334 priv = HILDON_CAPTION_GET_PRIVATE(widget);
336 if( !GTK_WIDGET_DRAWABLE(widget) )
339 GTK_WIDGET_CLASS(parent_class)->expose_event( widget, event );
341 /* If our child control is focused, we draw nice looking focus
342 graphics for the caption */
343 if ( priv->is_focused )
345 /* Determine focus box dimensions */
346 gtk_widget_get_child_requisition( priv->caption_area, &req );
347 align = hildon_caption_get_label_alignment(HILDON_CAPTION(widget));
349 alloc.width = priv->caption_area->allocation.width + HILDON_CAPTION_SPACING;
350 alloc.height = MIN (req.height + (2 * widget->style->ythickness), priv->caption_area->allocation.height);
351 alloc.x = priv->caption_area->allocation.x;
352 alloc.y = priv->caption_area->allocation.y +
353 MAX(((priv->caption_area->allocation.height - alloc.height) * align), 0);
355 /* Paint the focus box */
356 gtk_paint_box( widget->style, widget->window, GTK_STATE_ACTIVE,
357 GTK_SHADOW_OUT, NULL, widget, "selection",
358 alloc.x, alloc.y, alloc.width, alloc.height );
360 /* Paint caption contents on top of the focus box */
361 GTK_WIDGET_GET_CLASS(priv->caption_area)->expose_event(
362 priv->caption_area, event);
368 static void hildon_caption_set_property( GObject *object, guint param_id,
372 HildonCaptionPrivate *priv = HILDON_CAPTION_GET_PRIVATE(object);
377 /* Free old label string */
380 g_free( priv->text );
385 priv->text = g_strdup( g_value_get_string(value) );
386 hildon_caption_set_label_text( priv );
390 /* Remove old icon */
392 gtk_container_remove( GTK_CONTAINER(priv->icon_align), priv->icon );
394 /* Pack and display new icon */
395 priv->icon = g_value_get_object( value );
398 gtk_container_add(GTK_CONTAINER(priv->icon_align), priv->icon);
399 gtk_widget_show_all( priv->caption_area );
404 priv->status = g_value_get_enum( value );
406 /* For mandatory fields we display a special icon */
407 if( priv->status == HILDON_CAPTION_MANDATORY )
409 if( !priv->mandatory_icon )
413 /* Create mandatory icon */
414 priv->mandatory_icon = gtk_image_new_from_icon_name(
415 HILDON_CAPTION_MANDATORY_ICON,
416 HILDON_ICON_SIZE_NOTE );
418 align = hildon_caption_get_label_alignment(HILDON_CAPTION(object));
419 g_object_set(priv->mandatory_icon, "yalign", align, NULL);
421 /* Pack and show mandatory icon */
422 if( priv->mandatory_icon )
424 gtk_box_pack_end( GTK_BOX(priv->caption_area),
425 priv->mandatory_icon, FALSE, FALSE, 0 );
426 gtk_widget_show_all( priv->caption_area );
432 if( priv->mandatory_icon )
434 /* Remove mandatory icon */
435 gtk_container_remove( GTK_CONTAINER(priv->caption_area),
436 priv->mandatory_icon );
437 priv->mandatory_icon = NULL;
442 case PROP_SIZE_GROUP:
443 /* Detach from previous size group */
445 gtk_size_group_remove_widget( priv->group, priv->caption_area );
447 priv->group = g_value_get_object( value );
449 /* Attach to new size group */
451 gtk_size_group_add_widget( priv->group, priv->caption_area );
452 gtk_widget_queue_draw( GTK_WIDGET(object) );
457 /* Free old separator */
458 if( priv->separator )
460 g_free( priv->separator );
461 priv->separator = NULL;
464 priv->separator = g_strdup( g_value_get_string(value) );
465 hildon_caption_set_label_text( priv );
469 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
474 static void hildon_caption_get_property( GObject *object, guint param_id,
475 GValue *value, GParamSpec *pspec )
477 HildonCaptionPrivate *priv = HILDON_CAPTION_GET_PRIVATE(object);
482 g_value_set_string( value, priv->text );
485 g_value_set_object( value, priv->icon );
488 g_value_set_enum( value, priv->status );
490 case PROP_SIZE_GROUP:
491 g_value_set_object( value, priv->group );
494 g_value_set_string( value, priv->separator );
497 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
502 static void hildon_caption_set_child_property( GtkContainer *container,
510 case CHILD_PROP_EXPAND:
511 hildon_caption_set_child_expand( HILDON_CAPTION(container),
512 g_value_get_boolean(value) );
516 G_OBJECT_WARN_INVALID_PROPERTY_ID(container, property_id, pspec);
521 static void hildon_caption_get_child_property( GtkContainer *container,
529 case CHILD_PROP_EXPAND:
530 g_value_set_boolean( value, hildon_caption_get_child_expand(
531 HILDON_CAPTION(container)) );
535 G_OBJECT_WARN_INVALID_PROPERTY_ID(container, property_id, pspec);
540 /* We want to activate out child control on button press */
541 static gboolean hildon_caption_button_press( GtkWidget *widget,
542 GdkEventButton *event )
544 HildonCaptionPrivate *priv = HILDON_CAPTION_GET_PRIVATE(widget);
545 GtkWidget *child = GTK_BIN(widget)->child;
547 /* If child can take focus, we simply grab focus to it */
548 if ((GTK_WIDGET_CAN_FOCUS(child) || GTK_IS_CONTAINER(child)) &&
549 GTK_WIDGET_IS_SENSITIVE(child))
551 priv->is_focused = TRUE;
552 gtk_widget_grab_focus( GTK_BIN(widget)->child );
558 static void hildon_caption_init( HildonCaption *caption )
560 HildonCaptionPrivate *priv = NULL;
562 /* Initialize startup state */
563 priv = HILDON_CAPTION_GET_PRIVATE(caption);
564 priv->status = HILDON_CAPTION_OPTIONAL;
567 priv->is_focused = FALSE;
569 priv->separator = g_strdup(_("Ecdg_ti_caption_separator"));
571 gtk_widget_push_composite_child();
573 /* Create caption text */
574 priv->caption_area = gtk_hbox_new( FALSE, HILDON_CAPTION_SPACING );
575 priv->label = gtk_label_new( NULL );
576 priv->icon_align = gtk_alignment_new(0.5f, 0.5f, 0.0f, 0.0f);
578 /* We want to receive button presses for child widget activation */
579 gtk_event_box_set_above_child( GTK_EVENT_BOX(caption), FALSE );
580 gtk_widget_add_events( GTK_WIDGET(caption), GDK_BUTTON_PRESS_MASK );
582 /* Pack text label caption layout */
583 gtk_box_pack_end( GTK_BOX(priv->caption_area), priv->icon_align, FALSE, FALSE, 0);
584 gtk_box_pack_end( GTK_BOX(priv->caption_area), priv->label, FALSE, FALSE, 0 );
585 gtk_widget_set_parent( priv->caption_area, GTK_WIDGET(caption) );
587 gtk_widget_pop_composite_child();
589 gtk_widget_show_all( priv->caption_area );
592 static void hildon_caption_set_focus( GtkWindow *window, GtkWidget *widget,
595 HildonCaptionPrivate *priv = HILDON_CAPTION_GET_PRIVATE(caption);
597 /* Try to find caption among the ancestors of widget */
598 if (gtk_widget_is_ancestor(widget, caption))
600 priv->is_focused = TRUE;
601 gtk_widget_queue_draw( caption );
605 if( priv->is_focused == TRUE )
607 /* Caption wasn't found, so cannot focus */
608 priv->is_focused = FALSE;
609 gtk_widget_queue_draw( caption );
613 /* We need to connect/disconnect signal handlers to toplevel window
614 in which we reside. Ww want to update connected signals if our
616 static void hildon_caption_hierarchy_changed( GtkWidget *widget,
617 GtkWidget *previous_toplevel)
619 GtkWidget *current_ancestor;
620 HildonCaptionPrivate *priv;
622 priv = HILDON_CAPTION_GET_PRIVATE(widget);
624 if( GTK_WIDGET_CLASS(parent_class)->hierarchy_changed )
625 GTK_WIDGET_CLASS(parent_class)->hierarchy_changed( widget,
628 /* If we already were inside a window, remove old handler */
629 if (previous_toplevel) {
630 /* This is a compilation workaround for gcc > 3.3 since glib is buggy */
631 /* see http://bugzilla.gnome.org/show_bug.cgi?id=310175 */
635 g_signal_handlers_disconnect_by_func
636 (previous_toplevel, (gpointer) hildon_caption_set_focus, widget);
638 current_ancestor = gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW);
640 /* Install new handler for focus movement */
641 if (current_ancestor)
642 g_signal_connect( current_ancestor, "set-focus",
643 G_CALLBACK(hildon_caption_set_focus), widget );
646 static void hildon_caption_size_request( GtkWidget *widget,
647 GtkRequisition *requisition )
650 HildonCaptionPrivate *priv = NULL;
651 g_return_if_fail( HILDON_IS_CAPTION(widget) );
652 priv = HILDON_CAPTION_GET_PRIVATE(widget);
654 /* Use the same size requisition for the main box of the caption */
655 gtk_widget_size_request( priv->caption_area, &req );
657 if( GTK_WIDGET_CLASS(parent_class)->size_request )
658 GTK_WIDGET_CLASS(parent_class)->size_request( widget, requisition );
660 requisition->width += req.width + HILDON_CAPTION_SPACING * 3;
662 if( (req.height + (2 * widget->style->ythickness)) > requisition->height )
663 requisition->height = req.height + (2 * widget->style->ythickness);
666 /* We use HILDON_CAPTION_SPACING to make it look a bit nicer */
667 static void hildon_caption_size_allocate( GtkWidget *widget,
668 GtkAllocation *allocation )
670 GtkAllocation allocA;
671 GtkAllocation allocB;
673 GtkWidget *child = NULL;
674 HildonCaptionPrivate *priv = NULL;
675 g_assert( HILDON_IS_CAPTION(widget) );
676 priv = HILDON_CAPTION_GET_PRIVATE(widget);
678 /* Position the caption to its allocated location */
679 if( GTK_WIDGET_REALIZED(widget) )
680 gdk_window_move_resize (widget->window,
681 allocation->x + GTK_CONTAINER (widget)->border_width,
682 allocation->y + GTK_CONTAINER (widget)->border_width,
683 MAX (allocation->width - GTK_CONTAINER (widget)->border_width * 2, 0),
684 MAX (allocation->height - GTK_CONTAINER (widget)->border_width * 2, 0));
686 child = GTK_BIN(widget)->child;
688 widget->allocation = *allocation;
689 gtk_widget_get_child_requisition( priv->caption_area, &req );
691 allocA.height = allocB.height = allocation->height;
692 allocA.width = allocB.width = allocation->width;
693 allocA.x = allocB.x = allocB.y = allocA.y = 0;
695 /* Center the captioned widget */
696 if( allocA.width > req.width + HILDON_CAPTION_SPACING )
698 allocA.x += req.width + HILDON_CAPTION_SPACING * 2;
699 allocB.width = req.width;
702 /* Leave room for the other drawable parts of the caption control */
703 allocA.width -= req.width + HILDON_CAPTION_SPACING * 2;
705 /* Give the child at least its minimum requisition, unless it is expandable */
706 if( !priv->expand && child && GTK_WIDGET_VISIBLE(child) )
708 GtkRequisition child_req;
709 gtk_widget_get_child_requisition( child, &child_req );
710 allocA.width = MIN( allocA.width, child_req.width );
711 allocA.height = MIN( allocA.height, child_req.height );
714 /* Ensure there are no negative dimensions */
715 if( allocA.width < 0 )
717 allocB.width = req.width + allocA.width;
719 allocB.width = MAX (allocB.width, 0);
722 allocA.height = MAX (allocA.height, 0);
723 allocB.height = MAX (allocB.height, 0);
725 if (child && GTK_WIDGET_VISIBLE(child) )
726 gtk_widget_size_allocate( child, &allocA );
727 gtk_widget_size_allocate( priv->caption_area, &allocB );
730 static void hildon_caption_forall( GtkContainer *container,
731 gboolean include_internals,
732 GtkCallback callback, gpointer data )
734 HildonCaptionPrivate *priv = NULL;
736 g_assert( HILDON_IS_CAPTION(container) );
737 g_assert( callback != NULL );
739 priv = HILDON_CAPTION_GET_PRIVATE(container);
741 /* Execute callback for the child widgets */
742 if( GTK_CONTAINER_CLASS(parent_class)->forall )
743 GTK_CONTAINER_CLASS(parent_class)->forall( container, include_internals,
746 if( include_internals )
747 /* Execute callback for the parent box as well */
748 (*callback)( priv->caption_area, data );
753 * hildon_caption_set_sizegroup:
754 * @caption : a #HildonCaption
755 * @new_group : a #GtkSizeGroup
757 * Sets a #GtkSizeGroup of a given captioned control.
759 * Deprecated: use g_object_set, property :size-group
761 void hildon_caption_set_sizegroup( const HildonCaption *self,
762 GtkSizeGroup *group )
764 g_object_set( G_OBJECT(self), "size_group", group, NULL );
768 * hildon_caption_get_sizegroup:
769 * @caption : a #HildonCaption
771 * Query given captioned control for the #GtkSizeGroup assigned to it.
773 * @Returns : a #GtkSizeGroup
775 * Deprecated: Use g_object_get, property :size-group
777 GtkSizeGroup *hildon_caption_get_sizegroup( const HildonCaption *self )
779 HildonCaptionPrivate *priv;
780 g_return_val_if_fail( HILDON_IS_CAPTION (self), NULL );
781 priv = HILDON_CAPTION_GET_PRIVATE(self);
786 * hildon_caption_new:
787 * @group : a #GtkSizeGroup for controlling the size of related captions,
789 * @value : the caption text to accompany the text entry. The widget makes
790 * a copy of this text.
791 * @control : the control that is to be captioned
792 * @icon : an icon to accompany the label - can be NULL in which case no
794 * @flag : indicates whether this captioned control is mandatory or
797 * Creates a new instance of hildon_caption widget, with a specific
799 * Note: Clicking on a focused caption will trigger the activate signal.
800 * The default behaviour for the caption's activate signal is to call
801 * gtk_widget_activate on it's control.
803 * @Returns : a #GtkWidget pointer of Caption
805 GtkWidget *hildon_caption_new( GtkSizeGroup *group, const gchar *value,
806 GtkWidget *control, GtkWidget *icon,
807 HildonCaptionStatus flag)
810 g_return_val_if_fail( GTK_IS_WIDGET(control), NULL );
812 widget = g_object_new( HILDON_TYPE_CAPTION, "label", value,
813 "size_group", group, "icon", icon, "status", flag,
816 /* Pack the captioned widget */
817 hildon_caption_set_child_expand( HILDON_CAPTION(widget), TRUE );
818 gtk_container_add( GTK_CONTAINER(widget), control );
825 * hildon_caption_is_mandatory:
826 * @caption : a #HildonCaption
828 * Query #HildonCaption whether this captioned control is a mandatory one.
830 * @Returns : is this captioned control a mandatory one?
833 gboolean hildon_caption_is_mandatory( const HildonCaption *caption )
835 HildonCaptionPrivate *priv;
836 g_return_val_if_fail( HILDON_IS_CAPTION(caption), FALSE );
837 priv = HILDON_CAPTION_GET_PRIVATE(caption);
839 return priv->status == HILDON_CAPTION_MANDATORY;
843 * hildon_caption_set_status:
844 * @caption : a #HildonCaption
845 * @flag : one of the values from #HildonCaptionStatus
847 * Sets #HildonCaption status.
850 void hildon_caption_set_status( HildonCaption *caption,
851 HildonCaptionStatus flag )
853 g_return_if_fail( HILDON_IS_CAPTION(caption) );
855 g_object_set( G_OBJECT(caption), "status", flag, NULL );
859 * hildon_caption_get_status:
860 * @caption : a #HildonCaption
862 * Gets #HildonCaption status.
864 * @Returns : one of the values from #HildonCaptionStatus
867 HildonCaptionStatus hildon_caption_get_status( const HildonCaption *caption )
869 HildonCaptionPrivate *priv;
870 g_return_val_if_fail( HILDON_IS_CAPTION(caption), HILDON_CAPTION_OPTIONAL );
871 priv = HILDON_CAPTION_GET_PRIVATE(caption);
877 * hildon_caption_set_icon_image:
878 * @caption : a #HildonCaption
879 * @icon : the #GtkImage to use as the icon.
880 * calls gtk_widget_show on the icon if !GTK_WIDGET_VISIBLE(icon)
882 * Sets the icon to be used by this hildon_caption widget.
885 void hildon_caption_set_icon_image( HildonCaption *caption, GtkWidget *icon )
887 g_return_if_fail( HILDON_IS_CAPTION(caption) );
889 g_object_set( G_OBJECT(caption), "icon", icon, NULL );
893 * hildon_caption_get_icon_image:
894 * @caption : a #HildonCaption
896 * Gets icon of #HildonCaption
898 * @Returns : the #GtkImage that is being used as the icon by the
899 * hildon_caption, or NULL if no icon is in use
902 GtkWidget *hildon_caption_get_icon_image( const HildonCaption *caption )
904 HildonCaptionPrivate *priv;
905 g_return_val_if_fail( HILDON_IS_CAPTION(caption), NULL );
906 priv = HILDON_CAPTION_GET_PRIVATE(caption);
912 * hildon_caption_set_label:
913 * @caption : a #HildonCaption
914 * @label : the text to use
916 * Sets the label text that appears before the control.
917 * Separator character is added to the end of the label string. By default
918 * the separator is ":".
921 void hildon_caption_set_label( HildonCaption *caption, const gchar *label )
923 g_return_if_fail( HILDON_IS_CAPTION(caption) );
925 g_object_set( G_OBJECT(caption), "label", label, NULL );
929 * hildon_caption_get_label:
930 * @caption : a #HildonCaption
932 * Gets label of #HildonCaption
934 * @Returns : the text currently being used as the label of the caption
935 * control. The string is owned by the label and the caller should never
936 * free or modify this value.
939 gchar *hildon_caption_get_label( const HildonCaption *caption )
941 HildonCaptionPrivate *priv;
942 g_return_val_if_fail(HILDON_IS_CAPTION(caption), "");
943 priv = HILDON_CAPTION_GET_PRIVATE(caption);
945 return (gchar*)gtk_label_get_text(GTK_LABEL(GTK_LABEL(priv->label)));
949 * hildon_caption_set_separator:
950 * @caption : a #HildonCaption
951 * @separator : the separator to use
953 * Sets the separator character that appears after the label.
954 * The default seaparator character is ":"
958 void hildon_caption_set_separator( HildonCaption *caption,
959 const gchar *separator )
961 g_return_if_fail( HILDON_IS_CAPTION(caption) );
963 g_object_set( G_OBJECT(caption), "separator", separator, NULL );
967 * hildon_caption_get_separator:
968 * @caption : a #HildonCaption
970 * Gets separator string of #HildonCaption
972 * @Returns : the text currently being used as the separator of the caption
973 * control. The string is owned by the caption control and the caller should
974 * never free or modify this value.
977 gchar *hildon_caption_get_separator( const HildonCaption *caption )
979 HildonCaptionPrivate *priv;
980 g_return_val_if_fail(HILDON_IS_CAPTION(caption), "");
981 priv = HILDON_CAPTION_GET_PRIVATE(caption);
983 return priv->separator;
988 * hildon_caption_get_control:
989 * @caption : a #HildonCaption
991 * Gets caption's control.
993 * @Returns : a #GtkWidget
995 * Deprecated: use gtk_bin_get_child instead
997 GtkWidget *hildon_caption_get_control( const HildonCaption *caption )
999 g_return_val_if_fail( HILDON_IS_CAPTION(caption), NULL );
1000 return GTK_BIN(caption)->child;
1003 /*activates the child control
1004 *We have this signal so that if needed an application can
1005 *know when we've been activated (useful for captions with
1008 /* FIXME: There never are multiple children. Possibly activate
1009 signal could be removed entirely? (does anyone use it?) */
1010 static void hildon_caption_activate( GtkWidget *widget )
1012 HildonCaptionPrivate *priv;
1013 GtkWidget *child = GTK_BIN(widget)->child;
1014 priv = HILDON_CAPTION_GET_PRIVATE(widget);
1016 gtk_widget_grab_focus( child );
1020 * hildon_caption_set_child_expand:
1021 * @caption : a #HildonCaption
1022 * @expand : gboolean to determine is the child expandable
1024 * Sets child expandability.
1026 void hildon_caption_set_child_expand( HildonCaption *caption, gboolean expand )
1028 HildonCaptionPrivate *priv = NULL;
1029 GtkWidget *child = NULL;
1030 g_return_if_fail( HILDON_IS_CAPTION(caption) );
1032 priv = HILDON_CAPTION_GET_PRIVATE(caption);
1034 /* Did the setting really change? */
1035 if( priv->expand == expand )
1038 priv->expand = expand;
1039 child = GTK_BIN(caption)->child;
1041 /* We do not have a child, nothing to do */
1042 if( !GTK_IS_WIDGET(child) )
1045 if( GTK_WIDGET_VISIBLE (child) && GTK_WIDGET_VISIBLE (caption) )
1046 gtk_widget_queue_resize( child );
1048 gtk_widget_child_notify( child, "expand" );
1052 * hildon_caption_get_child_expand:
1053 * @caption : a #HildonCaption
1055 * Gets childs expandability.
1057 * @Returns : wheter the child is expandable or not.
1059 gboolean hildon_caption_get_child_expand( const HildonCaption *caption )
1061 HildonCaptionPrivate *priv = NULL;
1062 g_return_val_if_fail( HILDON_IS_CAPTION(caption), FALSE );
1063 priv = HILDON_CAPTION_GET_PRIVATE(caption);
1064 return priv->expand;
1068 * hildon_caption_set_control:
1069 * @caption : a #HildonCaption
1070 * @control : the control to use. Control should not be NULL.
1072 * Sets the control of the caption.
1073 * The old control will be destroyed, unless the caller has added a
1075 * Function unparents the old control (if there is one) and adds the new
1078 * Deprecated: use gtk_container_add
1080 void hildon_caption_set_control( HildonCaption *caption, GtkWidget *control )
1082 GtkWidget *child = NULL;
1083 g_return_if_fail( HILDON_IS_CAPTION(caption) );
1084 child = GTK_BIN(caption)->child;
1087 gtk_container_remove( GTK_CONTAINER(caption), child );
1091 gtk_container_add( GTK_CONTAINER(caption), control );
1099 hildon_caption_set_label_text( HildonCaptionPrivate *priv )
1102 g_assert ( priv != NULL );
1106 if( priv->separator )
1108 /* Don't duplicate the separator, if the string already contains one */
1109 if (g_str_has_suffix(priv->text, priv->separator))
1111 gtk_label_set_text( GTK_LABEL( priv->label ), priv->text );
1115 /* Append separator and set text */
1116 tmp = g_strconcat( priv->text, priv->separator, NULL );
1117 gtk_label_set_text( GTK_LABEL( priv->label ), tmp );
1123 gtk_label_set_text( GTK_LABEL( priv->label ), priv->text );
1128 /* Clear the label */
1129 gtk_label_set_text( GTK_LABEL( priv->label ), "" );
1135 * hildon_caption_set_label_alignment:
1136 * @caption: a #HildonCaption widget
1137 * @alignment: new vertical alignment
1139 * Sets the vertical alignment to be used for the
1140 * text part of the caption. Applications need to
1141 * align the child control themselves.
1143 void hildon_caption_set_label_alignment(HildonCaption *caption,
1146 HildonCaptionPrivate *priv;
1148 g_return_if_fail(HILDON_IS_CAPTION(caption));
1150 priv = HILDON_CAPTION_GET_PRIVATE(caption);
1151 g_object_set(priv->label, "yalign", alignment, NULL);
1152 g_object_set(priv->icon_align, "yalign", alignment, NULL);
1154 if (priv->mandatory_icon)
1155 g_object_set(priv->mandatory_icon, "yalign", alignment, NULL);
1159 * hildon_caption_get_label_alignment:
1160 * @caption: a #HildonCaption widget
1162 * Gets current vertical alignment for the text part.
1164 * Returns: vertical alignment
1166 gfloat hildon_caption_get_label_alignment(HildonCaption *caption)
1168 HildonCaptionPrivate *priv;
1171 g_return_val_if_fail( HILDON_IS_CAPTION(caption), 0);
1172 priv = HILDON_CAPTION_GET_PRIVATE(caption);
1173 g_object_get(priv->label, "yalign", &result, NULL);