001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.layer.markerlayer;
003
004import java.awt.BorderLayout;
005import java.awt.Cursor;
006import java.awt.GraphicsEnvironment;
007import java.awt.Image;
008import java.awt.event.ActionEvent;
009import java.awt.event.ActionListener;
010import java.net.URL;
011import java.util.Collections;
012
013import javax.swing.Icon;
014import javax.swing.ImageIcon;
015import javax.swing.JDialog;
016import javax.swing.JLabel;
017import javax.swing.JOptionPane;
018import javax.swing.JPanel;
019import javax.swing.JScrollPane;
020import javax.swing.JToggleButton;
021import javax.swing.JViewport;
022
023import org.openstreetmap.josm.Main;
024import org.openstreetmap.josm.data.coor.LatLon;
025import org.openstreetmap.josm.data.gpx.GpxConstants;
026import org.openstreetmap.josm.data.gpx.GpxLink;
027import org.openstreetmap.josm.data.gpx.WayPoint;
028import org.openstreetmap.josm.tools.ImageProvider;
029
030/**
031 * Marker representing an image. Uses a special icon, and when clicked,
032 * displays an image view dialog. Re-uses some code from GeoImageLayer.
033 *
034 * @author Frederik Ramm
035 *
036 */
037public class ImageMarker extends ButtonMarker {
038
039    public URL imageUrl;
040
041    public ImageMarker(LatLon ll, URL imageUrl, MarkerLayer parentLayer, double time, double offset) {
042        super(ll, "photo", parentLayer, time, offset);
043        this.imageUrl = imageUrl;
044    }
045
046    @Override public void actionPerformed(ActionEvent ev) {
047        final JPanel p = new JPanel(new BorderLayout());
048        final JScrollPane scroll = new JScrollPane(new JLabel(loadScaledImage(imageUrl, 580)));
049        final JViewport vp = scroll.getViewport();
050        p.add(scroll, BorderLayout.CENTER);
051
052        final JToggleButton scale = new JToggleButton(ImageProvider.get("misc", "rectangle"));
053
054        JPanel p2 = new JPanel();
055        p2.add(scale);
056        p.add(p2, BorderLayout.SOUTH);
057        scale.addActionListener(new ActionListener() {
058            @Override
059            public void actionPerformed(ActionEvent ev) {
060                p.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
061                if (scale.getModel().isSelected()) {
062                    ((JLabel) vp.getView()).setIcon(loadScaledImage(imageUrl, Math.max(vp.getWidth(), vp.getHeight())));
063                } else {
064                    ((JLabel) vp.getView()).setIcon(new ImageIcon(imageUrl));
065                }
066                p.setCursor(Cursor.getDefaultCursor());
067            }
068        });
069        scale.setSelected(true);
070        JOptionPane pane = new JOptionPane(p, JOptionPane.PLAIN_MESSAGE);
071        if (!GraphicsEnvironment.isHeadless()) {
072            JDialog dlg = pane.createDialog(Main.parent, imageUrl.toString());
073            dlg.setModal(false);
074            dlg.toFront();
075            dlg.setVisible(true);
076        }
077    }
078
079    private static Icon loadScaledImage(URL u, int maxSize) {
080        Image img = new ImageIcon(u).getImage();
081        int w = img.getWidth(null);
082        int h = img.getHeight(null);
083        if (w > h) {
084            h = (int) Math.round(maxSize*((double) h/w));
085            w = maxSize;
086        } else {
087            w = (int) Math.round(maxSize*((double) w/h));
088            h = maxSize;
089        }
090        return new ImageIcon(img.getScaledInstance(w, h, Image.SCALE_SMOOTH));
091    }
092
093    @Override
094    public WayPoint convertToWayPoint() {
095        WayPoint wpt = super.convertToWayPoint();
096        GpxLink link = new GpxLink(imageUrl.toString());
097        link.type = "image";
098        wpt.put(GpxConstants.META_LINKS, Collections.singleton(link));
099        return wpt;
100    }
101}