2 * This file is a part of hildon
4 * Copyright (C) 2008 Nokia Corporation, all rights reserved.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser Public License as published by
8 * the Free Software Foundation; version 2 of the license.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Lesser Public License for more details.
18 * SECTION:hildon-entry
19 * @short_description: Text entry in the Hildon framework.
21 * The #HildonEntry is text entry derived from the #GtkEntry widget providing
22 * additional commodities specific to the Hildon framework.
24 * Besides all the features inherited from #GtkEntry, a #HildonEntry
25 * can also have a placeholder text. This text will be shown if the
26 * entry is empty and doesn't have the input focus, but it's otherwise
27 * ignored. Thus, calls to hildon_entry_get_text() will never return
28 * the placeholder text, not even when it's being displayed.
30 * Although #HildonEntry is derived from #GtkEntry,
31 * gtk_entry_get_text() and gtk_entry_set_text() must never be used to
32 * get/set the text in this widget. hildon_entry_get_text() and
33 * hildon_entry_set_text() must be used instead.
36 * <title>Creating a HildonEntry with a placeholder</title>
43 * entry = hildon_entry_new (HILDON_SIZE_AUTO);
44 * hildon_entry_set_placeholder (HILDON_ENTRY (entry), "First name");
52 #include "hildon-entry.h"
54 G_DEFINE_TYPE (HildonEntry, hildon_entry, GTK_TYPE_ENTRY);
60 #define HILDON_ENTRY_GET_PRIVATE(obj) \
61 (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
62 HILDON_TYPE_ENTRY, HildonEntryPrivate));
64 struct _HildonEntryPrivate
67 guint showing_placeholder : 1;
68 guint setting_style : 1;
72 set_property (GObject *object,
82 size = g_value_get_flags (value);
83 /* If this is auto height, default to finger height. */
84 if (!(size & (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_THUMB_HEIGHT)))
85 size |= HILDON_SIZE_FINGER_HEIGHT;
86 hildon_gtk_widget_set_theme_size (GTK_WIDGET (object), size);
89 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
95 set_logical_color (HildonEntry *entry)
98 const gchar *colorname;
99 GtkWidget *widget = GTK_WIDGET (entry);
100 HildonEntryPrivate *priv = entry->priv;
102 colorname = priv->showing_placeholder ? "ReversedSecondaryTextColor" : "ReversedTextColor";
104 gtk_widget_ensure_style (widget);
105 if (gtk_style_lookup_color (widget->style, colorname, &color) == TRUE) {
106 priv->setting_style = TRUE;
107 gtk_widget_modify_text (widget, GTK_STATE_NORMAL, &color);
108 priv->setting_style = FALSE;
113 hildon_entry_style_set (GtkWidget *widget,
114 GtkStyle *previous_style)
116 HildonEntry *entry = HILDON_ENTRY (widget);
118 if (GTK_WIDGET_CLASS (hildon_entry_parent_class)->style_set)
119 GTK_WIDGET_CLASS (hildon_entry_parent_class)->style_set (widget, previous_style);
121 /* Prevent infinite recursion when calling set_logical_font() and
122 * set_logical_color() */
123 if (entry->priv->setting_style)
126 set_logical_color (entry);
130 hildon_entry_show_placeholder (HildonEntry *entry)
132 HildonEntryPrivate *priv = HILDON_ENTRY (entry)->priv;
134 priv->showing_placeholder = TRUE;
135 gtk_entry_set_text (GTK_ENTRY (entry), priv->placeholder);
137 set_logical_color (entry);
141 hildon_entry_hide_placeholder (HildonEntry *entry, const gchar *text)
143 HildonEntryPrivate *priv = HILDON_ENTRY (entry)->priv;
145 priv->showing_placeholder = FALSE;
146 gtk_entry_set_text (GTK_ENTRY (entry), text);
148 set_logical_color (entry);
152 * hildon_entry_set_text:
153 * @entry: a #HildonEntry
154 * @text: the new text
156 * Sets the text in @entry to @text, replacing its current contents.
158 * Note that you must never use gtk_entry_set_text() to set the text
164 hildon_entry_set_text (HildonEntry *entry,
167 g_return_if_fail (HILDON_IS_ENTRY (entry) && text != NULL);
169 if (text[0] == '\0' && !GTK_WIDGET_HAS_FOCUS (entry)) {
170 hildon_entry_show_placeholder (entry);
172 hildon_entry_hide_placeholder (entry, text);
177 * hildon_entry_get_text:
178 * @entry: a #HildonEntry
180 * Gets the current text in @entry.
182 * Note that you must never use gtk_entry_get_text() to get the text
183 * from a #HildonEntry.
185 * Also note that placeholder text (set using
186 * hildon_entry_set_placeholder()) is never returned. Only text set by
187 * hildon_entry_set_text() or typed by the user is considered.
189 * Returns: the text in @entry. This text must not be modified or
195 hildon_entry_get_text (HildonEntry *entry)
197 g_return_val_if_fail (HILDON_IS_ENTRY (entry), NULL);
199 if (entry->priv->showing_placeholder) {
203 return gtk_entry_get_text (GTK_ENTRY (entry));
207 * hildon_entry_set_placeholder:
208 * @entry: a #HildonEntry
209 * @text: the new text
211 * Sets the placeholder text in @entry to @text.
216 hildon_entry_set_placeholder (HildonEntry *entry,
219 g_return_if_fail (HILDON_IS_ENTRY (entry) && text != NULL);
221 g_free (entry->priv->placeholder);
222 entry->priv->placeholder = g_strdup (text);
224 /* Show the placeholder if it needs to be updated or if should be shown now. */
225 if (entry->priv->showing_placeholder ||
226 (!GTK_WIDGET_HAS_FOCUS (entry) && gtk_entry_get_text (GTK_ENTRY (entry)) [0] == '\0')) {
227 hildon_entry_show_placeholder (entry);
233 * @size: The size of the entry
235 * Creates a new entry.
237 * Returns: a new #HildonEntry
242 hildon_entry_new (HildonSizeType size)
244 return g_object_new (HILDON_TYPE_ENTRY, "size", size, NULL);
248 hildon_entry_focus_in_event (GtkWidget *widget,
249 GdkEventFocus *event)
251 if (HILDON_ENTRY (widget)->priv->showing_placeholder) {
252 hildon_entry_hide_placeholder (HILDON_ENTRY (widget), "");
255 if (GTK_WIDGET_CLASS (hildon_entry_parent_class)->focus_in_event) {
256 return GTK_WIDGET_CLASS (hildon_entry_parent_class)->focus_in_event (widget, event);
263 hildon_entry_focus_out_event (GtkWidget *widget,
264 GdkEventFocus *event)
266 if (gtk_entry_get_text (GTK_ENTRY (widget)) [0] == '\0') {
267 hildon_entry_show_placeholder (HILDON_ENTRY (widget));
270 if (GTK_WIDGET_CLASS (hildon_entry_parent_class)->focus_out_event) {
271 return GTK_WIDGET_CLASS (hildon_entry_parent_class)->focus_out_event (widget, event);
278 hildon_entry_finalize (GObject *object)
280 HildonEntryPrivate *priv = HILDON_ENTRY (object)->priv;
282 g_free (priv->placeholder);
284 if (G_OBJECT_CLASS (hildon_entry_parent_class)->finalize)
285 G_OBJECT_CLASS (hildon_entry_parent_class)->finalize (object);
289 hildon_entry_class_init (HildonEntryClass *klass)
291 GObjectClass *gobject_class = (GObjectClass *)klass;
292 GtkWidgetClass *widget_class = (GtkWidgetClass *)klass;
294 gobject_class->set_property = set_property;
295 gobject_class->finalize = hildon_entry_finalize;
296 widget_class->focus_in_event = hildon_entry_focus_in_event;
297 widget_class->focus_out_event = hildon_entry_focus_out_event;
298 widget_class->style_set = hildon_entry_style_set;
300 g_object_class_install_property (
306 "Size request for the entry",
307 HILDON_TYPE_SIZE_TYPE,
308 HILDON_SIZE_AUTO_WIDTH | HILDON_SIZE_FINGER_HEIGHT,
309 G_PARAM_CONSTRUCT | G_PARAM_WRITABLE));
311 g_type_class_add_private (klass, sizeof (HildonEntryPrivate));
315 hildon_entry_init (HildonEntry *self)
317 self->priv = HILDON_ENTRY_GET_PRIVATE (self);
318 self->priv->placeholder = g_strdup ("");
319 self->priv->showing_placeholder = FALSE;
320 self->priv->setting_style = FALSE;