-ST-TURN-IIL blue|255,0,255|absolute|20.0|95.0|below|66.0
-GAMMA-TURN-CLASSIC lightGray|0,255,255|20.0|95.0|below|66.0
+ST-TURN-IIL blue
+GAMMA-TURN-CLASSIC lightGray
BETA-TURN-IR 9a6a94
BETA-TURN-IL d6a6ca
BETA-BULGE 1dc451
PHOSPHORYLATION (T) c88395
BETA-TURN-IIL 8b5b50
ST-MOTIF ac25a1
+kdHydrophobicity ccffcc|333300|-3.9|4.5|above|-2.0
STARTGROUP uniprot
<html><a href="http://pfam.xfam.org/family/PF00111">Pfam family</a></html> FER_CAPAA -1 0 0 Pfam
NEST-RL FER1_MAIZE -1 241 243 NEST-RL
NEST-RL FER1_MAIZE -1 292 294 NEST-RL
ENDGROUP s3dm
+
+STARTGROUP kd
+A Q93XJ9_SOLTU -1 48 48 kdHydrophobicity 1.8
+A Q93XJ9_SOLTU -1 49 49 kdHydrophobicity -0.8
+A Q93XJ9_SOLTU -1 50 50 kdHydrophobicity -1.3
+A Q93XJ9_SOLTU -1 51 51 kdHydrophobicity -3.9
+A Q93XJ9_SOLTU -1 52 52 kdHydrophobicity 4.2
+A Q93XJ9_SOLTU -1 53 53 kdHydrophobicity -3.9
+A Q93XJ9_SOLTU -1 54 54 kdHydrophobicity 3.8
+A Q93XJ9_SOLTU -1 55 55 kdHydrophobicity 4.5
+A Q93XJ9_SOLTU -1 56 56 kdHydrophobicity -0.7
+A Q93XJ9_SOLTU -1 57 57 kdHydrophobicity -1.6
+A Q93XJ9_SOLTU -1 58 58 kdHydrophobicity -3.5
+A Q93XJ9_SOLTU -1 59 59 kdHydrophobicity -0.4
+A Q93XJ9_SOLTU -1 60 60 kdHydrophobicity -1.6
+A Q93XJ9_SOLTU -1 61 61 kdHydrophobicity 4.5
+A Q93XJ9_SOLTU -1 62 62 kdHydrophobicity -3.5
+A Q93XJ9_SOLTU -1 63 63 kdHydrophobicity 2.8
+A FER1_SPIOL -1 51 51 kdHydrophobicity 1.8
+A FER1_SPIOL -1 52 52 kdHydrophobicity 1.8
+A FER1_SPIOL -1 53 53 kdHydrophobicity -1.3
+A FER1_SPIOL -1 54 54 kdHydrophobicity -3.9
+A FER1_SPIOL -1 55 55 kdHydrophobicity 4.2
+A FER1_SPIOL -1 56 56 kdHydrophobicity -0.7
+A FER1_SPIOL -1 57 57 kdHydrophobicity 3.8
+A FER1_SPIOL -1 58 58 kdHydrophobicity 4.2
+A FER1_SPIOL -1 59 59 kdHydrophobicity -0.7
+A FER1_SPIOL -1 60 60 kdHydrophobicity -1.6
+A FER1_SPIOL -1 61 61 kdHydrophobicity -0.7
+A FER1_SPIOL -1 62 62 kdHydrophobicity -0.4
+A FER1_SPIOL -1 63 63 kdHydrophobicity -3.5
+A FER1_SPIOL -1 64 64 kdHydrophobicity 4.2
+A FER1_SPIOL -1 65 65 kdHydrophobicity -3.5
+A FER1_SPIOL -1 66 66 kdHydrophobicity 2.8
+C FER1_MAIZE -1 53 53 kdHydrophobicity 1.8
+C FER1_MAIZE -1 54 54 kdHydrophobicity -0.7
+C FER1_MAIZE -1 55 55 kdHydrophobicity -1.3
+C FER1_MAIZE -1 56 56 kdHydrophobicity -3.5
+C FER1_MAIZE -1 57 57 kdHydrophobicity 4.2
+C FER1_MAIZE -1 58 58 kdHydrophobicity -3.9
+C FER1_MAIZE -1 59 59 kdHydrophobicity 3.8
+C FER1_MAIZE -1 60 60 kdHydrophobicity 4.5
+C FER1_MAIZE -1 61 61 kdHydrophobicity -0.7
+C FER1_MAIZE -1 62 62 kdHydrophobicity -1.6
+C FER1_MAIZE -1 63 63 kdHydrophobicity -3.5
+C FER1_MAIZE -1 64 64 kdHydrophobicity -0.4
+C FER1_MAIZE -1 65 65 kdHydrophobicity -3.5
+C FER1_MAIZE -1 66 66 kdHydrophobicity 4.2
+C FER1_MAIZE -1 67 67 kdHydrophobicity -3.5
+C FER1_MAIZE -1 68 68 kdHydrophobicity 3.8
+ENDGROUP kd
</p>
<table>
<tr>
- <td><img src="AnnotationColumnSelectionWithSM.gif"></td>
+ <td><img src="AnnotationColumnSelectionWithSM.png"></td>
<td><img src="AnnotationColumnSelectionWithoutSM.gif"></td>
</tr>
</table>
<li>Select whether to filter the alignment above or below
the threshold.</li>
<li>Change the threshold value with the slider, or enter it
- in the text box.</li>
+ in the text box.
+ <li>The <em>As Percentage</em> checkbox allows thresholds to
+ be set as a percentage rather than absolute value.</li>
</ul>
<li><strong>Actions</strong>
<ul>
<td width="60" nowrap>
<div align="center">
<strong><a name="Jalview.2.10.2">2.10.2</a><br />
- <em>20/6/2017</em></strong>
+ <em>8/8/2017</em></strong>
</div>
</td>
<td><div align="left">
extension when importing structure files without embedded
names or PDB accessions
</li>
- <li><!-- JAL-2547 -->Amend sequence features dialog box can be opened by double clicking gaps within sequence feature extent</li>
+ <li><!-- JAL-2547 -->Amend sequence features dialog box can be opened by double clicking gaps within sequence feature extent</li>
+ <li><!-- JAL-2631 -->Graduated feature colour style example included in the example feature file</li>
</ul>
<em>Application</em>
<ul>
<li><!-- JAL-2385 -->Conservation shading or PID threshold lost when base colourscheme changed if slider not visible</li>
<li><!-- JAL-2547 -->Sequence features shown in tooltip for gaps before start of features</li>
<li><!-- JAL-2576 -->Very large alignments take a long time to load</li>
- <li><!-- JAL-2590 -->Cannot load Newick trees from eggnog ortholog database</li>
+ <li><!-- JAL-2590 -->Cannot load Newick trees from eggnog ortholog database</li>
+ <li><!-- JAL-2623 -->Graduated feature colour threshold not restored to UI when feature colour is edited</li>
+ <li><!-- JAL-2624 -->Feature colour thresholds not respected when rendered on overview and structures when opacity at 100%</li>
+ <li><!-- JAL-2630 -->Structure and alignment overview update as graduate feature colour settings are modified via the dialog box</li>
+ <li><!-- JAL-147 -->Vertical scrollbar jumps one page-width at a time when scrolling vertically in wrapped mode.</li>
+ <li><!-- JAL-2034 -->Overview window doesn't always update when a group defined on the alignment is resized</li>
+
</ul>
<em>Application</em>
<ul>
label.your_sequences_have_been_verified = Your sequences have been verified against known sequence databases.\n(Use Calculate | Show flanking regions to show enclosing sequence.)\nTo preserve data changes, save your alignment.\n\n
label.sequences_updated = Sequences updated
label.dbref_search_completed = DBRef search completed
-label.show_all_chains = Show all chains
label.fetch_all_param = Fetch all {0}
label.paste_new_window = Paste To New Window
label.settings_for_param = Settings for {0}
label.SEQUENCE_ID_for_DB_ACCESSION1 = Please review your URL links in the 'Connections' tab of the Preferences window:
label.SEQUENCE_ID_for_DB_ACCESSION2 = URL links using '$SEQUENCE_ID$' for DB accessions now use '$DB_ACCESSION$'.
label.do_not_display_again = Do not display this message again
-exception.url_cannot_have_miriam_id = {0} is a MIRIAM id and cannot be used as a custom url name
exception.url_cannot_have_duplicate_id = {0} cannot be used as a label for more than one line
label.filter = Filter text:
action.customfilter = Custom only
label.your_sequences_have_been_verified = Sus secuencias has sido verificadas en una base de datos de secuencias conocidas.\n(Usar Calcular | Mostrar flancos para ver ampliación.)\nPara mantener los datos actualizados, guarde su alineamiento.\n\n
label.sequences_updated = Secuencias actualizadas
label.dbref_search_completed = Búsqueda de DBRef terminada
-label.show_all_chains = Mostrar todas las cadenas
label.fetch_all_param = Recuperar todas {0}
label.paste_new_window = Pegar en una nueva ventana
label.settings_for_param = Configuración para {0}
label.SEQUENCE_ID_for_DB_ACCESSION1 = Por favor, revise sus URLs en la pestaña 'Conexiones' de la ventana de Preferencias:
label.SEQUENCE_ID_for_DB_ACCESSION2 = URL enlaza usando '$SEQUENCE_ID$' para accesiones DB ahora usar '$DB_ACCESSION$'.
label.do_not_display_again = No mostrar este mensaje de nuevo
-exception.url_cannot_have_miriam_id = {0} es una id MIRIAM y no puede ser usada como nombre url personalizado
exception.url_cannot_have_duplicate_id = {0} no puede ser usada como etiqueta en más de un enlace
label.filter = Filtrar texto:
action.customfilter = Sólo personalizado
label.invalid_name = Nombre inválido !
label.output_seq_details = Seleccionar Detalles de la secuencia para ver todas
label.urllinks = Enlaces
+label.default_cache_size = Tamaño del caché por defecto
+action.clear_cached_items = Borrar elementos en caché
label.quality_descr = Calidad de alineamiento basándose en puntuación Blosum62
label.conservation_descr = Conservación del alineamiento total menos de {0}% huecos
label.consensus_descr = % Identidad
label.complement_consensus_descr = % Identidad para cDNA
label.strucconsensus_descr = % Identidad para pares de bases
label.occupancy_descr = Número de posiciones alineadas
-label.togglehidden = Show hidden regions
+label.togglehidden = Mostrar regiones ocultas
+label.show_experimental = Habilitar funciones experimentales
+label.show_experimental_tip = Habilitar funciones nuevas y experimentales (ver Latest Release Notes para más detalles)
label.warning_hidden = Advertencia: {0} {1} está actualmente oculto
}
case KeyEvent.VK_PAGE_UP:
- if (viewport.getWrapAlignment())
- {
- ranges.scrollUp(true);
- }
- else
- {
- ranges.pageUp();
- }
+ ranges.pageUp();
break;
case KeyEvent.VK_PAGE_DOWN:
- if (viewport.getWrapAlignment())
- {
- ranges.scrollUp(false);
- }
- else
- {
- ranges.pageDown();
- }
+ ranges.pageDown();
break;
case KeyEvent.VK_Z:
}
Frame frame = new Frame();
- OverviewPanel overview = new OverviewPanel(alignPanel);
+ final OverviewPanel overview = new OverviewPanel(alignPanel);
frame.add(overview);
// +50 must allow for applet frame window
jalview.bin.JalviewLite.addFrame(frame, MessageManager.formatMessage(
@Override
public void windowClosing(WindowEvent e)
{
+ overview.dispose();
if (ap != null)
{
ap.setOverviewPanel(null);
import jalview.bin.JalviewLite;
import jalview.commands.CommandI;
import jalview.datamodel.AlignmentI;
+import jalview.datamodel.Annotation;
import jalview.datamodel.ColumnSelection;
import jalview.datamodel.HiddenColumns;
import jalview.datamodel.SearchResults;
}
- /**
- * get the consensus sequence as displayed under the PID consensus annotation
- * row.
- *
- * @return consensus sequence as a new sequence object
- */
- public SequenceI getConsensusSeq()
- {
- if (consensus == null)
- {
- updateConsensus(null);
- }
- if (consensus == null)
- {
- return null;
- }
- StringBuilder seqs = new StringBuilder(consensus.annotations.length);
- for (int i = 0; i < consensus.annotations.length; i++)
- {
- if (consensus.annotations[i] != null)
- {
- if (consensus.annotations[i].description.charAt(0) == '[')
- {
- seqs.append(consensus.annotations[i].description.charAt(1));
- }
- else
- {
- seqs.append(consensus.annotations[i].displayCharacter);
- }
- }
- }
- SequenceI sq = new Sequence("Consensus", seqs.toString());
- sq.setDescription("Percentage Identity Consensus "
- + ((ignoreGapsInConsensusCalculation) ? " without gaps" : ""));
- return sq;
- }
-
java.awt.Frame nullFrame;
protected FeatureSettings featureSettings = null;
sendViewPosition();
}
- private void adjustVertical(int offy)
+ private void adjustVertical(int newY)
{
- int oldX = vpRanges.getStartRes();
- int oldwidth = vpRanges.getViewportWidth();
- int oldY = vpRanges.getStartSeq();
- int oldheight = vpRanges.getViewportHeight();
-
if (av.getWrapAlignment())
{
- int rowSize = seqPanel.seqCanvas
- .getWrappedCanvasWidth(seqPanel.seqCanvas.getWidth());
-
- // if we're scrolling to the position we're already at, stop
- // this prevents infinite recursion of events when the scroll/viewport
- // ranges values are the same
- if ((offy * rowSize == oldX) && (oldwidth == rowSize))
+ /*
+ * if we're scrolling to the position we're already at, stop
+ * this prevents infinite recursion of events when the scroll/viewport
+ * ranges values are the same
+ */
+ int oldX = vpRanges.getStartRes();
+ int oldY = vpRanges.getWrappedScrollPosition(oldX);
+ if (oldY == newY)
{
return;
}
- else if (offy > -1)
+ if (newY > -1)
{
- vpRanges.setViewportStartAndWidth(offy * rowSize, rowSize);
+ /*
+ * limit page up/down to one width's worth of positions
+ */
+ int rowSize = vpRanges.getViewportWidth();
+ int newX = newY > oldY ? oldX + rowSize : oldX - rowSize;
+ vpRanges.setViewportStartAndWidth(Math.max(0, newX), rowSize);
}
}
else
{
int height = seqPanel.seqCanvas.getHeight() / av.getCharHeight();
+ int oldY = vpRanges.getStartSeq();
+ int oldheight = vpRanges.getViewportHeight();
// if we're scrolling to the position we're already at, stop
// this prevents infinite recursion of events when the scroll/viewport
// ranges values are the same
- if ((offy == oldY) && (height == oldheight))
+ if ((newY == oldY) && (height == oldheight))
{
return;
}
- vpRanges.setViewportStartAndHeight(offy, height);
+ vpRanges.setViewportStartAndHeight(newY, height);
}
if (av.getWrapAlignment() || !fastPaint)
{
}
- /*
+ /**
* Set vertical scroll bar parameters for wrapped panel
- * @param res
- * the residue to scroll to
+ *
+ * @param topLeftColumn
+ * the column position at top left (0..)
*/
- private void setScrollingForWrappedPanel(int res)
+ private void setScrollingForWrappedPanel(int topLeftColumn)
{
- // get the width of the alignment in residues
- int maxwidth = av.getAlignment().getWidth();
- if (av.hasHiddenColumns())
- {
- maxwidth = av.getAlignment().getHiddenColumns()
- .findColumnPosition(maxwidth) - 1;
- }
+ int scrollPosition = vpRanges.getWrappedScrollPosition(topLeftColumn);
+ int maxScroll = vpRanges.getWrappedMaxScroll(topLeftColumn);
- // get the width of the canvas in residues
- int canvasWidth = seqPanel.seqCanvas
- .getWrappedCanvasWidth(seqPanel.seqCanvas.getSize().width);
- if (canvasWidth > 0)
- {
- // position we want to scroll to is number of canvasWidth's to get there
- int current = res / canvasWidth;
-
- // max scroll position: add one because extent is 1 and scrollbar value
- // can only be set to at most max - extent
- int max = maxwidth / canvasWidth + 1;
- vscroll.setUnitIncrement(1);
- vscroll.setValues(current, 1, 0, max);
- }
+ /*
+ * a scrollbar's value can be set to at most (maximum-extent)
+ * so we add extent (1) to the maxScroll value
+ */
+ vscroll.setUnitIncrement(1);
+ vscroll.setValues(scrollPosition, 1, 0, maxScroll + 1);
}
protected Panel sequenceHolderPanel = new Panel();
import java.awt.event.ItemListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
-import java.util.Hashtable;
public class FeatureColourChooser extends Panel implements ActionListener,
AdjustmentListener, ItemListener, MouseListener
{
- JVDialog frame;
+ /*
+ * the absolute min-max range of a feature score is scaled to
+ * 1000 positions on the colour threshold slider
+ */
+ private static final int SCALE_FACTOR_1K = 1000;
- Frame owner;
+ private JVDialog frame;
- FeatureRenderer fr;
+ private Frame owner;
- FeatureSettings fs = null;
+ private FeatureRenderer fr;
- // AlignmentPanel ap;
+ private FeatureSettings fs = null;
- FeatureColourI cs;
+ private FeatureColourI cs;
- FeatureColourI oldcs;
+ private FeatureColourI oldcs;
- Hashtable oldgroupColours;
-
- boolean adjusting = false;
+ private boolean adjusting = false;
private float min, max;
- String type = null;
+ private String type = null;
private AlignFrame af = null;
- public FeatureColourChooser(AlignFrame af, String type)
+ private Panel minColour = new Panel();
+
+ private Panel maxColour = new Panel();
+
+ private Choice threshold = new Choice();
+
+ private Scrollbar slider = new Scrollbar(Scrollbar.HORIZONTAL);
+
+ private TextField thresholdValue = new TextField(20);
+
+ private Checkbox thresholdIsMin = new Checkbox();
+
+ private Checkbox colourFromLabel = new Checkbox();
+
+ private GraphLine threshline;
+
+ /**
+ * Constructor given a context AlignFrame and a feature type. This is used
+ * when opening the graduated colour dialog from the Amend Feature dialog.
+ *
+ * @param alignFrame
+ * @param featureType
+ */
+ public FeatureColourChooser(AlignFrame alignFrame, String featureType)
{
- this.af = af;
- init(af.getSeqcanvas().getFeatureRenderer(), type);
+ this.af = alignFrame;
+ init(alignFrame.getSeqcanvas().getFeatureRenderer(), featureType);
}
- public FeatureColourChooser(FeatureSettings fsettings, String type)
+ /**
+ * Constructor given a context FeatureSettings and a feature type. This is
+ * used when opening the graduated colour dialog from Feature Settings.
+ *
+ * @param fsettings
+ * @param featureType
+ */
+ public FeatureColourChooser(FeatureSettings fsettings, String featureType)
{
this.fs = fsettings;
- init(fsettings.fr, type);
- // this.ap = fsettings.ap;
+ init(fsettings.fr, featureType);
}
- private void init(FeatureRenderer frenderer, String type)
+ private void init(FeatureRenderer frenderer, String featureType)
{
- this.type = type;
+ this.type = featureType;
fr = frenderer;
float mm[] = fr.getMinMax().get(type)[0];
min = mm[0];
max = mm[1];
+ threshline = new GraphLine((max - min) / 2f, "Threshold", Color.black);
oldcs = fr.getFeatureColours().get(type);
if (oldcs.isGraduatedColour())
{
+ threshline.value = oldcs.getThreshold();
cs = new FeatureColour((FeatureColour) oldcs, min, max);
}
else
: 0));
adjusting = false;
- changeColour();
+ changeColour(true);
colourFromLabel.addItemListener(this);
slider.addAdjustmentListener(this);
slider.addMouseListener(this);
frame.setVisible(true);
if (frame.accept)
{
- changeColour();
+ changeColour(true);
}
else
{
// cancel
reset();
- PaintRefresher.Refresh(this, fr.getViewport().getSequenceSetId());
frame.setVisible(false);
}
}
thresholdIsMin.addItemListener(this);
this.setLayout(new GridLayout(4, 1));
+ Panel jPanel1 = new Panel();
jPanel1.setLayout(new FlowLayout());
+ Panel jPanel2 = new Panel();
jPanel2.setLayout(new FlowLayout());
+ Panel jPanel3 = new Panel();
jPanel3.setLayout(new GridLayout(1, 1));
+ Panel jPanel4 = new Panel();
jPanel4.setLayout(new FlowLayout());
jPanel1.setBackground(Color.white);
jPanel2.setBackground(Color.white);
this.add(jPanel4);// , java.awt.BorderLayout.CENTER);
}
- Panel minColour = new Panel();
-
- Panel maxColour = new Panel();
-
- Panel jPanel1 = new Panel();
-
- Panel jPanel2 = new Panel();
-
- Choice threshold = new Choice();
-
- Panel jPanel3 = new Panel();
-
- Panel jPanel4 = new Panel();
-
- Scrollbar slider = new Scrollbar(Scrollbar.HORIZONTAL);
-
- TextField thresholdValue = new TextField(20);
-
- // BorderLayout borderLayout1 = new BorderLayout();
-
- Checkbox thresholdIsMin = new Checkbox();
-
- Checkbox colourFromLabel = new Checkbox();
-
- private GraphLine threshline;
-
@Override
public void actionPerformed(ActionEvent evt)
{
try
{
float f = new Float(thresholdValue.getText()).floatValue();
- slider.setValue((int) (f * 1000));
+ slider.setValue((int) (f * SCALE_FACTOR_1K));
adjustmentValueChanged(null);
+
+ /*
+ * force repaint of any Overview window or structure
+ */
+ changeColour(true);
} catch (NumberFormatException ex)
{
}
}
else
{
- changeColour();
+ changeColour(true);
}
}
{
maxColour.setEnabled(!colourFromLabel.getState());
minColour.setEnabled(!colourFromLabel.getState());
- changeColour();
+ changeColour(true);
}
+ /**
+ * Handler called when the value of the threshold slider changes, either by
+ * user action or programmatically
+ */
@Override
public void adjustmentValueChanged(AdjustmentEvent evt)
{
}
}
+ /**
+ * Responds to a change of colour threshold by computing the absolute value
+ * and refreshing the alignment.
+ */
protected void valueChanged()
{
threshline.value = slider.getValue() / 1000f;
cs.setThreshold(threshline.value);
- changeColour();
+ changeColour(false);
PaintRefresher.Refresh(this, fr.getViewport().getSequenceSetId());
- // ap.paintAlignment(false);
}
public void minColour_actionPerformed(Color newCol)
{
if (newCol == null)
{
- UserDefinedColours udc = new UserDefinedColours(this,
+ new UserDefinedColours(this,
minColour.getBackground(), owner,
- MessageManager.getString("label.select_colour_minimum_value")); // frame.owner,
+ MessageManager.getString("label.select_colour_minimum_value"));
}
else
{
minColour.setBackground(newCol);
minColour.setForeground(newCol);
minColour.repaint();
- changeColour();
+ changeColour(true);
}
}
{
if (newCol == null)
{
-
- // UserDefinedColours udc = new UserDefinedColours(this,
- // "Select Colour for Maximum Value",maxColour.getBackground(),true);
- UserDefinedColours udc = new UserDefinedColours(this,
+ new UserDefinedColours(this,
maxColour.getBackground(), owner,
MessageManager.getString("label.select_colour_maximum_value"));
}
maxColour.setBackground(newCol);
maxColour.setForeground(newCol);
maxColour.repaint();
- changeColour();
+ changeColour(true);
}
}
- void changeColour()
+ void changeColour(boolean updateOverview)
{
// Check if combobox is still adjusting
if (adjusting)
return;
}
- int aboveThreshold = AnnotationColourGradient.NO_THRESHOLD;
+ int thresholdOption = AnnotationColourGradient.NO_THRESHOLD;
if (threshold.getSelectedIndex() == 1)
{
- aboveThreshold = AnnotationColourGradient.ABOVE_THRESHOLD;
+ thresholdOption = AnnotationColourGradient.ABOVE_THRESHOLD;
}
else if (threshold.getSelectedIndex() == 2)
{
- aboveThreshold = AnnotationColourGradient.BELOW_THRESHOLD;
+ thresholdOption = AnnotationColourGradient.BELOW_THRESHOLD;
}
slider.setEnabled(true);
acg.setColourByLabel(colourFromLabel.getState());
maxColour.setEnabled(!colourFromLabel.getState());
minColour.setEnabled(!colourFromLabel.getState());
- if (aboveThreshold == AnnotationColourGradient.NO_THRESHOLD)
+ if (thresholdOption == AnnotationColourGradient.NO_THRESHOLD)
{
slider.setEnabled(false);
thresholdValue.setEnabled(false);
thresholdValue.setText("");
}
- else if (aboveThreshold != AnnotationColourGradient.NO_THRESHOLD
- && threshline == null)
- {
- // todo visual indication of feature threshold
- threshline = new jalview.datamodel.GraphLine((max - min) / 2f,
- "Threshold", Color.black);
- }
-
- if (aboveThreshold != AnnotationColourGradient.NO_THRESHOLD)
+ if (thresholdOption != AnnotationColourGradient.NO_THRESHOLD)
{
adjusting = true;
acg.setThreshold(threshline.value);
- float range = max * 1000f - min * 1000f;
-
- slider.setMinimum((int) (min * 1000));
- slider.setMaximum((int) (max * 1000));
- slider.setValue((int) (threshline.value * 1000));
+ slider.setMinimum((int) (min * SCALE_FACTOR_1K));
+ slider.setMaximum((int) (max * SCALE_FACTOR_1K));
+ slider.setValue((int) (threshline.value * SCALE_FACTOR_1K));
thresholdValue.setText(threshline.value + "");
slider.setEnabled(true);
thresholdValue.setEnabled(true);
adjusting = false;
}
- acg.setAboveThreshold(true);
+ acg.setAboveThreshold(thresholdOption == AnnotationColourGradient.ABOVE_THRESHOLD);
+ acg.setBelowThreshold(thresholdOption == AnnotationColourGradient.BELOW_THRESHOLD);
+
if (thresholdIsMin.getState()
- && aboveThreshold != AnnotationColourGradient.NO_THRESHOLD)
+ && thresholdOption != AnnotationColourGradient.NO_THRESHOLD)
{
- if (aboveThreshold == AnnotationColourGradient.ABOVE_THRESHOLD)
+ if (thresholdOption == AnnotationColourGradient.ABOVE_THRESHOLD)
{
acg = new FeatureColour(acg, threshline.value, max);
}
fr.setColour(type, acg);
cs = acg;
- PaintRefresher.Refresh(this, fr.getViewport().getSequenceSetId());
- // ap.paintAlignment(false);
+ fs.selectionChanged(updateOverview);
}
void reset()
{
fr.setColour(type, oldcs);
- PaintRefresher.Refresh(this, fr.getViewport().getSequenceSetId());
- // ap.paintAlignment(true);
-
+ fs.selectionChanged(true);
}
@Override
@Override
public void mouseReleased(MouseEvent evt)
{
- if (evt.getSource() == minColour || evt.getSource() == maxColour)
+ if (evt.getSource() == minColour)
{
- // relay the event
- actionPerformed(new ActionEvent(evt.getSource(), 1, "Clicked"));
+ minColour_actionPerformed(null);
+ }
+ else if (evt.getSource() == maxColour)
+ {
+ maxColour_actionPerformed(null);
}
else
{
- PaintRefresher.Refresh(this, fr.getViewport().getSequenceSetId());
+ changeColour(true);
+ // PaintRefresher.Refresh(this, fr.getViewport().getSequenceSetId());
}
- // ap.paintAlignment(true);
}
@Override
Checkbox check = (Checkbox) featurePanel.getComponent(i);
check.setState(!check.getState());
}
- selectionChanged();
+ selectionChanged(true);
}
private ItemListener groupItemListener = new ItemListener()
@Override
public void itemStateChanged(ItemEvent evt)
{
- selectionChanged();
+ selectionChanged(true);
}
- void selectionChanged()
+ void selectionChanged(boolean updateOverview)
{
Component[] comps = featurePanel.getComponents();
int cSize = comps.length;
fr.setFeaturePriority(data);
- ap.paintAlignment(true);
+ ap.paintAlignment(updateOverview);
}
MyCheckbox selectedCheck;
public void fastPaint(int vertical)
{
- if (gg == null)
+ if (gg == null || av.getWrapAlignment())
{
repaint();
return;
void drawIds(int starty, int endy)
{
- // hardwired italic IDs in applet currently
- Font italic = new Font(av.getFont().getName(), Font.ITALIC, av
- .getFont().getSize());
- // temp variable for speed
avcharHeight = av.getCharHeight();
- gg.setFont(italic);
-
Color currentColor = Color.white;
Color currentTextColor = Color.black;
final boolean doHiddenCheck = av.isDisplayReferenceSeq()
- || av.hasHiddenRows(), hiddenRows = av.hasHiddenRows()
- && av.getShowHiddenMarkers();
+ || av.hasHiddenRows();
+ boolean hiddenRows = av.hasHiddenRows() && av.getShowHiddenMarkers();
if (av.getWrapAlignment())
{
- int maxwidth = av.getAlignment().getWidth();
- int alheight = av.getAlignment().getHeight();
+ drawIdsWrapped(starty, doHiddenCheck, hiddenRows);
+ return;
+ }
- if (av.hasHiddenColumns())
+ // Now draw the id strings
+ SequenceI seq;
+ for (int i = starty; i <= endy; i++)
+ {
+ seq = av.getAlignment().getSequenceAt(i);
+ if (seq == null)
{
- maxwidth = av.getAlignment().getHiddenColumns()
- .findColumnPosition(maxwidth) - 1;
+ continue;
+ }
+ // hardwired italic IDs in applet currently
+ Font italic = new Font(av.getFont().getName(), Font.ITALIC, av
+ .getFont().getSize());
+ gg.setFont(italic);
+ // boolean isrep=false;
+ if (doHiddenCheck)
+ {
+ // isrep =
+ setHiddenFont(seq);
}
- int annotationHeight = 0;
- AnnotationLabels labels = null;
-
- if (av.isShowAnnotation())
+ // Selected sequence colours
+ if ((searchResults != null) && searchResults.contains(seq))
{
- AnnotationPanel ap = new AnnotationPanel(av);
- annotationHeight = ap.adjustPanelHeight();
- labels = new AnnotationLabels(av);
+ currentColor = Color.black;
+ currentTextColor = Color.white;
}
- int hgap = avcharHeight;
- if (av.getScaleAboveWrapped())
+ else if ((av.getSelectionGroup() != null)
+ && av.getSelectionGroup().getSequences(null).contains(seq))
+ {
+ currentColor = Color.lightGray;
+ currentTextColor = Color.black;
+ }
+ else
{
- hgap += avcharHeight;
+ currentColor = av.getSequenceColour(seq);
+ currentTextColor = Color.black;
}
- int cHeight = alheight * avcharHeight + hgap + annotationHeight;
+ gg.setColor(currentColor);
+ // TODO: isrep could be used to highlight the representative in a
+ // different way
+ gg.fillRect(0, (i - starty) * avcharHeight, getSize().width,
+ avcharHeight);
+ gg.setColor(currentTextColor);
- int rowSize = av.getRanges().getEndRes()
- - av.getRanges().getStartRes();
- // Draw the rest of the panels
- for (int ypos = hgap, row = av.getRanges().getStartRes(); (ypos <= getSize().height)
- && (row < maxwidth); ypos += cHeight, row += rowSize)
+ gg.drawString(seq.getDisplayId(av.getShowJVSuffix()), 0,
+ (((i - starty) * avcharHeight) + avcharHeight)
+ - (avcharHeight / 5));
+
+ if (hiddenRows)
{
- for (int i = starty; i < alheight; i++)
- {
+ drawMarker(i, starty, 0);
+ }
+ }
+ }
- SequenceI s = av.getAlignment().getSequenceAt(i);
- gg.setFont(italic);
- if (doHiddenCheck)
- {
- setHiddenFont(s);
- }
- drawIdString(gg, hiddenRows, s, i, 0, ypos);
- }
+ /**
+ * Draws sequence ids in wrapped mode
+ *
+ * @param starty
+ * @param doHiddenCheck
+ * @param hiddenRows
+ */
+ protected void drawIdsWrapped(int starty, final boolean doHiddenCheck,
+ boolean hiddenRows)
+ {
+ int maxwidth = av.getAlignment().getWidth();
+ int alheight = av.getAlignment().getHeight();
- if (labels != null)
- {
- gg.translate(0, ypos + (alheight * avcharHeight));
- labels.drawComponent(gg, getSize().width);
- gg.translate(0, -ypos - (alheight * avcharHeight));
- }
+ if (av.hasHiddenColumns())
+ {
+ maxwidth = av.getAlignment().getHiddenColumns()
+ .findColumnPosition(maxwidth) - 1;
+ }
- }
+ int annotationHeight = 0;
+ AnnotationLabels labels = null;
+
+ if (av.isShowAnnotation())
+ {
+ AnnotationPanel ap = new AnnotationPanel(av);
+ annotationHeight = ap.adjustPanelHeight();
+ labels = new AnnotationLabels(av);
}
- else
+ int hgap = avcharHeight;
+ if (av.getScaleAboveWrapped())
{
- // Now draw the id strings
- SequenceI seq;
- for (int i = starty; i <= endy; i++)
- {
+ hgap += avcharHeight;
+ }
- seq = av.getAlignment().getSequenceAt(i);
- if (seq == null)
- {
- continue;
- }
- gg.setFont(italic);
- // boolean isrep=false;
- if (doHiddenCheck)
- {
- // isrep =
- setHiddenFont(seq);
- }
+ int cHeight = alheight * avcharHeight + hgap + annotationHeight;
- // Selected sequence colours
- if ((searchResults != null) && searchResults.contains(seq))
- {
- currentColor = Color.black;
- currentTextColor = Color.white;
- }
- else if ((av.getSelectionGroup() != null)
- && av.getSelectionGroup().getSequences(null).contains(seq))
- {
- currentColor = Color.lightGray;
- currentTextColor = Color.black;
- }
- else
- {
- currentColor = av.getSequenceColour(seq);
- currentTextColor = Color.black;
- }
+ int rowSize = av.getRanges().getViewportWidth();
- gg.setColor(currentColor);
- // TODO: isrep could be used to highlight the representative in a
- // different way
- gg.fillRect(0, (i - starty) * avcharHeight, getSize().width,
- avcharHeight);
- gg.setColor(currentTextColor);
+ // hardwired italic IDs in applet currently
+ Font italic = new Font(av.getFont().getName(), Font.ITALIC, av
+ .getFont().getSize());
+ gg.setFont(italic);
- gg.drawString(seq.getDisplayId(av.getShowJVSuffix()), 0,
- (((i - starty) * avcharHeight) + avcharHeight)
- - (avcharHeight / 5));
+ /*
+ * draw repeating sequence ids until out of sequence data or
+ * out of visible space, whichever comes first
+ */
+ int ypos = hgap;
+ int row = av.getRanges().getStartRes();
+ while ((ypos <= getHeight()) && (row < maxwidth))
+ {
+ for (int i = starty; i < alheight; i++)
+ {
- if (hiddenRows)
+ SequenceI s = av.getAlignment().getSequenceAt(i);
+ // gg.setFont(italic);
+ if (doHiddenCheck)
{
- drawMarker(i, starty, 0);
+ setHiddenFont(s);
}
+ drawIdString(gg, hiddenRows, s, i, 0, ypos);
}
+
+ if (labels != null)
+ {
+ gg.translate(0, ypos + (alheight * avcharHeight));
+ labels.drawComponent(gg, getSize().width);
+ gg.translate(0, -ypos - (alheight * avcharHeight));
+ }
+ ypos += cHeight;
+ row += rowSize;
}
}
return false;
}
+ /**
+ * Respond to viewport range changes (e.g. alignment panel was scrolled). Both
+ * scrolling and resizing change viewport ranges. Scrolling changes both start
+ * and end points, but resize only changes end values. Here we only want to
+ * fastpaint on a scroll, with resize using a normal paint, so scroll events
+ * are identified as changes to the horizontal or vertical start value.
+ * <p>
+ * In unwrapped mode, only responds to a vertical scroll, as horizontal scroll
+ * leaves sequence ids unchanged. In wrapped mode, only vertical scroll is
+ * provided, but it generates a change of "startres" which does require an
+ * update here.
+ */
@Override
public void propertyChange(PropertyChangeEvent evt)
{
- // Respond to viewport range changes (e.g. alignment panel was scrolled)
- // Both scrolling and resizing change viewport ranges: scrolling changes
- // both start and end points, but resize only changes end values.
- // Here we only want to fastpaint on a scroll, with resize using a normal
- // paint, so scroll events are identified as changes to the horizontal or
- // vertical start value.
- if (evt.getPropertyName().equals(ViewportRanges.STARTSEQ))
+ String propertyName = evt.getPropertyName();
+ if (propertyName.equals(ViewportRanges.STARTSEQ)
+ || (av.getWrapAlignment() && propertyName
+ .equals(ViewportRanges.STARTRES)))
{
fastPaint((int) evt.getNewValue() - (int) evt.getOldValue());
}
import java.awt.BorderLayout;
import java.awt.CheckboxMenuItem;
+import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Panel;
import java.awt.PopupMenu;
private boolean updateRunning = false;
+ private boolean draggingBox = false;
+
public OverviewPanel(AlignmentPanel alPanel)
{
this.av = alPanel.av;
@Override
public void mouseMoved(MouseEvent evt)
{
+ if (od.isPositionInBox(evt.getX(), evt.getY()))
+ {
+ // display drag cursor at mouse position
+ setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
+ }
+ else
+ {
+ // reset cursor
+ setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
+ }
}
@Override
public void mousePressed(MouseEvent evt)
{
- mouseAction(evt);
+ if ((evt.getModifiers()
+ & InputEvent.BUTTON3_MASK) == InputEvent.BUTTON3_MASK)
+ {
+ if (!Platform.isAMac())
+ {
+ showPopupMenu(evt);
+ }
+ }
+ else
+ {
+ if (!od.isPositionInBox(evt.getX(), evt.getY()))
+ {
+ // don't do anything if the mouse press is in the overview's box
+ // (wait to see if it's a drag instead)
+ // otherwise update the viewport
+ od.updateViewportFromMouse(evt.getX(), evt.getY(),
+ av.getAlignment().getHiddenSequences(),
+ av.getAlignment().getHiddenColumns());
+ }
+ else
+ {
+ draggingBox = true;
+ od.setDragPoint(evt.getX(), evt.getY(),
+ av.getAlignment().getHiddenSequences(),
+ av.getAlignment().getHiddenColumns());
+ }
+ }
}
@Override
public void mouseReleased(MouseEvent evt)
{
- mouseAction(evt);
+ if (draggingBox)
+ {
+ draggingBox = false;
+ }
}
@Override
public void mouseDragged(MouseEvent evt)
{
- mouseAction(evt);
- }
-
- private void mouseAction(MouseEvent evt)
- {
if ((evt.getModifiers() & InputEvent.BUTTON3_MASK) == InputEvent.BUTTON3_MASK)
{
if (!Platform.isAMac())
}
else
{
- od.updateViewportFromMouse(evt.getX(), evt.getY(), av.getAlignment()
- .getHiddenSequences(), av.getAlignment().getHiddenColumns());
+ if (draggingBox)
+ {
+ // set the mouse position as a fixed point in the box
+ // and drag relative to that position
+ od.adjustViewportFromMouse(evt.getX(), evt.getY(),
+ av.getAlignment().getHiddenSequences(),
+ av.getAlignment().getHiddenColumns());
+ }
+ else
+ {
+ od.updateViewportFromMouse(evt.getX(), evt.getY(),
+ av.getAlignment().getHiddenSequences(),
+ av.getAlignment().getHiddenColumns());
+ }
ap.paintAlignment(false);
}
}
*/
public void updateOverviewImage()
{
+ if (oviewCanvas == null)
+ {
+ /*
+ * panel has been disposed
+ */
+ return;
+ }
+
if ((getSize().width > 0) && (getSize().height > 0))
{
od.setWidth(getSize().width);
oviewCanvas.resetOviewDims(od);
updateOverviewImage();
}
+
+ /**
+ * Removes this object as a property change listener, and nulls references
+ */
+ protected void dispose()
+ {
+ try
+ {
+ av.getRanges().removePropertyChangeListener(this);
+ } finally
+ {
+ av = null;
+ oviewCanvas = null;
+ ap = null;
+ od = null;
+ }
+ }
}
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.List;
+import java.util.Map;
import java.util.Vector;
/**
*/
public class PaintRefresher
{
- static Hashtable components;
+ static Map<String, Vector<Component>> components;
/**
* DOCUMENT ME!
{
if (components == null)
{
- components = new Hashtable();
+ components = new Hashtable<String, Vector<Component>>();
}
if (components.containsKey(seqSetId))
{
- Vector comps = (Vector) components.get(seqSetId);
+ Vector<Component> comps = components.get(seqSetId);
if (!comps.contains(comp))
{
comps.addElement(comp);
}
else
{
- Vector vcoms = new Vector();
+ Vector<Component> vcoms = new Vector<>();
vcoms.addElement(comp);
components.put(seqSetId, vcoms);
}
return;
}
- Enumeration en = components.keys();
- while (en.hasMoreElements())
+ for (String id : components.keySet())
{
- String id = en.nextElement().toString();
- Vector comps = (Vector) components.get(id);
+ Vector<Component> comps = components.get(id);
comps.removeElement(comp);
if (comps.size() == 0)
{
}
Component comp;
- Vector comps = (Vector) components.get(id);
+ Vector<Component> comps = components.get(id);
if (comps == null)
{
return;
}
- Enumeration e = comps.elements();
+ Enumeration<Component> e = comps.elements();
while (e.hasMoreElements())
{
- comp = (Component) e.nextElement();
+ comp = e.nextElement();
if (comp == source)
{
public static AlignmentPanel[] getAssociatedPanels(String id)
{
- Vector comps = (Vector) components.get(id);
- Vector tmp = new Vector();
+ Vector<Component> comps = components.get(id);
+ Vector<Component> tmp = new Vector<>();
int i, iSize = comps.size();
for (i = 0; i < iSize; i++)
{
sg.setStartRes(min);
sg.setEndRes(max);
}
- ap.paintAlignment(true);
+ ap.paintAlignment(false);
av.sendSelection();
}
av.showColumn(reveal[0]);
reveal = null;
ap.paintAlignment(true);
- if (ap.overviewPanel != null)
- {
- ap.overviewPanel.updateOverviewImage();
- }
av.sendSelection();
}
});
av.showAllHiddenColumns();
reveal = null;
ap.paintAlignment(true);
- if (ap.overviewPanel != null)
- {
- ap.overviewPanel.updateOverviewImage();
- }
av.sendSelection();
}
});
}
ap.paintAlignment(true);
- if (ap.overviewPanel != null)
- {
- ap.overviewPanel.updateOverviewImage();
- }
av.sendSelection();
}
});
@Override
public void paint(Graphics g)
{
- drawScale(g, av.getRanges().getStartRes(), av.getRanges().getEndRes(),
- getSize().width,
- getSize().height);
+ /*
+ * shouldn't get called in wrapped mode as the scale above is
+ * drawn instead by SeqCanvas.drawNorthScale
+ */
+ if (!av.getWrapAlignment())
+ {
+ drawScale(g, av.getRanges().getStartRes(),
+ av.getRanges().getEndRes(), getSize().width, getSize().height);
+ }
}
// scalewidth will normally be screenwidth,
FontMetrics fm = getFontMetrics(av.getFont());
+ LABEL_EAST = 0;
+ LABEL_WEST = 0;
+
if (av.getScaleRightWrapped())
{
LABEL_EAST = fm.stringWidth(getMask());
av.setWrappedWidth(cWidth);
- av.getRanges().setEndRes(av.getRanges().getStartRes() + cWidth - 1);
+ av.getRanges().setViewportStartAndWidth(startRes, cWidth);
int endx;
int ypos = hgap;
- int maxwidth = av.getAlignment().getWidth() - 1;
+ int maxwidth = av.getAlignment().getWidth();
if (av.hasHiddenColumns())
{
maxwidth = av.getAlignment().getHiddenColumns()
- .findColumnPosition(maxwidth) - 1;
+ .findColumnPosition(maxwidth);
}
while ((ypos <= canvasHeight) && (startRes < maxwidth))
int res = 0;
int x = evt.getX();
+ int startRes = av.getRanges().getStartRes();
if (av.getWrapAlignment())
{
int y = evt.getY();
y -= hgap;
- x -= seqCanvas.LABEL_WEST;
+ x = Math.max(0, x - seqCanvas.LABEL_WEST);
int cwidth = seqCanvas.getWrappedCanvasWidth(getSize().width);
if (cwidth < 1)
}
wrappedBlock = y / cHeight;
- wrappedBlock += av.getRanges().getStartRes() / cwidth;
-
- res = wrappedBlock * cwidth + x / av.getCharWidth();
-
+ wrappedBlock += startRes / cwidth;
+ int startOffset = startRes % cwidth; // in case start is scrolled right
+ // from 0
+ res = wrappedBlock * cwidth + startOffset
+ + +Math.min(cwidth - 1, x / av.getCharWidth());
}
else
{
- res = (x / av.getCharWidth()) + av.getRanges().getStartRes();
+ res = (x / av.getCharWidth()) + startRes;
}
if (av.hasHiddenColumns())
// recover mapping between sequence's non-gap positions and positions
// mapping to view.
pruneDeletions(ShiftList.parseMap(origseq.gapMap()));
- int[] viscontigs = al.getHiddenColumns().getVisibleContigs(0,
- profileseq.getLength());
+ int[] viscontigs = getVisibleContigs(0, profileseq.getLength());
int spos = 0;
int offset = 0;
int absAlignmentIndex = alignment.findIndex(sequence);
int alignmentIndex = adjustForHiddenSeqs(absAlignmentIndex);
- if (hiddenSequences[alignmentIndex] != null)
+ if (alignmentIndex < 0 || hiddenSequences[alignmentIndex] != null)
{
System.out.println("ERROR!!!!!!!!!!!");
+ return;
}
hiddenSequences[alignmentIndex] = sequence;
}
/**
- * Convert absolute alignment index to visible alignment index
+ * Convert absolute alignment index to visible alignment index (or -1 if
+ * before the first visible sequence)
*
* @param alignmentIndex
* @return
return startRow - visibleDistance;
}
- int index = startRow;
+ int index = Math.min(startRow, hiddenSequences.length - 1);
int count = 0;
while ((index > -1) && (count < visibleDistance))
{
break;
}
case KeyEvent.VK_PAGE_UP:
- if (viewport.getWrapAlignment())
- {
- vpRanges.scrollUp(true);
- }
- else
- {
- vpRanges.pageUp();
- }
+ vpRanges.pageUp();
break;
case KeyEvent.VK_PAGE_DOWN:
- if (viewport.getWrapAlignment())
- {
- vpRanges.scrollUp(false);
- }
- else
- {
- vpRanges.pageDown();
- }
+ vpRanges.pageDown();
break;
}
}
{
viewport.setShowSequenceFeatures(showSeqFeatures.isSelected());
alignPanel.paintAlignment(true);
- if (alignPanel.getOverviewPanel() != null)
- {
- alignPanel.getOverviewPanel().updateOverviewImage();
- }
}
/**
}
JInternalFrame frame = new JInternalFrame();
- OverviewPanel overview = new OverviewPanel(alignPanel);
+ final OverviewPanel overview = new OverviewPanel(alignPanel);
frame.setContentPane(overview);
Desktop.addInternalFrame(frame, MessageManager.formatMessage(
"label.overview_params", new Object[] { this.getTitle() }),
public void internalFrameClosed(
javax.swing.event.InternalFrameEvent evt)
{
+ overview.dispose();
alignPanel.setOverviewPanel(null);
};
});
import jalview.datamodel.AlignedCodonFrame;
import jalview.datamodel.Alignment;
import jalview.datamodel.AlignmentI;
-import jalview.datamodel.Annotation;
import jalview.datamodel.ColumnSelection;
import jalview.datamodel.HiddenColumns;
import jalview.datamodel.PDBEntry;
import jalview.datamodel.SearchResults;
import jalview.datamodel.SearchResultsI;
-import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceGroup;
import jalview.datamodel.SequenceI;
import jalview.renderer.ResidueShader;
}
}
- /**
- * get the consensus sequence as displayed under the PID consensus annotation
- * row.
- *
- * @return consensus sequence as a new sequence object
- */
- public SequenceI getConsensusSeq()
- {
- if (consensus == null)
- {
- updateConsensus(null);
- }
- if (consensus == null)
- {
- return null;
- }
- StringBuffer seqs = new StringBuffer();
- for (int i = 0; i < consensus.annotations.length; i++)
- {
- Annotation annotation = consensus.annotations[i];
- if (annotation != null)
- {
- String description = annotation.description;
- if (description != null && description.startsWith("["))
- {
- // consensus is a tie - just pick the first one
- seqs.append(description.charAt(1));
- }
- else
- {
- seqs.append(annotation.displayCharacter);
- }
- }
- }
-
- SequenceI sq = new Sequence("Consensus", seqs.toString());
- sq.setDescription("Percentage Identity Consensus "
- + ((ignoreGapsInConsensusCalculation) ? " without gaps" : ""));
- return sq;
- }
-
boolean validCharWidth;
/**
annotationSpaceFillerHolder.setVisible(true);
}
- if (wrap)
- {
- int widthInRes = getSeqPanel().seqCanvas
- .getWrappedCanvasWidth(getSeqPanel().seqCanvas.getWidth());
- vpRanges.setViewportWidth(widthInRes);
- }
- else
- {
- int widthInRes = (getSeqPanel().seqCanvas.getWidth() / av
- .getCharWidth()) - 1;
- int heightInSeq = (getSeqPanel().seqCanvas.getHeight() / av
- .getCharHeight()) - 1;
+ int canvasWidth = getSeqPanel().seqCanvas.getWidth();
+ if (canvasWidth > 0)
+ { // may not yet be laid out
+ if (wrap)
+ {
+ int widthInRes = getSeqPanel().seqCanvas
+ .getWrappedCanvasWidth(canvasWidth);
+ vpRanges.setViewportWidth(widthInRes);
+ }
+ else
+ {
+ int widthInRes = (canvasWidth / av.getCharWidth()) - 1;
+ int heightInSeq = (getSeqPanel().seqCanvas.getHeight() / av
+ .getCharHeight()) - 1;
- vpRanges.setViewportWidth(widthInRes);
- vpRanges.setViewportHeight(heightInSeq);
+ vpRanges.setViewportWidth(widthInRes);
+ vpRanges.setViewportHeight(heightInSeq);
+ }
}
idSpaceFillerPanel1.setVisible(!wrap);
@Override
public void adjustmentValueChanged(AdjustmentEvent evt)
{
- int oldX = vpRanges.getStartRes();
- int oldwidth = vpRanges.getViewportWidth();
- int oldY = vpRanges.getStartSeq();
- int oldheight = vpRanges.getViewportHeight();
-
if (av.getWrapAlignment())
{
- if (evt.getSource() == hscroll)
- {
- return; // no horizontal scroll when wrapped
- }
- else if (evt.getSource() == vscroll)
+ adjustScrollingWrapped(evt);
+ return;
+ }
+
+ if (evt.getSource() == hscroll)
+ {
+ int oldX = vpRanges.getStartRes();
+ int oldwidth = vpRanges.getViewportWidth();
+ int x = hscroll.getValue();
+ int width = getSeqPanel().seqCanvas.getWidth() / av.getCharWidth();
+
+ // if we're scrolling to the position we're already at, stop
+ // this prevents infinite recursion of events when the scroll/viewport
+ // ranges values are the same
+ if ((x == oldX) && (width == oldwidth))
{
- int offy = vscroll.getValue();
- int rowSize = getSeqPanel().seqCanvas
- .getWrappedCanvasWidth(getSeqPanel().seqCanvas.getWidth());
-
- // if we're scrolling to the position we're already at, stop
- // this prevents infinite recursion of events when the scroll/viewport
- // ranges values are the same
- if ((offy * rowSize == oldX) && (oldwidth == rowSize))
- {
- return;
- }
- else if (offy > -1)
- {
- vpRanges.setViewportStartAndWidth(offy * rowSize, rowSize);
- }
+ return;
}
- else
+ vpRanges.setViewportStartAndWidth(x, width);
+ }
+ else if (evt.getSource() == vscroll)
+ {
+ int oldY = vpRanges.getStartSeq();
+ int oldheight = vpRanges.getViewportHeight();
+ int y = vscroll.getValue();
+ int height = getSeqPanel().seqCanvas.getHeight() / av.getCharHeight();
+
+ // if we're scrolling to the position we're already at, stop
+ // this prevents infinite recursion of events when the scroll/viewport
+ // ranges values are the same
+ if ((y == oldY) && (height == oldheight))
{
- // This is only called if file loaded is a jar file that
- // was wrapped when saved and user has wrap alignment true
- // as preference setting
- SwingUtilities.invokeLater(new Runnable()
- {
- @Override
- public void run()
- {
- // When updating scrolling to use ViewportChange events, this code
- // could not be validated and it is not clear if it is now being
- // called. Log warning here in case it is called and unforeseen
- // problems occur
- Cache.log
- .warn("Unexpected path through code: Wrapped jar file opened with wrap alignment set in preferences");
-
- // scroll to start of panel
- vpRanges.setStartRes(0);
- vpRanges.setStartSeq(0);
- }
- });
+ return;
}
+ vpRanges.setViewportStartAndHeight(y, height);
+ }
+ if (!fastPaint)
+ {
repaint();
}
- else
+ }
+
+ /**
+ * Responds to a scroll change by setting the start position of the viewport.
+ * Does
+ *
+ * @param evt
+ */
+ protected void adjustScrollingWrapped(AdjustmentEvent evt)
+ {
+ if (evt.getSource() == hscroll)
{
- // horizontal scroll
- if (evt.getSource() == hscroll)
- {
- int x = hscroll.getValue();
- int width = getSeqPanel().seqCanvas.getWidth() / av.getCharWidth();
+ return; // no horizontal scroll when wrapped
+ }
+ if (evt.getSource() == vscroll)
+ {
+ int newY = vscroll.getValue();
- // if we're scrolling to the position we're already at, stop
- // this prevents infinite recursion of events when the scroll/viewport
- // ranges values are the same
- if ((x == oldX) && (width == oldwidth))
- {
- return;
- }
- vpRanges.setViewportStartAndWidth(x, width);
- }
- else if (evt.getSource() == vscroll)
+ /*
+ * if we're scrolling to the position we're already at, stop
+ * this prevents infinite recursion of events when the scroll/viewport
+ * ranges values are the same
+ */
+ int oldX = vpRanges.getStartRes();
+ int oldY = vpRanges.getWrappedScrollPosition(oldX);
+ if (oldY == newY)
{
- int y = vscroll.getValue();
- int height = getSeqPanel().seqCanvas.getHeight()
- / av.getCharHeight();
-
- // if we're scrolling to the position we're already at, stop
- // this prevents infinite recursion of events when the scroll/viewport
- // ranges values are the same
- if ((y == oldY) && (height == oldheight))
- {
- return;
- }
- vpRanges.setViewportStartAndHeight(y, height);
+ return;
}
- if (!fastPaint)
+ if (newY > -1)
{
- repaint();
+ /*
+ * limit page up/down to one width's worth of positions
+ */
+ int rowSize = vpRanges.getViewportWidth();
+ int newX = newY > oldY ? oldX + rowSize : oldX - rowSize;
+ vpRanges.setViewportStartAndWidth(Math.max(0, newX), rowSize);
}
}
+ else
+ {
+ // This is only called if file loaded is a jar file that
+ // was wrapped when saved and user has wrap alignment true
+ // as preference setting
+ SwingUtilities.invokeLater(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ // When updating scrolling to use ViewportChange events, this code
+ // could not be validated and it is not clear if it is now being
+ // called. Log warning here in case it is called and unforeseen
+ // problems occur
+ Cache.log
+ .warn("Unexpected path through code: Wrapped jar file opened with wrap alignment set in preferences");
+
+ // scroll to start of panel
+ vpRanges.setStartRes(0);
+ vpRanges.setStartSeq(0);
+ }
+ });
+ }
+ repaint();
}
/**
setScrollValues(vpRanges.getStartRes(), vpRanges.getStartSeq());
}
- /*
- * Set vertical scroll bar parameters for wrapped panel
- * @param res
- * the residue to scroll to
+ /**
+ * Set vertical scroll bar position, and number of increments, for wrapped
+ * panel
+ *
+ * @param topLeftColumn
+ * the column position at top left (0..)
*/
- private void setScrollingForWrappedPanel(int res)
+ private void setScrollingForWrappedPanel(int topLeftColumn)
{
- // get the width of the alignment in residues
- int maxwidth = av.getAlignment().getWidth();
- if (av.hasHiddenColumns())
- {
- maxwidth = av.getAlignment().getHiddenColumns()
- .findColumnPosition(maxwidth) - 1;
- }
+ int scrollPosition = vpRanges.getWrappedScrollPosition(topLeftColumn);
+ int maxScroll = vpRanges.getWrappedMaxScroll(topLeftColumn);
- // get the width of the canvas in residues
- int canvasWidth = getSeqPanel().seqCanvas
- .getWrappedCanvasWidth(getSeqPanel().seqCanvas.getWidth());
- if (canvasWidth > 0)
- {
- // position we want to scroll to is number of canvasWidth's to get there
- int current = res / canvasWidth;
-
- // max scroll position: add one because extent is 1 and scrollbar value
- // can only be set to at most max - extent
- int max = maxwidth / canvasWidth + 1;
- vscroll.setUnitIncrement(1);
- vscroll.setValues(current, 1, 0, max);
- }
+ /*
+ * a scrollbar's value can be set to at most (maximum-extent)
+ * so we add extent (1) to the maxScroll value
+ */
+ vscroll.setUnitIncrement(1);
+ vscroll.setValues(scrollPosition, 1, 0, maxScroll + 1);
}
/**
public class FeatureColourChooser extends JalviewDialog
{
// FeatureSettings fs;
- FeatureRenderer fr;
+ private FeatureRenderer fr;
private FeatureColourI cs;
private FeatureColourI oldcs;
- /**
- *
- * @return the last colour setting selected by user - either oldcs (which may
- * be a java.awt.Color) or the new GraduatedColor
- */
- public FeatureColourI getLastColour()
- {
- if (cs == null)
- {
- return oldcs;
- }
- return cs;
- }
+ private AlignmentPanel ap;
- AlignmentPanel ap;
-
- boolean adjusting = false;
+ private boolean adjusting = false;
final private float min;
final private float scaleFactor;
- String type = null;
+ private String type = null;
+
+ private JPanel minColour = new JPanel();
+
+ private JPanel maxColour = new JPanel();
- public FeatureColourChooser(FeatureRenderer frender, String type)
+ private JComboBox<String> threshold = new JComboBox<>();
+
+ private JSlider slider = new JSlider();
+
+ private JTextField thresholdValue = new JTextField(20);
+
+ // TODO implement GUI for tolower flag
+ // JCheckBox toLower = new JCheckBox();
+
+ private JCheckBox thresholdIsMin = new JCheckBox();
+
+ private JCheckBox colourByLabel = new JCheckBox();
+
+ private GraphLine threshline;
+
+ private Color oldmaxColour;
+
+ private Color oldminColour;
+
+ private ActionListener colourEditor = null;
+
+ /**
+ * Constructor
+ *
+ * @param frender
+ * @param theType
+ */
+ public FeatureColourChooser(FeatureRenderer frender, String theType)
{
- this(frender, false, type);
+ this(frender, false, theType);
}
- public FeatureColourChooser(FeatureRenderer frender, boolean block,
- String type)
+ /**
+ * Constructor, with option to make a blocking dialog (has to complete in the
+ * AWT event queue thread). Currently this option is always set to false.
+ *
+ * @param frender
+ * @param blocking
+ * @param theType
+ */
+ FeatureColourChooser(FeatureRenderer frender, boolean blocking,
+ String theType)
{
this.fr = frender;
- this.type = type;
+ this.type = theType;
ap = fr.ap;
String title = MessageManager.formatMessage(
- "label.graduated_color_for_params", new String[] { type });
- initDialogFrame(this, true, block, title, 480, 185);
- // frame.setLayer(JLayeredPane.PALETTE_LAYER);
- // Desktop.addInternalFrame(frame, "Graduated Feature Colour for "+type,
- // 480, 145);
+ "label.graduated_color_for_params", new String[] { theType });
+ initDialogFrame(this, true, blocking, title, 480, 185);
slider.addChangeListener(new ChangeListener()
{
if (!adjusting)
{
thresholdValue.setText((slider.getValue() / scaleFactor) + "");
- valueChanged();
+ sliderValueChanged();
}
}
});
@Override
public void mouseReleased(MouseEvent evt)
{
+ /*
+ * only update Overview and/or structure colouring
+ * when threshold slider drag ends (mouse up)
+ */
if (ap != null)
{
ap.paintAlignment(true);
}
- ;
}
});
- float mm[] = fr.getMinMax().get(type)[0];
+ float mm[] = fr.getMinMax().get(theType)[0];
min = mm[0];
max = mm[1];
*/
scaleFactor = (max == min) ? 1f : 100f / (max - min);
- oldcs = fr.getFeatureColours().get(type);
+ oldcs = fr.getFeatureColours().get(theType);
if (!oldcs.isSimpleColour())
{
if (oldcs.isAutoScaled())
// initialise threshold slider and selector
threshold.setSelectedIndex(cs.isAboveThreshold() ? 1 : 2);
slider.setEnabled(true);
+ slider.setValue((int) (cs.getThreshold() * scaleFactor));
thresholdValue.setEnabled(true);
threshline = new GraphLine((max - min) / 2f, "Threshold", Color.black);
-
+ threshline.value = cs.getThreshold();
}
adjusting = false;
- changeColour();
+ changeColour(false);
waitForInput();
}
}
});
maxColour.setBorder(new LineBorder(Color.black));
- minText.setText(MessageManager.getString("label.min"));
+ JLabel minText = new JLabel(MessageManager.getString("label.min"));
minText.setFont(JvSwingUtils.getLabelFont());
- maxText.setText(MessageManager.getString("label.max"));
+ JLabel maxText = new JLabel(MessageManager.getString("label.max"));
maxText.setFont(JvSwingUtils.getLabelFont());
- this.setLayout(borderLayout1);
- jPanel2.setLayout(flowLayout1);
+ this.setLayout(new BorderLayout());
+ JPanel jPanel1 = new JPanel();
jPanel1.setBackground(Color.white);
+ JPanel jPanel2 = new JPanel();
+ jPanel2.setLayout(new FlowLayout());
jPanel2.setBackground(Color.white);
threshold.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
- threshold_actionPerformed(e);
+ threshold_actionPerformed();
}
});
threshold.setToolTipText(MessageManager
.getString("label.threshold_feature_above_threshold")); // index 1
threshold.addItem(MessageManager
.getString("label.threshold_feature_below_threshold")); // index 2
- jPanel3.setLayout(flowLayout2);
+
+ JPanel jPanel3 = new JPanel();
+ jPanel3.setLayout(new FlowLayout());
thresholdValue.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
- thresholdValue_actionPerformed(e);
+ thresholdValue_actionPerformed();
}
});
slider.setPaintLabels(false);
@Override
public void actionPerformed(ActionEvent actionEvent)
{
- thresholdIsMin_actionPerformed(actionEvent);
+ thresholdIsMin_actionPerformed();
}
});
colourByLabel.setBackground(Color.white);
@Override
public void actionPerformed(ActionEvent actionEvent)
{
- colourByLabel_actionPerformed(actionEvent);
+ colourByLabel_actionPerformed();
}
});
+
+ JPanel colourPanel = new JPanel();
colourPanel.setBackground(Color.white);
jPanel1.add(ok);
jPanel1.add(cancel);
- jPanel2.add(colourByLabel, java.awt.BorderLayout.WEST);
- jPanel2.add(colourPanel, java.awt.BorderLayout.EAST);
+ jPanel2.add(colourByLabel, BorderLayout.WEST);
+ jPanel2.add(colourPanel, BorderLayout.EAST);
colourPanel.add(minText);
colourPanel.add(minColour);
colourPanel.add(maxText);
colourPanel.add(maxColour);
- this.add(jPanel3, java.awt.BorderLayout.CENTER);
+ this.add(jPanel3, BorderLayout.CENTER);
jPanel3.add(threshold);
jPanel3.add(slider);
jPanel3.add(thresholdValue);
jPanel3.add(thresholdIsMin);
- this.add(jPanel1, java.awt.BorderLayout.SOUTH);
- this.add(jPanel2, java.awt.BorderLayout.NORTH);
+ this.add(jPanel1, BorderLayout.SOUTH);
+ this.add(jPanel2, BorderLayout.NORTH);
}
- JLabel minText = new JLabel();
-
- JLabel maxText = new JLabel();
-
- JPanel minColour = new JPanel();
-
- JPanel maxColour = new JPanel();
-
- JPanel colourPanel = new JPanel();
-
- JPanel jPanel1 = new JPanel();
-
- JPanel jPanel2 = new JPanel();
-
- BorderLayout borderLayout1 = new BorderLayout();
-
- JComboBox threshold = new JComboBox();
-
- FlowLayout flowLayout1 = new FlowLayout();
-
- JPanel jPanel3 = new JPanel();
-
- FlowLayout flowLayout2 = new FlowLayout();
-
- JSlider slider = new JSlider();
-
- JTextField thresholdValue = new JTextField(20);
-
- // TODO implement GUI for tolower flag
- // JCheckBox toLower = new JCheckBox();
-
- JCheckBox thresholdIsMin = new JCheckBox();
-
- JCheckBox colourByLabel = new JCheckBox();
-
- private GraphLine threshline;
-
- private Color oldmaxColour;
-
- private Color oldminColour;
-
- public void minColour_actionPerformed()
+ /**
+ * Action on clicking the 'minimum colour' - open a colour chooser dialog, and
+ * set the selected colour (if the user does not cancel out of the dialog)
+ */
+ protected void minColour_actionPerformed()
{
Color col = JColorChooser.showDialog(this,
MessageManager.getString("label.select_colour_minimum_value"),
minColour.setForeground(col);
}
minColour.repaint();
- changeColour();
+ changeColour(true);
}
- public void maxColour_actionPerformed()
+ /**
+ * Action on clicking the 'maximum colour' - open a colour chooser dialog, and
+ * set the selected colour (if the user does not cancel out of the dialog)
+ */
+ protected void maxColour_actionPerformed()
{
Color col = JColorChooser.showDialog(this,
MessageManager.getString("label.select_colour_maximum_value"),
maxColour.setForeground(col);
}
maxColour.repaint();
- changeColour();
+ changeColour(true);
}
- void changeColour()
+ /**
+ * Constructs and sets the selected colour options as the colour for the
+ * feature type, and repaints the alignment, and optionally the Overview
+ * and/or structure viewer if open
+ *
+ * @param updateOverview
+ */
+ void changeColour(boolean updateOverview)
{
// Check if combobox is still adjusting
if (adjusting)
{
acg = new FeatureColour(oldminColour = minColour.getBackground(),
oldmaxColour = maxColour.getBackground(), min, max);
-
}
if (!hasThreshold)
}
else if (threshline == null)
{
- // todo visual indication of feature threshold
+ /*
+ * todo not yet implemented: visual indication of feature threshold
+ */
threshline = new GraphLine((max - min) / 2f, "Threshold", Color.black);
}
slider.setMinimum((int) (min * scaleFactor));
slider.setMaximum((int) (max * scaleFactor));
- slider.setValue((int) (threshline.value * scaleFactor));
+ // slider.setValue((int) (threshline.value * scaleFactor));
+ slider.setValue(Math.round(threshline.value * scaleFactor));
thresholdValue.setText(threshline.value + "");
slider.setMajorTickSpacing((int) (range / 10f));
slider.setEnabled(true);
}
fr.setColour(type, acg);
cs = acg;
- ap.paintAlignment(false);
+ ap.paintAlignment(updateOverview);
}
@Override
@Override
public void okPressed()
{
- changeColour();
+ changeColour(false);
}
@Override
reset();
}
+ /**
+ * Action when the user cancels the dialog. All previous settings should be
+ * restored and rendered on the alignment, and any linked Overview window or
+ * structure.
+ */
void reset()
{
fr.setColour(type, oldcs);
- ap.paintAlignment(false);
+ ap.paintAlignment(true);
cs = null;
}
- public void thresholdCheck_actionPerformed(ActionEvent e)
- {
- changeColour();
- }
-
- public void annotations_actionPerformed(ActionEvent e)
- {
- changeColour();
- }
-
- public void threshold_actionPerformed(ActionEvent e)
+ /**
+ * Action on change of choice of No / Above / Below Threshold
+ */
+ protected void threshold_actionPerformed()
{
- changeColour();
+ changeColour(true);
}
- public void thresholdValue_actionPerformed(ActionEvent e)
+ /**
+ * Action on text entry of a threshold value
+ */
+ protected void thresholdValue_actionPerformed()
{
try
{
float f = Float.parseFloat(thresholdValue.getText());
slider.setValue((int) (f * scaleFactor));
threshline.value = f;
+
+ /*
+ * force repaint of any Overview window or structure
+ */
+ ap.paintAlignment(true);
} catch (NumberFormatException ex)
{
}
}
- public void valueChanged()
+ /**
+ * Action on change of threshold slider value. This may be done interactively
+ * (by moving the slider), or programmatically (to update the slider after
+ * manual input of a threshold value).
+ */
+ protected void sliderValueChanged()
{
- threshline.value = slider.getValue() / scaleFactor;
+ /*
+ * squash rounding errors by forcing min/max of slider to
+ * actual min/max of feature score range
+ */
+ int value = slider.getValue();
+ threshline.value = value == slider.getMaximum() ? max
+ : (value == slider.getMinimum() ? min : value / scaleFactor);
cs.setThreshold(threshline.value);
- changeColour();
- ap.paintAlignment(false);
+
+ /*
+ * repaint alignment, but not Overview or structure,
+ * to avoid overload while dragging the slider
+ */
+ changeColour(false);
}
- public void thresholdIsMin_actionPerformed(ActionEvent actionEvent)
+ protected void thresholdIsMin_actionPerformed()
{
- changeColour();
+ changeColour(true);
}
- public void colourByLabel_actionPerformed(ActionEvent actionEvent)
+ protected void colourByLabel_actionPerformed()
{
- changeColour();
+ changeColour(true);
}
- ActionListener colourEditor = null;
-
- public void addActionListener(ActionListener graduatedColorEditor)
+ void addActionListener(ActionListener graduatedColorEditor)
{
if (colourEditor != null)
{
colourEditor = graduatedColorEditor;
}
+ /**
+ * Answers the last colour setting selected by user - either oldcs (which may
+ * be a java.awt.Color) or the new GraduatedColor
+ *
+ * @return
+ */
+ FeatureColourI getLastColour()
+ {
+ if (cs == null)
+ {
+ return oldcs;
+ }
+ return cs;
+ }
+
}
*/
public void fastPaint(int vertical)
{
- if (gg == null)
+ /*
+ * for now, not attempting fast paint of wrapped ids...
+ */
+ if (gg == null || av.getWrapAlignment())
{
repaint();
Color currentColor = Color.white;
Color currentTextColor = Color.black;
- final boolean doHiddenCheck = av.isDisplayReferenceSeq()
- || av.hasHiddenRows(), hiddenRows = av.hasHiddenRows();
+ boolean hasHiddenRows = av.hasHiddenRows();
if (av.getWrapAlignment())
{
- int maxwidth = av.getAlignment().getWidth();
- int alheight = av.getAlignment().getHeight();
+ drawIdsWrapped(starty, hasHiddenRows);
+ return;
+ }
- if (av.hasHiddenColumns())
- {
- maxwidth = av.getAlignment().getHiddenColumns()
- .findColumnPosition(maxwidth) - 1;
- }
+ // No need to hang on to labels if we're not wrapped
+ labels = null;
- int annotationHeight = 0;
+ // Now draw the id strings
+ int panelWidth = getWidth();
+ int xPos = 0;
+
+ SequenceI sequence;
+ // Now draw the id strings
+ for (int i = starty; i <= endy; i++)
+ {
+ sequence = av.getAlignment().getSequenceAt(i);
- if (av.isShowAnnotation())
+ if (sequence == null)
{
- if (ap == null)
- {
- ap = new AnnotationPanel(av);
- }
+ continue;
+ }
- annotationHeight = ap.adjustPanelHeight();
- if (labels == null)
- {
- labels = new AnnotationLabels(av);
- }
+ if (hasHiddenRows || av.isDisplayReferenceSeq())
+ {
+ setHiddenFont(sequence);
}
- int hgap = av.getCharHeight();
- if (av.getScaleAboveWrapped())
+ // Selected sequence colours
+ if ((searchResults != null) && searchResults.contains(sequence))
{
- hgap += av.getCharHeight();
+ currentColor = Color.black;
+ currentTextColor = Color.white;
}
+ else if ((av.getSelectionGroup() != null)
+ && av.getSelectionGroup().getSequences(null)
+ .contains(sequence))
+ {
+ currentColor = Color.lightGray;
+ currentTextColor = Color.black;
+ }
+ else
+ {
+ currentColor = av.getSequenceColour(sequence);
+ currentTextColor = Color.black;
+ }
+
+ gg.setColor(currentColor);
+
+ gg.fillRect(0, (i - starty) * av.getCharHeight(), getWidth(),
+ av.getCharHeight());
- int cHeight = alheight * av.getCharHeight() + hgap + annotationHeight;
+ gg.setColor(currentTextColor);
- int rowSize = av.getRanges().getEndRes()
- - av.getRanges().getStartRes();
+ String string = sequence.getDisplayId(av.getShowJVSuffix());
- // Draw the rest of the panels
- for (int ypos = hgap, row = av.getRanges().getStartRes(); (ypos <= getHeight())
- && (row < maxwidth); ypos += cHeight, row += rowSize)
+ if (av.isRightAlignIds())
{
- for (int i = starty; i < alheight; i++)
- {
- SequenceI s = av.getAlignment().getSequenceAt(i);
- if (doHiddenCheck)
- {
- setHiddenFont(s);
- }
- else
- {
- gg.setFont(getIdfont());
- }
-
- drawIdString(gg, hiddenRows, s, i, 0, ypos);
- }
+ xPos = panelWidth - fm.stringWidth(string) - 4;
+ }
- if (labels != null && av.isShowAnnotation())
- {
- gg.translate(0, ypos + (alheight * av.getCharHeight()));
- labels.drawComponent(gg, getWidth());
- gg.translate(0, -ypos - (alheight * av.getCharHeight()));
- }
+ gg.drawString(string, xPos,
+ (((i - starty) * av.getCharHeight()) + av.getCharHeight())
+ - (av.getCharHeight() / 5));
+
+ if (hasHiddenRows)
+ {
+ drawMarker(i, starty, 0);
}
}
- else
- {
- // No need to hang on to labels if we're not wrapped
- labels = null;
+ }
- // Now draw the id strings
- int panelWidth = getWidth();
- int xPos = 0;
+ /**
+ * Draws sequence ids in wrapped mode
+ *
+ * @param starty
+ * @param hasHiddenRows
+ */
+ protected void drawIdsWrapped(int starty, boolean hasHiddenRows)
+ {
+ int maxwidth = av.getAlignment().getWidth();
+ int alheight = av.getAlignment().getHeight();
- SequenceI sequence;
- // Now draw the id strings
- for (int i = starty; i <= endy; i++)
- {
- sequence = av.getAlignment().getSequenceAt(i);
+ if (av.hasHiddenColumns())
+ {
+ maxwidth = av.getAlignment().getHiddenColumns()
+ .findColumnPosition(maxwidth) - 1;
+ }
- if (sequence == null)
- {
- continue;
- }
+ int annotationHeight = 0;
- if (doHiddenCheck)
- {
- setHiddenFont(sequence);
- }
+ if (av.isShowAnnotation())
+ {
+ if (ap == null)
+ {
+ ap = new AnnotationPanel(av);
+ }
- // Selected sequence colours
- if ((searchResults != null) && searchResults.contains(sequence))
- {
- currentColor = Color.black;
- currentTextColor = Color.white;
- }
- else if ((av.getSelectionGroup() != null)
- && av.getSelectionGroup().getSequences(null)
- .contains(sequence))
- {
- currentColor = Color.lightGray;
- currentTextColor = Color.black;
- }
- else
- {
- currentColor = av.getSequenceColour(sequence);
- currentTextColor = Color.black;
- }
+ annotationHeight = ap.adjustPanelHeight();
+ if (labels == null)
+ {
+ labels = new AnnotationLabels(av);
+ }
+ }
- gg.setColor(currentColor);
+ int hgap = av.getCharHeight();
+ if (av.getScaleAboveWrapped())
+ {
+ hgap += av.getCharHeight();
+ }
- gg.fillRect(0, (i - starty) * av.getCharHeight(), getWidth(),
- av.getCharHeight());
+ int cHeight = alheight * av.getCharHeight() + hgap + annotationHeight;
- gg.setColor(currentTextColor);
+ ViewportRanges ranges = av.getRanges();
- String string = sequence.getDisplayId(av.getShowJVSuffix());
+ int rowSize = ranges.getViewportWidth();
- if (av.isRightAlignIds())
+ /*
+ * draw repeating sequence ids until out of sequence data or
+ * out of visible space, whichever comes first
+ */
+ int ypos = hgap;
+ int row = ranges.getStartRes();
+ while ((ypos <= getHeight()) && (row < maxwidth))
+ {
+ for (int i = starty; i < alheight; i++)
+ {
+ SequenceI s = av.getAlignment().getSequenceAt(i);
+ if (hasHiddenRows || av.isDisplayReferenceSeq())
{
- xPos = panelWidth - fm.stringWidth(string) - 4;
+ setHiddenFont(s);
}
-
- gg.drawString(string, xPos,
- (((i - starty) * av.getCharHeight()) + av.getCharHeight())
- - (av.getCharHeight() / 5));
-
- if (hiddenRows)
+ else
{
- drawMarker(i, starty, 0);
+ gg.setFont(getIdfont());
}
+ drawIdString(gg, hasHiddenRows, s, i, 0, ypos);
+ }
+
+ if (labels != null && av.isShowAnnotation())
+ {
+ gg.translate(0, ypos + (alheight * av.getCharHeight()));
+ labels.drawComponent(gg, getWidth());
+ gg.translate(0, -ypos - (alheight * av.getCharHeight()));
}
+ ypos += cHeight;
+ row += rowSize;
}
}
this.idfont = idfont;
}
+ /**
+ * Respond to viewport range changes (e.g. alignment panel was scrolled). Both
+ * scrolling and resizing change viewport ranges. Scrolling changes both start
+ * and end points, but resize only changes end values. Here we only want to
+ * fastpaint on a scroll, with resize using a normal paint, so scroll events
+ * are identified as changes to the horizontal or vertical start value.
+ * <p>
+ * In unwrapped mode, only responds to a vertical scroll, as horizontal scroll
+ * leaves sequence ids unchanged. In wrapped mode, only vertical scroll is
+ * provided, but it generates a change of "startres" which does require an
+ * update here.
+ */
@Override
public void propertyChange(PropertyChangeEvent evt)
{
- // Respond to viewport range changes (e.g. alignment panel was scrolled)
- // Both scrolling and resizing change viewport ranges: scrolling changes
- // both start and end points, but resize only changes end values.
- // Here we only want to fastpaint on a scroll, with resize using a normal
- // paint, so scroll events are identified as changes to the horizontal or
- // vertical start value.
- if (evt.getPropertyName().equals(ViewportRanges.STARTSEQ))
+ String propertyName = evt.getPropertyName();
+ if (propertyName.equals(ViewportRanges.STARTSEQ)
+ || (av.getWrapAlignment() && propertyName
+ .equals(ViewportRanges.STARTRES)))
{
fastPaint((int) evt.getNewValue() - (int) evt.getOldValue());
}
}
lastid = seq;
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(false);
}
/**
{
av.getRanges().scrollRight(true);
}
- else
+ else if (!av.getWrapAlignment())
{
av.getRanges().scrollUp(false);
}
{
av.getRanges().scrollRight(false);
}
- else
+ else if (!av.getWrapAlignment())
{
av.getRanges().scrollUp(true);
}
av.isSelectionGroupChanged(true);
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(false);
}
/**
import jalview.viewmodel.ViewportListenerI;
import java.awt.BorderLayout;
+import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
private boolean showHidden = true;
+ private boolean draggingBox = false;
+
/**
* Creates a new OverviewPanel object.
*
@Override
public void mouseDragged(MouseEvent evt)
{
- if (!SwingUtilities.isRightMouseButton(evt)
- && !av.getWrapAlignment())
+ if (!SwingUtilities.isRightMouseButton(evt))
{
- od.updateViewportFromMouse(evt.getX(), evt.getY(), av
+ if (draggingBox)
+ {
+ // set the mouse position as a fixed point in the box
+ // and drag relative to that position
+ od.adjustViewportFromMouse(evt.getX(),
+ evt.getY(), av.getAlignment().getHiddenSequences(),
+ av.getAlignment().getHiddenColumns());
+ }
+ else
+ {
+ od.updateViewportFromMouse(evt.getX(), evt.getY(), av
.getAlignment().getHiddenSequences(), av.getAlignment()
.getHiddenColumns());
+ }
+ }
+ }
+ @Override
+ public void mouseMoved(MouseEvent evt)
+ {
+ if (od.isPositionInBox(evt.getX(), evt.getY()))
+ {
+ // display drag cursor at mouse position
+ setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
+ }
+ else
+ {
+ // reset cursor
+ setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
}
});
showPopupMenu(evt);
}
}
- else if (!av.getWrapAlignment())
+ else
+ // if (!av.getWrapAlignment())
{
- od.updateViewportFromMouse(evt.getX(), evt.getY(), av
- .getAlignment().getHiddenSequences(), av.getAlignment()
- .getHiddenColumns());
+ if (!od.isPositionInBox(evt.getX(), evt.getY()))
+ {
+ // don't do anything if the mouse press is in the overview's box
+ // (wait to see if it's a drag instead)
+ // otherwise update the viewport
+ od.updateViewportFromMouse(evt.getX(), evt.getY(),
+ av.getAlignment().getHiddenSequences(),
+ av.getAlignment().getHiddenColumns());
+ }
+ else
+ {
+ draggingBox = true;
+ od.setDragPoint(evt.getX(), evt.getY(),
+ av.getAlignment().getHiddenSequences(),
+ av.getAlignment().getHiddenColumns());
+ }
+ }
+ }
+
+ @Override
+ public void mouseReleased(MouseEvent evt)
+ {
+ if (draggingBox)
+ {
+ draggingBox = false;
}
}
}
});
-
updateOverviewImage();
}
*/
public void updateOverviewImage()
{
+ if (oviewCanvas == null)
+ {
+ /*
+ * panel has been disposed
+ */
+ return;
+ }
+
if ((getWidth() > 0) && (getHeight() > 0))
{
od.setWidth(getWidth());
Thread thread = new Thread(this);
thread.start();
repaint();
-
}
@Override
{
setBoxPosition();
}
+
+ /**
+ * Removes this object as a property change listener, and nulls references
+ */
+ protected void dispose()
+ {
+ try
+ {
+ av.getRanges().removePropertyChangeListener(this);
+ } finally
+ {
+ av = null;
+ oviewCanvas = null;
+ ap = null;
+ od = null;
+ }
+ }
}
av.showColumn(reveal[0]);
reveal = null;
ap.paintAlignment(true);
- if (ap.overviewPanel != null)
- {
- ap.overviewPanel.updateOverviewImage();
- }
av.sendSelection();
}
});
av.showAllHiddenColumns();
reveal = null;
ap.paintAlignment(true);
- if (ap.overviewPanel != null)
- {
- ap.overviewPanel.updateOverviewImage();
- }
av.sendSelection();
}
});
}
ap.paintAlignment(true);
- if (ap.overviewPanel != null)
- {
- ap.overviewPanel.updateOverviewImage();
- }
av.sendSelection();
}
});
@Override
public void paintComponent(Graphics g)
{
- drawScale(g, av.getRanges().getStartRes(), av.getRanges().getEndRes(),
- getWidth(), getHeight());
+ /*
+ * shouldn't get called in wrapped mode as the scale above is
+ * drawn instead by SeqCanvas.drawNorthScale
+ */
+ if (!av.getWrapAlignment())
+ {
+ drawScale(g, av.getRanges().getStartRes(),
+ av.getRanges().getEndRes(), getWidth(), getHeight());
+ }
}
// scalewidth will normally be screenwidth,
FontMetrics fm = getFontMetrics(av.getFont());
+ LABEL_EAST = 0;
+ LABEL_WEST = 0;
+
if (av.getScaleRightWrapped())
{
LABEL_EAST = fm.stringWidth(getMask());
av.setWrappedWidth(cWidth);
- av.getRanges().setEndRes(av.getRanges().getStartRes() + cWidth - 1);
+ av.getRanges().setViewportStartAndWidth(startRes, cWidth);
int endx;
int ypos = hgap;
- int maxwidth = av.getAlignment().getWidth() - 1;
+ int maxwidth = av.getAlignment().getWidth();
if (av.hasHiddenColumns())
{
maxwidth = av.getAlignment().getHiddenColumns()
- .findColumnPosition(maxwidth) - 1;
+ .findColumnPosition(maxwidth);
}
while ((ypos <= canvasHeight) && (startRes < maxwidth))
{
String eventName = evt.getPropertyName();
- if (!av.getWrapAlignment())
+ if (av.getWrapAlignment())
+ {
+ if (eventName.equals(ViewportRanges.STARTRES))
+ {
+ repaint();
+ }
+ }
+ else
{
int scrollX = 0;
if (eventName.equals(ViewportRanges.STARTRES))
int res = 0;
int x = evt.getX();
+ int startRes = av.getRanges().getStartRes();
if (av.getWrapAlignment())
{
int y = evt.getY();
y -= hgap;
- x -= seqCanvas.LABEL_WEST;
+ x = Math.max(0, x - seqCanvas.LABEL_WEST);
int cwidth = seqCanvas.getWrappedCanvasWidth(this.getWidth());
if (cwidth < 1)
}
wrappedBlock = y / cHeight;
- wrappedBlock += av.getRanges().getStartRes() / cwidth;
-
- res = wrappedBlock * cwidth + x / av.getCharWidth();
-
+ wrappedBlock += startRes / cwidth;
+ // allow for wrapped view scrolled right (possible from Overview)
+ int startOffset = startRes % cwidth;
+ res = wrappedBlock * cwidth + startOffset
+ + +Math.min(cwidth - 1, x / av.getCharWidth());
}
else
{
// right-hand gutter
x = seqCanvas.getX() + seqCanvas.getWidth();
}
- res = (x / av.getCharWidth()) + av.getRanges().getStartRes();
+ res = (x / av.getCharWidth()) + startRes;
if (res > av.getRanges().getEndRes())
{
// moused off right
av.getRanges().scrollRight(true);
}
- else
+ else if (!av.getWrapAlignment())
{
av.getRanges().scrollUp(false);
}
{
av.getRanges().scrollRight(false);
}
- else
+ else if (!av.getWrapAlignment())
{
av.getRanges().scrollUp(true);
}
}
Color featureColour = getColour(sequenceFeature);
+ if (featureColour == null)
+ {
+ // score feature outwith threshold for colouring
+ continue;
+ }
+
boolean isContactFeature = sequenceFeature.isContactFeature();
if (isContactFeature)
drawnColour = featureColour;
}
}
- else if (showFeature(sequenceFeature))
+ else
{
if (av.isShowSequenceFeaturesHeight()
&& !Float.isNaN(sequenceFeature.score))
public void setWrapAlignment(boolean state)
{
viewStyle.setWrapAlignment(state);
+ ranges.setWrappedMode(state);
}
/**
// common hide/show seq stuff
public void showAllHiddenSeqs()
{
+ int startSeq = ranges.getStartSeq();
+ int endSeq = ranges.getEndSeq();
+
if (alignment.getHiddenSequences().getSize() > 0)
{
if (selectionGroup == null)
hiddenRepSequences = null;
+ ranges.setStartEndSeq(startSeq, endSeq + tmp.size());
+
firePropertyChange("alignment", null, alignment.getSequences());
// used to set hasHiddenRows/hiddenRepSequences here, after the property
// changed event
public void showSequence(int index)
{
+ int startSeq = ranges.getStartSeq();
+ int endSeq = ranges.getEndSeq();
+
List<SequenceI> tmp = alignment.getHiddenSequences().showSequence(
index, hiddenRepSequences);
if (tmp.size() > 0)
selectionGroup.addSequence(seq, false);
setSequenceAnnotationsVisible(seq, true);
}
+
+ ranges.setStartEndSeq(startSeq, endSeq + tmp.size());
+
firePropertyChange("alignment", null, alignment.getSequences());
sendSelection();
}
public void hideSequence(SequenceI[] seq)
{
+ /*
+ * cache offset to first visible sequence
+ */
+ int startSeq = ranges.getStartSeq();
+
if (seq != null)
{
for (int i = 0; i < seq.length; i++)
alignment.getHiddenSequences().hideSequence(seq[i]);
setSequenceAnnotationsVisible(seq[i], false);
}
+ ranges.setStartSeq(startSeq);
firePropertyChange("alignment", null, alignment.getSequences());
}
}
{
return searchResults;
}
+
+ /**
+ * get the consensus sequence as displayed under the PID consensus annotation
+ * row.
+ *
+ * @return consensus sequence as a new sequence object
+ */
+ public SequenceI getConsensusSeq()
+ {
+ if (consensus == null)
+ {
+ updateConsensus(null);
+ }
+ if (consensus == null)
+ {
+ return null;
+ }
+ StringBuffer seqs = new StringBuffer();
+ for (int i = 0; i < consensus.annotations.length; i++)
+ {
+ Annotation annotation = consensus.annotations[i];
+ if (annotation != null)
+ {
+ String description = annotation.description;
+ if (description != null && description.startsWith("["))
+ {
+ // consensus is a tie - just pick the first one
+ seqs.append(description.charAt(1));
+ }
+ else
+ {
+ seqs.append(annotation.displayCharacter);
+ }
+ }
+ }
+
+ SequenceI sq = new Sequence("Consensus", seqs.toString());
+ sq.setDescription("Percentage Identity Consensus "
+ + ((ignoreGapsInConsensusCalculation) ? " without gaps" : ""));
+ return sq;
+ }
}
HiddenSequences hiddenSeqs, HiddenColumns hiddenCols);
/**
+ * Update the viewport location from a mouse drag within the overview's box
+ *
+ * @param mousex
+ * x location of mouse
+ * @param mousey
+ * y location of mouse
+ * @param hiddenSeqs
+ * the alignment's hidden sequences
+ * @param hiddenCols
+ * the alignment's hidden columns
+ */
+ public abstract void adjustViewportFromMouse(int mousex, int mousey,
+ HiddenSequences hiddenSeqs, HiddenColumns hiddenCols);
+
+ /**
+ * Initialise dragging from the mouse - must be called on initial mouse click
+ * before using adjustViewportFromMouse in drag operations
+ *
+ * @param mousex
+ * x location of mouse
+ * @param mousey
+ * y location of mouse
+ * @param hiddenSeqs
+ * the alignment's hidden sequences
+ * @param hiddenCols
+ * the alignment's hidden columns
+ */
+ public abstract void setDragPoint(int x, int y,
+ HiddenSequences hiddenSeqs, HiddenColumns hiddenCols);
+
+ /*
+ * Move the viewport so that the top left corner of the overview's box
+ * is at the mouse position (leftx, topy)
+ */
+ protected abstract void updateViewportFromTopLeft(int leftx, int topy,
+ HiddenSequences hiddenSeqs, HiddenColumns hiddenCols);
+
+ /**
* Set the overview panel's box position to match the viewport
*
* @param hiddenSeqs
*/
protected abstract void resetAlignmentDims();
+ /*
+ * Given the box coordinates in residues and sequences, set the box dimensions in the overview window
+ */
protected void setBoxPosition(int startRes, int startSeq, int vpwidth,
int vpheight)
{
resetAlignmentDims();
// boxX, boxY is the x,y location equivalent to startRes, startSeq
- boxX = Math.round((float) startRes * width / alwidth);
+ int xPos = Math.min(startRes, alwidth - vpwidth + 1);
+ boxX = Math.round((float) xPos * width / alwidth);
boxY = Math.round((float) startSeq * sequencesHeight / alheight);
// boxWidth is the width in residues translated to pixels
// boxHeight is the height in sequences translated to pixels
boxHeight = Math.round((float) vpheight * sequencesHeight / alheight);
}
+
+ /**
+ * Answers if a mouse position is in the overview's red box
+ *
+ * @param x
+ * mouse x position
+ * @param y
+ * mouse y position
+ * @return true if (x,y) is inside the box
+ */
+ public boolean isPositionInBox(int x, int y)
+ {
+ return (x > boxX && y > boxY && x < boxX + boxWidth
+ && y < boxY + boxHeight);
+ }
+
+ /*
+ * Given the centre x position, calculate the box's left x position
+ */
+ protected abstract int getLeftXFromCentreX(int mousex, HiddenColumns hidden);
+
+ /*
+ * Given the centre y position, calculate the box's top y position
+ */
+ protected abstract int getTopYFromCentreY(int mousey,
+ HiddenSequences hidden);
+
}
\ No newline at end of file
{
private ViewportRanges ranges;
+ private int xdiff; // when dragging, difference in alignment units between
+ // start residue and original mouse click position
+
+ private int ydiff; // when dragging, difference in alignment units between
+ // start sequence and original mouse click position
+
public OverviewDimensionsHideHidden(ViewportRanges vpranges,
boolean showAnnotationPanel)
{
public void updateViewportFromMouse(int mousex, int mousey,
HiddenSequences hiddenSeqs, HiddenColumns hiddenCols)
{
- resetAlignmentDims();
+ int xAsRes = getLeftXFromCentreX(mousex, hiddenCols);
+ int yAsSeq = getTopYFromCentreY(mousey, hiddenSeqs);
+
+ updateViewportFromTopLeft(xAsRes, yAsSeq, hiddenSeqs, hiddenCols);
+
+ }
+
+ @Override
+ public void adjustViewportFromMouse(int mousex, int mousey,
+ HiddenSequences hiddenSeqs, HiddenColumns hiddenCols)
+ {
+ // calculate translation in pixel terms:
+ // get mouse location in viewport coords, add translation in viewport
+ // coords, and update viewport as usual
+ int vpx = Math.round((float) mousex * alwidth / width);
+ int vpy = Math.round((float) mousey * alheight / sequencesHeight);
- int x = mousex;
- int y = mousey;
+ updateViewportFromTopLeft(vpx + xdiff, vpy + ydiff, hiddenSeqs,
+ hiddenCols);
- if (x < 0)
+ }
+
+ @Override
+ protected void updateViewportFromTopLeft(int leftx, int topy,
+ HiddenSequences hiddenSeqs, HiddenColumns hiddenCols)
+ {
+ int xAsRes = leftx;
+ int yAsSeq = topy;
+ resetAlignmentDims();
+
+ if (xAsRes < 0)
{
- x = 0;
+ xAsRes = 0;
}
- if (y < 0)
+ if (yAsSeq < 0)
{
- y = 0;
+ yAsSeq = 0;
}
- //
- // Convert x value to residue position
- //
-
- // need to determine where scrollCol should be, given x
- // to do this also need to know width of viewport, and some hidden column
- // correction
-
- // convert x to residues - this is an absolute position
- int xAsRes = Math.round((float) x * alwidth / width);
+ if (ranges.isWrappedMode())
+ {
+ yAsSeq = 0; // sorry, no vertical scroll when wrapped
+ }
// get viewport width in residues
int vpwidth = ranges.getViewportWidth();
}
}
-
- //
- // Convert y value to sequence position
- //
-
- // convert y to residues
- int yAsSeq = Math.round((float) y * alheight / sequencesHeight);
+ // Determine where scrollRow should be, given visYAsSeq
// get viewport height in sequences
// add 1 because height includes both endSeq and startSeq
// update viewport
ranges.setStartRes(xAsRes);
ranges.setStartSeq(yAsSeq);
-
}
@Override
alwidth = ranges.getVisibleAlignmentWidth();
alheight = ranges.getVisibleAlignmentHeight();
}
+
+ @Override
+ protected int getLeftXFromCentreX(int mousex, HiddenColumns hidden)
+ {
+ int vpx = Math.round((float) mousex * alwidth / width);
+ return vpx - ranges.getViewportWidth() / 2;
+ }
+
+ @Override
+ protected int getTopYFromCentreY(int mousey, HiddenSequences hidden)
+ {
+ int vpy = Math.round((float) mousey * alheight / sequencesHeight);
+ return vpy - ranges.getViewportHeight() / 2;
+ }
+
+ @Override
+ public void setDragPoint(int x, int y, HiddenSequences hiddenSeqs,
+ HiddenColumns hiddenCols)
+ {
+ // get alignment position of x and box (can get directly from vpranges) and
+ // calculate difference between the positions
+ int vpx = Math.round((float) x * alwidth / width);
+ int vpy = Math.round((float) y * alheight / sequencesHeight);
+
+ xdiff = ranges.getStartRes() - vpx;
+ ydiff = ranges.getStartSeq() - vpy;
+ }
+
}
{
private ViewportRanges ranges;
+ private int xdiff; // when dragging, difference in alignment units between
+ // start residue and original mouse click position
+
+ private int ydiff; // when dragging, difference in alignment units between
+ // start sequence and original mouse click position
+
/**
* Create an OverviewDimensions object
*
public void updateViewportFromMouse(int mousex, int mousey,
HiddenSequences hiddenSeqs, HiddenColumns hiddenCols)
{
- int x = mousex;
- int y = mousey;
+ // convert mousex and mousey to alignment units as well as
+ // translating to top left corner of viewport - this is an absolute position
+ int xAsRes = getLeftXFromCentreX(mousex, hiddenCols);
+ int yAsSeq = getTopYFromCentreY(mousey, hiddenSeqs);
+
+ // convert to visible positions
+ int visXAsRes = hiddenCols.findColumnPosition(xAsRes);
+ yAsSeq = hiddenSeqs.adjustForHiddenSeqs(
+ hiddenSeqs.findIndexWithoutHiddenSeqs(yAsSeq));
+ yAsSeq = Math.max(yAsSeq, 0); // -1 if before first visible sequence
+ int visYAsSeq = hiddenSeqs.findIndexWithoutHiddenSeqs(yAsSeq);
+ visYAsSeq = Math.max(visYAsSeq, 0); // -1 if before first visible sequence
+
+ // update viewport accordingly
+ updateViewportFromTopLeft(visXAsRes, visYAsSeq, hiddenSeqs, hiddenCols);
+ }
+
+ @Override
+ public void adjustViewportFromMouse(int mousex, int mousey,
+ HiddenSequences hiddenSeqs, HiddenColumns hiddenCols)
+ {
+ // calculate translation in pixel terms:
+ // get mouse location in viewport coords, add translation in viewport
+ // coords,
+ // convert back to pixel coords
+ int vpx = Math.round((float) mousex * alwidth / width);
+ int visXAsRes = hiddenCols.findColumnPosition(vpx) + xdiff;
+ int vpy = Math.round((float) mousey * alheight / sequencesHeight);
+ int visYAsRes = hiddenSeqs.findIndexWithoutHiddenSeqs(vpy) + ydiff;
+
+ // update viewport accordingly
+ updateViewportFromTopLeft(visXAsRes, visYAsRes,
+ hiddenSeqs,
+ hiddenCols);
+ }
+
+ @Override
+ protected void updateViewportFromTopLeft(int leftx, int topy,
+ HiddenSequences hiddenSeqs, HiddenColumns hiddenCols)
+ {
+ int visXAsRes = leftx;
+ int visYAsSeq = topy;
resetAlignmentDims();
- if (x < 0)
+ if (visXAsRes < 0)
{
- x = 0;
+ visXAsRes = 0;
}
- if (y < 0)
+ if (visYAsSeq < 0)
{
- y = 0;
+ visYAsSeq = 0;
}
- //
- // Convert x value to residue position
- //
-
- // need to determine where scrollCol should be, given x
- // to do this also need to know width of viewport, and some hidden column
- // correction
+ if (ranges.isWrappedMode())
+ {
+ visYAsSeq = 0; // sorry, no vertical scroll when wrapped
+ }
- // convert x to residues - this is an absolute position
- int xAsRes = Math.round((float) x * alwidth / width);
+ // Determine where scrollCol should be, given visXAsRes
// get viewport width in residues
int vpwidth = ranges.getViewportWidth();
- // get where x should be when accounting for hidden cols
- // if x is in a hidden col region, shift to left - but we still need
- // absolute position
- // so convert back after getting visible region position
- int visXAsRes = hiddenCols.findColumnPosition(xAsRes);
-
// check in case we went off the edge of the alignment
int visAlignWidth = hiddenCols.findColumnPosition(alwidth - 1);
if (visXAsRes + vpwidth - 1 > visAlignWidth)
}
}
- //
- // Convert y value to sequence position
- //
-
- // convert y to residues
- int yAsSeq = Math.round((float) y * alheight / sequencesHeight);
+ // Determine where scrollRow should be, given visYAsSeq
// get viewport height in sequences
int vpheight = ranges.getViewportHeight();
- // get where y should be when accounting for hidden rows
- // if y is in a hidden row region, shift up - but we still need absolute
- // position,
- // so convert back after getting visible region position
- yAsSeq = hiddenSeqs.adjustForHiddenSeqs(hiddenSeqs
- .findIndexWithoutHiddenSeqs(yAsSeq));
-
// check in case we went off the edge of the alignment
int visAlignHeight = hiddenSeqs.findIndexWithoutHiddenSeqs(alheight);
- int visYAsSeq = hiddenSeqs.findIndexWithoutHiddenSeqs(yAsSeq);
+
if (visYAsSeq + vpheight - 1 > visAlignHeight)
{
// went past the end of the alignment, adjust backwards
// update viewport
ranges.setStartRes(visXAsRes);
ranges.setStartSeq(visYAsSeq);
-
}
/**
alwidth = ranges.getAbsoluteAlignmentWidth();
alheight = ranges.getAbsoluteAlignmentHeight();
}
+
+ @Override
+ protected int getLeftXFromCentreX(int mousex, HiddenColumns hidden)
+ {
+ int vpx = Math.round((float) mousex * alwidth / width);
+ return hidden.subtractVisibleColumns(ranges.getViewportWidth() / 2,
+ vpx);
+ }
+
+ @Override
+ protected int getTopYFromCentreY(int mousey, HiddenSequences hidden)
+ {
+ int vpy = Math.round((float) mousey * alheight / sequencesHeight);
+ return hidden.subtractVisibleRows(ranges.getViewportHeight() / 2, vpy);
+ }
+
+ @Override
+ public void setDragPoint(int x, int y, HiddenSequences hiddenSeqs,
+ HiddenColumns hiddenCols)
+ {
+ // get alignment position of x and box (can get directly from vpranges) and
+ // calculate difference between the positions
+ int vpx = Math.round((float) x * alwidth / width);
+ int vpy = Math.round((float) y * alheight / sequencesHeight);
+
+ xdiff = ranges.getStartRes() - hiddenCols.findColumnPosition(vpx);
+ ydiff = ranges.getStartSeq()
+ - hiddenSeqs.findIndexWithoutHiddenSeqs(vpy);
+ }
+
}
public static final String ENDSEQ = "endseq";
+ private boolean wrappedMode = false;
+
// start residue of viewport
private int startRes;
public void setStartEndRes(int start, int end)
{
int oldstartres = this.startRes;
- if (start > getVisibleAlignmentWidth() - 1)
+
+ /*
+ * if not wrapped, don't leave white space at the right margin
+ */
+ int lastColumn = getVisibleAlignmentWidth() - 1;
+ if (!wrappedMode && (start > lastColumn))
{
- startRes = Math.max(getVisibleAlignmentWidth() - 1, 0);
+ startRes = Math.max(lastColumn, 0);
}
else if (start < 0)
{
{
endRes = 0;
}
- else if (end > getVisibleAlignmentWidth() - 1)
+ else if (!wrappedMode && (end > lastColumn))
{
- endRes = Math.max(getVisibleAlignmentWidth() - 1, 0);
+ endRes = Math.max(lastColumn, 0);
}
else
{
}
/**
- * Set last residue visible in the viewport. Fires a property change event.
- *
- * @param res
- * residue position
- */
- public void setEndRes(int res)
- {
- int startres = res;
- int width = getViewportWidth();
- if (startres + width - 1 > getVisibleAlignmentWidth() - 1)
- {
- startres = getVisibleAlignmentWidth() - width;
- }
- setStartEndRes(startres - width + 1, startres);
- }
-
- /**
* Set the first sequence visible in the viewport, maintaining the height. If
* the viewport would extend past the last sequence, sets the viewport so it
* sits at the bottom of the alignment. Fires a property change event.
public void setStartEndSeq(int start, int end)
{
int oldstartseq = this.startSeq;
- if (start > getVisibleAlignmentHeight() - 1)
+ int visibleHeight = getVisibleAlignmentHeight();
+ if (start > visibleHeight - 1)
{
- startSeq = Math.max(getVisibleAlignmentHeight() - 1, 0);
+ startSeq = Math.max(visibleHeight - 1, 0);
}
else if (start < 0)
{
}
int oldendseq = this.endSeq;
- if (end >= getVisibleAlignmentHeight())
+ if (end >= visibleHeight)
{
- endSeq = Math.max(getVisibleAlignmentHeight() - 1, 0);
+ endSeq = Math.max(visibleHeight - 1, 0);
}
else if (end < 0)
{
{
vpstart = 0;
}
- else if ((w <= getVisibleAlignmentWidth())
- && (vpstart + w - 1 > getVisibleAlignmentWidth() - 1))
- // viewport width is less than the full alignment and we are running off the
- // RHS edge
+
+ /*
+ * if not wrapped, don't leave white space at the right margin
+ */
+ if (!wrappedMode)
{
- vpstart = getVisibleAlignmentWidth() - w;
+ if ((w <= getVisibleAlignmentWidth())
+ && (vpstart + w - 1 > getVisibleAlignmentWidth() - 1))
+ {
+ vpstart = getVisibleAlignmentWidth() - w;
+ }
+
}
setStartEndRes(vpstart, vpstart + w - 1);
}
*/
public void pageUp()
{
- setViewportStartAndHeight(2 * startSeq - endSeq, getViewportHeight());
+ if (wrappedMode)
+ {
+ setStartRes(Math.max(0, getStartRes() - getViewportWidth()));
+ }
+ else
+ {
+ setViewportStartAndHeight(startSeq - (endSeq - startSeq),
+ getViewportHeight());
+ }
}
/**
*/
public void pageDown()
{
- setViewportStartAndHeight(endSeq, getViewportHeight());
+ if (wrappedMode)
+ {
+ /*
+ * if height is more than width (i.e. not all sequences fit on screen),
+ * increase page down to height
+ */
+ int newStart = getStartRes()
+ + Math.max(getViewportHeight(), getViewportWidth());
+
+ /*
+ * don't page down beyond end of alignment, or if not all
+ * sequences fit in the visible height
+ */
+ if (newStart < getVisibleAlignmentWidth())
+ {
+ setStartRes(newStart);
+ }
+ }
+ else
+ {
+ setViewportStartAndHeight(endSeq, getViewportHeight());
+ }
+ }
+
+ public void setWrappedMode(boolean wrapped)
+ {
+ wrappedMode = wrapped;
+ }
+
+ public boolean isWrappedMode()
+ {
+ return wrappedMode;
+ }
+
+ /**
+ * Answers the vertical scroll position (0..) to set, given the visible column
+ * that is at top left.
+ *
+ * <pre>
+ * Example:
+ * viewport width 40 columns (0-39, 40-79, 80-119...)
+ * column 0 returns scroll position 0
+ * columns 1-40 return scroll position 1
+ * columns 41-80 return scroll position 2
+ * etc
+ * </pre>
+ *
+ * @param topLeftColumn
+ * (0..)
+ * @return
+ */
+ public int getWrappedScrollPosition(final int topLeftColumn)
+ {
+ int w = getViewportWidth();
+
+ /*
+ * visible whole widths
+ */
+ int scroll = topLeftColumn / w;
+
+ /*
+ * add 1 for a part width if there is one
+ */
+ scroll += topLeftColumn % w > 0 ? 1 : 0;
+
+ return scroll;
+ }
+
+ /**
+ * Answers the maximum wrapped vertical scroll value, given the column
+ * position (0..) to show at top left of the visible region.
+ *
+ * @param topLeftColumn
+ * @return
+ */
+ public int getWrappedMaxScroll(int topLeftColumn)
+ {
+ int scrollPosition = getWrappedScrollPosition(topLeftColumn);
+
+ /*
+ * how many more widths could be drawn after this one?
+ */
+ int columnsRemaining = getVisibleAlignmentWidth() - topLeftColumn;
+ int width = getViewportWidth();
+ int widthsRemaining = columnsRemaining / width
+ + (columnsRemaining % width > 0 ? 1 : 0) - 1;
+ int maxScroll = scrollPosition + widthsRemaining;
+
+ return maxScroll;
}
}
public Color getColour(SequenceFeature feature)
{
FeatureColourI fc = getFeatureStyle(feature.getType());
- return fc.getColor(feature);
+ return fc.isColored(feature) ? fc.getColor(feature) : null;
}
+ /**
+ * Answers true unless the feature has a score value which lies outside a
+ * minimum or maximum threshold configured for colouring. This method does not
+ * check feature type or group visibility.
+ *
+ * @param sequenceFeature
+ * @return
+ */
protected boolean showFeature(SequenceFeature sequenceFeature)
{
FeatureColourI fc = getFeatureStyle(sequenceFeature.type);
assertNull(result);
}
+ @Test(groups = "Functional")
+ public void testPropagateInsertions()
+ {
+ // create an alignment with no gaps - this will be the profile seq and other
+ // JPRED seqs
+ AlignmentGenerator gen = new AlignmentGenerator(false);
+ AlignmentI al = gen.generate(20, 10, 1234, 0, 0);
+
+ // get the profileseq
+ SequenceI profileseq = al.getSequenceAt(0);
+ SequenceI gappedseq = new Sequence(profileseq);
+ gappedseq.insertCharAt(5, al.getGapCharacter());
+ gappedseq.insertCharAt(6, al.getGapCharacter());
+ gappedseq.insertCharAt(7, al.getGapCharacter());
+ gappedseq.insertCharAt(8, al.getGapCharacter());
+
+ // create an alignment view with the gapped sequence
+ SequenceI[] seqs = new SequenceI[1];
+ seqs[0] = gappedseq;
+ AlignmentI newal = new Alignment(seqs);
+ HiddenColumns hidden = new HiddenColumns();
+ hidden.hideColumns(15, 17);
+
+ AlignmentView view = new AlignmentView(newal, hidden, null, true, false,
+ false);
+
+ // confirm that original contigs are as expected
+ int[] oldcontigs = hidden.getVisibleContigs(0, 20);
+ int[] testcontigs = { 0, 14, 18, 19 };
+ assertTrue(Arrays.equals(oldcontigs, testcontigs));
+
+ // propagate insertions
+ HiddenColumns result = HiddenColumns.propagateInsertions(profileseq, al,
+ view);
+
+ // confirm that the contigs have changed to account for the gaps
+ int[] newcontigs = result.getVisibleContigs(0, 20);
+ testcontigs[1] = 10;
+ testcontigs[2] = 14;
+ assertTrue(Arrays.equals(newcontigs, testcontigs));
+
+ }
}
{
AlignmentI al = new Alignment(seqs);
HiddenSequences hs = al.getHiddenSequences();
- for (int i = 0; i < SEQ_COUNT; i++)
+ int height = al.getHeight();
+ for (int i = 0; i < height; i++)
{
assertEquals(i, hs.findIndexWithoutHiddenSeqs(i));
}
/*
* alignment is now seq0/2/3/4/7/8/9
*/
- assertEquals(SEQ_COUNT - 3, al.getHeight());
+ assertEquals(height - 3, al.getHeight());
assertEquals(0, hs.findIndexWithoutHiddenSeqs(0));
assertEquals(0, hs.findIndexWithoutHiddenSeqs(1));
assertEquals(1, hs.findIndexWithoutHiddenSeqs(2));
assertEquals(4, hs.findIndexWithoutHiddenSeqs(7));
assertEquals(5, hs.findIndexWithoutHiddenSeqs(8));
assertEquals(6, hs.findIndexWithoutHiddenSeqs(9));
+
+ /*
+ * hide first two sequences
+ */
+ hs.showAll(null);
+ hs.hideSequence(seqs[0]);
+ hs.hideSequence(seqs[1]);
+ assertEquals(-1, hs.findIndexWithoutHiddenSeqs(0));
+ assertEquals(-1, hs.findIndexWithoutHiddenSeqs(1));
+ for (int i = 2; i < height; i++)
+ {
+ assertEquals(i - 2, hs.findIndexWithoutHiddenSeqs(i));
+ }
}
/**
import jalview.schemes.PIDColourScheme;
import jalview.structure.StructureSelectionManager;
import jalview.util.MapList;
+import jalview.viewmodel.ViewportRanges;
import java.util.ArrayList;
import java.util.List;
}
;
Assert.assertEquals(c, 1, "Expected to find one occupancy row.");
+ }
+ @Test(groups = { "Functional" })
+ public void testGetConsensusSeq()
+ {
+ /*
+ * A-C
+ * A-C
+ * A-D
+ * --D
+ * consensus expected to be A-C
+ */
+ String fasta = ">s1\nA-C\n>s2\nA-C\n>s3\nA-D\n>s4\n--D\n";
+ AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(fasta,
+ DataSourceType.PASTE);
+ AlignViewport testme = af.getViewport();
+ SequenceI cons = testme.getConsensusSeq();
+ assertEquals("A-C", cons.getSequenceAsString());
+ }
+
+ @Test(groups = { "Functional" })
+ public void testHideRevealSequences()
+ {
+ ViewportRanges ranges = testee.getRanges();
+ assertEquals(3, al.getHeight());
+ assertEquals(0, ranges.getStartSeq());
+ assertEquals(2, ranges.getEndSeq());
+
+ /*
+ * hide first sequence
+ */
+ testee.hideSequence(new SequenceI[] { al.getSequenceAt(0) });
+ assertEquals(2, al.getHeight());
+ assertEquals(0, ranges.getStartSeq());
+ assertEquals(1, ranges.getEndSeq());
+
+ /*
+ * reveal hidden sequences above the first
+ */
+ testee.showSequence(0);
+ assertEquals(3, al.getHeight());
+ assertEquals(0, ranges.getStartSeq());
+ assertEquals(2, ranges.getEndSeq());
+
+ /*
+ * hide first and third sequences
+ */
+ testee.hideSequence(new SequenceI[] { al.getSequenceAt(0),
+ al.getSequenceAt(2) });
+ assertEquals(1, al.getHeight());
+ assertEquals(0, ranges.getStartSeq());
+ assertEquals(0, ranges.getEndSeq());
+
+ /*
+ * reveal all hidden sequences
+ */
+ testee.showAllHiddenSeqs();
+ assertEquals(3, al.getHeight());
+ assertEquals(0, ranges.getStartSeq());
+ assertEquals(2, ranges.getEndSeq());
}
}
* updated - JAL-1904), and verify (some) feature group colours
*/
colours = af.getFeatureRenderer().getFeatureColours();
- assertEquals("26 feature group colours not found", 26, colours.size());
+ assertEquals("27 feature group colours not found", 27, colours.size());
assertEquals(colours.get("Cath").getColour(), new Color(0x93b1d1));
assertEquals(colours.get("ASX-MOTIF").getColour(), new Color(0x6addbb));
+ FeatureColourI kdColour = colours.get("kdHydrophobicity");
+ assertTrue(kdColour.isGraduatedColour());
+ assertTrue(kdColour.isAboveThreshold());
+ assertEquals(-2f, kdColour.getThreshold());
/*
* verify (some) features on sequences
FeatureColourFinder finder2 = new FeatureColourFinder(null);
assertTrue(finder2.noFeaturesDisplayed());
}
+
+ @Test(groups = "Functional")
+ public void testFindFeatureColour_graduatedWithThreshold()
+ {
+ seq.addSequenceFeature(new SequenceFeature("kd", "hydrophobicity", 2,
+ 2, 0f, "KdGroup"));
+ seq.addSequenceFeature(new SequenceFeature("kd", "hydrophobicity", 4,
+ 4, 5f, "KdGroup"));
+ seq.addSequenceFeature(new SequenceFeature("kd", "hydrophobicity", 7,
+ 7, 10f, "KdGroup"));
+
+ /*
+ * graduated colour from 0 to 10
+ * above threshold value of 5
+ */
+ Color min = new Color(100, 50, 150);
+ Color max = new Color(200, 0, 100);
+ FeatureColourI fc = new FeatureColour(min, max, 0, 10);
+ fc.setAboveThreshold(true);
+ fc.setThreshold(5f);
+ fr.setColour("kd", fc);
+ fr.featuresAdded();
+ av.setShowSequenceFeatures(true);
+
+ /*
+ * position 2, column 1, score 0 - below threshold - default colour
+ */
+ Color c = finder.findFeatureColour(Color.blue, seq, 1);
+ assertEquals(c, Color.blue);
+
+ /*
+ * position 4, column 3, score 5 - at threshold - default colour
+ */
+ c = finder.findFeatureColour(Color.blue, seq, 3);
+ assertEquals(c, Color.blue);
+
+ /*
+ * position 7, column 9, score 10 - maximum colour in range
+ */
+ c = finder.findFeatureColour(Color.blue, seq, 9);
+ assertEquals(c, max);
+
+ /*
+ * now colour below threshold of 5
+ */
+ fc.setBelowThreshold(true);
+
+ /*
+ * position 2, column 1, score 0 - min colour
+ */
+ c = finder.findFeatureColour(Color.blue, seq, 1);
+ assertEquals(c, min);
+
+ /*
+ * position 4, column 3, score 5 - at threshold - default colour
+ */
+ c = finder.findFeatureColour(Color.blue, seq, 3);
+ assertEquals(c, Color.blue);
+
+ /*
+ * position 7, column 9, score 10 - above threshold - default colour
+ */
+ c = finder.findFeatureColour(Color.blue, seq, 9);
+ assertEquals(c, Color.blue);
+ }
}
package jalview.viewmodel;
import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
import jalview.analysis.AlignmentGenerator;
import jalview.datamodel.Alignment;
ViewportRanges vpranges;
- Hashtable<SequenceI, SequenceCollectionI> hiddenRepSequences = new Hashtable<SequenceI, SequenceCollectionI>();
+ Hashtable<SequenceI, SequenceCollectionI> hiddenRepSequences = new Hashtable<>();
HiddenColumns hiddenCols = new HiddenColumns();
assertEquals(od.getBoxX(), 0);
assertEquals(od.getBoxWidth(), boxWidth);
assertEquals(od.getBoxHeight(), boxHeight);
- assertEquals(vpranges.getStartSeq(),
+ assertEquals(vpranges.getStartSeq() + vpranges.getViewportHeight() / 2,
Math.round((float) 10 * alheight / od.getSequencesHeight()));
assertEquals(vpranges.getStartRes(), 0);
assertEquals(od.getBoxY(), 0);
assertEquals(od.getBoxWidth(), boxWidth);
assertEquals(od.getBoxHeight(), boxHeight);
- assertEquals(vpranges.getStartRes(),
- Math.round((float) 6 * alwidth / od.getWidth()));
+ assertEquals(vpranges.getStartRes(), 0);
assertEquals(vpranges.getStartSeq(), 0);
// overly large boxX value reset to width-boxWidth
- mouseClick(od, 100, 6);
+ mouseClick(od, 101, 6);
assertEquals(od.getBoxX(), od.getWidth() - od.getBoxWidth());
- assertEquals(od.getBoxY(), 6);
+ assertEquals(od.getBoxY(), 1);
assertEquals(od.getBoxWidth(), boxWidth);
assertEquals(od.getBoxHeight(), boxHeight);
assertEquals(vpranges.getStartRes(),
// overly large boxY value reset to sequenceHeight - boxHeight
mouseClick(od, 10, 520);
- assertEquals(od.getBoxX(), 10);
+ assertEquals(od.getBoxX(), 0);
assertEquals(od.getBoxY(), od.getSequencesHeight() - od.getBoxHeight());
assertEquals(od.getBoxWidth(), boxWidth);
assertEquals(od.getBoxHeight(), boxHeight);
/ od.getSequencesHeight()));
// move viewport so startRes non-zero and then mouseclick
- moveViewportH(50);
+ moveViewportH(20);
// click at viewport position
int oldboxx = od.getBoxX();
int oldboxy = od.getBoxY();
- mouseClick(od, od.getBoxX() + 5, od.getBoxY() + 2);
- assertEquals(od.getBoxX(), oldboxx + 5);
+ mouseClick(od, od.getBoxX() + od.getBoxWidth() / 2 + 6,
+ od.getBoxY() + od.getBoxHeight() / 2 + 3);
+ assertEquals(od.getBoxX(), oldboxx + 6);
assertEquals(od.getBoxWidth(), boxWidth);
assertEquals(od.getBoxHeight(), boxHeight);
assertEquals(vpranges.getStartRes(),
Math.round((float) od.getBoxX() * alwidth / od.getWidth()));
- assertEquals(od.getBoxY(), oldboxy + 2);
+ assertEquals(od.getBoxY(), oldboxy + 3);
assertEquals(
vpranges.getStartSeq(),
Math.round((float) od.getBoxY() * alheight
int lastHiddenCol = 30;
hiddenCols.hideColumns(0, lastHiddenCol);
- testBoxIsAtClickPoint(0, 0);
+ testBoxIsAtClickPoint(boxWidth / 2, boxHeight / 2);
// click to right of hidden columns, box moves to click point
- testBoxIsAtClickPoint(40, 0);
+ testBoxIsAtClickPoint(41 + boxWidth / 2, boxHeight / 2);
assertEquals(vpranges.getStartSeq(), 0);
assertEquals(vpranges.getStartRes(),
- Math.round((float) 40 * alwidth / od.getWidth()));
+ Math.round((float) 41 * alwidth / od.getWidth()));
// click to right of hidden columns such that box runs over right hand side
// of alignment
// box position is adjusted away from the edge
// overly large boxX value reset to width-boxWidth
- int xpos = 100;
- mouseClick(od, xpos, 0);
+ int xpos = 100 + boxWidth / 2;
+ mouseClick(od, xpos, boxHeight / 2);
assertEquals(od.getBoxX(), Math.round(od.getWidth()) - boxWidth);
assertEquals(od.getBoxY(), 0);
assertEquals(od.getBoxWidth(), boxWidth);
public void testFromMouseWithHiddenColsInMiddle()
{
od.updateViewportFromMouse(0, 0, al.getHiddenSequences(), hiddenCols);
- testBoxIsAtClickPoint(0, 0);
+ testBoxIsAtClickPoint(boxWidth / 2, boxHeight / 2);
assertEquals(od.getBoxX(), 0);
assertEquals(od.getBoxY(), 0);
assertEquals(od.getBoxWidth(), boxWidth);
hiddenCols.hideColumns(firstHidden, lastHidden);
od.setBoxPosition(al.getHiddenSequences(), hiddenCols);
- testBoxIsAtClickPoint(0, 0);
+ testBoxIsAtClickPoint(boxWidth / 2, boxHeight / 2);
assertEquals(od.getBoxX(), 0);
assertEquals(od.getBoxY(), 0);
assertEquals(od.getBoxWidth(), boxWidth);
// move box so that it overlaps with hidden cols on one side
// box width, boxX and scrollCol as for unhidden case
- int xpos = 55 - boxWidth; // 55 is position in overview approx halfway
+ int xpos = 54 - boxWidth / 2; // 54 is position in overview approx halfway
// between cols 60 and 70
- mouseClick(od, xpos, 0);
- testBoxIsAtClickPoint(xpos, 0);
- assertEquals(vpranges.getStartRes(),
- Math.round(xpos * alwidth / od.getWidth()));
+ mouseClick(od, xpos, boxHeight / 2);
+ testBoxIsAtClickPoint(xpos, boxHeight / 2);
+ assertEquals(vpranges.getStartRes(), 1 + // rounding
+ Math.round((xpos - boxWidth / 2) * alwidth / od.getWidth()));
assertEquals(vpranges.getStartSeq(), 0);
// move box so that it completely covers hidden cols
// box width, boxX and scrollCol as for unhidden case
xpos = 33;
- mouseClick(od, xpos, 0);
- testBoxIsAtClickPoint(xpos, 0);
+ mouseClick(od, xpos, boxHeight / 2);
+ testBoxIsAtClickPoint(xpos, boxHeight / 2);
assertEquals(vpranges.getStartRes(),
- Math.round((float) xpos * alwidth / od.getWidth()));
+ Math.round((float) (xpos - boxWidth / 2) * alwidth
+ / od.getWidth()));
assertEquals(vpranges.getStartSeq(), 0);
// move box so boxX is in hidden cols, box overhangs at right
// boxX and scrollCol at left of hidden area, box width unchanged
- xpos = 50;
- mouseClick(od, xpos, 0);
- testBoxIsAtClickPoint(xpos, 0);
- assertEquals(vpranges.getStartRes(),
- Math.round((float) xpos * alwidth / od.getWidth()));
+ xpos = Math.round((float) 50 * od.getWidth() / alwidth) + boxWidth / 2;
+ mouseClick(od, xpos, boxHeight / 2);
+ assertEquals(od.getBoxX() + od.getBoxWidth() / 2, xpos);
+ assertEquals(od.getBoxY(), 0);
+ assertEquals(od.getBoxWidth(), boxWidth);
+ assertEquals(od.getBoxHeight(), boxHeight);
+ assertEquals(vpranges.getStartRes(), 50);
assertEquals(vpranges.getStartSeq(), 0);
// move box so boxX is to right of hidden cols, but does not go beyond full
// width of alignment
// box width, boxX and scrollCol all as for non-hidden case
- xpos = 75;
- testBoxIsAtClickPoint(xpos, 0);
+ xpos = Math.round((float) 75 * od.getWidth() / alwidth) + boxWidth / 2;
+ mouseClick(od, xpos, boxHeight / 2);
+ assertEquals(od.getBoxX() + od.getBoxWidth() / 2, xpos);
+ assertEquals(od.getBoxY(), 0);
+ assertEquals(od.getBoxWidth(), boxWidth);
+ assertEquals(od.getBoxHeight(), boxHeight);
assertEquals(vpranges.getStartSeq(), 0);
- assertEquals(vpranges.getStartRes(),
- Math.round(xpos * alwidth / od.getWidth()));
+ assertEquals(vpranges.getStartRes(), 75);
// move box so it goes beyond full width of alignment
// boxX, scrollCol adjusted back, box width normal
xpos = 3000;
- mouseClick(od, xpos, 0);
+ mouseClick(od, xpos, boxHeight / 2);
assertEquals(od.getBoxX(), Math.round(od.getWidth()) - boxWidth);
assertEquals(od.getBoxY(), 0);
assertEquals(od.getBoxWidth(), boxWidth);
// click to left of hidden cols, without overlapping
// boxX, scrollCol and width as normal
- int xpos = 5;
- testBoxIsAtClickPoint(xpos, 0);
- assertEquals(vpranges.getStartSeq(), 0);
- assertEquals(vpranges.getStartRes(),
- Math.round((float) xpos * alwidth / od.getWidth()));
+ int xpos = 30;
+ int ypos = 6;
+ testBoxIsAtClickPoint(xpos, ypos);
+ assertEquals(vpranges.getStartSeq(), Math.round(
+ (float) (ypos - boxHeight / 2) * alheight / od.getHeight()));
+ assertEquals(vpranges.getStartRes(), Math.round(
+ (float) (xpos - boxWidth / 2) * alwidth / od.getWidth()));
// click to left of hidden cols, with overlap
// boxX and scrollCol adjusted for hidden cols, width normal
- xpos = Math.round((float) 145 * od.getWidth() / alwidth) - boxWidth;
- mouseClick(od, xpos, 0);
- testBoxIsAtClickPoint(xpos, 0);
+ xpos = Math.round((float) 144 * od.getWidth() / alwidth) - boxWidth;
+ mouseClick(od, xpos, boxHeight / 2);
+ testBoxIsAtClickPoint(xpos, boxHeight / 2);
assertEquals(vpranges.getStartRes(),
- Math.round((float) xpos * alwidth / od.getWidth()));
+ Math.round((float) (xpos - boxWidth / 2) * alwidth
+ / od.getWidth()));
assertEquals(vpranges.getStartSeq(), 0);
// click off end of alignment
assertEquals(od.getBoxHeight(), boxHeight);
// click below hidden rows
- mouseClick(od, 0, 150);
+ mouseClick(od, 0, 151 + boxHeight / 2);
assertEquals(od.getBoxX(), 0);
- assertEquals(od.getBoxY(), 150);
+ assertEquals(od.getBoxY(), 151);
assertEquals(od.getBoxWidth(), boxWidth);
assertEquals(od.getBoxHeight(), boxHeight);
}
assertEquals(od.getBoxHeight(), boxHeight);
// click above hidden rows, so that box overlaps
- int ypos = 35; // column value in residues
+ int ypos = 35 + viewHeight / 2; // row value in residues
mouseClick(od, 0,
Math.round((float) ypos * od.getSequencesHeight() / alheight));
assertEquals(od.getBoxX(), 0);
assertEquals(od.getBoxY(),
- Math.round((float) ypos * od.getSequencesHeight() / alheight));
+ Math.round((float) 35 * od.getSequencesHeight() / alheight));
assertEquals(od.getBoxWidth(), boxWidth);
assertEquals(od.getBoxHeight(), boxHeight);
// click so that box straddles hidden rows
- ypos = 44; // column value in residues
+ ypos = 45 + viewHeight / 2; // row value in residues
mouseClick(od, 0,
Math.round((float) ypos * od.getSequencesHeight() / alheight));
assertEquals(od.getBoxX(), 0);
assertEquals(od.getBoxY(),
- Math.round((float) ypos * od.getSequencesHeight() / alheight));
+ Math.round((float) 45 * od.getSequencesHeight() / alheight));
assertEquals(od.getBoxWidth(), boxWidth);
assertEquals(od.getBoxHeight(), boxHeight);
}
assertEquals(od.getBoxHeight(), boxHeight);
// click above hidden rows
- int ypos = 40; // row 40
+ int ypos = 41 + viewHeight / 2; // row 41
mouseClick(od, 0,
Math.round((float) ypos * od.getSequencesHeight() / alheight));
assertEquals(od.getBoxX(), 0);
assertEquals(od.getBoxY(),
- Math.round((float) ypos * od.getSequencesHeight() / alheight));
+ Math.round((float) 41 * od.getSequencesHeight() / alheight));
assertEquals(od.getBoxWidth(), boxWidth);
assertEquals(od.getBoxHeight(), boxHeight);
// click above hidden rows so box overlaps
// boxY, boxHeight remains same
- ypos = 497; // row 497
+ ypos = 497 + viewHeight / 2; // row 497
mouseClick(od, 0,
Math.round((float) ypos * od.getSequencesHeight() / alheight));
assertEquals(od.getBoxX(), 0);
assertEquals(od.getBoxHeight(), boxHeight);
}
+ /**
+ * Test the function to determine if a point is in the overview's box or not
+ */
+ @Test(groups = { "Functional" })
+ public void testPositionInBox()
+ {
+ od.updateViewportFromMouse(0, 0, al.getHiddenSequences(), hiddenCols);
+
+ assertFalse(od.isPositionInBox(0, 0));
+ assertTrue(od.isPositionInBox(10, 9));
+ assertFalse(od.isPositionInBox(0, 9));
+ assertFalse(od.isPositionInBox(9, 0));
+ assertFalse(od.isPositionInBox(75, 20));
+
+ // hide columns in the box area
+ // makes absolutely no difference
+ hiddenCols.hideColumns(1, 4);
+ od.setBoxPosition(al.getHiddenSequences(), hiddenCols);
+ assertFalse(od.isPositionInBox(0, 0));
+ assertTrue(od.isPositionInBox(10, 9));
+ assertFalse(od.isPositionInBox(0, 9));
+ assertFalse(od.isPositionInBox(9, 0));
+ assertFalse(od.isPositionInBox(75, 20));
+
+ // hide sequences in box area
+ // makes absolutely no difference
+ hideSequences(1, 3);
+ od.setBoxPosition(al.getHiddenSequences(), hiddenCols);
+ assertFalse(od.isPositionInBox(0, 0));
+ assertTrue(od.isPositionInBox(10, 9));
+ assertFalse(od.isPositionInBox(0, 9));
+ assertFalse(od.isPositionInBox(9, 0));
+ assertFalse(od.isPositionInBox(75, 20));
+ }
+
+ /**
+ * Test the dragging functionality
+ */
+ @Test(groups = { "Functional" })
+ public void testDragging()
+ {
+ od.updateViewportFromMouse(0, 0, al.getHiddenSequences(), hiddenCols);
+ od.setDragPoint(4, 16, al.getHiddenSequences(),
+ hiddenCols);
+ od.adjustViewportFromMouse(20, 22,
+ al.getHiddenSequences(), hiddenCols);
+
+ // updates require an OverviewPanel to exist which it doesn't here
+ // so call setBoxPosition() as it would be called by the AlignmentPanel
+ // normally
+ od.setBoxPosition(al.getHiddenSequences(), hiddenCols);
+
+ // corner moves 16 (20-4) right and 6 (22-16) up
+ assertEquals(od.getBoxX(), 16);
+ assertEquals(od.getBoxY(), 6);
+
+ // hide columns - makes no difference
+ hiddenCols.hideColumns(1, 4);
+ od.updateViewportFromMouse(0, 0, al.getHiddenSequences(), hiddenCols);
+ od.setDragPoint(4, 16, al.getHiddenSequences(), hiddenCols);
+ od.adjustViewportFromMouse(20, 22, al.getHiddenSequences(), hiddenCols);
+ od.setBoxPosition(al.getHiddenSequences(), hiddenCols);
+
+ // corner moves 16 (20-4) right and 6 (22-16) up
+ assertEquals(od.getBoxX(), 16);
+ assertEquals(od.getBoxY(), 6);
+
+ // hide sequences in box area
+ // makes absolutely no difference
+ hideSequences(1, 3);
+ od.updateViewportFromMouse(0, 0, al.getHiddenSequences(), hiddenCols);
+ od.setDragPoint(4, 16, al.getHiddenSequences(), hiddenCols);
+ od.adjustViewportFromMouse(20, 22, al.getHiddenSequences(), hiddenCols);
+ od.setBoxPosition(al.getHiddenSequences(), hiddenCols);
+
+ // corner moves 16 (20-4) right and 6 (22-16) up
+ assertEquals(od.getBoxX(), 16);
+ assertEquals(od.getBoxY(), 6);
+ }
+
/*
* Move viewport horizontally: startRes + previous width gives new horizontal extent. Vertical extent stays the same.
*/
private void testBoxIsAtClickPoint(int xpos, int ypos)
{
mouseClick(od, xpos, ypos);
- assertEquals(od.getBoxX(), xpos);
- assertEquals(od.getBoxY(), ypos);
+ assertEquals(od.getBoxX() + od.getBoxWidth() / 2, xpos);
+ assertEquals(od.getBoxY() + od.getBoxHeight() / 2, ypos);
assertEquals(od.getBoxWidth(), boxWidth);
assertEquals(od.getBoxHeight(), boxHeight);
package jalview.viewmodel;
import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
import jalview.analysis.AlignmentGenerator;
import jalview.datamodel.Alignment;
ViewportRanges vpranges;
- Hashtable<SequenceI, SequenceCollectionI> hiddenRepSequences = new Hashtable<SequenceI, SequenceCollectionI>();
+ Hashtable<SequenceI, SequenceCollectionI> hiddenRepSequences = new Hashtable<>();
HiddenColumns hiddenCols = new HiddenColumns();
assertEquals(od.getBoxX(), 0);
assertEquals(od.getBoxWidth(), boxWidth);
assertEquals(od.getBoxHeight(), boxHeight);
- assertEquals(vpranges.getStartSeq(),
+ assertEquals(vpranges.getStartSeq() + vpranges.getViewportHeight() / 2,
Math.round((float) 10 * alheight / od.getSequencesHeight()));
assertEquals(vpranges.getStartRes(), 0);
assertEquals(od.getBoxY(), 0);
assertEquals(od.getBoxWidth(), boxWidth);
assertEquals(od.getBoxHeight(), boxHeight);
- assertEquals(vpranges.getStartRes(),
- Math.round((float) 6 * alwidth / od.getWidth()));
+ assertEquals(vpranges.getStartRes(), 0);
assertEquals(vpranges.getStartSeq(), 0);
// overly large boxX value reset to width-boxWidth
- mouseClick(od, 100, 6);
+ mouseClick(od, 101, 6);
assertEquals(od.getBoxX(), od.getWidth() - od.getBoxWidth());
- assertEquals(od.getBoxY(), 6);
+ assertEquals(od.getBoxY(), 1);
assertEquals(od.getBoxWidth(), boxWidth);
assertEquals(od.getBoxHeight(), boxHeight);
assertEquals(vpranges.getStartRes(),
// overly large boxY value reset to sequenceHeight - boxHeight
mouseClick(od, 10, 520);
- assertEquals(od.getBoxX(), 10);
+ assertEquals(od.getBoxX(), 0);
assertEquals(od.getBoxY(), od.getSequencesHeight() - od.getBoxHeight());
assertEquals(od.getBoxWidth(), boxWidth);
assertEquals(od.getBoxHeight(), boxHeight);
- assertEquals(vpranges.getStartRes(),
+ assertEquals(0,
Math.round((float) od.getBoxX() * alwidth / od.getWidth()));
// here (float) od.getBoxY() * alheight / od.getSequencesHeight() = 507.5
/ od.getSequencesHeight()));
// move viewport so startRes non-zero and then mouseclick
- moveViewportH(50);
+ moveViewportH(20);
// click at viewport position
int oldboxx = od.getBoxX();
int oldboxy = od.getBoxY();
- mouseClick(od, od.getBoxX() + 5, od.getBoxY() + 2);
- assertEquals(od.getBoxX(), oldboxx + 5);
+ mouseClick(od, od.getBoxX() + od.getBoxWidth() / 2 + 6,
+ od.getBoxY() + od.getBoxHeight() / 2 + 3);
+ assertEquals(od.getBoxX(), oldboxx + 6);
assertEquals(od.getBoxWidth(), boxWidth);
assertEquals(od.getBoxHeight(), boxHeight);
assertEquals(vpranges.getStartRes(),
Math.round((float) od.getBoxX() * alwidth / od.getWidth()));
- assertEquals(od.getBoxY(), oldboxy + 2);
+ assertEquals(od.getBoxY(), oldboxy + 3);
assertEquals(
vpranges.getStartSeq(),
Math.round((float) od.getBoxY() * alheight
assertEquals(vpranges.getStartRes(), 0);
// click to right of hidden columns, box moves to click point
- testBoxIsAtClickPoint(40, 0);
+ mouseClick(od, 60 + boxWidth / 2, boxHeight / 2);
+ assertEquals(od.getBoxX(), 60);
+ assertEquals(od.getBoxY(), 0);
+ assertEquals(od.getBoxWidth(), boxWidth);
+ assertEquals(od.getBoxHeight(), boxHeight);
assertEquals(vpranges.getStartSeq(), 0);
assertEquals(vpranges.getStartRes(),
- Math.round((float) 40 * alwidth / od.getWidth())
+ Math.round(
+ (float) 60 * alwidth / od.getWidth())
- (lastHiddenCol + 1));
// click to right of hidden columns such that box runs over right hand side
// box position is adjusted away from the edge
// overly large boxX value reset to width-boxWidth
xpos = 100;
- mouseClick(od, xpos, 5);
+ mouseClick(od, xpos + boxWidth / 2, 5 + boxHeight / 2);
assertEquals(od.getBoxX(), od.getWidth() - od.getBoxWidth());
assertEquals(od.getBoxY(), 5);
assertEquals(od.getBoxWidth(), boxWidth);
// move box so that it overlaps with hidden cols on one side
// box width changes, boxX and scrollCol as for unhidden case
- int xpos = 55 - boxWidth; // 55 is position in overview approx halfway
+ int xpos = 54 - boxWidth / 2; // 54 is position in overview approx halfway
// between cols 60 and 70
- mouseClick(od, xpos, 0);
- assertEquals(od.getBoxX(), xpos);
+ mouseClick(od, xpos, boxHeight / 2);
+ assertEquals(od.getBoxX(), xpos - boxWidth / 2);
assertEquals(od.getBoxY(), 0);
assertEquals(
od.getBoxWidth(),
* od.getWidth() / alwidth));
assertEquals(od.getBoxHeight(), boxHeight);
assertEquals(vpranges.getStartRes(),
- Math.round(xpos * alwidth / od.getWidth()));
+ Math.round((xpos - boxWidth / 2) * alwidth / od.getWidth())
+ + 1); // +1 for rounding
assertEquals(vpranges.getStartSeq(), 0);
// move box so that it completely covers hidden cols
// box width changes, boxX and scrollCol as for hidden case
- xpos = 33;
+ xpos = 24 + boxWidth / 2;
mouseClick(od, xpos, 0);
- assertEquals(od.getBoxX(), xpos);
+ assertEquals(od.getBoxX(), 24);
assertEquals(od.getBoxY(), 0);
assertEquals(
od.getBoxWidth(),
* od.getWidth() / alwidth));
assertEquals(od.getBoxHeight(), boxHeight);
assertEquals(vpranges.getStartRes(),
- Math.round((float) xpos * alwidth / od.getWidth()));
- assertEquals(vpranges.getStartSeq(), 0);
-
- // move box so boxX is in hidden cols, box overhangs at right
- // boxX and scrollCol at left of hidden area, box width extends across
- // hidden region
- xpos = 50;
- mouseClick(od, xpos, 0);
- assertEquals(od.getBoxX(),
- Math.round((float) (firstHidden - 1) * od.getWidth() / alwidth));
- assertEquals(od.getBoxY(), 0);
- assertEquals(
- od.getBoxWidth(),
- boxWidth
- + Math.round((float) (lastHidden - firstHidden + 1)
- * od.getWidth() / alwidth));
- assertEquals(od.getBoxHeight(), boxHeight);
- assertEquals(vpranges.getStartRes(), firstHidden - 1);
+ Math.round((float) 24 * alwidth / od.getWidth()));
assertEquals(vpranges.getStartSeq(), 0);
// move box so boxX is to right of hidden cols, but does not go beyond full
// width of alignment
// box width, boxX and scrollCol all as for non-hidden case
- xpos = 75;
- testBoxIsAtClickPoint(xpos, 0);
+ xpos = Math.round((float) 75 * od.getWidth() / alwidth) + boxWidth / 2;
+ mouseClick(od, xpos, boxHeight / 2);
+ assertEquals(od.getBoxX(), xpos - boxWidth / 2);
+ assertEquals(od.getBoxY(), 0);
+ assertEquals(od.getBoxWidth(), boxWidth);
+ assertEquals(od.getBoxHeight(), boxHeight);
assertEquals(vpranges.getStartSeq(), 0);
assertEquals(vpranges.getStartRes(),
- Math.round(xpos * alwidth / od.getWidth())
- - (lastHidden - firstHidden + 1));
+ 75 - (lastHidden - firstHidden + 1));
// move box so it goes beyond full width of alignment
// boxX, scrollCol adjusted back, box width normal
xpos = 3000;
mouseClick(od, xpos, 5);
assertEquals(od.getBoxX(), od.getWidth() - od.getBoxWidth());
- assertEquals(od.getBoxY(), 5);
+ assertEquals(od.getBoxY(), 0);
assertEquals(od.getBoxWidth(), boxWidth);
assertEquals(od.getBoxHeight(), boxHeight);
assertEquals(
// click to left of hidden cols, without overlapping
// boxX, scrollCol and width as normal
- int xpos = 5;
- testBoxIsAtClickPoint(xpos, 0);
- assertEquals(vpranges.getStartSeq(), 0);
- assertEquals(vpranges.getStartRes(),
- Math.round((float) xpos * alwidth / od.getWidth()));
+ int xpos = 30;
+ int ypos = 6;
+ testBoxIsAtClickPoint(xpos, ypos);
+ assertEquals(vpranges.getStartSeq(), Math
+ .round((float) (ypos - boxHeight / 2) * alheight
+ / od.getHeight()));
+ assertEquals(vpranges.getStartRes(), Math.round(
+ (float) (xpos - boxWidth / 2) * alwidth / od.getWidth()));
// click to left of hidden cols, with overlap
// boxX and scrollCol adjusted for hidden cols, width normal
xpos = Math.round((float) 145 * od.getWidth() / alwidth) - boxWidth;
- mouseClick(od, xpos, 0);
+ mouseClick(od, xpos + boxWidth / 2, boxHeight / 2);
assertEquals(od.getBoxX(),
- Math.round((float) (firstHidden - 1) * od.getWidth() / alwidth)
+ Math.round((float) (firstHidden - 1)
+ * od.getWidth() / alwidth)
- boxWidth + 1);
assertEquals(od.getBoxY(), 0);
assertEquals(od.getBoxWidth(), boxWidth);
assertEquals(od.getBoxHeight(), boxHeight);
assertEquals(vpranges.getStartRes(),
- Math.round((float) od.getBoxX() * alwidth / od.getWidth()));
+ Math.round((float) (od.getBoxX()) * alwidth
+ / od.getWidth()));
assertEquals(vpranges.getStartSeq(), 0);
// click in hidden cols
assertEquals(od.getBoxHeight(), boxHeight);
// click below hidden rows
- mouseClick(od, 0, 150);
+ mouseClick(od, 0, 150 + boxHeight/2);
assertEquals(od.getBoxX(), 0);
assertEquals(od.getBoxY(), 150);
assertEquals(od.getBoxWidth(), boxWidth);
assertEquals(od.getBoxHeight(), boxHeight);
// click above hidden rows, so that box overlaps
- int ypos = 35; // column value in residues
+ int rowpos = 35; // row value in residues
+ int centrepos = 43; // centre row
mouseClick(od, 0,
- Math.round((float) ypos * od.getSequencesHeight() / alheight));
- assertEquals(od.getBoxX(), 0);
- assertEquals(od.getBoxY(),
- Math.round((float) ypos * od.getSequencesHeight() / alheight));
- assertEquals(od.getBoxWidth(), boxWidth);
- assertEquals(
- od.getBoxHeight(),
- boxHeight
- + Math.round((float) (lastHiddenRow - firstHiddenRow + 1)
- * od.getSequencesHeight() / alheight));
-
- // click so that box straddles hidden rows
- ypos = 44; // column value in residues
- mouseClick(od, 0,
- Math.round((float) ypos * od.getSequencesHeight() / alheight));
+ Math.round((float) centrepos * od.getSequencesHeight()
+ / alheight));
assertEquals(od.getBoxX(), 0);
assertEquals(od.getBoxY(),
- Math.round((float) ypos * od.getSequencesHeight() / alheight));
+ Math.round(
+ (float) rowpos * od.getSequencesHeight() / alheight));
assertEquals(od.getBoxWidth(), boxWidth);
assertEquals(
od.getBoxHeight(),
assertEquals(od.getBoxWidth(), boxWidth);
assertEquals(od.getBoxHeight(), boxHeight);
- // click above hidden rows
- int ypos = 40; // row 40
+ // click above hidden rows, no overlap
+ int ypos = 40 + viewHeight / 2; // top is row 40
mouseClick(od, 0,
Math.round((float) ypos * od.getSequencesHeight() / alheight));
assertEquals(od.getBoxX(), 0);
assertEquals(od.getBoxY(),
- Math.round((float) ypos * od.getSequencesHeight() / alheight));
+ Math.round((float) 40 * od.getSequencesHeight() / alheight));
assertEquals(od.getBoxWidth(), boxWidth);
assertEquals(od.getBoxHeight(), boxHeight);
// click above hidden rows so box overlaps
// boxY moved upwards, boxHeight remains same
- ypos = 497; // row 497
+ ypos = 497 + viewHeight / 2; // row 497
mouseClick(od, 0,
Math.round((float) ypos * od.getSequencesHeight() / alheight));
assertEquals(od.getBoxX(), 0);
assertEquals(od.getBoxHeight(), boxHeight);
// click within hidden rows
- ypos = 505;
+ ypos = 505 + boxHeight / 2;
mouseClick(od, 0,
Math.round((float) ypos * od.getSequencesHeight() / alheight));
assertEquals(od.getBoxX(), 0);
assertEquals(od.getBoxHeight(), boxHeight);
}
+ /**
+ * Test the function to determine if a point is in the overview's box or not
+ */
+ @Test(groups = { "Functional" })
+ public void testPositionInBox()
+ {
+ od.updateViewportFromMouse(0, 0, al.getHiddenSequences(), hiddenCols);
+
+ assertFalse(od.isPositionInBox(0, 0));
+ assertTrue(od.isPositionInBox(10, 9));
+ assertFalse(od.isPositionInBox(0, 9));
+ assertFalse(od.isPositionInBox(9, 0));
+ assertFalse(od.isPositionInBox(75, 20));
+
+ assertTrue(od.isPositionInBox(47, 6));
+ assertFalse(od.isPositionInBox(48, 6));
+ assertTrue(od.isPositionInBox(47, 9));
+ assertFalse(od.isPositionInBox(47, 10));
+
+ // hide columns in the box area
+ // extends area where a point is considered to be in the box
+ hiddenCols.hideColumns(1, 4);
+ od.setBoxPosition(al.getHiddenSequences(), hiddenCols);
+ assertFalse(od.isPositionInBox(0, 0));
+ assertTrue(od.isPositionInBox(10, 9));
+ assertFalse(od.isPositionInBox(0, 9));
+ assertFalse(od.isPositionInBox(9, 0));
+ assertFalse(od.isPositionInBox(75, 20));
+
+ assertTrue(od.isPositionInBox(47, 6));
+ assertTrue(od.isPositionInBox(48, 6));
+ assertTrue(od.isPositionInBox(47, 9));
+ assertFalse(od.isPositionInBox(47, 10));
+
+ // hide sequences in box area
+ // extends area where a point is considered to be in the box
+ hideSequences(1, 3);
+ ColumnSelection cs = new ColumnSelection();
+ hiddenCols.revealAllHiddenColumns(cs);
+ od.setBoxPosition(al.getHiddenSequences(), hiddenCols);
+ assertFalse(od.isPositionInBox(0, 0));
+ assertTrue(od.isPositionInBox(10, 9));
+ assertFalse(od.isPositionInBox(0, 9));
+ assertFalse(od.isPositionInBox(9, 0));
+ assertFalse(od.isPositionInBox(75, 20));
+
+ assertTrue(od.isPositionInBox(47, 6));
+ assertFalse(od.isPositionInBox(48, 6));
+ assertTrue(od.isPositionInBox(47, 9));
+ assertTrue(od.isPositionInBox(47, 10));
+ }
+
+ /**
+ * Test the dragging functionality
+ */
+ @Test(groups = { "Functional" })
+ public void testDragging()
+ {
+ od.updateViewportFromMouse(0, 0, al.getHiddenSequences(), hiddenCols);
+ od.setDragPoint(4, 16, al.getHiddenSequences(), hiddenCols);
+ od.adjustViewportFromMouse(20, 22, al.getHiddenSequences(), hiddenCols);
+
+ // updates require an OverviewPanel to exist which it doesn't here
+ // so call setBoxPosition() as it would be called by the AlignmentPanel
+ // normally
+ od.setBoxPosition(al.getHiddenSequences(), hiddenCols);
+
+ // corner moves 16 (20-4) right and 6 (22-16) up
+ assertEquals(od.getBoxX(), 16);
+ assertEquals(od.getBoxY(), 6);
+
+ // hide columns - box moves drag distance + hidden cols, vertically makes no
+ // difference
+ hiddenCols.hideColumns(1, 4);
+ od.updateViewportFromMouse(0, 0, al.getHiddenSequences(), hiddenCols);
+ od.setDragPoint(4, 16, al.getHiddenSequences(), hiddenCols);
+ od.adjustViewportFromMouse(20, 22, al.getHiddenSequences(), hiddenCols);
+ od.setBoxPosition(al.getHiddenSequences(), hiddenCols);
+
+ // corner moves 16 (20-4) + hiddenCols right and 6 (22-16) down
+ assertEquals(od.getBoxX(),
+ 16 + Math.round((float) 4 * od.getWidth() / alwidth));
+ assertEquals(od.getBoxY(), 6);
+
+ // hide sequences in box area
+ // makes absolutely no difference
+ hideSequences(1, 3);
+ od.updateViewportFromMouse(0, 0, al.getHiddenSequences(), hiddenCols);
+ od.setDragPoint(4, 16, al.getHiddenSequences(), hiddenCols);
+ od.adjustViewportFromMouse(20, 22, al.getHiddenSequences(), hiddenCols);
+ od.setBoxPosition(al.getHiddenSequences(), hiddenCols);
+
+ // corner moves 16 (20-4) + hiddenCols right and 6 (22-16) + hiddenRows down
+ assertEquals(od.getBoxX(),
+ 16 + Math.round((float) 4 * od.getWidth() / alwidth));
+ assertEquals(od.getBoxY(),
+ 6 + Math.round((float) 3 * od.getHeight() / alheight));
+ }
+
/*
* Move viewport horizontally: startRes + previous width gives new horizontal extent. Vertical extent stays the same.
*/
}
/*
- * Test that the box is positioned with the top left corner at xpos, ypos
+ * Test that the box is positioned with the centre at xpos, ypos
* and with the original width and height
*/
private void testBoxIsAtClickPoint(int xpos, int ypos)
{
mouseClick(od, xpos, ypos);
- assertEquals(od.getBoxX(), xpos);
- assertEquals(od.getBoxY(), ypos);
+ assertEquals(od.getBoxX() + od.getBoxWidth() / 2, xpos);
+ assertEquals(od.getBoxY() + od.getBoxHeight() / 2, ypos);
assertEquals(od.getBoxWidth(), boxWidth);
assertEquals(od.getBoxHeight(), boxHeight);
hiddenRepSequences.put(allseqs[start], theseSeqs);
}
+
+ /**
+ * Test setting of the box position, when there are hidden rows at the start
+ * of the alignment
+ */
+ @Test(groups = { "Functional" })
+ public void testFromMouseWithHiddenRowsAtStartWrapped()
+ {
+ vpranges.setWrappedMode(true);
+ od.updateViewportFromMouse(0, 0, al.getHiddenSequences(), hiddenCols);
+ assertEquals(od.getBoxX(), 0);
+ assertEquals(od.getBoxY(), 0);
+ assertEquals(od.getBoxHeight(), boxHeight);
+ assertEquals(od.getBoxWidth(), boxWidth);
+ assertEquals(vpranges.getStartRes(), 0);
+ assertEquals(vpranges.getStartSeq(), 0);
+
+ // hide rows at start and check updated box position is correct
+ // changes boxY but not boxheight
+ int lastHiddenRow = 30;
+ hideSequences(0, lastHiddenRow);
+
+ od.setBoxPosition(al.getHiddenSequences(), hiddenCols);
+ assertEquals(od.getBoxX(), 0);
+ assertEquals(od.getBoxY(),
+ Math.round((float) (lastHiddenRow + 1)
+ * od.getSequencesHeight() / alheight));
+ assertEquals(od.getBoxWidth(), boxWidth);
+ assertEquals(od.getBoxHeight(), boxHeight);
+
+ // click in hidden rows - same result
+ mouseClick(od, 0, 0);
+ assertEquals(od.getBoxX(), 0);
+ int boxY = od.getBoxY();
+ assertEquals(
+ boxY,
+ Math.round((float) (lastHiddenRow + 1)
+ * od.getSequencesHeight() / alheight));
+ assertEquals(od.getBoxWidth(), boxWidth);
+ assertEquals(od.getBoxHeight(), boxHeight);
+
+ // click below hidden rows
+ // vertical move of overview box is suppressed in wrapped mode
+ mouseClick(od, 0, 150);
+ assertEquals(od.getBoxX(), 0);
+ assertEquals(od.getBoxY(), boxY); // unchanged
+ assertEquals(od.getBoxWidth(), boxWidth);
+ assertEquals(od.getBoxHeight(), boxHeight);
+ }
}
import java.util.Arrays;
import java.util.List;
+import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
AlignmentI smallAl = gen.generate(7, 2, 2, 5, 5);
+ @BeforeClass(alwaysRun = true)
+ public void setUp()
+ {
+ gen = new AlignmentGenerator(false);
+ al = gen.generate(20, 30, 1, 5, 5);
+ smallAl = gen.generate(7, 2, 2, 5, 5);
+ }
+
@BeforeMethod(alwaysRun = true)
public void cleanUp()
{
}
@Test(groups = { "Functional" })
- public void testSetEndRes()
- {
- ViewportRanges vr = new ViewportRanges(al);
- vr.setEndRes(-1);
- assertEquals(vr.getEndRes(), 0);
-
- vr.setEndRes(al.getWidth() - 1);
- assertEquals(vr.getEndRes(), al.getWidth() - 1);
- }
-
- @Test(groups = { "Functional" })
public void testSetEndSeq()
{
ViewportRanges vr = new ViewportRanges(al);
vr.setEndSeq(al.getHeight());
assertEquals(vr.getEndSeq(), al.getHeight() - 1);
- vr.setEndRes(al.getHeight() - 1);
+ // vr.setEndRes(al.getHeight() - 1);
+ vr.setEndSeq(al.getHeight() - 1);
assertEquals(vr.getEndSeq(), al.getHeight() - 1);
}
assertTrue(l.verify(0, emptylist));
l.reset();
- vr.setEndRes(10);
- assertTrue(l.verify(1, Arrays.asList("startres")));
- l.reset();
-
- // no event fired for same value
- vr.setEndRes(10);
- assertTrue(l.verify(0, emptylist));
- l.reset();
-
vr.setStartSeq(4);
assertTrue(l.verify(1, Arrays.asList("startseq")));
l.reset();
assertTrue(l.verify(1, Arrays.asList("startres")));
l.reset();
}
+
+ @Test(groups = { "Functional" })
+ public void testGetWrappedScrollPosition()
+ {
+ AlignmentI al2 = gen.generate(157, 15, 1, 5, 5);
+ ViewportRanges vr = new ViewportRanges(al2);
+ vr.setStartEndRes(0, 39);
+ int width = vr.getViewportWidth(); // 40
+
+ /*
+ * scroll is 0 at column 0 (only)
+ */
+ assertEquals(vr.getWrappedScrollPosition(0), 0);
+
+ /*
+ * scroll is 1 at columns 1-40
+ */
+ int i = 1;
+ int j = width;
+ for (; i <= j; i++)
+ {
+ assertEquals(1, vr.getWrappedScrollPosition(i));
+ }
+
+ /*
+ * scroll is 2 at columns 41-80, etc
+ */
+ j += width;
+ for (; i <= j; i++)
+ {
+ assertEquals(2, vr.getWrappedScrollPosition(i), "For " + i);
+ }
+ }
+
+ @Test(groups = { "Functional" })
+ public void testPageUpDownWrapped()
+ {
+ /*
+ * 15 sequences, 110 residues wide (+gaps)
+ */
+ AlignmentI al2 = gen.generate(110, 15, 1, 5, 5);
+
+ ViewportRanges vr = new ViewportRanges(al2);
+ vr.setWrappedMode(true);
+
+ // first row
+ vr.setViewportStartAndWidth(0, 40);
+ int width = vr.getViewportWidth();
+ assertEquals(width, 40);
+ assertEquals(vr.getStartRes(), 0);
+ assertEquals(vr.getEndRes(), 39);
+ assertEquals(vr.getStartSeq(), 0);
+ assertEquals(vr.getEndSeq(), 14);
+
+ // second row
+ vr.pageDown();
+ assertEquals(vr.getStartRes(), 40);
+ assertEquals(vr.getEndRes(), 79);
+ assertEquals(vr.getStartSeq(), 0);
+ assertEquals(vr.getEndSeq(), 14);
+
+ // third and last row
+ // note endRes is nominal (>width) to preserve viewport width
+ vr.pageDown();
+ assertEquals(vr.getStartRes(), 80);
+ assertEquals(vr.getEndRes(), 119);
+ assertEquals(vr.getStartSeq(), 0);
+ assertEquals(vr.getEndSeq(), 14);
+
+ // another pageDown should do nothing
+ vr.pageDown();
+ assertEquals(vr.getStartRes(), 80);
+ assertEquals(vr.getEndRes(), 119);
+ assertEquals(vr.getStartSeq(), 0);
+ assertEquals(vr.getEndSeq(), 14);
+
+ // back to second row
+ vr.pageUp();
+ assertEquals(vr.getStartRes(), 40);
+ assertEquals(vr.getEndRes(), 79);
+ assertEquals(vr.getStartSeq(), 0);
+ assertEquals(vr.getEndSeq(), 14);
+
+ // back to first row
+ vr.pageUp();
+ assertEquals(vr.getStartRes(), 0);
+ assertEquals(vr.getEndRes(), 39);
+ assertEquals(vr.getStartSeq(), 0);
+ assertEquals(vr.getEndSeq(), 14);
+
+ // another pageUp should do nothing
+ vr.pageUp();
+ assertEquals(vr.getStartRes(), 0);
+ assertEquals(vr.getEndRes(), 39);
+ assertEquals(vr.getStartSeq(), 0);
+ assertEquals(vr.getEndSeq(), 14);
+
+ /*
+ * simulate scroll right a few positions
+ */
+ vr.setStartRes(5);
+ assertEquals(vr.getStartRes(), 5);
+ assertEquals(vr.getEndRes(), 5 + width - 1); // 44
+
+ vr.pageDown(); // 5-44 shifts to 45-84
+ assertEquals(vr.getStartRes(), 45);
+ assertEquals(vr.getEndRes(), 84);
+
+ vr.pageDown(); // 45-84 shifts to 85-124
+ assertEquals(vr.getStartRes(), 85);
+ assertEquals(vr.getEndRes(), 124);
+
+ vr.pageDown(); // no change - at end already
+ assertEquals(vr.getStartRes(), 85);
+ assertEquals(vr.getEndRes(), 124);
+
+ vr.pageUp(); // back we go
+ assertEquals(vr.getStartRes(), 45);
+ assertEquals(vr.getEndRes(), 84);
+
+ vr.pageUp();
+ assertEquals(vr.getStartRes(), 5);
+ assertEquals(vr.getEndRes(), 44);
+
+ vr.pageUp(); // back to the start
+ assertEquals(vr.getStartRes(), 0);
+ assertEquals(vr.getEndRes(), 39);
+ }
+
+ @Test(groups = { "Functional" })
+ public void testSetStartEndResWrapped()
+ {
+ ViewportRanges vr = new ViewportRanges(al);
+ vr.setWrappedMode(true);
+ vr.setStartEndRes(-1, -1);
+ assertEquals(vr.getStartRes(), 0);
+ assertEquals(vr.getEndRes(), 0);
+
+ vr.setStartEndRes(5, 19);
+ assertEquals(vr.getStartRes(), 5);
+ assertEquals(vr.getEndRes(), 19);
+
+ // bounds are not constrained to alignment width
+ // when in wrapped mode
+ vr.setStartEndRes(88, 888);
+ assertEquals(vr.getStartRes(), 88);
+ assertEquals(vr.getEndRes(), 888);
+
+ ViewportRanges vrsmall = new ViewportRanges(smallAl);
+ vrsmall.setWrappedMode(true);
+ vrsmall.setStartEndRes(88, 888);
+ assertEquals(vrsmall.getStartRes(), 88);
+ assertEquals(vrsmall.getEndRes(), 888);
+
+ // make visible alignment width = 0
+ smallAl.getHiddenColumns().hideColumns(0, 6);
+ vrsmall.setStartEndRes(0, 4);
+ assertEquals(vrsmall.getStartRes(), 0);
+ assertEquals(vrsmall.getEndRes(), 4);
+ }
+
+ @Test(groups = { "Functional" })
+ public void testSetViewportStartAndWidthWrapped()
+ {
+ ViewportRanges vr = new ViewportRanges(al);
+ vr.setWrappedMode(true);
+ vr.setViewportStartAndWidth(2, 6);
+ assertEquals(vr.getViewportWidth(), 6);
+ assertEquals(vr.getStartRes(), 2);
+
+ // reset -ve values of start to 0
+ vr.setViewportStartAndWidth(-1, 7);
+ assertEquals(vr.getViewportWidth(), 7);
+ assertEquals(vr.getStartRes(), 0);
+
+ // out of bounds values are not forced to within bounds
+ vr.setViewportStartAndWidth(35, 5);
+ assertEquals(vr.getViewportWidth(), 5);
+ assertEquals(vr.getStartRes(), 35);
+
+ // small alignment doesn't get bounds reset
+ ViewportRanges vrsmall = new ViewportRanges(smallAl);
+ vrsmall.setViewportStartAndWidth(0, 63);
+ assertEquals(vrsmall.getViewportWidth(), 7);
+ assertEquals(vrsmall.getStartRes(), 0);
+ }
+
+ @Test(groups = { "Functional" })
+ public void testGetWrappedMaxScroll()
+ {
+ // generate an ungapped alignment of width 140
+ int alignmentWidth = 140;
+ AlignmentI al2 = gen.generate(alignmentWidth, 15, 1, 0, 5);
+ ViewportRanges vr = new ViewportRanges(al2);
+ vr.setStartEndRes(0, 39);
+ int width = vr.getViewportWidth(); // 40
+ int partWidth = alignmentWidth % width; // 20
+
+ /*
+ * there are 3 * 40 remainder 20 residues
+ * number of widths depends on offset (scroll right)
+ * 4 widths (maxScroll = 3) if offset by 0 or more than 19 columns
+ * 5 widths (maxScroll = 4) if 1 <= offset <= 19
+ */
+ for (int col = 0; col < alignmentWidth; col++)
+ {
+ int offset = col % width;
+ if (offset > 0 && offset < partWidth)
+ {
+ assertEquals(vr.getWrappedMaxScroll(col), 4, "col " + col);
+ }
+ else
+ {
+ assertEquals(vr.getWrappedMaxScroll(col), 3, "col " + col);
+ }
+ }
+ }
}
// mock listener for property change events
<string><![CDATA[664]]></string>
</property>
<property name="sourceName">
- <string><![CDATA[min-jabaws-client-2.1.0.jar]]></string>
+ <string><![CDATA[jabaws-min-client-2.2.0.jar]]></string>
</property>
<property name="overrideUnixPermissions">
<boolean>false</boolean>