textview.inc 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643
  1. // included by gt_demo.pas
  2. (* Text Widget
  3. *
  4. * The GtkTextView widget displays a GtkTextBuffer. One GtkTextBuffer
  5. * can be displayed by multiple GtkTextViews. This demo has two views
  6. * displaying a single buffer, and shows off the widget's text
  7. * formatting features.
  8. *
  9. *)
  10. var
  11. text_window,
  12. text_egg_window : PGtkWidget;
  13. procedure easter_egg_callback (button : PGtkWidget;
  14. data : gpointer); forward; cdecl;
  15. const
  16. gray50_width = 2;
  17. gray50_height = 2;
  18. gray50_bits: array [0..1] of char = (#2, #1);
  19. procedure create_tags (buffer : PGtkTextBuffer);
  20. var
  21. stipple : PGdkBitmap;
  22. begin
  23. (* Create a bunch of tags. Note that it's also possible to
  24. * create tags with gtk_text_tag_new() then add them to the
  25. * tag table for the buffer, gtk_text_buffer_create_tag() is
  26. * just a convenience function. Also note that you don't have
  27. * to give tags a name; pass NULL for the name to create an
  28. * anonymous tag.
  29. *
  30. * In any real app, another useful optimization would be to create
  31. * a GtkTextTagTable in advance, and reuse the same tag table for
  32. * all the buffers with the same tag set, instead of creating
  33. * new copies of the same tags for every buffer.
  34. *
  35. * Tags are assigned default priorities in order of addition to the
  36. * tag table. That is, tags created later that affect the same text
  37. * property affected by an earlier tag will override the earlier
  38. * tag. You can modify tag priorities with
  39. * gtk_text_tag_set_priority().
  40. *)
  41. gtk_text_buffer_create_tag (buffer, 'heading',
  42. 'weight', [ PANGO_WEIGHT_BOLD,
  43. 'size', 15 * PANGO_SCALE,
  44. NULL] );
  45. gtk_text_buffer_create_tag (buffer, 'italic',
  46. 'style', [PANGO_STYLE_ITALIC, NULL]);
  47. gtk_text_buffer_create_tag (buffer, 'bold',
  48. 'weight', [ PANGO_WEIGHT_BOLD, NULL] );
  49. gtk_text_buffer_create_tag (buffer, 'big',
  50. (* points times the PANGO_SCALE factor *)
  51. 'size', [ 20 * PANGO_SCALE, NULL] );
  52. gtk_text_buffer_create_tag (buffer, 'xx-small',
  53. 'scale',[ PANGO_SCALE_XX_SMALL, NULL] );
  54. gtk_text_buffer_create_tag (buffer, 'x-large',
  55. 'scale', [ PANGO_SCALE_X_LARGE, NULL] );
  56. gtk_text_buffer_create_tag (buffer, 'monospace',
  57. 'family', [ 'monospace', NULL]);
  58. gtk_text_buffer_create_tag (buffer, 'blue_foreground',
  59. 'foreground', [ 'blue', NULL] );
  60. gtk_text_buffer_create_tag (buffer, 'red_background',
  61. 'background', [ 'red', NULL] );
  62. stipple := gdk_bitmap_create_from_data (NULL,
  63. gray50_bits, gray50_width,
  64. gray50_height);
  65. gtk_text_buffer_create_tag (buffer, 'background_stipple',
  66. 'background_stipple',[ stipple, NULL] );
  67. gtk_text_buffer_create_tag (buffer, 'foreground_stipple',
  68. 'foreground_stipple', [stipple, NULL]);
  69. g_object_unref (pGObject(stipple));
  70. gtk_text_buffer_create_tag (buffer, 'big_gap_before_line',
  71. 'pixels_above_lines', [30, NULL]);
  72. gtk_text_buffer_create_tag (buffer, 'big_gap_after_line',
  73. 'pixels_below_lines', [30, NULL]);
  74. gtk_text_buffer_create_tag (buffer, 'double_spaced_line',
  75. 'pixels_inside_wrap', [10, NULL]);
  76. gtk_text_buffer_create_tag (buffer, 'not_editable',
  77. 'editable', [FALSE, NULL]);
  78. gtk_text_buffer_create_tag (buffer, 'word_wrap',
  79. 'wrap_mode', [GTK_WRAP_WORD, NULL]);
  80. gtk_text_buffer_create_tag (buffer, 'char_wrap',
  81. 'wrap_mode', [GTK_WRAP_CHAR, NULL]);
  82. gtk_text_buffer_create_tag (buffer, 'no_wrap',
  83. 'wrap_mode', [GTK_WRAP_NONE, NULL]);
  84. gtk_text_buffer_create_tag (buffer, 'center',
  85. 'justification', [GTK_JUSTIFY_CENTER, NULL]);
  86. gtk_text_buffer_create_tag (buffer, 'right_justify',
  87. 'justification', [GTK_JUSTIFY_RIGHT, NULL]);
  88. gtk_text_buffer_create_tag (buffer, 'wide_margins',
  89. 'left_margin', [50, 'right_margin', 50,
  90. NULL]);
  91. gtk_text_buffer_create_tag (buffer, 'strikethrough',
  92. 'strikethrough', [TRUE, NULL]);
  93. gtk_text_buffer_create_tag (buffer, 'underline',
  94. 'underline', [PANGO_UNDERLINE_SINGLE, NULL]);
  95. gtk_text_buffer_create_tag (buffer, 'double_underline',
  96. 'underline', [PANGO_UNDERLINE_DOUBLE, NULL]);
  97. gtk_text_buffer_create_tag (buffer, 'superscript',
  98. 'rise', [10 * PANGO_SCALE, (* 10 pixels *)
  99. 'size', 8 * PANGO_SCALE, (* 8 points *)
  100. NULL]);
  101. gtk_text_buffer_create_tag (buffer, 'subscript',
  102. 'rise', [-10 * PANGO_SCALE, (* 10 pixels *)
  103. 'size', 8 * PANGO_SCALE, (* 8 points *)
  104. NULL]);
  105. gtk_text_buffer_create_tag (buffer, 'rtl_quote',
  106. 'wrap_mode', [ GTK_WRAP_WORD,
  107. 'direction', GTK_TEXT_DIR_RTL,
  108. 'indent', 30,
  109. 'left_margin', 20,
  110. 'right_margin', 20,
  111. NULL]);
  112. end;
  113. procedure insert_text (buffer : PGtkTextBuffer);
  114. var
  115. iter,
  116. text_start,
  117. text_end : TGtkTextIter;
  118. pixbuf,
  119. scaled : PGdkPixbuf;
  120. filename : pchar;
  121. begin
  122. (* demo_find_file() looks in the the current directory first,
  123. * so you can run gtk-demo without installing GTK, then looks
  124. * in the location where the file is installed.
  125. *)
  126. pixbuf := NULL;
  127. filename := demo_find_file ('gtk-logo-rgb.gif', NULL);
  128. if filename <> NULL then
  129. begin
  130. pixbuf := gdk_pixbuf_new_from_file (filename, NULL);
  131. g_free (filename);
  132. end;
  133. if pixbuf = NULL then
  134. begin
  135. g_error ('Failed to load image file gtk-logo-rgb.gif'#13#10);
  136. exit;
  137. end;
  138. scaled := gdk_pixbuf_scale_simple (pixbuf, 32, 32, GDK_INTERP_BILINEAR);
  139. g_object_unref (pGObject(pixbuf));
  140. pixbuf := scaled;
  141. (* get start of buffer; each insertion will revalidate the
  142. * iterator to point to just after the inserted text.
  143. *)
  144. gtk_text_buffer_get_iter_at_offset (buffer, @iter, 0);
  145. gtk_text_buffer_insert (buffer, @iter,
  146. 'The text widget can display text with all kinds of nifty attributes. '
  147. + 'It also supports multiple views of the same buffer; '
  148. + 'this demo is showing the same buffer in two places.'#13#10#13#10, -1);
  149. gtk_text_buffer_insert_with_tags_by_name (buffer, @iter, 'Font styles. ', -1,
  150. 'heading');
  151. gtk_text_buffer_insert (buffer, @iter, 'For example, you can have ', -1);
  152. gtk_text_buffer_insert_with_tags_by_name (buffer, @iter,
  153. 'italic', -1,
  154. 'italic'); // test: left out last argument " NULL "
  155. gtk_text_buffer_insert (buffer, @iter, ', ', -1);
  156. gtk_text_buffer_insert_with_tags_by_name (buffer, @iter,
  157. 'bold', -1,
  158. 'bold');
  159. gtk_text_buffer_insert (buffer, @iter, ', or ', -1);
  160. gtk_text_buffer_insert_with_tags_by_name (buffer, @iter,
  161. 'monospace (typewriter)', -1,
  162. 'monospace');
  163. gtk_text_buffer_insert (buffer, @iter, ', or ', -1);
  164. gtk_text_buffer_insert_with_tags_by_name (buffer, @iter,
  165. 'big', -1,
  166. 'big');
  167. gtk_text_buffer_insert (buffer, @iter, ' text. ', -1);
  168. gtk_text_buffer_insert (buffer, @iter,
  169. 'It''s best not to hardcode specific text sizes; '
  170. + 'you can use relative sizes as with CSS, such as ', -1);
  171. gtk_text_buffer_insert_with_tags_by_name (buffer, @iter,
  172. 'xx-small', -1,
  173. 'xx-small');
  174. gtk_text_buffer_insert (buffer, @iter, ' or ', -1);
  175. gtk_text_buffer_insert_with_tags_by_name (buffer, @iter,
  176. 'x-large', -1,
  177. 'x-large');
  178. gtk_text_buffer_insert (buffer, @iter,
  179. ' to ensure that your program properly adapts if the user '
  180. + ' changes the default font size.'#13#10#13#10, -1);
  181. gtk_text_buffer_insert_with_tags_by_name (buffer, @iter, 'Colors. ', -1,
  182. 'heading');
  183. gtk_text_buffer_insert (buffer, @iter, 'Colors such as ', -1);
  184. gtk_text_buffer_insert_with_tags_by_name (buffer, @iter,
  185. 'a blue foreground', -1,
  186. 'blue_foreground');
  187. gtk_text_buffer_insert (buffer, @iter, ' or ', -1);
  188. gtk_text_buffer_insert_with_tags_by_name (buffer, @iter,
  189. 'a red background', -1,
  190. 'red_background');
  191. gtk_text_buffer_insert (buffer, @iter, ' or even ', -1);
  192. gtk_text_buffer_insert_with_tags_by_name (buffer, @iter,
  193. 'a stippled red background', -1,
  194. 'red_background',
  195. ['background_stipple',
  196. NULL]);
  197. gtk_text_buffer_insert (buffer, @iter, ' or ', -1);
  198. gtk_text_buffer_insert_with_tags_by_name (buffer, @iter,
  199. 'a stippled blue foreground on solid red background', -1,
  200. 'blue_foreground',
  201. ['red_background',
  202. 'foreground_stipple',
  203. NULL]);
  204. gtk_text_buffer_insert (buffer, @iter, ' (select that to read it) can be used.'#13#10#13#10, -1);
  205. gtk_text_buffer_insert_with_tags_by_name (buffer, @iter, 'Underline, strikethrough, and rise. ', -1,
  206. 'heading');
  207. gtk_text_buffer_insert_with_tags_by_name (buffer, @iter,
  208. 'Strikethrough', -1,
  209. 'strikethrough');
  210. gtk_text_buffer_insert (buffer, @iter, ', ', -1);
  211. gtk_text_buffer_insert_with_tags_by_name (buffer, @iter,
  212. 'underline', -1,
  213. 'underline');
  214. gtk_text_buffer_insert (buffer, @iter, ', ', -1);
  215. gtk_text_buffer_insert_with_tags_by_name (buffer, @iter,
  216. 'double underline', -1,
  217. 'double_underline');
  218. gtk_text_buffer_insert (buffer, @iter, ', ', -1);
  219. gtk_text_buffer_insert_with_tags_by_name (buffer, @iter,
  220. 'superscript', -1,
  221. 'superscript');
  222. gtk_text_buffer_insert (buffer, @iter, ', and ', -1);
  223. gtk_text_buffer_insert_with_tags_by_name (buffer, @iter,
  224. 'subscript', -1,
  225. 'subscript');
  226. gtk_text_buffer_insert (buffer, @iter, ' are all supported.'#13#10#13#10, -1);
  227. gtk_text_buffer_insert_with_tags_by_name (buffer, @iter, 'Images. ', -1,
  228. 'heading');
  229. gtk_text_buffer_insert (buffer, @iter, 'The buffer can have images in it: ', -1);
  230. gtk_text_buffer_insert_pixbuf (buffer, @iter, pixbuf);
  231. gtk_text_buffer_insert_pixbuf (buffer, @iter, pixbuf);
  232. gtk_text_buffer_insert_pixbuf (buffer, @iter, pixbuf);
  233. gtk_text_buffer_insert (buffer, @iter, ' for example.'#13#10, -1);
  234. gtk_text_buffer_insert_with_tags_by_name (buffer, @iter, 'Spacing. ', -1,
  235. 'heading', [NULL]);
  236. gtk_text_buffer_insert (buffer, @iter, 'You can adjust the amount of space before each line.'#13#10, -1);
  237. gtk_text_buffer_insert_with_tags_by_name (buffer, @iter,
  238. 'This line has a whole lot of space before it.'#13#10, -1,
  239. 'big_gap_before_line', ['wide_margins', NULL]);
  240. gtk_text_buffer_insert_with_tags_by_name (buffer, @iter,
  241. 'You can also adjust the amount of space after each line; '
  242. + 'this line has a whole lot of space after it.'#13#10, -1,
  243. 'big_gap_after_line', ['wide_margins', NULL]);
  244. gtk_text_buffer_insert_with_tags_by_name (buffer, @iter,
  245. 'You can also adjust the amount of space between wrapped lines; '
  246. + 'this line has extra space between each wrapped line in the same paragraph. '
  247. + 'To show off wrapping, some filler text: the quick brown fox jumped over '
  248. + 'the lazy dog. Blah blah blah blah blah blah blah blah blah.'#13#10, -1,
  249. 'double_spaced_line', ['wide_margins', NULL]);
  250. gtk_text_buffer_insert (buffer, @iter, 'Also note that those lines have extra-wide margins.'#13#10#13#10, -1);
  251. gtk_text_buffer_insert_with_tags_by_name (buffer, @iter, 'Editability. ', -1,
  252. 'heading', [NULL]);
  253. gtk_text_buffer_insert_with_tags_by_name (buffer, @iter,
  254. 'This line is ''locked down'' and can''t be edited by the user - '
  255. + 'just try it! You can''t delete this line.'#13#10#13#10, -1,
  256. 'not_editable', [NULL]);
  257. gtk_text_buffer_insert_with_tags_by_name (buffer, @iter, 'Wrapping. ', -1,
  258. 'heading', [NULL]);
  259. gtk_text_buffer_insert (buffer, @iter,
  260. 'This line (and most of the others in this buffer) is word-wrapped, '
  261. + 'using the proper Unicode algorithm. Word wrap should work in all '
  262. + 'scripts and languages that GTK+ supports. Let''s make this a long '
  263. + 'paragraph to demonstrate: blah blah blah blah blah blah blah blah '
  264. + 'blah blah blah blah blah blah blah blah blah blah blah'#13#10#13#10, -1);
  265. gtk_text_buffer_insert_with_tags_by_name (buffer, @iter,
  266. 'This line has character-based wrapping, and can wrap between '
  267. + 'any two character glyphs. Let''s make this a long paragraph to '
  268. + 'demonstrate: blah blah blah blah blah blah blah blah blah blah '
  269. + 'blah blah blah blah blah blah blah blah blah'#13#10#13#10, -1,
  270. 'char_wrap', [NULL]);
  271. gtk_text_buffer_insert_with_tags_by_name (buffer, @iter, PChar(
  272. 'This line has all wrapping turned off, so it makes the horizontal '
  273. + 'scrollbar appear.'#13#10#13#10#13#10), -1,
  274. 'no_wrap', [NULL]);
  275. gtk_text_buffer_insert_with_tags_by_name (buffer, @iter, 'Justification. ', -1,
  276. 'heading', [NULL]);
  277. gtk_text_buffer_insert_with_tags_by_name (buffer, @iter,
  278. #13#10'This line has center justification.'#13#10, -1,
  279. 'center', [NULL]);
  280. gtk_text_buffer_insert_with_tags_by_name (buffer, @iter,
  281. 'This line has right justification.'#13#10, -1,
  282. 'right_justify', [NULL]);
  283. gtk_text_buffer_insert_with_tags_by_name (buffer, @iter,
  284. #13#10'This line has big wide margins. Text text text text text text '
  285. + 'text text text text text text text text text text text text text text '
  286. + 'text text text text text text text text text text text text text text '
  287. + 'text text.'#13#10, -1,'wide_margins', [NULL]);
  288. gtk_text_buffer_insert_with_tags_by_name (buffer, @iter, 'Internationalization. ', -1,
  289. 'heading', [NULL]);
  290. gtk_text_buffer_insert (buffer, @iter,
  291. 'You can put all sorts of Unicode text in the buffer.'#13#10#13#10
  292. + 'German (Deutsch Süd) Grüß Gott'#13#10
  293. + 'Greek (Ελληνικά) Γειά σας'#13#10
  294. + 'Hebrew שלום'#13#10
  295. + 'Japanese (日本語)'#13#10#13#10
  296. + 'The widget properly handles bidirectional text, word wrapping, '
  297. + 'DOS/UNIX/Unicode paragraph separators, grapheme boundaries, '
  298. + 'and so on using the Pango internationalization framework.'#13#10, -1);
  299. gtk_text_buffer_insert (buffer, @iter, 'Here''s a word-wrapped quote in a right-to-left language:'#13#10, -1);
  300. gtk_text_buffer_insert_with_tags_by_name (buffer, @iter,
  301. 'وقد بدأ ثلاث من أكثر المؤسسات تقدما في '
  302. + 'شبكة اكسيون برامجها كمنظمات لا تسعى للربح، '
  303. + 'ثم تحولت في السنوات الخمس الماضية إلى مؤسسات '
  304. + 'مالية منظمة، وباتت جزءا من النظام المالي في '
  305. + 'بلدانها، ولكنها تتخصص في خدمة قطاع المشروعات الصغيرة. '
  306. + 'وأحد أكثر هذه المؤسسات نجاحا هو »بانكوسول« '
  307. + 'في بوليفيا.'#13#10#13#10, -1,
  308. 'rtl_quote', [NULL]);
  309. gtk_text_buffer_insert (buffer, @iter, 'You can put widgets in the buffer: Here''s a button: ', -1);
  310. gtk_text_buffer_create_child_anchor (buffer, @iter);
  311. gtk_text_buffer_insert (buffer, @iter, ' and a menu: ', -1);
  312. gtk_text_buffer_create_child_anchor (buffer, @iter);
  313. gtk_text_buffer_insert (buffer, @iter, ' and a scale: ', -1);
  314. gtk_text_buffer_create_child_anchor (buffer, @iter);
  315. gtk_text_buffer_insert (buffer, @iter, ' and an animation: ', -1);
  316. gtk_text_buffer_create_child_anchor (buffer, @iter);
  317. gtk_text_buffer_insert (buffer, @iter, ' finally a text entry: ', -1);
  318. gtk_text_buffer_create_child_anchor (buffer, @iter);
  319. gtk_text_buffer_insert (buffer, @iter, '.'#13#10, -1);
  320. gtk_text_buffer_insert (buffer, @iter,
  321. #13#10#13#10'This demo doesn''t demonstrate all the GtkTextBuffer features; '
  322. + 'it leaves out, for example: invisible/hidden text (doesn''t work in GTK 2, but planned), '
  323. + 'tab stops, application-drawn areas on the sides of the widget for displaying breakpoints and such...', -1);
  324. (* Apply word_wrap tag to whole buffer *)
  325. gtk_text_buffer_get_bounds (buffer, @text_start, @text_end);
  326. gtk_text_buffer_apply_tag_by_name (buffer, 'word_wrap', @text_start, @text_end);
  327. g_object_unref (pGObject(pixbuf));
  328. end;
  329. function find_anchor (iter : PGtkTextIter): gboolean; cdecl;
  330. begin
  331. while gtk_text_iter_forward_char (iter) do
  332. begin
  333. if gtk_text_iter_get_child_anchor (iter)<> NULL then
  334. exit (TRUE);
  335. end;
  336. end;
  337. procedure attach_widgets (text_view : PGtkWidget);
  338. var
  339. iter : TGtkTextIter;
  340. buffer : PGtkTextBuffer;
  341. i : integer;
  342. anchor : PGtkTextChildAnchor;
  343. widget,
  344. menu,
  345. menu_item : PGtkWidget;
  346. filename : pgchar;
  347. begin
  348. buffer := gtk_text_view_get_buffer (pGtkTextView(text_view));
  349. gtk_text_buffer_get_start_iter (buffer, @iter);
  350. i := 0;
  351. while find_anchor (@iter) do
  352. begin
  353. anchor := gtk_text_iter_get_child_anchor (@iter);
  354. case i of
  355. 0: begin
  356. widget := gtk_button_new_with_label ('Click Me');
  357. g_signal_connect (pGObject(widget), 'clicked',
  358. TGCallback(@easter_egg_callback),
  359. NULL);
  360. end;
  361. 1: begin
  362. menu := gtk_menu_new ();
  363. widget := gtk_option_menu_new ();
  364. menu_item := gtk_menu_item_new_with_label ('Option 1');
  365. gtk_menu_shell_append (pGtkMenuShell(menu), menu_item);
  366. menu_item := gtk_menu_item_new_with_label ('Option 2');
  367. gtk_menu_shell_append (pGtkMenuShell(menu), menu_item);
  368. menu_item := gtk_menu_item_new_with_label ('Option 3');
  369. gtk_menu_shell_append (pGtkMenuShell(menu), menu_item);
  370. gtk_option_menu_set_menu (pGtkOptionMenu(widget), menu);
  371. end;
  372. 2: begin
  373. widget := gtk_hscale_new (NULL);
  374. gtk_range_set_range (pGtkRange(widget), 0, 100);
  375. gtk_widget_set_size_request (widget, 70, -1);
  376. end;
  377. 3: begin
  378. filename := demo_find_file ('floppybuddy.gif', NULL);
  379. widget := gtk_image_new_from_file (filename);
  380. g_free (filename);
  381. end;
  382. 4: begin
  383. widget := gtk_entry_new ();
  384. end;
  385. else begin
  386. widget := NULL; (* avoids a compiler warning *)
  387. exit;
  388. end;
  389. end; {of case}
  390. if widget <> NULL then
  391. begin
  392. gtk_text_view_add_child_at_anchor (pGtkTextView(text_view), widget, anchor);
  393. gtk_widget_show_all (widget);
  394. end;
  395. inc(i);
  396. end; {of while}
  397. end;
  398. function do_textview : PGtkWidget;
  399. var
  400. vpaned,
  401. view1,
  402. view2,
  403. sw : PGtkWidget;
  404. buffer : PGtkTextBuffer;
  405. begin
  406. if text_window = NULL then
  407. begin
  408. text_window := gtk_window_new (GTK_WINDOW_TOPLEVEL);
  409. gtk_window_set_default_size (pGtkWindow(text_window), 450, 450);
  410. g_signal_connect (text_window, 'destroy',
  411. TGCallback(@gtk_widget_destroyed), @text_window);
  412. gtk_window_set_title (pGtkWindow(text_window), 'TextView');
  413. gtk_container_set_border_width (pGtkContainer(text_window), 0);
  414. vpaned := gtk_vpaned_new ();
  415. gtk_container_set_border_width (pGtkContainer(vpaned), 5);
  416. gtk_container_add (pGtkContainer(text_window), vpaned);
  417. (* For convenience, we just use the autocreated buffer from
  418. * the first text view; you could also create the buffer
  419. * by itself with gtk_text_buffer_new(), then later create
  420. * a view widget.
  421. *)
  422. view1 := gtk_text_view_new ();
  423. buffer := gtk_text_view_get_buffer (pGtkTextView(view1));
  424. view2 := gtk_text_view_new_with_buffer (buffer);
  425. sw := gtk_scrolled_window_new (NULL, NULL);
  426. gtk_scrolled_window_set_policy (pGtkScrolledWindow(sw),
  427. GTK_POLICY_AUTOMATIC,
  428. GTK_POLICY_AUTOMATIC);
  429. gtk_paned_add1 (pGtkPaned(vpaned), sw);
  430. gtk_container_add (pGtkContainer(sw), view1);
  431. sw := gtk_scrolled_window_new (NULL, NULL);
  432. gtk_scrolled_window_set_policy (pGtkScrolledWindow(sw),
  433. GTK_POLICY_AUTOMATIC,
  434. GTK_POLICY_AUTOMATIC);
  435. gtk_paned_add2 (pGtkPaned(vpaned), sw);
  436. gtk_container_add (pGtkContainer(sw), view2);
  437. create_tags (buffer);
  438. insert_text (buffer);
  439. attach_widgets (view1);
  440. attach_widgets (view2);
  441. gtk_widget_show_all (vpaned);
  442. end;
  443. if not GTK_WIDGET_VISIBLE (text_window) then
  444. gtk_widget_show (text_window)
  445. else begin
  446. gtk_widget_destroy (text_window);
  447. text_window := NULL;
  448. end;
  449. do_textview := text_window;
  450. end;
  451. procedure recursive_attach_view (depth : integer;
  452. view : PGtkTextView;
  453. anchor : PGtkTextChildAnchor);
  454. var
  455. child_view,
  456. event_box,
  457. align : PGtkWidget;
  458. color : TGdkColor;
  459. begin
  460. if depth > 4 then
  461. exit;
  462. child_view := gtk_text_view_new_with_buffer (gtk_text_view_get_buffer (view));
  463. (* Event box is to add a black border around each child view *)
  464. event_box := gtk_event_box_new ();
  465. gdk_color_parse ('black', @color);
  466. gtk_widget_modify_bg (event_box, GTK_STATE_NORMAL, @color);
  467. align := gtk_alignment_new (0.5, 0.5, 1.0, 1.0);
  468. gtk_container_set_border_width (pGtkContainer(align), 1);
  469. gtk_container_add (pGtkContainer(event_box), align);
  470. gtk_container_add (pGtkContainer(align), child_view);
  471. gtk_text_view_add_child_at_anchor (view, event_box, anchor);
  472. recursive_attach_view (depth + 1, pGtkTextView(child_view), anchor);
  473. end;
  474. procedure easter_egg_callback(button : PGtkWidget;
  475. data : gpointer); cdecl;
  476. var
  477. sw,
  478. view : PGtkWidget;
  479. buffer : PGtkTextBuffer;
  480. iter : TGtkTextIter;
  481. anchor : PGtkTextChildAnchor;
  482. begin
  483. if text_egg_window <> NULL then
  484. begin
  485. gtk_window_present (pGtkWindow(text_egg_window));
  486. exit;
  487. end;
  488. buffer := gtk_text_buffer_new (NULL);
  489. gtk_text_buffer_get_start_iter (buffer, @iter);
  490. gtk_text_buffer_insert (buffer, @iter,
  491. 'This buffer is shared by a set of nested text views.'#13#10'Nested view:'#13#10, -1);
  492. anchor := gtk_text_buffer_create_child_anchor (buffer, @iter);
  493. gtk_text_buffer_insert (buffer, @iter,
  494. #13#10'Don''t do this in real applications, please.'#13#10, -1);
  495. view := gtk_text_view_new_with_buffer (buffer);
  496. recursive_attach_view (0, pGtkTextView(view), anchor);
  497. g_object_unref (pGObject(buffer));
  498. text_egg_window := gtk_window_new (GTK_WINDOW_TOPLEVEL);
  499. sw := gtk_scrolled_window_new (NULL, NULL);
  500. gtk_scrolled_window_set_policy (pGtkScrolledWindow(sw),
  501. GTK_POLICY_AUTOMATIC,
  502. GTK_POLICY_AUTOMATIC);
  503. gtk_container_add (pGtkContainer(text_egg_window), sw);
  504. gtk_container_add (pGtkContainer(sw), view);
  505. g_object_add_weak_pointer (pGObject(text_egg_window),
  506. gpointer (@text_egg_window));
  507. gtk_window_set_default_size (pGtkWindow(text_egg_window), 300, 400);
  508. gtk_widget_show_all (text_egg_window);
  509. end;
  510. // included by gt_demo.pas