JAL-2388 Added checkbox to toggle hidden columns menu & updated text
[jalview.git] / src / jalview / gui / OverviewPanel.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3  * Copyright (C) $$Year-Rel$$ The Jalview Authors
4  * 
5  * This file is part of Jalview.
6  * 
7  * Jalview is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License 
9  * as published by the Free Software Foundation, either version 3
10  * of the License, or (at your option) any later version.
11  *  
12  * Jalview is distributed in the hope that it will be useful, but 
13  * WITHOUT ANY WARRANTY; without even the implied warranty 
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
15  * PURPOSE.  See the GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
19  * The Jalview Authors are detailed in the 'AUTHORS' file.
20  */
21 package jalview.gui;
22
23 import jalview.util.MessageManager;
24 import jalview.util.Platform;
25 import jalview.viewmodel.OverviewDimensions;
26 import jalview.viewmodel.OverviewDimensionsHideHidden;
27 import jalview.viewmodel.OverviewDimensionsShowHidden;
28
29 import java.awt.BorderLayout;
30 import java.awt.Dimension;
31 import java.awt.event.ActionEvent;
32 import java.awt.event.ActionListener;
33 import java.awt.event.ComponentAdapter;
34 import java.awt.event.ComponentEvent;
35 import java.awt.event.MouseAdapter;
36 import java.awt.event.MouseEvent;
37 import java.awt.event.MouseMotionAdapter;
38
39 import javax.swing.JCheckBoxMenuItem;
40 import javax.swing.JPanel;
41 import javax.swing.JPopupMenu;
42 import javax.swing.SwingUtilities;
43
44 /**
45  * Panel displaying an overview of the full alignment, with an interactive box
46  * representing the viewport onto the alignment.
47  * 
48  * @author $author$
49  * @version $Revision$
50  */
51 public class OverviewPanel extends JPanel implements Runnable
52 {
53   private OverviewDimensions od;
54
55   private OverviewCanvas oviewCanvas;
56
57   private AlignViewport av;
58
59   private AlignmentPanel ap;
60
61   private JCheckBoxMenuItem displayToggle;
62
63   private boolean showHidden = true;
64
65   /**
66    * Creates a new OverviewPanel object.
67    * 
68    * @param alPanel
69    *          The alignment panel which is shown in the overview panel
70    */
71   public OverviewPanel(AlignmentPanel alPanel)
72   {
73     this.av = alPanel.av;
74     this.ap = alPanel;
75
76     od = new OverviewDimensionsShowHidden(av.getRanges(),
77             (av.isShowAnnotation() && av
78                     .getAlignmentConservationAnnotation() != null));
79
80     oviewCanvas = new OverviewCanvas(od, av);
81     setLayout(new BorderLayout());
82     add(oviewCanvas, BorderLayout.CENTER);
83
84     addComponentListener(new ComponentAdapter()
85     {
86       @Override
87       public void componentResized(ComponentEvent evt)
88       {
89         if ((getWidth() != od.getWidth())
90                 || (getHeight() != (od.getHeight())))
91         {
92           updateOverviewImage();
93         }
94       }
95     });
96
97     addMouseMotionListener(new MouseMotionAdapter()
98     {
99       @Override
100       public void mouseDragged(MouseEvent evt)
101       {
102         if (!SwingUtilities.isRightMouseButton(evt)
103                 && !av.getWrapAlignment())
104         {
105           od.updateViewportFromMouse(evt.getX(), evt.getY(), av
106                   .getAlignment().getHiddenSequences(), av.getAlignment()
107                   .getHiddenColumns());
108           ap.setScrollValues(od.getScrollCol(), od.getScrollRow());
109         }
110       }
111     });
112
113     addMouseListener(new MouseAdapter()
114     {
115       @Override
116       public void mousePressed(MouseEvent evt)
117       {
118         if (SwingUtilities.isRightMouseButton(evt))
119         {
120           if (!Platform.isAMac())
121           {
122             showPopupMenu(evt);
123           }
124         }
125         else if (!av.getWrapAlignment())
126         {
127           od.updateViewportFromMouse(evt.getX(), evt.getY(), av
128                   .getAlignment().getHiddenSequences(), av.getAlignment()
129                   .getHiddenColumns());
130           ap.setScrollValues(od.getScrollCol(), od.getScrollRow());
131         }
132       }
133
134       @Override
135       public void mouseClicked(MouseEvent evt)
136       {
137         if (SwingUtilities.isRightMouseButton(evt))
138         {
139           showPopupMenu(evt);
140         }
141       }
142     });
143
144
145     updateOverviewImage();
146   }
147
148   /*
149    * Displays the popup menu and acts on user input
150    */
151   private void showPopupMenu(MouseEvent e)
152   {
153     JPopupMenu popup = new JPopupMenu();
154     ActionListener menuListener = new ActionListener()
155     {
156       @Override
157       public void actionPerformed(ActionEvent event)
158       {
159         // switch on/off the hidden columns view
160         toggleHiddenColumns();
161         displayToggle.setSelected(showHidden);
162       }
163     };
164     displayToggle = new JCheckBoxMenuItem(
165             MessageManager.getString("label.togglehidden"));
166     displayToggle.setEnabled(true);
167     displayToggle.setSelected(showHidden);
168     popup.add(displayToggle);
169     displayToggle.addActionListener(menuListener);
170     popup.show(this, e.getX(), e.getY());
171   }
172
173   /*
174    * Toggle overview display between showing hidden columns and hiding hidden columns
175    */
176   private void toggleHiddenColumns()
177   {
178     if (showHidden)
179     {
180       showHidden = false;
181       od = new OverviewDimensionsHideHidden(av.getRanges(),
182               (av.isShowAnnotation() && av
183                       .getAlignmentConservationAnnotation() != null));
184     }
185     else
186     {
187       showHidden = true;
188       od = new OverviewDimensionsShowHidden(av.getRanges(),
189               (av.isShowAnnotation() && av
190                       .getAlignmentConservationAnnotation() != null));
191     }
192     oviewCanvas.resetOviewDims(od);
193     updateOverviewImage();
194   }
195
196   /**
197    * Updates the overview image when the related alignment panel is updated
198    */
199   public void updateOverviewImage()
200   {
201     if ((getWidth() > 0) && (getHeight() > 0))
202     {
203       od.setWidth(getWidth());
204       od.setHeight(getHeight());
205     }
206     
207     setPreferredSize(new Dimension(od.getWidth(), od.getHeight()));
208
209     if (oviewCanvas.restartDraw())
210     {
211       return;
212     }
213
214     Thread thread = new Thread(this);
215     thread.start();
216     repaint();
217
218   }
219
220   @Override
221   public void run()
222   {
223     oviewCanvas.draw(av.isShowSequenceFeatures(),
224             (av.isShowAnnotation() && av
225                     .getAlignmentConservationAnnotation() != null), ap
226                     .getSeqPanel().seqCanvas.getFeatureRenderer());
227     setBoxPosition();
228   }
229
230   /**
231    * Update the overview panel box when the associated alignment panel is
232    * changed
233    * 
234    */
235   public void setBoxPosition()
236   {
237     od.setBoxPosition(av.getAlignment().getHiddenSequences(), av
238             .getAlignment().getHiddenColumns());
239     repaint();
240   }
241 }