package com.kreative.paint.tool; import java.awt.Cursor; import java.awt.Graphics2D; import java.awt.Image; import java.awt.event.KeyEvent; import com.kreative.paint.document.draw.ShadowSettings; import com.kreative.paint.document.draw.ShapeDrawObject; import com.kreative.paint.geom.draw.RegularPolygonDrawObject; public class RegularPolygonTool extends AbstractPaintDrawTool implements ToolOptions.DrawPerpendicular, ToolOptions.DrawFromCenter, ToolOptions.DrawMultiple, ToolOptions.QuickShadow, ToolOptions.RegPolygon { private static final int K = 0xFF000000; private static final Image icon = ToolUtilities.makeIcon( 16, 16, new int[] { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,K,K,0,0,0,0,0,0,0, 0,0,0,0,0,K,K,0,0,K,K,0,0,0,0,0, 0,0,0,K,K,0,0,0,0,0,0,K,K,0,0,0, 0,K,K,0,0,0,0,0,0,0,0,0,0,K,K,0, 0,K,0,0,0,0,0,0,0,0,0,0,0,0,K,0, 0,K,0,0,0,0,0,0,0,0,0,0,0,0,K,0, 0,K,0,0,0,0,0,0,0,0,0,0,0,0,K,0, 0,K,0,0,0,0,0,0,0,0,0,0,0,0,K,0, 0,K,0,0,0,0,0,0,0,0,0,0,0,0,K,0, 0,K,0,0,0,0,0,0,0,0,0,0,0,0,K,0, 0,K,K,0,0,0,0,0,0,0,0,0,0,K,K,0, 0,0,0,K,K,0,0,0,0,0,0,K,K,0,0,0, 0,0,0,0,0,K,K,0,0,K,K,0,0,0,0,0, 0,0,0,0,0,0,0,K,K,0,0,0,0,0,0,0, } ); private static final Cursor curs = Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR); public ToolCategory getCategory() { return ToolCategory.SHAPE; } protected Image getBWIcon() { return icon; } private ShapeDrawObject makeShape(ToolEvent e) { float sx = e.getPreviousClickedX(); float sy = e.getPreviousClickedY(); float x = e.getX(); float y = e.getY(); if (e.isShiftDown() != e.tc().drawPerpendicular()) { double t = Math.toDegrees(Math.atan2(y-sy, x-sx)); int q = (int)Math.round(t / 15.0); switch (q) { case -12: case 0: case 12: y = sy; break; case -18: case -6: case 6: case 18: x = sx; break; case -21: case -15: case -9: case -3: case 3: case 9: case 15: case 21: { float w = Math.abs(x-sx); float h = Math.abs(y-sy); float s = Math.max(w, h); if (y > sy) y = sy+s; else y = sy-s; if (x > sx) x = sx+s; else x = sx-s; } break; case -23: case -22: case -14: case -13: case -11: case -10: case -2: case -1: case 1: case 2: case 10: case 11: case 13: case 14: case 22: case 23: { // x is fine, but find a new y double a = Math.toRadians(Math.round(t / 15.0) * 15.0); y = sy + (x-sx) * (float)Math.tan(a); } break; case -20: case -19: case -17: case -16: case -8: case -7: case -5: case -4: case 4: case 5: case 7: case 8: case 16: case 17: case 19: case 20: { // y is fine, but find a new x double a = Math.toRadians(Math.round(t / 15.0) * 15.0); x = sx + (y-sy) / (float)Math.tan(a); } break; } } return new RegularPolygonDrawObject( e.getPaintSettings(), e.tc().getPolygonSides(), e.tc().getPolygonStellation(), sx, sy, x, y, e.isAltDown() != e.tc().drawFromCenter() ); } private ShapeDrawObject makeObject(ToolEvent e) { ShapeDrawObject sh = makeShape(e); if (e.tc().useShadow()) { sh.setShadowSettings(new ShadowSettings( e.tc().getShadowType(), e.tc().getShadowOpacity(), e.tc().getShadowXOffset(), e.tc().getShadowYOffset() )); } return sh; } public boolean mousePressed(ToolEvent e) { e.beginTransaction(getName()); if (e.isCtrlDown() != e.tc().drawMultiple()) { ShapeDrawObject wsh = makeObject(e); if (e.isInDrawMode()) e.getDrawSurface().add(wsh); else wsh.paint(e.getPaintGraphics()); return true; } else return false; } public boolean mouseDragged(ToolEvent e) { if (e.isCtrlDown() != e.tc().drawMultiple()) { ShapeDrawObject wsh = makeObject(e); if (e.isInDrawMode()) e.getDrawSurface().add(wsh); else wsh.paint(e.getPaintGraphics()); return true; } else return false; } public boolean mouseReleased(ToolEvent e) { ShapeDrawObject wsh = makeObject(e); if (e.isInDrawMode()) e.getDrawSurface().add(wsh); else wsh.paint(e.getPaintGraphics()); e.commitTransaction(); return true; } public boolean paintIntermediate(ToolEvent e, Graphics2D g) { if (e.isMouseDown()) { ShapeDrawObject wsh = makeObject(e); wsh.paint(g); return true; } else return false; } public boolean keyPressed(ToolEvent e) { switch (e.getKeyCode()) { case KeyEvent.VK_LEFT: case KeyEvent.VK_DOWN: e.tc().decrementPolygonSides(); break; case KeyEvent.VK_RIGHT: case KeyEvent.VK_UP: e.tc().incrementPolygonSides(); break; case KeyEvent.VK_PLUS: case KeyEvent.VK_ADD: case KeyEvent.VK_EQUALS: e.tc().incrementPolygonStellation(); break; case KeyEvent.VK_MINUS: case KeyEvent.VK_SUBTRACT: e.tc().decrementPolygonStellation(); break; case KeyEvent.VK_3: e.tc().setPolygonSides(3); break; case KeyEvent.VK_4: e.tc().setPolygonSides(4); break; case KeyEvent.VK_5: e.tc().setPolygonSides(5); break; case KeyEvent.VK_6: e.tc().setPolygonSides(6); break; case KeyEvent.VK_7: e.tc().setPolygonSides(7); break; case KeyEvent.VK_8: e.tc().setPolygonSides(8); break; case KeyEvent.VK_9: e.tc().setPolygonSides(9); break; case KeyEvent.VK_0: e.tc().setPolygonSides(10); break; case KeyEvent.VK_1: e.tc().setPolygonSides(11); break; case KeyEvent.VK_2: e.tc().setPolygonSides(12); break; } if (e.isMouseDown() && e.isCtrlDown() != e.tc().drawMultiple()) { ShapeDrawObject wsh = makeObject(e); if (e.isInDrawMode()) e.getDrawSurface().add(wsh); else wsh.paint(e.getPaintGraphics()); return true; } return false; } public boolean keyReleased(ToolEvent e) { if (e.isMouseDown() && e.isCtrlDown() != e.tc().drawMultiple()) { ShapeDrawObject wsh = makeObject(e); if (e.isInDrawMode()) e.getDrawSurface().add(wsh); else wsh.paint(e.getPaintGraphics()); return true; } else return false; } public boolean doubleClickForOptions() { return true; } public Cursor getCursor(ToolEvent e) { return curs; } }