]> gitweb.fperrin.net Git - GpsPrune.git/blob - tim/prune/gui/colour/ColourerSelectorPanel.java
Version 17, September 2014
[GpsPrune.git] / tim / prune / gui / colour / ColourerSelectorPanel.java
1 package tim.prune.gui.colour;
2
3 import java.awt.Color;
4 import java.awt.Component;
5 import java.awt.GridLayout;
6 import java.awt.event.ActionEvent;
7 import java.awt.event.ActionListener;
8
9 import javax.swing.BorderFactory;
10 import javax.swing.BoxLayout;
11 import javax.swing.JComboBox;
12 import javax.swing.JLabel;
13 import javax.swing.JPanel;
14 import javax.swing.border.EtchedBorder;
15
16 import tim.prune.I18nManager;
17 import tim.prune.gui.GuiGridLayout;
18 import tim.prune.gui.colour.ColourerFactory.ColourerId;
19
20 /**
21  * Class to provide a gui panel for selecting a colourer
22  * including which colourer, the start/end colours and
23  * optionally the max number of colours
24  */
25 public class ColourerSelectorPanel extends JPanel
26 {
27         /** Combo box for selecting the type of colourer */
28         private JComboBox<String> _typeCombo = null;
29         /** Array of type ids as stored in combo box */
30         private ColourerId[] _typeIds = null;
31         /** Panel object holding the colour patches */
32         private JPanel _patchPanel = null;
33         /** Array of colour patches for start and end */
34         private ColourPatch[] _startEndPatches = null;
35         /** Panel holding the max colours selection */
36         JPanel _maxColoursPanel = null;
37         private JComboBox<String> _maxColoursCombo = null;
38
39         /** Array of label keys for the 2 patches */
40         private static final String[] LABEL_KEYS = {"start", "end"};
41
42
43         /**
44          * Constructor
45          * @param inColourChooser colour chooser to use (needs reference to parent dialog)
46          */
47         public ColourerSelectorPanel(ColourChooser inColourChooser)
48         {
49                 _typeIds = new ColourerId[] {ColourerId.NONE, ColourerId.BY_FILE,
50                         ColourerId.BY_SEGMENT, ColourerId.BY_DATE, ColourerId.BY_ALTITUDE,
51                         ColourerId.BY_SPEED, ColourerId.BY_VSPEED, ColourerId.BY_GRADIENT};
52                 makeGuiComponents(inColourChooser);
53         }
54
55
56         /**
57          * Create all the gui components and lay them out in the panel
58          * @param inColourChooser colour chooser to use
59          */
60         private void makeGuiComponents(ColourChooser inColourChooser)
61         {
62                 // Etched border and vertical layout
63                 setBorder(BorderFactory.createCompoundBorder(
64                         BorderFactory.createEtchedBorder(EtchedBorder.LOWERED), BorderFactory.createEmptyBorder(4, 4, 4, 4))
65                 );
66                 setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
67
68                 // Label at the top
69                 JLabel introLabel = new JLabel(I18nManager.getText("dialog.colourer.intro"));
70                 introLabel.setAlignmentX(Component.LEFT_ALIGNMENT);
71                 add(introLabel);
72
73                 // Combo box for selecting which colourer to use
74                 JPanel typePanel = new JPanel();
75                 GuiGridLayout grid = new GuiGridLayout(typePanel);
76                 final String keyPrefix = "dialog.colourer.type.";
77                 String[] colourerTypes = new String[_typeIds.length];
78                 for (int i=0; i<colourerTypes.length; i++)
79                 {
80                         colourerTypes[i] = I18nManager.getText(keyPrefix +
81                                 ColourerFactory.getDescriptionKey(_typeIds[i]));
82                 }
83                 _typeCombo = new JComboBox<String>(colourerTypes);
84                 _typeCombo.setAlignmentX(Component.LEFT_ALIGNMENT);
85                 _typeCombo.addActionListener(new ActionListener() {
86                         public void actionPerformed(ActionEvent e)
87                         {
88                                 onColourerTypeChanged();
89                         }
90                 });
91                 // Add to the panel
92                 grid.add(new JLabel(I18nManager.getText("dialog.colourer.type")));
93                 grid.add(_typeCombo);
94                 typePanel.setAlignmentX(Component.LEFT_ALIGNMENT);
95                 add(typePanel);
96
97                 // Make panel for colour patches
98                 _patchPanel = new JPanel();
99                 _patchPanel.setLayout(new GridLayout());
100                 _startEndPatches = new ColourPatch[2];
101
102                 // Blank column
103                 JPanel blankColumn = new JPanel();
104                 ColourPatch blankPatch = new ColourPatch(Color.BLACK);
105                 blankPatch.setVisible(false);
106                 blankColumn.add(blankPatch);
107                 _patchPanel.add(blankColumn);
108
109                 // Loop over two columns of patches
110                 for (int i=0; i<2; i++)
111                 {
112                         JPanel colPanel = new JPanel();
113                         colPanel.setLayout(new BoxLayout(colPanel, BoxLayout.Y_AXIS));
114                         // Top label and patch
115                         colPanel.add(new JLabel(I18nManager.getText("dialog.colourer." + LABEL_KEYS[i])));
116                         ColourPatch patch = new ColourPatch(Color.BLUE); // will be set by init() method shortly
117                         patch.addMouseListener(new PatchListener(patch, inColourChooser));
118                         colPanel.add(patch);
119                         _startEndPatches[i] = patch;
120
121                         // Add column to panel
122                         colPanel.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
123                         _patchPanel.add(colPanel);
124                 }
125
126                 // Blank column
127                 blankColumn = new JPanel();
128                 blankPatch = new ColourPatch(Color.BLACK);
129                 blankPatch.setVisible(false);
130                 blankColumn.add(blankPatch);
131                 _patchPanel.add(blankColumn);
132
133                 _patchPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
134                 add(_patchPanel);
135
136                 // Combo box for selecting max colours
137                 _maxColoursPanel = new JPanel();
138                 grid = new GuiGridLayout(_maxColoursPanel);
139                 grid.add(new JLabel(I18nManager.getText("dialog.colourer.maxcolours")));
140                 String[] colourOptions = new String[] {"2", "3", "5", "10", "15"};
141                 _maxColoursCombo = new JComboBox<String>(colourOptions);
142                 grid.add(_maxColoursCombo);
143                 _maxColoursPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
144                 add(_maxColoursPanel);
145         }
146
147         /**
148          * Init the colours from the colourer (if possible) or the default colour
149          * @param inColourer current colourer object, or null
150          * @param inDefaultColour current colour for points
151          */
152         public void init(PointColourer inColourer, Color inDefaultColour)
153         {
154                 Color startColour = null, endColour = null;
155                 if (inColourer != null)
156                 {
157                         selectColourerType(ColourerFactory.getId(inColourer));
158                         startColour = inColourer.getStartColour();
159                         endColour   = inColourer.getEndColour();
160                         _maxColoursCombo.setSelectedItem("" + inColourer.getMaxColours());
161                 }
162                 else
163                 {
164                         // no colourer, so default to 5 colours maximum
165                         _maxColoursCombo.setSelectedIndex(2);
166                 }
167                 if (startColour == null) {startColour = inDefaultColour;}
168                 if (endColour   == null) {endColour = makeDefaultEndColour(inDefaultColour);}
169                 if (startColour != null) {_startEndPatches[0].setBackground(startColour);}
170                 if (endColour != null)   {_startEndPatches[1].setBackground(endColour);}
171                 onColourerTypeChanged(); // make sure gui is updated
172         }
173
174         /**
175          * Make a default end colour if there isn't one already defined
176          * @param inStartColour start colour
177          * @return end colour, with the hue shifted by a third from the start
178          */
179         private static Color makeDefaultEndColour(Color inStartColour)
180         {
181                 float[] defaultHSB = Color.RGBtoHSB(inStartColour.getRed(), inStartColour.getGreen(), inStartColour.getBlue(), null);
182                 // add 120 degrees to the hue
183                 defaultHSB[0] += (1.0f/3f);
184                 return Color.getHSBColor(defaultHSB[0], defaultHSB[1], defaultHSB[2]);
185         }
186
187         /**
188          * React to the colourer type being changed
189          * by showing / hiding gui elements
190          */
191         private void onColourerTypeChanged()
192         {
193                 final ColourerId id = _typeIds[_typeCombo.getSelectedIndex()];
194                 // Set visibility of controls according to whether they're needed for the selected type
195                 _patchPanel.setVisible(ColourerFactory.areColoursRequired(id));
196                 _maxColoursPanel.setVisible(ColourerFactory.isMaxColoursRequired(id));
197         }
198
199         /**
200          * @return the selected colourer object, or null
201          */
202         public PointColourer getSelectedColourer()
203         {
204                 final ColourerId id = _typeIds[_typeCombo.getSelectedIndex()];
205                 return ColourerFactory.createColourer(id, _startEndPatches[0].getBackground(),
206                         _startEndPatches[1].getBackground(), _maxColoursCombo.getSelectedItem().toString());
207         }
208
209         /**
210          * Select the appropriate item in the dropdown
211          * @param inId id of colourer to choose
212          */
213         private void selectColourerType(ColourerId inId)
214         {
215                 int selIndex = -1;
216                 for (int i=0; i<_typeIds.length; i++)
217                 {
218                         if (_typeIds[i] == inId) {
219                                 selIndex = i;
220                                 break;
221                         }
222                 }
223                 if (selIndex < 0) {
224                         System.err.println("Id " + inId + " not found in _typeIds!");
225                 }
226                 else {
227                         _typeCombo.setSelectedIndex(selIndex);
228                 }
229         }
230 }