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