package statalign.postprocess.gui;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.geom.GeneralPath;
import java.awt.geom.Point2D;
import javax.swing.undo.UndoManager;
import fr.orsay.lri.varna.VARNAPanel;
import fr.orsay.lri.varna.controlers.ControleurBlinkingThread;
import fr.orsay.lri.varna.controlers.ControleurClicMovement;
import fr.orsay.lri.varna.controlers.ControleurDraggedMolette;
import fr.orsay.lri.varna.controlers.ControleurInterpolator;
import fr.orsay.lri.varna.controlers.ControleurMolette;
import fr.orsay.lri.varna.controlers.ControleurVARNAPanelKeys;
import fr.orsay.lri.varna.exceptions.ExceptionNonEqualLength;
import fr.orsay.lri.varna.models.VARNAConfig;
import fr.orsay.lri.varna.models.export.VueVARNAGraphics;
import fr.orsay.lri.varna.models.rna.ModeleBP;
import fr.orsay.lri.varna.models.rna.RNA;
import fr.orsay.lri.varna.views.VueUI;
public class StructureGUI extends VARNAPanel{
/**
* This class implements a graphical interface for displaying the current consensus structure. RNA
* graphics are provided by VARNA.
*
* @author Preeti Arunapuram
*/
private static final long serialVersionUID = 1L;
private static String sequence;
private static String structure;
private Graphics2D g2;
private ColorGradient cg = new ColorGradient(Color.WHITE, Color.BLACK);
private RNA _RNA = new RNA();
public String title;
public boolean probMode = true;
private double _scaleFactor = 1.0;
private float[][] probs;
private VARNAConfig _conf = new VARNAConfig();
UndoManager _manager;
private ControleurBlinkingThread _blink;
private Point _translation;
private boolean _horsCadre;
private boolean _premierAffichage;
private ControleurInterpolator _interpolator;
private VueUI _UI = new VueUI(this);
public StructureGUI(String title) throws ExceptionNonEqualLength {
sequence = null;
structure = null;
this.title = title;
}
public void paintComponent(Graphics g) {
//setBackground(Color.PINK);
//setBaseInnerColor(Color.GREEN);
//setBaseNameColor(Color.BLUE);
super.paintComponent(g);
g2 = (Graphics2D)g;
if(structure == null || sequence == null) {
g2.drawString("Waiting for data..", 30, 30);
return;
}
g2.setPaint(Color.BLACK);
g2.setFont(new Font("SANS_SERIF", Font.BOLD, 16));
g2.drawString(title, 10, 20);
g2.setFont(new Font("SANS_SERIF", Font.BOLD, 12));
if(!probMode) g2.drawString("Nucleotide Mode", 10, 40);
else g2.drawString("Probability Mode", 10, 40);
g2.setFont(new Font("MONOSPACED", Font.PLAIN, 12));
}
public void updateAndDraw(String seq, String str) {
sequence = seq;
structure = str;
repaint();
super.drawRNAInterpolated(sequence, structure, RNA.DRAW_MODE_RADIATE);
setBackground(VARNAConfig.DEFAULT_BACKGROUND_COLOR);
_manager = new UndoManager();
_manager.setLimit(10000);
_UI.addUndoableEditListener(_manager);
_blink = new ControleurBlinkingThread(this,
ControleurBlinkingThread.DEFAULT_FREQUENCY, 0, 1.0, 0.0, 0.2);
_blink.start();
_premierAffichage = true;
_translation = new Point(0, 0);
_horsCadre = false;
this.setFont(_conf._fontBasesGeneral);
// ajout des controleurs au VARNAPanel
ControleurClicMovement controleurClicMovement = new ControleurClicMovement( this);
this.addMouseListener(controleurClicMovement);
this.addMouseMotionListener(controleurClicMovement);
this.addMouseWheelListener(new ControleurMolette(this));
ControleurDraggedMolette ctrlDraggedMolette = new ControleurDraggedMolette(
this);
this.addMouseMotionListener(ctrlDraggedMolette);
this.addMouseListener(ctrlDraggedMolette);
ControleurVARNAPanelKeys ctrlKey = new ControleurVARNAPanelKeys(this);
this.addKeyListener(ctrlKey);
this.addFocusListener(ctrlKey);
_interpolator = new ControleurInterpolator(this);
_interpolator.start();
}
//@Override
public void drawSymbol(VueVARNAGraphics g2D,double posx, double posy,
double normx, double normy, double radius, boolean isCIS,
ModeleBP.Edge e) {
switch (e) {
case WATSON_CRICK:
if (isCIS) {
g2D.fillCircle( (posx - (radius) / 2.0),
(posy - (radius) / 2.0), radius);
} else {
Color bck = g2D.getColor();
g2D.setColor(Color.white);
g2D.fillCircle( posx - (radius) / 2.0,
(posy - (radius) / 2.0), (radius));
g2D.setColor(bck);
g2D.drawCircle( (posx - (radius) / 2.0),
(posy - (radius) / 2.0), (radius));
}
break;
case HOOGSTEEN: {
GeneralPath p2 = new GeneralPath();
p2.moveTo((float) (posx - radius * normx / 2.0 - radius * normy
/ 2.0), (float) (posy - radius * normy / 2.0 + radius
* normx / 2.0));
p2.lineTo((float) (posx + radius * normx / 2.0 - radius * normy
/ 2.0), (float) (posy + radius * normy / 2.0 + radius
* normx / 2.0));
p2.lineTo((float) (posx + radius * normx / 2.0 + radius * normy
/ 2.0), (float) (posy + radius * normy / 2.0 - radius
* normx / 2.0));
p2.lineTo((float) (posx - radius * normx / 2.0 + radius * normy
/ 2.0), (float) (posy - radius * normy / 2.0 - radius
* normx / 2.0));
p2.closePath();
if (isCIS) {
g2D.fill(p2);
} else {
Color bck = g2D.getColor();
g2D.setColor(Color.white);
g2D.fill(p2);
g2D.setColor(bck);
g2D.draw(p2);
}
}
break;
case SUGAR: {
double ix = radius * normx / 2.0;
double iy = radius * normy / 2.0;
double jx = radius * normy / 2.0;
double jy = -radius * normx / 2.0;
GeneralPath p2 = new GeneralPath();
p2.moveTo((float) (posx - ix + jx), (float) (posy - iy + jy));
p2.lineTo((float) (posx + ix + jx), (float) (posy + iy + jy));
p2.lineTo((float) (posx - jx), (float) (posy - jy));
p2.closePath();
if (isCIS) {
g2D.fill(p2);
} else {
Color bck = g2D.getColor();
g2D.setColor(Color.white);
g2D.fill(p2);
g2D.setColor(bck);
g2D.draw(p2);
}
}
break;
}
}
//@Override
public void drawBasePair(VueVARNAGraphics g2D,Point2D.Double orig,
Point2D.Double dest, ModeleBP style, double newRadius) {
double dx = dest.x - orig.x;
double dy = dest.y - orig.y;
double dist = Math.sqrt((dest.x - orig.x) * (dest.x - orig.x)
+ (dest.y - orig.y) * (dest.y - orig.y));
dx /= dist;
dy /= dist;
double nx = -dy;
double ny = dx;
orig = new Point2D.Double(orig.x+newRadius*dx,orig.y+newRadius*dy);
dest = new Point2D.Double(dest.x-newRadius*dx,dest.y-newRadius*dy);
if (_conf._mainBPStyle == VARNAConfig.BP_STYLE.BP_STYLE_LW)
{
double radiusCircle = ((RNA.BASE_PAIR_DISTANCE - _RNA.BASE_RADIUS) / 5.0)
* this._scaleFactor;
if (style.isCanonical())
{
g2D.setStrokeThickness(probs[style.getIndex3()][style.getIndex5()]);
((Graphics2D) g2D).setPaint(cg.getColor(probs[style.getIndex3()][style.getIndex5()]));
if (style.isCanonicalGC())
{
if ((orig.x != dest.x) || (orig.y != dest.y)) {
nx *= this._scaleFactor * _RNA.BASE_RADIUS / 4.0;
ny *= this._scaleFactor * _RNA.BASE_RADIUS / 4.0;
g2D.drawLine( (orig.x + nx), (orig.y + ny),
(dest.x + nx), (dest.y + ny));
g2D.drawLine( (orig.x - nx), (orig.y - ny),
(dest.x - nx), (dest.y - ny));
}
}
else if (style.isCanonicalAU()){
g2D.drawLine(orig.x, orig.y, dest.x,
dest.y);
}
else if (style.isWobbleUG()){
double cx = (dest.x + orig.x) / 2.0;
double cy = (dest.y + orig.y) / 2.0;
g2D.drawLine( orig.x, orig.y, dest.x,
dest.y);
drawSymbol(g2D, cx, cy, nx, ny, radiusCircle, false, ModeleBP.Edge.WATSON_CRICK);
}
else
{
double cx = (dest.x + orig.x) / 2.0;
double cy = (dest.y + orig.y) / 2.0;
g2D.drawLine( orig.x, orig.y, dest.x,
dest.y);
drawSymbol(g2D, cx, cy, nx, ny, radiusCircle, style
.isCIS(), style.getEdgePartner5());
}
} else {
ModeleBP.Edge p1 = style.getEdgePartner5();
ModeleBP.Edge p2 = style.getEdgePartner3();
double cx = (dest.x + orig.x) / 2.0;
double cy = (dest.y + orig.y) / 2.0;
g2D.drawLine( orig.x, orig.y,dest.x,
dest.y);
if (p1 == p2) {
drawSymbol(g2D, cx, cy, nx, ny, radiusCircle, style
.isCIS(), p1);
} else {
double vdx = (dest.x - orig.x);
double vdy = (dest.y - orig.y);
vdx /= 6.0;
vdy /= 6.0;
drawSymbol(g2D, cx + vdx, cy + vdy, nx, ny, radiusCircle,
style.isCIS(), p2);
drawSymbol(g2D, cx - vdx, cy - vdy, nx, ny, radiusCircle,
style.isCIS(), p1);
}
}
} else if (_conf._mainBPStyle == VARNAConfig.BP_STYLE.BP_STYLE_SIMPLE) {
g2D.drawLine( orig.x, orig.y,dest.x, dest.y);
} else if (_conf._mainBPStyle == VARNAConfig.BP_STYLE.BP_STYLE_RNAVIZ) {
double xcenter = (orig.x + dest.x) / 2.0;
double ycenter = (orig.y + dest.y) / 2.0;
double radius = Math.max(4.0 * this._scaleFactor, 1.0);
g2D.fillCircle( (xcenter - radius), (ycenter - radius), (2.0 * radius));
}
}
public void setMatrix(float[][] probMatrix) {
probs = probMatrix;
}
}