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