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 cairo.Context; 24 private import cairo.ImageSurface; 25 26 private import gtk.VBox; 27 private import gtk.HBox; 28 private import gtk.Box; 29 30 private import gtk.DrawingArea; 31 private import gdk.Event; 32 private import gtk.Widget; 33 private import gtk.ComboBox; 34 private import gtk.ComboBoxText; 35 36 private import gdk.Color; 37 private import gdk.Cairo; 38 39 private import gtk.SpinButton; 40 private import gtk.Adjustment; 41 42 version(Tango) private import tango.io.Stdout; 43 version(Tango) private import tango.stdc.stdio; 44 else private import std.stdio; 45 46 private import glib.Idle; 47 private import glib.Timeout; 48 49 50 /** 51 * This tests the gtkD drawing area widget 52 */ 53 class TestIdle : VBox 54 { 55 56 SpinButton timeoutSpin; 57 58 this() 59 { 60 61 debug(1) 62 { 63 printf("instantiating TestTimeout\n"); 64 } 65 66 super(false,7); 67 68 TestDrawing drawingArea = new TestDrawing(); 69 70 ComboBoxText operators = new ComboBoxText(); 71 operators.appendText("CLEAR"); 72 operators.appendText("SOURCE"); 73 operators.appendText("OVER"); 74 operators.appendText("IN"); 75 operators.appendText("OUT"); 76 operators.appendText("ATOP"); 77 operators.appendText("DEST"); 78 operators.appendText("DEST_OVER"); 79 operators.appendText("DEST_IN"); 80 operators.appendText("DEST_OUT"); 81 operators.appendText("DEST_ATOP"); 82 operators.appendText("XOR"); 83 operators.appendText("ADD"); 84 operators.appendText("SATURATE"); 85 operators.appendText("MULTIPLY"); 86 operators.appendText("SCREEN"); 87 operators.appendText("OVERLAY"); 88 operators.appendText("DARKEN"); 89 operators.appendText("LIGHTEN"); 90 operators.appendText("COLOR_DODGE"); 91 operators.appendText("COLOR_BURN"); 92 operators.appendText("HARD_LIGHT"); 93 operators.appendText("SOFT_LIGHT"); 94 operators.appendText("DIFFERENCE"); 95 operators.appendText("EXCLUSION"); 96 operators.appendText("HSL_HUE"); 97 operators.appendText("HSL_SATURATION"); 98 operators.appendText("HSL_COLOR"); 99 operators.appendText("HSL_LUMINOSITY"); 100 operators.setActive(2); 101 operators.addOnChanged(&drawingArea.onOperatorChanged); 102 103 ComboBoxText callType = new ComboBoxText(); 104 callType.appendText("Idle"); 105 callType.appendText("Timeout"); 106 callType.setActive(1); 107 callType.addOnChanged(&drawingArea.onCallTypeChanged); 108 109 timeoutSpin = new SpinButton(new Adjustment(200.0, 1.0, 1000.0, 1.0, 100.0, 0),1,0); 110 timeoutSpin.addOnValueChanged(&drawingArea.onTimeoutSpinValueChanged); 111 Box controlBox = new HBox(false, 7); 112 113 controlBox.packStart(operators, false, false, 2); 114 controlBox.packStart(callType, false, false, 2); 115 controlBox.packStart(timeoutSpin, false, false, 2); 116 117 packStart(drawingArea,true,true,0); 118 packStart(controlBox,false,false,0); 119 } 120 121 class TestDrawing : DrawingArea 122 { 123 124 Idle mainIdle; 125 Timeout mainTimeout; 126 127 bool continueIdleCallback; 128 CairoOperator operator = CairoOperator.OVER; 129 130 int x =0; 131 int y =0; 132 int xi =1; 133 int yi =1; 134 int totalcount = 0; 135 int count = 0; 136 int width; 137 int height; 138 ImageSurface surface; 139 140 CallType callType = CallType.Timeout; 141 142 this() 143 { 144 setSizeRequest(333,334); 145 146 addOnMap(&onMap); 147 addOnUnmap(&onUnmap); 148 addOnSizeAllocate(&onSizeAllocate); 149 addOnDraw(&onDraw); 150 } 151 152 public void onMap(Widget widget) 153 { 154 debug(trace) version(Tango) Stdout("idle.onMap").newline; 155 else writefln("idle.onMap"); 156 continueIdleCallback = true; 157 x = 0; 158 y = 0; 159 xi = 1; 160 yi = 1; 161 resetCallType(); 162 } 163 164 public void onUnmap(Widget widget) 165 { 166 debug(trace) version(Tango) Stdout("idle.onUnmap").newline; 167 else writefln("idle.onUnmap"); 168 continueIdleCallback = false; 169 } 170 171 void onSizeAllocate(GtkAllocation* allocation, Widget widget) 172 { 173 width = allocation.width; 174 height = allocation.height; 175 x = 0; 176 y = 0; 177 xi = 1; 178 yi = 1; 179 180 surface = ImageSurface.create(CairoFormat.ARGB32, width, height); 181 } 182 183 void onTimeoutSpinValueChanged(SpinButton spin) 184 { 185 if ( callType == CallType.Timeout ) 186 { 187 resetCallType(); 188 } 189 } 190 191 void resetCallType() 192 { 193 if ( mainIdle !is null ) 194 { 195 mainIdle.stop(); 196 } 197 if ( mainTimeout !is null ) 198 { 199 mainTimeout.stop(); 200 } 201 switch ( callType ) 202 { 203 case CallType.Idle: mainIdle = new Idle(&idleCallback); break; 204 case CallType.Timeout: mainTimeout = new Timeout(timeoutSpin.getValueAsInt(),&idleCallback, true); break; 205 default: mainIdle = new Idle(&idleCallback); break; 206 } 207 } 208 209 bool onDraw(Context context, Widget widget) 210 { 211 //Fill the Widget with the surface we are drawing on. 212 context.setSourceSurface(surface, 0, 0); 213 context.paint(); 214 215 return true; 216 } 217 218 bool idleCallback() 219 { 220 Context context = Context.create(surface); 221 context.setLineWidth(1); 222 context.setOperator(operator); 223 224 int xf; 225 int yf; 226 227 if ( xi<0 )xf = x; // going back 228 else xf = width-x; 229 230 if ( yi<0 )yf = y; // going up 231 else yf = height-y; 232 233 if ( xf<yf ) yf=xf; 234 235 //writefln("%s %s -> %s %s (%s %s)\n",x,y,xf,yf,x+yf*xi, y+yf*yi); 236 context.moveTo(x, y); 237 context.lineTo(x+yf*xi, y+yf*yi); 238 context.stroke(); 239 240 x += yf*xi; 241 y += yf*yi; 242 243 if ( x>=width || x<=0 ) xi = -xi; 244 if ( y>=height || y<=0 ) yi = -yi; 245 246 //Redraw the Widget. 247 this.queueDraw(); 248 249 return continueIdleCallback; 250 } 251 252 void onCallTypeChanged(ComboBoxText comboBoxText) 253 { 254 debug(trace) version(Tango) Stdout.format("gcOptions = {}", comboBoxText.getActiveText()).newline; 255 else writefln("gcOptions = %s", comboBoxText.getActiveText()); 256 switch ( comboBoxText.getActiveText() ) 257 { 258 case "Idle": callType = CallType.Idle; break; 259 case "Timeout": callType = CallType.Timeout; break; 260 default: callType = CallType.Timeout; break; 261 } 262 resetCallType(); 263 } 264 265 void onOperatorChanged(ComboBoxText comboBoxText) 266 { 267 debug(trace) version(Tango) Stdout.format("CairoOperator = {}", comboBoxText.getActiveText()).newline; 268 else writefln("CairoOperator = %s", comboBoxText.getActiveText()); 269 switch ( comboBoxText.getActiveText() ) 270 { 271 case "CLEAR": operator = CairoOperator.CLEAR; break; 272 case "SOURCE": operator = CairoOperator.SOURCE; break; 273 case "OVER": operator = CairoOperator.OVER; break; 274 case "IN": operator = CairoOperator.IN; break; 275 case "OUT": operator = CairoOperator.OUT; break; 276 case "ATOP": operator = CairoOperator.ATOP; break; 277 case "DEST": operator = CairoOperator.DEST; break; 278 case "DEST_OVER": operator = CairoOperator.DEST_OVER; break; 279 case "DEST_IN": operator = CairoOperator.DEST_IN; break; 280 case "DEST_OUT": operator = CairoOperator.DEST_OUT; break; 281 case "DEST_ATOP": operator = CairoOperator.DEST_ATOP; break; 282 case "XOR": operator = CairoOperator.XOR; break; 283 case "ADD": operator = CairoOperator.ADD; break; 284 case "SATURATE": operator = CairoOperator.SATURATE; break; 285 case "MULTIPLY": operator = CairoOperator.MULTIPLY; break; 286 case "SCREEN": operator = CairoOperator.SCREEN; break; 287 case "OVERLAY": operator = CairoOperator.OVERLAY; break; 288 case "DARKEN": operator = CairoOperator.DARKEN; break; 289 case "LIGHTEN": operator = CairoOperator.LIGHTEN; break; 290 case "COLOR_DODGE": operator = CairoOperator.COLOR_DODGE; break; 291 case "COLOR_BURN": operator = CairoOperator.COLOR_BURN; break; 292 case "HARD_LIGHT": operator = CairoOperator.HARD_LIGHT; break; 293 case "SOFT_LIGHT": operator = CairoOperator.SOFT_LIGHT; break; 294 case "DIFFERENCE": operator = CairoOperator.DIFFERENCE; break; 295 case "EXCLUSION": operator = CairoOperator.EXCLUSION; break; 296 case "HSL_HUE": operator = CairoOperator.HSL_HUE; break; 297 case "HSL_SATURATION": operator = CairoOperator.HSL_SATURATION; break; 298 case "HSL_COLOR": operator = CairoOperator.HSL_COLOR; break; 299 case "HSL_LUMINOSITY": operator = CairoOperator.HSL_LUMINOSITY; break; 300 default: operator = CairoOperator.OVER; break; 301 } 302 } 303 } 304 } 305 306 enum CallType 307 { 308 Idle, 309 Timeout, 310 } 311