1 11 package org.eclipse.ui.internal; 12 13 import org.eclipse.core.runtime.IProgressMonitor; 14 import org.eclipse.core.runtime.IStatus; 15 import org.eclipse.core.runtime.Status; 16 import org.eclipse.core.runtime.jobs.Job; 17 import org.eclipse.jface.preference.IPreferenceStore; 18 import org.eclipse.jface.util.Geometry; 19 import org.eclipse.swt.graphics.GC; 20 import org.eclipse.swt.graphics.Image; 21 import org.eclipse.swt.graphics.Rectangle; 22 import org.eclipse.swt.widgets.Control; 23 import org.eclipse.swt.widgets.Display; 24 import org.eclipse.swt.widgets.Shell; 25 import org.eclipse.ui.IWorkbenchPreferenceConstants; 26 import org.eclipse.ui.internal.util.PrefUtil; 27 28 35 public class RectangleAnimation extends Job { 36 private static class AnimationFeedbackFactory { 37 47 private static final int IMAGE_ANIMATION_THRESHOLD = 25; private static final int IMAGE_ANIMATION_TEST_LOOP_COUNT = 20; 50 52 public static double getCaptureSpeed(Shell wb) { 53 Rectangle bb = wb.getBounds(); 55 Image backingStore = new Image(wb.getDisplay(), bb); 56 GC gc = new GC(wb); 57 58 long startTime = System.currentTimeMillis(); 60 for (int i = 0; i < IMAGE_ANIMATION_TEST_LOOP_COUNT; i++) 61 gc.copyArea(backingStore, bb.x, bb.y); 62 gc.dispose(); 63 long endTime = System.currentTimeMillis(); 64 65 double fps = IMAGE_ANIMATION_TEST_LOOP_COUNT / ((endTime-startTime) / 1000.0); 67 double pps = fps * (bb.width*bb.height*4); System.out.println("FPS: " + fps + " Bytes/sec: " + (long)pps); return fps; 70 } 71 72 public boolean useImageAnimations(Shell wb) { 73 return getCaptureSpeed(wb) >= IMAGE_ANIMATION_THRESHOLD; 74 } 75 76 public static DefaultAnimationFeedback createAnimationRenderer(Shell parentShell) { 77 return new DefaultAnimationFeedback(); 90 } 91 } 92 93 public static final int TICK_TIMER = 1; 95 public static final int FRAME_COUNT = 2; 96 97 private Display display; 99 100 private boolean enableAnimations; 101 private int timingStyle = TICK_TIMER; 102 private int duration; 103 104 private DefaultAnimationFeedback feedbackRenderer; 106 private long stepCount; 107 private long frameCount; 108 private long startTime; 109 private long curTime; 110 private long prevTime; 111 112 private boolean done() { return amount() >= 1.0; } 114 115 public static Rectangle interpolate(Rectangle start, Rectangle end, 116 double amount) { 117 double initialWeight = 1.0 - amount; 118 119 Rectangle result = new Rectangle((int) (start.x * initialWeight + end.x 120 * amount), (int) (start.y * initialWeight + end.y * amount), 121 (int) (start.width * initialWeight + end.width * amount), 122 (int) (start.height * initialWeight + end.height * amount)); 123 124 return result; 125 } 126 127 private Runnable animationStep = new Runnable () { 129 130 public void run() { 131 prevTime = curTime; 133 curTime = System.currentTimeMillis(); 134 135 if (curTime != prevTime) { 137 clockTick(); 138 } 139 140 if (isUpdateStep()) { 141 updateDisplay(); 142 frameCount++; 143 } 144 145 stepCount++; 146 } 147 148 }; 149 150 165 public RectangleAnimation(Shell parentShell, Rectangle start, 166 Rectangle end, int duration) { 167 super(WorkbenchMessages.RectangleAnimation_Animating_Rectangle); 168 169 IPreferenceStore preferenceStore = PrefUtil.getAPIPreferenceStore(); 171 enableAnimations = preferenceStore.getBoolean(IWorkbenchPreferenceConstants.ENABLE_ANIMATIONS); 172 173 if (!enableAnimations) { 174 return; 175 } 176 177 display = parentShell.getDisplay(); 179 this.duration = duration; 180 181 setSystem(true); 183 184 feedbackRenderer = AnimationFeedbackFactory.createAnimationRenderer(parentShell); 186 187 feedbackRenderer.initialize(parentShell, start, end); 189 190 stepCount = 0; 192 curTime = startTime = System.currentTimeMillis(); 194 } 195 196 public RectangleAnimation(Shell parentShell, Rectangle start, Rectangle end) { 197 this(parentShell, start, end, 400); 198 } 199 200 public void addStartRect(Rectangle rect) { 201 if (feedbackRenderer != null) 202 feedbackRenderer.addStartRect(rect); 203 } 204 205 public void addEndRect(Rectangle rect) { 206 if (feedbackRenderer != null) 207 feedbackRenderer.addEndRect(rect); 208 } 209 210 public void addStartRect(Control ctrl) { 211 Rectangle ctrlBounds = ctrl.getBounds(); 212 Rectangle startRect = Geometry.toDisplay(ctrl.getParent(), ctrlBounds); 213 addStartRect(startRect); 214 } 215 216 public void addEndRect(Control ctrl) { 217 Rectangle ctrlBounds = ctrl.getBounds(); 218 Rectangle endRect = Geometry.toDisplay(ctrl.getParent(), ctrlBounds); 219 addEndRect(endRect); 220 } 221 222 225 protected void clockTick() { 226 } 227 228 231 protected boolean isUpdateStep() { 232 switch (timingStyle) { 233 case TICK_TIMER: 234 return prevTime != curTime; 235 236 case FRAME_COUNT: 237 return true; 238 } 239 240 return false; 241 } 242 243 private double amount() { 244 double amount = 0.0; 245 246 switch (timingStyle) { 247 case TICK_TIMER: 248 amount = (double) (curTime - startTime) / (double) duration; 249 break; 250 251 case FRAME_COUNT: 252 amount = (double)frameCount / (double)duration; 253 } 254 255 if (amount > 1.0) 256 amount = 1.0; 257 258 return amount; 259 } 260 261 264 protected void updateDisplay() { 265 feedbackRenderer.renderStep(amount()); 266 } 267 268 271 protected IStatus run(IProgressMonitor monitor) { 272 273 if (!enableAnimations || feedbackRenderer == null) { 275 return Status.OK_STATUS; 276 } 277 278 boolean isEmpty = feedbackRenderer.getStartRects().size() == 0; 280 if (isEmpty) { 281 return Status.OK_STATUS; 282 } 283 284 display.syncExec(new Runnable () { 286 public void run() { 287 feedbackRenderer.jobInit(); 288 } 289 }); 290 291 curTime = startTime = System.currentTimeMillis(); 293 294 while (!done()) { 295 display.syncExec(animationStep); 296 Thread.yield(); 298 } 299 300 display.syncExec(new Runnable () { 303 public void run() { 304 feedbackRenderer.dispose(); 305 } 306 }); 307 308 return Status.OK_STATUS; 309 } 310 } 311 | Popular Tags |