]> gitweb.fperrin.net Git - GpsPrune.git/blobdiff - src/tim/prune/gui/colour/ColourerSelectorPanel.java
Moved source into separate src directory due to popular request
[GpsPrune.git] / src / tim / prune / gui / colour / ColourerSelectorPanel.java
diff --git a/src/tim/prune/gui/colour/ColourerSelectorPanel.java b/src/tim/prune/gui/colour/ColourerSelectorPanel.java
new file mode 100644 (file)
index 0000000..85754a5
--- /dev/null
@@ -0,0 +1,230 @@
+package tim.prune.gui.colour;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.BorderFactory;
+import javax.swing.BoxLayout;
+import javax.swing.JComboBox;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.border.EtchedBorder;
+
+import tim.prune.I18nManager;
+import tim.prune.gui.GuiGridLayout;
+import tim.prune.gui.colour.ColourerFactory.ColourerId;
+
+/**
+ * Class to provide a gui panel for selecting a colourer
+ * including which colourer, the start/end colours and
+ * optionally the max number of colours
+ */
+public class ColourerSelectorPanel extends JPanel
+{
+       /** Combo box for selecting the type of colourer */
+       private JComboBox<String> _typeCombo = null;
+       /** Array of type ids as stored in combo box */
+       private ColourerId[] _typeIds = null;
+       /** Panel object holding the colour patches */
+       private JPanel _patchPanel = null;
+       /** Array of colour patches for start and end */
+       private ColourPatch[] _startEndPatches = null;
+       /** Panel holding the max colours selection */
+       JPanel _maxColoursPanel = null;
+       private JComboBox<String> _maxColoursCombo = null;
+
+       /** Array of label keys for the 2 patches */
+       private static final String[] LABEL_KEYS = {"start", "end"};
+
+
+       /**
+        * Constructor
+        * @param inColourChooser colour chooser to use (needs reference to parent dialog)
+        */
+       public ColourerSelectorPanel(ColourChooser inColourChooser)
+       {
+               _typeIds = new ColourerId[] {ColourerId.NONE, ColourerId.BY_FILE,
+                       ColourerId.BY_SEGMENT, ColourerId.BY_DATE, ColourerId.BY_ALTITUDE,
+                       ColourerId.BY_SPEED, ColourerId.BY_VSPEED, ColourerId.BY_GRADIENT};
+               makeGuiComponents(inColourChooser);
+       }
+
+
+       /**
+        * Create all the gui components and lay them out in the panel
+        * @param inColourChooser colour chooser to use
+        */
+       private void makeGuiComponents(ColourChooser inColourChooser)
+       {
+               // Etched border and vertical layout
+               setBorder(BorderFactory.createCompoundBorder(
+                       BorderFactory.createEtchedBorder(EtchedBorder.LOWERED), BorderFactory.createEmptyBorder(4, 4, 4, 4))
+               );
+               setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
+
+               // Label at the top
+               JLabel introLabel = new JLabel(I18nManager.getText("dialog.colourer.intro"));
+               introLabel.setAlignmentX(Component.LEFT_ALIGNMENT);
+               add(introLabel);
+
+               // Combo box for selecting which colourer to use
+               JPanel typePanel = new JPanel();
+               GuiGridLayout grid = new GuiGridLayout(typePanel);
+               final String keyPrefix = "dialog.colourer.type.";
+               String[] colourerTypes = new String[_typeIds.length];
+               for (int i=0; i<colourerTypes.length; i++)
+               {
+                       colourerTypes[i] = I18nManager.getText(keyPrefix +
+                               ColourerFactory.getDescriptionKey(_typeIds[i]));
+               }
+               _typeCombo = new JComboBox<String>(colourerTypes);
+               _typeCombo.setAlignmentX(Component.LEFT_ALIGNMENT);
+               _typeCombo.addActionListener(new ActionListener() {
+                       public void actionPerformed(ActionEvent e)
+                       {
+                               onColourerTypeChanged();
+                       }
+               });
+               // Add to the panel
+               grid.add(new JLabel(I18nManager.getText("dialog.colourer.type")));
+               grid.add(_typeCombo);
+               typePanel.setAlignmentX(Component.LEFT_ALIGNMENT);
+               add(typePanel);
+
+               // Make panel for colour patches
+               _patchPanel = new JPanel();
+               _patchPanel.setLayout(new GridLayout());
+               _startEndPatches = new ColourPatch[2];
+
+               // Blank column
+               JPanel blankColumn = new JPanel();
+               ColourPatch blankPatch = new ColourPatch(Color.BLACK);
+               blankPatch.setVisible(false);
+               blankColumn.add(blankPatch);
+               _patchPanel.add(blankColumn);
+
+               // Loop over two columns of patches
+               for (int i=0; i<2; i++)
+               {
+                       JPanel colPanel = new JPanel();
+                       colPanel.setLayout(new BoxLayout(colPanel, BoxLayout.Y_AXIS));
+                       // Top label and patch
+                       colPanel.add(new JLabel(I18nManager.getText("dialog.colourer." + LABEL_KEYS[i])));
+                       ColourPatch patch = new ColourPatch(Color.BLUE); // will be set by init() method shortly
+                       patch.addMouseListener(new PatchListener(patch, inColourChooser));
+                       colPanel.add(patch);
+                       _startEndPatches[i] = patch;
+
+                       // Add column to panel
+                       colPanel.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
+                       _patchPanel.add(colPanel);
+               }
+
+               // Blank column
+               blankColumn = new JPanel();
+               blankPatch = new ColourPatch(Color.BLACK);
+               blankPatch.setVisible(false);
+               blankColumn.add(blankPatch);
+               _patchPanel.add(blankColumn);
+
+               _patchPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
+               add(_patchPanel);
+
+               // Combo box for selecting max colours
+               _maxColoursPanel = new JPanel();
+               grid = new GuiGridLayout(_maxColoursPanel);
+               grid.add(new JLabel(I18nManager.getText("dialog.colourer.maxcolours")));
+               String[] colourOptions = new String[] {"2", "3", "5", "10", "15"};
+               _maxColoursCombo = new JComboBox<String>(colourOptions);
+               grid.add(_maxColoursCombo);
+               _maxColoursPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
+               add(_maxColoursPanel);
+       }
+
+       /**
+        * Init the colours from the colourer (if possible) or the default colour
+        * @param inColourer current colourer object, or null
+        * @param inDefaultColour current colour for points
+        */
+       public void init(PointColourer inColourer, Color inDefaultColour)
+       {
+               Color startColour = null, endColour = null;
+               if (inColourer != null)
+               {
+                       selectColourerType(ColourerFactory.getId(inColourer));
+                       startColour = inColourer.getStartColour();
+                       endColour   = inColourer.getEndColour();
+                       _maxColoursCombo.setSelectedItem("" + inColourer.getMaxColours());
+               }
+               else
+               {
+                       // no colourer, so default to 5 colours maximum
+                       _maxColoursCombo.setSelectedIndex(2);
+               }
+               if (startColour == null) {startColour = inDefaultColour;}
+               if (endColour   == null) {endColour = makeDefaultEndColour(inDefaultColour);}
+               if (startColour != null) {_startEndPatches[0].setBackground(startColour);}
+               if (endColour != null)   {_startEndPatches[1].setBackground(endColour);}
+               onColourerTypeChanged(); // make sure gui is updated
+       }
+
+       /**
+        * Make a default end colour if there isn't one already defined
+        * @param inStartColour start colour
+        * @return end colour, with the hue shifted by a third from the start
+        */
+       private static Color makeDefaultEndColour(Color inStartColour)
+       {
+               float[] defaultHSB = Color.RGBtoHSB(inStartColour.getRed(), inStartColour.getGreen(), inStartColour.getBlue(), null);
+               // add 120 degrees to the hue
+               defaultHSB[0] += (1.0f/3f);
+               return Color.getHSBColor(defaultHSB[0], defaultHSB[1], defaultHSB[2]);
+       }
+
+       /**
+        * React to the colourer type being changed
+        * by showing / hiding gui elements
+        */
+       private void onColourerTypeChanged()
+       {
+               final ColourerId id = _typeIds[_typeCombo.getSelectedIndex()];
+               // Set visibility of controls according to whether they're needed for the selected type
+               _patchPanel.setVisible(ColourerFactory.areColoursRequired(id));
+               _maxColoursPanel.setVisible(ColourerFactory.isMaxColoursRequired(id));
+       }
+
+       /**
+        * @return the selected colourer object, or null
+        */
+       public PointColourer getSelectedColourer()
+       {
+               final ColourerId id = _typeIds[_typeCombo.getSelectedIndex()];
+               return ColourerFactory.createColourer(id, _startEndPatches[0].getBackground(),
+                       _startEndPatches[1].getBackground(), _maxColoursCombo.getSelectedItem().toString());
+       }
+
+       /**
+        * Select the appropriate item in the dropdown
+        * @param inId id of colourer to choose
+        */
+       private void selectColourerType(ColourerId inId)
+       {
+               int selIndex = -1;
+               for (int i=0; i<_typeIds.length; i++)
+               {
+                       if (_typeIds[i] == inId) {
+                               selIndex = i;
+                               break;
+                       }
+               }
+               if (selIndex < 0) {
+                       System.err.println("Id " + inId + " not found in _typeIds!");
+               }
+               else {
+                       _typeCombo.setSelectedIndex(selIndex);
+               }
+       }
+}