1/* Text View/Multiple Views
2 *
3 * The GtkTextView widget displays a GtkTextBuffer. One GtkTextBuffer
4 * can be displayed by multiple GtkTextViews. This demo has two views
5 * displaying a single buffer, and shows off the widget's text
6 * formatting features.
7 *
8 */
9
10#include <gtk/gtk.h>
11#include <stdlib.h> /* for exit() */
12#include "paintable.h"
13
14static void easter_egg_callback (GtkWidget *button, gpointer data);
15
16static void
17create_tags (GtkTextBuffer *buffer)
18{
19 /* Create a bunch of tags. Note that it's also possible to
20 * create tags with gtk_text_tag_new() then add them to the
21 * tag table for the buffer, gtk_text_buffer_create_tag() is
22 * just a convenience function. Also note that you don't have
23 * to give tags a name; pass NULL for the name to create an
24 * anonymous tag.
25 *
26 * In any real app, another useful optimization would be to create
27 * a GtkTextTagTable in advance, and reuse the same tag table for
28 * all the buffers with the same tag set, instead of creating
29 * new copies of the same tags for every buffer.
30 *
31 * Tags are assigned default priorities in order of addition to the
32 * tag table. That is, tags created later that affect the same text
33 * property affected by an earlier tag will override the earlier
34 * tag. You can modify tag priorities with
35 * gtk_text_tag_set_priority().
36 */
37
38 gtk_text_buffer_create_tag (buffer, tag_name: "heading",
39 first_property_name: "weight", PANGO_WEIGHT_BOLD,
40 "size", 15 * PANGO_SCALE,
41 NULL);
42
43 gtk_text_buffer_create_tag (buffer, tag_name: "italic",
44 first_property_name: "style", PANGO_STYLE_ITALIC, NULL);
45
46 gtk_text_buffer_create_tag (buffer, tag_name: "bold",
47 first_property_name: "weight", PANGO_WEIGHT_BOLD, NULL);
48
49 gtk_text_buffer_create_tag (buffer, tag_name: "big",
50 /* points times the PANGO_SCALE factor */
51 first_property_name: "size", 20 * PANGO_SCALE, NULL);
52
53 gtk_text_buffer_create_tag (buffer, tag_name: "xx-small",
54 first_property_name: "scale", PANGO_SCALE_XX_SMALL, NULL);
55
56 gtk_text_buffer_create_tag (buffer, tag_name: "x-large",
57 first_property_name: "scale", PANGO_SCALE_X_LARGE, NULL);
58
59 gtk_text_buffer_create_tag (buffer, tag_name: "monospace",
60 first_property_name: "family", "monospace", NULL);
61
62 gtk_text_buffer_create_tag (buffer, tag_name: "blue_foreground",
63 first_property_name: "foreground", "blue", NULL);
64
65 gtk_text_buffer_create_tag (buffer, tag_name: "red_background",
66 first_property_name: "background", "red", NULL);
67
68 gtk_text_buffer_create_tag (buffer, tag_name: "big_gap_before_line",
69 first_property_name: "pixels_above_lines", 30, NULL);
70
71 gtk_text_buffer_create_tag (buffer, tag_name: "big_gap_after_line",
72 first_property_name: "pixels_below_lines", 30, NULL);
73
74 gtk_text_buffer_create_tag (buffer, tag_name: "double_spaced_line",
75 first_property_name: "pixels_inside_wrap", 10, NULL);
76
77 gtk_text_buffer_create_tag (buffer, tag_name: "not_editable",
78 first_property_name: "editable", FALSE, NULL);
79
80 gtk_text_buffer_create_tag (buffer, tag_name: "word_wrap",
81 first_property_name: "wrap_mode", GTK_WRAP_WORD, NULL);
82
83 gtk_text_buffer_create_tag (buffer, tag_name: "char_wrap",
84 first_property_name: "wrap_mode", GTK_WRAP_CHAR, NULL);
85
86 gtk_text_buffer_create_tag (buffer, tag_name: "no_wrap",
87 first_property_name: "wrap_mode", GTK_WRAP_NONE, NULL);
88
89 gtk_text_buffer_create_tag (buffer, tag_name: "center",
90 first_property_name: "justification", GTK_JUSTIFY_CENTER, NULL);
91
92 gtk_text_buffer_create_tag (buffer, tag_name: "right_justify",
93 first_property_name: "justification", GTK_JUSTIFY_RIGHT, NULL);
94
95 gtk_text_buffer_create_tag (buffer, tag_name: "wide_margins",
96 first_property_name: "left_margin", 50, "right_margin", 50,
97 NULL);
98
99 gtk_text_buffer_create_tag (buffer, tag_name: "strikethrough",
100 first_property_name: "strikethrough", TRUE, NULL);
101
102 gtk_text_buffer_create_tag (buffer, tag_name: "underline",
103 first_property_name: "underline", PANGO_UNDERLINE_SINGLE, NULL);
104
105 gtk_text_buffer_create_tag (buffer, tag_name: "double_underline",
106 first_property_name: "underline", PANGO_UNDERLINE_DOUBLE, NULL);
107
108 gtk_text_buffer_create_tag (buffer, tag_name: "superscript",
109 first_property_name: "rise", 10 * PANGO_SCALE, /* 10 pixels */
110 "size", 8 * PANGO_SCALE, /* 8 points */
111 NULL);
112
113 gtk_text_buffer_create_tag (buffer, tag_name: "subscript",
114 first_property_name: "rise", -10 * PANGO_SCALE, /* 10 pixels */
115 "size", 8 * PANGO_SCALE, /* 8 points */
116 NULL);
117
118 gtk_text_buffer_create_tag (buffer, tag_name: "rtl_quote",
119 first_property_name: "wrap_mode", GTK_WRAP_WORD,
120 "direction", GTK_TEXT_DIR_RTL,
121 "indent", 30,
122 "left_margin", 20,
123 "right_margin", 20,
124 NULL);
125}
126
127static void
128insert_text (GtkTextView *view)
129{
130 GtkWidget *widget = GTK_WIDGET (view);
131 GtkTextBuffer *buffer = gtk_text_view_get_buffer (text_view: view);
132 GtkTextIter iter;
133 GtkTextIter start, end;
134 GtkIconTheme *icon_theme;
135 GtkIconPaintable *icon;
136 GdkPaintable *nuclear;
137
138 icon_theme = gtk_icon_theme_get_for_display (display: gtk_widget_get_display (widget));
139 icon = gtk_icon_theme_lookup_icon (self: icon_theme,
140 icon_name: "face-cool",
141 NULL,
142 size: 32, scale: 1,
143 direction: gtk_widget_get_direction (widget),
144 flags: 0);
145 nuclear = gtk_nuclear_animation_new (TRUE);
146
147 /* get start of buffer; each insertion will revalidate the
148 * iterator to point to just after the inserted text.
149 */
150 gtk_text_buffer_get_iter_at_offset (buffer, iter: &iter, char_offset: 0);
151
152 gtk_text_buffer_begin_irreversible_action (buffer);
153 gtk_text_buffer_insert (buffer, iter: &iter,
154 text: "The text widget can display text with all kinds of nifty attributes. "
155 "It also supports multiple views of the same buffer; this demo is "
156 "showing the same buffer in two places.\n\n", len: -1);
157
158 gtk_text_buffer_insert_with_tags_by_name (buffer, iter: &iter,
159 text: "Font styles. ", len: -1,
160 first_tag_name: "heading", NULL);
161
162 gtk_text_buffer_insert (buffer, iter: &iter, text: "For example, you can have ", len: -1);
163 gtk_text_buffer_insert_with_tags_by_name (buffer, iter: &iter,
164 text: "italic", len: -1,
165 first_tag_name: "italic", NULL);
166 gtk_text_buffer_insert (buffer, iter: &iter, text: ", ", len: -1);
167 gtk_text_buffer_insert_with_tags_by_name (buffer, iter: &iter,
168 text: "bold", len: -1,
169 first_tag_name: "bold", NULL);
170 gtk_text_buffer_insert (buffer, iter: &iter, text: ", or ", len: -1);
171 gtk_text_buffer_insert_with_tags_by_name (buffer, iter: &iter,
172 text: "monospace (typewriter)", len: -1,
173 first_tag_name: "monospace", NULL);
174 gtk_text_buffer_insert (buffer, iter: &iter, text: ", or ", len: -1);
175 gtk_text_buffer_insert_with_tags_by_name (buffer, iter: &iter,
176 text: "big", len: -1,
177 first_tag_name: "big", NULL);
178 gtk_text_buffer_insert (buffer, iter: &iter, text: " text. ", len: -1);
179 gtk_text_buffer_insert (buffer, iter: &iter,
180 text: "It's best not to hardcode specific text sizes; you can use relative "
181 "sizes as with CSS, such as ", len: -1);
182 gtk_text_buffer_insert_with_tags_by_name (buffer, iter: &iter,
183 text: "xx-small", len: -1,
184 first_tag_name: "xx-small", NULL);
185 gtk_text_buffer_insert (buffer, iter: &iter, text: " or ", len: -1);
186 gtk_text_buffer_insert_with_tags_by_name (buffer, iter: &iter,
187 text: "x-large", len: -1,
188 first_tag_name: "x-large", NULL);
189 gtk_text_buffer_insert (buffer, iter: &iter,
190 text: " to ensure that your program properly adapts if the user changes the "
191 "default font size.\n\n", len: -1);
192
193 gtk_text_buffer_insert_with_tags_by_name (buffer, iter: &iter, text: "Colors. ", len: -1,
194 first_tag_name: "heading", NULL);
195
196 gtk_text_buffer_insert (buffer, iter: &iter, text: "Colors such as ", len: -1);
197 gtk_text_buffer_insert_with_tags_by_name (buffer, iter: &iter,
198 text: "a blue foreground", len: -1,
199 first_tag_name: "blue_foreground", NULL);
200 gtk_text_buffer_insert (buffer, iter: &iter, text: " or ", len: -1);
201 gtk_text_buffer_insert_with_tags_by_name (buffer, iter: &iter,
202 text: "a red background", len: -1,
203 first_tag_name: "red_background", NULL);
204 gtk_text_buffer_insert (buffer, iter: &iter, text: " or even ", len: -1);
205 gtk_text_buffer_insert_with_tags_by_name (buffer, iter: &iter,
206 text: "a blue foreground on red background", len: -1,
207 first_tag_name: "blue_foreground",
208 "red_background",
209 NULL);
210 gtk_text_buffer_insert (buffer, iter: &iter, text: " (select that to read it) can be used.\n\n", len: -1);
211
212 gtk_text_buffer_insert_with_tags_by_name (buffer, iter: &iter,
213 text: "Underline, strikethrough, and rise. ", len: -1,
214 first_tag_name: "heading", NULL);
215
216 gtk_text_buffer_insert_with_tags_by_name (buffer, iter: &iter,
217 text: "Strikethrough", len: -1,
218 first_tag_name: "strikethrough", NULL);
219 gtk_text_buffer_insert (buffer, iter: &iter, text: ", ", len: -1);
220 gtk_text_buffer_insert_with_tags_by_name (buffer, iter: &iter,
221 text: "underline", len: -1,
222 first_tag_name: "underline", NULL);
223 gtk_text_buffer_insert (buffer, iter: &iter, text: ", ", len: -1);
224 gtk_text_buffer_insert_with_tags_by_name (buffer, iter: &iter,
225 text: "double underline", len: -1,
226 first_tag_name: "double_underline", NULL);
227 gtk_text_buffer_insert (buffer, iter: &iter, text: ", ", len: -1);
228 gtk_text_buffer_insert_with_tags_by_name (buffer, iter: &iter,
229 text: "superscript", len: -1,
230 first_tag_name: "superscript", NULL);
231 gtk_text_buffer_insert (buffer, iter: &iter, text: ", and ", len: -1);
232 gtk_text_buffer_insert_with_tags_by_name (buffer, iter: &iter,
233 text: "subscript", len: -1,
234 first_tag_name: "subscript", NULL);
235 gtk_text_buffer_insert (buffer, iter: &iter, text: " are all supported.\n\n", len: -1);
236
237 gtk_text_buffer_insert_with_tags_by_name (buffer, iter: &iter, text: "Images. ", len: -1,
238 first_tag_name: "heading", NULL);
239
240 gtk_text_buffer_insert (buffer, iter: &iter, text: "The buffer can have images in it: ", len: -1);
241 gtk_text_buffer_insert_paintable (buffer, iter: &iter, paintable: GDK_PAINTABLE (ptr: icon));
242 gtk_text_buffer_insert_paintable (buffer, iter: &iter, paintable: GDK_PAINTABLE (ptr: icon));
243
244 gtk_text_buffer_insert_paintable (buffer, iter: &iter, paintable: nuclear);
245
246 gtk_text_buffer_insert (buffer, iter: &iter, text: " for example.\n\n", len: -1);
247
248 gtk_text_buffer_insert_with_tags_by_name (buffer, iter: &iter, text: "Spacing. ", len: -1,
249 first_tag_name: "heading", NULL);
250
251 gtk_text_buffer_insert (buffer, iter: &iter,
252 text: "You can adjust the amount of space before each line.\n", len: -1);
253
254 gtk_text_buffer_insert_with_tags_by_name (buffer, iter: &iter,
255 text: "This line has a whole lot of space before it.\n", len: -1,
256 first_tag_name: "big_gap_before_line", "wide_margins", NULL);
257 gtk_text_buffer_insert_with_tags_by_name (buffer, iter: &iter,
258 text: "You can also adjust the amount of space after each line; "
259 "this line has a whole lot of space after it.\n", len: -1,
260 first_tag_name: "big_gap_after_line", "wide_margins", NULL);
261
262 gtk_text_buffer_insert_with_tags_by_name (buffer, iter: &iter,
263 text: "You can also adjust the amount of space between wrapped lines; "
264 "this line has extra space between each wrapped line in the same "
265 "paragraph. To show off wrapping, some filler text: the quick "
266 "brown fox jumped over the lazy dog. Blah blah blah blah blah "
267 "blah blah blah blah.\n", len: -1,
268 first_tag_name: "double_spaced_line", "wide_margins", NULL);
269
270 gtk_text_buffer_insert (buffer, iter: &iter,
271 text: "Also note that those lines have extra-wide margins.\n\n", len: -1);
272
273 gtk_text_buffer_insert_with_tags_by_name (buffer, iter: &iter,
274 text: "Editability. ", len: -1,
275 first_tag_name: "heading", NULL);
276
277 gtk_text_buffer_insert_with_tags_by_name (buffer, iter: &iter,
278 text: "This line is 'locked down' and can't be edited by the user - just "
279 "try it! You can't delete this line.\n\n", len: -1,
280 first_tag_name: "not_editable", NULL);
281
282 gtk_text_buffer_insert_with_tags_by_name (buffer, iter: &iter,
283 text: "Wrapping. ", len: -1,
284 first_tag_name: "heading", NULL);
285
286 gtk_text_buffer_insert (buffer, iter: &iter,
287 text: "This line (and most of the others in this buffer) is word-wrapped, "
288 "using the proper Unicode algorithm. Word wrap should work in all "
289 "scripts and languages that GTK supports. Let's make this a long "
290 "paragraph to demonstrate: blah blah blah blah blah blah blah blah "
291 "blah blah blah blah blah blah blah blah blah blah blah\n\n", len: -1);
292
293 gtk_text_buffer_insert_with_tags_by_name (buffer, iter: &iter,
294 text: "This line has character-based wrapping, and can wrap between any two "
295 "character glyphs. Let's make this a long paragraph to demonstrate: "
296 "blah blah blah blah blah blah blah blah blah blah blah blah blah blah "
297 "blah blah blah blah blah\n\n", len: -1, first_tag_name: "char_wrap", NULL);
298
299 gtk_text_buffer_insert_with_tags_by_name (buffer, iter: &iter,
300 text: "This line has all wrapping turned off, so it makes the horizontal "
301 "scrollbar appear.\n\n\n", len: -1, first_tag_name: "no_wrap", NULL);
302
303 gtk_text_buffer_insert_with_tags_by_name (buffer, iter: &iter,
304 text: "Justification. ", len: -1,
305 first_tag_name: "heading", NULL);
306
307 gtk_text_buffer_insert_with_tags_by_name (buffer, iter: &iter,
308 text: "\nThis line has center justification.\n", len: -1,
309 first_tag_name: "center", NULL);
310
311 gtk_text_buffer_insert_with_tags_by_name (buffer, iter: &iter,
312 text: "This line has right justification.\n", len: -1,
313 first_tag_name: "right_justify", NULL);
314
315 gtk_text_buffer_insert_with_tags_by_name (buffer, iter: &iter,
316 text: "\nThis line has big wide margins. Text text text text text text text "
317 "text text text text text text text text text text text text text text "
318 "text text text text text text text text text text text text text text "
319 "text.\n", len: -1, first_tag_name: "wide_margins", NULL);
320
321 gtk_text_buffer_insert_with_tags_by_name (buffer, iter: &iter,
322 text: "Internationalization. ", len: -1,
323 first_tag_name: "heading", NULL);
324
325 gtk_text_buffer_insert (buffer, iter: &iter,
326 text: "You can put all sorts of Unicode text in the buffer.\n\nGerman "
327 "(Deutsch S\303\274d) Gr\303\274\303\237 Gott\nGreek "
328 "(\316\225\316\273\316\273\316\267\316\275\316\271\316\272\316\254) "
329 "\316\223\316\265\316\271\316\254 \317\203\316\261\317\202\nHebrew "
330 "\327\251\327\234\327\225\327\235\nJapanese "
331 "(\346\227\245\346\234\254\350\252\236)\n\nThe widget properly handles "
332 "bidirectional text, word wrapping, DOS/UNIX/Unicode paragraph separators, "
333 "grapheme boundaries, and so on using the Pango internationalization "
334 "framework.\n", len: -1);
335
336 gtk_text_buffer_insert (buffer, iter: &iter,
337 text: "Here's a word-wrapped quote in a right-to-left language:\n", len: -1);
338 gtk_text_buffer_insert_with_tags_by_name (buffer, iter: &iter,
339 text: "\331\210\331\202\330\257 \330\250\330\257\330\243 "
340 "\330\253\331\204\330\247\330\253 \331\205\331\206 "
341 "\330\243\331\203\330\253\330\261 \330\247\331\204\331\205\330\244\330\263\330\263\330\247\330\252 "
342 "\330\252\331\202\330\257\331\205\330\247 \331\201\331\212 "
343 "\330\264\330\250\331\203\330\251 \330\247\331\203\330\263\331\212\331\210\331\206 "
344 "\330\250\330\261\330\247\331\205\330\254\331\207\330\247 "
345 "\331\203\331\205\331\206\330\270\331\205\330\247\330\252 "
346 "\331\204\330\247 \330\252\330\263\330\271\331\211 \331\204\331\204\330\261\330\250\330\255\330\214 "
347 "\330\253\331\205 \330\252\330\255\331\210\331\204\330\252 "
348 "\331\201\331\212 \330\247\331\204\330\263\331\206\331\210\330\247\330\252 "
349 "\330\247\331\204\330\256\331\205\330\263 \330\247\331\204\331\205\330\247\330\266\331\212\330\251 "
350 "\330\245\331\204\331\211 \331\205\330\244\330\263\330\263\330\247\330\252 "
351 "\331\205\330\247\331\204\331\212\330\251 \331\205\331\206\330\270\331\205\330\251\330\214 "
352 "\331\210\330\250\330\247\330\252\330\252 \330\254\330\262\330\241\330\247 "
353 "\331\205\331\206 \330\247\331\204\331\206\330\270\330\247\331\205 "
354 "\330\247\331\204\331\205\330\247\331\204\331\212 \331\201\331\212 "
355 "\330\250\331\204\330\257\330\247\331\206\331\207\330\247\330\214 "
356 "\331\210\331\204\331\203\331\206\331\207\330\247 \330\252\330\252\330\256\330\265\330\265 "
357 "\331\201\331\212 \330\256\330\257\331\205\330\251 \331\202\330\267\330\247\330\271 "
358 "\330\247\331\204\331\205\330\264\330\261\331\210\330\271\330\247\330\252 "
359 "\330\247\331\204\330\265\330\272\331\212\330\261\330\251. \331\210\330\243\330\255\330\257 "
360 "\330\243\331\203\330\253\330\261 \331\207\330\260\331\207 "
361 "\330\247\331\204\331\205\330\244\330\263\330\263\330\247\330\252 "
362 "\331\206\330\254\330\247\330\255\330\247 \331\207\331\210 "
363 "\302\273\330\250\330\247\331\206\331\203\331\210\330\263\331\210\331\204\302\253 "
364 "\331\201\331\212 \330\250\331\210\331\204\331\212\331\201\331\212\330\247.\n\n", len: -1,
365 first_tag_name: "rtl_quote", NULL);
366
367 gtk_text_buffer_insert (buffer, iter: &iter,
368 text: "You can put widgets in the buffer: Here's a button: ", len: -1);
369 gtk_text_buffer_create_child_anchor (buffer, iter: &iter);
370 gtk_text_buffer_insert (buffer, iter: &iter, text: " and a menu: ", len: -1);
371 gtk_text_buffer_create_child_anchor (buffer, iter: &iter);
372 gtk_text_buffer_insert (buffer, iter: &iter, text: " and a scale: ", len: -1);
373 gtk_text_buffer_create_child_anchor (buffer, iter: &iter);
374 gtk_text_buffer_insert (buffer, iter: &iter, text: " finally a text entry: ", len: -1);
375 gtk_text_buffer_create_child_anchor (buffer, iter: &iter);
376 gtk_text_buffer_insert (buffer, iter: &iter, text: ".\n", len: -1);
377
378 gtk_text_buffer_insert (buffer, iter: &iter,
379 text: "\n\nThis demo doesn't demonstrate all the GtkTextBuffer features; "
380 "it leaves out, for example: invisible/hidden text, tab stops, "
381 "application-drawn areas on the sides of the widget for displaying "
382 "breakpoints and such...", len: -1);
383
384 /* Apply word_wrap tag to whole buffer */
385 gtk_text_buffer_get_bounds (buffer, start: &start, end: &end);
386 gtk_text_buffer_apply_tag_by_name (buffer, name: "word_wrap", start: &start, end: &end);
387
388 gtk_text_buffer_end_irreversible_action (buffer);
389
390 g_object_unref (object: icon);
391 g_object_unref (object: nuclear);
392}
393
394static gboolean
395find_anchor (GtkTextIter *iter)
396{
397 while (gtk_text_iter_forward_char (iter))
398 {
399 if (gtk_text_iter_get_child_anchor (iter))
400 return TRUE;
401 }
402 return FALSE;
403}
404
405static void
406attach_widgets (GtkTextView *text_view)
407{
408 GtkTextIter iter;
409 GtkTextBuffer *buffer;
410 int i;
411
412 buffer = gtk_text_view_get_buffer (text_view);
413
414 gtk_text_buffer_get_start_iter (buffer, iter: &iter);
415
416 i = 0;
417 while (find_anchor (iter: &iter))
418 {
419 GtkTextChildAnchor *anchor;
420 GtkWidget *widget;
421
422 anchor = gtk_text_iter_get_child_anchor (iter: &iter);
423
424 if (i == 0)
425 {
426 widget = gtk_button_new_with_label (label: "Click Me");
427
428 g_signal_connect (widget, "clicked",
429 G_CALLBACK (easter_egg_callback),
430 NULL);
431 }
432 else if (i == 1)
433 {
434 widget = gtk_combo_box_text_new ();
435
436 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), text: "Option 1");
437 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), text: "Option 2");
438 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), text: "Option 3");
439 }
440 else if (i == 2)
441 {
442 widget = gtk_scale_new (orientation: GTK_ORIENTATION_HORIZONTAL, NULL);
443 gtk_range_set_range (GTK_RANGE (widget), min: 0, max: 100);
444 gtk_widget_set_size_request (widget, width: 70, height: -1);
445 }
446 else if (i == 3)
447 {
448 widget = gtk_entry_new ();
449 }
450 else
451 {
452 widget = NULL; /* avoids a compiler warning */
453 g_assert_not_reached ();
454 }
455
456 gtk_text_view_add_child_at_anchor (text_view,
457 child: widget,
458 anchor);
459
460 ++i;
461 }
462}
463
464GtkWidget *
465do_textview (GtkWidget *do_widget)
466{
467 static GtkWidget *window = NULL;
468
469 if (!window)
470 {
471 GtkWidget *vpaned;
472 GtkWidget *view1;
473 GtkWidget *view2;
474 GtkWidget *sw;
475 GtkTextBuffer *buffer;
476
477 window = gtk_window_new ();
478 gtk_window_set_display (GTK_WINDOW (window),
479 display: gtk_widget_get_display (widget: do_widget));
480 gtk_window_set_default_size (GTK_WINDOW (window), width: 450, height: 450);
481 g_object_add_weak_pointer (G_OBJECT (window), weak_pointer_location: (gpointer *)&window);
482
483 gtk_window_set_title (GTK_WINDOW (window), title: "Multiple Views");
484
485 vpaned = gtk_paned_new (orientation: GTK_ORIENTATION_VERTICAL);
486 gtk_window_set_child (GTK_WINDOW (window), child: vpaned);
487
488 /* For convenience, we just use the autocreated buffer from
489 * the first text view; you could also create the buffer
490 * by itself with gtk_text_buffer_new(), then later create
491 * a view widget.
492 */
493 view1 = gtk_text_view_new ();
494 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view1));
495 view2 = gtk_text_view_new_with_buffer (buffer);
496
497 sw = gtk_scrolled_window_new ();
498 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
499 hscrollbar_policy: GTK_POLICY_AUTOMATIC,
500 vscrollbar_policy: GTK_POLICY_AUTOMATIC);
501 gtk_paned_set_start_child (GTK_PANED (vpaned), child: sw);
502 gtk_paned_set_resize_start_child (GTK_PANED (vpaned), FALSE);
503 gtk_paned_set_shrink_start_child (GTK_PANED (vpaned), TRUE);
504
505 gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), child: view1);
506
507 sw = gtk_scrolled_window_new ();
508 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
509 hscrollbar_policy: GTK_POLICY_AUTOMATIC,
510 vscrollbar_policy: GTK_POLICY_AUTOMATIC);
511 gtk_paned_set_end_child (GTK_PANED (vpaned), child: sw);
512 gtk_paned_set_resize_end_child (GTK_PANED (vpaned), TRUE);
513 gtk_paned_set_shrink_end_child (GTK_PANED (vpaned), TRUE);
514
515 gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), child: view2);
516
517 create_tags (buffer);
518 insert_text (GTK_TEXT_VIEW (view1));
519
520 attach_widgets (GTK_TEXT_VIEW (view1));
521 attach_widgets (GTK_TEXT_VIEW (view2));
522 }
523
524 if (!gtk_widget_get_visible (widget: window))
525 {
526 gtk_widget_show (widget: window);
527 }
528 else
529 {
530 gtk_window_destroy (GTK_WINDOW (window));
531 window = NULL;
532 }
533
534 return window;
535}
536
537static void
538recursive_attach_view (int depth,
539 GtkTextView *view,
540 GtkTextChildAnchor *anchor)
541{
542 GtkWidget *child_view, *frame;
543
544 if (depth > 4)
545 return;
546
547 child_view = gtk_text_view_new_with_buffer (buffer: gtk_text_view_get_buffer (text_view: view));
548 gtk_widget_set_size_request (widget: child_view, width: 260 - 20 * depth, height: -1);
549
550 /* Frame is to add a black border around each child view */
551 frame = gtk_frame_new (NULL);
552 gtk_frame_set_child (GTK_FRAME (frame), child: child_view);
553
554 gtk_text_view_add_child_at_anchor (text_view: view, child: frame, anchor);
555
556 recursive_attach_view (depth: depth + 1, GTK_TEXT_VIEW (child_view), anchor);
557}
558
559static void
560easter_egg_callback (GtkWidget *button,
561 gpointer data)
562{
563 static GtkWidget *window = NULL;
564 gpointer window_ptr;
565 GtkTextBuffer *buffer;
566 GtkWidget *view;
567 GtkTextIter iter;
568 GtkTextChildAnchor *anchor;
569 GtkWidget *sw;
570
571 if (window)
572 {
573 gtk_window_present (GTK_WINDOW (window));
574 return;
575 }
576
577 buffer = gtk_text_buffer_new (NULL);
578
579 gtk_text_buffer_get_start_iter (buffer, iter: &iter);
580
581 gtk_text_buffer_insert (buffer, iter: &iter,
582 text: "This buffer is shared by a set of nested text views.\n Nested view:\n", len: -1);
583 anchor = gtk_text_buffer_create_child_anchor (buffer, iter: &iter);
584 gtk_text_buffer_insert (buffer, iter: &iter,
585 text: "\nDon't do this in real applications, please.\n", len: -1);
586
587 view = gtk_text_view_new_with_buffer (buffer);
588
589 recursive_attach_view (depth: 0, GTK_TEXT_VIEW (view), anchor);
590
591 g_object_unref (object: buffer);
592
593 window = gtk_window_new ();
594 gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (gtk_widget_get_root (button)));
595 gtk_window_set_modal (GTK_WINDOW (window), TRUE);
596 sw = gtk_scrolled_window_new ();
597 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
598 hscrollbar_policy: GTK_POLICY_AUTOMATIC,
599 vscrollbar_policy: GTK_POLICY_AUTOMATIC);
600
601 gtk_window_set_child (GTK_WINDOW (window), child: sw);
602 gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), child: view);
603
604 window_ptr = &window;
605 g_object_add_weak_pointer (G_OBJECT (window), weak_pointer_location: window_ptr);
606
607 gtk_window_set_default_size (GTK_WINDOW (window), width: 300, height: 400);
608
609 gtk_widget_show (widget: window);
610}
611

source code of gtk/demos/gtk-demo/textview.c