package org.lemsml.jlems.viz.plot;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import org.lemsml.jlems.core.logging.E;
public class WorldCanvas extends BaseCanvas implements ModeSettable {
static final long serialVersionUID = 1001;
public static final String PAN = "pan";
public static final String ALL = "all";
public static final String EZOOM = "zoom";
public static final String BOX = "box";
public static final String ROLL = "roll";
public static final String ETURN = "turn";
public static final String MULTI = "all";
public static final String ZOOMIN = "zoomIn";
public static final String ZOOMOUT = "zoomOut";
protected WorldTransform wt;
protected Painter painter;
protected PaintInstructor paintInstructor;
protected Mouse mouse;
private boolean antialias = false;
private boolean tooltips = true;
Box reframeBox;
private boolean userAntialias;
public WorldCanvas() {
this(true);
}
public WorldCanvas(boolean interactive) {
super();
mouse = new Mouse(this, interactive);
wt = new WorldTransform();
painter = new Painter(wt);
setMouseMode("pan");
}
public boolean isAntialiasing() {
return antialias;
}
public void setAntialias(boolean b) {
userAntialias = b;
antialias = b;
repaint();
}
public void restoreAA() {
antialias = userAntialias;
}
public void setMode(String dom, String mod) {
if (dom.equals("antialias")) {
antialias = mod.equals("true");
userAntialias = antialias;
} else if (dom.equals("mouse")) {
setMouseMode(mod);
} else {
E.error("unrecognized mode " + dom);
}
repaint();
}
public void setMode(String dom, boolean b) {
if (dom.equals("antialias")) {
antialias = b;
userAntialias = b;
} else if (dom.equals("labels")) {
tooltips = b;
} else if (dom.equals("showAll")) {
reframe();
} else {
E.error("unrecognized mode " + dom);
}
repaint();
}
public void reluctantReframe() {
if (reframeBox == null) {
reframe();
} else if (paintInstructor != null) {
Box box = paintInstructor.getLimitBox();
if (box != null && box.differentFrom(reframeBox, 0.15)) {
frameToBox(box);
}
}
}
public void reframe() {
if (paintInstructor == null) {
E.shortWarning("no paint instructor?");
} else {
Box box = paintInstructor.getLimitBox();
frameToBox(box);
}
}
protected void frameToBox(Box box) {
if (box == null) {
E.warning("no limit box returned from " + paintInstructor.getClass().getName());
} else if (box.hasData()) {
//System.out.println("framing " + getHeight());
syncSize();
reframeBox = box.makeCopy();
box.pad();
painter.reframe(box);
repaint();
} else {
// ok? - mesage? TODO
}
}
public boolean showToolTips() {
return tooltips;
}
public void setMode(int imode) {
E.missing();
}
public void addRangeListener(RangeListener rl) {
wt.addRangeListener(rl);
}
public Painter getPainter() {
return painter;
}
WorldTransform getWorldTransform() {
return wt;
}
public void setClickListener(ClickListener cl) {
mouse.setClickListener(cl);
}
public void setRotationListener(RotationListener rl) {
wt.setRotationListener(rl);
}
public final void setMouseMode(String s) {
if (s.equals(PAN) || s.equals(ALL)) {
setMouseHandler(new PanZoomHandler());
} else if (s.equals(EZOOM)) {
setMouseHandler(new ClickZoomHandler());
} else if (s.equals(BOX)) {
setMouseHandler(new BoxSelectionHandler());
} else if (s.equals(ROLL)) {
setMouseHandler(new RollHandler());
} else if (s.equals(ETURN)) {
setMouseHandler(new TurnZoomHandler());
} else if (s.equals(ZOOMIN)) {
ClickZoomHandler czh = new ClickZoomHandler();
setMouseHandler(czh);
czh.activateIn();
} else if (s.equals(ZOOMOUT)) {
ClickZoomHandler czh = new ClickZoomHandler();
setMouseHandler(czh);
czh.activateOut();
}
}
public void setXRange(double[] lh) {
setXRange(lh[0], lh[1]);
}
public void setYRange(double[] lh) {
setYRange(lh[0], lh[1]);
}
public void ensureCovers(double[] xr, double[] yr) {
wt.ensureCovers(xr[0], yr[0], xr[1], yr[1]);
}
public void setXRange(double low, double high) {
wt.setXRange(low, high);
}
public void setYRange(double low, double high) {
wt.setYRange(low, high);
}
public void setFixedAspectRatio(double ar) {
wt.setFixedAspectRatio(ar);
}
public double[] getXRange() {
return wt.getXRange();
}
public double[] getYRange() {
return wt.getYRange();
}
public void viewAction(String s) {
if (s.equals("frame")) {
reframe();
}
}
public final void setMouseHandler(BaseMouseHandler mh) {
mouse.setHandler(mh);
}
public void fixRanges() {
wt.fixRanges();
}
public void setPaintInstructor(PaintInstructor pi) {
paintInstructor = pi;
}
public void syncSize() {
wt.setWidth(getWidth());
wt.setHeight(getHeight());
}
public void paintComponent(Graphics g0) {
syncSize();
g0.setColor(getDataBackground());
g0.fillRect(0, 0, getWidth(), getHeight());
Graphics2D g = (Graphics2D)g0;
painter.setGraphics(g);
prePaint(g);
paint2D(g);
postPaint(g);
mouse.echoPaint(g);
}
public void prePaint(Graphics2D g) {
// nothing to do
}
public void postPaint(Graphics2D g) {
// nothing to do
}
public void applyAAPreference(Graphics2D g) {
if (antialias) {
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
} else {
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
}
}
public void paint2D(Graphics2D g) {
E.info("pw painting ");
if (paintInstructor != null) {
applyAAPreference(g);
paintInstructor.instruct(painter);
}
}
void boxSelected(int x0, int y0, int x1, int y1) {
wt.setCanvasSize(getWidth(), getHeight());
wt.boxSelected(x0, y0, x1, y1);
repaint();
}
void initializeZoom(int xc, int yc) {
wt.initializeZoom(xc, yc);
}
void dragZoom(double fx, double fy, int xc, int yc) {
antialias = false;
wt.dragZoom(fx, fy, xc, yc);
}
void zoom(double fac, int xc, int yc) {
wt.zoom(fac, xc, yc);
repaint();
}
void zoom(double xfac, double yfac, int xc, int yc) {
wt.zoom(xfac, yfac, xc, yc);
repaint();
}
void trialPan(int xfrom, int yfrom, int xto, int yto) {
antialias = false;
wt.trialPan(xfrom, yfrom, xto, yto);
repaint();
}
void permanentPan(int xfrom, int yfrom, int xto, int yto) {
wt.permanentPan(xfrom, yfrom, xto, yto);
repaint();
}
void dragRollRotate(int px, int py) {
antialias = false;
wt.dragRollRotate(px, py);
repaint();
}
void dragZRotate(int px, int py) {
antialias = false;
wt.dragZRotate(px, py);
repaint();
}
public void turn(double d) {
wt.initializeRotation(getWidth() / 2, getHeight() / 2);
wt.zRotate(d / 180. * Math.PI);
repaint();
}
void initializeRotation(int px, int py) {
wt.initializeRotation(px, py);
}
void initializeRotation(double x, double y, double z) {
wt.initializeRotationLocal(x, y, z);
}
public void setColorRange(double cmin, double cmax) {
painter.setColorRange(cmin, cmax);
}
public void setColorTable(Color[] ac) {
painter.setColorTable(ac);
}
public int[] getIntPosition(Position pos) {
return wt.getIntPosition(pos.getX(), pos.getY());
}
public double[][] getProjectionMatrix() {
return wt.getProjectionMatrix();
}
public void setRollCenter(double x, double y, double z) {
// rollHandler.setRollCenter(x, y, z);
}
public double[] get2Center() {
return wt.get2Center();
}
public double[] get3Center() {
return wt.get3Center();
}
// first four elements should be top row of matrix;
public double[] getFourMatrix() {
double[][] pm = wt.getProjectionMatrix();
// double[] cen = wt.get3Center();
double[] cen2 = wt.get2Center();
double[] ret = new double[16];
double sf = 3. * wt.getScale();
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
ret[4 * i + j] = sf * pm[i][j];
}
ret[4 * i + 3] = cen2[i];
}
ret[15] = 1.;
return ret;
}
public void setFourMatrix(double[] fm) {
double[][] pm = new double[3][3];
double[] cen = new double[3];
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
pm[i][j]= fm[4 * i + j];
}
cen[i] = fm[4 * i + 3];
}
double m3xx, m3xy, m3xz, m3yx, m3yy, m3yz, m3zx, m3zy, m3zz;
m3xx = pm[0][0]; m3xy = pm[0][1]; m3xz = pm[0][2];
m3yx = pm[1][0]; m3yy = pm[1][1]; m3yz = pm[1][2];
m3zx = pm[2][0]; m3zy = pm[2][1]; m3zz = pm[2][2];
double det = (m3xx * (m3yy * m3zz - m3zy * m3yz) -
m3xy * (m3yx * m3zz - m3zx * m3yz) +
m3xz * (m3yx * m3zy - m3zx * m3yy));
double rdet = Math.pow(det, 1./3.);
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
pm[i][j] /= rdet;
}
}
double[] c0 = {0., 0., 0.};
for (int i = 0; i < 3; i++) {
cen[i] /= rdet;
}
wt.setProjectionMatrix(pm);
wt.set3Center(c0);
wt.set2Center(cen);
wt.setScale(0.3 * rdet); // ADHOC
repaint();
}
}