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 TestIdle;
20 
21 //debug = trace
22 
23 private import gtk.VBox;
24 private import gtk.HBox;
25 private import gtk.Box;
26 
27 private import gtk.DrawingArea;
28 private import gdk.Event;
29 private import gtk.Widget;
30 private import gtk.ComboBox;
31 
32 private import gdk.Color;
33 private import gdk.Drawable;
34 private import gdk.GC;
35 
36 private import gtk.SpinButton;
37 private import gtk.Adjustment;
38 
39 version(Tango) private import tango.io.Stdout;
40 version(Tango) private import tango.stdc.stdio;
41 else private import std.stdio;
42 
43 private import gtk.Idle;
44 private import gtk.Timeout;
45 
46 
47 /**
48  * This tests the gtkD drawing area widget
49  */
50 class TestIdle : VBox
51 {
52 
53 	SpinButton timeoutSpin;
54 
55 	this()
56 	{
57 
58 		debug(1)
59 		{
60 			printf("instantiating TestTimeout\n");
61 		}
62 
63 		super(false,7);
64 
65 		TestDrawing drawingArea = new TestDrawing();
66 
67 		ComboBox gcOptions = new ComboBox();
68 		gcOptions.appendText("GC COPY");
69 		gcOptions.appendText("GC INVERT");
70 		gcOptions.appendText("GC XOR");
71 		gcOptions.appendText("GC CLEAR");
72 		gcOptions.appendText("GC AND");
73 		gcOptions.appendText("GC AND_REVERSE");
74 		gcOptions.appendText("GC AND_INVERT");
75 		gcOptions.appendText("GC NOOP");
76 		gcOptions.appendText("GC OR");
77 		gcOptions.appendText("GC EQUIV");
78 		gcOptions.appendText("GC OR_REVERSE");
79 		gcOptions.appendText("GC COPY_INVERT");
80 		gcOptions.appendText("GC OR_INVERT");
81 		gcOptions.appendText("GC NAND");
82 		gcOptions.appendText("GC NOR");
83 		gcOptions.appendText("GC SET");
84 		gcOptions.setActive(1);
85 		gcOptions.addOnChanged(&drawingArea.onCGOptionsChanged);
86 
87 		ComboBox callType = new ComboBox();
88 		callType.appendText("Idle");
89 		callType.appendText("Timeout");
90 		callType.setActive(1);
91 		callType.addOnChanged(&drawingArea.onCallTypeChanged);
92 
93 		timeoutSpin = new SpinButton(new Adjustment(200.0, 1.0, 1000.0, 1.0, 100.0, 0),1,0);
94 		timeoutSpin.addOnValueChanged(&drawingArea.onTimeoutSpinValueChanged);
95 		Box controlBox = new HBox(false, 7);
96 
97 		controlBox.packStart(gcOptions, false, false, 2);
98 		controlBox.packStart(callType, false, false, 2);
99 		controlBox.packStart(timeoutSpin, false, false, 2);
100 
101 		packStart(drawingArea,true,true,0);
102 		packStart(controlBox,false,false,0);
103 	}
104 
105 	class TestDrawing : DrawingArea
106 	{
107 
108 		Idle mainIdle;
109 		Timeout mainTimeout;
110 
111 		bool continueIdleCallback;
112 		int gcFunction = 0;
113 		Color paintColor;
114 		Color black;
115 
116 		int x =0;
117 		int y =0;
118 		int xi =1;
119 		int yi =1;
120 		int totalcount = 0;
121 		int count = 0;
122 		int width;
123 		int height;
124 		//Color color = new Color();
125 		Drawable drawable;
126 		GC gc;
127 
128 		int callType = 1;	// ue 0 for Idle 1 for Timeout
129 
130 		this()
131 		{
132 			setSizeRequest(333,334);
133 
134 			paintColor = new Color(cast(ubyte)0,cast(ubyte)0,cast(ubyte)0);
135 			black = new Color(cast(ubyte)0,cast(ubyte)0,cast(ubyte)0);
136 
137 			addOnRealize(&onRealize);
138 			//addOnExpose(&exposeCallback);
139 			addOnMap(&onMap);
140 			addOnUnmap(&onUnmap);
141 			//addOnMotionNotify(&onMotionNotify);
142 			addOnSizeAllocate(&onSizeAllocate);
143 			//addOnButtonPress(&onButtonPress);
144 			//addOnButtonRelease(&onButtonRelease);
145 
146 		}
147 
148 		public void onRealize(Widget widget)
149 		{
150 			//printf("TestTimeout.realizeCallback\n");
151 			drawable = getWindow();
152 			gc = new GC(drawable);
153 			gc.setFunction(GdkFunction.INVERT);
154 			//return false;
155 		}
156 
157 		public void onMap(Widget widget)
158 		{
159 			debug(trace) version(Tango) Stdout("idle.onMap").newline;
160 			else writefln("idle.onMap");
161 			continueIdleCallback = true;
162 			x = 0;
163 			y = 0;
164 			xi = 1;
165 			yi = 1;
166 			resetCallType();
167 		}
168 
169 		public void onUnmap(Widget widget)
170 		{
171 			debug(trace) version(Tango) Stdout("idle.onUnmap").newline;
172 			else writefln("idle.onUnmap");
173 			continueIdleCallback = false;
174 		}
175 
176 		void onSizeAllocate(GtkAllocation* allocation, Widget widget)
177 		{
178 			width = allocation.width;
179 			height = allocation.height;
180 			x = 0;
181 			y = 0;
182 			xi = 1;
183 			yi = 1;
184 		}
185 
186 		void onTimeoutSpinValueChanged(SpinButton spin)
187 		{
188 			if ( callType == 1 )
189 			{
190 				resetCallType();
191 			}
192 		}
193 
194 		void resetCallType()
195 		{
196 			if ( mainIdle !is null )
197 			{
198 				mainIdle.stop();
199 			}
200 			if ( mainTimeout !is null )
201 			{
202 				mainTimeout.stop();
203 			}
204 			switch ( callType )
205 			{
206 				case 0: mainIdle = new Idle(&idleCallback); break;
207 				case 1: mainTimeout = new Timeout(timeoutSpin.getValueAsInt(),&idleCallback, true); break;
208 				default: mainIdle = new Idle(&idleCallback); break;
209 			}
210 		}
211 
212 		/**
213 		 * This will be called from the expose event call back.
214 		 * \bug this is called on get or loose focus - review
215 		 */
216 //		public bit exposeCallback(Widget widget)
217 //		{
218 //			//printf("testWindow.exposed ----------------------------- \n");
219 //			//drawPoins(widget.getDrawable());
220 //			return false;
221 //		}
222 
223 		bool idleCallback()
224 		{
225 
226 			//printf("%d %d\n",width,height);
227 			//drawable.drawPoint(gc,x,y);
228 
229 			int xf;
230 			int yf;
231 
232 			if ( xi<0 )xf = x;	// going back
233 			else xf = width-x;
234 
235 			if ( yi<0 )yf = y;	// going up
236 			else yf = height-y;
237 
238 			if ( xf<yf ) yf=xf;
239 
240 			//writefln("%s %s -> %s %s (%s %s)\n",x,y,xf,yf,x+yf*xi, y+yf*yi);
241 			drawable.drawLine(gc,x,y, x+yf*xi, y+yf*yi);
242 
243 			x += yf*xi;
244 			y += yf*yi;
245 
246 			if ( x>=width || x<=0 ) xi = -xi;
247 			if ( y>=height || y<=0 ) yi = -yi;
248 
249 			return continueIdleCallback;
250 		}
251 
252 		void onCallTypeChanged(ComboBox comboBox)
253 		{
254 			debug(trace) version(Tango) Stdout.format("gcOptions = {}", comboBox.getActiveText()).newline;
255 			else writefln("gcOptions = %s", comboBox.getActiveText());
256 			switch ( comboBox.getActiveText() )
257 			{
258 				case "Idle": callType = 0; break;
259 				case "Timeout": callType = 1; break;
260 				default: callType = 0; break;
261 			}
262 			resetCallType();
263 		}
264 
265 		void onCGOptionsChanged(ComboBox comboBox)
266 		{
267 			debug(trace) version(Tango) Stdout.format("gcOptions = {}", comboBox.getActiveText()).newline;
268 			else writefln("gcOptions = %s", comboBox.getActiveText());
269 			switch ( comboBox.getActiveText() )
270 			{
271 				case "GC COPY":			gc.setFunction(GdkFunction.COPY);		break;
272 				case "GC INVERT":		gc.setFunction(GdkFunction.INVERT);		break;
273 				case "GC XOR":			gc.setFunction(GdkFunction.XOR);		break;
274 				case "GC CLEAR":		gc.setFunction(GdkFunction.CLEAR);		break;
275 				case "GC AND":			gc.setFunction(GdkFunction.AND);		break;
276 				case "GC AND_REVERSE":	gc.setFunction(GdkFunction.AND_REVERSE);break;
277 				case "GC AND_INVERT":	gc.setFunction(GdkFunction.AND_INVERT);	break;
278 				case "GC NOOP":			gc.setFunction(GdkFunction.NOOP);		break;
279 				case "GC OR":			gc.setFunction(GdkFunction.OR);			break;
280 				case "GC EQUIV":		gc.setFunction(GdkFunction.EQUIV);		break;
281 				case "GC OR_REVERSE":	gc.setFunction(GdkFunction.OR_REVERSE);	break;
282 				case "GC COPY_INVERT":	gc.setFunction(GdkFunction.COPY_INVERT);break;
283 				case "GC OR_INVERT":	gc.setFunction(GdkFunction.OR_INVERT);	break;
284 				case "GC NAND":			gc.setFunction(GdkFunction.NAND);		break;
285 				case "GC NOR":			gc.setFunction(GdkFunction.NOR);		break;
286 				case "GC SET":			gc.setFunction(GdkFunction.SET);		break;
287 				default:				gc.setFunction(GdkFunction.INVERT);		break;
288 			}
289 		}
290 
291 	}
292 
293 }