/**
   * Displays the Tracker rectangles for manipulation by the user. Returns when the user has either
   * finished manipulating the rectangles or has cancelled the Tracker.
   *
   * @return <code>true</code> if the user did not cancel the Tracker, <code>false</code> otherwise
   * @exception SWTException
   *     <ul>
   *       <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
   *       <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
   *     </ul>
   */
  public boolean open() {
    checkWidget();
    Display display = this.display;
    cancelled = false;
    tracking = true;
    window = (NSWindow) new NSWindow().alloc();
    NSArray screens = NSScreen.screens();
    double /*float*/ minX = Float.MAX_VALUE, maxX = Float.MIN_VALUE;
    double /*float*/ minY = Float.MAX_VALUE, maxY = Float.MIN_VALUE;
    int count = (int) /*64*/ screens.count();
    for (int i = 0; i < count; i++) {
      NSScreen screen = new NSScreen(screens.objectAtIndex(i));
      NSRect frame = screen.frame();
      double /*float*/ x1 = frame.x, x2 = frame.x + frame.width;
      double /*float*/ y1 = frame.y, y2 = frame.y + frame.height;
      if (x1 < minX) minX = x1;
      if (x2 < minX) minX = x2;
      if (x1 > maxX) maxX = x1;
      if (x2 > maxX) maxX = x2;
      if (y1 < minY) minY = y1;
      if (y2 < minY) minY = y2;
      if (y1 > maxY) maxY = y1;
      if (y2 > maxY) maxY = y2;
    }
    NSRect frame = new NSRect();
    frame.x = minX;
    frame.y = minY;
    frame.width = maxX - minX;
    frame.height = maxY - minY;
    window =
        window.initWithContentRect(
            frame, OS.NSBorderlessWindowMask, OS.NSBackingStoreBuffered, false);
    window.setOpaque(false);
    window.setLevel(OS.NSStatusWindowLevel);
    window.setContentView(null);
    window.setBackgroundColor(NSColor.clearColor());
    NSGraphicsContext context = window.graphicsContext();
    NSGraphicsContext.static_saveGraphicsState();
    NSGraphicsContext.setCurrentContext(context);
    context.setCompositingOperation(OS.NSCompositeClear);
    frame.x = frame.y = 0;
    NSBezierPath.fillRect(frame);
    NSGraphicsContext.static_restoreGraphicsState();
    window.orderFrontRegardless();

    drawRectangles(window, rectangles, false);

    /*
     * If exactly one of UP/DOWN is specified as a style then set the cursor
     * orientation accordingly (the same is done for LEFT/RIGHT styles below).
     */
    int vStyle = style & (SWT.UP | SWT.DOWN);
    if (vStyle == SWT.UP || vStyle == SWT.DOWN) {
      cursorOrientation |= vStyle;
    }
    int hStyle = style & (SWT.LEFT | SWT.RIGHT);
    if (hStyle == SWT.LEFT || hStyle == SWT.RIGHT) {
      cursorOrientation |= hStyle;
    }

    Point cursorPos;
    boolean down = false;
    NSApplication application = NSApplication.sharedApplication();
    NSEvent currentEvent = application.currentEvent();
    if (currentEvent != null) {
      switch ((int) /*64*/ currentEvent.type()) {
        case OS.NSLeftMouseDown:
        case OS.NSLeftMouseDragged:
        case OS.NSRightMouseDown:
        case OS.NSRightMouseDragged:
        case OS.NSOtherMouseDown:
        case OS.NSOtherMouseDragged:
          down = true;
      }
    }
    if (down) {
      cursorPos = display.getCursorLocation();
    } else {
      if ((style & SWT.RESIZE) != 0) {
        cursorPos = adjustResizeCursor(true);
      } else {
        cursorPos = adjustMoveCursor();
      }
    }
    if (cursorPos != null) {
      oldX = cursorPos.x;
      oldY = cursorPos.y;
    }

    Control oldTrackingControl = display.trackingControl;
    display.trackingControl = null;
    /* Tracker behaves like a Dialog with its own OS event loop. */
    while (tracking && !cancelled) {
      display.addPool();
      try {
        if (parent != null && parent.isDisposed()) break;
        display.runSkin();
        display.runDeferredLayouts();
        NSEvent event =
            application.nextEventMatchingMask(
                0, NSDate.distantFuture(), OS.NSDefaultRunLoopMode, true);
        if (event == null) continue;
        int type = (int) /*64*/ event.type();
        switch (type) {
          case OS.NSLeftMouseUp:
          case OS.NSRightMouseUp:
          case OS.NSOtherMouseUp:
          case OS.NSMouseMoved:
          case OS.NSLeftMouseDragged:
          case OS.NSRightMouseDragged:
          case OS.NSOtherMouseDragged:
            mouse(event);
            break;
          case OS.NSKeyDown:
          case OS.NSKeyUp:
          case OS.NSFlagsChanged:
            key(event);
            break;
        }
        boolean dispatch = true;
        switch (type) {
          case OS.NSLeftMouseDown:
          case OS.NSLeftMouseUp:
          case OS.NSRightMouseDown:
          case OS.NSRightMouseUp:
          case OS.NSOtherMouseDown:
          case OS.NSOtherMouseUp:
          case OS.NSMouseMoved:
          case OS.NSLeftMouseDragged:
          case OS.NSRightMouseDragged:
          case OS.NSOtherMouseDragged:
          case OS.NSMouseEntered:
          case OS.NSMouseExited:
          case OS.NSKeyDown:
          case OS.NSKeyUp:
          case OS.NSFlagsChanged:
            dispatch = false;
        }
        if (dispatch) application.sendEvent(event);
        if (clientCursor != null && resizeCursor == null) {
          display.lockCursor = false;
          clientCursor.handle.set();
          display.lockCursor = true;
        }
        display.runAsyncMessages(false);
      } finally {
        display.removePool();
      }
    }

    /*
     * Cleanup: If this tracker was resizing then the last cursor that it created
     * needs to be destroyed.
     */
    if (resizeCursor != null) resizeCursor.dispose();
    resizeCursor = null;

    if (oldTrackingControl != null && !oldTrackingControl.isDisposed()) {
      display.trackingControl = oldTrackingControl;
    }
    display.setCursor(display.findControl(true));
    if (!isDisposed()) {
      drawRectangles(window, rectangles, true);
    }
    if (window != null) window.close();
    tracking = false;
    window = null;
    return !cancelled;
  }
 void mouse(NSEvent nsEvent) {
   NSPoint location;
   if (nsEvent == null || nsEvent.type() == OS.NSMouseMoved) {
     location = NSEvent.mouseLocation();
   } else {
     location = nsEvent.locationInWindow();
     location = nsEvent.window().convertBaseToScreen(location);
   }
   location.y = display.getPrimaryFrame().height - location.y;
   int newX = (int) location.x, newY = (int) location.y;
   if (newX != oldX || newY != oldY) {
     Rectangle[] oldRectangles = rectangles;
     Rectangle[] rectsToErase = new Rectangle[rectangles.length];
     for (int i = 0; i < rectangles.length; i++) {
       Rectangle current = rectangles[i];
       rectsToErase[i] = new Rectangle(current.x, current.y, current.width, current.height);
     }
     Event event = new Event();
     event.x = newX;
     event.y = newY;
     if ((style & SWT.RESIZE) != 0) {
       boolean orientationInit = resizeRectangles(newX - oldX, newY - oldY);
       inEvent = true;
       sendEvent(SWT.Resize, event);
       inEvent = false;
       /*
        * It is possible (but unlikely), that application
        * code could have disposed the widget in the move
        * event.  If this happens, return false to indicate
        * that the tracking has failed.
        */
       if (isDisposed()) {
         cancelled = true;
         return;
       }
       boolean draw = false;
       /*
        * It is possible that application code could have
        * changed the rectangles in the resize event.  If this
        * happens then only redraw the tracker if the rectangle
        * values have changed.
        */
       if (rectangles != oldRectangles) {
         int length = rectangles.length;
         if (length != rectsToErase.length) {
           draw = true;
         } else {
           for (int i = 0; i < length; i++) {
             if (!rectangles[i].equals(rectsToErase[i])) {
               draw = true;
               break;
             }
           }
         }
       } else {
         draw = true;
       }
       if (draw) {
         drawRectangles(window, rectsToErase, true);
         drawRectangles(window, rectangles, false);
       }
       Point cursorPos = adjustResizeCursor(orientationInit);
       if (cursorPos != null) {
         newX = cursorPos.x;
         newY = cursorPos.y;
       }
     } else {
       moveRectangles(newX - oldX, newY - oldY);
       inEvent = true;
       sendEvent(SWT.Move, event);
       inEvent = false;
       /*
        * It is possible (but unlikely), that application
        * code could have disposed the widget in the move
        * event.  If this happens, return false to indicate
        * that the tracking has failed.
        */
       if (isDisposed()) {
         cancelled = true;
         return;
       }
       boolean draw = false;
       /*
        * It is possible that application code could have
        * changed the rectangles in the move event.  If this
        * happens then only redraw the tracker if the rectangle
        * values have changed.
        */
       if (rectangles != oldRectangles) {
         int length = rectangles.length;
         if (length != rectsToErase.length) {
           draw = true;
         } else {
           for (int i = 0; i < length; i++) {
             if (!rectangles[i].equals(rectsToErase[i])) {
               draw = true;
               break;
             }
           }
         }
       } else {
         draw = true;
       }
       if (draw) {
         drawRectangles(window, rectsToErase, true);
         drawRectangles(window, rectangles, false);
       }
     }
     oldX = newX;
     oldY = newY;
   }
   switch ((int) /*64*/ nsEvent.type()) {
     case OS.NSLeftMouseUp:
     case OS.NSRightMouseUp:
     case OS.NSOtherMouseUp:
       tracking = false;
   }
 }
  void key(NSEvent nsEvent) {
    int nsType = (int) /*64*/ nsEvent.type();
    long /*int*/ modifierFlags = nsEvent.modifierFlags();
    int nsKeyCode = nsEvent.keyCode();
    int keyCode = Display.translateKey(nsKeyCode);

    switch (nsType) {
      case OS.NSKeyDown:
      case OS.NSKeyUp:
        {
          Event event = new Event();
          event.keyCode = keyCode;
          int type = nsType == OS.NSKeyDown ? SWT.KeyDown : SWT.KeyUp;
          if (!setKeyState(event, type, nsEvent)) break;
          if (!sendKeyEvent(type, event)) return;
          break;
        }
      case OS.NSFlagsChanged:
        {
          int mask = 0;
          switch (keyCode) {
            case SWT.ALT:
              mask = OS.NSAlternateKeyMask;
              break;
            case SWT.CONTROL:
              mask = OS.NSControlKeyMask;
              break;
            case SWT.COMMAND:
              mask = OS.NSCommandKeyMask;
              break;
            case SWT.SHIFT:
              mask = OS.NSShiftKeyMask;
              break;
            case SWT.CAPS_LOCK:
              Event event = new Event();
              event.keyCode = keyCode;
              setInputState(event, nsEvent, SWT.KeyDown);
              sendKeyEvent(SWT.KeyDown, event);
              setInputState(event, nsEvent, SWT.KeyUp);
              sendKeyEvent(SWT.KeyUp, event);
              break;
          }
          if (mask != 0) {
            int type = (mask & modifierFlags) != 0 ? SWT.KeyDown : SWT.KeyUp;
            Event event = new Event();
            event.keyCode = keyCode;
            setLocationMask(event, nsEvent);
            setInputState(event, nsEvent, type);
            if (!sendKeyEvent(type, event)) return;
          }
          break;
        }
    }

    int stepSize = (modifierFlags & OS.NSControlKeyMask) != 0 ? STEPSIZE_SMALL : STEPSIZE_LARGE;
    int xChange = 0, yChange = 0;
    switch (nsKeyCode) {
      case 53: /* Esc */
        cancelled = true;
        tracking = false;
        break;
      case 76: /* KP Enter */
      case 36: /* Return */
        tracking = false;
        break;
      case 123: /* Left arrow */
        xChange = -stepSize;
        break;
      case 124: /* Right arrow */
        xChange = stepSize;
        break;
      case 126: /* Up arrow */
        yChange = -stepSize;
        break;
      case 125: /* Down arrow */
        yChange = stepSize;
        break;
    }
    if (xChange != 0 || yChange != 0) {
      Rectangle[] oldRectangles = rectangles;
      Rectangle[] rectsToErase = new Rectangle[rectangles.length];
      for (int i = 0; i < rectangles.length; i++) {
        Rectangle current = rectangles[i];
        rectsToErase[i] = new Rectangle(current.x, current.y, current.width, current.height);
      }
      Event event = new Event();
      int newX = oldX + xChange;
      int newY = oldY + yChange;
      event.x = newX;
      event.y = newY;
      Point cursorPos;
      if ((style & SWT.RESIZE) != 0) {
        resizeRectangles(xChange, yChange);
        inEvent = true;
        sendEvent(SWT.Resize, event);
        inEvent = false;
        /*
         * It is possible (but unlikely) that application
         * code could have disposed the widget in the move
         * event.  If this happens return false to indicate
         * that the tracking has failed.
         */
        if (isDisposed()) {
          cancelled = true;
          return;
        }
        boolean draw = false;
        /*
         * It is possible that application code could have
         * changed the rectangles in the resize event.  If this
         * happens then only redraw the tracker if the rectangle
         * values have changed.
         */
        if (rectangles != oldRectangles) {
          int length = rectangles.length;
          if (length != rectsToErase.length) {
            draw = true;
          } else {
            for (int i = 0; i < length; i++) {
              if (!rectangles[i].equals(rectsToErase[i])) {
                draw = true;
                break;
              }
            }
          }
        } else {
          draw = true;
        }
        if (draw) {
          drawRectangles(window, rectsToErase, true);
          drawRectangles(window, rectangles, false);
        }
        cursorPos = adjustResizeCursor(true);
      } else {
        moveRectangles(xChange, yChange);
        inEvent = true;
        sendEvent(SWT.Move, event);
        inEvent = false;
        /*
         * It is possible (but unlikely) that application
         * code could have disposed the widget in the move
         * event.  If this happens return false to indicate
         * that the tracking has failed.
         */
        if (isDisposed()) {
          cancelled = true;
          return;
        }
        boolean draw = false;
        /*
         * It is possible that application code could have
         * changed the rectangles in the move event.  If this
         * happens then only redraw the tracker if the rectangle
         * values have changed.
         */
        if (rectangles != oldRectangles) {
          int length = rectangles.length;
          if (length != rectsToErase.length) {
            draw = true;
          } else {
            for (int i = 0; i < length; i++) {
              if (!rectangles[i].equals(rectsToErase[i])) {
                draw = true;
                break;
              }
            }
          }
        } else {
          draw = true;
        }
        if (draw) {
          drawRectangles(window, rectsToErase, true);
          drawRectangles(window, rectangles, false);
        }
        cursorPos = adjustMoveCursor();
      }
      if (cursorPos != null) {
        oldX = cursorPos.x;
        oldY = cursorPos.y;
      }
    }
  }
Beispiel #4
0
  /**
   * Displays the Tracker rectangles for manipulation by the user. Returns when the user has either
   * finished manipulating the rectangles or has cancelled the Tracker.
   *
   * @return <code>true</code> if the user did not cancel the Tracker, <code>false</code> otherwise
   * @exception SWTException
   *     <ul>
   *       <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
   *       <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
   *     </ul>
   */
  public boolean open() {
    checkWidget();
    cancelled = false;
    tracking = true;
    window = (NSWindow) new NSWindow().alloc();
    NSRect frame = NSScreen.mainScreen().frame();
    window =
        window.initWithContentRect_styleMask_backing_defer_(
            frame, OS.NSBorderlessWindowMask, OS.NSBackingStoreBuffered, false);
    window.setOpaque(false);
    window.setContentView(null);
    NSGraphicsContext context = window.graphicsContext();
    NSGraphicsContext.setCurrentContext(context);
    context.setCompositingOperation(OS.NSCompositeClear);
    NSBezierPath.fillRect(frame);
    window.orderFrontRegardless();

    drawRectangles(window, rectangles, false);

    /*
     * If exactly one of UP/DOWN is specified as a style then set the cursor
     * orientation accordingly (the same is done for LEFT/RIGHT styles below).
     */
    int vStyle = style & (SWT.UP | SWT.DOWN);
    if (vStyle == SWT.UP || vStyle == SWT.DOWN) {
      cursorOrientation |= vStyle;
    }
    int hStyle = style & (SWT.LEFT | SWT.RIGHT);
    if (hStyle == SWT.LEFT || hStyle == SWT.RIGHT) {
      cursorOrientation |= hStyle;
    }

    Point cursorPos;
    boolean down = false;
    NSApplication application = NSApplication.sharedApplication();
    NSEvent currentEvent = application.currentEvent();
    switch (currentEvent.type()) {
      case OS.NSLeftMouseDown:
      case OS.NSRightMouseDown:
      case OS.NSOtherMouseDown:
        down = true;
    }
    if (down) {
      cursorPos = display.getCursorLocation();
    } else {
      if ((style & SWT.RESIZE) != 0) {
        cursorPos = adjustResizeCursor(true);
      } else {
        cursorPos = adjustMoveCursor();
      }
    }
    if (cursorPos != null) {
      oldX = cursorPos.x;
      oldY = cursorPos.y;
    }

    /* Tracker behaves like a Dialog with its own OS event loop. */
    while (tracking && !cancelled) {
      NSAutoreleasePool pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init();
      NSEvent event =
          application.nextEventMatchingMask(
              0, NSDate.distantFuture(), OS.NSDefaultRunLoopMode, true);
      if (event == null) continue;
      int type = event.type();
      switch (type) {
        case OS.NSLeftMouseUp:
        case OS.NSRightMouseUp:
        case OS.NSOtherMouseUp:
        case OS.NSMouseMoved:
        case OS.NSLeftMouseDragged:
        case OS.NSRightMouseDragged:
        case OS.NSOtherMouseDragged:
          mouse(event);
          break;
        case OS.NSKeyDown:
          //			case OS.NSKeyUp:
        case OS.NSFlagsChanged:
          key(event);
          break;
      }
      /*
       * Don't dispatch mouse and key events in general, EXCEPT once this
       * tracker has finished its work.
       */
      boolean dispatch = true;
      if (!(tracking && !cancelled)) {
        switch (type) {
          case OS.NSLeftMouseDown:
          case OS.NSLeftMouseUp:
          case OS.NSRightMouseDown:
          case OS.NSRightMouseUp:
          case OS.NSOtherMouseDown:
          case OS.NSOtherMouseUp:
          case OS.NSMouseMoved:
          case OS.NSLeftMouseDragged:
          case OS.NSRightMouseDragged:
          case OS.NSOtherMouseDragged:
          case OS.NSMouseEntered:
          case OS.NSMouseExited:
          case OS.NSKeyDown:
          case OS.NSKeyUp:
          case OS.NSFlagsChanged:
            dispatch = false;
        }
      }
      if (dispatch) application.sendEvent(event);
      if (clientCursor != null && resizeCursor == null) {
        clientCursor.handle.set();
      }
      pool.release();
    }
    if (!isDisposed()) {
      drawRectangles(window, rectangles, true);
    }
    if (window != null) window.close();
    tracking = false;
    window = null;
    return !cancelled;
  }