Пример #1
0
 void setSelection(int index, boolean notify) {
   if (index < 0) return;
   int oldIndex = OS.gtk_notebook_get_current_page(handle);
   if (oldIndex == index) return;
   if (oldIndex != -1) {
     TabItem item = items[oldIndex];
     Control control = item.control;
     if (control != null && !control.isDisposed()) {
       control.setVisible(false);
     }
   }
   OS.g_signal_handlers_block_matched(handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, SWITCH_PAGE);
   OS.gtk_notebook_set_current_page(handle, index);
   OS.g_signal_handlers_unblock_matched(handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, SWITCH_PAGE);
   int newIndex = OS.gtk_notebook_get_current_page(handle);
   if (newIndex != -1) {
     TabItem item = items[newIndex];
     Control control = item.control;
     if (control != null && !control.isDisposed()) {
       control.setBounds(getClientArea());
       control.setVisible(true);
     }
     if (notify) {
       Event event = new Event();
       event.item = item;
       sendSelectionEvent(SWT.Selection, event, true);
     }
   }
 }
Пример #2
0
 /**
  * Sets the control that is used to fill the bounds of the item when the item is a <code>SEPARATOR
  * </code>.
  *
  * @param control the new control
  * @exception IllegalArgumentException
  *     <ul>
  *       <li>ERROR_INVALID_ARGUMENT - if the control has been disposed
  *       <li>ERROR_INVALID_PARENT - if the control is not in the same widget tree
  *     </ul>
  *
  * @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 setControl(Control control) {
   checkWidget();
   if (control != null) {
     if (control.isDisposed()) error(SWT.ERROR_INVALID_ARGUMENT);
     if (control.parent != parent) error(SWT.ERROR_INVALID_PARENT);
   }
   if ((style & SWT.SEPARATOR) == 0) return;
   if (control == null) {
     int property = OS.Control_BackgroundProperty();
     OS.DependencyObject_ClearValue(handle, property);
     OS.GCHandle_Free(property);
     Control oldControl = this.control;
     if (oldControl != null && !oldControl.isDisposed()) OS.Panel_SetZIndex(oldControl.handle, 0);
   } else {
     int brush = OS.Brushes_Transparent();
     OS.Control_Background(handle, brush);
     OS.GCHandle_Free(brush);
     int pt = OS.gcnew_Point(0, 0);
     if (pt == 0) error(SWT.ERROR_NO_HANDLES);
     int loc = OS.UIElement_TranslatePoint(handle, pt, parent.parentingHandle);
     OS.GCHandle_Free(pt);
     OS.Canvas_SetLeft(control.handle, OS.Point_X(loc));
     OS.Canvas_SetTop(control.handle, OS.Point_Y(loc));
     OS.Panel_SetZIndex(control.handle, parent.childCount);
     OS.GCHandle_Free(loc);
   }
   this.control = control;
 }
Пример #3
0
 void destroyItem(TabItem item) {
   int index = 0;
   int itemCount = getItemCount();
   while (index < itemCount) {
     if (items[index] == item) break;
     index++;
   }
   if (index == itemCount) error(SWT.ERROR_ITEM_NOT_REMOVED);
   int oldIndex = OS.gtk_notebook_get_current_page(handle);
   OS.g_signal_handlers_block_matched(handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, SWITCH_PAGE);
   OS.gtk_notebook_remove_page(handle, index);
   OS.g_signal_handlers_unblock_matched(handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, SWITCH_PAGE);
   System.arraycopy(items, index + 1, items, index, --itemCount - index);
   items[itemCount] = null;
   if (index == oldIndex) {
     int newIndex = OS.gtk_notebook_get_current_page(handle);
     if (newIndex != -1) {
       Control control = items[newIndex].getControl();
       if (control != null && !control.isDisposed()) {
         control.setBounds(getClientArea());
         control.setVisible(true);
       }
       Event event = new Event();
       event.item = items[newIndex];
       sendSelectionEvent(SWT.Selection, event, true);
       // the widget could be destroyed at this point
     }
   }
 }
Пример #4
0
 /**
  * Sets the control that is used to fill the client area of the tab folder when the user selects
  * the tab item.
  *
  * <p>
  *
  * @param control the new control (or null)
  * @exception IllegalArgumentException
  *     <ul>
  *       <li>ERROR_INVALID_ARGUMENT - if the control has been disposed
  *       <li>ERROR_INVALID_PARENT - if the control is not in the same widget tree
  *     </ul>
  *
  * @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 setControl(Control control) {
   checkWidget();
   if (control != null) {
     if (control.isDisposed()) {
       error(SWT.ERROR_INVALID_ARGUMENT);
     }
     if (control.parent != parent) {
       error(SWT.ERROR_INVALID_PARENT);
     }
   }
   if (this.control != null && this.control.isDisposed()) {
     this.control = null;
   }
   Control oldControl = this.control;
   Control newControl = control;
   this.control = control;
   int index = parent.indexOf(this);
   if (index != parent.getSelectionIndex()) {
     if (newControl != null) {
       newControl.setVisible(false);
     }
   } else {
     if (newControl != null) {
       newControl.setBounds(parent.getClientArea());
       newControl.setVisible(true);
     }
     if (oldControl != null) {
       oldControl.setVisible(false);
     }
   }
 }
Пример #5
0
 /**
  * Sets the control that is used to fill the bounds of the item when the item is a <code>SEPARATOR
  * </code>.
  *
  * @param control the new control
  * @exception IllegalArgumentException
  *     <ul>
  *       <li>ERROR_INVALID_ARGUMENT - if the control has been disposed
  *       <li>ERROR_INVALID_PARENT - if the control is not in the same widget tree
  *     </ul>
  *
  * @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 setControl(Control control) {
   checkWidget();
   if (control != null) {
     if (control.isDisposed()) error(SWT.ERROR_INVALID_ARGUMENT);
     if (control.parent != parent) error(SWT.ERROR_INVALID_PARENT);
   }
   if ((style & SWT.SEPARATOR) == 0) return;
   if (this.control == control) return;
   this.control = control;
   int[] argList = {
     OS.XmNseparatorType,
     control == null
         ? ((parent.style & SWT.FLAT) != 0 ? OS.XmSHADOW_ETCHED_IN : OS.XmSHADOW_ETCHED_OUT)
         : OS.XmNO_LINE,
   };
   OS.XtSetValues(handle, argList, argList.length / 2);
   if (control != null && !control.isDisposed()) {
     /*
      * It is possible that the control was created with a
      * z-order below that of the current tool item. In this
      * case, the control is not visible because it is
      * obscured by the tool item. The fix is to move the
      * control above this tool item in the z-order.
      * The code below is similar to the code found in
      * setZOrder.
      */
     int xDisplay = OS.XtDisplay(handle);
     if (xDisplay == 0) return;
     if (!OS.XtIsRealized(handle)) {
       Shell shell = parent.getShell();
       shell.realizeWidget();
     }
     int topHandle1 = control.topHandle();
     int window1 = OS.XtWindow(topHandle1);
     if (window1 == 0) return;
     int topHandle2 = this.topHandle();
     int window2 = OS.XtWindow(topHandle2);
     if (window2 == 0) return;
     XWindowChanges struct = new XWindowChanges();
     struct.sibling = window2;
     struct.stack_mode = OS.Above;
     int screen = OS.XDefaultScreen(xDisplay);
     int flags = OS.CWStackMode | OS.CWSibling;
     OS.XReconfigureWMWindow(xDisplay, window1, screen, flags, struct);
   }
   parent.relayout();
 }
Пример #6
0
 long /*int*/ gtk_switch_page(long /*int*/ widget, long /*int*/ page, long /*int*/ page_num) {
   int index = OS.gtk_notebook_get_current_page(handle);
   if (index != -1) {
     Control control = items[index].getControl();
     if (control != null && !control.isDisposed()) {
       control.setVisible(false);
     }
   }
   TabItem item = items[(int) /*64*/ page_num];
   Control control = item.getControl();
   if (control != null && !control.isDisposed()) {
     control.setBounds(getClientArea());
     control.setVisible(true);
   }
   Event event = new Event();
   event.item = item;
   sendSelectionEvent(SWT.Selection, event, false);
   return 0;
 }
Пример #7
0
 protected void layout(Composite composite, boolean flushCache) {
   CTabFolder folder = (CTabFolder) composite;
   // resize content
   if (folder.selectedIndex != -1) {
     Control control = folder.items[folder.selectedIndex].getControl();
     if (control != null && !control.isDisposed()) {
       control.setBounds(folder.getClientArea());
     }
   }
 }
Пример #8
0
 /**
  * Sets the control that is used to fill the bounds of the item when the item is a <code>SEPARATOR
  * </code>.
  *
  * @param control the new control
  * @exception IllegalArgumentException
  *     <ul>
  *       <li>ERROR_INVALID_ARGUMENT - if the control has been disposed
  *       <li>ERROR_INVALID_PARENT - if the control is not in the same widget tree
  *     </ul>
  *
  * @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 setControl(Control control) {
   checkWidget();
   if (control != null) {
     if (control.isDisposed()) error(SWT.ERROR_INVALID_ARGUMENT);
     if (control.parent != parent) error(SWT.ERROR_INVALID_PARENT);
   }
   if ((style & SWT.SEPARATOR) == 0) return;
   if (this.control == control) return;
   this.control = control;
   parent.relayout();
 }
Пример #9
0
 /**
  * Sets the control that is shown when the item is expanded.
  *
  * @param control the new control (or null)
  * @exception IllegalArgumentException
  *     <ul>
  *       <li>ERROR_INVALID_ARGUMENT - if the control has been disposed
  *       <li>ERROR_INVALID_PARENT - if the control is not in the same widget tree
  *     </ul>
  *
  * @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 setControl(Control control) {
   checkWidget();
   if (control != null) {
     if (control.isDisposed()) error(SWT.ERROR_INVALID_ARGUMENT);
     if (control.parent != parent) error(SWT.ERROR_INVALID_PARENT);
   }
   if (this.control == control) return;
   this.control = control;
   if (control != null) {
     control.setVisible(expanded);
   }
   parent.layoutItems(0, true);
 }
Пример #10
0
 int setBounds(int x, int y, int width, int height, boolean move, boolean resize) {
   int result = super.setBounds(x, y, width, height, move, resize);
   if ((result & RESIZED) != 0) {
     int index = getSelectionIndex();
     if (index != -1) {
       TabItem item = items[index];
       Control control = item.control;
       if (control != null && !control.isDisposed()) {
         control.setBounds(getClientArea());
       }
     }
   }
   return result;
 }
Пример #11
0
 void resizeControl() {
   if (control != null && !control.isDisposed()) {
     /*
      * Set the size and location of the control
      * separately to minimize flashing in the
      * case where the control does not resize
      * to the size that was requested.  This
      * case can occur when the control is a
      * combo box.
      */
     Rectangle itemRect = getBounds();
     control.setSize(itemRect.width, itemRect.height);
     Rectangle rect = control.getBounds();
     rect.x = itemRect.x + (itemRect.width - rect.width) / 2;
     rect.y = itemRect.y + (itemRect.height - rect.height) / 2;
     control.setLocation(rect.x, rect.y);
   }
 }
Пример #12
0
 void setBounds(int x, int y, int width, int height, boolean move, boolean size) {
   redraw();
   int headerHeight = parent.getBandHeight();
   if (move) {
     if (imageHeight > headerHeight) {
       y += (imageHeight - headerHeight);
     }
     this.x = x;
     this.y = y;
     redraw();
   }
   if (size) {
     this.width = width;
     this.height = height;
     redraw();
   }
   if (control != null && !control.isDisposed()) {
     if (move) control.setLocation(x + BORDER, y + headerHeight);
     if (size) control.setSize(Math.max(0, width - 2 * BORDER), Math.max(0, height - BORDER));
   }
 }
Пример #13
0
  void resizeControl(int yScroll) {
    if (control != null && !control.isDisposed()) {
      boolean visible = OS.gtk_expander_get_expanded(handle);
      if (visible) {
        int x = OS.GTK_WIDGET_X(clientHandle);
        int y = OS.GTK_WIDGET_Y(clientHandle);
        if (x != -1 && y != -1) {
          int width = OS.GTK_WIDGET_WIDTH(clientHandle);
          int height = OS.GTK_WIDGET_HEIGHT(clientHandle);
          int[] property = new int[1];
          OS.gtk_widget_style_get(handle, OS.focus_line_width, property, 0);
          y += property[0] * 2;
          height -= property[0] * 2;

          /*
           * Feature in GTK. When the ExpandBar is resize too small the control
           * shows up on top of the vertical scrollbar. This happen because the
           * GtkExpander does not set the size of child smaller than the request
           * size of its parent and because the control is not parented in the
           * hierarchy of the GtkScrolledWindow.
           * The fix is calculate the width ourselves when the scrollbar is visible.
           */
          ScrollBar vBar = parent.verticalBar;
          if (vBar != null) {
            if (OS.GTK_WIDGET_VISIBLE(vBar.handle)) {
              width =
                  OS.GTK_WIDGET_WIDTH(parent.scrolledHandle)
                      - parent.vScrollBarWidth()
                      - 2 * parent.spacing;
            }
          }
          control.setBounds(x, y - yScroll, width, Math.max(0, height), true, true);
        }
      }
      control.setVisible(visible);
    }
  }
Пример #14
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();
    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;
  }
Пример #15
0
  protected Point computeSize(Composite composite, int wHint, int hHint, boolean flushCache) {
    CTabFolder folder = (CTabFolder) composite;
    CTabItem[] items = folder.items;
    CTabFolderRenderer renderer = folder.renderer;
    // preferred width of tab area to show all tabs
    int tabW = 0;
    int selectedIndex = folder.selectedIndex;
    if (selectedIndex == -1) selectedIndex = 0;
    GC gc = new GC(folder);
    for (int i = 0; i < items.length; i++) {
      if (folder.single) {
        tabW =
            Math.max(tabW, renderer.computeSize(i, SWT.SELECTED, gc, SWT.DEFAULT, SWT.DEFAULT).x);
      } else {
        int state = 0;
        if (i == selectedIndex) state |= SWT.SELECTED;
        tabW += renderer.computeSize(i, state, gc, SWT.DEFAULT, SWT.DEFAULT).x;
      }
    }
    tabW += 3;

    if (folder.showMax)
      tabW +=
          renderer.computeSize(
                  CTabFolderRenderer.PART_MAX_BUTTON, SWT.NONE, gc, SWT.DEFAULT, SWT.DEFAULT)
              .x;
    if (folder.showMin)
      tabW +=
          renderer.computeSize(
                  CTabFolderRenderer.PART_MIN_BUTTON, SWT.NONE, gc, SWT.DEFAULT, SWT.DEFAULT)
              .x;
    if (folder.single)
      tabW +=
          renderer.computeSize(
                  CTabFolderRenderer.PART_CHEVRON_BUTTON, SWT.NONE, gc, SWT.DEFAULT, SWT.DEFAULT)
              .x;
    if (folder.topRight != null) {
      Point pt = folder.topRight.computeSize(SWT.DEFAULT, folder.tabHeight, flushCache);
      tabW += 3 + pt.x;
    }

    gc.dispose();

    int controlW = 0;
    int controlH = 0;
    // preferred size of controls in tab items
    for (int i = 0; i < items.length; i++) {
      Control control = items[i].getControl();
      if (control != null && !control.isDisposed()) {
        Point size = control.computeSize(wHint, hHint, flushCache);
        controlW = Math.max(controlW, size.x);
        controlH = Math.max(controlH, size.y);
      }
    }

    int minWidth = Math.max(tabW, controlW);
    int minHeight = (folder.minimized) ? 0 : controlH;
    if (minWidth == 0) minWidth = CTabFolder.DEFAULT_WIDTH;
    if (minHeight == 0) minHeight = CTabFolder.DEFAULT_HEIGHT;

    if (wHint != SWT.DEFAULT) minWidth = wHint;
    if (hHint != SWT.DEFAULT) minHeight = hHint;

    return new Point(minWidth, minHeight);
  }
Пример #16
0
 /**
  * Sets the control that is used to fill the bounds of the item when the item is a <code>SEPARATOR
  * </code>.
  *
  * @param control the new control
  * @exception IllegalArgumentException
  *     <ul>
  *       <li>ERROR_INVALID_ARGUMENT - if the control has been disposed
  *       <li>ERROR_INVALID_PARENT - if the control is not in the same widget tree
  *     </ul>
  *
  * @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 setControl(Control control) {
   checkWidget();
   if (control != null) {
     if (control.isDisposed()) error(SWT.ERROR_INVALID_ARGUMENT);
     if (control.parent != parent) error(SWT.ERROR_INVALID_PARENT);
   }
   if ((style & SWT.SEPARATOR) == 0) return;
   this.control = control;
   /*
    * Feature in Windows.  When a tool bar wraps, tool items
    * with the style BTNS_SEP are used as wrap points.  This
    * means that controls that are placed on top of separator
    * items are not positioned properly.  Also, vertical tool
    * bars are implemented using TB_SETROWS to set the number
    * of rows.  When a control is placed on top of a separator,
    * the height of the separator does not grow.  The fix in
    * both cases is to change the tool item style from BTNS_SEP
    * to BTNS_BUTTON, causing the item to wrap like a tool item
    * button.  The new tool item button is disabled to avoid key
    * traversal and the image is set to I_IMAGENONE to avoid
    * getting the first image from the image list.
    */
   if ((parent.style & (SWT.WRAP | SWT.VERTICAL)) != 0) {
     boolean changed = false;
     long /*int*/ hwnd = parent.handle;
     TBBUTTONINFO info = new TBBUTTONINFO();
     info.cbSize = TBBUTTONINFO.sizeof;
     info.dwMask = OS.TBIF_STYLE | OS.TBIF_STATE;
     OS.SendMessage(hwnd, OS.TB_GETBUTTONINFO, id, info);
     if (control == null) {
       if ((info.fsStyle & OS.BTNS_SEP) == 0) {
         changed = true;
         info.fsStyle &= ~(OS.BTNS_BUTTON | OS.BTNS_SHOWTEXT);
         info.fsStyle |= OS.BTNS_SEP;
         if ((state & DISABLED) != 0) {
           info.fsState &= ~OS.TBSTATE_ENABLED;
         } else {
           info.fsState |= OS.TBSTATE_ENABLED;
         }
       }
     } else {
       if ((info.fsStyle & OS.BTNS_SEP) != 0) {
         changed = true;
         info.fsStyle &= ~OS.BTNS_SEP;
         info.fsStyle |= OS.BTNS_BUTTON | OS.BTNS_SHOWTEXT;
         info.fsState &= ~OS.TBSTATE_ENABLED;
         info.dwMask |= OS.TBIF_IMAGE;
         info.iImage = OS.I_IMAGENONE;
       }
     }
     if (changed) {
       OS.SendMessage(hwnd, OS.TB_SETBUTTONINFO, id, info);
       /*
        * Bug in Windows.  When TB_SETBUTTONINFO changes the
        * style of a tool item from BTNS_SEP to BTNS_BUTTON
        * and the tool bar is wrapped, the tool bar does not
        * redraw properly.  Windows uses separator items as
        * wrap points and sometimes draws etching above or
        * below and entire row.  The fix is to redraw the
        * tool bar.
        */
       if (OS.SendMessage(hwnd, OS.TB_GETROWS, 0, 0) > 1) {
         OS.InvalidateRect(hwnd, null, true);
       }
     }
   }
   resizeControl();
 }