001: /*******************************************************************************
002: * Copyright (c) 2003, 2006 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.progress;
011:
012: import java.util.Collections;
013: import java.util.HashSet;
014: import java.util.Set;
015:
016: import org.eclipse.core.runtime.IProgressMonitor;
017: import org.eclipse.core.runtime.IStatus;
018: import org.eclipse.core.runtime.Status;
019: import org.eclipse.core.runtime.jobs.Job;
020: import org.eclipse.swt.SWT;
021: import org.eclipse.swt.graphics.Color;
022: import org.eclipse.swt.widgets.Control;
023: import org.eclipse.ui.progress.WorkbenchJob;
024:
025: /**
026: * The AnimationManager is the class that keeps track of the animation items to
027: * update.
028: */
029: public class AnimationManager {
030: private static AnimationManager singleton;
031:
032: boolean animated = false;
033:
034: private IJobProgressManagerListener listener;
035:
036: IAnimationProcessor animationProcessor;
037:
038: WorkbenchJob animationUpdateJob;
039:
040: public static AnimationManager getInstance() {
041: if (singleton == null) {
042: singleton = new AnimationManager();
043: }
044: return singleton;
045: }
046:
047: /**
048: * Get the background color to be used.
049: *
050: * @param control
051: * The source of the display.
052: * @return Color
053: */
054: static Color getItemBackgroundColor(Control control) {
055: return control.getDisplay().getSystemColor(
056: SWT.COLOR_INFO_BACKGROUND);
057: }
058:
059: AnimationManager() {
060:
061: animationProcessor = new ProgressAnimationProcessor(this );
062:
063: animationUpdateJob = new WorkbenchJob(
064: ProgressMessages.AnimationManager_AnimationStart) {
065:
066: /*
067: * (non-Javadoc)
068: *
069: * @see org.eclipse.ui.progress.UIJob#runInUIThread(org.eclipse.core.runtime.IProgressMonitor)
070: */
071: public IStatus runInUIThread(IProgressMonitor monitor) {
072:
073: if (animated) {
074: animationProcessor.animationStarted();
075: } else {
076: animationProcessor.animationFinished();
077: }
078: return Status.OK_STATUS;
079: }
080: };
081: animationUpdateJob.setSystem(true);
082:
083: listener = getProgressListener();
084: ProgressManager.getInstance().addListener(listener);
085:
086: }
087:
088: /**
089: * Add an item to the list
090: *
091: * @param item
092: */
093: void addItem(final AnimationItem item) {
094: animationProcessor.addItem(item);
095: }
096:
097: /**
098: * Remove an item from the list
099: *
100: * @param item
101: */
102: void removeItem(final AnimationItem item) {
103: animationProcessor.removeItem(item);
104: }
105:
106: /**
107: * Return whether or not the current state is animated.
108: *
109: * @return boolean
110: */
111: boolean isAnimated() {
112: return animated;
113: }
114:
115: /**
116: * Set whether or not the receiver is animated.
117: *
118: * @param boolean
119: */
120: void setAnimated(final boolean bool) {
121: animated = bool;
122: animationUpdateJob.schedule(100);
123: }
124:
125: /**
126: * Dispose the images in the receiver.
127: */
128: void dispose() {
129: setAnimated(false);
130: ProgressManager.getInstance().removeListener(listener);
131: }
132:
133: private IJobProgressManagerListener getProgressListener() {
134: return new IJobProgressManagerListener() {
135: Set jobs = Collections.synchronizedSet(new HashSet());
136:
137: /*
138: * (non-Javadoc)
139: *
140: * @see org.eclipse.ui.internal.progress.IJobProgressManagerListener#addJob(org.eclipse.ui.internal.progress.JobInfo)
141: */
142: public void addJob(JobInfo info) {
143: incrementJobCount(info);
144: }
145:
146: /*
147: * (non-Javadoc)
148: *
149: * @see org.eclipse.ui.internal.progress.IJobProgressManagerListener#refreshJobInfo(org.eclipse.ui.internal.progress.JobInfo)
150: */
151: public void refreshJobInfo(JobInfo info) {
152: int state = info.getJob().getState();
153: if (state == Job.RUNNING) {
154: addJob(info);
155: } else {
156: removeJob(info);
157: }
158: }
159:
160: /*
161: * (non-Javadoc)
162: *
163: * @see org.eclipse.ui.internal.progress.IJobProgressManagerListener#refreshAll()
164: */
165: public void refreshAll() {
166: ProgressManager manager = ProgressManager.getInstance();
167: jobs.clear();
168: setAnimated(false);
169: JobInfo[] currentInfos = manager
170: .getJobInfos(showsDebug());
171: for (int i = 0; i < currentInfos.length; i++) {
172: addJob(currentInfos[i]);
173: }
174: }
175:
176: /*
177: * (non-Javadoc)
178: *
179: * @see org.eclipse.ui.internal.progress.IJobProgressManagerListener#remove(org.eclipse.ui.internal.progress.JobInfo)
180: */
181: public void removeJob(JobInfo info) {
182: decrementJobCount(info.getJob());
183: }
184:
185: /*
186: * (non-Javadoc)
187: *
188: * @see org.eclipse.ui.internal.progress.IJobProgressManagerListener#showsDebug()
189: */
190: public boolean showsDebug() {
191: return false;
192: }
193:
194: private void incrementJobCount(JobInfo info) {
195: //Don't count the animate job itself
196: if (isNotTracked(info)) {
197: return;
198: }
199: if (jobs.isEmpty()) {
200: setAnimated(true);
201: }
202: jobs.add(info.getJob());
203: }
204:
205: /*
206: * Decrement the job count for the job
207: */
208: private void decrementJobCount(Job job) {
209: jobs.remove(job);
210: if (jobs.isEmpty()) {
211: setAnimated(false);
212: }
213: }
214:
215: /**
216: * If this is one of our jobs or not running then don't bother.
217: */
218: private boolean isNotTracked(JobInfo info) {
219: //We always track errors
220: Job job = info.getJob();
221: return job.getState() != Job.RUNNING
222: || animationProcessor.isProcessorJob(job);
223: }
224:
225: /*
226: * (non-Javadoc)
227: *
228: * @see org.eclipse.ui.internal.progress.IJobProgressManagerListener#addGroup(org.eclipse.ui.internal.progress.GroupInfo)
229: */
230: public void addGroup(GroupInfo info) {
231: //Don't care about groups
232: }
233:
234: /*
235: * (non-Javadoc)
236: *
237: * @see org.eclipse.ui.internal.progress.IJobProgressManagerListener#removeGroup(org.eclipse.ui.internal.progress.GroupInfo)
238: */
239: public void removeGroup(GroupInfo group) {
240: //Don't care about groups
241: }
242:
243: /*
244: * (non-Javadoc)
245: *
246: * @see org.eclipse.ui.internal.progress.IJobProgressManagerListener#refreshGroup(org.eclipse.ui.internal.progress.GroupInfo)
247: */
248: public void refreshGroup(GroupInfo info) {
249: //Don't care about groups
250: }
251: };
252: }
253:
254: /**
255: * Get the preferred width for widgets displaying the animation.
256: *
257: * @return int. Return 0 if there is no image data.
258: */
259: int getPreferredWidth() {
260: return animationProcessor.getPreferredWidth();
261: }
262:
263: }
|