X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fgui%2FSeqPanel.java;h=185c5c543fc023e6a01d77b59938fd144ffe80f0;hb=0b573ed90b14079f7326281f50c0c9cffdace586;hp=75bf0cce475cc334f8b6336070b0b43ccd692369;hpb=8c0019f5e35dcfdb8014f280ba1193db239c92dd;p=jalview.git diff --git a/src/jalview/gui/SeqPanel.java b/src/jalview/gui/SeqPanel.java index 75bf0cc..185c5c5 100644 --- a/src/jalview/gui/SeqPanel.java +++ b/src/jalview/gui/SeqPanel.java @@ -58,6 +58,8 @@ 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; @@ -67,8 +69,11 @@ 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; /** @@ -234,6 +239,8 @@ public class SeqPanel extends JPanel ToolTipManager.sharedInstance().registerComponent(this); ToolTipManager.sharedInstance().setInitialDelay(0); ToolTipManager.sharedInstance().setDismissDelay(10000); + + this.av = viewport; setBackground(Color.white); @@ -815,6 +822,8 @@ public class SeqPanel extends JPanel String lastMessage; + private String formattedTooltipText; + @Override public void mouseOverSequence(SequenceI sequence, int index, int pos) { @@ -860,8 +869,8 @@ public class SeqPanel extends JPanel ap.setToScrollComplementPanel(true); } - boolean noFastPaint = wasScrolled && av.getWrapAlignment(); - if (seqCanvas.highlightSearchResults(results, noFastPaint)) + boolean fastPaint = !(wasScrolled && av.getWrapAlignment()); + if (seqCanvas.highlightSearchResults(results, fastPaint)) { setStatusMessage(results); } @@ -1013,7 +1022,7 @@ public class SeqPanel extends JPanel mouseOverSequence(sequence, column, pos); } - tooltipText.setLength(6); // Cuts the buffer back to + tooltipText.setLength(6); // "" SequenceGroup[] groups = av.getAlignment().findAllGroups(sequence); if (groups != null) @@ -1085,9 +1094,9 @@ public class SeqPanel extends JPanel String textString = tooltipText.toString(); if (lastTooltip == null || !lastTooltip.equals(textString)) { - String formattedTooltipText = JvSwingUtils.wrapTooltip(true, + formattedTooltipText = JvSwingUtils.wrapTooltip(true, textString); - setToolTipText(formattedTooltipText); + setToolTipText(formattedTooltipText); lastTooltip = textString; } } @@ -1124,6 +1133,8 @@ public class SeqPanel extends JPanel private Point lastp = null; + private JToolTip tempTip = new JLabel().createToolTip(); + /* * (non-Javadoc) * @@ -1132,26 +1143,31 @@ public class SeqPanel extends JPanel @Override public Point getToolTipLocation(MouseEvent event) { + // BH 2018 + if (tooltipText == null || tooltipText.length() <= 6) { - lastp = null; return null; } - int x = event.getX(); - int w = getWidth(); - // switch sides when tooltip is too close to edge - int wdth = (w - x < 200) ? -(w / 2) : 5; - Point p = lastp; - if (!event.isShiftDown() || p == null) + if (lastp != null && event.isShiftDown()) { - p = new Point(event.getX() + wdth, event.getY() - 20); - lastp = p; + return lastp; } - /* - * TODO: try to set position so region is not obscured by tooltip - */ - return p; + + Point p = lastp; + int x = event.getX(); + int y = event.getY(); + int w = getWidth(); + + tempTip.setTipText(formattedTooltipText); + int tipWidth = (int) tempTip.getPreferredSize().getWidth(); + + // was x += (w - x < 200) ? -(w / 2) : 5; + x = (x + tipWidth < w ? x + 10 : w - tipWidth); + p = new Point(x, y + 20); // BH 2018 was - 20? + + return lastp = p; } String lastTooltip; @@ -2030,7 +2046,7 @@ public class SeqPanel extends JPanel if (mouseDragging && scrollThread == null) { - scrollThread = new ScrollThread(); + startScrolling(e.getPoint()); } } @@ -2076,17 +2092,13 @@ public class SeqPanel extends JPanel SearchResultsI highlight = new SearchResults(); highlight.addResult(sequence, features.get(0).getBegin(), features .get(0).getEnd()); - seqCanvas.highlightSearchResults(highlight, false); + seqCanvas.highlightSearchResults(highlight, true); /* - * open the Amend Features dialog; clear highlighting afterwards, - * whether changes were made or not + * open the Amend Features dialog */ - List seqs = Collections.singletonList(sequence); - seqCanvas.getFeatureRenderer().amendFeatures(seqs, features, false, - ap); - av.setSearchResults(null); // clear highlighting - seqCanvas.repaint(); // draw new/amended features + new FeatureEditor(ap, Collections.singletonList(sequence), features, + false).showDialog(); } } } @@ -2168,19 +2180,19 @@ public class SeqPanel extends JPanel } } - if (evt.isPopupTrigger()) // Mac: mousePressed - { - showPopupMenu(evt, pos); - return; - } - /* * defer right-mouse click handling to mouseReleased on Windows * (where isPopupTrigger() will answer true) * NB isRightMouseButton is also true for Cmd-click on Mac */ - if (SwingUtilities.isRightMouseButton(evt) && !Platform.isAMac()) + if (Platform.isWinRightButton(evt)) + { + return; + } + + if (evt.isPopupTrigger()) // Mac: mousePressed { + showPopupMenu(evt, pos); return; } @@ -2476,29 +2488,73 @@ public class SeqPanel extends JPanel /** * Starts a thread to scroll the alignment, towards a given mouse position - * outside the panel bounds + * outside the panel bounds, unless the alignment is in wrapped mode * * @param mousePos */ void startScrolling(Point mousePos) { - if (scrollThread == null) + /* + * set this.mouseDragging in case this was called from + * a drag in ScalePanel or AnnotationPanel + */ + mouseDragging = true; + if (!av.getWrapAlignment() && scrollThread == null) { scrollThread = new ScrollThread(); + scrollThread.setMousePosition(mousePos); + if (Platform.isJS()) + { + /* + * Javascript - run every 20ms until scrolling stopped + * or reaches the limit of scrollable alignment + */ + Timer t = new Timer(20, new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + if (scrollThread != null) + { + // if (!scrollOnce() {t.stop();}) gives compiler error :-( + scrollThread.scrollOnce(); + } + } + }); + t.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + if (scrollThread == null) + { + // SeqPanel.stopScrolling called + t.stop(); + } + } + }); + t.start(); + } + else + { + /* + * Java - run in a new thread + */ + scrollThread.start(); + } } - - mouseDragging = true; - scrollThread.setMousePosition(mousePos); } /** - * Performs scrolling of the visible alignment left, right, up or down + * Performs scrolling of the visible alignment left, right, up or down, until + * scrolling is stopped by calling stopScrolling, mouse drag is ended, or the + * limit of the alignment is reached */ class ScrollThread extends Thread { private Point mousePos; - private volatile boolean threadRunning = true; + private volatile boolean keepRunning = true; /** * Constructor @@ -2506,12 +2562,14 @@ public class SeqPanel extends JPanel public ScrollThread() { setName("SeqPanel$ScrollThread"); - start(); } /** * Sets the position of the mouse that determines the direction of the - * scroll to perform + * scroll to perform. If this is called as the mouse moves, scrolling should + * respond accordingly. For example, if the mouse is dragged right, scroll + * right should start; if the drag continues down, scroll down should also + * happen. * * @param p */ @@ -2525,7 +2583,7 @@ public class SeqPanel extends JPanel */ public void stopScrolling() { - threadRunning = false; + keepRunning = false; } /** @@ -2536,48 +2594,12 @@ public class SeqPanel extends JPanel @Override public void run() { - while (threadRunning && mouseDragging) + while (keepRunning) { if (mousePos != null) { - boolean scrolled = false; - ViewportRanges ranges = SeqPanel.this.av.getRanges(); - - /* - * scroll up or down - */ - if (mousePos.y < 0) - { - // mouse is above this panel - try scroll up - scrolled = ranges.scrollUp(true); - } - else if (mousePos.y >= getHeight()) - { - // mouse is below this panel - try scroll down - scrolled = ranges.scrollUp(false); - } - - /* - * scroll left or right - */ - if (mousePos.x < 0) - { - scrolled |= ranges.scrollRight(false); - } - else if (mousePos.x >= getWidth()) - { - scrolled |= ranges.scrollRight(true); - } - if (!scrolled) - { - /* - * we have reached the limit of the visible alignment - quit - */ - threadRunning = false; - SeqPanel.this.ap.repaint(); - } + keepRunning = scrollOnce(); } - try { Thread.sleep(20); @@ -2585,6 +2607,60 @@ public class SeqPanel extends JPanel { } } + SeqPanel.this.scrollThread = null; + } + + /** + * Scrolls + * + * Answers true if a scroll was performed, false if not - meaning either + * that the mouse position is within the panel, or the edge of the alignment + * has been reached. + */ + boolean scrollOnce() + { + /* + * quit after mouseUp ensures interrupt in JalviewJS + */ + if (!mouseDragging) + { + return false; + } + + boolean scrolled = false; + ViewportRanges ranges = SeqPanel.this.av.getRanges(); + + /* + * scroll up or down + */ + if (mousePos.y < 0) + { + // mouse is above this panel - try scroll up + scrolled = ranges.scrollUp(true); + } + else if (mousePos.y >= getHeight()) + { + // mouse is below this panel - try scroll down + scrolled = ranges.scrollUp(false); + } + + /* + * scroll left or right + */ + if (mousePos.x < 0) + { + scrolled |= ranges.scrollRight(false); + } + else if (mousePos.x >= getWidth()) + { + scrolled |= ranges.scrollRight(true); + } + return scrolled; } }