/* * Jitsi, the OpenSource Java VoIP and Instant Messaging client. * * Copyright @ 2015 Atlassian Pty Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package net.java.sip.communicator.plugin.whiteboard.gui.whiteboardshapes; import java.awt.*; import java.awt.geom.*; import java.util.*; import java.util.List; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.whiteboardobjects.*; /** * a WhiteboardShapeCircle, in XML : * <circle id="" cx="cx" cy="cy" r="l" /> * * @author Julien Waechter */ public class WhiteboardShapeCircle extends WhiteboardShape implements WhiteboardObjectCircle { /** * True is filled, false is unfilled. */ private boolean fill; /** * The coordinates of this object. */ private WhiteboardPoint whiteboardPoint; /** * The background color of this object */ private int backColor; /** * The number of pixels for the radius. */ private double radius; /** * Stores all selection points for this shape. */ private ArrayList<WhiteboardPoint> selectionPoints = new ArrayList<WhiteboardPoint>(); /** * WhiteboardShapeCircle constructor * * @param id String that uniquely identifies this WhiteboardObject. * @param t number of pixels that this object (or its border) * should be thick. * @param c WhiteboardShape's color (or rather it's border). * @param whiteboardPoint coordinates of this object. * @param radius The number of pixels for the radius. * @param fill True is filled, false is unfilled. */ public WhiteboardShapeCircle (String id, int t, Color c, WhiteboardPoint whiteboardPoint, double radius, boolean fill) { super (id); initShape(t, c, whiteboardPoint, radius, fill); } /** * WhiteboardShapeCircle constructor * * @param id String that uniquely identifies this WhiteboardObject. * @param thickness number of pixels that this object (or its border) * should be thick. * @param color WhiteboardShape's color (or rather it's border) * @param whiteboardPoint coordinates of this object. * @param radius The number of pixels for the radius. * @param fill True is filled, false is unfilled. * @param v2w 2D affine transform */ public WhiteboardShapeCircle ( String id, int thickness, Color color, WhiteboardPoint whiteboardPoint, int radius, boolean fill, AffineTransform v2w) { super(id); Point2D v0 = new Point2D.Double ( whiteboardPoint.getX (), whiteboardPoint.getY ()); Point2D w0 = v2w.transform (v0, null); WhiteboardPoint point = new WhiteboardPoint (w0.getX (),w0.getY ()); Point2D v1 = new Point2D.Double ( whiteboardPoint.getX () + radius, whiteboardPoint.getY ()); Point2D w1 = v2w.transform (v1, null); double r = w1.getX () - whiteboardPoint.getX (); initShape(thickness, color, point, r, fill); } /** * Initialize shape. * * @param thickness number of pixels that this object (or its border) * should be thick. * @param color WhiteboardShape's color (or rather it's border). * @param whiteboardPoint coordinates of this object. * @param radius The number of pixels for the radius. * @param fill True is filled, false is unfilled. */ private void initShape( int thickness, Color color, WhiteboardPoint whiteboardPoint, double radius, boolean fill) { setThickness (thickness); setColor (color); setWhiteboardPoint (whiteboardPoint); setRadius (radius); setFill (fill); this.recalculateSelectionPoints(); } /** * Returns the "bounding-box" of the circle * * @param w2v 2D affine transform * @return view rectangle */ private int[] getViewRect (AffineTransform w2v) { double cx = getWhiteboardPoint ().getX (); double cy = getWhiteboardPoint ().getY (); double r = getRadius (); Point2D wx0 = new Point2D.Double (cx - r, cy); Point2D wy0 = new Point2D.Double (cx, cy - r); Point2D wx1 = new Point2D.Double (cx + r, cy); Point2D wy1 = new Point2D.Double (cx, cy + r); Point2D vx0 = w2v.transform (wx0, null); Point2D vy0 = w2v.transform (wy0, null); Point2D vx1 = w2v.transform (wx1, null); Point2D vy1 = w2v.transform (wy1, null); int ix = (int) vx0.getX (); int iy = (int) vy0.getY (); int iwidth = (int) vx1.getX () - ix; int iheight = (int) vy1.getY () - iy ; return new int[] {ix, iy, iwidth, iheight}; } /** * Code to paint this WhiteboardShapeCircle * * @param g graphics context * @param t 2D affine transform */ @Override public void paintShape (Graphics2D g, AffineTransform t) { g.setStroke (new BasicStroke (this.getThickness (), BasicStroke.CAP_ROUND,BasicStroke.CAP_ROUND)); int[] view = getViewRect (t); if (fill) { g.fillOval (view[0], view[1], view[2], view[3]); } else { g.drawOval (view[0], view[1], view[2], view[3]); } } /** * Tests if the shape contains a point * * @param p coord point * @return true if shape contains p */ @Override public boolean contains (Point2D p) { double cx = getWhiteboardPoint ().getX (); double cy = getWhiteboardPoint ().getY (); double r = getRadius (); Ellipse2D ellipse = new Ellipse2D.Double (cx-r, cy-r, 2*r, 2*r); return ellipse.contains (p); } /** * Tests if a point p is on a selection point. * * @param p point * @return the nearest selection point */ @Override public WhiteboardPoint getSelectionPoint (Point2D p) { WhiteboardPoint givenPoint = new WhiteboardPoint(p.getX(), p.getY()); for (WhiteboardPoint point : selectionPoints) if (point.distance(givenPoint) < 10) return point; return null; } /** * Returns the list of selected points * * @return list of selected points */ @Override public List<WhiteboardPoint> getSelectionPoints () { return selectionPoints; } /** * Translates the shape * * @param deltaX x coordinates * @param deltaY y coordinates */ @Override public void translate (double deltaX, double deltaY) { double cx = getWhiteboardPoint ().getX (); double cy = getWhiteboardPoint ().getY (); this.getWhiteboardPoint().setX(cx + deltaX); this.getWhiteboardPoint().setY(cy + deltaY); this.recalculateSelectionPoints(); } /** * Translates a point from the shape * * @param deltaX x coordinate * @param deltaY y coordinate */ @Override public void translateSelectedPoint (double deltaX, double deltaY) { WhiteboardPoint modifyPoint = getModifyPoint(); if (modifyPoint == null) return; double cx = getWhiteboardPoint ().getX (); double cy = getWhiteboardPoint ().getY (); double r = getRadius (); if (modifyPoint.getX() == cx - r && modifyPoint.getY() == cy) { r -= deltaX; modifyPoint.setX(cx - r); } else if (modifyPoint.getX() == cx + r && modifyPoint.getY() == cy) { r += deltaX; modifyPoint.setX(cx + r); } else if (modifyPoint.getX() == cx && modifyPoint.getY() == cy - r) { r -= deltaY; modifyPoint.setY(cy - r); } else if (modifyPoint.getX() == cx && modifyPoint.getY() == cy + r) { r += deltaY; modifyPoint.setY(cy + r); } this.setRadius (r); this.setModifyPoint(modifyPoint); this.recalculateSelectionPoints(); } /** * Returns the coordinates of this whiteboard object. * * @return the coordinates of this object. */ public WhiteboardPoint getWhiteboardPoint () { return whiteboardPoint; } /** * Sets the coordinates of this whiteboard object. * * @param whiteboardPoint the coordinates of this object. */ public void setWhiteboardPoint (WhiteboardPoint whiteboardPoint) { this.whiteboardPoint = whiteboardPoint; } /** * Returns the radius (in pixels) of this whiteboard circle. * * @return the number of pixels for the radius. */ public double getRadius () { return this.radius; } /** * Sets the radius (in pixels) of this whiteboard circle. * * @param radius the number of pixels for the radius. */ public void setRadius (double radius) { this.radius = radius; } /** * Returns the fill state of the WhiteboardObject. * * @return True is filled, false is unfilled. */ public boolean isFill () { return this.fill; } /** * Sets the fill state of the WhiteboardObject. * True is filled, false is unfilled. * * @param fill The new fill state. */ public void setFill (boolean fill) { this.fill = fill; } /** * Specifies the background color for this object. The color parameter * must be encoded with standard RGB encoding: bits 24-31 are alpha, 16-23 * are red, 8-15 are green, 0-7 are blue. * * @param backColor the color that we'd like to set for the background of this * <tt>WhiteboardObject</tt> (using standard RGB encoding). */ public void setBackgroundColor (int backColor) { this.backColor = backColor; } /** * Returns an integer representing the background color of this object. The * return value uses standard RGB encoding: bits 24-31 are alpha, 16-23 are * red, 8-15 are green, 0-7 are blue. * * @return the RGB value of the background color of this object. */ public int getBackgroundColor () { return this.backColor; } /** * Recalculates the selection points coordinates and adds the new selection * points to the list of selection points. */ private void recalculateSelectionPoints() { selectionPoints.clear(); selectionPoints.add ( new WhiteboardPoint ( whiteboardPoint.getX() - radius, whiteboardPoint.getY())); selectionPoints.add ( new WhiteboardPoint ( whiteboardPoint.getX(), whiteboardPoint.getY() - radius)); selectionPoints.add ( new WhiteboardPoint ( whiteboardPoint.getX() + radius, whiteboardPoint.getY())); selectionPoints.add ( new WhiteboardPoint ( whiteboardPoint.getX(), whiteboardPoint.getY() + radius)); } }