0c4e03e89f57b538279384c4f4eb2fb462f2d466
[jalview.git] / src / jalview / gui / SliderPanel.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3  * Copyright (C) $$Year-Rel$$ 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.gui;
22
23 import jalview.datamodel.SequenceGroup;
24 import jalview.jbgui.GSliderPanel;
25 import jalview.renderer.ResidueShaderI;
26 import jalview.util.MessageManager;
27
28 import java.awt.event.MouseAdapter;
29 import java.awt.event.MouseEvent;
30 import java.beans.PropertyVetoException;
31
32 import javax.swing.JInternalFrame;
33 import javax.swing.JLayeredPane;
34 import javax.swing.event.ChangeEvent;
35 import javax.swing.event.ChangeListener;
36 import javax.swing.event.InternalFrameAdapter;
37 import javax.swing.event.InternalFrameEvent;
38
39 /**
40  * DOCUMENT ME!
41  * 
42  * @author $author$
43  * @version $Revision$
44  */
45 public class SliderPanel extends GSliderPanel
46 {
47   private static final String BACKGROUND = "Background";
48
49   static JInternalFrame conservationSlider;
50
51   static JInternalFrame PIDSlider;
52
53   AlignmentPanel ap;
54
55   boolean forConservation = true;
56
57   ResidueShaderI cs;
58
59   /**
60    * Returns the currently displayed slider panel (or null if none).
61    * 
62    * @return
63    */
64   public static SliderPanel getSliderPanel()
65   {
66     if (conservationSlider != null && conservationSlider.isVisible())
67     {
68       return (SliderPanel) conservationSlider.getContentPane();
69     }
70     if (PIDSlider != null && PIDSlider.isVisible())
71     {
72       return (SliderPanel) PIDSlider.getContentPane();
73     }
74     return null;
75   }
76
77   /**
78    * Creates a new SliderPanel object.
79    * 
80    * @param ap
81    *          DOCUMENT ME!
82    * @param value
83    *          DOCUMENT ME!
84    * @param forConserve
85    *          DOCUMENT ME!
86    * @param scheme
87    *          DOCUMENT ME!
88    */
89   public SliderPanel(final AlignmentPanel ap, int value,
90           boolean forConserve, ResidueShaderI scheme)
91   {
92     this.ap = ap;
93     this.cs = scheme;
94     forConservation = forConserve;
95     undoButton.setVisible(false);
96     applyButton.setVisible(false);
97
98     if (forConservation)
99     {
100       label.setText(MessageManager
101               .getString("label.enter_value_increase_conservation_visibility"));
102       slider.setMinimum(0);
103       slider.setMaximum(100);
104     }
105     else
106     {
107       label.setText(MessageManager
108               .getString("label.enter_percentage_identity_above_which_colour_residues"));
109       slider.setMinimum(0);
110       slider.setMaximum(100);
111     }
112
113     slider.addChangeListener(new ChangeListener()
114     {
115       @Override
116       public void stateChanged(ChangeEvent evt)
117       {
118         valueField.setText(slider.getValue() + "");
119         valueChanged(slider.getValue());
120       }
121     });
122
123     slider.addMouseListener(new MouseAdapter()
124     {
125       @Override
126       public void mouseReleased(MouseEvent evt)
127       {
128         ap.paintAlignment(true);
129       }
130     });
131
132     slider.setValue(value);
133     valueField.setText(value + "");
134   }
135
136   /**
137    * Method to 'set focus' of the Conservation slider panel
138    * 
139    * @param ap
140    *          the panel to repaint on change of slider
141    * @param rs
142    *          the colour scheme to update on change of slider
143    * @param source
144    *          a text description for the panel's title
145    * 
146    * @return
147    */
148   public static int setConservationSlider(AlignmentPanel ap,
149           ResidueShaderI rs, String source)
150   {
151     SliderPanel sliderPanel = null;
152
153     if (conservationSlider == null)
154     {
155       sliderPanel = new SliderPanel(ap, rs.getConservationInc(), true, rs);
156       conservationSlider = new JInternalFrame();
157       conservationSlider.setContentPane(sliderPanel);
158       conservationSlider.setLayer(JLayeredPane.PALETTE_LAYER);
159     }
160     else
161     {
162       sliderPanel = (SliderPanel) conservationSlider.getContentPane();
163       sliderPanel.valueField.setText(String.valueOf(rs.getConservationInc()));
164       sliderPanel.cs = rs;
165       sliderPanel.ap = ap;
166       sliderPanel.slider.setValue(rs.getConservationInc());
167     }
168
169     conservationSlider.setTitle(MessageManager.formatMessage(
170             "label.conservation_colour_increment",
171             new String[] { source == null ? BACKGROUND : source }));
172
173     if (ap.av.getAlignment().getGroups() != null)
174     {
175       sliderPanel.setAllGroupsCheckEnabled(true);
176     }
177     else
178     {
179       sliderPanel.setAllGroupsCheckEnabled(false);
180     }
181
182     return sliderPanel.getValue();
183   }
184
185   /**
186    * Hides the PID slider panel if it is shown
187    */
188   public static void hidePIDSlider()
189   {
190     if (PIDSlider != null)
191     {
192       try
193       {
194         PIDSlider.setClosed(true);
195         PIDSlider = null;
196       } catch (PropertyVetoException ex)
197       {
198       }
199     }
200   }
201
202   /**
203    * Hides the conservation slider panel if it is shown
204    */
205   public static void hideConservationSlider()
206   {
207     if (conservationSlider != null)
208     {
209       try
210       {
211         conservationSlider.setClosed(true);
212         conservationSlider = null;
213       } catch (PropertyVetoException ex)
214       {
215       }
216     }
217   }
218
219   /**
220    * DOCUMENT ME!
221    */
222   public static void showConservationSlider()
223   {
224     hidePIDSlider();
225
226     if (!conservationSlider.isVisible())
227     {
228       Desktop.addInternalFrame(conservationSlider,
229               conservationSlider.getTitle(), 420, 90, false);
230       conservationSlider
231               .addInternalFrameListener(new InternalFrameAdapter()
232               {
233                 @Override
234                 public void internalFrameClosed(InternalFrameEvent e)
235                 {
236                   conservationSlider = null;
237                 }
238               });
239       conservationSlider.setLayer(JLayeredPane.PALETTE_LAYER);
240     }
241   }
242
243   /**
244    * Method to 'set focus' of the PID slider panel
245    * 
246    * @param ap
247    *          the panel to repaint on change of slider
248    * @param rs
249    *          the colour scheme to update on change of slider
250    * @param source
251    *          a text description for the panel's title
252    * 
253    * @return
254    */
255   public static int setPIDSliderSource(AlignmentPanel ap,
256           ResidueShaderI rs, String source)
257   {
258     int threshold = rs.getThreshold();
259
260     SliderPanel sliderPanel = null;
261
262     if (PIDSlider == null)
263     {
264       sliderPanel = new SliderPanel(ap, threshold, false, rs);
265       PIDSlider = new JInternalFrame();
266       PIDSlider.setContentPane(sliderPanel);
267       PIDSlider.setLayer(JLayeredPane.PALETTE_LAYER);
268     }
269     else
270     {
271       sliderPanel = (SliderPanel) PIDSlider.getContentPane();
272       sliderPanel.cs = rs;
273       sliderPanel.ap = ap;
274       sliderPanel.valueField.setText(String.valueOf(rs.getThreshold()));
275       sliderPanel.slider.setValue(rs.getThreshold());
276     }
277
278     PIDSlider.setTitle(MessageManager.formatMessage(
279             "label.percentage_identity_threshold",
280             new String[] { source == null ? BACKGROUND : source }));
281
282     if (ap.av.getAlignment().getGroups() != null)
283     {
284       sliderPanel.setAllGroupsCheckEnabled(true);
285     }
286     else
287     {
288       sliderPanel.setAllGroupsCheckEnabled(false);
289     }
290
291     return sliderPanel.getValue();
292   }
293
294   /**
295    * DOCUMENT ME!
296    * 
297    * @return
298    */
299   public static JInternalFrame showPIDSlider()
300   {
301     hideConservationSlider();
302
303     if (!PIDSlider.isVisible())
304     {
305       Desktop.addInternalFrame(PIDSlider, PIDSlider.getTitle(), 420, 90,
306               false);
307       PIDSlider.setLayer(JLayeredPane.PALETTE_LAYER);
308       PIDSlider.addInternalFrameListener(new InternalFrameAdapter()
309       {
310         @Override
311         public void internalFrameClosed(InternalFrameEvent e)
312         {
313           PIDSlider = null;
314         }
315       });
316       PIDSlider.setLayer(JLayeredPane.PALETTE_LAYER);
317     }
318     return PIDSlider;
319   }
320
321   /**
322    * Updates the colour scheme with the current (identity threshold or
323    * conservation) percentage value. Also updates all groups if 'apply to all
324    * groups' is selected.
325    * 
326    * @param percent
327    */
328   public void valueChanged(int percent)
329   {
330     if (!forConservation)
331     {
332       ap.av.setThreshold(percent);
333     }
334     updateColourScheme(percent, cs);
335
336     if (allGroupsCheck.isSelected())
337     {
338       for (SequenceGroup sg : ap.av.getAlignment().getGroups())
339       {
340         updateColourScheme(percent, sg.getGroupColourScheme());
341       }
342     }
343
344     ap.getSeqPanel().seqCanvas.repaint();
345   }
346
347   /**
348    * Updates the colour scheme (if not null) with the current (identity
349    * threshold or conservation) percentage value
350    * 
351    * @param percent
352    * @param scheme
353    */
354   protected void updateColourScheme(int percent, ResidueShaderI scheme)
355   {
356     if (scheme == null)
357     {
358       return;
359     }
360     if (forConservation)
361     {
362       scheme.setConservationInc(percent);
363     }
364     else
365     {
366       scheme.setThreshold(percent, ap.av.isIgnoreGapsConsensus());
367     }
368   }
369
370   /**
371    * DOCUMENT ME!
372    * 
373    * @param b
374    *          DOCUMENT ME!
375    */
376   public void setAllGroupsCheckEnabled(boolean b)
377   {
378     allGroupsCheck.setEnabled(b);
379   }
380
381   /**
382    * DOCUMENT ME!
383    * 
384    * @param e
385    *          DOCUMENT ME!
386    */
387   @Override
388   public void valueField_actionPerformed()
389   {
390     try
391     {
392       int i = Integer.parseInt(valueField.getText());
393       slider.setValue(i);
394     } catch (NumberFormatException ex)
395     {
396       valueField.setText(slider.getValue() + "");
397     }
398   }
399
400   /**
401    * DOCUMENT ME!
402    * 
403    * @param value
404    *          DOCUMENT ME!
405    */
406   public void setValue(int value)
407   {
408     slider.setValue(value);
409   }
410
411   /**
412    * DOCUMENT ME!
413    * 
414    * @return DOCUMENT ME!
415    */
416   public int getValue()
417   {
418     return Integer.parseInt(valueField.getText());
419   }
420
421   @Override
422   public void slider_mouseReleased(MouseEvent e)
423   {
424     if (ap.overviewPanel != null)
425     {
426       ap.overviewPanel.updateOverviewImage();
427     }
428   }
429
430   public static int getConservationValue()
431   {
432     return getValue(conservationSlider);
433   }
434
435   static int getValue(JInternalFrame slider)
436   {
437     return slider == null ? 0 : ((SliderPanel) slider.getContentPane())
438             .getValue();
439   }
440
441   public static int getPIDValue()
442   {
443     return getValue(PIDSlider);
444   }
445
446   /**
447    * Answers true if the SliderPanel is for Conservation, false if it is for PID
448    * threshold
449    * 
450    * @return
451    */
452   public boolean isForConservation()
453   {
454     return forConservation;
455   }
456
457   /**
458    * Answers the title for the slider panel; this may include 'Background' if
459    * for the alignment, or the group id if for a group
460    * 
461    * @return
462    */
463   public String getTitle()
464   {
465     String title = null;
466     if (isForConservation())
467     {
468       if (conservationSlider != null)
469       {
470         title = conservationSlider.getTitle();
471       }
472     }
473     else if (PIDSlider != null)
474     {
475       title = PIDSlider.getTitle();
476     }
477     return title;
478   }
479 }