001    // License: GPL. For details, see LICENSE file.
002    package org.openstreetmap.josm.gui.bbox;
003    
004    import java.awt.Color;
005    import java.awt.Font;
006    import java.awt.FontMetrics;
007    import java.awt.Graphics2D;
008    import java.awt.Point;
009    import java.awt.RenderingHints;
010    import java.util.List;
011    
012    import javax.swing.ImageIcon;
013    
014    import org.openstreetmap.gui.jmapviewer.interfaces.TileSource;
015    import org.openstreetmap.josm.tools.ImageProvider;
016    
017    public class SourceButton {
018    
019        // Filled in paint, used in hit
020        private int barX;
021        private int barY;
022        private int barWidth;
023        private int layerHeight;
024    
025        private final TileSource[] sources;
026    
027        private ImageIcon enlargeImage;
028        private ImageIcon shrinkImage;
029    
030        private boolean isEnlarged = false;
031    
032        private int currentMap;
033    
034        public static final int HIDE_OR_SHOW = 1;
035    
036        public SourceButton(List<TileSource> sources) {
037            this.sources = sources.toArray(new TileSource[sources.size()]);
038            this.currentMap = 2;
039            enlargeImage = ImageProvider.get("layer-switcher-maximize.png");
040            shrinkImage = ImageProvider.get("layer-switcher-minimize.png");
041        }
042    
043        public void paint(Graphics2D g) {
044            if (isEnlarged) {
045                g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
046                int leftPadding = 5;
047                int radioButtonSize = 10;
048                int topPadding = 5;
049                int bottomPadding = 5;
050    
051                int textWidth = 0;
052    
053                g.setFont(g.getFont().deriveFont(Font.BOLD).deriveFont(15.0f));
054                FontMetrics fm = g.getFontMetrics();
055                for (TileSource source: sources) {
056                    int width = fm.stringWidth(source.getName());
057                    if (width > textWidth) {
058                        textWidth = width;
059                    }
060                }
061    
062                barWidth = textWidth + 50;
063                barX = g.getClipBounds().width  - barWidth - shrinkImage.getIconWidth();
064                barY = 30;
065                layerHeight = 20;
066    
067                g.setColor(new Color(0, 0, 139, 179));
068                g.fillRoundRect(barX, barY, barWidth + shrinkImage.getIconWidth(), sources.length * layerHeight + topPadding + bottomPadding, 10, 10);
069                for (int i=0; i<sources.length; i++) {
070                    g.setColor(Color.WHITE);
071                    g.fillOval(barX + leftPadding, barY + topPadding + i * layerHeight + 6, radioButtonSize, radioButtonSize);
072                    g.drawString(sources[i].getName(), barX + leftPadding + radioButtonSize + leftPadding, barY + topPadding + i * layerHeight + g.getFontMetrics().getHeight());
073                    if (currentMap == i + 2) {
074                        g.setColor(Color.BLACK);
075                        g.fillOval(barX + leftPadding + 1, barY + topPadding + 7 + i * layerHeight, radioButtonSize - 2, radioButtonSize - 2);
076                    }
077                }
078    
079                g.drawImage(shrinkImage.getImage(), barX + barWidth, barY, null);
080            } else {
081                barWidth = 0;
082                barX = g.getClipBounds().width  - shrinkImage.getIconWidth();
083                barY = 30;
084                g.drawImage(enlargeImage.getImage(), barX + barWidth, barY, null);
085            }
086        }
087    
088        public void toggle() {
089            this.isEnlarged = !this.isEnlarged;
090    
091        }
092    
093        public int hit(Point point) {
094            if (isEnlarged) {
095                if (barX + barWidth < point.x) {
096                    if (barY < point.y && point.y < barY + shrinkImage.getIconHeight())
097                        return HIDE_OR_SHOW;
098                } else if (barX < point.x && point.x < barX + barWidth) {
099                    int result = (point.y - barY - 5) / layerHeight;
100                    if (result >= 0 && result < sources.length) {
101                        currentMap = result + 2;
102                        return currentMap;
103                    }
104                }
105            } else {
106                if (barX + barWidth < point.x) {
107                    if (barY < point.y && point.y < barY + shrinkImage.getIconHeight())
108                        return HIDE_OR_SHOW;
109                }
110            }
111    
112            return 0;
113        }
114    
115        public TileSource hitToTileSource(int hit) {
116            if (hit >= 2 && hit < sources.length + 2)
117                return sources[hit - 2];
118            else
119                return null;
120        }
121    
122        public void setCurrentMap(TileSource tileSource) {
123            for (int i=0; i<sources.length; i++) {
124                if (sources[i].equals(tileSource)) {
125                    currentMap = i + 2;
126                    return;
127                }
128            }
129            currentMap = 2;
130        }
131    }