*
* Copyright (C) 2008 Nokia Corporation, all rights reserved.
*
- * Contact: Karl Lattimer <karl.lattimer@nokia.com>
- *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser Public License as published by
* the Free Software Foundation; version 2 of the license.
* gtk_entry_get_text() and gtk_entry_set_text() must never be used to
* get/set the text in this widget. hildon_entry_get_text() and
* hildon_entry_set_text() must be used instead.
+ *
+ * <example>
+ * <title>Creating a HildonEntry with a placeholder</title>
+ * <programlisting>
+ * GtkWidget *
+ * create_entry (void)
+ * {
+ * GtkWidget *entry;
+ * <!-- -->
+ * entry = hildon_entry_new (HILDON_SIZE_AUTO);
+ * hildon_entry_set_placeholder (HILDON_ENTRY (entry), "First name");
+ * <!-- -->
+ * return entry;
+ * }
+ * </programlisting>
+ * </example>
*/
#include "hildon-entry.h"
G_DEFINE_TYPE (HildonEntry, hildon_entry, GTK_TYPE_ENTRY);
+#define HILDON_ENTRY_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
+ HILDON_TYPE_ENTRY, HildonEntryPrivate));
+
+struct _HildonEntryPrivate
+{
+ gchar *placeholder;
+};
+
static const gchar *placeholder_widget_name = "hildon-entry-placeholder";
+/* Function used to decide whether to show the placeholder or not */
+static void
+hildon_entry_refresh_contents (GtkWidget *entry)
+{
+ HildonEntryPrivate *priv = HILDON_ENTRY (entry)->priv;
+ gboolean showing_placeholder, entry_has_focus;
+
+ showing_placeholder = g_str_equal (gtk_widget_get_name (entry), placeholder_widget_name);
+ entry_has_focus = GTK_WIDGET_HAS_FOCUS (entry);
+
+ if (showing_placeholder) {
+ if (entry_has_focus) {
+ /* Remove the placeholder when the widget obtains focus */
+ gtk_widget_set_name (entry, NULL);
+ gtk_entry_set_text (GTK_ENTRY (entry), "");
+ } else {
+ /* Update the placeholder (it may have been changed) */
+ gtk_entry_set_text (GTK_ENTRY (entry), priv->placeholder);
+ }
+ } else {
+ /* Show the placeholder when the widget is empty and has no focus */
+ const gchar *text = gtk_entry_get_text (GTK_ENTRY (entry));
+ if (text[0] == '\0' && !entry_has_focus) {
+ if (priv->placeholder[0] != '\0') {
+ gtk_widget_set_name (entry, placeholder_widget_name);
+ gtk_entry_set_text (GTK_ENTRY (entry), priv->placeholder);
+ }
+ }
+ }
+}
+
/**
* hildon_entry_set_text:
* @entry: a #HildonEntry
hildon_entry_set_text (HildonEntry *entry,
const gchar *text)
{
- g_return_if_fail (HILDON_IS_ENTRY (entry));
+ g_return_if_fail (HILDON_IS_ENTRY (entry) && text != NULL);
+ gtk_widget_set_name (GTK_WIDGET (entry), NULL);
gtk_entry_set_text (GTK_ENTRY (entry), text);
- gtk_widget_set_name (GTK_WIDGET (entry), NULL);
+ /* If the entry is cleared show the placeholder */
+ if (text[0] == '\0')
+ hildon_entry_refresh_contents (GTK_WIDGET (entry));
}
/**
hildon_entry_set_placeholder (HildonEntry *entry,
const gchar *text)
{
- g_return_if_fail (HILDON_IS_ENTRY (entry));
+ g_return_if_fail (HILDON_IS_ENTRY (entry) && text != NULL);
- gtk_widget_set_name (GTK_WIDGET (entry), placeholder_widget_name);
-
- gtk_entry_set_text (GTK_ENTRY (entry), text);
+ g_free (entry->priv->placeholder);
+ entry->priv->placeholder = g_strdup (text);
+ hildon_entry_refresh_contents (GTK_WIDGET (entry));
}
/**
hildon_entry_focus_in_event (GtkWidget *widget,
GdkEventFocus *event)
{
- if (g_str_equal (gtk_widget_get_name (widget), placeholder_widget_name)) {
- hildon_entry_set_text (HILDON_ENTRY (widget), "");
- }
+ hildon_entry_refresh_contents (widget);
+
if (GTK_WIDGET_CLASS (hildon_entry_parent_class)->focus_in_event) {
return GTK_WIDGET_CLASS (hildon_entry_parent_class)->focus_in_event (widget, event);
} else {
}
}
+static gboolean
+hildon_entry_focus_out_event (GtkWidget *widget,
+ GdkEventFocus *event)
+{
+ hildon_entry_refresh_contents (widget);
+
+ if (GTK_WIDGET_CLASS (hildon_entry_parent_class)->focus_out_event) {
+ return GTK_WIDGET_CLASS (hildon_entry_parent_class)->focus_out_event (widget, event);
+ } else {
+ return FALSE;
+ }
+}
+
+static void
+hildon_entry_finalize (GObject *object)
+{
+ HildonEntryPrivate *priv = HILDON_ENTRY (object)->priv;
+
+ g_free (priv->placeholder);
+
+ if (G_OBJECT_CLASS (hildon_entry_parent_class)->finalize)
+ G_OBJECT_CLASS (hildon_entry_parent_class)->finalize (object);
+}
+
static void
hildon_entry_class_init (HildonEntryClass *klass)
{
+ GObjectClass *gobject_class = (GObjectClass *)klass;
GtkWidgetClass *widget_class = (GtkWidgetClass *)klass;
+ gobject_class->finalize = hildon_entry_finalize;
widget_class->focus_in_event = hildon_entry_focus_in_event;
+ widget_class->focus_out_event = hildon_entry_focus_out_event;
+
+ g_type_class_add_private (klass, sizeof (HildonEntryPrivate));
}
static void
hildon_entry_init (HildonEntry *self)
{
+ self->priv = HILDON_ENTRY_GET_PRIVATE (self);
+ self->priv->placeholder = g_strdup ("");
}