Ignore:
Timestamp:
2019-11-02T15:11:34+01:00 (4 years ago)
Author:
Don-vip
Message:

fix #16796 - Rework of GPX track colors / layer preferences (patch by Bjoeni)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/gui/layer/gpx/ChooseTrackVisibilityAction.java

    r14337 r15496  
    55import static org.openstreetmap.josm.tools.I18n.tr;
    66
     7import java.awt.Color;
    78import java.awt.Component;
    89import java.awt.Dimension;
     
    1314import java.awt.event.MouseListener;
    1415import java.io.Serializable;
     16import java.util.ArrayList;
    1517import java.util.Arrays;
    1618import java.util.Comparator;
     19import java.util.List;
    1720import java.util.Map;
     21import java.util.Objects;
    1822import java.util.Optional;
    1923
    2024import javax.swing.AbstractAction;
     25import javax.swing.JColorChooser;
    2126import javax.swing.JComponent;
    2227import javax.swing.JLabel;
     28import javax.swing.JOptionPane;
    2329import javax.swing.JPanel;
    2430import javax.swing.JScrollPane;
     
    2632import javax.swing.JToggleButton;
    2733import javax.swing.ListSelectionModel;
     34import javax.swing.event.TableModelEvent;
    2835import javax.swing.table.DefaultTableModel;
    2936import javax.swing.table.TableCellRenderer;
    3037import javax.swing.table.TableRowSorter;
    3138
     39import org.apache.commons.jcs.access.exception.InvalidArgumentException;
    3240import org.openstreetmap.josm.data.SystemOfMeasurement;
    3341import org.openstreetmap.josm.data.gpx.GpxConstants;
     
    3644import org.openstreetmap.josm.gui.MainApplication;
    3745import org.openstreetmap.josm.gui.layer.GpxLayer;
     46import org.openstreetmap.josm.gui.preferences.display.GPXSettingsPanel;
    3847import org.openstreetmap.josm.gui.util.WindowGeometry;
    3948import org.openstreetmap.josm.tools.GBC;
     
    5665     */
    5766    public ChooseTrackVisibilityAction(final GpxLayer layer) {
    58         super(tr("Choose visible tracks"));
     67        super(tr("Choose track visibility and colors"));
    5968        new ImageProvider("dialogs/filter").getResource().attachImageIcon(this, true);
    6069        this.layer = layer;
     
    117126            TrackLength length = new TrackLength(trk.length());
    118127            String url = (String) Optional.ofNullable(attr.get("url")).orElse("");
    119             tracks[i] = new Object[]{name, desc, time, length, url};
     128            tracks[i] = new Object[]{name, desc, time, length, url, trk};
    120129            i++;
    121130        }
     
    123132    }
    124133
     134    private void showColorDialog(List<GpxTrack> tracks) {
     135        Color cl = tracks.stream().filter(Objects::nonNull)
     136                .map(GpxTrack::getColor).filter(Objects::nonNull)
     137                .findAny().orElse(GpxDrawHelper.DEFAULT_COLOR_PROPERTY.get());
     138        JColorChooser c = new JColorChooser(cl);
     139        Object[] options = new Object[]{tr("OK"), tr("Cancel"), tr("Default")};
     140        int answer = JOptionPane.showOptionDialog(
     141                MainApplication.getMainFrame(),
     142                c,
     143                tr("Choose a color"),
     144                JOptionPane.OK_CANCEL_OPTION,
     145                JOptionPane.PLAIN_MESSAGE,
     146                null,
     147                options,
     148                options[0]
     149        );
     150        switch (answer) {
     151        case 0:
     152            tracks.stream().forEach(t -> t.setColor(c.getColor()));
     153            GPXSettingsPanel.putLayerPrefLocal(layer, "colormode", "0"); //set Colormode to none
     154            break;
     155        case 1:
     156            return;
     157        case 2:
     158            tracks.stream().forEach(t -> t.setColor(null));
     159            break;
     160        }
     161        table.repaint();
     162    }
     163
    125164    /**
    126      * Builds an non-editable table whose 5th column will open a browser when double clicked.
     165     * Builds an editable table whose 5th column will open a browser when double clicked.
    127166     * The table will fill its parent.
    128167     * @param content table data
     
    139178                    JComponent jc = (JComponent) c;
    140179                    jc.setToolTipText(getValueAt(row, col).toString());
     180                    if (content.length > row
     181                            && content[row].length > 5
     182                            && content[row][5] instanceof GpxTrack) {
     183                        Color color = ((GpxTrack) content[row][5]).getColor();
     184                        if (color != null) {
     185                            double brightness = Math.sqrt(Math.pow(color.getRed(), 2) * .241
     186                                    + Math.pow(color.getGreen(), 2) * .691
     187                                    + Math.pow(color.getBlue(), 2) * .068);
     188                            if (brightness > 250) {
     189                                color = color.darker();
     190                            }
     191                            if (isRowSelected(row)) {
     192                                jc.setBackground(color);
     193                                if (brightness <= 130) {
     194                                    jc.setForeground(Color.WHITE);
     195                                } else {
     196                                    jc.setForeground(Color.BLACK);
     197                                }
     198                            } else {
     199                                if (brightness > 200) {
     200                                    color = color.darker(); //brightness >250 is darkened twice on purpose
     201                                }
     202                                jc.setForeground(color);
     203                                jc.setBackground(Color.WHITE);
     204                            }
     205                        } else {
     206                            jc.setForeground(Color.BLACK);
     207                            if (isRowSelected(row)) {
     208                                jc.setBackground(new Color(175, 210, 210));
     209                            } else {
     210                                jc.setBackground(Color.WHITE);
     211                            }
     212                        }
     213                    }
    141214                }
    142215                return c;
     
    145218            @Override
    146219            public boolean isCellEditable(int rowIndex, int colIndex) {
    147                 return false;
     220                return colIndex <= 1;
     221            }
     222
     223            @Override
     224            public void tableChanged(TableModelEvent e) {
     225                super.tableChanged(e);
     226                int col = e.getColumn();
     227                int row = e.getFirstRow();
     228                if (row >= 0 && row < content.length && col >= 0 && col <= 1) {
     229                    Object t = content[row][5];
     230                    String val = (String) getValueAt(row, col);
     231                    if (t != null && t instanceof GpxTrack) {
     232                        GpxTrack trk = (GpxTrack) t;
     233                        if (col == 0) {
     234                            trk.put("name", val);
     235                        } else {
     236                            trk.put("desc", val);
     237                        }
     238                    } else {
     239                        throw new InvalidArgumentException("Invalid object in table, must be GpxTrack.");
     240                    }
     241                }
    148242            }
    149243        };
     
    181275        t.addMouseListener(urlOpener);
    182276        t.setFillsViewportHeight(true);
     277        t.putClientProperty("terminateEditOnFocusLost", true);
    183278        return t;
    184279    }
     
    250345        msg.add(new JLabel(tr("<html>Select all tracks that you want to be displayed. " +
    251346                "You can drag select a range of tracks or use CTRL+Click to select specific ones. " +
    252                 "The map is updated live in the background. Open the URLs by double clicking them.</html>")),
     347                "The map is updated live in the background. Open the URLs by double clicking them, " +
     348                "edit name and description by double clicking the cell.</html>")),
    253349                GBC.eop().fill(GBC.HORIZONTAL));
    254350        // build table
    255351        final boolean[] trackVisibilityBackup = layer.trackVisibility.clone();
    256         table = buildTable(buildTableContents());
     352        Object[][] content = buildTableContents();
     353        table = buildTable(content);
    257354        selectVisibleTracksInTable();
    258355        listenToSelectionChanges();
     
    263360        int v = 1;
    264361        // build dialog
    265         ExtendedDialog ed = new ExtendedDialog(MainApplication.getMainFrame(), tr("Set track visibility for {0}", layer.getName()),
    266                 tr("Show all"), tr("Show selected only"), tr("Cancel"));
    267         ed.setButtonIcons("eye", "dialogs/filter", "cancel");
     362        ExtendedDialog ed = new ExtendedDialog(MainApplication.getMainFrame(),
     363                tr("Set track visibility for {0}", layer.getName()),
     364                tr("Set color for selected tracks..."), tr("Show all"), tr("Show selected only"), tr("Close")) {
     365            @Override
     366            protected void buttonAction(int buttonIndex, ActionEvent evt) {
     367                if (buttonIndex == 0) {
     368                    List<GpxTrack> trks = new ArrayList<>();
     369                    for (int i : table.getSelectedRows()) {
     370                        Object trk = content[i][5];
     371                        if (trk != null && trk instanceof GpxTrack) {
     372                            trks.add((GpxTrack) trk);
     373                        }
     374                    }
     375                    showColorDialog(trks);
     376                } else {
     377                    super.buttonAction(buttonIndex, evt);
     378                }
     379            }
     380        };
     381        ed.setButtonIcons("colorchooser", "eye", "dialogs/filter", "cancel");
    268382        ed.setContent(msg, false);
    269383        ed.setDefaultButton(2);
     
    276390        v = ed.getValue();
    277391        // cancel for unknown buttons and copy back original settings
    278         if (v != 1 && v != 2) {
     392        if (v != 2 && v != 3) {
    279393            layer.trackVisibility = Arrays.copyOf(trackVisibilityBackup, layer.trackVisibility.length);
    280394            MainApplication.getMap().repaint();
    281395            return;
    282396        }
    283         // set visibility (1 = show all, 2 = filter). If no tracks are selected
     397        // set visibility (2 = show all, 3 = filter). If no tracks are selected
    284398        // set all of them visible and...
    285399        ListSelectionModel s = table.getSelectionModel();
    286         final boolean all = v == 1 || s.isSelectionEmpty();
     400        final boolean all = v == 2 || s.isSelectionEmpty();
    287401        for (int i = 0; i < layer.trackVisibility.length; i++) {
    288402            layer.trackVisibility[table.convertRowIndexToModel(i)] = all || s.isSelectedIndex(i);
     
    291405        layer.invalidate();
    292406        // ...sync with layer visibility instead to avoid having two ways to hide everything
    293         layer.setVisible(v == 1 || !s.isSelectionEmpty());
     407        layer.setVisible(v == 2 || !s.isSelectionEmpty());
    294408    }
    295409}
Note: See TracChangeset for help on using the changeset viewer.