001: /*******************************************************************************
002: * Copyright (c) 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: ******************************************************************************/package org.eclipse.ui.internal;
011:
012: import org.eclipse.core.runtime.IProgressMonitor;
013: import org.eclipse.core.runtime.IStatus;
014: import org.eclipse.core.runtime.Status;
015: import org.eclipse.core.runtime.jobs.Job;
016: import org.eclipse.jface.preference.IPreferenceStore;
017: import org.eclipse.swt.widgets.Display;
018: import org.eclipse.ui.IWorkbenchPreferenceConstants;
019: import org.eclipse.ui.internal.util.PrefUtil;
020:
021: /**
022: * This job creates an Animation Engine that uses an Animation Feedback to render
023: * the animation. To begin the animation, instantiate this
024: * object then call schedule().
025: * @since 3.3
026: *
027: */
028: public class AnimationEngine extends Job {
029: public static final int TICK_TIMER = 1;
030: public static final int unlimitedDuration = -1;
031: private boolean enableAnimations;
032: private Display display;
033: private AnimationFeedbackBase feedbackRenderer;
034: private long startTime;
035: private long curTime;
036: private long prevTime;
037: private int timingStyle = TICK_TIMER;
038: private long frameCount;
039: private int duration;
040: private long stepCount;
041: public static final int FRAME_COUNT = 2;
042: private boolean stopAnimating = false;
043: private long sleepAmount;
044:
045: public AnimationEngine(AnimationFeedbackBase animationFeedback,
046: int durationIn) {
047: this (animationFeedback, durationIn, 0);
048: }
049:
050: /**
051: * Creates an Animation that will run for the given number of milliseconds.
052: *
053: * @param animationFeedback provides renderStep(), initialize() and jobInit() methods
054: * @param durationIn number of milliseconds over which the animation will run
055: * @param sleepAmountIn number of milliseconds to slow/delay the animation
056: */
057: public AnimationEngine(AnimationFeedbackBase animationFeedback,
058: int durationIn, long sleepAmountIn) {
059: super (WorkbenchMessages.RectangleAnimation_Animating_Rectangle);
060: sleepAmount = sleepAmountIn;
061: feedbackRenderer = animationFeedback;
062: duration = durationIn;
063:
064: // if animations aren't on this is a NO-OP
065: IPreferenceStore preferenceStore = PrefUtil
066: .getAPIPreferenceStore();
067: enableAnimations = preferenceStore
068: .getBoolean(IWorkbenchPreferenceConstants.ENABLE_ANIMATIONS);
069: if (!enableAnimations) {
070: return;
071: }
072:
073: stopAnimating = false;
074:
075: // Capture parameters
076: display = feedbackRenderer.getAnimationShell().getDisplay();
077: // Don't show the job in monitors
078: setSystem(true);
079:
080: // Set it up
081: feedbackRenderer.initialize(this );
082:
083: // Set the animation's initial state
084: stepCount = 0;
085: curTime = startTime = System.currentTimeMillis();
086:
087: }
088:
089: /**
090: * @return The current renderer
091: */
092: public AnimationFeedbackBase getFeedback() {
093: return feedbackRenderer;
094: }
095:
096: private Runnable animationStep = new Runnable() {
097:
098: public void run() {
099: // Capture time
100: prevTime = curTime;
101: curTime = System.currentTimeMillis();
102:
103: if (isUpdateStep()) {
104: updateDisplay();
105: frameCount++;
106: }
107: stepCount++;
108: }
109:
110: };
111:
112: protected void updateDisplay() {
113: feedbackRenderer.renderStep(this );
114: }
115:
116: protected boolean isUpdateStep() {
117: if (duration == unlimitedDuration) {
118: return true;
119: }
120:
121: switch (timingStyle) {
122: case TICK_TIMER:
123: return prevTime != curTime;
124: //for testing purposes
125: case FRAME_COUNT:
126: return true;
127: }
128:
129: return false;
130: }
131:
132: private boolean done() {
133: return amount() >= 1.0;
134: }
135:
136: public double amount() {
137: if (duration == unlimitedDuration) {
138: return 0;
139: }
140: double amount = 0.0;
141: switch (timingStyle) {
142: case TICK_TIMER:
143: amount = (double) (curTime - startTime) / (double) duration;
144: break;
145:
146: // For testing purposes
147: case FRAME_COUNT:
148: amount = (double) frameCount / (double) duration;
149: }
150:
151: if (amount > 1.0)
152: amount = 1.0;
153:
154: return amount;
155: }
156:
157: protected IStatus run(IProgressMonitor monitor) {
158: // TODO Auto-generated method stub
159:
160: // We use preferece value to indicate that the animation should be skipped on this platform.
161: if (!enableAnimations) {
162: return Status.OK_STATUS;
163: }
164:
165: // We're starting, initialize
166: display.syncExec(new Runnable() {
167: public void run() {
168: // 'jobInit' returns 'false' if it doesn't want to run...
169: stopAnimating = !feedbackRenderer
170: .jobInit(AnimationEngine.this );
171: }
172: });
173:
174: // Only start the animation timer -after- we've initialized
175: curTime = startTime = System.currentTimeMillis();
176:
177: while (!done() && !stopAnimating) {
178: display.syncExec(animationStep);
179: // Don't pin the CPU
180: try {
181: Thread.sleep(sleepAmount);
182: } catch (InterruptedException e) {
183: // TODO Auto-generated catch block
184: //e.printStackTrace();
185: }
186: }
187:
188: // We're done, clean up
189: display.syncExec(new Runnable() {
190: public void run() {
191: feedbackRenderer.dispose();
192: }
193: });
194:
195: return Status.OK_STATUS;
196: }
197:
198: public void cancelAnimation() {
199: stopAnimating = true;
200: }
201:
202: public long getFrameCount() {
203: return frameCount;
204: }
205: }
|