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