2 * This file is part of hildon-libs
4 * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
6 * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@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; version 2.1 of
11 * the License or 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_SPACING 6
59 #define HILDON_CAPTION_GET_PRIVATE(obj) \
60 (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
61 HILDON_TYPE_CAPTION, HildonCaptionPrivate));
64 static GtkEventBox *parent_class = NULL;
66 typedef struct _HildonCaptionPrivate HildonCaptionPrivate;
84 static void hildon_caption_class_init ( HildonCaptionClass *caption_class );
85 static void hildon_caption_init ( HildonCaption *caption );
86 static void hildon_caption_size_request ( GtkWidget *widget, GtkRequisition *requisition );
87 static void hildon_caption_size_allocate( GtkWidget *widget, GtkAllocation *allocation );
89 static void hildon_caption_forall( GtkContainer *container,
90 gboolean include_internals,
91 GtkCallback callback, gpointer data );
92 static void hildon_caption_hierarchy_changed( GtkWidget *widget,
93 GtkWidget *previous_toplevel);
94 static void hildon_caption_set_focus( GtkWindow *window, GtkWidget *widget,
96 static void hildon_caption_activate( GtkWidget *widget );
98 static void hildon_caption_set_property( GObject *object, guint param_id,
99 const GValue *value, GParamSpec *pspec );
100 static void hildon_caption_get_property( GObject *object, guint param_id,
101 GValue *value, GParamSpec *pspec );
102 static gboolean hildon_caption_expose( GtkWidget *widget,
103 GdkEventExpose *event );
104 static void hildon_caption_destroy( GtkObject *self );
105 static gboolean hildon_caption_button_press( GtkWidget *widget, GdkEventButton *event );
108 hildon_caption_set_label_text( HildonCaptionPrivate *priv );
110 static void hildon_caption_set_child_property (GtkContainer *container,
115 static void hildon_caption_get_child_property (GtkContainer *container,
121 struct _HildonCaptionPrivate
123 GtkWidget *caption_area;
126 GtkWidget *icon_align; /* Arbitrary icon widgets do not support alignment */
130 guint is_focused : 1;
132 HildonCaptionStatus status;
135 /* Register optional/mandatory type enumeration */
136 /* FIXME: mandatory icon was removed. The mandatory/optional logic
137 remains, it should most probably be removed as well. This imply APi
138 change, especially hildon_caption_new() */
140 hildon_caption_status_get_type (void)
142 static GType etype = 0;
144 static const GEnumValue values[] = {
145 { HILDON_CAPTION_OPTIONAL, "HILDON_CAPTION_OPTIONAL", "optional" },
146 { HILDON_CAPTION_MANDATORY, "HILDON_CAPTION_MANDATORY", "mandatory" },
149 etype = g_enum_register_static ("HildonCaptionStatus", values);
155 * hildon_caption_get_type:
157 * Initialises, and returns the type of a hildon caption.
159 * @Returns: GType of #HildonCaption
161 GType hildon_caption_get_type (void)
163 static GType caption_type = 0;
167 static const GTypeInfo caption_info = {
168 sizeof(HildonCaptionClass),
169 NULL, /* base_init */
170 NULL, /* base_finalize */
171 (GClassInitFunc) hildon_caption_class_init,
172 NULL, /* class_finalize */
173 NULL, /* class_data */
174 sizeof(HildonCaption),
176 (GInstanceInitFunc) hildon_caption_init,
178 caption_type = g_type_register_static( GTK_TYPE_EVENT_BOX,
179 "HildonCaption", &caption_info, 0 );
185 * Initialises the caption class.
187 static void hildon_caption_class_init( HildonCaptionClass *caption_class )
189 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(caption_class);
190 GObjectClass *gobject_class = G_OBJECT_CLASS(caption_class);
191 GtkContainerClass *container_class = GTK_CONTAINER_CLASS(caption_class);
193 parent_class = g_type_class_peek_parent( caption_class );
195 g_type_class_add_private( caption_class, sizeof(HildonCaptionPrivate) );
197 /* Override virtual functions */
198 gobject_class->get_property = hildon_caption_get_property;
199 gobject_class->set_property = hildon_caption_set_property;
201 caption_class->activate = hildon_caption_activate;
203 GTK_OBJECT_CLASS(caption_class)->destroy = hildon_caption_destroy;
205 container_class->forall = hildon_caption_forall;
206 container_class->set_child_property = hildon_caption_set_child_property;
207 container_class->get_child_property = hildon_caption_get_child_property;
209 widget_class->expose_event = hildon_caption_expose;
210 widget_class->hierarchy_changed = hildon_caption_hierarchy_changed;
211 widget_class->size_request = hildon_caption_size_request;
212 widget_class->size_allocate = hildon_caption_size_allocate;
213 widget_class->button_press_event = hildon_caption_button_press;
215 /* Create new signals and properties */
216 widget_class->activate_signal = g_signal_new( "activate",
221 G_STRUCT_OFFSET( HildonCaptionClass,
222 activate), NULL, NULL,
223 gtk_marshal_VOID__VOID,
227 * HildonCaption:label:
231 g_object_class_install_property( gobject_class, PROP_LABEL,
232 g_param_spec_string("label",
233 "Current label", "Caption label",
234 NULL, G_PARAM_READABLE | G_PARAM_WRITABLE) );
237 * HildonCaption:icon:
239 * The icon shown on the caption area.
241 g_object_class_install_property( gobject_class, PROP_ICON,
242 g_param_spec_object("icon",
244 "The icon shown on the caption area",
245 GTK_TYPE_WIDGET, G_PARAM_READABLE |
248 * HildonCaption:status:
250 * Mandatory or optional status.
252 g_object_class_install_property( gobject_class, PROP_STATUS,
253 g_param_spec_enum("status",
255 "Mandatory or optional status",
256 HILDON_TYPE_CAPTION_STATUS,
257 HILDON_CAPTION_OPTIONAL,
258 G_PARAM_READABLE | G_PARAM_WRITABLE) );
260 * HildonCaption:size_group:
262 * Current size group the caption is in.
264 g_object_class_install_property( gobject_class, PROP_SIZE_GROUP,
265 g_param_spec_object("size_group",
266 "Current size group",
267 "Current size group the caption is in",
268 GTK_TYPE_SIZE_GROUP, G_PARAM_READABLE |
272 * HildonCaption:separator:
274 * The current separator.
276 g_object_class_install_property( gobject_class, PROP_SEPARATOR,
277 g_param_spec_string("separator",
278 "Current separator", "Current separator",
279 _("ecdg_ti_caption_separator"),
280 G_PARAM_READABLE | G_PARAM_WRITABLE) );
282 /* Create child properties. These are related to
283 child <-> parent relationship, not to either of objects itself */
284 gtk_container_class_install_child_property (container_class,
286 g_param_spec_boolean ("expand",
287 "Same as GtkBox expand.",
288 "Same as GtkBox expand. Wheter the child should be expanded or not.",
293 /* Destroy can be called multiple times, remember to set pointers to NULL */
294 static void hildon_caption_destroy( GtkObject *self )
296 HildonCaptionPrivate *priv = HILDON_CAPTION_GET_PRIVATE(self);
298 /* Free our internal child */
299 if( priv->caption_area )
301 gtk_widget_unparent( priv->caption_area );
302 priv->caption_area = NULL;
305 /* Free user provided strings */
308 g_free( priv->text );
311 if( priv->separator )
313 g_free( priv->separator );
314 priv->separator = NULL;
317 /* Parent classes destroy takes care of user packed contents */
318 if( GTK_OBJECT_CLASS(parent_class)->destroy )
319 GTK_OBJECT_CLASS(parent_class)->destroy( self );
322 /* Parent, eventbox will run allocate also for the child which may be
323 * owning a window too. This window is then moved and resized
324 * and we do not want to do that (it causes flickering).
326 static gboolean hildon_caption_expose( GtkWidget *widget,
327 GdkEventExpose *event )
329 HildonCaptionPrivate *priv = NULL;
334 g_assert( HILDON_IS_CAPTION(widget) );
335 priv = HILDON_CAPTION_GET_PRIVATE(widget);
337 if( !GTK_WIDGET_DRAWABLE(widget) )
340 GTK_WIDGET_CLASS(parent_class)->expose_event( widget, event );
342 /* If our child control is focused, we draw nice looking focus
343 graphics for the caption */
344 if ( priv->is_focused )
346 /* Determine focus box dimensions */
347 gtk_widget_get_child_requisition( priv->caption_area, &req );
348 align = hildon_caption_get_label_alignment(HILDON_CAPTION(widget));
350 alloc.width = priv->caption_area->allocation.width + HILDON_CAPTION_SPACING;
351 alloc.height = MIN (req.height + (2 * widget->style->ythickness), priv->caption_area->allocation.height);
353 alloc.x = priv->caption_area->allocation.x - HILDON_CAPTION_SPACING; /* - left margin */
354 alloc.y = priv->caption_area->allocation.y +
355 MAX(((priv->caption_area->allocation.height - alloc.height) * align), 0);
357 /* Paint the focus box */
358 gtk_paint_box( widget->style, widget->window, GTK_STATE_ACTIVE,
359 GTK_SHADOW_OUT, NULL, widget, "selection",
360 alloc.x, alloc.y, alloc.width, alloc.height );
362 /* Paint caption contents on top of the focus box */
363 GTK_WIDGET_GET_CLASS(priv->caption_area)->expose_event(
364 priv->caption_area, event);
370 static void hildon_caption_set_property( GObject *object, guint param_id,
374 HildonCaptionPrivate *priv = HILDON_CAPTION_GET_PRIVATE(object);
379 /* Free old label string */
382 g_free( priv->text );
387 priv->text = g_strdup( g_value_get_string(value) );
388 hildon_caption_set_label_text( priv );
392 /* Remove old icon */
394 gtk_container_remove( GTK_CONTAINER(priv->icon_align), priv->icon );
396 /* Pack and display new icon */
397 priv->icon = g_value_get_object( value );
400 gtk_container_add(GTK_CONTAINER(priv->icon_align), priv->icon);
401 gtk_widget_show_all( priv->caption_area );
406 priv->status = g_value_get_enum( value );
409 case PROP_SIZE_GROUP:
410 /* Detach from previous size group */
412 gtk_size_group_remove_widget( priv->group, priv->caption_area );
414 priv->group = g_value_get_object( value );
416 /* Attach to new size group */
418 gtk_size_group_add_widget( priv->group, priv->caption_area );
419 gtk_widget_queue_draw( GTK_WIDGET(object) );
424 /* Free old separator */
425 if( priv->separator )
427 g_free( priv->separator );
428 priv->separator = NULL;
431 priv->separator = g_strdup( g_value_get_string(value) );
432 hildon_caption_set_label_text( priv );
436 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
441 static void hildon_caption_get_property( GObject *object, guint param_id,
442 GValue *value, GParamSpec *pspec )
444 HildonCaptionPrivate *priv = HILDON_CAPTION_GET_PRIVATE(object);
449 g_value_set_string( value, priv->text );
452 g_value_set_object( value, priv->icon );
455 g_value_set_enum( value, priv->status );
457 case PROP_SIZE_GROUP:
458 g_value_set_object( value, priv->group );
461 g_value_set_string( value, priv->separator );
464 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
469 static void hildon_caption_set_child_property( GtkContainer *container,
477 case CHILD_PROP_EXPAND:
478 hildon_caption_set_child_expand( HILDON_CAPTION(container),
479 g_value_get_boolean(value) );
483 G_OBJECT_WARN_INVALID_PROPERTY_ID(container, property_id, pspec);
488 static void hildon_caption_get_child_property( GtkContainer *container,
496 case CHILD_PROP_EXPAND:
497 g_value_set_boolean( value, hildon_caption_get_child_expand(
498 HILDON_CAPTION(container)) );
502 G_OBJECT_WARN_INVALID_PROPERTY_ID(container, property_id, pspec);
507 /* We want to activate out child control on button press */
508 static gboolean hildon_caption_button_press( GtkWidget *widget,
509 GdkEventButton *event )
511 HildonCaptionPrivate *priv = HILDON_CAPTION_GET_PRIVATE(widget);
512 GtkWidget *child = GTK_BIN(widget)->child;
515 if (priv->is_focused == TRUE)
518 /* If child can take focus, we simply grab focus to it */
519 if ((GTK_WIDGET_CAN_FOCUS(child) || GTK_IS_CONTAINER(child)) &&
520 GTK_WIDGET_IS_SENSITIVE(child))
522 /* Only if container can be focusable we must set is_focused to TRUE */
523 if (GTK_IS_CONTAINER(child))
525 if (gtk_widget_child_focus (child,
526 GTK_DIR_TAB_FORWARD))
527 priv->is_focused = TRUE;
531 priv->is_focused = TRUE;
532 gtk_widget_grab_focus (GTK_BIN (widget)->child);
539 static void hildon_caption_init( HildonCaption *caption )
541 HildonCaptionPrivate *priv = NULL;
543 /* Initialize startup state */
544 priv = HILDON_CAPTION_GET_PRIVATE(caption);
545 priv->status = HILDON_CAPTION_OPTIONAL;
548 priv->is_focused = FALSE;
550 priv->separator = g_strdup(_("ecdg_ti_caption_separator"));
552 gtk_widget_push_composite_child();
554 /* Create caption text */
555 priv->caption_area = gtk_hbox_new( FALSE, HILDON_CAPTION_SPACING );
556 priv->label = gtk_label_new( NULL );
557 priv->icon_align = gtk_alignment_new(0.5f, 0.5f, 0.0f, 0.0f);
559 /* We want to receive button presses for child widget activation */
560 gtk_event_box_set_above_child( GTK_EVENT_BOX(caption), FALSE );
561 gtk_widget_add_events( GTK_WIDGET(caption), GDK_BUTTON_PRESS_MASK );
563 /* Pack text label caption layout */
564 gtk_box_pack_end( GTK_BOX(priv->caption_area), priv->icon_align, FALSE, FALSE, 0);
565 gtk_box_pack_end( GTK_BOX(priv->caption_area), priv->label, FALSE, FALSE, 0 );
566 gtk_widget_set_parent( priv->caption_area, GTK_WIDGET(caption) );
568 gtk_widget_pop_composite_child();
570 hildon_caption_set_child_expand( caption, TRUE );
572 gtk_widget_show_all( priv->caption_area );
575 static void hildon_caption_set_focus( GtkWindow *window, GtkWidget *widget,
578 HildonCaptionPrivate *priv = HILDON_CAPTION_GET_PRIVATE(caption);
580 /* check if ancestor gone */
586 /* Try to find caption among the ancestors of widget */
587 if (gtk_widget_is_ancestor(widget, caption))
589 priv->is_focused = TRUE;
590 gtk_widget_queue_draw( caption );
594 if( priv->is_focused == TRUE )
596 /* Caption wasn't found, so cannot focus */
597 priv->is_focused = FALSE;
598 gtk_widget_queue_draw( caption );
602 /* We need to connect/disconnect signal handlers to toplevel window
603 in which we reside. Ww want to update connected signals if our
605 static void hildon_caption_hierarchy_changed( GtkWidget *widget,
606 GtkWidget *previous_toplevel)
608 GtkWidget *current_ancestor;
609 HildonCaptionPrivate *priv;
611 priv = HILDON_CAPTION_GET_PRIVATE(widget);
613 if( GTK_WIDGET_CLASS(parent_class)->hierarchy_changed )
614 GTK_WIDGET_CLASS(parent_class)->hierarchy_changed( widget,
617 /* If we already were inside a window, remove old handler */
618 if (previous_toplevel) {
619 /* This is a compilation workaround for gcc > 3.3 since glib is buggy */
620 /* see http://bugzilla.gnome.org/show_bug.cgi?id=310175 */
624 g_signal_handlers_disconnect_by_func
625 (previous_toplevel, (gpointer) hildon_caption_set_focus, widget);
627 current_ancestor = gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW);
629 /* Install new handler for focus movement */
630 if (current_ancestor)
631 g_signal_connect( current_ancestor, "set-focus",
632 G_CALLBACK(hildon_caption_set_focus), widget );
635 static void hildon_caption_size_request( GtkWidget *widget,
636 GtkRequisition *requisition )
639 HildonCaptionPrivate *priv = NULL;
640 g_return_if_fail( HILDON_IS_CAPTION(widget) );
641 priv = HILDON_CAPTION_GET_PRIVATE(widget);
643 /* Use the same size requisition for the main box of the caption */
644 gtk_widget_size_request( priv->caption_area, &req );
646 if( GTK_WIDGET_CLASS(parent_class)->size_request )
647 GTK_WIDGET_CLASS(parent_class)->size_request( widget, requisition );
649 requisition->width += req.width + HILDON_CAPTION_SPACING * 3;
651 if( (req.height + (2 * widget->style->ythickness)) > requisition->height )
652 requisition->height = req.height + (2 * widget->style->ythickness);
655 /* We use HILDON_CAPTION_SPACING to make it look a bit nicer */
656 static void hildon_caption_size_allocate( GtkWidget *widget,
657 GtkAllocation *allocation )
659 GtkAllocation allocA;
660 GtkAllocation allocB;
662 GtkWidget *child = NULL;
663 HildonCaptionPrivate *priv = NULL;
665 g_assert( HILDON_IS_CAPTION(widget) );
666 priv = HILDON_CAPTION_GET_PRIVATE(widget);
668 /* Position the caption to its allocated location */
669 if( GTK_WIDGET_REALIZED(widget) )
670 gdk_window_move_resize (widget->window,
671 allocation->x + GTK_CONTAINER (widget)->border_width,
672 allocation->y + GTK_CONTAINER (widget)->border_width,
673 MAX (allocation->width - GTK_CONTAINER (widget)->border_width * 2, 0),
674 MAX (allocation->height - GTK_CONTAINER (widget)->border_width * 2, 0));
676 child = GTK_BIN(widget)->child;
678 widget->allocation = *allocation;
679 gtk_widget_get_child_requisition( priv->caption_area, &req );
681 allocA.height = allocB.height = allocation->height;
682 allocA.width = allocB.width = allocation->width;
683 allocA.x = allocB.x = allocB.y = allocA.y = 0;
685 /* Center the captioned widget */
686 if( allocA.width > req.width + HILDON_CAPTION_SPACING )
688 allocA.x += req.width + HILDON_CAPTION_SPACING * 2;
689 allocB.width = req.width;
692 /* Leave at least the space of the HILDON_CAPTION_SPACING in the left */
693 allocB.x = HILDON_CAPTION_SPACING;
695 /* Leave room for the other drawable parts of the caption control */
696 allocA.width -= req.width + HILDON_CAPTION_SPACING * 2;
698 /* Give the child at least its minimum requisition, unless it is expandable */
699 if( !priv->expand && child && GTK_WIDGET_VISIBLE(child) )
701 GtkRequisition child_req;
702 gtk_widget_get_child_requisition( child, &child_req );
703 allocA.width = MIN( allocA.width, child_req.width );
704 allocA.height = MIN( allocA.height, child_req.height );
707 /* Ensure there are no negative dimensions */
708 if( allocA.width < 0 )
710 allocB.width = req.width + allocA.width;
712 allocB.width = MAX (allocB.width, 0);
715 allocA.height = MAX (allocA.height, 0);
716 allocB.height = MAX (allocB.height, 0);
718 if (child && GTK_WIDGET_VISIBLE(child) )
719 gtk_widget_size_allocate( child, &allocA );
721 gtk_widget_size_allocate( priv->caption_area, &allocB );
724 static void hildon_caption_forall( GtkContainer *container,
725 gboolean include_internals,
726 GtkCallback callback, gpointer data )
728 HildonCaptionPrivate *priv = NULL;
730 g_assert( HILDON_IS_CAPTION(container) );
731 g_assert( callback != NULL );
733 priv = HILDON_CAPTION_GET_PRIVATE(container);
735 /* Execute callback for the child widgets */
736 if( GTK_CONTAINER_CLASS(parent_class)->forall )
737 GTK_CONTAINER_CLASS(parent_class)->forall( container, include_internals,
740 if( include_internals )
741 /* Execute callback for the parent box as well */
742 (*callback)( priv->caption_area, data );
747 * hildon_caption_set_sizegroup:
748 * @caption : a #HildonCaption
749 * @new_group : a #GtkSizeGroup
751 * Sets a #GtkSizeGroup of a given captioned control.
753 * Deprecated: use g_object_set, property :size-group
755 void hildon_caption_set_sizegroup( const HildonCaption *self,
756 GtkSizeGroup *group )
758 g_object_set( G_OBJECT(self), "size_group", group, NULL );
762 * hildon_caption_get_sizegroup:
763 * @caption : a #HildonCaption
765 * Query given captioned control for the #GtkSizeGroup assigned to it.
767 * @Returns : a #GtkSizeGroup
769 * Deprecated: Use g_object_get, property :size-group
771 GtkSizeGroup *hildon_caption_get_sizegroup( const HildonCaption *self )
773 HildonCaptionPrivate *priv;
774 g_return_val_if_fail( HILDON_IS_CAPTION (self), NULL );
775 priv = HILDON_CAPTION_GET_PRIVATE(self);
780 * hildon_caption_new:
781 * @group : a #GtkSizeGroup for controlling the size of related captions,
783 * @value : the caption text to accompany the text entry. The widget makes
784 * a copy of this text.
785 * @control : the control that is to be captioned
786 * @icon : an icon to accompany the label - can be NULL in which case no
788 * @flag : indicates whether this captioned control is mandatory or
791 * Creates a new instance of hildon_caption widget, with a specific
793 * Note: Clicking on a focused caption will trigger the activate signal.
794 * The default behaviour for the caption's activate signal is to call
795 * gtk_widget_activate on it's control.
797 * @Returns : a #GtkWidget pointer of Caption
799 GtkWidget *hildon_caption_new( GtkSizeGroup *group, const gchar *value,
800 GtkWidget *child, GtkWidget *icon,
801 HildonCaptionStatus flag)
804 g_return_val_if_fail( GTK_IS_WIDGET(child), NULL );
806 widget = g_object_new( HILDON_TYPE_CAPTION, "label", value,
807 "child" /* From GtkContainer */, child, "size_group", group, "icon", icon, "status", flag,
814 * hildon_caption_is_mandatory:
815 * @caption : a #HildonCaption
817 * Query #HildonCaption whether this captioned control is a mandatory one.
819 * @Returns : is this captioned control a mandatory one?
822 gboolean hildon_caption_is_mandatory( const HildonCaption *caption )
824 HildonCaptionPrivate *priv;
825 g_return_val_if_fail( HILDON_IS_CAPTION(caption), FALSE );
826 priv = HILDON_CAPTION_GET_PRIVATE(caption);
828 return priv->status == HILDON_CAPTION_MANDATORY;
832 * hildon_caption_set_status:
833 * @caption : a #HildonCaption
834 * @flag : one of the values from #HildonCaptionStatus
836 * Sets #HildonCaption status.
839 void hildon_caption_set_status( HildonCaption *caption,
840 HildonCaptionStatus flag )
842 g_return_if_fail( HILDON_IS_CAPTION(caption) );
844 g_object_set( G_OBJECT(caption), "status", flag, NULL );
848 * hildon_caption_get_status:
849 * @caption : a #HildonCaption
851 * Gets #HildonCaption status.
853 * @Returns : one of the values from #HildonCaptionStatus
856 HildonCaptionStatus hildon_caption_get_status( const HildonCaption *caption )
858 HildonCaptionPrivate *priv;
859 g_return_val_if_fail( HILDON_IS_CAPTION(caption), HILDON_CAPTION_OPTIONAL );
860 priv = HILDON_CAPTION_GET_PRIVATE(caption);
866 * hildon_caption_set_icon_image:
867 * @caption : a #HildonCaption
868 * @icon : the #GtkImage to use as the icon.
869 * calls gtk_widget_show on the icon if !GTK_WIDGET_VISIBLE(icon)
871 * Sets the icon to be used by this hildon_caption widget.
874 void hildon_caption_set_icon_image( HildonCaption *caption, GtkWidget *icon )
876 g_return_if_fail( HILDON_IS_CAPTION(caption) );
878 g_object_set( G_OBJECT(caption), "icon", icon, NULL );
882 * hildon_caption_get_icon_image:
883 * @caption : a #HildonCaption
885 * Gets icon of #HildonCaption
887 * @Returns : the #GtkImage that is being used as the icon by the
888 * hildon_caption, or NULL if no icon is in use
891 GtkWidget *hildon_caption_get_icon_image( const HildonCaption *caption )
893 HildonCaptionPrivate *priv;
894 g_return_val_if_fail( HILDON_IS_CAPTION(caption), NULL );
895 priv = HILDON_CAPTION_GET_PRIVATE(caption);
901 * hildon_caption_set_label:
902 * @caption : a #HildonCaption
903 * @label : the text to use
905 * Sets the label text that appears before the control.
906 * Separator character is added to the end of the label string. By default
907 * the separator is ":".
910 void hildon_caption_set_label( HildonCaption *caption, const gchar *label )
912 g_return_if_fail( HILDON_IS_CAPTION(caption) );
914 g_object_set( G_OBJECT(caption), "label", label, NULL );
918 * hildon_caption_get_label:
919 * @caption : a #HildonCaption
921 * Gets label of #HildonCaption
923 * @Returns : the text currently being used as the label of the caption
924 * control. The string is owned by the label and the caller should never
925 * free or modify this value.
928 gchar *hildon_caption_get_label( const HildonCaption *caption )
930 HildonCaptionPrivate *priv;
931 g_return_val_if_fail(HILDON_IS_CAPTION(caption), "");
932 priv = HILDON_CAPTION_GET_PRIVATE(caption);
934 return (gchar*)gtk_label_get_text(GTK_LABEL(GTK_LABEL(priv->label)));
938 * hildon_caption_set_separator:
939 * @caption : a #HildonCaption
940 * @separator : the separator to use
942 * Sets the separator character that appears after the label.
943 * The default seaparator character is ":"
947 void hildon_caption_set_separator( HildonCaption *caption,
948 const gchar *separator )
950 g_return_if_fail( HILDON_IS_CAPTION(caption) );
952 g_object_set( G_OBJECT(caption), "separator", separator, NULL );
956 * hildon_caption_get_separator:
957 * @caption : a #HildonCaption
959 * Gets separator string of #HildonCaption
961 * @Returns : the text currently being used as the separator of the caption
962 * control. The string is owned by the caption control and the caller should
963 * never free or modify this value.
966 gchar *hildon_caption_get_separator( const HildonCaption *caption )
968 HildonCaptionPrivate *priv;
969 g_return_val_if_fail(HILDON_IS_CAPTION(caption), "");
970 priv = HILDON_CAPTION_GET_PRIVATE(caption);
972 return priv->separator;
977 * hildon_caption_get_control:
978 * @caption : a #HildonCaption
980 * Gets caption's control.
982 * @Returns : a #GtkWidget
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
1044 * Gets childs expandability.
1046 * @Returns : wheter the child is expandable or not.
1048 gboolean hildon_caption_get_child_expand( const HildonCaption *caption )
1050 HildonCaptionPrivate *priv = NULL;
1051 g_return_val_if_fail( HILDON_IS_CAPTION(caption), FALSE );
1052 priv = HILDON_CAPTION_GET_PRIVATE(caption);
1053 return priv->expand;
1057 * hildon_caption_set_control:
1058 * @caption : a #HildonCaption
1059 * @control : the control to use. Control should not be NULL.
1061 * Sets the control of the caption.
1062 * The old control will be destroyed, unless the caller has added a
1064 * Function unparents the old control (if there is one) and adds the new
1067 * Deprecated: use gtk_container_add
1069 void hildon_caption_set_control( HildonCaption *caption, GtkWidget *control )
1071 GtkWidget *child = NULL;
1072 g_return_if_fail( HILDON_IS_CAPTION(caption) );
1073 child = GTK_BIN(caption)->child;
1076 gtk_container_remove( GTK_CONTAINER(caption), child );
1080 gtk_container_add( GTK_CONTAINER(caption), control );
1088 hildon_caption_set_label_text( HildonCaptionPrivate *priv )
1091 g_assert ( priv != NULL );
1095 if( priv->separator )
1097 /* Don't duplicate the separator, if the string already contains one */
1098 if (g_str_has_suffix(priv->text, priv->separator))
1100 gtk_label_set_text( GTK_LABEL( priv->label ), priv->text );
1104 /* Append separator and set text */
1105 tmp = g_strconcat( priv->text, priv->separator, NULL );
1106 gtk_label_set_text( GTK_LABEL( priv->label ), tmp );
1112 gtk_label_set_text( GTK_LABEL( priv->label ), priv->text );
1117 /* Clear the label */
1118 gtk_label_set_text( GTK_LABEL( priv->label ), "" );
1124 * hildon_caption_set_label_alignment:
1125 * @caption: a #HildonCaption widget
1126 * @alignment: new vertical alignment
1128 * Sets the vertical alignment to be used for the
1129 * text part of the caption. Applications need to
1130 * align the child control themselves.
1134 void hildon_caption_set_label_alignment(HildonCaption *caption,
1137 HildonCaptionPrivate *priv;
1139 g_return_if_fail(HILDON_IS_CAPTION(caption));
1141 priv = HILDON_CAPTION_GET_PRIVATE(caption);
1142 g_object_set(priv->label, "yalign", alignment, NULL);
1143 g_object_set(priv->icon_align, "yalign", alignment, NULL);
1148 * hildon_caption_get_label_alignment:
1149 * @caption: a #HildonCaption widget
1151 * Gets current vertical alignment for the text part.
1153 * Returns: vertical alignment
1157 gfloat hildon_caption_get_label_alignment(HildonCaption *caption)
1159 HildonCaptionPrivate *priv;
1162 g_return_val_if_fail( HILDON_IS_CAPTION(caption), 0);
1163 priv = HILDON_CAPTION_GET_PRIVATE(caption);
1164 g_object_get(priv->label, "yalign", &result, NULL);