JAL-2089 patch broken merge to master for Release 2.10.0b1
[jalview.git] / src / jalview / appletgui / UserDefinedColours.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.api.FeatureColourI;
24 import jalview.datamodel.SequenceGroup;
25 import jalview.schemes.ColourSchemeI;
26 import jalview.schemes.FeatureColour;
27 import jalview.schemes.ResidueProperties;
28 import jalview.schemes.UserColourScheme;
29 import jalview.util.MessageManager;
30
31 import java.awt.Button;
32 import java.awt.Color;
33 import java.awt.Component;
34 import java.awt.Container;
35 import java.awt.Dialog;
36 import java.awt.Font;
37 import java.awt.Frame;
38 import java.awt.GridLayout;
39 import java.awt.Label;
40 import java.awt.Panel;
41 import java.awt.Rectangle;
42 import java.awt.Scrollbar;
43 import java.awt.TextField;
44 import java.awt.event.ActionEvent;
45 import java.awt.event.ActionListener;
46 import java.awt.event.AdjustmentEvent;
47 import java.awt.event.AdjustmentListener;
48 import java.awt.event.FocusEvent;
49 import java.awt.event.FocusListener;
50 import java.awt.event.MouseEvent;
51 import java.util.Vector;
52
53 public class UserDefinedColours extends Panel implements ActionListener,
54         AdjustmentListener, FocusListener
55 {
56
57   AlignmentPanel ap;
58
59   SequenceGroup seqGroup;
60
61   Button selectedButton;
62
63   Vector<Color> oldColours = new Vector<Color>();
64
65   ColourSchemeI oldColourScheme;
66
67   Frame frame;
68
69   MCview.AppletPDBCanvas pdbcanvas;
70
71   AppletJmol jmol;
72
73   Dialog dialog;
74
75   Object caller;
76
77   String originalLabel;
78
79   FeatureColourI originalColour;
80
81   int R = 0, G = 0, B = 0;
82
83   public ColourSchemeI loadDefaultColours()
84   {
85     // NOT IMPLEMENTED YET IN APPLET VERSION
86     return null;
87   }
88
89   public UserDefinedColours(AlignmentPanel ap, SequenceGroup sg)
90   {
91     this.ap = ap;
92     seqGroup = sg;
93
94     if (seqGroup != null)
95     {
96       oldColourScheme = seqGroup.cs;
97     }
98     else
99     {
100       oldColourScheme = ap.av.getGlobalColourScheme();
101     }
102
103     init();
104   }
105
106   public UserDefinedColours(MCview.AppletPDBCanvas pdb)
107   {
108     this.pdbcanvas = pdb;
109     init();
110   }
111
112   public UserDefinedColours(AppletJmol jmol)
113   {
114     this.jmol = jmol;
115     init();
116   }
117
118   public UserDefinedColours(FeatureRenderer fr, Frame alignframe)
119   {
120     caller = fr;
121     originalColour = new FeatureColour(fr.colourPanel.getBackground());
122     originalLabel = "Feature Colour";
123     setForDialog("Select Feature Colour", alignframe);
124     setTargetColour(fr.colourPanel.getBackground());
125     dialog.setVisible(true);
126   }
127
128   public UserDefinedColours(Component caller, Color col1, Frame alignframe)
129   {
130     this(caller, col1, alignframe, "Select Colour");
131   }
132
133   /**
134    * Makes a dialog to choose the colour
135    * 
136    * @param caller
137    *          - handles events
138    * @param col
139    *          - original colour
140    * @param alignframe
141    *          - the parent Frame for the dialog
142    * @param title
143    *          - window title
144    */
145   public UserDefinedColours(Component caller, Color col, Frame alignframe,
146           String title)
147   {
148     this.caller = caller;
149     originalColour = new FeatureColour(col);
150     originalLabel = title;
151     setForDialog(title, alignframe);
152     setTargetColour(col);
153     dialog.setVisible(true);
154   }
155
156   /**
157    * feature colour chooser
158    * 
159    * @param caller
160    * @param label
161    * @param colour
162    */
163   public UserDefinedColours(Object caller, String label, Color colour)
164   {
165     this(caller, label, new FeatureColour(colour), colour);
166   }
167
168   /**
169    * feature colour chooser when changing style to single color
170    * 
171    * @param me
172    * @param type
173    * @param graduatedColor
174    */
175   public UserDefinedColours(FeatureSettings me, String type,
176           FeatureColourI graduatedColor)
177   {
178     this(me, type, graduatedColor, graduatedColor.getMaxColour());
179   }
180
181   private UserDefinedColours(Object caller, String label,
182           FeatureColourI ocolour, Color colour)
183   {
184     this.caller = caller;
185     originalColour = ocolour;
186     originalLabel = label;
187     init();
188     remove(buttonPanel);
189
190     setTargetColour(colour);
191
192     okcancelPanel.setBounds(new Rectangle(0, 113, 400, 35));
193     frame.setTitle(MessageManager.getString("label.user_defined_colours")
194             + " - " + label);
195     frame.setSize(420, 200);
196   }
197
198   void setForDialog(String title, Container alignframe)
199   {
200     init();
201     frame.setVisible(false);
202     remove(buttonPanel);
203     if (alignframe instanceof Frame)
204     {
205       dialog = new Dialog((Frame) alignframe, title, true);
206     }
207     else
208     {
209       // if (alignframe instanceof JVDialog){
210       // // not 1.1 compatible!
211       // dialog = new Dialog(((JVDialog)alignframe), title, true);
212       // } else {
213       throw new Error(
214               MessageManager
215                       .getString("label.error_unsupported_owwner_user_colour_scheme"));
216     }
217
218     dialog.add(this);
219     this.setSize(400, 123);
220     okcancelPanel.setBounds(new Rectangle(0, 123, 400, 35));
221     int height = 160 + alignframe.getInsets().top + getInsets().bottom;
222     int width = 400;
223
224     dialog.setBounds(alignframe.getBounds().x
225             + (alignframe.getSize().width - width) / 2,
226             alignframe.getBounds().y
227                     + (alignframe.getSize().height - height) / 2, width,
228             height);
229
230   }
231
232   @Override
233   public void actionPerformed(ActionEvent evt)
234   {
235     final Object source = evt.getSource();
236     if (source == okButton)
237     {
238       okButton_actionPerformed();
239     }
240     else if (source == applyButton)
241     {
242       applyButton_actionPerformed();
243     }
244     else if (source == cancelButton)
245     {
246       cancelButton_actionPerformed();
247     }
248     else if (source == rText)
249     {
250       rText_actionPerformed();
251     }
252     else if (source == gText)
253     {
254       gText_actionPerformed();
255     }
256     else if (source == bText)
257     {
258       bText_actionPerformed();
259     }
260   }
261
262   @Override
263   public void adjustmentValueChanged(AdjustmentEvent evt)
264   {
265     if (evt.getSource() == rScroller)
266     {
267       rScroller_adjustmentValueChanged();
268     }
269     else if (evt.getSource() == gScroller)
270     {
271       gScroller_adjustmentValueChanged();
272     }
273     else if (evt.getSource() == bScroller)
274     {
275       bScroller_adjustmentValueChanged();
276     }
277   }
278
279   void init()
280   {
281     try
282     {
283       jbInit();
284     } catch (Exception e)
285     {
286       e.printStackTrace();
287     }
288     frame = new Frame();
289     frame.add(this);
290     jalview.bin.JalviewLite.addFrame(frame,
291             MessageManager.getString("label.user_defined_colours"), 420,
292             345);
293
294     if (seqGroup != null)
295     {
296       frame.setTitle(frame.getTitle() + " (" + seqGroup.getName() + ")");
297     }
298
299     for (int i = 0; i < 20; i++)
300     {
301       makeButton(ResidueProperties.aa2Triplet.get(ResidueProperties.aa[i])
302               + "", ResidueProperties.aa[i]);
303     }
304
305     makeButton("B", "B");
306     makeButton("Z", "Z");
307     makeButton("X", "X");
308     makeButton("Gap", "'.','-',' '");
309
310     validate();
311   }
312
313   protected void rText_actionPerformed()
314   {
315     try
316     {
317       int i = Integer.parseInt(rText.getText());
318       rScroller.setValue(i);
319       rScroller_adjustmentValueChanged();
320     } catch (NumberFormatException ex)
321     {
322     }
323   }
324
325   protected void gText_actionPerformed()
326   {
327     try
328     {
329       int i = Integer.parseInt(gText.getText());
330       gScroller.setValue(i);
331       gScroller_adjustmentValueChanged();
332     } catch (NumberFormatException ex)
333     {
334     }
335
336   }
337
338   protected void bText_actionPerformed()
339   {
340     try
341     {
342       int i = Integer.parseInt(bText.getText());
343       bScroller.setValue(i);
344       bScroller_adjustmentValueChanged();
345     } catch (NumberFormatException ex)
346     {
347     }
348
349   }
350
351   protected void rScroller_adjustmentValueChanged()
352   {
353     R = rScroller.getValue();
354     rText.setText(R + "");
355     colourChanged();
356   }
357
358   protected void gScroller_adjustmentValueChanged()
359   {
360     G = gScroller.getValue();
361     gText.setText(G + "");
362     colourChanged();
363   }
364
365   protected void bScroller_adjustmentValueChanged()
366   {
367     B = bScroller.getValue();
368     bText.setText(B + "");
369     colourChanged();
370   }
371
372   public void colourChanged()
373   {
374     Color col = new Color(R, G, B);
375     target.setBackground(col);
376     target.repaint();
377
378     if (selectedButton != null)
379     {
380       selectedButton.setBackground(col);
381       selectedButton.repaint();
382     }
383   }
384
385   void setTargetColour(Color col)
386   {
387     R = col.getRed();
388     G = col.getGreen();
389     B = col.getBlue();
390
391     rScroller.setValue(R);
392     gScroller.setValue(G);
393     bScroller.setValue(B);
394     rText.setText(R + "");
395     gText.setText(G + "");
396     bText.setText(B + "");
397     colourChanged();
398   }
399
400   public void colourButtonPressed(MouseEvent e)
401   {
402     selectedButton = (Button) e.getSource();
403     setTargetColour(selectedButton.getBackground());
404   }
405
406   void makeButton(String label, String aa)
407   {
408     final Button button = new Button();
409     Color col = Color.white;
410     if (oldColourScheme != null)
411     {
412       try
413       {
414         col = oldColourScheme.findColour(aa.charAt(0), -1, null);
415       } catch (Exception ex)
416       {
417       }
418     }
419     button.setBackground(col);
420     oldColours.addElement(col);
421     button.setLabel(label);
422     button.setForeground(col.darker().darker().darker());
423     button.setFont(new java.awt.Font("Verdana", 1, 10));
424     button.addMouseListener(new java.awt.event.MouseAdapter()
425     {
426       @Override
427       public void mousePressed(MouseEvent e)
428       {
429         colourButtonPressed(e);
430       }
431     });
432
433     buttonPanel.add(button, null);
434   }
435
436   protected void okButton_actionPerformed()
437   {
438     applyButton_actionPerformed();
439     if (dialog != null)
440     {
441       dialog.setVisible(false);
442     }
443
444     frame.setVisible(false);
445   }
446
447   public Color getColor()
448   {
449     return new Color(R, G, B);
450   }
451
452   protected void applyButton_actionPerformed()
453   {
454     if (caller != null)
455     {
456       if (caller instanceof FeatureSettings)
457       {
458         ((FeatureSettings) caller).setUserColour(originalLabel,
459                 new FeatureColour(getColor()));
460       }
461       else if (caller instanceof AnnotationColourChooser)
462       {
463         if (originalLabel.equals("Min Colour"))
464         {
465           ((AnnotationColourChooser) caller)
466                   .minColour_actionPerformed(getColor());
467         }
468         else
469         {
470           ((AnnotationColourChooser) caller)
471                   .maxColour_actionPerformed(getColor());
472         }
473       }
474       else if (caller instanceof FeatureRenderer)
475       {
476         ((FeatureRenderer) caller).colourPanel
477                 .updateColor(new FeatureColour(getColor()));
478       }
479       else if (caller instanceof FeatureColourChooser)
480       {
481         if (originalLabel.indexOf("inimum") > -1)
482         {
483           ((FeatureColourChooser) caller)
484                   .minColour_actionPerformed(getColor());
485         }
486         else
487         {
488           ((FeatureColourChooser) caller)
489                   .maxColour_actionPerformed(getColor());
490         }
491       }
492
493       return;
494     }
495
496     Color[] newColours = new Color[24];
497     for (int i = 0; i < 24; i++)
498     {
499       Button button = (Button) buttonPanel.getComponent(i);
500       newColours[i] = button.getBackground();
501     }
502
503     UserColourScheme ucs = new UserColourScheme(newColours);
504     if (ap != null)
505     {
506       ucs.setThreshold(0, ap.av.isIgnoreGapsConsensus());
507     }
508
509     if (ap != null)
510     {
511       if (seqGroup != null)
512       {
513         seqGroup.cs = ucs;
514       }
515       else
516       {
517         ap.av.setGlobalColourScheme(ucs);
518       }
519       ap.seqPanel.seqCanvas.img = null;
520       ap.paintAlignment(true);
521     }
522     else if (jmol != null)
523     {
524       jmol.setJalviewColourScheme(ucs);
525     }
526     else if (pdbcanvas != null)
527     {
528       pdbcanvas.setColours(ucs);
529     }
530   }
531
532   protected void cancelButton_actionPerformed()
533   {
534     if (caller != null)
535     {
536       if (caller instanceof FeatureSettings)
537       {
538         ((FeatureSettings) caller).setUserColour(originalLabel,
539                 originalColour);
540       }
541       else if (caller instanceof AnnotationColourChooser)
542       {
543         if (originalLabel.equals("Min Colour"))
544         {
545           ((AnnotationColourChooser) caller)
546                   .minColour_actionPerformed(originalColour.getColour());
547         }
548         else
549         {
550           ((AnnotationColourChooser) caller)
551                   .maxColour_actionPerformed(originalColour.getColour());
552         }
553       }
554       else if (caller instanceof FeatureRenderer)
555       {
556         ((FeatureRenderer) caller).colourPanel.updateColor(originalColour);
557
558       }
559
560       else if (caller instanceof FeatureColourChooser)
561       {
562         if (originalLabel.indexOf("inimum") > -1)
563         {
564           ((FeatureColourChooser) caller)
565                   .minColour_actionPerformed(originalColour.getColour());
566         }
567         else
568         {
569           ((FeatureColourChooser) caller)
570                   .maxColour_actionPerformed(originalColour.getColour());
571         }
572       }
573       if (dialog != null)
574       {
575         dialog.setVisible(false);
576       }
577
578       frame.setVisible(false);
579       return;
580     }
581
582     Color[] newColours = new Color[24];
583     for (int i = 0; i < 24; i++)
584     {
585       newColours[i] = oldColours.elementAt(i);
586       buttonPanel.getComponent(i).setBackground(newColours[i]);
587     }
588
589     UserColourScheme ucs = new UserColourScheme(newColours);
590
591     if (ap != null)
592     {
593       if (seqGroup != null)
594       {
595         seqGroup.cs = ucs;
596       }
597       else
598       {
599         ap.av.setGlobalColourScheme(ucs);
600       }
601       ap.paintAlignment(true);
602     }
603     else if (jmol != null)
604     {
605       jmol.setJalviewColourScheme(ucs);
606     }
607     else if (pdbcanvas != null)
608     {
609       pdbcanvas.pdb.setColours(ucs);
610     }
611
612     frame.setVisible(false);
613   }
614
615   protected Panel buttonPanel = new Panel();
616
617   protected GridLayout gridLayout = new GridLayout();
618
619   Panel okcancelPanel = new Panel();
620
621   protected Button okButton = new Button();
622
623   protected Button applyButton = new Button();
624
625   protected Button cancelButton = new Button();
626
627   protected Scrollbar rScroller = new Scrollbar();
628
629   Label label1 = new Label();
630
631   protected TextField rText = new TextField();
632
633   Label label4 = new Label();
634
635   protected Scrollbar gScroller = new Scrollbar();
636
637   protected TextField gText = new TextField();
638
639   Label label5 = new Label();
640
641   protected Scrollbar bScroller = new Scrollbar();
642
643   protected TextField bText = new TextField();
644
645   protected Panel target = new Panel();
646
647   private void jbInit() throws Exception
648   {
649     this.setLayout(null);
650     buttonPanel.setLayout(gridLayout);
651     gridLayout.setColumns(6);
652     gridLayout.setRows(4);
653     okButton.setFont(new java.awt.Font("Verdana", 0, 11));
654     okButton.setLabel(MessageManager.getString("action.ok"));
655     okButton.addActionListener(this);
656     applyButton.setFont(new java.awt.Font("Verdana", 0, 11));
657     applyButton.setLabel(MessageManager.getString("action.apply"));
658     applyButton.addActionListener(this);
659     cancelButton.setFont(new java.awt.Font("Verdana", 0, 11));
660     cancelButton.setLabel(MessageManager.getString("action.cancel"));
661     cancelButton.addActionListener(this);
662     this.setBackground(new Color(212, 208, 223));
663     okcancelPanel.setBounds(new Rectangle(0, 265, 400, 35));
664     buttonPanel.setBounds(new Rectangle(0, 123, 400, 142));
665     rScroller.setMaximum(256);
666     rScroller.setMinimum(0);
667     rScroller.setOrientation(0);
668     rScroller.setUnitIncrement(1);
669     rScroller.setVisibleAmount(1);
670     rScroller.setBounds(new Rectangle(36, 27, 119, 19));
671     rScroller.addAdjustmentListener(this);
672     label1.setAlignment(Label.RIGHT);
673     label1.setText("R");
674     label1.setBounds(new Rectangle(19, 30, 16, 15));
675     rText.setFont(new java.awt.Font("Dialog", Font.PLAIN, 10));
676     rText.setText("0        ");
677     rText.setBounds(new Rectangle(156, 27, 53, 19));
678     rText.addActionListener(this);
679     rText.addFocusListener(this);
680     label4.setAlignment(Label.RIGHT);
681     label4.setText("G");
682     label4.setBounds(new Rectangle(15, 56, 20, 15));
683     gScroller.setMaximum(256);
684     gScroller.setMinimum(0);
685     gScroller.setOrientation(0);
686     gScroller.setUnitIncrement(1);
687     gScroller.setVisibleAmount(1);
688     gScroller.setBounds(new Rectangle(35, 52, 120, 20));
689     gScroller.addAdjustmentListener(this);
690     gText.setFont(new java.awt.Font("Dialog", Font.PLAIN, 10));
691     gText.setText("0        ");
692     gText.setBounds(new Rectangle(156, 52, 53, 20));
693     gText.addActionListener(this);
694     gText.addFocusListener(this);
695     label5.setAlignment(Label.RIGHT);
696     label5.setText("B");
697     label5.setBounds(new Rectangle(14, 82, 20, 15));
698     bScroller.setMaximum(256);
699     bScroller.setMinimum(0);
700     bScroller.setOrientation(0);
701     bScroller.setUnitIncrement(1);
702     bScroller.setVisibleAmount(1);
703     bScroller.setBounds(new Rectangle(35, 78, 120, 20));
704     bScroller.addAdjustmentListener(this);
705     bText.setFont(new java.awt.Font("Dialog", Font.PLAIN, 10));
706     bText.setText("0        ");
707     bText.setBounds(new Rectangle(157, 78, 52, 20));
708     bText.addActionListener(this);
709     bText.addFocusListener(this);
710     target.setBackground(Color.black);
711     target.setBounds(new Rectangle(229, 26, 134, 79));
712     this.add(okcancelPanel, null);
713     okcancelPanel.add(okButton, null);
714     okcancelPanel.add(applyButton, null);
715     okcancelPanel.add(cancelButton, null);
716     this.add(rText);
717     this.add(gText);
718     this.add(bText);
719     this.add(buttonPanel, null);
720     this.add(target, null);
721     this.add(gScroller);
722     this.add(rScroller);
723     this.add(bScroller);
724     this.add(label5);
725     this.add(label4);
726     this.add(label1);
727   }
728
729   @Override
730   public void focusGained(FocusEvent e)
731   {
732     // noop
733   }
734
735   /**
736    * This method applies any change to an RGB value if the user tabs out of the
737    * field instead of pressing Enter
738    */
739   @Override
740   public void focusLost(FocusEvent e)
741   {
742     Component c = e.getComponent();
743     if (c == rText)
744     {
745       rText_actionPerformed();
746     }
747     else
748     {
749       if (c == gText)
750       {
751         gText_actionPerformed();
752       }
753       else
754       {
755         if (c == bText)
756         {
757           bText_actionPerformed();
758         }
759       }
760     }
761   }
762
763 }