Fix compilation warnings
[hildon] / src / 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
55 G_DEFINE_TYPE                                   (HildonEntry, hildon_entry, GTK_TYPE_ENTRY);
56
57 #define                                         HILDON_ENTRY_GET_PRIVATE(obj) \
58                                                 (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
59                                                 HILDON_TYPE_ENTRY, HildonEntryPrivate));
60
61 struct                                          _HildonEntryPrivate
62 {
63     gchar *placeholder;
64 };
65
66 static const gchar *placeholder_widget_name     = "hildon-entry-placeholder";
67
68 /* Function used to decide whether to show the placeholder or not */
69 static void
70 hildon_entry_refresh_contents                   (GtkWidget *entry)
71 {
72     HildonEntryPrivate *priv = HILDON_ENTRY (entry)->priv;
73     gboolean showing_placeholder, entry_has_focus;
74
75     showing_placeholder = g_str_equal (gtk_widget_get_name (entry), placeholder_widget_name);
76     entry_has_focus = GTK_WIDGET_HAS_FOCUS (entry);
77
78     if (showing_placeholder) {
79         if (entry_has_focus) {
80             /* Remove the placeholder when the widget obtains focus */
81             gtk_widget_set_name (entry, NULL);
82             gtk_entry_set_text (GTK_ENTRY (entry), "");
83         } else {
84             /* Update the placeholder (it may have been changed) */
85             gtk_entry_set_text (GTK_ENTRY (entry), priv->placeholder);
86         }
87     } else {
88         /* Show the placeholder when the widget is empty and has no focus */
89         const gchar *text = gtk_entry_get_text (GTK_ENTRY (entry));
90         if (text[0] == '\0' && !entry_has_focus) {
91             if (priv->placeholder[0] != '\0') {
92                 gtk_widget_set_name (entry, placeholder_widget_name);
93                 gtk_entry_set_text (GTK_ENTRY (entry), priv->placeholder);
94             }
95         }
96     }
97 }
98
99 /**
100  * hildon_entry_set_text:
101  * @entry: a #HildonEntry
102  * @text: the new text
103  *
104  * Sets the text in @entry to @text, replacing its current contents.
105  *
106  * Note that you must never use gtk_entry_set_text() to set the text
107  * of a #HildonEntry.
108  *
109  * Since: 2.2
110  */
111 void
112 hildon_entry_set_text                           (HildonEntry *entry,
113                                                  const gchar *text)
114 {
115     g_return_if_fail (HILDON_IS_ENTRY (entry) && text != NULL);
116
117     gtk_widget_set_name (GTK_WIDGET (entry), NULL);
118     gtk_entry_set_text (GTK_ENTRY (entry), text);
119
120     /* If the entry is cleared show the placeholder */
121     if (text[0] == '\0')
122         hildon_entry_refresh_contents (GTK_WIDGET (entry));
123 }
124
125 /**
126  * hildon_entry_get_text:
127  * @entry: a #HildonEntry
128  *
129  * Gets the current text in @entry.
130  *
131  * Note that you must never use gtk_entry_get_text() to get the text
132  * from a #HildonEntry.
133  *
134  * Also note that placeholder text (set using
135  * hildon_entry_set_placeholder()) is never returned. Only text set by
136  * hildon_entry_set_text() or typed by the user is considered.
137  *
138  * Returns: the text in @entry. This text must not be modified or
139  * freed.
140  *
141  * Since: 2.2
142  */
143 const gchar *
144 hildon_entry_get_text                           (HildonEntry *entry)
145 {
146     g_return_val_if_fail (HILDON_IS_ENTRY (entry), NULL);
147
148     if (g_str_equal (gtk_widget_get_name (GTK_WIDGET (entry)), placeholder_widget_name)) {
149         return "";
150     }
151
152     return gtk_entry_get_text (GTK_ENTRY (entry));
153 }
154
155 /**
156  * hildon_entry_set_placeholder:
157  * @entry: a #HildonEntry
158  * @text: the new text
159  *
160  * Sets the placeholder text in @entry to @text.
161  *
162  * Since: 2.2
163  */
164 void
165 hildon_entry_set_placeholder                    (HildonEntry *entry,
166                                                  const gchar *text)
167 {
168     g_return_if_fail (HILDON_IS_ENTRY (entry) && text != NULL);
169
170     g_free (entry->priv->placeholder);
171     entry->priv->placeholder = g_strdup (text);
172     hildon_entry_refresh_contents (GTK_WIDGET (entry));
173 }
174
175 /**
176  * hildon_entry_new:
177  * @size: The size of the entry
178  *
179  * Creates a new entry.
180  *
181  * Returns: a new #HildonEntry
182  *
183  * Since: 2.2
184  */
185 GtkWidget *
186 hildon_entry_new                                (HildonSizeType size)
187 {
188     GtkWidget *entry = g_object_new (HILDON_TYPE_ENTRY, NULL);
189
190     hildon_gtk_widget_set_theme_size (entry, size);
191
192     return entry;
193 }
194
195 static gboolean
196 hildon_entry_focus_in_event                     (GtkWidget     *widget,
197                                                  GdkEventFocus *event)
198 {
199     hildon_entry_refresh_contents (widget);
200
201     if (GTK_WIDGET_CLASS (hildon_entry_parent_class)->focus_in_event) {
202         return GTK_WIDGET_CLASS (hildon_entry_parent_class)->focus_in_event (widget, event);
203     } else {
204         return FALSE;
205     }
206 }
207
208 static gboolean
209 hildon_entry_focus_out_event                    (GtkWidget     *widget,
210                                                  GdkEventFocus *event)
211 {
212     hildon_entry_refresh_contents (widget);
213
214     if (GTK_WIDGET_CLASS (hildon_entry_parent_class)->focus_out_event) {
215         return GTK_WIDGET_CLASS (hildon_entry_parent_class)->focus_out_event (widget, event);
216     } else {
217         return FALSE;
218     }
219 }
220
221 static void
222 hildon_entry_finalize                           (GObject *object)
223 {
224     HildonEntryPrivate *priv = HILDON_ENTRY (object)->priv;
225
226     g_free (priv->placeholder);
227
228     if (G_OBJECT_CLASS (hildon_entry_parent_class)->finalize)
229         G_OBJECT_CLASS (hildon_entry_parent_class)->finalize (object);
230 }
231
232 static void
233 hildon_entry_class_init                         (HildonEntryClass *klass)
234 {
235     GObjectClass *gobject_class = (GObjectClass *)klass;
236     GtkWidgetClass *widget_class = (GtkWidgetClass *)klass;
237
238     gobject_class->finalize = hildon_entry_finalize;
239     widget_class->focus_in_event = hildon_entry_focus_in_event;
240     widget_class->focus_out_event = hildon_entry_focus_out_event;
241
242     g_type_class_add_private (klass, sizeof (HildonEntryPrivate));
243 }
244
245 static void
246 hildon_entry_init                               (HildonEntry *self)
247 {
248     self->priv = HILDON_ENTRY_GET_PRIVATE (self);
249     self->priv->placeholder = g_strdup ("");
250 }