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-text-view
19 * @short_description: Widget representing a text view in the Hildon framework.
21 * The #HildonTextView is a GTK widget which represents a text
22 * view. It is derived from the #GtkTextView widget and provides
23 * additional commodities specific to the Hildon framework.
25 * Besides all the features inherited from #GtkTextView, a
26 * #HildonTextView can also have a placeholder text. This text will be
27 * shown if the text view is empty and doesn't have the input focus,
28 * but it's otherwise ignored. Thus, calls to
29 * hildon_text_view_get_buffer() will never return the placeholder
30 * text, not even when it's being displayed.
32 * Although #HildonTextView is derived from #GtkTextView,
33 * gtk_text_view_get_buffer() and gtk_text_view_set_buffer() must
34 * never be used to get/set the buffer in this
35 * widget. hildon_text_view_get_buffer() and
36 * hildon_text_view_set_buffer() must be used instead.
39 #include "hildon-text-view.h"
41 G_DEFINE_TYPE (HildonTextView, hildon_text_view, GTK_TYPE_TEXT_VIEW);
43 #define HILDON_TEXT_VIEW_GET_PRIVATE(obj) \
44 (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
45 HILDON_TYPE_TEXT_VIEW, HildonTextViewPrivate));
47 typedef struct _HildonTextViewPrivate HildonTextViewPrivate;
49 struct _HildonTextViewPrivate
51 GtkTextBuffer *main_buffer; /* Used to show the "real" contents */
52 GtkTextBuffer *placeholder_buffer; /* Internal, used to display the placeholder */
53 gulong changed_id; /* ID of the main_buffer::changed signal handler */
56 static const gchar *placeholder_widget_name = "hildon-text-view-placeholder";
58 /* Function used to decide whether to show the placeholder or not */
60 hildon_text_view_refresh_contents (GtkWidget *text_view)
62 HildonTextViewPrivate *priv = HILDON_TEXT_VIEW_GET_PRIVATE (text_view);
63 gint bufsize = gtk_text_buffer_get_char_count (priv->main_buffer);
65 if ((bufsize > 0) || GTK_WIDGET_HAS_FOCUS (text_view)) {
66 /* Display the main buffer if it contains text or the widget is focused */
67 gtk_widget_set_name (text_view, NULL);
68 gtk_text_view_set_buffer (GTK_TEXT_VIEW (text_view), priv->main_buffer);
70 /* Otherwise, display the placeholder */
71 gtk_widget_set_name (text_view, placeholder_widget_name);
72 gtk_text_view_set_buffer (GTK_TEXT_VIEW (text_view), priv->placeholder_buffer);
77 * hildon_text_view_set_buffer:
78 * @text_view: a #HildonTextView
79 * @buffer: a #GtkTextBuffer
81 * Sets @buffer as the buffer being displayed by @text_view. The
82 * previous buffer displayed by the text view is unreferenced, and a
83 * reference is added to @buffer. If you owned a reference to @buffer
84 * before passing it to this function, you must remove that reference
87 * Note that you must never use gtk_text_view_set_buffer() to set the
88 * buffer of a #HildonTextView.
91 hildon_text_view_set_buffer (HildonTextView *text_view,
92 GtkTextBuffer *buffer)
94 HildonTextViewPrivate *priv;
96 g_return_if_fail (HILDON_IS_TEXT_VIEW (text_view));
97 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
99 priv = HILDON_TEXT_VIEW_GET_PRIVATE (text_view);
101 /* If this is the same buffer, don't do anything */
102 if (buffer == priv->main_buffer)
105 /* Disconnect the signal handler from the old buffer */
106 g_signal_handler_disconnect (priv->main_buffer, priv->changed_id);
108 /* Replace the old buffer with the new one */
109 g_object_unref (priv->main_buffer);
110 priv->main_buffer = g_object_ref (buffer);
112 /* Attach a callback to the new text buffer */
114 g_signal_connect_swapped (priv->main_buffer, "changed",
115 G_CALLBACK (hildon_text_view_refresh_contents), text_view);
117 /* Refresh textview contents */
118 hildon_text_view_refresh_contents (GTK_WIDGET (text_view));
122 * hildon_text_view_get_buffer:
123 * @text_view: a #HildonTextView
125 * Returns the text buffer in @text_view. The reference count is not
126 * incremented; the caller of this function won't own a new reference.
128 * Note that you must never use gtk_text_view_get_buffer() to get the
129 * buffer from a #HildonTextView.
131 * Also note that placeholder text (set using
132 * hildon_text_view_set_placeholder()) is never contained in this
135 * Returns: a #GtkTextBuffer
138 hildon_text_view_get_buffer (HildonTextView *text_view)
140 HildonTextViewPrivate *priv;
142 g_return_val_if_fail (HILDON_IS_TEXT_VIEW (text_view), NULL);
144 priv = HILDON_TEXT_VIEW_GET_PRIVATE (text_view);
146 /* Always return priv->main_buffer even if the placeholder is
148 return priv->main_buffer;
152 * hildon_text_view_set_placeholder:
153 * @text_view: a #HildonTextView
154 * @text: the new text
156 * Sets the placeholder text in @text_view to @text.
159 hildon_text_view_set_placeholder (HildonTextView *text_view,
162 HildonTextViewPrivate *priv;
164 g_return_if_fail (HILDON_IS_TEXT_VIEW (text_view) && text != NULL);
166 priv = HILDON_TEXT_VIEW_GET_PRIVATE (text_view);
168 gtk_text_buffer_set_text (priv->placeholder_buffer, text, -1);
172 * hildon_text_view_new:
174 * Creates a new text view.
176 * Returns: a new #HildonTextView
179 hildon_text_view_new (void)
181 GtkWidget *entry = g_object_new (HILDON_TYPE_TEXT_VIEW, NULL);
187 hildon_text_view_focus_in_event (GtkWidget *widget,
188 GdkEventFocus *event)
190 hildon_text_view_refresh_contents (widget);
192 if (GTK_WIDGET_CLASS (hildon_text_view_parent_class)->focus_in_event) {
193 return GTK_WIDGET_CLASS (hildon_text_view_parent_class)->focus_in_event (widget, event);
200 hildon_text_view_focus_out_event (GtkWidget *widget,
201 GdkEventFocus *event)
203 hildon_text_view_refresh_contents (widget);
205 if (GTK_WIDGET_CLASS (hildon_text_view_parent_class)->focus_out_event) {
206 return GTK_WIDGET_CLASS (hildon_text_view_parent_class)->focus_out_event (widget, event);
213 hildon_text_view_finalize (GObject *object)
215 HildonTextViewPrivate *priv = HILDON_TEXT_VIEW_GET_PRIVATE (object);
217 g_signal_handler_disconnect (priv->main_buffer, priv->changed_id);
218 g_object_unref (priv->main_buffer);
219 g_object_unref (priv->placeholder_buffer);
221 if (G_OBJECT_CLASS (hildon_text_view_parent_class)->finalize)
222 G_OBJECT_CLASS (hildon_text_view_parent_class)->finalize (object);
226 hildon_text_view_class_init (HildonTextViewClass *klass)
228 GObjectClass *gobject_class = (GObjectClass *)klass;
229 GtkWidgetClass *widget_class = (GtkWidgetClass *)klass;
231 gobject_class->finalize = hildon_text_view_finalize;
232 widget_class->focus_in_event = hildon_text_view_focus_in_event;
233 widget_class->focus_out_event = hildon_text_view_focus_out_event;
235 g_type_class_add_private (klass, sizeof (HildonTextViewPrivate));
239 hildon_text_view_init (HildonTextView *self)
241 HildonTextViewPrivate *priv = HILDON_TEXT_VIEW_GET_PRIVATE (self);
243 priv->main_buffer = gtk_text_buffer_new (NULL);
244 priv->placeholder_buffer = gtk_text_buffer_new (NULL);
246 hildon_text_view_refresh_contents (GTK_WIDGET (self));
249 g_signal_connect_swapped (priv->main_buffer, "changed",
250 G_CALLBACK (hildon_text_view_refresh_contents), self);