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 }