1.1 compatibility
[jalview.git] / src / jalview / appletgui / FeatureColourChooser.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Development Version 2.4.1)
3  * Copyright (C) 2009 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
4  * 
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  * 
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  * 
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
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 import java.awt.Rectangle;
29
30 public class FeatureColourChooser extends Panel implements
31         ActionListener, AdjustmentListener, ItemListener, MouseListener
32 {
33   JVDialog frame;
34   Frame owner;
35   FeatureRenderer fr;
36   FeatureSettings fs = null;
37   // AlignmentPanel ap;
38
39   GraduatedColor cs;
40   Object oldcs;
41
42   Hashtable oldgroupColours;
43
44
45   boolean adjusting = false;
46   private float min,max;
47   String type=null;
48
49   private AlignFrame af=null;
50   public FeatureColourChooser(AlignFrame af, String type)
51   {
52     this.af = af;
53     init(af.getSeqcanvas().getFeatureRenderer(), type);
54   }
55   public FeatureColourChooser(FeatureSettings fsettings, String type)
56   {
57     this.fs = fsettings;
58     init(fsettings.fr, type);
59     // this.ap = fsettings.ap;
60   }
61   private void init(FeatureRenderer frenderer,String type) {
62     this.type = type;
63     fr = frenderer;
64     float mm[] = ((float[][]) fr.minmax.get(type))[0];
65     min = mm[0];
66     max = mm[1];
67     oldcs = fr.featureColours.get(type);
68     if (oldcs instanceof GraduatedColor)
69     {
70       cs = new GraduatedColor((GraduatedColor) oldcs, min, max);
71     } else {
72       // promote original color to a graduated color
73       Color bl = Color.black;
74       if (oldcs instanceof Color)
75       {
76         bl = (Color) oldcs;
77       }
78       // original colour becomes the maximum colour
79       cs = new GraduatedColor(Color.white,bl,mm[0],mm[1]);
80     }
81     minColour.setBackground(cs.getMinColor());
82     maxColour.setBackground(cs.getMaxColor());
83     colourFromLabel.setState(cs.isColourByLabel());
84     adjusting = true;
85
86     try
87     {
88       jbInit();
89     } catch (Exception ex)
90     {
91     }
92     threshold.select(cs.getThreshType()==AnnotationColourGradient.NO_THRESHOLD ? 0 : cs.getThreshType() == AnnotationColourGradient.ABOVE_THRESHOLD ? 1 : 2);
93     
94     adjusting = false;
95     changeColour();
96     colourFromLabel.addItemListener(this);
97     slider.addAdjustmentListener(this);
98     slider.addMouseListener(this);
99     owner = (af!=null) ? af : fs.frame;
100     frame = new JVDialog(owner,"Graduated Feature Colour for "+type,true,480,248);
101     frame.setMainPanel(this);
102     validate();
103     frame.setVisible(true);
104     if (frame.accept) {
105       changeColour();
106     } else {
107       // cancel
108         reset();
109         PaintRefresher.Refresh(this, fr.av.getSequenceSetId());
110         frame.setVisible(false);
111     }
112   }
113
114   public FeatureColourChooser()
115   {
116     try
117     {
118       jbInit();
119     } catch (Exception ex)
120     {
121       ex.printStackTrace();
122     }
123   }
124
125   private void jbInit() throws Exception
126   {
127     minColour.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
128     minColour.setLabel("Min Colour");
129     minColour.addActionListener(this);
130
131     maxColour.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
132     maxColour.setLabel("Max Colour");
133     maxColour.addActionListener(this);
134
135     thresholdIsMin.addItemListener(this);
136
137     this.setLayout(new GridLayout(4,1));
138     jPanel1.setLayout(new FlowLayout());
139     jPanel2.setLayout(new FlowLayout());
140     jPanel3.setLayout(new GridLayout(1,1));
141     jPanel4.setLayout(new FlowLayout());
142     jPanel1.setBackground(Color.white);
143     jPanel2.setBackground(Color.white);
144     jPanel4.setBackground(Color.white);
145     threshold.addItemListener(this);
146     threshold.addItem("No Threshold");
147     threshold.addItem("Above Threshold");
148     threshold.addItem("Below Threshold");
149     thresholdValue.addActionListener(this);
150     slider.setBackground(Color.white);
151     slider.setEnabled(false);
152     slider.setSize(new Dimension(93, 21));
153     thresholdValue.setEnabled(false);
154     thresholdValue.setSize(new Dimension(79,22)); //setBounds(new Rectangle(248, 2, 79, 22));
155     thresholdValue.setColumns(5);
156     jPanel3.setBackground(Color.white);
157     
158     colourFromLabel.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
159     colourFromLabel.setLabel("Colour by Label");
160     colourFromLabel.setSize(new Dimension(139,22));
161     //threshold.setBounds(new Rectangle(11, 3, 139, 22));
162     thresholdIsMin.setBackground(Color.white);
163     thresholdIsMin.setLabel("Threshold is min/max");
164     thresholdIsMin.setSize(new Dimension(135,23));
165     //thresholdIsMin.setBounds(new Rectangle(328, 3, 135, 23));
166     jPanel1.add(minColour);
167     jPanel1.add(maxColour);
168     jPanel1.add(colourFromLabel);
169     jPanel2.add(threshold);
170     jPanel3.add(slider);
171     jPanel4.add(thresholdValue);
172     jPanel4.add(thresholdIsMin);
173     this.add(jPanel1);//, java.awt.BorderLayout.NORTH);
174     this.add(jPanel2);//, java.awt.BorderLayout.NORTH);
175     this.add(jPanel3);//, java.awt.BorderLayout.CENTER);
176     this.add(jPanel4);//, java.awt.BorderLayout.CENTER);
177   }
178
179   Button minColour = new Button();
180
181   Button maxColour = new Button();
182
183   
184   Panel jPanel1 = new Panel();
185
186   Panel jPanel2 = new Panel();
187
188   Choice threshold = new Choice();
189
190   Panel jPanel3 = new Panel();
191   Panel jPanel4 = new Panel();
192
193   Scrollbar slider = new Scrollbar(Scrollbar.HORIZONTAL);
194
195   TextField thresholdValue = new TextField(20);
196
197
198 //  BorderLayout borderLayout1 = new BorderLayout();
199
200   Checkbox thresholdIsMin = new Checkbox();
201   Checkbox colourFromLabel = new Checkbox();
202
203   private GraphLine threshline;
204
205   public void actionPerformed(ActionEvent evt)
206   {
207     if (evt.getSource() == thresholdValue)
208     {
209       try
210       {
211         float f = new Float(thresholdValue.getText()).floatValue();
212         slider.setValue((int) (f * 1000));
213         adjustmentValueChanged(null);
214       } catch (NumberFormatException ex)
215       {
216       }
217     }
218     else if (evt.getSource() == minColour)
219     {
220       minColour_actionPerformed(null);
221     }
222     else if (evt.getSource() == maxColour)
223     {
224       maxColour_actionPerformed(null);
225     }
226     else
227     {
228       changeColour();
229     }
230   }
231
232   public void itemStateChanged(ItemEvent evt)
233   {
234     maxColour.setEnabled(!colourFromLabel.getState());
235     minColour.setEnabled(!colourFromLabel.getState());
236     changeColour();
237   }
238
239   public void adjustmentValueChanged(AdjustmentEvent evt)
240   {
241     if (!adjusting)
242     {
243       thresholdValue.setText(((float) slider.getValue() / 1000f) + "");
244       valueChanged();
245     }
246   }
247   protected void valueChanged() {
248     threshline.value = (float) slider.getValue() / 1000f;
249     cs.setThresh(threshline.value);
250     changeColour();
251     PaintRefresher.Refresh(this, fr.av.getSequenceSetId());
252     // ap.paintAlignment(false);
253   }
254   public void minColour_actionPerformed(Color newCol)
255   {
256     if (newCol == null)
257     {
258       UserDefinedColours udc = new UserDefinedColours(this,minColour.getBackground(),owner, "Select Colour for Minimum Value"); // frame.owner,
259     } else {
260       minColour.setBackground(newCol);
261       minColour.repaint();
262       changeColour();
263     }
264     
265   }
266
267   public void maxColour_actionPerformed(Color newCol)
268   {
269     if (newCol == null)
270     {
271       
272       // UserDefinedColours udc = new UserDefinedColours(this, "Select Colour for Maximum Value",maxColour.getBackground(),true);
273       UserDefinedColours udc = new UserDefinedColours(this, maxColour.getBackground(), owner, "Select Colour for Maximum Value");
274     } else {
275       maxColour.setBackground(newCol);
276       maxColour.repaint();
277       changeColour();
278     }
279   }
280
281   void changeColour()
282   {
283     // Check if combobox is still adjusting
284     if (adjusting)
285     {
286       return;
287     }
288
289     int aboveThreshold = AnnotationColourGradient.NO_THRESHOLD;
290     if (threshold.getSelectedItem().equals("Above Threshold"))
291     {
292       aboveThreshold = AnnotationColourGradient.ABOVE_THRESHOLD;
293     }
294     else if (threshold.getSelectedItem().equals("Below Threshold"))
295     {
296       aboveThreshold = AnnotationColourGradient.BELOW_THRESHOLD;
297     }
298
299     slider.setEnabled(true);
300     thresholdValue.setEnabled(true);
301     GraduatedColor acg = new GraduatedColor(minColour.getBackground(), maxColour.getBackground(), min, max);
302
303     acg.setColourByLabel(colourFromLabel.getState());
304     maxColour.setEnabled(!colourFromLabel.getState());
305     minColour.setEnabled(!colourFromLabel.getState());
306     if (aboveThreshold == AnnotationColourGradient.NO_THRESHOLD)
307     {
308       slider.setEnabled(false);
309       thresholdValue.setEnabled(false);
310       thresholdValue.setText("");
311     }
312     
313     else if (aboveThreshold != AnnotationColourGradient.NO_THRESHOLD
314             && threshline == null)
315     {
316       // todo visual indication of feature threshold
317       threshline = new jalview.datamodel.GraphLine(
318                       (max - min) / 2f,
319                       "Threshold", Color.black);
320     }
321
322     if (aboveThreshold != AnnotationColourGradient.NO_THRESHOLD)
323     {
324       adjusting = true;
325       acg.setThresh(threshline.value);
326
327       float range = max * 1000f
328               - min * 1000f;
329
330       slider.setMinimum((int) (min * 1000));
331       slider.setMaximum((int) (max * 1000));
332       slider.setValue((int) (threshline.value * 1000));
333       thresholdValue.setText(threshline.value + "");
334       slider.setEnabled(true);
335       thresholdValue.setEnabled(true);
336       adjusting = false;
337     }
338
339     acg.setThreshType(aboveThreshold);
340     if (thresholdIsMin.getState() && aboveThreshold != AnnotationColourGradient.NO_THRESHOLD)
341     {
342       if (aboveThreshold==AnnotationColourGradient.ABOVE_THRESHOLD)
343       { 
344         acg = new GraduatedColor(acg, threshline.value, max);
345       } else { 
346         acg = new GraduatedColor(acg, min,threshline.value);
347       }
348     }
349     
350     fr.featureColours.put(type,acg);
351     cs = acg;
352     PaintRefresher.Refresh(this, fr.av.getSequenceSetId());
353     // ap.paintAlignment(false);
354   }
355
356   void reset()
357   {
358     fr.featureColours.put(type, oldcs);
359     PaintRefresher.Refresh(this, fr.av.getSequenceSetId());
360     // ap.paintAlignment(true);
361
362   }
363
364   public void mouseClicked(MouseEvent evt)
365   {
366   }
367
368   public void mousePressed(MouseEvent evt)
369   {
370   }
371
372   public void mouseReleased(MouseEvent evt)
373   {
374     PaintRefresher.Refresh(this, fr.av.getSequenceSetId());
375     // ap.paintAlignment(true);
376   }
377
378   public void mouseEntered(MouseEvent evt)
379   {
380   }
381
382   public void mouseExited(MouseEvent evt)
383   {
384   }
385
386 }