package org.nightlabs.jfire.trade.editor2d.ui.layout;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.apache.log4j.Logger;
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.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.nightlabs.base.ui.composite.XComposite;
import org.nightlabs.jfire.trade.editor2d.ILayout;
import org.nightlabs.jfire.trade.editor2d.ui.resource.Messages;
public class LayoutPreviewComposite<L extends ILayout> extends XComposite {
private static final Logger logger = Logger.getLogger(LayoutPreviewComposite.class);
private Label imageLabel;
private int maxWidth;
private int maxHeight;
private ILayoutPreviewRenderer<L> previewRenderer;
public LayoutPreviewComposite(Composite parent, ILayoutPreviewRenderer<L> renderer, int maxWidth, int maxHeight) {
super(parent, SWT.BORDER, LayoutMode.TIGHT_WRAPPER, LayoutDataMode.NONE);
Label previewLabel = new Label(this, SWT.NONE);
previewLabel.setText(Messages.getString("org.nightlabs.jfire.trade.editor2d.ui.layout.LayoutPreviewComposite.group.preview.text")); //$NON-NLS-1$
this.maxWidth = maxWidth;
this.maxHeight = maxHeight;
imageLabel = new Label(this, SWT.NONE);
final GridData layoutData = new GridData(SWT.BEGINNING, SWT.CENTER, false, false);
layoutData.widthHint = maxWidth;
layoutData.heightHint = maxHeight;
imageLabel.setLayoutData(layoutData);
previewRenderer = renderer;
}
private Map<String, Image> generatedPreviews = Collections.synchronizedMap(new HashMap<String, Image>());
private Job showPreviewJob;
public void showPreview(final L layout) {
imageLabel.setImage(null);
if (layout == null)
return;
imageLabel.setText(Messages.getString("org.nightlabs.jfire.trade.editor2d.ui.layout.LayoutPreviewComposite.label.text")); //$NON-NLS-1$
showPreviewJob = new Job(Messages.getString("org.nightlabs.jfire.trade.editor2d.ui.layout.LayoutPreviewComposite.job.loadPreview.name")) { //$NON-NLS-1$
@Override
protected IStatus run(IProgressMonitor monitor) {
Image prev = generatedPreviews.get(layout.getFileName());
if (prev == null) {
try {
prev = previewRenderer.renderPreview(layout, maxWidth, maxHeight);
generatedPreviews.put(layout.getFileName(), prev);
} catch (final Exception e) {
Display.getDefault().asyncExec(new Runnable() {
@Override
public void run() {
imageLabel.setText(Messages.getString("org.nightlabs.jfire.trade.editor2d.ui.layout.LayoutPreviewComposite.previewErrorMessage")); //$NON-NLS-1$
logger.info("Rendering the preview of " + layout.getFileName() + " failed: ", e); //$NON-NLS-1$ //$NON-NLS-2$
}
});
return Status.OK_STATUS;
}
}
final Image preview = prev;
final Job thisJob = this;
Display.getDefault().asyncExec(new Runnable() {
@Override
public void run() {
if (showPreviewJob == thisJob && !imageLabel.isDisposed()) {
imageLabel.setText(""); //$NON-NLS-1$
imageLabel.setImage(preview);
imageLabel.pack(true);
}
}
});
return Status.OK_STATUS;
}
};
showPreviewJob.setSystem(true);
showPreviewJob.schedule();
// add a dispose listener to destroy all images when this composite is disposed
addDisposeListener(new DisposeListener() {
@Override
public void widgetDisposed(DisposeEvent e) {
for (Image image : generatedPreviews.values())
image.dispose();
}
});
}
}