/*
* org.openmicroscopy.shoola.agents.dataBrowser.view.WellFieldsCanvas
*
*------------------------------------------------------------------------------
* Copyright (C) 2006-2009 University of Dundee. All rights reserved.
*
*
* 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; either version 2 of the License, or
* (at your option) any later version.
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*------------------------------------------------------------------------------
*/
package org.openmicroscopy.shoola.agents.dataBrowser.view;
//Java imports
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.swing.JPanel;
//Third-party libraries
//Application-internal dependencies
import org.openmicroscopy.shoola.agents.dataBrowser.browser.Thumbnail;
import org.openmicroscopy.shoola.agents.dataBrowser.browser.WellSampleNode;
import org.openmicroscopy.shoola.agents.imviewer.util.ImagePaintingFactory;
import org.openmicroscopy.shoola.util.image.geom.Factory;
import org.openmicroscopy.shoola.util.ui.UIUtilities;
/**
* Display all the fields for a given well.
*
* @author Jean-Marie Burel
* <a href="mailto:j.burel@dundee.ac.uk">j.burel@dundee.ac.uk</a>
* @author Donald MacDonald
* <a href="mailto:donald@lifesci.dundee.ac.uk">donald@lifesci.dundee.ac.uk</a>
* @version 3.0
* <small>
* (<b>Internal version:</b> $Revision: $Date: $)
* </small>
* @since 3.0-Beta4
*/
class WellFieldsCanvas
extends JPanel
{
/** Color of the axis and border. */
private static final Color LINE_COLOR = Color.BLACK;
/** The unit of reference. */
private static final int UNIT = 100;
/** The size of a tick. */
private static final int TICK = 2;
/** Reference to the parent. */
private WellFieldsView parent;
/** Collection of rectangles indicating where the image is painted. */
private Map<Rectangle, WellSampleNode> locations;
/**
* Draws the grid.
*
* @param g2D The graphics context.
* @param x The location on the X-axis of a unit.
* @param y The location on the Y-axis of a unit.
*/
private void drawGrid(Graphics2D g2D, int x, int y)
{
double f = parent.getMagnification();
int w = (int) (WellFieldsView.DEFAULT_WIDTH*f);
int h = (int) (WellFieldsView.DEFAULT_HEIGHT*f);
g2D.setColor(UIUtilities.LIGHT_GREY);
for (int i = 0; i < h; i = i+8) {
g2D.drawLine(0, i, w, i);
}
for (int i = 0; i < w; i = i+8) {
g2D.drawLine(i, 0, i, h);
}
g2D.setColor(LINE_COLOR);
//X-axis
g2D.drawLine(0, h/2, w, h/2);
int n = h/2;
if (x != 0) n = n/x;
for (int i = 1; i <= n; i++) {
g2D.drawLine(w/2+x*i, h/2-TICK, w/2+x*i, h/2+TICK);
g2D.drawLine(w/2-x*i, h/2-TICK, w/2-x*i, h/2+TICK);
}
//Y-axis
g2D.drawLine(w/2, 0, w/2, h);
n = h/2;
if (y != 0) n = n/y;
for (int i = 1; i <= n; i++) {
g2D.drawLine(w/2-TICK, h/2+y*i, w/2+TICK, h/2+y*i);
g2D.drawLine(w/2-TICK, h/2-y*i, w/2+TICK, h/2-y*i);
}
if (f > Thumbnail.MIN_SCALING_FACTOR) {
//draw unit
String s = ""+UNIT;
FontMetrics fm = getFontMetrics(getFont());
int fs = fm.stringWidth(s);
g2D.drawString(s, w/2+x-fs/2, h/2-3*TICK);
g2D.drawString(s, w/2+2*TICK, h/2-y+2*TICK);
s = "-"+UNIT;
fs = fm.stringWidth(s);
g2D.drawString(s, w/2-x-fs/2, h/2-3*TICK);
g2D.drawString(s, w/2+2*TICK, h/2+y+2*TICK);
}
//Border
g2D.drawRect(0, 0, w, h);
}
/** Sets the font according to the magnification factor. */
private void setFont()
{
Font f = getFont();
int size = (int) ((f.getSize()-4)*parent.getMagnification());
setFont(f.deriveFont(f.getStyle(), size));
}
/**
* Creates a new instance.
*
* @param parent The parent of the canvas.
*/
WellFieldsCanvas(WellFieldsView parent)
{
this.parent = parent;
setDoubleBuffered(true);
setPreferredSize(new Dimension(WellFieldsView.DEFAULT_WIDTH,
WellFieldsView.DEFAULT_HEIGHT));
setSize(getPreferredSize());
locations = new HashMap<Rectangle, WellSampleNode>();
setFont();
}
/**
* Returns the node corresponding to the passed location, or
* <code>null</code> if no nodes found.
*
* @param p The location.
* @return See above.
*/
WellSampleNode getNode(Point p)
{
Iterator<Rectangle> i = locations.keySet().iterator();
Rectangle r;
while (i.hasNext()) {
r = i.next();
if (r.contains(p)) return locations.get(r);
}
return null;
}
/**
* Overridden to paint the image.
* @see javax.swing.JComponent#paintComponent(Graphics)
*/
public void paintComponent(Graphics g)
{
super.paintComponent(g);
//g.setColor(getBackground());
locations.clear();
List<WellSampleNode> l = parent.getNodes();
if (l == null || l.size() == 0) return;
Graphics2D g2D = (Graphics2D) g;
ImagePaintingFactory.setGraphicRenderingSettings(g2D);
Iterator<WellSampleNode> i = l.iterator();
WellSampleNode n;
BufferedImage img;
Rectangle r;
double f = parent.getMagnification();
double factor = parent.getMagnificationUnscaled();
switch (parent.getLayoutFields()) {
case WellFieldsView.ROW_LAYOUT:
default:
int w = 0;
int h = 0;
double ff = f*factor;
while (i.hasNext()) {
n = i.next();
img = n.getThumbnail().getFullScaleThumb();
if (ff != 1) img = Factory.magnifyImage(ff, img);
if (img != null) {
if (w+img.getWidth() > WellFieldsView.DEFAULT_WIDTH*ff) {
w = 0;
h += img.getHeight()+1;
}
r = new Rectangle(w, h, img.getWidth(),
img.getHeight());
locations.put(r, n);
g2D.drawImage(img, null, w, h);
w += img.getWidth()+1;
}
}
break;
case WellFieldsView.SPATIAL_LAYOUT:
int x = 0;
int y = 0;
int xMin = Integer.MAX_VALUE;
int yMin = Integer.MAX_VALUE;
int xMax = Integer.MIN_VALUE;
int yMax = Integer.MIN_VALUE;
int width = 0;
int height = 0;
while (i.hasNext()) {
n = i.next();
img = n.getThumbnail().getFullScaleThumb();
if (img != null) {
if (width < img.getWidth())
width = img.getWidth();
if (height < img.getHeight())
height = img.getHeight();
x = (int) n.getPositionX();
y = (int) n.getPositionY();
if (x < xMin) xMin = x;
if (y < yMin) yMin = y;
if (xMax < x) xMax = x;
if (yMax < y) yMax = y;
}
}
int xc = Math.abs(xMin);
int yc = Math.abs(yMin);
i = l.iterator();
int vx = 0;
int vy = 0;
int wMax = xc+xMax+(int) (width*f);
int hMax = yc+yMax+(int) (height*f);
double rx = (double) WellFieldsView.DEFAULT_WIDTH*f/wMax;
double ry = (double) WellFieldsView.DEFAULT_HEIGHT*f/hMax;
drawGrid(g2D, (int) (UNIT*rx), (int) (UNIT*ry));
BufferedImage scaled;
while (i.hasNext()) {
n = i.next();
img = n.getThumbnail().getFullScaleThumb();
if (img != null) {
x = (int) n.getPositionX();
y = (int) n.getPositionY();
vx = (int) ((x+xc)*rx);
vy = (int) (WellFieldsView.DEFAULT_HEIGHT*f)-
(int) ((y+yc)*ry);
w = (int) (width*rx*f*factor);
h = (int) (height*ry*f);
vy = vy-h;
h = (int) (h*factor);
scaled = Factory.scaleBufferedImage(img, w, h);
r = new Rectangle(vx, vy, w, h);
g2D.drawImage(scaled, null, r.x, r.y);
locations.put(r, n);
}
}
}
g2D.dispose();
}
}