alternative to assert
[gtkD.git] / demos / duit / TTextView.d
blobb736a662c2a5b55dfa04979b38e9fa6cf4efd8bc
1 /*
2 * This file is part of dui.
3 *
4 * dui is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; either version 2.1 of the License, or
7 * (at your option) any later version.
8 *
9 * dui is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with dui; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 module duit.TTextView;
21 private import gtk.Window;
23 private import gtk.gtktypes;
24 private import gdk.gdktypes;
26 private import gtk.Widget;
27 private import gtk.TextView;
28 private import gtk.TextBuffer;
29 private import gtk.TextIter;
30 private import gtk.VPaned;
31 private import gtk.ScrolledWindow;
32 private import gtk.TextChildAnchor;
33 private import gtk.Button;
34 private import gtk.Menu;
35 private import gtk.MenuItem;
36 private import gtk.HScale;
37 private import gtk.Image;
38 private import gtk.Entry;
40 private import gdk.Bitmap;
41 private import gdk.Pixbuf;
43 private import gtk.ComboBox;
44 /**
45 * reproduces the gtk-demo TextView
46 * \bug the output shows erros like (DUITest.exe:5012): GLib-GObject-WARNING **: [Invalid UTF-8] gobject.c:882: object class `GtkTextTag' has no property named `l┌E'
49 public:
50 class TTextView : Window
52 TextView view1;
53 TextBuffer buffer;
54 TextView view2;
56 /**
57 * ctor. must reactivate the constructor name change loby
59 this()
61 super("TextView");
62 setDefaultSize(450,450);
63 setBorderWidth(0);
65 createTextViews();
67 setupWidgets();
69 createTags(buffer);
70 insertText(buffer);
72 attachWidgets(view1);
73 attachWidgets(view2);
75 showAll();
78 // bit windowDeleteCallback(Window window, Event event)
79 // {
80 // return false;
81 // }
82 //
83 // bit windowDestroyCallback(Window window, Event event)
84 // {
85 // printf("TTextView windowDestroyCallback\n");
86 // return false;
87 // }
89 /**
90 * creates the text view and buffer to use
92 void createTextViews()
94 view1 = new TextView();
95 buffer = view1.getBuffer();
96 view2 = new TextView(buffer);
99 /**
100 * sets up the widgets ot this test
102 void setupWidgets()
104 VPaned vPaned = new VPaned();
105 vPaned.setBorderWidth(5);
106 add(vPaned);
108 ScrolledWindow sw = new ScrolledWindow(PolicyType.AUTOMATIC, PolicyType.AUTOMATIC);
109 sw.add(view1);
110 vPaned.add1(sw);
111 sw = new ScrolledWindow(PolicyType.AUTOMATIC, PolicyType.AUTOMATIC);
112 sw.add(view2);
113 vPaned.add2(sw);
117 * Creates all the text tags to use
118 * @param buffer the TextBuffer
120 void createTags(TextBuffer buffer)
122 Bitmap stipple;
124 /* Create a bunch of tags. Note that it's also possible to
125 * create tags with gtk_text_tag_new() then add them to the
126 * tag table for the buffer, gtk_text_buffer_create_tag() is
127 * just a convenience function. Also note that you don't have
128 * to give tags a name; pass NULL for the name to create an
129 * anonymous tag.
131 * In any real app, another useful optimization would be to create
132 * a GtkTextTagTable in advance, and reuse the same tag table for
133 * all the buffers with the same tag set, instead of creating
134 * new copies of the same tags for every buffer.
136 * Tags are assigned default priorities in order of addition to the
137 * tag table. That is, tags created later that affect the same text
138 * property affected by an earlier tag will override the earlier
139 * tag. You can modify tag priorities with
140 * gtk_text_tag_set_priority().
143 buffer.createTag("heading",
144 "weight", PangoWeight.BOLD,
145 "size", 15 * PANGO_SCALE);
146 buffer.createTag("italic",
147 "style", cast(int)PangoStyle.ITALIC);
149 buffer.createTag("bold",
150 "weight", cast(int)PangoWeight.BOLD);
152 buffer.createTag("big",
153 /* points times the PANGO_SCALE factor */
154 "size", 20 * PANGO_SCALE);
156 buffer.createTag("xx-small",
157 "scale", PANGO_SCALE_XX_SMALL);
159 buffer.createTag("x-large",
160 "scale", PANGO_SCALE_X_LARGE);
162 buffer.createTag("monospace",
163 "family", "monospace");
165 buffer.createTag("blue_foreground",
166 "foreground", "blue");
168 buffer.createTag("red_background",
169 "background", "red");
171 const int gray50_width = 2;
172 const int gray50_height = 2;
173 static char gray50_bits[] = [0x02, 0x01];
175 stipple = Bitmap.createFromData(null, // drawablw
176 gray50_bits, gray50_width,
177 gray50_height);
179 buffer.createTag("background_stipple",
180 "background_stipple", stipple);
182 buffer.createTag("foreground_stipple",
183 "foreground_stipple", stipple);
185 buffer.createTag("big_gap_before_line",
186 "pixels_above_lines", 30);
188 buffer.createTag("big_gap_after_line",
189 "pixels_below_lines", 30);
191 buffer.createTag("double_spaced_line",
192 "pixels_inside_wrap", 10);
194 buffer.createTag("not_editable",
195 "editable", cast(int)false);
197 buffer.createTag("word_wrap",
198 "wrap_mode", cast(int)WrapMode.WORD);
200 buffer.createTag("char_wrap",
201 "wrap_mode", cast(int)WrapMode.CHAR);
203 buffer.createTag("no_wrap",
204 "wrap_mode", cast(int)WrapMode.NONE);
206 buffer.createTag("center",
207 "justification", cast(int)Justification.JUSTIFY_CENTER);
209 buffer.createTag("right_justify",
210 "justification", cast(int)Justification.JUSTIFY_RIGHT);
212 buffer.createTag("wide_margins",
213 "left_margin", 50, "right_margin", 50);
215 buffer.createTag("strikethrough",
216 "strikethrough", cast(int)true);
218 buffer.createTag("underline",
219 "underline", cast(int)PangoUnderline.SINGLE);
221 buffer.createTag("double_underline",
222 "underline", cast(int)PangoUnderline.DOUBLE);
224 buffer.createTag("superscript",
225 "rise", 10 * PANGO_SCALE, /* 10 pixels */
226 "size", 8 * PANGO_SCALE); /* 8 points */
228 buffer.createTag("subscript",
229 "rise", -10 * PANGO_SCALE, /* 10 pixels */
230 "size", 8 * PANGO_SCALE); /* 8 points */
233 buffer.createTag("rtl_quote",
234 "wrap_mode", WrapMode.WORD,
235 "direction", TextDirection.RTL,
236 "indent", 30,
237 "left_margin", 20,
238 "right_margin", 20);
242 * Inserts all the test text into the buffer
243 * @param buffer the TextBuffer
245 void insertText(TextBuffer buffer)
247 TextIter iter = new TextIter();
248 TextIter start = new TextIter();
249 TextIter end = new TextIter();
250 Pixbuf pixbuf;
251 Pixbuf scaled;
252 TextChildAnchor anchor;
253 char[] filename;
255 /* demo_find_file() looks in the the current directory first,
256 * so you can run gtk-demo without installing GTK, then looks
257 * in the location where the file is installed.
260 pixbuf = new Pixbuf("images/gtk-logo-rgb.gif", null);
262 if (pixbuf.getPixbufStruct() is null)
264 printf("Failed to load image file gtk-logo-rgb.gif\n");
265 pixbuf = null;
267 else
269 scaled = pixbuf.scaleSimple(32, 32, InterpType.BILINEAR);
270 pixbuf = pixbuf.scaleSimple(38, 38, InterpType.BILINEAR);
273 /* get start of buffer; each insertion will revalidate the
274 * iterator to point to just after the inserted text.
277 buffer.getIterAtOffset(iter, 0);
279 buffer.insert(iter, "The text widget can display text with all kinds of nifty attributes. It also supports multiple views of the same buffer; this demo is showing the same buffer in two places.\n\n");
281 buffer.insertWithTagsByName(iter, "Font styles. ","heading");
283 buffer.insert(iter, "For example, you can have ");
284 buffer.insertWithTagsByName(iter, "italic", "italic");
285 buffer.insert(iter, ", ");
286 buffer.insertWithTagsByName(iter, "bold", "bold");
287 buffer.insert(iter, ", or ");
288 buffer.insertWithTagsByName(iter, "monospace (typewriter)", "monospace");
289 buffer.insert(iter, ", or ");
290 buffer.insertWithTagsByName(iter, "big", "big");
291 buffer.insert(iter, " text. ");
292 buffer.insert(iter, "It's best not to hardcode specific text sizes; you can use relative sizes as with CSS, such as ");
293 buffer.insertWithTagsByName(iter, "xx-small", "xx-small");
294 buffer.insert(iter, " or ");
295 buffer.insertWithTagsByName(iter, "x-large", "x-large");
296 buffer.insert(iter, " to ensure that your program properly adapts if the user changes the default font size.\n\n");
298 buffer.insertWithTagsByName(iter, "Colors. ", "heading");
300 buffer.insert(iter, "Colors such as ");
301 buffer.insertWithTagsByName(iter, "a blue foreground", "blue_foreground");
302 buffer.insert(iter, " or ");
303 buffer.insertWithTagsByName(iter, "a red background", "red_background");
304 buffer.insert(iter, " or even ");
305 buffer.insertWithTagsByName(iter, "a stippled red background",
306 "red_background", "background_stipple");
308 buffer.insert(iter, " or ");
309 buffer.insertWithTagsByName(iter,
310 "a stippled blue foreground on solid red background",
311 "blue_foreground",
312 "red_background",
313 "foreground_stipple");
314 buffer.insert(iter, " (select that to read it) can be used.\n\n");
316 buffer.insertWithTagsByName(iter, "Underline, strikethrough, and rise. ", "heading");
318 buffer.insertWithTagsByName(iter, "Strikethrough", "strikethrough");
319 buffer.insert(iter, ", ");
320 buffer.insertWithTagsByName(iter, "underline", "underline");
321 buffer.insert(iter, ", ");
322 buffer.insertWithTagsByName(iter, "double underline", "double_underline");
323 buffer.insert(iter, ", ");
324 buffer.insertWithTagsByName(iter, "superscript", "superscript");
325 buffer.insert(iter, ", and ");
326 buffer.insertWithTagsByName(iter, "subscript", "subscript");
327 buffer.insert(iter, " are all supported.\n\n");
329 buffer.insertWithTagsByName(iter, "Images. ", "heading");
331 buffer.insert(iter, "The buffer can have images in it: ");
332 if ( pixbuf !is null )
334 buffer.insertPixbuf(iter, scaled);
335 buffer.insertPixbuf(iter, pixbuf);
336 buffer.insertPixbuf(iter, scaled);
338 else
340 buffer.insert(iter,"Sorry can't find the images");
342 buffer.insert(iter, " for example.\n\n");
344 buffer.insertWithTagsByName(iter, "Spacing. ", "heading");
346 buffer.insert(iter, "You can adjust the amount of space before each line.\n");
348 buffer.insertWithTagsByName(iter, "This line has a whole lot of space before it.\n",
349 "big_gap_before_line", "wide_margins");
350 buffer.insertWithTagsByName(iter,
351 "You can also adjust the amount of space after each line; this line has a whole lot of space after it.\n",
352 "big_gap_after_line", "wide_margins");
354 buffer.insertWithTagsByName(iter,
355 "You can also adjust the amount of space between wrapped lines; this line has extra space between each wrapped line in the same paragraph. To show off wrapping, some filler text: the quick brown fox jumped over the lazy dog. Blah blah blah blah blah blah blah blah blah.\n",
356 "double_spaced_line", "wide_margins");
358 buffer.insert(iter, "Also note that those lines have extra-wide margins.\n\n");
360 buffer.insertWithTagsByName(iter, "Editability. ", "heading");
362 buffer.insertWithTagsByName(iter,
363 "This line is 'locked down' and can't be edited by the user - just try it! You can't delete this line.\n\n",
364 "not_editable");
366 buffer.insertWithTagsByName(iter, "Wrapping. ", "heading");
368 buffer.insert(iter,
369 "This line (and most of the others in this buffer) is word-wrapped, using the proper Unicode algorithm. Word wrap should work in all scripts and languages that GTK+ supports. Let's make this a long paragraph to demonstrate: blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah\n\n");
371 buffer.insertWithTagsByName(iter,
372 "This line has character-based wrapping, and can wrap between any two character glyphs. Let's make this a long paragraph to demonstrate: blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah\n\n",
373 "char_wrap");
375 buffer.insertWithTagsByName(iter,
376 "This line has all wrapping turned off, so it makes the horizontal scrollbar appear.\n\n\n",
377 "no_wrap");
379 buffer.insertWithTagsByName(iter, "Justification. ", "heading");
381 buffer.insertWithTagsByName(iter,
382 "\nThis line has center justification.\n", "center");
384 buffer.insertWithTagsByName(iter,
385 "This line has right justification.\n", "right_justify");
387 buffer.insertWithTagsByName(iter,
388 "\nThis line has big wide margins. Text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text.\n",
389 "wide_margins");
391 buffer.insertWithTagsByName(iter, "Internationalization. ", "heading");
393 buffer.insert(iter,
394 "You can put all sorts of Unicode text in the buffer.\n\nGerman (Deutsch S\303\274d) Gr\303\274\303\237 Gott\nGreek (\316\225\316\273\316\273\316\267\316\275\316\271\316\272\316\254) \316\223\316\265\316\271\316\254 \317\203\316\261\317\202\nHebrew \327\251\327\234\327\225\327\235\nJapanese (\346\227\245\346\234\254\350\252\236)\n\nThe widget properly handles bidirectional text, word wrapping, DOS/UNIX/Unicode paragraph separators, grapheme boundaries, and so on using the Pango internationalization framework.\n");
396 buffer.insert(iter, "Here's a word-wrapped quote in a right-to-left language:\n");
397 buffer.insertWithTagsByName(iter, "\331\210\331\202\330\257 \330\250\330\257\330\243 \330\253\331\204\330\247\330\253 \331\205\331\206 \330\243\331\203\330\253\330\261 \330\247\331\204\331\205\330\244\330\263\330\263\330\247\330\252 \330\252\331\202\330\257\331\205\330\247 \331\201\331\212 \330\264\330\250\331\203\330\251 \330\247\331\203\330\263\331\212\331\210\331\206 \330\250\330\261\330\247\331\205\330\254\331\207\330\247 \331\203\331\205\331\206\330\270\331\205\330\247\330\252 \331\204\330\247 \330\252\330\263\330\271\331\211 \331\204\331\204\330\261\330\250\330\255\330\214 \330\253\331\205 \330\252\330\255\331\210\331\204\330\252 \331\201\331\212 \330\247\331\204\330\263\331\206\331\210\330\247\330\252 \330\247\331\204\330\256\331\205\330\263 \330\247\331\204\331\205\330\247\330\266\331\212\330\251 \330\245\331\204\331\211 \331\205\330\244\330\263\330\263\330\247\330\252 \331\205\330\247\331\204\331\212\330\251 \331\205\331\206\330\270\331\205\330\251\330\214 \331\210\330\250\330\247\330\252\330\252 \330\254\330\262\330\241\330\247 \331\205\331\206 \330\247\331\204\331\206\330\270\330\247\331\205 \330\247\331\204\331\205\330\247\331\204\331\212 \331\201\331\212 \330\250\331\204\330\257\330\247\331\206\331\207\330\247\330\214 \331\210\331\204\331\203\331\206\331\207\330\247 \330\252\330\252\330\256\330\265\330\265 \331\201\331\212 \330\256\330\257\331\205\330\251 \331\202\330\267\330\247\330\271 \330\247\331\204\331\205\330\264\330\261\331\210\330\271\330\247\330\252 \330\247\331\204\330\265\330\272\331\212\330\261\330\251. \331\210\330\243\330\255\330\257 \330\243\331\203\330\253\330\261 \331\207\330\260\331\207 \330\247\331\204\331\205\330\244\330\263\330\263\330\247\330\252 \331\206\330\254\330\247\330\255\330\247 \331\207\331\210 \302\273\330\250\330\247\331\206\331\203\331\210\330\263\331\210\331\204\302\253 \331\201\331\212 \330\250\331\210\331\204\331\212\331\201\331\212\330\247.\n\n",
398 "rtl_quote");
400 buffer.insert(iter, "You can put widgets in the buffer: Here's a button: ");
401 anchor = buffer.createChildAnchor(iter);
402 buffer.insert(iter, " and a menu: ");
403 anchor = buffer.createChildAnchor(iter);
404 buffer.insert(iter, " and a scale: ");
405 anchor = buffer.createChildAnchor(iter);
406 buffer.insert(iter, " and an animation: ");
407 anchor = buffer.createChildAnchor(iter);
408 buffer.insert(iter, " finally a text entry: ");
409 anchor = buffer.createChildAnchor(iter);
410 buffer.insert(iter, ".\n");
412 buffer.insert(iter, "\n\nThis demo doesn't demonstrate all the GtkTextBuffer features; it leaves out, for example: invisible/hidden text (doesn't work in GTK 2, but planned), tab stops, application-drawn areas on the sides of the widget for displaying breakpoints and such...");
414 /* Apply word_wrap tag to whole buffer */
415 buffer.getBounds(start, end);
416 buffer.applyTagByName("word_wrap", start, end);
421 * Attaches all test widgets to the text view
422 * @param view the TextView
424 void attachWidgets(TextView view)
426 TextIter iter = new TextIter();
427 TextBuffer buffer;
428 int i;
430 buffer = view.getBuffer();
432 buffer.getStartIter(iter);
434 i = 0;
436 while (findAnchor(iter))
438 TextChildAnchor anchor;// = new TextChildAnchor();
439 Widget widget;
440 anchor = iter.getChildAnchor();
442 if (i == 0)
444 Button button = new Button("Click Me");
445 widget = button;
447 else if (i == 1)
450 ComboBox comboBox = new ComboBox();
451 comboBox.appendText("Option 1");
452 comboBox.appendText("Option 2");
453 comboBox.appendText("Option 3");
454 widget = comboBox;
456 else if (i == 2)
458 HScale hScale = new HScale(0.0,100.0,5.0);
459 hScale.setSizeRequest(70, -1);
460 widget = hScale;
462 else if (i == 3)
464 Image image = new Image("images/floppybuddy.gif");
465 widget = image;
467 else if (i == 4)
469 widget = new Entry();
471 else
473 widget = null;
474 //g_assert_not_reached ();
477 if ( widget !is null )
479 view.addChildAtAnchor(widget,anchor);
482 ++i;
486 bit findAnchor (TextIter iter)
488 while (iter.forwardChar())
490 if (iter.getChildAnchor() !is null ) //gtk_text_iter_get_child_anchor (iter))
492 return true;
495 return false;