JAL-1432 updated copyright notices
[jalview.git] / src / jalview / appletgui / AnnotationColourChooser.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.0b1)
3  * Copyright (C) 2014 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 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  * The Jalview Authors are detailed in the 'AUTHORS' file.
18  */
19 package jalview.appletgui;
20
21 import java.util.*;
22
23 import java.awt.*;
24 import java.awt.event.*;
25
26 import jalview.datamodel.*;
27 import jalview.schemes.*;
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.getAlignment().getGroups() != null)
57     {
58       oldgroupColours = new Hashtable();
59       for (SequenceGroup sg : ap.av.getAlignment().getGroups())
60       {
61         if (sg.cs != null)
62         {
63           oldgroupColours.put(sg, sg.cs);
64         }
65         else
66         {
67           oldgroupColours.put(sg, "null");
68         }
69       }
70     }
71     this.av = av;
72     this.ap = ap;
73
74     slider.addAdjustmentListener(this);
75     slider.addMouseListener(this);
76
77     if (av.getAlignment().getAlignmentAnnotation() == null)
78     {
79       return;
80     }
81
82     setDefaultMinMax();
83
84     if (oldcs instanceof AnnotationColourGradient)
85     {
86       AnnotationColourGradient acg = (AnnotationColourGradient) oldcs;
87       currentColours.setState(acg.predefinedColours);
88       if (!acg.predefinedColours)
89       {
90         minColour.setBackground(acg.getMinColour());
91         maxColour.setBackground(acg.getMaxColour());
92       }
93     }
94
95     adjusting = true;
96
97     Vector list = new Vector();
98     int index = 1;
99     for (int i = 0; i < av.getAlignment().getAlignmentAnnotation().length; i++)
100     {
101       String label = av.getAlignment().getAlignmentAnnotation()[i].label;
102       if (!list.contains(label))
103         list.addElement(label);
104       else
105         list.addElement(label + "_" + (index++));
106     }
107
108     for (int i = 0; i < list.size(); i++)
109     {
110       annotations.addItem(list.elementAt(i).toString());
111     }
112
113     threshold.addItem("No Threshold");
114     threshold.addItem("Above Threshold");
115     threshold.addItem("Below Threshold");
116
117     if (oldcs instanceof AnnotationColourGradient)
118     {
119       AnnotationColourGradient acg = (AnnotationColourGradient) oldcs;
120       annotations.select(acg.getAnnotation());
121       switch (acg.getAboveThreshold())
122       {
123       case AnnotationColourGradient.NO_THRESHOLD:
124         threshold.select("No Threshold");
125         break;
126       case AnnotationColourGradient.ABOVE_THRESHOLD:
127         threshold.select("Above Threshold");
128         break;
129       case AnnotationColourGradient.BELOW_THRESHOLD:
130         threshold.select("Below Threshold");
131         break;
132       default:
133         throw new Error(
134                 "Implementation error: don't know about threshold setting for current AnnotationColourGradient.");
135       }
136       thresholdIsMin.setState(acg.thresholdIsMinMax);
137       thresholdValue.setText("" + acg.getAnnotationThreshold());
138     }
139
140     adjusting = false;
141
142     changeColour();
143
144     frame = new Frame();
145     frame.add(this);
146     jalview.bin.JalviewLite.addFrame(frame, "Colour by Annotation", 560,
147             175);
148     validate();
149   }
150
151   private void setDefaultMinMax()
152   {
153     minColour.setBackground(av.applet.getDefaultColourParameter(
154             "ANNOTATIONCOLOUR_MIN", Color.orange));
155     maxColour.setBackground(av.applet.getDefaultColourParameter(
156             "ANNOTATIONCOLOUR_MAX", Color.red));
157
158   }
159
160   public AnnotationColourChooser()
161   {
162     try
163     {
164       jbInit();
165     } catch (Exception ex)
166     {
167       ex.printStackTrace();
168     }
169   }
170
171   private void jbInit() throws Exception
172   {
173     minColour.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
174     minColour.setLabel("Min Colour");
175     minColour.addActionListener(this);
176
177     maxColour.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
178     maxColour.setLabel("Max Colour");
179     maxColour.addActionListener(this);
180
181     thresholdIsMin.addItemListener(this);
182     ok.setLabel("OK");
183     ok.addActionListener(this);
184
185     cancel.setLabel("Cancel");
186     cancel.addActionListener(this);
187
188     defColours.setLabel("Defaults");
189     defColours.addActionListener(this);
190
191     annotations.addItemListener(this);
192
193     thresholdValue.addActionListener(this);
194     slider.setBackground(Color.white);
195     slider.setPreferredSize(new Dimension(193, 21));
196     slider.setEnabled(false);
197     thresholdValue.setPreferredSize(new Dimension(79, 22));
198     thresholdValue.setEnabled(false);
199     thresholdValue.setColumns(5);
200     currentColours.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
201     currentColours.setLabel("Use Original Colours");
202     currentColours.addItemListener(this);
203
204     thresholdIsMin.setBackground(Color.white);
205     thresholdIsMin.setLabel("Threshold is min/max");
206
207     this.setLayout(borderLayout1);
208
209     jPanel1.setBackground(Color.white);
210
211     jPanel2.setLayout(new FlowLayout());
212     jPanel2.setBackground(Color.white);
213     threshold.addItemListener(this);
214     jPanel3.setLayout(new FlowLayout());
215     jPanel3.setBackground(Color.white);
216     Panel jPanel4 = new Panel();
217     jPanel4.setLayout(new BorderLayout());
218     jPanel4.setBackground(Color.white);
219
220     jPanel1.add(ok);
221     jPanel1.add(cancel);
222
223     jPanel2.add(annotations);
224     jPanel2.add(currentColours);
225     jPanel2.add(minColour);
226     jPanel2.add(maxColour);
227
228     jPanel4.add(thresholdIsMin, BorderLayout.WEST);
229     jPanel4.add(slider, BorderLayout.CENTER);
230     jPanel4.add(thresholdValue, BorderLayout.EAST);
231
232     Panel jPanel34 = new Panel();
233     jPanel34.setLayout(new BorderLayout());
234     jPanel34.setBackground(Color.white);
235     jPanel34.add(jPanel2, BorderLayout.NORTH);
236     jPanel34.add(threshold, BorderLayout.WEST);
237     jPanel3.add(defColours);
238     jPanel34.add(jPanel3, BorderLayout.EAST);
239     jPanel34.add(jPanel4, BorderLayout.SOUTH);
240
241     this.add(jPanel34, java.awt.BorderLayout.CENTER);
242     this.add(jPanel1, java.awt.BorderLayout.SOUTH);
243
244   }
245
246   Choice annotations = new Choice();
247
248   Button minColour = new Button();
249
250   Button maxColour = new Button();
251
252   Button ok = new Button();
253
254   Button cancel = new Button();
255
256   Button defColours = new Button();
257
258   Panel jPanel1 = new Panel();
259
260   Panel jPanel2 = new Panel();
261
262   Choice threshold = new Choice();
263
264   FlowLayout flowLayout1 = new FlowLayout();
265
266   Panel jPanel3 = new Panel();
267
268   Scrollbar slider = new Scrollbar(Scrollbar.HORIZONTAL);
269
270   TextField thresholdValue = new TextField(20);
271
272   Checkbox currentColours = new Checkbox();
273
274   BorderLayout borderLayout1 = new BorderLayout();
275
276   Checkbox thresholdIsMin = new Checkbox();
277
278   public void actionPerformed(ActionEvent evt)
279   {
280     if (evt.getSource() == thresholdValue)
281     {
282       try
283       {
284         float f = new Float(thresholdValue.getText()).floatValue();
285         slider.setValue((int) (f * 1000));
286         adjustmentValueChanged(null);
287       } catch (NumberFormatException ex)
288       {
289       }
290     }
291     else if (evt.getSource() == minColour)
292     {
293       minColour_actionPerformed(null);
294     }
295     else if (evt.getSource() == maxColour)
296     {
297       maxColour_actionPerformed(null);
298     }
299     else if (evt.getSource() == defColours)
300     {
301       defColour_actionPerformed();
302     }
303     else if (evt.getSource() == ok)
304     {
305       changeColour();
306       frame.setVisible(false);
307     }
308     else if (evt.getSource() == cancel)
309     {
310       reset();
311       ap.paintAlignment(true);
312       frame.setVisible(false);
313     }
314
315     else
316     {
317       changeColour();
318     }
319   }
320
321   public void itemStateChanged(ItemEvent evt)
322   {
323     if (evt.getSource() == currentColours)
324     {
325       if (currentColours.getState())
326       {
327         reset();
328       }
329
330       maxColour.setEnabled(!currentColours.getState());
331       minColour.setEnabled(!currentColours.getState());
332
333     }
334
335     changeColour();
336   }
337
338   public void adjustmentValueChanged(AdjustmentEvent evt)
339   {
340     if (!adjusting)
341     {
342       thresholdValue.setText(((float) slider.getValue() / 1000f) + "");
343       if (currentColours.getState()
344               && !(av.getGlobalColourScheme() instanceof AnnotationColourGradient))
345       {
346         changeColour();
347       }
348
349       currentAnnotation.threshold.value = (float) slider.getValue() / 1000f;
350       ap.paintAlignment(false);
351     }
352   }
353
354   public void minColour_actionPerformed(Color newCol)
355   {
356     if (newCol != null)
357     {
358       minColour.setBackground(newCol);
359       minColour.repaint();
360       changeColour();
361     }
362     else
363     {
364       new UserDefinedColours(this, "Min Colour", minColour.getBackground());
365     }
366
367   }
368
369   public void maxColour_actionPerformed(Color newCol)
370   {
371     if (newCol != null)
372     {
373       maxColour.setBackground(newCol);
374       maxColour.repaint();
375       changeColour();
376     }
377     else
378     {
379       new UserDefinedColours(this, "Max Colour", maxColour.getBackground());
380     }
381   }
382
383   public void defColour_actionPerformed()
384   {
385     setDefaultMinMax();
386     minColour.repaint();
387     maxColour.repaint();
388     changeColour();
389   }
390
391   void changeColour()
392   {
393     // Check if combobox is still adjusting
394     if (adjusting)
395     {
396       return;
397     }
398
399     currentAnnotation = av.getAlignment().getAlignmentAnnotation()[annotations
400             .getSelectedIndex()];
401
402     int aboveThreshold = -1;
403     if (threshold.getSelectedItem().equals("Above Threshold"))
404     {
405       aboveThreshold = AnnotationColourGradient.ABOVE_THRESHOLD;
406     }
407     else if (threshold.getSelectedItem().equals("Below Threshold"))
408     {
409       aboveThreshold = AnnotationColourGradient.BELOW_THRESHOLD;
410     }
411
412     slider.setEnabled(true);
413     thresholdValue.setEnabled(true);
414     thresholdIsMin.setEnabled(true);
415
416     if (aboveThreshold == AnnotationColourGradient.NO_THRESHOLD)
417     {
418       slider.setEnabled(false);
419       thresholdValue.setEnabled(false);
420       thresholdIsMin.setEnabled(false);
421       thresholdValue.setText("");
422     }
423     else if (aboveThreshold != AnnotationColourGradient.NO_THRESHOLD
424             && currentAnnotation.threshold == null)
425     {
426       currentAnnotation
427               .setThreshold(new jalview.datamodel.GraphLine(
428                       (currentAnnotation.graphMax - currentAnnotation.graphMin) / 2f,
429                       "Threshold", Color.black));
430     }
431
432     if (aboveThreshold != AnnotationColourGradient.NO_THRESHOLD)
433     {
434       adjusting = true;
435
436       slider.setMinimum((int) (currentAnnotation.graphMin * 1000));
437       slider.setMaximum((int) (currentAnnotation.graphMax * 1000));
438       slider.setValue((int) (currentAnnotation.threshold.value * 1000));
439       thresholdValue.setText(currentAnnotation.threshold.value + "");
440       slider.setEnabled(true);
441       thresholdValue.setEnabled(true);
442       adjusting = false;
443     }
444
445     AnnotationColourGradient acg = null;
446     if (currentColours.getState())
447     {
448       acg = new AnnotationColourGradient(currentAnnotation,
449               av.getGlobalColourScheme(), aboveThreshold);
450     }
451     else
452     {
453       acg = new AnnotationColourGradient(currentAnnotation,
454               minColour.getBackground(), maxColour.getBackground(),
455               aboveThreshold);
456     }
457
458     if (currentAnnotation.graphMin == 0f
459             && currentAnnotation.graphMax == 0f)
460     {
461       acg.predefinedColours = true;
462     }
463
464     acg.thresholdIsMinMax = thresholdIsMin.getState();
465
466     av.setGlobalColourScheme(acg);
467
468     if (av.getAlignment().getGroups() != null)
469     {
470       for (SequenceGroup sg : ap.av.getAlignment().getGroups())
471       {
472
473         if (sg.cs == null)
474         {
475           continue;
476         }
477
478         if (currentColours.getState())
479         {
480           sg.cs = new AnnotationColourGradient(currentAnnotation, sg.cs,
481                   aboveThreshold);
482         }
483         else
484         {
485           sg.cs = new AnnotationColourGradient(currentAnnotation,
486                   minColour.getBackground(), maxColour.getBackground(),
487                   aboveThreshold);
488         }
489
490       }
491     }
492
493     // update colours in linked windows
494     ap.paintAlignment(true);
495   }
496
497   void reset()
498   {
499     av.setGlobalColourScheme(oldcs);
500     if (av.getAlignment().getGroups() != null)
501     {
502       for (SequenceGroup sg : ap.av.getAlignment().getGroups())
503       {
504         Object cs = oldgroupColours.get(sg);
505         if (cs instanceof ColourSchemeI)
506         {
507           sg.cs = (ColourSchemeI) cs;
508         }
509         else
510         {
511           // probably the "null" string we set it to if it was null originally.
512           sg.cs = null;
513         }
514       }
515     }
516     ap.paintAlignment(true);
517
518   }
519
520   public void mouseClicked(MouseEvent evt)
521   {
522   }
523
524   public void mousePressed(MouseEvent evt)
525   {
526   }
527
528   public void mouseReleased(MouseEvent evt)
529   {
530     ap.paintAlignment(true);
531   }
532
533   public void mouseEntered(MouseEvent evt)
534   {
535   }
536
537   public void mouseExited(MouseEvent evt)
538   {
539   }
540
541 }