示例#1
0
  /**
   * Calculate and return the current selection rectangle
   *
   * @return A rectangle that spans from mousePos to mouseStartPos
   */
  private Rectangle getSelectionRectangle() {
    int x = mousePosStart.x;
    int y = mousePosStart.y;
    int w = mousePos.x - mousePosStart.x;
    int h = mousePos.y - mousePosStart.y;
    if (w < 0) {
      x += w;
      w = -w;
    }
    if (h < 0) {
      y += h;
      h = -h;
    }

    if (aspectRatio) {
      /* Keep the aspect ratio by growing the rectangle; the
       * rectangle is always under the cursor. */
      double aspectRatio = (double) nc.getWidth() / nc.getHeight();
      if ((double) w / h < aspectRatio) {
        int neww = (int) (h * aspectRatio);
        if (mousePos.x < mousePosStart.x) {
          x += w - neww;
        }
        w = neww;
      } else {
        int newh = (int) (w / aspectRatio);
        if (mousePos.y < mousePosStart.y) {
          y += h - newh;
        }
        h = newh;
      }
    }

    return new Rectangle(x, y, w, h);
  }
示例#2
0
 private void paintLasso() {
   if (mousePos == null || mousePosStart == null || mousePos == mousePosStart) {
     return;
   }
   lasso.addPoint(mousePos.x, mousePos.y);
   nc.requestPaintPoly(lasso);
 }
示例#3
0
 /**
  * Register itself at the given event source.
  *
  * @param eventSource The emitter of the mouse events.
  * @param lassoMode {@code true} to enable lasso mode, {@code false} to disable it.
  */
 public void register(NavigatableComponent eventSource, boolean lassoMode) {
   this.lassoMode = lassoMode;
   eventSource.addMouseListener(this);
   eventSource.addMouseMotionListener(this);
   selectionEndedListener.addPropertyChangeListener(this);
   eventSource.addPropertyChangeListener(
       "scale",
       new PropertyChangeListener() {
         @Override
         public void propertyChange(PropertyChangeEvent evt) {
           if (mousePosStart != null) {
             paintRect();
             mousePos = mousePosStart = null;
           }
         }
       });
 }
示例#4
0
  /** Check the state of the keys and buttons and set the selection accordingly. */
  @Override
  public void mouseReleased(MouseEvent e) {
    if (e.getButton() != MouseEvent.BUTTON1) return;
    if (mousePos == null || mousePosStart == null) return; // injected release from outside
    // disable the selection rect
    Rectangle r;
    if (!lassoMode) {
      nc.requestClearRect();
      r = getSelectionRectangle();

      lasso = rectToPolygon(r);
    } else {
      nc.requestClearPoly();
      lasso.addPoint(mousePos.x, mousePos.y);
      r = lasso.getBounds();
    }
    mousePosStart = null;
    mousePos = null;

    if ((e.getModifiersEx() & MouseEvent.BUTTON3_DOWN_MASK) == 0) {
      selectionEndedListener.selectionEnded(r, e);
    }
  }
示例#5
0
 @Override
 public void repaint(long tm, int x, int y, int width, int height) {
   // This is the main repaint method, all other methods are convenience methods and simply call
   // this method.
   // This is just an observation, not a must, but seems to be true for all implementations I found
   // so far.
   if (repaintListeners != null) {
     // Might get called early in super constructor
     for (RepaintListener l : repaintListeners) {
       l.repaint(tm, x, y, width, height);
     }
   }
   super.repaint(tm, x, y, width, height);
 }
示例#6
0
  /**
   * Return a list of all objects in the selection, respecting the different modifier.
   *
   * @param alt Whether the alt key was pressed, which means select all objects that are touched,
   *     instead those which are completely covered.
   * @return The collection of selected objects.
   */
  public Collection<OsmPrimitive> getSelectedObjects(boolean alt) {

    Collection<OsmPrimitive> selection = new LinkedList<>();

    // whether user only clicked, not dragged.
    boolean clicked = false;
    Rectangle bounding = lasso.getBounds();
    if (bounding.height <= 2 && bounding.width <= 2) {
      clicked = true;
    }

    if (clicked) {
      Point center = new Point(lasso.xpoints[0], lasso.ypoints[0]);
      OsmPrimitive osm = nc.getNearestNodeOrWay(center, OsmPrimitive.isSelectablePredicate, false);
      if (osm != null) {
        selection.add(osm);
      }
    } else {
      // nodes
      for (Node n : nc.getCurrentDataSet().getNodes()) {
        if (n.isSelectable() && lasso.contains(nc.getPoint2D(n))) {
          selection.add(n);
        }
      }

      // ways
      for (Way w : nc.getCurrentDataSet().getWays()) {
        if (!w.isSelectable() || w.getNodesCount() == 0) {
          continue;
        }
        if (alt) {
          for (Node n : w.getNodes()) {
            if (!n.isIncomplete() && lasso.contains(nc.getPoint2D(n))) {
              selection.add(w);
              break;
            }
          }
        } else {
          boolean allIn = true;
          for (Node n : w.getNodes()) {
            if (!n.isIncomplete() && !lasso.contains(nc.getPoint(n))) {
              allIn = false;
              break;
            }
          }
          if (allIn) {
            selection.add(w);
          }
        }
      }
    }
    return selection;
  }
示例#7
0
 /** Draws a selection rectangle on screen. */
 private void paintRect() {
   if (mousePos == null || mousePosStart == null || mousePos == mousePosStart) return;
   nc.requestPaintRect(getSelectionRectangle());
 }
示例#8
0
  /** Draw the component. */
  @Override
  public void paint(Graphics g) {
    if (!prepareToDraw()) {
      return;
    }

    List<Layer> visibleLayers = getVisibleLayersInZOrder();

    int nonChangedLayersCount = 0;
    for (Layer l : visibleLayers) {
      if (l.isChanged() || l == changedLayer) {
        break;
      } else {
        nonChangedLayersCount++;
      }
    }

    boolean canUseBuffer;

    synchronized (this) {
      canUseBuffer = !paintPreferencesChanged;
      paintPreferencesChanged = false;
    }
    canUseBuffer =
        canUseBuffer
            && nonChangedLayers.size() <= nonChangedLayersCount
            && lastViewID == getViewID()
            && lastClipBounds.contains(g.getClipBounds());
    if (canUseBuffer) {
      for (int i = 0; i < nonChangedLayers.size(); i++) {
        if (visibleLayers.get(i) != nonChangedLayers.get(i)) {
          canUseBuffer = false;
          break;
        }
      }
    }

    if (null == offscreenBuffer
        || offscreenBuffer.getWidth() != getWidth()
        || offscreenBuffer.getHeight() != getHeight()) {
      offscreenBuffer = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_3BYTE_BGR);
    }

    Graphics2D tempG = offscreenBuffer.createGraphics();
    tempG.setClip(g.getClip());
    Bounds box = getLatLonBounds(g.getClipBounds());

    if (!canUseBuffer || nonChangedLayersBuffer == null) {
      if (null == nonChangedLayersBuffer
          || nonChangedLayersBuffer.getWidth() != getWidth()
          || nonChangedLayersBuffer.getHeight() != getHeight()) {
        nonChangedLayersBuffer =
            new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_3BYTE_BGR);
      }
      Graphics2D g2 = nonChangedLayersBuffer.createGraphics();
      g2.setClip(g.getClip());
      g2.setColor(PaintColors.getBackgroundColor());
      g2.fillRect(0, 0, getWidth(), getHeight());

      for (int i = 0; i < nonChangedLayersCount; i++) {
        paintLayer(visibleLayers.get(i), g2, box);
      }
    } else {
      // Maybe there were more unchanged layers then last time - draw them to buffer
      if (nonChangedLayers.size() != nonChangedLayersCount) {
        Graphics2D g2 = nonChangedLayersBuffer.createGraphics();
        g2.setClip(g.getClip());
        for (int i = nonChangedLayers.size(); i < nonChangedLayersCount; i++) {
          paintLayer(visibleLayers.get(i), g2, box);
        }
      }
    }

    nonChangedLayers.clear();
    changedLayer = null;
    for (int i = 0; i < nonChangedLayersCount; i++) {
      nonChangedLayers.add(visibleLayers.get(i));
    }
    lastViewID = getViewID();
    lastClipBounds = g.getClipBounds();

    tempG.drawImage(nonChangedLayersBuffer, 0, 0, null);

    for (int i = nonChangedLayersCount; i < visibleLayers.size(); i++) {
      paintLayer(visibleLayers.get(i), tempG, box);
    }

    synchronized (temporaryLayers) {
      for (MapViewPaintable mvp : temporaryLayers) {
        mvp.paint(tempG, this, box);
      }
    }

    // draw world borders
    tempG.setColor(Color.WHITE);
    Bounds b = getProjection().getWorldBoundsLatLon();
    double lat = b.getMinLat();
    double lon = b.getMinLon();

    Point p = getPoint(b.getMin());

    GeneralPath path = new GeneralPath();

    path.moveTo(p.x, p.y);
    double max = b.getMax().lat();
    for (; lat <= max; lat += 1.0) {
      p = getPoint(new LatLon(lat >= max ? max : lat, lon));
      path.lineTo(p.x, p.y);
    }
    lat = max;
    max = b.getMax().lon();
    for (; lon <= max; lon += 1.0) {
      p = getPoint(new LatLon(lat, lon >= max ? max : lon));
      path.lineTo(p.x, p.y);
    }
    lon = max;
    max = b.getMinLat();
    for (; lat >= max; lat -= 1.0) {
      p = getPoint(new LatLon(lat <= max ? max : lat, lon));
      path.lineTo(p.x, p.y);
    }
    lat = max;
    max = b.getMinLon();
    for (; lon >= max; lon -= 1.0) {
      p = getPoint(new LatLon(lat, lon <= max ? max : lon));
      path.lineTo(p.x, p.y);
    }

    int w = getWidth();
    int h = getHeight();

    // Work around OpenJDK having problems when drawing out of bounds
    final Area border = new Area(path);
    // Make the viewport 1px larger in every direction to prevent an
    // additional 1px border when zooming in
    final Area viewport = new Area(new Rectangle(-1, -1, w + 2, h + 2));
    border.intersect(viewport);
    tempG.draw(border);

    if (Main.isDisplayingMapView() && Main.map.filterDialog != null) {
      Main.map.filterDialog.drawOSDText(tempG);
    }

    if (playHeadMarker != null) {
      playHeadMarker.paint(tempG, this);
    }

    g.drawImage(offscreenBuffer, 0, 0, null);
    super.paint(g);
  }