Jalview 2.6 source licence
[jalview.git] / src / jalview / appletgui / AnnotationColourChooser.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.6)
3  * Copyright (C) 2010 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle
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 of the License, or (at your option) any later version.
10  * 
11  * Jalview is distributed in the hope that it will be useful, but 
12  * WITHOUT ANY WARRANTY; without even the implied warranty 
13  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
14  * PURPOSE.  See the GNU General Public License for more details.
15  * 
16  * You should have received a copy of the GNU General Public License along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 package jalview.appletgui;
19
20 import java.util.*;
21
22 import java.awt.*;
23 import java.awt.event.*;
24
25 import jalview.datamodel.*;
26 import jalview.schemes.*;
27 import java.awt.Rectangle;
28
29 public class AnnotationColourChooser extends Panel implements
30         ActionListener, AdjustmentListener, ItemListener, MouseListener
31 {
32   Frame frame;
33
34   AlignViewport av;
35
36   AlignmentPanel ap;
37
38   ColourSchemeI oldcs;
39
40   Hashtable oldgroupColours;
41
42   jalview.datamodel.AlignmentAnnotation currentAnnotation;
43
44   boolean adjusting = false;
45
46   public AnnotationColourChooser(AlignViewport av, AlignmentPanel ap)
47   {
48     try
49     {
50       jbInit();
51     } catch (Exception ex)
52     {
53     }
54
55     oldcs = av.getGlobalColourScheme();
56     if (av.alignment.getGroups() != null)
57     {
58       oldgroupColours = new Hashtable();
59       Vector allGroups = ap.av.alignment.getGroups();
60       SequenceGroup sg;
61       for (int g = 0; g < allGroups.size(); g++)
62       {
63         sg = (SequenceGroup) allGroups.elementAt(g);
64         if (sg.cs != null)
65         {
66           oldgroupColours.put(sg, sg.cs);
67         }
68         else
69         {
70           oldgroupColours.put(sg, "null");
71         }
72       }
73     }
74     this.av = av;
75     this.ap = ap;
76
77     slider.addAdjustmentListener(this);
78     slider.addMouseListener(this);
79
80     if (av.alignment.getAlignmentAnnotation() == null)
81     {
82       return;
83     }
84
85     if (oldcs instanceof AnnotationColourGradient)
86     {
87       AnnotationColourGradient acg = (AnnotationColourGradient) oldcs;
88       minColour.setBackground(acg.getMinColour());
89       maxColour.setBackground(acg.getMaxColour());
90     }
91     else
92     {
93       minColour.setBackground(Color.orange);
94       maxColour.setBackground(Color.red);
95     }
96
97     adjusting = true;
98
99     Vector list = new Vector();
100     int index = 1;
101     for (int i = 0; i < av.alignment.getAlignmentAnnotation().length; i++)
102     {
103       String label = av.alignment.getAlignmentAnnotation()[i].label;
104       if (!list.contains(label))
105         list.addElement(label);
106       else
107         list.addElement(label + "_" + (index++));
108     }
109
110     for (int i = 0; i < list.size(); i++)
111     {
112       annotations.addItem(list.elementAt(i).toString());
113     }
114
115     threshold.addItem("No Threshold");
116     threshold.addItem("Above Threshold");
117     threshold.addItem("Below Threshold");
118
119     adjusting = false;
120
121     changeColour();
122
123     frame = new Frame();
124     frame.add(this);
125     jalview.bin.JalviewLite.addFrame(frame, "Colour by Annotation", 480,
126             145);
127     validate();
128   }
129
130   public AnnotationColourChooser()
131   {
132     try
133     {
134       jbInit();
135     } catch (Exception ex)
136     {
137       ex.printStackTrace();
138     }
139   }
140
141   private void jbInit() throws Exception
142   {
143     minColour.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
144     minColour.setLabel("Min Colour");
145     minColour.addActionListener(this);
146
147     maxColour.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
148     maxColour.setLabel("Max Colour");
149     maxColour.addActionListener(this);
150
151     thresholdIsMin.addItemListener(this);
152     ok.setLabel("OK");
153     ok.addActionListener(this);
154
155     cancel.setLabel("Cancel");
156     cancel.addActionListener(this);
157
158     this.setLayout(borderLayout1);
159     jPanel2.setLayout(flowLayout1);
160     annotations.addItemListener(this);
161
162     jPanel1.setBackground(Color.white);
163     jPanel2.setBackground(Color.white);
164     threshold.addItemListener(this);
165     jPanel3.setLayout(null);
166     thresholdValue.addActionListener(this);
167
168     slider.setBackground(Color.white);
169     slider.setEnabled(false);
170     slider.setBounds(new Rectangle(153, 3, 93, 21));
171     thresholdValue.setEnabled(false);
172     thresholdValue.setBounds(new Rectangle(248, 2, 79, 22));
173     thresholdValue.setColumns(5);
174     jPanel3.setBackground(Color.white);
175     currentColours.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
176     currentColours.setLabel("Use Original Colours");
177     currentColours.addItemListener(this);
178
179     threshold.setBounds(new Rectangle(11, 3, 139, 22));
180     thresholdIsMin.setBackground(Color.white);
181     thresholdIsMin.setLabel("Threshold is min/max");
182     thresholdIsMin.setBounds(new Rectangle(328, 3, 135, 23));
183     jPanel1.add(ok);
184     jPanel1.add(cancel);
185     jPanel2.add(annotations);
186     jPanel2.add(currentColours);
187     jPanel2.add(minColour);
188     jPanel2.add(maxColour);
189     jPanel3.add(threshold);
190     jPanel3.add(slider);
191     jPanel3.add(thresholdValue);
192     jPanel3.add(thresholdIsMin);
193     this.add(jPanel2, java.awt.BorderLayout.NORTH);
194     this.add(jPanel3, java.awt.BorderLayout.CENTER);
195     this.add(jPanel1, java.awt.BorderLayout.SOUTH);
196   }
197
198   Choice annotations = new Choice();
199
200   Button minColour = new Button();
201
202   Button maxColour = new Button();
203
204   Button ok = new Button();
205
206   Button cancel = new Button();
207
208   Panel jPanel1 = new Panel();
209
210   Panel jPanel2 = new Panel();
211
212   Choice threshold = new Choice();
213
214   FlowLayout flowLayout1 = new FlowLayout();
215
216   Panel jPanel3 = new Panel();
217
218   Scrollbar slider = new Scrollbar(Scrollbar.HORIZONTAL);
219
220   TextField thresholdValue = new TextField(20);
221
222   Checkbox currentColours = new Checkbox();
223
224   BorderLayout borderLayout1 = new BorderLayout();
225
226   Checkbox thresholdIsMin = new Checkbox();
227
228   public void actionPerformed(ActionEvent evt)
229   {
230     if (evt.getSource() == thresholdValue)
231     {
232       try
233       {
234         float f = new Float(thresholdValue.getText()).floatValue();
235         slider.setValue((int) (f * 1000));
236         adjustmentValueChanged(null);
237       } catch (NumberFormatException ex)
238       {
239       }
240     }
241     else if (evt.getSource() == minColour)
242     {
243       minColour_actionPerformed(null);
244     }
245     else if (evt.getSource() == maxColour)
246     {
247       maxColour_actionPerformed(null);
248     }
249
250     else if (evt.getSource() == ok)
251     {
252       changeColour();
253       frame.setVisible(false);
254     }
255     else if (evt.getSource() == cancel)
256     {
257       reset();
258       ap.paintAlignment(true);
259       frame.setVisible(false);
260     }
261
262     else
263     {
264       changeColour();
265     }
266   }
267
268   public void itemStateChanged(ItemEvent evt)
269   {
270     if (evt.getSource() == currentColours)
271     {
272       if (currentColours.getState())
273       {
274         reset();
275       }
276
277       maxColour.setEnabled(!currentColours.getState());
278       minColour.setEnabled(!currentColours.getState());
279
280     }
281
282     changeColour();
283   }
284
285   public void adjustmentValueChanged(AdjustmentEvent evt)
286   {
287     if (!adjusting)
288     {
289       thresholdValue.setText(((float) slider.getValue() / 1000f) + "");
290       if (currentColours.getState()
291               && !(av.getGlobalColourScheme() instanceof AnnotationColourGradient))
292       {
293         changeColour();
294       }
295
296       currentAnnotation.threshold.value = (float) slider.getValue() / 1000f;
297       ap.paintAlignment(false);
298     }
299   }
300
301   public void minColour_actionPerformed(Color newCol)
302   {
303     if (newCol != null)
304     {
305       minColour.setBackground(newCol);
306       minColour.repaint();
307       changeColour();
308     }
309     else
310     {
311       new UserDefinedColours(this, "Min Colour", minColour.getBackground());
312     }
313
314   }
315
316   public void maxColour_actionPerformed(Color newCol)
317   {
318     if (newCol != null)
319     {
320       maxColour.setBackground(newCol);
321       maxColour.repaint();
322       changeColour();
323     }
324     else
325     {
326       new UserDefinedColours(this, "Max Colour", maxColour.getBackground());
327     }
328   }
329
330   void changeColour()
331   {
332     // Check if combobox is still adjusting
333     if (adjusting)
334     {
335       return;
336     }
337
338     currentAnnotation = av.alignment.getAlignmentAnnotation()[annotations
339             .getSelectedIndex()];
340
341     int aboveThreshold = -1;
342     if (threshold.getSelectedItem().equals("Above Threshold"))
343     {
344       aboveThreshold = AnnotationColourGradient.ABOVE_THRESHOLD;
345     }
346     else if (threshold.getSelectedItem().equals("Below Threshold"))
347     {
348       aboveThreshold = AnnotationColourGradient.BELOW_THRESHOLD;
349     }
350
351     slider.setEnabled(true);
352     thresholdValue.setEnabled(true);
353
354     if (aboveThreshold == AnnotationColourGradient.NO_THRESHOLD)
355     {
356       slider.setEnabled(false);
357       thresholdValue.setEnabled(false);
358       thresholdValue.setText("");
359     }
360     else if (aboveThreshold != AnnotationColourGradient.NO_THRESHOLD
361             && currentAnnotation.threshold == null)
362     {
363       currentAnnotation
364               .setThreshold(new jalview.datamodel.GraphLine(
365                       (currentAnnotation.graphMax - currentAnnotation.graphMin) / 2f,
366                       "Threshold", Color.black));
367     }
368
369     if (aboveThreshold != AnnotationColourGradient.NO_THRESHOLD)
370     {
371       adjusting = true;
372
373       slider.setMinimum((int) (currentAnnotation.graphMin * 1000));
374       slider.setMaximum((int) (currentAnnotation.graphMax * 1000));
375       slider.setValue((int) (currentAnnotation.threshold.value * 1000));
376       thresholdValue.setText(currentAnnotation.threshold.value + "");
377       slider.setEnabled(true);
378       thresholdValue.setEnabled(true);
379       adjusting = false;
380     }
381
382     AnnotationColourGradient acg = null;
383     if (currentColours.getState())
384     {
385       acg = new AnnotationColourGradient(currentAnnotation, av
386               .getGlobalColourScheme(), aboveThreshold);
387     }
388     else
389     {
390       acg = new AnnotationColourGradient(currentAnnotation, minColour
391               .getBackground(), maxColour.getBackground(), aboveThreshold);
392     }
393
394     if (currentAnnotation.graphMin == 0f
395             && currentAnnotation.graphMax == 0f)
396     {
397       acg.predefinedColours = true;
398     }
399
400     acg.thresholdIsMinMax = thresholdIsMin.getState();
401
402     av.setGlobalColourScheme(acg);
403
404     if (av.alignment.getGroups() != null)
405     {
406       Vector allGroups = ap.av.alignment.getGroups();
407       SequenceGroup sg;
408       for (int g = 0; g < allGroups.size(); g++)
409       {
410         sg = (SequenceGroup) allGroups.elementAt(g);
411
412         if (sg.cs == null)
413         {
414           continue;
415         }
416
417         if (currentColours.getState())
418         {
419           sg.cs = new AnnotationColourGradient(currentAnnotation, sg.cs,
420                   aboveThreshold);
421         }
422         else
423         {
424           sg.cs = new AnnotationColourGradient(currentAnnotation, minColour
425                   .getBackground(), maxColour.getBackground(),
426                   aboveThreshold);
427         }
428
429       }
430     }
431
432     ap.paintAlignment(false);
433   }
434
435   void reset()
436   {
437     av.setGlobalColourScheme(oldcs);
438     if (av.alignment.getGroups() != null)
439     {
440       Vector allGroups = ap.av.alignment.getGroups();
441       SequenceGroup sg;
442       for (int g = 0; g < allGroups.size(); g++)
443       {
444         sg = (SequenceGroup) allGroups.elementAt(g);
445         Object cs = oldgroupColours.get(sg);
446         if (cs instanceof ColourSchemeI)
447         {
448           sg.cs = (ColourSchemeI) cs;
449         }
450         else
451         {
452           // probably the "null" string we set it to if it was null originally.
453           sg.cs = null;
454         }
455       }
456     }
457     ap.paintAlignment(true);
458
459   }
460
461   public void mouseClicked(MouseEvent evt)
462   {
463   }
464
465   public void mousePressed(MouseEvent evt)
466   {
467   }
468
469   public void mouseReleased(MouseEvent evt)
470   {
471     ap.paintAlignment(true);
472   }
473
474   public void mouseEntered(MouseEvent evt)
475   {
476   }
477
478   public void mouseExited(MouseEvent evt)
479   {
480   }
481
482 }