Fix debian/changelog
[hildon] / hildon / hildon-entry.c
1 /*
2  * This file is a part of hildon
3  *
4  * Copyright (C) 2008 Nokia Corporation, all rights reserved.
5  *
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.
9  *
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.
14  *
15  */
16
17 /**
18  * SECTION:hildon-entry
19  * @short_description: Widget representing a text entry in the Hildon framework.
20  *
21  * The #HildonEntry is a GTK widget which represents a text entry. It
22  * is derived from the #GtkEntry widget and provides additional
23  * commodities specific to the Hildon framework.
24  *
25  * Besides all the features inherited from #GtkEntry, a #HildonEntry
26  * can also have a placeholder text. This text will be shown if the
27  * entry is empty and doesn't have the input focus, but it's otherwise
28  * ignored. Thus, calls to hildon_entry_get_text() will never return
29  * the placeholder text, not even when it's being displayed.
30  *
31  * Although #HildonEntry is derived from #GtkEntry,
32  * gtk_entry_get_text() and gtk_entry_set_text() must never be used to
33  * get/set the text in this widget. hildon_entry_get_text() and
34  * hildon_entry_set_text() must be used instead.
35  *
36  * <example>
37  * <title>Creating a HildonEntry with a placeholder</title>
38  * <programlisting>
39  * GtkWidget *
40  * create_entry (void)
41  * {
42  *     GtkWidget *entry;
43  * <!-- -->
44  *     entry = hildon_entry_new (HILDON_SIZE_AUTO);
45  *     hildon_entry_set_placeholder (HILDON_ENTRY (entry), "First name");
46  * <!-- -->
47  *     return entry;
48  * }
49  * </programlisting>
50  * </example>
51  */
52
53 #include                                        "hildon-entry.h"
54 #include                                        "hildon-helper.h"
55
56 G_DEFINE_TYPE                                   (HildonEntry, hildon_entry, GTK_TYPE_ENTRY);
57
58 #define                                         HILDON_ENTRY_GET_PRIVATE(obj) \
59                                                 (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
60                                                 HILDON_TYPE_ENTRY, HildonEntryPrivate));
61
62 struct                                          _HildonEntryPrivate
63 {
64     gchar *placeholder;
65     gboolean showing_placeholder;
66 };
67
68 static void
69 hildon_entry_show_placeholder (HildonEntry *entry)
70 {
71     HildonEntryPrivate *priv = HILDON_ENTRY (entry)->priv;
72
73     priv->showing_placeholder = TRUE;
74     gtk_entry_set_text (GTK_ENTRY (entry), priv->placeholder);
75     hildon_helper_set_logical_color (GTK_WIDGET (entry),
76                                      GTK_RC_TEXT, GTK_STATE_NORMAL, "ReversedSecondaryTextColor");
77 }
78
79 static void
80 hildon_entry_hide_placeholder (HildonEntry *entry, const gchar *text)
81 {
82     HildonEntryPrivate *priv = HILDON_ENTRY (entry)->priv;
83
84     priv->showing_placeholder = FALSE;
85     gtk_entry_set_text (GTK_ENTRY (entry), text);
86     hildon_helper_set_logical_color (GTK_WIDGET (entry),
87                                      GTK_RC_TEXT, GTK_STATE_NORMAL, "ReversedTextColor");
88 }
89
90 /**
91  * hildon_entry_set_text:
92  * @entry: a #HildonEntry
93  * @text: the new text
94  *
95  * Sets the text in @entry to @text, replacing its current contents.
96  *
97  * Note that you must never use gtk_entry_set_text() to set the text
98  * of a #HildonEntry.
99  *
100  * Since: 2.2
101  */
102 void
103 hildon_entry_set_text                           (HildonEntry *entry,
104                                                  const gchar *text)
105 {
106     g_return_if_fail (HILDON_IS_ENTRY (entry) && text != NULL);
107
108     if (text[0] == '\0' && !GTK_WIDGET_HAS_FOCUS (entry)) {
109             hildon_entry_show_placeholder (entry);
110     } else {
111             hildon_entry_hide_placeholder (entry, text);
112     }
113 }
114
115 /**
116  * hildon_entry_get_text:
117  * @entry: a #HildonEntry
118  *
119  * Gets the current text in @entry.
120  *
121  * Note that you must never use gtk_entry_get_text() to get the text
122  * from a #HildonEntry.
123  *
124  * Also note that placeholder text (set using
125  * hildon_entry_set_placeholder()) is never returned. Only text set by
126  * hildon_entry_set_text() or typed by the user is considered.
127  *
128  * Returns: the text in @entry. This text must not be modified or
129  * freed.
130  *
131  * Since: 2.2
132  */
133 const gchar *
134 hildon_entry_get_text                           (HildonEntry *entry)
135 {
136     g_return_val_if_fail (HILDON_IS_ENTRY (entry), NULL);
137
138     if (entry->priv->showing_placeholder) {
139         return "";
140     }
141
142     return gtk_entry_get_text (GTK_ENTRY (entry));
143 }
144
145 /**
146  * hildon_entry_set_placeholder:
147  * @entry: a #HildonEntry
148  * @text: the new text
149  *
150  * Sets the placeholder text in @entry to @text.
151  *
152  * Since: 2.2
153  */
154 void
155 hildon_entry_set_placeholder                    (HildonEntry *entry,
156                                                  const gchar *text)
157 {
158     g_return_if_fail (HILDON_IS_ENTRY (entry) && text != NULL);
159
160     g_free (entry->priv->placeholder);
161     entry->priv->placeholder = g_strdup (text);
162
163     /* Show the placeholder if it needs to be updated or if should be shown now. */
164     if (entry->priv->showing_placeholder ||
165         (!GTK_WIDGET_HAS_FOCUS (entry) && gtk_entry_get_text (GTK_ENTRY (entry)) [0] == '\0')) {
166         hildon_entry_show_placeholder (entry);
167     }
168 }
169
170 /**
171  * hildon_entry_new:
172  * @size: The size of the entry
173  *
174  * Creates a new entry.
175  *
176  * Returns: a new #HildonEntry
177  *
178  * Since: 2.2
179  */
180 GtkWidget *
181 hildon_entry_new                                (HildonSizeType size)
182 {
183     GtkWidget *entry = g_object_new (HILDON_TYPE_ENTRY, NULL);
184
185     hildon_gtk_widget_set_theme_size (entry, size);
186
187     return entry;
188 }
189
190 static gboolean
191 hildon_entry_focus_in_event                     (GtkWidget     *widget,
192                                                  GdkEventFocus *event)
193 {
194     if (HILDON_ENTRY (widget)->priv->showing_placeholder) {
195             hildon_entry_hide_placeholder (HILDON_ENTRY (widget), "");
196     }
197
198     if (GTK_WIDGET_CLASS (hildon_entry_parent_class)->focus_in_event) {
199         return GTK_WIDGET_CLASS (hildon_entry_parent_class)->focus_in_event (widget, event);
200     } else {
201         return FALSE;
202     }
203 }
204
205 static gboolean
206 hildon_entry_focus_out_event                    (GtkWidget     *widget,
207                                                  GdkEventFocus *event)
208 {
209     if (gtk_entry_get_text (GTK_ENTRY (widget)) [0] == '\0') {
210         hildon_entry_show_placeholder (HILDON_ENTRY (widget));
211     }
212
213     if (GTK_WIDGET_CLASS (hildon_entry_parent_class)->focus_out_event) {
214         return GTK_WIDGET_CLASS (hildon_entry_parent_class)->focus_out_event (widget, event);
215     } else {
216         return FALSE;
217     }
218 }
219
220 static void
221 hildon_entry_finalize                           (GObject *object)
222 {
223     HildonEntryPrivate *priv = HILDON_ENTRY (object)->priv;
224
225     g_free (priv->placeholder);
226
227     if (G_OBJECT_CLASS (hildon_entry_parent_class)->finalize)
228         G_OBJECT_CLASS (hildon_entry_parent_class)->finalize (object);
229 }
230
231 static void
232 hildon_entry_class_init                         (HildonEntryClass *klass)
233 {
234     GObjectClass *gobject_class = (GObjectClass *)klass;
235     GtkWidgetClass *widget_class = (GtkWidgetClass *)klass;
236
237     gobject_class->finalize = hildon_entry_finalize;
238     widget_class->focus_in_event = hildon_entry_focus_in_event;
239     widget_class->focus_out_event = hildon_entry_focus_out_event;
240
241     g_type_class_add_private (klass, sizeof (HildonEntryPrivate));
242 }
243
244 static void
245 hildon_entry_init                               (HildonEntry *self)
246 {
247     self->priv = HILDON_ENTRY_GET_PRIVATE (self);
248     self->priv->placeholder = g_strdup ("");
249     self->priv->showing_placeholder = FALSE;
250 }