package tim.prune.gui.map;
+import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.FontMetrics;
import java.awt.Graphics;
+import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import tim.prune.UpdateMessageBroker;
import tim.prune.config.ColourScheme;
import tim.prune.config.Config;
+import tim.prune.data.Checker;
import tim.prune.data.Coordinate;
import tim.prune.data.DataPoint;
import tim.prune.data.DoubleRange;
private Selection _selection = null;
/** Previously selected point */
private int _prevSelectedPoint = -1;
- /** Tile cacher */
- private MapTileCacher _tileCacher = new MapTileCacher(this);
+ /** Tile manager */
+ private MapTileManager _tileManager = new MapTileManager(this);
/** Image to display */
private BufferedImage _mapImage = null;
/** Slider for transparency */
ItemListener mapCheckListener = new ItemListener() {
public void itemStateChanged(ItemEvent e)
{
- _tileCacher.clearAll();
+ _tileManager.clearMemoryCaches();
_recalculate = true;
Config.setConfigBoolean(Config.KEY_SHOW_MAP, e.getStateChange() == ItemEvent.SELECTED);
UpdateMessageBroker.informSubscribers(); // to let menu know
_prevSelectedPoint = selectedPoint;
}
- // Draw the mapImage if necessary
+ // Draw the map contents if necessary
if ((_mapImage == null || _recalculate))
{
- getMapTiles();
- _scaleBar.updateScale(_mapPosition.getZoom(), _mapPosition.getCentreTileY());
+ paintMapContents();
+ _scaleBar.updateScale(_mapPosition.getZoom(), _mapPosition.getYFromPixels(0, 0));
}
// Draw the prepared image onto the panel
if (_mapImage != null) {
/**
- * Get the map tiles for the current zoom level and given tile parameters
+ * Paint the map tiles and the points on to the _mapImage
*/
- private void getMapTiles()
+ private void paintMapContents()
{
if (_mapImage == null || _mapImage.getWidth() != getWidth() || _mapImage.getHeight() != getHeight())
{
// reset error message
if (!showMap) {_shownOsmErrorAlready = false;}
+ _recalculate = false;
// Only get map tiles if selected
if (showMap)
{
// init tile cacher
- _tileCacher.centreMap(_mapPosition.getZoom(), _mapPosition.getCentreTileX(), _mapPosition.getCentreTileY());
+ _tileManager.centreMap(_mapPosition.getZoom(), _mapPosition.getCentreTileX(), _mapPosition.getCentreTileY());
boolean loadingFailed = false;
if (_mapImage == null) return;
- if (_tileCacher.isOverzoomed())
+ if (_tileManager.isOverzoomed())
{
// display overzoom message
g.setColor(COLOR_MESSAGES);
}
else
{
+ int numLayers = _tileManager.getNumLayers();
// Loop over tiles drawing each one
int[] tileIndices = _mapPosition.getTileIndices(getWidth(), getHeight());
int[] pixelOffsets = _mapPosition.getDisplayOffsets(getWidth(), getHeight());
for (int tileY = tileIndices[2]; tileY <= tileIndices[3]; tileY++)
{
int y = (tileY - tileIndices[2]) * 256 - pixelOffsets[1];
- Image image = _tileCacher.getTile(tileX, tileY);
- if (image != null) {
- g.drawImage(image, x, y, 256, 256, null);
+ // Loop over layers
+ for (int l=0; l<numLayers; l++)
+ {
+ Image image = _tileManager.getTile(l, tileX, tileY);
+ if (image != null) {
+ g.drawImage(image, x, y, 256, 256, null);
+ }
}
}
}
// Make maps brighter / fainter
- float[] scaleFactors = {1.0f, 1.05f, 1.1f, 1.2f, 1.6f, 2.0f};
- float scaleFactor = scaleFactors[_transparencySlider.getValue()];
+ final float[] scaleFactors = {1.0f, 1.05f, 1.1f, 1.2f, 1.6f, 2.2f};
+ final float scaleFactor = scaleFactors[_transparencySlider.getValue()];
if (scaleFactor > 1.0f)
{
RenderingHints hints = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
// free g
g.dispose();
- _recalculate = false;
// Zoom to fit if no points found
if (pointsPainted <= 0 && _checkBounds) {
zoomToFit();
final Color secondColour = Config.getColourScheme().getColour(ColourScheme.IDX_SECONDARY);
final Color textColour = Config.getColourScheme().getColour(ColourScheme.IDX_TEXT);
+ // try to set double line width for painting
+ if (inG instanceof Graphics2D) {
+ ((Graphics2D) inG).setStroke(new BasicStroke(2.0f));
+ }
int pointsPainted = 0;
// draw track points
inG.setColor(pointColour);
// select point if it's a left-click
if (!inE.isMetaDown())
{
- int pointIndex = _track.getNearestPointIndex(
- _mapPosition.getXFromPixels(inE.getX(), getWidth()),
- _mapPosition.getYFromPixels(inE.getY(), getHeight()),
- _mapPosition.getBoundsFromPixels(CLICK_SENSITIVITY), false);
- // Extend selection for shift-click
- if (inE.isShiftDown()) {
- _trackInfo.extendSelection(pointIndex);
+ if (inE.getClickCount() == 1)
+ {
+ // single click
+ int pointIndex = _track.getNearestPointIndex(
+ _mapPosition.getXFromPixels(inE.getX(), getWidth()),
+ _mapPosition.getYFromPixels(inE.getY(), getHeight()),
+ _mapPosition.getBoundsFromPixels(CLICK_SENSITIVITY), false);
+ // Extend selection for shift-click
+ if (inE.isShiftDown()) {
+ _trackInfo.extendSelection(pointIndex);
+ }
+ else {
+ _trackInfo.selectPoint(pointIndex);
+ }
}
- else {
- _trackInfo.selectPoint(pointIndex);
+ else if (inE.getClickCount() == 2) {
+ // double click
+ panMap(inE.getX() - getWidth()/2, inE.getY() - getHeight()/2);
+ zoomIn();
}
}
else
_checkBounds = true;
}
if ((inUpdateType & DataSubscriber.MAPSERVER_CHANGED) > 0) {
- _tileCacher.setTileConfig(new MapTileConfig());
+ _tileManager.resetConfig();
}
repaint();
// enable or disable components
{
int code = inE.getKeyCode();
int currPointIndex = _selection.getCurrentPointIndex();
- // Check for meta key
- if (inE.isControlDown())
+ // Check for Ctrl key (for Linux/Win) or meta key (Clover key for Mac)
+ if (inE.isControlDown() || inE.isMetaDown())
{
// Check for arrow keys to zoom in and out
if (code == KeyEvent.VK_UP)
_trackInfo.selectPoint(currPointIndex-1);
else if (code == KeyEvent.VK_RIGHT)
_trackInfo.selectPoint(currPointIndex+1);
+ else if (code == KeyEvent.VK_PAGE_UP)
+ _trackInfo.selectPoint(Checker.getPreviousSegmentStart(
+ _trackInfo.getTrack(), _trackInfo.getSelection().getCurrentPointIndex()));
+ else if (code == KeyEvent.VK_PAGE_DOWN)
+ _trackInfo.selectPoint(Checker.getNextSegmentStart(
+ _trackInfo.getTrack(), _trackInfo.getSelection().getCurrentPointIndex()));
+ // Check for home and end
+ else if (code == KeyEvent.VK_HOME)
+ _trackInfo.selectPoint(0);
+ else if (code == KeyEvent.VK_END)
+ _trackInfo.selectPoint(_trackInfo.getTrack().getNumPoints()-1);
}
else
{
else if (code == KeyEvent.VK_LEFT)
rightwardsPan = -PAN_DISTANCE;
panMap(rightwardsPan, upwardsPan);
- // Check for delete key to delete current point
- if (code == KeyEvent.VK_DELETE && currPointIndex >= 0)
- {
+ // Check for backspace key to delete current point (delete key already handled by menu)
+ if (code == KeyEvent.VK_BACK_SPACE && currPointIndex >= 0) {
_app.deleteCurrentPoint();
}
}