/**
* Copyright (c) 2011-2013 KUBO Atsuhiro <kubo@iteman.jp>,
* All rights reserved.
*
* This file is part of MakeGood.
*
* 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
*/
package com.piece_framework.makegood.ui.widgets;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
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.swt.SWT;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.ImageLoader;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.ui.menus.WorkbenchWindowControlContribution;
import org.eclipse.ui.progress.UIJob;
import com.piece_framework.makegood.ui.Activator;
import com.piece_framework.makegood.ui.Messages;
import com.piece_framework.makegood.ui.views.ResultView;
import com.piece_framework.makegood.ui.views.ViewOpener;
/**
* @since 1.3.0
*/
public class ResultSquare extends WorkbenchWindowControlContribution {
private static final String IMAGE_PATH_MAKEGOOD = "icons/makegood.gif"; //$NON-NLS-1$
private static final String IMAGE_PATH_PASSED = "icons/square_passed.gif"; //$NON-NLS-1$
private static final String IMAGE_PATH_FAILED = "icons/square_failed.gif"; //$NON-NLS-1$
private static final String IMAGE_PATH_STOPPED = "icons/square_stopped.gif"; //$NON-NLS-1$
/**
* @since 2.1.0
*/
private static final String IMAGE_PATH_NOTESTS = "icons/square_notests.gif"; //$NON-NLS-1$
private static final String IMAGE_PATH_PROGRESS = "icons/square_progress.gif"; //$NON-NLS-1$
private Canvas canvas;
private Label square;
private ImageAnimator imageAnimator;
private Thread imageAnimatorThread;
private static ResultSquare currentResultSquare;
public static ResultSquare getInstance() {
return currentResultSquare;
}
@Override
protected Control createControl(Composite parent) {
currentResultSquare = this;
canvas = new Canvas(parent, SWT.NONE);
canvas.setLayout(new GridLayout(1, false));
square = new Label(canvas, SWT.NONE);
square.setToolTipText(Messages.ResultSquare_WaitingForTestRun);
square.setImage(Activator.getImageDescriptor(IMAGE_PATH_MAKEGOOD).createImage());
square.addMouseListener(new MouseListener() {
@Override
public void mouseDoubleClick(MouseEvent e) {
Job job = new UIJob("MakeGood View Open") { //$NON-NLS-1$
@Override
public IStatus runInUIThread(IProgressMonitor monitor) {
ViewOpener.open(ResultView.VIEW_ID);
return Status.OK_STATUS;
}
};
job.schedule();
}
@Override
public void mouseDown(MouseEvent e) {
}
@Override
public void mouseUp(MouseEvent e) {
}
});
URL imageURL = Activator.getDefault().getBundle().getEntry(IMAGE_PATH_PROGRESS);
if (imageURL == null) {
throw new RuntimeException(IMAGE_PATH_PROGRESS + " not found."); //$NON-NLS-1$
}
InputStream imageInputStream;
try {
imageInputStream = imageURL.openStream();
} catch (IOException e) {
throw new RuntimeException("Cannnot open stream for " + IMAGE_PATH_PROGRESS + "."); //$NON-NLS-1$ //$NON-NLS-2$
}
imageAnimator = new ImageAnimator(imageInputStream);
return canvas;
}
public void startTest() {
if (!canvas.isDisposed() && !square.isDisposed()) {
square.setVisible(false);
canvas.addPaintListener(imageAnimator.getPaintListener());
imageAnimatorThread = new Thread(imageAnimator);
imageAnimatorThread.start();
}
}
public void endTest() {
if (imageAnimatorThread != null) {
imageAnimatorThread.interrupt();
try {
imageAnimatorThread.join();
} catch (InterruptedException e) {
}
}
if (!canvas.isDisposed()) {
canvas.removePaintListener(imageAnimator.getPaintListener());
}
if (!square.isDisposed()) {
square.setVisible(true);
}
}
public void markAsPassed() {
if (!square.isDisposed()) {
square.setImage(Activator.getImageDescriptor(IMAGE_PATH_PASSED).createImage());
square.setToolTipText(Messages.ResultSquare_TestPassed);
}
}
public void markAsFailed() {
if (!square.isDisposed()) {
square.setImage(Activator.getImageDescriptor(IMAGE_PATH_FAILED).createImage());
square.setToolTipText(Messages.ResultSquare_TestFailed);
}
}
public void markAsStopped() {
if (!square.isDisposed()) {
square.setImage(Activator.getImageDescriptor(IMAGE_PATH_STOPPED).createImage());
square.setToolTipText(Messages.ResultSquare_TestRunStopped);
}
}
/**
* @since 2.1.0
*/
public void markAsNoTests() {
if (!square.isDisposed()) {
square.setImage(Activator.getImageDescriptor(IMAGE_PATH_NOTESTS).createImage());
square.setToolTipText(Messages.ResultSquare_NoTests);
}
}
private class ImageAnimator implements Runnable {
private ImageLoader imageLoader = new ImageLoader();
private GC gc;
private PaintListener paintListener;
private int currentFrameIndex = 1;
public ImageAnimator(InputStream imageInputStream) {
super();
imageLoader.load(imageInputStream);
gc = new GC(canvas);
paintListener = new PaintListener() {
@Override
public void paintControl(PaintEvent event) {
drawCurrentFrame(event.gc);
}
};
}
@Override
public void run() {
while (true) {
try {
Thread.sleep(imageLoader.data[currentFrameIndex].delayTime * 10);
} catch (InterruptedException e) {
return;
}
if (canvas.isDisposed()) return;
canvas.getDisplay().asyncExec(new Runnable() {
@Override
public void run(){
if (canvas.isDisposed()) return;
drawCurrentFrame(gc);
if (canvas.isDisposed()) return;
canvas.redraw();
if (currentFrameIndex == imageLoader.data.length - 1) {
currentFrameIndex = 0;
} else {
++currentFrameIndex;
}
}
});
}
}
public PaintListener getPaintListener() {
return paintListener;
}
/**
* @since 1.7.0
*/
private void drawCurrentFrame(GC gc) {
ImageData currentFrameData = imageLoader.data[currentFrameIndex];
Image frameImage = new Image(canvas.getDisplay(), currentFrameData);
gc.drawImage(frameImage, square.getBounds().x, square.getBounds().y);
frameImage.dispose();
}
}
}