alternative to assert
[gtkD.git] / gtkD / demos / gtkD / TTextView.d
blob6b1b3e007d946c106dd43dfecc8cfa0033440d23
1 /*
2 * This file is part of gtkD.
3 *
4 * gtkD 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 * gtkD 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 gtkD; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 module gtkD.TTextView;
21 private import gtk.Window;
23 private import gtkc.gtktypes;
24 private import gtkc.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;
45 version(Tango) private import tango.io.Stdout;
46 version(Tango) private import tango.text.convert.Layout;
48 version(Tango) private import tango.core.Vararg;
50 /**
51 * reproduces the gtk-demo TextView
52 * \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'
55 public:
56 class TTextView : Window
58 TextView view1;
59 TextBuffer buffer;
60 TextView view2;
62 /**
63 * ctor. must reactivate the constructor name change loby
65 this()
67 super("TextView");
68 setDefaultSize(450,450);
69 setBorderWidth(0);
71 createTextViews();
73 setupWidgets();
75 createTags(buffer);
76 insertText(buffer);
78 attachWidgets(view1);
79 attachWidgets(view2);
81 showAll();
84 // bit windowDeleteCallback(Window window, Event event)
85 // {
86 // return false;
87 // }
88 //
89 // bit windowDestroyCallback(Window window, Event event)
90 // {
91 // printf("TTextView windowDestroyCallback\n");
92 // return false;
93 // }
95 /**
96 * creates the text view and buffer to use
98 void createTextViews()
100 view1 = new TextView();
101 buffer = view1.getBuffer();
102 view2 = new TextView(buffer);
106 * sets up the widgets ot this test
108 void setupWidgets()
110 VPaned vPaned = new VPaned();
111 vPaned.setBorderWidth(5);
112 add(vPaned);
114 ScrolledWindow sw = new ScrolledWindow(PolicyType.AUTOMATIC, PolicyType.AUTOMATIC);
115 sw.add(view1);
116 vPaned.add1(sw);
117 sw = new ScrolledWindow(PolicyType.AUTOMATIC, PolicyType.AUTOMATIC);
118 sw.add(view2);
119 vPaned.add2(sw);
123 * Creates all the text tags to use
124 * @param buffer the TextBuffer
126 void createTags(TextBuffer buffer)
128 Bitmap stipple;
130 /* Create a bunch of tags. Note that it's also possible to
131 * create tags with gtk_text_tag_new() then add them to the
132 * tag table for the buffer, gtk_text_buffer_create_tag() is
133 * just a convenience function. Also note that you don't have
134 * to give tags a name; pass NULL for the name to create an
135 * anonymous tag.
137 * In any real app, another useful optimization would be to create
138 * a GtkTextTagTable in advance, and reuse the same tag table for
139 * all the buffers with the same tag set, instead of creating
140 * new copies of the same tags for every buffer.
142 * Tags are assigned default priorities in order of addition to the
143 * tag table. That is, tags created later that affect the same text
144 * property affected by an earlier tag will override the earlier
145 * tag. You can modify tag priorities with
146 * gtk_text_tag_set_priority().
149 buffer.createTag("heading",
150 "weight", PangoWeight.BOLD,
151 "size", 15 * PANGO_SCALE);
152 buffer.createTag("italic",
153 "style", cast(int)PangoStyle.ITALIC);
155 buffer.createTag("bold",
156 "weight", cast(int)PangoWeight.BOLD);
158 buffer.createTag("big",
159 /* points times the PANGO_SCALE factor */
160 "size", 20 * PANGO_SCALE);
162 buffer.createTag("xx-small",
163 "scale", PANGO_SCALE_XX_SMALL);
165 buffer.createTag("x-large",
166 "scale", PANGO_SCALE_X_LARGE);
168 buffer.createTag("monospace",
169 "family", "monospace");
171 buffer.createTag("blue_foreground",
172 "foreground", "blue");
174 buffer.createTag("red_background",
175 "background", "red");
177 const int gray50_width = 2;
178 const int gray50_height = 2;
179 static char gray50_bits[] = [0x02, 0x01];
181 stipple = Bitmap.createFromData(null, // drawablw
182 gray50_bits, gray50_width,
183 gray50_height);
185 buffer.createTag("background_stipple",
186 "background_stipple", stipple);
188 buffer.createTag("foreground_stipple",
189 "foreground_stipple", stipple);
191 buffer.createTag("big_gap_before_line",
192 "pixels_above_lines", 30);
194 buffer.createTag("big_gap_after_line",
195 "pixels_below_lines", 30);
197 buffer.createTag("double_spaced_line",
198 "pixels_inside_wrap", 10);
200 buffer.createTag("not_editable",
201 "editable", cast(int)false);
203 buffer.createTag("word_wrap",
204 "wrap_mode", cast(int)WrapMode.WORD);
206 buffer.createTag("char_wrap",
207 "wrap_mode", cast(int)WrapMode.CHAR);
209 buffer.createTag("no_wrap",
210 "wrap_mode", cast(int)WrapMode.NONE);
212 buffer.createTag("center",
213 "justification", cast(int)Justification.JUSTIFY_CENTER);
215 buffer.createTag("right_justify",
216 "justification", cast(int)Justification.JUSTIFY_RIGHT);
218 buffer.createTag("wide_margins",
219 "left_margin", 50, "right_margin", 50);
221 buffer.createTag("strikethrough",
222 "strikethrough", cast(int)true);
224 buffer.createTag("underline",
225 "underline", cast(int)PangoUnderline.SINGLE);
227 buffer.createTag("double_underline",
228 "underline", cast(int)PangoUnderline.DOUBLE);
230 buffer.createTag("superscript",
231 "rise", 10 * PANGO_SCALE, /* 10 pixels */
232 "size", 8 * PANGO_SCALE); /* 8 points */
234 buffer.createTag("subscript",
235 "rise", -10 * PANGO_SCALE, /* 10 pixels */
236 "size", 8 * PANGO_SCALE); /* 8 points */
239 buffer.createTag("rtl_quote",
240 "wrap_mode", WrapMode.WORD,
241 "direction", TextDirection.RTL,
242 "indent", 30,
243 "left_margin", 20,
244 "right_margin", 20);
248 * Inserts all the test text into the buffer
249 * @param buffer the TextBuffer
251 void insertText(TextBuffer buffer)
253 //version(Tango) {} else
255 TextIter iter = new TextIter();
256 TextIter start = new TextIter();
257 TextIter end = new TextIter();
258 Pixbuf pixbuf;
259 Pixbuf scaled;
260 TextChildAnchor anchor;
261 char[] filename;
263 /* demo_find_file() looks in the the current directory first,
264 * so you can run gtk-demo without installing GTK, then looks
265 * in the location where the file is installed.
268 pixbuf = new Pixbuf("images/gtk-logo-rgb.gif", null);
270 if (pixbuf.getPixbufStruct() is null)
272 version(Tango) Stdout("Failed to load image file gtk-logo-rgb.gif\n").newline;
273 else printf("Failed to load image file gtk-logo-rgb.gif\n");
274 pixbuf = null;
276 else
278 scaled = pixbuf.scaleSimple(32, 32, InterpType.BILINEAR);
279 pixbuf = pixbuf.scaleSimple(38, 38, InterpType.BILINEAR);
282 /* get start of buffer; each insertion will revalidate the
283 * iterator to point to just after the inserted text.
286 buffer.getIterAtOffset(iter, 0);
288 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");
290 buffer.insertWithTagsByName(iter, "Font styles. ","heading");
292 buffer.insert(iter, "For example, you can have ");
293 buffer.insertWithTagsByName(iter, "italic", "italic");
294 buffer.insert(iter, ", ");
295 buffer.insertWithTagsByName(iter, "bold", "bold");
296 buffer.insert(iter, ", or ");
297 buffer.insertWithTagsByName(iter, "monospace (typewriter)", "monospace");
298 buffer.insert(iter, ", or ");
299 buffer.insertWithTagsByName(iter, "big", "big");
300 buffer.insert(iter, " text. ");
301 buffer.insert(iter, "It's best not to hardcode specific text sizes; you can use relative sizes as with CSS, such as ");
302 buffer.insertWithTagsByName(iter, "xx-small", "xx-small");
303 buffer.insert(iter, " or ");
304 buffer.insertWithTagsByName(iter, "x-large", "x-large");
305 buffer.insert(iter, " to ensure that your program properly adapts if the user changes the default font size.\n\n");
307 buffer.insertWithTagsByName(iter, "Colors. ", "heading");
309 buffer.insert(iter, "Colors such as ");
310 buffer.insertWithTagsByName(iter, "a blue foreground", "blue_foreground");
311 buffer.insert(iter, " or ");
312 buffer.insertWithTagsByName(iter, "a red background", "red_background");
313 buffer.insert(iter, " or even ");
314 buffer.insertWithTagsByName(iter, "a stippled red background",
315 "red_background", "background_stipple");
317 buffer.insert(iter, " or ");
318 buffer.insertWithTagsByName(iter,
319 "a stippled blue foreground on solid red background",
320 "blue_foreground",
321 "red_background",
322 "foreground_stipple");
323 buffer.insert(iter, " (select that to read it) can be used.\n\n");
325 buffer.insertWithTagsByName(iter, "Underline, strikethrough, and rise. ", "heading");
327 buffer.insertWithTagsByName(iter, "Strikethrough", "strikethrough");
328 buffer.insert(iter, ", ");
329 buffer.insertWithTagsByName(iter, "underline", "underline");
330 buffer.insert(iter, ", ");
331 buffer.insertWithTagsByName(iter, "double underline", "double_underline");
332 buffer.insert(iter, ", ");
333 buffer.insertWithTagsByName(iter, "superscript", "superscript");
334 buffer.insert(iter, ", and ");
335 buffer.insertWithTagsByName(iter, "subscript", "subscript");
336 buffer.insert(iter, " are all supported.\n\n");
338 buffer.insertWithTagsByName(iter, "Images. ", "heading");
340 buffer.insert(iter, "The buffer can have images in it: ");
341 if ( pixbuf !is null )
343 buffer.insertPixbuf(iter, scaled);
344 buffer.insertPixbuf(iter, pixbuf);
345 buffer.insertPixbuf(iter, scaled);
347 else
349 buffer.insert(iter,"Sorry can't find the images");
351 buffer.insert(iter, " for example.\n\n");
353 buffer.insertWithTagsByName(iter, "Spacing. ", "heading");
355 buffer.insert(iter, "You can adjust the amount of space before each line.\n");
357 buffer.insertWithTagsByName(iter, "This line has a whole lot of space before it.\n",
358 "big_gap_before_line", "wide_margins");
359 buffer.insertWithTagsByName(iter,
360 "You can also adjust the amount of space after each line; this line has a whole lot of space after it.\n",
361 "big_gap_after_line", "wide_margins");
363 buffer.insertWithTagsByName(iter,
364 "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",
365 "double_spaced_line", "wide_margins");
367 buffer.insert(iter, "Also note that those lines have extra-wide margins.\n\n");
369 buffer.insertWithTagsByName(iter, "Editability. ", "heading");
371 buffer.insertWithTagsByName(iter,
372 "This line is 'locked down' and can't be edited by the user - just try it! You can't delete this line.\n\n",
373 "not_editable");
375 buffer.insertWithTagsByName(iter, "Wrapping. ", "heading");
377 buffer.insert(iter,
378 "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");
380 buffer.insertWithTagsByName(iter,
381 "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",
382 "char_wrap");
384 buffer.insertWithTagsByName(iter,
385 "This line has all wrapping turned off, so it makes the horizontal scrollbar appear.\n\n\n",
386 "no_wrap");
388 buffer.insertWithTagsByName(iter, "Justification. ", "heading");
390 buffer.insertWithTagsByName(iter,
391 "\nThis line has center justification.\n", "center");
393 buffer.insertWithTagsByName(iter,
394 "This line has right justification.\n", "right_justify");
396 buffer.insertWithTagsByName(iter,
397 "\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",
398 "wide_margins");
400 buffer.insertWithTagsByName(iter, "Internationalization. ", "heading");
402 buffer.insert(iter,
403 "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");
405 buffer.insert(iter, "Here's a word-wrapped quote in a right-to-left language:\n");
406 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",
407 "rtl_quote");
409 buffer.insert(iter, "You can put widgets in the buffer: Here's a button: ");
410 anchor = buffer.createChildAnchor(iter);
411 buffer.insert(iter, " and a menu: ");
412 anchor = buffer.createChildAnchor(iter);
413 buffer.insert(iter, " and a scale: ");
414 anchor = buffer.createChildAnchor(iter);
415 buffer.insert(iter, " and an animation: ");
416 anchor = buffer.createChildAnchor(iter);
417 buffer.insert(iter, " finally a text entry: ");
418 anchor = buffer.createChildAnchor(iter);
419 buffer.insert(iter, ".\n");
421 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...");
423 /* Apply word_wrap tag to whole buffer */
424 buffer.getBounds(start, end);
425 buffer.applyTagByName("word_wrap", start, end);
430 * Attaches all test widgets to the text view
431 * @param view the TextView
433 void attachWidgets(TextView view)
435 TextIter iter = new TextIter();
436 TextBuffer buffer;
437 int i;
439 buffer = view.getBuffer();
441 buffer.getStartIter(iter);
443 i = 0;
445 while (findAnchor(iter))
447 TextChildAnchor anchor;// = new TextChildAnchor();
448 Widget widget;
449 anchor = iter.getChildAnchor();
451 if (i == 0)
453 Button button = new Button("Click Me");
454 widget = button;
456 else if (i == 1)
459 ComboBox comboBox = new ComboBox();
460 comboBox.appendText("Option 1");
461 comboBox.appendText("Option 2");
462 comboBox.appendText("Option 3");
463 widget = comboBox;
465 else if (i == 2)
467 HScale hScale = new HScale(0.0,100.0,5.0);
468 hScale.setSizeRequest(70, -1);
469 widget = hScale;
471 else if (i == 3)
473 Image image = new Image("images/floppybuddy.gif");
474 widget = image;
476 else if (i == 4)
478 widget = new Entry();
480 else
482 widget = null;
483 //g_assert_not_reached ();
486 if ( widget !is null )
488 view.addChildAtAnchor(widget,anchor);
491 ++i;
495 bool findAnchor (TextIter iter)
497 while (iter.forwardChar())
499 if (iter.getChildAnchor() !is null ) //gtk_text_iter_get_child_anchor (iter))
501 return true;
504 return false;