X-Git-Url: http://gitweb.fperrin.net/?a=blobdiff_plain;f=tim%2Fprune%2Fgui%2FMapChart.java;h=a5e7819ba209ab14e6b565fc31e49cca1523e091;hb=63f178fd6c6b30b99a01f2a2d700963ea2dfef8b;hp=13b1b7d9e00a54292e4fe62d31084868e74de854;hpb=312fec956e43f5d0a38617da5d0add9c62563e2c;p=GpsPrune.git diff --git a/tim/prune/gui/MapChart.java b/tim/prune/gui/MapChart.java index 13b1b7d..a5e7819 100644 --- a/tim/prune/gui/MapChart.java +++ b/tim/prune/gui/MapChart.java @@ -19,10 +19,11 @@ import javax.swing.JMenuItem; import javax.swing.JPopupMenu; import tim.prune.App; +import tim.prune.DataSubscriber; import tim.prune.I18nManager; import tim.prune.data.DataPoint; -import tim.prune.data.Field; import tim.prune.data.TrackInfo; +//import tim.prune.gui.map.MapWindow; /** @@ -49,7 +50,7 @@ public class MapChart extends GenericChart implements MouseWheelListener, KeyLis private BufferedImage _image = null; private JPopupMenu _popup = null; private JCheckBoxMenuItem _autoPanMenuItem = null; - private String _trackString = null; + private JCheckBoxMenuItem _connectPointsMenuItem = null; private int _numPoints = -1; private double _scale; private double _offsetX, _offsetY, _zoomScale; @@ -83,27 +84,28 @@ public class MapChart extends GenericChart implements MouseWheelListener, KeyLis /** * Override track updating to refresh image */ - public void dataUpdated() + public void dataUpdated(byte inUpdateType) { - // Check if number of points has changed or Track - // object has a different signature - if (_track.getNumPoints() != _numPoints) + // Check if number of points has changed or data has been edited + if (_track.getNumPoints() != _numPoints || (inUpdateType & DATA_EDITED) > 0) { _image = null; + _lastSelectedPoint = -1; _numPoints = _track.getNumPoints(); } - super.dataUpdated(); + super.dataUpdated(inUpdateType); } /** * Override paint method to draw map + * @param inG graphics object */ - public void paint(Graphics g) + public void paint(Graphics inG) { if (_track == null) { - super.paint(g); + super.paint(inG); return; } @@ -126,25 +128,25 @@ public class MapChart extends GenericChart implements MouseWheelListener, KeyLis // Autopan is enabled and a point is selected - work out x and y to see if it's within range x = width/2 + (int) ((_track.getX(selectedPoint) - _offsetX) / _scale * _zoomScale); y = height/2 - (int) ((_track.getY(selectedPoint) - _offsetY) / _scale * _zoomScale); - if (x < BORDER_WIDTH) + if (x <= BORDER_WIDTH) { // autopan left _offsetX -= (width / 4 - x) * _scale / _zoomScale; _image = null; } - else if (x > (width - BORDER_WIDTH)) + else if (x >= (width - BORDER_WIDTH)) { // autopan right _offsetX += (x - width * 3/4) * _scale / _zoomScale; _image = null; } - if (y < BORDER_WIDTH) + if (y <= BORDER_WIDTH) { // autopan up _offsetY += (height / 4 - y) * _scale / _zoomScale; _image = null; } - else if (y > (height - BORDER_WIDTH)) + else if (y >= (height - BORDER_WIDTH)) { // autopan down _offsetY -= (y - height * 3/4) * _scale / _zoomScale; @@ -153,19 +155,23 @@ public class MapChart extends GenericChart implements MouseWheelListener, KeyLis } _lastSelectedPoint = selectedPoint; + // Create background if necessary if (_image == null || width != _image.getWidth() || height != _image.getHeight()) { createBackgroundImage(); } + // return if image has been set to null by other thread + if (_image == null) {return;} + // draw buffered image onto g - g.drawImage(_image, 0, 0, width, height, COLOR_BG, null); + inG.drawImage(_image, 0, 0, width, height, COLOR_BG, null); // draw selected range, if any if (_trackInfo.getSelection().hasRangeSelected() && !_zoomDragging) { int rangeStart = _trackInfo.getSelection().getStart(); int rangeEnd = _trackInfo.getSelection().getEnd(); - g.setColor(COLOR_CURR_RANGE); + inG.setColor(COLOR_CURR_RANGE); for (int i=rangeStart; i<=rangeEnd; i++) { x = width/2 + (int) ((_track.getX(i) - _offsetX) / _scale * _zoomScale); @@ -173,7 +179,7 @@ public class MapChart extends GenericChart implements MouseWheelListener, KeyLis if (x > BORDER_WIDTH && x < (width - BORDER_WIDTH) && y < (height - BORDER_WIDTH) && y > BORDER_WIDTH) { - g.drawOval(x - 2, y - 2, 4, 4); + inG.drawRect(x - 2, y - 2, 4, 4); } } } @@ -181,43 +187,51 @@ public class MapChart extends GenericChart implements MouseWheelListener, KeyLis // Highlight selected point if (selectedPoint >= 0 && !_zoomDragging) { - g.setColor(COLOR_CROSSHAIRS); + inG.setColor(COLOR_CROSSHAIRS); x = width/2 + (int) ((_track.getX(selectedPoint) - _offsetX) / _scale * _zoomScale); y = height/2 - (int) ((_track.getY(selectedPoint) - _offsetY) / _scale * _zoomScale); if (x > BORDER_WIDTH && x < (width - BORDER_WIDTH) && y < (height - BORDER_WIDTH) && y > BORDER_WIDTH) { // Draw cross-hairs for current point - g.drawLine(x, BORDER_WIDTH, x, height - BORDER_WIDTH); - g.drawLine(BORDER_WIDTH, y, width - BORDER_WIDTH, y); + inG.drawLine(x, BORDER_WIDTH, x, height - BORDER_WIDTH); + inG.drawLine(BORDER_WIDTH, y, width - BORDER_WIDTH, y); // Show selected point afterwards to make sure it's on top - g.drawOval(x - 2, y - 2, 4, 4); - g.drawOval(x - 3, y - 3, 6, 6); + inG.drawOval(x - 2, y - 2, 4, 4); + inG.drawOval(x - 3, y - 3, 6, 6); } } + // Draw rectangle for dragging zoom area if (_zoomDragging) { - g.setColor(COLOR_CROSSHAIRS); - g.drawLine(_zoomDragFromX, _zoomDragFromY, _zoomDragFromX, _zoomDragToY); - g.drawLine(_zoomDragFromX, _zoomDragFromY, _zoomDragToX, _zoomDragFromY); - g.drawLine(_zoomDragToX, _zoomDragFromY, _zoomDragToX, _zoomDragToY); - g.drawLine(_zoomDragFromX, _zoomDragToY, _zoomDragToX, _zoomDragToY); + inG.setColor(COLOR_CROSSHAIRS); + inG.drawLine(_zoomDragFromX, _zoomDragFromY, _zoomDragFromX, _zoomDragToY); + inG.drawLine(_zoomDragFromX, _zoomDragFromY, _zoomDragToX, _zoomDragFromY); + inG.drawLine(_zoomDragToX, _zoomDragFromY, _zoomDragToX, _zoomDragToY); + inG.drawLine(_zoomDragFromX, _zoomDragToY, _zoomDragToX, _zoomDragToY); } + + // Attempt to grab keyboard focus if possible + //requestFocus(); (causes problems here) } /** - * Draw the map onto an offscreen image + * Plot the points onto an offscreen image + * which doesn't have to be redrawn when the selection changes */ private void createBackgroundImage() { int width = getWidth(); int height = getHeight(); int x, y; - // Make a new image and initialise it - _image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + int lastX = 0, lastY = 0; + // Initialise image + if (_image == null || _image.getWidth() != width || _image.getHeight() != height) { + _image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + } Graphics bufferedG = _image.getGraphics(); super.paint(bufferedG); @@ -226,6 +240,7 @@ public class MapChart extends GenericChart implements MouseWheelListener, KeyLis bufferedG.setColor(COLOR_POINT); int halfWidth = width/2; int halfHeight = height/2; + boolean currPointTrackpoint = false, lastPointTrackpoint = false; for (int i=0; i BORDER_WIDTH && x < (width - BORDER_WIDTH) && y < (height - BORDER_WIDTH) && y > BORDER_WIDTH) { - bufferedG.drawOval(x - 2, y - 2, 4, 4); + // draw block for point (a bit faster than circles) + bufferedG.drawRect(x - 2, y - 2, 3, 3); + + // See whether to connect the point with previous one or not + currPointTrackpoint = !_track.getPoint(i).isWaypoint() && _track.getPoint(i).getPhoto() == null; + if (_connectPointsMenuItem.isSelected() && currPointTrackpoint && lastPointTrackpoint) + { + bufferedG.drawLine(lastX, lastY, x, y); + } + lastPointTrackpoint = currPointTrackpoint; + } + else { + lastPointTrackpoint = false; } + lastX = x; lastY = y; } // Loop again and show waypoints with names @@ -245,9 +273,12 @@ public class MapChart extends GenericChart implements MouseWheelListener, KeyLis for (int i=0; i= LIMIT_WAYPOINT_NAMES || _image == null) {break;} + // calculate coordinates of point x = halfWidth + (int) ((_track.getX(i) - _offsetX) / _scale * _zoomScale); y = halfHeight - (int) ((_track.getY(i) - _offsetY) / _scale * _zoomScale); if (x > BORDER_WIDTH && x < (width - BORDER_WIDTH) @@ -258,36 +289,34 @@ public class MapChart extends GenericChart implements MouseWheelListener, KeyLis int nameWidth = fm.stringWidth(waypointName); if (nameWidth < (width - 2 * BORDER_WIDTH)) { - double nameAngle = 0.3; - double nameRadius = 1.0; boolean drawnName = false; - while (!drawnName) + // Make arrays for coordinates right left up down + int[] nameXs = {x + 2, x - nameWidth - 2, x - nameWidth/2, x - nameWidth/2}; + int[] nameYs = {y + (nameHeight/2), y + (nameHeight/2), y - 2, y + nameHeight + 2}; + for (int extraSpace = 4; extraSpace < 13 && !drawnName; extraSpace+=2) { - int nameX = x + (int) (nameRadius * Math.cos(nameAngle)) - (nameWidth/2); - int nameY = y + (int) (nameRadius * Math.sin(nameAngle)) + (nameHeight/2); - if (nameX > BORDER_WIDTH && (nameX + nameWidth) < (width - BORDER_WIDTH) - && nameY < (height - BORDER_WIDTH) && (nameY - nameHeight) > BORDER_WIDTH) + // Shift arrays for coordinates right left up down + nameXs[0] += 2; nameXs[1] -= 2; + nameYs[2] -= 2; nameYs[3] += 2; + // Check each direction in turn right left up down + for (int a=0; a<4; a++) { - // name can fit in grid - does it overlap data points? - if (!overlapsPoints(nameX, nameY, nameWidth, nameHeight) || nameRadius > 50.0) + if (nameXs[a] > BORDER_WIDTH && (nameXs[a] + nameWidth) < (width - BORDER_WIDTH) + && nameYs[a] < (height - BORDER_WIDTH) && (nameYs[a] - nameHeight) > BORDER_WIDTH + && !overlapsPoints(nameXs[a], nameYs[a], nameWidth, nameHeight)) { - bufferedG.drawString(waypointName, nameX, nameY); + // Found a rectangle to fit - draw name here and quit + bufferedG.drawString(waypointName, nameXs[a], nameYs[a]); drawnName = true; - numWaypointNamesShown++; + break; } } - nameAngle += 0.08; - nameRadius += 0.2; - // wasn't room within the radius, so don't print name - if (nameRadius > 50.0) - { - drawnName = true; - } } } } } } + bufferedG.dispose(); } @@ -301,15 +330,22 @@ public class MapChart extends GenericChart implements MouseWheelListener, KeyLis */ private boolean overlapsPoints(int inX, int inY, int inWidth, int inHeight) { - // if (true) return true; - for (int x=0; x BORDER_WIDTH && yClick > BORDER_WIDTH && xClick < (getWidth() - BORDER_WIDTH) && yClick < (getHeight() - BORDER_WIDTH)) { // Check left click or right click - if (e.isMetaDown()) + if (inE.isMetaDown()) { // Only show popup if track has data if (_track != null && _track.getNumPoints() > 0) - _popup.show(this, e.getX(), e.getY()); + _popup.show(this, xClick, yClick); } else { @@ -454,6 +512,8 @@ public class MapChart extends GenericChart implements MouseWheelListener, KeyLis double xZoom = Math.abs(getWidth() * 1.0 / (e.getX() - _zoomDragFromX)); double yZoom = Math.abs(getHeight() * 1.0 / (e.getY() - _zoomDragFromY)); double extraZoom = (xZoom>yZoom?yZoom:xZoom); + // deselect point if selected (to stop autopan) + _trackInfo.getSelection().selectPoint(-1); // Pan first to ensure pan occurs with correct scale panMap(yPan, xPan); // Then zoom in and request repaint @@ -513,7 +573,11 @@ public class MapChart extends GenericChart implements MouseWheelListener, KeyLis panMap(upwardsPan, rightwardsPan); // Check for delete key to delete current point if (code == KeyEvent.VK_DELETE && _trackInfo.getSelection().getCurrentPointIndex() >= 0) + { _app.deleteCurrentPoint(); + // reset last selected point to trigger autopan + _lastSelectedPoint = -1; + } } } @@ -578,4 +642,15 @@ public class MapChart extends GenericChart implements MouseWheelListener, KeyLis { // ignore } + + /** + * Show a map window - probably only temporarily here until it gets fixed + */ +/* + private void showMap() + { + MapWindow map = new MapWindow(_track); + map.show(); + } +*/ }