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 3 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.
13  *
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., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
17  */
18 
19 module TestWindow;
20 
21 //debug = 1;
22 
23 //version=cairo;
24 
25 version(cairo)private import cairo.clock;
26 
27 private import gtk.Version;
28 private import gtk.Table;
29 
30 version(Tango)
31 {
32 	private import tango.text.convert.Layout;
33 	private import tango.io.Stdout;
34 	private import tango.core.Thread;
35 	private import tango.math.random.Kiss;
36 
37 	version = DRuntime;
38 }
39 else version(D_Version2)
40 {
41 	private import core.thread;
42 	private import std.random;
43 
44 	version = DRuntime;
45 }
46 else
47 {
48 	private import std.thread;
49 	private import std.random;
50 }
51 
52 import gdk.Threads;
53 
54 private import gtk.Main;
55 private import gtk.MainWindow;
56 private import gtk.Adjustment;
57 private import gtk.AccelGroup;
58 
59 private import TestEntries;
60 
61 //private import gtkDTree;
62 private import TestStock;
63 private import TestDrawingArea;
64 private import TestScales;
65 private import TestText;
66 //private import TestTree;
67 private import TestTreeView;
68 private import TestTreeView1;
69 private import TestImage;
70 private import TestThemes;
71 private import TestAspectFrame;
72 private import TestIdle;
73 private import TTextView;
74 //private import TEditableCells;
75 
76 private import gtk.MenuItem;
77 private import gtk.Widget;
78 private import gtk.MenuBar;
79 private import gtk.Notebook;
80 //private import gtk.ComboBoxTextEntry;
81 private import gtk.FileChooserDialog;
82 private import gtk.FileSelection;
83 private import gtk.FontSelectionDialog;
84 private import gtk.ColorSelectionDialog;
85 private import gtk.InputDialog;
86 private import gtk.Button;
87 private import gtk.VBox;
88 private import gtk.MessageDialog;
89 private import gtk.Frame;
90 private import gtk.ObjectGtk;
91 private import gtk.HButtonBox;
92 private import gtk.Statusbar;
93 private import gtk.Menu;
94 private import gtk.HandleBox;
95 private import gtk.Toolbar;
96 private import gtk.SeparatorToolItem;
97 private import gtk.ToolButton;
98 private import gtk.RadioButton;
99 private import gtk.CheckButton;
100 private import gtk.ToggleButton;
101 //private import gtk.ListItem;
102 private import gtk.HBox;
103 private import gtk.Arrow;
104 //private import gtk.ListG;
105 //private import gtk.OptionMenu;
106 private import gtk.ButtonBox;
107 private import gtk.Calendar;
108 private import gtk.VButtonBox;
109 private import gtk.SpinButton;
110 private import gtk.ListStore;
111 private import gtk.TreeIter;
112 private import gtk.TreeView;
113 private import gtk.TreeViewColumn;
114 private import gtk.CellRendererText;
115 //private import gtk.SListG;
116 //private import ddi.Drawable;
117 private import gtk.Window;
118 
119 private import gtk.ScrolledWindow;
120 private import gtk.MessageDialog;
121 
122 
123 
124 version(Tango) private import tango.core.Memory;
125 else version(D_Version2) private import core.memory;
126 else private import std.gc;
127 
128 private import glib.ListSG;
129 
130 private import glib.Str;
131 private import gtk.Label;
132 private import glib.ListG;
133 private import gtk.ComboBoxEntry;
134 private import gtk.Paned;
135 private import gtk.HPaned;
136 private import gtk.VPaned;
137 
138 private import gtk.Calendar;
139 version(Tango) private import tango.io.Stdout;
140 else private import std.stdio;
141 private import gtk.VButtonBox;
142 private import gtk.FileChooserButton;
143 private import gdk.Drawable;
144 
145 private import gtk.AboutDialog;
146 private import gtk.Dialog;
147 
148 private import gtk.TreeStore;
149 private import gdk.Pixbuf;
150 private import gtk.ComboBox;
151 
152 private import gtk.TreePath;
153 private import gtk.CellRenderer;
154 private import gtk.CellRendererPixbuf;
155 
156 /**
157  * This tests the DUI widgets
158  */
159 
160 
161 class TestWindow : MainWindow
162 {
163 	/**
164 	 * Executed when the user tries to close the window
165 	 * @return true to refuse to close the window
166 	 */
167 	public: int windowDelete(GdkEvent* event, Widget widget)
168 	{
169 
170 		debug(events) printf("TestWindow.widgetDelete : this and widget to delete %X %X\n",this,window);
171 		MessageDialog d = new MessageDialog(
172 										this,
173 										GtkDialogFlags.MODAL,
174 										MessageType.QUESTION,
175 										ButtonsType.YES_NO,
176 										"Are you sure you want' to exit these GtkDTests?");
177 		int responce = d.run();
178 		if ( responce == ResponseType.YES )
179 		{
180 			Main.exit(0);
181 		}
182 		d.destroy();
183 		return true;
184 	}
185 
186 	void anyButtonExits(Button button)
187 	{
188 			Main.exit(0);
189 	}
190 
191 	this()
192 	{
193 		super("GtkD tests");
194 		setup();
195 		showAll();
196 
197 		string versionCompare = Version.checkVersion(2,8,0);
198 
199 		if ( versionCompare.length > 0 )
200 		{
201 			MessageDialog d = new MessageDialog(this,
202 										GtkDialogFlags.MODAL,
203 										MessageType.WARNING,
204 										ButtonsType.OK,
205 										"GtkD : Gtk+ version missmatch\n" ~ versionCompare ~
206 										"\nYou might run into problems!"
207 										"\n\nPress OK to continue");
208 			d.run();
209 			d.destroy();
210 		}
211 	}
212 
213 	void setup()
214 	{
215 		//Frame.defaultBorder = 7;
216 
217 		VBox mainBox = new VBox(false,0);
218 		mainBox.packStart(getMenuBar(),false,false,0);
219 		mainBox.packStart(getToolbar(),false,false,0);
220 
221 		Notebook notebook = setNotebook();
222 		notebook.setBorderWidth(10);
223 		mainBox.packStart(notebook,true,true,0);
224 
225 		Button cancelButton = new Button(StockID.CANCEL, &anyButtonExits);
226 		Button exitButton = new Button(StockID.QUIT, &anyButtonExits);
227 		Button quitButton = new Button(StockID.OK, &anyButtonExits);
228 
229 		ButtonBox bBox = HButtonBox.createActionBox();
230 
231 		bBox.packEnd(exitButton,0,0,10);
232 		bBox.packEnd(cancelButton,0,0,10);
233 		bBox.packEnd(quitButton,0,0,10);
234 		mainBox.packStart(bBox,false,false,0);
235 
236 		Statusbar statusbar = new Statusbar();
237 
238 		mainBox.packStart(statusbar,false,true,0);
239 		add(mainBox);
240 
241 		notebook.appendPage(new TestEntries,"Entry");
242 		testEventBox(notebook);
243 
244 		testButtons(notebook);
245 
246 		notebook.appendPage(new TestStock,"Stock");
247 		testLists(notebook);
248 		testNotebook(notebook);
249 		testPaned(notebook);
250 		testDialogs(notebook);
251 		testViewport(notebook);
252 
253 		version(Windows)
254 		{
255 			// todo - threads are still broken on windows
256 		}
257 		else
258 		{
259 			testThreads(notebook);
260 		}
261 
262 		notebook.appendPage(new TestScales,"Scales");
263 			testSpinButton(notebook);
264 
265 		notebook.appendPage(new Label("Deprecated,\nuse TreeView\ninstead"),"Tree");
266 		notebook.appendPage(new TestTreeView,"TreeView");
267 		notebook.appendPage(new TestTreeView1,"TreeView 1");
268 			testList(notebook);
269 
270 		version(linux) {
271 			// this block crashes gtk+ on win32 for some reason
272 			notebook.appendPage(new Frame(new TestDrawingArea,"Drawing Area"),"Drawing");
273 			notebook.appendPage(new TestText,"Text");
274 			notebook.appendPage(new TestImage(this),"Image");
275 			notebook.appendPage(new TestThemes(this),"Themes");
276 			notebook.appendPage(new TestAspectFrame(),"Aspect Frame");
277 			notebook.appendPage(new TestIdle(),"Idle");
278 			version(cairo)notebook.appendPage(new Clock(), "Cairo");
279 			gtkDemo(notebook);
280 		}
281 	}
282 
283 	MenuBar getMenuBar()
284 	{
285 
286 		AccelGroup accelGroup = new AccelGroup();
287 
288 		addAccelGroup(accelGroup);
289 
290 
291 		MenuBar menuBar = new MenuBar();
292 
293 		Menu menu = menuBar.append("_File");;
294 
295 		MenuItem item = new MenuItem(&onMenuActivate, "_New","file.new", true, accelGroup, 'n');
296 		//item.addAccelerator("activate",accelGroup,'n',GdkModifierType.CONTROL_MASK,GtkAccelFlags.VISIBLE);
297 
298 		menu.append(item);
299 		menu.append(new MenuItem(&onMenuActivate, "_Open","file.open", true, accelGroup, 'o'));
300 		menu.append(new MenuItem(&onMenuActivate, "_Close","file.close", true, accelGroup, 'c'));
301 		menu.append(new MenuItem(&onMenuActivate, "E_xit","file.exit", true, accelGroup, 'x'));
302 
303 
304 		menu = menuBar.append("_Edit");
305 
306 		menu.append(new MenuItem(&onMenuActivate,"_Find","edit.find", true, accelGroup, 'f'));
307 		menu.append(new MenuItem(&onMenuActivate,"_Search","edit.search", true, accelGroup, 's'));
308 
309 		menu = menuBar.append("_Help");
310 		menu.append(new MenuItem(&onMenuActivate,"_About","help.about", true, accelGroup, 'a',GdkModifierType.CONTROL_MASK|GdkModifierType.SHIFT_MASK));
311 
312 
313 
314 
315 		return menuBar;
316 	}
317 
318 	class GtkDAbout : AboutDialog
319 	{
320 		this()
321 		{
322 			string[] names;
323 			names ~= "Antonio Monteiro (binding/wrapping/proxying/decorating for D)";
324 			names ~= "www.gtk.org (base C library)";
325 
326 			setAuthors( names );
327 			setDocumenters( names );
328 			setArtists( names );
329 			setLicense("License is LGPL");
330 			setWebsite("http://lisdev.com");
331 		}
332 	}
333 
334 	void onMenuActivate(MenuItem menuItem)
335 	{
336 		string action = menuItem.getActionName();
337 		switch( action )
338 		{
339 			case "help.about":
340 				GtkDAbout dlg = new GtkDAbout();
341 				dlg.addOnResponse(&onDialogResponse);
342 				dlg.showAll();
343 				break;
344 			default:
345 				MessageDialog d = new MessageDialog(
346 					this,
347 					GtkDialogFlags.MODAL,
348 					MessageType.INFO,
349 					ButtonsType.OK,
350 					"You pressed menu item "~action);
351 				d.run();
352 				d.destroy();
353 			break;
354 		}
355 
356 	}
357 
358 	void onDialogResponse(int response, Dialog dlg)
359 	{
360 		if(response == GtkResponseType.CANCEL)
361 			dlg.destroy();
362 	}
363 
364 	Widget getToolbar()
365 	{
366 		HandleBox handleBox = new HandleBox();
367 		Toolbar toolbar = new Toolbar();
368 		toolbar.insert(new ToolButton(StockID.OPEN));
369 		toolbar.insert(new ToolButton(StockID.CLOSE));
370 		toolbar.insert(new SeparatorToolItem());
371 		toolbar.insert(new ToolButton(StockID.SAVE));
372 		toolbar.insert(new ToolButton(StockID.SAVE_AS));
373 
374 		handleBox.add(toolbar);
375 
376 		return handleBox;
377 
378 	}
379 
380 	Notebook setNotebook()
381 	{
382 		Notebook notebook = new Notebook();
383 		notebook.addOnSwitchPage(&onNotebookSwitchPage);
384 		notebook.setTabPos(PositionType.LEFT);
385 		return notebook;
386 	}
387 
388 	void onNotebookSwitchPage(void* notePage, uint pageNumber, Notebook notebook)
389 	{
390 		//writefln("Notebook switch to page %s", pageNumber);
391 		// fullCollect helps finding objects that shouldn't have been collected
392 		version(Tango) GC.collect();
393 		else version(D_Version2) GC.collect();
394 		else std.gc.fullCollect();
395 		//writefln("exiting Notebook switch to page %s", pageNumber);
396 	}
397 
398 	//private import EventBox;
399 
400 	void testEventBox(Notebook notebook)
401 	{
402 
403 //		EventBox eventBox = new EventBox();
404 //		eventBox.add(new Label("label on event box"));
405 //		notebook.appendPage(eventBox,"Buttons");
406 
407 		//EventBox eventBox = new EventBox();
408 		//eventBox.add(new Label("label on event box"));
409 		notebook.appendPage(new Label("just a simple label"),new Label("label"));
410 
411 	}
412 
413 	void testButtons(Notebook notebook)
414 	{
415 
416 		Table table = new Table(2,12,0);
417 
418 		//ListSG listSG = new ListSG();
419 
420 		RadioButton radio1Button = new RadioButton(cast(ListSG)null,"Option 1");
421 		RadioButton radio2Button = new RadioButton(radio1Button,"Option 2");
422 		RadioButton radio3Button = new RadioButton(radio2Button,"Option 3");
423 		RadioButton radio4Button = new RadioButton(radio3Button,"Option 4");
424 		RadioButton radio5Button = new RadioButton(radio4Button,"Option 5");
425 		RadioButton radio6Button = new RadioButton(radio5Button,"Option 6");
426 		RadioButton radio7Button = new RadioButton(radio6Button,"Option 7");
427 		RadioButton radio8Button = new RadioButton(radio7Button,"Option 8");
428 		RadioButton radio9Button = new RadioButton(radio8Button,"Option 9");
429 		table.attach(radio1Button,0,1,0,1,AttachOptions.FILL,AttachOptions.FILL,4,4);
430 		table.attach(radio2Button,0,1,1,2,AttachOptions.FILL,AttachOptions.FILL,4,4);
431 		table.attach(radio3Button,0,1,2,3,AttachOptions.FILL,AttachOptions.FILL,4,4);
432 		table.attach(radio4Button,0,1,3,4,AttachOptions.FILL,AttachOptions.FILL,4,4);
433 		table.attach(radio5Button,0,1,4,5,AttachOptions.FILL,AttachOptions.FILL,4,4);
434 		table.attach(radio6Button,0,1,5,6,AttachOptions.FILL,AttachOptions.FILL,4,4);
435 		table.attach(radio7Button,0,1,6,7,AttachOptions.FILL,AttachOptions.FILL,4,4);
436 		table.attach(radio8Button,0,1,7,8,AttachOptions.FILL,AttachOptions.FILL,4,4);
437 		table.attach(radio9Button,0,1,8,9,AttachOptions.FILL,AttachOptions.FILL,4,4);
438 
439 		CheckButton editableButton = new CheckButton("editable");
440 		CheckButton visibleButton = new CheckButton("visible");
441 		table.attach(editableButton,0,1,9,10,AttachOptions.FILL,AttachOptions.FILL,4,4);
442 		table.attach(visibleButton,0,1,10,11,AttachOptions.FILL,AttachOptions.FILL,4,4);
443 
444 		ToggleButton toggleButton = new ToggleButton("Toggle this");
445 		table.attach(toggleButton,0,1,11,12,AttachOptions.FILL,AttachOptions.FILL,4,4);
446 
447 		Button button = new Button("test events");
448 		table.attach(button,0,1,12,13,AttachOptions.FILL,AttachOptions.FILL,4,4);
449 
450 		void bActivate(Button button)
451 		{
452 			version(Tango) Stdout("button Activate").newline;
453 			else printf("button Activate\n");
454 		}
455 		void bClicked(Button button)
456 		{
457 			version(Tango) Stdout("button Clicked").newline;
458 			else printf("button Clicked\n");
459 		}
460 		void bEnter(Button button)
461 		{
462 			version(Tango) Stdout("button Enter").newline;
463 			else printf("button Enter\n");
464 		}
465 		void bLeave(Button button)
466 		{
467 			version(Tango) Stdout("button Leave").newline;
468 			else printf("button Leave\n");
469 		}
470 		void bPressed(Button button)
471 		{
472 			version(Tango) Stdout("button Pressed").newline;
473 			else printf("button Pressed\n");
474 		}
475 		void bReleased(Button button)
476 		{
477 			version(Tango) Stdout("button Released").newline;
478 			else printf("button Released\n");
479 		}
480 		button.addOnActivate(&bActivate);
481 		button.addOnClicked(&bClicked);
482 		button.addOnEnter(&bEnter);
483 		button.addOnLeave(&bLeave);
484 		button.addOnPressed(&bPressed);
485 		button.addOnReleased(&bReleased);
486 
487 //		for ( ShadowType shadow = 0; shadow<=ShadowType.max ; shadow ++)
488 //		{
489 //			for ( DirectionType direction = 0 ; direction<=DirectionType.max ; direction++)
490 //			{
491 //				table.attach(new Arrow(direction,shadow),direction+1,direction+2,shadow,shadow+1,AttachOptions.FILL,AttachOptions.FILL,4,4);
492 //				table.attach(new Arrow(direction,shadow),direction+1,direction+2,shadow,shadow+1,AttachOptions.FILL,AttachOptions.FILL,4,4);
493 //				table.attach(new Arrow(direction,shadow),direction+1,direction+2,shadow,shadow+1,AttachOptions.FILL,AttachOptions.FILL,4,4);
494 //				table.attach(new Arrow(direction,shadow),direction+1,direction+2,shadow,shadow+1,AttachOptions.FILL,AttachOptions.FILL,4,4);
495 //			}
496 //		}
497 
498 
499 		notebook.appendPage(new Frame(table,"Buttons"),"Buttons");
500 
501 	}
502 
503 	class ComboStore : TreeStore
504 	{
505 		this()
506 		{
507 			//int* i = cast(int*)pixbufGetType();
508 
509 			GType[] columns;
510 			columns ~= GType.STRING;
511 			columns ~= GType.STRING;
512 			super(columns);
513 		}
514 
515 	}
516 
517 
518 	void testLists(Notebook notebook)
519 	{
520 		VBox mainBox = new VBox(false,3);
521 
522 		// comboBoxTextEntry from a list of strings
523 		mainBox.packStart(new Label("String combo"),false,true,0);
524 		static string[] cbList = ["item 1","item 2","item 3","item 4","item 5","item 6","item 7","item 8","item 9"];
525 		comboText = new ComboBoxEntry();
526 		string entry3 = "Combo box text entry 3";
527 		comboText.appendText("Combo box text entry 1");
528 		comboText.appendText("Combo box text entry 2");
529 		comboText.appendText(entry3);
530 		comboText.appendText("Combo box text entry 4");
531 		comboText.appendText("Combo box text entry 5");
532 		comboText.setActive(2);
533 
534 		ButtonBox actionBox1 = HButtonBox.createActionBox();
535 		actionBox1.packStart(comboText,false,false,0);
536 
537 		Button showCombo1 = new Button("ShowCombo", &showTextCombo);
538 		actionBox1.packStart(showCombo1,false,false,0);
539 
540 		mainBox.packStart(new Frame(actionBox1, "Text entry ComboBox"),false,false,0);
541 
542 
543 
544 		// TODO combo with widgets
545 
546 
547 		// new ComboBox + TreeModel
548 
549 		ComboStore comboStore = new ComboStore();
550 
551 		TreeIter iterFirst;	// to set the first active iter
552 		TreeIter iterChild;
553 		TreeIter iterTop = comboStore.append(null);
554 		comboStore.setValue(iterTop, 0, "Paganini" );
555 		iterFirst = comboStore.append(iterTop);
556 		comboStore.setValue(iterFirst, 0, "Nicolo" );
557 
558 		iterTop = comboStore.append(null);
559 		comboStore.setValue(iterTop, 0, "List" );
560 		iterChild = comboStore.append(iterTop);
561 		comboStore.setValue(iterChild, 0, "Franz" );
562 
563 		iterTop = comboStore.append(null);
564 		comboStore.setValue(iterTop, 0, "Beethoven" );
565 		iterChild = comboStore.append(iterTop);
566 		comboStore.setValue(iterChild, 0, "Ludwic" );
567 		iterChild = comboStore.append(iterTop);
568 		comboStore.setValue(iterChild, 0, "Maria" );
569 		iterChild = comboStore.append(iterTop);
570 		comboStore.setValue(iterChild, 0, "Van" );
571 
572 		iterTop = comboStore.append(null);
573 		comboStore.setValue(iterTop, 0, "Bach" );
574 		iterChild = comboStore.append(iterTop);
575 		comboStore.setValue(iterChild, 0, "Johann" );
576 		iterChild = comboStore.append(iterTop);
577 		comboStore.setValue(iterChild, 0, "Sebastian" );
578 
579 		ComboBox treeCombo = new ComboBox(comboStore);
580 		treeCombo.setWrapWidth(1);
581 		CellRenderer renderer = new CellRendererText();
582 		treeCombo.packStart(renderer, true);
583 		treeCombo.addAttribute(renderer, "text",0);
584 		
585 		// TODO something is wrong gettign the ier from the path
586 		//TreePath path = new TreePath("0,0");
587 		//comboStore.getIter(iterChild, path);
588 		//treeCombo.setActiveIter(iterChild);
589 		// use a previously set iter
590 		treeCombo.setActiveIter(iterFirst);
591 
592 		mainBox.packStart(new Frame(treeCombo,"Tree Combo box"),false,true,0);
593 
594 		simpleCombo = new ComboBox();
595 		simpleCombo.appendText("Top");
596 		simpleCombo.appendText("Bottom");
597 		simpleCombo.appendText("Left");
598 		simpleCombo.appendText("Right");
599 		simpleCombo.setActive(0);
600 
601 		// actions
602 
603 		ButtonBox actionBox = HButtonBox.createActionBox();
604 		actionBox.packStart(simpleCombo,false,false,0);
605 
606 		Button showCombo = new Button("ShowCombo", &showSimpleCombo);
607 		actionBox.packStart(showCombo,false,false,0);
608 
609 		mainBox.packStart(new Frame(actionBox, "Simple text list"),false,false,0);
610 
611 		notebook.appendPage(new Frame(mainBox,"Lists"),"Lists");
612 
613 	}
614 	ComboBox simpleCombo;
615 	ComboBoxEntry comboText;
616 
617 	void showTextCombo(Button button)
618 	{
619 		version(Tango) Stdout("Combo selected text = ")(comboText.getActiveText()).newline;
620 		else writefln("Combo selected text = %s",comboText.getActiveText());
621 	}
622 
623 	void showSimpleCombo(Button button)
624 	{
625 		version(Tango) Stdout("Combo selected text = ")(simpleCombo.getActiveText()).newline;
626 		else writefln("Combo selected text = %s",simpleCombo.getActiveText());
627 	}
628 
629 	class NB : Notebook
630 	{
631 		void itemActivated(MenuItem menu_item)
632 		{
633 			version(Tango) Stdout("NB.activateCallback").newline;
634 			else printf("NB.activateCallback\n");
635 		}
636 		void buttonClicked(Button button)
637 		{
638 			setCurrentPage(2);
639 		}
640 
641 		void switchPage(Notebook notebook, /*NotebookPage page,*/ guint pageNumber)
642 		{
643 			version(Tango) Stdout("new page = ")(pageNumber).newline;
644 			else printf("new page = %d\n",pageNumber);
645 		}
646 	}
647 
648 
649 	NB nb;
650 
651 	void posLeft(Button button)
652 	{
653 		nb.setTabPos(PositionType.LEFT);
654 	}
655 	void posRight(Button button)
656 	{
657 		nb.setTabPos(PositionType.RIGHT);
658 	}
659 	void posTop(Button button)
660 	{
661 		nb.setTabPos(PositionType.TOP);
662 	}
663 	void posBottom(Button button)
664 	{
665 		nb.setTabPos(PositionType.BOTTOM);
666 	}
667 
668 	/**
669 	 * tests notebook
670 	 * @param nodebook
671 	 */
672 	void testNotebook(Notebook notebook)
673 	{
674 
675       	nb = new NB();
676       	nb.setTabPos(PositionType.min);
677       	nb.popupEnable();
678 		nb.setShowBorder(false);
679 		nb.setBorderWidth(0);
680 
681       	class PageMove
682       	{
683       		Notebook notebook;
684       		PositionType toPos;
685       		this(Notebook notebook,PositionType toPos)
686       		{
687       			this.notebook = notebook;
688       			this.toPos = toPos;
689       		}
690       		void buttonClickedCallback()
691       		{
692       			notebook.setTabPos(toPos);
693       		}
694       	}
695 
696 		PageMove toLeft = new PageMove(nb,PositionType.LEFT);
697 		PageMove toRight = new PageMove(nb,PositionType.RIGHT);
698 		PageMove toTop = new PageMove(nb,PositionType.TOP);
699 		PageMove toBottom = new PageMove(nb,PositionType.BOTTOM);
700 
701 
702 		notebook.appendPage(nb,new Label("Notebook"));
703 
704       	for( char i = '1' ; i<'5' ; i++ )
705       	{
706       		Table table = new Table(2,2,true);
707 			Button left = new Button("Left "~ i);
708 			left.addOnClicked(&posLeft);
709 			Button right = new Button("Right "~ i);
710 			right.addOnClicked(&posRight);
711 			Button top = new Button("top "~ i);
712 			top.addOnClicked(&posTop);
713 			Button bottom = new Button("bottom "~ i);
714 			bottom.addOnClicked(&posBottom);
715 
716 			table.attach(top,0,1,0,1,AttachOptions.SHRINK,AttachOptions.SHRINK,4,4);
717 			table.attach(right,1,2,0,1,AttachOptions.SHRINK,AttachOptions.SHRINK,4,4);
718 			table.attach(left,0,1,1,2,AttachOptions.SHRINK,AttachOptions.SHRINK,4,4);
719 			table.attach(bottom,1,2,1,2,AttachOptions.SHRINK,AttachOptions.SHRINK,4,4);
720       		if ( i == 3 )
721 			{
722 
723 //				MenuItem menuItem = new MenuItem("menu page 3",&nb.itemActivated);
724 //
725 //				Menu menu = new Menu();
726 //				menu.append(new MenuItem("page 3.1",&nb.itemActivated));
727 //				menu.append(new MenuItem("page 3.2",&nb.itemActivated));
728 //				menu.append(new MenuItem("page 3.3",&nb.itemActivated));
729 //				menu.append(new MenuItem("page 3.4",&nb.itemActivated));
730 //
731 //				menuItem.setSubmenu(menu);
732 
733 				HBox box = new HBox(false,0);
734 				box.setBorderWidth(0);
735 				Button button = new Button("Page " ~ i ~ "\0");
736 				button.addOnClicked(&nb.buttonClicked);
737 				button.setBorderWidth(0);
738 				button.setRelief(ReliefStyle.NONE);
739 				CheckButton checkButton = new CheckButton();
740 				checkButton.setBorderWidth(0);
741 				box.packStart(checkButton,false,false,0);
742 				box.packStart(button,false,false,0);
743 				//nb.appendPageMenu(table,box,menuItem);
744 				//nb.appendPage(table,box);
745 			}
746 			else
747 			{
748 				nb.appendPage(table,new Label("Page " ~ i ~ "\0"));
749 			}
750       	}
751 		//nb.addOnSwitchPage(&nb.switchPage);
752 	}
753 
754 	void testPaned(Notebook notebook)
755 	{
756 
757 		Paned mainPaned = new VPaned();
758 		Paned p0 = mainPaned;
759 		Button p1;
760 		Paned p2;
761 
762 		bool h = true;
763 		for ( char c='1' ; c<='5' ; c++ )
764 		{
765 			p1 = new Button("Pane "~c);
766 			if ( h ) p2 = new HPaned();
767 			else p2 = new VPaned();
768 
769 			p0.add1(p1);
770 			p0.add2(p2);
771 			p0 = p2;
772 			h = !h;
773 		}
774 
775 		notebook.appendPage(mainPaned,new Label("Paned"));
776 
777 	}
778 
779 	FileChooserDialog fcd;
780 	FileSelection fs;
781 	FontSelectionDialog f;
782 	ColorSelectionDialog d;
783 	InputDialog id;
784 
785 	void showFileChooser(Button button)
786 	{
787 		string[] a;
788 		ResponseType[] r;
789 		a ~= "Lets go!";
790 		a ~= "Please don't";
791 		r ~= ResponseType.OK;
792 		r ~= ResponseType.CANCEL;
793 		if ( fcd  is  null )
794 		{
795 			fcd = new FileChooserDialog("File Chooser", this, FileChooserAction.OPEN, a, r);
796 		}
797 
798 		fcd.setSelectMultiple(true);
799 		fcd.run();
800 //		writefln("file selected = %s",fcd.getFileName());
801 //
802 //		foreach ( int i, string selection ; fs.getSelections())
803 //		{
804 //			printf("File(s) selected [%d] %.*s\n",i,selection);
805 //		}
806 		fcd.hide();
807 	}
808 
809 
810 
811 	void showFileSel(Button button)
812 	{
813 
814 		if ( fs  is  null )
815 		{
816 			fs = new FileSelection("File Selection");
817 		}
818 		//fs.showAll();
819 		//fs.setMultiple(true);
820 		fs.run();
821 		//printf("file selected = %.*s\n",fs.getFileName());
822 //		string[] selections = fs.getSelections();
823 //		for ( int i=0 ;i<selections.length ; i++)
824 //		{
825 //			printf("File(s) selected [%d] %.*s\n",i,selections[i]);
826 //		}
827 		fs.hide();
828 	}
829 
830 	void showColor(Button button)
831 	{
832 		if ( d  is  null )
833 		{
834 			d = new ColorSelectionDialog("Select the color");
835 		}
836 		d.run();
837 		d.hide();
838 	}
839 
840 	void showInput(Button button)
841 	{
842 		if ( id  is  null )
843 		{
844 			id = new InputDialog();
845 			id.getCloseButton().addOnClicked(&CloseInputDialog);
846 		}
847 		id.run();
848 	}
849 
850 	void CloseInputDialog(Button button)
851 	{
852 		id.hide();
853 	}
854 
855 	void showCalendar(Button button)
856 	{
857 		Window calWin = new Window("Calendar");
858 		Calendar calendar = new Calendar();
859 		//calendar.setTitle("No Title");
860 		calWin.add(calendar);
861 		calWin.showAll();
862 	}
863 
864 	void showFont(Button button)
865 	{
866 		if ( f  is  null )
867 		{
868 			f = new FontSelectionDialog("Select the font");
869 		}
870 		f.run();
871 		string fontName = f.getFontName();
872 		f.hide();
873 	}
874 
875 	Button fontButton;
876 
877 	void testDialogs(Notebook notebook)
878 	{
879 
880 		ButtonBox bBox = VButtonBox.createActionBox();
881 
882 		if ( fcd  is  null )
883 		{
884 			fcd = new FileChooserDialog("File Chooser", this, FileChooserAction.OPEN);
885 		}
886 
887 
888 		Button fileChooser = new Button("File Chooser", &showFileChooser);
889 		FileChooserButton fcb = new FileChooserButton(fcd);
890 
891 		Button fileSel = new Button("File Selection", &showFileSel);
892 		Button color = new Button("Color Dialog", &showColor);
893 		Button input = new Button("Input Dialog", &showInput);
894 		Button calendar = new Button("Calendar Dialog", &showCalendar);
895 		fontButton = new Button("Font Dialog", &showFont);
896 		//fontButton.modifyFont("[Newspaper][16]");
897 
898 		bBox.packStart(fileChooser,0,0,10);
899 		bBox.packStart(fcb,0,0,10);
900 		bBox.packStart(fileSel,0,0,10);
901 		bBox.packStart(color,0,0,10);
902 		bBox.packStart(input,0,0,10);
903 		bBox.packStart(calendar,0,0,10);
904 		bBox.packStart(fontButton,0,0,10);
905 
906 		notebook.appendPage(new Frame(bBox,"Dialogs"),new Label("Dialogs"));
907 
908 	}
909 
910 	version(D_Version2)
911 		mixin("__gshared Button[] threadTestButtons;");
912 	else
913 		Button[] threadTestButtons;
914 
915 	static T1[] t1s;
916 
917 	class T1 : Thread
918 	{
919 		int num;
920 
921 		this(int num)
922 		{
923 			super(&run);
924 			this.num = num;
925 		}
926 
927 		version(DRuntime) void run()
928 		{
929 			runCommon();
930 		}
931 		else override int run()
932 		{
933 			return runCommon();
934 		}
935 
936 
937 		int runCommon()
938 		{
939 			while(1)
940 			{
941 				version(Tango) size_t buttonNum = Kiss.instance.natural(threadTestButtons.length);
942 				else version(D_Version2) size_t buttonNum = uniform(0, threadTestButtons.length);
943 				else size_t buttonNum = rand()%threadTestButtons.length;
944 				Button button = threadTestButtons[buttonNum];
945 
946 				gdkThreadsEnter();
947 				button.removeAll();
948 				version(Tango) button.setLabel( (new Layout!(char))("{}", num));
949 				else           button.setLabel(std..string.format("%s", num));
950 				gdkThreadsLeave();
951 				yield();
952 			}
953 			assert(0);
954 		}
955 	}
956 
957 	void testThreads(Notebook notebook)
958 	{
959 
960 		Table grid = new Table(8,8,0);
961 		for ( int i = 0 ; i<8 ; i++)
962 		{
963 			for ( int j = 0 ; j<8; j++)
964 			{
965 				version(Tango) Button button = new Button((new Layout!(char))("{}",(j+8*i)));
966 				else Button button = new Button(std..string.format("%s",(j+8*i)));
967 				threadTestButtons ~= button;
968 				grid.attach( button,
969 							i,i+1,
970 							j,j+1,
971 							AttachOptions.SHRINK,AttachOptions.SHRINK,4,4);
972 
973 				t1s ~= new T1(j+8*i);
974 			}
975 		}
976 
977 		void stop(Button button)
978 		{
979 			foreach ( T1 t ; t1s )
980 			{
981 				version(Tango)
982 				{
983 					if ( t.isRunning() )
984 					{
985 						t.sleep(100.0);
986 					}
987 				}
988 				else version(D_Version2)
989 				{
990 					if ( t.isRunning() )
991 					{
992 						t.sleep(dur!("hnsecs")(100));
993 					}
994 				}
995 				else switch( t.getState() )
996 				{
997 					case Thread.TS.RUNNING:
998 						t.pause();
999 						break;
1000 
1001 					default:
1002 						break;
1003 				}
1004 			}
1005 		}
1006 
1007 		void go(Button button)
1008 		{
1009 			foreach ( T1 t ; t1s )
1010 			{
1011 				version(DRuntime)
1012 				{
1013 					if ( !t.isRunning() )
1014 					{
1015 						t.start();
1016 					}
1017 				}
1018 				else switch( t.getState() )
1019 				{
1020 					case Thread.TS.INITIAL:
1021 						t.start();
1022 						break;
1023 
1024 					default:
1025 						t.resume();
1026 						break;
1027 				}
1028 			}
1029 		}
1030 
1031 		VBox vbox = new VBox(false, 2);
1032 		vbox.packStart(grid, true, true,2);
1033 		ButtonBox actions = HButtonBox.createActionBox();
1034 
1035 		Button button = new Button(StockID.STOP, &stop);
1036 		actions.packStart(button, false, false, 7);
1037 		button = new Button(StockID.OK, &go);
1038 		actions.packStart(button, false, false, 7);
1039 
1040 		vbox.packStart(actions, false, false, 2);
1041 
1042 		notebook.appendPage(vbox,new Label("Threads"));
1043 	}
1044 
1045 	void testViewport(Notebook notebook)
1046 	{
1047 
1048 		Table grid = new Table(21,21,0);
1049 		for ( int i = 0 ; i<21 ; i++)
1050 		{
1051 			for ( int j = 0 ; j<21; j++)
1052 			{
1053 				if ( (i == j) || (i+j==20) || (i==10) || (j==10))
1054 				{
1055 					grid.attach(
1056 						new Button("Button"),
1057 							i,i+1,
1058 							j,j+1,
1059 							AttachOptions.SHRINK,AttachOptions.SHRINK,4,4);
1060 				}
1061 			}
1062 		}
1063 
1064 		ScrolledWindow sw = new ScrolledWindow(null,null);
1065 		sw.addWithViewport(grid);
1066 		notebook.appendPage(sw,new Label("Viewport"));
1067 	}
1068 
1069 	void testSpinButton(Notebook notebook)
1070 	{
1071 		Table table = new Table(2,1,false);
1072 
1073 		SpinButton spin = new SpinButton(new Adjustment(1.0, 0.0, 100.0, 1.0, 10.0, 0),1,0);
1074 		table.attach(new Label("Spin this:"),0,1,0,1,AttachOptions.FILL,AttachOptions.FILL,4,4);
1075 		table.attach(spin,1,2,0,1,AttachOptions.FILL,AttachOptions.FILL,4,4);
1076 
1077 		notebook.appendPage(table,"Spin Buttons");
1078 
1079 	}
1080 
1081 	void testList(Notebook notebook)
1082 	{
1083 		debug(Tango) Stdout("TestWindow.testList 1").newline;
1084 
1085 		class TestListStore : ListStore
1086 		{
1087 			this()
1088 			{
1089 				static GType [3] columns = [
1090 								GType.STRING,
1091 								GType.STRING,
1092 								GType.STRING
1093 								];
1094 				super(columns);
1095 			}
1096 		}
1097 
1098 		TestListStore testListStore = new TestListStore();
1099 
1100 		TreeIter iterTop = testListStore.createIter();
1101 
1102 		static int [3] cols = [0,1,2];
1103 		string[] vals;
1104 		vals ~= "Antonio";
1105 		vals ~= "Canada";
1106 		vals ~= "Ontario";
1107 		testListStore.set(iterTop,cols,vals);
1108 
1109 		testListStore.append(iterTop);
1110 		string[] vals1;
1111 		vals1 ~= "John Reimer";
1112 		vals1 ~= "Canada";
1113 		vals1 ~= "BC";
1114 		testListStore.set(iterTop,cols,vals1);
1115 
1116 		testListStore.append(iterTop);
1117 		string[] vals2;
1118 		vals2 ~= "Friend of GtkD 2";
1119 		vals2 ~= "Poland";
1120 		vals2 ~= "Torun";
1121 		testListStore.set(iterTop,cols,vals2);
1122 
1123 		testListStore.append(iterTop);
1124 		string[] vals3;
1125 		vals3 ~= "Friend of GtkD 3";
1126 		vals3 ~= "Norway";
1127 		vals3 ~= "Norway";
1128 		testListStore.set(iterTop,cols,vals3);
1129 
1130 		TreeView treeView = new TreeView(testListStore);
1131 		treeView.setHeadersClickable(true);
1132 		treeView.setRulesHint(true);
1133 
1134 		//CellRendererText cellText = new CellRendererText();
1135 		TreeViewColumn column = new TreeViewColumn("Author",new CellRendererText(),"text", 0);
1136 		treeView.appendColumn(column);
1137 		column.setResizable(true);
1138 		column.setReorderable(true);
1139 		column.setSortColumnId(0);
1140 		column.setSortIndicator(true);
1141 
1142 		column = new TreeViewColumn("Country",new CellRendererText(),"text", 1);
1143 		treeView.appendColumn(column);
1144 		column.setResizable(true);
1145 		column.setReorderable(true);
1146 		column.setSortColumnId(1);
1147 		column.setSortIndicator(true);
1148 
1149 		column = new TreeViewColumn("Province",new CellRendererText(),"text", 2);
1150 		treeView.appendColumn(column);
1151 		column.setResizable(true);
1152 		column.setReorderable(true);
1153 		column.setSortColumnId(2);
1154 		column.setSortIndicator(true);
1155 
1156 		//notebook.appendPage(treeView,"ListView");
1157 		ScrolledWindow sw = new ScrolledWindow(null,null);
1158 		sw.addWithViewport(treeView);
1159 		notebook.appendPage(sw,"ListView");
1160 
1161 		debug(Tango) Stdout("TestWindow.testList END").newline;
1162 	}
1163 
1164 	void testDelete(Notebook notebook)
1165 	{
1166 //		ulong l = 0;
1167 //		while(true)
1168 //		{
1169 //			int i =0;
1170 //			while(i<1 )
1171 //			{
1172 //				//Button b = new Button("Button");
1173 //				Drawable d = getDrawable();
1174 //				delete d;
1175 //				++i;
1176 //			}
1177 //			++l;
1178 //			printf("testDelete count = %d\n\0",l*i);
1179 //		}
1180 
1181 	}
1182 
1183 	void gtkDemo(Notebook notebook)
1184 	{
1185 		debug(Tango) Stdout("TestWindow.gtkDemo 1").newline;
1186 		void showTTextView(Button button)
1187 		{
1188 			new TTextView();
1189 		}
1190 
1191 		debug(Tango) Stdout("TestWindow.gtkDemo 2").newline;
1192 		void showTEditableCells(Button button)
1193 		{
1194 		//	new TEditableCells();
1195 		}
1196 
1197 		debug(Tango) Stdout("TestWindow.gtkDemo 3").newline;
1198 		ButtonBox vBBox = VButtonBox.createActionBox();
1199 
1200 		debug(Tango) Stdout("TestWindow.gtkDemo 4").newline;
1201 		Button button = new Button("Text View");
1202 		button.addOnClicked(&showTTextView);
1203 		vBBox.packStart(button,false,false,4);
1204 
1205 		debug(Tango) Stdout("TestWindow.gtkDemo 5").newline;
1206 		button = new Button("Editable Cells");
1207 		button.addOnClicked(&showTEditableCells);
1208 		vBBox.packStart(button,false,false,4);
1209 
1210 		debug(Tango) Stdout("TestWindow.gtkDemo 6").newline;
1211 		notebook.appendPage(vBBox,"gtk-demo");
1212 
1213 		debug(Tango) Stdout("TestWindow.gtkDemo 7").newline;
1214 
1215 	}
1216 
1217 }
1218 
1219 private import gtkc.Loader;
1220 
1221 void main(string[] args)
1222 {
1223 	Linker.dumpLoadLibraries();
1224 	Linker.dumpFailedLoads();
1225 
1226 	version(Windows)
1227 	{
1228 		// todo threads are still broken on windows...
1229 		Main.init(args);
1230 	}
1231 	else
1232 	{
1233 		Main.initMultiThread(args);
1234 	}
1235 
1236 	TestWindow window = new TestWindow();
1237 
1238 	debug(1)writefln("before Main.run");
1239 	Main.run();
1240 	debug(1)writefln("after Main.run");
1241 }