void releaseHandle() {
   super.releaseHandle();
   if (nsColumn != null) {
     nsColumn.headerCell().release();
     nsColumn.release();
   }
   nsColumn = null;
   parent = null;
 }
 /**
  * Sets the width of the receiver.
  *
  * @param width the new width
  * @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 void setWidth(int width) {
   checkWidget();
   if (width < 0) return;
   // TODO how to differentiate 0 and 1 cases?
   width = Math.max(0, width - Tree.CELL_GAP);
   nsColumn.setWidth(width);
 }
 /**
  * Gets the width of the receiver.
  *
  * @return the width
  * @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 int getWidth() {
   checkWidget();
   int width = (int) nsColumn.width();
   // TODO how to differentiate 0 and 1 cases?
   if (width > 0) width += Tree.CELL_GAP;
   return width;
 }
 public void setText(String string) {
   checkWidget();
   if (string == null) error(SWT.ERROR_NULL_ARGUMENT);
   super.setText(string);
   char[] buffer = new char[text.length()];
   text.getChars(0, buffer.length, buffer, 0);
   int length = fixMnemonic(buffer);
   displayText = new String(buffer, 0, length);
   NSString title = NSString.stringWith(displayText);
   nsColumn.headerCell().setTitle(title);
   NSTableHeaderView headerView = ((NSOutlineView) parent.view).headerView();
   if (headerView == null) return;
   int index = parent.indexOf(nsColumn);
   NSRect rect = headerView.headerRectOfColumn(index);
   headerView.setNeedsDisplayInRect(rect);
 }
  /**
   * Causes the receiver to be resized to its preferred size. For a composite, this involves
   * computing the preferred size from its layout, if there is one.
   *
   * @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 void pack() {
    checkWidget();

    int width = 0;

    /* compute header width */
    NSTableHeaderCell headerCell = nsColumn.headerCell();
    NSSize size = headerCell.cellSize();
    width += Math.ceil(size.width);
    if (image != null) {
      NSSize imageSize = image.handle.size();
      width += Math.ceil(imageSize.width) + MARGIN;
    }
    if (parent.sortColumn == this && parent.sortDirection != SWT.NONE) {
      NSRect sortRect = headerCell.sortIndicatorRectForBounds(new NSRect());
      width += Math.ceil(sortRect.width + 2 * MARGIN);
    }

    /* compute item widths down column */
    GC gc = new GC(parent);
    width = Math.max(width, parent.calculateWidth(parent.items, parent.indexOf(this), gc, true));
    gc.dispose();
    setWidth(width);
  }
 /**
  * Sets the resizable attribute. A column that is not resizable cannot be dragged by the user but
  * may be resized by the programmer.
  *
  * @param resizable the resize attribute
  * @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 void setResizable(boolean resizable) {
   checkWidget();
   nsColumn.setResizingMask(
       resizable ? OS.NSTableColumnUserResizingMask : OS.NSTableColumnNoResizing);
 }
 /**
  * Gets the resizable attribute. A column that is not resizable cannot be dragged by the user but
  * may be resized by the programmer.
  *
  * @return the resizable attribute
  * @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 getResizable() {
   checkWidget();
   return nsColumn.resizingMask() != OS.NSTableColumnNoResizing;
 }
  void drawInteriorWithFrame_inView(
      long /*int*/ id, long /*int*/ sel, NSRect cellRect, long /*int*/ view) {
    /*
     * Feature in Cocoa.  When the last column in a tree does not reach the
     * rightmost edge of the tree view, the cell that draws the rightmost-
     * column's header is also invoked to draw the header space between its
     * right edge and the tree's right edge.  If this case is detected then
     * nothing should be drawn.
     */
    int columnIndex = parent.indexOf(nsColumn);
    NSRect headerRect = parent.headerView.headerRectOfColumn(columnIndex);
    if (headerRect.x != cellRect.x || headerRect.width != cellRect.width) return;

    NSGraphicsContext context = NSGraphicsContext.currentContext();
    context.saveGraphicsState();

    int contentWidth = 0;
    NSSize stringSize = null, imageSize = null;
    NSAttributedString attrString = null;
    NSTableHeaderCell headerCell = nsColumn.headerCell();
    if (displayText != null) {
      Font font = Font.cocoa_new(display, headerCell.font());
      attrString =
          parent.createString(
              displayText, font, null, SWT.LEFT, false, (parent.state & DISABLED) == 0, false);
      stringSize = attrString.size();
      contentWidth += Math.ceil(stringSize.width);
      if (image != null) contentWidth += MARGIN; /* space between image and text */
    }
    if (image != null) {
      imageSize = image.handle.size();
      contentWidth += Math.ceil(imageSize.width);
    }

    if (parent.sortColumn == this && parent.sortDirection != SWT.NONE) {
      boolean ascending = parent.sortDirection == SWT.UP;
      headerCell.drawSortIndicatorWithFrame(cellRect, new NSView(view), ascending, 0);
      /* remove the arrow's space from the available drawing width */
      NSRect sortRect = headerCell.sortIndicatorRectForBounds(cellRect);
      cellRect.width = Math.max(0, sortRect.x - cellRect.x);
    }

    int drawX = 0;
    if ((style & SWT.CENTER) != 0) {
      drawX = (int) (cellRect.x + Math.max(MARGIN, ((cellRect.width - contentWidth) / 2)));
    } else if ((style & SWT.RIGHT) != 0) {
      drawX = (int) (cellRect.x + Math.max(MARGIN, cellRect.width - contentWidth - MARGIN));
    } else {
      drawX = (int) cellRect.x + MARGIN;
    }

    if (image != null) {
      NSRect destRect = new NSRect();
      destRect.x = drawX;
      destRect.y = cellRect.y;
      destRect.width = Math.min(imageSize.width, cellRect.width - 2 * MARGIN);
      destRect.height = Math.min(imageSize.height, cellRect.height);
      boolean isFlipped = new NSView(view).isFlipped();
      if (isFlipped) {
        context.saveGraphicsState();
        NSAffineTransform transform = NSAffineTransform.transform();
        transform.scaleXBy(1, -1);
        transform.translateXBy(0, -(destRect.height + 2 * destRect.y));
        transform.concat();
      }
      NSRect sourceRect = new NSRect();
      sourceRect.width = destRect.width;
      sourceRect.height = destRect.height;
      image.handle.drawInRect(destRect, sourceRect, OS.NSCompositeSourceOver, 1f);
      if (isFlipped) context.restoreGraphicsState();
      drawX += destRect.width;
    }

    if (displayText != null && displayText.length() > 0) {
      if (image != null) drawX += MARGIN; /* space between image and text */
      NSRect destRect = new NSRect();
      destRect.x = drawX;
      destRect.y = cellRect.y;
      destRect.width = Math.min(stringSize.width, cellRect.x + cellRect.width - MARGIN - drawX);
      destRect.height = Math.min(stringSize.height, cellRect.height);
      attrString.drawInRect(destRect);
    }
    if (attrString != null) attrString.release();

    context.restoreGraphicsState();
  }
 void deregister() {
   super.deregister();
   display.removeWidget(nsColumn.headerCell());
 }