[3719] | 1 | // License: GPL. For details, see LICENSE file.
|
---|
[3094] | 2 | package org.openstreetmap.josm.gui.bbox;
|
---|
[1390] | 3 |
|
---|
[3597] | 4 | import java.awt.Color;
|
---|
[6539] | 5 | import java.awt.Dimension;
|
---|
[3597] | 6 | import java.awt.Font;
|
---|
| 7 | import java.awt.FontMetrics;
|
---|
[6539] | 8 | import java.awt.Graphics;
|
---|
[3597] | 9 | import java.awt.Graphics2D;
|
---|
[1390] | 10 | import java.awt.Point;
|
---|
[3597] | 11 | import java.awt.RenderingHints;
|
---|
[6539] | 12 | import java.awt.event.MouseAdapter;
|
---|
| 13 | import java.awt.event.MouseEvent;
|
---|
| 14 | import java.awt.event.MouseListener;
|
---|
[6364] | 15 | import java.util.Collection;
|
---|
[1390] | 16 |
|
---|
| 17 | import javax.swing.ImageIcon;
|
---|
[6539] | 18 | import javax.swing.JComponent;
|
---|
[1390] | 19 |
|
---|
[3602] | 20 | import org.openstreetmap.gui.jmapviewer.interfaces.TileSource;
|
---|
[6364] | 21 | import org.openstreetmap.josm.tools.CheckParameterUtil;
|
---|
[1390] | 22 | import org.openstreetmap.josm.tools.ImageProvider;
|
---|
| 23 |
|
---|
[6539] | 24 | public class SourceButton extends JComponent {
|
---|
[1390] | 25 |
|
---|
[6603] | 26 | private static final int LAYER_HEIGHT = 20;
|
---|
| 27 | private static final int LEFT_PADDING = 5;
|
---|
| 28 | private static final int TOP_PADDING = 5;
|
---|
| 29 | private static final int BOTTOM_PADDING = 5;
|
---|
[1390] | 30 |
|
---|
[8308] | 31 | private transient TileSource[] sources;
|
---|
[3597] | 32 |
|
---|
[6539] | 33 | private final ImageIcon enlargeImage;
|
---|
| 34 | private final ImageIcon shrinkImage;
|
---|
| 35 | private final Dimension hiddenDimension;
|
---|
[1390] | 36 |
|
---|
[6539] | 37 | // Calculated after component is added to container
|
---|
| 38 | private int barWidth;
|
---|
| 39 | private Dimension shownDimension;
|
---|
| 40 | private Font font;
|
---|
| 41 |
|
---|
[8840] | 42 | private boolean isEnlarged;
|
---|
[1390] | 43 |
|
---|
[3602] | 44 | private int currentMap;
|
---|
[6539] | 45 | private final SlippyMapBBoxChooser slippyMapBBoxChooser;
|
---|
[1390] | 46 |
|
---|
[6539] | 47 | public SourceButton(SlippyMapBBoxChooser slippyMapBBoxChooser, Collection<TileSource> sources) {
|
---|
| 48 | this.slippyMapBBoxChooser = slippyMapBBoxChooser;
|
---|
[6364] | 49 | setSources(sources);
|
---|
[8056] | 50 | enlargeImage = ImageProvider.get("layer-switcher-maximize");
|
---|
| 51 | shrinkImage = ImageProvider.get("layer-switcher-minimize");
|
---|
[6539] | 52 |
|
---|
[8510] | 53 | hiddenDimension = new Dimension(enlargeImage.getIconWidth(), enlargeImage.getIconHeight());
|
---|
[6539] | 54 | setPreferredSize(hiddenDimension);
|
---|
| 55 |
|
---|
| 56 | addMouseListener(mouseListener);
|
---|
[1390] | 57 | }
|
---|
[6539] | 58 |
|
---|
[8308] | 59 | private final transient MouseListener mouseListener = new MouseAdapter() {
|
---|
[6539] | 60 | @Override
|
---|
| 61 | public void mouseReleased(MouseEvent e) {
|
---|
| 62 | if (e.getButton() == MouseEvent.BUTTON1) {
|
---|
| 63 | Point point = e.getPoint();
|
---|
| 64 | if (isEnlarged) {
|
---|
| 65 | if (barWidth < point.x && point.y < shrinkImage.getIconHeight()) {
|
---|
| 66 | toggle();
|
---|
| 67 | } else {
|
---|
[6603] | 68 | int result = (point.y - 5) / LAYER_HEIGHT;
|
---|
[6539] | 69 | if (result >= 0 && result < SourceButton.this.sources.length) {
|
---|
| 70 | SourceButton.this.slippyMapBBoxChooser.toggleMapSource(SourceButton.this.sources[result]);
|
---|
| 71 | currentMap = result;
|
---|
| 72 | toggle();
|
---|
| 73 | }
|
---|
| 74 | }
|
---|
| 75 | } else {
|
---|
| 76 | toggle();
|
---|
| 77 | }
|
---|
| 78 | }
|
---|
| 79 | }
|
---|
| 80 | };
|
---|
| 81 |
|
---|
[6364] | 82 | /**
|
---|
| 83 | * Set the tile sources.
|
---|
| 84 | * @param sources The tile sources to display
|
---|
| 85 | * @since 6364
|
---|
| 86 | */
|
---|
| 87 | public final void setSources(Collection<TileSource> sources) {
|
---|
| 88 | CheckParameterUtil.ensureParameterNotNull(sources, "sources");
|
---|
| 89 | this.sources = sources.toArray(new TileSource[sources.size()]);
|
---|
[6539] | 90 | shownDimension = null;
|
---|
[6364] | 91 | }
|
---|
[1390] | 92 |
|
---|
[6539] | 93 | @Override
|
---|
| 94 | protected void paintComponent(Graphics graphics) {
|
---|
| 95 | Graphics2D g = (Graphics2D) graphics.create();
|
---|
| 96 | try {
|
---|
| 97 | calculateShownDimension();
|
---|
| 98 | g.setFont(font);
|
---|
| 99 | if (isEnlarged) {
|
---|
| 100 | g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
---|
| 101 | int radioButtonSize = 10;
|
---|
[1390] | 102 |
|
---|
[6539] | 103 | g.setColor(new Color(0, 0, 139, 179));
|
---|
[8509] | 104 | g.fillRoundRect(0, 0, barWidth + shrinkImage.getIconWidth(),
|
---|
| 105 | sources.length * LAYER_HEIGHT + TOP_PADDING + BOTTOM_PADDING, 10, 10);
|
---|
[8510] | 106 | for (int i = 0; i < sources.length; i++) {
|
---|
[6539] | 107 | g.setColor(Color.WHITE);
|
---|
[6603] | 108 | g.fillOval(LEFT_PADDING, TOP_PADDING + i * LAYER_HEIGHT + 6, radioButtonSize, radioButtonSize);
|
---|
[8509] | 109 | g.drawString(sources[i].getName(), LEFT_PADDING + radioButtonSize + LEFT_PADDING,
|
---|
| 110 | TOP_PADDING + i * LAYER_HEIGHT + g.getFontMetrics().getHeight());
|
---|
[6539] | 111 | if (currentMap == i) {
|
---|
| 112 | g.setColor(Color.BLACK);
|
---|
[6603] | 113 | g.fillOval(LEFT_PADDING + 1, TOP_PADDING + 7 + i * LAYER_HEIGHT, radioButtonSize - 2, radioButtonSize - 2);
|
---|
[6539] | 114 | }
|
---|
[3597] | 115 | }
|
---|
[1390] | 116 |
|
---|
[6539] | 117 | g.drawImage(shrinkImage.getImage(), barWidth, 0, null);
|
---|
| 118 | } else {
|
---|
| 119 | g.drawImage(enlargeImage.getImage(), 0, 0, null);
|
---|
[1390] | 120 | }
|
---|
[6539] | 121 | } finally {
|
---|
| 122 | g.dispose();
|
---|
[1390] | 123 | }
|
---|
| 124 | }
|
---|
| 125 |
|
---|
| 126 | public void toggle() {
|
---|
| 127 | this.isEnlarged = !this.isEnlarged;
|
---|
[6539] | 128 | calculateShownDimension();
|
---|
[8510] | 129 | setPreferredSize(isEnlarged ? shownDimension : hiddenDimension);
|
---|
[6539] | 130 | revalidate();
|
---|
[1390] | 131 | }
|
---|
| 132 |
|
---|
[3602] | 133 | public void setCurrentMap(TileSource tileSource) {
|
---|
[8510] | 134 | for (int i = 0; i < sources.length; i++) {
|
---|
[3602] | 135 | if (sources[i].equals(tileSource)) {
|
---|
[6539] | 136 | currentMap = i;
|
---|
[3602] | 137 | return;
|
---|
| 138 | }
|
---|
| 139 | }
|
---|
[6539] | 140 | currentMap = 0;
|
---|
[3602] | 141 | }
|
---|
[6539] | 142 |
|
---|
| 143 | private void calculateShownDimension() {
|
---|
| 144 | if (shownDimension == null) {
|
---|
| 145 | font = getFont().deriveFont(Font.BOLD).deriveFont(15.0f);
|
---|
| 146 | int textWidth = 0;
|
---|
| 147 | FontMetrics fm = getFontMetrics(font);
|
---|
| 148 | for (TileSource source: sources) {
|
---|
| 149 | int width = fm.stringWidth(source.getName());
|
---|
| 150 | if (width > textWidth) {
|
---|
| 151 | textWidth = width;
|
---|
| 152 | }
|
---|
| 153 | }
|
---|
| 154 | barWidth = textWidth + 50;
|
---|
[6603] | 155 | shownDimension = new Dimension(barWidth + shrinkImage.getIconWidth(), sources.length * LAYER_HEIGHT + TOP_PADDING + BOTTOM_PADDING);
|
---|
[6539] | 156 | }
|
---|
| 157 | }
|
---|
[1390] | 158 | }
|
---|