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