1
// included by gt_demo.pas
5
* The GtkTextView widget displays a GtkTextBuffer. One GtkTextBuffer
6
* can be displayed by multiple GtkTextViews. This demo has two views
7
* displaying a single buffer, and shows off the widget's text
14
text_egg_window : PGtkWidget;
16
procedure easter_egg_callback (button : PGtkWidget;
17
data : gpointer); forward; cdecl;
23
gray50_bits: array [0..1] of char = (#2, #1);
25
procedure create_tags (buffer : PGtkTextBuffer);
30
(* Create a bunch of tags. Note that it's also possible to
31
* create tags with gtk_text_tag_new() then add them to the
32
* tag table for the buffer, gtk_text_buffer_create_tag() is
33
* just a convenience function. Also note that you don't have
34
* to give tags a name; pass NULL for the name to create an
37
* In any real app, another useful optimization would be to create
38
* a GtkTextTagTable in advance, and reuse the same tag table for
39
* all the buffers with the same tag set, instead of creating
40
* new copies of the same tags for every buffer.
42
* Tags are assigned default priorities in order of addition to the
43
* tag table. That is, tags created later that affect the same text
44
* property affected by an earlier tag will override the earlier
45
* tag. You can modify tag priorities with
46
* gtk_text_tag_set_priority().
49
gtk_text_buffer_create_tag (buffer, 'heading',
50
'weight', [ PANGO_WEIGHT_BOLD,
51
'size', 15 * PANGO_SCALE,
54
gtk_text_buffer_create_tag (buffer, 'italic',
55
'style', [PANGO_STYLE_ITALIC, NULL]);
57
gtk_text_buffer_create_tag (buffer, 'bold',
58
'weight', [ PANGO_WEIGHT_BOLD, NULL] );
60
gtk_text_buffer_create_tag (buffer, 'big',
61
(* points times the PANGO_SCALE factor *)
62
'size', [ 20 * PANGO_SCALE, NULL] );
64
gtk_text_buffer_create_tag (buffer, 'xx-small',
65
'scale',[ PANGO_SCALE_XX_SMALL, NULL] );
67
gtk_text_buffer_create_tag (buffer, 'x-large',
68
'scale', [ PANGO_SCALE_X_LARGE, NULL] );
70
gtk_text_buffer_create_tag (buffer, 'monospace',
71
'family', [ 'monospace', NULL]);
73
gtk_text_buffer_create_tag (buffer, 'blue_foreground',
74
'foreground', [ 'blue', NULL] );
76
gtk_text_buffer_create_tag (buffer, 'red_background',
77
'background', [ 'red', NULL] );
79
stipple := gdk_bitmap_create_from_data (NULL,
80
gray50_bits, gray50_width,
83
gtk_text_buffer_create_tag (buffer, 'background_stipple',
84
'background_stipple',[ stipple, NULL] );
86
gtk_text_buffer_create_tag (buffer, 'foreground_stipple',
87
'foreground_stipple', [stipple, NULL]);
89
g_object_unref (pGObject(stipple));
91
gtk_text_buffer_create_tag (buffer, 'big_gap_before_line',
92
'pixels_above_lines', [30, NULL]);
94
gtk_text_buffer_create_tag (buffer, 'big_gap_after_line',
95
'pixels_below_lines', [30, NULL]);
97
gtk_text_buffer_create_tag (buffer, 'double_spaced_line',
98
'pixels_inside_wrap', [10, NULL]);
100
gtk_text_buffer_create_tag (buffer, 'not_editable',
101
'editable', [FALSE, NULL]);
103
gtk_text_buffer_create_tag (buffer, 'word_wrap',
104
'wrap_mode', [GTK_WRAP_WORD, NULL]);
106
gtk_text_buffer_create_tag (buffer, 'char_wrap',
107
'wrap_mode', [GTK_WRAP_CHAR, NULL]);
109
gtk_text_buffer_create_tag (buffer, 'no_wrap',
110
'wrap_mode', [GTK_WRAP_NONE, NULL]);
112
gtk_text_buffer_create_tag (buffer, 'center',
113
'justification', [GTK_JUSTIFY_CENTER, NULL]);
115
gtk_text_buffer_create_tag (buffer, 'right_justify',
116
'justification', [GTK_JUSTIFY_RIGHT, NULL]);
118
gtk_text_buffer_create_tag (buffer, 'wide_margins',
119
'left_margin', [50, 'right_margin', 50,
122
gtk_text_buffer_create_tag (buffer, 'strikethrough',
123
'strikethrough', [TRUE, NULL]);
125
gtk_text_buffer_create_tag (buffer, 'underline',
126
'underline', [PANGO_UNDERLINE_SINGLE, NULL]);
128
gtk_text_buffer_create_tag (buffer, 'double_underline',
129
'underline', [PANGO_UNDERLINE_DOUBLE, NULL]);
131
gtk_text_buffer_create_tag (buffer, 'superscript',
132
'rise', [10 * PANGO_SCALE, (* 10 pixels *)
133
'size', 8 * PANGO_SCALE, (* 8 points *)
136
gtk_text_buffer_create_tag (buffer, 'subscript',
137
'rise', [-10 * PANGO_SCALE, (* 10 pixels *)
138
'size', 8 * PANGO_SCALE, (* 8 points *)
141
gtk_text_buffer_create_tag (buffer, 'rtl_quote',
142
'wrap_mode', [ GTK_WRAP_WORD,
143
'direction', GTK_TEXT_DIR_RTL,
150
procedure insert_text (buffer : PGtkTextBuffer);
154
text_end : TGtkTextIter;
160
(* demo_find_file() looks in the the current directory first,
161
* so you can run gtk-demo without installing GTK, then looks
162
* in the location where the file is installed.
165
filename := demo_find_file ('gtk-logo-rgb.gif', NULL);
167
if filename <> NULL then
169
pixbuf := gdk_pixbuf_new_from_file (filename, NULL);
173
if pixbuf = NULL then
175
g_error ('Failed to load image file gtk-logo-rgb.gif'#13#10);
179
scaled := gdk_pixbuf_scale_simple (pixbuf, 32, 32, GDK_INTERP_BILINEAR);
180
g_object_unref (pGObject(pixbuf));
183
(* get start of buffer; each insertion will revalidate the
184
* iterator to point to just after the inserted text.
186
gtk_text_buffer_get_iter_at_offset (buffer, @iter, 0);
188
gtk_text_buffer_insert (buffer, @iter,
189
'The text widget can display text with all kinds of nifty attributes. '
190
+ 'It also supports multiple views of the same buffer; '
191
+ 'this demo is showing the same buffer in two places.'#13#10#13#10, -1);
193
gtk_text_buffer_insert_with_tags_by_name (buffer, @iter, 'Font styles. ', -1,
196
gtk_text_buffer_insert (buffer, @iter, 'For example, you can have ', -1);
198
gtk_text_buffer_insert_with_tags_by_name (buffer, @iter,
200
'italic'); // test: left out last argument " NULL "
201
gtk_text_buffer_insert (buffer, @iter, ', ', -1);
202
gtk_text_buffer_insert_with_tags_by_name (buffer, @iter,
205
gtk_text_buffer_insert (buffer, @iter, ', or ', -1);
206
gtk_text_buffer_insert_with_tags_by_name (buffer, @iter,
207
'monospace (typewriter)', -1,
209
gtk_text_buffer_insert (buffer, @iter, ', or ', -1);
210
gtk_text_buffer_insert_with_tags_by_name (buffer, @iter,
213
gtk_text_buffer_insert (buffer, @iter, ' text. ', -1);
214
gtk_text_buffer_insert (buffer, @iter,
215
'It''s best not to hardcode specific text sizes; '
216
+ 'you can use relative sizes as with CSS, such as ', -1);
218
gtk_text_buffer_insert_with_tags_by_name (buffer, @iter,
221
gtk_text_buffer_insert (buffer, @iter, ' or ', -1);
222
gtk_text_buffer_insert_with_tags_by_name (buffer, @iter,
225
gtk_text_buffer_insert (buffer, @iter,
226
' to ensure that your program properly adapts if the user '
227
+ ' changes the default font size.'#13#10#13#10, -1);
229
gtk_text_buffer_insert_with_tags_by_name (buffer, @iter, 'Colors. ', -1,
232
gtk_text_buffer_insert (buffer, @iter, 'Colors such as ', -1);
233
gtk_text_buffer_insert_with_tags_by_name (buffer, @iter,
234
'a blue foreground', -1,
236
gtk_text_buffer_insert (buffer, @iter, ' or ', -1);
237
gtk_text_buffer_insert_with_tags_by_name (buffer, @iter,
238
'a red background', -1,
240
gtk_text_buffer_insert (buffer, @iter, ' or even ', -1);
241
gtk_text_buffer_insert_with_tags_by_name (buffer, @iter,
242
'a stippled red background', -1,
244
['background_stipple',
247
gtk_text_buffer_insert (buffer, @iter, ' or ', -1);
248
gtk_text_buffer_insert_with_tags_by_name (buffer, @iter,
249
'a stippled blue foreground on solid red background', -1,
252
'foreground_stipple',
254
gtk_text_buffer_insert (buffer, @iter, ' (select that to read it) can be used.'#13#10#13#10, -1);
256
gtk_text_buffer_insert_with_tags_by_name (buffer, @iter, 'Underline, strikethrough, and rise. ', -1,
259
gtk_text_buffer_insert_with_tags_by_name (buffer, @iter,
262
gtk_text_buffer_insert (buffer, @iter, ', ', -1);
263
gtk_text_buffer_insert_with_tags_by_name (buffer, @iter,
266
gtk_text_buffer_insert (buffer, @iter, ', ', -1);
267
gtk_text_buffer_insert_with_tags_by_name (buffer, @iter,
268
'double underline', -1,
270
gtk_text_buffer_insert (buffer, @iter, ', ', -1);
271
gtk_text_buffer_insert_with_tags_by_name (buffer, @iter,
274
gtk_text_buffer_insert (buffer, @iter, ', and ', -1);
275
gtk_text_buffer_insert_with_tags_by_name (buffer, @iter,
278
gtk_text_buffer_insert (buffer, @iter, ' are all supported.'#13#10#13#10, -1);
280
gtk_text_buffer_insert_with_tags_by_name (buffer, @iter, 'Images. ', -1,
283
gtk_text_buffer_insert (buffer, @iter, 'The buffer can have images in it: ', -1);
284
gtk_text_buffer_insert_pixbuf (buffer, @iter, pixbuf);
285
gtk_text_buffer_insert_pixbuf (buffer, @iter, pixbuf);
286
gtk_text_buffer_insert_pixbuf (buffer, @iter, pixbuf);
287
gtk_text_buffer_insert (buffer, @iter, ' for example.'#13#10, -1);
289
gtk_text_buffer_insert_with_tags_by_name (buffer, @iter, 'Spacing. ', -1,
292
gtk_text_buffer_insert (buffer, @iter, 'You can adjust the amount of space before each line.'#13#10, -1);
294
gtk_text_buffer_insert_with_tags_by_name (buffer, @iter,
295
'This line has a whole lot of space before it.'#13#10, -1,
296
'big_gap_before_line', ['wide_margins', NULL]);
297
gtk_text_buffer_insert_with_tags_by_name (buffer, @iter,
298
'You can also adjust the amount of space after each line; '
299
+ 'this line has a whole lot of space after it.'#13#10, -1,
300
'big_gap_after_line', ['wide_margins', NULL]);
302
gtk_text_buffer_insert_with_tags_by_name (buffer, @iter,
303
'You can also adjust the amount of space between wrapped lines; '
304
+ 'this line has extra space between each wrapped line in the same paragraph. '
305
+ 'To show off wrapping, some filler text: the quick brown fox jumped over '
306
+ 'the lazy dog. Blah blah blah blah blah blah blah blah blah.'#13#10, -1,
307
'double_spaced_line', ['wide_margins', NULL]);
309
gtk_text_buffer_insert (buffer, @iter, 'Also note that those lines have extra-wide margins.'#13#10#13#10, -1);
311
gtk_text_buffer_insert_with_tags_by_name (buffer, @iter, 'Editability. ', -1,
314
gtk_text_buffer_insert_with_tags_by_name (buffer, @iter,
315
'This line is ''locked down'' and can''t be edited by the user - '
316
+ 'just try it! You can''t delete this line.'#13#10#13#10, -1,
317
'not_editable', [NULL]);
319
gtk_text_buffer_insert_with_tags_by_name (buffer, @iter, 'Wrapping. ', -1,
322
gtk_text_buffer_insert (buffer, @iter,
323
'This line (and most of the others in this buffer) is word-wrapped, '
324
+ 'using the proper Unicode algorithm. Word wrap should work in all '
325
+ 'scripts and languages that GTK+ supports. Let''s make this a long '
326
+ 'paragraph to demonstrate: blah blah blah blah blah blah blah blah '
327
+ 'blah blah blah blah blah blah blah blah blah blah blah'#13#10#13#10, -1);
329
gtk_text_buffer_insert_with_tags_by_name (buffer, @iter,
330
'This line has character-based wrapping, and can wrap between '
331
+ 'any two character glyphs. Let''s make this a long paragraph to '
332
+ 'demonstrate: blah blah blah blah blah blah blah blah blah blah '
333
+ 'blah blah blah blah blah blah blah blah blah'#13#10#13#10, -1,
334
'char_wrap', [NULL]);
336
gtk_text_buffer_insert_with_tags_by_name (buffer, @iter,
337
+ 'This line has all wrapping turned off, so it makes the horizontal '
338
+ 'scrollbar appear.'#13#10#13#10#13#10, -1,
341
gtk_text_buffer_insert_with_tags_by_name (buffer, @iter, 'Justification. ', -1,
344
gtk_text_buffer_insert_with_tags_by_name (buffer, @iter,
345
#13#10'This line has center justification.'#13#10, -1,
348
gtk_text_buffer_insert_with_tags_by_name (buffer, @iter,
349
'This line has right justification.'#13#10, -1,
350
'right_justify', [NULL]);
352
gtk_text_buffer_insert_with_tags_by_name (buffer, @iter,
353
#13#10'This line has big wide margins. Text text text text text text '
354
+ 'text text text text text text text text text text text text text text '
355
+ 'text text text text text text text text text text text text text text '
356
+ 'text text.'#13#10, -1,'wide_margins', [NULL]);
358
gtk_text_buffer_insert_with_tags_by_name (buffer, @iter, 'Internationalization. ', -1,
361
gtk_text_buffer_insert (buffer, @iter,
362
'You can put all sorts of Unicode text in the buffer.'#13#10#13#10
363
+ 'German (Deutsch Süd) Grüß Gott'#13#10
364
+ 'Greek (Ελληνικά) Γειά σας'#13#10
365
+ 'Hebrew שלום'#13#10
366
+ 'Japanese (日本語)'#13#10#13#10
367
+ 'The widget properly handles bidirectional text, word wrapping, '
368
+ 'DOS/UNIX/Unicode paragraph separators, grapheme boundaries, '
369
+ 'and so on using the Pango internationalization framework.'#13#10, -1);
371
gtk_text_buffer_insert (buffer, @iter, 'Here''s a word-wrapped quote in a right-to-left language:'#13#10, -1);
372
gtk_text_buffer_insert_with_tags_by_name (buffer, @iter,
373
'وقد بدأ ثلاث من أكثر المؤسسات تقدما في '
374
+ 'شبكة اكسيون برامجها كمنظمات لا تسعى للربح، '
375
+ 'ثم تحولت في السنوات الخمس الماضية إلى مؤسسات '
376
+ 'مالية منظمة، وباتت جزءا من النظام المالي في '
377
+ 'بلدانها، ولكنها تتخصص في خدمة قطاع المشروعات الصغيرة. '
378
+ 'وأحد أكثر هذه المؤسسات نجاحا هو »بانكوسول« '
379
+ 'في بوليفيا.'#13#10#13#10, -1,
380
'rtl_quote', [NULL]);
382
gtk_text_buffer_insert (buffer, @iter, 'You can put widgets in the buffer: Here''s a button: ', -1);
383
gtk_text_buffer_create_child_anchor (buffer, @iter);
384
gtk_text_buffer_insert (buffer, @iter, ' and a menu: ', -1);
385
gtk_text_buffer_create_child_anchor (buffer, @iter);
386
gtk_text_buffer_insert (buffer, @iter, ' and a scale: ', -1);
387
gtk_text_buffer_create_child_anchor (buffer, @iter);
388
gtk_text_buffer_insert (buffer, @iter, ' and an animation: ', -1);
389
gtk_text_buffer_create_child_anchor (buffer, @iter);
390
gtk_text_buffer_insert (buffer, @iter, ' finally a text entry: ', -1);
391
gtk_text_buffer_create_child_anchor (buffer, @iter);
392
gtk_text_buffer_insert (buffer, @iter, '.'#13#10, -1);
394
gtk_text_buffer_insert (buffer, @iter,
395
#13#10#13#10'This demo doesn''t demonstrate all the GtkTextBuffer features; '
396
+ 'it leaves out, for example: invisible/hidden text (doesn''t work in GTK 2, but planned), '
397
+ 'tab stops, application-drawn areas on the sides of the widget for displaying breakpoints and such...', -1);
399
(* Apply word_wrap tag to whole buffer *)
400
gtk_text_buffer_get_bounds (buffer, @text_start, @text_end);
401
gtk_text_buffer_apply_tag_by_name (buffer, 'word_wrap', @text_start, @text_end);
403
g_object_unref (pGObject(pixbuf));
406
function find_anchor (iter : PGtkTextIter): gboolean; cdecl;
409
while gtk_text_iter_forward_char (iter) do
411
if gtk_text_iter_get_child_anchor (iter)<> NULL then
416
procedure attach_widgets (text_view : PGtkWidget);
419
buffer : PGtkTextBuffer;
422
anchor : PGtkTextChildAnchor;
425
menu_item : PGtkWidget;
430
buffer := gtk_text_view_get_buffer (pGtkTextView(text_view));
432
gtk_text_buffer_get_start_iter (buffer, @iter);
435
while find_anchor (@iter) do
437
anchor := gtk_text_iter_get_child_anchor (@iter);
441
widget := gtk_button_new_with_label ('Click Me');
443
g_signal_connect (pGObject(widget), 'clicked',
444
TGCallback(@easter_egg_callback),
448
menu := gtk_menu_new ();
450
widget := gtk_option_menu_new ();
452
menu_item := gtk_menu_item_new_with_label ('Option 1');
453
gtk_menu_shell_append (pGtkMenuShell(menu), menu_item);
455
menu_item := gtk_menu_item_new_with_label ('Option 2');
456
gtk_menu_shell_append (pGtkMenuShell(menu), menu_item);
458
menu_item := gtk_menu_item_new_with_label ('Option 3');
459
gtk_menu_shell_append (pGtkMenuShell(menu), menu_item);
461
gtk_option_menu_set_menu (pGtkOptionMenu(widget), menu);
464
widget := gtk_hscale_new (NULL);
465
gtk_range_set_range (pGtkRange(widget), 0, 100);
466
gtk_widget_set_size_request (widget, 70, -1);
469
filename := demo_find_file ('floppybuddy.gif', NULL);
470
widget := gtk_image_new_from_file (filename);
474
widget := gtk_entry_new ();
477
widget := NULL; (* avoids a compiler warning *)
482
if widget <> NULL then
484
gtk_text_view_add_child_at_anchor (pGtkTextView(text_view), widget, anchor);
485
gtk_widget_show_all (widget);
493
function do_textview : PGtkWidget;
499
buffer : PGtkTextBuffer;
502
if text_window = NULL then
504
text_window := gtk_window_new (GTK_WINDOW_TOPLEVEL);
505
gtk_window_set_default_size (pGtkWindow(text_window), 450, 450);
507
g_signal_connect (text_window, 'destroy',
508
TGCallback(@gtk_widget_destroyed), @text_window);
510
gtk_window_set_title (pGtkWindow(text_window), 'TextView');
511
gtk_container_set_border_width (pGtkContainer(text_window), 0);
513
vpaned := gtk_vpaned_new ();
514
gtk_container_set_border_width (pGtkContainer(vpaned), 5);
515
gtk_container_add (pGtkContainer(text_window), vpaned);
517
(* For convenience, we just use the autocreated buffer from
518
* the first text view; you could also create the buffer
519
* by itself with gtk_text_buffer_new(), then later create
522
view1 := gtk_text_view_new ();
523
buffer := gtk_text_view_get_buffer (pGtkTextView(view1));
524
view2 := gtk_text_view_new_with_buffer (buffer);
526
sw := gtk_scrolled_window_new (NULL, NULL);
527
gtk_scrolled_window_set_policy (pGtkScrolledWindow(sw),
528
GTK_POLICY_AUTOMATIC,
529
GTK_POLICY_AUTOMATIC);
531
gtk_paned_add1 (pGtkPaned(vpaned), sw);
533
gtk_container_add (pGtkContainer(sw), view1);
535
sw := gtk_scrolled_window_new (NULL, NULL);
536
gtk_scrolled_window_set_policy (pGtkScrolledWindow(sw),
537
GTK_POLICY_AUTOMATIC,
538
GTK_POLICY_AUTOMATIC);
539
gtk_paned_add2 (pGtkPaned(vpaned), sw);
541
gtk_container_add (pGtkContainer(sw), view2);
543
create_tags (buffer);
544
insert_text (buffer);
546
attach_widgets (view1);
547
attach_widgets (view2);
549
gtk_widget_show_all (vpaned);
552
if not GTK_WIDGET_VISIBLE (text_window) then
553
gtk_widget_show (text_window)
555
gtk_widget_destroy (text_window);
559
do_textview := text_window;
562
procedure recursive_attach_view (depth : integer;
564
anchor : PGtkTextChildAnchor);
575
child_view := gtk_text_view_new_with_buffer (gtk_text_view_get_buffer (view));
577
(* Event box is to add a black border around each child view *)
578
event_box := gtk_event_box_new ();
579
gdk_color_parse ('black', @color);
580
gtk_widget_modify_bg (event_box, GTK_STATE_NORMAL, @color);
582
align := gtk_alignment_new (0.5, 0.5, 1.0, 1.0);
583
gtk_container_set_border_width (pGtkContainer(align), 1);
585
gtk_container_add (pGtkContainer(event_box), align);
586
gtk_container_add (pGtkContainer(align), child_view);
588
gtk_text_view_add_child_at_anchor (view, event_box, anchor);
590
recursive_attach_view (depth + 1, pGtkTextView(child_view), anchor);
593
procedure easter_egg_callback(button : PGtkWidget;
594
data : gpointer); cdecl;
598
buffer : PGtkTextBuffer;
600
anchor : PGtkTextChildAnchor;
603
if text_egg_window <> NULL then
605
gtk_window_present (pGtkWindow(text_egg_window));
609
buffer := gtk_text_buffer_new (NULL);
611
gtk_text_buffer_get_start_iter (buffer, @iter);
613
gtk_text_buffer_insert (buffer, @iter,
614
'This buffer is shared by a set of nested text views.'#13#10'Nested view:'#13#10, -1);
615
anchor := gtk_text_buffer_create_child_anchor (buffer, @iter);
616
gtk_text_buffer_insert (buffer, @iter,
617
#13#10'Don''t do this in real applications, please.'#13#10, -1);
619
view := gtk_text_view_new_with_buffer (buffer);
621
recursive_attach_view (0, pGtkTextView(view), anchor);
623
g_object_unref (pGObject(buffer));
625
text_egg_window := gtk_window_new (GTK_WINDOW_TOPLEVEL);
626
sw := gtk_scrolled_window_new (NULL, NULL);
627
gtk_scrolled_window_set_policy (pGtkScrolledWindow(sw),
628
GTK_POLICY_AUTOMATIC,
629
GTK_POLICY_AUTOMATIC);
631
gtk_container_add (pGtkContainer(text_egg_window), sw);
632
gtk_container_add (pGtkContainer(sw), view);
634
g_object_add_weak_pointer (pGObject(text_egg_window),
635
gpointer (@text_egg_window));
637
gtk_window_set_default_size (pGtkWindow(text_egg_window), 300, 400);
639
gtk_widget_show_all (text_egg_window);
642
// included by gt_demo.pas