001    // GraphLab Project: http://graphlab.sharif.edu
002    // Copyright (C) 2008 Mathematical Science Department of Sharif University of Technology
003    // Distributed under the terms of the GNU General Public License (GPL): http://www.gnu.org/licenses/
004    package graphlab.graph.old;
005    
006    import graphlab.graph.graph.EdgeModel;
007    import graphlab.graph.graph.GraphPoint;
008    import graphlab.graph.graph.VertexModel;
009    import graphlab.platform.lang.ArrayX;
010    import graphlab.platform.lang.FromStringProvider;
011    import graphlab.platform.preferences.GraphPreferences;
012    import graphlab.platform.preferences.UserDefinedEligiblity;
013    import graphlab.platform.preferences.lastsettings.StorableOnExit;
014    import graphlab.platform.preferences.lastsettings.UserModifiableProperty;
015    
016    import java.awt.*;
017    import java.util.HashMap;
018    import java.util.Vector;
019    
020    
021    public class ArrowHandler implements StorableOnExit, UserDefinedEligiblity, FromStringProvider<Arrow> {
022        //I thinked and decided to choose the base arrows to be Polygons. i think it will be enough for the most needs, but it can't handle more complex needs, like arrows that are images.
023    
024        @UserModifiableProperty(displayName = "Default Arrwo Size for Edges")
025        public static Integer arrowSize = 10;
026    
027    
028        /**
029         * draws the arrow of the edge on the graphics
030         *
031         * @param zoomFactor the zoom factor of Graph Model
032         */
033        public static void paint(Graphics _g, EdgeModel e, double zoomFactor) {
034    //        new ArrowHandler();
035            Arrow arrow = e.getArrow();
036            Graphics2D g = (Graphics2D) _g;
037    
038            double angle = e.getAngle();
039    
040            VertexModel v2 = e.target;
041            GraphPoint v2ShapeSize = v2.getSize();
042            int w = (int) v2ShapeSize.getX();
043            int h = (int) v2ShapeSize.getY();
044            double t = Math.atan2(w * Math.sin(angle), h * Math.cos(angle));
045            GraphPoint loc = e.target.getLocation();
046            int x2 = (int) ((zoomFactor * loc.x) + ((w / 2) * Math.cos(t)));
047            int y2 = (int) ((zoomFactor * loc.y) + ((h / 2) * Math.sin(t)));
048    
049            g.translate(x2 + 1, y2 + 1);
050            g.rotate(angle + Math.PI);
051            arrow.paintArrow(g, arrowSize, arrowSize);
052            g.rotate(-angle - Math.PI);
053            g.translate(-x2 - 1, -y2 - 1);
054        }
055    
056        public static PolygonArrow defaultArrow;
057    
058        static {
059            //create and add default arrows
060            int xPoints[] = {0, -15, -15};
061            int yPoints[] = {0, -15 / 2, 15 / 2};
062            defaultArrow = new PolygonArrow(new Polygon(xPoints, yPoints, 3), "Default");
063            PolygonArrow ar1 = new PolygonArrow(new Polygon(new int[]{0, -15, -10, -15}, new int[]{0, -7, 0, 7}, 4), "Narrow");
064            PolygonArrow ar2 = new PolygonArrow(new Polygon(new int[]{0, -15, -5, -15}, new int[]{0, -7, 0, 7}, 4), "Very Narrow");
065            PolygonArrow ar3 = new PolygonArrow(new Polygon(new int[]{0, -15, -30, -15}, new int[]{0, -7, 0, 7}, 4), "Box");
066            knownArrows = new Vector<Arrow>();
067            registerArrow(defaultArrow);
068            registerArrow(ar1);
069            registerArrow(ar2);
070            registerArrow(ar3);
071    
072        }
073    
074        public static Vector<Arrow> knownArrows;
075    
076        public static void registerArrow(Arrow arrow) {
077            knownArrows.add(arrow);
078        }
079    
080        public GraphPreferences GraphPrefFactory() {
081            return new GraphPreferences(this.getClass().getSimpleName(), this, "Graph Drawings");
082        }
083    
084        public HashMap<Object, ArrayX> defineEligibleValuesForSettings(HashMap<Object, ArrayX> objectValues) {
085            ArrayX t = new ArrayX(new Integer(3));
086            t.addValidValue(new Integer(10));
087            t.addValidValue(new Integer(20));
088            t.addValidValue(new Integer(30));
089    //        t.addValidValue(15);
090    
091            try {
092                objectValues.put(this.getClass().getField("arrowSize"), t);
093            } catch (NoSuchFieldException e) {
094                e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
095            }
096    
097            return objectValues;
098        }
099    
100        public Arrow fromString(String toString) {
101            for (Arrow s : knownArrows) {
102                if (s.getName().equals(toString)) {
103                    return s;
104                }
105            }
106            return null;
107        }
108    }