add VK_F key, up down
[jalview.git] / src / jalview / gui / AlignmentPanel.java
1 package jalview.gui;\r
2 \r
3 import jalview.jbgui.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 import java.awt.print.*;\r
10 \r
11 public class AlignmentPanel extends GAlignmentPanel implements AdjustmentListener, Printable\r
12 {\r
13 \r
14   AlignViewport     av;\r
15   OverviewPanel overviewPanel;\r
16   SeqPanel   seqPanel;\r
17   IdPanel    idPanel;\r
18   SecondaryStructurePanel ssPanel;\r
19   public AlignFrame alignFrame;\r
20   ScalePanel scalePanel;\r
21   ScorePanel scorePanel;\r
22 \r
23   public AlignmentPanel(AlignFrame af, final AlignViewport av)\r
24   {\r
25     alignFrame = af;\r
26     this.av         = av;\r
27     seqPanel        = new SeqPanel  (av, this);\r
28     idPanel         = new IdPanel   (av, this);\r
29     scalePanel = new ScalePanel(av, this);\r
30     scorePanel = new ScorePanel(av);\r
31     ssPanel = new SecondaryStructurePanel(av);\r
32 \r
33     secondaryPanelHolder.add(ssPanel, BorderLayout.CENTER);\r
34     idPanelHolder.add(idPanel, BorderLayout.CENTER);\r
35     idPanel.addNotify();\r
36     scalePanelHolder.add(scalePanel, BorderLayout.CENTER);\r
37     scorePanelHolder.add(scorePanel, BorderLayout.CENTER);\r
38     seqPanelHolder.add(seqPanel, BorderLayout.CENTER);\r
39     setScrollValues(0,0);\r
40 \r
41     hscroll.addAdjustmentListener(this);\r
42     vscroll.addAdjustmentListener(this);\r
43 \r
44     addComponentListener(new ComponentAdapter()\r
45    {\r
46      public void componentResized(ComponentEvent evt)\r
47      {\r
48           RefreshPanels();\r
49      }\r
50    });\r
51 \r
52 \r
53    hscroll.setFocusable(false);\r
54    vscroll.setFocusable(false);\r
55    setFocusable(true);\r
56 \r
57    addKeyListener(new KeyAdapter()\r
58    {\r
59      public void keyPressed(KeyEvent evt)\r
60      {\r
61        switch(evt.getKeyCode())\r
62        {\r
63          case  27: // escape key\r
64            av.setRubberbandGroup(null);\r
65            RefreshPanels();\r
66            break;\r
67          case KeyEvent.VK_X:\r
68            alignFrame.cut_actionPerformed(null);\r
69            break;\r
70          case KeyEvent.VK_C:\r
71            alignFrame.copy_actionPerformed(null);\r
72            break;\r
73          case KeyEvent.VK_V:\r
74            alignFrame.paste(true);\r
75            break;\r
76          case KeyEvent.VK_A:\r
77            alignFrame.selectAllSequenceMenuItem_actionPerformed(null);\r
78            break;\r
79         case KeyEvent.VK_DOWN:\r
80           alignFrame.moveSelectedSequences(false);\r
81           break;\r
82         case KeyEvent.VK_UP:\r
83           alignFrame.moveSelectedSequences(true);\r
84           break;\r
85         case KeyEvent.VK_F:\r
86           alignFrame.findMenuItem_actionPerformed(null);\r
87           break;\r
88        }\r
89      }\r
90    });\r
91   }\r
92 \r
93 \r
94  public void highlightSearchResults(int [] results)\r
95  {\r
96    seqPanel.seqCanvas.highlightSearchResults( results );\r
97 \r
98    // do we need to scroll the panel?\r
99    if(results!=null && (av.getStartSeq()>results[0]\r
100                         || av.getEndSeq()<results[0]\r
101                         || av.getStartRes()>results[1]\r
102                         || av.getEndRes()<results[2]))\r
103        setScrollValues(results[1], results[0]);\r
104 \r
105 \r
106  }\r
107 \r
108 \r
109  public OverviewPanel getOverviewPanel()\r
110  {\r
111    return overviewPanel;\r
112  }\r
113 \r
114  public void setOverviewPanel(OverviewPanel op)\r
115  {\r
116    overviewPanel = op;\r
117  }\r
118 \r
119 \r
120   public void setGraphPanelVisible(boolean b)\r
121   {\r
122     idSpaceFillerPanel.setVisible(b);\r
123     scorePanelHolder.setVisible(b);\r
124 \r
125     RefreshPanels();\r
126     // bit annoying to call this twice, can you do better?\r
127     RefreshPanels();\r
128   }\r
129 \r
130   public void setSecondaryStructureVisible(boolean b)\r
131   {\r
132     secondaryPanelHolder.setVisible(b);\r
133     RefreshPanels();\r
134   }\r
135 \r
136   public void setWrapAlignment(boolean wrap)\r
137   {\r
138     scorePanelHolder.setVisible(!wrap);\r
139     scalePanelHolder.setVisible(!wrap);\r
140     secondaryPanelHolder.setVisible(!wrap);\r
141 \r
142     hscroll.setVisible(!wrap);\r
143 \r
144     idSpaceFillerPanel.setVisible(!wrap);\r
145     idSpaceFillerPanel1.setVisible(!wrap);\r
146 \r
147     RefreshPanels();\r
148 \r
149   }\r
150 \r
151 \r
152   public void setColourScheme()\r
153   {\r
154     ColourSchemeI cs = av.getGlobalColourScheme();\r
155 \r
156     if(av.getConservationSelected())\r
157     {\r
158 \r
159        Alignment al = (Alignment)av.getAlignment();\r
160        Conservation c = new Conservation("All",\r
161                             ResidueProperties.propHash, 3, al.getSequences(), 0,\r
162                             al.getWidth() );\r
163 \r
164        c.calculate();\r
165        c.verdict(false, 100);\r
166        ConservationColourScheme ccs = new ConservationColourScheme(c, cs);\r
167 \r
168        av.setGlobalColourScheme( ccs );\r
169 \r
170     }\r
171 \r
172     RefreshPanels();\r
173   }\r
174 \r
175   public void RefreshPanels()\r
176   {\r
177     requestFocus();\r
178     invalidate();\r
179     seqPanel.seqCanvas.paintFlag = true;\r
180     idPanel.idCanvas.paintFlag = true;\r
181     idPanelHolder.setPreferredSize( idPanel.idCanvas.getPreferredSize() );\r
182 \r
183     if(av.getWrapAlignment())\r
184     {\r
185       int max = av.alignment.getWidth()/ (seqPanel.seqCanvas.getWidth()/av.charWidth)+1;\r
186 \r
187       int h  = (av.alignment.getHeight() + 2)*av.charHeight;\r
188       vextent = seqPanel.seqCanvas.getHeight()/h;\r
189       vscroll.setValues(0,vextent,0,max);\r
190     }\r
191     else\r
192 \r
193     setScrollValues(av.getStartRes(), av.getStartSeq());\r
194     av.getConsensus(true);\r
195     if(overviewPanel!=null)\r
196       overviewPanel.updateOverviewImage();\r
197 \r
198     validate();\r
199     repaint();\r
200 \r
201   }\r
202 \r
203   int hextent = 0;\r
204   int vextent = 0;\r
205 \r
206   public void setScrollValues(int x, int y)\r
207   {\r
208     hextent = seqPanel.seqCanvas.getWidth()/av.getCharWidth();\r
209     vextent = seqPanel.seqCanvas.getHeight()/av.getCharHeight();\r
210 \r
211     if(hextent+x  >  av.getAlignment().getWidth())\r
212       x =  av.getAlignment().getWidth()- hextent;\r
213 \r
214     if(vextent+y > av.getAlignment().getHeight())\r
215       y = av.getAlignment().getHeight() - vextent;\r
216 \r
217     if(y<0)\r
218       y = 0;\r
219 \r
220     if(x<0)\r
221       x=0;\r
222 \r
223     hscroll.setValues(x,hextent,0,av.getAlignment().getWidth());\r
224     vscroll.setValues(y,vextent,0,av.getAlignment().getHeight() );\r
225 \r
226 \r
227     repaint();\r
228 \r
229   }\r
230 \r
231 \r
232   public void adjustmentValueChanged(AdjustmentEvent evt)\r
233   {\r
234 \r
235     if (evt.getSource() == hscroll)\r
236     {\r
237       int x = hscroll.getValue();\r
238       av.setStartRes(x);\r
239       av.setEndRes(x + seqPanel.seqCanvas.getWidth()/av.getCharWidth()-1);\r
240     }\r
241 \r
242     if (evt.getSource() == vscroll)\r
243     {\r
244       int offy = vscroll.getValue();\r
245       if (av.getWrapAlignment())\r
246       {\r
247         av.setStartRes( vscroll.getValue() * av.getChunkWidth());\r
248         // System.out.println(vscroll.getValue()+" "+ av.getChunkWidth());\r
249       //  int resSpan = av.alignment.getWidth()/ (seqPanel.seqCanvas.getWidth()/av.charWidth)+1;\r
250      //   int h  = (av.alignment.getHeight() + 2)*av.charHeight;\r
251       //  vextent = seqPanel.seqCanvas.getHeight()/h;\r
252      //   vscroll.setValues(0,vextent,0,max);\r
253 \r
254 \r
255       // av.setStartSeq(  );\r
256       }\r
257       else\r
258       {\r
259         av.setStartSeq(offy);\r
260         av.setEndSeq(offy + seqPanel.seqCanvas.getHeight() / av.getCharHeight());\r
261       }\r
262     }\r
263 \r
264 \r
265     if(overviewPanel!=null)\r
266       overviewPanel.setBoxPosition();\r
267 \r
268     seqPanel.seqCanvas.paintFlag=true;\r
269     repaint();\r
270   }\r
271 \r
272 \r
273 \r
274   public int print(Graphics pg, PageFormat pf, int pi) throws PrinterException\r
275   {\r
276     if(av.getWrapAlignment())\r
277     {\r
278      return PrintWrappedAlignment(pg, pf, pi);\r
279     }\r
280 \r
281     pg.translate((int)pf.getImageableX(), (int)pf.getImageableY());\r
282 \r
283     int pwidth = (int)pf.getImageableWidth();\r
284     int pheight = (int)pf.getImageableHeight();\r
285     int idWidth = (int)idPanel.idCanvas.getLabelWidth().getWidth();\r
286 \r
287 \r
288     pg.setColor(Color.white);\r
289     pg.fillRect(0,0,pwidth, pheight);\r
290     pg.setFont( av.getFont() );\r
291 \r
292     ////////////////////////////////////\r
293     /// How many sequences and residues can we fit on a printable page?\r
294     int totalRes = (pwidth - idWidth)/av.getCharWidth();\r
295     int totalSeq = (int)((pheight - 30)/av.getCharHeight())-1;\r
296     int pagesWide = av.getAlignment().getWidth() / totalRes +1;\r
297     int pagesHigh = av.getAlignment().getHeight() / totalSeq +1;\r
298 \r
299     if (pi >= pagesWide*pagesHigh)\r
300      return Printable.NO_SUCH_PAGE;\r
301 \r
302     /////////////////////////////\r
303     /// Only print these sequences and residues on this page\r
304     int startRes, endRes, startSeq, endSeq;\r
305     startRes = (pi % pagesWide) * totalRes;\r
306     endRes = startRes + totalRes-1;\r
307     if(endRes>av.getAlignment().getWidth())\r
308       endRes = av.getAlignment().getWidth();\r
309 \r
310      startSeq = (pi / pagesWide) * totalSeq;\r
311      endSeq = startSeq + totalSeq;\r
312      if(endSeq > av.getAlignment().getHeight())\r
313        endSeq = av.getAlignment().getHeight();\r
314 \r
315 \r
316     ////////////////\r
317     //draw Scale\r
318     pg.translate(idWidth,0);\r
319     scalePanel.scaleCanvas.drawScale(pg, startRes, endRes, pwidth-idWidth);\r
320 \r
321     pg.translate(-idWidth, 30);\r
322     ////////////////\r
323     // Draw the ids\r
324     Color currentColor=null;\r
325     Color currentTextColor=null;\r
326     for(int i=startSeq; i<endSeq; i++)\r
327     {\r
328       if (av.getSelection().contains(av.getAlignment().getSequenceAt(i)))\r
329       {\r
330         currentColor = Color.gray;\r
331         currentTextColor = Color.black;\r
332       }\r
333       else\r
334       {\r
335         currentColor = av.getAlignment().getSequenceAt(i).getColor();\r
336         currentTextColor = Color.black;\r
337       }\r
338 \r
339       pg.setColor(currentColor);\r
340       pg.fillRect(0,  jalview.analysis.AlignmentUtil.getPixelHeight(startSeq, i, av.getCharHeight()),\r
341                               idWidth,\r
342                               av.getCharHeight());\r
343 \r
344       pg.setColor(currentTextColor);\r
345 \r
346       String string = av.getAlignment().getSequenceAt(i).getDisplayId();\r
347       pg.drawString(string, 0,  jalview.analysis.AlignmentUtil.getPixelHeight\r
348                     (startSeq, i, av.getCharHeight()) + av.getCharHeight() - (av.getCharHeight() / 5));\r
349     }\r
350 \r
351     // draw main sequence panel\r
352     pg.translate(idWidth,0);\r
353     pg.setClip(0,0,pwidth-idWidth, pheight);\r
354     seqPanel.seqCanvas.drawPanel(pg,startRes,endRes,startSeq,endSeq,startRes,startSeq,0);\r
355 \r
356     return Printable.PAGE_EXISTS;\r
357   }\r
358 \r
359   class VPanel extends javax.swing.JPanel\r
360   {\r
361     Image image;\r
362     public VPanel(Image i)\r
363     {\r
364       image = i;\r
365       repaint();\r
366     }\r
367     public void paintComponent(Graphics g)\r
368     {\r
369       if(image!=null)\r
370         g.drawImage(image,0,0,this);\r
371     }\r
372 \r
373   }\r
374 \r
375   public int PrintWrappedAlignment(Graphics pg, PageFormat pf, int pi)\r
376   {\r
377     pg.translate((int)pf.getImageableX(), (int)pf.getImageableY());\r
378 \r
379     int pwidth = (int)pf.getImageableWidth();\r
380     int pheight = (int)pf.getImageableHeight();\r
381     int idWidth = (int)idPanel.idCanvas.getLabelWidth().getWidth();\r
382 \r
383     if( seqPanel.seqCanvas.getWidth() < pwidth-idWidth)\r
384       pwidth = seqPanel.seqCanvas.getWidth() + idWidth;\r
385 \r
386     pg.setColor(Color.white);\r
387     pg.fillRect(0,0,pwidth, pheight);\r
388     pg.setFont( av.getFont() );\r
389 \r
390     ////////////////////////////////////\r
391     /// How many sequences and residues can we fit on a printable page?\r
392     AlignmentI da = av.alignment;\r
393     int endy   = da.getHeight();\r
394     int chunkHeight =  (da.getHeight() + 2)*av.charHeight;\r
395     int chunkWidth  =   (pwidth-idWidth)/av.charWidth;\r
396 \r
397     int noChunksOnPage = pheight / chunkHeight;\r
398     int totalChunks = endy / chunkHeight;\r
399 \r
400     if ( pi*noChunksOnPage > totalChunks )\r
401      return Printable.NO_SUCH_PAGE;\r
402 \r
403     ////////////////\r
404     // Draw the ids\r
405     pg.setClip(0,0,pwidth, noChunksOnPage*chunkHeight);\r
406 \r
407     int row = pi*noChunksOnPage;\r
408     pg.setColor(Color.black);\r
409     for(int ypos=2*av.charHeight;\r
410         ypos <= pheight && row*chunkWidth<da.getWidth();\r
411         ypos += chunkHeight, row++ )\r
412     {\r
413       for (int i = 0; i < endy; i++)\r
414       {\r
415         SequenceI s = da.getSequenceAt(i);\r
416         pg.drawString(s.getDisplayId(), 0,\r
417                       AlignmentUtil.getPixelHeight(0, i, av.charHeight) + ypos +\r
418                       av.charHeight - (av.charHeight / 5));\r
419       }\r
420     }\r
421 \r
422     // draw main sequence panel\r
423     pg.translate(idWidth,0);\r
424     seqPanel.seqCanvas.drawWrappedPanel(pg, pwidth-idWidth, pheight, pi*noChunksOnPage*chunkWidth);\r
425 \r
426 \r
427     return Printable.NO_SUCH_PAGE;//.PAGE_EXISTS;\r
428 \r
429   }\r
430 }\r
431 \r
432 \r
433 \r