package org.geogebra.desktop.gui.dialog;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Ellipse2D;
import java.awt.geom.GeneralPath;
import java.awt.geom.Line2D;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.ListCellRenderer;
import org.geogebra.common.plugin.EuclidianStyleConstants;
import org.geogebra.desktop.awt.GGraphics2DD;
import org.geogebra.desktop.factories.AwtFactoryD;
/**
* @author George Sturr 2009-9-19 This class defines the ComboBox renderer where
* the user chooses the point style for GeoPoint
*
*/
public class PointStyleListRenderer extends JPanel implements ListCellRenderer {
private static final long serialVersionUID = 1L;
private int pointStyle = -1;
// for drawing
private int pointSize = 4;
private Ellipse2D.Double circle = new Ellipse2D.Double();
private Line2D.Double line1, line2, line3, line4;
private GeneralPath gp = null;
private static BasicStroke borderStroke = AwtFactoryD.getDefaultStrokeAwt();
private static BasicStroke[] crossStrokes = new BasicStroke[10];
public PointStyleListRenderer() {
setOpaque(true);
}
@Override
public Component getListCellRendererComponent(JList list, Object value,
int index, boolean isSelected, boolean cellHasFocus) {
// get the selected point style
pointStyle = value == null ? EuclidianStyleConstants.POINT_STYLE_DOT
: ((Integer) value).intValue();
if (isSelected) {
setBackground(Color.LIGHT_GRAY);
} else {
setBackground(Color.WHITE);
}
return this;
}
@Override
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
GGraphics2DD.setAntialiasing(g2);
// paint cell background
if (getBackground() == Color.LIGHT_GRAY) {
g2.setPaint(Color.LIGHT_GRAY);
} else {
g2.setPaint(Color.WHITE);
}
g2.fillRect(0, 0, getWidth(), getHeight());
// draw point using routine from euclidian.DrawPoint
g2.setPaint(Color.BLACK);
getPath();
switch (pointStyle) {
case EuclidianStyleConstants.POINT_STYLE_PLUS:
case EuclidianStyleConstants.POINT_STYLE_CROSS:
// draw cross like: X or +
g2.setStroke(crossStrokes[pointSize]);
g2.draw(line1);
g2.draw(line2);
break;
case EuclidianStyleConstants.POINT_STYLE_EMPTY_DIAMOND:
// draw diamond
g2.setStroke(crossStrokes[pointSize]);
g2.draw(line1);
g2.draw(line2);
g2.draw(line3);
g2.draw(line4);
break;
case EuclidianStyleConstants.POINT_STYLE_FILLED_DIAMOND:
case EuclidianStyleConstants.POINT_STYLE_TRIANGLE_NORTH:
case EuclidianStyleConstants.POINT_STYLE_TRIANGLE_SOUTH:
case EuclidianStyleConstants.POINT_STYLE_TRIANGLE_EAST:
case EuclidianStyleConstants.POINT_STYLE_TRIANGLE_WEST:
// draw diamond
g2.setStroke(crossStrokes[pointSize]);
g2.draw(gp);
g2.fill(gp);
break;
case EuclidianStyleConstants.POINT_STYLE_CIRCLE:
// draw a circle
g2.setStroke(crossStrokes[pointSize]);
g2.draw(circle);
break;
// case EuclidianStyleConstants.POINT_STYLE_CIRCLE:
default:
// draw a dot
g2.fill(circle);
g2.setStroke(borderStroke);
g2.draw(circle);
}
}
public void getPath() {
// clear old path
if (gp != null) {
gp.reset();
}
// set point size
pointSize = 4;
int diameter = 2 * pointSize;
// set coords = center of cell
double[] coords = new double[2];
coords[0] = getWidth() / 2.0;
coords[1] = getHeight() / 2.0;
// get draw path using routine from euclidian.DrawPoint
double xUL = coords[0] - pointSize;
double yUL = coords[1] - pointSize;
double root3over2 = Math.sqrt(3.0) / 2.0;
switch (pointStyle) {
case EuclidianStyleConstants.POINT_STYLE_DOT:
default:
// do nothing
break;
case EuclidianStyleConstants.POINT_STYLE_FILLED_DIAMOND:
double xR = coords[0] + pointSize;
double yB = coords[1] + pointSize;
if (gp == null) {
gp = new GeneralPath();
}
gp.moveTo((float) (xUL + xR) / 2, (float) yUL);
gp.lineTo((float) xUL, (float) (yB + yUL) / 2);
gp.lineTo((float) (xUL + xR) / 2, (float) yB);
gp.lineTo((float) xR, (float) (yB + yUL) / 2);
gp.closePath();
if (crossStrokes[pointSize] == null) {
crossStrokes[pointSize] = new BasicStroke(pointSize / 2f);
}
break;
case EuclidianStyleConstants.POINT_STYLE_TRIANGLE_SOUTH:
case EuclidianStyleConstants.POINT_STYLE_TRIANGLE_NORTH:
double direction = 1.0;
if (pointStyle == EuclidianStyleConstants.POINT_STYLE_TRIANGLE_NORTH) {
direction = -1.0;
}
if (gp == null) {
gp = new GeneralPath();
}
gp.moveTo((float) coords[0],
(float) (coords[1] + direction * pointSize));
gp.lineTo((float) (coords[0] + pointSize * root3over2),
(float) (coords[1] - direction * pointSize / 2));
gp.lineTo((float) (coords[0] - pointSize * root3over2),
(float) (coords[1] - direction * pointSize / 2));
gp.lineTo((float) coords[0],
(float) (coords[1] + direction * pointSize));
gp.closePath();
if (crossStrokes[pointSize] == null) {
crossStrokes[pointSize] = new BasicStroke(pointSize / 2f);
}
break;
case EuclidianStyleConstants.POINT_STYLE_TRIANGLE_EAST:
case EuclidianStyleConstants.POINT_STYLE_TRIANGLE_WEST:
direction = 1.0;
if (pointStyle == EuclidianStyleConstants.POINT_STYLE_TRIANGLE_WEST) {
direction = -1.0;
}
if (gp == null) {
gp = new GeneralPath();
}
gp.moveTo((float) (coords[0] + direction * pointSize),
(float) coords[1]);
gp.lineTo((float) (coords[0] - direction * pointSize / 2),
(float) (coords[1] + pointSize * root3over2));
gp.lineTo((float) (coords[0] - direction * pointSize / 2),
(float) (coords[1] - pointSize * root3over2));
gp.lineTo((float) (coords[0] + direction * pointSize),
(float) coords[1]);
gp.closePath();
if (crossStrokes[pointSize] == null) {
crossStrokes[pointSize] = new BasicStroke(pointSize / 2f);
}
break;
case EuclidianStyleConstants.POINT_STYLE_EMPTY_DIAMOND:
xR = coords[0] + pointSize;
yB = coords[1] + pointSize;
if (line1 == null) {
line1 = new Line2D.Double();
line2 = new Line2D.Double();
}
if (line3 == null) {
line3 = new Line2D.Double();
line4 = new Line2D.Double();
}
line1.setLine((xUL + xR) / 2, yUL, xUL, (yB + yUL) / 2);
line2.setLine(xUL, (yB + yUL) / 2, (xUL + xR) / 2, yB);
line3.setLine((xUL + xR) / 2, yB, xR, (yB + yUL) / 2);
line4.setLine(xR, (yB + yUL) / 2, (xUL + xR) / 2, yUL);
if (crossStrokes[pointSize] == null) {
crossStrokes[pointSize] = new BasicStroke(pointSize / 2f);
}
break;
case EuclidianStyleConstants.POINT_STYLE_PLUS:
xR = coords[0] + pointSize;
yB = coords[1] + pointSize;
if (line1 == null) {
line1 = new Line2D.Double();
line2 = new Line2D.Double();
}
line1.setLine((xUL + xR) / 2, yUL, (xUL + xR) / 2, yB);
line2.setLine(xUL, (yB + yUL) / 2, xR, (yB + yUL) / 2);
if (crossStrokes[pointSize] == null) {
crossStrokes[pointSize] = new BasicStroke(pointSize / 2f);
}
break;
case EuclidianStyleConstants.POINT_STYLE_CROSS:
xR = coords[0] + pointSize;
yB = coords[1] + pointSize;
if (line1 == null) {
line1 = new Line2D.Double();
line2 = new Line2D.Double();
}
line1.setLine(xUL, yUL, xR, yB);
line2.setLine(xUL, yB, xR, yUL);
if (crossStrokes[pointSize] == null) {
crossStrokes[pointSize] = new BasicStroke(pointSize / 2f);
}
break;
case EuclidianStyleConstants.POINT_STYLE_CIRCLE:
if (crossStrokes[pointSize] == null) {
crossStrokes[pointSize] = new BasicStroke(pointSize / 2f);
}
break;
}
// for circle points
circle.setFrame(xUL, yUL, diameter, diameter);
}
}