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