JAL-2371 CollectionColourScheme renamed ResidueShader and moved to
[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.renderer.ResidueShader;
26 import jalview.schemes.ColourSchemeI;
27 import jalview.schemes.FeatureColour;
28 import jalview.schemes.ResidueProperties;
29 import jalview.schemes.UserColourScheme;
30 import jalview.util.MessageManager;
31
32 import java.awt.Button;
33 import java.awt.Color;
34 import java.awt.Component;
35 import java.awt.Container;
36 import java.awt.Dialog;
37 import java.awt.Font;
38 import java.awt.Frame;
39 import java.awt.GridLayout;
40 import java.awt.Label;
41 import java.awt.Panel;
42 import java.awt.Rectangle;
43 import java.awt.Scrollbar;
44 import java.awt.TextField;
45 import java.awt.event.ActionEvent;
46 import java.awt.event.ActionListener;
47 import java.awt.event.AdjustmentEvent;
48 import java.awt.event.AdjustmentListener;
49 import java.awt.event.FocusEvent;
50 import java.awt.event.FocusListener;
51 import java.awt.event.MouseEvent;
52 import java.util.Vector;
53
54 public class UserDefinedColours extends Panel implements ActionListener,
55         AdjustmentListener, FocusListener
56 {
57
58   AlignmentPanel ap;
59
60   SequenceGroup seqGroup;
61
62   Button selectedButton;
63
64   Vector<Color> oldColours = new Vector<Color>();
65
66   ColourSchemeI oldColourScheme;
67
68   Frame frame;
69
70   MCview.AppletPDBCanvas pdbcanvas;
71
72   AppletJmol jmol;
73
74   Dialog dialog;
75
76   Object caller;
77
78   String originalLabel;
79
80   FeatureColourI originalColour;
81
82   int R = 0, G = 0, B = 0;
83
84   public ColourSchemeI loadDefaultColours()
85   {
86     // NOT IMPLEMENTED YET IN APPLET VERSION
87     return null;
88   }
89
90   public UserDefinedColours(AlignmentPanel ap, SequenceGroup sg)
91   {
92     this.ap = ap;
93     seqGroup = sg;
94
95     if (seqGroup != null)
96     {
97       oldColourScheme = seqGroup.getColourScheme();
98     }
99     else
100     {
101       oldColourScheme = ap.av.getGlobalColourScheme();
102     }
103
104     init();
105   }
106
107   public UserDefinedColours(MCview.AppletPDBCanvas pdb)
108   {
109     this.pdbcanvas = pdb;
110     init();
111   }
112
113   public UserDefinedColours(AppletJmol jmol)
114   {
115     this.jmol = jmol;
116     init();
117   }
118
119   public UserDefinedColours(FeatureRenderer fr, Frame alignframe)
120   {
121     caller = fr;
122     originalColour = new FeatureColour(fr.colourPanel.getBackground());
123     originalLabel = "Feature Colour";
124     setForDialog("Select Feature Colour", alignframe);
125     setTargetColour(fr.colourPanel.getBackground());
126     dialog.setVisible(true);
127   }
128
129   public UserDefinedColours(Component caller, Color col1, Frame alignframe)
130   {
131     this(caller, col1, alignframe, "Select Colour");
132   }
133
134   /**
135    * Makes a dialog to choose the colour
136    * 
137    * @param caller
138    *          - handles events
139    * @param col
140    *          - original colour
141    * @param alignframe
142    *          - the parent Frame for the dialog
143    * @param title
144    *          - window title
145    */
146   public UserDefinedColours(Component caller, Color col, Frame alignframe,
147           String title)
148   {
149     this.caller = caller;
150     originalColour = new FeatureColour(col);
151     originalLabel = title;
152     setForDialog(title, alignframe);
153     setTargetColour(col);
154     dialog.setVisible(true);
155   }
156
157   /**
158    * feature colour chooser
159    * 
160    * @param caller
161    * @param label
162    * @param colour
163    */
164   public UserDefinedColours(Object caller, String label, Color colour)
165   {
166     this(caller, label, new FeatureColour(colour), colour);
167   }
168
169   /**
170    * feature colour chooser when changing style to single color
171    * 
172    * @param me
173    * @param type
174    * @param graduatedColor
175    */
176   public UserDefinedColours(FeatureSettings me, String type,
177           FeatureColourI graduatedColor)
178   {
179     this(me, type, graduatedColor, graduatedColor.getMaxColour());
180   }
181
182   private UserDefinedColours(Object caller, String label,
183           FeatureColourI ocolour, Color colour)
184   {
185     this.caller = caller;
186     originalColour = ocolour;
187     originalLabel = label;
188     init();
189     remove(buttonPanel);
190
191     setTargetColour(colour);
192
193     okcancelPanel.setBounds(new Rectangle(0, 113, 400, 35));
194     frame.setTitle(MessageManager.getString("label.user_defined_colours")
195             + " - " + label);
196     frame.setSize(420, 200);
197   }
198
199   void setForDialog(String title, Container alignframe)
200   {
201     init();
202     frame.setVisible(false);
203     remove(buttonPanel);
204     if (alignframe instanceof Frame)
205     {
206       dialog = new Dialog((Frame) alignframe, title, true);
207     }
208     else
209     {
210       // if (alignframe instanceof JVDialog){
211       // // not 1.1 compatible!
212       // dialog = new Dialog(((JVDialog)alignframe), title, true);
213       // } else {
214       throw new Error(
215               MessageManager
216                       .getString("label.error_unsupported_owwner_user_colour_scheme"));
217     }
218
219     dialog.add(this);
220     this.setSize(400, 123);
221     okcancelPanel.setBounds(new Rectangle(0, 123, 400, 35));
222     int height = 160 + alignframe.getInsets().top + getInsets().bottom;
223     int width = 400;
224
225     dialog.setBounds(alignframe.getBounds().x
226             + (alignframe.getSize().width - width) / 2,
227             alignframe.getBounds().y
228                     + (alignframe.getSize().height - height) / 2, width,
229             height);
230
231   }
232
233   @Override
234   public void actionPerformed(ActionEvent evt)
235   {
236     final Object source = evt.getSource();
237     if (source == okButton)
238     {
239       okButton_actionPerformed();
240     }
241     else if (source == applyButton)
242     {
243       applyButton_actionPerformed();
244     }
245     else if (source == cancelButton)
246     {
247       cancelButton_actionPerformed();
248     }
249     else if (source == rText)
250     {
251       rText_actionPerformed();
252     }
253     else if (source == gText)
254     {
255       gText_actionPerformed();
256     }
257     else if (source == bText)
258     {
259       bText_actionPerformed();
260     }
261   }
262
263   @Override
264   public void adjustmentValueChanged(AdjustmentEvent evt)
265   {
266     if (evt.getSource() == rScroller)
267     {
268       rScroller_adjustmentValueChanged();
269     }
270     else if (evt.getSource() == gScroller)
271     {
272       gScroller_adjustmentValueChanged();
273     }
274     else if (evt.getSource() == bScroller)
275     {
276       bScroller_adjustmentValueChanged();
277     }
278   }
279
280   void init()
281   {
282     try
283     {
284       jbInit();
285     } catch (Exception e)
286     {
287       e.printStackTrace();
288     }
289     frame = new Frame();
290     frame.add(this);
291     jalview.bin.JalviewLite.addFrame(frame,
292             MessageManager.getString("label.user_defined_colours"), 420,
293             345);
294
295     if (seqGroup != null)
296     {
297       frame.setTitle(frame.getTitle() + " (" + seqGroup.getName() + ")");
298     }
299
300     for (int i = 0; i < 20; i++)
301     {
302       makeButton(ResidueProperties.aa2Triplet.get(ResidueProperties.aa[i])
303               + "", ResidueProperties.aa[i]);
304     }
305
306     makeButton("B", "B");
307     makeButton("Z", "Z");
308     makeButton("X", "X");
309     makeButton("Gap", "'.','-',' '");
310
311     validate();
312   }
313
314   protected void rText_actionPerformed()
315   {
316     try
317     {
318       int i = Integer.parseInt(rText.getText());
319       rScroller.setValue(i);
320       rScroller_adjustmentValueChanged();
321     } catch (NumberFormatException ex)
322     {
323     }
324   }
325
326   protected void gText_actionPerformed()
327   {
328     try
329     {
330       int i = Integer.parseInt(gText.getText());
331       gScroller.setValue(i);
332       gScroller_adjustmentValueChanged();
333     } catch (NumberFormatException ex)
334     {
335     }
336
337   }
338
339   protected void bText_actionPerformed()
340   {
341     try
342     {
343       int i = Integer.parseInt(bText.getText());
344       bScroller.setValue(i);
345       bScroller_adjustmentValueChanged();
346     } catch (NumberFormatException ex)
347     {
348     }
349
350   }
351
352   protected void rScroller_adjustmentValueChanged()
353   {
354     R = rScroller.getValue();
355     rText.setText(R + "");
356     colourChanged();
357   }
358
359   protected void gScroller_adjustmentValueChanged()
360   {
361     G = gScroller.getValue();
362     gText.setText(G + "");
363     colourChanged();
364   }
365
366   protected void bScroller_adjustmentValueChanged()
367   {
368     B = bScroller.getValue();
369     bText.setText(B + "");
370     colourChanged();
371   }
372
373   public void colourChanged()
374   {
375     Color col = new Color(R, G, B);
376     target.setBackground(col);
377     target.repaint();
378
379     if (selectedButton != null)
380     {
381       selectedButton.setBackground(col);
382       selectedButton.repaint();
383     }
384   }
385
386   void setTargetColour(Color col)
387   {
388     R = col.getRed();
389     G = col.getGreen();
390     B = col.getBlue();
391
392     rScroller.setValue(R);
393     gScroller.setValue(G);
394     bScroller.setValue(B);
395     rText.setText(R + "");
396     gText.setText(G + "");
397     bText.setText(B + "");
398     colourChanged();
399   }
400
401   public void colourButtonPressed(MouseEvent e)
402   {
403     selectedButton = (Button) e.getSource();
404     setTargetColour(selectedButton.getBackground());
405   }
406
407   void makeButton(String label, String aa)
408   {
409     final Button button = new Button();
410     Color col = Color.white;
411     if (oldColourScheme != null && oldColourScheme.isSimple())
412     {
413       col = oldColourScheme.findColour(aa.charAt(0), 0, null, null, 0f);
414     }
415     button.setBackground(col);
416     oldColours.addElement(col);
417     button.setLabel(label);
418     button.setForeground(col.darker().darker().darker());
419     button.setFont(new java.awt.Font("Verdana", 1, 10));
420     button.addMouseListener(new java.awt.event.MouseAdapter()
421     {
422       @Override
423       public void mousePressed(MouseEvent e)
424       {
425         colourButtonPressed(e);
426       }
427     });
428
429     buttonPanel.add(button, null);
430   }
431
432   protected void okButton_actionPerformed()
433   {
434     applyButton_actionPerformed();
435     if (dialog != null)
436     {
437       dialog.setVisible(false);
438     }
439
440     frame.setVisible(false);
441   }
442
443   public Color getColor()
444   {
445     return new Color(R, G, B);
446   }
447
448   protected void applyButton_actionPerformed()
449   {
450     if (caller != null)
451     {
452       if (caller instanceof FeatureSettings)
453       {
454         ((FeatureSettings) caller).setUserColour(originalLabel,
455                 new FeatureColour(getColor()));
456       }
457       else if (caller instanceof AnnotationColourChooser)
458       {
459         if (originalLabel.equals("Min Colour"))
460         {
461           ((AnnotationColourChooser) caller)
462                   .minColour_actionPerformed(getColor());
463         }
464         else
465         {
466           ((AnnotationColourChooser) caller)
467                   .maxColour_actionPerformed(getColor());
468         }
469       }
470       else if (caller instanceof FeatureRenderer)
471       {
472         ((FeatureRenderer) caller).colourPanel
473                 .updateColor(new FeatureColour(getColor()));
474       }
475       else if (caller instanceof FeatureColourChooser)
476       {
477         if (originalLabel.indexOf("inimum") > -1)
478         {
479           ((FeatureColourChooser) caller)
480                   .minColour_actionPerformed(getColor());
481         }
482         else
483         {
484           ((FeatureColourChooser) caller)
485                   .maxColour_actionPerformed(getColor());
486         }
487       }
488
489       return;
490     }
491
492     Color[] newColours = new Color[24];
493     for (int i = 0; i < 24; i++)
494     {
495       Button button = (Button) buttonPanel.getComponent(i);
496       newColours[i] = button.getBackground();
497     }
498
499     UserColourScheme ucs = new UserColourScheme(newColours);
500     // if (ap != null)
501     // {
502     // ucs.setThreshold(0, ap.av.isIgnoreGapsConsensus());
503     // }
504
505     if (ap != null)
506     {
507       if (seqGroup != null)
508       {
509         seqGroup.cs = new ResidueShader(ucs);
510         seqGroup.getGroupColourScheme().setThreshold(0,
511                 ap.av.isIgnoreGapsConsensus());
512       }
513       else
514       {
515         ap.av.setGlobalColourScheme(ucs);
516         ap.av.getViewportColourScheme().setThreshold(0,
517                 ap.av.isIgnoreGapsConsensus());
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 = new ResidueShader(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 }