/*
- * Jalview - A Sequence Alignment Editor and Viewer (Development Version 2.4.1)
- * Copyright (C) 2009 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.6)
+ * Copyright (C) 2010 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * This file is part of Jalview.
*
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with Jalview. If not, see <http://www.gnu.org/licenses/>.
*/
package jalview.gui;
import javax.swing.*;
+import com.stevesoft.pat.Regex;
+
import jalview.analysis.AAFrequency;
+import jalview.analysis.StructureFrequency;
import jalview.datamodel.*;
import jalview.schemes.ColourSchemeI;
final String SHEET = "Sheet";
+ /**
+ * For RNA secondary structure "stems" aka helices
+ */
+ final String STEM = "RNA Helix";
+
final String LABEL = "Label";
final String REMOVE = "Remove Annotation";
final Color SHEET_COLOUR = Color.green.darker().darker();
+ final Color STEM_COLOUR = Color.blue.darker();
+
/** DOCUMENT ME!! */
AlignViewport av;
boolean MAC = false;
+ // for editing cursor
+ int cursorX = 0;
+
+ int cursorY = 0;
+
/**
* Creates a new AnnotationPanel object.
*
* @param ap
- * DOCUMENT ME!
+ * DOCUMENT ME!
*/
public AnnotationPanel(AlignmentPanel ap)
{
* DOCUMENT ME!
*
* @param evt
- * DOCUMENT ME!
+ * DOCUMENT ME!
*/
public void adjustmentValueChanged(AdjustmentEvent evt)
{
}
/**
- * Calculates the height of the annotation displayed in the annotation panel.
- * Callers should normally call the ap.adjustAnnotationHeight method to ensure all
- * annotation associated components are updated correctly.
- *
+ * Calculates the height of the annotation displayed in the annotation panel.
+ * Callers should normally call the ap.adjustAnnotationHeight method to ensure
+ * all annotation associated components are updated correctly.
+ *
*/
public int adjustPanelHeight()
{
+ int height = calcPanelHeight();
+ this.setPreferredSize(new Dimension(1, height));
+ if (ap != null)
+ {
+ // revalidate only when the alignment panel is fully constructed
+ ap.validate();
+ }
+
+ return height;
+ }
+
+ /**
+ * calculate the height for visible annotation, revalidating bounds where
+ * necessary ABSTRACT GUI METHOD
+ *
+ * @return total height of annotation
+ */
+ public int calcPanelHeight()
+ {
// setHeight of panels
AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();
int height = 0;
{
for (int i = 0; i < aa.length; i++)
{
- if (aa[i]==null)
+ if (aa[i] == null)
{
System.err.println("Null annotation row: ignoring.");
continue;
height += aa[i].height;
}
}
- else
+ if (height == 0)
{
+ // set minimum
height = 20;
}
-
- this.setPreferredSize(new Dimension(1, height));
- if (ap!=null)
- {
- // revalidate only when the alignment panel is fully constructed
- ap.validate();
- }
-
return height;
}
* DOCUMENT ME!
*
* @param evt
- * DOCUMENT ME!
+ * DOCUMENT ME!
*/
public void actionPerformed(ActionEvent evt)
{
AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();
+ if (aa == null)
+ {
+ return;
+ }
Annotation[] anot = aa[activeRow].annotations;
if (anot.length < av.getColumnSelection().getMax())
if (anot[index] == null)
{
anot[index] = new Annotation(label, "", ' ', 0); // TODO: verify that
- // null exceptions
- // aren't raised
- // elsewhere.
+ // null exceptions
+ // aren't raised
+ // elsewhere.
}
else
{
symbol = "\u03B2";
}
+ // Added by LML to color stems
+ else if (evt.getActionCommand().equals(STEM))
+ {
+ type = 'S';
+ symbol = "\u03C3";
+ }
+
if (!aa[activeRow].hasIcons)
{
aa[activeRow].hasIcons = true;
continue;
String tlabel = null;
if (anot[index] != null)
- {
+ { // LML added stem code
if (label2.equals(HELIX) || label2.equals(SHEET)
- || label2.equals(LABEL))
+ || label2.equals(STEM) || label2.equals(LABEL))
{
tlabel = anot[index].description;
- if (tlabel == null || tlabel.length()<1)
+ if (tlabel == null || tlabel.length() < 1)
{
- if (label2.equals(HELIX) || label2.equals(SHEET))
+ if (label2.equals(HELIX) || label2.equals(SHEET)
+ || label2.equals(STEM))
{
tlabel = "" + anot[index].secondaryStructure;
}
* DOCUMENT ME!
*
* @param evt
- * DOCUMENT ME!
+ * DOCUMENT ME!
*/
public void mousePressed(MouseEvent evt)
{
}
JPopupMenu pop = new JPopupMenu("Structure type");
- JMenuItem item = new JMenuItem(HELIX);
- item.addActionListener(this);
- pop.add(item);
- item = new JMenuItem(SHEET);
- item.addActionListener(this);
- pop.add(item);
+ JMenuItem item;
+ /*
+ * Just display the needed structure options
+ */
+ if (av.alignment.isNucleotide() == true)
+ {
+ item = new JMenuItem(STEM);
+ item.addActionListener(this);
+ pop.add(item);
+ }
+ else
+ {
+ item = new JMenuItem(HELIX);
+ item.addActionListener(this);
+ pop.add(item);
+ item = new JMenuItem(SHEET);
+ item.addActionListener(this);
+ pop.add(item);
+ }
item = new JMenuItem(LABEL);
item.addActionListener(this);
pop.add(item);
* DOCUMENT ME!
*
* @param evt
- * DOCUMENT ME!
+ * DOCUMENT ME!
*/
public void mouseReleased(MouseEvent evt)
{
* DOCUMENT ME!
*
* @param evt
- * DOCUMENT ME!
+ * DOCUMENT ME!
*/
public void mouseEntered(MouseEvent evt)
{
* DOCUMENT ME!
*
* @param evt
- * DOCUMENT ME!
+ * DOCUMENT ME!
*/
public void mouseExited(MouseEvent evt)
{
* DOCUMENT ME!
*
* @param evt
- * DOCUMENT ME!
+ * DOCUMENT ME!
*/
public void mouseDragged(MouseEvent evt)
{
* DOCUMENT ME!
*
* @param evt
- * DOCUMENT ME!
+ * DOCUMENT ME!
*/
public void mouseMoved(MouseEvent evt)
{
res = av.getColumnSelection().adjustForHiddenColumns(res);
}
- if (aa[row].annotations != null && row > -1
+ if (row > -1 && aa[row].annotations != null
&& res < (int) aa[row].annotations.length)
{
if (aa[row].graphGroup > -1)
}
}
else if (aa[row].annotations[res] != null
- && aa[row].annotations[res].description != null)
+ && aa[row].annotations[res].description != null
+ && aa[row].annotations[res].description.length() > 0)
{
this.setToolTipText(aa[row].annotations[res].description);
}
+ else
+ {
+ // clear the tooltip.
+ this.setToolTipText(null);
+ }
if (aa[row].annotations[res] != null)
{
* DOCUMENT ME!
*
* @param evt
- * DOCUMENT ME!
+ * DOCUMENT ME!
*/
public void mouseClicked(MouseEvent evt)
{
+ if (activeRow != -1)
+ {
+ AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();
+ AlignmentAnnotation anot = aa[activeRow];
+
+ if (anot.description.equals("secondary structure"))
+ {
+ // System.out.println(anot.description+" "+anot.getRNAStruc());
+ }
+ }
+ }
+
+ // TODO mouseClicked-content and drawCursor are quite experimental!
+ public void drawCursor(Graphics graphics, SequenceI seq, int res, int x1,
+ int y1)
+ {
+ int pady = av.charHeight / 5;
+ int charOffset = 0;
+ graphics.setColor(Color.black);
+ graphics.fillRect(x1, y1, av.charWidth, av.charHeight);
+
+ if (av.validCharWidth)
+ {
+ graphics.setColor(Color.white);
+
+ char s = seq.getCharAt(res);
+
+ charOffset = (av.charWidth - fm.charWidth(s)) / 2;
+ graphics.drawString(String.valueOf(s), charOffset + x1,
+ (y1 + av.charHeight) - pady);
+ }
+
}
/**
* DOCUMENT ME!
*
* @param g
- * DOCUMENT ME!
+ * DOCUMENT ME!
*/
public void paintComponent(Graphics g)
{
* non-Thread safe repaint
*
* @param horizontal
- * repaint with horizontal shift in alignment
+ * repaint with horizontal shift in alignment
*/
public void fastPaint(int horizontal)
{
* DOCUMENT ME!
*
* @param g
- * DOCUMENT ME!
+ * DOCUMENT ME!
* @param startRes
- * DOCUMENT ME!
+ * DOCUMENT ME!
* @param endRes
- * DOCUMENT ME!
+ * DOCUMENT ME!
*/
public void drawComponent(Graphics g, int startRes, int endRes)
{
boolean validRes = false;
boolean validEnd = false;
boolean labelAllCols = false;
- boolean centreColLabels,centreColLabelsDef = av.getCentreColumnLabels();
- boolean scaleColLabel=false;
+ boolean centreColLabels, centreColLabelsDef = av
+ .getCentreColumnLabels();
+ boolean scaleColLabel = false;
boolean[] graphGroupDrawn = new boolean[aa.length];
int charOffset = 0; // offset for a label
- float fmWidth, fmScaling = 1f; // scaling for a label to fit it into a column.
+ float fmWidth, fmScaling = 1f; // scaling for a label to fit it into a
+ // column.
Font ofont = g.getFont();
// \u03B2 \u03B1
for (int i = 0; i < aa.length; i++)
scaleColLabel = row.scaleColLabel;
lastSS = ' ';
lastSSX = 0;
-
if (row.graph > 0)
{
if (row.graphGroup > -1 && graphGroupDrawn[row.graphGroup])
continue;
}
- x = 0;
+ // first pass sets up state for drawing continuation from left-hand column
+ // of startRes
+ x = (startRes == 0) ? 0 : -1;
while (x < endRes - startRes)
{
if (av.hasHiddenColumns)
{
validRes = true;
}
-
- if (activeRow == i)
+ if (x > -1)
{
- g.setColor(Color.red);
-
- if (av.getColumnSelection() != null)
+ if (activeRow == i)
{
- for (int n = 0; n < av.getColumnSelection().size(); n++)
- {
- int v = av.getColumnSelection().columnAt(n);
+ g.setColor(Color.red);
- if (v == column)
+ if (av.getColumnSelection() != null)
+ {
+ for (int n = 0; n < av.getColumnSelection().size(); n++)
{
- g
- .fillRect(x * av.charWidth, y, av.charWidth,
- av.charHeight);
+ int v = av.getColumnSelection().columnAt(n);
+
+ if (v == column)
+ {
+ g.fillRect(x * av.charWidth, y, av.charWidth,
+ av.charHeight);
+ }
}
}
}
- }
- if (av.validCharWidth && validRes
- && row.annotations[column].displayCharacter != null
- && (row.annotations[column].displayCharacter.length() > 0))
- {
-
- if (centreColLabels || scaleColLabel)
+ if (av.validCharWidth
+ && validRes
+ && row.annotations[column].displayCharacter != null
+ && (row.annotations[column].displayCharacter.length() > 0))
{
- fmWidth = (float) fm
- .charsWidth(row.annotations[column].displayCharacter
- .toCharArray(), 0,
- row.annotations[column].displayCharacter.length());
-
- if ( scaleColLabel ) {
- // justify the label and scale to fit in column
- if (fmWidth > av.charWidth) {
- // scale only if the current font isn't already small enough
- fmScaling = av.charWidth;
- fmScaling /= fmWidth;
- g.setFont(ofont.deriveFont(AffineTransform.getScaleInstance(fmScaling, 1.0)));
- // and update the label's width to reflect the scaling.
- fmWidth = av.charWidth;
+
+ if (centreColLabels || scaleColLabel)
+ {
+ fmWidth = (float) fm.charsWidth(
+ row.annotations[column].displayCharacter
+ .toCharArray(), 0,
+ row.annotations[column].displayCharacter.length());
+
+ if (scaleColLabel)
+ {
+ // justify the label and scale to fit in column
+ if (fmWidth > av.charWidth)
+ {
+ // scale only if the current font isn't already small enough
+ fmScaling = av.charWidth;
+ fmScaling /= fmWidth;
+ g.setFont(ofont.deriveFont(AffineTransform
+ .getScaleInstance(fmScaling, 1.0)));
+ // and update the label's width to reflect the scaling.
+ fmWidth = av.charWidth;
+ }
}
}
- } else {
- fmWidth = (float) fm
- .charWidth(row.annotations[column].displayCharacter.charAt(0));
- }
- charOffset = (int) ((av.charWidth - fmWidth) / 2f);
-
- if (row.annotations[column].colour == null)
- g.setColor(Color.black);
- else
- g.setColor(row.annotations[column].colour);
+ else
+ {
+ fmWidth = (float) fm
+ .charWidth(row.annotations[column].displayCharacter
+ .charAt(0));
+ }
+ charOffset = (int) ((av.charWidth - fmWidth) / 2f);
- if (column == 0 || row.graph > 0)
- {
- g.drawString(row.annotations[column].displayCharacter,
- (x * av.charWidth) + charOffset, y + iconOffset);
- }
- else if (row.annotations[column - 1] == null
- || (labelAllCols||!row.annotations[column].displayCharacter
- .equals(row.annotations[column - 1].displayCharacter) || (row.annotations[column].displayCharacter
- .length() < 2 && row.annotations[column].secondaryStructure == ' ')))
- {
- g.drawString(row.annotations[column].displayCharacter, x
- * av.charWidth + charOffset, y + iconOffset);
+ if (row.annotations[column].colour == null)
+ g.setColor(Color.black);
+ else
+ g.setColor(row.annotations[column].colour);
+
+ if (column == 0 || row.graph > 0)
+ {
+ g.drawString(row.annotations[column].displayCharacter,
+ (x * av.charWidth) + charOffset, y + iconOffset);
+ }
+ else if (row.annotations[column - 1] == null
+ || (labelAllCols
+ || !row.annotations[column].displayCharacter
+ .equals(row.annotations[column - 1].displayCharacter) || (row.annotations[column].displayCharacter
+ .length() < 2 && row.annotations[column].secondaryStructure == ' ')))
+ {
+ g.drawString(row.annotations[column].displayCharacter, x
+ * av.charWidth + charOffset, y + iconOffset);
+ }
+ g.setFont(ofont);
}
- g.setFont(ofont);
}
-
if (row.hasIcons)
{
- if (!validRes
- || (row.annotations[column].secondaryStructure != lastSS))
+ char ss = validRes ? row.annotations[column].secondaryStructure
+ : ' ';
+ if (ss == 'S')
{
- switch (lastSS)
+ // distinguish between forward/backward base-pairing
+ if (row.annotations[column].displayCharacter.indexOf(')') > -1)
{
- case 'H':
- g.setColor(HELIX_COLOUR);
- if (MAC)
+ ss = 's';
+ }
+ }
+ if (!validRes || (ss != lastSS))
+ {
+ if (x > -1)
+ {
+ switch (lastSS)
{
- // Off by 1 offset when drawing rects and ovals
- // to offscreen image on the MAC
- g.fillRoundRect(lastSSX, y + 4 + iconOffset,
- (x * av.charWidth) - lastSSX, 7, 8, 8);
+ case 'H':
+ drawHelixAnnot(g, row, lastSSX, x, y, iconOffset, startRes,
+ column, validRes, validEnd);
break;
- }
-
- int sCol = (lastSSX / av.charWidth) + startRes;
- int x1 = lastSSX;
- int x2 = (x * av.charWidth);
- if (sCol == 0
- || row.annotations[sCol - 1] == null
- || row.annotations[sCol - 1].secondaryStructure != 'H')
- {
- g.fillArc(lastSSX, y + 4 + iconOffset, av.charWidth, 8, 90,
- 180);
- x1 += av.charWidth / 2;
- }
-
- if (!validRes || row.annotations[column] == null
- || row.annotations[column].secondaryStructure != 'H')
- {
- g.fillArc((x * av.charWidth) - av.charWidth, y + 4
- + iconOffset, av.charWidth, 8, 270, 180);
- x2 -= av.charWidth / 2;
- }
-
- g.fillRect(x1, y + 4 + iconOffset, x2 - x1, 8);
- break;
-
- case 'E':
- g.setColor(SHEET_COLOUR);
- g.fillRect(lastSSX, y + 4 + iconOffset, (x * av.charWidth)
- - lastSSX - 4, 7);
- g.fillPolygon(new int[]
- { (x * av.charWidth) - 4, (x * av.charWidth) - 4,
- (x * av.charWidth) }, new int[]
- { y + iconOffset, y + 14 + iconOffset, y + 8 + iconOffset },
- 3);
+ case 'E':
+ drawSheetAnnot(g, row, lastSSX, x, y, iconOffset, startRes,
+ column, validRes, validEnd);
+ break;
- break;
+ case 'S': // Stem case for RNA secondary structure
+ case 's': // and opposite direction
+ drawStemAnnot(g, row, lastSSX, x, y, iconOffset, startRes,
+ column, validRes, validEnd);
+ break;
- default:
- g.setColor(Color.gray);
- g.fillRect(lastSSX, y + 6 + iconOffset, (x * av.charWidth)
- - lastSSX, 2);
+ default:
+ g.setColor(Color.gray);
+ g.fillRect(lastSSX, y + 6 + iconOffset, (x * av.charWidth)
+ - lastSSX, 2);
- break;
+ break;
+ }
}
-
if (validRes)
{
- lastSS = row.annotations[column].secondaryStructure;
+ lastSS = ss;
}
else
{
lastSS = ' ';
}
-
- lastSSX = (x * av.charWidth);
+ if (x > -1)
+ {
+ lastSSX = (x * av.charWidth);
+ }
}
}
-
column++;
x++;
}
-
if (column >= row.annotations.length)
{
column = row.annotations.length - 1;
switch (lastSS)
{
case 'H':
- g.setColor(HELIX_COLOUR);
- if (MAC)
- {
- // Off by 1 offset when drawing rects and ovals
- // to offscreen image on the MAC
- g.fillRoundRect(lastSSX, y + 4 + iconOffset, (x * av.charWidth)
- - lastSSX, 7, 8, 8);
- break;
- }
-
- int sCol = (lastSSX / av.charWidth) + startRes;
- int x1 = lastSSX;
- int x2 = (x * av.charWidth);
-
- if (sCol == 0 || row.annotations[sCol - 1] == null
- || row.annotations[sCol - 1].secondaryStructure != 'H')
- {
- g
- .fillArc(lastSSX, y + 4 + iconOffset, av.charWidth, 8,
- 90, 180);
- x1 += av.charWidth / 2;
- }
-
- if (row.annotations[column] == null
- || row.annotations[column].secondaryStructure != 'H')
- {
- g.fillArc((x * av.charWidth) - av.charWidth,
- y + 4 + iconOffset, av.charWidth, 8, 270, 180);
- x2 -= av.charWidth / 2;
- }
-
- g.fillRect(x1, y + 4 + iconOffset, x2 - x1, 8);
-
+ drawHelixAnnot(g, row, lastSSX, x, y, iconOffset, startRes,
+ column, validRes, validEnd);
break;
case 'E':
- g.setColor(SHEET_COLOUR);
-
- if (!validEnd || row.annotations[endRes] == null
- || row.annotations[endRes].secondaryStructure != 'E')
- {
- g.fillRect(lastSSX, y + 4 + iconOffset, (x * av.charWidth)
- - lastSSX - 4, 7);
- g.fillPolygon(new int[]
- { (x * av.charWidth) - 4, (x * av.charWidth) - 4,
- (x * av.charWidth) }, new int[]
- { y + iconOffset, y + 14 + iconOffset, y + 7 + iconOffset }, 3);
- }
- else
- {
- g.fillRect(lastSSX, y + 4 + iconOffset, (x + 1) * av.charWidth
- - lastSSX, 7);
- }
+ drawSheetAnnot(g, row, lastSSX, x, y, iconOffset, startRes,
+ column, validRes, validEnd);
+ break;
+ case 's':
+ case 'S': // Stem case for RNA secondary structure
+ drawStemAnnot(g, row, lastSSX, x, y, iconOffset, startRes,
+ column, validRes, validEnd);
break;
-
default:
- g.setColor(Color.gray);
- g.fillRect(lastSSX, y + 6 + iconOffset, (x * av.charWidth)
- - lastSSX, 2);
-
+ drawGlyphLine(g, row, lastSSX, x, y, iconOffset, startRes,
+ column, validRes, validEnd);
break;
}
}
}
}
+ private void drawStemAnnot(Graphics g, AlignmentAnnotation row,
+ int lastSSX, int x, int y, int iconOffset, int startRes,
+ int column, boolean validRes, boolean validEnd)
+ {
+ g.setColor(STEM_COLOUR);
+ int sCol = (lastSSX / av.charWidth) + startRes;
+ int x1 = lastSSX;
+ int x2 = (x * av.charWidth);
+ Regex closeparen = new Regex("(\\))");
+
+ String dc = column == 0 ? ""
+ : row.annotations[column - 1].displayCharacter;
+
+ boolean diffupstream = sCol == 0 || row.annotations[sCol - 1] == null
+ || !dc.equals(row.annotations[sCol - 1].displayCharacter);
+ boolean diffdownstream = !validRes || !validEnd
+ || row.annotations[column] == null
+ || !dc.equals(row.annotations[column].displayCharacter);
+ // System.out.println("Column "+column+" diff up: "+diffupstream+" down:"+diffdownstream);
+ // If a closing base pair half of the stem, display a backward arrow
+ if (column > 0 && closeparen.search(dc))
+ {
+ if (diffupstream)
+ // if (validRes && column>1 && row.annotations[column-2]!=null &&
+ // dc.equals(row.annotations[column-2].displayCharacter))
+ {
+ g.fillPolygon(new int[]
+ { lastSSX + 5, lastSSX + 5, lastSSX }, new int[]
+ { y + iconOffset, y + 14 + iconOffset, y + 8 + iconOffset }, 3);
+ x1 += 5;
+ }
+ if (diffdownstream)
+ {
+ x2 -= 1;
+ }
+ }
+ else
+ {
+ // display a forward arrow
+ if (diffdownstream)
+ {
+ g.fillPolygon(new int[]
+ { x2 - 5, x2 - 5, x2 }, new int[]
+ { y + iconOffset, y + 14 + iconOffset, y + 8 + iconOffset }, 3);
+ x2 -= 5;
+ }
+ if (diffupstream)
+ {
+ x1 += 1;
+ }
+ }
+ // draw arrow body
+ g.fillRect(x1, y + 4 + iconOffset, x2 - x1, 7);
+ }
+
+ private void drawGlyphLine(Graphics g, AlignmentAnnotation row,
+ int lastSSX, int x, int y, int iconOffset, int startRes,
+ int column, boolean validRes, boolean validEnd)
+ {
+ g.setColor(Color.gray);
+ g
+ .fillRect(lastSSX, y + 6 + iconOffset, (x * av.charWidth)
+ - lastSSX, 2);
+ }
+
+ private void drawSheetAnnot(Graphics g, AlignmentAnnotation row,
+ int lastSSX, int x, int y, int iconOffset, int startRes,
+ int column, boolean validRes, boolean validEnd)
+ {
+ g.setColor(SHEET_COLOUR);
+
+ if (!validEnd || !validRes || row.annotations[column] == null
+ || row.annotations[column].secondaryStructure != 'E')
+ {
+ g.fillRect(lastSSX, y + 4 + iconOffset, (x * av.charWidth) - lastSSX
+ - 4, 7);
+ g.fillPolygon(
+ new int[]
+ { (x * av.charWidth) - 4, (x * av.charWidth) - 4,
+ (x * av.charWidth) }, new int[]
+ { y + iconOffset, y + 14 + iconOffset, y + 7 + iconOffset },
+ 3);
+ }
+ else
+ {
+ g.fillRect(lastSSX, y + 4 + iconOffset, (x + 1) * av.charWidth
+ - lastSSX, 7);
+ }
+
+ }
+
+ private void drawHelixAnnot(Graphics g, AlignmentAnnotation row,
+ int lastSSX, int x, int y, int iconOffset, int startRes,
+ int column, boolean validRes, boolean validEnd)
+ {
+ g.setColor(HELIX_COLOUR);
+
+ int sCol = (lastSSX / av.charWidth) + startRes;
+ int x1 = lastSSX;
+ int x2 = (x * av.charWidth);
+
+ if (MAC)
+ {
+ int ofs = av.charWidth / 2;
+ // Off by 1 offset when drawing rects and ovals
+ // to offscreen image on the MAC
+ g.fillRoundRect(lastSSX, y + 4 + iconOffset, x2 - x1, 8, 8, 8);
+ if (sCol == 0 || row.annotations[sCol - 1] == null
+ || row.annotations[sCol - 1].secondaryStructure != 'H')
+ {
+ }
+ else
+ {
+ // g.setColor(Color.orange);
+ g.fillRoundRect(lastSSX, y + 4 + iconOffset, x2 - x1 - ofs + 1, 8,
+ 0, 0);
+ }
+ if (!validRes || row.annotations[column] == null
+ || row.annotations[column].secondaryStructure != 'H')
+ {
+
+ }
+ else
+ {
+ // g.setColor(Color.magenta);
+ g.fillRoundRect(lastSSX + ofs, y + 4 + iconOffset, x2 - x1 - ofs
+ + 1, 8, 0, 0);
+
+ }
+
+ return;
+ }
+
+ if (sCol == 0 || row.annotations[sCol - 1] == null
+ || row.annotations[sCol - 1].secondaryStructure != 'H')
+ {
+ g.fillArc(lastSSX, y + 4 + iconOffset, av.charWidth, 8, 90, 180);
+ x1 += av.charWidth / 2;
+ }
+
+ if (!validRes || row.annotations[column] == null
+ || row.annotations[column].secondaryStructure != 'H')
+ {
+ g.fillArc((x * av.charWidth) - av.charWidth, y + 4 + iconOffset,
+ av.charWidth, 8, 270, 180);
+ x2 -= av.charWidth / 2;
+ }
+
+ g.fillRect(x1, y + 4 + iconOffset, x2 - x1, 8);
+ }
+
public void drawLineGraph(Graphics g, AlignmentAnnotation aa, int sRes,
int eRes, int y, float min, float max, int graphHeight)
{
int eRes, float min, float max, int y)
{
ColourSchemeI profcolour = av.getGlobalColourScheme();
- if (profcolour==null)
+ if (profcolour == null)
{
profcolour = new jalview.schemes.ZappoColourScheme();
}
int column;
int aaMax = aa.annotations.length - 1;
boolean renderHistogram = true, renderProfile = true;
- if (aa.autoCalculated && aa.label.startsWith("Consensus")) {
- // TODO: generalise this to have render styles for consensus/profile data
- if (aa.groupRef!=null)
+ if (aa.autoCalculated && aa.label.startsWith("Consensus"))
+ {
+ // TODO: generalise this to have render styles for consensus/profile data
+ if (aa.groupRef != null)
{
renderHistogram = aa.groupRef.isShowConsensusHistogram();
- renderProfile = aa.groupRef.isIncludeAllConsSymbols();
- } else {
+ renderProfile = aa.groupRef.isShowSequenceLogo();
+ }
+ else
+ {
renderHistogram = av.isShowConsensusHistogram();
- renderProfile = av.isShowConsensusProfile();
+ renderProfile = av.isShowSequenceLogo();
}
}
while (x < eRes - sRes)
- (int) (((aa.annotations[column].value - min) / (range)) * aa.graphHeight);
if (renderHistogram)
- {
- if (y1 - y2 > 0)
{
- g.fillRect(x * av.charWidth, y2, av.charWidth, y1 - y2);
- }
- else
- {
- g.fillRect(x * av.charWidth, y1, av.charWidth, y2 - y1);
- }
+ if (y1 - y2 > 0)
+ {
+ g.fillRect(x * av.charWidth, y2, av.charWidth, y1 - y2);
+ }
+ else
+ {
+ g.fillRect(x * av.charWidth, y1, av.charWidth, y2 - y1);
+ }
}
// draw profile if available
- if (aa.annotations[column].value!=0 && renderProfile)
+ if (renderProfile && aa.annotations[column].value != 0)
{
- int profl[] = getProfileFor(aa,column);
- int ht = y1,htn=y2-y1;//aa.graphHeight;
+
+ int profl[] = getProfileFor(aa, column);
+ // just try to draw the logo if profl is not null
+ if (profl != null)
+ {
+
+ int ht = y1, htn = y2 - y1;// aa.graphHeight;
float wdth;
- double ht2=0;
- char[] dc = new char[1];
+ double ht2 = 0;
+ char[] dc;
+
+ /**
+ * profl.length == 51 indicates that the profile of a secondary
+ * structure conservation row was accesed.
+ * Therefore dc gets length 2, to have space for a basepair instead of
+ * just a single nucleotide
+ */
+ if (profl.length == 51)
+ {
+ dc = new char[2];
+ }
+ else
+ {
+ dc = new char[1];
+ }
+
LineMetrics lm;
- for (int c=1;profl!=null && c<profl[0];)
+ for (int c = 1; profl != null && c < profl[0];)
{
dc[0] = (char) profl[c++];
- wdth = av.charWidth;
- wdth/=(float) fm
- .charsWidth(dc,0,1);
+
+ if (aa.label.startsWith("StrucConsensus"))
+ {
+ dc[1] = (char) profl[c++];
+ }
- if (c>2)
+ wdth = av.charWidth;
+ wdth /= (float) fm.charsWidth(dc, 0, dc.length);
+
+ if (c > 2)
{
- ht+=(int)ht2;
+ ht += (int) ht2;
}
{
- //if (aa.annotations[column].value==0) {
- // g.setFont(ofont.deriveFont(AffineTransform.getScaleInstance(wdth, (ht2=(aa.graphHeight*0.1/av.charHeight)))));
- // ht = y2-(int)ht2;
- //} else {
- g.setFont(ofont.deriveFont(AffineTransform.getScaleInstance(wdth, (ht2=(htn*((double)profl[c++])/100.0))/av.charHeight)));
- lm = g.getFontMetrics().getLineMetrics(dc,0,1, g);
- //htn -=ht2;
- //}
- g.setColor(profcolour.findColour(dc[0])); // (av.globalColourScheme!=null) ? );// try to get a colourscheme for the group(aa.groupRef.cs==null) ? av.textColour2 : cs.findColour(dc));
- g.drawChars(dc,0,1,x*av.charWidth, (int) (ht+lm.getHeight()));
+ // if (aa.annotations[column].value==0) {
+ // g.setFont(ofont.deriveFont(AffineTransform.getScaleInstance(wdth,
+ // (ht2=(aa.graphHeight*0.1/av.charHeight)))));
+ // ht = y2-(int)ht2;
+ // } else {
+ g.setFont(ofont.deriveFont(AffineTransform.getScaleInstance(
+ wdth, (ht2 = (htn * ((double) profl[c++]) / 100.0))
+ / av.charHeight)));
+ lm = g.getFontMetrics().getLineMetrics(dc, 0, 1, g);
+ // htn -=ht2;
+ // }
+ g.setColor(profcolour.findColour(dc[0])); // (av.globalColourScheme!=null)
+ // ? );// try to get a
+ // colourscheme for the
+ // group(aa.groupRef.cs==null)
+ // ? av.textColour2 :
+ // cs.findColour(dc));
+ // System.out.println(dc[0]);
+
+ g.drawChars(dc, 0, dc.length, x * av.charWidth,
+ (int) (ht + lm.getHeight()));
+
// ht+=g.getFontMetrics().getAscent()-g.getFontMetrics().getDescent();
}
}
g.setFont(ofont);
+ }
}
x++;
}
private int[] getProfileFor(AlignmentAnnotation aa, int column)
{
- if (aa.autoCalculated && aa.label.startsWith("Consensus")) {
- if (aa.groupRef!=null && aa.groupRef.consensusData!=null && aa.groupRef.isIncludeAllConsSymbols()) {
- return AAFrequency.extractProfile(aa.groupRef.consensusData[column],aa.groupRef.getIgnoreGapsConsensus());
- }
- // TODO extend annotation row to enable dynamic and static profile data to be stored
- if (aa.groupRef==null && aa.sequenceRef==null && av.isShowConsensusProfile())
+ if (aa.autoCalculated && aa.label.startsWith("Consensus"))
{
- return AAFrequency.extractProfile(av.hconsensus[column],av.getIgnoreGapsConsensus());
+ if (aa.groupRef != null && aa.groupRef.consensusData != null
+ && aa.groupRef.isShowSequenceLogo())
+ {
+ return AAFrequency.extractProfile(
+ aa.groupRef.consensusData[column], aa.groupRef
+ .getIgnoreGapsConsensus());
+ }
+ // TODO extend annotation row to enable dynamic and static profile data to
+ // be stored
+ if (aa.groupRef == null && aa.sequenceRef == null
+ && av.isShowSequenceLogo())
+ {
+ return AAFrequency.extractProfile(av.hconsensus[column], av
+ .getIgnoreGapsConsensus());
+ }
}
+ else
+ {
+ if (aa.autoCalculated && aa.label.startsWith("StrucConsensus"))
+ {
+ if (aa.groupRef != null && aa.groupRef.consensusData != null
+ && aa.groupRef.isShowSequenceLogo())
+ {
+ //TODO check what happens for group selections
+ return StructureFrequency.extractProfile(
+ aa.groupRef.consensusData[column], aa.groupRef
+ .getIgnoreGapsConsensus(),column);
+ }
+ // TODO extend annotation row to enable dynamic and static profile data
+ // to
+ // be stored
+ if (aa.groupRef == null && aa.sequenceRef == null
+ && av.isShowSequenceLogo())
+ {
+ return StructureFrequency.extractProfile(av.hStrucConsensus[column],
+ av.getIgnoreGapsConsensus(),column);
+ }
+ }
+
}
return null;
}