JAL-1807 update
[jalviewjs.git] / unused / appletgui / ScalePanel.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.appletgui;
22
23 import jalview.datamodel.ColumnSelection;
24 import jalview.datamodel.SequenceGroup;
25 import jalview.util.MessageManager;
26
27 import java.awt.Color;
28 import java.awt.FontMetrics;
29 import java.awt.Graphics;
30 import java.awt.event.ActionEvent;
31 import java.awt.event.ActionListener;
32 import java.awt.event.InputEvent;
33 import java.awt.event.MouseEvent;
34 import java.awt.event.MouseListener;
35 import java.awt.event.MouseMotionListener;
36
37 import javax.swing.JMenuItem;
38 import javax.swing.JPanel;
39 import javax.swing.JPopupMenu;
40
41 public class ScalePanel extends JPanel implements MouseMotionListener,
42         MouseListener
43 {
44
45   protected int offy = 4;
46
47   public int width;
48
49   protected AlignViewport av;
50
51   AlignmentPanel ap;
52
53   boolean stretchingGroup = false;
54
55   int min; // used by mouseDragged to see if user
56
57   int max; // used by mouseDragged to see if user
58
59   boolean mouseDragging = false;
60
61   int[] reveal;
62
63   public ScalePanel(AlignViewport av, AlignmentPanel ap)
64   {
65     setLayout(null);
66     this.av = av;
67     this.ap = ap;
68
69     addMouseListener(this);
70     addMouseMotionListener(this);
71
72   }
73
74   public void mousePressed(MouseEvent evt)
75   {
76     int x = (evt.getX() / av.getCharWidth()) + av.getStartRes();
77     final int res;
78
79     if (av.hasHiddenColumns())
80     {
81       res = av.getColumnSelection().adjustForHiddenColumns(x);
82     }
83     else
84     {
85       res = x;
86     }
87
88     min = res;
89     max = res;
90     if ((evt.getModifiers() & InputEvent.BUTTON3_MASK) == InputEvent.BUTTON3_MASK)
91     {
92       JPopupMenu pop = new JPopupMenu();
93       if (reveal != null)
94       {
95         JMenuItem item = new JMenuItem(
96                 MessageManager.getString("label.reveal"));
97         item.addActionListener(new ActionListener()
98         {
99           public void actionPerformed(ActionEvent e)
100           {
101             av.showColumn(reveal[0]);
102             reveal = null;
103             ap.paintAlignment(true);
104             if (ap.overviewPanel != null)
105             {
106               ap.overviewPanel.updateOverviewImage();
107             }
108           }
109         });
110         pop.add(item);
111
112         if (av.getColumnSelection().hasManyHiddenColumns())
113         {
114           item = new JMenuItem(MessageManager.getString("action.reveal_all"));
115           item.addActionListener(new ActionListener()
116           {
117             public void actionPerformed(ActionEvent e)
118             {
119               av.showAllHiddenColumns();
120               reveal = null;
121               ap.paintAlignment(true);
122               if (ap.overviewPanel != null)
123               {
124                 ap.overviewPanel.updateOverviewImage();
125               }
126             }
127           });
128           pop.add(item);
129         }
130         this.add(pop);
131         pop.show(this, evt.getX(), evt.getY());
132       }
133       else if (av.getColumnSelection().contains(res))
134       {
135         JMenuItem item = new JMenuItem(
136                 MessageManager.getString("label.hide_columns"));
137         item.addActionListener(new ActionListener()
138         {
139           public void actionPerformed(ActionEvent e)
140           {
141             av.hideColumns(res, res);
142             if (av.getSelectionGroup() != null
143                     && av.getSelectionGroup().getSize() == av
144                             .getAlignment().getHeight())
145             {
146               av.setSelectionGroup(null);
147             }
148
149             ap.paintAlignment(true);
150             if (ap.overviewPanel != null)
151             {
152               ap.overviewPanel.updateOverviewImage();
153             }
154           }
155         });
156         pop.add(item);
157         this.add(pop);
158         pop.show(this, evt.getX(), evt.getY());
159       }
160     }
161     else
162     // LEFT MOUSE TO SELECT
163     {
164       if (!evt.isControlDown() && !evt.isShiftDown())
165       {
166         av.getColumnSelection().clear();
167       }
168
169       av.getColumnSelection().addElement(res);
170       SequenceGroup sg = new SequenceGroup();
171       for (int i = 0; i < av.getAlignment().getSequences().size(); i++)
172       {
173         sg.addSequence(av.getAlignment().getSequenceAt(i), false);
174       }
175
176       sg.setStartRes(res);
177       sg.setEndRes(res);
178       av.setSelectionGroup(sg);
179
180       if (evt.isShiftDown())
181       {
182         int min = Math.min(av.getColumnSelection().getMin(), res);
183         int max = Math.max(av.getColumnSelection().getMax(), res);
184         for (int i = min; i < max; i++)
185         {
186           av.getColumnSelection().addElement(i);
187         }
188         sg.setStartRes(min);
189         sg.setEndRes(max);
190       }
191     }
192
193     ap.paintAlignment(true);
194     av.sendSelection();
195   }
196
197   public void mouseReleased(MouseEvent evt)
198   {
199     mouseDragging = false;
200
201     int res = (evt.getX() / av.getCharWidth()) + av.getStartRes();
202
203     if (res > av.getAlignment().getWidth())
204     {
205       res = av.getAlignment().getWidth() - 1;
206     }
207
208     if (av.hasHiddenColumns())
209     {
210       res = av.getColumnSelection().adjustForHiddenColumns(res);
211     }
212
213     if (!stretchingGroup)
214     {
215       ap.paintAlignment(false);
216
217       return;
218     }
219
220     SequenceGroup sg = av.getSelectionGroup();
221
222     if (res > sg.getStartRes())
223     {
224       sg.setEndRes(res);
225     }
226     else if (res < sg.getStartRes())
227     {
228       sg.setStartRes(res);
229     }
230
231     stretchingGroup = false;
232     ap.paintAlignment(false);
233     av.sendSelection();
234   }
235
236   public void mouseDragged(MouseEvent evt)
237   {
238     mouseDragging = true;
239
240     int res = (evt.getX() / av.getCharWidth()) + av.getStartRes();
241     if (res < 0)
242     {
243       res = 0;
244     }
245
246     if (av.hasHiddenColumns())
247     {
248       res = av.getColumnSelection().adjustForHiddenColumns(res);
249     }
250
251     if (res > av.getAlignment().getWidth())
252     {
253       res = av.getAlignment().getWidth() - 1;
254     }
255
256     if (res < min)
257     {
258       min = res;
259     }
260
261     if (res > max)
262     {
263       max = res;
264     }
265
266     SequenceGroup sg = av.getSelectionGroup();
267
268     if (sg != null)
269     {
270       stretchingGroup = true;
271
272       if (!av.getColumnSelection().contains(res))
273       {
274         av.getColumnSelection().addElement(res);
275       }
276
277       if (res > sg.getStartRes())
278       {
279         sg.setEndRes(res);
280       }
281       if (res < sg.getStartRes())
282       {
283         sg.setStartRes(res);
284       }
285
286       int col;
287       for (int i = min; i <= max; i++)
288       {
289         col = av.getColumnSelection().adjustForHiddenColumns(i);
290
291         if ((col < sg.getStartRes()) || (col > sg.getEndRes()))
292         {
293           av.getColumnSelection().removeElement(col);
294         }
295         else
296         {
297           av.getColumnSelection().addElement(col);
298         }
299       }
300
301       ap.paintAlignment(false);
302     }
303   }
304
305   public void mouseEntered(MouseEvent evt)
306   {
307     if (mouseDragging)
308     {
309       ap.seqPanel.scrollCanvas(null);
310     }
311   }
312
313   public void mouseExited(MouseEvent evt)
314   {
315     if (mouseDragging)
316     {
317       ap.seqPanel.scrollCanvas(evt);
318     }
319   }
320
321   public void mouseClicked(MouseEvent evt)
322   {
323
324   }
325
326   public void mouseMoved(MouseEvent evt)
327   {
328     if (!av.hasHiddenColumns())
329     {
330       return;
331     }
332
333     int res = (evt.getX() / av.getCharWidth()) + av.getStartRes();
334
335     res = av.getColumnSelection().adjustForHiddenColumns(res);
336
337     reveal = null;
338     for (int[] region : av.getColumnSelection().getHiddenColumns())
339     {
340       if (res + 1 == region[0] || res - 1 == region[1])
341       {
342         reveal = region;
343         break;
344       }
345     }
346
347     repaint();
348   }
349
350   public void update(Graphics g)
351   {
352     paint(g);
353   }
354
355   public void paint(Graphics g)
356   {
357     drawScale(g, av.getStartRes(), av.getEndRes(), getSize().width,
358             getSize().height);
359   }
360
361   // scalewidth will normally be screenwidth,
362   public void drawScale(Graphics gg, int startx, int endx, int width,
363           int height)
364   {
365     gg.setFont(av.getFont());
366     // Fill in the background
367     gg.setColor(Color.white);
368     gg.fillRect(0, 0, width, height);
369     gg.setColor(Color.black);
370
371     // Fill the selected columns
372     ColumnSelection cs = av.getColumnSelection();
373     gg.setColor(new Color(220, 0, 0));
374     int avcharWidth = av.getCharWidth(), avcharHeight = av.getCharHeight();
375     for (int i = 0; i < cs.size(); i++)
376     {
377       int sel = cs.columnAt(i);
378       if (av.hasHiddenColumns())
379       {
380         sel = av.getColumnSelection().findColumnPosition(sel);
381       }
382
383       if ((sel >= startx) && (sel <= endx))
384       {
385         gg.fillRect((sel - startx) * avcharWidth, 0, avcharWidth,
386                 getSize().height);
387       }
388     }
389
390     // Draw the scale numbers
391     gg.setColor(Color.black);
392
393     int scalestartx = (startx / 10) * 10;
394
395     FontMetrics fm = gg.getFontMetrics(av.getFont());
396     int y = avcharHeight - fm.getDescent();
397
398     if ((scalestartx % 10) == 0)
399     {
400       scalestartx += 5;
401     }
402
403     String string;
404     int maxX = 0;
405
406     for (int i = scalestartx; i < endx; i += 5)
407     {
408       if ((i % 10) == 0)
409       {
410         string = String.valueOf(av.getColumnSelection()
411                 .adjustForHiddenColumns(i));
412         if ((i - startx - 1) * avcharWidth > maxX)
413         {
414           gg.drawString(string, (i - startx - 1) * avcharWidth, y);
415           maxX = (i - startx + 1) * avcharWidth + fm.stringWidth(string);
416         }
417
418         gg.drawLine(
419 ((i - startx - 1) * avcharWidth) + (avcharWidth / 2),
420                 y + 2,
421                 ((i - startx - 1) * avcharWidth) + (avcharWidth / 2),
422                 y + (fm.getDescent() * 2));
423
424       }
425       else
426       {
427         gg.drawLine(
428 ((i - startx - 1) * avcharWidth) + (avcharWidth / 2),
429                 y + fm.getDescent(),
430  ((i - startx - 1) * avcharWidth)
431                 + (avcharWidth / 2),
432                 y + (fm.getDescent() * 2));
433       }
434     }
435
436     if (av.hasHiddenColumns())
437     {
438       gg.setColor(Color.blue);
439       int res;
440       if (av.getShowHiddenMarkers())
441       {
442         for (int i = 0; i < av.getColumnSelection().getHiddenColumns()
443                 .size(); i++)
444         {
445
446           res = av.getColumnSelection().findHiddenRegionPosition(i)
447                   - startx;
448
449           if (res < 0 || res > endx - scalestartx)
450           {
451             continue;
452           }
453
454           gg.fillPolygon(new int[]
455           { res * avcharWidth - avcharHeight / 4,
456               res * avcharWidth + avcharHeight / 4, res * avcharWidth },
457                   new int[]
458                   { y - avcharHeight / 2, y - avcharHeight / 2, y + 8 },
459                   3);
460
461         }
462       }
463
464       if (reveal != null && reveal[0] > startx && reveal[0] < endx)
465       {
466         gg.drawString(MessageManager.getString("label.reveal_columns"),
467                 reveal[0] * avcharWidth, 0);
468       }
469     }
470
471   }
472
473 }