--- /dev/null
+/*
+ VARNA is a tool for the automated drawing, visualization and annotation of the secondary structure of RNA, designed as a companion software for web servers and databases.
+ Copyright (C) 2008 Kevin Darty, Alain Denise and Yann Ponty.
+ electronic mail : Yann.Ponty@lri.fr
+ paper mail : LRI, bat 490 Université Paris-Sud 91405 Orsay Cedex France
+
+ This file is part of VARNA version 3.1.
+ VARNA version 3.1 is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+
+ VARNA version 3.1 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with VARNA version 3.1.
+ If not, see http://www.gnu.org/licenses.
+ */
+package fr.orsay.lri.varna.controlers;
+
+import java.awt.Component;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.MouseMotionListener;
+import java.awt.geom.Point2D;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Vector;
+
+import javax.swing.JMenu;
+import javax.swing.JMenuItem;
+import javax.swing.event.PopupMenuEvent;
+import javax.swing.event.PopupMenuListener;
+
+import fr.orsay.lri.varna.VARNAPanel;
+import fr.orsay.lri.varna.exceptions.ExceptionNAViewAlgorithm;
+import fr.orsay.lri.varna.models.annotations.TextAnnotation;
+import fr.orsay.lri.varna.models.rna.ModeleBase;
+import fr.orsay.lri.varna.models.rna.ModeleBaseNucleotide;
+import fr.orsay.lri.varna.models.rna.ModeleBasesComparison;
+import fr.orsay.lri.varna.models.rna.ModeleBP;
+import fr.orsay.lri.varna.models.rna.RNA;
+
+
+/**
+ * Controller of the mouse click
+ *
+ * @author darty
+ *
+ */
+public class ControleurClicMovement implements MouseListener,
+ MouseMotionListener, PopupMenuListener {
+ private VARNAPanel _vp;
+ private boolean _presenceMenuSelection;
+ private JMenu _submenuSelection;
+ public Point _spawnPoint;
+ public Point _initialPoint;
+ public Point _prevPoint;
+ public Point _currentPoint;
+
+ public static final double MIN_SELECTION_DISTANCE = 40.0;
+ public static final double HYSTERESIS_DISTANCE = 10.0;
+
+ private ModeleBase _selectedBase = null;
+
+
+ public enum MouseStates {
+ NONE,
+ MOVE_ELEMENT,
+ MOVE_OR_SELECT_ELEMENT,
+ SELECT_ELEMENT,
+ SELECT_REGION_OR_UNSELECT,
+ SELECT_REGION,
+ CREATE_BP,
+ POPUP_MENU,
+ MOVE_ANNOTATION,
+ };
+ private MouseStates _currentState = MouseStates.NONE;
+
+
+
+ public ControleurClicMovement(VARNAPanel _vuep) {
+ _vp = _vuep;
+ _vp.getPopup().addPopupMenuListener(this);
+ _presenceMenuSelection = false;
+ }
+
+ public void mouseClicked(MouseEvent arg0) {
+ }
+
+ public void mouseEntered(MouseEvent arg0) {
+ }
+
+ public void mouseExited(MouseEvent arg0) {
+ }
+
+ public void mousePressed(MouseEvent arg0)
+ {
+ _vp.requestFocus();
+ boolean button1 = (arg0.getButton() == MouseEvent.BUTTON1);
+ boolean button2 = (arg0.getButton() == MouseEvent.BUTTON2);
+ boolean button3 = (arg0.getButton() == MouseEvent.BUTTON3);
+ boolean shift = arg0.isShiftDown();
+ boolean ctrl = arg0.isControlDown();
+ boolean alt = arg0.isAltDown();
+ _vp.removeSelectedAnnotation();
+ if (button1 && !ctrl && !alt && !shift)
+ {
+ if (_vp.isModifiable())
+ {
+ _currentState = MouseStates.MOVE_OR_SELECT_ELEMENT;
+ if (_vp.getRealCoords() != null
+ && _vp.getRealCoords().length != 0
+ && _vp.getRNA().get_listeBases().size() != 0)
+ {
+ _selectedBase = _vp.getNearestBase(arg0.getX(),arg0.getY(),false,false);
+ TextAnnotation selectedAnnotation = _vp.getNearestAnnotation(arg0.getX(), arg0.getY());
+ _initialPoint = new Point(arg0.getX(),arg0.getY());
+ _currentPoint = new Point(_initialPoint);
+ _prevPoint = new Point(_initialPoint);
+ if (_selectedBase != null)
+ {
+ if (_vp.getRNA().get_drawMode() == RNA.DRAW_MODE_RADIATE)
+ {
+ _vp.highlightSelectedBase(_selectedBase);
+ } else {
+ if (!_vp.getSelectionIndices().contains(_selectedBase.getIndex()))
+ {
+ _vp.highlightSelectedBase(_selectedBase);
+ }
+ else
+ {
+ // Otherwise, keep current selection as it is and move it
+ }
+ }
+ }
+ else
+ {
+ if (selectedAnnotation != null)
+ {
+ _currentState = MouseStates.MOVE_ANNOTATION;
+ _vp.set_selectedAnnotation(selectedAnnotation);
+ _vp.highlightSelectedAnnotation();
+ }
+ else
+ {
+ _vp.clearSelection();
+ _selectedBase = null;
+ _currentState = MouseStates.SELECT_REGION_OR_UNSELECT;
+ _initialPoint = new Point(arg0.getX(),arg0.getY());
+ _prevPoint = new Point(_initialPoint);
+ _currentPoint = new Point(_initialPoint);
+ }
+ }
+ }
+ }
+ }
+ else if (button1 && ctrl && !alt && !shift)
+ {
+ _selectedBase = _vp.getNearestBase(arg0.getX(),arg0.getY(),false,false);
+ if (_selectedBase != null)
+ {
+ _vp.clearSelection();
+ _currentState = MouseStates.CREATE_BP;
+ _vp.highlightSelectedBase(_selectedBase);
+ _vp.setOriginLink(_vp.logicToPanel(_selectedBase.getCoords()));
+ _initialPoint = new Point(arg0.getX(),arg0.getY());
+ _currentPoint = new Point(_initialPoint);
+ }
+ }
+ else if (button1 && !ctrl && !alt && shift)
+ {
+ _currentState = MouseStates.SELECT_ELEMENT;
+ _initialPoint = new Point(arg0.getX(),arg0.getY());
+ _currentPoint = new Point(_initialPoint);
+ }
+ else if (button3)
+ {
+ _currentState = MouseStates.POPUP_MENU;
+ if (_presenceMenuSelection) {
+ _vp.getPopupMenu().removeSelectionMenu();
+ }
+ if ((_vp.getRealCoords() != null) && _vp.getRNA().get_listeBases().size() != 0) {
+ updateNearestBase(arg0);
+ // on insere dans le menu les nouvelles options
+ addMenu(arg0);
+ if (_vp.get_selectedAnnotation() != null)
+ _vp.highlightSelectedAnnotation();
+ }
+ // affichage du popup menu
+ if (_vp.getRNA().get_drawMode() == RNA.DRAW_MODE_LINEAR) {
+ _vp.getPopup().get_rotation().setEnabled(false);
+ } else {
+ _vp.getPopup().get_rotation().setEnabled(true);
+ }
+ _vp.getPopup().updateDialog();
+ _vp.getPopup().show(_vp, arg0.getX(), arg0.getY());
+ }
+ _vp.repaint();
+ }
+
+ public void mouseDragged(MouseEvent me) {
+ if ((_currentState == MouseStates.MOVE_OR_SELECT_ELEMENT)||(_currentState == MouseStates.MOVE_ELEMENT))
+ {
+ _vp.lockScrolling();
+
+ _currentState = MouseStates.MOVE_ELEMENT;
+ // si on deplace la souris et qu'une base est selectionnée
+ if (_selectedBase != null) {
+ if (_vp.getRNA().get_drawMode() == RNA.DRAW_MODE_RADIATE) {
+ _vp.highlightSelectedStem(_selectedBase);
+ // dans le cas radiale on deplace une helice
+ _vp.getVARNAUI().UIMoveHelixAtom(_selectedBase.getIndex(), _vp.panelToLogicPoint(new Point2D.Double(me.getX(), me.getY())));
+ } else {
+ // dans le cas circulaire naview ou line on deplace une base
+ _currentPoint = new Point(me.getX(), me.getY());
+ moveSelection(_prevPoint,_currentPoint);
+ _prevPoint = new Point(_currentPoint);
+ }
+ _vp.repaint();
+ }
+ }
+ else if (_currentState == MouseStates.MOVE_ANNOTATION)
+ {
+ if (_vp.get_selectedAnnotation()!=null)
+ {
+ Point2D.Double p = _vp.panelToLogicPoint(new Point2D.Double(me.getX(), me.getY()));
+ _vp.get_selectedAnnotation().setAncrage(p.x,p.y);
+ _vp.repaint();
+ }
+ }
+ else if ((_currentState == MouseStates.SELECT_ELEMENT)||(_currentState == MouseStates.SELECT_REGION_OR_UNSELECT))
+ {
+ if (_initialPoint.distance(me.getX(),me.getY())>HYSTERESIS_DISTANCE)
+ _currentState = MouseStates.SELECT_REGION;
+ }
+ else if (_currentState == MouseStates.SELECT_REGION)
+ {
+ _currentPoint = new Point(me.getX(),me.getY());
+ int minx = Math.min(_currentPoint.x, _initialPoint.x);
+ int miny = Math.min(_currentPoint.y, _initialPoint.y);
+ int maxx = Math.max(_currentPoint.x, _initialPoint.x);
+ int maxy = Math.max(_currentPoint.y, _initialPoint.y);
+ _vp.setSelectionRectangle(new Rectangle(minx,miny,maxx-minx,maxy-miny));
+ }
+ else if (_currentState == MouseStates.CREATE_BP)
+ {
+ if (_initialPoint.distance(me.getX(),me.getY())>HYSTERESIS_DISTANCE)
+ {
+ ModeleBase newSelectedBase = _vp.getNearestBase(me.getX(),me.getY(),false,false);
+ _vp.setHoverBase(newSelectedBase);
+ if (newSelectedBase==null)
+ {
+ _vp.setDestinationLink(new Point2D.Double(me.getX(),me.getY()));
+ _vp.clearSelection();
+ _vp.addToSelection(_selectedBase.getIndex());
+ }
+ else
+ {
+ ModeleBase mborig = _selectedBase;
+ _vp.clearSelection();
+ _vp.addToSelection(newSelectedBase.getIndex());
+ _vp.addToSelection(mborig.getIndex());
+ _vp.setDestinationLink(_vp.logicToPanel(newSelectedBase.getCoords()));
+ }
+ _vp.repaint();
+ }
+
+ }
+ }
+
+
+ public void mouseReleased(MouseEvent arg0) {
+ if (arg0.getButton() == MouseEvent.BUTTON1)
+ {
+ _vp.fireBaseClicked(_selectedBase, arg0);
+ //System.out.println(""+_currentState);
+
+ if (_currentState == MouseStates.MOVE_ELEMENT)
+ {
+ _vp.clearSelection();
+ _selectedBase = null;
+ _vp.unlockScrolling();
+ _vp.removeSelectedAnnotation();
+ }
+ else if (_currentState == MouseStates.SELECT_REGION_OR_UNSELECT)
+ {
+ _vp.clearSelection();
+ _selectedBase = null;
+ _vp.removeSelectedAnnotation();
+ }
+ else if (_currentState == MouseStates.SELECT_ELEMENT)
+ {
+ if (_vp.getRealCoords() != null
+ && _vp.getRealCoords().length != 0
+ && _vp.getRNA().get_listeBases().size() != 0)
+ {
+ int selectedIndex = _vp.getNearestBaseIndex(arg0.getX(),arg0.getY(),false,false);
+ if (selectedIndex !=-1)
+ {
+ _vp.toggleSelection(selectedIndex);
+ }
+ }
+ _selectedBase = null;
+ }
+ else if (_currentState == MouseStates.SELECT_REGION)
+ {
+ _vp.removeSelectionRectangle();
+ }
+ else if (_currentState == MouseStates.CREATE_BP)
+ {
+ if (_initialPoint.distance(arg0.getX(),arg0.getY())>HYSTERESIS_DISTANCE)
+ {
+ int selectedIndex = _vp.getNearestBaseIndex(arg0.getX(),arg0.getY(),false,false);
+ if (selectedIndex>=0)
+ {
+ ModeleBase mb = _vp.getNearestBase(arg0.getX(),arg0.getY(),false,false);
+ ModeleBase mborig = _selectedBase;
+ ModeleBP msbp = new ModeleBP(mb,mborig);
+ if (mb!=mborig)
+ {
+ _vp.getVARNAUI().UIAddBP(mb.getIndex(),mborig.getIndex(),msbp);
+ }
+ }
+ }
+ _vp.removeLink();
+ _vp.clearSelection();
+ _vp.repaint();
+ }
+ else
+ {
+ _vp.clearSelection();
+ }
+
+ }
+ _currentState = MouseStates.NONE;
+ _vp.repaint();
+ }
+
+
+ private void addMenu(MouseEvent arg0) {
+ // creation du menu
+ _submenuSelection = new JMenu("Selection");
+ addCurrent();
+ // ajout des option sur base
+ addMenuBase();
+ // ajout des option sur paire de base
+ if (_vp.getRNA().get_listeBases().get(_vp.getNearestBase())
+ .getElementStructure() != -1) {
+ addMenuBasePair();
+ }
+
+ // detection renflement
+ detectBulge();
+ // detection 3'
+ detect3Prime();
+ // detection 5'
+ detect5Prime();
+ // detection boucle
+ detectLoop();
+ // detection d'helice
+ detectHelix();
+ // detection tige
+ detectStem();
+ // Ajout de toutes bases
+ addAllBase();
+ // detection d'annotation
+ detectAnnotation(arg0);
+
+ _vp.getPopup().addSelectionMenu(_submenuSelection);
+ _presenceMenuSelection = true;
+ }
+
+ private void detectAnnotation(MouseEvent arg0) {
+ if (_vp.getListeAnnotations().size() != 0) {
+ double dist = Double.MAX_VALUE;
+ double d2;
+ Point2D.Double position;
+ for (TextAnnotation textAnnot : _vp.getListeAnnotations()) {
+ // calcul de la distance
+ position = textAnnot.getCenterPosition();
+ position = _vp.transformCoord(position);
+ d2 = Math.sqrt(Math.pow((position.x - arg0.getX()), 2)
+ + Math.pow((position.y - arg0.getY()), 2));
+ // si la valeur est inferieur au minimum actuel
+ if (dist > d2) {
+ _vp.set_selectedAnnotation(textAnnot);
+ dist = d2;
+ }
+ }
+ _submenuSelection.addSeparator();
+ _vp.getPopup().addAnnotationMenu(_submenuSelection,true);
+ }
+ }
+
+ private void detectBulge() {
+ int indiceB = _vp.getNearestBase();
+ ArrayList<Integer> indices = _vp.getRNA().findBulge(indiceB);
+ if ((indices.size() > 0)
+ && (_vp.getRNA().getHelixCountOnLoop(_vp.getNearestBase()) == 2)) {
+ JMenu submenuBulge = new JMenu("Bulge");
+ submenuBulge.addChangeListener(new ControleurSelectionHighlight(
+ new Vector<Integer>(indices), _vp, submenuBulge));
+ submenuBulge.setActionCommand("bulge");
+ if (!_vp.isModifiable())
+ submenuBulge.setEnabled(false);
+ _vp.getPopupMenu().addColorOptions(submenuBulge);
+ _submenuSelection.add(submenuBulge);
+ }
+ }
+
+ private void detectHelix() {
+ int indiceH = _vp.getNearestBase();
+ ArrayList<Integer> indices = _vp.getRNA().findHelix(indiceH);
+ if (indices.size() != 0) {
+ // ajout menu helice
+ JMenu submenuHelix = new JMenu("Helix");
+ submenuHelix.addChangeListener(new ControleurSelectionHighlight(
+ new Vector<Integer>(indices), _vp, submenuHelix));
+ submenuHelix.setActionCommand("helix");
+ if (!_vp.isModifiable())
+ submenuHelix.setEnabled(false);
+ _vp.getPopupMenu().addColorOptions(submenuHelix);
+ submenuHelix.addSeparator();
+ _vp.getPopupMenu().addAnnotationMenu(submenuHelix);
+ _submenuSelection.add(submenuHelix);
+ }
+ }
+
+ private void detectStem() {
+ int indiceS = _vp.getNearestBase();
+ ArrayList<Integer> indices = _vp.getRNA().findStem(indiceS);
+ if (indices.size() > 0) {
+ JMenu submenuStem = new JMenu("Stem");
+ submenuStem.addChangeListener(new ControleurSelectionHighlight(
+ new Vector<Integer>(indices), _vp, submenuStem));
+ submenuStem.setActionCommand("stem");
+ if (!_vp.isModifiable())
+ submenuStem.setEnabled(false);
+ _vp.getPopupMenu().addColorOptions(submenuStem);
+ _submenuSelection.add(submenuStem);
+ }
+ }
+
+ private void detect3Prime() {
+ // detection 3'
+ int indice3 = _vp.getNearestBase();
+ ArrayList<Integer> indices = _vp.getRNA().find3Prime(indice3);
+ if (indices.size() != 0) {
+ JMenu submenu3Prime = new JMenu("3'");
+ submenu3Prime.addChangeListener(new ControleurSelectionHighlight(
+ new Vector<Integer>(indices), _vp, submenu3Prime));
+ submenu3Prime.setActionCommand("3'");
+ if (!_vp.isModifiable())
+ submenu3Prime.setEnabled(false);
+ _vp.getPopupMenu().addColorOptions(submenu3Prime);
+ _submenuSelection.add(submenu3Prime);
+ }
+ }
+
+ private void detect5Prime() {
+ int indice5 = _vp.getNearestBase();
+ ArrayList<Integer> indices = _vp.getRNA().find5Prime(indice5);
+ if (indices.size() != 0) {
+ JMenu submenu5Prime = new JMenu("5'");
+ submenu5Prime.addChangeListener(new ControleurSelectionHighlight(
+ new Vector<Integer>(indices), _vp, submenu5Prime));
+ submenu5Prime.setActionCommand("5'");
+ if (!_vp.isModifiable())
+ submenu5Prime.setEnabled(false);
+ _vp.getPopupMenu().addColorOptions(submenu5Prime);
+ _submenuSelection.add(submenu5Prime);
+ }
+ }
+
+ private void detectLoop() {
+ int indexL = _vp.getNearestBase();
+ if (_vp.getRNA().get_listeBases().get(indexL).getElementStructure() == -1) {
+ ArrayList<Integer> listLoop = _vp.getRNA().findLoop(indexL);
+ JMenu submenuLoop = new JMenu("Loop");
+ submenuLoop.addChangeListener(new ControleurSelectionHighlight(
+ listLoop, _vp, submenuLoop));
+ submenuLoop.setActionCommand("loop1");
+ if (!_vp.isModifiable())
+ submenuLoop.setEnabled(false);
+ _vp.getPopupMenu().addColorOptions(submenuLoop);
+ submenuLoop.addSeparator();
+ _vp.getPopupMenu().addAnnotationMenu(submenuLoop);
+ _submenuSelection.add(submenuLoop);
+ } else {
+ ArrayList<Integer> listLoop1 = _vp.getRNA().findLoopForward(indexL);
+ if (listLoop1.size() > 0) {
+ JMenu submenuLoop1 = new JMenu("Forward loop");
+ submenuLoop1
+ .addChangeListener(new ControleurSelectionHighlight(
+ listLoop1, _vp, submenuLoop1));
+ submenuLoop1.setActionCommand("loop1");
+ if (!_vp.isModifiable())
+ submenuLoop1.setEnabled(false);
+ _vp.getPopupMenu().addColorOptions(submenuLoop1);
+ submenuLoop1.addSeparator();
+ _vp.getPopupMenu().addAnnotationMenu(submenuLoop1);
+ _submenuSelection.add(submenuLoop1);
+ }
+ ArrayList<Integer> listLoop2 = _vp.getRNA()
+ .findLoopBackward(indexL);
+ if (listLoop2.size() > 0) {
+ JMenu submenuLoop2 = new JMenu("Backward loop");
+ submenuLoop2
+ .addChangeListener(new ControleurSelectionHighlight(
+ listLoop2, _vp, submenuLoop2));
+ submenuLoop2.setActionCommand("loop2");
+ if (!_vp.isModifiable())
+ submenuLoop2.setEnabled(false);
+ _vp.getPopupMenu().addColorOptions(submenuLoop2);
+ submenuLoop2.addSeparator();
+ _vp.getPopupMenu().addAnnotationMenu(submenuLoop2);
+ _submenuSelection.add(submenuLoop2);
+ }
+ }
+ }
+
+ private void addCurrent() {
+ Collection<? extends ModeleBase> mbs = _vp.getSelection().getBases();
+ if (mbs.size()>0)
+ {
+ JMenu submenuAll = new JMenu("Current");
+ submenuAll.addChangeListener(new ControleurSelectionHighlight(
+ mbs, _vp, submenuAll));
+ submenuAll.setActionCommand("current");
+ if (!_vp.isModifiable())
+ submenuAll.setEnabled(false);
+ _vp.getPopupMenu().addColorOptions(submenuAll);
+ _submenuSelection.add(submenuAll);
+ }
+ }
+
+
+ private void addMenuBase() {
+ JMenu submenuBase = new JMenu();
+ ModeleBase mb = _vp.getRNA().get_listeBases().get(_vp.getNearestBase());
+ if (mb instanceof ModeleBasesComparison) {
+ submenuBase.setText("Base #" + (mb.getBaseNumber()) + ":"
+ + ((ModeleBasesComparison) mb).getBases());
+ } else {
+ submenuBase.setText("Base #" + (mb.getBaseNumber()) + ":"
+ + ((ModeleBaseNucleotide) mb).getBase());
+ }
+ submenuBase.addChangeListener(new ControleurSelectionHighlight(mb
+ .getIndex(), _vp, submenuBase));
+ submenuBase.setActionCommand("base");
+ // option disponible seulement en mode modifiable
+ if (!_vp.isModifiable())
+ submenuBase.setEnabled(false);
+
+ JMenuItem baseChar = new JMenuItem("Edit base");
+ baseChar.setActionCommand("baseChar");
+ baseChar.addActionListener(_vp.getPopupMenu().get_controleurMenu());
+ submenuBase.add(baseChar);
+ _vp.getPopupMenu().addColorOptions(submenuBase);
+ submenuBase.addSeparator();
+ _vp.getPopupMenu().addAnnotationMenu(submenuBase);
+ _submenuSelection.add(submenuBase);
+ }
+
+ private void addAllBase() {
+ ArrayList<Integer> indices = _vp.getRNA().findAll();
+ JMenu submenuAll = new JMenu("All");
+ submenuAll.addChangeListener(new ControleurSelectionHighlight(
+ new Vector<Integer>(indices), _vp, submenuAll));
+ submenuAll.setActionCommand("all");
+ if (!_vp.isModifiable())
+ submenuAll.setEnabled(false);
+ _vp.getPopupMenu().addColorOptions(submenuAll);
+ _submenuSelection.add(submenuAll);
+ }
+
+ private void addMenuBasePair() {
+ int indiceBP = _vp.getNearestBase();
+ ArrayList<Integer> indices = _vp.getRNA().findPair(indiceBP);
+ ModeleBase base = _vp.getRNA()
+ .get_listeBases().get(_vp.getNearestBase());
+ if (base.getElementStructure() != -1) {
+ JMenu submenuBasePair = new JMenu();
+ ModeleBase partner = _vp
+ .getRNA().get_listeBases().get(
+ base.getElementStructure());
+ submenuBasePair
+ .addChangeListener(new ControleurSelectionHighlight(
+ indices, _vp, submenuBasePair));
+ submenuBasePair.setText("Base pair #("
+ + (Math.min(base.getBaseNumber(), partner
+ .getBaseNumber()))
+ + ","
+ + (Math.max(base.getBaseNumber(), partner
+ .getBaseNumber())) + ")");
+ submenuBasePair.setActionCommand("bp");
+ // option disponible seulement en mode modifiable
+ if (!_vp.isModifiable())
+ submenuBasePair.setEnabled(false);
+
+ JMenuItem basepair = new JMenuItem("Edit BP");
+ basepair.setActionCommand("basepair");
+ basepair.addActionListener(_vp.getPopupMenu()
+ .get_controleurMenu());
+
+ _vp.getPopupMenu().addColorOptions(submenuBasePair);
+ Component[] comps = submenuBasePair.getMenuComponents();
+ int offset = -1;
+ for (int i = 0; i < comps.length; i++) {
+ Component c = comps[i];
+ if (c instanceof JMenuItem) {
+ JMenuItem jmi = (JMenuItem) c;
+ if (jmi.getActionCommand().contains(",BPColor")) {
+ offset = i;
+ }
+ }
+ }
+ if (offset != -1) {
+ submenuBasePair.insert(basepair, offset);
+ } else {
+ submenuBasePair.add(basepair);
+ }
+ _submenuSelection.add(submenuBasePair);
+ }
+ }
+
+ private void updateNearestBase(MouseEvent arg0) {
+ int i = _vp.getNearestBaseIndex(arg0.getX(),arg0.getY(),true,false);
+ if (i!=-1)
+ _vp.setNearestBase(i);
+ }
+
+
+
+
+ public void mouseMoved(MouseEvent arg0) {
+ _selectedBase = _vp.getNearestBase(arg0.getX(),arg0.getY());
+ TextAnnotation selectedAnnotation = _vp.getNearestAnnotation(arg0.getX(),arg0.getY());
+ _vp.setHoverBase(_selectedBase);
+ if (_selectedBase != null)
+ {
+ }
+ else if (selectedAnnotation!=null)
+ {
+ _vp.set_selectedAnnotation(selectedAnnotation);
+ _vp.highlightSelectedAnnotation();
+ _vp.repaint();
+ }
+ _vp.setLastSelectedPosition(new Point2D.Double(arg0.getX(),arg0.getY()));
+ }
+
+
+
+ private void moveSelection(Point prev, Point cur)
+ {
+ Point2D.Double p1 = _vp.panelToLogicPoint(new Point2D.Double(prev.x,prev.y));
+ Point2D.Double p2 = _vp.panelToLogicPoint(new Point2D.Double(cur.x,cur.y));
+ double dx = (p2.x - p1.x);
+ double dy = (p2.y - p1.y);
+
+ if (_vp.isModifiable())
+ {
+ double ndx = dx;
+ double ndy = dy;
+ if (_vp.getRNA().get_drawMode() == RNA.DRAW_MODE_LINEAR)
+ {
+ ndy=0.0;
+ }
+ _vp.getVARNAUI().UIShiftBaseCoord(_vp.getSelectionIndices(), ndx, ndy);
+ _vp.fireLayoutChanged();
+
+ }
+ }
+
+
+ public void popupMenuCanceled(PopupMenuEvent arg0) {
+ }
+
+ public void popupMenuWillBecomeInvisible(PopupMenuEvent arg0) {
+ _vp.resetAnnotationHighlight();
+ _selectedBase = null;
+ }
+
+ public void popupMenuWillBecomeVisible(PopupMenuEvent arg0) {
+ }
+}
\ No newline at end of file