1 /******************************************************************************* 2 * Copyright (c) 2000, 2008 IBM Corporation and others. 3 * All rights reserved. This program and the accompanying materials 4 * are made available under the terms of the Eclipse Public License v1.0 5 * which accompanies this distribution, and is available at 6 * http://www.eclipse.org/legal/epl-v10.html 7 * 8 * Contributors: 9 * IBM Corporation - initial API and implementation 10 * Port to the D programming language: 11 * Frank Benoit <benoit@tionex.de> 12 *******************************************************************************/ 13 module org.eclipse.swt.custom.AnimatedProgress; 14 15 16 import org.eclipse.swt.SWT; 17 import org.eclipse.swt.SWTException; 18 import org.eclipse.swt.events.ControlAdapter; 19 import org.eclipse.swt.events.ControlEvent; 20 import org.eclipse.swt.events.DisposeEvent; 21 import org.eclipse.swt.events.DisposeListener; 22 import org.eclipse.swt.events.PaintEvent; 23 import org.eclipse.swt.events.PaintListener; 24 import org.eclipse.swt.graphics.Color; 25 import org.eclipse.swt.graphics.GC; 26 import org.eclipse.swt.graphics.Point; 27 import org.eclipse.swt.graphics.Rectangle; 28 import org.eclipse.swt.widgets.Canvas; 29 import org.eclipse.swt.widgets.Composite; 30 import org.eclipse.swt.widgets.Display; 31 import java.lang.Runnable; 32 33 /** 34 * A control for showing progress feedback for a long running operation. 35 * 36 * @deprecated As of Eclipse 2.1, use ProgressBar with the style SWT.INDETERMINATE 37 * 38 * <dl> 39 * <dt><b>Styles:</b><dd>VERTICAL, HORIZONTAL, BORDER 40 * </dl> 41 * 42 * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a> 43 */ 44 public class AnimatedProgress : Canvas { 45 46 alias Canvas.computeSize computeSize; 47 48 static const int SLEEP = 70; 49 static const int DEFAULT_WIDTH = 160; 50 static const int DEFAULT_HEIGHT = 18; 51 bool active = false; 52 bool showStripes = false; 53 int value; 54 int orientation = SWT.HORIZONTAL; 55 bool showBorder = false; 56 57 /** 58 * Constructs a new instance of this class given its parent 59 * and a style value describing its behavior and appearance. 60 * <p> 61 * The style value is either one of the style constants defined in 62 * class <code>SWT</code> which is applicable to instances of this 63 * class, or must be built by <em>bitwise OR</em>'ing together 64 * (that is, using the <code>int</code> "|" operator) two or more 65 * of those <code>SWT</code> style constants. The class description 66 * lists the style constants that are applicable to the class. 67 * Style bits are also inherited from superclasses. 68 * </p> 69 * 70 * @param parent a widget which will be the parent of the new instance (cannot be null) 71 * @param style the style of widget to construct 72 * 73 * @exception IllegalArgumentException <ul> 74 * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> 75 * </ul> 76 * @exception SWTException <ul> 77 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> 78 * </ul> 79 * 80 * @see SWT#VERTICAL 81 * @see SWT#HORIZONTAL 82 * @see SWT#BORDER 83 * @see #getStyle() 84 */ 85 public this(Composite parent, int style) { 86 super(parent, checkStyle(style)); 87 88 if ((style & SWT.VERTICAL) !is 0) { 89 orientation = SWT.VERTICAL; 90 } 91 showBorder = (style & SWT.BORDER) !is 0; 92 93 addControlListener(new class() ControlAdapter { 94 override 95 public void controlResized(ControlEvent e) { 96 redraw(); 97 } 98 }); 99 addPaintListener(new class() PaintListener { 100 public void paintControl(PaintEvent e) { 101 paint(e); 102 } 103 }); 104 addDisposeListener(new class() DisposeListener { 105 public void widgetDisposed(DisposeEvent e){ 106 stop(); 107 } 108 }); 109 } 110 private static int checkStyle (int style) { 111 int mask = SWT.NONE; 112 return style & mask; 113 } 114 /** 115 * Stop the animation if it is not already stopped and 116 * reset the presentation to a blank appearance. 117 * 118 * @exception SWTException <ul> 119 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 120 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 121 * </ul> 122 */ 123 public void clear(){ 124 synchronized { 125 checkWidget(); 126 if (active) stop(); 127 showStripes = false; 128 redraw(); 129 } 130 } 131 public override Point computeSize(int wHint, int hHint, bool changed) { 132 checkWidget(); 133 Point size = null; 134 if (orientation is SWT.HORIZONTAL) { 135 size = new Point(DEFAULT_WIDTH, DEFAULT_HEIGHT); 136 } else { 137 size = new Point(DEFAULT_HEIGHT, DEFAULT_WIDTH); 138 } 139 if (wHint !is SWT.DEFAULT) size.x = wHint; 140 if (hHint !is SWT.DEFAULT) size.y = hHint; 141 142 return size; 143 } 144 private void drawBevelRect(GC gc, int x, int y, int w, int h, Color topleft, Color bottomright) { 145 gc.setForeground(topleft); 146 gc.drawLine(x, y, x+w-1, y); 147 gc.drawLine(x, y, x, y+h-1); 148 149 gc.setForeground(bottomright); 150 gc.drawLine(x+w, y, x+w, y+h); 151 gc.drawLine(x, y+h, x+w, y+h); 152 } 153 void paint(PaintEvent event) { 154 GC gc = event.gc; 155 Display disp= getDisplay(); 156 157 Rectangle rect= getClientArea(); 158 gc.fillRectangle(rect); 159 if (showBorder) { 160 drawBevelRect(gc, rect.x, rect.y, rect.width-1, rect.height-1, 161 disp.getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW), 162 disp.getSystemColor(SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW)); 163 } 164 165 paintStripes(gc); 166 } 167 void paintStripes(GC gc) { 168 169 if (!showStripes) return; 170 171 Rectangle rect= getClientArea(); 172 // Subtracted border painted by paint. 173 rect = new Rectangle(rect.x+2, rect.y+2, rect.width-4, rect.height-4); 174 175 gc.setLineWidth(2); 176 gc.setClipping(rect); 177 Color color = getDisplay().getSystemColor(SWT.COLOR_LIST_SELECTION); 178 gc.setBackground(color); 179 gc.fillRectangle(rect); 180 gc.setForeground(this.getBackground()); 181 int step = 12; 182 int foregroundValue = value is 0 ? step - 2 : value - 2; 183 if (orientation is SWT.HORIZONTAL) { 184 int y = rect.y - 1; 185 int w = rect.width; 186 int h = rect.height + 2; 187 for (int i= 0; i < w; i+= step) { 188 int x = i + foregroundValue; 189 gc.drawLine(x, y, x, h); 190 } 191 } else { 192 int x = rect.x - 1; 193 int w = rect.width + 2; 194 int h = rect.height; 195 196 for (int i= 0; i < h; i+= step) { 197 int y = i + foregroundValue; 198 gc.drawLine(x, y, w, y); 199 } 200 } 201 202 if (active) { 203 value = (value + 2) % step; 204 } 205 } 206 /** 207 * Start the animation. 208 * 209 * @exception SWTException <ul> 210 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 211 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 212 * </ul> 213 */ 214 public void start() { 215 synchronized { 216 checkWidget(); 217 if (active) return; 218 219 active = true; 220 showStripes = true; 221 222 Display display = getDisplay(); 223 Runnable [] timer = new Runnable [1]; 224 225 timer [0] = new class( display, timer ) Runnable { 226 Display disp; 227 Runnable [] runs; 228 this( Display disp, Runnable[] runs ){ 229 this.disp = disp; 230 this.runs = runs; 231 } 232 public void run () { 233 if (!active) return; 234 GC gc = new GC(this.outer); 235 paintStripes(gc); 236 gc.dispose(); 237 disp.timerExec (SLEEP, runs [0]); 238 } 239 }; 240 display.timerExec (SLEEP, timer [0]); 241 } 242 } 243 /** 244 * Stop the animation. Freeze the presentation at its current appearance. 245 */ 246 public void stop() { 247 synchronized { 248 //checkWidget(); 249 active = false; 250 } 251 } 252 }