X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2Fjalview%2Fgui%2FSeqPanel.java;h=2caea17d01aabf8bb9af9bd7c6d5935f0486412e;hb=eb3e681d6e82ccdd5d312d1981dfb306e7f479f0;hp=18e9365b22044442d15f06396ec96e58ceb27a65;hpb=1f54b227847c46fefbe0bfbe923c08fb22bab52d;p=jalview.git diff --git a/src/jalview/gui/SeqPanel.java b/src/jalview/gui/SeqPanel.java index 18e9365..2caea17 100644 --- a/src/jalview/gui/SeqPanel.java +++ b/src/jalview/gui/SeqPanel.java @@ -20,8 +20,31 @@ */ package jalview.gui; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Point; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.event.MouseMotionListener; +import java.awt.event.MouseWheelEvent; +import java.awt.event.MouseWheelListener; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JToolTip; +import javax.swing.SwingUtilities; +import javax.swing.Timer; +import javax.swing.ToolTipManager; + import jalview.api.AlignViewportI; -import jalview.bin.Cache; +import jalview.bin.Console; import jalview.commands.EditCommand; import jalview.commands.EditCommand.Action; import jalview.commands.EditCommand.Edit; @@ -53,29 +76,6 @@ import jalview.viewmodel.AlignmentViewport; import jalview.viewmodel.ViewportRanges; import jalview.viewmodel.seqfeatures.FeatureRendererModel; -import java.awt.BorderLayout; -import java.awt.Color; -import java.awt.Font; -import java.awt.FontMetrics; -import java.awt.Point; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.MouseEvent; -import java.awt.event.MouseListener; -import java.awt.event.MouseMotionListener; -import java.awt.event.MouseWheelEvent; -import java.awt.event.MouseWheelListener; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JToolTip; -import javax.swing.SwingUtilities; -import javax.swing.Timer; -import javax.swing.ToolTipManager; - /** * DOCUMENT ME! * @@ -137,7 +137,7 @@ public class SeqPanel extends JPanel MousePos o = (MousePos) obj; boolean b = (column == o.column && seqIndex == o.seqIndex && annotationIndex == o.annotationIndex); - // System.out.println(obj + (b ? "= " : "!= ") + this); + // jalview.bin.Console.outPrintln(obj + (b ? "= " : "!= ") + this); return b; } @@ -212,13 +212,21 @@ public class SeqPanel extends JPanel StringBuffer keyboardNo2; - java.net.URL linkImageURL; - private final SequenceAnnotationReport seqARep; - StringBuilder tooltipText = new StringBuilder(); + /* + * the last tooltip on mousing over the alignment (or annotation in wrapped mode) + * - the tooltip is not set again if unchanged + * - this is the tooltip text _before_ formatting as html + */ + private String lastTooltip; - String tmpString; + /* + * the last tooltip on mousing over the alignment (or annotation in wrapped mode) + * - used to decide where to place the tooltip in getTooltipLocation() + * - this is the tooltip text _after_ formatting as html + */ + private String lastFormattedTooltip; EditCommand editCommand; @@ -234,13 +242,11 @@ public class SeqPanel extends JPanel */ public SeqPanel(AlignViewport viewport, AlignmentPanel alignPanel) { - linkImageURL = getClass().getResource("/images/link.gif"); - seqARep = new SequenceAnnotationReport(linkImageURL.toString()); + seqARep = new SequenceAnnotationReport(true); ToolTipManager.sharedInstance().registerComponent(this); ToolTipManager.sharedInstance().setInitialDelay(0); ToolTipManager.sharedInstance().setDismissDelay(10000); - - + this.av = viewport; setBackground(Color.white); @@ -268,6 +274,9 @@ public class SeqPanel extends JPanel /** * Computes the column and sequence row (and possibly annotation row when in * wrapped mode) for the given mouse position + *
+ * Mouse position is not set if in wrapped mode with the cursor either between + * sequences, or over the left or right vertical scale. * * @param evt * @return @@ -332,15 +341,39 @@ public class SeqPanel extends JPanel return new MousePos(col, seqIndex, annIndex); } + + /** + * @param evt + * @return absolute column in alignment nearest to the mouse pointer + */ + int findAlignmentColumn(MouseEvent evt) + { + return findNearestColumn(evt, true); + } + /** * Returns the aligned sequence position (base 0) at the mouse position, or * the closest visible one + *
+ * Returns -1 if in wrapped mode with the mouse over either left or right
+ * vertical scale.
*
* @param evt
* @return
*/
int findColumn(MouseEvent evt)
{
+ return findNearestColumn(evt, false);
+ }
+
+ /**
+ * @param nearestColumn
+ * when false returns negative values for out of bound positions - -1
+ * for scale left/right, <-1 if far to right
+ * @return nearest absolute column to mouse pointer
+ */
+ private int findNearestColumn(MouseEvent evt, boolean nearestColumn)
+ {
int res = 0;
int x = evt.getX();
@@ -364,7 +397,14 @@ public class SeqPanel extends JPanel
if (x < 0)
{
// mouse is over left scale
- return -1;
+ if (!nearestColumn)
+ {
+ return -1;
+ }
+ else
+ {
+ x = 0;
+ }
}
int cwidth = seqCanvas.getWrappedCanvasWidth(this.getWidth());
@@ -374,8 +414,15 @@ public class SeqPanel extends JPanel
}
if (x >= cwidth * charWidth)
{
- // mouse is over right scale
- return -1;
+ if (!nearestColumn)
+ {
+ // mouse is over right scale
+ return -1;
+ }
+ else
+ {
+ x = cwidth * charWidth - 1;
+ }
}
wrappedBlock = y / cHeight;
@@ -392,8 +439,14 @@ public class SeqPanel extends JPanel
* rather than right-hand gutter
*/
x = Math.min(x, seqCanvas.getX() + seqCanvas.getWidth());
+ if (nearestColumn)
+ {
+ x = Math.max(x, 0);
+ }
+
res = (x / charWidth) + startRes;
res = Math.min(res, av.getRanges().getEndRes());
+
}
if (av.hasHiddenColumns())
@@ -470,45 +523,85 @@ public class SeqPanel extends JPanel
void moveCursor(int dx, int dy)
{
- seqCanvas.cursorX += dx;
- seqCanvas.cursorY += dy;
+ moveCursor(dx, dy, false);
+ }
+ void moveCursor(int dx, int dy, boolean nextWord)
+ {
HiddenColumns hidden = av.getAlignment().getHiddenColumns();
- if (av.hasHiddenColumns() && !hidden.isVisible(seqCanvas.cursorX))
+ if (nextWord)
{
- int original = seqCanvas.cursorX - dx;
int maxWidth = av.getAlignment().getWidth();
-
- if (!hidden.isVisible(seqCanvas.cursorX))
- {
- int visx = hidden.absoluteToVisibleColumn(seqCanvas.cursorX - dx);
- int[] region = hidden.getRegionWithEdgeAtRes(visx);
-
- if (region != null) // just in case
+ int maxHeight = av.getAlignment().getHeight();
+ SequenceI seqAtRow = av.getAlignment()
+ .getSequenceAt(seqCanvas.cursorY);
+ // look for next gap or residue
+ boolean isGap = Comparison
+ .isGap(seqAtRow.getCharAt(seqCanvas.cursorX));
+ int p = seqCanvas.cursorX, lastP, r = seqCanvas.cursorY, lastR;
+ do
+ {
+ lastP = p;
+ lastR = r;
+ if (dy != 0)
{
- if (dx == 1)
+ r += dy;
+ if (r < 0)
{
- // moving right
- seqCanvas.cursorX = region[1] + 1;
+ r = 0;
}
- else if (dx == -1)
+ if (r >= maxHeight)
{
- // moving left
- seqCanvas.cursorX = region[0] - 1;
+ r = maxHeight - 1;
}
+ seqAtRow = av.getAlignment().getSequenceAt(r);
}
- seqCanvas.cursorX = (seqCanvas.cursorX < 0) ? 0 : seqCanvas.cursorX;
- }
+ p = nextVisible(hidden, maxWidth, p, dx);
+ } while ((dx != 0 ? p != lastP : r != lastR)
+ && isGap == Comparison.isGap(seqAtRow.getCharAt(p)));
+ seqCanvas.cursorX = p;
+ seqCanvas.cursorY = r;
+ }
+ else
+ {
+ int maxWidth = av.getAlignment().getWidth();
+ seqCanvas.cursorX = nextVisible(hidden, maxWidth, seqCanvas.cursorX,
+ dx);
+ seqCanvas.cursorY += dy;
+ }
+ scrollToVisible(false);
+ }
- if (seqCanvas.cursorX >= maxWidth
- || !hidden.isVisible(seqCanvas.cursorX))
+ private int nextVisible(HiddenColumns hidden, int maxWidth, int original,
+ int dx)
+ {
+ int newCursorX = original + dx;
+ if (av.hasHiddenColumns() && !hidden.isVisible(newCursorX))
+ {
+ int visx = hidden.absoluteToVisibleColumn(newCursorX - dx);
+ int[] region = hidden.getRegionWithEdgeAtRes(visx);
+
+ if (region != null) // just in case
{
- seqCanvas.cursorX = original;
+ if (dx == 1)
+ {
+ // moving right
+ newCursorX = region[1] + 1;
+ }
+ else if (dx == -1)
+ {
+ // moving left
+ newCursorX = region[0] - 1;
+ }
}
}
-
- scrollToVisible(false);
+ newCursorX = (newCursorX < 0) ? 0 : newCursorX;
+ if (newCursorX >= maxWidth || !hidden.isVisible(newCursorX))
+ {
+ newCursorX = original;
+ }
+ return newCursorX;
}
/**
@@ -566,7 +659,7 @@ public class SeqPanel extends JPanel
if (av.getAlignment().getHiddenColumns().isVisible(seqCanvas.cursorX))
{
setStatusMessage(av.getAlignment().getSequenceAt(seqCanvas.cursorY),
- seqCanvas.cursorX, seqCanvas.cursorY);
+ seqCanvas.cursorX, seqCanvas.cursorY);
}
if (repaintNeeded)
@@ -575,7 +668,6 @@ public class SeqPanel extends JPanel
}
}
-
void setSelectionAreaAtCursor(boolean topLeft)
{
SequenceI sequence = av.getAlignment().getSequenceAt(seqCanvas.cursorY);
@@ -822,8 +914,6 @@ public class SeqPanel extends JPanel
String lastMessage;
- private String formattedTooltipText;
-
@Override
public void mouseOverSequence(SequenceI sequence, int index, int pos)
{
@@ -831,7 +921,7 @@ public class SeqPanel extends JPanel
if (lastMessage == null || !lastMessage.equals(tmp))
{
- // System.err.println("mouseOver Sequence: "+tmp);
+ // jalview.bin.Console.errPrintln("mouseOver Sequence: "+tmp);
ssm.mouseOverSequence(sequence, index, pos, av);
}
lastMessage = tmp;
@@ -904,19 +994,19 @@ public class SeqPanel extends JPanel
AlignFrame af = Desktop.getAlignFrameFor(complement);
FeatureRendererModel fr2 = af.getFeatureRenderer();
- int j = results.getSize();
+ List