/**
TrakEM2 plugin for ImageJ(C).
Copyright (C) 2005-2009 Albert Cardona and Rodney Douglas.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation (http://www.gnu.org/licenses/gpl.txt )
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
You may contact Albert Cardona at acardona at ini.phys.ethz.ch
Institute of Neuroinformatics, University of Zurich / ETH, Switzerland.
**/
package ini.trakem2.display;
import ini.trakem2.persistence.FSLoader;
import ini.trakem2.utils.IJError;
import ini.trakem2.utils.Utils;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import javax.swing.JPanel;
public class SnapshotPanel extends JPanel implements MouseListener {
private static final long serialVersionUID = 1L;
private Display display;
private Displayable d;
static public final int SIDE = 50;
static public final Color GREY = new Color(215, 215, 215);
public SnapshotPanel(Display display, Displayable d) {
this.display = display;
this.d = d;
// Always a square
Dimension dim = new Dimension(SIDE, SIDE);
setMinimumSize(dim);
setMaximumSize(dim);
setPreferredSize(dim);
}
public void set(final Displayable d) {
this.d = d;
repaint();
}
public void update(Graphics g) {
paint(g);
}
private BufferedImage img = null;
private void fillBackground(Graphics g, double lw, double lh, int slw, int slh) {
if (lw != lh) {
g.setColor(Color.black);
g.fillRect(0, 0, slw, slh);
g.setColor(GREY);
g.fillRect(slw, 0, SIDE - slw, SIDE);
g.fillRect(0, slh, slw, SIDE - slh);
} else {
g.setColor(Color.black);
g.fillRect(0, 0, SIDE, SIDE);
}
}
/** Paint the snapshot image over a black background that represents a scaled Layer. */
public void paint(final Graphics g) {
if (null == g) return; // happens if not visible
synchronized (this) {
if (null != img) {
// Paint and flush
g.drawImage(img, 0, 0, null);
this.img.flush();
this.img = null;
return;
}
}
// Else, repaint background to avoid flickering
final Layer la = display.getLayer();
if (null == la) {
Utils.log2("SnapshotPanel: null layer?");
return;
}
final double lw = la.getLayerWidth();
final double lh = la.getLayerHeight();
final double scale = Math.min(SIDE / lw,
SIDE / lh);
final int slw = (int)(lw * scale);
final int slh = (int)(lh * scale);
fillBackground(g, lw, lh, slw, slh);
// ... and create the image in a separate thread and repaint again
FSLoader.repainter.submit(new Runnable() { public void run() {
try {
if (!display.isPartiallyWithinViewport(d)) return;
BufferedImage img = new BufferedImage(SIDE, SIDE, BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = img.createGraphics();
fillBackground(g2, lw, lh, slw, slh);
g2.scale(scale, scale);
try {
// Avoid painting images that have an alpha mask: takes forever.
//if (d.getClass() == Patch.class && ((Patch)d).hasAlphaChannel()) {
// d.paintAsBox(g2);
//} else {
final Layer la = display.getLayer();
d.paintSnapshot(g2, la, la.getParent().getColorCueLayerRange(la), d.getLayerSet().get2DBounds(), scale);
//}
} catch (Exception e) {
d.paintAsBox(g2);
}
synchronized (this) {
if (null != SnapshotPanel.this.img) SnapshotPanel.this.img.flush();
SnapshotPanel.this.img = img;
}
repaint();
} catch (Throwable t) {
IJError.print(t);
}
}});
}
public void mousePressed(MouseEvent me) {
//must enable cancel!//if (display.isTransforming()) return;
display.setActive(d);
if (me.isPopupTrigger() || (ij.IJ.isMacOSX() && me.isControlDown()) || MouseEvent.BUTTON2 == me.getButton()) {
display.showPopup(this, me.getX(), me.getY());
}
}
public void mouseReleased(MouseEvent me) {}
public void mouseEntered(MouseEvent me) {}
public void mouseExited (MouseEvent me) {}
public void mouseClicked(MouseEvent me) {}
}