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.plugins.main.select;
005    
006    import graphlab.graph.atributeset.GraphAttrSet;
007    import graphlab.graph.event.GraphEvent;
008    import graphlab.graph.graph.*;
009    import graphlab.graph.ui.GraphRectRegionSelect;
010    import graphlab.library.exceptions.InvalidVertexException;
011    import graphlab.platform.core.AbstractAction;
012    import graphlab.platform.core.BlackBoard;
013    import graphlab.plugins.main.core.actions.VertexTransformer;
014    import graphlab.ui.UIUtils;
015    
016    import java.awt.*;
017    import java.awt.event.KeyEvent;
018    import java.awt.geom.Rectangle2D;
019    
020    /**
021     * @author azin azadi
022     */
023    public class RectangularSelect extends AbstractAction {
024        String event = UIUtils.getUIEventKey("rectangular select");
025        GraphModel g;
026        boolean deleteOlderSelections = true;
027        GraphRectRegionSelect graphRectRegionSelector = new GraphRectRegionSelect(blackboard) {
028    
029            public void onMouseMoved(GraphEvent data) {
030                _onMouseMoved(data);
031            }
032    
033            public void onDrop(GraphEvent data) {
034                _onDrop(data);
035            }
036        };
037        static BlackBoard gb;
038    
039        /**
040         * constructor
041         *
042         * @param bb the blackboard of the action
043         */
044        public RectangularSelect(BlackBoard bb) {
045            super(bb);
046            gb = bb;
047            listen4Event(GraphEvent.EVENT_KEY);
048            graphRectRegionSelector.startSelectingRegion();
049            KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventPostProcessor(new KeyEventPostProcessor() {
050                public boolean postProcessKeyEvent(KeyEvent e) {
051                    deleteOlderSelections = true;
052                    invertOlderSelections = false;
053                    if (e.isControlDown())
054                        deleteOlderSelections = false;
055                    if (e.isShiftDown())
056                        invertOlderSelections = true; //not yet implemented //todo: implement
057                    return false;
058                }
059            });
060        }
061    
062        public void performAction(String eventName, Object value) {
063    //        StatusBarMessage.showQuickMessage(blackboard, "press Control for continues selection.");
064            g = blackboard.getData(GraphAttrSet.name);
065            GraphEvent ge = blackboard.getData(GraphEvent.EVENT_KEY);
066    
067            if (ge.eventType == GraphEvent.DRAGGING_STARTED)
068                graphRectRegionSelector.startSelectingRegion();
069        }
070    
071        void _onMouseMoved(GraphEvent data) {
072            if (VertexTransformer.isPositionOnResizeBoxes(data.mousePos, blackboard))
073                return;
074            SubGraph selection = RectangularSelect.calculateSelected(g, graphRectRegionSelector.getCurrentRect().getBounds());
075            if (!deleteOlderSelections) {
076                SubGraph sd = Select.getSelection(blackboard);
077                for (VertexModel v : sd.vertices)
078                    selection.vertices.add(v);
079                for (EdgeModel e : sd.edges)
080                    selection.edges.add(e);
081            }
082            blackboard.setData(Select.EVENT_KEY, selection);
083        }
084    
085        void _onDrop(GraphEvent data) {
086    //        if (isEnable())
087            graphRectRegionSelector.startSelectingRegion();
088        }
089    
090    
091        boolean invertOlderSelections = false;
092    
093    //    public void paint(Graphics p, Component unused) {
094    //        //System.out.println(x + " " + y + " " + xx + " " + yy);
095    //        p.setColor(black);
096    //        p.drawLine(x, y, xx, yy);
097    //    }
098    
099        public static SubGraph calculateSelected(GraphModel g, Rectangle bounds) {
100            SubGraph sd = new SubGraph();
101            for (VertexModel vm : g) {
102                GraphPoint loc = vm.getLocation();
103                Point cent = vm.getCenter();
104                if (bounds.contains(loc.x, loc.y)) {
105                    sd.vertices.add(vm);
106                }
107            }
108            EdgeModel em;
109            for (VertexModel v1 : sd.vertices) {
110                for (VertexModel v2 : sd.vertices) {
111                    try {
112                        EdgeModel edge = g.getEdge(v1, v2);
113                        if (edge != null) {
114                            sd.edges.add(edge);
115                        }
116                    }
117                    catch (InvalidVertexException e) {
118                    }
119                }
120            }
121    //        for (Iterator<Edge> ei=gv.edgeIterator();ei.hasNext();){
122    //            em=ei.next();
123    //            if (bounds.contains(em.view.getBounds()))
124    //                sd.edges.add(em);
125    //        }
126            return sd;
127        }
128    
129        public static boolean isVertexInRect(VertexModel v, GraphModel g, Rectangle viewBounds) {
130            GraphPoint shapeSize = v.getSize();
131            int w = (int) shapeSize.getX();
132            int h = (int) shapeSize.getY();
133    
134            Rectangle2D.Double selBounds = new Rectangle2D.Double(viewBounds.getX(), viewBounds.getY(), viewBounds.width, viewBounds.height);
135            GraphPoint loc = v.getLocation();
136            Rectangle2D.Double verBounds = new Rectangle2D.Double(loc.x, loc.y, w, h);
137            return selBounds.contains(verBounds);
138        }
139    }