| // MapCanvas.java |
| package org.eclipse.stem.ui.views.geographic.map; |
| |
| /******************************************************************************* |
| * Copyright (c) 2007 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| |
| import java.io.File; |
| import java.io.IOException; |
| import java.util.ConcurrentModificationException; |
| import java.util.List; |
| import java.util.concurrent.CopyOnWriteArrayList; |
| |
| import org.eclipse.jface.viewers.ISelection; |
| import org.eclipse.jface.viewers.ISelectionChangedListener; |
| import org.eclipse.jface.viewers.ISelectionProvider; |
| import org.eclipse.jface.viewers.IStructuredSelection; |
| import org.eclipse.jface.viewers.SelectionChangedEvent; |
| import org.eclipse.jface.viewers.StructuredSelection; |
| import org.eclipse.jface.window.DefaultToolTip; |
| import org.eclipse.stem.core.common.DublinCore; |
| import org.eclipse.stem.core.common.Identifiable; |
| import org.eclipse.stem.core.graph.Edge; |
| import org.eclipse.stem.core.graph.Node; |
| import org.eclipse.stem.core.graph.NodeLabel; |
| import org.eclipse.stem.core.model.STEMTime; |
| import org.eclipse.stem.core.sequencer.Sequencer; |
| import org.eclipse.stem.data.geography.GeographicNames; |
| import org.eclipse.stem.definitions.labels.AreaLabel; |
| import org.eclipse.stem.definitions.labels.PopulationLabel; |
| import org.eclipse.stem.definitions.nodes.Region; |
| import org.eclipse.stem.diseasemodels.standard.StandardDiseaseModelLabel; |
| import org.eclipse.stem.jobs.simulation.ISimulation; |
| import org.eclipse.stem.populationmodels.standard.PopulationModelLabel; |
| import org.eclipse.stem.ui.adapters.color.ColorProviderAdapter; |
| import org.eclipse.stem.ui.adapters.color.ColorScaleComposite; |
| import org.eclipse.stem.ui.adapters.color.StandardColorProvider; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.events.DisposeEvent; |
| import org.eclipse.swt.events.DisposeListener; |
| import org.eclipse.swt.events.KeyAdapter; |
| import org.eclipse.swt.events.KeyEvent; |
| import org.eclipse.swt.events.MouseAdapter; |
| import org.eclipse.swt.events.MouseEvent; |
| import org.eclipse.swt.events.MouseMoveListener; |
| import org.eclipse.swt.events.MouseTrackAdapter; |
| import org.eclipse.swt.events.MouseWheelListener; |
| import org.eclipse.swt.events.PaintEvent; |
| import org.eclipse.swt.events.PaintListener; |
| import org.eclipse.swt.graphics.Color; |
| import org.eclipse.swt.graphics.GC; |
| import org.eclipse.swt.graphics.Image; |
| import org.eclipse.swt.graphics.ImageData; |
| import org.eclipse.swt.graphics.ImageLoader; |
| import org.eclipse.swt.graphics.Point; |
| import org.eclipse.swt.graphics.Rectangle; |
| import org.eclipse.swt.widgets.Canvas; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Control; |
| |
| /** |
| * This class is a SWT Widget that displays a "map" view of the geographic |
| * features of a {@link org.eclipse.stem.jobs.simulation.Simulation}. |
| */ |
| public class MapCanvas |
| extends Canvas |
| implements ISelectionProvider, PaintListener, MouseWheelListener, MouseMoveListener, DisposeListener |
| { |
| |
| private static final int TOOLTIP_HIDE_DELAY = 30000; // milliseconds |
| |
| private static final double INITIAL_ZOOM_FACTOR = 1; |
| private static final double INITIAL_X_TRANSLATION = 0; |
| private static final double INITIAL_Y_TRANSLATION = 0; |
| |
| protected static final double ZOOMING_FACTOR = 1.1; |
| protected static final double UNZOOMING_FACTOR = 1 / ZOOMING_FACTOR; |
| |
| protected static final int BORDER_ALPHA = 25; |
| |
| /** |
| * This is the list of polygons that are rendered. |
| */ |
| private StemPolygonsList polygonsToRender; |
| |
| double zoomFactor = INITIAL_ZOOM_FACTOR; |
| private float gainFactor = 1.0f; |
| private double xTranslation = INITIAL_X_TRANSLATION; |
| private double yTranslation = INITIAL_Y_TRANSLATION; |
| boolean drawPolygonBorders = true; |
| StemPolygonTransform pointsTransformer = new StemPolygonTransform(); |
| boolean toUpdateTranform = true; |
| |
| private final StandardColorProvider stdColorProvider = new StandardColorProvider(this.getDisplay()); |
| private ColorProviderAdapter colorProvider = null; |
| |
| private boolean useLogScaling = true; |
| |
| boolean leftMouseButtonPressed = false; |
| int lastOffsetX; |
| int lastOffsetY; |
| ColorScaleComposite colorScale = null; |
| |
| private ISelection selection; |
| /** |
| * The collection of ISelectionChangedListener waiting to be told about |
| * selections. |
| */ |
| protected final List<ISelectionChangedListener> selectionChangedListeners = new CopyOnWriteArrayList<ISelectionChangedListener>(); |
| private Rectangle polygonsBoundsRect = null; |
| private static final int MARGIN = 10; |
| |
| private final MouseTrackHandler mouseTrackHandler = new MouseTrackHandler(); |
| private final MouseButtonHandler mouseButtonHandler = new MouseButtonHandler(); |
| private final MouseHoverHandler mouseHoverHandler = new MouseHoverHandler(); |
| private final KeyHandler keyHandler = new KeyHandler(); |
| |
| protected Image canvasImage; |
| |
| private ISimulation simulation; |
| private STEMTime time; |
| private Sequencer sequencer; |
| |
| private DefaultToolTip tooltip; |
| |
| /** |
| * @param parent |
| * @param style |
| */ |
| public MapCanvas(final Composite parent, final int style) { |
| super(parent, SWT.DOUBLE_BUFFERED | SWT.NO_BACKGROUND); |
| |
| addPaintListener(this); |
| addMouseWheelListener(this); |
| addMouseTrackListener(mouseTrackHandler); |
| addMouseMoveListener(this); |
| addKeyListener(keyHandler); |
| addDisposeListener(this); |
| addMouseListener(mouseButtonHandler); |
| addMouseTrackListener(mouseHoverHandler); |
| |
| tooltip = new DefaultToolTip(this); |
| tooltip.setHideDelay(TOOLTIP_HIDE_DELAY); |
| |
| } // MapCanvas |
| |
| |
| /** |
| * @see org.eclipse.swt.events.PaintListener#paintControl(org.eclipse.swt.events.PaintEvent) |
| */ |
| public void paintControl(final PaintEvent e) { |
| final GC gc = e.gc; |
| final Point controlSize = ((Control) e.getSource()).getSize(); |
| toUpdateTranform = true; |
| |
| Image newCanvasImage = new Image(e.display, controlSize.x, controlSize.y); |
| |
| GC localGC = new GC(newCanvasImage); |
| draw(localGC, 0, 0, controlSize.x, controlSize.y); |
| localGC.dispose(); |
| |
| gc.drawImage(newCanvasImage, 0, 0); |
| |
| Image oldCanvasImage = canvasImage; |
| canvasImage = newCanvasImage; |
| if (oldCanvasImage != null && !oldCanvasImage.isDisposed()) { |
| oldCanvasImage.dispose(); |
| } |
| |
| } |
| |
| |
| /** |
| * @param path |
| * @throws IOException |
| */ |
| public void saveCanvasImage(File path) throws IOException |
| { |
| try { |
| if (canvasImage != null && !canvasImage.isDisposed()) { |
| ImageLoader loader = new ImageLoader(); |
| loader.data = new ImageData[] {canvasImage.getImageData()}; |
| loader.save(path.getAbsolutePath(), SWT.IMAGE_PNG); |
| } |
| } catch (Exception e) { |
| throw new IOException("MapCanvas:saveCanvasImage() Unable to save map canvas image to the file "+ path.getAbsolutePath()); |
| } |
| } |
| |
| /** |
| * @return |
| */ |
| public Image getCanvasImage() |
| { |
| return canvasImage; |
| } |
| |
| /** |
| * @param e |
| */ |
| public void mouseScrolled(final MouseEvent e) { |
| // Zoom Out? |
| if (e.count >= 0) { |
| // Yes |
| zoomIn(); |
| } else { |
| zoomOut(); |
| } |
| } |
| |
| /** |
| * @param e |
| */ |
| public void mouseMove(MouseEvent e) { |
| |
| if (leftMouseButtonPressed) { |
| // Yes |
| // new x and y are defined by current mouse location subtracted |
| // by previously processed mouse location |
| final int newX = e.x - lastOffsetX; |
| final int newY = e.y - lastOffsetY; |
| lastOffsetX = e.x; |
| lastOffsetY = e.y; |
| |
| // Did we move from the spot where the mouse went down? |
| if (newX != 0 || newY != 0) { |
| // Yes |
| // This is a translation of the map then |
| // update the canvas translation |
| addTranslation(newX, newY); |
| } // if moved |
| } |
| } |
| |
| /** |
| * @see org.eclipse.swt.events.DisposeListener#widgetDisposed(org.eclipse.swt.events.DisposeEvent) |
| */ |
| public void widgetDisposed(@SuppressWarnings("unused") final DisposeEvent e) { |
| if (!isDisposed()) { |
| dispose(); |
| } |
| } |
| |
| /** |
| * @param polygonsToRender |
| */ |
| public void render(final StemPolygonsList polygonsToRender, ISimulation sim) { |
| simulation = sim; |
| this.polygonsToRender = polygonsToRender; |
| redraw(); |
| } // render |
| |
| /** |
| * @param drawPolygonBorders |
| */ |
| public final void setDrawPolygonBorders(final boolean drawPolygonBorders) { |
| this.drawPolygonBorders = drawPolygonBorders; |
| } |
| |
| /** |
| * @param gainFactor |
| */ |
| public final void setGainFactor(final float gainFactor) { |
| this.gainFactor = gainFactor; |
| } |
| |
| /** |
| * @param useLogScaling |
| */ |
| public final void setUseLogScaling(final boolean useLogScaling) { |
| this.useLogScaling = useLogScaling; |
| } |
| |
| /** |
| * Reset |
| */ |
| public void reset() { |
| xTranslation = INITIAL_X_TRANSLATION; |
| yTranslation = INITIAL_Y_TRANSLATION; |
| zoomFactor = INITIAL_ZOOM_FACTOR; |
| } // reset |
| |
| /** |
| * The method which gets the MapCanvas' polygons list, and draws it on the |
| * MapCanvas. |
| * |
| * @param gc |
| * @param x |
| * @param y |
| * @param width |
| * @param height |
| */ |
| void draw(final GC gc, final int x, final int y, final int width, |
| final int height) { |
| |
| gc.setBackground(stdColorProvider.getBackgroundColor()); |
| drawBackground(gc, x, y, width, height); |
| gc.setLineWidth(0); //Zero means the fastest possible line drawing algorithm |
| |
| |
| |
| if (polygonsToRender == null || polygonsToRender.isEmpty()) { |
| return; |
| } |
| |
| //Do we need to recalculate the transform? |
| if (toUpdateTranform) { |
| //Yes, compute it |
| computeTransform(polygonsToRender); |
| //Update all polygons about the changes in the transform |
| for (StemPolygon stempoly : polygonsToRender) { |
| stempoly.setPointsTransformer(pointsTransformer); |
| } |
| toUpdateTranform = false; |
| } |
| |
| Color bordersColor = stdColorProvider.getBordersColor(); |
| |
| for (final StemPolygon stempoly : polygonsToRender) { |
| |
| Identifiable identifiable = stempoly.getIdentifiable(); |
| |
| if (identifiable instanceof Node) { |
| colorProvider.setTarget(identifiable); |
| |
| //Update the G2D with the appropriate color before filling the polygon |
| colorProvider.updateGC(gc, gainFactor, useLogScaling); |
| gc.fillPolygon(stempoly.transformedPoints); |
| |
| if (drawPolygonBorders) { |
| gc.setForeground(bordersColor); |
| gc.setAlpha(BORDER_ALPHA); |
| gc.drawPolygon(stempoly.transformedPoints); |
| gc.setAlpha(255); // set it back |
| } |
| } |
| |
| if (identifiable instanceof Edge) { |
| |
| gc.setForeground(stdColorProvider.getEdgesColor()); |
| if (stempoly.transformedPoints == null) { |
| stempoly.setPointsTransformer(pointsTransformer); |
| } |
| gc.drawLine( |
| stempoly.transformedPoints[0], |
| stempoly.transformedPoints[1], |
| stempoly.transformedPoints[2], |
| stempoly.transformedPoints[3]); |
| } |
| } // for each StemPolygon |
| |
| |
| // if(colorProvider instanceof AbstractRelativeValueColorProviderAdapter) { |
| // AbstractRelativeValueColorProviderAdapter c = (AbstractRelativeValueColorProviderAdapter) colorProvider; |
| // drawColorScale(c); |
| // } |
| |
| gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_BLACK)); |
| } // draw |
| |
| |
| |
| /** |
| * |
| * @param adapter |
| */ |
| // private void drawColorScale(AbstractRelativeValueColorProviderAdapter adapter) { |
| // Color saturatedColor = adapter.getForegroundFillColor(); // to transparent color over the background |
| // Color textColor = saturatedColor; // text |
| // Color backGround = adapter.getBackgroundFillColor(); // textBackground |
| // |
| // if (colorScale == null) { |
| // colorScale = new ColorScaleComposite(this, saturatedColor, new double[]{0.0, 1.0/gainFactor}, useLogScaling, SWT.BORDER, backGround, textColor); |
| // } |
| // colorScale.updateColorScale(saturatedColor, new double[]{0.0, 1.0/gainFactor},useLogScaling, backGround, textColor); |
| // } |
| |
| /** |
| * @param polygonList |
| */ |
| private void computeTransform(final StemPolygonsList polygonList) { |
| if (polygonsBoundsRect == null) { |
| polygonsBoundsRect = polygonList.getBounds(); |
| if (polygonsBoundsRect == null) { |
| return; |
| } |
| } |
| |
| final Rectangle canvasBounds = getBounds(); |
| |
| final int effectiveCanvasWidth = canvasBounds.width - 2 * MARGIN; |
| final int effectiveCanvasHeight = canvasBounds.height - 2 * MARGIN; |
| final double width = polygonsBoundsRect.width; |
| final double height = polygonsBoundsRect.height; |
| final double WIDTH_RATIO = effectiveCanvasWidth / width; |
| final double HEIGHT_RATIO = effectiveCanvasHeight / height; |
| final double SCALE_FACTOR = Math.min(WIDTH_RATIO, HEIGHT_RATIO) |
| * zoomFactor; |
| |
| // Figure out the extra translation needed to center the image either |
| // vertically or horizontally in the canvas |
| int xCenteringTranslation = 0; |
| int yCenteringTranslation = 0; |
| // Anything to center? |
| if (width > 0 && height > 0) { |
| // Yes |
| xCenteringTranslation = (effectiveCanvasWidth - (int) (width * SCALE_FACTOR)) / 2; |
| yCenteringTranslation = (effectiveCanvasHeight - (int) (height * SCALE_FACTOR)) / 2; |
| } // if anything to center |
| int boundsMinX = polygonsBoundsRect.x; |
| int boundsMinY = polygonsBoundsRect.y; |
| |
| pointsTransformer.setOffsetX(-boundsMinX * SCALE_FACTOR + MARGIN + xCenteringTranslation + xTranslation * zoomFactor); |
| pointsTransformer.setOffsetY(-boundsMinY * SCALE_FACTOR + MARGIN + yCenteringTranslation + yTranslation * zoomFactor); |
| pointsTransformer.setScale(SCALE_FACTOR); |
| } // computeTransform |
| |
| void zoomIn() { |
| zoomFactor *= ZOOMING_FACTOR; |
| toUpdateTranform = true; |
| redraw(); |
| } |
| |
| void zoomOut() { |
| zoomFactor *= UNZOOMING_FACTOR; |
| toUpdateTranform = true; |
| redraw(); |
| } |
| |
| /** |
| * |
| */ |
| protected static class MouseTrackHandler extends MouseTrackAdapter { |
| @Override |
| public void mouseEnter(@SuppressWarnings("unused") |
| final MouseEvent e) { |
| |
| // The Map does not NEED to steal focus at all |
| // IF in the future we need focus then the following |
| // Guard claused protects against irrelevant/unneeded stealing of focus |
| |
| // if there is NOTHING in the map, don't steal focus |
| //if (polygonsToRender != null && !polygonsToRender.isEmpty()) { |
| //forceFocus(); |
| //} |
| } |
| } |
| |
| /** |
| * |
| */ |
| protected class KeyHandler extends KeyAdapter { |
| @Override |
| public void keyReleased(final KeyEvent e) { |
| switch (e.keyCode) { |
| case SWT.ARROW_UP: |
| zoomIn(); |
| break; |
| case SWT.ARROW_DOWN: |
| zoomOut(); |
| break; |
| default: |
| break; |
| } // switch |
| } |
| } |
| |
| /** |
| * A helper class that defines a mouse-listener that will provide the user |
| * the ability to move the map inside the view. |
| * |
| */ |
| protected class MouseButtonHandler extends MouseAdapter { |
| /** |
| * @see org.eclipse.swt.events.MouseListener#mouseDown(org.eclipse.swt.events.MouseEvent) |
| */ |
| @Override |
| public void mouseDown(final MouseEvent e) { |
| // Is the left mouse button? |
| if (e.button == 1) { |
| // Yes |
| // Capture the starting point |
| lastOffsetX = e.x; |
| lastOffsetY = e.y; |
| leftMouseButtonPressed = true; |
| } // if |
| } // mouseDown |
| |
| /** |
| * @see org.eclipse.swt.events.MouseListener#mouseUp(org.eclipse.swt.events.MouseEvent) |
| */ |
| @Override |
| public void mouseUp(final MouseEvent e) { |
| // Is it the left mouse button? |
| if (e.button == 1) { |
| // Yes |
| // new x and y are defined by current mouse location subtracted |
| // by previously processed mouse location |
| final int newX = e.x - lastOffsetX; |
| final int newY = e.y - lastOffsetY; |
| |
| // Did we move from the spot where the mouse went down? |
| if (newX != 0 || newY != 0) { |
| // Yes |
| // This is a translation of the map then |
| // update the canvas translation |
| addTranslation(newX, newY); |
| } // if moved |
| else { |
| // No |
| // This is a potential selection of a polygon |
| final StemPolygon polygon = getPolygon(e); |
| // Are we clicking on a polygon? |
| if (polygon != null) { |
| // Yes |
| // Get the Identifiable associated with the polygon and |
| // make it the current selection. |
| // Build the GeographicSelectionElements |
| // and pass it via the StructuredSelection as the 2nd |
| // element |
| final GeographicSelectionElements gse = new GeographicSelectionElements(); |
| |
| // Convert from canvas space coordinates to lat/long by |
| // the inverse |
| // transform. |
| final Point latLongPosition = pointsTransformer.getInversedPoint(e.x, e.y);//inverseMap(new Point(e.x, e.y)); |
| final double longitude = polygon |
| .unScaleLongitude(latLongPosition.x); |
| final double latitude = polygon |
| .unScaleLatitude(latLongPosition.y); |
| gse.setPoint(longitude, latitude); |
| final Identifiable regnImpl = polygon.getIdentifiable(); |
| final Object[] elements = new Object[] { regnImpl, gse }; |
| final IStructuredSelection selection = new StructuredSelection( |
| elements); |
| fireSelection(selection); |
| } |
| } // else didn't move |
| leftMouseButtonPressed = false; |
| } // if left mouse button |
| //Remember the map canvas that has been clicked on |
| SelectedReportsManager.getInstance().setRecentClickedMapCanvas((MapCanvas)e.getSource()); |
| } // mouseUp |
| } // MouseButtonHandler |
| |
| protected class MouseHoverHandler extends MouseTrackAdapter { |
| |
| // @Override |
| // public void mouseEnter(MouseEvent e) { |
| // final Cursor cursor = new Cursor(getDisplay(), SWT.CURSOR_SIZEALL); |
| // Canvas mapCanvas = (Canvas)e.getSource(); |
| // mapCanvas.setCursor(cursor); |
| // super.mouseEnter(e); |
| // } |
| // |
| // @Override |
| // public void mouseExit(MouseEvent e) { |
| // final Cursor cursor = new Cursor(getDisplay(), SWT.CURSOR_ARROW); |
| // Canvas mapCanvas = (Canvas)e.getSource(); |
| // mapCanvas.setCursor(cursor); |
| // super.mouseExit(e); |
| // } |
| |
| /** |
| * @see org.eclipse.swt.events.MouseTrackListener#mouseHover(org.eclipse.swt.events.MouseEvent) |
| */ |
| @Override |
| public void mouseHover(final MouseEvent e) { |
| |
| // Convert from canvas space coordinates to lat/long by the inverse |
| // transform. |
| final Point latLongPosition = pointsTransformer.getInversedPoint(e.x, e.y);//inverseMap(new Point(e.x, e.y)); |
| |
| // Try to get the polygon that matches the position of the mouse |
| final StemPolygon polygon = getPolygon(latLongPosition); |
| |
| // Did we find an enclosing polygon? |
| if (polygon != null) { |
| // Yes |
| // We want to get the ISO-key for the identifiable, it will be |
| // at the end of the value of the dublin core "identifier" |
| // attribute |
| Identifiable identifiable = polygon.getIdentifiable(); |
| final DublinCore dc = identifiable.getDublinCore(); |
| final String dcIdentifier = dc.getIdentifier(); |
| |
| final String isoKey = dcIdentifier.substring(dcIdentifier |
| .lastIndexOf("/") + 1); |
| // Did we get it? |
| |
| String toolTipText = null; |
| |
| if (isoKey != null && !isoKey.equals("")) { |
| // Yes |
| final String geographicName = GeographicNames |
| .getName(isoKey); |
| boolean retry = true; |
| StringBuilder sb=null; |
| while(retry) { |
| retry = false; |
| try { |
| sb = new StringBuilder(geographicName); |
| sb.append(" ("); |
| sb.append(isoKey); |
| sb.append(")"); |
| |
| Region region = (Region)identifiable; |
| for (NodeLabel nextLabel : region.getLabels()) { |
| if (nextLabel instanceof PopulationModelLabel) { |
| sb.append("\nPopulation (now): " + nextLabel); |
| } |
| if(nextLabel instanceof PopulationLabel) { |
| sb.append("\nPopulation ("+((PopulationLabel)nextLabel).getValidYear()+"):"+nextLabel); |
| } |
| if (nextLabel instanceof AreaLabel) { |
| sb.append("\nArea: " + nextLabel); |
| } |
| if (nextLabel instanceof StandardDiseaseModelLabel) { |
| sb.append("\n" + ((StandardDiseaseModelLabel)nextLabel).toTooltipString()); |
| } |
| } |
| |
| if (latLongPosition != null) { |
| double latitude = -1 * StemPolygon.getUnscaledLatitude(latLongPosition.y); |
| double longitude = -1 * StemPolygon.getUnscaledLongitude(latLongPosition.x); |
| sb.append("\nLatitude: " + latitude + ", Longitude: " + longitude); |
| } |
| |
| sequencer = simulation.getScenario().getSequencer(); |
| time = sequencer.getCurrentTime(); |
| sb.append("\nTime: "+ time.toString()); |
| } catch(ConcurrentModificationException cme) { |
| retry = true; // Should be rare, just retry |
| } |
| } |
| |
| toolTipText = sb.toString(); |
| |
| } // if |
| else { |
| toolTipText = polygon.getTitle(); |
| } |
| |
| if (tooltip != null) { |
| if (toolTipText != null) { |
| tooltip.setText(toolTipText); |
| tooltip.show(new Point(e.x, e.y)); |
| } else { |
| tooltip.hide(); |
| } |
| } |
| |
| |
| |
| /* |
| * // Yes //mapCanvas.setToolTipText(polygon.getTitle() + "\n" |
| * +polygon.getRelativeValue()); |
| * |
| * String key = |
| * propertySelectionControl.getSelectedPropertyString(); |
| * mapCanvas.setToolTipText("Name: " + polygon.getTitle() + "\n" + |
| * "Relative Value: " + polygon.getRelativeValue(key)); |
| */ |
| } // if |
| else { |
| // No |
| if (tooltip != null) { |
| tooltip.hide(); |
| } |
| } |
| } // mouseHover |
| |
| } // MouseHoverHandler |
| |
| /** |
| * @param e |
| * a mouse event |
| * @return the polygon the matches the position of the mouse, or |
| * <code>null</code> if there is no such polygon. |
| */ |
| StemPolygon getPolygon(final MouseEvent e) { |
| // Convert from canvas space coordinates to lat/long by the inverse |
| // transform. |
| //final Point latLongPosition = inverseMap(new Point(e.x, e.y)); |
| final Point latLongPosition = pointsTransformer.getInversedPoint(e.x, e.y); |
| return getPolygon(latLongPosition); |
| |
| } // getPolygon |
| |
| /** |
| * @param point a point (probably within the polygon) |
| * @return the polygon the matches the position of the point, or |
| * <code>null</code> if there is no such polygon. |
| */ |
| StemPolygon getPolygon(final Point point) { |
| StemPolygon retValue = null; |
| |
| if (point != null && polygonsToRender != null) { |
| // Find the Polygon that contains the lat/long coordinates |
| retValue = polygonsToRender.getContainingRegionPolygon(point); |
| } // if |
| return retValue; |
| } // getPolygon |
| |
| /** |
| * Adds offsets to the current translation. |
| * |
| * @param xTranslationAddition |
| * @param yTranslationAddition |
| */ |
| protected void addTranslation(final double xTranslationAddition, |
| final double yTranslationAddition) { |
| this.xTranslation += (xTranslationAddition / zoomFactor); |
| this.yTranslation += (yTranslationAddition / zoomFactor); |
| toUpdateTranform = true; |
| redraw(); |
| } // addTranslation |
| |
| /** |
| * @see org.eclipse.jface.viewers.ISelectionProvider#addSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener) |
| */ |
| public void addSelectionChangedListener( |
| final ISelectionChangedListener listener) { |
| selectionChangedListeners.add(listener); |
| } |
| |
| /** |
| * @see org.eclipse.jface.viewers.ISelectionProvider#removeSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener) |
| */ |
| public void removeSelectionChangedListener( |
| final ISelectionChangedListener listener) { |
| selectionChangedListeners.remove(listener); |
| } |
| |
| /** |
| * @return the selection |
| */ |
| public final ISelection getSelection() { |
| return selection; |
| } |
| |
| /** |
| * @see org.eclipse.jface.viewers.ISelectionProvider#setSelection(org.eclipse.jface.viewers.ISelection) |
| */ |
| public void setSelection(final ISelection selection) { |
| this.selection = selection; |
| fireSelection(selection); |
| } |
| |
| void fireSelection(final ISelection selection) { |
| |
| final SelectionChangedEvent event = new SelectionChangedEvent(this, |
| selection); |
| for (final ISelectionChangedListener listener : selectionChangedListeners) { |
| listener.selectionChanged(event); |
| } // for each ISelectionChangedListener |
| |
| } // fireSelection |
| |
| /** |
| * @param colorProvider the colorProvider to set |
| */ |
| public void setColorProvider(ColorProviderAdapter colorProvider) { |
| this.colorProvider = colorProvider; |
| |
| // if(colorProvider instanceof AbstractRelativeValueColorProviderAdapter) { |
| // AbstractRelativeValueColorProviderAdapter c = (AbstractRelativeValueColorProviderAdapter) colorProvider; |
| // drawColorScale(c); |
| // } |
| |
| } |
| |
| /** |
| * @see org.eclipse.swt.widgets.Widget#dispose() |
| */ |
| @Override |
| public void dispose() { |
| tooltip = null; |
| |
| removePaintListener(this); |
| removeMouseWheelListener(this); |
| removeMouseTrackListener(mouseTrackHandler); |
| removeMouseMoveListener(this); |
| removeKeyListener(keyHandler); |
| removeDisposeListener(this); |
| removeMouseListener(mouseButtonHandler); |
| removeMouseTrackListener(mouseHoverHandler); |
| } |
| |
| } // MapCanvas |