package com.nwoods.jgo.examples.demo1;
import java.awt.;
import java.awt.geom.;
import com.nwoods.jgo.;
public class RotatablePolygon extends JGoPolygon {
public RotatablePolygon() {}
public void rotate(float cx, float cy, double angle) { // angle is in Radians, clockwise
if (angle == 0) return;
double rad = angle;
double cosine = Math.cos(rad);
double sine = Math.sin(rad);
int numpts = getNumPoints();
foredate(JGoStroke.ChangedAllPoints);
setSuspendUpdates(true);
Point2D.Float temp = new Point2D.Float();
for (int i = 0; i < numpts; i++) {
Point p = getPoint(i);
rotatePoint(p.x, p.y, cx, cy, cosine, sine, temp);
setPoint(i, Math.round(temp.x), Math.round(temp.y));
}
setBoundingRectInvalid(true);
setSuspendUpdates(false);
update(JGoStroke.ChangedAllPoints, 0, null);
setAngleInternal(getAngle() + angle);
}
public static Point2D.Float rotatePoint(float px, float py, float cx, float cy, double cosine, double sine, Point2D.Float result) {
if (px == cx && py == cy) {
result.x = px;
result.y = py;
} else {
double dx = (double)px-(double)cx;
double dy = (double)py-(double)cy;
result.x = (float)(cx + cosinedx - sinedy);
result.y = (float)(cy + sinedx + cosinedy);
}
return result;
}
private void setAngleInternal(double angle) {
double old = getAngle();
if (angle >= Math.PI2) angle -= Math.PI2;
else if (angle < 0) angle += Math.PI2;
if (old != angle) {
myAngle = angle;
update(ChangedAngle, 0, new Double(old));
}
}
public double getAngle() { return myAngle; }
public void setAngle(double value) {
double old = myAngle;
if (old != value) {
rotate(getLeft() + getWidth()/2.0f, getTop() + getHeight()/2.0f, value-old);
}
}
protected void gainedSelection(JGoSelection selection) {
if (!isResizable()) {
selection.createBoundingHandle(this);
} else {
if (isReshapable()) {
super.gainedSelection(selection);
} else {
Rectangle rect = getBoundingRect();
int x1 = rect.x;
int x2 = rect.x + (rect.width/2);
int x3 = rect.x + rect.width;
int y1 = rect.y;
int y2 = rect.y + (rect.height/2);
int y3 = rect.y + rect.height;
// create the handles
selection.createResizeHandle(this, x1,y1, TopLeft, true);
selection.createResizeHandle(this, x3,y1, TopRight, true);
selection.createResizeHandle(this, x1,y3, BottomLeft, true);
selection.createResizeHandle(this, x3,y3, BottomRight, true);
// if we’re supposed to, create the middle line handles
if (!is4ResizeHandles()) {
selection.createResizeHandle(this, x2,y1, TopMiddle, true);
selection.createResizeHandle(this, x3,y2, SideRight, true);
selection.createResizeHandle(this, x2,y3, BottomMiddle, true);
selection.createResizeHandle(this, x1,y2, SideLeft, true);
}
}
}
}
public boolean isReshapable() { return myReshapable; }
public void setReshapable(boolean value) {
boolean old = myReshapable;
if (old != value) {
myReshapable = value;
update(ChangedReshapable, (old ? 1 : 0), null);
}
}
public void copyNewValueForRedo(JGoDocumentChangedEdit e) {
switch (e.getFlags()) {
case ChangedReshapable:
e.setNewValueBoolean(isReshapable());
return;
case ChangedAngle:
e.setNewValueDouble(getAngle());
return;
default:
super.copyNewValueForRedo(e);
return;
}
}
public void changeValue(JGoDocumentChangedEdit e, boolean undo) {
switch (e.getFlags()) {
case ChangedReshapable:
setReshapable(e.getValueBoolean(undo));
return;
case ChangedAngle:
setAngle(e.getValueDouble(undo));
return;
default:
super.changeValue(e, undo);
return;
}
}
public static final int ChangedReshapable = LastChangedHint + 2323;
public static final int ChangedAngle = LastChangedHint + 2324;
// RotatablePolygon state
private boolean myReshapable = true;
private double myAngle = 0; // in radians
}