package nodebox.handle;
import nodebox.graphics.GraphicsContext;
import nodebox.graphics.Point;
import nodebox.util.Geometry;
public class CircleScaleHandle extends AbstractHandle {
public enum Mode {
RADIUS, DIAMETER
}
private boolean dragging = false;
private String radiusName;
private String positionName = null;
private Mode mode;
private Point pt = null;
public CircleScaleHandle() {
this("radius", Mode.RADIUS);
}
public CircleScaleHandle(String radiusName) {
this(radiusName, Mode.RADIUS);
}
public CircleScaleHandle(Mode mode) {
this("radius", mode);
}
public CircleScaleHandle(String radiusName, Mode mode) {
this(radiusName, mode, null);
}
public CircleScaleHandle(String radiusName, Mode mode, String positionName) {
this.radiusName = radiusName;
this.mode = mode;
this.positionName = positionName;
}
private Point getCenter() {
if (positionName != null)
return (Point) getValue(positionName);
else
return Point.ZERO;
}
private double getRadius() {
double val = (Double) getValue(radiusName);
if (mode == Mode.DIAMETER)
return Math.abs(val / 2);
return Math.abs(val);
}
public void draw(GraphicsContext ctx) {
Point center = getCenter();
double x = center.x;
double y = center.y;
double radius = getRadius();
ctx.nofill();
ctx.ellipsemode(GraphicsContext.EllipseMode.CENTER);
ctx.stroke(HANDLE_COLOR);
ctx.ellipse(x, y, radius * 2, radius * 2);
if (pt != null)
drawDot(ctx, pt.x, pt.y);
}
@Override
public boolean mousePressed(Point pt) {
this.pt = null;
double radius = getRadius();
Point center = getCenter();
float d = (float) Geometry.distance(center.x, center.y, pt.x, pt.y);
dragging = (radius - 4 <= d && d <= radius + 4);
return dragging;
}
@Override
public boolean mouseDragged(Point pt) {
if (!dragging) return false;
Point center = getCenter();
float newSize = (float) Geometry.distance(center.x, center.y, pt.x, pt.y);
if (mode == Mode.DIAMETER)
newSize *= 2;
if (newSize == getRadius()) return false;
silentSet(radiusName, newSize);
this.pt = pt;
return true;
}
@Override
public boolean mouseReleased(Point pt) {
if (!dragging) return false;
dragging = false;
this.pt = null;
updateHandle();
return true;
}
@Override
public boolean mouseMoved(Point pt) {
Point center = getCenter();
double x = center.x;
double y = center.y;
double radius = getRadius();
float d = (float) Geometry.distance(x, y, pt.x, pt.y);
if (radius - 4 <= d && d <= radius + 4) {
float a = (float) Geometry.angle(x, y, pt.x, pt.y);
double[] xy;
xy = Geometry.coordinates(x, y, radius, a);
this.pt = new Point((float) xy[0], (float) xy[1]);
} else {
this.pt = null;
}
updateHandle();
return true;
}
}