2 * This file is a part of hildon
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 (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.
40 #include "hildon-caption.h"
41 #include <gtk/gtkhbox.h>
42 #include <gtk/gtklabel.h>
43 #include <gtk/gtkimage.h>
44 #include <gtk/gtkentry.h>
45 #include <gtk/gtkcombo.h>
46 #include <gtk/gtkcombobox.h>
47 #include <gtk/gtkcomboboxentry.h>
48 #include <gtk/gtkoptionmenu.h>
49 #include <gtk/gtkmarshal.h>
50 #include <gtk/gtkalignment.h>
51 #include <gtk/gtkcheckbutton.h>
54 #include "hildon-defines.h"
56 #include "hildon-caption-private.h"
59 dgettext("hildon-libs", String)
61 #define HILDON_CAPTION_SPACING 6
63 static GtkEventBox* parent_class = NULL;
66 hildon_caption_class_init (HildonCaptionClass *caption_class);
69 hildon_caption_init (HildonCaption *caption);
72 hildon_caption_size_request (GtkWidget *widget,
73 GtkRequisition *requisition);
76 hildon_caption_size_allocate (GtkWidget *widget,
77 GtkAllocation *allocation);
80 hildon_caption_forall (GtkContainer *container,
81 gboolean include_internals,
86 hildon_caption_hierarchy_changed (GtkWidget *widget,
87 GtkWidget *previous_toplevel);
90 hildon_caption_set_focus (GtkWindow *window,
95 hildon_caption_grab_focus (GtkWidget *widget);
98 hildon_caption_activate (GtkWidget *widget);
101 hildon_caption_set_property (GObject *object,
107 hildon_caption_get_property (GObject *object,
113 hildon_caption_expose (GtkWidget *widget,
114 GdkEventExpose *event);
117 hildon_caption_destroy (GtkObject *self);
120 hildon_caption_button_press (GtkWidget *widget,
121 GdkEventButton *event);
124 hildon_caption_set_label_text (HildonCaptionPrivate *priv,
128 hildon_caption_set_child_property (GtkContainer *container,
135 hildon_caption_get_child_property (GtkContainer *container,
160 * hildon_caption_get_type:
162 * Initializes and returns the type of a hildon caption.
164 * @Returns: GType of #HildonCaption
167 hildon_caption_get_type (void)
169 static GType caption_type = 0;
173 static const GTypeInfo caption_info = {
174 sizeof (HildonCaptionClass),
175 NULL, /* base_init */
176 NULL, /* base_finalize */
177 (GClassInitFunc) hildon_caption_class_init,
178 NULL, /* class_finalize */
179 NULL, /* class_data */
180 sizeof (HildonCaption),
182 (GInstanceInitFunc) hildon_caption_init,
184 caption_type = g_type_register_static (GTK_TYPE_EVENT_BOX,
185 "HildonCaption", &caption_info, 0 );
191 * Initialises the caption class.
194 hildon_caption_class_init (HildonCaptionClass *caption_class)
196 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (caption_class);
197 GObjectClass *gobject_class = G_OBJECT_CLASS (caption_class);
198 GtkContainerClass *container_class = GTK_CONTAINER_CLASS (caption_class);
200 parent_class = g_type_class_peek_parent (caption_class);
202 g_type_class_add_private (caption_class, sizeof (HildonCaptionPrivate));
204 /* Override virtual functions */
205 gobject_class->get_property = hildon_caption_get_property;
206 gobject_class->set_property = hildon_caption_set_property;
207 caption_class->activate = (gpointer) hildon_caption_activate;
208 GTK_OBJECT_CLASS(caption_class)->destroy = hildon_caption_destroy;
210 container_class->forall = hildon_caption_forall;
211 container_class->set_child_property = hildon_caption_set_child_property;
212 container_class->get_child_property = hildon_caption_get_child_property;
214 widget_class->expose_event = hildon_caption_expose;
215 widget_class->hierarchy_changed = hildon_caption_hierarchy_changed;
216 widget_class->size_request = hildon_caption_size_request;
217 widget_class->size_allocate = hildon_caption_size_allocate;
218 widget_class->button_press_event = hildon_caption_button_press;
219 widget_class->grab_focus = hildon_caption_grab_focus;
221 /* Create new signals and properties */
222 widget_class->activate_signal = g_signal_new ("activate",
223 G_OBJECT_CLASS_TYPE (
227 G_STRUCT_OFFSET (HildonCaptionClass,
228 activate), NULL, NULL,
229 gtk_marshal_VOID__VOID,
233 * HildonCaption:label:
237 g_object_class_install_property (gobject_class, PROP_LABEL,
238 g_param_spec_string ("label",
239 "Current label", "Caption label",
240 NULL, G_PARAM_READABLE | G_PARAM_WRITABLE) );
243 * HildonCaption:markup:
245 * Caption markup. Mutually exclusive with label.
247 g_object_class_install_property (gobject_class, PROP_MARKUP,
248 g_param_spec_string ("markup",
249 "Current markup", "Caption markup",
250 NULL, G_PARAM_WRITABLE) );
253 * HildonCaption:icon:
255 * The icon shown on the caption area.
257 g_object_class_install_property (gobject_class, PROP_ICON,
258 g_param_spec_object ("icon",
260 "The icon shown on the caption area",
261 GTK_TYPE_WIDGET, G_PARAM_READABLE |
264 * HildonCaption:status:
266 * Mandatory or optional status.
268 g_object_class_install_property (gobject_class, PROP_STATUS,
269 g_param_spec_enum ("status",
271 "Mandatory or optional status",
272 HILDON_TYPE_CAPTION_STATUS,
273 HILDON_CAPTION_OPTIONAL,
274 G_PARAM_READABLE | G_PARAM_WRITABLE) );
276 * HildonCaption:icon-position:
278 * If the icon is positioned on the left or right side.
280 g_object_class_install_property (gobject_class, PROP_ICON_POSITION,
281 g_param_spec_enum ("icon-position",
283 "If the icon is on the left or right side",
284 HILDON_TYPE_CAPTION_ICON_POSITION,
285 HILDON_CAPTION_POSITION_RIGHT,
286 G_PARAM_READABLE | G_PARAM_WRITABLE) );
289 * HildonCaption:size_group:
291 * Current size group the caption is in.
293 g_object_class_install_property (gobject_class, PROP_SIZE_GROUP,
294 g_param_spec_object ("size_group",
295 "Current size group",
296 "Current size group the caption is in",
297 GTK_TYPE_SIZE_GROUP, G_PARAM_READABLE |
301 * HildonCaption:separator:
303 * The current separator.
305 g_object_class_install_property (gobject_class, PROP_SEPARATOR,
306 g_param_spec_string ("separator",
307 "Current separator", "Current separator",
308 _("ecdg_ti_caption_separator"),
309 G_PARAM_READABLE | G_PARAM_WRITABLE) );
311 /* Create child properties. These are related to
312 child <-> parent relationship, not to either of objects itself */
313 gtk_container_class_install_child_property (container_class,
315 g_param_spec_boolean ("expand",
316 "Same as GtkBox expand.",
317 "Same as GtkBox expand. Wheter the child should be expanded or not.",
322 /* Destroy can be called multiple times, remember to set pointers to NULL */
324 hildon_caption_destroy (GtkObject *self)
326 HildonCaptionPrivate *priv = HILDON_CAPTION_GET_PRIVATE (self);
328 /* Free our internal child */
329 if (priv && priv->caption_area)
331 gtk_widget_unparent (priv->caption_area);
332 priv->caption_area = NULL;
335 /* Free user provided strings */
336 if (priv && priv->text)
342 if (priv && priv->separator)
344 g_free (priv->separator);
345 priv->separator = NULL;
348 /* Parent classes destroy takes care of user packed contents */
349 if (GTK_OBJECT_CLASS (parent_class)->destroy)
350 GTK_OBJECT_CLASS (parent_class)->destroy (self);
353 /* Parent, eventbox will run allocate also for the child which may be
354 * owning a window too. This window is then moved and resized
355 * and we do not want to do that (it causes flickering).
358 hildon_caption_expose (GtkWidget *widget,
359 GdkEventExpose *event)
361 HildonCaptionPrivate *priv = NULL;
366 g_assert (HILDON_IS_CAPTION (widget));
367 priv = HILDON_CAPTION_GET_PRIVATE (widget);
370 if (! GTK_WIDGET_DRAWABLE (widget))
373 GTK_WIDGET_CLASS (parent_class)->expose_event (widget, event);
375 /* If our child control is focused, we draw nice looking focus
376 graphics for the caption */
377 if (priv->is_focused && priv->text)
379 /* Determine focus box dimensions */
380 gtk_widget_get_child_requisition (priv->caption_area, &req);
381 align = hildon_caption_get_label_alignment (HILDON_CAPTION(widget));
383 alloc.width = priv->caption_area->allocation.width + HILDON_CAPTION_SPACING;
384 alloc.height = MIN (req.height + (2 * widget->style->ythickness), priv->caption_area->allocation.height);
386 alloc.x = priv->caption_area->allocation.x - HILDON_CAPTION_SPACING; /* - left margin */
387 alloc.y = priv->caption_area->allocation.y +
388 MAX (((priv->caption_area->allocation.height - alloc.height) * align), 0);
390 /* Paint the focus box */
391 gtk_paint_box (widget->style, widget->window, GTK_STATE_ACTIVE,
392 GTK_SHADOW_OUT, NULL, widget, "selection",
393 alloc.x, alloc.y, alloc.width, alloc.height);
395 /* Paint caption contents on top of the focus box */
396 GTK_WIDGET_GET_CLASS (priv->caption_area)->expose_event (priv->caption_area, event);
403 hildon_caption_set_property (GObject *object,
408 HildonCaptionPrivate *priv = HILDON_CAPTION_GET_PRIVATE (object);
413 case PROP_ICON_POSITION:
414 hildon_caption_set_icon_position (HILDON_CAPTION (object), g_value_get_enum (value));
418 /* Free old label string */
426 priv->text = g_value_dup_string (value);
427 hildon_caption_set_label_text (priv, FALSE);
431 /* Free old label string */
439 priv->text = g_value_dup_string (value);
440 hildon_caption_set_label_text (priv, TRUE);
444 /* Remove old icon */
446 gtk_container_remove (GTK_CONTAINER (priv->icon_align), priv->icon);
448 /* Pack and display new icon */
449 priv->icon = g_value_get_object (value);
452 gtk_container_add (GTK_CONTAINER (priv->icon_align), priv->icon);
453 gtk_widget_show_all (priv->caption_area);
458 priv->status = g_value_get_enum (value);
461 case PROP_SIZE_GROUP:
462 /* Detach from previous size group */
464 gtk_size_group_remove_widget (priv->group, priv->caption_area);
466 priv->group = g_value_get_object (value);
468 /* Attach to new size group */
470 gtk_size_group_add_widget (priv->group, priv->caption_area);
472 gtk_widget_queue_draw (GTK_WIDGET(object));
477 /* Free old separator */
480 g_free (priv->separator);
481 priv->separator = NULL;
484 priv->separator = g_value_dup_string (value);
485 hildon_caption_set_label_text (priv, FALSE);
489 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
495 hildon_caption_get_property (GObject *object,
500 HildonCaptionPrivate *priv = HILDON_CAPTION_GET_PRIVATE (object);
505 g_value_set_string (value, priv->text);
509 g_value_set_object (value, priv->icon);
513 g_value_set_enum (value, priv->status);
516 case PROP_ICON_POSITION:
517 g_value_set_enum (value, priv->icon_position);
520 case PROP_SIZE_GROUP:
521 g_value_set_object (value, priv->group);
525 g_value_set_string (value, priv->separator);
529 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
535 hildon_caption_set_child_property (GtkContainer *container,
543 case CHILD_PROP_EXPAND:
544 hildon_caption_set_child_expand (HILDON_CAPTION (container),
545 g_value_get_boolean (value));
549 G_OBJECT_WARN_INVALID_PROPERTY_ID (container, property_id, pspec);
555 hildon_caption_get_child_property (GtkContainer *container,
563 case CHILD_PROP_EXPAND:
564 g_value_set_boolean (value, hildon_caption_get_child_expand(
565 HILDON_CAPTION (container)));
569 G_OBJECT_WARN_INVALID_PROPERTY_ID(container, property_id, pspec);
574 /* We want to activate out child control on button press */
576 hildon_caption_button_press (GtkWidget *widget,
577 GdkEventButton *event)
579 gtk_widget_grab_focus (GTK_BIN (widget)->child);
581 /* we'll update our focused state in set-focus when/if the child receives
588 hildon_caption_init (HildonCaption *caption)
590 HildonCaptionPrivate *priv = NULL;
592 /* Initialize startup state */
593 priv = HILDON_CAPTION_GET_PRIVATE (caption);
596 priv->status = HILDON_CAPTION_OPTIONAL;
599 priv->is_focused = FALSE;
602 priv->separator = g_strdup(_("ecdg_ti_caption_separator"));
604 gtk_widget_push_composite_child();
606 /* Create caption text */
607 priv->caption_area = gtk_hbox_new (FALSE, HILDON_CAPTION_SPACING);
608 priv->label = gtk_label_new (NULL);
609 priv->icon_align = gtk_alignment_new (0.5f, 0.5f, 0.0f, 0.0f);
610 priv->icon_position = HILDON_CAPTION_POSITION_RIGHT;
612 /* We want to receive button presses for child widget activation */
613 gtk_event_box_set_above_child (GTK_EVENT_BOX (caption), FALSE);
614 gtk_widget_add_events (GTK_WIDGET (caption), GDK_BUTTON_PRESS_MASK);
616 /* Pack text label caption layout */
617 gtk_box_pack_end (GTK_BOX (priv->caption_area), priv->icon_align, FALSE, FALSE, 0);
618 gtk_box_pack_end (GTK_BOX (priv->caption_area), priv->label, FALSE, FALSE, 0);
619 gtk_widget_set_parent (priv->caption_area, GTK_WIDGET (caption));
621 gtk_widget_pop_composite_child ();
623 hildon_caption_set_child_expand (caption, TRUE);
625 gtk_widget_show_all (priv->caption_area);
629 hildon_caption_set_focus (GtkWindow *window,
633 HildonCaptionPrivate *priv = HILDON_CAPTION_GET_PRIVATE (caption);
636 /* check if ancestor gone */
642 /* Try to find caption among the ancestors of widget */
643 if (gtk_widget_is_ancestor (widget, caption))
645 priv->is_focused = TRUE;
646 gtk_widget_queue_draw (caption);
650 if (priv->is_focused == TRUE)
652 /* Caption wasn't found, so cannot focus */
653 priv->is_focused = FALSE;
654 gtk_widget_queue_draw (caption);
658 /* We need to connect/disconnect signal handlers to toplevel window
659 in which we reside. Ww want to update connected signals if our
662 hildon_caption_hierarchy_changed (GtkWidget *widget,
663 GtkWidget *previous_toplevel)
665 GtkWidget *current_ancestor;
666 HildonCaptionPrivate *priv;
668 priv = HILDON_CAPTION_GET_PRIVATE (widget);
671 if (GTK_WIDGET_CLASS (parent_class)->hierarchy_changed)
672 GTK_WIDGET_CLASS (parent_class)->hierarchy_changed (widget, previous_toplevel);
674 /* If we already were inside a window, remove old handler */
675 if (previous_toplevel) {
676 /* This is a compilation workaround for gcc > 3.3 since glib is buggy */
677 /* see http://bugzilla.gnome.org/show_bug.cgi?id=310175 */
681 g_signal_handlers_disconnect_by_func
682 (previous_toplevel, (gpointer) hildon_caption_set_focus, widget);
685 current_ancestor = gtk_widget_get_ancestor (widget, GTK_TYPE_WINDOW);
687 /* Install new handler for focus movement */
688 if (current_ancestor)
689 g_signal_connect( current_ancestor, "set-focus",
690 G_CALLBACK (hildon_caption_set_focus), widget );
694 hildon_caption_size_request (GtkWidget *widget,
695 GtkRequisition *requisition)
698 HildonCaptionPrivate *priv = NULL;
699 g_return_if_fail (HILDON_IS_CAPTION(widget));
701 priv = HILDON_CAPTION_GET_PRIVATE (widget);
704 /* Use the same size requisition for the main box of the caption */
705 gtk_widget_size_request (priv->caption_area, &req);
707 if (GTK_WIDGET_CLASS (parent_class)->size_request)
708 GTK_WIDGET_CLASS (parent_class)->size_request (widget, requisition);
710 requisition->width += req.width + HILDON_CAPTION_SPACING * 3;
712 if ((req.height + (2 * widget->style->ythickness)) > requisition->height)
713 requisition->height = req.height + (2 * widget->style->ythickness);
716 /* We use HILDON_CAPTION_SPACING to make it look a bit nicer */
718 hildon_caption_size_allocate (GtkWidget *widget,
719 GtkAllocation *allocation)
721 GtkAllocation child_alloc;
722 GtkAllocation caption_alloc;
723 GtkRequisition req, child_req;
724 GtkWidget *child = NULL;
725 HildonCaptionPrivate *priv = NULL;
728 g_assert (HILDON_IS_CAPTION (widget));
729 priv = HILDON_CAPTION_GET_PRIVATE (widget);
732 /* Get the rtl status */
733 rtl = (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL);
735 /* Position the caption to its allocated location */
736 if (GTK_WIDGET_REALIZED (widget))
737 gdk_window_move_resize (widget->window,
738 allocation->x + GTK_CONTAINER (widget)->border_width,
739 allocation->y + GTK_CONTAINER (widget)->border_width,
740 MAX (allocation->width - GTK_CONTAINER (widget)->border_width * 2, 0),
741 MAX (allocation->height - GTK_CONTAINER (widget)->border_width * 2, 0));
743 child = GTK_BIN (widget)->child;
745 gtk_widget_get_child_requisition (child, &child_req);
747 widget->allocation = *allocation;
748 gtk_widget_get_child_requisition (priv->caption_area, &req);
750 child_alloc.height = caption_alloc.height = allocation->height;
751 child_alloc.width = caption_alloc.width = allocation->width;
752 child_alloc.x = caption_alloc.x = caption_alloc.y = child_alloc.y = 0;
754 /* Center the captioned widget */
757 if (caption_alloc.width > child_req.width + HILDON_CAPTION_SPACING)
759 caption_alloc.x = caption_alloc.width - req.width;
760 child_alloc.width = child_req.width;
762 caption_alloc.width -= child_req.width + HILDON_CAPTION_SPACING * 2;
766 if (child_alloc.width > req.width + HILDON_CAPTION_SPACING)
768 child_alloc.x += req.width + HILDON_CAPTION_SPACING * 2;
769 caption_alloc.width = req.width;
771 /* Leave at least the space of the HILDON_CAPTION_SPACING in the left */
772 caption_alloc.x = HILDON_CAPTION_SPACING;
774 /* Leave room for the other drawable parts of the caption control */
775 child_alloc.width -= req.width + HILDON_CAPTION_SPACING * 2;
778 /* Give the child at least its minimum requisition, unless it is expandable */
779 if (! priv->expand && child && GTK_WIDGET_VISIBLE(child))
781 child_alloc.width = MIN (child_alloc.width, child_req.width);
782 child_alloc.height = MIN (child_alloc.height, child_req.height);
783 /* Center the child */
784 child_alloc.y = (allocation->height - child_alloc.height -
785 2 * GTK_CONTAINER (widget)->border_width)/2;
788 /* Ensure there are no negative dimensions */
789 if (child_alloc.width < 0)
791 caption_alloc.width = req.width + child_alloc.width;
792 child_alloc.width = 0;
793 caption_alloc.width = MAX (caption_alloc.width, 0);
797 child_alloc.x = caption_alloc.x - child_req.width - HILDON_CAPTION_SPACING * 2;
799 child_alloc.height = MAX (child_alloc.height, 0);
800 caption_alloc.height = MAX (caption_alloc.height, 0);
802 if (child && GTK_WIDGET_VISIBLE(child) )
803 gtk_widget_size_allocate (child, &child_alloc );
805 gtk_widget_size_allocate (priv->caption_area, &caption_alloc);
809 hildon_caption_forall (GtkContainer *container,
810 gboolean include_internals,
811 GtkCallback callback,
814 HildonCaptionPrivate *priv = NULL;
816 g_assert (HILDON_IS_CAPTION (container));
817 g_assert (callback != NULL);
819 priv = HILDON_CAPTION_GET_PRIVATE (container);
822 /* Execute callback for the child widgets */
823 if (GTK_CONTAINER_CLASS (parent_class)->forall)
824 GTK_CONTAINER_CLASS (parent_class)->forall (container, include_internals, callback, data);
826 if (include_internals)
827 /* Execute callback for the parent box as well */
828 (*callback) (priv->caption_area, data);
832 * hildon_caption_set_size_group:
833 * @caption : a #HildonCaption
834 * @new_group : a #GtkSizeGroup
836 * Sets a #GtkSizeGroup of a given captioned control.
840 hildon_caption_set_size_group (const HildonCaption *self,
843 g_object_set (G_OBJECT(self), "size_group", group, NULL);
847 * hildon_caption_get_size_group:
848 * @caption : a #HildonCaption
850 * Query given captioned control for the #GtkSizeGroup assigned to it.
852 * @Returns : a #GtkSizeGroup
856 hildon_caption_get_size_group (const HildonCaption *self)
858 HildonCaptionPrivate *priv;
859 g_return_val_if_fail (HILDON_IS_CAPTION (self), NULL);
861 priv = HILDON_CAPTION_GET_PRIVATE(self);
868 * hildon_caption_new:
869 * @group : a #GtkSizeGroup for controlling the size of related captions,
871 * @value : the caption text to accompany the text entry. The widget makes
872 * a copy of this text.
873 * @control : the control that is to be captioned
874 * @icon : an icon to accompany the label - can be NULL in which case no
876 * @flag : indicates whether this captioned control is mandatory or
879 * Creates a new instance of hildon_caption widget, with a specific
881 * Note: Clicking on a focused caption will trigger the activate signal.
882 * The default behaviour for the caption's activate signal is to call
883 * gtk_widget_activate on it's control.
885 * @Returns : a #GtkWidget pointer of Caption
888 hildon_caption_new (GtkSizeGroup *group,
892 HildonCaptionStatus flag)
895 g_return_val_if_fail (GTK_IS_WIDGET (child), NULL);
897 widget = g_object_new (HILDON_TYPE_CAPTION,
905 /* Do not expand GtkCheckButton by default, we want to reduce its activation area */
906 if (GTK_IS_CHECK_BUTTON (child))
907 hildon_caption_set_child_expand (HILDON_CAPTION (widget), FALSE);
913 * hildon_caption_is_mandatory:
914 * @caption : a #HildonCaption
916 * Query #HildonCaption whether this captioned control is a mandatory one.
918 * @Returns : is this captioned control a mandatory one?
921 hildon_caption_is_mandatory (const HildonCaption *caption)
923 HildonCaptionPrivate *priv;
925 g_return_val_if_fail (HILDON_IS_CAPTION (caption), FALSE);
927 priv = HILDON_CAPTION_GET_PRIVATE (caption);
930 return (priv->status == HILDON_CAPTION_MANDATORY);
934 * hildon_caption_set_icon_position:
935 * @caption : a #HildonCaption
936 * @pos : one of the values from #HildonCaptionIconPosition
938 * Sets #HildonCaption icon position.
942 hildon_caption_set_icon_position (HildonCaption *caption,
943 HildonCaptionIconPosition pos)
945 g_return_if_fail (HILDON_IS_CAPTION (caption));
946 HildonCaptionPrivate *priv = HILDON_CAPTION_GET_PRIVATE (caption);
949 g_return_if_fail (priv->caption_area != NULL);
951 int order = (pos == HILDON_CAPTION_POSITION_LEFT) ? -1 : 0;
952 gtk_box_reorder_child (GTK_BOX (priv->caption_area), priv->icon_align, order);
954 priv->icon_position = pos;
958 * hildon_caption_get_icon_position:
959 * @caption : a #HildonCaption
961 * Gets #HildonCaption icon position.
963 * @Returns : one of the values from #HildonCaptionIconPosition.
967 HildonCaptionIconPosition
968 hildon_caption_get_icon_position (const HildonCaption *caption)
970 g_return_val_if_fail (HILDON_IS_CAPTION (caption), 0);
972 HildonCaptionPrivate *priv = HILDON_CAPTION_GET_PRIVATE (caption);
975 return priv->icon_position;
979 * hildon_caption_set_status:
980 * @caption : a #HildonCaption
981 * @flag : one of the values from #HildonCaptionStatus
983 * Sets #HildonCaption status.
986 hildon_caption_set_status (HildonCaption *caption,
987 HildonCaptionStatus flag)
989 g_return_if_fail (HILDON_IS_CAPTION(caption));
991 g_object_set (G_OBJECT(caption), "status", flag, NULL);
995 * hildon_caption_get_status:
996 * @caption : a #HildonCaption
998 * Gets #HildonCaption status.
1000 * @Returns : one of the values from #HildonCaptionStatus
1003 hildon_caption_get_status (const HildonCaption *caption)
1005 HildonCaptionPrivate *priv;
1006 g_return_val_if_fail (HILDON_IS_CAPTION (caption), HILDON_CAPTION_OPTIONAL);
1008 priv = HILDON_CAPTION_GET_PRIVATE(caption);
1011 return priv->status;
1015 * hildon_caption_set_icon_image:
1016 * @caption : a #HildonCaption
1017 * @icon : the #GtkImage to use as the icon.
1018 * calls gtk_widget_show on the icon if !GTK_WIDGET_VISIBLE(icon)
1020 * Sets the icon image widget to be used by this hildon_caption widget.
1023 hildon_caption_set_icon_image (HildonCaption *caption,
1026 g_return_if_fail (HILDON_IS_CAPTION(caption));
1028 g_object_set (G_OBJECT(caption), "icon", icon, NULL);
1032 * hildon_caption_get_icon_image:
1033 * @caption : a #HildonCaption
1035 * Gets icon of #HildonCaption
1037 * @Returns : the #GtkImage widget that is being used as the icon by the
1038 * hildon_caption, or NULL if no icon image is in use.
1041 hildon_caption_get_icon_image (const HildonCaption *caption)
1043 HildonCaptionPrivate *priv;
1045 g_return_val_if_fail (HILDON_IS_CAPTION (caption), NULL);
1047 priv = HILDON_CAPTION_GET_PRIVATE (caption);
1054 * hildon_caption_set_label:
1055 * @caption : a #HildonCaption
1056 * @label : the text to use
1058 * Sets the label text that appears before the control.
1059 * Separator character is added to the end of the label string. By default
1060 * the separator is ":".
1063 hildon_caption_set_label (HildonCaption *caption,
1066 g_return_if_fail (HILDON_IS_CAPTION (caption));
1068 g_object_set (G_OBJECT(caption), "label", label, NULL);
1072 * hildon_caption_set_label_markup:
1073 * @caption : a #HildonCaption
1074 * @markup : the markup text to use
1076 * Sets the label markup text that appears before the control. It acts like
1077 * #hildon_caption_set_label but is using the markup text that allows to specify
1078 * text properties such as bold or italic.
1081 hildon_caption_set_label_markup (HildonCaption *caption,
1082 const gchar *markup)
1084 g_return_if_fail (HILDON_IS_CAPTION (caption));
1086 g_object_set (G_OBJECT(caption), "markup", markup, NULL);
1090 * hildon_caption_get_label:
1091 * @caption : a #HildonCaption
1093 * Gets label of #HildonCaption
1095 * @Returns : the text currently being used as the label of the caption
1096 * control. The string is owned by the label and the caller should never
1097 * free or modify this value.
1100 hildon_caption_get_label (const HildonCaption *caption)
1102 HildonCaptionPrivate *priv;
1103 g_return_val_if_fail (HILDON_IS_CAPTION (caption), "");
1104 priv = HILDON_CAPTION_GET_PRIVATE (caption);
1107 return (gchar*) gtk_label_get_text (GTK_LABEL (priv->label));
1111 * hildon_caption_set_separator:
1112 * @caption : a #HildonCaption
1113 * @separator : the separator to use
1115 * Sets the separator character that appears after the label.
1116 * The default seaparator character is ":"
1120 hildon_caption_set_separator (HildonCaption *caption,
1121 const gchar *separator)
1123 g_return_if_fail (HILDON_IS_CAPTION (caption));
1125 g_object_set (G_OBJECT (caption), "separator", separator, NULL);
1129 * hildon_caption_get_separator:
1130 * @caption : a #HildonCaption
1132 * Gets separator string of #HildonCaption
1134 * @Returns : the text currently being used as the separator of the caption
1135 * control. The string is owned by the caption control and the caller should
1136 * never free or modify this value.
1139 hildon_caption_get_separator (const HildonCaption *caption)
1141 HildonCaptionPrivate *priv;
1142 g_return_val_if_fail (HILDON_IS_CAPTION (caption), "");
1144 priv = HILDON_CAPTION_GET_PRIVATE (caption);
1147 return priv->separator;
1150 /* Activates the child control
1151 * We have this signal so that if needed an application can
1152 * know when we've been activated (useful for captions with
1154 * FIXME: There never are multiple children. Possibly activate
1155 * signal could be removed entirely? (does anyone use it?)
1158 hildon_caption_activate (GtkWidget *widget)
1160 GtkWidget *child = GTK_BIN (widget)->child;
1161 gtk_widget_grab_focus (child);
1165 hildon_caption_grab_focus (GtkWidget *widget)
1167 gtk_widget_grab_focus (GTK_BIN (widget)->child);
1171 * hildon_caption_set_child_expand:
1172 * @caption : a #HildonCaption
1173 * @expand : gboolean to determine if the child is expandable
1175 * Sets child expandability.
1178 hildon_caption_set_child_expand (HildonCaption *caption,
1181 HildonCaptionPrivate *priv = NULL;
1182 GtkWidget *child = NULL;
1183 g_return_if_fail (HILDON_IS_CAPTION (caption));
1185 priv = HILDON_CAPTION_GET_PRIVATE (caption);
1188 /* Did the setting really change? */
1189 if (priv->expand == expand)
1192 priv->expand = expand;
1193 child = GTK_BIN (caption)->child;
1195 /* We do not have a child, nothing to do */
1196 if (! GTK_IS_WIDGET (child))
1199 if (GTK_WIDGET_VISIBLE (child) && GTK_WIDGET_VISIBLE (caption))
1200 gtk_widget_queue_resize (child);
1202 gtk_widget_child_notify (child, "expand");
1206 * hildon_caption_get_child_expand:
1207 * @caption : a #HildonCaption
1209 * Gets childs expandability.
1211 * @Returns : wheter the child is expandable or not.
1214 hildon_caption_get_child_expand (const HildonCaption *caption)
1216 HildonCaptionPrivate *priv = NULL;
1217 g_return_val_if_fail (HILDON_IS_CAPTION (caption), FALSE);
1219 priv = HILDON_CAPTION_GET_PRIVATE (caption);
1222 return priv->expand;
1226 hildon_caption_set_label_text (HildonCaptionPrivate *priv,
1230 g_assert (priv != NULL);
1234 if (priv->separator)
1236 /* Don't duplicate the separator, if the string already contains one */
1237 if (g_str_has_suffix (priv->text, priv->separator))
1240 gtk_label_set_markup (GTK_LABEL (priv->label), priv->text);
1242 gtk_label_set_text (GTK_LABEL (priv->label), priv->text);
1246 /* Append separator and set text */
1247 tmp = g_strconcat( priv->text, priv->separator, NULL );
1250 gtk_label_set_markup (GTK_LABEL (priv->label), tmp);
1252 gtk_label_set_text (GTK_LABEL (priv->label), tmp);
1260 gtk_label_set_markup (GTK_LABEL (priv->label), priv->text);
1262 gtk_label_set_text (GTK_LABEL (priv->label), priv->text);
1267 /* Clear the label */
1269 gtk_label_set_markup (GTK_LABEL (priv->label), "");
1271 gtk_label_set_text (GTK_LABEL (priv->label), "" );
1276 * hildon_caption_set_label_alignment:
1277 * @caption: a #HildonCaption widget
1278 * @alignment: new vertical alignment
1280 * Sets the vertical alignment to be used for the
1281 * text part of the caption. Applications need to
1282 * align the child control themselves.
1286 hildon_caption_set_label_alignment (HildonCaption *caption,
1289 HildonCaptionPrivate *priv;
1291 g_return_if_fail (HILDON_IS_CAPTION (caption));
1293 priv = HILDON_CAPTION_GET_PRIVATE (caption);
1296 g_object_set (priv->label, "yalign", alignment, NULL);
1297 g_object_set (priv->icon_align, "yalign", alignment, NULL);
1302 * hildon_caption_get_label_alignment:
1303 * @caption: a #HildonCaption widget
1305 * Gets current vertical alignment for the text part.
1307 * Returns: vertical alignment
1311 hildon_caption_get_label_alignment (HildonCaption *caption)
1313 HildonCaptionPrivate *priv;
1316 g_return_val_if_fail (HILDON_IS_CAPTION (caption), 0);
1317 priv = HILDON_CAPTION_GET_PRIVATE (caption);
1320 g_object_get (priv->label, "yalign", &result, NULL);