/*
* Copyright (c) 2012 European Synchrotron Radiation Facility,
* Diamond Light Source Ltd.
*
* 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
*/
package fable.imageviewer.component;
import java.util.Vector;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.part.ViewPart;
import fable.framework.navigator.controller.SampleController;
import fable.framework.navigator.views.SampleNavigatorView;
import fable.framework.toolbox.FableUtils;
/**
* ImagePlay implements a view to step through images and/or play images in a
* loop. The play controls view does not allow multiple views. The view can be
* detached for ease of use.
*
* @author Andy Gotz (ESRF)
*
*/
public class ImagePlay extends ViewPart {
public static final String ID = "fable.imageviewer.views.ImagePlay";
private Button imageNextButton, imagePreviousButton;
private Button imageFirstButton, imageLastButton;
private Button imagePauseButton;
/**
* Flag indicating whether it is playing or paused.
*/
private boolean advancePlay = false;
private int currentFileIndex = 0, playStep = 1, playWait = 3000;
private Thread playThread = null;
private static ImageComponent iv = null;
public ImagePlay() {
}
@Override
public void createPartControl(Composite parent) {
int buttonAlignH = SWT.FILL;
int buttonAlignV = SWT.FILL;
boolean buttonGrabH = true;
boolean buttonGrabV = false;
GridLayout parentField = new GridLayout();
parentField.numColumns = 5;
parentField.makeColumnsEqualWidth = true;
parent.setLayout(parentField);
parent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
imageFirstButton = new Button(parent, SWT.PUSH);
imageFirstButton.setText("<<");
imageFirstButton.setLayoutData(new GridData(buttonAlignH, buttonAlignV,
buttonGrabH, buttonGrabV));
imageFirstButton.setToolTipText("Go to first image");
imageFirstButton.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
if (isAdvancePlay()) {
startPlay(-1, 300);
} else {
if (iv == null) {
FableUtils.errMsg(this,
"ImagePlay: Unable to find a main ImageView");
return;
}
iv.getController().setCurrentFileIndex(0);
iv.getController().getFirstImage();
}
}
});
imagePreviousButton = new Button(parent, SWT.PUSH);
imagePreviousButton.setText("<");
imagePreviousButton.setLayoutData(new GridData(buttonAlignH,
buttonAlignV, buttonGrabH, buttonGrabV));
imagePreviousButton.setToolTipText("Go to previous image");
imagePreviousButton.setEnabled(true);
imagePreviousButton.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
if (isAdvancePlay()) {
startPlay(-1, 3000);
} else {
if (iv == null) {
FableUtils.errMsg(this,
"ImagePlay: Unable to find a main ImageView");
return;
}
int fileIndex = iv.getController().getCurrentFileIndex() - 1;
/* if first image then wrap around to last image */
if (fileIndex >= 0) {
iv.getController().setCurrentFileIndex(fileIndex);
} else {
if (iv.getController().getCurrentsample() != null) {
iv.getController().setCurrentFileIndex(
iv.getController().getCurrentsample()
.getFilteredfiles().size() - 1);
}
iv.getController().getNext(-1);
}
}
}
});
imagePauseButton = new Button(parent, SWT.PUSH);
imagePauseButton.setText("Play");
imagePauseButton.setLayoutData(new GridData(buttonAlignH, buttonAlignV,
buttonGrabH, buttonGrabV));
imagePauseButton.setToolTipText("Play");
imagePauseButton.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
setAdvancePlay(!isAdvancePlay());
if (isAdvancePlay()) {
startPlay(1, 3000);
imagePauseButton.setText("||");
imagePauseButton.setToolTipText("Pause");
} else {
imagePauseButton.setText("Play");
imagePauseButton.setToolTipText("Play");
}
}
});
imageNextButton = new Button(parent, SWT.PUSH);
imageNextButton.setText(">");
imageNextButton.setLayoutData(new GridData(buttonAlignH, buttonAlignV,
buttonGrabH, buttonGrabV));
imageNextButton.setToolTipText("Go to next image");
imageNextButton.setEnabled(true);
imageNextButton.addSelectionListener(new SelectionAdapter() {
public void widgetDefaultSelected(SelectionEvent e) {
// widgetDefaultSelected is not called, so do nothing.
}
public void widgetSelected(SelectionEvent e) {
if (isAdvancePlay()) {
startPlay(1, 3000);
} else {
if (iv == null) {
FableUtils.errMsg(this,
"ImagePlay: Unable to find a main ImageView");
return;
}
int fileIndex = iv.getController().getCurrentFileIndex() + 1;
/* if last image then wrap around to first image */
if (iv.getController().getCurrentsample() != null) {
if (fileIndex >= iv.getController().getCurrentsample()
.getFilteredfiles().size())
fileIndex = 0;
iv.getController().setCurrentFileIndex(fileIndex);
}
iv.getController().getNext(1);
}
}
});
imageLastButton = new Button(parent, SWT.PUSH);
imageLastButton.setText(">>");
imageLastButton.setLayoutData(new GridData(buttonAlignH, buttonAlignV,
buttonGrabH, buttonGrabV));
imageLastButton.setToolTipText("Go to last image");
imageLastButton.addSelectionListener(new SelectionAdapter() {
public void widgetDefaultSelected(SelectionEvent e) {
// widgetDefaultSelected is not called, so do nothing.
}
public void widgetSelected(SelectionEvent e) {
if (isAdvancePlay()) {
startPlay(1, 300);
} else {
if (iv == null) {
FableUtils.errMsg(this,
"ImagePlay: Unable to find a main ImageView");
return;
}
if (iv.getController().getCurrentsample() != null) {
int lastFileIndex = iv.getController()
.getCurrentsample().getFilteredfiles().size();
iv.getController().setCurrentFileIndex(
lastFileIndex - 1);
}
iv.getController().getLastImage();
}
}
});
}
@Override
public void setFocus() {
// TODO Auto-generated method stub
}
/**
* @return the advancePlay
*/
public boolean isAdvancePlay() {
return advancePlay;
}
/**
* @param advancePlay
* the advancePlay to set
*/
public void setAdvancePlay(boolean advancePlay) {
this.advancePlay = advancePlay;
}
public void startPlay(int step, int wait) {
playStep = step;
playWait = wait;
if (playThread == null) {
playThread = PlayThread();
playThread.start();
}
}
/**
* This method will return a thread to advance the file index in play mode.
* It should be called by the play buttons back and forward. The thread is
* ready to be run with start(). The thread will stop when the play flag is
* set to false.
*
* @return play thread
*/
public Thread PlayThread() {
return new Thread() {
public void run() {
if (iv == null) {
FableUtils.errMsg(this,
"PlayThread: Unable to find a main ImageView");
return;
}
SampleController controller = iv.getController();
Vector<Integer> selectedFiles = SampleNavigatorView.view
.getSelectedFilesIndex();
int selectedFilesIndex = 0;
if (selectedFiles.size() <= 1) {
currentFileIndex = controller.getCurrentFileIndex();
} else {
currentFileIndex = selectedFiles.firstElement();
}
while (advancePlay) {
try {
if (selectedFiles.size() <= 1) {
currentFileIndex += playStep;
} else {
selectedFilesIndex += playStep;
if (selectedFilesIndex >= selectedFiles.size())
selectedFilesIndex = 0;
currentFileIndex = selectedFiles
.elementAt(selectedFilesIndex);
}
/** Added by Gaelle for 2d peaks file. */
controller.getNext(playStep);
/***/
if (controller.getCurrentsample() != null) {
if (currentFileIndex >= controller
.getCurrentsample().getFilteredfiles()
.size()) {
currentFileIndex = 0;
} else if (currentFileIndex < 0) {
currentFileIndex = controller
.getCurrentsample().getFilteredfiles()
.size() - 1;
}
/*
* why does the controller need to be in the SWT
* thread to set the sample file index ?
*/
Display.getDefault().asyncExec(new Runnable() {
public void run() {
iv.getController().setCurrentFileIndex(
currentFileIndex);
}
});
}
Thread.sleep(playWait);
} catch (InterruptedException ex) {
// KE: Is this an unexpected occurrence. If not, better
// to use a SWTUtils dialog.
FableUtils.excTraceMsg(this, "PlayThread Interrupted",
ex);
}
}
playThread = null;
}
};
}
/**
* Set the view to which the play controls will apply (usually the main
* image view)
*
* @param view
* - ImageView to attach play controls to
*/
public static void setView(ImageComponent view) {
iv = view;
}
}