X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2Fjalview%2Fgui%2FSeqPanel.java;h=5eb97e0c0291736916a0a94f27ef919d435fa531;hb=3516fc4a1037ffc86d51f900850ed7a04a0174cb;hp=5ae4a0e0ce02eebd5bf8d8118349f9ca9bc0bd5c;hpb=4313fc0bf442a0668d74224f78080b1182acb20d;p=jalview.git diff --git a/src/jalview/gui/SeqPanel.java b/src/jalview/gui/SeqPanel.java index 5ae4a0e..5eb97e0 100644 --- a/src/jalview/gui/SeqPanel.java +++ b/src/jalview/gui/SeqPanel.java @@ -22,6 +22,7 @@ package jalview.gui; import jalview.api.AlignViewportI; import jalview.bin.Cache; +import jalview.bin.Jalview; import jalview.commands.EditCommand; import jalview.commands.EditCommand.Action; import jalview.commands.EditCommand.Edit; @@ -48,12 +49,15 @@ import jalview.util.MappingUtils; import jalview.util.MessageManager; import jalview.util.Platform; import jalview.viewmodel.AlignmentViewport; +import jalview.viewmodel.ViewportRanges; 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; @@ -66,6 +70,7 @@ import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JToolTip; import javax.swing.SwingUtilities; +import javax.swing.Timer; import javax.swing.ToolTipManager; /** @@ -632,13 +637,14 @@ public class SeqPanel extends JPanel return; } - if (!editingSeqs) + if (editingSeqs) + { + endEditing(); + } + else { doMouseReleasedDefineMode(evt, didDrag); - return; } - - endEditing(); } /** @@ -745,8 +751,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); } @@ -1019,7 +1025,7 @@ public class SeqPanel extends JPanel text.append(" (").append(Integer.toString(residuePos)).append(")"); } - ap.alignFrame.statusBar.setText(text.toString()); + ap.alignFrame.setStatus(text.toString()); } /** @@ -1183,9 +1189,9 @@ public class SeqPanel extends JPanel } mouseDragging = true; - if ((scrollThread != null) && (scrollThread.isRunning())) + if (scrollThread != null) { - scrollThread.setEvent(evt); + scrollThread.setMousePosition(evt.getPoint()); } } @@ -1246,7 +1252,7 @@ public class SeqPanel extends JPanel } message.append(Math.abs(startres - lastres) + " gaps."); - ap.alignFrame.statusBar.setText(message.toString()); + ap.alignFrame.setStatus(message.toString()); // Are we editing within a selection group? if (groupEditing || (sg != null @@ -1597,10 +1603,10 @@ public class SeqPanel extends JPanel } /** - * DOCUMENT ME! + * On reentering the panel, stops any scrolling that was started on dragging + * out of the panel * * @param e - * DOCUMENT ME! */ @Override public void mouseEntered(MouseEvent e) @@ -1609,31 +1615,21 @@ public class SeqPanel extends JPanel { oldSeq = 0; } - - if ((scrollThread != null) && (scrollThread.isRunning())) - { - scrollThread.stopScrolling(); - scrollThread = null; - } + stopScrolling(); } /** - * DOCUMENT ME! + * On leaving the panel, if the mouse is being dragged, starts a thread to + * scroll it until the mouse is released (in unwrapped mode only) * * @param e - * DOCUMENT ME! */ @Override public void mouseExited(MouseEvent e) { - if (av.getWrapAlignment()) - { - return; - } - - if (mouseDragging && scrollThread == null) + if (mouseDragging) { - scrollThread = new ScrollThread(); + startScrolling(e.getPoint()); } } @@ -1673,22 +1669,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); - new FeatureEditor(ap).amendFeatures(seqs, features, new Runnable() - { - @Override - public void run() - { - av.setSearchResults(null); // clear highlighting - seqCanvas.repaint(); // draw new/amended features - } - }); + new FeatureEditor(ap, Collections.singletonList(sequence), features, + false).showDialog(); } } } @@ -1946,10 +1933,7 @@ public class SeqPanel extends JPanel return; } - if (res >= av.getAlignment().getWidth()) - { - res = av.getAlignment().getWidth() - 1; - } + res = Math.min(res, av.getAlignment().getWidth()-1); if (stretchGroup.getEndRes() == res) { @@ -2035,92 +2019,153 @@ public class SeqPanel extends JPanel mouseDragging = true; - if ((scrollThread != null) && (scrollThread.isRunning())) + if (scrollThread != null) { - scrollThread.setEvent(evt); + scrollThread.setMousePosition(evt.getPoint()); } } - void scrollCanvas(MouseEvent evt) + /** + * Stops the scroll thread if it is running + */ + void stopScrolling() { - if (evt == null) + if (scrollThread != null) { - if ((scrollThread != null) && (scrollThread.isRunning())) - { - scrollThread.stopScrolling(); - scrollThread = null; - } - mouseDragging = false; + scrollThread.stopScrolling(); + scrollThread = null; } - else + mouseDragging = false; + } + + /** + * Starts a thread to scroll the alignment, towards a given mouse position + * outside the panel bounds, unless the alignment is in wrapped mode + * + * @param mousePos + */ + void startScrolling(Point mousePos) + { + /* + * set this.mouseDragging in case this was called from + * a drag in ScalePanel or AnnotationPanel + */ + mouseDragging = true; + if (!av.getWrapAlignment() && scrollThread == null) { - if (scrollThread == null) + scrollThread = new ScrollThread(); + scrollThread.setMousePosition(mousePos); + if (!Jalview.isJS()) { - scrollThread = new ScrollThread(); + /* + * Java - run in a new thread + */ + scrollThread.start(); + } + else + { + /* + * Javascript - run every 20ms until scrolling stopped + * or reaches the limit of scrollable alignment + */ + // java.util.Timer version: + // Timer t = new Timer("ScrollThreadTimer", true); + // TimerTask task = new TimerTask() + // { + // @Override + // public void run() + // { + // if (!scrollThread.scrollOnce()) + // { + // cancel(); + // } + // } + // }; + // t.schedule(task, 20, 20); + 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) + { + // finished and nulled itself + t.stop(); + } + } + }); + t.start(); } - - mouseDragging = true; - scrollThread.setEvent(evt); } - } - // this class allows scrolling off the bottom of the visible alignment + /** + * 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 { - MouseEvent evt; + private Point mousePos; - private volatile boolean threadRunning = true; + private volatile boolean keepRunning = true; + /** + * Constructor + */ public ScrollThread() { - start(); + setName("SeqPanel$ScrollThread"); } - public void setEvent(MouseEvent e) + /** + * Sets the position of the mouse that determines the direction of the + * 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 + */ + public void setMousePosition(Point p) { - evt = e; + mousePos = p; } + /** + * Sets a flag that will cause the thread to exit + */ public void stopScrolling() { - threadRunning = false; - } - - public boolean isRunning() - { - return threadRunning; + keepRunning = false; } + /** + * Scrolls the alignment left or right, and/or up or down, depending on the + * last notified mouse position, until the limit of the alignment is + * reached, or a flag is set to stop the scroll + */ @Override public void run() { - while (threadRunning) + while (keepRunning) { - if (evt != null) + if (mousePos != null) { - if (mouseDragging && (evt.getY() < 0) - && (av.getRanges().getStartSeq() > 0)) - { - av.getRanges().scrollUp(true); - } - - if (mouseDragging && (evt.getY() >= getHeight()) && (av - .getAlignment().getHeight() > av.getRanges().getEndSeq())) - { - av.getRanges().scrollUp(false); - } - - if (mouseDragging && (evt.getX() < 0)) - { - av.getRanges().scrollRight(false); - } - else if (mouseDragging && (evt.getX() >= getWidth())) - { - av.getRanges().scrollRight(true); - } + keepRunning = scrollOnce(); } - try { Thread.sleep(20); @@ -2128,6 +2173,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; } }