Blob Blame History Raw
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Text Widget Overview: GTK+ 2 Reference Manual</title>
<meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
<link rel="home" href="index.html" title="GTK+ 2 Reference Manual">
<link rel="up" href="TextWidgetObjects.html" title="Multiline Text Editor">
<link rel="prev" href="TextWidgetObjects.html" title="Multiline Text Editor">
<link rel="next" href="GtkTextIter.html" title="GtkTextIter">
<meta name="generator" content="GTK-Doc V1.26.1 (XML mode)">
<link rel="stylesheet" href="style.css" type="text/css">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
<td width="100%" align="left" class="shortcuts"></td>
<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
<td><a accesskey="u" href="TextWidgetObjects.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
<td><a accesskey="p" href="TextWidgetObjects.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
<td><a accesskey="n" href="GtkTextIter.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
</tr></table>
<div class="refentry">
<a name="TextWidget"></a><div class="titlepage"></div>
<div class="refnamediv"><table width="100%"><tr>
<td valign="top">
<h2><span class="refentrytitle">Text Widget Overview</span></h2>
<p>Text Widget Overview — Overview of GtkTextBuffer, GtkTextView, and friends</p>
</td>
<td class="gallery_image" valign="top" align="right"></td>
</tr></table></div>
<div class="refsect1">
<a name="id-1.4.8.2.3"></a><h2>Conceptual Overview</h2>
<p>
GTK+ has an extremely powerful framework for multiline text editing.  The
primary objects involved in the process are <a class="link" href="GtkTextBuffer.html" title="GtkTextBuffer"><span class="type">GtkTextBuffer</span></a>, which represents the 
text being edited, and <a class="link" href="GtkTextView.html" title="GtkTextView"><span class="type">GtkTextView</span></a>, a widget which can display a <a class="link" href="GtkTextBuffer.html" title="GtkTextBuffer"><span class="type">GtkTextBuffer</span></a>. 
Each buffer can be displayed by any number of views.
</p>
<p>
One of the important things to remember about text in GTK+ is that it's in the
UTF-8 encoding. This means that one character can be encoded as multiple
bytes. Character counts are usually referred to as
<em class="firstterm">offsets</em>, while byte counts are called
<em class="firstterm">indexes</em>. If you confuse these two, things will work fine
with ASCII, but as soon as your buffer contains multibyte characters, bad 
things will happen.
</p>
<p>
Text in a buffer can be marked with <em class="firstterm">tags</em>. A tag is an
attribute that can be applied to some range of text. For example, a tag might 
be called "bold" and make the text inside the tag bold. However, the tag
concept is more general than that; tags don't have to affect appearance. They 
can instead affect the behavior of mouse and key presses, "lock" a range of 
text so the user can't edit it, or countless other things. A tag is 
represented by a <a class="link" href="GtkTextTag.html" title="GtkTextTag"><span class="type">GtkTextTag</span></a> object. One <a class="link" href="GtkTextTag.html" title="GtkTextTag"><span class="type">GtkTextTag</span></a> can be applied to any 
number of text ranges in any number of buffers.
</p>
<p>
Each tag is stored in a <a class="link" href="GtkTextTagTable.html" title="GtkTextTagTable"><span class="type">GtkTextTagTable</span></a>. A tag table defines a set of
tags that can be used together. Each buffer has one tag table associated with
it; only tags from that tag table can be used with the buffer. A single tag
table can be shared between multiple buffers, however.
</p>
<p>
Tags can have names, which is convenient sometimes (for example, you can name
your tag that makes things bold "bold"), but they can also be anonymous (which
is convenient if you're creating tags on-the-fly).
</p>
<p>
Most text manipulation is accomplished with <em class="firstterm">iterators</em>,
represented by a <a class="link" href="GtkTextIter.html" title="GtkTextIter"><span class="type">GtkTextIter</span></a>. An iterator represents a position between two 
characters in the text buffer. <a class="link" href="GtkTextIter.html" title="GtkTextIter"><span class="type">GtkTextIter</span></a> is a struct designed to be 
allocated on the stack; it's guaranteed to be copiable by value and never 
contain any heap-allocated data. Iterators are not valid indefinitely; 
whenever the buffer is modified in a way that affects the number of characters 
in the buffer, all outstanding iterators become invalid. (Note that deleting 
5 characters and then reinserting 5 still invalidates iterators, though you 
end up with the same number of characters you pass through a state with a 
different number).
</p>
<p>
Because of this, iterators can't be used to preserve positions across buffer
modifications. To preserve a position, the <a class="link" href="GtkTextMark.html" title="GtkTextMark"><span class="type">GtkTextMark</span></a> object is ideal. You
can think of a mark as an invisible cursor or insertion point; it floats in 
the buffer, saving a position. If the text surrounding the mark is deleted, 
the mark remains in the position the text once occupied; if text is inserted 
at the mark, the mark ends up either to the left or to the right of the new 
text, depending on its <em class="firstterm">gravity</em>. The standard text 
cursor in left-to-right languages is a mark with right gravity, because it 
stays to the right of inserted text.
</p>
<p>
Like tags, marks can be either named or anonymous. There are two marks built-in
to <a class="link" href="GtkTextBuffer.html" title="GtkTextBuffer"><span class="type">GtkTextBuffer</span></a>; these are named <code class="literal">"insert"</code> and 
<code class="literal">"selection_bound"</code> and refer to the insertion point and the 
boundary of the selection which is not the insertion point, respectively. If 
no text is selected, these two marks will be in the same position. You can 
manipulate what is selected and where the cursor appears by moving these 
marks around.
<a href="#ftn.id-1.4.8.2.3.9.4" class="footnote" name="id-1.4.8.2.3.9.4"><sup class="footnote">[2]</sup></a>
</p>
<p>
Text buffers always contain at least one line, but may be empty (that
is, buffers can contain zero characters). The last line in the text
buffer never ends in a line separator (such as newline); the other
lines in the buffer always end in a line separator. Line separators
count as characters when computing character counts and character
offsets. Note that some Unicode line separators are represented with 
multiple bytes in UTF-8, and the two-character sequence "\r\n" is also
considered a line separator.
</p>
</div>
<div class="refsect1">
<a name="id-1.4.8.2.4"></a><h2>Simple Example</h2>
<p>
The simplest usage of <a class="link" href="GtkTextView.html" title="GtkTextView"><span class="type">GtkTextView</span></a>  might look like this:
</p>
<div class="informalexample">
  <table class="listing_frame" border="0" cellpadding="0" cellspacing="0">
    <tbody>
      <tr>
        <td class="listing_lines" align="right"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13</pre></td>
        <td class="listing_code"><pre class="programlisting">GtkWidget <span class="gtkdoc opt">*</span>view<span class="gtkdoc opt">;</span>
GtkTextBuffer <span class="gtkdoc opt">*</span>buffer<span class="gtkdoc opt">;</span>

view <span class="gtkdoc opt">=</span> <span class="function"><a href="GtkTextView.html#gtk-text-view-new">gtk_text_view_new</a></span> <span class="gtkdoc opt">();</span>

buffer <span class="gtkdoc opt">=</span> <span class="function"><a href="GtkTextView.html#gtk-text-view-get-buffer">gtk_text_view_get_buffer</a></span> <span class="gtkdoc opt">(</span><span class="function">GTK_TEXT_VIEW</span> <span class="gtkdoc opt">(</span>view<span class="gtkdoc opt">));</span>

<span class="function"><a href="GtkTextBuffer.html#gtk-text-buffer-set-text">gtk_text_buffer_set_text</a></span> <span class="gtkdoc opt">(</span>buffer<span class="gtkdoc opt">,</span> <span class="string">&quot;Hello, this is some text&quot;</span><span class="gtkdoc opt">, -</span><span class="number">1</span><span class="gtkdoc opt">);</span>

<span class="comment">/* Now you might put the view in a container and display it on the</span>
<span class="comment"> * screen; when the user edits the text, signals on the buffer</span>
<span class="comment"> * will be emitted, such as &quot;changed&quot;, &quot;insert_text&quot;, and so on.</span>
<span class="comment"> */</span></pre></td>
      </tr>
    </tbody>
  </table>
</div>

<p>
In many cases it's also convenient to first create the buffer with 
<a class="link" href="GtkTextBuffer.html#gtk-text-buffer-new" title="gtk_text_buffer_new ()"><code class="function">gtk_text_buffer_new()</code></a>, then create a widget for that buffer with 
<a class="link" href="GtkTextView.html#gtk-text-view-new-with-buffer" title="gtk_text_view_new_with_buffer ()"><code class="function">gtk_text_view_new_with_buffer()</code></a>. Or you can change the buffer the widget 
displays after the widget is created with <a class="link" href="GtkTextView.html#gtk-text-view-set-buffer" title="gtk_text_view_set_buffer ()"><code class="function">gtk_text_view_set_buffer()</code></a>.
</p>
</div>
<div class="refsect1">
<a name="id-1.4.8.2.5"></a><h2>Example of Changing Text Attributes</h2>
<p>

There are two ways to affect text attributes in <a class="link" href="GtkTextView.html" title="GtkTextView"><span class="type">GtkTextView</span></a>.
You can change the default attributes for a given <a class="link" href="GtkTextView.html" title="GtkTextView"><span class="type">GtkTextView</span></a>, and you can 
apply tags that change the attributes for a region of text.  For text features 
that come from the theme — such as font and foreground color — use 
standard <a class="link" href="GtkWidget.html" title="GtkWidget"><span class="type">GtkWidget</span></a> functions such as <a class="link" href="GtkWidget.html#gtk-widget-modify-font" title="gtk_widget_modify_font ()"><code class="function">gtk_widget_modify_font()</code></a> or 
<a class="link" href="GtkWidget.html#gtk-widget-modify-text" title="gtk_widget_modify_text ()"><code class="function">gtk_widget_modify_text()</code></a>. For other attributes there are dedicated methods on 
<a class="link" href="GtkTextView.html" title="GtkTextView"><span class="type">GtkTextView</span></a> such as <a class="link" href="GtkTextView.html#gtk-text-view-set-tabs" title="gtk_text_view_set_tabs ()"><code class="function">gtk_text_view_set_tabs()</code></a>.

</p>
<div class="informalexample">
  <table class="listing_frame" border="0" cellpadding="0" cellspacing="0">
    <tbody>
      <tr>
        <td class="listing_lines" align="right"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31</pre></td>
        <td class="listing_code"><pre class="programlisting">GtkWidget <span class="gtkdoc opt">*</span>view<span class="gtkdoc opt">;</span>
GtkTextBuffer <span class="gtkdoc opt">*</span>buffer<span class="gtkdoc opt">;</span>
GtkTextIter start<span class="gtkdoc opt">,</span> end<span class="gtkdoc opt">;</span>
PangoFontDescription <span class="gtkdoc opt">*</span>font_desc<span class="gtkdoc opt">;</span>
GdkColor color<span class="gtkdoc opt">;</span>
GtkTextTag <span class="gtkdoc opt">*</span>tag<span class="gtkdoc opt">;</span>

view <span class="gtkdoc opt">=</span> <span class="function"><a href="GtkTextView.html#gtk-text-view-new">gtk_text_view_new</a></span> <span class="gtkdoc opt">();</span>

buffer <span class="gtkdoc opt">=</span> <span class="function"><a href="GtkTextView.html#gtk-text-view-get-buffer">gtk_text_view_get_buffer</a></span> <span class="gtkdoc opt">(</span><span class="function">GTK_TEXT_VIEW</span> <span class="gtkdoc opt">(</span>view<span class="gtkdoc opt">));</span>

<span class="function"><a href="GtkTextBuffer.html#gtk-text-buffer-set-text">gtk_text_buffer_set_text</a></span> <span class="gtkdoc opt">(</span>buffer<span class="gtkdoc opt">,</span> <span class="string">&quot;Hello, this is some text&quot;</span><span class="gtkdoc opt">, -</span><span class="number">1</span><span class="gtkdoc opt">);</span>

<span class="comment">/* Change default font throughout the widget */</span>
font_desc <span class="gtkdoc opt">=</span> <span class="function"><a href="../pango/pango-Fonts.html#pango-font-description-from-string">pango_font_description_from_string</a></span> <span class="gtkdoc opt">(</span><span class="string">&quot;Serif 15&quot;</span><span class="gtkdoc opt">);</span>
<span class="function"><a href="GtkWidget.html#gtk-widget-modify-font">gtk_widget_modify_font</a></span> <span class="gtkdoc opt">(</span>view<span class="gtkdoc opt">,</span> font_desc<span class="gtkdoc opt">);</span>
<span class="function"><a href="../pango/pango-Fonts.html#pango-font-description-free">pango_font_description_free</a></span> <span class="gtkdoc opt">(</span>font_desc<span class="gtkdoc opt">);</span>

<span class="comment">/* Change default color throughout the widget */</span>
<span class="function"><a href="../html/gdk2-Colormaps-and-Colors.html#gdk-color-parse">gdk_color_parse</a></span> <span class="gtkdoc opt">(</span><span class="string">&quot;green&quot;</span><span class="gtkdoc opt">, &amp;</span>color<span class="gtkdoc opt">);</span>
<span class="function"><a href="GtkWidget.html#gtk-widget-modify-text">gtk_widget_modify_text</a></span> <span class="gtkdoc opt">(</span>view<span class="gtkdoc opt">,</span> GTK_STATE_NORMAL<span class="gtkdoc opt">, &amp;</span>color<span class="gtkdoc opt">);</span>

<span class="comment">/* Change left margin throughout the widget */</span>
<span class="function"><a href="GtkTextView.html#gtk-text-view-set-left-margin">gtk_text_view_set_left_margin</a></span> <span class="gtkdoc opt">(</span><span class="function">GTK_TEXT_VIEW</span> <span class="gtkdoc opt">(</span>view<span class="gtkdoc opt">),</span> <span class="number">30</span><span class="gtkdoc opt">);</span>

<span class="comment">/* Use a tag to change the color for just one part of the widget */</span>
tag <span class="gtkdoc opt">=</span> <span class="function"><a href="GtkTextBuffer.html#gtk-text-buffer-create-tag">gtk_text_buffer_create_tag</a></span> <span class="gtkdoc opt">(</span>buffer<span class="gtkdoc opt">,</span> <span class="string">&quot;blue_foreground&quot;</span><span class="gtkdoc opt">,</span>
	   		            <span class="string">&quot;foreground&quot;</span><span class="gtkdoc opt">,</span> <span class="string">&quot;blue&quot;</span><span class="gtkdoc opt">,</span> NULL<span class="gtkdoc opt">);</span>  
<span class="function"><a href="GtkTextBuffer.html#gtk-text-buffer-get-iter-at-offset">gtk_text_buffer_get_iter_at_offset</a></span> <span class="gtkdoc opt">(</span>buffer<span class="gtkdoc opt">, &amp;</span>start<span class="gtkdoc opt">,</span> <span class="number">7</span><span class="gtkdoc opt">);</span>
<span class="function"><a href="GtkTextBuffer.html#gtk-text-buffer-get-iter-at-offset">gtk_text_buffer_get_iter_at_offset</a></span> <span class="gtkdoc opt">(</span>buffer<span class="gtkdoc opt">, &amp;</span>end<span class="gtkdoc opt">,</span> <span class="number">12</span><span class="gtkdoc opt">);</span>
<span class="function"><a href="GtkTextBuffer.html#gtk-text-buffer-apply-tag">gtk_text_buffer_apply_tag</a></span> <span class="gtkdoc opt">(</span>buffer<span class="gtkdoc opt">,</span> tag<span class="gtkdoc opt">, &amp;</span>start<span class="gtkdoc opt">, &amp;</span>end<span class="gtkdoc opt">);</span></pre></td>
      </tr>
    </tbody>
  </table>
</div>

<p>

</p>
<p>
The <span class="application">gtk-demo</span> application that comes with
GTK+ contains more example code for <a class="link" href="GtkTextView.html" title="GtkTextView"><span class="type">GtkTextView</span></a>.
</p>
</div>
<div class="footnotes">
<br><hr style="width:100; text-align:left;margin-left: 0">
<div id="ftn.id-1.4.8.2.3.9.4" class="footnote"><p><a href="#id-1.4.8.2.3.9.4" class="para"><sup class="para">[2] </sup></a>
If you want to place the cursor in response to a user action, be sure to use
<a class="link" href="GtkTextBuffer.html#gtk-text-buffer-place-cursor" title="gtk_text_buffer_place_cursor ()"><code class="function">gtk_text_buffer_place_cursor()</code></a>, which moves both at once without causing a 
temporary selection (moving one then the other temporarily selects the range in 
between the old and new positions).
</p></div>
</div>
</div>
<div class="footer">
<hr>Generated by GTK-Doc V1.26.1</div>
</body>
</html>