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
25 #include <gtk/gtkhbox.h>
26 #include <gtk/gtklabel.h>
27 #include <gtk/gtkimage.h>
28 #include <gtk/gtkentry.h>
29 #include <gtk/gtkcombo.h>
30 #include <gtk/gtkcombobox.h>
31 #include <gtk/gtkcomboboxentry.h>
32 #include <gtk/gtkoptionmenu.h>
33 #include <gtk/gtkmarshal.h>
34 #include <gtk/gtkalignment.h>
37 #include "hildon-caption.h"
38 #include "hildon-defines.h"
44 #define _(String) dgettext(PACKAGE, String)
46 #define HILDON_CAPTION_MANDATORY_ICON "qgn_list_gene_mandat_field"
47 #define HILDON_CAPTION_SPACING 6
49 #define HILDON_CAPTION_GET_PRIVATE(obj) \
50 (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
51 HILDON_TYPE_CAPTION, HildonCaptionPrivate));
54 static GtkEventBox *parent_class = NULL;
56 typedef struct _HildonCaptionPrivate HildonCaptionPrivate;
74 static void hildon_caption_class_init( HildonCaptionClass *caption_class );
75 static void hildon_caption_init( HildonCaption *caption );
76 static void hildon_caption_size_request( GtkWidget *widget,
77 GtkRequisition *requisition );
78 static void hildon_caption_size_allocate( GtkWidget *widget,
79 GtkAllocation *allocation );
80 static void hildon_caption_forall( GtkContainer *container,
81 gboolean include_internals,
82 GtkCallback callback, gpointer data );
83 static void hildon_caption_hierarchy_changed( GtkWidget *widget,
84 GtkWidget *previous_toplevel);
85 static void hildon_caption_set_focus( GtkWindow *window, GtkWidget *widget,
87 static void hildon_caption_activate( GtkWidget *widget );
89 static void hildon_caption_set_property( GObject *object, guint param_id,
90 const GValue *value, GParamSpec *pspec );
91 static void hildon_caption_get_property( GObject *object, guint param_id,
92 GValue *value, GParamSpec *pspec );
93 static gboolean hildon_caption_expose( GtkWidget *widget,
94 GdkEventExpose *event );
95 static void hildon_caption_destroy( GtkObject *self );
96 static gboolean hildon_caption_button_press( GtkWidget *widget, GdkEventButton *event );
99 hildon_caption_set_label_text( HildonCaptionPrivate *priv );
101 static void hildon_caption_set_child_property (GtkContainer *container,
106 static void hildon_caption_get_child_property (GtkContainer *container,
112 struct _HildonCaptionPrivate
114 GtkWidget *caption_area;
115 GtkWidget *mandatory_icon;
118 GtkWidget *icon_align; /* Arbitrary icon widgets do not support alignment */
122 guint is_focused : 1;
124 HildonCaptionStatus status;
127 /* Register optional/mandatory type enumeration */
129 hildon_caption_status_get_type (void)
131 static GType etype = 0;
133 static const GEnumValue values[] = {
134 { HILDON_CAPTION_OPTIONAL, "HILDON_CAPTION_OPTIONAL", "optional" },
135 { HILDON_CAPTION_MANDATORY, "HILDON_CAPTION_MANDATORY", "mandatory" },
138 etype = g_enum_register_static ("HildonCaptionStatus", values);
144 * hildon_caption_get_type:
145 * @Returns : GType of #HildonCaption.
147 * Initialises, and returns the type of a hildon caption.
149 GType hildon_caption_get_type (void)
151 static GType caption_type = 0;
155 static const GTypeInfo caption_info = {
156 sizeof(HildonCaptionClass),
157 NULL, /* base_init */
158 NULL, /* base_finalize */
159 (GClassInitFunc) hildon_caption_class_init,
160 NULL, /* class_finalize */
161 NULL, /* class_data */
162 sizeof(HildonCaption),
164 (GInstanceInitFunc) hildon_caption_init,
166 caption_type = g_type_register_static( GTK_TYPE_EVENT_BOX,
167 "HildonCaption", &caption_info, 0 );
173 * Initialises the caption class.
175 static void hildon_caption_class_init( HildonCaptionClass *caption_class )
177 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(caption_class);
178 GObjectClass *gobject_class = G_OBJECT_CLASS(caption_class);
179 GtkContainerClass *container_class = GTK_CONTAINER_CLASS(caption_class);
181 parent_class = g_type_class_peek_parent( caption_class );
183 g_type_class_add_private( caption_class, sizeof(HildonCaptionPrivate) );
185 /* Override virtual functions */
186 gobject_class->get_property = hildon_caption_get_property;
187 gobject_class->set_property = hildon_caption_set_property;
188 caption_class->activate = hildon_caption_activate;
189 GTK_OBJECT_CLASS(caption_class)->destroy = hildon_caption_destroy;
190 container_class->forall = hildon_caption_forall;
191 container_class->set_child_property = hildon_caption_set_child_property;
192 container_class->get_child_property = hildon_caption_get_child_property;
193 widget_class->expose_event = hildon_caption_expose;
194 widget_class->hierarchy_changed = hildon_caption_hierarchy_changed;
195 widget_class->size_request = hildon_caption_size_request;
196 widget_class->size_allocate = hildon_caption_size_allocate;
197 widget_class->button_press_event = hildon_caption_button_press;
199 /* Create new signals and properties */
200 widget_class->activate_signal = g_signal_new( "activate",
205 G_STRUCT_OFFSET( HildonCaptionClass,
206 activate), NULL, NULL,
207 gtk_marshal_VOID__VOID,
211 * HildonCaption:label:
215 g_object_class_install_property( gobject_class, PROP_LABEL,
216 g_param_spec_string("label",
217 "Current label", "Caption label",
218 NULL, G_PARAM_READABLE | G_PARAM_WRITABLE) );
221 * HildonCaption:icon:
223 * The icon shown on the caption area.
225 g_object_class_install_property( gobject_class, PROP_ICON,
226 g_param_spec_object("icon",
228 "The icon shown on the caption area",
229 GTK_TYPE_WIDGET, G_PARAM_READABLE |
232 * HildonCaption:status:
234 * Mandatory or optional status.
236 g_object_class_install_property( gobject_class, PROP_STATUS,
237 g_param_spec_enum("status",
239 "Mandatory or optional status",
240 HILDON_TYPE_CAPTION_STATUS,
241 HILDON_CAPTION_OPTIONAL,
242 G_PARAM_READABLE | G_PARAM_WRITABLE) );
244 * HildonCaption:size_group:
246 * Current size group the caption is in.
248 g_object_class_install_property( gobject_class, PROP_SIZE_GROUP,
249 g_param_spec_object("size_group",
250 "Current size group",
251 "Current size group the caption is in",
252 GTK_TYPE_SIZE_GROUP, G_PARAM_READABLE |
256 * HildonCaption:separator:
258 * The current separator.
260 g_object_class_install_property( gobject_class, PROP_SEPARATOR,
261 g_param_spec_string("separator",
262 "Current separator", "Current separator",
263 _("Ecdg_ti_caption_separator"),
264 G_PARAM_READABLE | G_PARAM_WRITABLE) );
266 /* Create child properties. These are related to
267 child <-> parent relationship, not to either of objects itself */
268 gtk_container_class_install_child_property (container_class,
270 g_param_spec_boolean ("expand",
271 "Same as GtkBox expand.",
272 "Same as GtkBox expand. Wheter the child should be expanded or not.",
277 /* Destroy can be called multiple times, remember to set pointers to NULL */
278 static void hildon_caption_destroy( GtkObject *self )
280 HildonCaptionPrivate *priv = HILDON_CAPTION_GET_PRIVATE(self);
282 /* Free our internal child */
283 if( priv->caption_area )
285 gtk_widget_unparent( priv->caption_area );
286 priv->caption_area = NULL;
289 /* Free user provided strings */
292 g_free( priv->text );
295 if( priv->separator )
297 g_free( priv->separator );
298 priv->separator = NULL;
301 /* Parent classes destroy takes care of user packed contents */
302 if( GTK_OBJECT_CLASS(parent_class)->destroy )
303 GTK_OBJECT_CLASS(parent_class)->destroy( self );
306 /* Parent, eventbox will run allocate also for the child which may be
307 * owning a window too. This window is then moved and resized and we do not
308 * want to do that -> It causes flickering.
309 * And just because we also want to
311 static gboolean hildon_caption_expose( GtkWidget *widget,
312 GdkEventExpose *event )
314 HildonCaptionPrivate *priv = NULL;
319 g_return_val_if_fail( HILDON_IS_CAPTION(widget), TRUE );
320 priv = HILDON_CAPTION_GET_PRIVATE(widget);
322 if( !GTK_WIDGET_DRAWABLE(widget) )
325 GTK_WIDGET_CLASS(parent_class)->expose_event( widget, event );
327 /* If our child control is focused, we draw nice looking focus
328 graphics for the caption */
329 if ( priv->is_focused )
331 /* Determine focus box dimensions */
332 gtk_widget_get_child_requisition( priv->caption_area, &req );
333 align = hildon_caption_get_label_alignment(HILDON_CAPTION(widget));
335 alloc.width = priv->caption_area->allocation.width + HILDON_CAPTION_SPACING;
336 alloc.height = MIN (req.height + (2 * widget->style->ythickness), priv->caption_area->allocation.height);
337 alloc.x = priv->caption_area->allocation.x;
338 alloc.y = priv->caption_area->allocation.y +
339 MAX(((priv->caption_area->allocation.height - alloc.height) * align), 0);
341 /* Paint the focus box */
342 gtk_paint_box( widget->style, widget->window, GTK_STATE_ACTIVE,
343 GTK_SHADOW_OUT, NULL, widget, "selection",
344 alloc.x, alloc.y, alloc.width, alloc.height );
346 /* Paint caption contents on top of the focus box */
347 GTK_WIDGET_GET_CLASS(priv->caption_area)->expose_event(
348 priv->caption_area, event);
354 static void hildon_caption_set_property( GObject *object, guint param_id,
358 HildonCaptionPrivate *priv = HILDON_CAPTION_GET_PRIVATE(object);
363 /* Free old label string */
366 g_free( priv->text );
371 priv->text = g_strdup( g_value_get_string(value) );
372 hildon_caption_set_label_text( priv );
376 /* Remove old icon */
378 gtk_container_remove( GTK_CONTAINER(priv->icon_align), priv->icon );
380 /* Pack and display new icon */
381 priv->icon = g_value_get_object( value );
384 gtk_container_add(GTK_CONTAINER(priv->icon_align), priv->icon);
385 gtk_widget_show_all( priv->caption_area );
390 priv->status = g_value_get_enum( value );
392 /* For mandatory fields we display a special icon */
393 if( priv->status == HILDON_CAPTION_MANDATORY )
395 if( !priv->mandatory_icon )
399 /* Create mandatory icon */
400 priv->mandatory_icon = gtk_image_new_from_icon_name(
401 HILDON_CAPTION_MANDATORY_ICON,
402 HILDON_ICON_SIZE_NOTE );
404 align = hildon_caption_get_label_alignment(HILDON_CAPTION(object));
405 g_object_set(priv->mandatory_icon, "yalign", align, NULL);
407 /* Pack and show mandatory icon */
408 if( priv->mandatory_icon )
410 gtk_box_pack_end( GTK_BOX(priv->caption_area),
411 priv->mandatory_icon, FALSE, FALSE, 0 );
412 gtk_widget_show_all( priv->caption_area );
418 if( priv->mandatory_icon )
420 /* Remove mandatory icon */
421 gtk_container_remove( GTK_CONTAINER(priv->caption_area),
422 priv->mandatory_icon );
423 priv->mandatory_icon = NULL;
428 case PROP_SIZE_GROUP:
429 /* Detach from previous size group */
431 gtk_size_group_remove_widget( priv->group, priv->caption_area );
433 priv->group = g_value_get_object( value );
435 /* Attach to new size group */
437 gtk_size_group_add_widget( priv->group, priv->caption_area );
438 gtk_widget_queue_draw( GTK_WIDGET(object) );
443 /* Free old separator */
444 if( priv->separator )
446 g_free( priv->separator );
447 priv->separator = NULL;
450 priv->separator = g_strdup( g_value_get_string(value) );
451 hildon_caption_set_label_text( priv );
455 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
460 static void hildon_caption_get_property( GObject *object, guint param_id,
461 GValue *value, GParamSpec *pspec )
463 HildonCaptionPrivate *priv = HILDON_CAPTION_GET_PRIVATE(object);
468 g_value_set_string( value, priv->text );
471 g_value_set_object( value, priv->icon );
474 g_value_set_enum( value, priv->status );
476 case PROP_SIZE_GROUP:
477 g_value_set_object( value, priv->group );
480 g_value_set_string( value, priv->separator );
483 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
488 static void hildon_caption_set_child_property( GtkContainer *container,
496 case CHILD_PROP_EXPAND:
497 hildon_caption_set_child_expand( HILDON_CAPTION(container),
498 g_value_get_boolean(value) );
502 G_OBJECT_WARN_INVALID_PROPERTY_ID(container, property_id, pspec);
507 static void hildon_caption_get_child_property( GtkContainer *container,
515 case CHILD_PROP_EXPAND:
516 g_value_set_boolean( value, hildon_caption_get_child_expand(
517 HILDON_CAPTION(container)) );
521 G_OBJECT_WARN_INVALID_PROPERTY_ID(container, property_id, pspec);
526 /* We want to activate out child control on button press */
527 static gboolean hildon_caption_button_press( GtkWidget *widget,
528 GdkEventButton *event )
530 HildonCaptionPrivate *priv = HILDON_CAPTION_GET_PRIVATE(widget);
531 GtkWidget *child = GTK_BIN(widget)->child;
533 /* If child can take focus, we simply grab focus to it */
534 if ((GTK_WIDGET_CAN_FOCUS(child) || GTK_IS_CONTAINER(child)) &&
535 GTK_WIDGET_IS_SENSITIVE(child))
537 priv->is_focused = TRUE;
538 gtk_widget_grab_focus( GTK_BIN(widget)->child );
544 static void hildon_caption_init( HildonCaption *caption )
546 HildonCaptionPrivate *priv = NULL;
548 /* Initialize startup state */
549 priv = HILDON_CAPTION_GET_PRIVATE(caption);
550 priv->status = HILDON_CAPTION_OPTIONAL;
553 priv->is_focused = FALSE;
555 priv->separator = g_strdup(_("Ecdg_ti_caption_separator"));
557 gtk_widget_push_composite_child();
559 /* Create caption text */
560 priv->caption_area = gtk_hbox_new( FALSE, HILDON_CAPTION_SPACING );
561 priv->label = gtk_label_new( NULL );
562 priv->icon_align = gtk_alignment_new(0.5f, 0.5f, 0.0f, 0.0f);
564 /* We want to receive button presses for child widget activation */
565 gtk_event_box_set_above_child( GTK_EVENT_BOX(caption), FALSE );
566 gtk_widget_add_events( GTK_WIDGET(caption), GDK_BUTTON_PRESS_MASK );
568 /* Pack text label caption layout */
569 gtk_box_pack_end( GTK_BOX(priv->caption_area), priv->icon_align, FALSE, FALSE, 0);
570 gtk_box_pack_end( GTK_BOX(priv->caption_area), priv->label, FALSE, FALSE, 0 );
571 gtk_widget_set_parent( priv->caption_area, GTK_WIDGET(caption) );
573 gtk_widget_pop_composite_child();
575 gtk_widget_show_all( priv->caption_area );
578 static void hildon_caption_set_focus( GtkWindow *window, GtkWidget *widget,
581 HildonCaptionPrivate *priv = HILDON_CAPTION_GET_PRIVATE(caption);
583 /* Try to find caption among the ancestors of widget */
584 if (gtk_widget_is_ancestor(widget, caption))
586 priv->is_focused = TRUE;
587 gtk_widget_queue_draw( caption );
591 if( priv->is_focused == TRUE )
593 /* Caption wasn't found, so cannot focus */
594 priv->is_focused = FALSE;
595 gtk_widget_queue_draw( caption );
599 /* We need to connect/disconnect signal handlers to toplevel window
600 in which we reside. Ww want to update connected signals if our
602 static void hildon_caption_hierarchy_changed( GtkWidget *widget,
603 GtkWidget *previous_toplevel)
605 GtkWidget *current_ancestor;
606 HildonCaptionPrivate *priv;
608 priv = HILDON_CAPTION_GET_PRIVATE(widget);
610 if( GTK_WIDGET_CLASS(parent_class)->hierarchy_changed )
611 GTK_WIDGET_CLASS(parent_class)->hierarchy_changed( widget,
614 /* If we already were inside a window, remove old handler */
615 if (previous_toplevel) {
616 /* This is a compilation workaround for gcc > 3.3 since glib is buggy */
617 /* see http://bugzilla.gnome.org/show_bug.cgi?id=310175 */
621 g_signal_handlers_disconnect_by_func
622 (previous_toplevel, (gpointer) hildon_caption_set_focus, widget);
624 current_ancestor = gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW);
626 /* Install new handler for focus movement */
627 if (current_ancestor)
628 g_signal_connect( current_ancestor, "set-focus",
629 G_CALLBACK(hildon_caption_set_focus), widget );
632 static void hildon_caption_size_request( GtkWidget *widget,
633 GtkRequisition *requisition )
636 HildonCaptionPrivate *priv = NULL;
637 g_return_if_fail( HILDON_IS_CAPTION(widget) );
638 priv = HILDON_CAPTION_GET_PRIVATE(widget);
640 /* Use the same size requisition for the main box of the caption */
641 gtk_widget_size_request( priv->caption_area, &req );
643 if( GTK_WIDGET_CLASS(parent_class)->size_request )
644 GTK_WIDGET_CLASS(parent_class)->size_request( widget, requisition );
646 requisition->width += req.width + HILDON_CAPTION_SPACING * 3;
648 if( (req.height + (2 * widget->style->ythickness)) > requisition->height )
649 requisition->height = req.height + (2 * widget->style->ythickness);
652 /* We use HILDON_CAPTION_SPACING to make it look a bit nicer */
653 static void hildon_caption_size_allocate( GtkWidget *widget,
654 GtkAllocation *allocation )
656 GtkAllocation allocA;
657 GtkAllocation allocB;
659 GtkWidget *child = NULL;
660 HildonCaptionPrivate *priv = NULL;
661 g_return_if_fail( HILDON_IS_CAPTION(widget) );
662 priv = HILDON_CAPTION_GET_PRIVATE(widget);
664 /* Position the caption to its allocated location */
665 if( GTK_WIDGET_REALIZED(widget) )
666 gdk_window_move_resize (widget->window,
667 allocation->x + GTK_CONTAINER (widget)->border_width,
668 allocation->y + GTK_CONTAINER (widget)->border_width,
669 MAX (allocation->width - GTK_CONTAINER (widget)->border_width * 2, 0),
670 MAX (allocation->height - GTK_CONTAINER (widget)->border_width * 2, 0));
672 child = GTK_BIN(widget)->child;
674 widget->allocation = *allocation;
675 gtk_widget_get_child_requisition( priv->caption_area, &req );
677 allocA.height = allocB.height = allocation->height;
678 allocA.width = allocB.width = allocation->width;
679 allocA.x = allocB.x = allocB.y = allocA.y = 0;
681 /* Center the captioned widget */
682 if( allocA.width > req.width + HILDON_CAPTION_SPACING )
684 allocA.x += req.width + HILDON_CAPTION_SPACING * 2;
685 allocB.width = req.width;
688 /* Leave room for the other drawable parts of the caption control */
689 allocA.width -= req.width + HILDON_CAPTION_SPACING * 2;
691 /* Give the child at least its minimum requisition, unless it is expandable */
692 if( !priv->expand && child && GTK_WIDGET_VISIBLE(child) )
694 GtkRequisition child_req;
695 gtk_widget_get_child_requisition( child, &child_req );
696 allocA.width = MIN( allocA.width, child_req.width );
697 allocA.height = MIN( allocA.height, child_req.height );
700 /* Ensure there are no negative dimensions */
701 if( allocA.width < 0 )
703 allocB.width = req.width + allocA.width;
705 allocB.width = MAX (allocB.width, 0);
708 allocA.height = MAX (allocA.height, 0);
709 allocB.height = MAX (allocB.height, 0);
711 if (child && GTK_WIDGET_VISIBLE(child) )
712 gtk_widget_size_allocate( child, &allocA );
713 gtk_widget_size_allocate( priv->caption_area, &allocB );
716 static void hildon_caption_forall( GtkContainer *container,
717 gboolean include_internals,
718 GtkCallback callback, gpointer data )
720 HildonCaptionPrivate *priv = NULL;
722 g_return_if_fail( HILDON_IS_CAPTION(container) );
723 g_return_if_fail( callback != NULL );
725 priv = HILDON_CAPTION_GET_PRIVATE(container);
727 /* Execute callback for the child widgets */
728 if( GTK_CONTAINER_CLASS(parent_class)->forall )
729 GTK_CONTAINER_CLASS(parent_class)->forall( container, include_internals,
732 if( include_internals )
733 /* Execute callback for the parent box as well */
734 (*callback)( priv->caption_area, data );
739 * hildon_caption_set_sizegroup:
740 * @caption : A #HildonCaption
741 * @new_group : A #GtkSizeGroup
743 * Sets a #GtkSizeGroup of a given captioned control.
745 * Deprecated: Use g_object_set, property "size_group".
747 void hildon_caption_set_sizegroup( const HildonCaption *self,
748 GtkSizeGroup *group )
750 g_object_set( G_OBJECT(self), "size_group", group, NULL );
754 * hildon_caption_get_sizegroup:
755 * @caption : A #HildonCaption
756 * @Returns : A #GtkSizeGroup
758 * Query given captioned control for the #GtkSizeGroup assigned to it.
760 * Deprecated: Use g_object_get, property "size_group".
762 GtkSizeGroup *hildon_caption_get_sizegroup( const HildonCaption *self )
764 HildonCaptionPrivate *priv;
765 g_return_val_if_fail( HILDON_IS_CAPTION (self), NULL );
766 priv = HILDON_CAPTION_GET_PRIVATE(self);
771 * hildon_caption_new:
772 * @group : a #GtkSizeGroup for controlling the size of related captions.
774 * @value : the caption text to accompany the text entry. The widget makes
775 * a copy of this text.
776 * @control : the control that is to be captioned
777 * @icon : an icon to accompany the label - can be NULL in which case no
779 * @flag : indicates whether this captioned control is mandatory or
781 * @returns : A #GtkWidget pointer of Caption
783 * Creates a new instance of hildon_caption widget, with a specific
785 * Note: Clicking on a focused caption will trigger the activate signal.
786 * The default behaviour for the caption's activate signal is to call
787 * gtk_widget_activate on it's control.
789 GtkWidget *hildon_caption_new( GtkSizeGroup *group, const gchar *value,
790 GtkWidget *control, GtkWidget *icon,
791 HildonCaptionStatus flag)
794 g_return_val_if_fail( GTK_IS_WIDGET(control), NULL );
796 widget = g_object_new( HILDON_TYPE_CAPTION, "label", value,
797 "size_group", group, "icon", icon, "status", flag,
800 /* Pack the captioned widget */
801 hildon_caption_set_child_expand( HILDON_CAPTION(widget), TRUE );
802 gtk_container_add( GTK_CONTAINER(widget), control );
809 * hildon_caption_is_mandatory:
810 * @caption : A #HildonCaption
811 * @returns : is this captioned control a mandatory one?
813 * Query #HildonCaption whether this captioned control is a mandatory one.
817 gboolean hildon_caption_is_mandatory( const HildonCaption *caption )
819 HildonCaptionPrivate *priv;
820 g_return_val_if_fail( HILDON_IS_CAPTION(caption), FALSE );
821 priv = HILDON_CAPTION_GET_PRIVATE(caption);
823 return priv->status == HILDON_CAPTION_MANDATORY;
827 * hildon_caption_set_status:
828 * @caption : A #HildonCaption
829 * @flag : one of the values from #HildonCaptionStatus
831 * Sets #HildonCaption status.
836 void hildon_caption_set_status( HildonCaption *caption,
837 HildonCaptionStatus flag )
839 g_return_if_fail( HILDON_IS_CAPTION(caption) );
841 g_object_set( G_OBJECT(caption), "status", flag, NULL );
845 * hildon_caption_get_status:
846 * @caption : A #HildonCaption
847 * @returns : one of the values from #HildonCaptionStatus
849 * Gets #HildonCaption status.
853 HildonCaptionStatus hildon_caption_get_status( const HildonCaption *caption )
855 HildonCaptionPrivate *priv;
856 g_return_val_if_fail( HILDON_IS_CAPTION(caption), HILDON_CAPTION_OPTIONAL );
857 priv = HILDON_CAPTION_GET_PRIVATE(caption);
863 * hildon_caption_set_icon_image:
864 * @caption : A #HildonCaption
865 * @icon : the #GtkImage to use as the icon.
866 * calls gtk_widget_show on the icon if !GTK_WIDGET_VISIBLE(icon)
868 * Sets the icon to be used by this hildon_caption widget.
872 void hildon_caption_set_icon_image( HildonCaption *caption, GtkWidget *icon )
874 g_return_if_fail( HILDON_IS_CAPTION(caption) );
876 g_object_set( G_OBJECT(caption), "icon", icon, NULL );
880 * hildon_caption_get_icon_image:
881 * @caption : A #HildonCaption
882 * @returns : the #GtkImage that is being used as the icon by the
883 * hildon_caption, or NULL if no icon is in use.
885 * Gets icon of #HildonCaption
889 GtkWidget *hildon_caption_get_icon_image( const HildonCaption *caption )
891 HildonCaptionPrivate *priv;
892 g_return_val_if_fail( HILDON_IS_CAPTION(caption), NULL );
893 priv = HILDON_CAPTION_GET_PRIVATE(caption);
899 * hildon_caption_set_label:
900 * @caption : A #HildonCaption
901 * @label : the text to use
903 * Sets the label text that appears before the control.
904 * Separator character is added to the end of the label string. By default
905 * the separator is ":".
909 void hildon_caption_set_label( HildonCaption *caption, const gchar *label )
911 g_return_if_fail( HILDON_IS_CAPTION(caption) );
913 g_object_set( G_OBJECT(caption), "label", label, NULL );
917 * hildon_caption_get_label:
918 * @caption : A #HildonCaption
919 * @returns : the text currently being used as the label of the caption
920 * control. The string is owned by the label and the caller should never free or
923 * Gets label of #HildonCaption
927 gchar *hildon_caption_get_label( const HildonCaption *caption )
929 HildonCaptionPrivate *priv;
930 g_return_val_if_fail(HILDON_IS_CAPTION(caption), "");
931 priv = HILDON_CAPTION_GET_PRIVATE(caption);
933 return (gchar*)gtk_label_get_text(GTK_LABEL(GTK_LABEL(priv->label)));
937 * hildon_caption_set_separator:
938 * @caption : A #HildonCaption
939 * @separator : the separator to use
941 * Sets the separator character that appears after the label.
942 * The default seaparator character is ":"
948 void hildon_caption_set_separator( HildonCaption *caption,
949 const gchar *separator )
951 g_return_if_fail( HILDON_IS_CAPTION(caption) );
953 g_object_set( G_OBJECT(caption), "separator", separator, NULL );
957 * hildon_caption_get_separator:
958 * @caption : A #HildonCaption
959 * @returns : the text currently being used as the separator of the caption
960 * control. The string is owned by the caption control and the caller should
961 * never free or modify this value.
963 * Gets separator string of #HildonCaption
967 gchar *hildon_caption_get_separator( const HildonCaption *caption )
969 HildonCaptionPrivate *priv;
970 g_return_val_if_fail(HILDON_IS_CAPTION(caption), "");
971 priv = HILDON_CAPTION_GET_PRIVATE(caption);
973 return priv->separator;
978 * hildon_caption_get_control:
979 * @caption : A #HildonCaption
980 * @returns : A #GtkWidget
982 * Gets caption's control.
984 * Deprecated: use gtk_bin_get_child instead
986 GtkWidget *hildon_caption_get_control( const HildonCaption *caption )
988 g_return_val_if_fail( HILDON_IS_CAPTION(caption), NULL );
989 return GTK_BIN(caption)->child;
992 /*activates the child control
993 *We have this signal so that if needed an application can
994 *know when we've been activated (useful for captions with
997 /* FIXME: There never are multiple children. Possibly activate
998 signal could be removed entirely? (does anyone use it?) */
999 static void hildon_caption_activate( GtkWidget *widget )
1001 HildonCaptionPrivate *priv;
1002 GtkWidget *child = GTK_BIN(widget)->child;
1003 priv = HILDON_CAPTION_GET_PRIVATE(widget);
1005 gtk_widget_grab_focus( child );
1009 * hildon_caption_set_child_expand:
1010 * @caption : A #HildonCaption
1011 * @expand : gboolean to determine is the child expandable
1013 * Sets child expandability.
1015 void hildon_caption_set_child_expand( HildonCaption *caption, gboolean expand )
1017 HildonCaptionPrivate *priv = NULL;
1018 GtkWidget *child = NULL;
1019 g_return_if_fail( HILDON_IS_CAPTION(caption) );
1021 priv = HILDON_CAPTION_GET_PRIVATE(caption);
1023 /* Did the setting really change? */
1024 if( priv->expand == expand )
1027 priv->expand = expand;
1028 child = GTK_BIN(caption)->child;
1030 /* We do not have a child, nothing to do */
1031 if( !GTK_IS_WIDGET(child) )
1034 if( GTK_WIDGET_VISIBLE (child) && GTK_WIDGET_VISIBLE (caption) )
1035 gtk_widget_queue_resize( child );
1037 gtk_widget_child_notify( child, "expand" );
1041 * hildon_caption_get_child_expand:
1042 * @caption : A #HildonCaption
1043 * @returns : Wheter the child is expandable or not.
1045 * Gets childs expandability.
1047 gboolean hildon_caption_get_child_expand( const HildonCaption *caption )
1049 HildonCaptionPrivate *priv = NULL;
1050 g_return_val_if_fail( HILDON_IS_CAPTION(caption), FALSE );
1051 priv = HILDON_CAPTION_GET_PRIVATE(caption);
1052 return priv->expand;
1056 * hildon_caption_set_control:
1057 * @caption : A #HildonCaption
1058 * @control : The control to use. Control should not be NULL.
1060 * Sets the control of the caption.
1061 * The old control will be destroyed, unless the caller has added a
1063 * Function unparents the old control (if there is one) and adds the new
1066 * Deprecated: Use gtk_container_add.
1068 void hildon_caption_set_control( HildonCaption *caption, GtkWidget *control )
1070 GtkWidget *child = NULL;
1071 g_return_if_fail( HILDON_IS_CAPTION(caption) );
1072 child = GTK_BIN(caption)->child;
1075 gtk_container_remove( GTK_CONTAINER(caption), child );
1079 gtk_container_add( GTK_CONTAINER(caption), control );
1087 hildon_caption_set_label_text( HildonCaptionPrivate *priv )
1090 g_assert ( priv != NULL );
1094 if( priv->separator )
1096 /* Don't duplicate the separator, if the string already contains one */
1097 if (g_str_has_suffix(priv->text, priv->separator))
1099 gtk_label_set_text( GTK_LABEL( priv->label ), priv->text );
1103 /* Append separator and set text */
1104 tmp = g_strconcat( priv->text, priv->separator, NULL );
1105 gtk_label_set_text( GTK_LABEL( priv->label ), tmp );
1111 gtk_label_set_text( GTK_LABEL( priv->label ), priv->text );
1116 /* Clear the label */
1117 gtk_label_set_text( GTK_LABEL( priv->label ), "" );
1123 * hildon_caption_set_label_alignment:
1124 * @caption: a #HildonCaption widget.
1125 * @alignment: new vertical alignment.
1127 * Sets the vertical alignment to be used for the
1128 * text part of the caption. Applications need to
1129 * align the child control themselves.
1131 void hildon_caption_set_label_alignment(HildonCaption *caption,
1134 HildonCaptionPrivate *priv;
1136 g_return_if_fail(HILDON_IS_CAPTION(caption));
1138 priv = HILDON_CAPTION_GET_PRIVATE(caption);
1139 g_object_set(priv->label, "yalign", alignment, NULL);
1140 g_object_set(priv->icon_align, "yalign", alignment, NULL);
1142 if (priv->mandatory_icon)
1143 g_object_set(priv->mandatory_icon, "yalign", alignment, NULL);
1147 * hildon_caption_get_label_alignment:
1148 * @caption: a #HildonCaption widget.
1150 * Gets current vertical alignment for the text part.
1152 * Returns: vertical alignment.
1154 gfloat hildon_caption_get_label_alignment(HildonCaption *caption)
1156 HildonCaptionPrivate *priv;
1159 g_return_val_if_fail( HILDON_IS_CAPTION(caption), 0);
1160 priv = HILDON_CAPTION_GET_PRIVATE(caption);
1161 g_object_get(priv->label, "yalign", &result, NULL);