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
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.
37 #include "hildon-caption.h"
38 #include <gtk/gtkhbox.h>
39 #include <gtk/gtklabel.h>
40 #include <gtk/gtkimage.h>
41 #include <gtk/gtkentry.h>
42 #include <gtk/gtkcombo.h>
43 #include <gtk/gtkcombobox.h>
44 #include <gtk/gtkcomboboxentry.h>
45 #include <gtk/gtkoptionmenu.h>
46 #include <gtk/gtkmarshal.h>
47 #include <gtk/gtkalignment.h>
50 #include "hildon-defines.h"
53 #define _(String) dgettext(PACKAGE, String)
55 #define HILDON_CAPTION_SPACING 6
57 #define HILDON_CAPTION_GET_PRIVATE(obj) \
58 (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
59 HILDON_TYPE_CAPTION, HildonCaptionPrivate));
62 static GtkEventBox *parent_class = NULL;
64 typedef struct _HildonCaptionPrivate HildonCaptionPrivate;
83 static void hildon_caption_class_init ( HildonCaptionClass *caption_class );
84 static void hildon_caption_init ( HildonCaption *caption );
85 static void hildon_caption_size_request ( GtkWidget *widget, GtkRequisition *requisition );
86 static void hildon_caption_size_allocate( GtkWidget *widget, GtkAllocation *allocation );
88 static void hildon_caption_forall( GtkContainer *container,
89 gboolean include_internals,
90 GtkCallback callback, gpointer data );
91 static void hildon_caption_hierarchy_changed( GtkWidget *widget,
92 GtkWidget *previous_toplevel);
93 static void hildon_caption_set_focus( GtkWindow *window, GtkWidget *widget,
95 static void hildon_caption_activate( GtkWidget *widget );
97 static void hildon_caption_set_property( GObject *object, guint param_id,
98 const GValue *value, GParamSpec *pspec );
99 static void hildon_caption_get_property( GObject *object, guint param_id,
100 GValue *value, GParamSpec *pspec );
101 static gboolean hildon_caption_expose( GtkWidget *widget,
102 GdkEventExpose *event );
103 static void hildon_caption_destroy( GtkObject *self );
104 static gboolean hildon_caption_button_press( GtkWidget *widget, GdkEventButton *event );
107 hildon_caption_set_label_text( HildonCaptionPrivate *priv );
109 static void hildon_caption_set_child_property (GtkContainer *container,
114 static void hildon_caption_get_child_property (GtkContainer *container,
120 struct _HildonCaptionPrivate
122 GtkWidget *caption_area;
125 GtkWidget *icon_align; /* Arbitrary icon widgets do not support alignment */
129 guint is_focused : 1;
131 HildonCaptionStatus status;
132 HildonCaptionIconPosition icon_position;
136 * hildon_caption_get_type:
138 * Initialises, and returns the type of a hildon caption.
140 * @Returns: GType of #HildonCaption
142 GType hildon_caption_get_type (void)
144 static GType caption_type = 0;
148 static const GTypeInfo caption_info = {
149 sizeof(HildonCaptionClass),
150 NULL, /* base_init */
151 NULL, /* base_finalize */
152 (GClassInitFunc) hildon_caption_class_init,
153 NULL, /* class_finalize */
154 NULL, /* class_data */
155 sizeof(HildonCaption),
157 (GInstanceInitFunc) hildon_caption_init,
159 caption_type = g_type_register_static( GTK_TYPE_EVENT_BOX,
160 "HildonCaption", &caption_info, 0 );
166 * Initialises the caption class.
168 static void hildon_caption_class_init( HildonCaptionClass *caption_class )
170 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(caption_class);
171 GObjectClass *gobject_class = G_OBJECT_CLASS(caption_class);
172 GtkContainerClass *container_class = GTK_CONTAINER_CLASS(caption_class);
174 parent_class = g_type_class_peek_parent( caption_class );
176 g_type_class_add_private( caption_class, sizeof(HildonCaptionPrivate) );
178 /* Override virtual functions */
179 gobject_class->get_property = hildon_caption_get_property;
180 gobject_class->set_property = hildon_caption_set_property;
182 caption_class->activate = (gpointer) hildon_caption_activate;
184 GTK_OBJECT_CLASS(caption_class)->destroy = hildon_caption_destroy;
186 container_class->forall = hildon_caption_forall;
187 container_class->set_child_property = hildon_caption_set_child_property;
188 container_class->get_child_property = hildon_caption_get_child_property;
190 widget_class->expose_event = hildon_caption_expose;
191 widget_class->hierarchy_changed = hildon_caption_hierarchy_changed;
192 widget_class->size_request = hildon_caption_size_request;
193 widget_class->size_allocate = hildon_caption_size_allocate;
194 widget_class->button_press_event = hildon_caption_button_press;
196 /* Create new signals and properties */
197 widget_class->activate_signal = g_signal_new( "activate",
202 G_STRUCT_OFFSET( HildonCaptionClass,
203 activate), NULL, NULL,
204 gtk_marshal_VOID__VOID,
208 * HildonCaption:label:
212 g_object_class_install_property( gobject_class, PROP_LABEL,
213 g_param_spec_string("label",
214 "Current label", "Caption label",
215 NULL, G_PARAM_READABLE | G_PARAM_WRITABLE) );
218 * HildonCaption:icon:
220 * The icon shown on the caption area.
222 g_object_class_install_property( gobject_class, PROP_ICON,
223 g_param_spec_object("icon",
225 "The icon shown on the caption area",
226 GTK_TYPE_WIDGET, G_PARAM_READABLE |
229 * HildonCaption:status:
231 * Mandatory or optional status.
233 g_object_class_install_property( gobject_class, PROP_STATUS,
234 g_param_spec_enum("status",
236 "Mandatory or optional status",
237 HILDON_TYPE_CAPTION_STATUS,
238 HILDON_CAPTION_OPTIONAL,
239 G_PARAM_READABLE | G_PARAM_WRITABLE) );
241 * HildonCaption:icon-position:
243 * If the icon is positioned on the left or right side.
247 g_object_class_install_property( gobject_class, PROP_ICON_POSITION,
248 g_param_spec_enum("icon-position",
250 "If the icon is on the left or right side",
251 HILDON_TYPE_CAPTION_ICON_POSITION,
252 HILDON_CAPTION_POSITION_RIGHT,
253 G_PARAM_READABLE | G_PARAM_WRITABLE) );
256 * HildonCaption:size_group:
258 * Current size group the caption is in.
260 g_object_class_install_property( gobject_class, PROP_SIZE_GROUP,
261 g_param_spec_object("size_group",
262 "Current size group",
263 "Current size group the caption is in",
264 GTK_TYPE_SIZE_GROUP, G_PARAM_READABLE |
268 * HildonCaption:separator:
270 * The current separator.
272 g_object_class_install_property( gobject_class, PROP_SEPARATOR,
273 g_param_spec_string("separator",
274 "Current separator", "Current separator",
275 _("ecdg_ti_caption_separator"),
276 G_PARAM_READABLE | G_PARAM_WRITABLE) );
278 /* Create child properties. These are related to
279 child <-> parent relationship, not to either of objects itself */
280 gtk_container_class_install_child_property (container_class,
282 g_param_spec_boolean ("expand",
283 "Same as GtkBox expand.",
284 "Same as GtkBox expand. Wheter the child should be expanded or not.",
289 /* Destroy can be called multiple times, remember to set pointers to NULL */
290 static void hildon_caption_destroy( GtkObject *self )
292 HildonCaptionPrivate *priv = HILDON_CAPTION_GET_PRIVATE(self);
294 /* Free our internal child */
295 if( priv->caption_area )
297 gtk_widget_unparent( priv->caption_area );
298 priv->caption_area = NULL;
301 /* Free user provided strings */
304 g_free( priv->text );
307 if( priv->separator )
309 g_free( priv->separator );
310 priv->separator = NULL;
313 /* Parent classes destroy takes care of user packed contents */
314 if( GTK_OBJECT_CLASS(parent_class)->destroy )
315 GTK_OBJECT_CLASS(parent_class)->destroy( self );
318 /* Parent, eventbox will run allocate also for the child which may be
319 * owning a window too. This window is then moved and resized
320 * and we do not want to do that (it causes flickering).
322 static gboolean hildon_caption_expose( GtkWidget *widget,
323 GdkEventExpose *event )
325 HildonCaptionPrivate *priv = NULL;
330 g_assert( HILDON_IS_CAPTION(widget) );
331 priv = HILDON_CAPTION_GET_PRIVATE(widget);
333 if( !GTK_WIDGET_DRAWABLE(widget) )
336 GTK_WIDGET_CLASS(parent_class)->expose_event( widget, event );
338 /* If our child control is focused, we draw nice looking focus
339 graphics for the caption */
340 if ( priv->is_focused && priv->text )
342 /* Determine focus box dimensions */
343 gtk_widget_get_child_requisition( priv->caption_area, &req );
344 align = hildon_caption_get_label_alignment(HILDON_CAPTION(widget));
346 alloc.width = priv->caption_area->allocation.width + HILDON_CAPTION_SPACING;
347 alloc.height = MIN (req.height + (2 * widget->style->ythickness), priv->caption_area->allocation.height);
349 alloc.x = priv->caption_area->allocation.x - HILDON_CAPTION_SPACING; /* - left margin */
350 alloc.y = priv->caption_area->allocation.y +
351 MAX(((priv->caption_area->allocation.height - alloc.height) * align), 0);
353 /* Paint the focus box */
354 gtk_paint_box( widget->style, widget->window, GTK_STATE_ACTIVE,
355 GTK_SHADOW_OUT, NULL, widget, "selection",
356 alloc.x, alloc.y, alloc.width, alloc.height );
358 /* Paint caption contents on top of the focus box */
359 GTK_WIDGET_GET_CLASS(priv->caption_area)->expose_event(
360 priv->caption_area, event);
366 static void hildon_caption_set_property( GObject *object, guint param_id,
370 HildonCaptionPrivate *priv = HILDON_CAPTION_GET_PRIVATE(object);
374 case PROP_ICON_POSITION:
376 hildon_caption_set_icon_position (HILDON_CAPTION (object),
377 g_value_get_enum (value));
382 /* Free old label string */
385 g_free( priv->text );
390 priv->text = g_value_dup_string(value);
391 hildon_caption_set_label_text( priv );
395 /* Remove old icon */
397 gtk_container_remove( GTK_CONTAINER(priv->icon_align), priv->icon );
399 /* Pack and display new icon */
400 priv->icon = g_value_get_object( value );
403 gtk_container_add(GTK_CONTAINER(priv->icon_align), priv->icon);
404 gtk_widget_show_all( priv->caption_area );
409 priv->status = g_value_get_enum( value );
412 case PROP_SIZE_GROUP:
413 /* Detach from previous size group */
415 gtk_size_group_remove_widget( priv->group, priv->caption_area );
417 priv->group = g_value_get_object( value );
419 /* Attach to new size group */
421 gtk_size_group_add_widget( priv->group, priv->caption_area );
422 gtk_widget_queue_draw( GTK_WIDGET(object) );
427 /* Free old separator */
428 if( priv->separator )
430 g_free( priv->separator );
431 priv->separator = NULL;
434 priv->separator = g_value_dup_string(value);
435 hildon_caption_set_label_text( priv );
439 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
444 static void hildon_caption_get_property( GObject *object, guint param_id,
445 GValue *value, GParamSpec *pspec )
447 HildonCaptionPrivate *priv = HILDON_CAPTION_GET_PRIVATE(object);
452 g_value_set_string( value, priv->text );
455 g_value_set_object( value, priv->icon );
458 g_value_set_enum( value, priv->status );
460 case PROP_ICON_POSITION:
461 g_value_set_enum( value, priv->icon_position);
463 case PROP_SIZE_GROUP:
464 g_value_set_object( value, priv->group );
467 g_value_set_string( value, priv->separator );
470 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
475 static void hildon_caption_set_child_property( GtkContainer *container,
483 case CHILD_PROP_EXPAND:
484 hildon_caption_set_child_expand( HILDON_CAPTION(container),
485 g_value_get_boolean(value) );
489 G_OBJECT_WARN_INVALID_PROPERTY_ID(container, property_id, pspec);
494 static void hildon_caption_get_child_property( GtkContainer *container,
502 case CHILD_PROP_EXPAND:
503 g_value_set_boolean( value, hildon_caption_get_child_expand(
504 HILDON_CAPTION(container)) );
508 G_OBJECT_WARN_INVALID_PROPERTY_ID(container, property_id, pspec);
513 /* We want to activate out child control on button press */
514 static gboolean hildon_caption_button_press( GtkWidget *widget,
515 GdkEventButton *event )
517 HildonCaptionPrivate *priv = HILDON_CAPTION_GET_PRIVATE(widget);
518 GtkWidget *child = GTK_BIN(widget)->child;
521 if (priv->is_focused == TRUE)
524 /* If child can take focus, we simply grab focus to it */
525 if ((GTK_WIDGET_CAN_FOCUS(child) || GTK_IS_CONTAINER(child)) &&
526 GTK_WIDGET_IS_SENSITIVE(child))
528 /* Only if container can be focusable we must set is_focused to TRUE */
529 if (GTK_IS_CONTAINER(child))
531 if (gtk_widget_child_focus (child,
532 GTK_DIR_TAB_FORWARD))
533 priv->is_focused = TRUE;
537 priv->is_focused = TRUE;
538 gtk_widget_grab_focus (GTK_BIN (widget)->child);
545 static void hildon_caption_init( HildonCaption *caption )
547 HildonCaptionPrivate *priv = NULL;
549 /* Initialize startup state */
550 priv = HILDON_CAPTION_GET_PRIVATE(caption);
551 priv->status = HILDON_CAPTION_OPTIONAL;
554 priv->is_focused = FALSE;
557 priv->separator = g_strdup(_("ecdg_ti_caption_separator"));
559 gtk_widget_push_composite_child();
561 /* Create caption text */
562 priv->caption_area = gtk_hbox_new( FALSE, HILDON_CAPTION_SPACING );
563 priv->label = gtk_label_new( NULL );
564 priv->icon_align = gtk_alignment_new(0.5f, 0.5f, 0.0f, 0.0f);
565 priv->icon_position = HILDON_CAPTION_POSITION_RIGHT;
567 /* We want to receive button presses for child widget activation */
568 gtk_event_box_set_above_child( GTK_EVENT_BOX(caption), FALSE );
569 gtk_widget_add_events( GTK_WIDGET(caption), GDK_BUTTON_PRESS_MASK );
571 /* Pack text label caption layout */
572 gtk_box_pack_end( GTK_BOX(priv->caption_area), priv->icon_align, FALSE, FALSE, 0);
573 gtk_box_pack_end( GTK_BOX(priv->caption_area), priv->label, FALSE, FALSE, 0 );
574 gtk_widget_set_parent( priv->caption_area, GTK_WIDGET(caption) );
577 gtk_widget_pop_composite_child();
579 hildon_caption_set_child_expand( caption, TRUE );
581 gtk_widget_show_all( priv->caption_area );
584 static void hildon_caption_set_focus( GtkWindow *window, GtkWidget *widget,
587 HildonCaptionPrivate *priv = HILDON_CAPTION_GET_PRIVATE(caption);
589 /* check if ancestor gone */
595 /* Try to find caption among the ancestors of widget */
596 if (gtk_widget_is_ancestor(widget, caption))
598 priv->is_focused = TRUE;
599 gtk_widget_queue_draw( caption );
603 if( priv->is_focused == TRUE )
605 /* Caption wasn't found, so cannot focus */
606 priv->is_focused = FALSE;
607 gtk_widget_queue_draw( caption );
611 /* We need to connect/disconnect signal handlers to toplevel window
612 in which we reside. Ww want to update connected signals if our
614 static void hildon_caption_hierarchy_changed( GtkWidget *widget,
615 GtkWidget *previous_toplevel)
617 GtkWidget *current_ancestor;
618 HildonCaptionPrivate *priv;
620 priv = HILDON_CAPTION_GET_PRIVATE(widget);
622 if( GTK_WIDGET_CLASS(parent_class)->hierarchy_changed )
623 GTK_WIDGET_CLASS(parent_class)->hierarchy_changed( widget,
626 /* If we already were inside a window, remove old handler */
627 if (previous_toplevel) {
628 /* This is a compilation workaround for gcc > 3.3 since glib is buggy */
629 /* see http://bugzilla.gnome.org/show_bug.cgi?id=310175 */
633 g_signal_handlers_disconnect_by_func
634 (previous_toplevel, (gpointer) hildon_caption_set_focus, widget);
636 current_ancestor = gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW);
638 /* Install new handler for focus movement */
639 if (current_ancestor)
640 g_signal_connect( current_ancestor, "set-focus",
641 G_CALLBACK(hildon_caption_set_focus), widget );
644 static void hildon_caption_size_request( GtkWidget *widget,
645 GtkRequisition *requisition )
648 HildonCaptionPrivate *priv = NULL;
649 g_return_if_fail( HILDON_IS_CAPTION(widget) );
650 priv = HILDON_CAPTION_GET_PRIVATE(widget);
652 /* Use the same size requisition for the main box of the caption */
653 gtk_widget_size_request( priv->caption_area, &req );
655 if( GTK_WIDGET_CLASS(parent_class)->size_request )
656 GTK_WIDGET_CLASS(parent_class)->size_request( widget, requisition );
658 requisition->width += req.width + HILDON_CAPTION_SPACING * 3;
660 if( (req.height + (2 * widget->style->ythickness)) > requisition->height )
661 requisition->height = req.height + (2 * widget->style->ythickness);
664 /* We use HILDON_CAPTION_SPACING to make it look a bit nicer */
665 static void hildon_caption_size_allocate( GtkWidget *widget,
666 GtkAllocation *allocation )
668 GtkAllocation allocA;
669 GtkAllocation allocB;
671 GtkWidget *child = NULL;
672 HildonCaptionPrivate *priv = NULL;
674 g_assert( HILDON_IS_CAPTION(widget) );
675 priv = HILDON_CAPTION_GET_PRIVATE(widget);
677 /* Position the caption to its allocated location */
678 if( GTK_WIDGET_REALIZED(widget) )
679 gdk_window_move_resize (widget->window,
680 allocation->x + GTK_CONTAINER (widget)->border_width,
681 allocation->y + GTK_CONTAINER (widget)->border_width,
682 MAX (allocation->width - GTK_CONTAINER (widget)->border_width * 2, 0),
683 MAX (allocation->height - GTK_CONTAINER (widget)->border_width * 2, 0));
685 child = GTK_BIN(widget)->child;
687 widget->allocation = *allocation;
688 gtk_widget_get_child_requisition( priv->caption_area, &req );
690 allocA.height = allocB.height = allocation->height;
691 allocA.width = allocB.width = allocation->width;
692 allocA.x = allocB.x = allocB.y = allocA.y = 0;
694 /* Center the captioned widget */
695 if( allocA.width > req.width + HILDON_CAPTION_SPACING )
697 allocA.x += req.width + HILDON_CAPTION_SPACING * 2;
698 allocB.width = req.width;
701 /* Leave at least the space of the HILDON_CAPTION_SPACING in the left */
702 allocB.x = HILDON_CAPTION_SPACING;
704 /* Leave room for the other drawable parts of the caption control */
705 allocA.width -= req.width + HILDON_CAPTION_SPACING * 2;
707 /* Give the child at least its minimum requisition, unless it is expandable */
708 if( !priv->expand && child && GTK_WIDGET_VISIBLE(child) )
710 GtkRequisition child_req;
711 gtk_widget_get_child_requisition( child, &child_req );
712 allocA.width = MIN( allocA.width, child_req.width );
713 allocA.height = MIN( allocA.height, child_req.height );
716 /* Ensure there are no negative dimensions */
717 if( allocA.width < 0 )
719 allocB.width = req.width + allocA.width;
721 allocB.width = MAX (allocB.width, 0);
724 allocA.height = MAX (allocA.height, 0);
725 allocB.height = MAX (allocB.height, 0);
727 if (child && GTK_WIDGET_VISIBLE(child) )
728 gtk_widget_size_allocate( child, &allocA );
730 gtk_widget_size_allocate( priv->caption_area, &allocB );
733 static void hildon_caption_forall( GtkContainer *container,
734 gboolean include_internals,
735 GtkCallback callback, gpointer data )
737 HildonCaptionPrivate *priv = NULL;
739 g_assert( HILDON_IS_CAPTION(container) );
740 g_assert( callback != NULL );
742 priv = HILDON_CAPTION_GET_PRIVATE(container);
744 /* Execute callback for the child widgets */
745 if( GTK_CONTAINER_CLASS(parent_class)->forall )
746 GTK_CONTAINER_CLASS(parent_class)->forall( container, include_internals,
749 if( include_internals )
750 /* Execute callback for the parent box as well */
751 (*callback)( priv->caption_area, data );
756 * hildon_caption_set_sizegroup:
757 * @caption : a #HildonCaption
758 * @new_group : a #GtkSizeGroup
760 * Sets a #GtkSizeGroup of a given captioned control.
763 void hildon_caption_set_size_group( const HildonCaption *self,
764 GtkSizeGroup *group )
766 g_object_set( G_OBJECT(self), "size_group", group, NULL );
770 * hildon_caption_get_sizegroup:
771 * @caption : a #HildonCaption
773 * Query given captioned control for the #GtkSizeGroup assigned to it.
775 * @Returns : a #GtkSizeGroup
778 GtkSizeGroup *hildon_caption_get_size_group( const HildonCaption *self )
780 HildonCaptionPrivate *priv;
781 g_return_val_if_fail( HILDON_IS_CAPTION (self), NULL );
782 priv = HILDON_CAPTION_GET_PRIVATE(self);
787 * hildon_caption_new:
788 * @group : a #GtkSizeGroup for controlling the size of related captions,
790 * @value : the caption text to accompany the text entry. The widget makes
791 * a copy of this text.
792 * @control : the control that is to be captioned
793 * @icon : an icon to accompany the label - can be NULL in which case no
795 * @flag : indicates whether this captioned control is mandatory or
798 * Creates a new instance of hildon_caption widget, with a specific
800 * Note: Clicking on a focused caption will trigger the activate signal.
801 * The default behaviour for the caption's activate signal is to call
802 * gtk_widget_activate on it's control.
804 * @Returns : a #GtkWidget pointer of Caption
806 GtkWidget *hildon_caption_new( GtkSizeGroup *group, const gchar *value,
807 GtkWidget *child, GtkWidget *icon,
808 HildonCaptionStatus flag)
811 g_return_val_if_fail( GTK_IS_WIDGET(child), NULL );
813 widget = g_object_new( HILDON_TYPE_CAPTION, "label", value,
814 "child" /* From GtkContainer */, child, "size_group", group, "icon", icon, "status", flag,
821 * hildon_caption_is_mandatory:
822 * @caption : a #HildonCaption
824 * Query #HildonCaption whether this captioned control is a mandatory one.
826 * @Returns : is this captioned control a mandatory one?
829 gboolean hildon_caption_is_mandatory( const HildonCaption *caption )
831 HildonCaptionPrivate *priv;
832 g_return_val_if_fail( HILDON_IS_CAPTION(caption), FALSE );
833 priv = HILDON_CAPTION_GET_PRIVATE(caption);
835 return priv->status == HILDON_CAPTION_MANDATORY;
839 * hildon_caption_set_icon_position:
840 * @caption : a #HildonCaption
841 * @pos : one of the values from #HildonCaptionIconPosition
843 * Sets #HildonCaption icon position.
848 void hildon_caption_set_icon_position( HildonCaption *caption,
849 HildonCaptionIconPosition pos )
851 g_return_if_fail (HILDON_IS_CAPTION (caption));
852 HildonCaptionPrivate *priv = HILDON_CAPTION_GET_PRIVATE(caption);
854 g_return_if_fail (priv->caption_area != NULL);
855 int order = (pos == HILDON_CAPTION_POSITION_LEFT) ? -1 : 0;
856 gtk_box_reorder_child (GTK_BOX (priv->caption_area), priv->icon_align, order);
858 priv->icon_position = pos;
862 * hildon_caption_get_icon_position:
863 * @caption : a #HildonCaption
865 * Gets #HildonCaption icon position.
867 * @Returns : one of the values from #HildonCaptionIconPosition.
872 HildonCaptionIconPosition hildon_caption_get_icon_position( const HildonCaption *caption )
874 g_return_val_if_fail (HILDON_IS_CAPTION (caption), 0);
875 HildonCaptionPrivate *priv = HILDON_CAPTION_GET_PRIVATE(caption);
877 return priv->icon_position;
881 * hildon_caption_set_status:
882 * @caption : a #HildonCaption
883 * @flag : one of the values from #HildonCaptionStatus
885 * Sets #HildonCaption status.
888 void hildon_caption_set_status( HildonCaption *caption,
889 HildonCaptionStatus flag )
891 g_return_if_fail( HILDON_IS_CAPTION(caption) );
893 g_object_set( G_OBJECT(caption), "status", flag, NULL );
897 * hildon_caption_get_status:
898 * @caption : a #HildonCaption
900 * Gets #HildonCaption status.
902 * @Returns : one of the values from #HildonCaptionStatus
905 HildonCaptionStatus hildon_caption_get_status( const HildonCaption *caption )
907 HildonCaptionPrivate *priv;
908 g_return_val_if_fail( HILDON_IS_CAPTION(caption), HILDON_CAPTION_OPTIONAL );
909 priv = HILDON_CAPTION_GET_PRIVATE(caption);
915 * hildon_caption_set_icon_image:
916 * @caption : a #HildonCaption
917 * @icon : the #GtkImage to use as the icon.
918 * calls gtk_widget_show on the icon if !GTK_WIDGET_VISIBLE(icon)
920 * Sets the icon to be used by this hildon_caption widget.
923 void hildon_caption_set_icon_image( HildonCaption *caption, GtkWidget *icon )
925 g_return_if_fail( HILDON_IS_CAPTION(caption) );
927 g_object_set( G_OBJECT(caption), "icon", icon, NULL );
931 * hildon_caption_get_icon_image:
932 * @caption : a #HildonCaption
934 * Gets icon of #HildonCaption
936 * @Returns : the #GtkImage that is being used as the icon by the
937 * hildon_caption, or NULL if no icon is in use
940 GtkWidget *hildon_caption_get_icon_image( const HildonCaption *caption )
942 HildonCaptionPrivate *priv;
943 g_return_val_if_fail( HILDON_IS_CAPTION(caption), NULL );
944 priv = HILDON_CAPTION_GET_PRIVATE(caption);
950 * hildon_caption_set_label:
951 * @caption : a #HildonCaption
952 * @label : the text to use
954 * Sets the label text that appears before the control.
955 * Separator character is added to the end of the label string. By default
956 * the separator is ":".
959 void hildon_caption_set_label( HildonCaption *caption, const gchar *label )
961 g_return_if_fail( HILDON_IS_CAPTION(caption) );
963 g_object_set( G_OBJECT(caption), "label", label, NULL );
967 * hildon_caption_get_label:
968 * @caption : a #HildonCaption
970 * Gets label of #HildonCaption
972 * @Returns : the text currently being used as the label of the caption
973 * control. The string is owned by the label and the caller should never
974 * free or modify this value.
977 gchar *hildon_caption_get_label( 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 (gchar*)gtk_label_get_text(GTK_LABEL(GTK_LABEL(priv->label)));
987 * hildon_caption_set_separator:
988 * @caption : a #HildonCaption
989 * @separator : the separator to use
991 * Sets the separator character that appears after the label.
992 * The default seaparator character is ":"
996 void hildon_caption_set_separator( HildonCaption *caption,
997 const gchar *separator )
999 g_return_if_fail( HILDON_IS_CAPTION(caption) );
1001 g_object_set( G_OBJECT(caption), "separator", separator, NULL );
1005 * hildon_caption_get_separator:
1006 * @caption : a #HildonCaption
1008 * Gets separator string of #HildonCaption
1010 * @Returns : the text currently being used as the separator of the caption
1011 * control. The string is owned by the caption control and the caller should
1012 * never free or modify this value.
1015 gchar *hildon_caption_get_separator( const HildonCaption *caption )
1017 HildonCaptionPrivate *priv;
1018 g_return_val_if_fail(HILDON_IS_CAPTION(caption), "");
1019 priv = HILDON_CAPTION_GET_PRIVATE(caption);
1021 return priv->separator;
1024 /*activates the child control
1025 *We have this signal so that if needed an application can
1026 *know when we've been activated (useful for captions with
1029 /* FIXME: There never are multiple children. Possibly activate
1030 signal could be removed entirely? (does anyone use it?) */
1031 static void hildon_caption_activate( GtkWidget *widget )
1033 HildonCaptionPrivate *priv;
1034 GtkWidget *child = GTK_BIN(widget)->child;
1035 priv = HILDON_CAPTION_GET_PRIVATE(widget);
1037 gtk_widget_grab_focus( child );
1041 * hildon_caption_set_child_expand:
1042 * @caption : a #HildonCaption
1043 * @expand : gboolean to determine is the child expandable
1045 * Sets child expandability.
1047 void hildon_caption_set_child_expand( HildonCaption *caption, gboolean expand )
1049 HildonCaptionPrivate *priv = NULL;
1050 GtkWidget *child = NULL;
1051 g_return_if_fail( HILDON_IS_CAPTION(caption) );
1053 priv = HILDON_CAPTION_GET_PRIVATE(caption);
1055 /* Did the setting really change? */
1056 if( priv->expand == expand )
1059 priv->expand = expand;
1060 child = GTK_BIN(caption)->child;
1062 /* We do not have a child, nothing to do */
1063 if( !GTK_IS_WIDGET(child) )
1066 if( GTK_WIDGET_VISIBLE (child) && GTK_WIDGET_VISIBLE (caption) )
1067 gtk_widget_queue_resize( child );
1069 gtk_widget_child_notify( child, "expand" );
1073 * hildon_caption_get_child_expand:
1074 * @caption : a #HildonCaption
1076 * Gets childs expandability.
1078 * @Returns : wheter the child is expandable or not.
1080 gboolean hildon_caption_get_child_expand( const HildonCaption *caption )
1082 HildonCaptionPrivate *priv = NULL;
1083 g_return_val_if_fail( HILDON_IS_CAPTION(caption), FALSE );
1084 priv = HILDON_CAPTION_GET_PRIVATE(caption);
1085 return priv->expand;
1089 hildon_caption_set_label_text( HildonCaptionPrivate *priv )
1092 g_assert ( priv != NULL );
1096 if( priv->separator )
1098 /* Don't duplicate the separator, if the string already contains one */
1099 if (g_str_has_suffix(priv->text, priv->separator))
1101 gtk_label_set_text( GTK_LABEL( priv->label ), priv->text );
1105 /* Append separator and set text */
1106 tmp = g_strconcat( priv->text, priv->separator, NULL );
1107 gtk_label_set_text( GTK_LABEL( priv->label ), tmp );
1113 gtk_label_set_text( GTK_LABEL( priv->label ), priv->text );
1118 /* Clear the label */
1119 gtk_label_set_text( GTK_LABEL( priv->label ), "" );
1125 * hildon_caption_set_label_alignment:
1126 * @caption: a #HildonCaption widget
1127 * @alignment: new vertical alignment
1129 * Sets the vertical alignment to be used for the
1130 * text part of the caption. Applications need to
1131 * align the child control themselves.
1135 void hildon_caption_set_label_alignment(HildonCaption *caption,
1138 HildonCaptionPrivate *priv;
1140 g_return_if_fail(HILDON_IS_CAPTION(caption));
1142 priv = HILDON_CAPTION_GET_PRIVATE(caption);
1143 g_object_set(priv->label, "yalign", alignment, NULL);
1144 g_object_set(priv->icon_align, "yalign", alignment, NULL);
1149 * hildon_caption_get_label_alignment:
1150 * @caption: a #HildonCaption widget
1152 * Gets current vertical alignment for the text part.
1154 * Returns: vertical alignment
1158 gfloat hildon_caption_get_label_alignment(HildonCaption *caption)
1160 HildonCaptionPrivate *priv;
1163 g_return_val_if_fail( HILDON_IS_CAPTION(caption), 0);
1164 priv = HILDON_CAPTION_GET_PRIVATE(caption);
1165 g_object_get(priv->label, "yalign", &result, NULL);