Package org.openstreetmap.josm.gui

Source Code of org.openstreetmap.josm.gui.MapMover$ZoomerAction

// License: GPL. Copyright 2007 by Immanuel Scholz and others
package org.openstreetmap.josm.gui;

import static org.openstreetmap.josm.tools.I18n.tr;

import java.awt.Cursor;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.util.LinkedList;

import javax.swing.AbstractAction;
import javax.swing.JComponent;
import javax.swing.JPanel;

import org.openstreetmap.josm.data.coor.EastNorth;
import org.openstreetmap.josm.tools.Shortcut;

import es.emergya.ui.gis.Contextful;
import es.emergya.ui.gis.ICustomMapView;
import es.emergya.ui.gis.MapMoveListener;
import es.emergya.ui.gis.RotatableView;
import es.emergya.ui.plugins.ZoomPerformed;

/**
* Enables moving of the map by holding down the right mouse button and drag the
* mouse. Also, enables zooming by the mouse wheel.
*
* @author imi
*/
public class MapMover extends MouseAdapter implements MouseMotionListener,
    MouseWheelListener {

  private final class ZoomerAction extends AbstractAction {
    private final String action;

    public ZoomerAction(String action) {
      this.action = action;
    }

    public void actionPerformed(ActionEvent e) {
      if (action.equals(".") || action.equals(",")) {
        Point mouse = nc.getMousePosition();
        if (mouse == null)
          mouse = new Point((int) nc.getBounds().getCenterX(),
              (int) nc.getBounds().getCenterY());
        MouseWheelEvent we = new MouseWheelEvent(nc, e.getID(), e
            .getWhen(), e.getModifiers(), mouse.x, mouse.y, 0,
            false, MouseWheelEvent.WHEEL_UNIT_SCROLL, 1, action
                .equals(",") ? -1 : 1);
        mouseWheelMoved(we);
      } else {
        EastNorth center = nc.getCenter();
        EastNorth newcenter = nc.getEastNorth(nc.getWidth() / 2
            + nc.getWidth() / 5, nc.getHeight() / 2
            + nc.getHeight() / 5);
        if (action.equals("left"))
          nc.zoomTo(new EastNorth(2 * center.east()
              - newcenter.east(), center.north()), nc.getScale());
        else if (action.equals("right"))
          nc.zoomTo(new EastNorth(newcenter.east(), center.north()),
              nc.getScale());
        else if (action.equals("up"))
          nc.zoomTo(new EastNorth(center.east(), 2 * center.north()
              - newcenter.north()), nc.getScale());
        else if (action.equals("down"))
          nc.zoomTo(new EastNorth(center.east(), newcenter.north()),
              nc.getScale());
      }
    }
  }

  /**
   * The point in the map that was the under the mouse point when moving
   * around started.
   */
  private EastNorth mousePosMove;
  /**
   * The map to move around.
   */
  private final NavigatableComponent nc;
  /**
   * The old cursor when we changed it to movement cursor.
   */
  private Cursor oldCursor;
  /**
   * Button to drag
   */
  private int panButton = MouseEvent.BUTTON3;
  private int panMask = MouseEvent.BUTTON3_DOWN_MASK;
  private int rotationMask = MouseEvent.BUTTON3_DOWN_MASK
      | MouseEvent.ALT_DOWN_MASK;

  private boolean movementInPlace = false;

  /**
   * Create a new MapMover
   */
  public MapMover(NavigatableComponent navComp, JPanel contentPane) {
    this.nc = navComp;
    nc.addMouseListener(this);
    nc.addMouseMotionListener(this);
    nc.addMouseWheelListener(this);

    if (contentPane != null) {
      contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
          Shortcut.registerShortcut("system:movefocusright",
              tr("Map: {0}", tr("Move right")),
              KeyEvent.VK_RIGHT, Shortcut.GROUP_HOTKEY)
              .getKeyStroke(), "MapMover.Zoomer.right");
      contentPane.getActionMap().put("MapMover.Zoomer.right",
          new ZoomerAction("right"));

      contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
          Shortcut.registerShortcut("system:movefocusleft",
              tr("Map: {0}", tr("Move left")), KeyEvent.VK_LEFT,
              Shortcut.GROUP_HOTKEY).getKeyStroke(),
          "MapMover.Zoomer.left");
      contentPane.getActionMap().put("MapMover.Zoomer.left",
          new ZoomerAction("left"));

      contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
          Shortcut.registerShortcut("system:movefocusup",
              tr("Map: {0}", tr("Move up")), KeyEvent.VK_UP,
              Shortcut.GROUP_HOTKEY).getKeyStroke(),
          "MapMover.Zoomer.up");
      contentPane.getActionMap().put("MapMover.Zoomer.up",
          new ZoomerAction("up"));

      contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
          Shortcut.registerShortcut("system:movefocusdown",
              tr("Map: {0}", tr("Move down")), KeyEvent.VK_DOWN,
              Shortcut.GROUP_HOTKEY).getKeyStroke(),
          "MapMover.Zoomer.down");
      contentPane.getActionMap().put("MapMover.Zoomer.down",
          new ZoomerAction("down"));

      contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
          Shortcut.registerShortcut("view:zoominalternate",
              tr("Map: {0}", tr("Zoom in")), KeyEvent.VK_COMMA,
              Shortcut.GROUP_HOTKEY).getKeyStroke(),
          "MapMover.Zoomer.in");
      contentPane.getActionMap().put("MapMover.Zoomer.in",
          new ZoomerAction(","));

      contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
          Shortcut.registerShortcut("view:zoomoutalternate",
              tr("Map: {0}", tr("Zoom out")), KeyEvent.VK_PERIOD,
              Shortcut.GROUP_HOTKEY).getKeyStroke(),
          "MapMover.Zoomer.out");
      contentPane.getActionMap().put("MapMover.Zoomer.out",
          new ZoomerAction("."));
    }
  }

  private int x;

  /**
   * If the button set on {@link #panButton} is pressed, move the map
   */
  public void mouseDragged(MouseEvent e) {
    int offMask = getOffMask();
    if ((e.getModifiersEx() & (panMask | offMask)) == panMask) {
      if (e.isAltDown()) {
        ((RotatableView) nc).rotate(e.getX() < x ? 0.1 : -0.1);
        x = e.getX();
        return;
      }
      if (mousePosMove == null)
        startMovement(e);
      EastNorth center = nc.getCenter();
      EastNorth mouseCenter = nc.getEastNorth(e.getX(), e.getY());
      EastNorth p = new EastNorth(mousePosMove.east() + center.east()
          - mouseCenter.east(), mousePosMove.north() + center.north()
          - mouseCenter.north());
      nc.zoomTo(p, nc.getScale());
    } else
      endMovement();
  }

  /**
   * Start the movement, if it was the button set on {@link #panButton}.
   */
  @Override
  public void mousePressed(MouseEvent e) {
    int offMask = getOffMask();
    if (e.getButton() == panButton && (e.getModifiersEx() & offMask) == 0)
      startMovement(e);
  }

  /**
   * Change the cursor back to it's pre-move cursor.
   */
  @Override
  public void mouseReleased(MouseEvent e) {
    if (e.getButton() == panButton)
      endMovement();
    else if ((e.getButton() == MouseEvent.BUTTON3)
        && nc instanceof Contextful)
      ((Contextful) nc).showMenu(e.getComponent(), e.getX(), e.getY());
  }

  /**
   * Start movement by setting a new cursor and remember the current mouse
   * position.
   *
   * @param e
   *            The mouse event that leat to the movement from.
   */
  private void startMovement(MouseEvent e) {
    if (movementInPlace)
      return;
    movementInPlace = true;
    mousePosMove = nc.getEastNorth(e.getX(), e.getY());
    oldCursor = nc.getCursor();
    nc.setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
    if (nc instanceof MapMoveListener)
      ((MapMoveListener) nc).movementStarted();
  }

  /**
   * End the movement. Setting back the cursor and clear the movement
   * variables
   */
  private void endMovement() {
    if (!movementInPlace)
      return;
    movementInPlace = false;
    if (oldCursor != null)
      nc.setCursor(oldCursor);
    else
      nc.setCursor(Cursor.getDefaultCursor());
    mousePosMove = null;
    oldCursor = null;
    if (nc instanceof MapMoveListener)
      ((MapMoveListener) nc).movementEnded();
  }

  /**
   * Zoom the map by 1/5th of current zoom per wheel-delta.
   *
   * @param e
   *            The wheel event.
   */
  public void mouseWheelMoved(MouseWheelEvent e) {
    double newScale = nc.getScale() * Math.pow(0.8, -e.getWheelRotation());

    // New center position so that point under the mouse pointer stays the
    // same place as it was before zooming
    // You will get the formula by simplifying this expression: newCenter =
    // oldCenter + mouseCoordinatesInNewZoom - mouseCoordinatesInOldZoom
    // double newX = nc.center.east() - (e.getX() - nc.getWidth()/2.0) *
    // (newScale - nc.scale);
    // double newY = nc.center.north() + (e.getY() - nc.getHeight()/2.0) *
    // (newScale - nc.scale);

    // nc.zoomTo(new EastNorth(newX, newY), newScale);
    nc.zoomTo(nc.getEastNorth(e.getX(), e.getY()), newScale);
    if (nc instanceof ZoomPerformed)
      ((ZoomPerformed) nc).zoomPerformed();
  }

  /**
   * Does nothing. Only to satisfy MouseMotionListener
   */
  public void mouseMoved(MouseEvent e) {
    if (nc instanceof ICustomMapView)
      ((ICustomMapView) nc).updateMousePosition();
  }

  /**
   * @return The button that will trigger the map pan
   */
  public int getPanButton() {
    return panButton;
  }

  public int getPanMask() {
    return panMask;
  }

  public double getRotationMask() {
    return rotationMask;
  }

  /**
   * Sets the button that will trigger the map pan
   *
   * @param panButton
   *            {@link MouseEvent#BUTTON1}, {@link MouseEvent#BUTTON2} or
   *            {@link MouseEvent#BUTTON3}
   */
  public void setPanButton(int panButton) {
    if (panButton == MouseEvent.BUTTON1 || panButton == MouseEvent.BUTTON2
        || panButton == MouseEvent.BUTTON3) {
      this.panButton = panButton;
      switch (panButton) {
      case MouseEvent.BUTTON1:
        this.panMask = MouseEvent.BUTTON1_DOWN_MASK;
        break;
      case MouseEvent.BUTTON2:
        this.panMask = MouseEvent.BUTTON2_DOWN_MASK;
        break;
      case MouseEvent.BUTTON3:
        this.panMask = MouseEvent.BUTTON2_DOWN_MASK;
        break;
      }
    } else
      throw new IllegalArgumentException(
          "One of the three mouse buttons only");
  }

  private int getOffMask() {
    LinkedList<Integer> masks = new LinkedList<Integer>();
    masks.add(MouseEvent.BUTTON1_DOWN_MASK);
    masks.add(MouseEvent.BUTTON2_DOWN_MASK);
    masks.add(MouseEvent.BUTTON3_DOWN_MASK);

    masks.remove(new Integer(this.panMask));

    int mask = 0;
    for (Integer m : masks) {
      mask = mask | m;
    }
    return mask;
  }
}
TOP

Related Classes of org.openstreetmap.josm.gui.MapMover$ZoomerAction

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.