Пример #1
0
  /*
   * Called by the delegate to dispatch the event to Java. Event
   * coordinates are relative to non-client window are, i.e. the top-left
   * point of the client area is (insets.top, insets.left).
   */
  @Override
  public void notifyMouseEvent(
      PlatformWindow eventPlatformWindow,
      int id,
      long when,
      int button,
      int x,
      int y,
      int screenX,
      int screenY,
      int modifiers,
      int clickCount,
      boolean popupTrigger,
      byte[] bdata) {
    // TODO: fill "bdata" member of AWTEvent
    Rectangle r = getBounds();
    // findPeerAt() expects parent coordinates
    LWComponentPeer<?, ?> targetPeer = findPeerAt(r.x + x, r.y + y);

    if (id == MouseEvent.MOUSE_EXITED) {
      isMouseOver = false;
      if (lastMouseEventPeer != null) {
        if (lastMouseEventPeer.isEnabled()) {
          Point lp = lastMouseEventPeer.windowToLocal(x, y, this);
          Component target = lastMouseEventPeer.getTarget();
          postMouseExitedEvent(
              target, when, modifiers, lp, screenX, screenY, clickCount, popupTrigger, button);
        }

        // Sometimes we may get MOUSE_EXITED after lastCommonMouseEventPeer is switched
        // to a peer from another window. So we must first check if this peer is
        // the same as lastWindowPeer
        if (lastCommonMouseEventPeer != null
            && lastCommonMouseEventPeer.getWindowPeerOrSelf() == this) {
          lastCommonMouseEventPeer = null;
        }
        lastMouseEventPeer = null;
      }
    } else if (id == MouseEvent.MOUSE_ENTERED) {
      isMouseOver = true;
      if (targetPeer != null) {
        if (targetPeer.isEnabled()) {
          Point lp = targetPeer.windowToLocal(x, y, this);
          Component target = targetPeer.getTarget();
          postMouseEnteredEvent(
              target, when, modifiers, lp, screenX, screenY, clickCount, popupTrigger, button);
        }
        lastCommonMouseEventPeer = targetPeer;
        lastMouseEventPeer = targetPeer;
      }
    } else {

      LWWindowPeer topmostWindowPeer =
          eventPlatformWindow != null ? eventPlatformWindow.getPeer() : null;

      // topmostWindowPeer == null condition is added for the backward
      // compatibility with applets. It can be removed when the
      // getTopmostPlatformWindowUnderMouse() method will be properly
      // implemented in CPlatformEmbeddedFrame class
      if (topmostWindowPeer == this || topmostWindowPeer == null) {
        generateMouseEnterExitEventsForComponents(
            when, button, x, y, screenX, screenY, modifiers, clickCount, popupTrigger, targetPeer);
      } else {
        LWComponentPeer<?, ?> topmostTargetPeer = topmostWindowPeer.findPeerAt(r.x + x, r.y + y);
        topmostWindowPeer.generateMouseEnterExitEventsForComponents(
            when,
            button,
            x,
            y,
            screenX,
            screenY,
            modifiers,
            clickCount,
            popupTrigger,
            topmostTargetPeer);
      }

      // TODO: fill "bdata" member of AWTEvent

      int eventButtonMask = (button > 0) ? MouseEvent.getMaskForButton(button) : 0;
      int otherButtonsPressed = modifiers & ~eventButtonMask;

      // For pressed/dragged/released events OS X treats other
      // mouse buttons as if they were BUTTON2, so we do the same
      int targetIdx = (button > 3) ? MouseEvent.BUTTON2 - 1 : button - 1;

      // MOUSE_ENTERED/EXITED are generated for the components strictly under
      // mouse even when dragging. That's why we first update lastMouseEventPeer
      // based on initial targetPeer value and only then recalculate targetPeer
      // for MOUSE_DRAGGED/RELEASED events
      if (id == MouseEvent.MOUSE_PRESSED) {

        // Ungrab only if this window is not an owned window of the grabbing one.
        if (!isGrabbing() && grabbingWindow != null && !grabbingWindow.isOneOfOwnersOf(this)) {
          grabbingWindow.ungrab();
        }
        if (otherButtonsPressed == 0) {
          mouseClickButtons = eventButtonMask;
        } else {
          mouseClickButtons |= eventButtonMask;
        }

        // The window should be focused on mouse click. If it gets activated by the native platform,
        // this request will be no op. It will take effect when:
        // 1. A simple not focused window is clicked.
        // 2. An active but not focused owner frame/dialog is clicked.
        // The mouse event then will trigger a focus request "in window" to the component, so the
        // window
        // should gain focus before.
        requestWindowFocus(CausedFocusEvent.Cause.MOUSE_EVENT);

        mouseDownTarget[targetIdx] = targetPeer;
      } else if (id == MouseEvent.MOUSE_DRAGGED) {
        // Cocoa dragged event has the information about which mouse
        // button is being dragged. Use it to determine the peer that
        // should receive the dragged event.
        targetPeer = mouseDownTarget[targetIdx];
        mouseClickButtons &= ~modifiers;
      } else if (id == MouseEvent.MOUSE_RELEASED) {
        // TODO: currently, mouse released event goes to the same component
        // that received corresponding mouse pressed event. For most cases,
        // it's OK, however, we need to make sure that our behavior is consistent
        // with 1.6 for cases where component in question have been
        // hidden/removed in between of mouse pressed/released events.
        targetPeer = mouseDownTarget[targetIdx];

        if ((modifiers & eventButtonMask) == 0) {
          mouseDownTarget[targetIdx] = null;
        }

        // mouseClickButtons is updated below, after MOUSE_CLICK is sent
      }

      if (targetPeer == null) {
        // TODO This can happen if this window is invisible. this is correct behavior in this case?
        targetPeer = this;
      }

      Point lp = targetPeer.windowToLocal(x, y, this);
      if (targetPeer.isEnabled()) {
        MouseEvent event =
            new MouseEvent(
                targetPeer.getTarget(),
                id,
                when,
                modifiers,
                lp.x,
                lp.y,
                screenX,
                screenY,
                clickCount,
                popupTrigger,
                button);
        postEvent(event);
      }

      if (id == MouseEvent.MOUSE_RELEASED) {
        if ((mouseClickButtons & eventButtonMask) != 0 && targetPeer.isEnabled()) {
          postEvent(
              new MouseEvent(
                  targetPeer.getTarget(),
                  MouseEvent.MOUSE_CLICKED,
                  when,
                  modifiers,
                  lp.x,
                  lp.y,
                  screenX,
                  screenY,
                  clickCount,
                  popupTrigger,
                  button));
        }
        mouseClickButtons &= ~eventButtonMask;
      }
    }
    notifyUpdateCursor();
  }