/*
* File Shape.java
*
* Copyright (C) 2010 Remco Bouckaert remco@cs.auckland.ac.nz
*
* This file is part of BEAST2.
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership and licensing.
*
* BEAST is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* BEAST 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with BEAST; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
package beast.app.draw;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JPanel;
import org.w3c.dom.Node;
abstract public class Shape {
int m_x = 0;
int m_y = 0;
int m_w = 1;
int m_h = 1;
int m_nPenWidth = 1;
boolean m_bFilled = true;
Color m_fillcolor = DEFUALT_FILL_COLOR;
Color m_pencolor = DEFUALT_PEN_COLOR;
public boolean m_bNeedsDrawing = true;
final static Color DEFUALT_FILL_COLOR = new Color(128, 128, 128);
final static Color DEFUALT_PEN_COLOR = new Color(0, 0, 0);
String m_sID;
Document m_doc;
String getID() {
return m_sID;
}
public Shape() {
}
public Shape(Node node, Document doc) {
m_doc = doc;
}
public void draw(Graphics2D g, JPanel panel) {
}
void drawLabel(Graphics2D g) {
if (getLabel() != null) {
FontMetrics fm = g.getFontMetrics(g.getFont());
String label = getLabel();
if (m_doc != null && m_doc.sanitiseIDs()) {
if (label.contains(".")) {
label = label.substring(0, label.indexOf('.'));
}
}
int i = 0;
while (label.indexOf('\n') >= 0) {
String str = label.substring(0, label.indexOf('\n'));
g.drawString(str, m_x + m_w / 2 - fm.stringWidth(str) / 2, m_y + m_h / 2 + i * fm.getHeight());
label = label.substring(str.length() + 1);
i++;
}
g.drawString(label, m_x + m_w / 2 - fm.stringWidth(label) / 2, m_y + m_h / 2 + i * fm.getHeight());
}
} // drawLabel
List<TrackPoint> getTracker() {
List<TrackPoint> tracker = new ArrayList<>(8);
tracker.add(new TrackPoint(m_x, m_y, Cursor.NW_RESIZE_CURSOR));
tracker.add(new TrackPoint(m_x + m_w, m_y, Cursor.NE_RESIZE_CURSOR));
tracker.add(new TrackPoint(m_x, m_y + m_h, Cursor.SW_RESIZE_CURSOR));
tracker.add(new TrackPoint(m_x + m_w, m_y + m_h, Cursor.SE_RESIZE_CURSOR));
tracker.add(new TrackPoint(m_x, m_y + m_h / 2, Cursor.W_RESIZE_CURSOR));
tracker.add(new TrackPoint(m_x + m_w, m_y + m_h / 2, Cursor.E_RESIZE_CURSOR));
tracker.add(new TrackPoint(m_x + m_w / 2, m_y, Cursor.N_RESIZE_CURSOR));
tracker.add(new TrackPoint(m_x + m_w / 2, m_y + m_h, Cursor.S_RESIZE_CURSOR));
return tracker;
}
void parse(Node node, Document doc, boolean reconstructBEASTObjects) {
if (node.getAttributes().getNamedItem("id") != null) {
m_sID = node.getAttributes().getNamedItem("id").getNodeValue();
}
if (node.getAttributes().getNamedItem("x") != null) {
m_x = (new Integer(node.getAttributes().getNamedItem("x").getNodeValue())).intValue();
m_x += 400;
}
if (node.getAttributes().getNamedItem("y") != null) {
m_y = (new Integer(node.getAttributes().getNamedItem("y").getNodeValue())).intValue();
if (node.getAttributes().getNamedItem("h") != null) {
m_h = (new Integer(node.getAttributes().getNamedItem("h").getNodeValue())).intValue();
}
m_y = 550 - m_y - m_h;
}
if (node.getAttributes().getNamedItem("w") != null) {
m_w = (new Integer(node.getAttributes().getNamedItem("w").getNodeValue())).intValue();
}
if (node.getAttributes().getNamedItem("penwidth") != null) {
m_nPenWidth = (new Integer(node.getAttributes().getNamedItem("penwidth").getNodeValue())).intValue();
}
if (node.getAttributes().getNamedItem("fillcolor") != null) {
m_fillcolor = string2Color(node.getAttributes().getNamedItem("fillcolor").getNodeValue());
}
if (node.getAttributes().getNamedItem("pencolor") != null) {
m_pencolor = string2Color(node.getAttributes().getNamedItem("pencolor").getNodeValue());
}
if (node.getAttributes().getNamedItem("filled") != null) {
m_bFilled = !node.getAttributes().getNamedItem("filled").getNodeValue().equals("no");
}
}
String XMLnormalizeAtt(String str) {
StringBuffer str2 = new StringBuffer();
for (int strIndex = 0; strIndex < str.length(); strIndex++) {
switch (str.charAt(strIndex)) {
case '<':
str2.append("<");
break;
case '>':
str2.append(">");
break;
case '\"':
str2.append(""");
break;
case '\'':
str2.append("'");
break;
case '&':
str2.append("&");
break;
case 13:
break;
case '\n':
str2.append("
");
break;
default:
str2.append(str.charAt(strIndex));
}
}
return str2.toString();
} // XMLnormalizeAtt
String getAtts() {
return " id='" + getID() + "'" +
" x='" + (m_x - 400) + "'" +
" y='" + (550 - m_y - m_h) + "'" +
" w='" + m_w + "'" +
" h='" + m_h + "'" +
(m_nPenWidth != 1 ? " penwidth='" + m_nPenWidth + "'" : "") +
(!m_bFilled ? " filled='no'" : "") +
(m_fillcolor.equals(DEFUALT_FILL_COLOR) ? "" : " fillcolor='" + m_fillcolor.getRed() + " " + m_fillcolor.getGreen() + " " + m_fillcolor.getBlue() + "'") +
(m_pencolor.equals(DEFUALT_PEN_COLOR) ? "" : " pencolor='" + m_pencolor.getRed() + " " + m_pencolor.getGreen() + " " + m_pencolor.getBlue() + "'")
;
}
void assignFrom(Shape other) {
m_x = other.m_x;
m_y = other.m_y;
m_w = other.m_w;
m_h = other.m_h;
m_nPenWidth = other.m_nPenWidth;
m_bFilled = other.m_bFilled;
m_fillcolor = other.m_fillcolor;
m_pencolor = other.m_pencolor;
}
Color string2Color(String color) {
int space = color.indexOf(' ');
if (space < 0) {
return new Color(128, 128, 128);
}
int start = 0;
String rStr = color.substring(start, space);
int r = (new Integer(rStr)).intValue();
start = space + 1;
space = color.indexOf(' ', start);
if (space < 0) {
return new Color(128, 128, 128);
}
String gStr = color.substring(start, space);
int g = (new Integer(gStr)).intValue();
start = space + 1;
space = color.indexOf(' ', start);
if (space < 0) {
space = color.length();
}
String isStr = color.substring(start, space);
int b = (new Integer(isStr)).intValue();
return new Color(r, g, b);
} // string2Color
public String getXML() {
return "<shape" + getAtts() + "/>";
}
boolean intersects(int x, int y) {
return (x >= m_x - 1 && x <= m_x + m_w + 1 && y >= m_y - 1 && y <= m_y + m_h + 1);
}
boolean intersects(Rectangle rect) {
return rect.intersects(m_x - 1, m_y - 1, m_w + 2, m_h + 2);
}
// boolean intersects(int x, int y) {
// return false;
// }
// boolean intersects(Rectangle rect) {
// return false;
// }
int offsetX(int x) {
return x - m_x;
}
int offsetY(int y) {
return y - m_y;
}
void offset(int dX, int dY) {
m_x += dX;
m_y += dY;
}
void movePosition(int offsetX, int offsetY, int toX, int toY) {
m_x = toX - offsetX;
m_y = toY - offsetY;
} // movePosition
void movePoint(int point, int offsetX, int offsetY, int toX, int toY) {
switch (point) {
case 0:
m_w = m_w + m_x - toX + offsetX;
m_x = toX - offsetX;
m_h = m_h + m_y - toY + offsetY;
m_y = toY - offsetY;
break;
case 1:
m_w = toX - offsetX - m_x;
m_h = m_h + m_y - toY + offsetY;
m_y = toY - offsetY;
break;
case 2:
m_w = m_w + m_x - toX + offsetX;
m_x = toX - offsetX;
m_h = toY - offsetY - m_y;
break;
case 3:
m_w = toX - offsetX - m_x;
m_h = toY - offsetY - m_y;
break;
case 5:
m_w = toX - offsetX - m_x;
break;
case 4:
m_w = m_w + m_x - toX + offsetX;
m_x = toX - offsetX;
break;
case 7:
m_h = toY - offsetY - m_y;
break;
case 6:
m_h = m_h + m_y - toY + offsetY;
m_y = toY - offsetY;
break;
}
} // movePoint
void normalize() {
int x1 = m_x;
int x2 = m_x + m_w;
int y1 = m_y;
int y2 = m_y + m_h;
m_x = Math.min(x1, x2);
m_w = Math.max(x1, x2) - m_x;
m_y = Math.min(y1, y2);
m_h = Math.max(y1, y2) - m_y;
}
public Color getFillColor() {
return m_fillcolor;
}
void setFillColor(Color color) {
m_fillcolor = color;
}
Color getPenColor() {
return m_pencolor;
}
void setPenColor(Color color) {
m_pencolor = color;
}
int getX() {
return m_x;
}
int getY() {
return m_y;
}
int getX2() {
return m_x + m_w;
}
int getY2() {
return m_y + m_h;
}
void setX(int x) {
m_x = x;
}
void setY(int y) {
m_y = y;
}
void setX2(int x2) {
m_w = x2 - m_x;
}
void setY2(int y2) {
m_h = y2 - m_y;
}
//void setLabel(String label) {}
String getLabel() {
return "";
}
boolean isFilled() {
return m_bFilled;
}
void toggleFilled() {
m_bFilled = !m_bFilled;
}
int getPenWidth() {
return m_nPenWidth;
}
void setPenWidth(int penWidth) {
m_nPenWidth = penWidth;
}
abstract void toSVG(PrintStream out);
void drawSVGString(PrintStream out, Font font, Color color, String textAnchor) {
if (getLabel() != null) {
String label = getLabel();
//int i = 0;
while (label.indexOf('\n') >= 0) {
String str = label.substring(0, label.indexOf('\n'));
out.println("<text x='"
+ (m_x + m_w / 2)
+ "' y='"
+ (m_y + m_h / 2)
+ "' font-family='" + font.getFamily() + "' "
+ "font-size='" + font.getSize() + "pt' " + "font-style='"
+ (font.isBold() ? "oblique" : "") + (font.isItalic() ? "italic" : "") + "' "
+
"stroke='rgb(" + color.getRed() + "," + color.getGreen()
+ "," + color.getBlue() + ")' text-anchor='" + textAnchor + "'>" + str + "</text>\n");
label = label.substring(str.length() + 1);
//i++;
}
out.println("<text x='"
+ (m_x + m_w / 2)
+ "' y='"
+ (m_y + m_h / 2)
+ "' font-family='" + font.getFamily() + "' "
+ "font-size='" + font.getSize() + "pt' " + "font-style='"
+ (font.isBold() ? "oblique" : "") + (font.isItalic() ? "italic" : "") + "' "
+
"stroke='rgb(" + color.getRed() + "," + color.getGreen() + "," + color.getBlue() + ")' " +
"text-anchor='" + textAnchor + "'>" + label + "</text>\n");
}
}
}