/*******************************************************************************
* Copyright (c) 2003, 2015 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
* Sebastian Sampaoli <seba.sampaoli@gmail.com> Bug - 428355
*******************************************************************************/
package org.eclipse.e4.ui.progress.internal;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.inject.Singleton;
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.e4.core.di.annotations.Creatable;
import org.eclipse.e4.ui.progress.UIJob;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.widgets.Control;
/**
* The AnimationManager is the class that keeps track of the animation items to
* update.
*/
@Creatable
@Singleton
public class AnimationManager {
boolean animated = false;
private IJobProgressManagerListener listener;
IAnimationProcessor animationProcessor;
Job animationUpdateJob;
@Inject
ProgressManager progressManager;
/**
* Get the background color to be used.
*
* @param control
* The source of the display.
* @return Color
*/
static Color getItemBackgroundColor(Control control) {
return control.getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND);
}
@PostConstruct
void init() {
animationProcessor = new ProgressAnimationProcessor(this);
animationUpdateJob = new UIJob(ProgressMessages.AnimationManager_AnimationStart) {
@Override
public IStatus runInUIThread(IProgressMonitor monitor) {
if (animated) {
animationProcessor.animationStarted();
} else {
animationProcessor.animationFinished();
}
return Status.OK_STATUS;
}
};
animationUpdateJob.setSystem(true);
listener = getProgressListener();
progressManager.addListener(listener);
}
/**
* Add an item to the list
*
* @param item
*/
void addItem(final AnimationItem item) {
animationProcessor.addItem(item);
}
/**
* Remove an item from the list
*
* @param item
*/
void removeItem(final AnimationItem item) {
animationProcessor.removeItem(item);
}
/**
* Return whether or not the current state is animated.
*
* @return boolean
*/
boolean isAnimated() {
return animated;
}
/**
* Set whether or not the receiver is animated.
*
* @param boolean
*/
void setAnimated(final boolean bool) {
animated = bool;
animationUpdateJob.schedule(100);
}
/**
* Dispose the images in the receiver.
*/
void dispose() {
setAnimated(false);
progressManager.removeListener(listener);
}
private IJobProgressManagerListener getProgressListener() {
return new IJobProgressManagerListener() {
Set<Job> jobs = Collections.synchronizedSet(new HashSet<Job>());
@Override
public void addJob(JobInfo info) {
incrementJobCount(info);
}
@Override
public void refreshJobInfo(JobInfo info) {
int state = info.getJob().getState();
if (state == Job.RUNNING) {
addJob(info);
} else {
removeJob(info);
}
}
@Override
public void refreshAll() {
jobs.clear();
setAnimated(false);
JobInfo[] currentInfos = progressManager.getJobInfos(showsDebug());
for (JobInfo currentInfo : currentInfos) {
addJob(currentInfo);
}
}
@Override
public void removeJob(JobInfo info) {
decrementJobCount(info.getJob());
}
@Override
public boolean showsDebug() {
return false;
}
private void incrementJobCount(JobInfo info) {
//Don't count the animate job itself
if (isNotTracked(info)) {
return;
}
if (jobs.isEmpty()) {
setAnimated(true);
}
jobs.add(info.getJob());
}
/*
* Decrement the job count for the job
*/
private void decrementJobCount(Job job) {
jobs.remove(job);
if (jobs.isEmpty()) {
setAnimated(false);
}
}
/**
* If this is one of our jobs or not running then don't bother.
*/
private boolean isNotTracked(JobInfo info) {
//We always track errors
Job job = info.getJob();
return job.getState() != Job.RUNNING
|| animationProcessor.isProcessorJob(job);
}
@Override
public void addGroup(GroupInfo info) {
//Don't care about groups
}
@Override
public void removeGroup(GroupInfo group) {
//Don't care about groups
}
@Override
public void refreshGroup(GroupInfo info) {
//Don't care about groups
}
};
}
/**
* Get the preferred width for widgets displaying the animation.
*
* @return int. Return 0 if there is no image data.
*/
int getPreferredWidth() {
return animationProcessor.getPreferredWidth();
}
}