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