// PathVisio, // a tool for data visualization and analysis using Biological Pathways // Copyright 2006-2011 BiGCaT Bioinformatics // // 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 org.pathvisio.core.view; import java.awt.Color; import java.awt.Graphics2D; import java.awt.Shape; import java.awt.geom.Area; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.pathvisio.core.model.PathwayElement; /** * This represents the view of a PathwayElement with ObjectType.GROUP. * This can be drawn as a shaded area, or the group can be invisible. * * Also contains the getGroupGraphics method to quickly access all Graphics' that * are in this group. */ public class Group extends Graphics implements LinkProvider, VElementMouseListener { public static final int FLAG_SELECTED = 1 << 0; public static final int FLAG_MOUSEOVER = 1 << 1; public static final int FLAG_ANCHORSVISIBLE = 1 << 2; public Group(VPathway canvas, PathwayElement pe) { super(canvas, pe); canvas.addVElementMouseListener(this); } /** * Generates current id-ref pairs from all current groups * * @return HashMap */ protected Map getIdRefPairs() { // idRefPairs Map idRefPairs = new HashMap(); // Populate hash map of id-ref pairs for all groups for (VPathwayElement vpe : canvas.getDrawingObjects()) { if (vpe instanceof Graphics && vpe instanceof Group) { PathwayElement pe = ((Graphics) vpe).getPathwayElement(); if (pe.getGroupRef() != null) { idRefPairs.put(pe.getGroupId(), pe.getGroupRef()); } } } return idRefPairs; } /** * Generates list of group references nested under this group * * @return ArrayList */ protected List getRefList() { Map idRefPairs = this.getIdRefPairs(); List refList = new ArrayList(); String thisId = this.getPathwayElement().getGroupId(); refList.add(thisId); boolean hit = true; while (hit) { hit = false; // search for hits in hash map; add to refList for (String id : idRefPairs.keySet()) { if (refList.contains(idRefPairs.get(id))) { refList.add(id); hit = true; } } // remove hits from hash map for (int i = 0; i < refList.size(); i++) { idRefPairs.remove(refList.get(i)); } } return refList; } // /** // * Determines whether any member of the highest-level group object related // * to the current group object contains the point specified // * // * @param point - // * the point to check // * @return True if the object contains the point, false otherwise // */ // protected boolean vContains(Point2D point) // { // ArrayList refList = this.getRefList(); // // // return true if group object is referenced by selection // for (VPathwayElement vpe : canvas.getDrawingObjects()) // { // if (vpe instanceof Graphics && !(vpe instanceof Group) // && vpe.vContains(point)) // { // PathwayElement pe = ((Graphics) vpe).getPathwayElement(); // String ref = pe.getGroupRef(); // // System.out.println("pe: " + pe + " ref: " + ref + " refList: // // " // // + refList.toString()); // if (ref != null && refList.contains(ref)) // { // // System.out.println(ref + " contains point"); // return true; // } // } // } // return false; // } /** * Determines whether the area defined by the grouped elements * contains the point specified. The elements themselves are * excluded to support individual selection within a group. The * ultimate effect is then selection of group by clicking the area * and not the members of the group. * * @param point - * the point to check * @return True if the object contains the point, false otherwise */ protected boolean vContains(Point2D point) { // return false if point falls on any individual element for (VPathwayElement vpe : canvas.getDrawingObjects()) { if (vpe instanceof Graphics && !(vpe instanceof Group) && vpe.vContains(point)) { return false; } } // return true if point within bounds of grouped objects if (this.getVShape(true).contains(point)) { return true; } else { return false; } } // @Override // protected boolean vIntersects(Rectangle2D r) // { // ArrayList refList = this.getRefList(); // // // return true if group object is referenced by selection // for (VPathwayElement vpe : canvas.getDrawingObjects()) // { // if (vpe instanceof Graphics && !(vpe instanceof Group) // && vpe.vIntersects(r)) // { // PathwayElement pe = ((Graphics) vpe).getPathwayElement(); // String ref = pe.getGroupRef(); // if (ref != null && refList.contains(ref)) // { // // System.out.println(ref + " intersects point"); // return true; // } // } // } // return false; // } /** * Returns graphics for members of a group, including nested members * * @return ArrayList */ public List getGroupGraphics() { List gg = new ArrayList(); // return true if group object is referenced by selection for (VPathwayElement vpe : canvas.getDrawingObjects()) { if (vpe instanceof Graphics && vpe != this) { Graphics vpeg = (Graphics) vpe; PathwayElement pe = vpeg.getPathwayElement(); String ref = pe.getGroupRef(); if (ref != null && ref.equals(getPathwayElement().getGroupId())) { gg.add(vpeg); } } } return gg; } @Override public void select() { for (Graphics g : getGroupGraphics()) { g.select(); } super.select(); } @Override public void deselect() { for (Graphics g : getGroupGraphics()) { g.deselect(); } super.deselect(); } @Override protected void vMoveBy(double dx, double dy) { canvas.moveMultipleElements(getGroupGraphics(), dx, dy); // update group outline markDirty(); } protected void doDraw(Graphics2D g2d) { //Build the flags int flags = 0; if(isSelected()) flags += FLAG_SELECTED; if(mouseover) flags += FLAG_MOUSEOVER; if(anchorsShowing) flags += FLAG_ANCHORSVISIBLE; //Draw the group style appearance GroupPainter p = GroupPainterRegistry.getPainter(gdata.getGroupStyle().toString()); p.drawGroup(g2d, this, flags); } boolean mouseover = false; public void vElementMouseEvent(VElementMouseEvent e) { if(e.getElement() == this) { boolean old = mouseover; if(e.getType() == VElementMouseEvent.TYPE_MOUSEENTER) { mouseover = true; } else if(e.getType() == VElementMouseEvent.TYPE_MOUSEEXIT) { mouseover = false; } if(old != mouseover) { markDirty(); } } } public void highlight(Color c) { super.highlight(c); //Highlight the children for(Graphics g : getGroupGraphics()) { g.highlight(); } } protected Shape calculateVOutline() { //Include rotation and stroke Area a = new Area(getVShape(true)); return a; } protected Shape getVShape(boolean rotate) { Rectangle2D mb = null; if(rotate) { mb = gdata.getRBounds(); } else { mb = gdata.getMBounds(); } return canvas.vFromM(mb); } protected void setVScaleRectangle(Rectangle2D r) { // TODO Auto-generated method stub } private LinkProvider linkAnchorDelegate = new DefaultLinkAnchorDelegate(this); private boolean anchorsShowing = false; public void showLinkAnchors() { anchorsShowing = true; linkAnchorDelegate.showLinkAnchors(); } public void hideLinkAnchors() { anchorsShowing = false; linkAnchorDelegate.hideLinkAnchors(); } public LinkAnchor getLinkAnchorAt(Point2D p) { return linkAnchorDelegate.getLinkAnchorAt(p); } @Override protected void destroy() { super.destroy(); canvas.removeVElementMouseListener(this); } /** * Use this to override default linkAnchorDelegate */ public void setLinkAnchorDelegate (LinkProvider delegate) { if (delegate == null) throw new NullPointerException("passed illegal null value for delegate"); linkAnchorDelegate = delegate; } }