/** {@inheritDoc} */
  @Override
  public void mouseDragged(final MouseEvent aEvent) {
    final MouseEvent event = convertEvent(aEvent);
    final Point point = event.getPoint();

    // Update the selected channel while dragging...
    this.controller.setSelectedChannel(point);

    if (getModel().isCursorMode() && (this.movingCursor >= 0)) {
      this.controller.moveCursor(this.movingCursor, getCursorDropPoint(point));

      aEvent.consume();
    } else {
      if ((this.lastClickPosition == null)
          && ((aEvent.getModifiersEx() & InputEvent.BUTTON1_DOWN_MASK) != 0)) {
        this.lastClickPosition = new Point(point);
      }

      final JScrollPane scrollPane =
          getAncestorOfClass(JScrollPane.class, (Component) aEvent.getSource());
      if ((scrollPane != null) && (this.lastClickPosition != null)) {
        final JViewport viewPort = scrollPane.getViewport();
        final Component signalView = this.controller.getSignalDiagram().getSignalView();

        boolean horizontalOnly = (aEvent.getModifiersEx() & InputEvent.ALT_DOWN_MASK) != 0;
        boolean verticalOnly =
            horizontalOnly && ((aEvent.getModifiersEx() & InputEvent.SHIFT_DOWN_MASK) != 0);

        int dx = aEvent.getX() - this.lastClickPosition.x;
        int dy = aEvent.getY() - this.lastClickPosition.y;

        Point scrollPosition = viewPort.getViewPosition();
        int newX = scrollPosition.x;
        if (!verticalOnly) {
          newX -= dx;
        }
        int newY = scrollPosition.y;
        if (verticalOnly || !horizontalOnly) {
          newY -= dy;
        }

        int diagramWidth = signalView.getWidth();
        int viewportWidth = viewPort.getWidth();
        int maxX = diagramWidth - viewportWidth - 1;
        scrollPosition.x = Math.max(0, Math.min(maxX, newX));

        int diagramHeight = signalView.getHeight();
        int viewportHeight = viewPort.getHeight();
        int maxY = diagramHeight - viewportHeight;
        scrollPosition.y = Math.max(0, Math.min(maxY, newY));

        viewPort.setViewPosition(scrollPosition);
      }

      // Use UNCONVERTED/ORIGINAL mouse event!
      handleZoomRegion(aEvent, this.lastClickPosition);
    }
  }
 /**
  * Determines whether or not the given mouse event is actually a popup trigger.
  *
  * @param aPoint the <em>corrected</em> mouse position, where the popup is to be shown, cannot be
  *     <code>null</code>;
  * @param aEvent the mouse event that could be a popup trigger, cannot be <code>null</code>.
  */
 private boolean handlePopupTrigger(final Point aPoint, final MouseEvent aEvent) {
   final boolean popupTrigger = isCursorPopupTrigger(aEvent);
   if (popupTrigger) {
     JPopupMenu contextMenu = createCursorPopup(aPoint, aEvent.getLocationOnScreen());
     if (contextMenu != null) {
       contextMenu.show(aEvent.getComponent(), aEvent.getX(), aEvent.getY());
       // Mark the event as consumed...
       aEvent.consume();
     }
   }
   return popupTrigger;
 }
  /** {@inheritDoc} */
  @Override
  public void mouseClicked(final MouseEvent aEvent) {
    // Ensure the focus is moved to the main signal diagram component...
    getSignalDiagram().requestFocusInWindow();

    if (getModel().isCursorMode() && (aEvent.getClickCount() == 2)) {
      final MouseEvent event = convertEvent(aEvent);

      final Cursor hoveredCursor = findCursor(event.getPoint());
      if (hoveredCursor != null) {
        editCursorProperties(hoveredCursor);
        // Consume the event to stop further processing...
        aEvent.consume();
      }
    }
  }