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