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