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 }