JAL-3058 refactored raising JColorChooser for JS compatibility
[jalview.git] / src / jalview / gui / TextColourChooser.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.gui.JalviewColourChooser.ColourChooserListener;
25 import jalview.util.MessageManager;
26
27 import java.awt.BorderLayout;
28 import java.awt.Color;
29 import java.awt.Dimension;
30 import java.awt.event.MouseAdapter;
31 import java.awt.event.MouseEvent;
32 import java.util.HashMap;
33 import java.util.Map;
34
35 import javax.swing.BorderFactory;
36 import javax.swing.JColorChooser;
37 import javax.swing.JLabel;
38 import javax.swing.JPanel;
39 import javax.swing.JSlider;
40 import javax.swing.event.ChangeEvent;
41 import javax.swing.event.ChangeListener;
42
43 public class TextColourChooser
44 {
45   AlignmentPanel ap;
46
47   SequenceGroup sg;
48
49   Color original1, original2;
50
51   int originalThreshold;
52
53   Map<SequenceGroup, Color> groupColour1;
54
55   Map<SequenceGroup, Color> groupColour2;
56
57   Map<SequenceGroup, Integer> groupThreshold;
58
59   /**
60    * Show a dialogue which allows the user to select two text colours and adjust
61    * a slider for the cross-over point
62    * 
63    * @param alignPanel
64    *          the AlignmentPanel context
65    * @param sequenceGroup
66    *          the SequenceGroup context (only for group pop-menu option)
67    */
68   public void chooseColour(AlignmentPanel alignPanel,
69           SequenceGroup sequenceGroup)
70   {
71     this.ap = alignPanel;
72     this.sg = sequenceGroup;
73
74     saveInitialSettings();
75
76     final JSlider slider = new JSlider(0, 750, originalThreshold);
77     final JPanel col1 = new JPanel();
78     col1.setPreferredSize(new Dimension(40, 20));
79     col1.setBorder(BorderFactory.createEtchedBorder());
80     col1.setToolTipText(MessageManager.getString("label.dark_colour"));
81     col1.setBackground(original1);
82     final JPanel col2 = new JPanel();
83     col2.setPreferredSize(new Dimension(40, 20));
84     col2.setBorder(BorderFactory.createEtchedBorder());
85     col2.setToolTipText(MessageManager.getString("label.light_colour"));
86     col2.setBackground(original2);
87     final JPanel bigpanel = new JPanel(new BorderLayout());
88     JPanel panel = new JPanel();
89     bigpanel.add(panel, BorderLayout.CENTER);
90     bigpanel.add(
91             new JLabel("<html>"
92                     + MessageManager.getString(
93                             "label.select_dark_light_set_threshold")
94                     + "</html>"),
95             BorderLayout.NORTH);
96     panel.add(col1);
97     panel.add(slider);
98     panel.add(col2);
99
100     col1.addMouseListener(new MouseAdapter()
101     {
102       @Override
103       public void mousePressed(MouseEvent e)
104       {
105         String ttl = MessageManager.getString("label.select_colour_for_text");
106         ColourChooserListener listener = new ColourChooserListener()
107         {
108           @Override
109           public void colourSelected(Color c)
110           {
111             colour1Changed(c);
112             col1.setBackground(c);
113           }
114         };
115         JalviewColourChooser.showColourChooser(bigpanel, ttl,
116                 col1.getBackground(), listener);
117       }
118     });
119
120     col2.addMouseListener(new MouseAdapter()
121     {
122       @Override
123       public void mousePressed(MouseEvent e)
124       {
125         String ttl = MessageManager.getString("label.select_colour_for_text");
126         ColourChooserListener listener = new ColourChooserListener()
127         {
128           @Override
129           public void colourSelected(Color c)
130           {
131             colour2Changed(c);
132             col2.setBackground(c);
133           }
134         };
135         JalviewColourChooser.showColourChooser(bigpanel, ttl,
136                 col2.getBackground(), listener);
137       }
138     });
139
140     slider.addChangeListener(new ChangeListener()
141     {
142       @Override
143       public void stateChanged(ChangeEvent evt)
144       {
145         thresholdChanged(slider.getValue());
146       }
147     });
148
149     int reply = JvOptionPane.showInternalOptionDialog(alignPanel, bigpanel,
150             MessageManager.getString(
151                     "label.adjunst_foreground_text_colour_threshold"),
152             JvOptionPane.OK_CANCEL_OPTION, JvOptionPane.QUESTION_MESSAGE,
153             null, null, null);
154
155     if (reply == JvOptionPane.CANCEL_OPTION)
156     {
157       restoreInitialSettings();
158     }
159   }
160
161   /**
162    * Restore initial settings on Cancel
163    */
164   protected void restoreInitialSettings()
165   {
166     if (sg == null)
167     {
168       ap.av.setTextColour(original1);
169       ap.av.setTextColour2(original2);
170       ap.av.setThresholdTextColour(originalThreshold);
171     }
172     else
173     {
174       sg.textColour = original1;
175       sg.textColour2 = original2;
176       sg.thresholdTextColour = originalThreshold;
177     }
178
179     /*
180      * if 'Apply To All Groups' was in force, there will be 
181      * group-specific settings to restore as well
182      */
183     for (SequenceGroup group : this.groupColour1.keySet())
184     {
185       group.textColour = groupColour1.get(group);
186       group.textColour2 = groupColour2.get(group);
187       group.thresholdTextColour = groupThreshold.get(group);
188     }
189   }
190
191   /**
192    * Save settings on entry, for restore on Cancel
193    */
194   protected void saveInitialSettings()
195   {
196     groupColour1 = new HashMap<>();
197     groupColour2 = new HashMap<>();
198     groupThreshold = new HashMap<>();
199
200     if (sg == null)
201     {
202       /*
203        * alignment scope
204        */
205       original1 = ap.av.getTextColour();
206       original2 = ap.av.getTextColour2();
207       originalThreshold = ap.av.getThresholdTextColour();
208       if (ap.av.getColourAppliesToAllGroups()
209               && ap.av.getAlignment().getGroups() != null)
210       {
211         /*
212          * if applying changes to all groups, need to be able to 
213          * restore group settings as well
214          */
215         for (SequenceGroup group : ap.av.getAlignment().getGroups())
216         {
217           groupColour1.put(group, group.textColour);
218           groupColour2.put(group, group.textColour2);
219           groupThreshold.put(group, group.thresholdTextColour);
220         }
221       }
222     }
223     else
224     {
225       /*
226        * Sequence group scope
227        */
228       original1 = sg.textColour;
229       original2 = sg.textColour2;
230       originalThreshold = sg.thresholdTextColour;
231     }
232   }
233
234   void colour1Changed(Color col)
235   {
236     if (sg == null)
237     {
238       ap.av.setTextColour(col);
239       if (ap.av.getColourAppliesToAllGroups())
240       {
241         setGroupTextColour();
242       }
243     }
244     else
245     {
246       sg.textColour = col;
247     }
248
249     ap.paintAlignment(false, false);
250   }
251
252   void colour2Changed(Color col)
253   {
254     if (sg == null)
255     {
256       ap.av.setTextColour2(col);
257       if (ap.av.getColourAppliesToAllGroups())
258       {
259         setGroupTextColour();
260       }
261     }
262     else
263     {
264       sg.textColour2 = col;
265     }
266
267     ap.paintAlignment(false, false);
268   }
269
270   void thresholdChanged(int value)
271   {
272     if (sg == null)
273     {
274       ap.av.setThresholdTextColour(value);
275       if (ap.av.getColourAppliesToAllGroups())
276       {
277         setGroupTextColour();
278       }
279     }
280     else
281     {
282       sg.thresholdTextColour = value;
283     }
284
285     ap.paintAlignment(false, false);
286   }
287
288   void setGroupTextColour()
289   {
290     if (ap.av.getAlignment().getGroups() == null)
291     {
292       return;
293     }
294
295     for (SequenceGroup group : ap.av.getAlignment().getGroups())
296     {
297       group.textColour = ap.av.getTextColour();
298       group.textColour2 = ap.av.getTextColour2();
299       group.thresholdTextColour = ap.av.getThresholdTextColour();
300     }
301   }
302
303 }