package org.archstudio.bna.things.utility;
import java.awt.geom.Arc2D;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Point2D;
import javax.media.opengl.GL;
import javax.media.opengl.GL2ES2;
import org.archstudio.bna.IBNAView;
import org.archstudio.bna.ICoordinate;
import org.archstudio.bna.ICoordinateMapper;
import org.archstudio.bna.things.AbstractThingPeer;
import org.archstudio.bna.ui.jogl.IJOGLResources;
import org.archstudio.bna.ui.swt.ISWTResources;
import org.archstudio.swtutils.constants.LineStyle;
import org.archstudio.sysutils.ExpandableFloatBuffer;
import org.archstudio.sysutils.SystemUtils;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.graphics.Rectangle;
public class RotaterThingPeer<T extends RotaterThing> extends AbstractThingPeer<T> {
protected static final int UNDERHANG = 4;
protected static final int WEDGE_SIZE = 15;
public RotaterThingPeer(T thing, IBNAView view, ICoordinateMapper cm) {
super(thing, view, cm);
}
@Override
public void draw(GL2ES2 gl, Rectangle localBounds, IJOGLResources r) {
Point2D lap = cm.worldToLocal(t.getAnchorPoint());
int Radius = t.getRadius();
int radius = Radius / 4;
int angle = t.getAngle();
float angleRadians = (float) Math.PI * angle / 180;
float error = 0.25f;
float radianDelta = (float) Math.acos(2 * (1 - error / Radius) * (1 - error / Radius) - 1);
r.pushMatrix(lap.getX(), lap.getY(), 0);
ExpandableFloatBuffer xyzVertices = new ExpandableFloatBuffer();
ExpandableFloatBuffer rgbaColors = new ExpandableFloatBuffer();
{ // background circle
xyzVertices.rewind();
rgbaColors.rewind();
float[] vertex = new float[] { 0, 0, 0 };
float[] colors = new float[] { 0, 0, 0, 0, 0, 0, 0, 0.25f };
for (float radians = 0; radians < 2f * Math.PI; radians += radianDelta) {
float x = (float) Math.cos(radians);
float y = (float) Math.sin(radians);
vertex[0] = x * radius;
vertex[1] = y * radius;
xyzVertices.put(vertex);
vertex[0] = x * (Radius - UNDERHANG);
vertex[1] = y * (Radius - UNDERHANG);
xyzVertices.put(vertex);
rgbaColors.put(colors);
}
float x = 1;
float y = 0;
vertex[0] = x * radius;
vertex[1] = y * radius;
xyzVertices.put(vertex);
vertex[0] = x * (Radius - UNDERHANG);
vertex[1] = y * (Radius - UNDERHANG);
xyzVertices.put(vertex);
rgbaColors.put(colors);
int points = xyzVertices.position() / 3;
xyzVertices.rewind();
rgbaColors.rewind();
r.fillShape(GL.GL_TRIANGLE_STRIP, xyzVertices.getBackingBuffer(), rgbaColors.getBackingBuffer(), points);
}
{ // outer circle edge
r.drawShape(new Ellipse2D.Double(-Radius + UNDERHANG, -Radius + UNDERHANG, 2 * (Radius - UNDERHANG) - 1,
2 * (Radius - UNDERHANG) - 1), new RGB(0, 0, 0), 1, LineStyle.SOLID, 1);
}
{ // red wedge
xyzVertices.rewind();
rgbaColors.rewind();
float[] vertex = new float[] { 0, 0, 0 };
float[] color = new float[] { 1, 0, 0, 0.5f };
xyzVertices.put(vertex);
rgbaColors.put(color);
color[3] = 1;
for (float radians = -WEDGE_SIZE * (float) Math.PI / 180; radians < WEDGE_SIZE * (float) Math.PI / 180; radians += radianDelta) {
float x = (float) Math.cos(radians + angleRadians) * Radius;
float y = (float) Math.sin(radians + angleRadians) * Radius;
vertex[0] = x;
vertex[1] = y;
xyzVertices.put(vertex);
rgbaColors.put(color);
}
float radians = WEDGE_SIZE * (float) Math.PI / 180;
float x = (float) Math.cos(radians + angleRadians) * Radius;
float y = (float) Math.sin(radians + angleRadians) * Radius;
vertex[0] = x;
vertex[1] = y;
xyzVertices.put(vertex);
rgbaColors.put(color);
int points = xyzVertices.position() / 3;
xyzVertices.rewind();
rgbaColors.rewind();
r.fillShape(GL.GL_TRIANGLE_FAN, xyzVertices.getBackingBuffer(), rgbaColors.getBackingBuffer(), points);
}
r.popMatrix();
}
@Override
public void draw(GC gc, Rectangle localBounds, ISWTResources r) {
Point2D lap = cm.worldToLocal(t.getAnchorPoint());
int radius = t.getRadius();
int angle = t.getAngle();
Rectangle o;
o = new Rectangle(SystemUtils.round(lap.getX()) - (radius - UNDERHANG), SystemUtils.round(lap.getY())
- (radius - UNDERHANG), 2 * (radius - UNDERHANG), 2 * (radius - UNDERHANG));
gc.setAlpha(64);
gc.setBackground(gc.getDevice().getSystemColor(SWT.COLOR_GRAY));
gc.fillOval(o.x, o.y, o.width, o.height);
gc.setAlpha(255);
gc.setForeground(gc.getDevice().getSystemColor(SWT.COLOR_BLACK));
gc.drawOval(o.x, o.y, o.width, o.height);
o = new Rectangle(SystemUtils.round(lap.getX()) - radius, SystemUtils.round(lap.getY()) - radius, 2 * radius,
2 * radius);
r.fillShape(new Arc2D.Double(o.x, o.y, o.width, o.height, -angle - WEDGE_SIZE, WEDGE_SIZE * 2, Arc2D.PIE),
new RGB(255, 0, 0), new RGB(255, 0, 0), 0.5);
}
@Override
public boolean isInThing(ICoordinate location) {
Point2D lap = cm.worldToLocal(t.getAnchorPoint());
int radius = t.getRadius();
Point lLocation = location.getLocalPoint();
float distance = (float) Point2D.distance(lap.getX(), lap.getY(), lLocation.x, lLocation.y);
return distance <= radius;
}
}