/******************************************************************************* * Copyright (c) 2007 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation ******************************************************************************/ package org.eclipse.ui.internal; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.IWorkbenchPreferenceConstants; import org.eclipse.ui.internal.util.PrefUtil; /** * This job creates an Animation Engine that uses an Animation Feedback to render * the animation. To begin the animation, instantiate this * object then call schedule(). * @since 3.3 * */ public class AnimationEngine extends Job { public static final int TICK_TIMER = 1; public static final int unlimitedDuration = -1; private boolean enableAnimations; private Display display; private AnimationFeedbackBase feedbackRenderer; private long startTime; private long curTime; private long prevTime; private int timingStyle = TICK_TIMER; private long frameCount; private int duration; private long stepCount; public static final int FRAME_COUNT = 2; private boolean stopAnimating = false; private long sleepAmount; public AnimationEngine(AnimationFeedbackBase animationFeedback, int durationIn) { this(animationFeedback, durationIn, 0); } /** * Creates an Animation that will run for the given number of milliseconds. * * @param animationFeedback provides renderStep(), initialize() and jobInit() methods * @param durationIn number of milliseconds over which the animation will run * @param sleepAmountIn number of milliseconds to slow/delay the animation */ public AnimationEngine(AnimationFeedbackBase animationFeedback, int durationIn, long sleepAmountIn) { super(WorkbenchMessages.RectangleAnimation_Animating_Rectangle); sleepAmount = sleepAmountIn; feedbackRenderer = animationFeedback; duration = durationIn; // if animations aren't on this is a NO-OP IPreferenceStore preferenceStore = PrefUtil.getAPIPreferenceStore(); enableAnimations = preferenceStore .getBoolean(IWorkbenchPreferenceConstants.ENABLE_ANIMATIONS); if (!enableAnimations) { return; } stopAnimating = false; // Capture parameters display = feedbackRenderer.getAnimationShell().getDisplay(); // Don't show the job in monitors setSystem(true); // Set it up feedbackRenderer.initialize(this); // Set the animation's initial state stepCount = 0; curTime = startTime = System.currentTimeMillis(); } /** * @return The current renderer */ public AnimationFeedbackBase getFeedback() { return feedbackRenderer; } private Runnable animationStep = new Runnable() { public void run() { // Capture time prevTime = curTime; curTime = System.currentTimeMillis(); if (isUpdateStep()) { updateDisplay(); frameCount++; } stepCount++; } }; protected void updateDisplay() { feedbackRenderer.renderStep(this); } protected boolean isUpdateStep() { if (duration == unlimitedDuration) { return true; } switch (timingStyle) { case TICK_TIMER: return prevTime != curTime; //for testing purposes case FRAME_COUNT: return true; } return false; } private boolean done() { return amount() >= 1.0; } public double amount() { if (duration == unlimitedDuration) { return 0; } double amount = 0.0; switch (timingStyle) { case TICK_TIMER: amount = (double) (curTime - startTime) / (double) duration; break; // For testing purposes case FRAME_COUNT: amount = (double) frameCount / (double) duration; } if (amount > 1.0) amount = 1.0; return amount; } protected IStatus run(IProgressMonitor monitor) { // TODO Auto-generated method stub // We use preferece value to indicate that the animation should be skipped on this platform. if (!enableAnimations) { return Status.OK_STATUS; } // We're starting, initialize display.syncExec(new Runnable() { public void run() { // 'jobInit' returns 'false' if it doesn't want to run... stopAnimating = !feedbackRenderer.jobInit(AnimationEngine.this); } }); // Only start the animation timer -after- we've initialized curTime = startTime = System.currentTimeMillis(); while (!done() && !stopAnimating) { display.syncExec(animationStep); // Don't pin the CPU try { Thread.sleep(sleepAmount); } catch (InterruptedException e) { // TODO Auto-generated catch block //e.printStackTrace(); } } // We're done, clean up display.syncExec(new Runnable() { public void run() { feedbackRenderer.dispose(); } }); return Status.OK_STATUS; } public void cancelAnimation() { stopAnimating = true; } public long getFrameCount() { return frameCount; } }