ddfc4320becb5e5535b3821800a1cb65bda0c666
[jalview.git] / src / jalview / appletgui / AlignmentPanel.java
1 package jalview.appletgui;\r
2 \r
3 import jalview.jbappletgui.GAlignmentPanel;\r
4 import jalview.schemes.*;\r
5 import jalview.analysis.*;\r
6 import jalview.datamodel.*;\r
7 import java.awt.*;\r
8 import java.awt.event.*;\r
9 \r
10 public class AlignmentPanel extends GAlignmentPanel implements AdjustmentListener\r
11 {\r
12 \r
13   AlignViewport     av;\r
14   OverviewPanel overviewPanel;\r
15   SeqPanel   seqPanel;\r
16   IdPanel    idPanel;\r
17   IdwidthAdjuster idwidthAdjuster;\r
18   public AlignFrame alignFrame;\r
19   ScalePanel scalePanel;\r
20   AnnotationPanel annotationPanel;\r
21   AnnotationLabels alabels;\r
22 \r
23   // this value is set false when selection area being dragged\r
24   boolean fastPaint = true;\r
25 \r
26   public AlignmentPanel(AlignFrame af, final AlignViewport av)\r
27   {\r
28     alignFrame = af;\r
29     this.av         = av;\r
30     seqPanel        = new SeqPanel  (av, this);\r
31     idPanel         = new IdPanel   (av, this);\r
32     scalePanel      = new ScalePanel(av, this);\r
33     idwidthAdjuster = new IdwidthAdjuster(this);\r
34     annotationPanel = new AnnotationPanel(this);\r
35     alabels         = new AnnotationLabels(this);\r
36 \r
37 \r
38     idPanelHolder.add(idPanel, BorderLayout.CENTER);\r
39     idSpaceFillerPanel1.add(idwidthAdjuster, BorderLayout.CENTER);\r
40     annotationScroller.add(annotationPanel);\r
41     annotationSpaceFillerHolder.add(alabels, BorderLayout.CENTER);\r
42     scalePanelHolder.add(scalePanel, BorderLayout.CENTER);\r
43     seqPanelHolder.add(seqPanel, BorderLayout.CENTER);\r
44 \r
45     fontChanged();\r
46     setScrollValues(0, 0);\r
47 \r
48     hscroll.addAdjustmentListener(this);\r
49     vscroll.addAdjustmentListener(this);\r
50 \r
51    seqPanel.seqCanvas.addKeyListener( new MyKeyAdapter() );\r
52    idPanel.idCanvas.addKeyListener( new MyKeyAdapter() );\r
53 \r
54    addComponentListener(new ComponentAdapter()\r
55      {\r
56        public void componentResized(ComponentEvent evt)\r
57        {\r
58          setScrollValues(av.getStartRes(), av.getStartSeq());\r
59          repaint();\r
60        }\r
61      });\r
62 \r
63      Dimension d = calculateIdWidth();\r
64      idPanel.idCanvas.setSize(d);\r
65 \r
66      hscrollFillerPanel.setSize(d.width, annotationPanel.getSize().height);\r
67      annotationScroller.setSize(annotationPanel.getSize());\r
68 \r
69      idPanel.idCanvas.setSize(d.width, seqPanel.seqCanvas.getSize().height);\r
70      annotationSpaceFillerHolder.setSize(d.width,annotationPanel.getSize().height);\r
71      alabels.setSize(d.width,annotationPanel.getSize().height);\r
72 \r
73   }\r
74 \r
75   class MyKeyAdapter extends KeyAdapter\r
76   {\r
77      public void keyPressed(KeyEvent evt)\r
78      {\r
79        switch(evt.getKeyCode())\r
80        {\r
81          case  27: // escape key\r
82            av.setSelectionGroup(null);\r
83            alignFrame.alignPanel.repaint();\r
84            break;\r
85          case KeyEvent.VK_X:\r
86            if(evt.isControlDown())\r
87            alignFrame.cut_actionPerformed(null);\r
88            break;\r
89          case KeyEvent.VK_C:\r
90          if(evt.isControlDown())\r
91            alignFrame.copy_actionPerformed(null);\r
92            break;\r
93          case KeyEvent.VK_V:\r
94           if(evt.isControlDown())\r
95            alignFrame.paste(true);\r
96            break;\r
97          case KeyEvent.VK_A:\r
98          if(evt.isControlDown())\r
99            alignFrame.selectAllSequenceMenuItem_actionPerformed(null);\r
100            break;\r
101         case KeyEvent.VK_DOWN:\r
102           alignFrame.moveSelectedSequences(false);\r
103           break;\r
104         case KeyEvent.VK_UP:\r
105           alignFrame.moveSelectedSequences(true);\r
106           break;\r
107         case KeyEvent.VK_F:\r
108          if(evt.isControlDown())\r
109           alignFrame.findMenuItem_actionPerformed(null);\r
110           break;\r
111        }\r
112      }\r
113   }\r
114 \r
115   public void fontChanged()\r
116   {\r
117     // set idCanvas bufferedImage to null\r
118     // to prevent drawing old image\r
119     FontMetrics fm = getFontMetrics(av.getFont());\r
120 \r
121     scalePanel.setSize(new Dimension(10, av.charHeight+fm.getDescent()));\r
122     idwidthAdjuster.setSize(new Dimension(10, av.charHeight+fm.getDescent()));\r
123 \r
124     annotationPanel.adjustPanelHeight();\r
125     annotationPanel.repaint();\r
126     Dimension d = calculateIdWidth();\r
127     d.setSize(d.width + 4, seqPanel.seqCanvas.getSize().height);\r
128     idPanel.idCanvas.setSize(d);\r
129     hscrollFillerPanel.setSize(d);\r
130 \r
131     alignFrame.pack();\r
132   }\r
133 \r
134   public void setIdWidth(int w, int h)\r
135   {\r
136     idPanel.idCanvas.setSize(w,h);\r
137     idPanelHolder.setSize(w,idPanelHolder.getSize().height);\r
138     alabels.setSize(w,alabels.getSize().height);\r
139     validate();\r
140   }\r
141   Dimension calculateIdWidth()\r
142   {\r
143     Frame frame = new Frame();\r
144     frame.addNotify();\r
145     Graphics g = frame.getGraphics();\r
146     if(g==null)\r
147     {\r
148       Frame f = new Frame();\r
149       f.addNotify();\r
150       g = f.getGraphics();\r
151     }\r
152 \r
153     FontMetrics fm = g.getFontMetrics(av.font);\r
154     AlignmentI al = av.getAlignment();\r
155 \r
156        int i   = 0;\r
157        int idWidth = 0;\r
158        String id;\r
159        while (i < al.getHeight() && al.getSequenceAt(i) != null)\r
160        {\r
161          SequenceI s   = al.getSequenceAt(i);\r
162          if(av.getShowFullId())\r
163            id   = s.getDisplayId();\r
164          else\r
165            id = s.getName();\r
166 \r
167          if (fm.stringWidth(id) > idWidth)\r
168            idWidth = fm.stringWidth(id);\r
169          i++;\r
170        }\r
171 \r
172        // Also check annotation label widths\r
173        i=0;\r
174        if(al.getAlignmentAnnotation()!=null)\r
175        {\r
176          fm = g.getFontMetrics(frame.getFont());\r
177          while (i < al.getAlignmentAnnotation().length)\r
178          {\r
179            String label = al.getAlignmentAnnotation()[i].label;\r
180            if (fm.stringWidth(label) > idWidth)\r
181              idWidth = fm.stringWidth(label);\r
182            i++;\r
183          }\r
184        }\r
185 \r
186        return new Dimension(idWidth, idPanel.idCanvas.getSize().height);\r
187   }\r
188 \r
189 \r
190  public void highlightSearchResults(int [] results)\r
191  {\r
192    seqPanel.seqCanvas.highlightSearchResults( results );\r
193 \r
194    // do we need to scroll the panel?\r
195    if(results!=null && (av.getStartSeq()>results[0]\r
196                         || av.getEndSeq()<results[0]\r
197                         || av.getStartRes()>results[1]\r
198                         || av.getEndRes()<results[2]))\r
199        setScrollValues(results[1], results[0]);\r
200 \r
201 \r
202  }\r
203 \r
204 \r
205  public OverviewPanel getOverviewPanel()\r
206  {\r
207    return overviewPanel;\r
208  }\r
209 \r
210  public void setOverviewPanel(OverviewPanel op)\r
211  {\r
212    overviewPanel = op;\r
213  }\r
214 \r
215 \r
216   public void setAnnotationVisible(boolean b)\r
217   {\r
218     annotationSpaceFillerHolder.setVisible(b);\r
219     annotationScroller.setVisible(b);\r
220     validate();\r
221     repaint();\r
222   }\r
223 \r
224 \r
225   public void setWrapAlignment(boolean wrap)\r
226   {\r
227     scalePanelHolder.setVisible(!wrap);\r
228     hscroll.setVisible(!wrap);\r
229     idwidthAdjuster.setVisible(!wrap);\r
230 \r
231     av.setShowAnnotation(!wrap);\r
232     annotationScroller.setVisible(!wrap);\r
233     annotationSpaceFillerHolder.setVisible(!wrap);\r
234     idSpaceFillerPanel1.setVisible(!wrap);\r
235 \r
236     validate();\r
237     repaint();\r
238 \r
239   }\r
240 \r
241 \r
242   public void setColourScheme()\r
243   {\r
244     ColourSchemeI cs = av.getGlobalColourScheme();\r
245 \r
246     if(av.getConservationSelected())\r
247     {\r
248 \r
249        Alignment al = (Alignment)av.getAlignment();\r
250        Conservation c = new Conservation("All",\r
251                             ResidueProperties.propHash, 3, al.getSequences(), 0,\r
252                             al.getWidth() );\r
253 \r
254        c.calculate();\r
255        c.verdict(false, av.ConsPercGaps);\r
256        ConservationColourScheme ccs = new ConservationColourScheme(c, cs);\r
257 \r
258        av.setGlobalColourScheme( ccs );\r
259 \r
260     }\r
261 \r
262     repaint();\r
263   }\r
264 \r
265 \r
266   int hextent = 0;\r
267   int vextent = 0;\r
268 \r
269   // return value is true if the scroll is valid\r
270   public boolean scrollUp(boolean up)\r
271   {\r
272     if(up)\r
273     {\r
274       if(vscroll.getValue()<1)\r
275         return false;\r
276       fastPaint  = false;\r
277       vscroll.setValue(vscroll.getValue() - 1);\r
278     }\r
279     else\r
280     {\r
281      if(vextent+vscroll.getValue() >= av.getAlignment().getHeight())\r
282        return false;\r
283       fastPaint  = false;\r
284       vscroll.setValue(vscroll.getValue() + 1);\r
285     }\r
286     fastPaint = true;\r
287     return true;\r
288   }\r
289 \r
290   public boolean scrollRight(boolean right)\r
291   {\r
292 \r
293     if (right)\r
294     {\r
295       if (hscroll.getValue() < 1)\r
296         return false;\r
297       fastPaint = false;\r
298       hscroll.setValue(hscroll.getValue() - 1);\r
299     }\r
300     else\r
301     {\r
302       if (hextent + hscroll.getValue() >= av.getAlignment().getWidth())\r
303         return false;\r
304       fastPaint = false;\r
305       hscroll.setValue(hscroll.getValue() + 1);\r
306     }\r
307     fastPaint = true;\r
308     return true;\r
309   }\r
310 \r
311 \r
312   public void setScrollValues(int x, int y)\r
313   {\r
314 \r
315     av.setStartRes(x);\r
316     av.setStartSeq(y);\r
317     av.setEndRes(x + seqPanel.seqCanvas.getSize().width/av.getCharWidth()-1);\r
318 \r
319     hextent = seqPanel.seqCanvas.getSize().width/av.charWidth;\r
320     vextent = seqPanel.seqCanvas.getSize().height/av.charHeight;\r
321 \r
322     if(hextent > av.alignment.getWidth())\r
323       hextent = av.alignment.getWidth();\r
324     if(vextent > av.alignment.getHeight())\r
325       vextent = av.alignment.getHeight();\r
326 \r
327     if(hextent+x  >  av.getAlignment().getWidth())\r
328       x =  av.getAlignment().getWidth()- hextent;\r
329 \r
330     if(vextent+y > av.getAlignment().getHeight())\r
331       y = av.getAlignment().getHeight() - vextent;\r
332 \r
333     if(y<0)\r
334       y = 0;\r
335 \r
336     if(x<0)\r
337       x=0;\r
338 \r
339 \r
340     int endSeq = y + vextent;\r
341     if(endSeq>av.alignment.getHeight())\r
342       endSeq = av.alignment.getHeight();\r
343 \r
344 \r
345     av.setEndSeq( endSeq );\r
346     hscroll.setValues(x,hextent,0,av.getAlignment().getWidth());\r
347     vscroll.setValues(y,vextent,0,av.getAlignment().getHeight() );\r
348 \r
349   }\r
350 \r
351 \r
352   public void adjustmentValueChanged(AdjustmentEvent evt)\r
353   {\r
354     int oldX = av.getStartRes();\r
355     int oldY = av.getStartSeq();\r
356 \r
357     if (evt.getSource() == hscroll)\r
358     {\r
359       int x = hscroll.getValue();\r
360       av.setStartRes(x);\r
361       av.setEndRes(x + seqPanel.seqCanvas.getSize().width/av.getCharWidth()-1);\r
362     }\r
363 \r
364     if (evt.getSource() == vscroll)\r
365     {\r
366       int offy = vscroll.getValue();\r
367       if (av.getWrapAlignment())\r
368       {\r
369         int rowSize = seqPanel.seqCanvas.getWrappedCanvasWidth(seqPanel.seqCanvas.getSize().width);\r
370         av.setStartRes( vscroll.getValue() * rowSize );\r
371         av.setEndRes( (vscroll.getValue()+1) * rowSize );\r
372       }\r
373       else\r
374       {\r
375         av.setStartSeq(offy);\r
376         av.setEndSeq(offy + seqPanel.seqCanvas.getSize().height / av.getCharHeight());\r
377       }\r
378     }\r
379 \r
380     if(overviewPanel!=null)\r
381       overviewPanel.setBoxPosition();\r
382 \r
383     if(av.getWrapAlignment() || !fastPaint)\r
384       repaint();\r
385     else\r
386     {\r
387       idPanel.idCanvas.fastPaint(av.getStartSeq() - oldY);\r
388       seqPanel.seqCanvas.fastPaint(av.getStartRes() - oldX,\r
389                                    av.getStartSeq() - oldY);\r
390 \r
391       scalePanel.repaint();\r
392       if (av.getShowAnnotation())\r
393         annotationPanel.fastPaint(av.getStartRes() - oldX);\r
394     }\r
395 \r
396   }\r
397 \r
398   public void update(Graphics g)\r
399   {\r
400     paint (g);\r
401   }\r
402 \r
403 \r
404   public void paint(Graphics g)\r
405   {\r
406     Dimension d = idPanel.idCanvas.getSize();\r
407     idPanel.idCanvas.setSize(d.width, seqPanel.seqCanvas.getSize().height);\r
408     annotationSpaceFillerHolder.setSize(d.width,annotationPanel.getSize().height);\r
409     alabels.setSize(d.width,annotationPanel.getSize().height);\r
410 \r
411     alabels.repaint();\r
412     idPanel.idCanvas.repaint();\r
413     seqPanel.seqCanvas.repaint();\r
414     scalePanel.repaint();\r
415     annotationPanel.repaint();\r
416 \r
417 \r
418     if (av.getWrapAlignment())\r
419     {\r
420       int max = av.alignment.getWidth() / seqPanel.seqCanvas.getWrappedCanvasWidth(seqPanel.seqCanvas.getSize().width);\r
421       vscroll.setMaximum(max);\r
422       vscroll.setUnitIncrement(1);\r
423       vscroll.setVisibleAmount(1);\r
424     }\r
425     else\r
426     {\r
427       setScrollValues(av.getStartRes(), av.getStartSeq());\r
428     }\r
429 \r
430 \r
431 \r
432   }\r
433 }\r