+++ /dev/null
-package fr.orsay.lri.varna.models.annotations;
-
-import java.awt.Color;
-import java.awt.Shape;
-import java.awt.geom.GeneralPath;
-import java.awt.geom.Point2D;
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.LinkedList;
-
-import javax.xml.transform.sax.TransformerHandler;
-
-import org.xml.sax.SAXException;
-import org.xml.sax.helpers.AttributesImpl;
-
-import fr.orsay.lri.varna.VARNAPanel;
-import fr.orsay.lri.varna.controlers.ControleurClicMovement;
-import fr.orsay.lri.varna.models.VARNAConfigLoader;
-import fr.orsay.lri.varna.models.rna.ModeleBase;
-import fr.orsay.lri.varna.models.rna.RNA;
-import fr.orsay.lri.varna.models.rna.VARNAPoint;
-import fr.orsay.lri.varna.utils.XMLUtils;
-import fr.orsay.lri.varna.views.VueHighlightRegionEdit;
-import fr.orsay.lri.varna.views.VueUI;
-
-public class HighlightRegionAnnotation implements Serializable {
-
- public static final String HEADER_TEXT = "HighlightRegionAnnotation";
-
- private static final long serialVersionUID = 7087014168028684775L;
- public static final Color DEFAULT_OUTLINE_COLOR = Color.decode("#6ed86e");
- public static final Color DEFAULT_FILL_COLOR = Color.decode("#bcffdd");
- public static final double DEFAULT_RADIUS = 16.0;
-
- private Color _outlineColor = DEFAULT_OUTLINE_COLOR;
- private Color _fillColor = DEFAULT_FILL_COLOR;
- private double _radius = DEFAULT_RADIUS;
- private ArrayList<ModeleBase> _bases;
-
- public static String XML_ELEMENT_NAME = "region";
- public static String XML_VAR_OUTLINE_NAME = "outline";
- public static String XML_VAR_FILL_NAME = "fill";
- public static String XML_VAR_RADIUS_NAME = "radius";
-
- public void toXML(TransformerHandler hd) throws SAXException
- {
- AttributesImpl atts = new AttributesImpl();
- atts.addAttribute("","",XML_VAR_OUTLINE_NAME,"CDATA",""+XMLUtils.toHTMLNotation(_outlineColor));
- atts.addAttribute("","",XML_VAR_FILL_NAME,"CDATA",""+XMLUtils.toHTMLNotation(_fillColor));
- atts.addAttribute("","",XML_VAR_RADIUS_NAME,"CDATA",""+_radius);
- hd.startElement("","",XML_ELEMENT_NAME,atts);
- XMLUtils.toXML(hd, _bases);
- hd.endElement("","",XML_ELEMENT_NAME);
- }
-
- public HighlightRegionAnnotation(RNA r, int startIndex, int stopIndex)
- {
- this(r.getBasesBetween(startIndex, stopIndex));
- }
-
- public HighlightRegionAnnotation()
- {
- this(new ArrayList<ModeleBase>());
- }
-
- public HighlightRegionAnnotation(ArrayList<ModeleBase> b)
- {
- this(b,DEFAULT_FILL_COLOR,DEFAULT_OUTLINE_COLOR,DEFAULT_RADIUS);
- }
-
-
- public HighlightRegionAnnotation(ArrayList<ModeleBase> b,Color fill, Color outline, double radius)
- {
- _bases = b;
- _fillColor = fill;
- _outlineColor = outline;
- _radius = radius;
- }
-
- public HighlightRegionAnnotation clone()
- {
- return new HighlightRegionAnnotation(_bases,_fillColor,_outlineColor,_radius);
- }
-
- public int getMinIndex()
- {
- int min = Integer.MAX_VALUE;
- for (ModeleBase mb : _bases)
- {
- min = Math.min(min, mb.getIndex());
- }
- return min;
- }
-
- public int getMaxIndex()
- {
- int max = Integer.MIN_VALUE;
- for (ModeleBase mb : _bases)
- {
- max = Math.max(max, mb.getIndex());
- }
- return max;
- }
-
-
- public void setOutlineColor(Color c)
- {
- _outlineColor = c;
- }
-
- public ArrayList<ModeleBase> getBases()
- {
- return _bases;
- }
-
- public void setBases(ArrayList<ModeleBase> b)
- {
- _bases = b;
- }
-
- public void setFillColor(Color c)
- {
- _fillColor = c;
- }
-
- public Color getFillColor()
- {
- return _fillColor;
- }
-
- public Color getOutlineColor()
- {
- return _outlineColor;
- }
-
- public double getRadius()
- {
- return _radius;
- }
-
- public void setRadius(double v)
- {
- _radius = v;
- }
-
- public static final int NUM_STEPS_ROUNDED_CORNERS = 16;
-
- private Point2D.Double symImage(Point2D.Double p, Point2D.Double center)
- {
- return new Point2D.Double(2.*center.x-p.x, 2.*center.y-p.y);
- }
-
- private LinkedList<Point2D.Double> buildRoundedCorner(Point2D.Double p1, Point2D.Double p2, Point2D.Double anotherPoint)
- {
- LinkedList<Point2D.Double> result = new LinkedList<Point2D.Double>();
- Point2D.Double m = new Point2D.Double((p1.x+p2.x)/2.0,(p1.y+p2.y)/2.0);
- double rad = p1.distance(p2)/2.;
- double angle = Math.atan2(p1.y-m.y, p1.x-m.x);
-
- double incr = Math.PI/((double)NUM_STEPS_ROUNDED_CORNERS+1);
-
- Point2D.Double pdir = new Point2D.Double(m.x+rad*Math.cos(angle+Math.PI/2.),m.y+rad*Math.sin(angle+Math.PI/2.));
- if (pdir.distance(anotherPoint)<p1.distance(anotherPoint))
- { incr = -incr; }
-
- for(int k=1;k<=NUM_STEPS_ROUNDED_CORNERS;k++)
- {
- double angle2 = angle+k*incr;
- Point2D.Double interForward = new Point2D.Double(m.x+rad*Math.cos(angle2),m.y+rad*Math.sin(angle2));
- result.addLast(interForward);
- }
- return result;
- }
-
-
- public GeneralPath getShape(Point2D.Double[] realCoords,Point2D.Double[] realCenters, double scaleFactor)
- {
- GeneralPath p = new GeneralPath();
- LinkedList<Point2D.Double> pointList = new LinkedList<Point2D.Double>();
- for (int i = 0;i<getBases().size();i++)
- {
- int j1 = getBases().get(i).getIndex();
- {
- int j0 = j1-1;
- int j2 = j1+1;
- Point2D.Double p0 = new Point2D.Double(0., 0.);
- Point2D.Double p1 = new Point2D.Double(0., 0.);
- Point2D.Double p2 = new Point2D.Double(0., 0.);
- if (i==0)
- {
- // Single point
- if (i==getBases().size()-1)
- {
- p1 = realCoords[j1];
- p0 = new Point2D.Double(p1.x+scaleFactor *getRadius(), p1.y);
- p2 = new Point2D.Double(p1.x-scaleFactor *getRadius(), p1.y);
- }
- else
- {
- p1 = realCoords[j1];
- p2 = realCoords[j2];
- p0 = symImage(p2, p1);
- }
- }
- else if (i==getBases().size()-1)
- {
- p0 = realCoords[j0];
- p1 = realCoords[j1];
- p2 = symImage(p0, p1);;
- }
- else
- {
- p0 = realCoords[j0];
- p1 = realCoords[j1];
- p2 = realCoords[j2];
- }
-
- double dist1 = p2.distance(p1);
- Point2D.Double v1 = new Point2D.Double((p2.x-p1.x)/dist1,(p2.y-p1.y)/dist1);
- Point2D.Double vn1 = new Point2D.Double(v1.y,-v1.x);
- double dist2 = p1.distance(p0);
- Point2D.Double v2 = new Point2D.Double((p1.x-p0.x)/dist2,(p1.y-p0.y)/dist2);
- Point2D.Double vn2 = new Point2D.Double(v2.y,-v2.x);
- double h = (new Point2D.Double(vn2.x-vn1.x,vn2.y-vn1.y).distance(new Point2D.Double(0,0))/2.0);
- Point2D.Double vn = new Point2D.Double((vn1.x+vn2.x)/2.0,(vn1.y+vn2.y)/2.0);
- double D = vn.distance(new Point2D.Double(0.0,0.0));
- vn.x/= D;
- vn.y/= D;
- double nnorm = (D+h*h/D);
-
- double nnormF = nnorm;
- double nnormB = nnorm;
-
-
- Point2D.Double interForward = new Point2D.Double(p1.x + nnormF*scaleFactor *getRadius()*vn.x,
- p1.y + nnormF*scaleFactor *getRadius()*vn.y);
- Point2D.Double interBackward = new Point2D.Double(p1.x - nnormB*scaleFactor *getRadius()*vn.x,
- p1.y - nnormB*scaleFactor *getRadius()*vn.y);
-
-
- if (pointList.size()>0)
- {
- Point2D.Double prev1 = pointList.getLast();
- Point2D.Double prev2 = pointList.getFirst();
-
- if ((interForward.distance(prev1)+interBackward.distance(prev2))<(interForward.distance(prev2)+interBackward.distance(prev1)))
- {
- pointList.addLast(interForward);
- pointList.addFirst(interBackward);
- }
- else
- {
- pointList.addFirst(interForward);
- pointList.addLast(interBackward);
- }
- }
- else
- {
- pointList.addLast(interForward);
- pointList.addFirst(interBackward);
- }
- }
- }
- if (getBases().size()==1)
- {
- int midl = pointList.size()/2;
- Point2D.Double mid = pointList.get(midl);
- Point2D.Double apoint = new Point2D.Double(mid.x+1.,mid.y);
- LinkedList<Point2D.Double> pointListStart = buildRoundedCorner(pointList.get(midl-1), pointList.get(midl), apoint);
- pointList.addAll(midl, pointListStart);
- mid = pointList.get(midl);
- apoint = new Point2D.Double(mid.x+1.,mid.y);
- LinkedList<Point2D.Double> pointListEnd = buildRoundedCorner(pointList.get(pointList.size()-1),pointList.get(0), apoint);
- pointList.addAll(0,pointListEnd);
- }
- else if (getBases().size()>1)
- {
- int midl = pointList.size()/2;
- Point2D.Double apoint = symImage(pointList.get(midl),pointList.get(midl-1));
- LinkedList<Point2D.Double> pointListStart = buildRoundedCorner(pointList.get(midl-1), pointList.get(midl), apoint);
- pointList.addAll(midl, pointListStart);
- apoint = symImage(realCoords[getBases().get(getBases().size()-1).getIndex()],
- realCoords[getBases().get(getBases().size()-2).getIndex()]);
- LinkedList<Point2D.Double> pointListEnd = buildRoundedCorner(pointList.get(pointList.size()-1),pointList.get(0), apoint);
- pointList.addAll(0,pointListEnd);
- }
-
-
- if (pointList.size()>0)
- {
- Point2D.Double point = pointList.get(0);
- p.moveTo((float)point.x, (float)point.y);
-
- for (int i=1;i<pointList.size();i++)
- {
- point = pointList.get(i);
- p.lineTo((float)point.x, (float)point.y);
- }
- p.closePath();
- }
- return p;
- }
-
-
- public static HighlightRegionAnnotation parseHighlightRegionAnnotation(String txt, VARNAPanel vp)
- {
- try
- {
- String[] parts = txt.split(":");
- String[] coords = parts[0].split("-");
- int from = Integer.parseInt(coords[0]);
- int to = Integer.parseInt(coords[1]);
- int i = vp.getRNA().getIndexFromBaseNumber(from);
- int j = vp.getRNA().getIndexFromBaseNumber(to);
- Color fill = HighlightRegionAnnotation.DEFAULT_FILL_COLOR;
- Color outline = HighlightRegionAnnotation.DEFAULT_OUTLINE_COLOR;
- double radius = HighlightRegionAnnotation.DEFAULT_RADIUS;
- ArrayList<ModeleBase> bases = vp.getRNA().getBasesBetween(i, j);
- if (parts.length>1)
- {
- try
- {
- String[] options = parts[1].split(",");
- for (int k = 0; k < options.length; k++)
- {
- //System.out.println(options[k]);
- try
- {
- String[] data = options[k].split("=");
- String lhs = data[0].toLowerCase();
- String rhs = data[1];
- if (lhs.equals("fill"))
- {
- fill = VARNAConfigLoader.getSafeColor(rhs, fill);
- }
- else if (lhs.equals("outline"))
- {
- outline = VARNAConfigLoader.getSafeColor(rhs, outline);
- }
- else if (lhs.equals("radius"))
- {
- radius = Double.parseDouble(rhs);
- }
- }
- catch(Exception e)
- {
- }
- }
- }
- catch(Exception e)
- {
- e.printStackTrace();
- }
- }
- return new HighlightRegionAnnotation(bases,fill,outline,radius);
- }
- catch(Exception e)
- {
- e.printStackTrace();
- }
- return null;
- }
-
- public String toString()
- {
- //String result = "HighlightRegionAnnotation[";
- //result += "fill:"+_fillColor.toString();
- //result += ",outline:"+_outlineColor.toString();
- //result += ",radius:"+_radius;
- //return result+"]";
- String result = "Highlighted region "+getMinIndex()+"-"+getMaxIndex();
- return result;
- }
-
-}