/** * Circle.java * Copyright (C) 2010 New Zealand Digital Library, http://expeditee.org * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package org.expeditee.items; import java.util.Collection; import java.util.LinkedList; import org.expeditee.core.Colour; import org.expeditee.core.Dimension; import org.expeditee.core.Fill; import org.expeditee.core.Point; import org.expeditee.core.Stroke; import org.expeditee.core.bounds.AxisAlignedBoxBounds; import org.expeditee.core.bounds.EllipticalBounds; import org.expeditee.core.bounds.PolygonBounds; import org.expeditee.gio.EcosystemManager; /** * @author root * */ public class Circle extends XRayable { private Item _center; private Line _line; /** * Construct a circle * * @param _source */ public Circle(Text source) { super(source); // Collection connected = source.getAllConnected(); // assert (connected.size() == 4); _line = source.getLines().get(0); _center = _line.getOppositeEnd(_source); _center.addEnclosure(this); _line.setHidden(true); invalidateBounds(); } public Collection getItemsToSave() { Collection toSave = super.getItemsToSave(); toSave.add(_center); return toSave; } @Override public Collection getConnected() { Collection conn = super.getConnected(); conn.add(_center); conn.add(_line); return conn; } @Override public void addAllConnected(Collection connected) { super.addAllConnected(connected); if (!connected.contains(_center)) { connected.add(_center); connected.add(_line); } } @Override public boolean isFloating() { return _center.isFloating() || super.isFloating(); } @Override public boolean isEnclosed() { return true; } @Override public PolygonBounds getEnclosedShape() { // assert(_poly != null); // Ensure that vector items will gradient fill are painted OK!! return ((EllipticalBounds) updateBounds()).getPolygon(16); } @Override public double getEnclosedArea() { double radius = getRadius(); return Math.PI * radius * radius; } @Override public Collection getEnclosingDots() { Collection enclosed = new LinkedList(); enclosed.add(this); enclosed.add(_center); return enclosed; } /* * (non-Javadoc) * * @see org.expeditee.items.Item#copy() */ @Override public Item copy() { Collection toCopy = new LinkedList(); toCopy.add(_source); toCopy.add(_line); toCopy.add(_center); Collection newItems = ItemUtils.CopyItems(toCopy); assert (newItems.size() == 3); // find the Source item from the three items Text newSource = null; for (Item i : newItems) { if (i instanceof Text) { newSource = (Text) i; if (ItemUtils.startsWithTag(i, "@c")) break; } } assert (newSource != null); Circle newCircle = new Circle(newSource); Item.DuplicateItem(this, newCircle); newCircle._line.setVisible(_line.isVisible()); newCircle._source.setVisible(_source.isVisible()); newCircle.invalidateBounds(); return newCircle; } /** * Gets the radius of this circle. * * @return the radius of the cicle */ public double getRadius() { return _line.getLength(); } @Override public boolean contains(Point p) { double radius = getRadius(); double distance = Math.sqrt(Math.pow(Math.abs(_center.getX() - p.getX()), 2) + Math.pow(Math.abs(_center.getY() - p.getY()), 2)); return Math.abs(distance - radius) < getGravity() * 2; } /* * (non-Javadoc) * * @see org.expeditee.items.Item#paint(java.awt.Graphics2D) */ @Override public void paint() { int radius = (int) Math.round(getRadius()); Point centre = new Point(_center.getX(), _center.getY()); Dimension diameters = new Dimension(radius * 2, radius * 2); Fill fill = new Fill(getFillColor()); Colour lineColour = null; Stroke lineStroke = null; if (isHighlighted()) { lineColour = getHighlightColor(); lineStroke = HIGHLIGHT_STROKE; } else if (getThickness() > 0 || getFillColor() == null) { lineColour = getPaintColor(); lineStroke = _line.getStroke(); } EcosystemManager.getGraphicsManager().drawOval(centre, diameters, 0.0f, fill, lineColour, lineStroke); if (isHighlighted()) { _center.paint(); } } @Override public void setHighlightModeAndColour(HighlightMode mode, Colour color) { _center.setHighlightModeAndColour(mode, color); super.setHighlightModeAndColour(mode, color); } @Override public void setHighlightColor(Colour c) { _center.setHighlightColor(c); /*return*/ super.setHighlightColor(c); } @Override public void setFillColor(Colour c) { super.setFillColor(c); _center.setColor(c); invalidateCommonTrait(ItemAppearence.FillColor); } @Override public void setGradientColor(Colour c) { super.setGradientColor(c); invalidateCommonTrait(ItemAppearence.GradientColor); } // @Override // public void setPosition(float x, float y) { // // float deltaX = x - _source._x; // // float deltaY = y - _source._y; // // _center.setPosition(_center._x + deltaX, _center._y + deltaY); // _source.setPosition(x, y); // // updatePolygon(); // } // TODO use an algorithm to get more precicely for contains and intersects /* * (non-Javadoc) * * @see org.expeditee.items.Item#setAnnotation(boolean) */ @Override public void setAnnotation(boolean val) { // TODO Auto-generated method stub } /* * (non-Javadoc) * * @see org.expeditee.items.Item#updatePolygon() */ @Override public EllipticalBounds updateBounds() { return new EllipticalBounds(_center.getPosition(), (int) (getRadius() * 2)); } @Override public float getSize() { return (float) getRadius(); } /** Resizes the circle from the center. */ @Override public void setSize(float size) { double ratio = size / getRadius(); // Extend the line along the same plane as the underlying line _source.translate(_center.getPosition(), ratio); invalidateBounds(); } @Override public void setLinePattern(int[] pattern) { _line.setLinePattern(pattern); } @Override public int[] getLinePattern() { return _line.getLinePattern(); } // TODO: Why is this commented out? cts16 @Override public void translate(Point origin, double ratio) { invalidateBounds(); // _center.translate(origin, ratio); // super.translate(origin, ratio); } @Override public AxisAlignedBoxBounds getDrawingArea() { float thickness = getThickness(); double radius = getRadius(); int size = (int) ((2 * radius) + 3.0 + thickness); return new AxisAlignedBoxBounds((int) (_center.getX() - radius - 0.5 - (thickness / 2.0)), (int) (_center.getY() - radius - 0.5 - (thickness / 2.0)), size, size); } // @Override // public void setPosition(float x, float y){ // float deltaX = x - _source._x; // float deltaY = y = _source._y; // _center.setPosition(deltaX, deltaY); // super.setPosition(x,y); // } public Item getCenter() { return _center; } @Override public void setPermission(PermissionTriple permissionPair) { super.setPermission(permissionPair); _center.setPermission(permissionPair); _line.setPermission(permissionPair); } @Override public void scale(Float scale, int originX, int originY) { getCenter().scale(scale, originX, originY); super.scale(scale, originX, originY); } @Override public void setThickness(float thick, boolean setConnected) { super.setThickness(thick, setConnected); _line.refreshStroke(thick); } @Override public boolean isConnectedToAnnotation() { return false; } }