*
* Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
*
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ * Contact: Rodrigo Novo <rodrigo.novo@nokia.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; version 2.1 of
- * the License.
+ * the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
/**
* SECTION:hildon-caption
* @short_description: A single-child container widget that precedes the
- * contained widget with a field label and an optional icon
+ * contained widget with a field label and an optional icon.
*
* #HildonCaption is a single-child container widget that precedes the
* contained widget with a field label and an optional icon. It allows
#include <config.h>
#endif
-#include "hildon-caption.h"
-#include <gtk/gtkhbox.h>
-#include <gtk/gtklabel.h>
-#include <gtk/gtkimage.h>
-#include <gtk/gtkentry.h>
-#include <gtk/gtkcombo.h>
-#include <gtk/gtkcombobox.h>
-#include <gtk/gtkcomboboxentry.h>
-#include <gtk/gtkoptionmenu.h>
-#include <gtk/gtkmarshal.h>
-#include <gtk/gtkalignment.h>
-#include <stdio.h>
-#include <string.h>
-#include "hildon-defines.h"
#include <libintl.h>
+#include <gtk/gtk.h>
+
+#include "hildon-defines.h"
+#include "hildon-caption.h"
#include "hildon-caption-private.h"
#define _(String)\
GtkWidget *caption);
static void
+hildon_caption_grab_focus (GtkWidget *widget);
+
+static void
hildon_caption_activate (GtkWidget *widget);
static void
GValue *value,
GParamSpec *pspec);
-static gboolean
-hildon_caption_expose (GtkWidget *widget,
- GdkEventExpose *event);
-
static void
hildon_caption_destroy (GtkObject *self);
GdkEventButton *event);
static void
-hildon_caption_set_label_text (HildonCaptionPrivate *priv);
+hildon_caption_set_label_text (HildonCaptionPrivate *priv,
+ gboolean markup);
static void
hildon_caption_set_child_property (GtkContainer *container,
{
PROP_0,
PROP_LABEL,
+ PROP_MARKUP,
PROP_ICON,
PROP_STATUS,
PROP_SEPARATOR,
*
* Initializes and returns the type of a hildon caption.
*
- * @Returns: GType of #HildonCaption
+ * Returns: GType of #HildonCaption
*/
GType G_GNUC_CONST
hildon_caption_get_type (void)
container_class->set_child_property = hildon_caption_set_child_property;
container_class->get_child_property = hildon_caption_get_child_property;
- widget_class->expose_event = hildon_caption_expose;
widget_class->hierarchy_changed = hildon_caption_hierarchy_changed;
widget_class->size_request = hildon_caption_size_request;
widget_class->size_allocate = hildon_caption_size_allocate;
widget_class->button_press_event = hildon_caption_button_press;
+ widget_class->grab_focus = hildon_caption_grab_focus;
/* Create new signals and properties */
widget_class->activate_signal = g_signal_new ("activate",
G_SIGNAL_ACTION,
G_STRUCT_OFFSET (HildonCaptionClass,
activate), NULL, NULL,
- gtk_marshal_VOID__VOID,
+ g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
/**
g_param_spec_string ("label",
"Current label", "Caption label",
NULL, G_PARAM_READABLE | G_PARAM_WRITABLE) );
+
+ /**
+ * HildonCaption:markup:
+ *
+ * Caption markup. Mutually exclusive with label.
+ */
+ g_object_class_install_property (gobject_class, PROP_MARKUP,
+ g_param_spec_string ("markup",
+ "Current markup", "Caption markup",
+ NULL, G_PARAM_WRITABLE) );
/**
* HildonCaption:icon:
GTK_OBJECT_CLASS (parent_class)->destroy (self);
}
-/* Parent, eventbox will run allocate also for the child which may be
- * owning a window too. This window is then moved and resized
- * and we do not want to do that (it causes flickering).
- */
-static gboolean
-hildon_caption_expose (GtkWidget *widget,
- GdkEventExpose *event)
-{
- HildonCaptionPrivate *priv = NULL;
- GtkRequisition req;
- GtkAllocation alloc;
- gfloat align;
-
- g_assert (HILDON_IS_CAPTION (widget));
- priv = HILDON_CAPTION_GET_PRIVATE (widget);
- g_assert (priv);
-
- if (! GTK_WIDGET_DRAWABLE (widget))
- return FALSE;
-
- GTK_WIDGET_CLASS (parent_class)->expose_event (widget, event);
-
- /* If our child control is focused, we draw nice looking focus
- graphics for the caption */
- if (priv->is_focused && priv->text)
- {
- /* Determine focus box dimensions */
- gtk_widget_get_child_requisition (priv->caption_area, &req);
- align = hildon_caption_get_label_alignment (HILDON_CAPTION(widget));
-
- alloc.width = priv->caption_area->allocation.width + HILDON_CAPTION_SPACING;
- alloc.height = MIN (req.height + (2 * widget->style->ythickness), priv->caption_area->allocation.height);
-
- alloc.x = priv->caption_area->allocation.x - HILDON_CAPTION_SPACING; /* - left margin */
- alloc.y = priv->caption_area->allocation.y +
- MAX (((priv->caption_area->allocation.height - alloc.height) * align), 0);
-
- /* Paint the focus box */
- gtk_paint_box (widget->style, widget->window, GTK_STATE_ACTIVE,
- GTK_SHADOW_OUT, NULL, widget, "selection",
- alloc.x, alloc.y, alloc.width, alloc.height);
-
- /* Paint caption contents on top of the focus box */
- GTK_WIDGET_GET_CLASS (priv->caption_area)->expose_event (priv->caption_area, event);
- }
-
- return FALSE;
-}
-
static void
hildon_caption_set_property (GObject *object,
guint param_id,
GParamSpec *pspec)
{
HildonCaptionPrivate *priv = HILDON_CAPTION_GET_PRIVATE (object);
- g_assert (priv);
switch (param_id)
{
/* Update label */
priv->text = g_value_dup_string (value);
- hildon_caption_set_label_text (priv);
+ hildon_caption_set_label_text (priv, FALSE);
+ break;
+
+ case PROP_MARKUP:
+ /* Free old label string */
+ if (priv->text)
+ {
+ g_free (priv->text);
+ priv->text = NULL;
+ }
+
+ /* Update label */
+ priv->text = g_value_dup_string (value);
+ hildon_caption_set_label_text (priv, TRUE);
break;
case PROP_ICON:
}
priv->separator = g_value_dup_string (value);
- hildon_caption_set_label_text (priv);
+ hildon_caption_set_label_text (priv, FALSE);
break;
default:
hildon_caption_button_press (GtkWidget *widget,
GdkEventButton *event)
{
- HildonCaptionPrivate *priv = HILDON_CAPTION_GET_PRIVATE (widget);
- g_assert (priv);
- GtkWidget *child = GTK_BIN (widget)->child;
-
- /* nothing to do */
- if (priv->is_focused == TRUE)
- return FALSE;
-
- /* If child can take focus, we simply grab focus to it */
- if ((GTK_WIDGET_CAN_FOCUS (child) || GTK_IS_CONTAINER (child)) &&
- GTK_WIDGET_IS_SENSITIVE (child))
- {
- /* Only if container can be focusable we must set is_focused to TRUE */
- if (GTK_IS_CONTAINER (child))
- {
- if (gtk_widget_child_focus (child, GTK_DIR_TAB_FORWARD))
- priv->is_focused = TRUE;
- }
- else
- {
- priv->is_focused = TRUE;
- gtk_widget_grab_focus (GTK_BIN (widget)->child);
- }
- }
+ gtk_widget_grab_focus (GTK_BIN (widget)->child);
+
+ /* we'll update our focused state in set-focus when/if the child receives
+ * focus */
return FALSE;
}
/* Initialize startup state */
priv = HILDON_CAPTION_GET_PRIVATE (caption);
- g_assert (priv);
priv->status = HILDON_CAPTION_OPTIONAL;
priv->icon = NULL;
GtkWidget *caption)
{
HildonCaptionPrivate *priv = HILDON_CAPTION_GET_PRIVATE (caption);
- g_assert (priv);
/* check if ancestor gone */
if (! widget)
GtkWidget *previous_toplevel)
{
GtkWidget *current_ancestor;
- HildonCaptionPrivate *priv;
-
- priv = HILDON_CAPTION_GET_PRIVATE (widget);
- g_assert (priv);
if (GTK_WIDGET_CLASS (parent_class)->hierarchy_changed)
GTK_WIDGET_CLASS (parent_class)->hierarchy_changed (widget, previous_toplevel);
g_return_if_fail (HILDON_IS_CAPTION(widget));
priv = HILDON_CAPTION_GET_PRIVATE (widget);
- g_assert (priv);
/* Use the same size requisition for the main box of the caption */
gtk_widget_size_request (priv->caption_area, &req);
hildon_caption_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
- GtkAllocation allocA;
- GtkAllocation allocB;
- GtkRequisition req;
+ GtkAllocation child_alloc;
+ GtkAllocation caption_alloc;
+ GtkRequisition req, child_req = {0};
GtkWidget *child = NULL;
HildonCaptionPrivate *priv = NULL;
+ gboolean rtl;
g_assert (HILDON_IS_CAPTION (widget));
priv = HILDON_CAPTION_GET_PRIVATE (widget);
- g_assert (priv);
+
+ /* Get the rtl status */
+ rtl = (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL);
/* Position the caption to its allocated location */
if (GTK_WIDGET_REALIZED (widget))
MAX (allocation->height - GTK_CONTAINER (widget)->border_width * 2, 0));
child = GTK_BIN (widget)->child;
+ if (child)
+ gtk_widget_get_child_requisition (child, &child_req);
- widget->allocation = *allocation;
+ widget->allocation = *allocation;
gtk_widget_get_child_requisition (priv->caption_area, &req);
- allocA.height = allocB.height = allocation->height;
- allocA.width = allocB.width = allocation->width;
- allocA.x = allocB.x = allocB.y = allocA.y = 0;
+ child_alloc.height = caption_alloc.height = allocation->height;
+ child_alloc.width = caption_alloc.width = allocation->width;
+ child_alloc.x = caption_alloc.x = caption_alloc.y = child_alloc.y = 0;
/* Center the captioned widget */
- if (allocA.width > req.width + HILDON_CAPTION_SPACING)
+ if (rtl)
{
- allocA.x += req.width + HILDON_CAPTION_SPACING * 2;
- allocB.width = req.width;
+ if (caption_alloc.width > child_req.width + HILDON_CAPTION_SPACING)
+ {
+ caption_alloc.x = caption_alloc.width - req.width;
+ child_alloc.width = child_req.width;
+ }
+ caption_alloc.width -= child_req.width + HILDON_CAPTION_SPACING * 2;
}
+ else
+ {
+ if (child_alloc.width > req.width + HILDON_CAPTION_SPACING)
+ {
+ child_alloc.x += req.width + HILDON_CAPTION_SPACING * 2;
+ caption_alloc.width = req.width;
+ }
+ /* Leave at least the space of the HILDON_CAPTION_SPACING in the left */
+ caption_alloc.x = HILDON_CAPTION_SPACING;
- /* Leave at least the space of the HILDON_CAPTION_SPACING in the left */
- allocB.x = HILDON_CAPTION_SPACING;
-
- /* Leave room for the other drawable parts of the caption control */
- allocA.width -= req.width + HILDON_CAPTION_SPACING * 2;
+ /* Leave room for the other drawable parts of the caption control */
+ child_alloc.width -= req.width + HILDON_CAPTION_SPACING * 2;
+ }
/* Give the child at least its minimum requisition, unless it is expandable */
if (! priv->expand && child && GTK_WIDGET_VISIBLE(child))
{
- GtkRequisition child_req;
- gtk_widget_get_child_requisition (child, &child_req);
- allocA.width = MIN (allocA.width, child_req.width);
- allocA.height = MIN (allocA.height, child_req.height);
+ child_alloc.width = MIN (child_alloc.width, child_req.width);
+ child_alloc.height = MIN (child_alloc.height, child_req.height);
+ /* Center the child */
+ child_alloc.y = (allocation->height - child_alloc.height -
+ 2 * GTK_CONTAINER (widget)->border_width)/2;
}
/* Ensure there are no negative dimensions */
- if (allocA.width < 0)
+ if (child_alloc.width < 0)
{
- allocB.width = req.width + allocA.width;
- allocA.width = 0;
- allocB.width = MAX (allocB.width, 0);
+ caption_alloc.width = req.width + child_alloc.width;
+ child_alloc.width = 0;
+ caption_alloc.width = MAX (caption_alloc.width, 0);
}
- allocA.height = MAX (allocA.height, 0);
- allocB.height = MAX (allocB.height, 0);
+ if (rtl)
+ child_alloc.x = caption_alloc.x - child_req.width - HILDON_CAPTION_SPACING * 2;
+
+ child_alloc.height = MAX (child_alloc.height, 0);
+ caption_alloc.height = MAX (caption_alloc.height, 0);
if (child && GTK_WIDGET_VISIBLE(child) )
- gtk_widget_size_allocate( child, &allocA );
+ gtk_widget_size_allocate (child, &child_alloc );
- gtk_widget_size_allocate (priv->caption_area, &allocB);
+ gtk_widget_size_allocate (priv->caption_area, &caption_alloc);
}
static void
g_assert (callback != NULL);
priv = HILDON_CAPTION_GET_PRIVATE (container);
- g_assert (priv);
/* Execute callback for the child widgets */
if (GTK_CONTAINER_CLASS (parent_class)->forall)
}
/**
- * hildon_caption_set_sizegroup:
+ * hildon_caption_set_size_group:
* @caption : a #HildonCaption
* @new_group : a #GtkSizeGroup
*
}
/**
- * hildon_caption_get_sizegroup:
+ * hildon_caption_get_size_group:
* @caption : a #HildonCaption
*
* Query given captioned control for the #GtkSizeGroup assigned to it.
*
- * @Returns : a #GtkSizeGroup
+ * Returns: a #GtkSizeGroup
*
*/
GtkSizeGroup*
g_return_val_if_fail (HILDON_IS_CAPTION (self), NULL);
priv = HILDON_CAPTION_GET_PRIVATE(self);
- g_assert (priv);
return priv->group;
}
* The default behaviour for the caption's activate signal is to call
* gtk_widget_activate on it's control.
*
- * @Returns : a #GtkWidget pointer of Caption
+ * Returns: a #GtkWidget pointer of Caption
*/
GtkWidget*
hildon_caption_new (GtkSizeGroup *group,
"status", flag,
NULL);
+ /* Do not expand GtkCheckButton by default, we want to reduce its activation area */
+ if (GTK_IS_CHECK_BUTTON (child))
+ hildon_caption_set_child_expand (HILDON_CAPTION (widget), FALSE);
+
return widget;
}
*
* Query #HildonCaption whether this captioned control is a mandatory one.
*
- * @Returns : is this captioned control a mandatory one?
+ * Returns: is this captioned control a mandatory one?
*/
gboolean
hildon_caption_is_mandatory (const HildonCaption *caption)
g_return_val_if_fail (HILDON_IS_CAPTION (caption), FALSE);
priv = HILDON_CAPTION_GET_PRIVATE (caption);
- g_assert (priv);
return (priv->status == HILDON_CAPTION_MANDATORY);
}
{
g_return_if_fail (HILDON_IS_CAPTION (caption));
HildonCaptionPrivate *priv = HILDON_CAPTION_GET_PRIVATE (caption);
- g_assert (priv);
g_return_if_fail (priv->caption_area != NULL);
*
* Gets #HildonCaption icon position.
*
- * @Returns : one of the values from #HildonCaptionIconPosition.
+ * Returns: one of the values from #HildonCaptionIconPosition.
*
*/
g_return_val_if_fail (HILDON_IS_CAPTION (caption), 0);
HildonCaptionPrivate *priv = HILDON_CAPTION_GET_PRIVATE (caption);
- g_assert (priv);
return priv->icon_position;
}
/**
* hildon_caption_get_status:
- * @caption : a #HildonCaption
+ * @caption: a #HildonCaption
*
* Gets #HildonCaption status.
*
- * @Returns : one of the values from #HildonCaptionStatus
+ * Returns: one of the values from #HildonCaptionStatus
*/
HildonCaptionStatus
hildon_caption_get_status (const HildonCaption *caption)
g_return_val_if_fail (HILDON_IS_CAPTION (caption), HILDON_CAPTION_OPTIONAL);
priv = HILDON_CAPTION_GET_PRIVATE(caption);
- g_assert (priv);
return priv->status;
}
*
* Gets icon of #HildonCaption
*
- * @Returns : the #GtkImage widget that is being used as the icon by the
+ * Returns: the #GtkImage widget that is being used as the icon by the
* hildon_caption, or NULL if no icon image is in use.
*/
GtkWidget*
g_return_val_if_fail (HILDON_IS_CAPTION (caption), NULL);
priv = HILDON_CAPTION_GET_PRIVATE (caption);
- g_assert (priv);
return priv->icon;
}
hildon_caption_set_label (HildonCaption *caption,
const gchar *label)
{
- g_return_if_fail (HILDON_IS_CAPTION(caption));
+ g_return_if_fail (HILDON_IS_CAPTION (caption));
g_object_set (G_OBJECT(caption), "label", label, NULL);
}
/**
+ * hildon_caption_set_label_markup:
+ * @caption : a #HildonCaption
+ * @markup : the markup text to use
+ *
+ * Sets the label markup text that appears before the control. It acts like
+ * #hildon_caption_set_label but is using the markup text that allows to specify
+ * text properties such as bold or italic.
+ */
+void
+hildon_caption_set_label_markup (HildonCaption *caption,
+ const gchar *markup)
+{
+ g_return_if_fail (HILDON_IS_CAPTION (caption));
+
+ g_object_set (G_OBJECT(caption), "markup", markup, NULL);
+}
+
+/**
* hildon_caption_get_label:
* @caption : a #HildonCaption
*
* Gets label of #HildonCaption
*
- * @Returns : the text currently being used as the label of the caption
+ * Returns: the text currently being used as the label of the caption
* control. The string is owned by the label and the caller should never
* free or modify this value.
*/
HildonCaptionPrivate *priv;
g_return_val_if_fail (HILDON_IS_CAPTION (caption), "");
priv = HILDON_CAPTION_GET_PRIVATE (caption);
- g_assert (priv);
- return (gchar*) gtk_label_get_text (GTK_LABEL (GTK_LABEL (priv->label)));
+ return (gchar*) gtk_label_get_text (GTK_LABEL (priv->label));
}
/**
*
* Gets separator string of #HildonCaption
*
- * @Returns : the text currently being used as the separator of the caption
+ * Returns: the text currently being used as the separator of the caption
* control. The string is owned by the caption control and the caller should
* never free or modify this value.
*/
g_return_val_if_fail (HILDON_IS_CAPTION (caption), "");
priv = HILDON_CAPTION_GET_PRIVATE (caption);
- g_assert (priv);
return priv->separator;
}
gtk_widget_grab_focus (child);
}
+static void
+hildon_caption_grab_focus (GtkWidget *widget)
+{
+ gtk_widget_grab_focus (GTK_BIN (widget)->child);
+}
+
/**
* hildon_caption_set_child_expand:
* @caption : a #HildonCaption
g_return_if_fail (HILDON_IS_CAPTION (caption));
priv = HILDON_CAPTION_GET_PRIVATE (caption);
- g_assert (priv);
/* Did the setting really change? */
if (priv->expand == expand)
*
* Gets childs expandability.
*
- * @Returns : wheter the child is expandable or not.
+ * Returns: wheter the child is expandable or not.
*/
gboolean
hildon_caption_get_child_expand (const HildonCaption *caption)
g_return_val_if_fail (HILDON_IS_CAPTION (caption), FALSE);
priv = HILDON_CAPTION_GET_PRIVATE (caption);
- g_assert (priv);
return priv->expand;
}
static void
-hildon_caption_set_label_text (HildonCaptionPrivate *priv)
+hildon_caption_set_label_text (HildonCaptionPrivate *priv,
+ gboolean markup)
{
gchar *tmp = NULL;
g_assert (priv != NULL);
/* Don't duplicate the separator, if the string already contains one */
if (g_str_has_suffix (priv->text, priv->separator))
{
- gtk_label_set_text (GTK_LABEL (priv->label), priv->text);
+ if (markup)
+ gtk_label_set_markup (GTK_LABEL (priv->label), priv->text);
+ else
+ gtk_label_set_text (GTK_LABEL (priv->label), priv->text);
}
else
{
/* Append separator and set text */
tmp = g_strconcat( priv->text, priv->separator, NULL );
- gtk_label_set_text (GTK_LABEL( priv->label), tmp);
+
+ if (markup)
+ gtk_label_set_markup (GTK_LABEL (priv->label), tmp);
+ else
+ gtk_label_set_text (GTK_LABEL (priv->label), tmp);
+
g_free (tmp);
}
}
else
{
- gtk_label_set_text (GTK_LABEL (priv->label), priv->text);
+ if (markup)
+ gtk_label_set_markup (GTK_LABEL (priv->label), priv->text);
+ else
+ gtk_label_set_text (GTK_LABEL (priv->label), priv->text);
}
}
else
{
/* Clear the label */
- gtk_label_set_text (GTK_LABEL (priv->label), "" );
+ if (markup)
+ gtk_label_set_markup (GTK_LABEL (priv->label), "");
+ else
+ gtk_label_set_text (GTK_LABEL (priv->label), "" );
}
-
}
/**
g_return_if_fail (HILDON_IS_CAPTION (caption));
priv = HILDON_CAPTION_GET_PRIVATE (caption);
- g_assert (priv);
g_object_set (priv->label, "yalign", alignment, NULL);
g_object_set (priv->icon_align, "yalign", alignment, NULL);
g_return_val_if_fail (HILDON_IS_CAPTION (caption), 0);
priv = HILDON_CAPTION_GET_PRIVATE (caption);
- g_assert (priv);
g_object_get (priv->label, "yalign", &result, NULL);