updated to jalview 2.1 and begun ArchiveClient/VamsasClient/VamsasStore updates.
[jalview.git] / src / jalview / appletgui / ScalePanel.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer
3  * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
18  */
19
20 package jalview.appletgui;
21
22 import java.awt.*;
23 import java.awt.event.*;
24
25 import jalview.datamodel.*;
26
27 public class ScalePanel
28     extends Panel implements MouseMotionListener, MouseListener
29 {
30
31   protected int offy = 4;
32   public int width;
33
34   protected AlignViewport av;
35   AlignmentPanel ap;
36
37   boolean stretchingGroup = false;
38   int min; //used by mouseDragged to see if user
39   int max; //used by mouseDragged to see if user
40   boolean mouseDragging = false;
41   int [] reveal;
42
43   public ScalePanel(AlignViewport av, AlignmentPanel ap)
44   {
45     setLayout(null);
46     this.av = av;
47     this.ap = ap;
48
49     addMouseListener(this);
50     addMouseMotionListener(this);
51
52   }
53
54   public void mousePressed(MouseEvent evt)
55   {
56     int x = (evt.getX() / av.getCharWidth()) + av.getStartRes();
57     final int res;
58
59     if (av.hasHiddenColumns)
60       res = av.getColumnSelection().adjustForHiddenColumns(x);
61     else
62       res = x;
63
64     min = res;
65     max = res;
66     if ((evt.getModifiers() & InputEvent.BUTTON3_MASK)
67         == InputEvent.BUTTON3_MASK)
68     {
69       PopupMenu pop = new PopupMenu();
70       if (reveal != null)
71       {
72         MenuItem item = new MenuItem("Reveal");
73         item.addActionListener(new ActionListener()
74         {
75           public void actionPerformed(ActionEvent e)
76           {
77             av.showColumn(reveal[0]);
78             reveal = null;
79             ap.repaint();
80             if (ap.overviewPanel != null)
81               ap.overviewPanel.updateOverviewImage();
82           }
83         });
84         pop.add(item);
85
86         if (av.getColumnSelection().getHiddenColumns().size() > 1)
87         {
88           item = new MenuItem("Reveal All");
89           item.addActionListener(new ActionListener()
90           {
91             public void actionPerformed(ActionEvent e)
92             {
93               av.showAllHiddenColumns();
94               reveal = null;
95               ap.repaint();
96               if (ap.overviewPanel != null)
97                 ap.overviewPanel.updateOverviewImage();
98             }
99           });
100           pop.add(item);
101         }
102         this.add(pop);
103         pop.show(this, evt.getX(), evt.getY());
104       }
105       else if (av.getColumnSelection().contains(res))
106       {
107         MenuItem item = new MenuItem("Hide Columns");
108         item.addActionListener(new ActionListener()
109         {
110           public void actionPerformed(ActionEvent e)
111           {
112             av.hideColumns(res, res);
113             if (av.getSelectionGroup() != null
114                 &&
115                 av.getSelectionGroup().getSize(false) == av.alignment.getHeight())
116               av.setSelectionGroup(null);
117
118             ap.repaint();
119             if (ap.overviewPanel != null)
120               ap.overviewPanel.updateOverviewImage();
121           }
122         });
123         pop.add(item);
124         this.add(pop);
125         pop.show(this, evt.getX(), evt.getY());
126       }
127     }
128     else // LEFT MOUSE TO SELECT
129     {
130       if (!evt.isControlDown() && !evt.isShiftDown())
131       {
132         av.getColumnSelection().clear();
133       }
134
135       av.getColumnSelection().addElement(res);
136       SequenceGroup sg = new SequenceGroup();
137       for (int i = 0; i < av.alignment.getSequences().size(); i++)
138       {
139         sg.addSequence(av.alignment.getSequenceAt(i), false);
140       }
141
142       sg.setStartRes(res);
143       sg.setEndRes(res);
144       av.setSelectionGroup(sg);
145
146       if(evt.isShiftDown())
147       {
148         int min = Math.min(av.getColumnSelection().getMin(), res);
149         int max = Math.max(av.getColumnSelection().getMax(), res);
150         for (int i = min; i<max; i++)
151         {
152             av.getColumnSelection().addElement(i);
153         }
154         sg.setStartRes(min);
155         sg.setEndRes(max);
156       }
157     }
158
159     ap.repaint();
160   }
161
162   public void mouseReleased(MouseEvent evt)
163   {
164     mouseDragging = false;
165
166     int res = (evt.getX() / av.getCharWidth()) + av.getStartRes();
167
168     if(res> av.alignment.getWidth())
169     {
170       res = av.alignment.getWidth()-1;
171     }
172
173     if(av.hasHiddenColumns)
174       res = av.getColumnSelection().adjustForHiddenColumns(res);
175
176     if (!stretchingGroup)
177     {
178         ap.repaint();
179
180         return;
181     }
182
183     SequenceGroup sg = av.getSelectionGroup();
184
185     if (res > sg.getStartRes())
186     {
187         sg.setEndRes(res);
188     }
189     else if (res < sg.getStartRes())
190     {
191         sg.setStartRes(res);
192     }
193
194     stretchingGroup = false;
195     ap.repaint();
196   }
197
198   public void mouseDragged(MouseEvent evt)
199   {
200     mouseDragging = true;
201
202     int res = (evt.getX() / av.getCharWidth()) + av.getStartRes();
203     if (res < 0)
204       res = 0;
205
206     if (av.hasHiddenColumns)
207       res = av.getColumnSelection().adjustForHiddenColumns(res);
208
209     if (res > av.alignment.getWidth())
210     {
211       res = av.alignment.getWidth() - 1;
212     }
213
214     if (res < min)
215     {
216       min = res;
217     }
218
219     if (res > max)
220     {
221       max = res;
222     }
223
224     SequenceGroup sg = av.getSelectionGroup();
225
226     if (sg != null)
227     {
228       stretchingGroup = true;
229
230       if (!av.getColumnSelection().contains(res))
231       {
232         av.getColumnSelection().addElement(res);
233       }
234
235       if (res > sg.getStartRes())
236       {
237         sg.setEndRes(res);
238       }
239       if (res < sg.getStartRes())
240       {
241         sg.setStartRes(res);
242       }
243
244       for (int i = min; i <= max; i++)
245       {
246         if ( (i < sg.getStartRes()) || (i > sg.getEndRes()))
247         {
248           av.getColumnSelection().removeElement(i);
249         }
250         else
251         {
252           av.getColumnSelection().addElement(i);
253         }
254       }
255
256       ap.repaint();
257     }
258   }
259
260
261   public void mouseEntered(MouseEvent evt)
262   {
263     if (mouseDragging)
264       ap.seqPanel.scrollCanvas(null);
265   }
266
267   public void mouseExited(MouseEvent evt)
268   {
269     if (mouseDragging)
270       ap.seqPanel.scrollCanvas(evt);
271   }
272
273   public void mouseClicked(MouseEvent evt)
274   {
275
276   }
277
278   public void mouseMoved(MouseEvent evt)
279   {
280     if (!av.hasHiddenColumns)
281       return;
282
283     int res = (evt.getX() / av.getCharWidth()) + av.getStartRes();
284
285     res = av.getColumnSelection().adjustForHiddenColumns(res);
286
287     reveal = null;
288     for (int i = 0; i < av.getColumnSelection().getHiddenColumns().size(); i++)
289     {
290       int[] region = (int[]) av.getColumnSelection().getHiddenColumns().
291           elementAt(i);
292       if (res + 1 == region[0] || res - 1 == region[1])
293       {
294         reveal = region;
295         break;
296       }
297     }
298
299     repaint();
300   }
301
302   public void update(Graphics g)
303   {
304     paint(g);
305   }
306
307   public void paint(Graphics g)
308   {
309     drawScale(g, av.getStartRes(), av.getEndRes(), getSize().width,
310               getSize().height);
311   }
312
313 // scalewidth will normally be screenwidth,
314   public void drawScale(Graphics gg, int startx, int endx, int width,
315                         int height)
316   {
317     gg.setFont(av.getFont());
318
319
320     //Fill in the background
321     gg.setColor(Color.white);
322     gg.fillRect(0, 0, width, height);
323     gg.setColor(Color.black);
324
325     //Fill the selected columns
326     ColumnSelection cs = av.getColumnSelection();
327     gg.setColor(new Color(220, 0, 0));
328
329     for (int i = 0; i < cs.size(); i++)
330     {
331         int sel = cs.columnAt(i);
332         if(av.hasHiddenColumns)
333           sel = av.getColumnSelection().findColumnPosition(sel);
334
335
336         if ((sel >= startx) && (sel <= endx))
337         {
338             gg.fillRect((sel - startx) * av.charWidth, 0, av.charWidth,
339                 getSize().height);
340         }
341     }
342
343     // Draw the scale numbers
344     gg.setColor(Color.black);
345
346     int scalestartx = (startx / 10) * 10;
347
348     FontMetrics fm = gg.getFontMetrics(av.getFont());
349     int y = av.charHeight - fm.getDescent();
350
351     if ((scalestartx % 10) == 0)
352     {
353         scalestartx += 5;
354     }
355
356     String string;
357     int maxX=0;
358
359     for (int i = scalestartx; i < endx; i += 5)
360     {
361         if ((i % 10) == 0)
362         {
363             string = String.valueOf(av.getColumnSelection().adjustForHiddenColumns(i));
364             if ( (i - startx - 1) * av.charWidth > maxX)
365             {
366               gg.drawString(string,
367                             (i - startx - 1) * av.charWidth, y);
368               maxX = (i - startx + 1) * av.charWidth + fm.stringWidth(string);
369             }
370
371             gg.drawLine( (int) ( ( (i - startx - 1) * av.charWidth) +
372                                 (av.charWidth / 2)), y + 2,
373                         (int) ( ( (i - startx - 1) * av.charWidth) +
374                                (av.charWidth / 2)),
375                         y + (fm.getDescent() * 2));
376
377         }
378         else
379         {
380             gg.drawLine((int) (((i - startx - 1) * av.charWidth) +
381                 (av.charWidth / 2)), y + fm.getDescent(),
382                 (int) (((i - startx - 1) * av.charWidth) +
383                 (av.charWidth / 2)), y + (fm.getDescent() * 2));
384         }
385     }
386
387     if (av.hasHiddenColumns)
388     {
389       gg.setColor(Color.blue);
390       int res;
391       if(av.getShowHiddenMarkers())
392       {
393         for (int i = 0; i < av.getColumnSelection().getHiddenColumns().size();
394              i++)
395         {
396
397           res = av.getColumnSelection().findHiddenRegionPosition(i) -
398               startx;
399
400           if(res < 0 || res > endx-scalestartx)
401             continue;
402
403           gg.fillPolygon(new int[]
404                          {res * av.charWidth - av.charHeight / 4,
405                          res * av.charWidth + av.charHeight / 4,
406                          res * av.charWidth},
407                          new int[]
408                          {
409                          y - av.charHeight / 2, y - av.charHeight / 2,
410                          y + 8
411           }, 3);
412
413         }
414       }
415
416       if (reveal != null && reveal[0] > startx && reveal[0] < endx)
417       {
418         gg.drawString("Reveal Columns", reveal[0] * av.charWidth, 0);
419       }
420     }
421
422   }
423
424 }