JAL-3161 limit tooltip and status updates to visible columns
[jalview.git] / src / jalview / appletgui / 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.appletgui;
22
23 import jalview.analysis.Conservation;
24 import jalview.datamodel.SequenceGroup;
25 import jalview.renderer.ResidueShaderI;
26 import jalview.util.MessageManager;
27
28 import java.awt.BorderLayout;
29 import java.awt.Button;
30 import java.awt.Checkbox;
31 import java.awt.Color;
32 import java.awt.FlowLayout;
33 import java.awt.Frame;
34 import java.awt.Label;
35 import java.awt.Panel;
36 import java.awt.Scrollbar;
37 import java.awt.TextField;
38 import java.awt.event.ActionEvent;
39 import java.awt.event.ActionListener;
40 import java.awt.event.AdjustmentEvent;
41 import java.awt.event.AdjustmentListener;
42 import java.awt.event.FocusAdapter;
43 import java.awt.event.FocusEvent;
44 import java.awt.event.MouseEvent;
45 import java.awt.event.MouseListener;
46 import java.awt.event.WindowAdapter;
47 import java.awt.event.WindowEvent;
48 import java.util.List;
49
50 public class SliderPanel extends Panel
51         implements ActionListener, AdjustmentListener, MouseListener
52 {
53   private static final String BACKGROUND = "Background";
54
55   AlignmentPanel ap;
56
57   boolean forConservation = true;
58
59   ResidueShaderI cs;
60
61   static Frame conservationSlider;
62
63   static Frame PIDSlider;
64
65   public static int setConservationSlider(AlignmentPanel ap,
66           ResidueShaderI ccs, String source)
67   {
68     SliderPanel sp = null;
69
70     if (conservationSlider == null)
71     {
72       sp = new SliderPanel(ap, ccs.getConservationInc(), true, ccs);
73       conservationSlider = new Frame();
74       conservationSlider.add(sp);
75     }
76     else
77     {
78       sp = (SliderPanel) conservationSlider.getComponent(0);
79       sp.cs = ccs;
80       sp.valueField.setText(String.valueOf(ccs.getConservationInc()));
81     }
82
83     conservationSlider.setTitle(MessageManager.formatMessage(
84             "label.conservation_colour_increment", new String[]
85             { source == null ? BACKGROUND : source }));
86     List<SequenceGroup> groups = ap.av.getAlignment().getGroups();
87     if (groups != null && !groups.isEmpty())
88     {
89       sp.setAllGroupsCheckEnabled(true);
90     }
91     else
92     {
93       sp.setAllGroupsCheckEnabled(false);
94     }
95
96     return sp.getValue();
97   }
98
99   public static void showConservationSlider()
100   {
101     try
102     {
103       PIDSlider.setVisible(false);
104       PIDSlider = null;
105     } catch (Exception ex)
106     {
107     }
108
109     if (!conservationSlider.isVisible())
110     {
111       jalview.bin.JalviewLite.addFrame(conservationSlider,
112               conservationSlider.getTitle(), 420, 100);
113       conservationSlider.addWindowListener(new WindowAdapter()
114       {
115         @Override
116         public void windowClosing(WindowEvent e)
117         {
118           conservationSlider = null;
119         }
120       });
121
122     }
123
124   }
125
126   public static int setPIDSliderSource(AlignmentPanel ap,
127           ResidueShaderI ccs, String source)
128   {
129     SliderPanel pid = null;
130     if (PIDSlider == null)
131     {
132       pid = new SliderPanel(ap, ccs.getThreshold(), false, ccs);
133       PIDSlider = new Frame();
134       PIDSlider.add(pid);
135     }
136     else
137     {
138       pid = (SliderPanel) PIDSlider.getComponent(0);
139       pid.cs = ccs;
140       pid.valueField.setText(String.valueOf(ccs.getThreshold()));
141     }
142     PIDSlider.setTitle(MessageManager.formatMessage(
143             "label.percentage_identity_threshold", new String[]
144             { source == null ? BACKGROUND : source }));
145
146     if (ap.av.getAlignment().getGroups() != null)
147     {
148       pid.setAllGroupsCheckEnabled(true);
149     }
150     else
151     {
152       pid.setAllGroupsCheckEnabled(false);
153     }
154
155     return pid.getValue();
156
157   }
158
159   public static void showPIDSlider()
160   {
161     try
162     {
163       conservationSlider.setVisible(false);
164       conservationSlider = null;
165     } catch (Exception ex)
166     {
167     }
168
169     if (!PIDSlider.isVisible())
170     {
171       jalview.bin.JalviewLite.addFrame(PIDSlider, PIDSlider.getTitle(), 420,
172               100);
173       PIDSlider.addWindowListener(new WindowAdapter()
174       {
175         @Override
176         public void windowClosing(WindowEvent e)
177         {
178           PIDSlider = null;
179         }
180       });
181     }
182
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       PIDSlider.setVisible(false);
193       PIDSlider = null;
194     }
195   }
196
197   /**
198    * Hides the Conservation slider panel if it is shown
199    */
200   public static void hideConservationSlider()
201   {
202     if (conservationSlider != null)
203     {
204       conservationSlider.setVisible(false);
205       conservationSlider = null;
206     }
207   }
208
209   public SliderPanel(AlignmentPanel ap, int value, boolean forConserve,
210           ResidueShaderI shader)
211   {
212     try
213     {
214       jbInit();
215     } catch (Exception e)
216     {
217       e.printStackTrace();
218     }
219     this.ap = ap;
220     this.cs = shader;
221     forConservation = forConserve;
222     undoButton.setVisible(false);
223     applyButton.setVisible(false);
224     if (forConservation)
225     {
226       label.setText(MessageManager
227               .getString("label.modify_conservation_visibility"));
228       slider.setMinimum(0);
229       slider.setMaximum(50 + slider.getVisibleAmount());
230       slider.setUnitIncrement(1);
231     }
232     else
233     {
234       label.setText(MessageManager
235               .getString("label.colour_residues_above_occurrence"));
236       slider.setMinimum(0);
237       slider.setMaximum(100 + slider.getVisibleAmount());
238       slider.setBlockIncrement(1);
239     }
240
241     slider.addAdjustmentListener(this);
242     slider.addMouseListener(this);
243
244     slider.setValue(value);
245     valueField.setText(value + "");
246   }
247
248   public void valueChanged(int i)
249   {
250     if (cs == null)
251     {
252       return;
253     }
254     if (forConservation)
255     {
256       cs.setConservationApplied(true);
257       cs.setConservationInc(i);
258     }
259     else
260     {
261       cs.setThreshold(i, ap.av.isIgnoreGapsConsensus());
262     }
263
264     if (allGroupsCheck.getState())
265     {
266       for (SequenceGroup group : ap.av.getAlignment().getGroups())
267       {
268         ResidueShaderI groupColourScheme = group.getGroupColourScheme();
269         if (forConservation)
270         {
271           if (!groupColourScheme.conservationApplied())
272           {
273             /*
274              * first time the colour scheme has had Conservation shading applied
275              * - compute conservation
276              */
277             Conservation c = new Conservation("Group",
278                     group.getSequences(null), group.getStartRes(),
279                     group.getEndRes());
280             c.calculate();
281             c.verdict(false, ap.av.getConsPercGaps());
282             group.cs.setConservation(c);
283
284           }
285           groupColourScheme.setConservationApplied(true);
286           groupColourScheme.setConservationInc(i);
287         }
288         else
289         {
290           groupColourScheme.setThreshold(i, ap.av.isIgnoreGapsConsensus());
291         }
292       }
293     }
294
295     ap.seqPanel.seqCanvas.repaint();
296   }
297
298   public void setAllGroupsCheckEnabled(boolean b)
299   {
300     allGroupsCheck.setState(ap.av.getColourAppliesToAllGroups());
301     allGroupsCheck.setEnabled(b);
302   }
303
304   @Override
305   public void actionPerformed(ActionEvent evt)
306   {
307     if (evt.getSource() == applyButton)
308     {
309       applyButton_actionPerformed();
310     }
311     else if (evt.getSource() == undoButton)
312     {
313       undoButton_actionPerformed();
314     }
315     else if (evt.getSource() == valueField)
316     {
317       valueField_actionPerformed();
318     }
319   }
320
321   @Override
322   public void adjustmentValueChanged(AdjustmentEvent evt)
323   {
324     valueField.setText(slider.getValue() + "");
325     valueChanged(slider.getValue());
326   }
327
328   public void valueField_actionPerformed()
329   {
330     try
331     {
332       int i = Integer.valueOf(valueField.getText());
333       slider.setValue(i);
334     } catch (NumberFormatException ex)
335     {
336       valueField.setText(String.valueOf(slider.getValue()));
337     }
338   }
339
340   public void setValue(int value)
341   {
342     slider.setValue(value);
343   }
344
345   public int getValue()
346   {
347     return Integer.parseInt(valueField.getText());
348   }
349
350   // this is used for conservation colours, PID colours and redundancy threshold
351   protected Scrollbar slider = new Scrollbar();
352
353   protected TextField valueField = new TextField();
354
355   protected Label label = new Label();
356
357   Panel jPanel1 = new Panel();
358
359   Panel jPanel2 = new Panel();
360
361   protected Button applyButton = new Button();
362
363   protected Button undoButton = new Button();
364
365   FlowLayout flowLayout1 = new FlowLayout();
366
367   protected Checkbox allGroupsCheck = new Checkbox();
368
369   BorderLayout borderLayout1 = new BorderLayout();
370
371   BorderLayout borderLayout2 = new BorderLayout();
372
373   FlowLayout flowLayout2 = new FlowLayout();
374
375   private void jbInit() throws Exception
376   {
377     this.setLayout(borderLayout2);
378
379     // slider.setMajorTickSpacing(10);
380     // slider.setMinorTickSpacing(1);
381     // slider.setPaintTicks(true);
382     slider.setBackground(Color.white);
383     slider.setFont(new java.awt.Font("Verdana", 0, 11));
384     slider.setOrientation(0);
385     valueField.setFont(new java.awt.Font("Verdana", 0, 11));
386     valueField.setText("   ");
387     valueField.addActionListener(this);
388     valueField.setColumns(3);
389     valueField.addFocusListener(new FocusAdapter()
390     {
391       @Override
392       public void focusLost(FocusEvent e)
393       {
394         valueField_actionPerformed();
395         valueChanged(slider.getValue());
396       }
397     });
398
399     label.setFont(new java.awt.Font("Verdana", 0, 11));
400     label.setText(MessageManager.getString("label.set_this_label_text"));
401     jPanel1.setLayout(borderLayout1);
402     jPanel2.setLayout(flowLayout1);
403     applyButton.setFont(new java.awt.Font("Verdana", 0, 11));
404     applyButton.setLabel(MessageManager.getString("action.apply"));
405     applyButton.addActionListener(this);
406     undoButton.setEnabled(false);
407     undoButton.setFont(new java.awt.Font("Verdana", 0, 11));
408     undoButton.setLabel(MessageManager.getString("action.undo"));
409     undoButton.addActionListener(this);
410     allGroupsCheck.setEnabled(false);
411     allGroupsCheck.setFont(new java.awt.Font("Verdana", 0, 11));
412     allGroupsCheck.setLabel(
413             MessageManager.getString("action.apply_threshold_all_groups"));
414     allGroupsCheck
415             .setName(MessageManager.getString("action.apply_all_groups"));
416     this.setBackground(Color.white);
417     this.setForeground(Color.black);
418     jPanel2.add(label, null);
419     jPanel2.add(applyButton, null);
420     jPanel2.add(undoButton, null);
421     jPanel2.add(allGroupsCheck);
422     jPanel1.add(valueField, java.awt.BorderLayout.EAST);
423     jPanel1.add(slider, java.awt.BorderLayout.CENTER);
424     this.add(jPanel1, java.awt.BorderLayout.SOUTH);
425     this.add(jPanel2, java.awt.BorderLayout.CENTER);
426   }
427
428   protected void applyButton_actionPerformed()
429   {
430   }
431
432   protected void undoButton_actionPerformed()
433   {
434   }
435
436   @Override
437   public void mousePressed(MouseEvent evt)
438   {
439   }
440
441   @Override
442   public void mouseReleased(MouseEvent evt)
443   {
444     ap.paintAlignment(true, true);
445   }
446
447   @Override
448   public void mouseClicked(MouseEvent evt)
449   {
450   }
451
452   @Override
453   public void mouseEntered(MouseEvent evt)
454   {
455   }
456
457   @Override
458   public void mouseExited(MouseEvent evt)
459   {
460   }
461 }