Point minimumSize(int wHint, int hHint, boolean flushCache) {
   Control[] children = _getChildren();
   int width = 0, height = 0;
   for (int i = 0; i < children.length; i++) {
     Control child = children[i];
     int index = 0;
     int count = 0;
     long /*int*/ list = OS.gtk_container_get_children(handle);
     if (list != 0) {
       count = OS.g_list_length(list);
       OS.g_list_free(list);
     }
     while (index < count) {
       if (items[index].control == child) break;
       index++;
     }
     if (index == count) {
       Rectangle rect = child.getBounds();
       width = Math.max(width, rect.x + rect.width);
       height = Math.max(height, rect.y + rect.height);
     } else {
       Point size = child.computeSize(wHint, hHint, flushCache);
       width = Math.max(width, size.x);
       height = Math.max(height, size.y);
     }
   }
   return new Point(width, height);
 }
 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
     }
   }
 }
 private void onDispose() {
   if (control == null) return;
   this.Release();
   if (controlListener != null) {
     control.removeListener(SWT.Dispose, controlListener);
     control.removeListener(SWT.DragDetect, controlListener);
   }
   controlListener = null;
   control.setData(DND.DRAG_SOURCE_KEY, null);
   control = null;
   transferAgents = null;
 }
Beispiel #4
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);
 }
 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;
 }
 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);
     }
   }
 }
  /**
   * Creates a new <code>DragSource</code> to handle dragging from the specified <code>Control
   * </code>. Creating an instance of a DragSource may cause system resources to be allocated
   * depending on the platform. It is therefore mandatory that the DragSource instance be disposed
   * when no longer required.
   *
   * @param control the <code>Control</code> that the user clicks on to initiate the drag
   * @param style the bitwise OR'ing of allowed operations; this may be a combination of any of
   *     DND.DROP_NONE, DND.DROP_COPY, DND.DROP_MOVE, DND.DROP_LINK
   * @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>
   *
   * @exception SWTError
   *     <ul>
   *       <li>ERROR_CANNOT_INIT_DRAG - unable to initiate drag source; this will occur if more than
   *           one drag source is created for a control or if the operating system will not allow
   *           the creation of the drag source
   *     </ul>
   *     <p>NOTE: ERROR_CANNOT_INIT_DRAG should be an SWTException, since it is a recoverable error,
   *     but can not be changed due to backward compatibility.
   * @see Widget#dispose
   * @see DragSource#checkSubclass
   * @see DND#DROP_NONE
   * @see DND#DROP_COPY
   * @see DND#DROP_MOVE
   * @see DND#DROP_LINK
   */
  public DragSource(Control control, int style) {
    super(control, checkStyle(style));
    this.control = control;
    if (control.getData(DND.DRAG_SOURCE_KEY) != null) {
      DND.error(DND.ERROR_CANNOT_INIT_DRAG);
    }
    control.setData(DND.DRAG_SOURCE_KEY, this);
    createCOMInterfaces();
    this.AddRef();

    controlListener =
        new Listener() {
          public void handleEvent(Event event) {
            if (event.type == SWT.Dispose) {
              if (!DragSource.this.isDisposed()) {
                DragSource.this.dispose();
              }
            }
            if (event.type == SWT.DragDetect) {
              if (!DragSource.this.isDisposed()) {
                DragSource.this.drag(event);
              }
            }
          }
        };
    control.addListener(SWT.Dispose, controlListener);
    control.addListener(SWT.DragDetect, controlListener);

    this.addListener(
        SWT.Dispose,
        new Listener() {
          public void handleEvent(Event e) {
            DragSource.this.onDispose();
          }
        });

    Object effect = control.getData(DEFAULT_DRAG_SOURCE_EFFECT);
    if (effect instanceof DragSourceEffect) {
      dragEffect = (DragSourceEffect) effect;
    } else if (control instanceof Tree) {
      dragEffect = new TreeDragSourceEffect((Tree) control);
    } else if (control instanceof Table) {
      dragEffect = new TableDragSourceEffect((Table) control);
    }
  }
Beispiel #8
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);
   }
 }
Beispiel #9
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();
 }
Beispiel #10
0
 Widget[] computeTabList() {
   if (isTabGroup()) {
     if (getEnabled()) {
       if ((style & SWT.SEPARATOR) != 0) {
         if (control != null) return control.computeTabList();
       } else {
         return new Widget[] {this};
       }
     }
   }
   return new Widget[0];
 }
Beispiel #11
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));
   }
 }
Beispiel #12
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);
    }
  }
 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;
 }
 void scrollInPixels(int destX, int destY, int x, int y, int width, int height, boolean all) {
   forceResize();
   boolean isFocus = caret != null && caret.isFocusCaret();
   if (isFocus) caret.killFocus();
   RECT sourceRect = new RECT();
   OS.SetRect(sourceRect, x, y, x + width, y + height);
   RECT clientRect = new RECT();
   OS.GetClientRect(handle, clientRect);
   if (OS.IntersectRect(clientRect, sourceRect, clientRect)) {
     if (OS.IsWinCE) {
       OS.UpdateWindow(handle);
     } else {
       int flags = OS.RDW_UPDATENOW | OS.RDW_ALLCHILDREN;
       OS.RedrawWindow(handle, null, 0, flags);
     }
   }
   int deltaX = destX - x, deltaY = destY - y;
   if (findImageControl() != null) {
     if (OS.IsWinCE) {
       OS.InvalidateRect(handle, sourceRect, true);
     } else {
       int flags = OS.RDW_ERASE | OS.RDW_FRAME | OS.RDW_INVALIDATE;
       if (all) flags |= OS.RDW_ALLCHILDREN;
       OS.RedrawWindow(handle, sourceRect, 0, flags);
     }
     OS.OffsetRect(sourceRect, deltaX, deltaY);
     if (OS.IsWinCE) {
       OS.InvalidateRect(handle, sourceRect, true);
     } else {
       int flags = OS.RDW_ERASE | OS.RDW_FRAME | OS.RDW_INVALIDATE;
       if (all) flags |= OS.RDW_ALLCHILDREN;
       OS.RedrawWindow(handle, sourceRect, 0, flags);
     }
   } else {
     int flags = OS.SW_INVALIDATE | OS.SW_ERASE;
     /*
      * Feature in Windows.  If any child in the widget tree partially
      * intersects the scrolling rectangle, Windows moves the child
      * and copies the bits that intersect the scrolling rectangle but
      * does not redraw the child.
      *
      * Feature in Windows.  When any child in the widget tree does not
      * intersect the scrolling rectangle but the parent does intersect,
      * Windows does not move the child.  This is the documented (but
      * strange) Windows behavior.
      *
      * The fix is to not use SW_SCROLLCHILDREN and move the children
      * explicitly after scrolling.
      */
     //		if (all) flags |= OS.SW_SCROLLCHILDREN;
     OS.ScrollWindowEx(handle, deltaX, deltaY, sourceRect, null, 0, null, flags);
   }
   if (all) {
     Control[] children = _getChildren();
     for (int i = 0; i < children.length; i++) {
       Control child = children[i];
       Rectangle rect = child.getBoundsInPixels();
       if (Math.min(x + width, rect.x + rect.width) >= Math.max(x, rect.x)
           && Math.min(y + height, rect.y + rect.height) >= Math.max(y, rect.y)) {
         child.setLocationInPixels(rect.x + deltaX, rect.y + deltaY);
       }
     }
   }
   if (isFocus) caret.setFocus();
 }
Beispiel #15
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();
 }
  private void drag(Event dragEvent) {
    DNDEvent event = new DNDEvent();
    event.widget = this;
    event.x = dragEvent.x;
    event.y = dragEvent.y;
    event.time = OS.GetMessageTime();
    event.doit = true;
    notifyListeners(DND.DragStart, event);
    if (!event.doit || transferAgents == null || transferAgents.length == 0) return;

    int[] pdwEffect = new int[1];
    int operations = opToOs(getStyle());
    Display display = control.getDisplay();
    String key = "org.eclipse.swt.internal.win32.runMessagesInIdle"; // $NON-NLS-1$
    Object oldValue = display.getData(key);
    display.setData(key, Boolean.TRUE);
    ImageList imagelist = null;
    Image image = event.image;
    hwndDrag = 0;
    topControl = null;
    if (image != null) {
      imagelist = new ImageList(SWT.NONE);
      imagelist.add(image);
      topControl = control.getShell();
      /*
       * Bug in Windows. The image is inverted if the shell is RIGHT_TO_LEFT.
       * The fix is to create a transparent window that covers the shell client
       * area and use it during the drag to prevent the image from being inverted.
       * On XP if the shell is RTL, the image is not displayed.
       */
      int offsetX = event.offsetX;
      hwndDrag = topControl.handle;
      if ((topControl.getStyle() & SWT.RIGHT_TO_LEFT) != 0) {
        offsetX = image.getBounds().width - offsetX;
        RECT rect = new RECT();
        OS.GetClientRect(topControl.handle, rect);
        hwndDrag =
            OS.CreateWindowEx(
                OS.WS_EX_TRANSPARENT | OS.WS_EX_NOINHERITLAYOUT,
                WindowClass,
                null,
                OS.WS_CHILD | OS.WS_CLIPSIBLINGS,
                0,
                0,
                rect.right - rect.left,
                rect.bottom - rect.top,
                topControl.handle,
                0,
                OS.GetModuleHandle(null),
                null);
        OS.ShowWindow(hwndDrag, OS.SW_SHOW);
      }
      OS.ImageList_BeginDrag(imagelist.getHandle(), 0, offsetX, event.offsetY);
      /*
       * Feature in Windows. When ImageList_DragEnter() is called,
       * it takes a snapshot of the screen  If a drag is started
       * when another window is in front, then the snapshot will
       * contain part of the other window, causing pixel corruption.
       * The fix is to force all paints to be delivered before
       * calling ImageList_DragEnter().
       */
      if (OS.IsWinCE) {
        OS.UpdateWindow(topControl.handle);
      } else {
        int flags = OS.RDW_UPDATENOW | OS.RDW_ALLCHILDREN;
        OS.RedrawWindow(topControl.handle, null, 0, flags);
      }
      POINT pt = new POINT();
      pt.x = dragEvent.x;
      pt.y = dragEvent.y;
      OS.MapWindowPoints(control.handle, 0, pt, 1);
      RECT rect = new RECT();
      OS.GetWindowRect(hwndDrag, rect);
      OS.ImageList_DragEnter(hwndDrag, pt.x - rect.left, pt.y - rect.top);
    }
    int result = COM.DRAGDROP_S_CANCEL;
    try {
      result =
          COM.DoDragDrop(iDataObject.getAddress(), iDropSource.getAddress(), operations, pdwEffect);
    } finally {
      // ensure that we don't leave transparent window around
      if (hwndDrag != 0) {
        OS.ImageList_DragLeave(hwndDrag);
        OS.ImageList_EndDrag();
        imagelist.dispose();
        if (hwndDrag != topControl.handle) OS.DestroyWindow(hwndDrag);
        hwndDrag = 0;
        topControl = null;
      }
      display.setData(key, oldValue);
    }
    int operation = osToOp(pdwEffect[0]);
    if (dataEffect == DND.DROP_MOVE) {
      operation =
          (operation == DND.DROP_NONE || operation == DND.DROP_COPY)
              ? DND.DROP_TARGET_MOVE
              : DND.DROP_MOVE;
    } else {
      if (dataEffect != DND.DROP_NONE) {
        operation = dataEffect;
      }
    }
    event = new DNDEvent();
    event.widget = this;
    event.time = OS.GetMessageTime();
    event.doit = (result == COM.DRAGDROP_S_DROP);
    event.detail = operation;
    notifyListeners(DND.DragEnd, event);
    dataEffect = DND.DROP_NONE;
  }