Beispiel #1
0
 /**
  * Constructs a new instance of this class given the display to create it on and a style value
  * describing its behavior and appearance.
  *
  * <p>The style value is either one of the style constants defined in class <code>SWT</code> which
  * is applicable to instances of this class, or must be built by <em>bitwise OR</em>'ing together
  * (that is, using the <code>int</code> "|" operator) two or more of those <code>SWT</code> style
  * constants. The class description lists the style constants that are applicable to the class.
  * Style bits are also inherited from superclasses.
  *
  * <p>Note: Currently, null can be passed in for the display argument. This has the effect of
  * creating the tracker on the currently active display if there is one. If there is no current
  * display, the tracker is created on a "default" display. <b>Passing in null as the display
  * argument is not considered to be good coding style, and may not be supported in a future
  * release of SWT.</b>
  *
  * @param display the display to create the tracker on
  * @param style the style of control to construct
  * @exception SWTException
  *     <ul>
  *       <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent
  *       <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass
  *     </ul>
  *
  * @see SWT#LEFT
  * @see SWT#RIGHT
  * @see SWT#UP
  * @see SWT#DOWN
  */
 public Tracker(Display display, int style) {
   if (display == null) display = Display.getCurrent();
   if (display == null) display = Display.getDefault();
   if (!display.isValidThread()) {
     error(SWT.ERROR_THREAD_INVALID_ACCESS);
   }
   this.style = checkStyle(style);
   this.display = display;
 }
 /**
  * Returns the receiver's image data. This is the icon that is associated with the receiver in the
  * operating system.
  *
  * @return the image data for the program, may be null
  */
 public ImageData getImageData() {
   NSAutoreleasePool pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init();
   try {
     NSWorkspace workspace = NSWorkspace.sharedWorkspace();
     NSString fullPath;
     if (this.fullPath != null) {
       fullPath = NSString.stringWith(this.fullPath);
     } else {
       fullPath = workspace.fullPathForApplication(NSString.stringWith(name));
     }
     if (fullPath != null) {
       NSImage nsImage = workspace.iconForFile(fullPath);
       if (nsImage != null) {
         NSSize size = new NSSize();
         size.width = size.height = 16;
         nsImage.setSize(size);
         nsImage.retain();
         Image image = Image.cocoa_new(Display.getCurrent(), SWT.BITMAP, nsImage);
         ImageData imageData = image.getImageData();
         image.dispose();
         return imageData;
       }
     }
     return null;
   } finally {
     pool.release();
   }
 }
  /**
   * 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 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;
      }
    }
  }