DemosText.mod 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525
  1. IMPLEMENTATION MODULE DemosText ;
  2. (*
  3. See the GTK C originals in gtk/demos/gtk-demo:
  4. read_more.c -> DoReadMore
  5. rotated_text.c-> DoRotatedText
  6. textmask.c -> DoTextMask
  7. textscroll.c -> DoTextScroll
  8. textundo.c -> DoTextUndo
  9. The gtk-demo contract is: on the first call build the window and store
  10. it in a module-level variable; on later calls just toggle the window's
  11. visibility, destroying it (and clearing the variable) when it is
  12. already visible. Return the window, or NIL once destroyed.
  13. Several C helpers used by the originals are not part of the binding
  14. set under src/, so those spots are simplified and marked below:
  15. * ReadMore is a custom GtkWidget subclass with its own measure() and
  16. size_allocate(); subclassing is not exposed, so a plain wrapping
  17. GtkLabel plus a "Read More" button is used instead.
  18. * The Pango custom shape renderer / PangoAttrList of rotated_text
  19. are not bound; the layout is drawn with its plain font.
  20. * gtk_text_buffer_set_enable_undo(), *begin/end_irreversible_action()
  21. and gtk_text_view_scroll_mark_onscreen() are not bound.
  22. * cairo_fill_preserve() is not bound; textmask rebuilds the path to
  23. stroke the outline.
  24. *)
  25. FROM SYSTEM IMPORT ADDRESS, ADR, CAST;
  26. FROM GtkWindow IMPORT gtk_window_new, gtk_window_set_title,
  27. gtk_window_set_default_size, gtk_window_set_resizable,
  28. gtk_window_set_child, gtk_window_destroy;
  29. FROM GtkWidget IMPORT gtk_widget_set_visible, gtk_widget_get_visible,
  30. gtk_widget_set_size_request, gtk_widget_set_vexpand, gtk_widget_set_hexpand,
  31. gtk_widget_add_css_class;
  32. FROM GtkBox IMPORT gtk_box_new, gtk_box_append;
  33. FROM GtkEnums IMPORT GtkVertical, GtkHorizontal, GtkWrapWord;
  34. FROM GtkLabel IMPORT gtk_label_new, gtk_label_set_wrap,
  35. gtk_label_set_max_width_chars;
  36. FROM GtkButton IMPORT gtk_button_new_with_label;
  37. FROM GtkScrolledWindow IMPORT gtk_scrolled_window_new,
  38. gtk_scrolled_window_set_child, gtk_scrolled_window_set_policy,
  39. GtkPolicyAutomatic;
  40. FROM GtkTextView IMPORT gtk_text_view_new, gtk_text_view_get_buffer,
  41. gtk_text_view_set_wrap_mode, gtk_text_view_set_left_margin,
  42. gtk_text_view_set_right_margin, gtk_text_view_set_top_margin,
  43. gtk_text_view_set_bottom_margin, gtk_text_view_scroll_to_mark;
  44. FROM GtkTextBuffer IMPORT gtk_text_buffer_get_start_iter,
  45. gtk_text_buffer_insert, gtk_text_buffer_get_end_iter,
  46. gtk_text_buffer_create_mark, gtk_text_buffer_get_mark,
  47. gtk_text_buffer_get_iter_at_mark;
  48. FROM GtkTextIter IMPORT GtkTextIter;
  49. FROM GtkDrawingArea IMPORT gtk_drawing_area_new,
  50. gtk_drawing_area_set_content_width, gtk_drawing_area_set_content_height,
  51. gtk_drawing_area_set_draw_func;
  52. FROM Pango IMPORT pango_font_description_from_string,
  53. pango_font_description_free, pango_layout_set_text,
  54. pango_layout_set_font_description, pango_layout_get_pixel_size;
  55. FROM PangoCairo IMPORT pango_cairo_create_layout, pango_cairo_show_layout,
  56. pango_cairo_update_layout;
  57. FROM Cairo IMPORT cairo_move_to, cairo_rotate, cairo_scale, cairo_translate,
  58. cairo_set_source, cairo_save, cairo_restore, cairo_fill, cairo_stroke,
  59. cairo_set_source_rgb, cairo_set_line_width, cairo_select_font_face,
  60. cairo_set_font_size, cairo_text_path, cairo_pattern_create_linear,
  61. cairo_pattern_add_color_stop_rgb, cairo_pattern_destroy,
  62. CairoFontSlantNormal, CairoFontWeightBold;
  63. FROM GObject IMPORT g_signal_connect_data, GConnectDefault, g_object_unref;
  64. FROM GLib IMPORT g_timeout_add, g_source_remove, guint, GSourceContinue;
  65. CONST
  66. (* rotated_text *)
  67. Radius = 150; (* pixels; window is 4*Radius by 2*Radius *)
  68. NWords = 5;
  69. Pi = 3.141592653589793;
  70. RotatedText = "I \xE2\x99\xA5 GTK";
  71. ReadMoreText =
  72. "I'd just like to interject for a moment. What you're referring to as Linux, is in fact, GNU/Linux, or as I've recently taken to calling it, GNU plus Linux. Linux is not an operating system unto itself, but rather another free component of a fully functioning GNU system made useful by the GNU corelibs, shell utilities and vital system components comprising a full OS as defined by POSIX.\n\nMany computer users run a modified version of the GNU system every day, without realizing it. Through a peculiar turn of events, the version of GNU which is widely used today is often called \x22Linux\x22, and many of its users are not aware that it is basically the GNU system, developed by the GNU Project.\n\nThere really is a Linux, and these people are using it, but it is just a part of the system they use. Linux is the kernel: the program in the system that allocates the machine's resources to the other programs that you run. The kernel is an essential part of an operating system, but useless by itself; it can only function in the context of a complete operating system. Linux is normally used in combination with the GNU operating system: the whole system is basically GNU with Linux added, or GNU/Linux. All the so-called \x22Linux\x22 distributions are really distributions of GNU/Linux.";
  73. UndoText =
  74. "The GtkTextView supports undo and redo through the use of a GtkTextBuffer. You can enable or disable undo support using gtk_text_buffer_set_enable_undo().\nType to add more text.\nUse Control+z to undo and Control+Shift+z or Control+y to redo previously undone operations.";
  75. ScrollToEndPrefix =
  76. "Scroll to end scroll to end scroll to end scroll to end ";
  77. ScrollToBottomPrefix =
  78. "Scroll to bottom scroll to bottom scroll to bottom scroll to bottom ";
  79. VAR
  80. readMoreWindow, rotatedTextWindow, textMaskWindow,
  81. textScrollWindow, textUndoWindow: ADDRESS;
  82. (* static counters of the C originals *)
  83. endCount, bottomCount: INTEGER;
  84. (* ================================================================== *)
  85. (* read_more *)
  86. (* ================================================================== *)
  87. PROCEDURE OnReadMore (button: ADDRESS; data: ADDRESS);
  88. BEGIN
  89. (* The real demo grows the custom widget; with no subclassing the
  90. best we can do is hide the reveal button. *)
  91. gtk_widget_set_visible(button, 0)
  92. END OnReadMore;
  93. PROCEDURE DoReadMore (doWidget: ADDRESS) : ADDRESS;
  94. VAR
  95. box, label, button: ADDRESS;
  96. BEGIN
  97. IF readMoreWindow = NIL THEN
  98. readMoreWindow := gtk_window_new();
  99. gtk_window_set_title(readMoreWindow, "Read More");
  100. gtk_window_set_default_size(readMoreWindow, 400, 300);
  101. box := gtk_box_new(GtkVertical, 6);
  102. gtk_window_set_child(readMoreWindow, box);
  103. label := gtk_label_new(ReadMoreText);
  104. gtk_label_set_wrap(label, 1);
  105. gtk_label_set_max_width_chars(label, 30);
  106. gtk_widget_set_vexpand(label, 1);
  107. gtk_box_append(box, label);
  108. button := gtk_button_new_with_label("Read More");
  109. g_signal_connect_data(button, "clicked", ADR(OnReadMore), NIL, NIL,
  110. GConnectDefault);
  111. gtk_box_append(box, button)
  112. END;
  113. IF gtk_widget_get_visible(readMoreWindow) = 0 THEN
  114. gtk_widget_set_visible(readMoreWindow, 1)
  115. ELSE
  116. gtk_window_destroy(readMoreWindow);
  117. readMoreWindow := NIL
  118. END;
  119. RETURN readMoreWindow
  120. END DoReadMore;
  121. (* ================================================================== *)
  122. (* rotated_text *)
  123. (* ================================================================== *)
  124. PROCEDURE RotatedTextDraw (area: ADDRESS; cr: ADDRESS;
  125. width, height: INTEGER; data: ADDRESS);
  126. VAR
  127. layout, desc, pattern: ADDRESS;
  128. deviceRadius: REAL;
  129. lw, lh, i: INTEGER;
  130. BEGIN
  131. IF width < height THEN
  132. deviceRadius := VAL(REAL, width) / 2.0
  133. ELSE
  134. deviceRadius := VAL(REAL, height) / 2.0
  135. END;
  136. cairo_translate(cr,
  137. deviceRadius + (VAL(REAL, width) - 2.0 * deviceRadius) / 2.0,
  138. deviceRadius + (VAL(REAL, height) - 2.0 * deviceRadius) / 2.0);
  139. cairo_scale(cr, deviceRadius / 150.0, deviceRadius / 150.0);
  140. pattern := cairo_pattern_create_linear(-150.0, -150.0, 150.0, 150.0);
  141. cairo_pattern_add_color_stop_rgb(pattern, 0.0, 0.5, 0.0, 0.0);
  142. cairo_pattern_add_color_stop_rgb(pattern, 1.0, 0.0, 0.0, 0.5);
  143. cairo_set_source(cr, pattern);
  144. layout := pango_cairo_create_layout(cr);
  145. pango_layout_set_text(layout, RotatedText, -1);
  146. desc := pango_font_description_from_string("Serif 18");
  147. pango_layout_set_font_description(layout, desc);
  148. pango_font_description_free(desc);
  149. FOR i := 0 TO NWords - 1 DO
  150. pango_cairo_update_layout(cr, layout);
  151. pango_layout_get_pixel_size(layout, lw, lh);
  152. cairo_move_to(cr, -VAL(REAL, lw) / 2.0, -150.0 * 0.9);
  153. pango_cairo_show_layout(cr, layout);
  154. cairo_rotate(cr, 2.0 * Pi / VAL(REAL, NWords))
  155. END;
  156. g_object_unref(layout);
  157. cairo_pattern_destroy(pattern)
  158. END RotatedTextDraw;
  159. PROCEDURE DoRotatedText (doWidget: ADDRESS) : ADDRESS;
  160. VAR
  161. box, drawingArea, label: ADDRESS;
  162. BEGIN
  163. IF rotatedTextWindow = NIL THEN
  164. rotatedTextWindow := gtk_window_new();
  165. gtk_window_set_title(rotatedTextWindow, "Rotated Text");
  166. gtk_window_set_default_size(rotatedTextWindow, 4 * Radius, 2 * Radius);
  167. box := gtk_box_new(GtkHorizontal, 0);
  168. gtk_window_set_child(rotatedTextWindow, box);
  169. drawingArea := gtk_drawing_area_new();
  170. gtk_drawing_area_set_content_width(drawingArea, 2 * Radius);
  171. gtk_drawing_area_set_content_height(drawingArea, 2 * Radius);
  172. gtk_widget_set_hexpand(drawingArea, 1);
  173. gtk_widget_set_vexpand(drawingArea, 1);
  174. gtk_box_append(box, drawingArea);
  175. gtk_widget_add_css_class(drawingArea, "view");
  176. gtk_drawing_area_set_draw_func(drawingArea, ADR(RotatedTextDraw),
  177. NIL, NIL);
  178. label := gtk_label_new(RotatedText);
  179. gtk_widget_set_hexpand(label, 1);
  180. gtk_widget_set_vexpand(label, 1);
  181. gtk_box_append(box, label)
  182. END;
  183. IF gtk_widget_get_visible(rotatedTextWindow) = 0 THEN
  184. gtk_widget_set_visible(rotatedTextWindow, 1)
  185. ELSE
  186. gtk_window_destroy(rotatedTextWindow);
  187. rotatedTextWindow := NIL
  188. END;
  189. RETURN rotatedTextWindow
  190. END DoRotatedText;
  191. (* ================================================================== *)
  192. (* textmask *)
  193. (* ================================================================== *)
  194. PROCEDURE MaskPath (cr: ADDRESS);
  195. BEGIN
  196. cairo_move_to(cr, 30.0, 20.0);
  197. cairo_text_path(cr, "Pango power!");
  198. cairo_move_to(cr, 30.0, 60.0);
  199. cairo_text_path(cr, "Pango power!");
  200. cairo_move_to(cr, 30.0, 100.0);
  201. cairo_text_path(cr, "Pango power!")
  202. END MaskPath;
  203. PROCEDURE TextMaskDraw (area: ADDRESS; cr: ADDRESS;
  204. width, height: INTEGER; data: ADDRESS);
  205. VAR
  206. pattern: ADDRESS;
  207. BEGIN
  208. cairo_save(cr);
  209. cairo_select_font_face(cr, "sans", CairoFontSlantNormal,
  210. CairoFontWeightBold);
  211. cairo_set_font_size(cr, 34.0);
  212. MaskPath(cr);
  213. pattern := cairo_pattern_create_linear(0.0, 0.0,
  214. VAL(REAL, width), VAL(REAL, height));
  215. cairo_pattern_add_color_stop_rgb(pattern, 0.0, 1.0, 0.0, 0.0);
  216. cairo_pattern_add_color_stop_rgb(pattern, 0.2, 1.0, 0.0, 0.0);
  217. cairo_pattern_add_color_stop_rgb(pattern, 0.3, 1.0, 1.0, 0.0);
  218. cairo_pattern_add_color_stop_rgb(pattern, 0.4, 0.0, 1.0, 0.0);
  219. cairo_pattern_add_color_stop_rgb(pattern, 0.6, 0.0, 1.0, 1.0);
  220. cairo_pattern_add_color_stop_rgb(pattern, 0.7, 0.0, 0.0, 1.0);
  221. cairo_pattern_add_color_stop_rgb(pattern, 0.8, 1.0, 0.0, 1.0);
  222. cairo_pattern_add_color_stop_rgb(pattern, 1.0, 1.0, 0.0, 1.0);
  223. cairo_set_source(cr, pattern);
  224. cairo_fill(cr); (* cairo_fill_preserve is unbound *)
  225. cairo_pattern_destroy(pattern);
  226. (* Rebuild the path (fill consumed it) and outline it in black. *)
  227. MaskPath(cr);
  228. cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
  229. cairo_set_line_width(cr, 0.5);
  230. cairo_stroke(cr);
  231. cairo_restore(cr)
  232. END TextMaskDraw;
  233. PROCEDURE DoTextMask (doWidget: ADDRESS) : ADDRESS;
  234. VAR
  235. da: ADDRESS;
  236. BEGIN
  237. IF textMaskWindow = NIL THEN
  238. textMaskWindow := gtk_window_new();
  239. gtk_window_set_resizable(textMaskWindow, 1);
  240. gtk_widget_set_size_request(textMaskWindow, 400, 240);
  241. gtk_window_set_title(textMaskWindow, "Text Mask");
  242. da := gtk_drawing_area_new();
  243. gtk_window_set_child(textMaskWindow, da);
  244. gtk_drawing_area_set_draw_func(da, ADR(TextMaskDraw), NIL, NIL)
  245. END;
  246. IF gtk_widget_get_visible(textMaskWindow) = 0 THEN
  247. gtk_widget_set_visible(textMaskWindow, 1)
  248. ELSE
  249. gtk_window_destroy(textMaskWindow);
  250. textMaskWindow := NIL
  251. END;
  252. RETURN textMaskWindow
  253. END DoTextMask;
  254. (* ================================================================== *)
  255. (* textscroll *)
  256. (* ================================================================== *)
  257. (* Fill s with n spaces (NUL-terminated). *)
  258. PROCEDURE MakeSpaces (n: INTEGER; VAR s: ARRAY OF CHAR);
  259. VAR
  260. i, hi: INTEGER;
  261. BEGIN
  262. hi := VAL(INTEGER, HIGH(s));
  263. IF n > hi - 1 THEN
  264. n := hi - 1
  265. END;
  266. FOR i := 0 TO n - 1 DO
  267. s[i] := ' '
  268. END;
  269. s[n] := 0C
  270. END MakeSpaces;
  271. (* Copy prefix then append the decimal rendering of n (NUL-terminated). *)
  272. PROCEDURE BuildScrollText (prefix: ARRAY OF CHAR; n: INTEGER;
  273. VAR s: ARRAY OF CHAR);
  274. VAR
  275. pos, k, hi: INTEGER;
  276. digits: ARRAY [0..15] OF CHAR;
  277. BEGIN
  278. hi := VAL(INTEGER, HIGH(s));
  279. pos := 0;
  280. WHILE (pos < hi) AND (prefix[pos] # 0C) DO
  281. s[pos] := prefix[pos];
  282. INC(pos)
  283. END;
  284. k := 0;
  285. IF n = 0 THEN
  286. digits[0] := '0';
  287. k := 1
  288. ELSE
  289. WHILE n > 0 DO
  290. digits[k] := CHR(ORD('0') + VAL(CARDINAL, n MOD 10));
  291. n := n DIV 10;
  292. INC(k)
  293. END
  294. END;
  295. WHILE k > 0 DO
  296. DEC(k);
  297. IF pos < hi THEN
  298. s[pos] := digits[k];
  299. INC(pos)
  300. END
  301. END;
  302. s[pos] := 0C
  303. END BuildScrollText;
  304. PROCEDURE ScrollToEnd (textview: ADDRESS) : INTEGER;
  305. VAR
  306. buffer, mark: ADDRESS;
  307. iter: GtkTextIter;
  308. spaces, text: ARRAY [0..255] OF CHAR;
  309. BEGIN
  310. buffer := gtk_text_view_get_buffer(textview);
  311. mark := gtk_text_buffer_get_mark(buffer, "end");
  312. gtk_text_buffer_get_iter_at_mark(buffer, iter, mark);
  313. MakeSpaces(endCount, spaces);
  314. INC(endCount);
  315. gtk_text_buffer_insert(buffer, iter, "\n", -1);
  316. gtk_text_buffer_insert(buffer, iter, spaces, -1);
  317. BuildScrollText(ScrollToEndPrefix, endCount, text);
  318. gtk_text_buffer_insert(buffer, iter, text, -1);
  319. gtk_text_view_scroll_to_mark(textview, mark, 0.0, 0, 0.0, 0.0);
  320. IF endCount > 150 THEN
  321. endCount := 0
  322. END;
  323. RETURN GSourceContinue
  324. END ScrollToEnd;
  325. PROCEDURE ScrollToBottom (textview: ADDRESS) : INTEGER;
  326. VAR
  327. buffer, mark: ADDRESS;
  328. iter: GtkTextIter;
  329. spaces, text: ARRAY [0..255] OF CHAR;
  330. BEGIN
  331. buffer := gtk_text_view_get_buffer(textview);
  332. gtk_text_buffer_get_end_iter(buffer, iter);
  333. MakeSpaces(bottomCount, spaces);
  334. INC(bottomCount);
  335. gtk_text_buffer_insert(buffer, iter, "\n", -1);
  336. gtk_text_buffer_insert(buffer, iter, spaces, -1);
  337. BuildScrollText(ScrollToBottomPrefix, bottomCount, text);
  338. gtk_text_buffer_insert(buffer, iter, text, -1);
  339. (* gtk_text_iter_set_line_offset() and gtk_text_buffer_move_mark()
  340. are not bound, so the "scroll" mark stays at its original spot. *)
  341. mark := gtk_text_buffer_get_mark(buffer, "scroll");
  342. gtk_text_view_scroll_to_mark(textview, mark, 0.0, 0, 0.0, 0.0);
  343. IF bottomCount > 40 THEN
  344. bottomCount := 0
  345. END;
  346. RETURN GSourceContinue
  347. END ScrollToBottom;
  348. PROCEDURE SetupScroll (textview: ADDRESS; toEnd: BOOLEAN) : guint;
  349. VAR
  350. buffer, mark: ADDRESS;
  351. iter: GtkTextIter;
  352. BEGIN
  353. buffer := gtk_text_view_get_buffer(textview);
  354. gtk_text_buffer_get_end_iter(buffer, iter);
  355. IF toEnd THEN
  356. mark := gtk_text_buffer_create_mark(buffer, "end", iter, 0);
  357. RETURN g_timeout_add(50, ScrollToEnd, textview)
  358. ELSE
  359. mark := gtk_text_buffer_create_mark(buffer, "scroll", iter, 1);
  360. RETURN g_timeout_add(100, ScrollToBottom, textview)
  361. END
  362. END SetupScroll;
  363. (* void remove_timeout(GtkWidget *window, gpointer timeout) *)
  364. PROCEDURE RemoveTimeout (window: ADDRESS; data: ADDRESS);
  365. BEGIN
  366. g_source_remove(CAST(guint, data))
  367. END RemoveTimeout;
  368. PROCEDURE CreateTextView (hbox: ADDRESS; toEnd: BOOLEAN);
  369. VAR
  370. swindow, textview: ADDRESS;
  371. timeout: guint;
  372. BEGIN
  373. swindow := gtk_scrolled_window_new();
  374. gtk_widget_set_hexpand(swindow, 1);
  375. gtk_box_append(hbox, swindow);
  376. textview := gtk_text_view_new();
  377. gtk_scrolled_window_set_child(swindow, textview);
  378. timeout := SetupScroll(textview, toEnd);
  379. (* Remove the timeout when the view goes away, so it cannot scroll a
  380. destroyed widget. *)
  381. g_signal_connect_data(textview, "destroy", ADR(RemoveTimeout),
  382. CAST(ADDRESS, timeout), NIL, GConnectDefault)
  383. END CreateTextView;
  384. PROCEDURE DoTextScroll (doWidget: ADDRESS) : ADDRESS;
  385. VAR
  386. hbox: ADDRESS;
  387. BEGIN
  388. IF textScrollWindow = NIL THEN
  389. textScrollWindow := gtk_window_new();
  390. gtk_window_set_title(textScrollWindow, "Automatic Scrolling");
  391. gtk_window_set_default_size(textScrollWindow, 600, 400);
  392. hbox := gtk_box_new(GtkHorizontal, 6);
  393. gtk_window_set_child(textScrollWindow, hbox);
  394. CreateTextView(hbox, TRUE);
  395. CreateTextView(hbox, FALSE)
  396. END;
  397. IF gtk_widget_get_visible(textScrollWindow) = 0 THEN
  398. gtk_widget_set_visible(textScrollWindow, 1)
  399. ELSE
  400. gtk_window_destroy(textScrollWindow);
  401. textScrollWindow := NIL
  402. END;
  403. RETURN textScrollWindow
  404. END DoTextScroll;
  405. (* ================================================================== *)
  406. (* textundo *)
  407. (* ================================================================== *)
  408. PROCEDURE DoTextUndo (doWidget: ADDRESS) : ADDRESS;
  409. VAR
  410. view, sw, buffer: ADDRESS;
  411. iter: GtkTextIter;
  412. BEGIN
  413. IF textUndoWindow = NIL THEN
  414. textUndoWindow := gtk_window_new();
  415. gtk_window_set_default_size(textUndoWindow, 330, 330);
  416. gtk_window_set_resizable(textUndoWindow, 0);
  417. gtk_window_set_title(textUndoWindow, "Undo and Redo");
  418. view := gtk_text_view_new();
  419. gtk_text_view_set_wrap_mode(view, GtkWrapWord);
  420. gtk_text_view_set_left_margin(view, 20);
  421. gtk_text_view_set_right_margin(view, 20);
  422. gtk_text_view_set_top_margin(view, 20);
  423. gtk_text_view_set_bottom_margin(view, 20);
  424. buffer := gtk_text_view_get_buffer(view);
  425. (* gtk_text_buffer_set_enable_undo() is not bound; the buffer keeps
  426. its default undo support, so Ctrl+Z / Ctrl+Y still work. *)
  427. gtk_text_buffer_get_start_iter(buffer, iter);
  428. gtk_text_buffer_insert(buffer, iter, UndoText, -1);
  429. sw := gtk_scrolled_window_new();
  430. gtk_scrolled_window_set_policy(sw, GtkPolicyAutomatic,
  431. GtkPolicyAutomatic);
  432. gtk_window_set_child(textUndoWindow, sw);
  433. gtk_scrolled_window_set_child(sw, view)
  434. END;
  435. IF gtk_widget_get_visible(textUndoWindow) = 0 THEN
  436. gtk_widget_set_visible(textUndoWindow, 1)
  437. ELSE
  438. gtk_window_destroy(textUndoWindow);
  439. textUndoWindow := NIL
  440. END;
  441. RETURN textUndoWindow
  442. END DoTextUndo;
  443. BEGIN
  444. readMoreWindow := NIL;
  445. rotatedTextWindow := NIL;
  446. textMaskWindow := NIL;
  447. textScrollWindow := NIL;
  448. textUndoWindow := NIL;
  449. endCount := 0;
  450. bottomCount := 0
  451. END DemosText.