package org.freeplane.view.swing.map;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.geom.Ellipse2D;
interface Drawable{
void draw(Graphics2D g, NodeView nodeView, Rectangle r);
}
class DrawableNothing implements Drawable{
public void draw(Graphics2D g, NodeView nodeView, Rectangle r) {
}
}
abstract class DrawableShape implements Drawable{
private final Color fillColor;
public DrawableShape(Color fillColor) {
this.fillColor = fillColor;
}
public void draw(Graphics2D g, NodeView nodeView, Rectangle r) {
final Color color = g.getColor();
final Color edgeColor = nodeView.getEdgeColor();
final Shape shape = getShape(r);
g.setColor(getFillColor(nodeView));
g.fill(shape);
g.setColor(edgeColor);
drawShape(g, shape, r, nodeView);
g.setColor(color);
}
protected void drawShape(Graphics2D g, final Shape shape, Rectangle r, NodeView nodeView) {
g.draw(shape);
}
abstract Shape getShape(Rectangle r);
protected Color getFillColor(NodeView nodeView) {
return fillColor;
}
}
class DrawableEllipse extends DrawableShape{
public DrawableEllipse(Color fillColor) {
super(fillColor);
}
Shape getShape(Rectangle r){
return new Ellipse2D.Float(r.x, r.y, r.width, r.height);
}
}
class FoldingCircle extends DrawableEllipse{
final private boolean folded;
final private boolean hiddenChild;
public FoldingCircle(Color fillColor, boolean folded, boolean hiddenChild) {
super(fillColor);
this.folded = folded;
this.hiddenChild =hiddenChild;
}
@Override
protected void drawShape(Graphics2D g, Shape shape, Rectangle r, NodeView nodeView) {
super.drawShape(g, shape, r, nodeView);
if(nodeView.isRoot() & ! folded)
return;
if(! nodeView.getMainView().getMouseArea().equals(MouseArea.FOLDING))
g.setColor(nodeView.getEdgeColor());
else
g.setColor(super.getFillColor(nodeView));
if(! hiddenChild)
g.drawLine(r.x + r.width / 4, r.y + r.height / 2, r.x + r.width * 3/ 4, r.y + r.height / 2);
if(folded || hiddenChild)
g.drawLine(r.x + r.width / 2, r.y + r.height / 4, r.x + r.width / 2, r.y + r.height * 3 / 4);
}
@Override
protected Color getFillColor(NodeView nodeView) {
if(nodeView.getMainView().getMouseArea().equals(MouseArea.FOLDING)){
return Color.GRAY;
}
return super.getFillColor(nodeView);
}
}
class DrawableTriangle extends DrawableShape{
public DrawableTriangle(Color fillColor) {
super(fillColor);
}
Shape getShape(Rectangle r){
final Polygon polygon = new Polygon();
polygon.addPoint(r.x, r.y);
polygon.addPoint(r.x + r.width, r.y);
polygon.addPoint(r.x + (r.width + 1) / 2, r.y + r.height);
polygon.addPoint(r.x + r.width / 2, r.y + r.height);
polygon.addPoint(r.x, r.y);
return polygon;
}
}
public enum FoldingMark implements Drawable{
UNFOLDED(new DrawableNothing()), ITSELF_FOLDED(new DrawableEllipse(Color.WHITE)), UNVISIBLE_CHILDREN_FOLDED(new DrawableEllipse(Color.GRAY)),
SHORTENED(new DrawableTriangle(Color.WHITE)),
FOLDING_CIRCLE_FOLDED(new FoldingCircle(Color.WHITE, true, false)), FOLDING_CIRCLE_UNFOLDED(new FoldingCircle(Color.WHITE, false, false)),
FOLDING_CIRCLE_HIDDEN_CHILD(new FoldingCircle(Color.WHITE, false, true));
final Drawable drawable;
FoldingMark(Drawable drawable){
this.drawable = drawable;
}
public void draw(Graphics2D g, NodeView nodeView, Rectangle r) {
drawable.draw(g, nodeView, r);
}
}